
paul@f0:~ % doas freebsd-update fetch paul@f0:~ % doas freebsd-update install paul@f0:~ % doas shutdown -r now .. .. paul@f0:~ % doas pkg update paul@f0:~ % doas pkg upgrade paul@f0:~ % reboot
paul@f0:~ % doas pkg install wireguard-tools paul@f0:~ % doas sysrc wireguard_interfaces=wg0 wireguard_interfaces: -> wg0 paul@f0:~ % doas sysrc wireguard_enable=YES wireguard_enable: -> YES paul@f0:~ % doas mkdir -p /usr/local/etc/wireguard paul@f0:~ % doas touch /usr/local/etc/wireguard/wg0.conf paul@f0:~ % doas service wireguard start paul@f0:~ % doas wg show interface: wg0 public key: L+V9o0fNYkMVKNqsX7spBzD/9oSvxM/C7ZCZX1jLO3Q= private key: (hidden) listening port: 20246
paul@f0:~ % cat <<END | doas tee -a /etc/hosts 192.168.1.120 r0 r0.lan r0.lan.buetow.org 192.168.1.121 r1 r1.lan r1.lan.buetow.org 192.168.1.122 r2 r2.lan r2.lan.buetow.org 192.168.2.130 f0.wg0 f0.wg0.wan.buetow.org 192.168.2.131 f1.wg0 f1.wg0.wan.buetow.org 192.168.2.132 f2.wg0 f2.wg0.wan.buetow.org 192.168.2.120 r0.wg0 r0.wg0.wan.buetow.org 192.168.2.121 r1.wg0 r1.wg0.wan.buetow.org 192.168.2.122 r2.wg0 r2.wg0.wan.buetow.org 192.168.2.110 blowfish.wg0 blowfish.wg0.wan.buetow.org 192.168.2.111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org END
[root@r0 ~] dnf update -y [root@r0 ~] reboot
[root@r0 ~] dnf install -y wireguard-tools [root@r0 ~] mkdir -p /etc/wireguard [root@r0 ~] touch /etc/wireguard/wg0.conf [root@r0 ~] systemctl enable wg-quick@wg0.service [root@r0 ~] systemctl start wg-quick@wg0.service [root@r0 ~] systemctl disable firewalld
[root@r0 ~] cat <<END >>/etc/hosts 192.168.1.130 f0 f0.lan f0.lan.buetow.org 192.168.1.131 f1 f1.lan f1.lan.buetow.org 192.168.1.132 f2 f2.lan f2.lan.buetow.org 192.168.2.130 f0.wg0 f0.wg0.wan.buetow.org 192.168.2.131 f1.wg0 f1.wg0.wan.buetow.org 192.168.2.132 f2.wg0 f2.wg0.wan.buetow.org 192.168.2.120 r0.wg0 r0.wg0.wan.buetow.org 192.168.2.121 r1.wg0 r1.wg0.wan.buetow.org 192.168.2.122 r2.wg0 r2.wg0.wan.buetow.org 192.168.2.110 blowfish.wg0 blowfish.wg0.wan.buetow.org 192.168.2.111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org END
[root@r0 ~] dnf install -y policycoreutils-python-utils [root@r0 ~] semanage permissive -a wireguard_t [root@r0 ~] reboot
blowfish$ doas pkg_add wireguard-tools blowfish$ doas mkdir /etc/wireguard blowfish$ doas touch /etc/wireguard/wg0.conf blowsish$ cat <<END | doas tee /etc/hostname.wg0 inet 192.168.2.110 255.255.255.0 NONE up !/usr/local/bin/wg setconf wg0 /etc/wireguard/wg0.conf END
blowfish$ cat <<END | doas tee -a /etc/hosts 192.168.2.130 f0.wg0 f0.wg0.wan.buetow.org 192.168.2.131 f1.wg0 f1.wg0.wan.buetow.org 192.168.2.132 f2.wg0 f2.wg0.wan.buetow.org 192.168.2.120 r0.wg0 r0.wg0.wan.buetow.org 192.168.2.121 r1.wg0 r1.wg0.wan.buetow.org 192.168.2.122 r2.wg0 r2.wg0.wan.buetow.org 192.168.2.110 blowfish.wg0 blowfish.wg0.wan.buetow.org 192.168.2.111 fishfinger.wg0 fishfinger.wg0.wan.buetow.org END
[Interface] # f0.wg0.wan.buetow.org Address = 192.168.2.130 PrivateKey = ************************** ListenPort = 56709 [Peer] # f1.lan.buetow.org as f1.wg0.wan.buetow.org PublicKey = ************************** PresharedKey = ************************** AllowedIPs = 192.168.2.131/32 Endpoint = 192.168.1.131:56709 # No KeepAlive configured [Peer] # f2.lan.buetow.org as f2.wg0.wan.buetow.org PublicKey = ************************** PresharedKey = ************************** AllowedIPs = 192.168.2.132/32 Endpoint = 192.168.1.132:56709 # No KeepAlive configured [Peer] # r0.lan.buetow.org as r0.wg0.wan.buetow.org PublicKey = ************************** PresharedKey = ************************** AllowedIPs = 192.168.2.120/32 Endpoint = 192.168.1.120:56709 # No KeepAlive configured [Peer] # r1.lan.buetow.org as r1.wg0.wan.buetow.org PublicKey = ************************** PresharedKey = ************************** AllowedIPs = 192.168.2.121/32 Endpoint = 192.168.1.121:56709 # No KeepAlive configured [Peer] # r2.lan.buetow.org as r2.wg0.wan.buetow.org PublicKey = ************************** PresharedKey = ************************** AllowedIPs = 192.168.2.122/32 Endpoint = 192.168.1.122:56709 # No KeepAlive configured [Peer] # blowfish.buetow.org as blowfish.wg0.wan.buetow.org PublicKey = ************************** PresharedKey = ************************** AllowedIPs = 192.168.2.110/32 Endpoint = 23.88.35.144:56709 PersistentKeepalive = 25 [Peer] # fishfinger.buetow.org as fishfinger.wg0.wan.buetow.org PublicKey = ************************** PresharedKey = ************************** AllowedIPs = 192.168.2.111/32 Endpoint = 46.23.94.99:56709 PersistentKeepalive = 25
> git clone https://codeberg.org/snonux/wireguardmeshgenerator > cd ./wireguardmeshgenerator > bundle install > sudo dnf install -y wireguard-tools
---
hosts:
f0:
os: FreeBSD
ssh:
user: paul
conf_dir: /usr/local/etc/wireguard
sudo_cmd: doas
reload_cmd: service wireguard reload
lan:
domain: 'lan.buetow.org'
ip: '192.168.1.130'
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.130'
f1:
os: FreeBSD
ssh:
user: paul
conf_dir: /usr/local/etc/wireguard
sudo_cmd: doas
reload_cmd: service wireguard reload
lan:
domain: 'lan.buetow.org'
ip: '192.168.1.131'
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.131'
f2:
os: FreeBSD
ssh:
user: paul
conf_dir: /usr/local/etc/wireguard
sudo_cmd: doas
reload_cmd: service wireguard reload
lan:
domain: 'lan.buetow.org'
ip: '192.168.1.132'
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.132'
r0:
os: Linux
ssh:
user: root
conf_dir: /etc/wireguard
sudo_cmd:
reload_cmd: systemctl reload wg-quick@wg0.service
lan:
domain: 'lan.buetow.org'
ip: '192.168.1.120'
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.120'
r1:
os: Linux
ssh:
user: root
conf_dir: /etc/wireguard
sudo_cmd:
reload_cmd: systemctl reload wg-quick@wg0.service
lan:
domain: 'lan.buetow.org'
ip: '192.168.1.121'
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.121'
r2:
os: Linux
ssh:
user: root
conf_dir: /etc/wireguard
sudo_cmd:
reload_cmd: systemctl reload wg-quick@wg0.service
lan:
domain: 'lan.buetow.org'
ip: '192.168.1.122'
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.122'
blowfish:
os: OpenBSD
ssh:
user: rex
conf_dir: /etc/wireguard
sudo_cmd: doas
reload_cmd: sh /etc/netstart wg0
internet:
domain: 'buetow.org'
ip: '23.88.35.144'
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.110'
fishfinger:
os: OpenBSD
ssh:
user: rex
conf_dir: /etc/wireguard
sudo_cmd: doas
reload_cmd: sh /etc/netstart wg0
internet:
domain: 'buetow.org'
ip: '46.23.94.99'
wg0:
domain: 'wg0.wan.buetow.org'
ip: '192.168.2.111'
begin
options = { hosts: [] }
OptionParser.new do |opts|
opts.banner = 'Usage: wireguardmeshgenerator.rb [options]'
opts.on('--generate', 'Generate Wireguard configs') do
options[:generate] = true
end
opts.on('--install', 'Install Wireguard configs') do
options[:install] = true
end
opts.on('--clean', 'Clean Wireguard configs') do
options[:clean] = true
end
opts.on('--hosts=HOSTS', 'Comma separated hosts to configure') do |hosts|
options[:hosts] = hosts.split(',')
end
end.parse!
conf = YAML.load_file('wireguardmeshgenerator.yaml').freeze
conf['hosts'].keys.select { options[:hosts].empty? || options[:hosts].include?(_1) }
.each do |host|
# Generate Wireguard configuration for the host reload!
WireguardConfig.new(host, conf['hosts']).generate! if options[:generate]
# Install Wireguard configuration for the host.
InstallConfig.new(host, conf['hosts']).upload!.install!.reload! if options[:install]
# Clean Wireguard configuration for the host.
WireguardConfig.new(host, conf['hosts']).clean! if options[:clean]
end
rescue StandardError => e
puts "Error: #{e.message}"
puts e.backtrace.join("\n")
exit 2
end
task :generate do ruby 'wireguardmeshgenerator.rb', '--generate' end task :clean do ruby 'wireguardmeshgenerator.rb', '--clean' end task :install do ruby 'wireguardmeshgenerator.rb', '--install' end task default: :generate
> rake generate /usr/bin/ruby wireguardmeshgenerator.rb --generate Generating dist/f0/etc/wireguard/wg0.conf Generating dist/f1/etc/wireguard/wg0.conf Generating dist/f2/etc/wireguard/wg0.conf Generating dist/r0/etc/wireguard/wg0.conf Generating dist/r1/etc/wireguard/wg0.conf Generating dist/r2/etc/wireguard/wg0.conf Generating dist/blowfish/etc/wireguard/wg0.conf Generating dist/fishfinger/etc/wireguard/wg0.conf
> find keys/ -type f keys/f0/priv.key keys/f0/pub.key keys/psk/f0_f1.key keys/psk/f0_f2.key keys/psk/f0_r0.key keys/psk/f0_r1.key keys/psk/f0_r2.key keys/psk/blowfish_f0.key keys/psk/f0_fishfinger.key keys/psk/f1_f2.key keys/psk/f1_r0.key keys/psk/f1_r1.key keys/psk/f1_r2.key keys/psk/blowfish_f1.key keys/psk/f1_fishfinger.key keys/psk/f2_r0.key keys/psk/f2_r1.key keys/psk/f2_r2.key keys/psk/blowfish_f2.key keys/psk/f2_fishfinger.key keys/psk/r0_r1.key keys/psk/r0_r2.key keys/psk/blowfish_r0.key keys/psk/fishfinger_r0.key keys/psk/r1_r2.key keys/psk/blowfish_r1.key keys/psk/fishfinger_r1.key keys/psk/blowfish_r2.key keys/psk/fishfinger_r2.key keys/psk/blowfish_fishfinger.key keys/f1/priv.key keys/f1/pub.key keys/f2/priv.key keys/f2/pub.key keys/r0/priv.key keys/r0/pub.key keys/r1/priv.key keys/r1/pub.key keys/r2/priv.key keys/r2/pub.key keys/blowfish/priv.key keys/blowfish/pub.key keys/fishfinger/priv.key keys/fishfinger/pub.key
> rake install /usr/bin/ruby wireguardmeshgenerator.rb --install Uploading dist/f0/etc/wireguard/wg0.conf to f0.lan.buetow.org:. Installing Wireguard config on f0 Uploading cmd.sh to f0.lan.buetow.org:. + [ ! -d /usr/local/etc/wireguard ] + doas chmod 700 /usr/local/etc/wireguard + doas mv -v wg0.conf /usr/local/etc/wireguard wg0.conf -> /usr/local/etc/wireguard/wg0.conf + doas chmod 644 /usr/local/etc/wireguard/wg0.conf + rm cmd.sh Reloading Wireguard on f0 Uploading cmd.sh to f0.lan.buetow.org:. + doas service wireguard reload + rm cmd.sh Uploading dist/f1/etc/wireguard/wg0.conf to f1.lan.buetow.org:. Installing Wireguard config on f1 Uploading cmd.sh to f1.lan.buetow.org:. + [ ! -d /usr/local/etc/wireguard ] + doas chmod 700 /usr/local/etc/wireguard + doas mv -v wg0.conf /usr/local/etc/wireguard wg0.conf -> /usr/local/etc/wireguard/wg0.conf + doas chmod 644 /usr/local/etc/wireguard/wg0.conf + rm cmd.sh Reloading Wireguard on f1 Uploading cmd.sh to f1.lan.buetow.org:. + doas service wireguard reload + rm cmd.sh Uploading dist/f2/etc/wireguard/wg0.conf to f2.lan.buetow.org:. Installing Wireguard config on f2 Uploading cmd.sh to f2.lan.buetow.org:. + [ ! -d /usr/local/etc/wireguard ] + doas chmod 700 /usr/local/etc/wireguard + doas mv -v wg0.conf /usr/local/etc/wireguard wg0.conf -> /usr/local/etc/wireguard/wg0.conf + doas chmod 644 /usr/local/etc/wireguard/wg0.conf + rm cmd.sh Reloading Wireguard on f2 Uploading cmd.sh to f2.lan.buetow.org:. + doas service wireguard reload + rm cmd.sh Uploading dist/r0/etc/wireguard/wg0.conf to r0.lan.buetow.org:. Installing Wireguard config on r0 Uploading cmd.sh to r0.lan.buetow.org:. + '[' '!' -d /etc/wireguard ']' + chmod 700 /etc/wireguard + mv -v wg0.conf /etc/wireguard renamed 'wg0.conf' -> '/etc/wireguard/wg0.conf' + chmod 644 /etc/wireguard/wg0.conf + rm cmd.sh Reloading Wireguard on r0 Uploading cmd.sh to r0.lan.buetow.org:. + systemctl reload wg-quick@wg0.service + rm cmd.sh Uploading dist/r1/etc/wireguard/wg0.conf to r1.lan.buetow.org:. Installing Wireguard config on r1 Uploading cmd.sh to r1.lan.buetow.org:. + '[' '!' -d /etc/wireguard ']' + chmod 700 /etc/wireguard + mv -v wg0.conf /etc/wireguard renamed 'wg0.conf' -> '/etc/wireguard/wg0.conf' + chmod 644 /etc/wireguard/wg0.conf + rm cmd.sh Reloading Wireguard on r1 Uploading cmd.sh to r1.lan.buetow.org:. + systemctl reload wg-quick@wg0.service + rm cmd.sh Uploading dist/r2/etc/wireguard/wg0.conf to r2.lan.buetow.org:. Installing Wireguard config on r2 Uploading cmd.sh to r2.lan.buetow.org:. + '[' '!' -d /etc/wireguard ']' + chmod 700 /etc/wireguard + mv -v wg0.conf /etc/wireguard renamed 'wg0.conf' -> '/etc/wireguard/wg0.conf' + chmod 644 /etc/wireguard/wg0.conf + rm cmd.sh Reloading Wireguard on r2 Uploading cmd.sh to r2.lan.buetow.org:. + systemctl reload wg-quick@wg0.service + rm cmd.sh Uploading dist/blowfish/etc/wireguard/wg0.conf to blowfish.buetow.org:. Installing Wireguard config on blowfish Uploading cmd.sh to blowfish.buetow.org:. + [ ! -d /etc/wireguard ] + doas chmod 700 /etc/wireguard + doas mv -v wg0.conf /etc/wireguard wg0.conf -> /etc/wireguard/wg0.conf + doas chmod 644 /etc/wireguard/wg0.conf + rm cmd.sh Reloading Wireguard on blowfish Uploading cmd.sh to blowfish.buetow.org:. + doas sh /etc/netstart wg0 + rm cmd.sh Uploading dist/fishfinger/etc/wireguard/wg0.conf to fishfinger.buetow.org:. Installing Wireguard config on fishfinger Uploading cmd.sh to fishfinger.buetow.org:. + [ ! -d /etc/wireguard ] + doas chmod 700 /etc/wireguard + doas mv -v wg0.conf /etc/wireguard wg0.conf -> /etc/wireguard/wg0.conf + doas chmod 644 /etc/wireguard/wg0.conf + rm cmd.sh Reloading Wireguard on fishfinger Uploading cmd.sh to fishfinger.buetow.org:. + doas sh /etc/netstart wg0 + rm cmd.sh
> rake clean > rake generate > rake install
paul@f0:~ % doas wg show interface: wg0 public key: Jm6YItMt94++dIeOyVi1I9AhNt2qQcryxCZezoX7X2Y= private key: (hidden) listening port: 56709 peer: 8PvGZH1NohHpZPVJyjhctBX9xblsNvYBhpg68FsFcns= preshared key: (hidden) endpoint: 46.23.94.99:56709 allowed ips: 192.168.2.111/32 latest handshake: 1 minute, 46 seconds ago transfer: 124 B received, 1.75 KiB sent persistent keepalive: every 25 seconds peer: Xow+d3qVXgUMk4pcRSQ6Fe+vhYBa3VDyHX/4jrGoKns= preshared key: (hidden) endpoint: 23.88.35.144:56709 allowed ips: 192.168.2.110/32 latest handshake: 1 minute, 52 seconds ago transfer: 124 B received, 1.60 KiB sent persistent keepalive: every 25 seconds peer: s3e93XoY7dPUQgLiVO4d8x/SRCFgEew+/wP7+zwgehI= preshared key: (hidden) endpoint: 192.168.1.120:56709 allowed ips: 192.168.2.120/32 peer: 2htXdNcxzpI2FdPDJy4T4VGtm1wpMEQu1AkQHjNY6F8= preshared key: (hidden) endpoint: 192.168.1.131:56709 allowed ips: 192.168.2.131/32 peer: 0Y/H20W8YIbF7DA1sMwMacLI8WS9yG+1/QO7m2oyllg= preshared key: (hidden) endpoint: 192.168.1.122:56709 allowed ips: 192.168.2.122/32 peer: Hhy9kMPOOjChXV2RA5WeCGs+J0FE3rcNPDw/TLSn7i8= preshared key: (hidden) endpoint: 192.168.1.121:56709 allowed ips: 192.168.2.121/32 peer: SlGVsACE1wiaRoGvCR3f7AuHfRS+1jjhS+YwEJ2HvF0= preshared key: (hidden) endpoint: 192.168.1.132:56709 allowed ips: 192.168.2.132/32
paul@f0:~ % foreach peer ( f1 f2 r0 r1 r2 blowfish fishfinger ) foreach? ping -c2 $peer.wg0 foreach? echo foreach? end PING f1.wg0 (192.168.2.131): 56 data bytes 64 bytes from 192.168.2.131: icmp_seq=0 ttl=64 time=0.334 ms 64 bytes from 192.168.2.131: icmp_seq=1 ttl=64 time=0.260 ms --- f1.wg0 ping statistics --- 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.260/0.297/0.334/0.037 ms PING f2.wg0 (192.168.2.132): 56 data bytes 64 bytes from 192.168.2.132: icmp_seq=0 ttl=64 time=0.323 ms 64 bytes from 192.168.2.132: icmp_seq=1 ttl=64 time=0.303 ms --- f2.wg0 ping statistics --- 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.303/0.313/0.323/0.010 ms PING r0.wg0 (192.168.2.120): 56 data bytes 64 bytes from 192.168.2.120: icmp_seq=0 ttl=64 time=0.716 ms 64 bytes from 192.168.2.120: icmp_seq=1 ttl=64 time=0.406 ms --- r0.wg0 ping statistics --- 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.406/0.561/0.716/0.155 ms PING r1.wg0 (192.168.2.121): 56 data bytes 64 bytes from 192.168.2.121: icmp_seq=0 ttl=64 time=0.639 ms 64 bytes from 192.168.2.121: icmp_seq=1 ttl=64 time=0.629 ms --- r1.wg0 ping statistics --- 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.629/0.634/0.639/0.005 ms PING r2.wg0 (192.168.2.122): 56 data bytes 64 bytes from 192.168.2.122: icmp_seq=0 ttl=64 time=0.569 ms 64 bytes from 192.168.2.122: icmp_seq=1 ttl=64 time=0.479 ms --- r2.wg0 ping statistics --- 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.479/0.524/0.569/0.045 ms PING blowfish.wg0 (192.168.2.110): 56 data bytes 64 bytes from 192.168.2.110: icmp_seq=0 ttl=255 time=35.745 ms 64 bytes from 192.168.2.110: icmp_seq=1 ttl=255 time=35.481 ms --- blowfish.wg0 ping statistics --- 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 35.481/35.613/35.745/0.132 ms PING fishfinger.wg0 (192.168.2.111): 56 data bytes 64 bytes from 192.168.2.111: icmp_seq=0 ttl=255 time=33.992 ms 64 bytes from 192.168.2.111: icmp_seq=1 ttl=255 time=33.751 ms --- fishfinger.wg0 ping statistics --- 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 33.751/33.872/33.992/0.120 ms
paul@f0:~ % doas wg show interface: wg0 public key: Jm6YItMt94++dIeOyVi1I9AhNt2qQcryxCZezoX7X2Y= private key: (hidden) listening port: 56709 peer: 0Y/H20W8YIbF7DA1sMwMacLI8WS9yG+1/QO7m2oyllg= preshared key: (hidden) endpoint: 192.168.1.122:56709 allowed ips: 192.168.2.122/32 latest handshake: 10 seconds ago transfer: 440 B received, 532 B sent peer: Hhy9kMPOOjChXV2RA5WeCGs+J0FE3rcNPDw/TLSn7i8= preshared key: (hidden) endpoint: 192.168.1.121:56709 allowed ips: 192.168.2.121/32 latest handshake: 12 seconds ago transfer: 440 B received, 564 B sent peer: s3e93XoY7dPUQgLiVO4d8x/SRCFgEew+/wP7+zwgehI= preshared key: (hidden) endpoint: 192.168.1.120:56709 allowed ips: 192.168.2.120/32 latest handshake: 14 seconds ago transfer: 440 B received, 564 B sent peer: SlGVsACE1wiaRoGvCR3f7AuHfRS+1jjhS+YwEJ2HvF0= preshared key: (hidden) endpoint: 192.168.1.132:56709 allowed ips: 192.168.2.132/32 latest handshake: 17 seconds ago transfer: 472 B received, 564 B sent peer: Xow+d3qVXgUMk4pcRSQ6Fe+vhYBa3VDyHX/4jrGoKns= preshared key: (hidden) endpoint: 23.88.35.144:56709 allowed ips: 192.168.2.110/32 latest handshake: 55 seconds ago transfer: 472 B received, 596 B sent persistent keepalive: every 25 seconds peer: 8PvGZH1NohHpZPVJyjhctBX9xblsNvYBhpg68FsFcns= preshared key: (hidden) endpoint: 46.23.94.99:56709 allowed ips: 192.168.2.111/32 latest handshake: 55 seconds ago transfer: 472 B received, 596 B sent persistent keepalive: every 25 seconds peer: 2htXdNcxzpI2FdPDJy4T4VGtm1wpMEQu1AkQHjNY6F8= preshared key: (hidden) endpoint: 192.168.1.131:56709 allowed ips: 192.168.2.131/32
_______ s
|.-----.| s
|| Tmux|| s
||_.-._|| |\ \\\\__ o s
`--)-(--` | \_/ o \ o s
__[=== o]__ > _ (( <_ oo s
|:::::::::::|\ | / \__+___/ s
jgs `-=========-`() |/ |/ s
mod. by Paul B.
alias tn 'tmux::new' alias ta 'tmux::attach' alias tx 'tmux::remote' alias ts 'tmux::search' alias tssh 'tmux::cluster_ssh' alias tm tmux alias tl 'tmux list-sessions' alias foo 'tmux::new foo' alias bar 'tmux::new bar' alias baz 'tmux::new baz'
# Create new session and if alread exists attach to it
function tmux::new
set -l session $argv[1]
_tmux::cleanup_default
if test -z "$session"
tmux::new (string join "" T (date +%s))
else
tmux new-session -d -s $session
tmux -2 attach-session -t $session || tmux -2 switch-client -t $session
end
end
function _tmux::cleanup_default
tmux list-sessions | string match -r '^T.*: ' | string match -v -r attached | string split ':' | while read -l s
echo "Killing $s"
tmux kill-session -t "$s"
end
end
function tmux::attach
set -l session $argv[1]
if test -z "$session"
tmux attach-session || tmux::new
else
tmux attach-session -t $session || tmux::new $session
end
end
function tmux::remote
set -l server $argv[1]
tmux new -s $server "ssh -A -t $server 'tmux attach-session || tmux'" || tmux attach-session -d -t $server
end
set-option -g prefix C-g
function tmux::search
set -l session (tmux list-sessions | fzf | cut -d: -f1)
if test -z "$TMUX"
tmux attach-session -t $session
else
tmux switch -t $session
end
end

function tmux::cluster_ssh
if test -f "$argv[1]"
tmux::tssh_from_file $argv[1]
return
end
tmux::tssh_from_argument $argv
end
function tmux::tssh_from_argument
set -l session $argv[1]
set first_server_or_container $argv[2]
set remaining_servers $argv[3..-1]
if test -z "$first_server_or_container"
set first_server_or_container $session
end
tmux new-session -d -s $session (_tmux::connect_command "$first_server_or_container")
if not tmux list-session | grep "^$session:"
echo "Could not create session $session"
return 2
end
for server_or_container in $remaining_servers
tmux split-window -t $session "tmux select-layout tiled; $(_tmux::connect_command "$server_or_container")"
end
tmux setw -t $session synchronize-panes on
tmux -2 attach-session -t $session || tmux -2 switch-client -t $session
end
bind-key p setw synchronize-panes off bind-key P setw synchronize-panes on
function tmux::tssh_from_file
set -l serverlist $argv[1]
set -l session (basename $serverlist | cut -d. -f1)
tmux::tssh_from_argument $session (awk '{ print $1 }' $serverlist | sed 's/.lan./.lan/g')
end
$ tssh fish blowfish.buetow.org fishfinger.buetow.org \
fishbone.buetow.org user@octopus.buetow.org
$ tssh manyservers.txt
bind-key -T copy-mode-vi 'v' send -X begin-selection bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel
source ~/.config/tmux/tmux.local.conf set-option -g allow-rename off set-option -g history-limit 100000 set-option -g status-bg '#444444' set-option -g status-fg '#ffa500' set-option -s escape-time 0
set-window-option -g mode-keys vi bind-key -T copy-mode-vi 'v' send -X begin-selection bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel
bind-key h select-pane -L bind-key j select-pane -D bind-key k select-pane -U bind-key l select-pane -R bind-key H resize-pane -L 5 bind-key J resize-pane -D 5 bind-key K resize-pane -U 5 bind-key L resize-pane -R 5
bind-key c new-window -c '#{pane_current_path}'
bind-key F new-window -n "session-switcher" "tmux list-sessions | fzf | cut -d: -f1 | xargs tmux switch-client -t"
bind-key T choose-tree

bind-key p setw synchronize-panes off bind-key P setw synchronize-panes on bind-key r source-file ~/.config/tmux/tmux.conf \; display-message "tmux.conf reloaded"
__ (`/\ `=\/\ __...--~~~~~-._ _.-~~~~~--...__ `=\/\ \ / \\ `=\/ V \\ //_\___--~~~~~~-._ | _.-~~~~~~--...__\\ // ) (..----~~~~._\ | /_.~~~~----.....__\\ ===( INK )==========\\|//==================== __ejm\___/________dwb`---`______________________

paul@f0:~ % dmesg | grep 'Features2=.*POPCNT' Features2=0x7ffafbbf<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,EST,TM2,SSSE3,SDBG, FMA,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,TSCDLT,AESNI,XSAVE, OSXSAVE,AVX,F16C,RDRAND>
paul@f0:~ % doas pkg install vm-bhyve bhyve-firmware paul@f0:~ % doas sysrc vm_enable=YES vm_enable: -> YES paul@f0:~ % doas sysrc vm_dir=zfs:zroot/bhyve vm_dir: -> zfs:zroot/bhyve paul@f0:~ % doas zfs create zroot/bhyve paul@f0:~ % doas vm init paul@f0:~ % doas vm switch create public paul@f0:~ % doas vm switch add public re0
paul@f0:~ % zfs list | grep bhyve zroot/bhyve 1.74M 453G 1.74M /zroot/bhyve
paul@f0:~ % doas ln -s /zroot/bhyve/ /bhyve
paul@f0:~ % doas vm list NAME DATASTORE LOADER CPU MEMORY VNC AUTO STATE
paul@f0:~ % doas vm iso \ https://download.rockylinux.org/pub/rocky/9/isos/x86_64/Rocky-9.5-x86_64-minimal.iso /zroot/bhyve/.iso/Rocky-9.5-x86_64-minimal.iso 1808 MB 4780 kBps 06m28s paul@f0:/bhyve % doas vm create rocky
paul@f0:/bhyve/rocky % cat rocky.conf loader="bhyveload" cpu=1 memory=256M network0_type="virtio-net" network0_switch="public" disk0_type="virtio-blk" disk0_name="disk0.img" uuid="1c4655ac-c828-11ef-a920-e8ff1ed71ca0" network0_mac="58:9c:fc:0d:13:3f"
guest="linux" loader="uefi" uefi_vars="yes" cpu=4 memory=14G network0_type="virtio-net" network0_switch="public" disk0_type="virtio-blk" disk0_name="disk0.img" graphics="yes" graphics_vga=io uuid="1c45400b-c828-11ef-8871-e8ff1ed71cac" network0_mac="58:9c:fc:0d:13:3f"
paul@f0:~ % doas vm install rocky Rocky-9.5-x86_64-minimal.iso Starting rocky * found guest in /zroot/bhyve/rocky * booting... paul@f0:/bhyve/rocky % doas vm list NAME DATASTORE LOADER CPU MEMORY VNC AUTO STATE rocky default uefi 4 14G 0.0.0.0:5900 No Locked (f0.lan.buetow.org) paul@f0:/bhyve/rocky % doas sockstat -4 | grep 5900 root bhyve 6079 8 tcp4 *:5900 *:*
paul@f0:/bhyve/rocky % doas vm stop rocky paul@f0:/bhyve/rocky % doas truncate -s 100G disk0.img paul@f0:/bhyve/rocky % doas vm install rocky Rocky-9.5-x86_64-minimal.iso




paul@f0:/bhyve/rocky % cat <<END | doas tee -a /etc/rc.conf vm_list="rocky" vm_delay="5"
paul@f0:~ % doas vm list NAME DATASTORE LOADER CPU MEMORY VNC AUTO STATE rocky default uefi 4 14G 0.0.0.0:5900 Yes [1] Running (2063)
192.168.1.130 f0 f0.lan f0.lan.buetow.org 192.168.1.131 f1 f1.lan f1.lan.buetow.org 192.168.1.132 f2 f2.lan f2.lan.buetow.org
paul@f0:/bhyve/rocky % cat <<END | doas tee -a /etc/hosts 192.168.1.120 r0 r0.lan r0.lan.buetow.org 192.168.1.121 r1 r1.lan r1.lan.buetow.org 192.168.1.122 r2 r2.lan r2.lan.buetow.org END
[root@r0 ~] % dnmcli connection modify enp0s5 ipv4.address 192.168.1.120/24 [root@r0 ~] % dnmcli connection modify enp0s5 ipv4.gateway 192.168.1.1 [root@r0 ~] % dnmcli connection modify enp0s5 ipv4.DNS 192.168.1.1 [root@r0 ~] % dnmcli connection modify enp0s5 ipv4.method manual [root@r0 ~] % dnmcli connection down enp0s5 [root@r0 ~] % dnmcli connection up enp0s5 [root@r0 ~] % hostnamectl set-hostname r0.lan.buetow.org [root@r0 ~] % cat <<END >>/etc/hosts 192.168.1.120 r0 r0.lan r0.lan.buetow.org 192.168.1.121 r1 r1.lan r1.lan.buetow.org 192.168.1.122 r2 r2.lan r2.lan.buetow.org END
% for i in 0 1 2; do ssh-copy-id root@r$i.lan.buetow.org; done
[root@r0 ~] % dnf update [root@r0 ~] % reboot
package main
import "testing"
func BenchmarkCPUSilly1(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = i * i
}
}
func BenchmarkCPUSilly2(b *testing.B) {
var sillyResult float64
for i := 0; i < b.N; i++ {
sillyResult += float64(i)
sillyResult *= float64(i)
divisor := float64(i) + 1
if divisor > 0 {
sillyResult /= divisor
}
}
_ = sillyResult // to avoid compiler optimization
}
paul@f0:~ % doas pkg install git go paul@f0:~ % mkdir ~/git && cd ~/git && \ git clone https://codeberg.org/snonux/sillybench && \ cd sillybench
paul@f0:~/git/sillybench % go version go version go1.24.1 freebsd/amd64 paul@f0:~/git/sillybench % go test -bench=. goos: freebsd goarch: amd64 pkg: codeberg.org/snonux/sillybench cpu: Intel(R) N100 BenchmarkCPUSilly1-4 1000000000 0.4022 ns/op BenchmarkCPUSilly2-4 1000000000 0.4027 ns/op PASS ok codeberg.org/snonux/sillybench 0.891s
[root@r0 ~]# dnf install golang git [root@r0 ~]# mkdir ~/git && cd ~/git && \ git clone https://codeberg.org/snonux/sillybench && \ cd sillybench
[root@r0 sillybench]# go version go version go1.22.9 (Red Hat 1.22.9-2.el9_5) linux/amd64 [root@r0 sillybench]# go test -bench=. goos: linux goarch: amd64 pkg: codeberg.org/snonux/sillybench cpu: Intel(R) N100 BenchmarkCPUSilly1-4 1000000000 0.4347 ns/op BenchmarkCPUSilly2-4 1000000000 0.4345 ns/op
root@freebsd:~/git/sillybench # go test -bench=. goos: freebsd goarch: amd64 pkg: codeberg.org/snonux/sillybench cpu: Intel(R) N100 BenchmarkCPUSilly1 1000000000 0.4273 ns/op BenchmarkCPUSilly2 1000000000 0.4286 ns/op PASS ok codeberg.org/snonux/sillybench 0.949s
paul@f0:~ % doas ubench -s 1 Unix Benchmark Utility v.0.3 Copyright (C) July, 1999 PhysTech, Inc. Author: Sergei Viznyuk <sv@phystech.com> http://www.phystech.com/download/ubench.html FreeBSD 14.2-RELEASE-p1 FreeBSD 14.2-RELEASE-p1 GENERIC amd64 Ubench Single CPU: 671010 (0.40s) Ubench Single MEM: 1705237 (0.48s) ----------------------------------- Ubench Single AVG: 1188123
paul@f0:~ % doas ubench Unix Benchmark Utility v.0.3 Copyright (C) July, 1999 PhysTech, Inc. Author: Sergei Viznyuk <sv@phystech.com> http://www.phystech.com/download/ubench.html FreeBSD 14.2-RELEASE-p1 FreeBSD 14.2-RELEASE-p1 GENERIC amd64 Ubench CPU: 2660220 Ubench MEM: 3095182 -------------------- Ubench AVG: 2877701
root@freebsd:~ # ubench -s 1 Unix Benchmark Utility v.0.3 Copyright (C) July, 1999 PhysTech, Inc. Author: Sergei Viznyuk <sv@phystech.com> http://www.phystech.com/download/ubench.html FreeBSD 14.2-RELEASE-p1 FreeBSD 14.2-RELEASE-p1 GENERIC amd64 Ubench Single CPU: 672792 (0.40s) Ubench Single MEM: 852757 (0.48s) ----------------------------------- Ubench Single AVG: 762774
root@freebsd:~ # ubench Unix Benchmark Utility v.0.3 Copyright (C) July, 1999 PhysTech, Inc. Author: Sergei Viznyuk <sv@phystech.com> http://www.phystech.com/download/ubench.html FreeBSD 14.2-RELEASE-p1 FreeBSD 14.2-RELEASE-p1 GENERIC amd64 Ubench CPU: 2652857 swap_pager: out of swap space swp_pager_getswapspace(27): failed swap_pager: out of swap space swp_pager_getswapspace(18): failed Apr 4 23:02:43 freebsd kernel: pid 862 (ubench), jid 0, uid 0, was killed: failed to reclaim memory swp_pager_getswapspace(6): failed Apr 4 23:02:46 freebsd kernel: pid 863 (ubench), jid 0, uid 0, was killed: failed to reclaim memory Apr 4 23:02:47 freebsd kernel: pid 864 (ubench), jid 0, uid 0, was killed: failed to reclaim memory Apr 4 23:02:48 freebsd kernel: pid 865 (ubench), jid 0, uid 0, was killed: failed to reclaim memory Apr 4 23:02:49 freebsd kernel: pid 861 (ubench), jid 0, uid 0, was killed: failed to reclaim memory Apr 4 23:02:51 freebsd kernel: pid 839 (ubench), jid 0, uid 0, was killed: failed to reclaim memory
PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND 7449 root 14 20 0 14G 78M kqread 2 2:12 399.81% bhyve

git clone https://codeberg.org/snonux/gos.git cd gos
go build -o gos ./cmd/gos go build -o gosc ./cmd/gosc sudo mv gos ~/go/bin sudo mv gosc ~/go/bin
go-task install
{
"MastodonURL": "https://mastodon.example.com",
"MastodonAccessToken": "your-mastodon-access-token",
"LinkedInClientID": "your-linkedin-client-id",
"LinkedInSecret": "your-linkedin-client-secret",
"LinkedInRedirectURL": "http://localhost:8080/callback",
}
./gos --dry
./gos

This is a sample message to be posted on social media platforms. Maybe add a link here: https://foo.zone #foo #cool #gos #golang
share:mastodon The content of the post here
share:mastodon The content of the post is here https://some.foo/link #some #hashtags
share:mastodon,ask,prio Hello wold :-)
share:mastodon,ask,prio Hello World :-)
~/.gosdir/db/platforms/linkedin/foo.share:-mastodon.txt.20241022-102343.queued
./db/platforms/linkedin/foo.share:-mastodon.txt.20241112-121323.posted
gos --geminiSummaryFor 202410,202411,202412
gos --gemtexterEnable --geminiSummaryFor 202410,202411,202412
gos --gemtexterEnable --geminiSummaryFor 202410,202411,202412 --geminiCapsules "foo.zone,paul.buetow.org"
/\_/\ /\_/\ ( o.o ) WHOA!! ( o.o ) > ^ < > ^ < / \ MOEEW! / \ /______\ /______\


