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
|
set -euf
|
||||||
|
|
||||||
. ./lib/prelude.sh
|
PATH="$PWD/bin${PATH+:$PATH}"
|
||||||
|
export PATH
|
||||||
|
|
||||||
user=root
|
user=root
|
||||||
host=$1
|
host=$1
|
||||||
@ -12,4 +13,4 @@ host=$1
|
|||||||
config=./modules/$host/default.nix
|
config=./modules/$host/default.nix
|
||||||
target=${2-$user@$host}
|
target=${2-$user@$host}
|
||||||
|
|
||||||
verbose deploy "$config" "$target"
|
exec ssh-deploy "$config" "$target"
|
||||||
|
188
infest
188
infest
@ -1,187 +1,15 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
set -xeuf
|
#
|
||||||
|
# usage: ./infest cac-servername hostname
|
||||||
|
#
|
||||||
|
set -euf
|
||||||
|
|
||||||
. ./lib/prelude.sh
|
PATH="$PWD/bin${PATH+:$PATH}"
|
||||||
. ./lib/cac.sh
|
export PATH
|
||||||
. ./lib/cacnixos.sh
|
|
||||||
|
|
||||||
nix_url=https://nixos.org/releases/nix/nix-1.8/nix-1.8-x86_64-linux.tar.bz2
|
nix_url=https://nixos.org/releases/nix/nix-1.8/nix-1.8-x86_64-linux.tar.bz2
|
||||||
nix_sha256=52fab207b4ce4d098a12d85357d0353e972c492bab0aa9e08e1600363e76fefb
|
nix_sha256=52fab207b4ce4d098a12d85357d0353e972c492bab0aa9e08e1600363e76fefb
|
||||||
nix_find_sha1sum=86f8775bd4f0841edd4c816df861cebf509d58c3
|
nix_find_sha1sum=86f8775bd4f0841edd4c816df861cebf509d58c3
|
||||||
|
export nix_url nix_sha256 nix_find_sha1sum
|
||||||
|
|
||||||
# This is somewhat required because cloudatcost requires whitelisting
|
exec infest-cac "$@"
|
||||||
# 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 "$@"
|
|
||||||
|
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