openshift setup is working

This commit is contained in:
Andrew Cantino 2014-10-05 01:13:47 -07:00
parent b466788bcc
commit b071f6170d
18 changed files with 323 additions and 113 deletions

View file

@ -3,3 +3,5 @@
# available. Otherwise it will execute while your application is stopped
# before the deploy step. This script gets executed directly, so it
# could be python, php, ruby, etc.
echo "-> Build step"

View file

@ -4,6 +4,41 @@
# up again. This script gets executed directly, so it could be python, php,
# ruby, etc.
echo "-> Deploy step"
pushd ${OPENSHIFT_REPO_DIR} > /dev/null
if [ -f ${OPENSHIFT_REPO_DIR}/.env.example ]
then
# Default to the environment variable values set in .env.example
# source ${OPENSHIFT_REPO_DIR}/.env.example
#
# grep = ${OPENSHIFT_REPO_DIR}/.env.example | sed -e 's/^#[^ ]//' | grep -v -e '^#' | cut -d= -f1 | \
# while read var ; do
# eval "echo \"$var=\\\"\${HUGINN_$var:-\$$var}\\\"\""
# done | grep -v -e ^= > ${OPENSHIFT_REPO_DIR}/.env
echo "DATABASE_NAME=${OPENSHIFT_APP_NAME}" > ${OPENSHIFT_REPO_DIR}/.env
echo "DATABASE_USERNAME=${OPENSHIFT_MYSQL_DB_USERNAME}" >> ${OPENSHIFT_REPO_DIR}/.env
echo "DATABASE_PASSWORD=${OPENSHIFT_MYSQL_DB_PASSWORD}" >> ${OPENSHIFT_REPO_DIR}/.env
echo "DATABASE_HOST=${OPENSHIFT_MYSQL_DB_HOST}" >> ${OPENSHIFT_REPO_DIR}/.env
echo "DATABASE_PORT=${OPENSHIFT_MYSQL_DB_PORT}" >> ${OPENSHIFT_REPO_DIR}/.env
echo "DATABASE_SOCKET=${OPENSHIFT_MYSQL_DB_SOCKET}" >> ${OPENSHIFT_REPO_DIR}/.env
chmod ugo+r ${OPENSHIFT_REPO_DIR}/.env
source ${OPENSHIFT_REPO_DIR}/.env
else
cat <<EOM
***
*
* WARNING: No .env.example file found.
*
***
EOM
fi
gem install bundler
echo "Migrating"
RAILS_ENV="production" bundle exec rake db:migrate
popd > /dev/null

View file

@ -2,3 +2,5 @@
# This is a simple post deploy hook executed after your application
# is deployed and started. This script gets executed directly, so
# it could be python, php, ruby, etc.
echo "-> Post deploy step"

View file

@ -13,3 +13,4 @@
# Application start and stop is subject to different timeouts
# throughout the system.
echo "-> Post start ruby step"

View file

@ -12,3 +12,5 @@
# prevent your application from stopping cleanly or starting at all.
# Application start and stop is subject to different timeouts
# throughout the system.
echo "-> Post stop ruby step"

View file

@ -4,6 +4,8 @@
# before the build step. This script gets executed directly, so it
# could be python, php, ruby, etc.
echo "-> Pre-build step"
STORED_ASSETS="${OPENSHIFT_DATA_DIR}/assets"
LIVE_ASSETS="${OPENSHIFT_REPO_DIR}/public/assets"

View file

@ -13,20 +13,16 @@
# Application start and stop is subject to different timeouts
# throughout the system.
echo "-> Pro start ruby step"
if [ -f ${OPENSHIFT_REPO_DIR}/.env.example ]
then
grep = ${OPENSHIFT_REPO_DIR}/.env.example | sed -e 's/^#[^ ]//' | grep -v -e '^#' | cut -d= -f1 | \
while read var ; do
eval "echo \"$var=\\\"\${$var:-\$$var}\\\"\""
done | grep -v -e ^= > ${OPENSHIFT_REPO_DIR}/.env
chmod ugo+r ${OPENSHIFT_REPO_DIR}/.env
source ${OPENSHIFT_REPO_DIR}/.env
else
cat <<EOM
***
*
* WARNING: No .env.example file found.
* WARNING: No .env file found.
*
***
EOM

View file

@ -12,3 +12,5 @@
# prevent your application from stopping cleanly or starting at all.
# Application start and stop is subject to different timeouts
# throughout the system.
echo "-> Pre stop ruby step"

View file

