Compare commits

..

4 commits

Author SHA1 Message Date
5c88f24f8e TMP: Deploy from deploy-vms-branch
Some checks failed
CI / build (push) Successful in 1m49s
CI / deploy (docs-ops.qo.is) (push) Failing after 12s
CI / deploy (system-vm) (push) Failing after 13s
2025-04-19 18:20:49 +03:00
d7d88d4509 Update CI pipleline for auto deployment 2025-04-19 18:20:30 +03:00
00421a0e44 Add SSH_DEPLOY_KEY handling to auto-deploy script 2025-04-19 18:20:04 +03:00
6a745892a4 Create script to auto-deploy with retries 2025-04-19 17:12:53 +03:00
8 changed files with 92 additions and 29 deletions

View file

@ -25,11 +25,17 @@ jobs:
attic use "$CACHE_REPOSITORY" attic use "$CACHE_REPOSITORY"
- name: Run Builds and Checks - name: Run Builds and Checks
run: nix-fast-build --no-nom --max-jobs 6 --skip-cached --attic-cache "$CACHE_REPOSITORY" run: nix-fast-build --no-nom --max-jobs 6 --skip-cached --attic-cache "$CACHE_REPOSITORY"
- name: Deploy Docs deploy:
if: success() && github.ref == 'refs/heads/main' needs: build
run: | if: success() && github.ref == 'refs/heads/54-deploy-vms-automatically'
mkdir ~/.ssh/ runs-on: nix
echo -e "Host lindberg-webapps.backplane.net.qo.is\n StrictHostKeyChecking no" >> ~/.ssh/config env:
(umask 0077 && printf "%s\n" "${{ secrets.SSH_DEPLOY_KEY }}" > ~/.ssh/id_ed25519) SSH_DEPLOY_KEY: "${{ secrets.SSH_DEPLOY_KEY }}"
deploy --skip-checks --remote-build .#lindberg-webapps.\"docs-ops.qo.is\" strategy:
# Remote build is neccessary due to non-wheel nix users signing restrictions. However, the build should come from the cache anyway. matrix:
profile:
- docs-ops.qo.is
- system-vm
steps:
- name: "Deploy Profile ${{ matrix.profile }}"
run: "auto-deploy ${{ matrix.profile }}"

View file

@ -6,12 +6,17 @@ and that you need to have SSH root access to the target machines.
## Deploy system categories ## Deploy system categories
This is also used in CI. We currently split out nixosConfigurations into these categories:
- `system-ci`: Systems should be updated separately because they might break automated deployment processes.
- `system-vm`: Virtual systems.
- `system-physical`: Physical systems.
You can roll updates with retries by category with:
```bash ```bash
auto-deploy system-vm
auto-deploy vm auto-deploy system-physical
auto-deploy physical
``` ```
## Deploy to selected target hosts ## Deploy to selected target hosts

View file

@ -12,5 +12,6 @@ in
sshUser = "nginx-${domain}"; sshUser = "nginx-${domain}";
path = deployPkgs.deploy-rs.lib.activate.noop self.packages.${system}.docs; path = deployPkgs.deploy-rs.lib.activate.noop self.packages.${system}.docs;
profilePath = "/var/lib/nginx-${domain}/root"; profilePath = "/var/lib/nginx-${domain}/root";
remoteBuild = true;
}; };
} }

View file

@ -0,0 +1,27 @@
{
deployPkgs,
pkgs,
self,
...
}:
let
inherit (pkgs.lib) pipe filterAttrs mapAttrs;
in
{
nodes = pipe self.nixosConfigurations [
(filterAttrs (_n: v: v.config.qois.git-ci-runner.enable))
(mapAttrs (
host: config: {
hostname = "${host}.backplane.net.qo.is";
profiles.system-ci = {
sshUser = "root";
user = "root";
activationTimeout = 300;
confirmTimeout = 60;
remoteBuild = true;
path = deployPkgs.deploy-rs.lib.activate.nixos config;
};
}
))
];
}

View file