package main
import "log"
type fun func() string
func (f fun) Bar() string {
return "Bar"
}
func main() {
var f fun = func() string {
return "Foo"
}
log.Println("Example 1: ", f())
log.Println("Example 2: ", f.Bar())
log.Println("Example 3: ", fun(f.Bar).Bar())
log.Println("Example 4: ", fun(fun(f.Bar).Bar).Bar())
}
❯ go run main.go 2025/02/07 22:56:14 Example 1: Foo 2025/02/07 22:56:14 Example 2: Bar 2025/02/07 22:56:14 Example 3: Bar 2025/02/07 22:56:14 Example 4: Bar
❯ touch Maß ❯ ls -l -rw-r--r--@ 1 paul wheel 0 Feb 7 23:02 Maß ❯ touch Mass ❯ ls -l -rw-r--r--@ 1 paul wheel 0 Feb 7 23:02 Maß ❯ rm Mass ❯ ls -l ❯ touch Mass ❯ ls -ltr -rw-r--r--@ 1 paul wheel 0 Feb 7 23:02 Mass ❯ rm Maß ❯ ls -l
ADFS::4.$.Documents.Techwriter.Myfile
arr = {10, 20, 30, 40, 50}
print(arr[1]) -- Accessing the first element
❯ lua foo.lua 10
# (C) 2006 by Paul C. Buetow
Christmas:{time;#!!!
Children: do tell $wishes;
Santa: for $each (@children) {
BEGIN { read $each, $their, wishes and study them; use Memoize#ing
} use constant gift, 'wrapping';
package Gifts; pack $each, gift and bless $each and goto deliver
or do import if not local $available,!!! HO, HO, HO;
redo Santa, pipe $gifts, to_childs;
redo Santa and do return if last one, is, delivered;
deliver: gift and require diagnostics if our $gifts ,not break;
do{ use NEXT; time; tied $gifts} if broken and dump the, broken, ones;
The_children: sleep and wait for (each %gift) and try { to => untie $gifts };
redo Santa, pipe $gifts, to_childs;
redo Santa and do return if last one, is, delivered;
The_christmas_tree: formline s/ /childrens/, $gifts;
alarm and warn if not exists $Christmas{ tree}, @t, $ENV{HOME};
write <<EMail
to the parents to buy a new christmas tree!!!!111
and send the
EMail
;wait and redo deliver until defined local $tree;
redo Santa, pipe $gifts, to_childs;
redo Santa and do return if last one, is, delivered ;}
END {} our $mission and do sleep until next Christmas ;}
__END__
This is perl, v5.8.8 built for i386-freebsd-64int