@ -66,7 +66,7 @@ module WebRequestConcern
module ClassMethods
def default_user_agent
ENV.fetch('DEFAULT_HTTP_USER_AGENT', Faraday.new.headers[:user_agent])
ENV.fetch('DEFAULT_HTTP_USER_AGENT', "Huginn - https://github.com/cantino/huginn")
end
end
end

View file

@ -1,5 +1,5 @@
class SystemMailer < ActionMailer::Base
default :from => ENV['EMAIL_FROM_ADDRESS'] || 'you@example.com'
default :from => ENV['EMAIL_FROM_ADDRESS'].presence || 'you@example.com'
def send_message(options)
@groups = options[:groups]

View file

@ -1,6 +1,6 @@
#!/usr/bin/env ruby
require 'open3'
require 'io/console'
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'setup_tools'))
include SetupTools
unless `which heroku` =~ /heroku/
puts "It looks like the heroku command line tool hasn't been installed yet. Please install"
@ -9,56 +9,25 @@ unless `which heroku` =~ /heroku/
exit 1
end
def capture(cmd, opts = {})
o, s = Open3.capture2e(cmd, opts)
o.strip
end
def ask(question, opts = {})
print question + " "
STDOUT.flush
(opts[:noecho] ? STDIN.noecho(&:gets) : gets).strip
end
def nag(question, opts = {})
answer = ''
while answer.length == 0
answer = ask(question, opts)
end
answer
end
def yes?(question)
ask(question + " (y/n)") =~ /^y/i
end
def grab_heroku_config!
config_data = capture("heroku config -s")
$config = {}
if config_data !~ /has no config vars/
config_data.split("\n").map do |line|
next if line =~ /^\s*(#|$)/ # skip comments and empty lines
first_equal_sign = line.index('=')
$config[line.slice(0, first_equal_sign)] = line.slice(first_equal_sign + 1, line.length)
end
grab_config_with_cmd!("heroku config -s")
end
def set_env(key, value)
capture("heroku config:set #{key}=#{value}")
end
def check_login!
unless File.exists?(File.expand_path("~/.netrc")) && File.read(File.expand_path("~/.netrc")) =~ /heroku/
puts "It looks like you need to log in to Heroku. Please run 'heroku auth:login' before continuing."
exit 1
end
puts "Welcome #{`heroku auth:whoami`.strip}! It looks like you're logged into Heroku."
puts
end
def set_value(key, value, options = {})
if $config[key].nil? || $config[key] == '' || ($config[key] != value && options[:force] != false)
puts "Setting #{key} to #{value}" unless options[:silent]
puts capture("heroku config:set #{key}=#{value}")
$config[key] = value
end
end
unless File.exists?(File.expand_path("~/.netrc")) && File.read(File.expand_path("~/.netrc")) =~ /heroku/
puts "It looks like you need to log in to Heroku. Please run 'heroku auth:login' before continuing."
exit 1
end
puts "Welcome #{`heroku auth:whoami`.strip}! It looks like you're logged into Heroku."
puts
check_login!
info = capture("heroku info")
if info =~ /No app specified/i
@ -74,26 +43,10 @@ if info =~ /No app specified/i
end
app_name = info.scan(/http:\/\/([\w\d-]+)\.herokuapp\.com/).flatten.first
unless yes?("Your Heroku app name is #{app_name}. Is this correct?")
puts "Well, then I'm not sure what to do here, sorry."
exit 1
end
confirm_app_name app_name
grab_heroku_config!
if $config.length > 0
puts
puts "Your current Heroku config:"
$config.each do |key, value|
puts ' ' + key + ' ' * (25 - [key.length, 25].min) + '= ' + value
end
end
unless $config['APP_SECRET_TOKEN']
puts "Setting up APP_SECRET_TOKEN..."
puts capture("heroku config:set APP_SECRET_TOKEN=`rake secret`")
end
print_config
set_defaults!
unless $config['DOMAIN']
set_value 'DOMAIN', "#{app_name}.herokuapp.com", force: false
@ -103,17 +56,6 @@ end
set_value 'BUILDPACK_URL', "https://github.com/ddollar/heroku-buildpack-multi.git"
set_value 'PROCFILE_PATH', "deployment/heroku/Procfile.heroku", force: false
set_value 'ON_HEROKU', "true"
set_value 'FORCE_SSL', "true"
set_value 'USE_GRAPHVIZ_DOT', 'dot'
unless $config['INVITATION_CODE']
puts "You need to set an invitation code for your Huginn instance. If you plan to share this instance, you will"
puts "tell this code to anyone who you'd like to invite. If you won't share it, then just set this to something"
puts "that people will not guess."
invitation_code = nag("What code would you like to use?")
set_value 'INVITATION_CODE', invitation_code
end
unless $config['SMTP_DOMAIN'] && $config['SMTP_USER_NAME'] && $config['SMTP_PASSWORD'] && $config['SMTP_SERVER'] && $config['EMAIL_FROM_ADDRESS']
puts "Okay, let's setup outgoing email settings. The simplest solution is to use the free sendgrid Heroku addon."

141
bin/setup_openshift Executable file
View file

@ -0,0 +1,141 @@
#!/usr/bin/env ruby
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'setup_tools'))
include SetupTools
if ARGV.length > 0
mode = ARGV.shift
else
mode = ''
end
unless `which rhc` =~ /rhc/
puts "It looks like the 'rhc' command line tool hasn't been installed yet. Please install"
puts "it with 'gem install rhc', run 'rhc setup', and then run this script again."
exit 1
end
def grab_openshift_config!
grab_config_with_cmd!("rhc env list")
end
def set_env(key, value)
capture("rhc env set #{key}=#{value}")
end
def check_login!
unless Dir[File.join(File.expand_path('~/.openshift'), 'token_*')].length > 0
puts "It looks like you need to log in to OpenShift. Please run 'rhc setup' before continuing a choose the option to 'Generate a token now'."
exit 1
end
puts "Welcome #{`rhc account`.scan(/Login (.*?) on /).first.first}! It looks like you're logged into OpenShift."
puts
end
check_login!
info = capture("rhc app show")
just_made = false
if info =~ /must specify an application/i
foreman_cartridge = 'http://cartreflect-claytondev.rhcloud.com/reflect?github=cantino/huginn-openshift-foreman-cartridge'
cmd = "rhc app create huginn ruby-2.0 mysql-5.5 #{foreman_cartridge} -s -r tmp-huginn"
puts "It looks like you don't have an OpenShift app set up yet for this repo. I can make one for you."
if yes?("Would you like me to create an OpenShift app for you now in this repo?")
puts `#{cmd}`
git_config = capture("git config --list -f tmp-huginn/.git/config").split("\n")
git_config.grep(/^rhc\./).each do |line|
path, value = line.split('=')
puts `git config #{path} #{value}`
end
url = git_config.grep(/^remote\.origin\.url/).first.split('=').last
puts "Adding remote #{url}"
puts `git remote add openshift #{url}`
puts "Removing tmp OpenShift repo"
puts `rm -rf ./tmp-huginn`
puts "Updating git"
puts `git fetch openshift`
info = capture("rhc app show")
just_made = true
else
puts "Okay, exiting so you can do it."
exit 0
end
elsif info =~ /Application '.*?' not found/
puts "It looks like you've deleted your OpenShift app. If that's the case, you should"
puts "edit .git/config and remove the sections under [rhc] and under [remote \"openshift\"]."
exit 1
end
app_name, app_url = info.scan(/^([\w\d]+) @ https?:\/\/([^\/ ]+)/i).flatten
confirm_app_name app_name unless just_made
grab_openshift_config!
print_config
set_defaults!
first_time = mode =~ /^first/i
unless $config['DOMAIN']
set_value 'DOMAIN', app_url, force: false
first_time = true
end
set_value 'BUNDLE_WITHOUT', 'development:test'
puts `rhc ssh huginn 'gem install bundler'`
puts
puts "To setup outbound email, we suggest using Gmail. See the 'Outgoing email settings' section in .env.example."
puts "You'll need to set those environment variables in OpenShift using 'rhc env set VARIABLE=VALUE'"
puts
branch = capture("git rev-parse --abbrev-ref HEAD")
if first_time || yes?("Should I push your current branch (#{branch}) to OpenShift?")
puts "This may take a moment..."
puts capture("git push openshift #{branch}:master -f")
end
if first_time
puts "Restarting..."
puts capture("rhc app restart")
puts capture("rhc cartridge restart foreman")
puts "Done!"
puts
puts
puts "I can make an admin user on your new Huginn instance and setup some example Agents."
if yes?("Should I create a new admin user and some example Agents?")
done = false
while !done
seed_email = nag "Okay, what is your email address?"
seed_username = nag "And what username would you like to login as?"
seed_password = nag "Finally, what password would you like to use?", noecho: true
puts "\nJust a moment..."
result = capture("rhc ssh huginn 'cd $OPENSHIFT_REPO_DIR && RAILS_ENV=production bundle exec rake db:seed SEED_EMAIL=#{seed_email} SEED_USERNAME=#{seed_username} SEED_PASSWORD=#{seed_password}'")
puts result
if result =~ /Validation failed/
puts "ERROR:"
puts
puts result
puts
else
done = true
end
end
puts
puts
puts "Okay, you should be all set! Visit http://#{app_url} and login as '#{seed_username}' with your password."
puts
puts "If you'd like to make more users, you can visit http://#{app_url}/users/sign_up and use the invitation code:"
else
puts
puts "Visit https://#{app_url}/users/sign_up and use the invitation code shown below:"
end
puts
puts "\t#{$config['INVITATION_CODE']}"
end
puts
puts "Done!"

