Skip to content
This repository has been archived by the owner on Dec 31, 2022. It is now read-only.

Commit

Permalink
Merge 75bee10 into 3020734
Browse files Browse the repository at this point in the history
  • Loading branch information
olbrich committed Mar 8, 2021
2 parents 3020734 + 75bee10 commit 0a1bd0c
Show file tree
Hide file tree
Showing 14 changed files with 155 additions and 63 deletions.
8 changes: 8 additions & 0 deletions .rubocop.yml
Expand Up @@ -121,6 +121,14 @@ Metrics/AbcSize:
Metrics/BlockLength:
Enabled: false

Metrics/ClassLength:
Enabled: true
CountAsOne: ["array", "hash", "heredoc"]

Metrics/MethodLength:
Enabled: true
CountAsOne: ["array", "hash", "heredoc"]

Metrics/PerceivedComplexity:
Max: 10
Enabled: true
Expand Down
17 changes: 8 additions & 9 deletions Dockerfile
Expand Up @@ -5,8 +5,8 @@ RUN apt-get update && \
apt-get install --yes --no-install-recommends apt-transport-https && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN echo 'deb https://deb.nodesource.com/node_14.x buster main' > /etc/apt/sources.list.d/nodesource.list && \
curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \
RUN echo 'deb http://deb.nodesource.com/node_14.x buster main' > /etc/apt/sources.list.d/nodesource.list && \
curl -sk https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \
apt-get update && \
apt-get install --yes --target-release=buster --no-install-recommends build-essential git locales nodejs python3-pip python3-setuptools python3-sphinx python3-yaml && \
apt-get clean && \
Expand All @@ -18,7 +18,7 @@ RUN echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen
RUN locale-gen
ENV LC_ALL en_US.UTF-8

RUN curl -o /tmp/chefdk.deb https://packages.chef.io/files/stable/chefdk/1.6.11/debian/8/chefdk_1.6.11-1_amd64.deb && \
RUN curl -k -o /tmp/chefdk.deb https://packages.chef.io/files/stable/chefdk/1.6.11/debian/8/chefdk_1.6.11-1_amd64.deb && \
dpkg -i /tmp/chefdk.deb && \
rm -rf /tmp/chefdk.deb

Expand All @@ -36,14 +36,13 @@ RUN bundle install -j 4
COPY package.json $APP_HOME/
RUN npm install

COPY .chef.login $APP_HOME/
RUN mkdir -p /root/.chef
RUN printf "client_key \"/cookbooks/opsworks_ruby/client.pem\"\n" >> /root/.chef/knife.rb
RUN printf "node_name \"$(cat /cookbooks/opsworks_ruby/.chef.login)\"\n" >> /root/.chef/knife.rb
RUN printf "cookbook_path \"/cookbooks\"\n" >> /root/.chef/knife.rb
# COPY .chef.login $APP_HOME/
# RUN mkdir -p /root/.chef
# RUN printf "client_key \"/cookbooks/opsworks_ruby/client.pem\"\n" >> /root/.chef/knife.rb
# RUN printf "node_name \"$(cat /cookbooks/opsworks_ruby/.chef.login)\"\n" >> /root/.chef/knife.rb
# RUN printf "cookbook_path \"/cookbooks\"\n" >> /root/.chef/knife.rb

COPY README.md $APP_HOME/
COPY metadata.rb $APP_HOME/
COPY Berksfile* $APP_HOME/
RUN chef exec berks

45 changes: 40 additions & 5 deletions libraries/drivers_appserver_base.rb
Expand Up @@ -7,7 +7,9 @@ class Base < Drivers::Base
include Drivers::Dsl::Output
include Drivers::Dsl::Packages

# Hook function called from the 'setup' recipe.
def setup
super
handle_packages
end

Expand All @@ -17,6 +19,7 @@ def configure
end

def before_deploy
super
setup_application_yml
setup_dot_env
end
Expand All @@ -37,18 +40,30 @@ def appserver_config
raise NotImplementedError
end

# Creates a monit config file for managing the appserver and then notifies
# monit to reload it.
def add_appserver_monit
opts = { app_shortname: app['shortname'], appserver_name: adapter, appserver_command: appserver_command,
deploy_to: deploy_dir(app), environment: environment }