paul@f0: ~ % doas freebsd-update fetch paul@f0: ~ % doas freebsd-update install paul@f0: ~ % doas freebsd-update -r 14.2-RELEASE upgrade paul@f0: ~ % doas freebsd-update install paul@f0: ~ % doas shutdown -r now
paul@f0: ~ % doas freebsd-update install paul@f0: ~ % doas pkg update paul@f0: ~ % doas pkg upgrade paul@f0: ~ % doas shutdown -r now
paul@f0:~ % uname -a FreeBSD f0.lan.buetow.org 14.2-RELEASE FreeBSD 14.2-RELEASE releng/14.2-n269506-c8918d6c7412 GENERIC amd64


paul@f0: ~ % doas dmesg | grep UPS ugen0.2: <American Power Conversion Back-UPS BX750MI> at usbus0
paul@f0: ~ % doas install apcupsd
paul@f0:/usr/local/etc/apcupsd % diff -u apcupsd.conf.sample apcupsd.conf --- apcupsd.conf.sample 2024-11-01 16:40:42.000000000 +0200 +++ apcupsd.conf 2024-12-03 10:58:24.009501000 +0200 @@ -31,7 +31,7 @@ # 940-1524C, 940-0024G, 940-0095A, 940-0095B, # 940-0095C, 940-0625A, M-04-02-2000 # -UPSCABLE smart +UPSCABLE usb # To get apcupsd to work, in addition to defining the cable # above, you must also define a UPSTYPE, which corresponds to @@ -88,8 +88,10 @@ # that apcupsd binds to that particular unit # (helpful if you have more than one USB UPS). # -UPSTYPE apcsmart -DEVICE /dev/usv +UPSTYPE usb +DEVICE # POLLTIME <int> # Interval (in seconds) at which apcupsd polls the UPS for status. This
# If during a power failure, the remaining battery percentage # (as reported by the UPS) is below or equal to BATTERYLEVEL, # apcupsd will initiate a system shutdown. BATTERYLEVEL 5 # If during a power failure, the remaining runtime in minutes # (as calculated internally by the UPS) is below or equal to MINUTES, # apcupsd, will initiate a system shutdown. MINUTES 3
paul@f0:/usr/local/etc/apcupsd % doas sysrc apcupsd_enable=YES apcupsd_enable: -> YES paul@f0:/usr/local/etc/apcupsd % doas service apcupsd start Starting apcupsd.
paul@f0:~ % apcaccess APC : 001,035,0857 DATE : 2025-01-26 14:43:27 +0200 HOSTNAME : f0.lan.buetow.org VERSION : 3.14.14 (31 May 2016) freebsd UPSNAME : f0.lan.buetow.org CABLE : USB Cable DRIVER : USB UPS Driver UPSMODE : Stand Alone STARTTIME: 2025-01-26 14:43:25 +0200 MODEL : Back-UPS BX750MI STATUS : ONLINE LINEV : 230.0 Volts LOADPCT : 4.0 Percent BCHARGE : 100.0 Percent TIMELEFT : 65.3 Minutes MBATTCHG : 5 Percent MINTIMEL : 3 Minutes MAXTIME : 0 Seconds SENSE : Medium LOTRANS : 145.0 Volts HITRANS : 295.0 Volts ALARMDEL : No alarm BATTV : 13.6 Volts LASTXFER : Automatic or explicit self test NUMXFERS : 0 TONBATT : 0 Seconds CUMONBATT: 0 Seconds XOFFBATT : N/A SELFTEST : NG STATFLAG : 0x05000008 SERIALNO : 9B2414A03599 BATTDATE : 2001-01-01 NOMINV : 230 Volts NOMBATTV : 12.0 Volts NOMPOWER : 410 Watts END APC : 2025-01-26 14:44:06 +0200
paul@f1:~ % apcaccess -h f0.lan.buetow.org | grep Percent LOADPCT : 12.0 Percent BCHARGE : 94.0 Percent MBATTCHG : 5 Percent
paul@f2:/usr/local/etc/apcupsd % diff -u apcupsd.conf.sample apcupsd.conf --- apcupsd.conf.sample 2024-11-01 16:40:42.000000000 +0200 +++ apcupsd.conf 2025-01-26 15:52:45.108469000 +0200 @@ -31,7 +31,7 @@ # 940-1524C, 940-0024G, 940-0095A, 940-0095B, # 940-0095C, 940-0625A, M-04-02-2000 # -UPSCABLE smart +UPSCABLE ether # To get apcupsd to work, in addition to defining the cable # above, you must also define a UPSTYPE, which corresponds to @@ -52,7 +52,6 @@ # Network Information Server. This is used if the # UPS powering your computer is connected to a # different computer for monitoring. -# # snmp hostname:port:vendor:community # SNMP network link to an SNMP-enabled UPS device. # Hostname is the ip address or hostname of the UPS @@ -88,8 +87,8 @@ # that apcupsd binds to that particular unit # (helpful if you have more than one USB UPS). # -UPSTYPE apcsmart -DEVICE /dev/usv +UPSTYPE net +DEVICE f0.lan.buetow.org:3551 # POLLTIME <int> # Interval (in seconds) at which apcupsd polls the UPS for status. This @@ -147,12 +146,12 @@ # If during a power failure, the remaining battery percentage # (as reported by the UPS) is below or equal to BATTERYLEVEL, # apcupsd will initiate a system shutdown. -BATTERYLEVEL 5 +BATTERYLEVEL 10 # If during a power failure, the remaining runtime in minutes # (as calculated internally by the UPS) is below or equal to MINUTES, # apcupsd, will initiate a system shutdown. -MINUTES 3 +MINUTES 6 # If during a power failure, the UPS has run on batteries for TIMEOUT # many seconds or longer, apcupsd will initiate a system shutdown.So I also ran the following commands on f1 and f2:
paul@f1:/usr/local/etc/apcupsd % doas sysrc apcupsd_enable=YES apcupsd_enable: -> YES paul@f1:/usr/local/etc/apcupsd % doas service apcupsd start Starting apcupsd.
paul@f1:~ % doas apcaccess | grep Percent LOADPCT : 5.0 Percent BCHARGE : 95.0 Percent MBATTCHG : 5 Percent
Broadcast Message from root@f0.lan.buetow.org
(no tty) at 15:03 EET...
Power failure. Running on UPS batteries.
paul@f0:/usr/local/etc/apcupsd % apcaccess -p TIMELEFT 63.9 Minutes
Broadcast Message from root@f0.lan.buetow.org
(no tty) at 15:08 EET...
*** FINAL System shutdown message from root@f0.lan.buetow.org ***
System going down IMMEDIATELY
apcupsd initiated shutdown
Jan 26 17:36:24 f2 apcupsd[2159]: Power failure. Jan 26 17:36:30 f2 apcupsd[2159]: Running on UPS batteries. Jan 26 17:36:30 f2 apcupsd[2159]: Battery charge below low limit. Jan 26 17:36:30 f2 apcupsd[2159]: Initiating system shutdown! Jan 26 17:36:30 f2 apcupsd[2159]: User logins prohibited Jan 26 17:36:32 f2 apcupsd[2159]: apcupsd exiting, signal 15 Jan 26 17:36:32 f2 apcupsd[2159]: apcupsd shutdown succeeded
export EDITOR=hx
export VISUAL=$EDITOR
export GIT_EDITOR=$EDITOR
export HELIX_CONFIG_DIR=$HOME/.config/helix
editor::helix::random_theme () {
# May add more theme search paths based on OS. This one is
# for Fedora Linux, but there is also MacOS, etc.
local -r theme_dir=/usr/share/helix/runtime/themes
if [ ! -d $theme_dir ]; then
echo "Helix theme dir $theme_dir doesnt exist"
return 1
fi
local -r config_file=$HELIX_CONFIG_DIR/config.toml
local -r random_theme="$(basename "$(ls $theme_dir \
| grep -v random.toml | grep .toml | sort -R \
| head -n 1)" | cut -d. -f1)"
sed "/^theme =/ { s/.*/theme = \"$random_theme\"/; }" \
$config_file > $config_file.tmp &&
mv $config_file.tmp $config_file
}
if [ -f $HELIX_CONFIG_DIR/config.toml ]; then
editor::helix::random_theme
fi
[paul@earth] ~ % editor::helix::random_theme [paul@earth] ~ % head -n 1 ~/.config/helix/config.toml theme = "jellybeans" [paul@earth] ~ % editor::helix::random_theme [paul@earth] ~ % head -n 1 ~/.config/helix/config.toml theme = "rose_pine" [paul@earth] ~ % editor::helix::random_theme [paul@earth] ~ % head -n 1 ~/.config/helix/config.toml theme = "noctis" [paul@earth] ~ %
export EDITOR=hx
export VISUAL=$EDITOR
export GIT_EDITOR=$EDITOR
export HELIX_CONFIG_DIR=$HOME/.config/helix
editor::helix::theme::get_random () {
for dir in $(hx --health \
| awk '/^Runtime directories/ { print $3 }' | tr ';' ' '); do
if [ -d $dir/themes ]; then
ls $dir/themes
fi
done | grep -F .toml | sort -R | head -n 1 | cut -d. -f1
}
editor::helix::theme::set () {
local -r theme="$1"; shift
local -r config_file=$HELIX_CONFIG_DIR/config.toml
sed "/^theme =/ { s/.*/theme = \"$theme\"/; }" \
$config_file > $config_file.tmp &&
mv $config_file.tmp $config_file
}
if [ -f $HELIX_CONFIG_DIR/config.toml ]; then
editor::helix::theme::set $(editor::helix::theme::get_random)
fi