View file

@ -18,7 +18,7 @@ module Huginn
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
config.time_zone = ENV['TIMEZONE'].present? ? ENV['TIMEZONE'] : "Pacific Time (US & Canada)"
config.time_zone = ENV['TIMEZONE'].presence || "Pacific Time (US & Canada)"
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]

View file

@ -1,37 +1,37 @@
development:
adapter: <%= ENV['DATABASE_ADAPTER'] || "mysql2" %>
encoding: <%= ENV['DATABASE_ENCODING'] || "utf8" %>
reconnect: <%= ENV['DATABASE_RECONNECT'] || "true" %>
database: <%= ENV['DATABASE_NAME'] || "huginn_development" %>
pool: <%= ENV['DATABASE_POOL'] || "5" %>
username: <%= ENV['DATABASE_USERNAME'] || "root" %>
adapter: <%= ENV['DATABASE_ADAPTER'].presence || "mysql2" %>
encoding: <%= ENV['DATABASE_ENCODING'].presence || "utf8" %>
reconnect: <%= ENV['DATABASE_RECONNECT'].presence || "true" %>
database: <%= ENV['DATABASE_NAME'].presence || "huginn_development" %>
pool: <%= ENV['DATABASE_POOL'].presence || "5" %>
username: <%= ENV['DATABASE_USERNAME'].presence || "root" %>
password: <%= ENV['DATABASE_PASSWORD'] || "" %>
host: <%= ENV['DATABASE_HOST'] || "" %>
port: <%= ENV['DATABASE_PORT'] || "" %>
socket: <%= ENV['DATABASE_SOCKET'] || ["/var/run/mysqld/mysqld.sock", "/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock"].find{ |path| File.exist? path } %>
socket: <%= ENV['DATABASE_SOCKET'] || ["/var/run/mysqld/mysqld.sock", "/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock"].find { |path| File.exist? path } %>
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: <%= ENV['DATABASE_ADAPTER'] || "mysql2" %>
database: <%= ENV['TEST_DATABASE_NAME'] || "huginn_test" %>
username: <%= ENV['DATABASE_USERNAME'] || "root" %>
password: <%= ENV['DATABASE_PASSWORD'] || "" %>
socket: <%= ENV['DATABASE_SOCKET'] || ["/var/run/mysqld/mysqld.sock", "/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock"].find{ |path| File.exist? path } %>
encoding: <%= ENV['DATABASE_ENCODING'] || "utf8" %>
reconnect: <%= ENV['DATABASE_RECONNECT'] || "true" %>
adapter: <%= ENV['DATABASE_ADAPTER'].presence || "mysql2" %>
encoding: <%= ENV['DATABASE_ENCODING'].presence || "utf8" %>
reconnect: <%= ENV['DATABASE_RECONNECT'].presence || "true" %>
database: <%= ENV['TEST_DATABASE_NAME'].presence || "huginn_test" %>
pool: <%= ENV['DATABASE_POOL'].presence || "5" %>
username: <%= ENV['DATABASE_USERNAME'].presence || "root" %>
password: <%= ENV['DATABASE_PASSWORD'].presence || "" %>
socket: <%= ENV['DATABASE_SOCKET'] || ["/var/run/mysqld/mysqld.sock", "/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock"].find { |path| File.exist? path } %>
port: <%= ENV['DATABASE_PORT'] || "" %>
pool: <%= ENV['DATABASE_POOL'] || "5" %>
production:
adapter: <%= ENV['DATABASE_ADAPTER'] || "mysql2" %>
encoding: <%= ENV['DATABASE_ENCODING'] || "utf8" %>
reconnect: <%= ENV['DATABASE_RECONNECT'] || "true" %>
database: <%= ENV['DATABASE_NAME'] || "huginn_production" %>
pool: <%= ENV['DATABASE_POOL'] || "5" %>
username: <%= ENV['DATABASE_USERNAME'] || "root" %>
password: <%= ENV['DATABASE_PASSWORD'] || "password" %>
adapter: <%= ENV['DATABASE_ADAPTER'].presence || "mysql2" %>
encoding: <%= ENV['DATABASE_ENCODING'].presence || "utf8" %>
reconnect: <%= ENV['DATABASE_RECONNECT'].presence || "true" %>
database: <%= ENV['DATABASE_NAME'].presence || "huginn_production" %>
pool: <%= ENV['DATABASE_POOL'].presence || "5" %>
username: <%= ENV['DATABASE_USERNAME'].presence || "root" %>
password: <%= ENV['DATABASE_PASSWORD'].presence || "password" %>
host: <%= ENV['DATABASE_HOST'] || "" %>
port: <%= ENV['DATABASE_PORT'] || "" %>
socket: <%= ENV['DATABASE_SOCKET'] || ["/var/run/mysqld/mysqld.sock", "/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock"].find{ |path| File.exist? path } %>

