From 3f71e5e47055550d187eb1b60d889f82bb1de28f Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 14 Feb 2021 18:59:26 +0100 Subject: update --- bin/open | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100755 bin/open (limited to 'bin') diff --git a/bin/open b/bin/open deleted file mode 100755 index 0fa97a7..0000000 --- a/bin/open +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -exec >/tmp/open.out 2>&1 -set -x - -cmd=xdg-open -case $1 in -(*.mkv|*.mp4) cmd=vlc;; -esac - -exec $cmd "$@" -- cgit v1.2.3 From 17b6d57450341896743f31ae67921d2abd8551bc Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 22 Feb 2021 17:10:51 +0100 Subject: updated --- bin/gauth | 4 +++- bin/p4a | 3 +++ bin/xt | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100755 bin/p4a (limited to 'bin') diff --git a/bin/gauth b/bin/gauth index 575d6fc..699cd84 100755 --- a/bin/gauth +++ b/bin/gauth @@ -1,7 +1,9 @@ #!/bin/sh # Use backup from andOTP -gpg -qd ~/.otp_accounts.json.gpg | +#gpg -qd ~/otp_accounts.json.gpg.pgp | +#gpg -qd ~/.otp_accounts.json.gpg | +cat ~/otp_accounts.json | jq -r '.[] | "\(.label) \(.secret)"' | while read -r l s; do echo "$l $(oathtool --totp -b "$s")" diff --git a/bin/p4a b/bin/p4a new file mode 100755 index 0000000..30e54ff --- /dev/null +++ b/bin/p4a @@ -0,0 +1,3 @@ +#!/bin/sh +adb forward tcp:8222 tcp:8022 +ssh ssh://u0_a250@localhost:8222 diff --git a/bin/xt b/bin/xt index 71b92d3..9395b3e 100755 --- a/bin/xt +++ b/bin/xt @@ -1,4 +1,5 @@ #!/bin/sh -exec xterm -sl 500 -j -cr red "$@" & +#exec xterm -sl 500 -j -cr red "$@" & +exec xterm "$@" & #cmd="urxvtc ${@:--T $HOSTNAME}" #eval "$cmd" || { [ $? = 2 ] && urxvtd -q -o -f && eval "$cmd"; } -- cgit v1.2.3 From 45ecd3877ab52d73f4bec998ad456aa270ffddac Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Tue, 23 Feb 2021 14:52:10 +0100 Subject: update --- bin/update_hosts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 bin/update_hosts (limited to 'bin') diff --git a/bin/update_hosts b/bin/update_hosts new file mode 100755 index 0000000..6444550 --- /dev/null +++ b/bin/update_hosts @@ -0,0 +1,16 @@ +#!/bin/sh -ex + +# Update /etc/hosts with a well curated blacklist of malware, ads, porn, etc. +# Custom hosts are preserved. + +[ "$USER" = root ] || exec sudo "$0" "$@" +cd /etc +cp -p hosts hosts.old +hosts=$(awk '/^# Custom host /, /^# End of custom host /' hosts.old) +curl -s https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts | +awk 'BEGIN { hosts = ARGV[1]; ARGV[1] = "" } +/^# Custom host / { print hosts; next } +/^# End of custom host / { next } +{print}' "$hosts" > hosts.new +mv hosts.new hosts +[ "$(uname -s)" != Darwin ] || dscacheutil -flushcache -- cgit v1.2.3 From 9793ed6f2c0a89728d19a8b06d084c3c3fb102e5 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Wed, 24 Feb 2021 22:28:41 +0100 Subject: update --- bin/start_godoc | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 bin/start_godoc (limited to 'bin') diff --git a/bin/start_godoc b/bin/start_godoc new file mode 100755 index 0000000..15bb70a --- /dev/null +++ b/bin/start_godoc @@ -0,0 +1,3 @@ +#!/bin/sh + +/Users/marc/go/bin/godoc >/tmp/godoc.out 2>&1 & -- cgit v1.2.3 From 9e34d600e3d8f8e50b8b87779c76c62924f41d2f Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 28 Feb 2021 14:05:43 +0100 Subject: update --- bin/vm | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100755 bin/vm (limited to 'bin') diff --git a/bin/vm b/bin/vm new file mode 100755 index 0000000..22886d8 --- /dev/null +++ b/bin/vm @@ -0,0 +1,65 @@ +#!/bin/sh + +# vm is a tool to manage virtual machines. + +vm_version='vm-0.1' +unset CDPATH +export LC_ALL=C IFS=' +' + +add() { + usage 'add name' 'Add a new VM' && return + echo 'not implemented yet' +} + +del() { + usage 'del name' 'Delete a VM' && return + echo 'not implemented yet' +} + +die() { echo "$0: fatal: $@" >&2; exit 1; } + +help() { + usage 'help' 'Print this help text' && return + printf "$vm_version\nUsage: vm command [options] [args]\n" + Opth=1; for c in $Cmdlist; do $c; done +} + +info() { + usage 'info name' 'Print informations on a VM' && return + echo 'not implemented yet' +} + +list() { + usage 'list' 'list VMs' && return + echo 'not implemented yet' +} + +start() { + usage 'start name' 'Start a VM' && return + echo 'not implemented yet' +} + +stop() { + usage 'stop name' 'Stop a VM' && return + echo 'not implemented yet' +} + +usage() { [ "$Opth" ] && printf " %-34s %s\n" "$1" "$2"; } + +version() { + usage 'version' 'Print version' && return + echo "$vm_version" +} + +# Main starts here. +Cmdlist='add del info help list start stop version' +[ "$1" ] && C=$1 && shift 1 || { help; exit 1; } +for c in $Cmdlist +do + case $c in + ($C) cmd=$c; break;; + ($C*) [ "$cmd" ] && die "ambiguous command $C" || cmd=$c;; + esac +done +[ "$cmd" ] || die "no command \"$C\"" && $cmd "$@" -- cgit v1.2.3 From 737e83162766162be992f76e068386736abea71d Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 28 Feb 2021 22:10:26 +0100 Subject: update --- bin/rdate | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100755 bin/rdate (limited to 'bin') diff --git a/bin/rdate b/bin/rdate new file mode 100755 index 0000000..a69d137 --- /dev/null +++ b/bin/rdate @@ -0,0 +1,11 @@ +#!/bin/sh + +# Set date on remote machine from local one. This version works +# from MacOS to AlpineLinux. It is intended to re-sync clock of a +# virtual machine after host wakeup. + +# TODO: option to display the time difference between host and remote. +# hint: use 'date +%s' to get timestamp in seconds since epoch. + +ssh "$1" "sudo date $(date +%m%d%H%M%Y.%S)" + -- cgit v1.2.3 From 9aa9c25a4d2ced1ea41d1d981b3fad9fe28a17a6 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sat, 6 Mar 2021 16:58:38 +0100 Subject: update --- bin/vm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/vm b/bin/vm index 22886d8..4b0e960 100755 --- a/bin/vm +++ b/bin/vm @@ -21,7 +21,9 @@ die() { echo "$0: fatal: $@" >&2; exit 1; } help() { usage 'help' 'Print this help text' && return - printf "$vm_version\nUsage: vm command [options] [args]\n" + echo "$vm_version +Manage virtual machines +Usage: vm command [options] [args]" Opth=1; for c in $Cmdlist; do $c; done } -- cgit v1.2.3 From 050afa8def0739b459122b9d4c7fcf854ae1ed2a Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 12 Mar 2021 12:31:20 +0100 Subject: added wol. Updated vm --- bin/vm | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ bin/wol | 6 ++++++ 2 files changed, 68 insertions(+), 6 deletions(-) create mode 100755 bin/wol (limited to 'bin') diff --git a/bin/vm b/bin/vm index 4b0e960..5a8ea8d 100755 --- a/bin/vm +++ b/bin/vm @@ -9,7 +9,10 @@ export LC_ALL=C IFS=' add() { usage 'add name' 'Add a new VM' && return - echo 'not implemented yet' + [ -d "$idir/$1" ] && die "vm $1 already exists in $idir/$1" + init_alpine || die "could not init alpine iso" + mkdir -p "$idir/$1" && cd "$idir/$1" || die "add $1 failed" + pwd } del() { @@ -32,9 +35,54 @@ info() { echo 'not implemented yet' } -list() { - usage 'list' 'list VMs' && return - echo 'not implemented yet' +init() { + : +} + +init_alpine() { + mkdir -p "$sdir/alpine" && cd "$sdir/alpine" || die "init alpine failed" + [ -f Makefile ] || cat << \EOT > Makefile +# Do no edit. This file is generated by vm. +# Install a run a native AlpineLinux VM in Apple silicon MacOS + +# Check https://alpinelinux.org/downloads for possible upgrades +iso_url = https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/aarch64/alpine-virt-3.13.2-aarch64.iso +iso = $(notdir $(iso_url)) +isoinfo ?= /opt/homebrew/bin/isoinfo + +all: initrd vmlinux + +runiso: initrd vmlinux $(iso) + vftool -k vmlinux -i initrd -d hdd.img -c $(iso) + +initrd: $(iso) $(isoinfo) + isoinfo -i $(iso) -J -x /boot/initramfs-virt > $@ + +vmlinux: $(iso) $(isoinfo) + isoinfo -i $(iso) -J -x /boot/vmlinuz-virt | gunzip > $@ + +$(iso): + curl -LO $(iso_url) || { rm -f $@; false; } + +$(isoinfo): + brew install cdrtools +EOT + + make -s all +} + +ls() { + usage 'ls' 'list VMs' && return + [ -d "$idir" ] && cd "$idir" || return + for i in *; do + echo "$i" + done +} + +runiso() { + usage 'runiso [isoname]' 'run a cdrom iso' && return + init_alpine + make runiso } start() { @@ -55,7 +103,15 @@ version() { } # Main starts here. -Cmdlist='add del info help list start stop version' +pdir="$HOME/.vm" +sdir="$pdir/iso" +edir="$pdir/engine" +idir="$pdir/img" + +engines="vftool" # Todo: add qemu (when supported on m1) +isos="alpine" # Todo: add freebsd, openbsd, archlinux, debian, ubuntu, macOS, win10, etc... + +Cmdlist='add del info help ls runiso start stop version' [ "$1" ] && C=$1 && shift 1 || { help; exit 1; } for c in $Cmdlist do @@ -64,4 +120,4 @@ do ($C*) [ "$cmd" ] && die "ambiguous command $C" || cmd=$c;; esac done -[ "$cmd" ] || die "no command \"$C\"" && $cmd "$@" +[ "$cmd" ] || { help; exit 1; } && $cmd "$@" diff --git a/bin/wol b/bin/wol new file mode 100755 index 0000000..39bce0d --- /dev/null +++ b/bin/wol @@ -0,0 +1,6 @@ +#!/bin/sh -x +ip_plex=192.168.1.90 mac_plex=b0:83:fe:61:a7:aa +eval "mac=\$mac_$1 ip=\$ip_$1" +wakeonlan "$mac" +ping -o "$ip" +ssh "root@$ip" -- cgit v1.2.3 From 556754fb516ff84965a510d0205f3c1d6cf64505 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Wed, 17 Mar 2021 16:17:42 +0100 Subject: improved vm --- bin/vm | 133 +++++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 45 deletions(-) (limited to 'bin') diff --git a/bin/vm b/bin/vm index 5a8ea8d..e8f7684 100755 --- a/bin/vm +++ b/bin/vm @@ -1,32 +1,50 @@ #!/bin/sh -# vm is a tool to manage virtual machines. +# vm is a tool to manage and operate virtual machines. vm_version='vm-0.1' + +# TODO: +# - DONE: fetch, build and install vftool in .vm/vftool +# - setup a config file per VM +# - creation of hdd image +# - script install from CDROM iso: +# - setup system, including static IP address +# - setup user account from host +# - setup ssh from host +# - time synchronization from host +# + unset CDPATH export LC_ALL=C IFS=' ' add() { usage 'add name' 'Add a new VM' && return - [ -d "$idir/$1" ] && die "vm $1 already exists in $idir/$1" + [ -d "$dir/$1" ] && die "vm $1 already exists in $dir/$1" init_alpine || die "could not init alpine iso" - mkdir -p "$idir/$1" && cd "$idir/$1" || die "add $1 failed" + mkdir -p "$dir/$1" && cd "$dir/$1" || die "add $1 failed" pwd } +console() { + usage 'console name' 'Attach a console to a VM' && return + [ "$1" ] || die 'console: name is missing' + cd "$dir/$1" || die 'console $1 failed' + [ -f vftool.pid ] || die "vm $1 is not active" + screen -r "$1" +} + del() { usage 'del name' 'Delete a VM' && return echo 'not implemented yet' } -die() { echo "$0: fatal: $@" >&2; exit 1; } +die() { [ "$1" ] && echo "$@" >&2; exit 1; } help() { usage 'help' 'Print this help text' && return - echo "$vm_version -Manage virtual machines -Usage: vm command [options] [args]" + echo "$vm_version\nManage virtual machines\nUsage: vm command [options] [args]" Opth=1; for c in $Cmdlist; do $c; done } @@ -35,16 +53,9 @@ info() { echo 'not implemented yet' } -init() { - : -} - -init_alpine() { - mkdir -p "$sdir/alpine" && cd "$sdir/alpine" || die "init alpine failed" - [ -f Makefile ] || cat << \EOT > Makefile -# Do no edit. This file is generated by vm. -# Install a run a native AlpineLinux VM in Apple silicon MacOS +# CAUTION: be careful to preserve tabs in the following Makefile template string. +alpine_makefile='# Generated by "vm". DO NOT EDIT. # Check https://alpinelinux.org/downloads for possible upgrades iso_url = https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/aarch64/alpine-virt-3.13.2-aarch64.iso iso = $(notdir $(iso_url)) @@ -52,9 +63,6 @@ isoinfo ?= /opt/homebrew/bin/isoinfo all: initrd vmlinux -runiso: initrd vmlinux $(iso) - vftool -k vmlinux -i initrd -d hdd.img -c $(iso) - initrd: $(iso) $(isoinfo) isoinfo -i $(iso) -J -x /boot/initramfs-virt > $@ @@ -63,36 +71,79 @@ vmlinux: $(iso) $(isoinfo) $(iso): curl -LO $(iso_url) || { rm -f $@; false; } + ln -sf $(iso) iso $(isoinfo): brew install cdrtools -EOT +' +init_alpine() { + mkdir -p "$dir/alpine-iso" && cd "$dir/alpine-iso" || die 'init alpine failed' + [ -f 'Makefile' ] || echo "$alpine_makefile" > Makefile make -s all } +init_vftool() { + [ -x "$dir/vftool" ] && return + cd '/tmp' && + git clone --depth=1 'https://github.com/evansm7/vftool' && + cd 'vftool' && + make && + cp 'build/vftool' "$dir/vftool" + rm -rf '/tmp/vftool' +} + +log() { + usage 'log name' 'print logs of a VM' && return + [ "$1" ] || die "log failed: name missing" + cd "$dir/$1" || die "log $1 failed" + cat vftool.log.old vftool.log 2>/dev/null +} + ls() { usage 'ls' 'list VMs' && return - [ -d "$idir" ] && cd "$idir" || return - for i in *; do - echo "$i" + [ -d "$dir" ] && cd "$dir" || return + for i in */; do + i=${i%/} + [ -f "$i/vftool.pid" ] && state=active || state=stopped + printf "%-20s %s\n" "$i" "$state" done } -runiso() { - usage 'runiso [isoname]' 'run a cdrom iso' && return - init_alpine - make runiso -} - start() { - usage 'start name' 'Start a VM' && return - echo 'not implemented yet' + usage 'start [-a][-c vm] name' 'Start a VM' && return + while getopts :ac: opt; do + case $opt in + (a) attach=1 ;; + (c) from=$OPTARG ;; + (*) Opth=1 start; exit;; + esac + done + shift $((OPTIND - 1)) + + [ "$1" ] || die "start failed: name missing" + init_vftool + cd "$dir/$1" || die "start $1 failed" + [ -f vftool.pid ] && die "Error: process $(cat vftool.pid) is active or $PWD/vftool.pid should be removed" + start_vm & } +start_vm() ( + trap 'rm -f vftool.pid' EXIT + [ -f vftool.log ] && cat vftool.log >> vftool.log.old + "$dir/vftool" -k vmlinux -i initrd -c iso >vftool.log 2>&1 & sleep 1 + exec 1>>vftool.log 2>&1 + echo "$!" >vftool.pid + screen -S "${PWD##*/}" -d -m "$(grep -om 1 '\/dev\/tty.*' vftool.log)" + wait +) + stop() { usage 'stop name' 'Stop a VM' && return - echo 'not implemented yet' + [ "$1" ] || die 'stop: name missing' + cd "$dir/$1" || die 'stop $1 failed' + [ -f vftool.pid ] || die "stop: vm $1 is not active" + kill $(cat vftool.pid) } usage() { [ "$Opth" ] && printf " %-34s %s\n" "$1" "$2"; } @@ -103,21 +154,13 @@ version() { } # Main starts here. -pdir="$HOME/.vm" -sdir="$pdir/iso" -edir="$pdir/engine" -idir="$pdir/img" - -engines="vftool" # Todo: add qemu (when supported on m1) -isos="alpine" # Todo: add freebsd, openbsd, archlinux, debian, ubuntu, macOS, win10, etc... - -Cmdlist='add del info help ls runiso start stop version' +dir="$HOME/.vm" +Cmdlist='add console del info help ls log start stop version' [ "$1" ] && C=$1 && shift 1 || { help; exit 1; } -for c in $Cmdlist -do +for c in $Cmdlist; do case $c in - ($C) cmd=$c; break;; - ($C*) [ "$cmd" ] && die "ambiguous command $C" || cmd=$c;; + ($C) cmd=$c; break ;; + ($C*) [ "$cmd" ] && die "ambiguous command $C" || cmd=$c ;; esac done [ "$cmd" ] || { help; exit 1; } && $cmd "$@" -- cgit v1.2.3 From d86227be78743b71c713a7ce6267cfcea73f6582 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Thu, 18 Mar 2021 16:28:30 +0100 Subject: update --- bin/vm | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'bin') diff --git a/bin/vm b/bin/vm index e8f7684..83ce0ea 100755 --- a/bin/vm +++ b/bin/vm @@ -1,12 +1,12 @@ #!/bin/sh -# vm is a tool to manage and operate virtual machines. +# vm is a command line tool to manage and operate virtual machines. vm_version='vm-0.1' # TODO: # - DONE: fetch, build and install vftool in .vm/vftool -# - setup a config file per VM +# - DONE: setup a config file per VM # - creation of hdd image # - script install from CDROM iso: # - setup system, including static IP address @@ -61,7 +61,7 @@ iso_url = https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/aarch64/alpine-vi iso = $(notdir $(iso_url)) isoinfo ?= /opt/homebrew/bin/isoinfo -all: initrd vmlinux +all: initrd vmlinux config initrd: $(iso) $(isoinfo) isoinfo -i $(iso) -J -x /boot/initramfs-virt > $@ @@ -69,9 +69,11 @@ initrd: $(iso) $(isoinfo) vmlinux: $(iso) $(isoinfo) isoinfo -i $(iso) -J -x /boot/vmlinuz-virt | gunzip > $@ +config: $(iso) + @echo "iso=$(iso)" >config + $(iso): curl -LO $(iso_url) || { rm -f $@; false; } - ln -sf $(iso) iso $(isoinfo): brew install cdrtools @@ -79,7 +81,7 @@ $(isoinfo): init_alpine() { mkdir -p "$dir/alpine-iso" && cd "$dir/alpine-iso" || die 'init alpine failed' - [ -f 'Makefile' ] || echo "$alpine_makefile" > Makefile + [ -f 'Makefile' ] || printf "%s" "$alpine_makefile" > Makefile make -s all } @@ -129,10 +131,21 @@ start() { } start_vm() ( - trap 'rm -f vftool.pid' EXIT [ -f vftool.log ] && cat vftool.log >> vftool.log.old - "$dir/vftool" -k vmlinux -i initrd -c iso >vftool.log 2>&1 & sleep 1 - exec 1>>vftool.log 2>&1 + exec 1>vftool.log 2>&1 + . config || die "vm: could not source $PWD/config" + trap 'rm -f vftool.pid' EXIT + + "$dir/vftool" \ + -k vmlinux \ + -i initrd \ + ${iso+-c "$iso"} \ + ${hdd+-d "$hdd"} \ + ${cpu+-p "$cpu"} \ + ${ram+-m "$ram"} \ + ${arg+-m "$arg"} \ + >>vftool.log 2>&1 & sleep 1 + echo "$!" >vftool.pid screen -S "${PWD##*/}" -d -m "$(grep -om 1 '\/dev\/tty.*' vftool.log)" wait -- cgit v1.2.3 From a8e3586e9b691c2a25b5f2e50a2761d5fcad18f8 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 19 Mar 2021 22:27:11 +0100 Subject: update --- bin/vm | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'bin') diff --git a/bin/vm b/bin/vm index 83ce0ea..0eaa921 100755 --- a/bin/vm +++ b/bin/vm @@ -8,6 +8,7 @@ vm_version='vm-0.1' # - DONE: fetch, build and install vftool in .vm/vftool # - DONE: setup a config file per VM # - creation of hdd image +# - import iso, kernel, initrd from existing vm # - script install from CDROM iso: # - setup system, including static IP address # - setup user account from host @@ -20,13 +21,31 @@ export LC_ALL=C IFS=' ' add() { - usage 'add name' 'Add a new VM' && return + usage 'add [Options] name' 'Add a new VM' && return + while getopts :c:p:s: opt; do + case $opt in + c|k|p|s) eval "$opt=$OPTARG";; + *) Opth=1 add; exit ;; + esac + done + shift $((OPTIND - 1)) + [ -d "$dir/$1" ] && die "vm $1 already exists in $dir/$1" init_alpine || die "could not init alpine iso" mkdir -p "$dir/$1" && cd "$dir/$1" || die "add $1 failed" - pwd + hdd=${p-$1.raw} + [ -f "$hdd" ] || dd if=/dev/zero of=$hdd bs=1 count=0 seek=${s-32g} 2>/dev/null + echo "hdd=\"$hdd\"" > config + [ "$c" ] && { + [ -d "../$c" ] || die "invalid directory: $dir/$c" + iso=$(getconf "$c" iso) + [ "$iso" ] && echo "iso=\"../$c/$iso\"" >> config + cp "../$c/vmlinux" "../$c/initrd" . + } } +getconf() { awk -F '=' -v k="$2" '$1 == k {print $2}' "$dir/$1/config"; } + console() { usage 'console name' 'Attach a console to a VM' && return [ "$1" ] || die 'console: name is missing' @@ -128,6 +147,7 @@ start() { cd "$dir/$1" || die "start $1 failed" [ -f vftool.pid ] && die "Error: process $(cat vftool.pid) is active or $PWD/vftool.pid should be removed" start_vm & + [ "$attach" ] && sleep 1 && vm console $1 } start_vm() ( @@ -139,8 +159,8 @@ start_vm() ( "$dir/vftool" \ -k vmlinux \ -i initrd \ - ${iso+-c "$iso"} \ ${hdd+-d "$hdd"} \ + ${iso+-c "$iso"} \ ${cpu+-p "$cpu"} \ ${ram+-m "$ram"} \ ${arg+-m "$arg"} \ -- cgit v1.2.3 From 262eb286cb7c8d7412160cacfb022247b1f09f00 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 22 Mar 2021 08:50:26 +0100 Subject: update --- bin/vm | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 17 deletions(-) (limited to 'bin') diff --git a/bin/vm b/bin/vm index 0eaa921..11fed61 100755 --- a/bin/vm +++ b/bin/vm @@ -7,9 +7,12 @@ vm_version='vm-0.1' # TODO: # - DONE: fetch, build and install vftool in .vm/vftool # - DONE: setup a config file per VM -# - creation of hdd image -# - import iso, kernel, initrd from existing vm +# - DONE: creation of hdd image +# - DONE: delete a VM +# - DONE: import iso, kernel, initrd from existing vm +# - when no vm is specified, apply command to last one # - script install from CDROM iso: +# - patch alpine setup-disk # - setup system, including static IP address # - setup user account from host # - setup ssh from host @@ -22,9 +25,9 @@ export LC_ALL=C IFS=' add() { usage 'add [Options] name' 'Add a new VM' && return - while getopts :c:p:s: opt; do + while getopts :c:i:k:p:s: opt; do case $opt in - c|k|p|s) eval "$opt=$OPTARG";; + [cikps]) eval "$opt=$OPTARG";; *) Opth=1 add; exit ;; esac done @@ -32,6 +35,7 @@ add() { [ -d "$dir/$1" ] && die "vm $1 already exists in $dir/$1" init_alpine || die "could not init alpine iso" + [ "$1" = 'alpine-iso' ] && return mkdir -p "$dir/$1" && cd "$dir/$1" || die "add $1 failed" hdd=${p-$1.raw} [ -f "$hdd" ] || dd if=/dev/zero of=$hdd bs=1 count=0 seek=${s-32g} 2>/dev/null @@ -41,11 +45,11 @@ add() { iso=$(getconf "$c" iso) [ "$iso" ] && echo "iso=\"../$c/$iso\"" >> config cp "../$c/vmlinux" "../$c/initrd" . + echo "kernel=${k-vmlinux}" >> config + echo "initrd=initrd" >> config } } -getconf() { awk -F '=' -v k="$2" '$1 == k {print $2}' "$dir/$1/config"; } - console() { usage 'console name' 'Attach a console to a VM' && return [ "$1" ] || die 'console: name is missing' @@ -56,10 +60,39 @@ console() { del() { usage 'del name' 'Delete a VM' && return - echo 'not implemented yet' + case $1 in ''|*/*|.*) die "invalid VM name: $1" ;; esac + [ -d "$dir/$1" ] || die "$dir/$1 not found" + cd "$dir" && rm -r "$1" +} + +die() { [ "$1" ] && echo "$0: $@" >&2; exit 1; } + +edit() { + usage 'edit name' 'Edit a VM configuration' && return + [ -f "$dir/$1/config" ] || die "$dir/$1/config not found" + ${EDITOR-vi} "$dir/$1/config" +} + +exp() { + usage 'exp name' 'experiment on a VM' && return + cd "$dir/$1" || die "invalid VM: $1" + [ -f vftool.pid ] || die "vm $1 is not active" + + screen -X stuff 'root +' + screen -X stuff 'sed -i "s/die..Bootloader/;; #/" /sbin/setup-disk +' + screen -X stuff 'grep BOOTLOADER /sbin/setup-disk +' + } -die() { [ "$1" ] && echo "$@" >&2; exit 1; } +finalize() { + tty=$(vftool_tty) + echo "root\nuname -a" >> "$tty" +} + +getconf() { awk -F '=' -v k="$2" '$1 == k {print $2}' "$dir/$1/config"; } help() { usage 'help' 'Print this help text' && return @@ -90,6 +123,11 @@ vmlinux: $(iso) $(isoinfo) config: $(iso) @echo "iso=$(iso)" >config + @echo "initrd=initrd" >>config + @echo "kernel=vmlinux" >>config + @echo "cpu=1" >> config + @echo "ram=512" >> config + @echo "arg=\"console=hvc0\"" >> config $(iso): curl -LO $(iso_url) || { rm -f $@; false; } @@ -126,17 +164,19 @@ ls() { [ -d "$dir" ] && cd "$dir" || return for i in */; do i=${i%/} + [ "$i" = '*' ] && continue [ -f "$i/vftool.pid" ] && state=active || state=stopped printf "%-20s %s\n" "$i" "$state" done } start() { - usage 'start [-a][-c vm] name' 'Start a VM' && return - while getopts :ac: opt; do + usage 'start [-af][-c vm] name' 'Start a VM' && return + while getopts :ac:f opt; do case $opt in - (a) attach=1 ;; + (a) a=1 ;; (c) from=$OPTARG ;; + (f) f=1 ;; (*) Opth=1 start; exit;; esac done @@ -146,8 +186,9 @@ start() { init_vftool cd "$dir/$1" || die "start $1 failed" [ -f vftool.pid ] && die "Error: process $(cat vftool.pid) is active or $PWD/vftool.pid should be removed" - start_vm & - [ "$attach" ] && sleep 1 && vm console $1 + start_vm & sleep 2 + [ "$f" ] && finalize + [ "$a" ] && vm console $1 } start_vm() ( @@ -157,8 +198,8 @@ start_vm() ( trap 'rm -f vftool.pid' EXIT "$dir/vftool" \ - -k vmlinux \ - -i initrd \ + ${kernel+-k "$kernel"} \ + ${initrd+-i "$initrd"} \ ${hdd+-d "$hdd"} \ ${iso+-c "$iso"} \ ${cpu+-p "$cpu"} \ @@ -167,7 +208,7 @@ start_vm() ( >>vftool.log 2>&1 & sleep 1 echo "$!" >vftool.pid - screen -S "${PWD##*/}" -d -m "$(grep -om 1 '\/dev\/tty.*' vftool.log)" + screen -S "${PWD##*/}" -d -m "$(vftool_tty)" wait ) @@ -186,9 +227,11 @@ version() { echo "$vm_version" } +vftool_tty() { grep -om 1 '\/dev\/tty.*' 'vftool.log'; } + # Main starts here. dir="$HOME/.vm" -Cmdlist='add console del info help ls log start stop version' +Cmdlist='add console del edit exp info help ls log start stop version' [ "$1" ] && C=$1 && shift 1 || { help; exit 1; } for c in $Cmdlist; do case $c in -- cgit v1.2.3 From 73aec290b0f95b7be7ef952b042359bb95b18645 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 26 Mar 2021 10:38:56 +0100 Subject: improve update_hosts --- bin/update_hosts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/update_hosts b/bin/update_hosts index 6444550..793344c 100755 --- a/bin/update_hosts +++ b/bin/update_hosts @@ -1,9 +1,10 @@ -#!/bin/sh -ex +#!/bin/sh -e # Update /etc/hosts with a well curated blacklist of malware, ads, porn, etc. # Custom hosts are preserved. [ "$USER" = root ] || exec sudo "$0" "$@" +echo "last update: $(date -r /etc/hosts)" cd /etc cp -p hosts hosts.old hosts=$(awk '/^# Custom host /, /^# End of custom host /' hosts.old) @@ -14,3 +15,4 @@ awk 'BEGIN { hosts = ARGV[1]; ARGV[1] = "" } {print}' "$hosts" > hosts.new mv hosts.new hosts [ "$(uname -s)" != Darwin ] || dscacheutil -flushcache +diff -u /etc/hosts.old /etc/hosts | diffstat -- cgit v1.2.3 From 9734e798057795f89a7bd0a0d933745f0d249b2f Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 26 Mar 2021 12:01:52 +0100 Subject: improve update_hosts --- bin/update_hosts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/update_hosts b/bin/update_hosts index 793344c..8d148a6 100755 --- a/bin/update_hosts +++ b/bin/update_hosts @@ -3,8 +3,18 @@ # Update /etc/hosts with a well curated blacklist of malware, ads, porn, etc. # Custom hosts are preserved. + [ "$USER" = root ] || exec sudo "$0" "$@" -echo "last update: $(date -r /etc/hosts)" + +echo "Check from https://github.com/StevenBlack/hosts" +lsd=$(curl -s "https://api.github.com/repos/StevenBlack/hosts/commits?path=hosts&page=1&per_page=1"| jq -r '.[0].commit.committer.date') +echo "last source update: $(date -j -f "%FT%TZ" "$lsd")" +echo "last local update: $(date -r /etc/hosts)" +if [ $(date -j -f "%FT%TZ" "$lsd" +%s) -lt $(date -r /etc/hosts +%s) ]; then + echo "Nothing to do" + exit +fi + cd /etc cp -p hosts hosts.old hosts=$(awk '/^# Custom host /, /^# End of custom host /' hosts.old) -- cgit v1.2.3 From a8243acb9f5cabd19cc9df16a15018129e0b225e Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 26 Mar 2021 13:50:43 +0100 Subject: improve update_hosts --- bin/update_hosts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'bin') diff --git a/bin/update_hosts b/bin/update_hosts index 8d148a6..4427cd2 100755 --- a/bin/update_hosts +++ b/bin/update_hosts @@ -10,19 +10,18 @@ echo "Check from https://github.com/StevenBlack/hosts" lsd=$(curl -s "https://api.github.com/repos/StevenBlack/hosts/commits?path=hosts&page=1&per_page=1"| jq -r '.[0].commit.committer.date') echo "last source update: $(date -j -f "%FT%TZ" "$lsd")" echo "last local update: $(date -r /etc/hosts)" -if [ $(date -j -f "%FT%TZ" "$lsd" +%s) -lt $(date -r /etc/hosts +%s) ]; then - echo "Nothing to do" - exit -fi +[ $(date -j -f "%FT%TZ" "$lsd" +%s) -lt $(date -r /etc/hosts +%s) ] && echo "Nothing to do" && exit cd /etc cp -p hosts hosts.old hosts=$(awk '/^# Custom host /, /^# End of custom host /' hosts.old) -curl -s https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts | -awk 'BEGIN { hosts = ARGV[1]; ARGV[1] = "" } -/^# Custom host / { print hosts; next } -/^# End of custom host / { next } -{print}' "$hosts" > hosts.new +curl -s 'https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts' | awk ' + BEGIN { hosts = ARGV[1]; ARGV[1] = "" } + /^# Custom host / { print hosts; next } + /^# End of custom host / { next } + { print } +' "$hosts" > hosts.new + mv hosts.new hosts [ "$(uname -s)" != Darwin ] || dscacheutil -flushcache diff -u /etc/hosts.old /etc/hosts | diffstat -- cgit v1.2.3 From ae04cc260d63765fc20a2d7bb21d121986f71445 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 29 Mar 2021 10:26:13 +0200 Subject: update --- bin/icat | 2 ++ bin/vm | 50 +++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 7 deletions(-) (limited to 'bin') diff --git a/bin/icat b/bin/icat index 0170513..d363e09 100755 --- a/bin/icat +++ b/bin/icat @@ -2,6 +2,8 @@ # Display images directly in terminal. # Tested with xterm v361. Depends on imagemagick convert(1). +[ "$LC_TERMINAL" = iTerm2 ] && [ -x "$HOME/.iterm2/imgcat" ] && exec "$HOME/.iterm2/imgcat" "$@" + # maxsize prints the geomtry size of terminal window, with # a maximum value of 1000 pixels for width and height, or # 640x480 if terminal size can not be probed. diff --git a/bin/vm b/bin/vm index 11fed61..818d6f8 100755 --- a/bin/vm +++ b/bin/vm @@ -62,7 +62,8 @@ del() { usage 'del name' 'Delete a VM' && return case $1 in ''|*/*|.*) die "invalid VM name: $1" ;; esac [ -d "$dir/$1" ] || die "$dir/$1 not found" - cd "$dir" && rm -r "$1" + [ -f "$dir/$1/vftool.pid" ] && die "vm $1 is still active, stop it first" + rm -rf "$dir/$1" } die() { [ "$1" ] && echo "$0: $@" >&2; exit 1; } @@ -78,13 +79,48 @@ exp() { cd "$dir/$1" || die "invalid VM: $1" [ -f vftool.pid ] || die "vm $1 is not active" - screen -X stuff 'root + sleep 1 && screen -X stuff 'root ' - screen -X stuff 'sed -i "s/die..Bootloader/;; #/" /sbin/setup-disk + sleep 1 && screen -X stuff 'sed -i.bak "s/die..Bootloader/;; # die \"Bootloader/" /sbin/setup-disk ' - screen -X stuff 'grep BOOTLOADER /sbin/setup-disk + sleep 1 && screen -X stuff 'setup-alpine -e +' + sleep 1 && screen -X stuff 'none +' + sleep 1 && screen -X stuff "$1 +" + sleep 1 && screen -X stuff 'eth0 +' + sleep 1 && screen -X stuff '192.168.64.2 +' + sleep 1 && screen -X stuff '255.255.255.0 +' + sleep 1 && screen -X stuff '192.168.64.1 +' + sleep 1 && screen -X stuff 'n +' + sleep 3 && screen -X stuff ' +' + sleep 1 && screen -X stuff '192.168.64.1 +' + sleep 1 && screen -X stuff 'Europe/Paris +' + sleep 5 && screen -X stuff 'none +' + sleep 1 && screen -X stuff 'chrony +' + sleep 5 && screen -X stuff '1 +' + sleep 1 && screen -X stuff 'openssh +' + sleep 5 && screen -X stuff 'vda +' + sleep 3 && screen -X stuff 'sys +' + sleep 1 && screen -X stuff 'y +' + sleep 20 && screen -X stuff 'cat /etc/fstab ' - } finalize() { @@ -109,7 +145,7 @@ info() { alpine_makefile='# Generated by "vm". DO NOT EDIT. # Check https://alpinelinux.org/downloads for possible upgrades -iso_url = https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/aarch64/alpine-virt-3.13.2-aarch64.iso +iso_url = https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/aarch64/alpine-virt-3.13.3-aarch64.iso iso = $(notdir $(iso_url)) isoinfo ?= /opt/homebrew/bin/isoinfo @@ -204,7 +240,7 @@ start_vm() ( ${iso+-c "$iso"} \ ${cpu+-p "$cpu"} \ ${ram+-m "$ram"} \ - ${arg+-m "$arg"} \ + -a "${arg-console=hvc0}" \ >>vftool.log 2>&1 & sleep 1 echo "$!" >vftool.pid -- cgit v1.2.3 From 3f9cb5afb3b6ee2d4234d5e4d3e5398cf022bc41 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sat, 10 Apr 2021 14:15:57 +0200 Subject: update vm --- bin/vm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'bin') diff --git a/bin/vm b/bin/vm index 818d6f8..19255d2 100755 --- a/bin/vm +++ b/bin/vm @@ -47,6 +47,9 @@ add() { cp "../$c/vmlinux" "../$c/initrd" . echo "kernel=${k-vmlinux}" >> config echo "initrd=initrd" >> config + echo "cpu=1" >> config + echo "ram=512" >> config + echo "arg=\"console=hvc0\"" >> config } } @@ -119,7 +122,7 @@ exp() { ' sleep 1 && screen -X stuff 'y ' - sleep 20 && screen -X stuff 'cat /etc/fstab + sleep 20 && screen -X stuff 'blkid /dev/vda3 ' } @@ -253,7 +256,7 @@ stop() { [ "$1" ] || die 'stop: name missing' cd "$dir/$1" || die 'stop $1 failed' [ -f vftool.pid ] || die "stop: vm $1 is not active" - kill $(cat vftool.pid) + kill $(cat vftool.pid) || rm -f vftool.pid } usage() { [ "$Opth" ] && printf " %-34s %s\n" "$1" "$2"; } -- cgit v1.2.3 From 6962b31552fbf1a2516b0777cc4a52d99a76f6f2 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Wed, 5 May 2021 20:32:05 +0200 Subject: update --- bin/update_hosts | 1 - 1 file changed, 1 deletion(-) (limited to 'bin') diff --git a/bin/update_hosts b/bin/update_hosts index 4427cd2..75c41d1 100755 --- a/bin/update_hosts +++ b/bin/update_hosts @@ -3,7 +3,6 @@ # Update /etc/hosts with a well curated blacklist of malware, ads, porn, etc. # Custom hosts are preserved. - [ "$USER" = root ] || exec sudo "$0" "$@" echo "Check from https://github.com/StevenBlack/hosts" -- cgit v1.2.3 From ebfa4aaf6afe44ffcc15261d8333c861c62ae27d Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 9 May 2021 16:59:33 +0200 Subject: add gemini --- bin/gemini | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100755 bin/gemini (limited to 'bin') diff --git a/bin/gemini b/bin/gemini new file mode 100755 index 0000000..1bc3d57 --- /dev/null +++ b/bin/gemini @@ -0,0 +1,132 @@ +#!/usr/bin/env yaegi +package main + +import ( + "bufio" + "crypto/tls" + "fmt" + "io/ioutil" + "net/url" + "os" + "strconv" + "strings" +) + +func main() { + stdinReader := bufio.NewReader(os.Stdin) + var u string // URL + links := make([]string, 0, 100) + history := make([]string, 0, 100) + for { + fmt.Print("> ") + cmd, _ := stdinReader.ReadString('\n') + cmd = strings.TrimSpace(cmd) + // Command dispatch + switch strings.ToLower(cmd) { + case "": // Nothing + continue + case "q": // Quit + fmt.Println("Bye!") + os.Exit(0) + case "b": // Back + if len(history) < 2 { + fmt.Println("No history yet!") + continue + } + u = history[len(history)-2] + history = history[0 : len(history)-2] + default: + index, err := strconv.Atoi(cmd) + if err != nil { + // Treat this as a URL + u = cmd + if !strings.HasPrefix(u, "gemini://") { + u = "gemini://" + u + } + } else { + // Treat this as a menu lookup + u = links[index-1] + } + } + // Parse URL + parsed, err := url.Parse(u) + if err != nil { + fmt.Println("Error parsing URL!") + continue + } + // Connect to server + conn, err := tls.Dial("tcp", parsed.Host+":1965", &tls.Config{InsecureSkipVerify: true}) + if err != nil { + fmt.Println("Failed to connect: " + err.Error()) + continue + } + defer conn.Close() + // Send request + conn.Write([]byte(u + "\r\n")) + // Receive and parse response header + reader := bufio.NewReader(conn) + responseHeader, err := reader.ReadString('\n') + parts := strings.Fields(responseHeader) + status, err := strconv.Atoi(parts[0][0:1]) + meta := parts[1] + // Switch on status code + switch status { + case 1, 3, 6: + // No input, redirects or client certs + fmt.Println("Unsupported feature!") + case 2: + // Successful transaction + // text/* content only + if !strings.HasPrefix(meta, "text/") { + fmt.Println("Unsupported type " + meta) + continue + } + // Read everything + bodyBytes, err := ioutil.ReadAll(reader) + if err != nil { + fmt.Println("Error reading body") + continue + } + body := string(bodyBytes) + if meta == "text/gemini" { + // Handle Gemini map + links = make([]string, 0, 100) + preformatted := false + for _, line := range strings.Split(body, "\n") { + if strings.HasPrefix(line, "```") { + preformatted = !preformatted + } else if preformatted { + fmt.Println(line) + } else if strings.HasPrefix(line, "=>") { + line = line[2:] + bits := strings.Fields(line) + parsedLink, err := url.Parse(bits[0]) + if err != nil { + continue + } + link := parsed.ResolveReference(parsedLink).String() + var label string + if len(bits) == 1 { + label = link + } else { + label = strings.Join(bits[1:], " ") + } + links = append(links, link) + fmt.Printf("[%d] %s\n", len(links), label) + } else { + // This should really be wrapped, but there's + // no easy support for this in Go's standard + // library + fmt.Println(line) + } + } + } else { + // Just print any other kind of text + fmt.Print(body) + } + history = append(history, u) + case 4, 5: + fmt.Println("ERROR: " + meta) + } + } +} -- cgit v1.2.3 From 67efb5857e720ebbe323ea7284793c43f27b0f67 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sat, 29 May 2021 18:16:42 +0200 Subject: update --- bin/md | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100755 bin/md (limited to 'bin') diff --git a/bin/md b/bin/md new file mode 100755 index 0000000..ca08090 --- /dev/null +++ b/bin/md @@ -0,0 +1,136 @@ +#!/bin/sh + +# See https://spec.commonmark.org for reference +md2html() { + awk ' + function newblock(nb) { + if (text) print "<" block ">" text "" + text = "" + block = nb ? nb : "p" + } + + function subinline(tgl, inl) { + while (match($0, tgl)) { + if (inline[ni] == inl) + ni -= sub(tgl, "") + else if (sub(tgl, "<" inl ">")) + inline[++ni] = inl + } + } + + function dolink(href, lnk) { + # Undo escaped html in uris + gsub(/&/, "\\&", href) + gsub(/</, "<", href) + gsub(/>/, ">", href) + # & can be tricky, and not standard: + gsub(/&/, "\\\\\\&", href) + gsub(/&/, "\\\\\\&", lnk) + return "" lnk "" + } + + BEGIN { ni = 0; nl = 0; text = ""; block = "p" } + + # Escape html + esc != "false" { gsub("&", "\\&"); gsub("<", "\\<"); gsub(">", "\\>") } + + # Horizontal rules (_ is not in markdown) + /^[ ]*([-*_] ?)+[ ]*$/ && text == "" { print "
"; next } + + # Tables (not in markdown) + # Syntax: + # Right Align| Center Align |Left Align + /([ ]\|)|(\|[ ])/ { + if (block != "table") newblock("table") + nc = split($0, cells, "|") + $0 = "\n" + for (i = 1; i <= nc; i++) { + align = "left" + if (sub(/^[ ]+/, "", cells[i])) { + if (sub(/[ ]+$/, "", cells[i])) + align = "center" + else + align = "right" + } + sub(/[ ]+$/, "", cells[i]) + $0 = $0 "" cells[i] "\n" + } + $0 = $0 "" + } + + # Ordered and unordered (possibly nested) lists + /^[ ]*([*+-]|(([0-9]+[\.-]?)+))[ ]/ { + newblock("li") + nnl = 1 + while (match($0, /^[ ]/)) { sub(/^[ ]/,""); nnl++ } + while (nl > nnl) print "" + while (nl < nnl) { + list[++nl] = "ol" + if (match($0, /^[*+-]/)) list[nl] = "ul" + print "<" list[nl] ">" + } + sub(/^([*+-]|(([0-9]+[\.-]?)+))[ ]/,"") + } + + # Multi line list items + block == "li" { sub(/^( *)|( *)/,"") } + + # Code blocks + /^( | )/ { + if (block != "code") newblock("code") + sub(/^( | )/, "") + text = text $0 "\n" + next + } + + # Paragraph + /^$/ { newblock(); while(nl > 0) print "" } + + # Setex-style Headers (plus h3 with underscores) + /^=+$/ { block = "h" 1; next } + /^-+$/ { block = "h" 2; next } + /^_+$/ { block = "h" 3; next } + + # Atx-style headers + /^#/ { + newblock() + match($0, /#+/) + n = RLENGTH + if (n > 6) n = 6 + sub(/# */, "#") + text = substr($0, RLENGTH + 1) + block = "h" n + next + } + + { + # Images + while (match($0, /!\[[^\]]+\]\([^\)]+\)/)) { + split(substr($0, RSTART, RLENGTH), a, /(!\[)|\)|(\]\()/) + sub(/!\[[^\]]+\]\([^\)]+\)/, "\""") + } + # Links + while (match($0, /\[[^\]]+\]\([^\)]+\)/)) { + split(substr($0, RSTART, RLENGTH), a, /[\[\)]|(\]\()/) + sub(/\[[^\]]+\]\([^\)]+\)/, dolink(a[3], a[2])) + } + # Auto links (uri matching is poor) + na = split($0, a, /(^\()|[ ]|([,\.\)]([ ]|$))/) + for (i = 1; i <= na; i++) + if (match(a[i], /^(((https?|ftp|file|news|irc):\/\/)|(mailto:)).+$/)) + sub(a[i], dolink(a[i], a[i])) + # Inline + subinline("(\\*\\*)|(__)", "strong") + subinline("\\*", "em") + subinline("`", "code") + text = text (text ? " " : "") $0 + } + + END { + while(ni > 0) text = text "" + newblock() + while(nl > 0) print "" + }' "$1" +} + +md2html "$1" -- cgit v1.2.3 From 2dc5563129877c1aad571e2023a7e9cc8eec5d04 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 30 May 2021 19:01:16 +0200 Subject: update --- bin/vm | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'bin') diff --git a/bin/vm b/bin/vm index 19255d2..b0e1303 100755 --- a/bin/vm +++ b/bin/vm @@ -28,7 +28,7 @@ add() { while getopts :c:i:k:p:s: opt; do case $opt in [cikps]) eval "$opt=$OPTARG";; - *) Opth=1 add; exit ;; + *) Opth=1 add "$1"; exit ;; esac done shift $((OPTIND - 1)) @@ -38,25 +38,27 @@ add() { [ "$1" = 'alpine-iso' ] && return mkdir -p "$dir/$1" && cd "$dir/$1" || die "add $1 failed" hdd=${p-$1.raw} - [ -f "$hdd" ] || dd if=/dev/zero of=$hdd bs=1 count=0 seek=${s-32g} 2>/dev/null + [ -f "$hdd" ] || dd if=/dev/zero of="$hdd" bs=1 count=0 seek="${s-32g}" 2>/dev/null echo "hdd=\"$hdd\"" > config [ "$c" ] && { [ -d "../$c" ] || die "invalid directory: $dir/$c" iso=$(getconf "$c" iso) - [ "$iso" ] && echo "iso=\"../$c/$iso\"" >> config cp "../$c/vmlinux" "../$c/initrd" . - echo "kernel=${k-vmlinux}" >> config - echo "initrd=initrd" >> config - echo "cpu=1" >> config - echo "ram=512" >> config - echo "arg=\"console=hvc0\"" >> config + [ "$iso" ] && echo "iso=\"../$c/$iso\"" >> config + cat <<- EOT >> config + kernel=${k-vmlinux} + initrd=initrd + cpu=1 + ram=512 + arg="console=hvc0" + EOT } } console() { usage 'console name' 'Attach a console to a VM' && return [ "$1" ] || die 'console: name is missing' - cd "$dir/$1" || die 'console $1 failed' + cd "$dir/$1" || die "console $1 failed" [ -f vftool.pid ] || die "vm $1 is not active" screen -r "$1" } @@ -66,10 +68,10 @@ del() { case $1 in ''|*/*|.*) die "invalid VM name: $1" ;; esac [ -d "$dir/$1" ] || die "$dir/$1 not found" [ -f "$dir/$1/vftool.pid" ] && die "vm $1 is still active, stop it first" - rm -rf "$dir/$1" + rm -rf "${dir:?}/$1" } -die() { [ "$1" ] && echo "$0: $@" >&2; exit 1; } +die() { [ "$1" ] && echo "$0: $*" >&2; exit 1; } edit() { usage 'edit name' 'Edit a VM configuration' && return @@ -128,14 +130,14 @@ exp() { finalize() { tty=$(vftool_tty) - echo "root\nuname -a" >> "$tty" + printf 'root\nuname -a\n' >> "$tty" } getconf() { awk -F '=' -v k="$2" '$1 == k {print $2}' "$dir/$1/config"; } help() { usage 'help' 'Print this help text' && return - echo "$vm_version\nManage virtual machines\nUsage: vm command [options] [args]" + printf '%s\n' "$vm_version\nManage virtual machines\nUsage: vm command [options] [args]" Opth=1; for c in $Cmdlist; do $c; done } @@ -210,13 +212,12 @@ ls() { } start() { - usage 'start [-af][-c vm] name' 'Start a VM' && return - while getopts :ac:f opt; do + usage 'start [-af] name' 'Start a VM' && return + while getopts :af opt; do case $opt in (a) a=1 ;; - (c) from=$OPTARG ;; (f) f=1 ;; - (*) Opth=1 start; exit;; + (*) Opth=1 start "$1"; exit;; esac done shift $((OPTIND - 1)) @@ -227,7 +228,7 @@ start() { [ -f vftool.pid ] && die "Error: process $(cat vftool.pid) is active or $PWD/vftool.pid should be removed" start_vm & sleep 2 [ "$f" ] && finalize - [ "$a" ] && vm console $1 + [ "$a" ] && vm console "$1" } start_vm() ( @@ -254,9 +255,9 @@ start_vm() ( stop() { usage 'stop name' 'Stop a VM' && return [ "$1" ] || die 'stop: name missing' - cd "$dir/$1" || die 'stop $1 failed' + cd "$dir/$1" || die "stop $1 failed" [ -f vftool.pid ] || die "stop: vm $1 is not active" - kill $(cat vftool.pid) || rm -f vftool.pid + kill "$(cat vftool.pid)" || rm -f vftool.pid } usage() { [ "$Opth" ] && printf " %-34s %s\n" "$1" "$2"; } @@ -274,8 +275,8 @@ Cmdlist='add console del edit exp info help ls log start stop version' [ "$1" ] && C=$1 && shift 1 || { help; exit 1; } for c in $Cmdlist; do case $c in - ($C) cmd=$c; break ;; - ($C*) [ "$cmd" ] && die "ambiguous command $C" || cmd=$c ;; + ("$C") cmd=$c; break ;; + ("$C"*) [ "$cmd" ] && die "ambiguous command $C" || cmd=$c ;; esac done [ "$cmd" ] || { help; exit 1; } && $cmd "$@" -- cgit v1.2.3 From 87b63654a7a881afefddaeb6c3dbbf32105070bb Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 4 Jun 2021 16:43:08 +0200 Subject: update, add fv --- bin/fv | 6 ++++++ bin/update_hosts | 6 +++--- bin/vm | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) create mode 100755 bin/fv (limited to 'bin') diff --git a/bin/fv b/bin/fv new file mode 100755 index 0000000..5662ed3 --- /dev/null +++ b/bin/fv @@ -0,0 +1,6 @@ +#!/bin/sh +# quick file viewer +#exec fzf --multi --preview-window=right:66% --preview 'cat {1}' +exec fzf --ansi --multi --preview-window=right:75% \ + --bind=left:preview-page-up --bind=right:preview-page-down \ + --preview 'cat {1}' diff --git a/bin/update_hosts b/bin/update_hosts index 75c41d1..e7321bf 100755 --- a/bin/update_hosts +++ b/bin/update_hosts @@ -5,7 +5,7 @@ [ "$USER" = root ] || exec sudo "$0" "$@" -echo "Check from https://github.com/StevenBlack/hosts" +echo "Checking from https://github.com/StevenBlack/hosts:" lsd=$(curl -s "https://api.github.com/repos/StevenBlack/hosts/commits?path=hosts&page=1&per_page=1"| jq -r '.[0].commit.committer.date') echo "last source update: $(date -j -f "%FT%TZ" "$lsd")" echo "last local update: $(date -r /etc/hosts)" @@ -14,7 +14,7 @@ echo "last local update: $(date -r /etc/hosts)" cd /etc cp -p hosts hosts.old hosts=$(awk '/^# Custom host /, /^# End of custom host /' hosts.old) -curl -s 'https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts' | awk ' +curl -s 'https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts' | awk ' BEGIN { hosts = ARGV[1]; ARGV[1] = "" } /^# Custom host / { print hosts; next } /^# End of custom host / { next } @@ -22,5 +22,5 @@ curl -s 'https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts' | aw ' "$hosts" > hosts.new mv hosts.new hosts -[ "$(uname -s)" != Darwin ] || dscacheutil -flushcache +[ "$(uname -s)" != Darwin ] || { dscacheutil -flushcache; killall -HUP mDNSResponder; } diff -u /etc/hosts.old /etc/hosts | diffstat diff --git a/bin/vm b/bin/vm index b0e1303..732ba49 100755 --- a/bin/vm +++ b/bin/vm @@ -179,7 +179,7 @@ $(isoinfo): init_alpine() { mkdir -p "$dir/alpine-iso" && cd "$dir/alpine-iso" || die 'init alpine failed' - [ -f 'Makefile' ] || printf "%s" "$alpine_makefile" > Makefile + [ -f 'Makefile' ] || printf '%s' "$alpine_makefile" > Makefile make -s all } -- cgit v1.2.3 From 6462de909492c58a8b1061633cec1c325539b3b6 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 11 Jun 2021 00:33:09 +0200 Subject: added migrate_vimki --- bin/migrate_vimki | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100755 bin/migrate_vimki (limited to 'bin') diff --git a/bin/migrate_vimki b/bin/migrate_vimki new file mode 100755 index 0000000..15242e6 --- /dev/null +++ b/bin/migrate_vimki @@ -0,0 +1,58 @@ +#!/bin/sh + +# Migrate Wiki content from vimki to vimki2 format. + +fixfile() { + awk ' + { + for (i = 1; i <= NR; i++) { + if (match($i, /^[A-Z][A-Z_0-9]*[a-z][a-z0-9]*[_A-Z]/) == 0) continue + s = $i + l = "" + while (match(s, /^[A-Z][A-Z_0-9]*[a-z]+/) != 0) { + l = l substr(s, 1, RLENGTH) " " + s = substr(s, RLENGTH+1) + } + p = match(s, /[^A-Za-z0-9_]/) + if (p != 0) { + s2 = substr(s, 1, p-1) "]" substr(s, p) + s = s2 + } else s = s "]" + l = "[" l s + gsub(/[ \t_]+/, " ", l) + sub(/ *]/, "]", l) + $i = tolower(l) + } + print + } + ' "${1:-HomePage}" +} + +fixname() { + echo "$1" | awk '{ + s = $0 + l = "" + while (match(s, /^[A-Z][A-Z_0-9]*[a-z]+/) != 0) { + l = l substr(s, 1, RLENGTH) " " + s = substr(s, RLENGTH+1) + } + p = match(s, /[^A-Za-z0-9_]/) + if (p != 0) { + s2 = substr(s, 1, p-1) "]" substr(s, p) + s = s2 + } + l = l s + gsub(/[ \t_]+/, " ", l) + sub(/ *$/, "", l) + print tolower(l) + + }' +} + +mkdir -p $HOME/Wiki2 +cd $HOME/Wiki +for file in *; do + new=$(fixname "$file") + echo "$new" + fixfile "$file" > "$HOME/Wiki2/$new" +done -- cgit v1.2.3 From 2621ec5405f52343cf253d02e307c5b160cf7f04 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 13 Jun 2021 14:49:53 +0200 Subject: update --- bin/update_hosts | 8 ++++---- bin/vimki | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) create mode 100755 bin/vimki (limited to 'bin') diff --git a/bin/update_hosts b/bin/update_hosts index e7321bf..8550ec3 100755 --- a/bin/update_hosts +++ b/bin/update_hosts @@ -13,11 +13,11 @@ echo "last local update: $(date -r /etc/hosts)" cd /etc cp -p hosts hosts.old -hosts=$(awk '/^# Custom host /, /^# End of custom host /' hosts.old) +hosts=$(awk '/^# Custom host/, /^# End of custom host/' hosts.old) curl -s 'https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts' | awk ' - BEGIN { hosts = ARGV[1]; ARGV[1] = "" } - /^# Custom host / { print hosts; next } - /^# End of custom host / { next } + BEGIN { hosts = ARGV[1]; ARGV[1] = "" } + /^# Custom host/ { print hosts; next } + /^# End of custom host/ { next } { print } ' "$hosts" > hosts.new diff --git a/bin/vimki b/bin/vimki new file mode 100755 index 0000000..50ab6ea --- /dev/null +++ b/bin/vimki @@ -0,0 +1,29 @@ +#!/bin/sh + +# Batch operations on vimki + +# rename changes the link name and propagates the change in the wiki +rename1() { + gawk -v old="$1" -v new="$2" -v IGNORECASE=1 ' + { + gsub("[[]" old "[]]", "[" new "]") + print + } + ' "$3" +} + +linkfile() { + echo "$1" + #echo "$1" | tr '[:upper:] àçéèêëîïôèùûü' '[:lower:]_aceeeeiiouuu' +} + +rename() { + for f in *; do + rename1 "$1" "$2" "$f" > "$f.$$" && mv "$f.$$" "$f" + done + oldf="$(linkfile "$1")" + [ -f "$oldf" ] && mv "$oldf" "$(linkfile "$2")" +} + +cd ~/Wiki +"$@" -- cgit v1.2.3 From 53569210e7967c6d891affb027c1ea202194f9c0 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sat, 19 Jun 2021 13:00:21 +0200 Subject: vimki: rename handle accents and punctuation --- bin/vimki | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'bin') diff --git a/bin/vimki b/bin/vimki index 50ab6ea..f2ba45b 100755 --- a/bin/vimki +++ b/bin/vimki @@ -5,25 +5,46 @@ # rename changes the link name and propagates the change in the wiki rename1() { gawk -v old="$1" -v new="$2" -v IGNORECASE=1 ' + BEGIN { + rx = old + gsub(/_/, "\\W+", rx) + gsub(/a/, "[aåäáàâã]", rx) + gsub(/c/, "[cç]", rx) + gsub(/e/, "[eéèêë]", rx) + gsub(/i/, "[iîíìï]", rx) + gsub(/o/, "[oôöóõò]", rx) + gsub(/u/, "[uùûüú]", rx) + gsub(/y/, "[yÿ]", rx) + gsub(/n/, "[nñ]", rx) + } { - gsub("[[]" old "[]]", "[" new "]") + gsub("[[]" rx "[]]", "[" new "]") print } ' "$3" } linkfile() { - echo "$1" - #echo "$1" | tr '[:upper:] àçéèêëîïôèùûü' '[:lower:]_aceeeeiiouuu' + echo "$1" | + tr '[:upper:]' '[:lower:]' | + tr 'åäáàâãçéèêëîíìïôöóõòùûüúÿñ' 'aaaaaaceeeeiiiiooooouuuuyn' | + awk '{gsub(/\W+/, "_"); print}' } rename() { - for f in *; do + for f in *.md; do + [ "$(head -c 8 "$f")" = VimCrypt ] && continue rename1 "$1" "$2" "$f" > "$f.$$" && mv "$f.$$" "$f" done oldf="$(linkfile "$1")" [ -f "$oldf" ] && mv "$oldf" "$(linkfile "$2")" } +fixfiles() { + for f in *; do + mv "$f" "$(linkfile "$f")" + done +} + cd ~/Wiki "$@" -- cgit v1.2.3 From 6f40c5ba8549a66bd2b9ab449f57a574f0c2e905 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sat, 19 Jun 2021 15:59:06 +0200 Subject: vimki: fix rename --- bin/vimki | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'bin') diff --git a/bin/vimki b/bin/vimki index f2ba45b..3c6626c 100755 --- a/bin/vimki +++ b/bin/vimki @@ -24,6 +24,8 @@ rename1() { ' "$3" } +#shellcheck disable=SC2020 + linkfile() { echo "$1" | tr '[:upper:]' '[:lower:]' | @@ -36,8 +38,8 @@ rename() { [ "$(head -c 8 "$f")" = VimCrypt ] && continue rename1 "$1" "$2" "$f" > "$f.$$" && mv "$f.$$" "$f" done - oldf="$(linkfile "$1")" - [ -f "$oldf" ] && mv "$oldf" "$(linkfile "$2")" + oldf="$(linkfile "$1").md" + [ -f "$oldf" ] && mv "$oldf" "$(linkfile "$2").md" } fixfiles() { @@ -46,5 +48,5 @@ fixfiles() { done } -cd ~/Wiki +cd ~/Wiki || exit "$@" -- cgit v1.2.3 From 1433c15716d0da97d54d39f7397b80654ce10415 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 20 Jun 2021 14:33:05 +0200 Subject: vimki: fix rename --- bin/vimki | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'bin') diff --git a/bin/vimki b/bin/vimki index 3c6626c..2f64162 100755 --- a/bin/vimki +++ b/bin/vimki @@ -5,8 +5,16 @@ # rename changes the link name and propagates the change in the wiki rename1() { gawk -v old="$1" -v new="$2" -v IGNORECASE=1 ' + { + gsub("[[]" old "[]]", "[" new "]") + print + } + ' "$3" +} + +link2rx() { + gawk -v rx="$1" -v IGNORECASE=1 ' BEGIN { - rx = old gsub(/_/, "\\W+", rx) gsub(/a/, "[aåäáàâã]", rx) gsub(/c/, "[cç]", rx) @@ -16,12 +24,8 @@ rename1() { gsub(/u/, "[uùûüú]", rx) gsub(/y/, "[yÿ]", rx) gsub(/n/, "[nñ]", rx) - } - { - gsub("[[]" rx "[]]", "[" new "]") - print - } - ' "$3" + print rx + }' } #shellcheck disable=SC2020 @@ -34,9 +38,10 @@ linkfile() { } rename() { + rx=$(link2rx "$1") for f in *.md; do [ "$(head -c 8 "$f")" = VimCrypt ] && continue - rename1 "$1" "$2" "$f" > "$f.$$" && mv "$f.$$" "$f" + rename1 "$rx" "$2" "$f" > "$f.$$" && mv "$f.$$" "$f" done oldf="$(linkfile "$1").md" [ -f "$oldf" ] && mv "$oldf" "$(linkfile "$2").md" -- cgit v1.2.3 From 0ad6087640b7c6f9bee6e954f0736d9c183f6a5c Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 20 Jun 2021 15:36:38 +0200 Subject: vimki: parallelize rename --- bin/vimki | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'bin') diff --git a/bin/vimki b/bin/vimki index 2f64162..e3e0f4d 100755 --- a/bin/vimki +++ b/bin/vimki @@ -4,12 +4,13 @@ # rename changes the link name and propagates the change in the wiki rename1() { + [ "$(head -c 8 "$3")" = VimCrypt ] && return gawk -v old="$1" -v new="$2" -v IGNORECASE=1 ' { gsub("[[]" old "[]]", "[" new "]") print } - ' "$3" + ' "$3" > "$3.$$" && mv "$3.$$" "$3" } link2rx() { @@ -39,10 +40,8 @@ linkfile() { rename() { rx=$(link2rx "$1") - for f in *.md; do - [ "$(head -c 8 "$f")" = VimCrypt ] && continue - rename1 "$rx" "$2" "$f" > "$f.$$" && mv "$f.$$" "$f" - done + # Parallelize renaming + echo *.md | xargs -n 1 -P 8 "$0" rename1 "$rx" "$2" oldf="$(linkfile "$1").md" [ -f "$oldf" ] && mv "$oldf" "$(linkfile "$2").md" } -- cgit v1.2.3 From e70107cb6a2f1fe17b848c43774b4e946749ea23 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 15 Aug 2021 11:26:14 +0200 Subject: update --- bin/update_kernel_host | 8 ++++++++ bin/vm | 10 ++++++---- bin/wol | 4 ++-- 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100755 bin/update_kernel_host (limited to 'bin') diff --git a/bin/update_kernel_host b/bin/update_kernel_host new file mode 100755 index 0000000..6180921 --- /dev/null +++ b/bin/update_kernel_host @@ -0,0 +1,8 @@ +#!/bin/sh -ex + +# After 'apk upgrade', update kernel and initrd on VM host + +sudo cp /boot/initramfs-virt /tmp +sudo chmod a+r /tmp/initramfs-virt +gunzip < /boot/vmlinuz-virt > /tmp/vmlinux +scp /tmp/initramfs-virt /tmp/vmlinux marc@m1:.vm/vm1/ diff --git a/bin/vm b/bin/vm index 732ba49..97e3521 100755 --- a/bin/vm +++ b/bin/vm @@ -212,11 +212,12 @@ ls() { } start() { - usage 'start [-af] name' 'Start a VM' && return - while getopts :af opt; do + usage 'start [-afs] name' 'Start a VM' && return + while getopts :afs opt; do case $opt in (a) a=1 ;; (f) f=1 ;; + (s) s=1 ;; (*) Opth=1 start "$1"; exit;; esac done @@ -227,8 +228,9 @@ start() { cd "$dir/$1" || die "start $1 failed" [ -f vftool.pid ] && die "Error: process $(cat vftool.pid) is active or $PWD/vftool.pid should be removed" start_vm & sleep 2 - [ "$f" ] && finalize - [ "$a" ] && vm console "$1" + ! [ "$f" ] || finalize + ! [ "$a" ] || vm console "$1" + ! [ "$s" ] || exec ssh "$1" } start_vm() ( diff --git a/bin/wol b/bin/wol index 39bce0d..7975df9 100755 --- a/bin/wol +++ b/bin/wol @@ -1,6 +1,6 @@ -#!/bin/sh -x +#!/bin/sh ip_plex=192.168.1.90 mac_plex=b0:83:fe:61:a7:aa eval "mac=\$mac_$1 ip=\$ip_$1" wakeonlan "$mac" -ping -o "$ip" +while ! nc -zw 2 "$ip" 22; do printf .; sleep 2; done ssh "root@$ip" -- cgit v1.2.3 From 7a36b02b5f3ae6560030c97513b8c15d9abd16d8 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sat, 27 Nov 2021 11:04:34 +0100 Subject: update --- bin/update_hosts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'bin') diff --git a/bin/update_hosts b/bin/update_hosts index 8550ec3..40ec470 100755 --- a/bin/update_hosts +++ b/bin/update_hosts @@ -5,11 +5,11 @@ [ "$USER" = root ] || exec sudo "$0" "$@" -echo "Checking from https://github.com/StevenBlack/hosts:" -lsd=$(curl -s "https://api.github.com/repos/StevenBlack/hosts/commits?path=hosts&page=1&per_page=1"| jq -r '.[0].commit.committer.date') +echo 'Checking from https://github.com/StevenBlack/hosts:' +lsd=$(curl -s 'https://api.github.com/repos/StevenBlack/hosts/commits?path=hosts&page=1&per_page=1' | jq -r '.[0].commit.committer.date') echo "last source update: $(date -j -f "%FT%TZ" "$lsd")" echo "last local update: $(date -r /etc/hosts)" -[ $(date -j -f "%FT%TZ" "$lsd" +%s) -lt $(date -r /etc/hosts +%s) ] && echo "Nothing to do" && exit +[ $(date -j -f "%FT%TZ" "$lsd" +%s) -lt $(date -r /etc/hosts +%s) ] && echo 'Nothing to do' && exit cd /etc cp -p hosts hosts.old -- cgit v1.2.3 From b9df08e08dc7eba9352bc68a4d1bb55c8d27529f Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sun, 28 Nov 2021 15:45:27 +0100 Subject: update --- bin/backup | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'bin') diff --git a/bin/backup b/bin/backup index 72c69c3..adce78d 100755 --- a/bin/backup +++ b/bin/backup @@ -1,8 +1,6 @@ #!/bin/sh # Incremental backup using rsync(1). -[ "$USER" = root ] || exec sudo "$0" "$@" - backup() { date=$(date +%Y%m%d_%H%M%S) last=$(rsync --list-only "$dest/" 2>/dev/null | cut -b 47- | tail -1) @@ -12,25 +10,29 @@ backup() { (*) opt_link=;; esac - rsync -HSxa$optv --exclude-from=$ignore $opt_link / /boot "$dest/$date" + rsync -HSxa$optv --exclude-from=$ignore $opt_link $volumes "$dest/$date" } dest=/.history -ignore=/etc/backup/ignore +ignore=/etc/backupignore +volumes='/ /boot' -while getopts :d:i:nv opt; do +while getopts :d:i:nuv opt; do case $opt in (d) dest="$OPTARG" ;; (i) ignore="$OPTARG" ;; (n|v) optv="$opt$optv" ;; - (*) echo "Usage: $0 [-nv] [-d [host:]dir] [clean|diff]"; exit 1 ;; + (u) optu=1 volumes="$HOME" ignore="$HOME/.backupignore" ;; + (*) echo "Usage: $0 [-nuv] [-d [[user@]host:]dir] [clean|diff]"; exit 1 ;; esac done shift $((OPTIND - 1)) +[ "$optu" ] || [ "$USER" = root ] || exec sudo "$0" "$@" + [ "$1" ] && cmd=$1 && shift || cmd="" case $cmd in (""|save) backup ;; -(clean) exec backup-clean ${optv+-$optv} "$dest";; +(clean) exec backup-clean ${optv+-$optv} "$@" "$dest";; (diff) exec diffdir "$@";; esac -- cgit v1.2.3 From ea345acc22fbb3a0ac36a7d1ea43de3dae0f51a1 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Thu, 2 Dec 2021 15:26:02 +0100 Subject: update --- bin/backup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/backup b/bin/backup index adce78d..9de097f 100755 --- a/bin/backup +++ b/bin/backup @@ -3,7 +3,7 @@ backup() { date=$(date +%Y%m%d_%H%M%S) - last=$(rsync --list-only "$dest/" 2>/dev/null | cut -b 47- | tail -1) + last=$(rsync --list-only "$dest/" 2>/dev/null | awk '{r=$NF} END {print r}') case $last in ([12]*) opt_link=--link-dest=../$last;; -- cgit v1.2.3 From 14b5c600034a9d52497af2974f30dafc21710282 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 6 Dec 2021 15:36:55 +0100 Subject: update --- bin/backup | 57 ++++++++++++++---------- bin/backup-clean | 132 +++++++++++++++++++++++-------------------------------- 2 files changed, 88 insertions(+), 101 deletions(-) (limited to 'bin') diff --git a/bin/backup b/bin/backup index 9de097f..3964927 100755 --- a/bin/backup +++ b/bin/backup @@ -1,38 +1,47 @@ #!/bin/sh -# Incremental backup using rsync(1). -backup() { - date=$(date +%Y%m%d_%H%M%S) - last=$(rsync --list-only "$dest/" 2>/dev/null | awk '{r=$NF} END {print r}') +usage() { + echo "Usage: $0 [-nv] [[[user@]host]:dir] - case $last in - ([12]*) opt_link=--link-dest=../$last;; - (*) opt_link=;; - esac +Incremental backup using rsync(1). If run as root, a full system +backup is performed. Otherwise, the user's home directory is backed. - rsync -HSxa$optv --exclude-from=$ignore $opt_link $volumes "$dest/$date" -} +Options: +-n dry-run +-v verbose -dest=/.history -ignore=/etc/backupignore -volumes='/ /boot' +Files: +- $HOME/.backupignore exclude files from user backup (non root) +- /etc/backupignore exclude files from system backup (root) + +Environment: +- BACKUP backup directory" +} -while getopts :d:i:nuv opt; do +while getopts :nv opt; do case $opt in - (d) dest="$OPTARG" ;; - (i) ignore="$OPTARG" ;; (n|v) optv="$opt$optv" ;; - (u) optu=1 volumes="$HOME" ignore="$HOME/.backupignore" ;; - (*) echo "Usage: $0 [-nuv] [-d [[user@]host:]dir] [clean|diff]"; exit 1 ;; + (*) usage; exit 1 ;; esac done shift $((OPTIND - 1)) -[ "$optu" ] || [ "$USER" = root ] || exec sudo "$0" "$@" +BACKUP=${1:-$BACKUP} +[ "$BACKUP" ] || { usage; exit 1; } -[ "$1" ] && cmd=$1 && shift || cmd="" -case $cmd in -(""|save) backup ;; -(clean) exec backup-clean ${optv+-$optv} "$@" "$dest";; -(diff) exec diffdir "$@";; +[ "$USER" = root ] && + ignore=/etc/backupignore volumes='/ /boot' || + ignore="$HOME/.backupignore" volumes="$HOME" +[ -f "$ignore" ] && ignore="--exclude-from=$ignore" || ignore= + +last=$(rsync --list-only "$BACKUP/" 2>/dev/null | awk '{r=$NF} END {print r}') +case $last in +([12]*) opt_link=--link-dest=../$last;; +(*) opt_link=;; esac + +date=$(date +%Y-%m-%d-%H%M%S) + +[ "$optv" ] && echo "# Backup $volumes to $BACKUP/$date" + +exec rsync -HSxa$optv $ignore $opt_link $volumes "$BACKUP/$date" diff --git a/bin/backup-clean b/bin/backup-clean index 30d25db..f5baa29 100755 --- a/bin/backup-clean +++ b/bin/backup-clean @@ -1,89 +1,67 @@ #!/bin/sh -# backup garbage collector -[ "$USER" = root ] || exec sudo "$0" "$@" -# Durations, in number of seconds. -hd=3600 # hour duration: 60s * 60 -h12=43200 # 12h: hd * 12 -dd=86400 # day duration: hd * 24 -wd=604800 # week duration: dd * 7 -md=2592000 # month duration: dd * 30 -yd=31557600 # year duration: dd * 365.25 +usage() { + echo "Usage: $0 [-nv] [[[user@]host:]dir] -now=$(date +'%Y%m%d_%H%M%S') +$0 removes old backups and keeps: +- backups for the current day +- 1 backup per past day for the current month +- 1 backup per past month for the current year +- 1 backup per past year -# The following works only for busybox date, not coreutils -# Kept for reference only. -#date2ts() { d=${1%_*} t=${1#*_}; date -d "$d${t%??}" +%s; } +Options: +-n dry run +-v verbose -# Convert date to timestamp, using date from GNU coreutils, -# works also with busybox date. -date2ts() { - t=$1; r=${t#????}; Y=${t%$r} # Year (with century) - t=$r; r=${t#??}; m=${t%$r} # Month - t=$r; r=${t#??}; d=${t%$r} # Day - t=${r#_}; r=${t#??}; H=${t%$r} # Hour - t=$r; r=${t#??}; M=${t%$r} # Minute - S=${t#??} # Second - date -d "$Y-$m-$d $H:$M:$S" +%s - #date -jf "%Y-%m-%d %H:%M:%S" "$Y-$m-$d $H:$M:$S" +%s # BSD, MacOS (not tested) +Environment variables: +- BACKUP - backup directory" } -ts2date() { date -d "@$1" +'%Y%m%d_%H%M%S'; } - -tsn=$(date2ts "$now") - -# Minimal retention delay in seconds, according to backup age, -# implemented using POSIX shell arithmetic. -retention_delay() { - d=$((tsn - $1)) - if [ $((d < h12)) = 1 ]; then - r=0 # keep all backups in the last 12 hours - elif [ $((d < dd)) = 1 ]; then - r=$hd # keep 1 backup per hour in the last day - elif [ $((d < wd)) = 1 ]; then - r=$dd # keep 1 backup per day in the last week - elif [ $((d < md)) = 1 ]; then - r=$wd # keep 1 backup per week in the last month - elif [ $((d < yd)) = 1 ]; then - r=$md # keep 1 backup per month in the last year - else - r=$yd # keep 1 backup per year in the previous years - fi - echo $r -} - -dest=/.history -while getopts :d:nv opt; do +while getopts :nv opt; do case $opt in - (d) tsn=$(date2ts "$OPTARG") ;; - (n) optn=1 ;; - (v) optv=1 ;; - (*) echo "Usage: $0 [-nv] [dir]"; exit 1 ;; + (n) optn=echo ;; + (v) optv=-t ;; + (*) usage; exit 1 ;; esac done -shift $((OPTIND - 1)) -[ "$1" ] && dest=$1 +shift $((OPTIND -1)) + +BACKUP=${1:-$BACKUP} +[ "$BACKUP" ] || { usage; exit 1; } -# Sorted list of backups, most recent first. -lbu=$(ls -rv "$dest") -lasy=${lbu##* +host=${BACKUP%:*} dir=${BACKUP#*:} +ls='ls -r' rm="xargs -r $optv $optn rm -rf" +[ "$host" = "$dir" ] || ls="ssh $host $ls" rm="ssh $host $rm" + +[ "$optv" ] && echo "# Cleaning backups on $BACKUP" + +$ls "$dir" | +awk -v now=$(date +%Y-%m-%d) -v dir="$dir" ' +BEGIN { + yn = substr(now, 1, 4) # Year now + mn = substr(now, 6, 2) # Month now + dn = substr(now, 9, 2) # Day now } -for d in $lbu; do - tsc=$(date2ts "$d") - if ! [ "$tsp" ]; then - [ "$optv" ] && echo "keep $dest/$d" - tsp=$tsc - continue - fi - mrd=$(retention_delay "$tsp") - dp=$((tsp - tsc)) - #if [ $((dp < mrd)) = 1 ]; then - if [ "$d" != "last" -a $((dp < mrd)) = 1 ]; then - [ "$optv" ] && echo "delete $dest/$d" - [ "$optn" ] || rm -rf "${dest:?}/$d" - else - [ "$optv" ] && echo "keep $dest/$d" - tsp=$tsc - fi -done +{ + yb = substr($0, 1, 4) # Year backup + mb = substr($0, 6, 2) # Month backup + db = substr($0, 9, 2) # Day backup + $0 = dir "/" $0 + + dy = yn - yb + dm = dy * 12 + mn - mb + # if (yb != yn) { + if (dm > 12) + if (yb in yearly) print; else yearly[yb] = 1 + next + } + # if (mb != mn) { + dd = dm * 30 + dn - db + if (dd > 30) { + if (mb in monthly) print; else monthly[mb] = 1 + next + } + if (db != dn) { + if (db in dayly) print; else dayly[db] = 1 + } +}' | $rm -- cgit v1.2.3 From 4233fc9c6bc0f2f136a495efcd497394edd5156b Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Tue, 7 Dec 2021 14:50:57 +0100 Subject: update --- bin/backup | 3 +-- bin/backup-clean | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'bin') diff --git a/bin/backup b/bin/backup index 3964927..d682849 100755 --- a/bin/backup +++ b/bin/backup @@ -42,6 +42,5 @@ esac date=$(date +%Y-%m-%d-%H%M%S) -[ "$optv" ] && echo "# Backup $volumes to $BACKUP/$date" - +echo "# Backup $volumes to $BACKUP/$date" exec rsync -HSxa$optv $ignore $opt_link $volumes "$BACKUP/$date" diff --git a/bin/backup-clean b/bin/backup-clean index f5baa29..34e6d97 100755 --- a/bin/backup-clean +++ b/bin/backup-clean @@ -33,7 +33,7 @@ host=${BACKUP%:*} dir=${BACKUP#*:} ls='ls -r' rm="xargs -r $optv $optn rm -rf" [ "$host" = "$dir" ] || ls="ssh $host $ls" rm="ssh $host $rm" -[ "$optv" ] && echo "# Cleaning backups on $BACKUP" +echo "# Cleaning backups on $BACKUP" $ls "$dir" | awk -v now=$(date +%Y-%m-%d) -v dir="$dir" ' @@ -51,7 +51,7 @@ BEGIN { dy = yn - yb dm = dy * 12 + mn - mb # if (yb != yn) { - if (dm > 12) + if (dm > 12) { if (yb in yearly) print; else yearly[yb] = 1 next } -- cgit v1.2.3 From e200c8d78ca1d3388c25c1cef8892b1dd015bbf7 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 28 Jan 2022 12:19:59 +0100 Subject: update --- bin/vm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'bin') diff --git a/bin/vm b/bin/vm index 97e3521..6b03d0e 100755 --- a/bin/vm +++ b/bin/vm @@ -242,7 +242,8 @@ start_vm() ( "$dir/vftool" \ ${kernel+-k "$kernel"} \ ${initrd+-i "$initrd"} \ - ${hdd+-d "$hdd"} \ + ${hda+-d "$hda"} \ + ${hdb+-d "$hdb"} \ ${iso+-c "$iso"} \ ${cpu+-p "$cpu"} \ ${ram+-m "$ram"} \ -- cgit v1.2.3