aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/mini_environments.js2
-rw-r--r--app/controllers/govuk_guix/revisions_controller.rb4
-rw-r--r--app/controllers/mini_environments_controller.rb36
-rw-r--r--app/controllers/que_jobs_controller.rb19
-rw-r--r--app/helpers/govuk_guix/revisions_helper.rb2
-rw-r--r--app/jobs/destroy_job.rb1
-rw-r--r--app/jobs/govuk_guix/build_job.rb33
-rw-r--r--app/jobs/govuk_guix/fetch_revision_job.rb49
-rw-r--r--app/jobs/govuk_guix/job.rb24
-rw-r--r--app/jobs/start_job.rb (renamed from app/jobs/setup_job.rb)6
-rw-r--r--app/models/govuk_guix.rb5
-rw-r--r--app/models/govuk_guix/revision.rb3
-rw-r--r--app/models/mini_environment.rb1
-rw-r--r--app/views/govuk_guix/revisions/index.html.erb10
-rw-r--r--app/views/layouts/application.html.erb1
-rw-r--r--app/views/mini_environments/new.html.erb13
-rw-r--r--app/views/mini_environments/show.html.erb64
-rw-r--r--app/views/que_jobs/cancel.html.erb2
-rw-r--r--app/views/que_jobs/retry_now.html.erb2
19 files changed, 257 insertions, 20 deletions
diff --git a/app/assets/javascripts/mini_environments.js b/app/assets/javascripts/mini_environments.js
deleted file mode 100644
index dee720f..0000000
--- a/app/assets/javascripts/mini_environments.js
+++ /dev/null
@@ -1,2 +0,0 @@
-// Place all the behaviors and hooks related to the matching controller here.
-// All this logic will automatically be available in application.js.
diff --git a/app/controllers/govuk_guix/revisions_controller.rb b/app/controllers/govuk_guix/revisions_controller.rb
new file mode 100644
index 0000000..a890fd0
--- /dev/null
+++ b/app/controllers/govuk_guix/revisions_controller.rb
@@ -0,0 +1,4 @@
+class GovukGuix::RevisionsController < ApplicationController
+ def index
+ end
+end
diff --git a/app/controllers/mini_environments_controller.rb b/app/controllers/mini_environments_controller.rb
index c45ed4a..8009777 100644
--- a/app/controllers/mini_environments_controller.rb
+++ b/app/controllers/mini_environments_controller.rb
@@ -8,14 +8,38 @@ class MiniEnvironmentsController < ApplicationController
end
def create
- ActiveRecord::Base.transaction do
- @mini_environment = MiniEnvironment.create(
- params.require(:mini_environment).permit(:name)
- )
+ @mini_environment = MiniEnvironment.create(
+ params
+ .require(:mini_environment)
+ .permit(
+ :name,
+ :govuk_guix_revision_id
+ )
+ )
- SetupJob.enqueue(@mini_environment.id)
- end
+ GovukGuix::BuildJob.enqueue(@mini_environment.id)
redirect_to @mini_environment
end
+
+ def perform_action
+ @mini_environment = MiniEnvironment.find(params[:mini_environment_id])
+
+ action = params.require(:commit)
+
+ case action
+ when 'Destroy'
+ DestroyJob.enqueue(@mini_environment.id)
+
+ flash[:notice] = "Destroying mini environment"
+ when 'Start'
+ StartJob.enqueue(@mini_environment.id)
+
+ flash[:notice] = "Starting mini environment"
+ else
+ flash[:error] = "Unknown action #{action}"
+ end
+
+ render 'show'
+ end
end
diff --git a/app/controllers/que_jobs_controller.rb b/app/controllers/que_jobs_controller.rb
new file mode 100644
index 0000000..bab2c47
--- /dev/null
+++ b/app/controllers/que_jobs_controller.rb
@@ -0,0 +1,19 @@
+class QueJobsController < ApplicationController
+ def cancel
+ ActiveRecord::Base.connection.execute(
+ "DELETE FROM que_jobs WHERE job_id = #{job_id}::bigint"
+ )
+ end
+
+ def retry_now
+ ActiveRecord::Base.connection.execute(
+ "UPDATE que_jobs
+ SET run_at = now()
+ WHERE job_id = #{job_id}::bigint"
+ )
+ end
+
+ def job_id
+ params[:id].to_i
+ end
+end
diff --git a/app/helpers/govuk_guix/revisions_helper.rb b/app/helpers/govuk_guix/revisions_helper.rb
new file mode 100644
index 0000000..eb84706
--- /dev/null
+++ b/app/helpers/govuk_guix/revisions_helper.rb
@@ -0,0 +1,2 @@
+module GovukGuix::RevisionsHelper
+end
diff --git a/app/jobs/destroy_job.rb b/app/jobs/destroy_job.rb
index 7f13fdd..2bc72c1 100644
--- a/app/jobs/destroy_job.rb
+++ b/app/jobs/destroy_job.rb
@@ -12,6 +12,7 @@ class DestroyJob < TerraformJob
aws_region: 'eu-west-1',
slug: @mini_environment.name.parameterize,
ssh_public_key: ssh_public_key,
+ start_command: @mini_environment.start_command
},
force: true
)
diff --git a/app/jobs/govuk_guix/build_job.rb b/app/jobs/govuk_guix/build_job.rb
new file mode 100644
index 0000000..381a717
--- /dev/null
+++ b/app/jobs/govuk_guix/build_job.rb
@@ -0,0 +1,33 @@
+require 'ruby_terraform'
+require 'open3'
+
+class GovukGuix::BuildJob < GovukGuix::Job
+ @retry_interval = 30
+
+ def run(mini_environment_id)
+ logger.info "GovukGuix::BuildJob: Building mini environment #{mini_environment_id}"
+
+ mini_environment = MiniEnvironment.find(mini_environment_id)
+
+ slug = mini_environment.name.parameterize
+
+ command = [
+ "#{mini_environment.govuk_guix_revision.store_path}/bin/govuk",
+ "system",
+ "build",
+ "--rails-environment=production",
+ "--app-domain=#{slug}.aws.cbaines.net",
+ "--web-domain=www.#{slug}.aws.cbaines.net",
+ "--use-high-ports=false",
+ "--use-https=certbot",
+ "--fallback",
+ ]
+
+ run_command(command) do |output|
+ store_path = output.last.strip
+ logger.debug("GovukGuix::BuildJob: start_command: #{store_path}")
+
+ mini_environment.update(start_command: store_path)
+ end
+ end
+end
diff --git a/app/jobs/govuk_guix/fetch_revision_job.rb b/app/jobs/govuk_guix/fetch_revision_job.rb
new file mode 100644
index 0000000..b1cb171
--- /dev/null
+++ b/app/jobs/govuk_guix/fetch_revision_job.rb
@@ -0,0 +1,49 @@
+require 'ruby_terraform'
+require 'git'
+require 'open3'
+
+class GovukGuix::FetchRevisionJob < GovukGuix::Job
+ @retry_interval = 30
+
+ def run(commit_hash)
+ repository.fetch
+
+ repository.checkout(commit_hash)
+
+ command = [
+ "#{repository_directory}/guix-pre-inst-env",
+ "guix",
+ "build",
+ "-e",
+ "(begin (use-modules (gds packages govuk)) (current-govuk-guix))"
+ ]
+
+ run_command(command) do |output|
+ store_path = output.last.strip
+ logger.debug("FetchRevisionJob: store_path: #{store_path}")
+
+ GovukGuix::Revision.create(
+ commit_hash: commit_hash,
+ store_path: store_path
+ )
+ end
+ end
+
+ def repository
+ @_repository ||= begin
+ if File.exists? repository_directory
+ Git.open(repository_directory, :log => Rails.logger)
+ else
+ Git.clone(repository_remote_location, repository_directory)
+ end
+ end
+ end
+
+ def repository_directory
+ 'tmp/cache/govuk-guix'
+ end
+
+ def repository_remote_location
+ 'git@git.cbaines.net:gds/govuk-guix'
+ end
+end
diff --git a/app/jobs/govuk_guix/job.rb b/app/jobs/govuk_guix/job.rb
new file mode 100644
index 0000000..0161cb1
--- /dev/null
+++ b/app/jobs/govuk_guix/job.rb
@@ -0,0 +1,24 @@
+class GovukGuix::Job < Que::Job
+ def run_command(command)
+ logger.debug("#{self.class}: Running command #{command}")
+
+ Open3.popen2e(*command) do |stdin, stdout_and_stderr, wait_thr|
+ logger.info("#{self.class}: commmand running, pid #{wait_thr.pid}")
+
+ output = []
+ stdout_and_stderr.each_line do |line|
+ logger.debug("#{self.class}: #{line}")
+ output << line
+ end
+
+ exit_status = wait_thr.value
+ unless exit_status == 0
+ logger.error("#{self.class}: failed, exit status #{exit_status}")
+
+ raise "#{output.join}\n"
+ end
+
+ yield(output)
+ end
+ end
+end
diff --git a/app/jobs/setup_job.rb b/app/jobs/start_job.rb
index 6791dd6..ec17732 100644
--- a/app/jobs/setup_job.rb
+++ b/app/jobs/start_job.rb
@@ -1,10 +1,10 @@
require 'ruby_terraform'
-class SetupJob < TerraformJob
+class StartJob < TerraformJob
@retry_interval = 30
def run_terraform
- puts "Setting up #{@mini_environment.name}"
+ logger.info "Setting up #{@mini_environment.name}"
Dir.chdir('terraform/aws') do
RubyTerraform.init(
@@ -15,11 +15,11 @@ class SetupJob < TerraformJob
)
RubyTerraform.apply(
- directory: 'mini_environment',
vars: {
aws_region: 'eu-west-1',
slug: @mini_environment.name.parameterize,
ssh_public_key: ssh_public_key,
+ start_command: @mini_environment.start_command
},
auto_approve: true
)
diff --git a/app/models/govuk_guix.rb b/app/models/govuk_guix.rb
new file mode 100644
index 0000000..e98da8e
--- /dev/null
+++ b/app/models/govuk_guix.rb
@@ -0,0 +1,5 @@
+module GovukGuix
+ def self.table_name_prefix
+ 'govuk_guix_'
+ end
+end
diff --git a/app/models/govuk_guix/revision.rb b/app/models/govuk_guix/revision.rb
new file mode 100644
index 0000000..147b6d6
--- /dev/null
+++ b/app/models/govuk_guix/revision.rb
@@ -0,0 +1,3 @@
+class GovukGuix::Revision < ApplicationRecord
+ self.primary_key = "commit_hash"
+end
diff --git a/app/models/mini_environment.rb b/app/models/mini_environment.rb
index 2d6d8ae..87ecff8 100644
--- a/app/models/mini_environment.rb
+++ b/app/models/mini_environment.rb
@@ -1,5 +1,6 @@
class MiniEnvironment < ApplicationRecord
has_many :finished_terraform_jobs, dependent: :destroy
+ belongs_to :govuk_guix_revision, class_name: 'GovukGuix::Revision'
def enqueued_terraform_jobs
Que.execute("SELECT * FROM que_jobs WHERE args->>0 = '#{id}'")
diff --git a/app/views/govuk_guix/revisions/index.html.erb b/app/views/govuk_guix/revisions/index.html.erb
new file mode 100644
index 0000000..54f9e4a
--- /dev/null
+++ b/app/views/govuk_guix/revisions/index.html.erb
@@ -0,0 +1,10 @@
+
+<% GovukGuix::Revision.all.each do |revision| %>
+
+ <div>
+
+ <%= revision.inspect %>
+
+ </div>
+
+<% end %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 5b90ace..35ea5ff 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -1,6 +1,5 @@
<% content_for :head do %>
<%= stylesheet_link_tag "application", :media => "all" %>
- <%= javascript_include_tag "application" %>
<%= csrf_meta_tag %>
<%= yield :extra_headers %>
<% end %>
diff --git a/app/views/mini_environments/new.html.erb b/app/views/mini_environments/new.html.erb
index 84d2316..7d3f2f2 100644
--- a/app/views/mini_environments/new.html.erb
+++ b/app/views/mini_environments/new.html.erb
@@ -1,8 +1,8 @@
<div class="row">
<div class="col-md-8">
- <%= form_for @mini_environment,
- url: { action: "create" },
- html: { class: 'form-horizontal' } do |f| %>
+ <%= form_with(model: @mini_environment,
+ url: { action: "create" },
+ html: { class: 'form-horizontal' }) do |f| %>
<div class="form-group">
<%= f.label :name, class: 'col-sm-2 control-label' %>
@@ -10,6 +10,13 @@
<%= f.text_field :name, class: 'form-control' %>
</div>
</div>
+
+ <div class="form-group">
+ <%= f.label :govuk_guix_revision_id, class: 'col-sm-2 control-label' %>
+ <div class="col-sm-10">
+ <%= f.collection_select :govuk_guix_revision_id, GovukGuix::Revision.all, :commit_hash, :commit_hash %>
+ </div>
+ </div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
diff --git a/app/views/mini_environments/show.html.erb b/app/views/mini_environments/show.html.erb
index 0cc6bc6..a852e6c 100644
--- a/app/views/mini_environments/show.html.erb
+++ b/app/views/mini_environments/show.html.erb
@@ -1,5 +1,21 @@
<h1>Name: <%= @mini_environment.name %></h1>
+<%= form_with(url: mini_environment_perform_action_path(@mini_environment),
+ local: true,
+ method: "post") do %>
+ <%= submit_tag('Start',
+ disabled: !@mini_environment.start_command.present?,
+ role: 'button',
+ class: 'btn btn-lg btn-success')
+ %>
+
+ <%= submit_tag("Destroy",
+ #disabled: !@mini_environment.start_command.present?,
+ role: 'button',
+ class: 'btn btn-lg btn-danger')
+ %>
+<% end %>
+
<a href="https://signon.<%= @mini_environment.name.parameterize %>.aws.cbaines.net">View</a>
<h2>Finished jobs</h2>
@@ -11,10 +27,48 @@
<h2>Enqueued jobs</h2>
-<% @mini_environment.enqueued_terraform_jobs.each do |job| %>
- <%= job['job_class'] %>
+<div class="panel-group"
+ id="accordion"
+ role="tablist"
+ aria-multiselectable="true">
+
+ <% @mini_environment.enqueued_terraform_jobs.each do |job| %>
- <pre>
- <%= job['last_error'] %>
- </pre>
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab" id="headingOne">
+ <h4 class="panel-title">
+ <a role="button"
+ data-toggle="collapse"
+ data-parent="#accordion"
+ href="#collapseOne"
+ aria-expanded="true"
+ aria-controls="collapseOne">
+ <%= job['job_class'] %>
+ </a>
+ <span class="pull-right">
+ Retrying next in <%= distance_of_time_in_words_to_now(job['run_at'], include_seconds: true) %>
+ </span>
+ </h4>
+ </div>
+ <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">
+ <div class="panel-body">
+ This job has failed <%= job['error_count'] %> times.
+
+ <div class="pull-right">
+ <%= form_with(url: retry_now_que_job_path(job['job_id'])) do %>
+ <%= submit_tag('Retry now', class: 'btn btn-default')
+ %>
+ <% end %>
+ <%= form_with(url: cancel_que_job_path(job['job_id'])) do %>
+ <%= submit_tag('Cancel', class: 'btn btn-default')
+ %>
+ <% end %>
+ </div>
+
+ <pre><%= job['last_error'] %></pre>
+ </div>
+ </div>
+ </div>
<% end %>
+
+</div>
diff --git a/app/views/que_jobs/cancel.html.erb b/app/views/que_jobs/cancel.html.erb
new file mode 100644
index 0000000..5886237
--- /dev/null
+++ b/app/views/que_jobs/cancel.html.erb
@@ -0,0 +1,2 @@
+<h1>QueJobs#cancel</h1>
+<p>Find me in app/views/que_jobs/cancel.html.erb</p>
diff --git a/app/views/que_jobs/retry_now.html.erb b/app/views/que_jobs/retry_now.html.erb
new file mode 100644
index 0000000..1c8ecee
--- /dev/null
+++ b/app/views/que_jobs/retry_now.html.erb
@@ -0,0 +1,2 @@
+<h1>QueJobs#retry_now</h1>
+<p>Find me in app/views/que_jobs/retry_now.html.erb</p>