[paul@earth]~/Downloads% sudo dd \ if=FreeBSD-14.1-RELEASE-amd64-bootonly.iso \ of=/dev/sda conv=sync

root@f0:~ # freebsd-update fetch root@f0:~ # freebsd-update install root@f0:~ # freebsd-update reboot
root@f0:~ # cat <<END >>/etc/hosts 192.168.1.130 f0 f0.lan f0.lan.buetow.org 192.168.1.131 f1 f1.lan f1.lan.buetow.org 192.168.1.132 f2 f2.lan f2.lan.buetow.org END
root@f0:~ # pkg install helix doas zfs-periodic uptimed
root@f0:~ # cp /usr/local/etc/doas.conf.sample /usr/local/etc/doas.conf
root@f0:~ # cat <<END >>/etc/periodic.conf daily_zfs_snapshot_enable="YES" daily_zfs_snapshot_pools="zroot" daily_zfs_snapshot_keep="7" weekly_zfs_snapshot_enable="YES" weekly_zfs_snapshot_pools="zroot" weekly_zfs_snapshot_keep="5" monthly_zfs_snapshot_enable="YES" monthly_zfs_snapshot_pools="zroot" monthly_zfs_snapshot_keep="6" END
root@f0:~ # cp /usr/local/mimecast/etc/uptimed.conf-dist \ /usr/local/mimecast/etc/uptimed.conf root@f0:~ # hx /usr/local/mimecast/etc/uptimed.conf
root@f0:~ # service uptimed enable root@f0:~ # service uptimed start
root@f0:~ # uprecords
# Uptime | System Boot up
----------------------------+---------------------------------------------------
-> 1 0 days, 00:07:34 | FreeBSD 14.1-RELEASE Mon Dec 2 12:21:44 2024
----------------------------+---------------------------------------------------
NewRec 0 days, 00:07:33 | since Mon Dec 2 12:21:44 2024
up 0 days, 00:07:34 | since Mon Dec 2 12:21:44 2024
down 0 days, 00:00:00 | since Mon Dec 2 12:21:44 2024
%up 100.000 | since Mon Dec 2 12:21:44 2024
paul@f0:~ % ifconfig re0
re0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
ether e8:ff:1e:d7:1c:ac
inet 192.168.1.130 netmask 0xffffff00 broadcast 192.168.1.255
inet6 fe80::eaff:1eff:fed7:1cac%re0 prefixlen 64 scopeid 0x1
inet6 fd22:c702:acb7:0:eaff:1eff:fed7:1cac prefixlen 64 detached autoconf
inet6 2a01:5a8:304:1d5c:eaff:1eff:fed7:1cac prefixlen 64 autoconf pltime 10800 vltime 14400
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
paul@f0:~ % sysctl hw.physmem hw.physmem: 16902905856
paul@f0:~ % sysctl dev.cpu | grep freq: dev.cpu.3.freq: 705 dev.cpu.2.freq: 705 dev.cpu.1.freq: 604 dev.cpu.0.freq: 604
paul@f0:~ % doas pkg install ubench paul@f0:~ % rehash # For tcsh to find the newly installed command paul@f0:~ % ubench & paul@f0:~ % sysctl dev.cpu | grep freq: dev.cpu.3.freq: 2922 dev.cpu.2.freq: 2922 dev.cpu.1.freq: 2923 dev.cpu.0.freq: 2922




