diff options
-rw-r--r-- | README.md | 32 | ||||
-rwxr-xr-x | bin/_cac_curl_api_v1 | 10 | ||||
-rwxr-xr-x | bin/_cac_exec | 8 | ||||
-rwxr-xr-x | bin/_cac_get_api_v1 | 3 | ||||
-rwxr-xr-x | bin/_cac_post_api_v1 | 3 | ||||
-rwxr-xr-x | bin/cac-cloudpro-build | 5 | ||||
-rwxr-xr-x | bin/cac-cloudpro-delete | 3 | ||||
-rwxr-xr-x | bin/cac-cloudpro-resources | 3 | ||||
-rwxr-xr-x | bin/cac-console | 3 | ||||
-rwxr-xr-x | bin/cac-get-server-by | 17 | ||||
-rwxr-xr-x | bin/cac-listservers | 12 | ||||
-rwxr-xr-x | bin/cac-listtasks | 3 | ||||
-rwxr-xr-x | bin/cac-listtemplates | 4 | ||||
-rwxr-xr-x | bin/cac-powerop | 3 | ||||
-rwxr-xr-x | bin/cac-rdns | 3 | ||||
-rwxr-xr-x | bin/cac-renameserver | 3 | ||||
-rwxr-xr-x | bin/cac-runmode | 3 | ||||
-rwxr-xr-x | bin/cac-ssh | 17 | ||||
-rwxr-xr-x | bin/cacnixos-networking | 28 | ||||
-rwxr-xr-x | bin/infest-CentOS-7-64bit | 150 | ||||
-rwxr-xr-x | bin/infest-cac | 21 | ||||
-rwxr-xr-x | cac | 337 | ||||
-rwxr-xr-x | infest | 15 | ||||
-rwxr-xr-x | infest-cac-CentOS-7-64bit.sh | 33 | ||||
-rw-r--r-- | infest.d/cac-CentOS-7-64bit/finalize.sh | 66 | ||||
-rw-r--r-- | infest.d/cac-CentOS-7-64bit/prepare.sh | 104 | ||||
-rw-r--r-- | infest.d/nixos-install.sh | 8 |
27 files changed, 580 insertions, 317 deletions
diff --git a/README.md b/README.md new file mode 100644 index 000000000..8a72d2fee --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ + + +# Turn a Cloud at Cost CentOS-7-64bit server into NixOS + +1. Configure the system (`$systemname`) you'd like to install (see Configuration below). +2. Create new server instance (either Custom or cloudpro) using "CentOS-7-64bit". + Note the servername (something like c731445864-cloudpro-388922936). +3. `cac_login=xxx cac_key=yyy ./infest-cac-CentOS-7-64bit.sh servername:$servername $systename` +4. Enjoy. (`ssh root@$systename`) + +# Configuration + +Configure your system in modules/$systemname +See modules/cd/default.nix as an example. + +Notice that modules/$systemname/networking will be autogenerated (but not committed). + +secrets/$systemname/nix/foo can be accessed as `<secrets/foo>` from within the configuration. + +You might want `secrets/$systemname/rsync/etc/tinc/retiolum/rsa_key.priv`. + +You might want `secrets/$systemname/nix/hashedPasswords.nix`, which looks like + +```nix +_: { users.extraUsers.root.hashedPassword = "XXX"; } +``` + +`XXX` can be generated with e.g. + +``` +mkpasswd -m sha-512 -S $(openssl rand -base64 16 | tr -d '+=' | head -c 16) +``` diff --git a/bin/_cac_curl_api_v1 b/bin/_cac_curl_api_v1 deleted file mode 100755 index 65acebd9a..000000000 --- a/bin/_cac_curl_api_v1 +++ /dev/null @@ -1,10 +0,0 @@ -#! /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 -) diff --git a/bin/_cac_exec b/bin/_cac_exec deleted file mode 100755 index c932454e2..000000000 --- a/bin/_cac_exec +++ /dev/null @@ -1,8 +0,0 @@ -#! /bin/sh -set -euf - -if test -z "${cac_via-}"; then - exec "$@" -else - exec ssh -q "$cac_via" -t "$@" -fi diff --git a/bin/_cac_get_api_v1 b/bin/_cac_get_api_v1 deleted file mode 100755 index 67aac8560..000000000 --- a/bin/_cac_get_api_v1 +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -set -euf -exec _cac_curl_api_v1 -G "$@" diff --git a/bin/_cac_post_api_v1 b/bin/_cac_post_api_v1 deleted file mode 100755 index b946ed9fa..000000000 --- a/bin/_cac_post_api_v1 +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -set -euf -exec _cac_curl_api_v1 -XPOST "$@" diff --git a/bin/cac-cloudpro-build b/bin/cac-cloudpro-build deleted file mode 100755 index 782fa0d72..000000000 --- a/bin/cac-cloudpro-build +++ /dev/null @@ -1,5 +0,0 @@ -#! /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}" diff --git a/bin/cac-cloudpro-delete b/bin/cac-cloudpro-delete deleted file mode 100755 index ee1dbbc7e..000000000 --- a/bin/cac-cloudpro-delete +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -set -euf -exec _cac_post_api_v1 cloudpro/delete sid="$1" diff --git a/bin/cac-cloudpro-resources b/bin/cac-cloudpro-resources deleted file mode 100755 index 9ec5872e7..000000000 --- a/bin/cac-cloudpro-resources +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -set -euf -exec _cac_get_api_v1 cloudpro/resources diff --git a/bin/cac-console b/bin/cac-console deleted file mode 100755 index ed1cbd5ff..000000000 --- a/bin/cac-console +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -set -euf -exec _cac_post_api_v1 console sid="$1" diff --git a/bin/cac-get-server-by b/bin/cac-get-server-by deleted file mode 100755 index b6d6b4ba3..000000000 --- a/bin/cac-get-server-by +++ /dev/null @@ -1,17 +0,0 @@ -#! /bin/sh -set -euf - -cac-listservers \ - | jq \ - --arg k "$1" \ - --arg v "$2" \ - ' - map(select(.[$k]==$v)) | - if (. | length) == 0 then - null - elif (. | length) == 1 then - .[0] - else - . - end - ' diff --git a/bin/cac-listservers b/bin/cac-listservers deleted file mode 100755 index 1e815d2af..000000000 --- a/bin/cac-listservers +++ /dev/null @@ -1,12 +0,0 @@ -#! /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 diff --git a/bin/cac-listtasks b/bin/cac-listtasks deleted file mode 100755 index 14be3948a..000000000 --- a/bin/cac-listtasks +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -set -euf -exec _cac_get_api_v1 listtasks diff --git a/bin/cac-listtemplates b/bin/cac-listtemplates deleted file mode 100755 index c4414e019..000000000 --- a/bin/cac-listtemplates +++ /dev/null @@ -1,4 +0,0 @@ -#! /bin/sh -set -euf - -exec _cac_get_api_v1 listtemplates diff --git a/bin/cac-powerop b/bin/cac-powerop deleted file mode 100755 index c897835f0..000000000 --- a/bin/cac-powerop +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -set -euf -exec _cac_post_api_v1 powerop sid="$1" action="$2" diff --git a/bin/cac-rdns b/bin/cac-rdns deleted file mode 100755 index c2d9ecdab..000000000 --- a/bin/cac-rdns +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -set -euf -exec _cac_post_api_v1 rdns sid="$1" hostname="$2" diff --git a/bin/cac-renameserver b/bin/cac-renameserver deleted file mode 100755 index f0eff9b3d..000000000 --- a/bin/cac-renameserver +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -set -euf -exec _cac_post_api_v1 renameserver sid="$1" name="$2" diff --git a/bin/cac-runmode b/bin/cac-runmode deleted file mode 100755 index 200b9fb79..000000000 --- a/bin/cac-runmode +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -set -euf -exec _cac_post_api_v1 rdns sid="$1" mode="$2" diff --git a/bin/cac-ssh b/bin/cac-ssh deleted file mode 100755 index a0ec5dcf3..000000000 --- a/bin/cac-ssh +++ /dev/null @@ -1,17 +0,0 @@ -#! /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" \ - "$@" diff --git a/bin/cacnixos-networking b/bin/cacnixos-networking deleted file mode 100755 index 4b246ebf1..000000000 --- a/bin/cacnixos-networking +++ /dev/null @@ -1,28 +0,0 @@ -#! /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' diff --git a/bin/infest-CentOS-7-64bit b/bin/infest-CentOS-7-64bit deleted file mode 100755 index a8afea14b..000000000 --- a/bin/infest-CentOS-7-64bit +++ /dev/null @@ -1,150 +0,0 @@ -#! /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 diff --git a/bin/infest-cac b/bin/infest-cac deleted file mode 100755 index d7d7bb96c..000000000 --- a/bin/infest-cac +++ /dev/null @@ -1,21 +0,0 @@ -#! /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 @@ -0,0 +1,337 @@ +#! /bin/sh +set -euf + +PATH=$PWD/bin:$PATH +export PATH + +cac_listservers_cache=$PWD/tmp/cac_listservers_cache.json + + +cac() { + __cac_cli__command=$1 + shift + __cac_cli__"$__cac_cli__command" "$@" +} + +# WIP +__cac_cli__help() {( + exec sed < "$0" -n ' + s/^__cac_cli__\([^(]\+\)().*/\1/p + ' +)} + +# usage: console +__cac_cli__console() {( + server=$(__cac_cli__getserver "$1") + sid=$(echo $server | jq -r .sid) + # TODO check reply status == ok + _cac_post_api_v1 console sid="$sid" | jq -r .console +)} + +__cac_cli__listservers() { + jq -r . $cac_listservers_cache +} + +__cac_cli__update() {( + umask 0077 + servers=$(_cac_listservers) + echo $servers > $cac_listservers_cache.tmp + mv $cac_listservers_cache.tmp $cac_listservers_cache +)} + +__cac_cli__getserver() {( + + case $1 in + *:*) + k=${1%%:*} + v=${1#*:} + ;; + *) + k=label + v=${1#*:} + ;; + esac + + if result=$(jq \ + -e \ + --arg k "$k" \ + --arg v "$v" \ + ' + map(select(.[$k]==$v)) | + if (. | length) == 1 then + .[0] + else + null + end + ' \ + $cac_listservers_cache); then + echo $result | jq -r . + else + echo "$0 getserver $k:$v => not unique server found" >&2 + exit 23 + fi +)} + +__cac_cli__generatenetworking() {( + server=$(__cac_cli__getserver "$1") + + hostname=$(echo $server | jq -r .label) + + 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 '# Generated file: %s generatenetworking %s %s\n' "$0" "$1" "$2" + #printf '# on %s\n' "$(date -Is)" + #printf '\n' + printf '_:\n' + 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' +)} + +__cac_cli__powerop() {( + server=$(__cac_cli__getserver "$1") + action=$2 + + sid=$(echo $server | jq -r .sid) + + reply=$(_cac_post_api_v1 powerop sid="$sid" action="$action") + + case $(echo $reply | jq -r .status) in + ok) + echo $reply | jq -r . >&2 + __cac_cli__update + ;; + *) + echo bad reply: >&2 + echo $reply | jq -r . >&2 + exit 23 + ;; + esac +)} +__cac_cli__pushconfig() {( + server=$(__cac_cli__getserver "$1") + + prefix=${2-/} + + hostname=$(echo $server | jq -r .label) + + address=$(echo $server | jq -r .ip) + target=root@$address + + RSYNC_RSH='sshpass -e ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' + SSHPASS=$(echo $server | jq -r .rootpass) + export RSYNC_RSH SSHPASS + + pushgit . $prefix/etc/nixos/ + pushgit hosts $prefix/etc/nixos/hosts/ + pushgit tmp/nixpkgs/$hostname $prefix/etc/nixos/nixpkgs/ + pushdir secrets/$hostname/nix $prefix/etc/nixos/secrets/ + pushdir secrets/$hostname/rsync $prefix/ + echo "_:{imports=[./modules/$hostname];}" \ + | $RSYNC_RSH "$target" tee "$prefix/etc/nixos/configuration.nix" \ + > /dev/null + + ## TODO chmod and chown secrets +)} + +__cac_cli__setlabel() {( + server=$(__cac_cli__getserver "$1") + label=$2 + + sid=$(echo $server | jq -r .sid) + + reply=$(_cac_post_api_v1 renameserver sid="$sid" name="$label") + + case $(echo $reply | jq -r .status) in + ok) + echo $reply | jq -r . >&2 + __cac_cli__update + ;; + *) + echo bad reply: >&2 + echo $reply | jq -r . >&2 + exit 23 + ;; + esac +)} + +__cac_cli__setmode() {( + server=$(__cac_cli__getserver "$1") + mode=$2 + + sid=$(echo $server | jq -r .sid) + + reply=$(_cac_post_api_v1 runmode sid="$sid" mode="$mode") + + case $(echo $reply | jq -r .status) in + ok) + echo $reply | jq -r . >&2 + __cac_cli__update + ;; + *) + echo bad reply: >&2 + echo $reply | jq -r . + exit 23 + ;; + esac +)} + +__cac_cli__ssh() {( + server=$(__cac_cli__getserver "$1") + shift + + address=$(echo $server | jq -r .ip) + target=root@$address + + SSHPASS=$(echo $server | jq -r .rootpass) + export SSHPASS + + exec sshpass -e ssh \ + -S none \ + -o StrictHostKeyChecking=no \ + -o UserKnownHostsFile=/dev/null \ + $target \ + "$@" +)} + + +# usage: ./cac waitstatus mode:Safe 'Powered On' +# blocks until server has specfied state +__cac_cli__waitstatus() { + server=$(__cac_cli__getserver "$1") + status=$(echo $server | jq -r .status) + + case $status in + $2) + return + ;; + esac + + echo "$(date -Is) Waiting for status: $2; current status: $status ..." >&2 + + __cac_cli__waitforcacheupdate __cac_cli__waitstatus "$@" +} + + +# XXX for __cac_cli__waitforcacheupdate and __cac_cli__poll cache means $cac_listservers_cache + +# blocks until cache has been updated then executes "$@" +__cac_cli__waitforcacheupdate() { + case $(inotifywait --format %f -q -e moved_to $(dirname $cac_listservers_cache)) in + $(basename $cac_listservers_cache)) "$@";; + *) __cac_cli__waitforcacheupdate "$@";; + esac +} + +# usage: with cac ./cac poll 60s +# continuously update cache, sleeping at least $1 between updates +__cac_cli__poll() { + __cac_cli__update + t=${1-1m} + echo "$(date -Is) cache updated; sleeping $t ..." >&2 + sleep "$t" + __cac_cli__poll "$@" +} + + +_cac_listservers() {( + servers=$(_cac_get_api_v1 listservers) + status=$(echo $servers | jq -r .status) + + if [ "$status" = ok ]; then + echo "$servers" | jq -r .data + else + echo "cac_listservers: bad listservers status: $status" >&2 + exit 1 + fi +)} + + + + +# rsyncfiles : lines filename |> local-dir x remote-dir -> ? |> ? +rsyncfiles() {( + set -x + rsync \ + --rsync-path="mkdir -p \"$2\" && rsync" \ + -vzrlptD \ + --files-from=- \ + "$1"/ \ + "$target:$2" +)} + + +# gitfiles : git-work-tree -> lines filename +gitfiles() { + git -C "$1" archive --format=tar HEAD | tar t | sed '/\/$/d' +} + +# pushgit : git-work-tree x remote-dir -> ? +pushgit() { + gitfiles "$1" | rsyncfiles "$1" "$2" +} + +# dirfiles : local-dir -> lines filename +dirfiles() {( + cd "$1" + find . -type f | sed 's/^\.\///' +)} + +# pushgit : local-dir x remote-dir -> ? +pushdir() { + dirfiles "$1" | rsyncfiles "$1" "$2" +} + + + + + + +_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 -sS "$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 + ) +} + +_cac_exec() { + if test -z "${cac_via-}"; then + env -- "$@" + else + ssh -q "$cac_via" -t "$@" + fi +} + + + + + +case ${run-true} in + true) cac "$@";; +esac diff --git a/infest b/infest deleted file mode 100755 index 8c891c428..000000000 --- a/infest +++ /dev/null @@ -1,15 +0,0 @@ -#! /bin/sh -# -# usage: ./infest cac-servername hostname -# -set -euf - -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 - -exec infest-cac "$@" diff --git a/infest-cac-CentOS-7-64bit.sh b/infest-cac-CentOS-7-64bit.sh new file mode 100755 index 000000000..32090ae9e --- /dev/null +++ b/infest-cac-CentOS-7-64bit.sh @@ -0,0 +1,33 @@ +#! /bin/sh +set -xeuf + +serverspec=$1 +systemname=$2 + +./cac poll 10s 2>/dev/null & +pollpid=$! +trap "kill $pollpid; trap - EXIT" EXIT + +./cac waitstatus $serverspec 'Powered On' + +# TODO don't set label/mode if they're already good +./cac setlabel $serverspec $systemname +./cac setmode $systemname normal +./cac generatenetworking $systemname > modules/$systemname/networking.nix + +cat infest.d/cac-CentOS-7-64bit/prepare.sh | ./cac ssh $systemname \ + nix_url=https://nixos.org/releases/nix/nix-1.9/nix-1.9-x86_64-linux.tar.bz2 \ + nix_sha256=5c76611c631e79aef5faf3db2d253237998bbee0f61fa093f925fa32203ae32b \ + /bin/sh + +./cac pushconfig $systemname /mnt + +# This needs to be run twice because (at least): +# Initialized empty Git repository in /var/lib/git/$reponame +# chown: invalid user: 'git:nogroup' +cat infest.d/nixos-install.sh | ./cac ssh $systemname || : +cat infest.d/nixos-install.sh | ./cac ssh $systemname + +cat infest.d/cac-CentOS-7-64bit/finalize.sh | ./cac ssh $systemname + +./cac powerop $systemname reset diff --git a/infest.d/cac-CentOS-7-64bit/finalize.sh b/infest.d/cac-CentOS-7-64bit/finalize.sh new file mode 100644 index 000000000..b70276b33 --- /dev/null +++ b/infest.d/cac-CentOS-7-64bit/finalize.sh @@ -0,0 +1,66 @@ +#! /bin/sh +set -eu +{ + umount /mnt2 + umount /mnt/nix + umount /mnt/boot + umount /mnt + umount /boot + + PATH=$(for i in /nix/store/*coreutils*/bin; do :; done; echo $i) + export PATH + + mkdir /oldshit + + mv /bin /oldshit/ + mv /newshit/bin / + + # TODO ensure /boot is empty + rmdir /newshit/boot + + # skip /dev + rmdir /newshit/dev + + mv /etc /oldshit/ + mv /newshit/etc / + + # TODO ensure /home is empty + rmdir /newshit/home + + # skip /nix (it's already there) + rmdir /newshit/nix + + # skip /proc + rmdir /newshit/proc + + # skip /run + rmdir /newshit/run + + # skip /sys + rmdir /newshit/sys + + # skip /tmp + # TODO rmdir /newshit/tmp + + mv /usr /oldshit/ + mv /newshit/usr / + + mv /var /oldshit/ + mv /newshit/var / + + mv /root /oldshit/ + mv /newshit/root / + + mv /lib /oldshit/ + mv /lib64 /oldshit/ + mv /sbin /oldshit/ + mv /mnt2 /oldshit/ + mv /srv /oldshit/ + mv /opt /oldshit/ + + + mv /newshit /root/ # TODO this one shoult be empty + mv /oldshit /root/ + + sync +} diff --git a/infest.d/cac-CentOS-7-64bit/prepare.sh b/infest.d/cac-CentOS-7-64bit/prepare.sh new file mode 100644 index 000000000..f932e9c30 --- /dev/null +++ b/infest.d/cac-CentOS-7-64bit/prepare.sh @@ -0,0 +1,104 @@ +#! /bin/sh +set -euf + +: $nix_url +: $nix_sha256 + +{ + # + # prepare host + # + + type bzip2 2>/dev/null || yum install -y bzip2 + type rsync 2>/dev/null || yum install -y rsync + + if ! getent group nixbld >/dev/null; then + groupadd -g 30000 -r nixbld + fi + for i in `seq 1 10`; do + if ! getent passwd nixbld$i 2>/dev/null; then + useradd \ + -c "CentOS Nix build user $i" \ + -d /var/empty \ + -g 30000 \ + -G 30000 \ + -l \ + -M \ + -s /sbin/nologin \ + -u $(expr 30000 + $i) \ + nixbld$i + rm -f /var/spool/mail/nixbld$i + fi + done + + # generate fake sudo because + # sudo: sorry, you must have a tty to run sudo + mkdir -p bin + printf '#! /bin/sh\nexec env "$@"\n' > bin/sudo + chmod +x bin/sudo + + PATH=$PWD/bin:$PATH + export PATH + + # install nix on host (cf. https://nixos.org/nix/install) + if ! test -e /root/.nix-profile/etc/profile.d/nix.sh; then + ( + verify() { + echo $nix_sha256 $(basename $nix_url) | sha256sum -c + } + if ! verify; then + curl -C - -O "$nix_url" + verify + fi + ) + tar jxf $(basename $nix_url) + $(basename $nix_url .tar.bz2)/install + fi + + MANPATH=/var/empty . /root/.nix-profile/etc/profile.d/nix.sh + + if ! type nixos-install 2>/dev/null; then + nixpkgs_expr='import <nixpkgs> { system = builtins.currentSystem; }' + nixpkgs_path=$(find /nix/store -mindepth 1 -maxdepth 1 -name *-nixpkgs-* -type d) + 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.nixos-install + fi + + # + # mount install directory + # + + if ! mount | grep -Fq '/dev/mapper/centos-root on /mnt type xfs'; then + mkdir -p /newshit + mount --bind /newshit /mnt + fi + + if ! mount | grep -Fq '/dev/sda1 on /mnt/boot type xfs'; then + mkdir -p /mnt/boot + mount /dev/sda1 /mnt/boot + fi + + if ! mount | grep -Fq '/dev/mapper/centos-root on /mnt/nix type xfs'; then + mkdir -p /mnt/nix + mount --bind /nix /mnt/nix + fi + + mount | grep 'on /mnt\>' >&2 + + # + # prepare install directory + # + # XXX This should be done by (?) + # remote_dir=/mnt ./cac pushconfig servername:c731445864-cloudpro-134581046 rmdir + + mkdir -p /mnt/etc/nixos + mkdir -m 0555 -p /mnt/var/empty + + # add eye candy + address=$(echo $SSH_CONNECTION | awk '{print$3}') + echo 'PS1='\''\[\e[1;31m\]\u@'"$address"'\[\e[m\] \[\e[1;32m\]\w\[\e[m |