file_path = File.join(node['monit']['basedir'], "#{opts[:appserver_name]}_#{opts[:app_shortname]}.monitrc")
opts = {
app_shortname: app['shortname'],
adapter: adapter,
appserver_command: appserver_command,
appserver_name: adapter,
deploy_to: deploy_dir(app),
environment: environment,
source_cookbook: appserver_monit_template_cookbook
}
file_path = File.join(node['monit']['basedir'],
"#{opts[:appserver_name]}_#{opts[:app_shortname]}.monitrc")
context.template file_path do
mode '0640'
source 'appserver.monitrc.erb'
source "#{opts[:adapter]}.monitrc.erb"
cookbook opts[:source_cookbook].to_s
variables opts
notifies :run, 'execute[monit reload]', :immediately
end
end

# Immediately attempts to restart the appserver using monit.
def restart_monit
return if ENV['TEST_KITCHEN'] # Don't like it, but we can't run multiple processes in Docker on travis

Expand All @@ -63,8 +78,28 @@ def unmonitor_monit
end
end

# Invoke the monit start command for the appserver. This may only be
# needed during the initial setup of the instance. After that the
# 'restart' command is sufficient.
def start_monit
context.execute "monit start #{adapter}_#{app['shortname']}" do
retries 3
end
end

private

# Overriding the appserver monit configs can be useful to provide more
# fine-grained control over how the appserver starts, stops and restarts.
# It can also allow additional configuration to provide alerting.
#
# @return [String] configured cookbook to pull custom appserver monit
# configs from. Defaults to `opsworks_ruby`.
def appserver_monit_template_cookbook
node['deploy'][app['shortname']].try(:[], driver_type).try(:[],
'monit_template_cookbook') || context.cookbook_name
end