,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
-=[ typewriters ]=- 1/98
.-------.
.-------. _|~~ ~~ |_
_|~~ ~~ |_ .-------. =(_|_______|_)
=(_|_______|_)= _|~~ ~~ |_ |:::::::::| .-------.
|:::::::::| =(_|_______|_) |:::::::[]| _|~~ ~~ |_
|:::::::[]| |:::::::::| |o=======.| =(_|_______|_)
|o=======.| |:::::::[]| `"""""""""` |:::::::::|
jgs `"""""""""` |o=======.| |:::::::[]|
mod. by Paul Buetow `"""""""""` |o=======.|
`"""""""""`
<< template::inline::toc
declare -xr HTML_THEME_DIR=./extras/html/themes/simple
__..._ _...__
_..-" `Y` "-._
\ Once upon | /
\\ a time..| //
\\\ | ///
\\\ _..---.|.---.._ ///
jgs \\`_..---.Y.---.._`//
||====================================================================|| ||//$\\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\//$\\|| ||(100)==================| FEDERAL SPONSOR NOTE |================(100)|| ||\\$// ~ '------========--------' \\$//|| ||<< / /$\ // ____ \\ \ >>|| ||>>| 12 //L\\ // ///..) \\ L38036133B 12 |<<|| ||<<| \\ // || <|| >\ || |>>|| ||>>| \$/ || $$ --/ || One Hundred |<<|| ||<<| L38036133B *\\ |\_/ //* series |>>|| ||>>| 12 *\\/___\_//* 1989 |<<|| ||<<\ Open Source ______/Franklin\________ Supporting />>|| ||//$\ ~| SPONSORING AND FUNDING |~ /$\\|| ||(100)=================== AWESOME OPEN SOURCE =================(100)|| ||\\$//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\\$//|| ||====================================================================||
,---,---,---,---,---,---,---,---,---,---,---,---,---,-------,
|1/2| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | + | ' | <- |
|---'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-----|
| ->| | Q | W | E | R | T | Y | U | I | O | P | ] | ^ | |
|-----',--',--',--',--',--',--',--',--',--',--',--',--'| |
| Caps | A | S | D | F | G | H | J | K | L | \ | [ | * | |
|----,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'---'----|
| | < | Z | X | C | V | B | N | M | , | . | - | |
|----'-,-',--'--,'---'---'---'---'---'---'-,-'---',--,------|
| ctrl | | alt | |altgr | | ctrl |
'------' '-----'--------------------------'------' '------'
Nieminen Mika





,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
/\_/\ WHOA!! ( o.o ) > ^ < / - \ / \ /______\ \
❯ traceroute -m 60 bad.horse traceroute to bad.horse (162.252.205.157), 60 hops max, 60 byte packets 1 _gateway (192.168.1.1) 5.237 ms 5.264 ms 6.009 ms 2 77-85-0-2.ip.btc-net.bg (77.85.0.2) 8.753 ms 7.112 ms 8.336 ms 3 212-39-69-103.ip.btc-net.bg (212.39.69.103) 9.434 ms 9.268 ms 9.986 ms 4 * * * 5 xe-1-2-0.mpr1.fra4.de.above.net (80.81.194.26) 39.812 ms 39.030 ms 39.772 ms 6 * ae12.cs1.fra6.de.eth.zayo.com (64.125.26.172) 123.576 ms * 7 * * * 8 * * * 9 ae10.cr1.lhr15.uk.eth.zayo.com (64.125.29.17) 119.097 ms 119.478 ms 120.767 ms 10 ae2.cr1.lhr11.uk.zip.zayo.com (64.125.24.140) 120.398 ms 121.147 ms 120.948 ms 11 * * * 12 ae25.mpr1.yyz1.ca.zip.zayo.com (64.125.23.117) 145.072 ms * 181.773 ms 13 ae5.mpr1.tor3.ca.zip.zayo.com (64.125.23.118) 168.239 ms 168.158 ms 168.137 ms 14 64.124.217.237.IDIA-265104-ZYO.zip.zayo.com (64.124.217.237) 168.026 ms 167.999 ms 165.451 ms 15 * * * 16 t00.toroc1.on.ca.sn11.net (162.252.204.2) 131.598 ms 131.308 ms 131.482 ms 17 bad.horse (162.252.205.130) 131.430 ms 145.914 ms 130.514 ms 18 bad.horse (162.252.205.131) 136.634 ms 145.295 ms 135.631 ms 19 bad.horse (162.252.205.132) 139.158 ms 148.363 ms 138.934 ms 20 bad.horse (162.252.205.133) 145.395 ms 148.054 ms 147.140 ms 21 he.rides.across.the.nation (162.252.205.134) 149.687 ms 147.731 ms 150.135 ms 22 the.thoroughbred.of.sin (162.252.205.135) 156.644 ms 155.155 ms 156.447 ms 23 he.got.the.application (162.252.205.136) 161.187 ms 162.318 ms 162.674 ms 24 that.you.just.sent.in (162.252.205.137) 166.763 ms 166.675 ms 164.243 ms 25 it.needs.evaluation (162.252.205.138) 172.073 ms 171.919 ms 171.390 ms 26 so.let.the.games.begin (162.252.205.139) 175.386 ms 174.180 ms 175.965 ms 27 a.heinous.crime (162.252.205.140) 180.857 ms 180.766 ms 180.192 ms 28 a.show.of.force (162.252.205.141) 187.942 ms 186.669 ms 186.986 ms 29 a.murder.would.be.nice.of.course (162.252.205.142) 191.349 ms 191.939 ms 190.740 ms 30 bad.horse (162.252.205.143) 195.425 ms 195.716 ms 196.186 ms 31 bad.horse (162.252.205.144) 199.238 ms 200.620 ms 200.318 ms 32 bad.horse (162.252.205.145) 207.554 ms 206.729 ms 205.201 ms 33 he-s.bad (162.252.205.146) 211.087 ms 211.649 ms 211.712 ms 34 the.evil.league.of.evil (162.252.205.147) 212.657 ms 216.777 ms 216.589 ms 35 is.watching.so.beware (162.252.205.148) 220.911 ms 220.326 ms 221.961 ms 36 the.grade.that.you.receive (162.252.205.149) 225.384 ms 225.696 ms 225.640 ms 37 will.be.your.last.we.swear (162.252.205.150) 232.312 ms 230.989 ms 230.919 ms 38 so.make.the.bad.horse.gleeful (162.252.205.151) 235.761 ms 235.291 ms 235.585 ms 39 or.he-ll.make.you.his.mare (162.252.205.152) 241.350 ms 239.407 ms 238.394 ms 40 o_o (162.252.205.153) 246.154 ms 247.650 ms 247.110 ms 41 you-re.saddled.up (162.252.205.154) 250.925 ms 250.401 ms 250.619 ms 42 there-s.no.recourse (162.252.205.155) 256.071 ms 251.154 ms 255.340 ms 43 it-s.hi-ho.silver (162.252.205.156) 260.152 ms 261.775 ms 261.544 ms 44 signed.bad.horse (162.252.205.157) 262.430 ms 261.410 ms 261.365 ms
#include <stdio.h>
int main(void) {
int array[5] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < 5; i++)
printf("%d\n", array[i]);
for (int i = 0; i < 5; i++)
printf("%d\n", i[array]);
for (int i = 0; i < 5; i++)
printf("%d\n", *(i + array));
}
#include <stdio.h>
int main(void) {
int $array[5] = { 1, 2, 3, 4, 5 };
for (int $i = 0; $i < 5; $i++)
printf("%d\n", $array[$i]);
for (int $i = 0; $i < 5; $i++)
printf("%d\n", $i[$array]);
for (int $i = 0; $i < 5; $i++)
printf("%d\n", *($i + $array));
}
#!/usr/bin/ksh93
typeset -T Point_t=(
integer -h 'x coordinate' x=0
integer -h 'y coordinate' y=0
typeset -h 'point color' color="red"
function getcolor {
print -r ${_.color}
}
function setcolor {
_.color=$1
}
setxy() {
_.x=$1; _.y=$2
}
getxy() {
print -r "(${_.x},${_.y})"
}
)
Point_t point
echo "Initial coordinates are (${point.x},${point.y}). Color is ${point.color}"
point.setxy 5 6
point.setcolor blue
echo "New coordinates are ${point.getxy}. Color is ${point.getcolor}"
exit 0
package main
import "fmt"
func main() {
var i int
f := func() *int {
return &i
}
*f()++
fmt.Println(i)
}
def _token:
def _re($re; f):
( . as {$remain, $string_stack}
| $remain
| match($re; "m").string
| f as $token
| { result: ($token | del(.string_stack))
, remain: $remain[length:]
, string_stack:
( if $token.string_stack == null then $string_stack
else $token.string_stack
end
)
}
);
if .remain == "" then empty
else
( . as {$string_stack}
| _re("^\\s+"; {whitespace: .})
// _re("^#[^\n]*"; {comment: .})
// _re("^\\.[_a-zA-Z][_a-zA-Z0-9]*"; {index: .[1:]})
// _re("^[_a-zA-Z][_a-zA-Z0-9]*"; {ident: .})
// _re("^@[_a-zA-Z][_a-zA-Z0-9]*"; {at_ident: .})
// _re("^\\$[_a-zA-Z][_a-zA-Z0-9]*"; {binding: .})
# 1.23, .123, 123e2, 1.23e2, 123E2, 1.23e+2, 1.23E-2 or 123
// _re("^(?:[0-9]*\\.[0-9]+|[0-9]+)(?:[eE][-\\+]?[0-9]+)?"; {number: .})
// _re("^\"(?:[^\"\\\\]|\\\\.)*?\\\\\\(";
( .[1:-2]
| _unescape
| {string_start: ., string_stack: ($string_stack+["\\("])}
)
)
.
.
.
(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?: \r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:( ?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0 31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\ >(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+ (?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?: (?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n) ?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\ r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n) ?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t] )*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])* )(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*) *:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+ |\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r \n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?: \r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t >))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031 >+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\]( ?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(? :(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(? :\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(? :(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)? [ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]| \\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<> @,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|" (?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t] )*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(? :[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[ \]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000- \031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|( ?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,; :\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([ ^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\" .\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\ >\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\ [\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\ r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\] |\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0 00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\ .|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@, ;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(? :[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])* (?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\". \[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[ ^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\] >))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*( ?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:( ?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[ \["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t >)*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t >)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(? :\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+| \Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?: [^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\ >]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n) ?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[" ()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n) ?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<> @,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@, ;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t] )*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)? (?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\". \[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?: \r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[ "()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t]) *))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]) +|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\ .(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:( ?:\r\n)?[ \t])*))*)?;\s*)
_______
|.-----.|
|| Tmux||
||_.-._||
`--)-(--`
__[=== o]___
|:::::::::::|\
jgs `-=========-`()
mod. by Paul B.
alias tm=tmux alias tl='tmux list-sessions' alias tn=tmux::new alias ta=tmux::attach alias tx=tmux::remote alias ts=tmux::search alias tssh=tmux::cluster_ssh
# Create new session and if alread exists attach to it
tmux::new () {
readonly session=$1
local date=date
if where gdate &>/dev/null; then
date=gdate
fi
tmux::cleanup_default
if [ -z "$session" ]; then
tmux::new T$($date +%s)
else
tmux new-session -d -s $session
tmux -2 attach-session -t $session || tmux -2 switch-client -t $session
fi
}
alias tn=tmux::new
tmux::cleanup_default () {
local s
tmux list-sessions | grep '^T.*: ' | grep -F -v attached |
cut -d: -f1 | while read -r s; do
echo "Killing $s"
tmux kill-session -t "$s"
done
}
tmux::attach () {
readonly session=$1
if [ -z "$session" ]; then
tmux attach-session || tmux::new
else
tmux attach-session -t $session || tmux::new $session
fi
}
alias ta=tmux::attach
tmux::remote () {
readonly server=$1
tmux new -s $server "ssh -t $server 'tmux attach-session || tmux'" || \
tmux attach-session -d -t $server
}
alias tr=tmux::remote
set-option -g prefix C-g
tmux::search () {
local -r session=$(tmux list-sessions | fzf | cut -d: -f1)
if [ -z "$TMUX" ]; then
tmux attach-session -t $session
else
tmux switch -t $session
fi
}
alias ts=tmux::search