View file

@ -41,7 +41,7 @@ Huginn::Application.configure do
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = ENV['FORCE_SSL'].present? && ENV['FORCE_SSL'] == 'true' ? true : false
config.force_ssl = ENV['FORCE_SSL'] == 'true'
# See everything in the log (default is :info)
# config.log_level = :debug

View file

@ -18,7 +18,7 @@ Thread.new do
sleep 45
if ENV['DOMAIN']
force_ssl = ENV['FORCE_SSL'].present? && ENV['FORCE_SSL'] == 'true'
force_ssl = ENV['FORCE_SSL'] == 'true'
Net::HTTP.get_response(URI((force_ssl ? "https://" : "http://") + ENV['DOMAIN']))
end

View file

@ -106,7 +106,7 @@ class HuginnScheduler
end
def run!
tzinfo_friendly_timezone = ActiveSupport::TimeZone::MAPPING[ENV['TIMEZONE'].present? ? ENV['TIMEZONE'] : "Pacific Time (US & Canada)"]
tzinfo_friendly_timezone = ActiveSupport::TimeZone::MAPPING[ENV['TIMEZONE'].presence || "Pacific Time (US & Canada)"]
# Schedule event propagation.
@rufus_scheduler.every '1m' do

85
lib/setup_tools.rb Executable file
View file