def add_appserver_config
opts = { deploy_dir: deploy_dir(app), out: out, deploy_env: deploy_env,
webserver: Drivers::Webserver::Factory.build(context, app).adapter,
Expand Down
25 changes: 25 additions & 0 deletions libraries/drivers_appserver_puma.rb
Expand Up @@ -18,6 +18,7 @@ def configure
def after_deploy
super
restart_monit
start_monit
end

def after_undeploy
Expand All @@ -33,6 +34,30 @@ def appserver_config
'puma.rb'
end

# Invoke the monit start command for the appserver. This may only be
# needed during the initial setup of the instance. After that the
# 'restart' command is sufficient. If puma is already running this
# resource will not do anything.
def start_monit
pidfile = "/var/run/lock/#{app['shortname']}/puma.pid"
context.execute "monit start #{adapter}_#{app['shortname']}" do
retries 3
creates pidfile
end
end

# Immediately attempts to restart the appserver using monit. Do not
# attempt a restart if the pid file doesn't exist
def restart_monit
return if ENV['TEST_KITCHEN'] # Don't like it, but we can't run multiple processes in Docker on travis

pidfile = "/var/run/lock/#{app['shortname']}/puma.pid"
context.execute "monit restart #{adapter}_#{app['shortname']}" do
retries 3
only_if { ::File.exist?(pidfile) }
end
end

def appserver_command
"bundle exec puma -C #{deploy_dir(app)}/shared/config/puma.rb"
end
Expand Down
2 changes: 1 addition & 1 deletion libraries/drivers_webserver_base.rb
Expand Up @@ -2,7 +2,7 @@

module Drivers
module Webserver
class Base < Drivers::Base # rubocop:disable Metrics/ClassLength
class Base < Drivers::Base
include Drivers::Dsl::Logrotate
include Drivers::Dsl::Notifies
include Drivers::Dsl::Output
Expand Down
20 changes: 16 additions & 4 deletions libraries/drivers_worker_base.rb
Expand Up @@ -7,23 +7,35 @@ class Base < Drivers::Base
include Drivers::Dsl::Packages

def setup
super
handle_packages
end

def validate_app_engine; end

protected

# Adds or updates the monit configs for the worker and notifies monit to
# reload the configuration.
def add_worker_monit
opts = { application: app['shortname'], name: app['name'], out: out, deploy_to: deploy_dir(app),
environment: environment, adapter: adapter, app_shortname: app['shortname'],
source_cookbook: worker_monit_template_cookbook }
opts = {
adapter: adapter,
app_shortname: app['shortname'],
application: app['shortname'],
deploy_to: deploy_dir(app),
environment: environment,
name: app['name'],
out: out,
source_cookbook: worker_monit_template_cookbook
}

context.template File.join(node['monit']['basedir'], "#{opts[:adapter]}_#{opts[:application]}.monitrc") do
context.template File.join(node['monit']['basedir'],
"#{opts[:adapter]}_#{opts[:application]}.monitrc") do
mode '0640'
source "#{opts[:adapter]}.monitrc.erb"
cookbook opts[:source_cookbook].to_s
variables opts
notifies :run, 'execute[monit reload]', :immediately
end
end

Expand Down
1 change: 1 addition & 0 deletions recipes/configure.rb
Expand Up @@ -37,6 +37,7 @@
fire_hook(:configure, items: databases + [source, framework, appserver, worker, webserver])

execute 'monit reload' do
action :nothing
only_if 'which monit'
end
end
6 changes: 6 additions & 0 deletions recipes/setup.rb
Expand Up @@ -197,3 +197,9 @@

fire_hook(:setup, items: databases + [source, framework, appserver, worker, webserver])
end

# setup hooks for appservers and workers may need to reload monit configs
execute 'monit reload' do
action :nothing
only_if 'which monit'
end
2 changes: 0 additions & 2 deletions spec/fixtures/aws_opsworks_app.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# rubocop:disable Metrics/MethodLength
def aws_opsworks_app(override = {})
item = {
app_id: '3aef37c1-7e2b-4255-bbf1-03e06f07701a',
Expand Down Expand Up @@ -41,4 +40,3 @@ def aws_opsworks_app(override = {})

JSON.parse(item.to_json)
end
# rubocop:enable Metrics/MethodLength
2 changes: 0 additions & 2 deletions spec/fixtures/aws_opsworks_rds_db_instance.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# rubocop:disable Metrics/MethodLength
def aws_opsworks_rds_db_instance(override = {})
item = {
rds_db_instance_arn: 'arn:aws:rds:us-west-2:850906259207:db:dummy-project',
Expand All @@ -17,4 +16,3 @@ def aws_opsworks_rds_db_instance(override = {})

JSON.parse(item.to_json)
end
# rubocop:enable Metrics/MethodLength
72 changes: 32 additions & 40 deletions spec/unit/recipes/configure_spec.rb
Expand Up @@ -393,7 +393,9 @@
expect(chef_run_rhel)
.to render_file("/etc/monit.d/sidekiq_#{aws_opsworks_app['shortname']}.monitrc")
.with_content('group sidekiq_dummy_project_group')
expect(chef_run_rhel).to run_execute('monit reload')
expect(
chef_run_rhel.template("/etc/monit.d/sidekiq_#{aws_opsworks_app['shortname']}.monitrc")
).to notify('execute[monit reload]')
end

it 'creates unicorn.monitrc conf' do
Expand Down Expand Up @@ -465,7 +467,9 @@
expect(chef_run)
.to render_file("/etc/monit/conf.d/sidekiq_#{aws_opsworks_app['shortname']}.monitrc")
.with_content('group sidekiq_dummy_project_group')
expect(chef_run).to run_execute('monit reload')
expect(
chef_run.template("/etc/monit/conf.d/sidekiq_#{aws_opsworks_app['shortname']}.monitrc")
).to notify('execute[monit reload]')
end

it 'creates unicorn.monitrc conf' do
Expand Down Expand Up @@ -739,7 +743,9 @@
expect(chef_run)
.to render_file("/etc/monit/conf.d/resque_#{aws_opsworks_app['shortname']}.monitrc")
.with_content('group resque_dummy_project_group')
expect(chef_run).to run_execute('monit reload')
expect(
chef_run.template("/etc/monit/conf.d/resque_#{aws_opsworks_app['shortname']}.monitrc")
).to notify('execute[monit reload]')
end

it 'creates puma.monitrc conf' do
Expand All @@ -749,23 +755,13 @@
.with_content('check process puma_dummy_project with pidfile /run/lock/dummy_project/puma.pid')
expect(chef_run)
.to render_file("/etc/monit/conf.d/puma_#{aws_opsworks_app['shortname']}.monitrc")
.with_content(
'start program = "/bin/sh -c \'cd /srv/www/dummy_project/current && ENV_VAR1="test" ' \
'ENV_VAR2="some data" HANAMI_ENV="staging" DATABASE_URL="mysql2://dbuser:03c1bc98cdd5eb2f9c75@' \
'dummy-project.c298jfowejf.us-west-2.rds.amazon.com:3265/dummydb" ' \
'HOME="/home/deploy" USER="deploy" bundle exec puma ' \
'-C /srv/www/dummy_project/shared/config/puma.rb ' \
'| logger -t puma-dummy_project\'" as uid "deploy" and gid "deploy" with timeout 90 seconds'
)
expect(chef_run)
.to render_file("/etc/monit/conf.d/puma_#{aws_opsworks_app['shortname']}.monitrc")
.with_content(
'stop program = "/bin/sh -c \'cat /run/lock/dummy_project/puma.pid ' \
'| xargs --no-run-if-empty kill -QUIT; sleep 5\'" as uid "deploy" and gid "deploy"'
)
expect(chef_run)
.to render_file("/etc/monit/conf.d/puma_#{aws_opsworks_app['shortname']}.monitrc")
.with_content('group puma_dummy_project_group')
.with_content <<~MONITRC
check process puma_dummy_project with pidfile /run/lock/dummy_project/puma.pid
start program = "/bin/sh -c 'cd /srv/www/dummy_project/current && ENV_VAR1="test" ENV_VAR2="some data" HANAMI_ENV="staging" DATABASE_URL="mysql2://dbuser:03c1bc98cdd5eb2f9c75@dummy-project.c298jfowejf.us-west-2.rds.amazon.com:3265/dummydb" HOME="/home/deploy" USER="deploy" bin/pumactl -F /srv/www/dummy_project/shared/config/puma.rb start | logger -t puma-dummy_project'" as uid "deploy" and gid "deploy" with timeout 90 seconds
restart program = "/bin/sh -c 'cd /srv/www/dummy_project/current && ENV_VAR1="test" ENV_VAR2="some data" HANAMI_ENV="staging" DATABASE_URL="mysql2://dbuser:03c1bc98cdd5eb2f9c75@dummy-project.c298jfowejf.us-west-2.rds.amazon.com:3265/dummydb" HOME="/home/deploy" USER="deploy" bin/pumactl -F /srv/www/dummy_project/shared/config/puma.rb restart | logger -t puma-dummy_project'" as uid "deploy" and gid "deploy" with timeout 90 seconds
stop program = "/bin/sh -c 'cd /srv/www/dummy_project/current && ENV_VAR1="test" ENV_VAR2="some data" HANAMI_ENV="staging" DATABASE_URL="mysql2://dbuser:03c1bc98cdd5eb2f9c75@dummy-project.c298jfowejf.us-west-2.rds.amazon.com:3265/dummydb" HOME="/home/deploy" USER="deploy" bin/pumactl -F /srv/www/dummy_project/shared/config/puma.rb stop | logger -t puma-dummy_project'" as uid "deploy" and gid "deploy" with timeout 90 seconds
group puma_dummy_project_group
MONITRC
end

context 'rhel' do
Expand Down Expand Up @@ -832,7 +828,9 @@
expect(chef_run_rhel)
.to render_file("/etc/monit.d/resque_#{aws_opsworks_app['shortname']}.monitrc")
.with_content('group resque_dummy_project_group')
expect(chef_run_rhel).to run_execute('monit reload')
expect(
chef_run_rhel.template("/etc/monit.d/resque_#{aws_opsworks_app['shortname']}.monitrc")
).to notify('execute[monit reload]')
end

it 'renders apache2 configuration files in proper place' do
Expand All @@ -858,23 +856,13 @@
.with_content('check process puma_dummy_project with pidfile /run/lock/dummy_project/puma.pid')
expect(chef_run_rhel)
.to render_file("/etc/monit.d/puma_#{aws_opsworks_app['shortname']}.monitrc")
.with_content(
'start program = "/bin/sh -c \'cd /srv/www/dummy_project/current && ENV_VAR1="test" ' \
'ENV_VAR2="some data" HANAMI_ENV="staging" DATABASE_URL="mysql2://dbuser:03c1bc98cdd5eb2f9c75@' \
'dummy-project.c298jfowejf.us-west-2.rds.amazon.com:3265/dummydb" ' \
'HOME="/home/deploy" USER="deploy" bundle exec puma ' \
'-C /srv/www/dummy_project/shared/config/puma.rb ' \
'| logger -t puma-dummy_project\'" as uid "deploy" and gid "deploy" with timeout 90 seconds'
)
expect(chef_run_rhel)
.to render_file("/etc/monit.d/puma_#{aws_opsworks_app['shortname']}.monitrc")
.with_content(
'stop program = "/bin/sh -c \'cat /run/lock/dummy_project/puma.pid ' \
'| xargs --no-run-if-empty kill -QUIT; sleep 5\'" as uid "deploy" and gid "deploy"'
)
expect(chef_run_rhel)
.to render_file("/etc/monit.d/puma_#{aws_opsworks_app['shortname']}.monitrc")
.with_content('group puma_dummy_project_group')
.with_content <<~MONITRC
check process puma_dummy_project with pidfile /run/lock/dummy_project/puma.pid
start program = "/bin/sh -c 'cd /srv/www/dummy_project/current && ENV_VAR1="test" ENV_VAR2="some data" HANAMI_ENV="staging" DATABASE_URL="mysql2://dbuser:03c1bc98cdd5eb2f9c75@dummy-project.c298jfowejf.us-west-2.rds.amazon.com:3265/dummydb" HOME="/home/deploy" USER="deploy" bin/pumactl -F /srv/www/dummy_project/shared/config/puma.rb start | logger -t puma-dummy_project'" as uid "deploy" and gid "deploy" with timeout 90 seconds
restart program = "/bin/sh -c 'cd /srv/www/dummy_project/current && ENV_VAR1="test" ENV_VAR2="some data" HANAMI_ENV="staging" DATABASE_URL="mysql2://dbuser:03c1bc98cdd5eb2f9c75@dummy-project.c298jfowejf.us-west-2.rds.amazon.com:3265/dummydb" HOME="/home/deploy" USER="deploy" bin/pumactl -F /srv/www/dummy_project/shared/config/puma.rb restart | logger -t puma-dummy_project'" as uid "deploy" and gid "deploy" with timeout 90 seconds
stop program = "/bin/sh -c 'cd /srv/www/dummy_project/current && ENV_VAR1="test" ENV_VAR2="some data" HANAMI_ENV="staging" DATABASE_URL="mysql2://dbuser:03c1bc98cdd5eb2f9c75@dummy-project.c298jfowejf.us-west-2.rds.amazon.com:3265/dummydb" HOME="/home/deploy" USER="deploy" bin/pumactl -F /srv/www/dummy_project/shared/config/puma.rb stop | logger -t puma-dummy_project'" as uid "deploy" and gid "deploy" with timeout 90 seconds
group puma_dummy_project_group
MONITRC
end
end
end
Expand Down Expand Up @@ -1164,7 +1152,9 @@
expect(chef_run)
.to render_file("/etc/monit/conf.d/delayed_job_#{aws_opsworks_app['shortname']}.monitrc")
.with_content('group delayed_job_dummy_project_group')
expect(chef_run).to run_execute('monit reload')
expect(
chef_run.template("/etc/monit/conf.d/delayed_job_#{aws_opsworks_app['shortname']}.monitrc")
).to notify('execute[monit reload]')
end

it 'creates thin.monitrc conf' do
Expand Down Expand Up @@ -1247,7 +1237,9 @@
expect(chef_run_rhel)
.to render_file("/etc/monit.d/delayed_job_#{aws_opsworks_app['shortname']}.monitrc")
.with_content('group delayed_job_dummy_project_group')
expect(chef_run_rhel).to run_execute('monit reload')
expect(
chef_run_rhel.template("/etc/monit.d/delayed_job_#{aws_opsworks_app['shortname']}.monitrc")
).to notify('execute[monit reload]')
end

it 'creates thin.monitrc conf' do
Expand Down

0 comments on commit 0a1bd0c

Please sign in to comment.