sh: functions -> bin/
This commit is contained in:
parent
b95a514bcc
commit
36670f3e1c
10
bin/_cac_curl_api_v1
Executable file
10
bin/_cac_curl_api_v1
Executable file
@ -0,0 +1,10 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
exec _cac_exec curl -fsS "$1" "https://panel.cloudatcost.com/api/v1/$2.php" $(
|
||||
shift 2
|
||||
set -- "$@" login="$cac_login" key="$cac_key"
|
||||
for arg; do
|
||||
echo -d $(printf '%s' "$arg" | urlencode)
|
||||
done
|
||||
)
|
8
bin/_cac_exec
Executable file
8
bin/_cac_exec
Executable file
@ -0,0 +1,8 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
if test -z "${cac_via-}"; then
|
||||
exec "$@"
|
||||
else
|
||||
exec ssh -q "$cac_via" -t "$@"
|
||||
fi
|
3
bin/_cac_get_api_v1
Executable file
3
bin/_cac_get_api_v1
Executable file
@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec _cac_curl_api_v1 -G "$@"
|
3
bin/_cac_post_api_v1
Executable file
3
bin/_cac_post_api_v1
Executable file
@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec _cac_curl_api_v1 -XPOST "$@"
|
5
bin/bre-escape
Executable file
5
bin/bre-escape
Executable file
@ -0,0 +1,5 @@
|
||||
#! /bin/sh
|
||||
# bre-escape : lines string |> lines bre-escaped-string
|
||||
set -euf
|
||||
|
||||
sed 's:[\.\[\\\*\^\$]:\\&:g'
|
15
bin/bre-invert-word
Executable file
15
bin/bre-invert-word
Executable file
@ -0,0 +1,15 @@
|
||||
#! /bin/sh
|
||||
# bre-invert-word : string -> BRE
|
||||
set -euf
|
||||
|
||||
# TODO escape chars in the resulting BRE.
|
||||
awk -v input="$1" '
|
||||
BEGIN {
|
||||
split(input,s,"")
|
||||
for (i in s) {
|
||||
c=s[i]
|
||||
printf "\\|%s[^%s]", y, c
|
||||
y = y c
|
||||
}
|
||||
}
|
||||
'
|
5
bin/cac-cloudpro-build
Executable file
5
bin/cac-cloudpro-build
Executable file
@ -0,0 +1,5 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
# default os=26 is CentOS-7-64bit
|
||||
exec _cac_post_api_v1 cloudpro/build cpu="$1" ram="$2" storage="$3" os="${4-26}"
|
3
bin/cac-cloudpro-delete
Executable file
3
bin/cac-cloudpro-delete
Executable file
@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec _cac_post_api_v1 cloudpro/delete sid="$1"
|
3
bin/cac-cloudpro-resources
Executable file
3
bin/cac-cloudpro-resources
Executable file
@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec _cac_get_api_v1 cloudpro/resources
|
3
bin/cac-console
Executable file
3
bin/cac-console
Executable file
@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec _cac_post_api_v1 console sid="$1"
|
15
bin/cac-get-server-by
Executable file
15
bin/cac-get-server-by
Executable file
@ -0,0 +1,15 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
cac-listservers \
|
||||
| jq \
|
||||
--arg k "$1" \
|
||||
--arg v "$2" \
|
||||
'
|
||||
map(select(.[$k]==$v)) |
|
||||
if (. | length) == 1 then
|
||||
.[0]
|
||||
else
|
||||
.
|
||||
end
|
||||
'
|
12
bin/cac-listservers
Executable file
12
bin/cac-listservers
Executable file
@ -0,0 +1,12 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
listservers=$(_cac_get_api_v1 listservers)
|
||||
status=$(echo "$listservers" | jq -r .status)
|
||||
|
||||
if [ "$status" = ok ]; then
|
||||
echo "$listservers" | jq -r .data
|
||||
else
|
||||
echo "$0: bad listservers status: $status" >&2
|
||||
exit 1
|
||||
fi
|
3
bin/cac-listtasks
Executable file
3
bin/cac-listtasks
Executable file
@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec _cac_get_api_v1 listtasks
|
4
bin/cac-listtemplates
Executable file
4
bin/cac-listtemplates
Executable file
@ -0,0 +1,4 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
exec _cac_get_api_v1 listtemplates
|
3
bin/cac-powerop
Executable file
3
bin/cac-powerop
Executable file
@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec _cac_post_api_v1 powerop sid="$1" action="$2"
|
3
bin/cac-rdns
Executable file
3
bin/cac-rdns
Executable file
@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec _cac_post_api_v1 rdns sid="$1" hostname="$2"
|
3
bin/cac-renameserver
Executable file
3
bin/cac-renameserver
Executable file
@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec _cac_post_api_v1 renameserver sid="$1" name="$2"
|
3
bin/cac-runmode
Executable file
3
bin/cac-runmode
Executable file
@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec _cac_post_api_v1 rdns sid="$1" mode="$2"
|
17
bin/cac-ssh
Executable file
17
bin/cac-ssh
Executable file
@ -0,0 +1,17 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
server=$1
|
||||
shift
|
||||
|
||||
address=$(echo $server | jq -r .ip)
|
||||
target=root@$address
|
||||
|
||||
SSHPASS=$(echo $server | jq -r .rootpass)
|
||||
export SSHPASS
|
||||
|
||||
exec sshpass -e ssh \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
"$target" \
|
||||
"$@"
|
28
bin/cacnixos-networking
Executable file
28
bin/cacnixos-networking
Executable file
@ -0,0 +1,28 @@
|
||||
#! /bin/sh
|
||||
# cacnixos-networking : cac-server x hostname -> nixos-module
|
||||
# TODO use label for hostname
|
||||
set -euf
|
||||
|
||||
server=$1
|
||||
hostname=$2
|
||||
|
||||
address=$(echo $server | jq -r .ip)
|
||||
gateway=$(echo $server | jq -r .gateway)
|
||||
nameserver=8.8.8.8
|
||||
netmask=$(echo $server | jq -r .netmask)
|
||||
prefix=$(netmask-to-prefix $netmask)
|
||||
|
||||
printf '{...}:\n'
|
||||
printf '{\n'
|
||||
printf ' networking.hostName = "%s";\n' $hostname
|
||||
printf ' networking.interfaces.enp2s1.ip4 = [\n'
|
||||
printf ' {\n'
|
||||
printf ' address = "%s";\n' $address
|
||||
printf ' prefixLength = %d;\n' $prefix
|
||||
printf ' }\n'
|
||||
printf ' ];\n'
|
||||
printf ' networking.defaultGateway = "%s";\n' $gateway
|
||||
printf ' networking.nameservers = [\n'
|
||||
printf ' "%s"\n' $nameserver
|
||||
printf ' ];\n'
|
||||
printf '}\n'
|
6
bin/filter-secrets
Executable file
6
bin/filter-secrets
Executable file
@ -0,0 +1,6 @@
|
||||
#! /bin/sh
|
||||
# filter_secrets : lines string |> lines secrets-file-candidate
|
||||
set -euf
|
||||
|
||||
# Notice how false positives are possible.
|
||||
sed -n 's:^\(.*/\)\?\(secrets/.*\):'"${PWD//:/\\:}"'/\2:p'
|
10
bin/import-statements
Executable file
10
bin/import-statements
Executable file
@ -0,0 +1,10 @@
|
||||
#! /bin/sh
|
||||
# import-statements : lines (path ":" string) |> lines (path ":" relpath)
|
||||
set -euf
|
||||
sed -n '
|
||||
s@^\([^:]\+:\)\('"$(bre-invert-word import)"'\)*\<import\s\+@\1@
|
||||
t1;d
|
||||
:1; s@^\([^:]\+:\)\(\.*/\S*\)@\1\2\n@
|
||||
t2;d
|
||||
:2; P;D
|
||||
'
|
150
bin/infest-CentOS-7-64bit
Executable file
150
bin/infest-CentOS-7-64bit
Executable file
@ -0,0 +1,150 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
server=$1
|
||||
hostname=$2
|
||||
|
||||
address=$(echo $server | jq -r .ip)
|
||||
RSYNC_RSH='sshpass -e ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
|
||||
SSHPASS=$(echo $server | jq -r .rootpass)
|
||||
export SSHPASS
|
||||
export RSYNC_RSH
|
||||
|
||||
main="modules/$hostname/default.nix"
|
||||
target="root@$address"
|
||||
|
||||
cacnixos-networking "$server" $hostname \
|
||||
> modules/$hostname/networking.nix
|
||||
|
||||
echo '(
|
||||
set -xeuf
|
||||
type bzip2 || yum install -y bzip2
|
||||
type rsync || yum install -y rsync
|
||||
)' \
|
||||
| sshpass -e ssh \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
"root@$address" \
|
||||
/bin/sh
|
||||
|
||||
make-rsync-filter "$main" \
|
||||
| rsync -f '. -' -zvrlptD --delete-excluded ./ "$target":/etc/nixos/
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
echo '(
|
||||
set -xeuf
|
||||
groupadd -g 30000 nixbld || :
|
||||
for i in `seq 1 10`; do
|
||||
useradd -c "foolsgarden Nix build user $i" \
|
||||
-d /var/empty \
|
||||
-s /sbin/nologin \
|
||||
-g 30000 \
|
||||
-G 30000 \
|
||||
-l -u $(expr 30000 + $i) \
|
||||
nixbld$i || :
|
||||
rm -f /var/spool/mail/nixbld$i
|
||||
done
|
||||
|
||||
#curl https://nixos.org/nix/install | sh
|
||||
nix_tar=$nix_basename.tar.bz2
|
||||
if ! echo $nix_sha256 $nix_tar | sha256sum -c; then
|
||||
curl -O -C - $nix_url || :
|
||||
if ! echo $nix_sha256 $nix_tar | sha256sum -c; then
|
||||
curl -O $nix_url || :
|
||||
if ! echo $nix_sha256 $nix_tar | sha256sum -c; then
|
||||
echo $0: cannot download $nix_url >&2
|
||||
exit 5
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! test -d $nix_basename; then
|
||||
tar jxf $nix_basename.tar.bz2
|
||||
fi
|
||||
|
||||
nix_find=$nix_basename.find.txt
|
||||
if ! echo $nix_find_sha1sum $nix_find | sha1sum -c; then
|
||||
find $nix_basename | sort > $nix_find
|
||||
if ! echo $nix_find_sha1sum $nix_find | sha1sum -c; then
|
||||
echo $0: cannot unpack $nix_basename.tar.bz2 >&2
|
||||
# TODO we could retry
|
||||
exit 6
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p bin
|
||||
PATH=$HOME/bin:$PATH
|
||||
export PATH
|
||||
|
||||
# generate fake sudo because
|
||||
# sudo: sorry, you must have a tty to run sudo
|
||||
{
|
||||
echo "#! /bin/sh"
|
||||
echo "exec env \"\$@\""
|
||||
} > bin/sudo
|
||||
chmod +x bin/sudo
|
||||
|
||||
./$nix_basename/install
|
||||
|
||||
. /root/.nix-profile/etc/profile.d/nix.sh
|
||||
|
||||
nixpkgs_expr="import <nixpkgs> { system = builtins.currentSystem; }"
|
||||
nixpkgs_path=$(
|
||||
find /nix/store -mindepth 1 -maxdepth 1 -name *-nixpkgs-* -type d
|
||||
)
|
||||
|
||||
for i in nixos-generate-config nixos-install; do
|
||||
nix-env \
|
||||
--arg config "{ nix.package = ($nixpkgs_expr).nix; }" \
|
||||
--arg pkgs "$nixpkgs_expr" \
|
||||
--arg modulesPath "throw \"no modulesPath\"" \
|
||||
-f $nixpkgs_path/nixpkgs/nixos/modules/installer/tools/tools.nix \
|
||||
-iA config.system.build.$i
|
||||
done
|
||||
|
||||
# TODO following fail when aborted in-between
|
||||
if ! test -d /int; then
|
||||
mkdir -p /int
|
||||
mount --bind /int /mnt
|
||||
fi
|
||||
if ! test -d /mnt/boot; then
|
||||
mkdir -p /mnt/boot
|
||||
mount /dev/sda1 /mnt/boot
|
||||
fi
|
||||
|
||||
mkdir -p /mnt/etc/nixos
|
||||
rsync -zvrlptD --delete-excluded /etc/nixos/ /mnt/etc/nixos/
|
||||
|
||||
mkdir -m 0444 -p /mnt/var/empty
|
||||
|
||||
ln -s $main /mnt/etc/nixos/configuration.nix
|
||||
nixos-install \
|
||||
-I secrets=/etc/nixos/secrets
|
||||
|
||||
find / \
|
||||
1> /root/pre-rsync-find.out \
|
||||
2> /root/pre-rsync-find.err
|
||||
|
||||
rsync -va --force /int/ /
|
||||
|
||||
# find / -type f -mtime +1 -exec rm -v {} \; 2>&1 > rm.log
|
||||
# ^ too aggressive, kills journal which is bad
|
||||
# shutdown -r now
|
||||
# nix-channel --add https://nixos.org/channels/nixos-unstable nixos
|
||||
# nix-channel --remove nixpkgs
|
||||
# nix-channel --update
|
||||
|
||||
)' \
|
||||
| sshpass -e ssh \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
"root@$address" \
|
||||
-T /usr/bin/env \
|
||||
nix_url="$nix_url" \
|
||||
nix_basename="$(basename $nix_url .tar.bz2)" \
|
||||
nix_sha256="$nix_sha256" \
|
||||
nix_find_sha1sum="$nix_find_sha1sum" \
|
||||
main="$main" \
|
||||
/bin/sh
|
21
bin/infest-cac
Executable file
21
bin/infest-cac
Executable file
@ -0,0 +1,21 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
server=$(cac-get-server-by servername "$1")
|
||||
hostname=$2
|
||||
|
||||
serverstatus=$(echo $server | jq -r .status)
|
||||
case $serverstatus in
|
||||
'Powered On') : ;;
|
||||
*)
|
||||
echo $0: bad server status: $serverstatus >&2
|
||||
exit 2
|
||||
esac
|
||||
|
||||
template=$(echo $server | jq -r .template)
|
||||
case $template in
|
||||
'CentOS-7-64bit') infest-"$template" "$server" "$hostname";;
|
||||
*)
|
||||
echo $0: bad template: $template >&2
|
||||
exit 3
|
||||
esac
|
18
bin/json-assert-type
Executable file
18
bin/json-assert-type
Executable file
@ -0,0 +1,18 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
formal_type=$1
|
||||
|
||||
actual_value=$2
|
||||
actual_type=$(echo $actual_value | jq -r type)
|
||||
|
||||
if [ "$actual_type" != "$formal_type" ]; then
|
||||
backtrace
|
||||
printf 'error: expected %s, got %s\n' \
|
||||
"$formal_type" \
|
||||
"$actual_type" \
|
||||
>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$actual_value"
|
7
bin/list-hosts
Executable file
7
bin/list-hosts
Executable file
@ -0,0 +1,7 @@
|
||||
#! /bin/sh
|
||||
# list-hosts : lines tinc-host-file
|
||||
set -euf
|
||||
|
||||
# Precondition: $PWD/hosts is the correct repository :)
|
||||
git -C hosts ls-tree --name-only HEAD \
|
||||
| awk '{print ENVIRON["PWD"]"/hosts/"$$0}'
|
20
bin/list-module-imports
Executable file
20
bin/list-module-imports
Executable file
@ -0,0 +1,20 @@
|
||||
#! /bin/sh
|
||||
# list-module-imports : nix-file -> lines nix-file
|
||||
set -euf
|
||||
|
||||
if echo "$1" | grep -q ^/; then
|
||||
:
|
||||
else
|
||||
set -- "./$1"
|
||||
fi
|
||||
|
||||
imports=$(nix-instantiate \
|
||||
-I secrets=secrets \
|
||||
--strict \
|
||||
--json \
|
||||
--eval \
|
||||
-E \
|
||||
"with builtins; with import ./lib/modules.nix; map toString (list-imports $1)")
|
||||
|
||||
echo "$imports" \
|
||||
| jq -r .[]
|
12
bin/ls-bre
Executable file
12
bin/ls-bre
Executable file
@ -0,0 +1,12 @@
|
||||
#! /bin/sh
|
||||
# ls-bre : directory -> BRE
|
||||
# Create a BRE from the files in a directory.
|
||||
set -euf
|
||||
|
||||
ls "$1" \
|
||||
| tr \\n / \
|
||||
| sed '
|
||||
s:[\.\[\\\*\^\$]:\\&:g
|
||||
s:/$::
|
||||
s:/:\\|:g
|
||||
'
|
10
bin/make-parent-dirs
Executable file
10
bin/make-parent-dirs
Executable file
@ -0,0 +1,10 @@
|
||||
#! /bin/sh
|
||||
# make-parent-dirs : lines path |> lines directory
|
||||
# List all parent directories of a path.
|
||||
set -euf
|
||||
|
||||
set -- "$(sed -n 's|/[^/]*$||p' | grep . | sort | uniq)"
|
||||
if echo "$1" | grep -q .; then
|
||||
echo "$1"
|
||||
echo "$1" | make-parent-dirs
|
||||
fi
|
6
bin/make-relative-to
Executable file
6
bin/make-relative-to
Executable file
@ -0,0 +1,6 @@
|
||||
#! /bin/sh
|
||||
# make-relative-to : lines path |> directory -> lines path
|
||||
# Non-matching paths won't get altered.
|
||||
set -euf
|
||||
|
||||
sed "s:^$(echo "$1/" | bre-escape | sed 's/:/\\:/g')::"
|
33
bin/make-rsync-filter
Executable file
33
bin/make-rsync-filter
Executable file
@ -0,0 +1,33 @@
|
||||
#! /bin/sh
|
||||
# make-rsync-filter : nixos-config -> rsync-filter
|
||||
set -euf
|
||||
|
||||
main=$1
|
||||
|
||||
hosts=$(list-hosts)
|
||||
module_imports=$(list-module-imports "$main")
|
||||
other_imports=$(
|
||||
echo "$module_imports" \
|
||||
| xargs grep -H . \
|
||||
| import-statements \
|
||||
| slash-path-relpath \
|
||||
| undot-paths \
|
||||
| sort \
|
||||
| uniq \
|
||||
| sed '/\.nix$/!s:$:/default.nix:' \
|
||||
)
|
||||
secrets=$(echo "$module_imports" | xargs cat | quoted-strings | filter-secrets)
|
||||
|
||||
# TODO collect all other paths from *_imports
|
||||
|
||||
abs_deps=$(
|
||||
echo "$hosts"
|
||||
echo "$module_imports"
|
||||
echo "$other_imports"
|
||||
echo "$secrets"
|
||||
)
|
||||
|
||||
rel_deps=$(echo "$abs_deps" | make-relative-to "$PWD")
|
||||
filter=$(echo "$rel_deps" | make-rsync-whitelist)
|
||||
|
||||
echo "$filter"
|
15
bin/make-rsync-whitelist
Executable file
15
bin/make-rsync-whitelist
Executable file
@ -0,0 +1,15 @@
|
||||
#! /bin/sh
|
||||
# make-rsync-whitelist : lines relpath |> liens rsync-filter
|
||||
set -euf
|
||||
|
||||
set -- "$(cat)"
|
||||
|
||||
# include all files in stdin and their directories
|
||||
{
|
||||
echo "$1"
|
||||
echo "$1" | make-parent-dirs | sort | uniq
|
||||
} \
|
||||
| sed 's|^|+ /|'
|
||||
|
||||
# exclude everything else
|
||||
echo '- *'
|
12
bin/netmask-to-prefix
Executable file
12
bin/netmask-to-prefix
Executable file
@ -0,0 +1,12 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
|
||||
netmask=$1
|
||||
|
||||
binaryNetmask=$(echo $1 | sed 's/^/obase=2;/;s/\./;/g' | bc | tr -d \\n)
|
||||
binaryPrefix=$(echo $binaryNetmask | sed -n 's/^\(1*\)0*$/\1/p')
|
||||
if ! echo $binaryPrefix | grep -q .; then
|
||||
echo $0: bad netmask: $netmask >&2
|
||||
exit 4
|
||||
fi
|
||||
printf %s $binaryPrefix | tr -d 0 | wc -c
|
13
bin/nixpkgs-rev
Executable file
13
bin/nixpkgs-rev
Executable file
@ -0,0 +1,13 @@
|
||||
#! /bin/sh
|
||||
# nixpkgs-rev : nixos-config -> git_rev
|
||||
set -euf
|
||||
nix-instantiate \
|
||||
-I nixos-config="$1" \
|
||||
--eval \
|
||||
--json \
|
||||
-E \
|
||||
'
|
||||
(import <nixos-config> {config={}; pkgs={};}).nixpkgs.rev
|
||||
' \
|
||||
2> /dev/null \
|
||||
| jq -r . 2> /dev/null
|
13
bin/nixpkgs-url
Executable file
13
bin/nixpkgs-url
Executable file
@ -0,0 +1,13 @@
|
||||
#! /bin/sh
|
||||
# nixpkgs-url : nixos-config -> git_url
|
||||
set -euf
|
||||
nix-instantiate \
|
||||
-I nixos-config="$1" \
|
||||
--eval \
|
||||
--json \
|
||||
-E \
|
||||
'
|
||||
(import <nixos-config> {config={}; pkgs={};}).nixpkgs.url
|
||||
' \
|
||||
2> /dev/null \
|
||||
| jq -r . 2> /dev/null
|
15
bin/quoted-strings
Executable file
15
bin/quoted-strings
Executable file
@ -0,0 +1,15 @@
|
||||
#! /bin/sh
|
||||
# quoted_strings : lines string |> lines string
|
||||
# Extract all (double-) quoted strings from stdin.
|
||||
#
|
||||
# 0. find begin of string or skip line
|
||||
# 1. find end of string or skip line
|
||||
# 2. print string and continue after string
|
||||
set -euf
|
||||
|
||||
sed '
|
||||
s:[^"]*":: ;t1;d
|
||||
:1; s:\(\([^"]\|\\"\)*\)":\1\n: ;t2;d
|
||||
:2; P;D
|
||||
' \
|
||||
| sed 's:\\":":g'
|
8
bin/slash-path-relpath
Executable file
8
bin/slash-path-relpath
Executable file
@ -0,0 +1,8 @@
|
||||
#! /bin/sh
|
||||
# slash_path_relpath : lines (path ":" relpath) |> lines path
|
||||
#
|
||||
# Example: "/foo/bar: baz" => "/foo/baz"
|
||||
#
|
||||
set -euf
|
||||
|
||||
sed -n 's@/[^/]\+:@/@p'
|
26
bin/ssh-deploy
Executable file
26
bin/ssh-deploy
Executable file
@ -0,0 +1,26 @@
|
||||
#! /bin/sh
|
||||
# ssh-deploy : nixos-config x [user@]hostname -> ()
|
||||
set -xeuf
|
||||
|
||||
main=$1
|
||||
target=$2
|
||||
nixpkgs_dir=/var/nixpkgs # TODO make configurable
|
||||
|
||||
git_url=$(nixpkgs-url $main)
|
||||
git_rev=$(nixpkgs-rev $main)
|
||||
|
||||
if [ "$git_url" = '' ] || [ "$git_rev" = '' ]; then
|
||||
echo "specify nixpkgs.url and nixpkgs.rev in $main !"
|
||||
exit 23
|
||||
fi
|
||||
|
||||
filter=$(make-rsync-filter "$main")
|
||||
|
||||
echo "$filter" \
|
||||
| rsync -f '. -' -zvrlptD --delete-excluded ./ "$target":/etc/nixos/
|
||||
|
||||
ssh-fetch-git "$target" "$nixpkgs_dir" "$git_url" "$git_rev"
|
||||
ssh "$target" nixos-rebuild switch \
|
||||
-I nixos-config=/etc/nixos/"$main" \
|
||||
-I nixpkgs="$nixpkgs_dir" \
|
||||
-I secrets=/etc/nixos/secrets \
|
35
bin/ssh-fetch-git
Executable file
35
bin/ssh-fetch-git
Executable file
@ -0,0 +1,35 @@
|
||||
#! /bin/sh
|
||||
# ssh-fetch-git : [user@]hostname x remote_dir x git_url x git_rev -> ()
|
||||
set -euf
|
||||
|
||||
target=$1
|
||||
remote_dir=$2
|
||||
git_url=$3
|
||||
git_rev=$4
|
||||
|
||||
echo '
|
||||
set -euf
|
||||
|
||||
if [ ! -d "$remote_dir" ]; then
|
||||
mkdir -p "$remote_dir"
|
||||
fi
|
||||
|
||||
cd "$remote_dir"
|
||||
|
||||
git init -q
|
||||
|
||||
if ! current_url=$(git config remote.src.url); then
|
||||
git remote add src "$git_url"
|
||||
elif [ $current_url != $git_url ]; then
|
||||
git remote set-url src "$git_url"
|
||||
fi
|
||||
|
||||
git fetch src
|
||||
|
||||
git checkout "$git_rev"
|
||||
' \
|
||||
| ssh "$target" env \
|
||||
remote_dir="$remote_dir" \
|
||||
git_rev="$git_rev" \
|
||||
git_url="$git_url" \
|
||||
/bin/sh
|
14
bin/undot-paths
Executable file
14
bin/undot-paths
Executable file
@ -0,0 +1,14 @@
|
||||
#! /bin/sh
|
||||
# undot_paths : lines path |> lines path
|
||||
# Remove all dots (. and ..) from input paths.
|
||||
set -euf
|
||||
|
||||
sed '
|
||||
:0
|
||||
s://\+:/:g
|
||||
s:/\.\(/\|$\):\1:g
|
||||
s:/[^/]\+/\.\.\(/\|$\):\1:g
|
||||
s:^/\(\.\./\)\+:/:
|
||||
t0
|
||||
s:^$:/:
|
||||
'
|
35
bin/urlencode
Executable file
35
bin/urlencode
Executable file
@ -0,0 +1,35 @@
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
exec sed '
|
||||
s/%/%25/g
|
||||
s/ /%20/g
|
||||
s/!/%21/g
|
||||
s/"/%22/g
|
||||
s/#/%23/g
|
||||
s/\$/%24/g
|
||||
s/\&/%26/g
|
||||
s/'\''/%27/g
|
||||
s/(/%28/g
|
||||
s/)/%29/g
|
||||
s/\*/%2a/g
|
||||
s/+/%2b/g
|
||||
s/,/%2c/g
|
||||
s/-/%2d/g
|
||||
s/\./%2e/g
|
||||
s/\//%2f/g
|
||||
s/:/%3a/g
|
||||
s/;/%3b/g
|
||||
s//%3e/g
|
||||
s/?/%3f/g
|
||||
s/@/%40/g
|
||||
s/\[/%5b/g
|
||||
s/\\/%5c/g
|
||||
s/\]/%5d/g
|
||||
s/\^/%5e/g
|
||||
s/_/%5f/g
|
||||
s/`/%60/g
|
||||
s/{/%7b/g
|
||||
s/|/%7c/g
|
||||
s/}/%7d/g
|
||||
s/~/%7e/g
|
||||
'
|
5
deploy
5
deploy
@ -4,7 +4,8 @@
|
||||
#
|
||||
set -euf
|
||||
|
||||
. ./lib/prelude.sh
|
||||
PATH="$PWD/bin${PATH+:$PATH}"
|
||||
export PATH
|
||||
|
||||
user=root
|
||||
host=$1
|
||||
@ -12,4 +13,4 @@ host=$1
|
||||
config=./modules/$host/default.nix
|
||||
target=${2-$user@$host}
|
||||
|
||||
verbose deploy "$config" "$target"
|
||||
exec ssh-deploy "$config" "$target"
|
||||
|
188
infest
188
infest
@ -1,187 +1,15 @@
|
||||
#! /bin/sh
|
||||
set -xeuf
|
||||
#
|
||||
# usage: ./infest cac-servername hostname
|
||||
#
|
||||
set -euf
|
||||
|
||||
. ./lib/prelude.sh
|
||||
. ./lib/cac.sh
|
||||
. ./lib/cacnixos.sh
|
||||
PATH="$PWD/bin${PATH+:$PATH}"
|
||||
export PATH
|
||||
|
||||
nix_url=https://nixos.org/releases/nix/nix-1.8/nix-1.8-x86_64-linux.tar.bz2
|
||||
nix_sha256=52fab207b4ce4d098a12d85357d0353e972c492bab0aa9e08e1600363e76fefb
|
||||
nix_find_sha1sum=86f8775bd4f0841edd4c816df861cebf509d58c3
|
||||
export nix_url nix_sha256 nix_find_sha1sum
|
||||
|
||||
# This is somewhat required because cloudatcost requires whitelisting
|
||||
# of hosts. If you whitelist your localhost, then leave this empty.
|
||||
# cac_via=
|
||||
#
|
||||
# cac_key=
|
||||
# cac_login=
|
||||
# cac_servername=
|
||||
|
||||
# hostname=
|
||||
|
||||
main() {
|
||||
server=$(cac_getserver_by_servername "$cac_servername")
|
||||
|
||||
serverstatus=$(echo $server | jq -r .status)
|
||||
case $serverstatus in
|
||||
'Powered On') : ;;
|
||||
*)
|
||||
echo $0: bad server status: $serverstatus >&2
|
||||
exit 2
|
||||
esac
|
||||
|
||||
template=$(echo $server | jq -r .template)
|
||||
case $template in
|
||||
'CentOS-7-64bit') infest_centos7_64bit "$server";;
|
||||
*)
|
||||
echo $0: bad template: $template >&2
|
||||
exit 3
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
infest_centos7_64bit() {
|
||||
server=$1
|
||||
address=$(echo $server | jq -r .ip)
|
||||
RSYNC_RSH='sshpass -e ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
|
||||
SSHPASS=$(echo $server | jq -r .rootpass)
|
||||
export SSHPASS
|
||||
export RSYNC_RSH
|
||||
|
||||
main="modules/$hostname/default.nix"
|
||||
target="root@$address"
|
||||
|
||||
cacnixos_networking "$server" $hostname \
|
||||
> modules/$hostname/networking.nix
|
||||
|
||||
echo '(
|
||||
set -xeuf
|
||||
type bzip2 || yum install -y bzip2
|
||||
type rsync || yum install -y rsync
|
||||
)' \
|
||||
| sshpass -e ssh \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
"root@$address" \
|
||||
/bin/sh
|
||||
|
||||
rsync_filter "$main" \
|
||||
| rsync -f '. -' -zvrlptD --delete-excluded ./ "$target":/etc/nixos/
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
echo '(
|
||||
set -xeuf
|
||||
groupadd -g 30000 nixbld || :
|
||||
for i in `seq 1 10`; do
|
||||
useradd -c "foolsgarden Nix build user $i" \
|
||||
-d /var/empty \
|
||||
-s /sbin/nologin \
|
||||
-g 30000 \
|
||||
-G 30000 \
|
||||
-l -u $(expr 30000 + $i) \
|
||||
nixbld$i || :
|
||||
rm -f /var/spool/mail/nixbld$i
|
||||
done
|
||||
|
||||
#curl https://nixos.org/nix/install | sh
|
||||
nix_tar=$nix_basename.tar.bz2
|
||||
if ! echo $nix_sha256 $nix_tar | sha256sum -c; then
|
||||
curl -O -C - $nix_url || :
|
||||
if ! echo $nix_sha256 $nix_tar | sha256sum -c; then
|
||||
curl -O $nix_url || :
|
||||
if ! echo $nix_sha256 $nix_tar | sha256sum -c; then
|
||||
echo $0: cannot download $nix_url >&2
|
||||
exit 5
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! test -d $nix_basename; then
|
||||
tar jxf $nix_basename.tar.bz2
|
||||
fi
|
||||
|
||||
nix_find=$nix_basename.find.txt
|
||||
if ! echo $nix_find_sha1sum $nix_find | sha1sum -c; then
|
||||
find $nix_basename | sort > $nix_find
|
||||
if ! echo $nix_find_sha1sum $nix_find | sha1sum -c; then
|
||||
echo $0: cannot unpack $nix_basename.tar.bz2 >&2
|
||||
# TODO we could retry
|
||||
exit 6
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p bin
|
||||
PATH=$HOME/bin:$PATH
|
||||
export PATH
|
||||
|
||||
# generate fake sudo because
|
||||
# sudo: sorry, you must have a tty to run sudo
|
||||
{
|
||||
echo "#! /bin/sh"
|
||||
echo "exec env \"\$@\""
|
||||
} > bin/sudo
|
||||
chmod +x bin/sudo
|
||||
|
||||
./$nix_basename/install
|
||||
|
||||
. /root/.nix-profile/etc/profile.d/nix.sh
|
||||
|
||||
nixpkgs_expr="import <nixpkgs> { system = builtins.currentSystem; }"
|
||||
nixpkgs_path=$(
|
||||
find /nix/store -mindepth 1 -maxdepth 1 -name *-nixpkgs-* -type d
|
||||
)
|
||||
|
||||
for i in nixos-generate-config nixos-install; do
|
||||
nix-env \
|
||||
--arg config "{ nix.package = ($nixpkgs_expr).nix; }" \
|
||||
--arg pkgs "$nixpkgs_expr" \
|
||||
--arg modulesPath "throw \"no modulesPath\"" \
|
||||
-f $nixpkgs_path/nixpkgs/nixos/modules/installer/tools/tools.nix \
|
||||
-iA config.system.build.$i
|
||||
done
|
||||
|
||||
# TODO following fail when aborted in-between
|
||||
if ! test -d /int; then
|
||||
mkdir -p /int
|
||||
mount --bind /int /mnt
|
||||
fi
|
||||
if ! test -d /mnt/boot; then
|
||||
mkdir -p /mnt/boot
|
||||
mount /dev/sda1 /mnt/boot
|
||||
fi
|
||||
|
||||
mkdir -p /mnt/etc/nixos
|
||||
rsync -zvrlptD --delete-excluded /etc/nixos/ /mnt/etc/nixos/
|
||||
|
||||
mkdir -m 0444 -p /mnt/var/empty
|
||||
|
||||
ln -s $main /mnt/etc/nixos/configuration.nix
|
||||
nixos-install \
|
||||
-I secrets=/etc/nixos/secrets
|
||||
|
||||
rsync -va --force /int/ /
|
||||
|
||||
# find / -type f -mtime +1 -exec rm -v {} \; 2>&1 > rm.log
|
||||
# ^ too aggressive, kills journal which is bad
|
||||
# shutdown -r now
|
||||
# nix-channel --add https://nixos.org/channels/nixos-unstable nixos
|
||||
# nix-channel --remove nixpkgs
|
||||
# nix-channel --update
|
||||
|
||||
)' \
|
||||
| sshpass -e ssh \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
"root@$address" \
|
||||
-T /usr/bin/env \
|
||||
nix_url="$nix_url" \
|
||||
nix_basename="$(basename $nix_url .tar.bz2)" \
|
||||
nix_sha256="$nix_sha256" \
|
||||
nix_find_sha1sum="$nix_find_sha1sum" \
|
||||
main="$main" \
|
||||
/bin/sh
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exec infest-cac "$@"
|
||||
|
105
lib/cac.sh
105
lib/cac.sh
@ -1,105 +0,0 @@
|
||||
. ./lib/url.sh
|
||||
|
||||
cac_ssh() {(
|
||||
server=$1
|
||||
shift
|
||||
|
||||
address=$(echo $server | jq -r .ip)
|
||||
target=root@$address
|
||||
|
||||
SSHPASS=$(echo $server | jq -r .rootpass)
|
||||
export SSHPASS
|
||||
|
||||
exec sshpass -e ssh \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
"$target" \
|
||||
"$@"
|
||||
)}
|
||||
|
||||
cac_getserver_by_servername() {(
|
||||
serverlist=$(cac_listservers)
|
||||
echo $serverlist \
|
||||
| jq \
|
||||
--arg name "$1" \
|
||||
'.[]|select(.servername==$name)'
|
||||
)}
|
||||
|
||||
|
||||
cac_listservers() {(
|
||||
listservers=$(_cac_get_api_v1 listservers)
|
||||
status=$(echo "$listservers" | jq -r .status)
|
||||
if [ "$status" = ok ]; then
|
||||
echo "$listservers" | jq -r .data
|
||||
else
|
||||
echo "$0: bad listservers status: $status" >&2
|
||||
exit 1
|
||||
fi
|
||||
)}
|
||||
|
||||
cac_listtasks() {
|
||||
_cac_get_api_v1 listtasks
|
||||
}
|
||||
|
||||
cac_listtemplates() {
|
||||
_cac_get_api_v1 listtemplates
|
||||
}
|
||||
|
||||
cac_console() {
|
||||
_cac_post_api_v1 console sid="$1"
|
||||
}
|
||||
|
||||
cac_powerop() {
|
||||
_cac_post_api_v1 powerop sid="$1" action="$2"
|
||||
}
|
||||
|
||||
cac_renameserver() {
|
||||
_cac_post_api_v1 renameserver sid="$1" name="$2"
|
||||
}
|
||||
|
||||
cac_rnds() {
|
||||
_cac_post_api_v1 rdns sid="$1" hostname="$2"
|
||||
}
|
||||
|
||||
cac_runmode() {
|
||||
_cac_post_api_v1 rdns sid="$1" mode="$2"
|
||||
}
|
||||
|
||||
# default os=26 is CentOS-7-64bit
|
||||
cac_cloudpro_build() {
|
||||
_cac_post_api_v1 cloudpro/build cpu="$1" ram="$2" storage="$3" os="${4-26}"
|
||||
}
|
||||
|
||||
cac_cloudpro_delete() {
|
||||
_cac_post_api_v1 cloudpro/delete sid="$1"
|
||||
}
|
||||
|
||||
cac_cloudpro_resources() {
|
||||
_cac_get_api_v1 cloudpro/resources
|
||||
}
|
||||
|
||||
_cac_get_api_v1() {
|
||||
_cac_curl_api_v1 -G "$@"
|
||||
}
|
||||
|
||||
_cac_post_api_v1() {
|
||||
_cac_curl_api_v1 -XPOST "$@"
|
||||
}
|
||||
|
||||
_cac_curl_api_v1() {
|
||||
_cac_exec curl -fsS "$1" "https://panel.cloudatcost.com/api/v1/$2.php" $(
|
||||
shift 2
|
||||
set -- "$@" login="$cac_login" key="$cac_key"
|
||||
for arg; do
|
||||
echo -d $(printf '%s' "$arg" | url_encode)
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
_cac_exec() {
|
||||
if test -z "${cac_via-}"; then
|
||||
(exec "$@")
|
||||
else
|
||||
ssh -q "$cac_via" -t "$@"
|
||||
fi
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
. ./lib/net.sh
|
||||
|
||||
# cacnixos_networking : cac-server x hostname -> nixos-module
|
||||
cacnixos_networking() {(
|
||||
server=$1
|
||||
hostname=$2
|
||||
|
||||
address=$(echo $server | jq -r .ip)
|
||||
gateway=$(echo $server | jq -r .gateway)
|
||||
nameserver=8.8.8.8
|
||||
netmask=$(echo $server | jq -r .netmask)
|
||||
prefix=$(net_netmask_to_prefix $netmask)
|
||||
|
||||
printf '{...}:\n'
|
||||
printf '{\n'
|
||||
printf ' networking.hostName = "%s";\n' $hostname
|
||||
printf ' networking.interfaces.enp2s1.ip4 = [\n'
|
||||
printf ' {\n'
|
||||
printf ' address = "%s";\n' $address
|
||||
printf ' prefixLength = %d;\n' $prefix
|
||||
printf ' }\n'
|
||||
printf ' ];\n'
|
||||
printf ' networking.defaultGateway = "%s";\n' $gateway
|
||||
printf ' networking.nameservers = [\n'
|
||||
printf ' "%s"\n' $nameserver
|
||||
printf ' ];\n'
|
||||
printf '}\n'
|
||||
)}
|
@ -1,9 +0,0 @@
|
||||
net_netmask_to_prefix() {(
|
||||
binaryNetmask=$(echo $1 | sed 's/^/obase=2;/;s/\./;/g' | bc | tr -d \\n)
|
||||
binaryPrefix=$(echo $binaryNetmask | sed -n 's/^\(1*\)0*$/\1/p')
|
||||
if ! echo $binaryPrefix | grep -q .; then
|
||||
echo $0: bad netmask: $netmask >&2
|
||||
exit 4
|
||||
fi
|
||||
printf %s $binaryPrefix | tr -d 0 | wc -c
|
||||
)}
|
261
lib/prelude.sh
261
lib/prelude.sh
@ -1,261 +0,0 @@
|
||||
# clone_or_update : [user@]hostname x local_dir x git_url x git_rev -> ()
|
||||
clone_or_update() {(
|
||||
target=$1
|
||||
nixpkgs_dir=$2
|
||||
git_url=$3
|
||||
git_rev=$4
|
||||
|
||||
echo '
|
||||
set -euf
|
||||
|
||||
if [ ! -d "$nixpkgs_dir" ]; then
|
||||
mkdir -p "$nixpkgs_dir"
|
||||
fi
|
||||
|
||||
cd "$nixpkgs_dir"
|
||||
|
||||
git init -q
|
||||
|
||||
if ! current_url=$(git config remote.src.url); then
|
||||
git remote add src "$git_url"
|
||||
elif [ $current_url != $git_url ]; then
|
||||
git remote set-url src "$git_url"
|
||||
fi
|
||||
|
||||
git fetch src
|
||||
|
||||
git checkout "$git_rev"
|
||||
' \
|
||||
| ssh "$target" env \
|
||||
nixpkgs_dir="$nixpkgs_dir" \
|
||||
git_rev="$git_rev" \
|
||||
git_url="$git_url" \
|
||||
/bin/sh
|
||||
)}
|
||||
|
||||
# deploy : nixos-config x [user@]hostname -> ()
|
||||
deploy() {(
|
||||
main=$1
|
||||
target=$2
|
||||
nixpkgs_dir=/var/nixpkgs # TODO make configurable
|
||||
|
||||
git_url=$(nixpkgs_url $main)
|
||||
git_rev=$(nixpkgs_rev $main)
|
||||
|
||||
if [ "$git_url" = '' ] || [ "$git_rev" = '' ]; then
|
||||
echo "specify nixpkgs.url and nixpkgs.rev in $main !"
|
||||
exit 23
|
||||
fi
|
||||
|
||||
filter=$(rsync_filter "$main")
|
||||
|
||||
echo "$filter" \
|
||||
| rsync -f '. -' -zvrlptD --delete-excluded ./ "$target":/etc/nixos/
|
||||
|
||||
clone_or_update "$target" "$nixpkgs_dir" "$git_url" "$git_rev"
|
||||
ssh "$target" nixos-rebuild switch \
|
||||
-I nixos-config=/etc/nixos/"$main" \
|
||||
-I nixpkgs="$nixpkgs_dir" \
|
||||
-I secrets=/etc/nixos/secrets \
|
||||
)}
|
||||
|
||||
# rsync_filter : nixos-config -> rsync-filter
|
||||
rsync_filter() {(
|
||||
main=$1
|
||||
|
||||
hosts=$(list_hosts)
|
||||
module_imports=$(set -euf; list_module_imports "$main")
|
||||
other_imports=$(
|
||||
echo "$module_imports" \
|
||||
| xargs grep -H . \
|
||||
| import_statements \
|
||||
| slash_path_relpath \
|
||||
| undot_paths \
|
||||
| sort \
|
||||
| uniq \
|
||||
| sed '/\.nix$/!s:$:/default.nix:' \
|
||||
)
|
||||
secrets=$(echo "$module_imports" | xargs cat | quoted_strings | filter_secrets)
|
||||
|
||||
# TODO collect all other paths from *_imports
|
||||
|
||||
abs_deps=$(
|
||||
echo "$hosts"
|
||||
echo "$module_imports"
|
||||
echo "$other_imports"
|
||||
echo "$secrets"
|
||||
)
|
||||
|
||||
rel_deps=$(echo "$abs_deps" | make_relative_to "$PWD")
|
||||
filter=$(echo "$rel_deps" | make_rsync_whitelist)
|
||||
|
||||
echo "$filter"
|
||||
)}
|
||||
|
||||
# list_module_imports : nix-file -> lines nix-file
|
||||
list_module_imports() {
|
||||
if echo "$1" | grep -q ^/; then
|
||||
:
|
||||
else
|
||||
set -- "./$1"
|
||||
fi
|
||||
imports=$(nix-instantiate \
|
||||
-I secrets=secrets \
|
||||
--strict \
|
||||
--json \
|
||||
--eval \
|
||||
-E \
|
||||
"with builtins; with import ./lib/modules.nix; map toString (list-imports $1)")
|
||||
echo "$imports" \
|
||||
| jq -r .[]
|
||||
}
|
||||
|
||||
# list_hosts : lines tinc-host-file
|
||||
# Precondition: $PWD/hosts is the correct repository :)
|
||||
list_hosts() {
|
||||
git -C hosts ls-tree --name-only HEAD \
|
||||
| awk '{print ENVIRON["PWD"]"/hosts/"$$0}'
|
||||
}
|
||||
|
||||
# filter_secrets : lines string |> lines secrets-file-candidate
|
||||
# Notice how false positives are possible.
|
||||
filter_secrets() {
|
||||
sed -n 's:^\(.*/\)\?\(secrets/.*\):'"${PWD//:/\\:}"'/\2:p'
|
||||
}
|
||||
|
||||
# import_statements : lines (path ":" string) |> lines (path ":" relpath)
|
||||
import_statements() {
|
||||
sed -n '
|
||||
s@^\([^:]\+:\)\('"$(bre_invert_word import)"'\)*\<import\s\+@\1@
|
||||
t1;d
|
||||
:1; s@^\([^:]\+:\)\(\.*/\S*\)@\1\2\n@
|
||||
t2;d
|
||||
:2; P;D
|
||||
'
|
||||
}
|
||||
|
||||
# slash_path_relpath : lines (path ":" relpath) |> lines path
|
||||
#
|
||||
# Example: "/foo/bar: baz" => "/foo/baz"
|
||||
#
|
||||
slash_path_relpath() {
|
||||
sed -n 's@/[^/]\+:@/@p'
|
||||
}
|
||||
|
||||
# undot_paths : lines path |> lines path
|
||||
# Remove all dots (. and ..) from input paths.
|
||||
undot_paths() {
|
||||
sed '
|
||||
:0
|
||||
s://\+:/:g
|
||||
s:/\.\(/\|$\):\1:g
|
||||
s:/[^/]\+/\.\.\(/\|$\):\1:g
|
||||
s:^/\(\.\./\)\+:/:
|
||||
t0
|
||||
s:^$:/:
|
||||
'
|
||||
}
|
||||
|
||||
# quoted_strings : lines string |> lines string
|
||||
# Extract all (double-) quoted strings from stdin.
|
||||
#
|
||||
# 0. find begin of string or skip line
|
||||
# 1. find end of string or skip line
|
||||
# 2. print string and continue after string
|
||||
quoted_strings() {
|
||||
sed '
|
||||
s:[^"]*":: ;t1;d
|
||||
:1; s:\(\([^"]\|\\"\)*\)":\1\n: ;t2;d
|
||||
:2; P;D
|
||||
' \
|
||||
| sed 's:\\":":g'
|
||||
}
|
||||
|
||||
# bre_escape : lines string |> lines bre-escaped-string
|
||||
bre_escape() {
|
||||
sed 's:[\.\[\\\*\^\$]:\\&:g'
|
||||
}
|
||||
|
||||
# bre_invert_word : string -> BRE
|
||||
# TODO escape chars in the resulting BRE.
|
||||
bre_invert_word() {
|
||||
awk -v input="$1" '
|
||||
BEGIN {
|
||||
split(input,s,"")
|
||||
for (i in s) {
|
||||
c=s[i]
|
||||
printf "\\|%s[^%s]", y, c
|
||||
y = y c
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
# ls_bre : directory -> BRE
|
||||
# Create a BRE from the files in a directory.
|
||||
ls_bre() {
|
||||
ls "$1" \
|
||||
| tr \\n / \
|
||||
| sed '
|
||||
s:[\.\[\\\*\^\$]:\\&:g
|
||||
s:/$::
|
||||
s:/:\\|:g
|
||||
'
|
||||
}
|
||||
|
||||
# make_relative_to : lines path |> directory -> lines path
|
||||
# Non-matching paths won't get altered.
|
||||
make_relative_to() {
|
||||
sed "s:^$(echo "$1/" | bre_escape | sed 's/:/\\:/g')::"
|
||||
}
|
||||
|
||||
# make_rsync_whitelist : lines relpath |> liens rsync-filter
|
||||
make_rsync_whitelist() {
|
||||
set -- "$(cat)"
|
||||
|
||||
# include all files in stdin and their directories
|
||||
{
|
||||
echo "$1"
|
||||
echo "$1" | make_parent_dirs | sort | uniq
|
||||
} \
|
||||
| sed 's|^|+ /|'
|
||||
|
||||
# exclude everything else
|
||||
echo '- *'
|
||||
}
|
||||
|
||||
# make_parent_dirs : lines path |> lines directory
|
||||
# List all parent directories of a path.
|
||||
make_parent_dirs() {
|
||||
set -- "$(sed -n 's|/[^/]*$||p' | grep . | sort | uniq)"
|
||||
if echo "$1" | grep -q .; then
|
||||
echo "$1"
|
||||
echo "$1" | make_parent_dirs
|
||||
fi
|
||||
}
|
||||
|
||||
# nixpkgs_url : nixos-config -> git_url
|
||||
nixpkgs_url() {
|
||||
nix-instantiate \
|
||||
-I nixos-config="$1" \
|
||||
--eval \
|
||||
--json \
|
||||
-E '(import <nixos-config> {config={}; pkgs={};}).nixpkgs.url' 2> /dev/null \
|
||||
| jq -r .
|
||||
}
|
||||
|
||||
# nixpkgs_rev : nixos-config -> git_rev
|
||||
nixpkgs_rev() {
|
||||
nix-instantiate \
|
||||
-I nixos-config="$1" \
|
||||
--eval \
|
||||
--json \
|
||||
-E '(import <nixos-config> {config={}; pkgs={};}).nixpkgs.rev' 2> /dev/null \
|
||||
| jq -r . 2> /dev/null
|
||||
}
|
||||
|
||||
# verbose COMMAND [ARGS...]
|
||||
verbose() {
|
||||
echo "$@" >&2
|
||||
"$@"
|
||||
}
|
35
lib/url.sh
35
lib/url.sh
@ -1,35 +0,0 @@
|
||||
url_encode() {
|
||||
sed '
|
||||
s/%/%25/g
|
||||
s/ /%20/g
|
||||
s/!/%21/g
|
||||
s/"/%22/g
|
||||
s/#/%23/g
|
||||
s/\$/%24/g
|
||||
s/\&/%26/g
|
||||
s/'\''/%27/g
|
||||
s/(/%28/g
|
||||
s/)/%29/g
|
||||
s/\*/%2a/g
|
||||
s/+/%2b/g
|
||||
s/,/%2c/g
|
||||
s/-/%2d/g
|
||||
s/\./%2e/g
|
||||
s/\//%2f/g
|
||||
s/:/%3a/g
|
||||
s/;/%3b/g
|
||||
s//%3e/g
|
||||
s/?/%3f/g
|
||||
s/@/%40/g
|
||||
s/\[/%5b/g
|
||||
s/\\/%5c/g
|
||||
s/\]/%5d/g
|
||||
s/\^/%5e/g
|
||||
s/_/%5f/g
|
||||
s/`/%60/g
|
||||
s/{/%7b/g
|
||||
s/|/%7c/g
|
||||
s/}/%7d/g
|
||||
s/~/%7e/g
|
||||
'
|
||||
}
|
Loading…
Reference in New Issue
Block a user