tmux::cluster_ssh () {
if [ -f "$1" ]; then
tmux::tssh_from_file $1
return
fi
tmux::tssh_from_argument $@
}
alias tssh=tmux::cluster_ssh
tmux::tssh_from_argument () {
local -r session=$1; shift
local first_server=$1; shift
tmux new-session -d -s $session "ssh -t $first_server"
if ! tmux list-session | grep "^$session:"; then
echo "Could not create session $session"
return 2
fi
for server in "${@[@]}"; do
tmux split-window -t $session "tmux select-layout tiled; ssh -t $server"
done
tmux setw -t $session synchronize-panes on
tmux -2 attach-session -t $session | tmux -2 switch-client -t $session
}
bind-key p setw synchronize-panes off bind-key P setw synchronize-panes on
tmux::tssh_from_file () {
local -r serverlist=$1; shift
local -r session=$(basename $serverlist | cut -d. -f1)
tmux::tssh_from_argument $session $(awk '{ print $1} ' $serverlist | sed 's/.lan./.lan/g')
}
$ tssh fish blowfish.buetow.org fishfinger.buetow.org \
fishbone.buetow.org user@octopus.buetow.org
$ tssh manyservers.txt
bind-key -T copy-mode-vi 'v' send -X begin-selection bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel
source ~/.config/tmux/tmux.local.conf set-option -g allow-rename off set-option -g history-limit 100000 set-option -g status-bg '#444444' set-option -g status-fg '#ffa500' set-option -s escape-time 0
set-window-option -g mode-keys vi bind-key -T copy-mode-vi 'v' send -X begin-selection bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel
bind-key h select-pane -L bind-key j select-pane -D bind-key k select-pane -U bind-key l select-pane -R bind-key H resize-pane -L 5 bind-key J resize-pane -D 5 bind-key K resize-pane -U 5 bind-key L resize-pane -R 5
bind-key c new-window -c '#{pane_current_path}'
bind-key F new-window -n "session-switcher" "tmux list-sessions | fzf | cut -d: -f1 | xargs tmux switch-client -t"
bind-key T choose-tree