@ -0,0 +1,85 @@
require 'open3'
require 'io/console'
require 'securerandom'
module SetupTools
def capture(cmd, opts = {})
o, s = Open3.capture2e(cmd, opts)
o.strip
end
def grab_config_with_cmd!(cmd)
config_data = capture(cmd)
$config = {}
if config_data !~ /has no config vars/
config_data.split("\n").map do |line|
next if line =~ /^\s*(#|$)/ # skip comments and empty lines
first_equal_sign = line.index('=')
raise "Invalid line found in config: #{line}" unless first_equal_sign
$config[line.slice(0, first_equal_sign)] = line.slice(first_equal_sign + 1, line.length)
end
end
end
def print_config
if $config.length > 0
puts
puts "Your current config:"
$config.each do |key, value|
puts ' ' + key + ' ' * (25 - [key.length, 25].min) + '= ' + value
end
end
end
def set_defaults!
unless $config['APP_SECRET_TOKEN']
puts "Setting up APP_SECRET_TOKEN..."
set_value 'APP_SECRET_TOKEN', SecureRandom.hex(64)
end
set_value 'RAILS_ENV', "production"
set_value 'FORCE_SSL', "true"
set_value 'USE_GRAPHVIZ_DOT', 'dot'
unless $config['INVITATION_CODE']
puts "You need to set an invitation code for your Huginn instance. If you plan to share this instance, you will"
puts "tell this code to anyone who you'd like to invite. If you won't share it, then just set this to something"
puts "that people will not guess."
invitation_code = nag("What code would you like to use?")
set_value 'INVITATION_CODE', invitation_code
end
end
def confirm_app_name(app_name)
unless yes?("Your app name is '#{app_name}'. Is this correct?")
puts "Well, then I'm not sure what to do here, sorry."
exit 1
end
end
# expects set_env(key, value) to be defined.
def set_value(key, value, options = {})
if $config[key].nil? || $config[key] == '' || ($config[key] != value && options[:force] != false)
puts "Setting #{key} to #{value}" unless options[:silent]
puts set_env(key, value)
$config[key] = value
end
end
def ask(question, opts = {})
print question + " "
STDOUT.flush
(opts[:noecho] ? STDIN.noecho(&:gets) : gets).strip
end
def nag(question, opts = {})
answer = ''
while answer.length == 0
answer = ask(question, opts)
end
answer
end
def yes?(question)
ask(question + " (y/n)") =~ /^y/i
end
end