@ -9,7 +9,7 @@ let
in in
{ {
nodes = pipe self.nixosConfigurations [ nodes = pipe self.nixosConfigurations [
(filterAttrs (_n: v: v.config.services.qemuGuest.enable == false)) (filterAttrs (_n: v: !v.config.services.qemuGuest.enable && !v.config.qois.git-ci-runner.enable))
(mapAttrs ( (mapAttrs (
host: config: { host: config: {
hostname = "${host}.backplane.net.qo.is"; hostname = "${host}.backplane.net.qo.is";

View file

@ -9,7 +9,7 @@ let
in in
{ {
nodes = pipe self.nixosConfigurations [ nodes = pipe self.nixosConfigurations [
(filterAttrs (_n: v: v.config.services.qemuGuest.enable)) (filterAttrs (_n: v: v.config.services.qemuGuest.enable && !v.config.qois.git-ci-runner.enable))
(mapAttrs ( (mapAttrs (
host: config: { host: config: {
hostname = "${host}.backplane.net.qo.is"; hostname = "${host}.backplane.net.qo.is";

View file

@ -3,25 +3,42 @@
#### Environment #### Environment
FLAKE_ROOT="$(git rev-parse --show-toplevel)" FLAKE_ROOT="$(git rev-parse --show-toplevel)"
export PROFILE="" export PROFILE="${1:-}"
case "${1:-''}" in if [ -z "${PROFILE}" ]; then
vm | physical) echo "🛑 Error: No deployment profile was specified as first parameter (e.g. \"${0} system-vm\")" 1>&2
PROFILE="system-$1"
;;
*)
echo "🛑 Error: Please use 'vm' or 'physical' as first parameter."
exit 1 exit 1
;; fi
esac
HOSTS=$(nix eval --raw "$FLAKE_ROOT"#deploy.nodes --apply " if [ -z "${SSH_DEPLOY_KEY:-}" ]; then
echo " Info: SSH_DEPLOY_KEY env variable was not set, ignoring."
SSH_KEY_FILE_ARG=""
else
TEMP_KEY_FILE=$(mktemp /dev/shm/ssh_deploy_key.XXXXXXXX)
touch "${TEMP_KEY_FILE}" && chmod 600 "${TEMP_KEY_FILE}"
printf "%s\n" "${SSH_DEPLOY_KEY}" >"${TEMP_KEY_FILE}"
SSH_KEY_FILE_ARG="-i ${TEMP_KEY_FILE}"
# Set up a trap to remove the temporary key file on script exit
trap 'rm -f "${TEMP_KEY_FILE}"' EXIT
trap 'rm -f "${TEMP_KEY_FILE}"' SIGINT
trap 'rm -f "${TEMP_KEY_FILE}"' SIGTERM
trap 'rm -f "${TEMP_KEY_FILE}"' SIGQUIT
fi
HOSTS=$(nix eval --raw "${FLAKE_ROOT}"#deploy.nodes --apply "
nodes: let nodes: let
inherit (builtins) attrNames filter concatStringsSep; inherit (builtins) attrNames filter concatStringsSep;
names = attrNames nodes; names = attrNames nodes;
profile = \"$PROFILE\"; profile = \"${PROFILE}\";
filteredNames = filter (name: nodes.\${name}.profiles ? \${profile}) names; filteredNames = filter (name: nodes.\${name}.profiles ? \${profile}) names;
in concatStringsSep \"\\n\" filteredNames in concatStringsSep \"\\n\" filteredNames
") ")
if [ -z "$HOSTS" ]; then
echo "🛑 Error: No deployments matching the profile ${PROFILE} were found." 1>&2
exit 1
fi
KNOWN_HOSTS_FILE=$(nix eval --raw .#nixosConfigurations.lindberg.config.environment.etc."ssh/ssh_known_hosts".source)
#### Helpers #### Helpers
retry() { retry() {
@ -30,7 +47,7 @@ retry() {
local -i attempt_num=1 local -i attempt_num=1
until "$@"; do until "$@"; do
if ((attempt_num == max_attempts)); then if ((attempt_num == max_attempts)); then
echo "⚠️ Warning: Attempt $attempt_num failed and there are no more attempts left!" echo "🛑 Error: Attempt $attempt_num failed and there are no more attempts left!" 1>&2
return 1 return 1
else else
echo "⚠️ Attempt $attempt_num failed! Trying again in $attempt_num seconds..." echo "⚠️ Attempt $attempt_num failed! Trying again in $attempt_num seconds..."
@ -41,5 +58,8 @@ retry() {
#### Execution #### Execution
for HOST in $HOSTS; do for HOST in $HOSTS; do
retry 3 deploy --skip-checks --targets "${FLAKE_ROOT}#${HOST}.${PROFILE}" retry 3 deploy \
--skip-checks \
--ssh-opts "-o UserKnownHostsFile=${KNOWN_HOSTS_FILE} ${SSH_KEY_FILE_ARG:-''}" \
--targets "${FLAKE_ROOT}#\"${HOST}\".\"${PROFILE}\""
done done

View file

@ -22,10 +22,14 @@ Deploy updates:
nix develop nix develop
# Deploy vms # Deploy vms
auto-deploy vm auto-deploy system-vm
# Deploy CI hosts
auto-deploy system-ci
# Deploy physical hosts # Deploy physical hosts
auto-deploy physical auto-deploy system-physical
``` ```