bind-key p setw synchronize-panes off bind-key P setw synchronize-panes on bind-key r source-file ~/.config/tmux/tmux.conf \; display-message "tmux.conf reloaded"
Art by Laura Brown .'`~~~~~~~~~~~`'. ( .'11 12 1'. ) | :10 \ 2: | | :9 @-> 3: | | :8 4; | '. '..7 6 5..' .' ~-------------~ ldb
Cluster :UK, :uk01 do
Customer.C1A1.segments.volumes.each do |volume|
puts volume.usage_stats
volume.move_off! if volume.over_subscribed?
end
end
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
Art by Michael J. Penick (mod. by Paul B.)
ACME-sky
__________
/ nsd tower\ (
/____________\ (\) awk-ward
|:_:_:_:_:_| )) plant
|_:_,--.:_:| dig-bubble (\// )
|:_:|__|_:_| relayd-castle _ ) )) ((
_ |_ _ :_:| _ _ _ (_) (((( /)\`
| |_| |_| | _| | |_| |_| | o \\)) (( (
\_:_:_:_:/|_|_|_|\:_:_:_:_/ . (( ))))
|_,-._:_:_:_:_:_:_:_.-,_| )) ((//
|:|_|:_:_:,---,:_:_:|_|:| ,-. )/
|_:_:_:_,'puffy `,_:_:_:_| _ o ,;'))((
|:_:_:_/ _ | _ \_:_:_:| (_O (( ))
_____|_:_:_| (o)-(o) |_:_:_|--'`-. ,--. ksh under-water (((\'/
', ;|:_:_:| -( .-. )- |:_:_:| ', ; `--._\ /,---.~ goat \`))
. ` |_:_:_| \`-'/ |_:_:_|. ` . ` /()\.__( ) .,-----'`-\(( sed-root
', ;|:_:_:| `-' |:_:_:| ', ; ', ; `--'| \ ', ; ', ; ',')).,--
. ` MJP ` . ` . ` . ` . httpd-soil ` . . ` . ` . ` . ` . `
', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ;
#!/bin/ksh
ZONES_DIR=/var/nsd/zones/master/
DEFAULT_MASTER=fishfinger.buetow.org
DEFAULT_STANDBY=blowfish.buetow.org
determine_master_and_standby () {
local master=$DEFAULT_MASTER
local standby=$DEFAULT_STANDBY
.
.
.
local -i health_ok=1
if ! ftp -4 -o - https://$master/index.txt | grep -q "Welcome to $master"; then
echo "https://$master/index.txt IPv4 health check failed"
health_ok=0
elif ! ftp -6 -o - https://$master/index.txt | grep -q "Welcome to $master"; then
echo "https://$master/index.txt IPv6 health check failed"
health_ok=0
fi
if [ $health_ok -eq 0 ]; then
local tmp=$master
master=$standby
standby=$tmp
fi
.
.
.
}
fishfinger$ grep failover /var/nsd/zones/master/foo.zone.zone
300 IN A 46.23.94.99 ; Enable failover
300 IN AAAA 2a03:6000:6f67:624::99 ; Enable failover
www 300 IN A 46.23.94.99 ; Enable failover
www 300 IN AAAA 2a03:6000:6f67:624::99 ; Enable failover
standby 300 IN A 23.88.35.144 ; Enable failover
standby 300 IN AAAA 2a01:4f8:c17:20f1::42 ; Enable failover
transform () {
sed -E '
/IN A .*; Enable failover/ {
/^standby/! {
s/^(.*) 300 IN A (.*) ; (.*)/\1 300 IN A '$(cat /var/nsd/run/master_a)' ; \3/;
}
/^standby/ {
s/^(.*) 300 IN A (.*) ; (.*)/\1 300 IN A '$(cat /var/nsd/run/standby_a)' ; \3/;
}
}
/IN AAAA .*; Enable failover/ {
/^standby/! {
s/^(.*) 300 IN AAAA (.*) ; (.*)/\1 300 IN AAAA '$(cat /var/nsd/run/master_aaaa)' ; \3/;
}
/^standby/ {
s/^(.*) 300 IN AAAA (.*) ; (.*)/\1 300 IN AAAA '$(cat /var/nsd/run/standby_aaaa)' ; \3/;
}
}
/ ; serial/ {
s/^( +) ([0-9]+) .*; (.*)/\1 '$(date +%s)' ; \3/;
}
'
}
#! Race condition !#
if [ -f $zone_file.bak ]; then
mv $zone_file.bak $zone_file
fi
cat $zone_file | transform > $zone_file.new.tmp
grep -v ' ; serial' $zone_file.new.tmp > $zone_file.new.noserial.tmp
grep -v ' ; serial' $zone_file > $zone_file.old.noserial.tmp
echo "Has zone $zone_file changed?"
if diff -u $zone_file.old.noserial.tmp $zone_file.new.noserial.tmp; then
echo "The zone $zone_file hasn't changed"
rm $zone_file.*.tmp
return 0
fi
cp $zone_file $zone_file.bak
mv $zone_file.new.tmp $zone_file
rm $zone_file.*.tmp
echo "Reloading nsd"
nsd-control reload
if ! zone_is_ok $zone; then
echo "Rolling back $zone_file changes"
cp $zone_file $zone_file.invalid
mv $zone_file.bak $zone_file
echo "Reloading nsd"
nsd-control reload
zone_is_ok $zone
return 3
fi
for cleanup in invalid bak; do
if [ -f $zone_file.$cleanup ]; then
rm $zone_file.$cleanup
fi
done
echo "Failover of zone $zone to $MASTER completed"
return 1
# Weekly auto-failover for Let's Encrypt automation
local -i -r week_of_the_year=$(date +%U)
if [ $(( week_of_the_year % 2 )) -eq 0 ]; then
local tmp=$master
master=$standby
standby=$tmp
fi



FISHKISSFISHKIS
SFISHKISSFISHKISSFISH F
ISHK ISSFISHKISSFISHKISS FI
SHKISS FISHKISSFISHKISSFISS FIS
HKISSFISHKISSFISHKISSFISHKISSFISH KISS
FISHKISSFISHKISSFISHKISSFISHKISS FISHK
SSFISHKISSFISHKISSFISHKISSFISHKISSF
ISHKISSFISHKISSFISHKISSFISHKISSF ISHKI
SSFISHKISSFISHKISSFISHKISSFISHKIS SFIS
HKISSFISHKISSFISHKISSFISHKISS FIS
HKISSFISHKISSFISHKISSFISHK IS
SFISHKISSFISHKISSFISH K
ISSFISHKISSFISHK
$ doas installboot sd0 # Update the bootloader (not for every upgrade required) $ doas sysupgrade # Update all binaries (including Kernel)
$ doas sysmerge # Update system configuration files $ doas pkg_add -u # Update all packages $ doas reboot # Just in case, reboot one more time
..--""""----..
.-" ..--""""--.j-.
.-" .-" .--.""--..
.-" .-" ..--"-. \/ ;
.-" .-"_.--..--"" ..--' "-. :
.' .' / `. \..--"" __ _ \ ;
:.__.-" \ / .' ( )"-. Y
; ;: ( ) ( ). \
.': /:: : \ \
.'.-"\._ _.-" ; ; ( ) .-. ( ) \
" `.""" .j" : : \ ; ; \
bug /"""""/ ; ( ) "" :.( ) \
/\ / : \ \`.: _ \
: `. / ; `( ) (\/ :" \ \
\ `. : "-.(_)_.' t-' ;
\ `. ; ..--":
`. `. : ..--"" :
`. "-. ; ..--"" ;
`. "-.:_..--"" ..--"
`. : ..--""
"-. : ..--""
"-.;_..--""
'\ '\ '\ . . |>18>>
\ \ \ . ' . |
O>> O>> O>> . 'o |
\ .\. .. .\. .. . |
/\ . /\ . /\ . . |
/ / . / / .'. / / .' . |
jgs^^^^^^^`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Art by Joan Stark, mod. by Paul Buetow
#!/usr/bin/env bash
log () {
local -r level="$1"; shift
local -r message="$1"; shift
local -i pid="$$"
local -r callee=${FUNCNAME[1]}
local -r stamp=$(date +%Y%m%d-%H%M%S)
echo "$level|$stamp|$pid|$callee|$message" >&2
}
at_home_friday_evening () {
log INFO 'One Peperoni Pizza, please'
}
at_home_friday_evening
❯ ./logexample.sh INFO|20231210-082732|123002|at_home_friday_evening|One Peperoni Pizza, please

#!/usr/bin/env bash
outer() {
inner() {
echo 'Intel inside!'
}
inner
}
inner
outer
inner
❯ ./inner.sh /tmp/inner.sh: line 10: inner: command not found Intel inside! Intel inside!
#!/usr/bin/env bash
outer1() {
inner() {
echo 'Intel inside!'
}
inner
}
outer2() {
inner() {
echo 'Wintel inside!'
}
inner
}
outer1
inner
outer2
inner
❯ ./inner2.sh Intel inside! Intel inside! Wintel inside! Wintel inside!
#!/usr/bin/env bash
some_expensive_operations() {
echo "Doing expensive operations with '$1' from pid $$"
}
for i in {0..9}; do echo $i; done \
| xargs -P10 -I{} bash -c 'some_expensive_operations "{}"'
❯ ./xargs.sh bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found
#!/usr/bin/env bash
some_expensive_operations() {
echo "Doing expensive operations with '$1' from pid $$"
}
export -f some_expensive_operations
for i in {0..9}; do echo $i; done \
| xargs -P10 -I{} bash -c 'some_expensive_operations "{}"'
❯ ./xargs.sh Doing expensive operations with '0' from pid 132831 Doing expensive operations with '1' from pid 132832 Doing expensive operations with '2' from pid 132833 Doing expensive operations with '3' from pid 132834 Doing expensive operations with '4' from pid 132835 Doing expensive operations with '5' from pid 132836 Doing expensive operations with '6' from pid 132837 Doing expensive operations with '7' from pid 132838 Doing expensive operations with '8' from pid 132839 Doing expensive operations with '9' from pid 132840
#!/usr/bin/env bash
some_other_function() {
echo "$1"
}
some_expensive_operations() {
some_other_function "Doing expensive operations with '$1' from pid $$"
}
export -f some_expensive_operations
for i in {0..9}; do echo $i; done \
| xargs -P10 -I{} bash -c 'some_expensive_operations "{}"'
#!/usr/bin/env bash
foo() {
local foo=bar # Declare local/dynamic variable
bar
echo "$foo"
}
bar() {
echo "$foo"
foo=baz
}
foo=foo # Declare global variable
foo # Call function foo
echo "$foo"
❯ ./dynamic.sh bar baz foo
#!/usr/bin/env bash
declare -r foo=foo
declare -r bar=bar
if [ "$foo" = foo ]; then
if [ "$bar" = bar ]; then
echo ok1
fi
fi
if [ "$foo" = foo ] && [ "$bar" == bar ]; then
echo ok2a
fi
[ "$foo" = foo ] && [ "$bar" == bar ] && echo ok2b
if [[ "$foo" = foo && "$bar" == bar ]]; then
echo ok3a
fi
[[ "$foo" = foo && "$bar" == bar ]] && echo ok3b
if test "$foo" = foo && test "$bar" = bar; then
echo ok4a
fi
test "$foo" = foo && test "$bar" = bar && echo ok4b
❯ ./if.sh ok1 ok2a ok2b ok3a ok3b ok4a ok4b
#!/usr/bin/env bash # Single line comment # These are two single line # comments one after another : <<COMMENT This is another way a multi line comment could be written! COMMENT
#!/usr/bin/env bash echo foo echo echo baz >> $0 echo bar
❯ ./if.sh foo bar baz ❯ cat if.sh #!/usr/bin/env bash echo foo echo echo baz >> $0 echo bar echo baz
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⣾⠿⠿⠿⠶⠾⠿⠿⣿⣿⣿⣿⣿⣿⠿⠿⠶⠶⠿⠿⠿⣷⠀⠀⠀⠀ ⠀⠀⠀⣸⢿⣆⠀⠀⠀⠀⠀⠀⠀⠙⢿⡿⠉⠀⠀⠀⠀⠀⠀⠀⣸⣿⡆⠀⠀⠀ ⠀⠀⢠⡟⠀⢻⣆⠀⠀⠀⠀⠀⠀⠀⣾⣧⠀⠀⠀⠀⠀⠀⠀⣰⡟⠀⢻⡄⠀⠀ ⠀⢀⣾⠃⠀⠀⢿⡄⠀⠀⠀⠀⠀⢠⣿⣿⡀⠀⠀⠀⠀⠀⢠⡿⠀⠀⠘⣷⡀⠀ ⠀⣼⣏⣀⣀⣀⣈⣿⡀⠀⠀⠀⠀⣸⣿⣿⡇⠀⠀⠀⠀⢀⣿⣃⣀⣀⣀⣸⣧⠀ ⠀⢻⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⣿⣿⣿⣿⠀⠀⠀⠀⠈⢿⣿⣿⣿⣿⣿⡿⠀ ⠀⠀⠉⠛⠛⠛⠋⠁⠀⠀⠀⠀⢸⣿⣿⣿⣿⡆⠀⠀⠀⠀⠈⠙⠛⠛⠛⠉⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠴⠶⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠶⠦⠀⠀
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
___ .---------.._
______!fsc!_....-' .g8888888p. '-------....._
.' // .g8: :8p..---....___ \'.
| foo.zone // () d88: :88b|==========! !|
| // 888: :888|==========| !|
|___ \\_______'T88888888888P''----------'//|
| \ """"""""""""""""""""""""""""""""""/ |
| !...._____ .="""=. .[] ____...! |
| / ! .g$p. ! .[] : |
| ! : $$$$$ : .[] : |
| !irregular.ninja ! 'T$P' ! .[] '.|
| \__ "=._.=" .() __ |
|.--' '----._______________________.----' '--.|
'._____________________________________________.'
% sudo dnf install -y ImageMagick make git
% git clone https://codeberg.org/snonux/photoalbum Cloning into 'photoalbum'... remote: Enumerating objects: 1624, done. remote: Total 1624 (delta 0), reused 0 (delta 0), pack-reused 1624 Receiving objects: 100% (1624/1624), 193.36 KiB | 1.49 MiB/s, done. Resolving deltas: 100% (1227/1227), done. % cd photoalbum /home/paul/photoalbum % make cut -d' ' -f2 changelog | head -n 1 | sed 's/(//;s/)//' > .version test ! -d ./bin && mkdir ./bin || exit 0 sed "s/PHOTOALBUMVERSION/$(cat .version)/" src/photoalbum.sh > ./bin/photoalbum chmod 0755 ./bin/photoalbum % sudo make install test ! -d /usr/bin && mkdir -p /usr/bin || exit 0 cp ./bin/* /usr/bin test ! -d /usr/share/photoalbum/templates && mkdir -p /usr/share/photoalbum/templates || exit 0 cp -R ./share/templates /usr/share/photoalbum/ test ! -d /etc/default && mkdir -p /etc/default || exit 0 cp ./src/photoalbum.default.conf /etc/default/photoalbum
% photoalbum version This is Photoalbum Version 0.5.1
% mkdir irregular.ninja % cd irregular.ninja % # cp -Rpv ~/Photos/your-photos ./incoming
photoalbum clean|generate|version [rcfile] photoalbum photoalbum makemake
% photoalbum makemake You may now customize ./photoalbumrc and run make % cat Makefile all: photoalbum generate photoalbumrc clean: photoalbum clean photoalbumrc % cat photoalbumrc # The title of the photoalbum TITLE='A simple Photoalbum' # Thumbnail height geometry THUMBHEIGHT=300 # Normal geometry height (when viewing photo). Uncomment, to keep original size. HEIGHT=1200 # Max previews per page. MAXPREVIEWS=40 # Randomly shuffle all previews. # SHUFFLE=yes # Diverse directories, need to be full paths, not relative! INCOMING_DIR=$(pwd)/incoming DIST_DIR=$(pwd)/dist TEMPLATE_DIR=/usr/share/photoalbum/templates/default #TEMPLATE_DIR=/usr/share/photoalbum/templates/minimal # Includes a .tar of the incoming dir in the dist, can be yes or no TARBALL_INCLUDE=yes TARBALL_SUFFIX=.tar TAR_OPTS='-c' # Some debugging options #set -e #set -x
--- photoalbumrc 2023-10-29 21:42:00.894202045 +0200 +++ photoalbumrc.new 2023-06-04 10:40:08.030994440 +0300 @@ -1,23 +1,24 @@ # The title of the photoalbum -TITLE='A simple Photoalbum' +TITLE='Irregular.Ninja' # Thumbnail height geometry -THUMBHEIGHT=300 +THUMBHEIGHT=400 # Normal geometry height (when viewing photo). Uncomment, to keep original size. -HEIGHT=1200 +HEIGHT=1800 # Max previews per page. MAXPREVIEWS=40 -# Randomly shuffle all previews. -# SHUFFLE=yes +# Randomly shuffle +SHUFFLE=yes # Diverse directories, need to be full paths, not relative! -INCOMING_DIR=$(pwd)/incoming +INCOMING_DIR=~/Nextcloud/Photos/irregular.ninja DIST_DIR=$(pwd)/dist TEMPLATE_DIR=/usr/share/photoalbum/templates/default #TEMPLATE_DIR=/usr/share/photoalbum/templates/minimal # Includes a .tar of the incoming dir in the dist, can be yes or no -TARBALL_INCLUDE=yes +TARBALL_INCLUDE=no TARBALL_SUFFIX=.tar TAR_OPTS='-c'
% make photoalbum generate photoalbumrc Processing 1055079_cool-water-wallpapers-hd-hd-desktop-wal.jpg to /home/paul/irregular.ninja/dist/photos/1055079_cool-water-wallpapers-hd-hd-desktop-wal.jpg Processing 11271242324.jpg to /home/paul/irregular.ninja/dist/photos/11271242324.jpg Processing 11271306683.jpg to /home/paul/irregular.ninja/dist/photos/11271306683.jpg Processing 13950707932.jpg to /home/paul/irregular.ninja/dist/photos/13950707932.jpg Processing 14077406487.jpg to /home/paul/irregular.ninja/dist/photos/14077406487.jpg Processing 14859380100.jpg to /home/paul/irregular.ninja/dist/photos/14859380100.jpg Processing 14869239578.jpg to /home/paul/irregular.ninja/dist/photos/14869239578.jpg Processing 14879132910.jpg to /home/paul/irregular.ninja/dist/photos/14879132910.jpg . . . Generating /home/paul/irregular.ninja/dist/html/7-4.html Creating thumb /home/paul/irregular.ninja/dist/thumbs/20211130_091051.jpg Creating blur /home/paul/irregular.ninja/dist/blurs/20211130_091051.jpg Generating /home/paul/irregular.ninja/dist/html/page-7.html Generating /home/paul/irregular.ninja/dist/html/7-5.html Generating /home/paul/irregular.ninja/dist/html/7-5.html Generating /home/paul/irregular.ninja/dist/html/7-5.html Creating thumb /home/paul/irregular.ninja/dist/thumbs/DSCF0188.JPG Creating blur /home/paul/irregular.ninja/dist/blurs/DSCF0188.JPG Generating /home/paul/irregular.ninja/dist/html/page-7.html Generating /home/paul/irregular.ninja/dist/html/7-6.html Generating /home/paul/irregular.ninja/dist/html/7-6.html Generating /home/paul/irregular.ninja/dist/html/7-6.html Creating thumb /home/paul/irregular.ninja/dist/thumbs/P3500897-01.jpg Creating blur /home/paul/irregular.ninja/dist/blurs/P3500897-01.jpg . . . Generating /home/paul/irregular.ninja/dist/html/8-0.html Generating /home/paul/irregular.ninja/dist/html/8-41.html Generating /home/paul/irregular.ninja/dist/html/9-0.html Generating /home/paul/irregular.ninja/dist/html/9-41.html Generating /home/paul/irregular.ninja/dist/html/index.html Generating /home/paul/irregular.ninja/dist/.//index.html
% ls ./dist blurs html index.html photos thumbs
% rsync --delete -av ./dist/. admin@blowfish.buetow.org:/var/www/htdocs/irregular.ninja/
,_---~~~~~----._
_,,_,*^____ _____``*g*\"*,
____ _____ _ _ / __/ /' ^. / \ ^@q f
| _ \_ _|_ _(_) | @f | ((@| |@)) l 0 _/
| | | || |/ _` | | | \`/ \~____ / __ \_____/ \
| |_| || | (_| | | | | _l__l_ I
|____/ |_|\__,_|_|_| } [______] I
] | | | |
] ~ ~ |
| Let's tail those logs! |
| |
% dtail --servers serverlist.txt --grep INFO --files "/var/log/dserver/*.log"

% dtail --servers serverlist.txt --grep INFO "/var/log/dserver/*.log"
% dtail --servers serverlist.txt \
--files '/var/log/dserver/*.log' \
--query 'from STATS select sum($goroutines),sum($cgocalls),
last($time),max(lifetimeConnections)'

% dtail --servers serverlist.txt \
--files '/var/log/dserver/*.log' \
'from STATS select sum($goroutines),sum($cgocalls),
last($time),max(lifetimeConnections)'
% dtail --servers serverlist.txt \
--files '/var/log/dserver/*.log' \
--query 'from STATS select $hostname,max($goroutines),max($cgocalls),$loadavg,
lifetimeConnections group by $hostname order by max($cgocalls)'

% dtail --servers serverlist.txt \
--files '/var/log/dserver/*.log' \
--query 'from STATS select ... outfile append result.csv'
% dcat --servers serverlist.txt --files /etc/hostname

% dcat --servers serverlist.txt /etc/hostname
% dgrep --servers server1.example.org:2223 \
--files /etc/passwd \
--regex nologin

% dmap --servers serverlist.txt \
--files '/var/log/dserver/*.log' \
--query 'from STATS select $hostname,max($goroutines),max($cgocalls),$loadavg,
lifetimeConnections group by $hostname order by max($cgocalls)'

% dmap --files /var/log/dserver/dserver.log
--query 'from STATS select $hostname,max($goroutines),max($cgocalls),$loadavg,
lifetimeConnections group by $hostname order by max($cgocalls)'
% dmap 'from STATS select $hostname,max($goroutines),max($cgocalls),$loadavg,
lifetimeConnections group by $hostname order by max($cgocalls)' \
/var/log/dsever/dserver.log
% cat /var/log/dserver/dserver.log | \
dmap 'from STATS select $hostname,max($goroutines),max($cgocalls),$loadavg,
lifetimeConnections group by $hostname order by max($cgocalls)'
% cat example.csv name,lastname,age,profession Michael,Jordan,40,Basketball player Michael,Jackson,100,Singer Albert,Einstein,200,Physician % dmap --query 'select lastname,name where age > 40 logformat csv outfile result.csv' example.csv % cat result.csv lastname,name Jackson,Michael Einstein,Albert
% dtail /var/log/dserver/dserver.log
% dtail --logLevel trace /var/log/dserver/dserver.log
% dcat /etc/passwd
% dcat --plain /etc/passwd > /etc/test # Should show no differences. diff /etc/test /etc/passwd
% dgrep --regex ERROR --files /var/log/dserver/dsever.log
% dgrep --before 10 --after 10 --max 10 --grep ERROR /var/log/dserver/dsever.log
▓▓▓▓░░
DC on fire:
▓▓ ▓▓ ▓▓
░░ ░░ ▓▓▓▓ ██ ░░ ▓▓▓▓ ▓▓
▓▓░░░░ ░░ ▓▓▓▓ ▓▓░░ ▓▓▓▓
░░░░ ▓▓▓▓▓▓ ▓▓ ▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓
▓▓░░ ▓▓▒▒▒▒▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓▓ ▓▓▒▒▒▒▓▓▓▓ ▓▓▓▓
██▓▓ ▓▓▒▒░░▒▒▓▓ ▓▓██ ▓▓▓▓▓▓ ▓▓▒▒▓▓ ▓▓▒▒░░▒▒▓▓ ██▓▓▓▓
▓▓▓▓██ ▓▓▒▒░░░░▒▒▓▓ ▓▓▓▓ ▓▓▒▒▒▒▓▓ ▓▓▒▒░░▒▒▓▓██▓▓ ▓▓▒▒░░░░▒▒▓▓ ▓▓▒▒▒▒▓▓
▓▓▒▒▒▒▓▓▓▓▒▒░░▒▒▓▓▓▓▓▓▒▒▒▒▓▓ ▓▓▓▓░░▒▒▓▓ ▓▓▒▒░░▒▒▓▓▒▒▒▒▓▓ ▓▓▒▒░░▒▒▓▓▓▓▓▓▓▓░░▒▒▓▓
▒▒░░▒▒▓▓▓▓▒▒░░▒▒▓▓▓▓▒▒░░▒▒▓▓ ▓▓▒▒░░▒▒▓▓ ▓▓░░░░▒▒▒▒░░░░▒▒██████▒▒░░▒▒██▓▓▓▓▒▒░░▒▒▓▓██
░░░░▒▒▓▓▒▒░░▒▒▓▓▓▓▓▓▒▒░░▒▒▓▓██▒▒░░░░▒▒▓▓ ▓▓▒▒░░▒▒▓▓▒▒▒▒░░▒▒▓▓▓▓▒▒░░▒▒▓▓▓▓▓▓▒▒░░░░▒▒▓▓▓▓
░░░░▒▒▓▓▒▒░░░░▓▓██▒▒░░░░▒▒▓▓██▒▒░░░░▒▒██▓▓▓▓▒▒░░▒▒▓▓▓▓▒▒░░░░▒▒▓▓▒▒░░░░██▓▓▓▓▒▒░░░░▒▒████
▒▒░░▒▒▓▓▓▓░░░░▒▒▓▓▒▒▒▒░░░░▒▒▓▓▓▓▒▒░░░░▒▒▓▓▓▓▒▒░░░░▒▒▓▓▒▒░░▒▒▓▓▓▓▓▓░░░░▒▒▓▓▓▓▓▓▒▒░░░░▒▒▓▓
▒▒░░▒▒▓▓▒▒▒▒░░▒▒██▒▒▒▒░░▒▒▒▒██▒▒▒▒░░░░░░▒▒▓▓▒▒░░░░▒▒▒▒░░░░▒▒████▒▒▒▒░░▒▒██▓▓▒▒▒▒░░░░░░▒▒
░░░░░░▒▒░░░░░░░░▒▒▒▒▒▒░░░░▒▒▒▒▒▒░░░░░░░░▒▒▒▒░░░░░░▒▒▒▒░░░░░░▒▒▒▒░░░░░░░░▒▒▒▒▒▒░░░░░░░░▒▒
░░░░░░░░░░▒▒░░░░░░░░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░░░░░░░
-=[ typewriters ]=- 1/98
.-------.
.-------. _|~~ ~~ |_
_|~~ ~~ |_ .-------. =(_|_______|_)
=(_|_______|_)= _|~~ ~~ |_ |:::::::::|
|:::::::::| =(_|_______|_) |:::::::[]|
|:::::::[]| |:::::::::| |o=======.|
|o=======.| |:::::::[]| `"""""""""`
jgs `"""""""""` |o=======.|
mod. by Paul Buetow `"""""""""`
```bash if [ -n "$foo" ]; then echo "$foo" fi ```
if [ -n "$foo" ]; then echo "$foo" fi
declare -xr MASTODON_URI='https://fosstodon.org/@snonux'
=> https://fosstodon.org/@snonux Me at Mastodon
<a href='https://fosstodon.org/@snonux' rel='me'>Me at Mastodon</a>
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''

_____________________________ ____________________________
/ \ / \
| _______________________ || ______________________ |
| / \ || / \ |
| | # Alerts with status c| || | # Unhandled alerts: | |
| | hanged: | || | | |
| | | || | CRITICAL: Check Pizza| |
| | OK->CRITICAL: Check Pi| || | : Late delivery | |
| | zza: Late delivery | || | | |
| | | || | WARNING: Check Thirst| |
| | | || | : OutofKombuchaExcept| |
| \_______________________/ || \______________________/ |
| /|\ GOGIOS MONITOR 1 _ || /|\ GOGIOS MONITOR 2 _ |
\_____________________________/ \____________________________/
!_________________________! !________________________!
------------------------------------------------
ASCII art was modified by Paul Buetow
The original can be found at
https://asciiart.website/index.php?art=objects/computers
Subject: GOGIOS Report [C:2 W:0 U:0 OK:51] This is the recent Gogios report! # Alerts with status changed: OK->CRITICAL: Check ICMP4 vulcan.buetow.org: Check command timed out OK->CRITICAL: Check ICMP6 vulcan.buetow.org: Check command timed out # Unhandled alerts: CRITICAL: Check ICMP4 vulcan.buetow.org: Check command timed out CRITICAL: Check ICMP6 vulcan.buetow.org: Check command timed out Have a nice day!
git clone https://codeberg.org/snonux/gogios.git cd gogios go build -o gogios cmd/gogios/main.go doas cp gogios /usr/local/bin/gogios doas chmod 755 /usr/local/bin/gogios
export GOOS=openbsd export GOARCH=amd64 go build -o gogios cmd/gogios/main.go
doas adduser -group _gogios -batch _gogios doas usermod -d /var/run/gogios _gogios doas mkdir -p /var/run/gogios doas chown _gogios:_gogios /var/run/gogios doas chmod 750 /var/run/gogios
doas pkg_add monitoring-plugins doas pkg_add nrpe # If you want to execute checks remotely via NRPE.
echo 'This is a test email from OpenBSD.' | mail -s 'Test Email' your-email@example.com
{
"EmailTo": "paul@dev.buetow.org",
"EmailFrom": "gogios@buetow.org",
"CheckTimeoutS": 10,
"CheckConcurrency": 2,
"StateDir": "/var/run/gogios",
"Checks": {
"Check ICMP4 www.foo.zone": {
"Plugin": "/usr/local/libexec/nagios/check_ping",
"Args": [ "-H", "www.foo.zone", "-4", "-w", "50,10%", "-c", "100,15%" ],
"Retries": 3,
"RetryInterval": 10
},
"Check ICMP6 www.foo.zone": {
"Plugin": "/usr/local/libexec/nagios/check_ping",
"Args": [ "-H", "www.foo.zone", "-6", "-w", "50,10%", "-c", "100,15%" ],
"Retries": 3,
"RetryInterval": 10
},
"www.foo.zone HTTP IPv4": {
"Plugin": "/usr/local/libexec/nagios/check_http",
"Args": ["www.foo.zone", "-4"],
"DependsOn": ["Check ICMP4 www.foo.zone"]
},
"www.foo.zone HTTP IPv6": {
"Plugin": "/usr/local/libexec/nagios/check_http",
"Args": ["www.foo.zone", "-6"],
"DependsOn": ["Check ICMP6 www.foo.zone"]
}
"Check NRPE Disk Usage foo.zone": {
"Plugin": "/usr/local/libexec/nagios/check_nrpe",
"Args": ["-H", "foo.zone", "-c", "check_disk", "-p", "5666", "-4"]
}
}
}
doas -u _gogios /usr/local/bin/gogios -cfg /etc/gogios.json
*/5 8-22 * * * /usr/local/bin/gogios -cfg /etc/gogios.json 0 7 * * * /usr/local/bin/gogios -renotify -cfg /etc/gogios.json
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
+-----+-----------------+-----------------------------+ | Pos | Host | Lifespan | +-----+-----------------+-----------------------------+ | 1. | dionysus | 8 years, 6 months, 17 days | | 2. | uranus | 7 years, 2 months, 16 days | | 3. | alphacentauri | 6 years, 9 months, 13 days | | 4. | *vulcan | 4 years, 5 months, 6 days | | 5. | sun | 3 years, 10 months, 2 days | | 6. | uugrn | 3 years, 5 months, 5 days | | 7. | deltavega | 3 years, 1 months, 21 days | | 8. | pluto | 2 years, 10 months, 30 days | | 9. | tauceti | 2 years, 3 months, 22 days | | 10. | callisto | 2 years, 3 months, 13 days | +-----+-----------------+-----------------------------+
$ raku guprecords.raku --stats=dir=$HOME/git/uprecords/stats --all
Top 20 Uptime's by Host +-----+-----------------+-----------------------------+ | Pos | Host | Uptime | +-----+-----------------+-----------------------------+ | 1. | *vulcan | 4 years, 5 months, 6 days | | 2. | uranus | 3 years, 11 months, 21 days | | 3. | sun | 3 years, 9 months, 26 days | | 4. | uugrn | 3 years, 5 months, 5 days | | 5. | deltavega | 3 years, 1 months, 21 days | | 6. | pluto | 2 years, 10 months, 29 days | | 7. | tauceti | 2 years, 3 months, 19 days | | 8. | tauceti-f | 1 years, 9 months, 18 days | | 9. | *ultramega15289 | 1 years, 8 months, 17 days | | 10. | *earth | 1 years, 5 months, 22 days | | 11. | *blowfish | 1 years, 4 months, 20 days | | 12. | ultramega8477 | 1 years, 3 months, 25 days | | 13. | host0 | 1 years, 3 months, 9 days | | 14. | tauceti-e | 1 years, 2 months, 20 days | | 15. | makemake | 1 years, 1 months, 6 days | | 16. | callisto | 0 years, 10 months, 31 days | | 17. | alphacentauri | 0 years, 10 months, 28 days | | 18. | london | 0 years, 9 months, 16 days | | 19. | twofish | 0 years, 8 months, 31 days | | 20. | *fishfinger | 0 years, 8 months, 17 days | +-----+-----------------+-----------------------------+
# Uptime | System Boot up
----------------------------+---------------------------------------------------
1 545 days, 17:58:15 | Linux 3.10.0-1160.15.2.e Sun Jul 25 19:32:25 2021
2 279 days, 10:12:14 | Linux 3.10.0-957.21.3.el Sun Jun 30 12:43:41 2019
3 161 days, 06:08:43 | Linux 3.10.0-1160.15.2.e Sun Feb 14 11:05:38 2021
4 107 days, 01:26:35 | Linux 3.10.0-957.1.3.el7 Thu Dec 20 09:29:13 2018
5 96 days, 21:13:49 | Linux 3.10.0-1127.13.1.e Sat Jul 25 17:56:22 2020
-> 6 89 days, 23:05:32 | Linux 3.10.0-1160.81.1.e Sun Jan 22 12:39:36 2023
7 63 days, 18:30:45 | Linux 3.10.0-957.10.1.el Sat Apr 27 18:12:43 2019
8 63 days, 06:53:33 | Linux 3.10.0-1127.8.2.el Sat May 23 10:41:08 2020
9 48 days, 11:44:49 | Linux 3.10.0-1062.18.1.e Sat Apr 4 22:56:07 2020
10 42 days, 08:00:13 | Linux 3.10.0-1127.19.1.e Sat Nov 7 11:47:33 2020
11 36 days, 22:57:19 | Linux 3.10.0-1160.6.1.el Sat Dec 19 19:47:57 2020
12 21 days, 06:16:28 | Linux 3.10.0-957.10.1.el Sat Apr 6 11:56:01 2019
13 12 days, 20:11:53 | Linux 3.10.0-1160.11.1.e Mon Jan 25 18:45:27 2021
14 7 days, 21:29:18 | Linux 3.10.0-1127.13.1.e Fri Oct 30 14:18:04 2020
15 6 days, 20:07:18 | Linux 3.10.0-1160.15.2.e Sun Feb 7 14:57:35 2021
16 1 day , 21:46:41 | Linux 3.10.0-957.1.3.el7 Tue Dec 18 11:42:19 2018
17 0 days, 01:25:57 | Linux 3.10.0-957.1.3.el7 Tue Dec 18 10:16:08 2018
18 0 days, 00:42:34 | Linux 3.10.0-1160.15.2.e Sun Jul 25 18:49:38 2021
19 0 days, 00:08:32 | Linux 3.10.0-1160.81.1.e Sun Jan 22 12:30:52 2023
----------------------------+---------------------------------------------------
1up in 6 days, 22:08:18 | at Sat Apr 29 10:53:25 2023
no1 in 455 days, 18:52:44 | at Sun Jul 21 07:37:51 2024
up 1586 days, 00:20:28 | since Tue Dec 18 10:16:08 2018
down 0 days, 01:08:32 | since Tue Dec 18 10:16:08 2018
%up 99.997 | since Tue Dec 18 10:16:08 2018
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
-=[ typewriters ]=- 1/98
.-------.
_|~~ ~~ |_ .-------.
=(_|_______|_)= _|~~ ~~ |_
|:::::::::| =(_|_______|_)
|:::::::[]| |:::::::::|
|o=======.| |:::::::[]|
jgs `"""""""""` |o=======.|
mod. by Paul Buetow `"""""""""`
# Hello world
<< echo "> This site was generated at $(date --iso-8601=seconds) by \`Gemtexter\`"
Welcome to this capsule!
<<<
for i in {1..10}; do
echo Multiline template line $i
done
>>>
# Hello world > This site was generated at 2023-03-15T19:07:59+02:00 by `Gemtexter` Welcome to this capsule! Multiline template line 1 Multiline template line 2 Multiline template line 3 Multiline template line 4 Multiline template line 5 Multiline template line 6 Multiline template line 7 Multiline template line 8 Multiline template line 9 Multiline template line 10
See more entries about DTail and Golang: << template::inline::rindex dtail golang Blablabla...
See more entries about DTail and Golang: => ./2022-10-30-installing-dtail-on-openbsd.gmi 2022-10-30 Installing DTail on OpenBSD => ./2022-04-22-programming-golang.gmi 2022-04-22 The Golang Programming language => ./2022-03-06-the-release-of-dtail-4.0.0.gmi 2022-03-06 The release of DTail 4.0.0 => ./2021-04-22-dtail-the-distributed-log-tail-program.gmi 2021-04-22 DTail - The distributed log tail program (You are currently reading this) Blablabla...
declare -xr PRE_GENERATE_HOOK=./pre_generate_hook.sh declare -xr POST_PUBLISH_HOOK=./post_publish_hook.sh
% cat gemfeed/2023-02-26-title-here.gmi # Title here The remaining content of the Gemtext file...
% cat gemfeed/2023-02-26-title-here.gmi # Title here > Published at 2023-02-26T21:43:51+01:00 The remaining content of the Gemtext file...
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''