Skip to content

consolidate deploy_nixos/main.tf providers #87

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 2 additions & 35 deletions deploy_nixos/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ locals {
ssh_private_key = local.ssh_private_key_file == "-" ? var.ssh_private_key : file(local.ssh_private_key_file)
ssh_agent = var.ssh_agent == null ? (local.ssh_private_key != "") : var.ssh_agent
build_on_target = data.external.nixos-instantiate.result["currentSystem"] != var.target_system ? true : tobool(var.build_on_target)
packed_keys_json = jsonencode(var.keys)
}

# used to detect changes in the configuration
Expand All @@ -151,41 +152,6 @@ data "external" "nixos-instantiate" {
resource "null_resource" "deploy_nixos" {
triggers = merge(var.triggers, local.triggers)

connection {
type = "ssh"
host = var.target_host
port = var.target_port
user = var.target_user
agent = local.ssh_agent
timeout = "100s"
private_key = local.ssh_private_key == "-" ? "" : local.ssh_private_key
}

# copy the secret keys to the host
provisioner "file" {
content = jsonencode(var.keys)
destination = "packed-keys.json"
}

# FIXME: move this to nixos-deploy.sh
provisioner "file" {
source = "${path.module}/unpack-keys.sh"
destination = "unpack-keys.sh"
}

# FIXME: move this to nixos-deploy.sh
provisioner "file" {
source = "${path.module}/maybe-sudo.sh"
destination = "maybe-sudo.sh"
}

provisioner "remote-exec" {
inline = [
"chmod +x unpack-keys.sh maybe-sudo.sh",
"./maybe-sudo.sh ./unpack-keys.sh ./packed-keys.json",
]
}

# do the actual deployment
provisioner "local-exec" {
interpreter = concat([
Expand All @@ -196,6 +162,7 @@ resource "null_resource" "deploy_nixos" {
var.target_port,
local.build_on_target,
local.ssh_private_key == "" ? "-" : local.ssh_private_key,
local.packed_keys_json,
"switch",
var.delete_older_than,
],
Expand Down
41 changes: 31 additions & 10 deletions deploy_nixos/nixos-deploy.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# nixos-deploy deploys a nixos-instantiate-generated drvPath to a target host
#
# Usage: nixos-deploy.sh <drvPath> <host> <switch-action> [<build-opts>] ignoreme
# Usage: nixos-deploy.sh <drvPath> <outPath> <targetHost> <targetPort> <buildOnTarget> <sshPrivateKey> <packedKeysJson> <switch-action> <deleteOlderThan> [<build-opts>] ignoreme
set -euo pipefail

### Defaults ###
Expand All @@ -23,6 +23,7 @@ sshOpts=(
# verbose output for easier debugging
-v
)
scpOpts=("${sshOpts[@]}")

### Argument parsing ###

Expand All @@ -32,24 +33,28 @@ targetHost="$3"
targetPort="$4"
buildOnTarget="$5"
sshPrivateKey="$6"
action="$7"
deleteOlderThan="$8"
shift 8
packedKeysJson="$7"
action="$8"
deleteOlderThan="$9"
shift 9

# remove the last argument
set -- "${@:1:$(($# - 1))}"
buildArgs+=("$@")

sshOpts+=( -p "${targetPort}" )
scpOpts+=( -P "${targetPort}" )

workDir=$(mktemp -d)
trap 'rm -rf "$workDir"' EXIT

if [[ -n "${sshPrivateKey}" && "${sshPrivateKey}" != "-" ]]; then
sshPrivateKeyFile="$workDir/ssh_key"
echo "$sshPrivateKey" > "$sshPrivateKeyFile"
chmod 0700 "$sshPrivateKeyFile"
sshOpts+=( -o "IdentityFile=${sshPrivateKeyFile}" )
chmod 0600 "$sshPrivateKeyFile"
flag="IdentityFile=${sshPrivateKeyFile}"
sshOpts+=( -o "$flag" )
scpOpts+=( -o "$flag" )
fi

### Functions ###
Expand All @@ -62,6 +67,11 @@ copyToTarget() {
NIX_SSHOPTS="${sshOpts[*]}" nix-copy-closure --to "$targetHost" "$@"
}

remoteTempDir=""
makeRemoteTempDir() {
remoteTempDir=$(ssh "${sshOpts[@]}" "$targetHost" "mktemp -d")
}

# assumes that passwordless sudo is enabled on the server
targetHostCmd() {
# ${*@Q} escapes the arguments losslessly into space-separted quoted strings.
Expand All @@ -70,16 +80,16 @@ targetHostCmd() {
# Tested with OpenSSH_7.9p1.
#
# shellcheck disable=SC2029
ssh "${sshOpts[@]}" "$targetHost" "./maybe-sudo.sh ${*@Q}"
ssh "${sshOpts[@]}" "$targetHost" "'$remoteTempDir/maybe-sudo.sh' ${*@Q}"
}

# Setup a temporary ControlPath for this session. This speeds-up the
# operations by not re-creating SSH sessions between each command. At the end
# of the run, the session is forcefully terminated.
setupControlPath() {
sshOpts+=(
-o "ControlPath=$workDir/ssh_control"
)
local flag="ControlPath=$workDir/ssh_control"
sshOpts+=(-o "$flag")
scpOpts+=(-o "$flag")
cleanupControlPath() {
local ret=$?
# Avoid failing during the shutdown
Expand All @@ -97,6 +107,17 @@ setupControlPath() {

setupControlPath

makeRemoteTempDir
unpackKeysPath="$remoteTempDir/unpack-keys.sh"
maybeSudoPath="$remoteTempDir/maybe-sudo.sh"
packedKeysPath="$remoteTempDir/packed-keys.json"
scriptDir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
scp "${scpOpts[@]}" "$scriptDir/unpack-keys.sh" "$targetHost:$unpackKeysPath"
scp "${scpOpts[@]}" "$scriptDir/maybe-sudo.sh" "$targetHost:$maybeSudoPath"
echo "$packedKeysJson" | ssh "${sshOpts[@]}" "$targetHost" "cat > '$packedKeysPath'"
ssh "${sshOpts[@]}" "$targetHost" "chmod +x '$maybeSudoPath' '$unpackKeysPath' 1>/dev/null"
ssh "${sshOpts[@]}" "$targetHost" "'$maybeSudoPath' '$unpackKeysPath' '$packedKeysPath' 1>/dev/null"

if [[ "${buildOnTarget:-false}" == true ]]; then

# Upload derivation
Expand Down