diff options
-rw-r--r-- | app/controllers/govuk_guix/revisions_controller.rb | 6 | ||||
-rw-r--r-- | app/models/backends/terraform_aws.rb | 8 | ||||
-rw-r--r-- | app/models/backends/terraform_aws/backend_methods.rb | 6 | ||||
-rw-r--r-- | app/models/backends/terraform_aws/mini_environment_methods.rb | 10 | ||||
-rw-r--r-- | app/services/govuk_guix/build_mini_environment.rb | 6 | ||||
-rw-r--r-- | lib/remote_host.rb | 25 | ||||
-rw-r--r-- | lib/shell_utils.rb | 14 |
7 files changed, 54 insertions, 21 deletions
diff --git a/app/controllers/govuk_guix/revisions_controller.rb b/app/controllers/govuk_guix/revisions_controller.rb index 6e75e82..17634dd 100644 --- a/app/controllers/govuk_guix/revisions_controller.rb +++ b/app/controllers/govuk_guix/revisions_controller.rb @@ -33,12 +33,8 @@ class GovukGuix::RevisionsController < ApplicationController # Assume that the AWS backend is in use backend = Backends::TerraformAws.first - remote_host = backend.backend_latest_terraform_state.output_value( - 'guix_daemon_public_dns' - ) - options = { - run_remotely_on_host: "ubuntu@#{remote_host}" + run_remotely_on_host: backend.build_remote_host } end diff --git a/app/models/backends/terraform_aws.rb b/app/models/backends/terraform_aws.rb index d0655ee..2bf68a3 100644 --- a/app/models/backends/terraform_aws.rb +++ b/app/models/backends/terraform_aws.rb @@ -64,6 +64,14 @@ class Backends::TerraformAws < ApplicationRecord } end + def build_remote_host + RemoteHost.new( + 'ubuntu', + backend_latest_terraform_state.output_value('guix_daemon_public_dns'), + ssh_private_key + ) + end + def terraform_state_id "backend/terraform_aws/#{id}" end diff --git a/app/models/backends/terraform_aws/backend_methods.rb b/app/models/backends/terraform_aws/backend_methods.rb index 7489325..f069d77 100644 --- a/app/models/backends/terraform_aws/backend_methods.rb +++ b/app/models/backends/terraform_aws/backend_methods.rb @@ -20,12 +20,8 @@ module Backends::TerraformAws::BackendMethods def create_data_snapshot - remote_host = backend_latest_terraform_state.output_value( - 'guix_daemon_public_dns' - ) - GovukGuix::CreateDataSnapshotJob.enqueue( - run_remotely_on_host: "ubuntu@#{remote_host}", + run_remotely_on_host: build_remote_host, backend_type: self.class.name, backend_id: id ) diff --git a/app/models/backends/terraform_aws/mini_environment_methods.rb b/app/models/backends/terraform_aws/mini_environment_methods.rb index 1885af7..350df2a 100644 --- a/app/models/backends/terraform_aws/mini_environment_methods.rb +++ b/app/models/backends/terraform_aws/mini_environment_methods.rb @@ -22,14 +22,6 @@ module Backends::TerraformAws::MiniEnvironmentMethods def build(mini_environment) slug = mini_environment.name.parameterize - remote_build_host = - mini_environment - .backend - .backend_latest_terraform_state - .output_value( - 'guix_daemon_public_dns' - ) - GovukGuix::BuildMiniEnvironment.build( mini_environment.id, services: mini_environment.services.map(&:build_argument_string), @@ -50,7 +42,7 @@ module Backends::TerraformAws::MiniEnvironmentMethods '/var/log/govuk-mini-environment-admin=/var/log' ] }, - run_remotely_on_host: "ubuntu@#{remote_build_host}" + run_remotely_on_host: mini_environment.backend.build_remote_host ) end diff --git a/app/services/govuk_guix/build_mini_environment.rb b/app/services/govuk_guix/build_mini_environment.rb index a0361b0..8e2d912 100644 --- a/app/services/govuk_guix/build_mini_environment.rb +++ b/app/services/govuk_guix/build_mini_environment.rb @@ -37,12 +37,16 @@ module GovukGuix::BuildMiniEnvironment remote_host = options[:run_remotely_on_host] if remote_host && Guix.available_locally? + # TODO: This doesn't use the private key specified by the + # backend, so it'll only work when the default SSH key has + # access to the remote host. + # Copy the revision to the remote host, to ensure it's available # there run_command( 'guix', 'copy', - "--to=#{remote_host}", + "--to=#{remote_host.user_at_address}", mini_environment.govuk_guix_revision.store_path ) end diff --git a/lib/remote_host.rb b/lib/remote_host.rb new file mode 100644 index 0000000..9110394 --- /dev/null +++ b/lib/remote_host.rb @@ -0,0 +1,25 @@ +# GOV.UK Mini Environment Admin +# Copyright © 2018 Christopher Baines <mail@cbaines.net> +# +# This file is part of the GOV.UK Mini Environment Admin. +# +# The GOV.UK Mini Environment Admin is free software: you can +# redistribute it and/or modify it under the terms of the GNU Affero +# General Public License as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later +# version. +# +# The GOV.UK Mini Environment Admin is distributed in the hope that it +# will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with the GOV.UK Mini Environment Admin. If not, see +# <http://www.gnu.org/licenses/>. + +RemoteHost = Struct.new(:user, :address, :private_key) do + def user_at_address + "#{user}@#{address}" + end +end diff --git a/lib/shell_utils.rb b/lib/shell_utils.rb index 0cd8947..75ee3ca 100644 --- a/lib/shell_utils.rb +++ b/lib/shell_utils.rb @@ -20,6 +20,7 @@ require 'open3' require 'shellwords' +require 'tempfile' module ShellUtils def run_command(*command, run_remotely_on_host: nil) @@ -28,11 +29,19 @@ module ShellUtils Shellwords.escape(arg) end + identity_file = Tempfile.new( + 'private-identity-file', + Rails.root.join('tmp') + ) + identity_file.write(run_remotely_on_host.private_key) + identity_file.close + command = [ 'ssh', # Use a automatically trust on first use model '-o', 'StrictHostKeyChecking=no', - run_remotely_on_host, + '-i', identity_file.path, + run_remotely_on_host.user_at_address, *command ] end @@ -52,9 +61,12 @@ module ShellUtils unless exit_status == 0 logger.error(self.class) { "failed, exit status #{exit_status}" } + identity_file.unlink if identity_file raise "Running #{command.join(' ')} failed:\n\n#{output.join}\n" end + identity_file.unlink if identity_file + output end end |