@@ -0,0 +1,7 @@ |
||
| 1 |
+#!/bin/bash |
|
| 2 |
+# This is a simple build script and will be executed on your CI system if |
|
| 3 |
+# available. Otherwise it will execute while your application is stopped |
|
| 4 |
+# before the deploy step. This script gets executed directly, so it |
|
| 5 |
+# could be python, php, ruby, etc. |
|
| 6 |
+ |
|
| 7 |
+echo "-> Build step" |
@@ -0,0 +1,25 @@ |
||
| 1 |
+#!/bin/bash |
|
| 2 |
+# This deploy hook gets executed after dependencies are resolved and the |
|
| 3 |
+# build hook has been run but before the application has been started back |
|
| 4 |
+# up again. This script gets executed directly, so it could be python, php, |
|
| 5 |
+# ruby, etc. |
|
| 6 |
+ |
|
| 7 |
+echo "-> Deploy step" |
|
| 8 |
+ |
|
| 9 |
+pushd ${OPENSHIFT_REPO_DIR} > /dev/null
|
|
| 10 |
+ |
|
| 11 |
+echo "DATABASE_NAME=${OPENSHIFT_APP_NAME}" > ${OPENSHIFT_REPO_DIR}/.env
|
|
| 12 |
+echo "DATABASE_USERNAME=${OPENSHIFT_MYSQL_DB_USERNAME}" >> ${OPENSHIFT_REPO_DIR}/.env
|
|
| 13 |
+echo "DATABASE_PASSWORD=${OPENSHIFT_MYSQL_DB_PASSWORD}" >> ${OPENSHIFT_REPO_DIR}/.env
|
|
| 14 |
+echo "DATABASE_HOST=${OPENSHIFT_MYSQL_DB_HOST}" >> ${OPENSHIFT_REPO_DIR}/.env
|
|
| 15 |
+echo "DATABASE_PORT=${OPENSHIFT_MYSQL_DB_PORT}" >> ${OPENSHIFT_REPO_DIR}/.env
|
|
| 16 |
+echo "DATABASE_SOCKET=${OPENSHIFT_MYSQL_DB_SOCKET}" >> ${OPENSHIFT_REPO_DIR}/.env
|
|
| 17 |
+ |
|
| 18 |
+chmod ugo+r ${OPENSHIFT_REPO_DIR}/.env
|
|
| 19 |
+ |
|
| 20 |
+source ${OPENSHIFT_REPO_DIR}/.env
|
|
| 21 |
+ |
|
| 22 |
+gem install bundler |
|
| 23 |
+echo "Migrating" |
|
| 24 |
+RAILS_ENV="production" bundle exec rake db:migrate |
|
| 25 |
+popd > /dev/null |
@@ -0,0 +1,6 @@ |
||
| 1 |
+#!/bin/bash |
|
| 2 |
+# This is a simple post deploy hook executed after your application |
|
| 3 |
+# is deployed and started. This script gets executed directly, so |
|
| 4 |
+# it could be python, php, ruby, etc. |
|
| 5 |
+ |
|
| 6 |
+echo "-> Post deploy step" |
@@ -0,0 +1,16 @@ |
||
| 1 |
+#!/bin/bash |
|
| 2 |
+ |
|
| 3 |
+# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED* |
|
| 4 |
+# immediately before (re)starting or stopping the specified cartridge. |
|
| 5 |
+# They are able to make any desired environment variable changes as |
|
| 6 |
+# well as other adjustments to the application environment. |
|
| 7 |
+ |
|
| 8 |
+# The post_start_cartridge and post_stop_cartridge hooks are executed |
|
| 9 |
+# immediately after (re)starting or stopping the specified cartridge. |
|
| 10 |
+ |
|
| 11 |
+# Exercise caution when adding commands to these hooks. They can |
|
| 12 |
+# prevent your application from stopping cleanly or starting at all. |
|
| 13 |
+# Application start and stop is subject to different timeouts |
|
| 14 |
+# throughout the system. |
|
| 15 |
+ |
|
| 16 |
+echo "-> Post start ruby step" |
@@ -0,0 +1,16 @@ |
||
| 1 |
+#!/bin/bash |
|
| 2 |
+ |
|
| 3 |
+# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED* |
|
| 4 |
+# immediately before (re)starting or stopping the specified cartridge. |
|
| 5 |
+# They are able to make any desired environment variable changes as |
|
| 6 |
+# well as other adjustments to the application environment. |
|
| 7 |
+ |
|
| 8 |
+# The post_start_cartridge and post_stop_cartridge hooks are executed |
|
| 9 |
+# immediately after (re)starting or stopping the specified cartridge. |
|
| 10 |
+ |
|
| 11 |
+# Exercise caution when adding commands to these hooks. They can |
|
| 12 |
+# prevent your application from stopping cleanly or starting at all. |
|
| 13 |
+# Application start and stop is subject to different timeouts |
|
| 14 |
+# throughout the system. |
|
| 15 |
+ |
|
| 16 |
+echo "-> Post stop ruby step" |
@@ -0,0 +1,24 @@ |
||
| 1 |
+#!/bin/bash |
|
| 2 |
+# This is a simple script and will be executed on your CI system if |
|
| 3 |
+# available. Otherwise it will execute while your application is stopped |
|
| 4 |
+# before the build step. This script gets executed directly, so it |
|
| 5 |
+# could be python, php, ruby, etc. |
|
| 6 |
+ |
|
| 7 |
+echo "-> Pre-build step" |
|
| 8 |
+ |
|
| 9 |
+STORED_ASSETS="${OPENSHIFT_DATA_DIR}/assets"
|
|
| 10 |
+LIVE_ASSETS="${OPENSHIFT_REPO_DIR}/public/assets"
|
|
| 11 |
+ |
|
| 12 |
+# Ensure our stored assets directory exists |
|
| 13 |
+if [ ! -d "${STORED_ASSETS}" ]; then
|
|
| 14 |
+ echo " Creating permanent assets directory" |
|
| 15 |
+ mkdir "${STORED_ASSETS}"
|
|
| 16 |
+fi |
|
| 17 |
+ |
|
| 18 |
+# Create symlink to stored assets unless we're uploading our own assets |
|
| 19 |
+if [ -d "${LIVE_ASSETS}" ]; then
|
|
| 20 |
+ echo " WARNING: Assets included in git repository, not using stored assets" |
|
| 21 |
+else |
|
| 22 |
+ echo " Restoring stored assets" |
|
| 23 |
+ ln -s "${STORED_ASSETS}" "${LIVE_ASSETS}"
|
|
| 24 |
+fi |
@@ -0,0 +1,21 @@ |
||
| 1 |
+#!/bin/bash |
|
| 2 |
+ |
|
| 3 |
+# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED* |
|
| 4 |
+# immediately before (re)starting or stopping the specified cartridge. |
|
| 5 |
+# They are able to make any desired environment variable changes as |
|
| 6 |
+# well as other adjustments to the application environment. |
|
| 7 |
+ |
|
| 8 |
+# The post_start_cartridge and post_stop_cartridge hooks are executed |
|
| 9 |
+# immediately after (re)starting or stopping the specified cartridge. |
|
| 10 |
+ |
|
| 11 |
+# Exercise caution when adding commands to these hooks. They can |
|
| 12 |
+# prevent your application from stopping cleanly or starting at all. |
|
| 13 |
+# Application start and stop is subject to different timeouts |
|
| 14 |
+# throughout the system. |
|
| 15 |
+ |
|
| 16 |
+echo "-> Pro start ruby step" |
|
| 17 |
+ |
|
| 18 |
+if [ -f ${OPENSHIFT_REPO_DIR}/.env ]
|
|
| 19 |
+then |
|
| 20 |
+ source ${OPENSHIFT_REPO_DIR}/.env
|
|
| 21 |
+fi |
@@ -0,0 +1,16 @@ |
||
| 1 |
+#!/bin/bash |
|
| 2 |
+ |
|
| 3 |
+# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED* |
|
| 4 |
+# immediately before (re)starting or stopping the specified cartridge. |
|
| 5 |
+# They are able to make any desired environment variable changes as |
|
| 6 |
+# well as other adjustments to the application environment. |
|
| 7 |
+ |
|
| 8 |
+# The post_start_cartridge and post_stop_cartridge hooks are executed |
|
| 9 |
+# immediately after (re)starting or stopping the specified cartridge. |
|
| 10 |
+ |
|
| 11 |
+# Exercise caution when adding commands to these hooks. They can |
|
| 12 |
+# prevent your application from stopping cleanly or starting at all. |
|
| 13 |
+# Application start and stop is subject to different timeouts |
|
| 14 |
+# throughout the system. |
|
| 15 |
+ |
|
| 16 |
+echo "-> Pre stop ruby step" |
@@ -0,0 +1,22 @@ |
||
| 1 |
+Run scripts or jobs on a periodic basis |
|
| 2 |
+======================================= |
|
| 3 |
+Any scripts or jobs added to the minutely, hourly, daily, weekly or monthly |
|
| 4 |
+directories will be run on a scheduled basis (frequency is as indicated by the |
|
| 5 |
+name of the directory) using run-parts. |
|
| 6 |
+ |
|
| 7 |
+run-parts ignores any files that are hidden or dotfiles (.*) or backup |
|
| 8 |
+files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved}
|
|
| 9 |
+ |
|
| 10 |
+The presence of two specially named files jobs.deny and jobs.allow controls |
|
| 11 |
+how run-parts executes your scripts/jobs. |
|
| 12 |
+ jobs.deny ===> Prevents specific scripts or jobs from being executed. |
|
| 13 |
+ jobs.allow ===> Only execute the named scripts or jobs (all other/non-named |
|
| 14 |
+ scripts that exist in this directory are ignored). |
|
| 15 |
+ |
|
| 16 |
+The principles of jobs.deny and jobs.allow are the same as those of cron.deny |
|
| 17 |
+and cron.allow and are described in detail at: |
|
| 18 |
+ http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-Automating_System_Tasks.html#s2-autotasks-cron-access |
|
| 19 |
+ |
|
| 20 |
+See: man crontab or above link for more details and see the the weekly/ |
|
| 21 |
+ directory for an example. |
|
| 22 |
+ |
@@ -0,0 +1,16 @@ |
||
| 1 |
+Run scripts or jobs on a weekly basis |
|
| 2 |
+===================================== |
|
| 3 |
+Any scripts or jobs added to this directory will be run on a scheduled basis |
|
| 4 |
+(weekly) using run-parts. |
|
| 5 |
+ |
|
| 6 |
+run-parts ignores any files that are hidden or dotfiles (.*) or backup |
|
| 7 |
+files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} and handles
|
|
| 8 |
+the files named jobs.deny and jobs.allow specially. |
|
| 9 |
+ |
|
| 10 |
+In this specific example, the chronograph script is the only script or job file |
|
| 11 |
+executed on a weekly basis (due to white-listing it in jobs.allow). And the |
|
| 12 |
+README and chrono.dat file are ignored either as a result of being black-listed |
|
| 13 |
+in jobs.deny or because they are NOT white-listed in the jobs.allow file. |
|
| 14 |
+ |
|
| 15 |
+For more details, please see ../README.cron file. |
|
| 16 |
+ |
@@ -0,0 +1 @@ |
||
| 1 |
+Time And Relative D...n In Execution (Open)Shift! |
@@ -0,0 +1,3 @@ |
||
| 1 |
+#!/bin/bash |
|
| 2 |
+ |
|
| 3 |
+echo "`date`: `cat $(dirname \"$0\")/chrono.dat`" |
@@ -0,0 +1,12 @@ |
||
| 1 |
+# |
|
| 2 |
+# Script or job files listed in here (one entry per line) will be |
|
| 3 |
+# executed on a weekly-basis. |
|
| 4 |
+# |
|
| 5 |
+# Example: The chronograph script will be executed weekly but the README |
|
| 6 |
+# and chrono.dat files in this directory will be ignored. |
|
| 7 |
+# |
|
| 8 |
+# The README file is actually ignored due to the entry in the |
|
| 9 |
+# jobs.deny which is checked before jobs.allow (this file). |
|
| 10 |
+# |
|
| 11 |
+chronograph |
|
| 12 |
+ |
@@ -0,0 +1,7 @@ |
||
| 1 |
+# |
|
| 2 |
+# Any script or job files listed in here (one entry per line) will NOT be |
|
| 3 |
+# executed (read as ignored by run-parts). |
|
| 4 |
+# |
|
| 5 |
+ |
|
| 6 |
+README |
|
| 7 |
+ |
@@ -0,0 +1,8 @@ |
||
| 1 |
+Markers |
|
| 2 |
+=========== |
|
| 3 |
+ |
|
| 4 |
+Adding marker files to this directory will have the following effects: |
|
| 5 |
+ |
|
| 6 |
+force_clean_build - Previous output from bundle install --deployment will be |
|
| 7 |
+ removed and all gems will be reinstalled according to the current |
|
| 8 |
+ Gemfile/Gemfile.lock. |
@@ -66,7 +66,7 @@ module WebRequestConcern |
||
| 66 | 66 |
|
| 67 | 67 |
module ClassMethods |
| 68 | 68 |
def default_user_agent |
| 69 |
- ENV.fetch('DEFAULT_HTTP_USER_AGENT', Faraday.new.headers[:user_agent])
|
|
| 69 |
+ ENV.fetch('DEFAULT_HTTP_USER_AGENT', "Huginn - https://github.com/cantino/huginn")
|
|
| 70 | 70 |
end |
| 71 | 71 |
end |
| 72 | 72 |
end |
@@ -1,5 +1,5 @@ |
||
| 1 | 1 |
class SystemMailer < ActionMailer::Base |
| 2 |
- default :from => ENV['EMAIL_FROM_ADDRESS'] || 'you@example.com' |
|
| 2 |
+ default :from => ENV['EMAIL_FROM_ADDRESS'].presence || 'you@example.com' |
|
| 3 | 3 |
|
| 4 | 4 |
def send_message(options) |
| 5 | 5 |
@groups = options[:groups] |
@@ -1,6 +1,6 @@ |
||
| 1 | 1 |
#!/usr/bin/env ruby |
| 2 |
-require 'open3' |
|
| 3 |
-require 'io/console' |
|
| 2 |
+require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'setup_tools')) |
|
| 3 |
+include SetupTools |
|
| 4 | 4 |
|
| 5 | 5 |
unless `which heroku` =~ /heroku/ |
| 6 | 6 |
puts "It looks like the heroku command line tool hasn't been installed yet. Please install" |
@@ -9,60 +9,25 @@ unless `which heroku` =~ /heroku/ |
||
| 9 | 9 |
exit 1 |
| 10 | 10 |
end |
| 11 | 11 |
|
| 12 |
-def capture(cmd, opts = {})
|
|
| 13 |
- if opts.delete(:no_stderr) |
|
| 14 |
- o, s = Open3.capture2(cmd, opts) |
|
| 15 |
- else |
|
| 16 |
- o, s = Open3.capture2e(cmd, opts) |
|
| 17 |
- end |
|
| 18 |
- o.strip |
|
| 19 |
-end |
|
| 20 |
- |
|
| 21 |
-def ask(question, opts = {})
|
|
| 22 |
- print question + " " |
|
| 23 |
- STDOUT.flush |
|
| 24 |
- (opts[:noecho] ? STDIN.noecho(&:gets) : gets).strip |
|
| 25 |
-end |
|
| 26 |
- |
|
| 27 |
-def nag(question, opts = {})
|
|
| 28 |
- answer = '' |
|
| 29 |
- while answer.length == 0 |
|
| 30 |
- answer = ask(question, opts) |
|
| 31 |
- end |
|
| 32 |
- answer |
|
| 12 |
+def grab_heroku_config! |
|
| 13 |
+ grab_config_with_cmd!("heroku config -s", no_stderr: true)
|
|
| 33 | 14 |
end |
| 34 | 15 |
|
| 35 |
-def yes?(question) |
|
| 36 |
- ask(question + " (y/n)") =~ /^y/i |
|
| 16 |
+def set_env(key, value) |
|
| 17 |
+ capture("heroku config:set #{key}=#{value}")
|
|
| 37 | 18 |
end |
| 38 | 19 |
|
| 39 |
-def grab_heroku_config! |
|
| 40 |
- config_data = capture("heroku config -s", no_stderr: true)
|
|
| 41 |
- $config = {}
|
|
| 42 |
- if config_data !~ /has no config vars/ |
|
| 43 |
- config_data.split("\n").map do |line|
|
|
| 44 |
- next if line =~ /^\s*(#|$)/ # skip comments and empty lines |
|
| 45 |
- first_equal_sign = line.index('=')
|
|
| 46 |
- $config[line.slice(0, first_equal_sign)] = line.slice(first_equal_sign + 1, line.length) |
|
| 47 |
- end |
|
| 20 |
+def check_login! |
|
| 21 |
+ unless File.exists?(File.expand_path("~/.netrc")) && File.read(File.expand_path("~/.netrc")) =~ /heroku/
|
|
| 22 |
+ puts "It looks like you need to log in to Heroku. Please run 'heroku auth:login' before continuing." |
|
| 23 |
+ exit 1 |
|
| 48 | 24 |
end |
| 49 |
-end |
|
| 50 | 25 |
|
| 51 |
-def set_value(key, value, options = {})
|
|
| 52 |
- if $config[key].nil? || $config[key] == '' || ($config[key] != value && options[:force] != false) |
|
| 53 |
- puts "Setting #{key} to #{value}" unless options[:silent]
|
|
| 54 |
- puts capture("heroku config:set #{key}=#{value}")
|
|
| 55 |
- $config[key] = value |
|
| 56 |
- end |
|
| 26 |
+ puts "Welcome #{`heroku auth:whoami`.strip}! It looks like you're logged into Heroku."
|
|
| 27 |
+ puts |
|
| 57 | 28 |
end |
| 58 | 29 |
|
| 59 |
-unless File.exist?(File.expand_path("~/.netrc")) && File.read(File.expand_path("~/.netrc")) =~ /heroku/
|
|
| 60 |
- puts "It looks like you need to log in to Heroku. Please run 'heroku auth:login' before continuing." |
|
| 61 |
- exit 1 |
|
| 62 |
-end |
|
| 63 |
- |
|
| 64 |
-puts "Welcome #{`heroku auth:whoami`.strip}! It looks like you're logged into Heroku."
|
|
| 65 |
-puts |
|
| 30 |
+check_login! |
|
| 66 | 31 |
|
| 67 | 32 |
info = capture("heroku info")
|
| 68 | 33 |
if info =~ /No app specified/i |
@@ -77,25 +42,18 @@ if info =~ /No app specified/i |
||
| 77 | 42 |
end |
| 78 | 43 |
end |
| 79 | 44 |
|
| 80 |
-app_name = info.scan(/http:\/\/([\w\d-]+)\.herokuapp\.com/).flatten.first |
|
| 81 |
- |
|
| 82 |
-unless yes?("Your Heroku app name is #{app_name}. Is this correct?")
|
|
| 83 |
- puts "Well, then I'm not sure what to do here, sorry." |
|
| 84 |
- exit 1 |
|
| 85 |
-end |
|
| 86 |
- |
|
| 87 | 45 |
if (root_id = `git rev-list --max-parents=0 HEAD`.chomp) != '620acffa5a302c6a27165d3214cf3da6be6c1d0d' |
| 88 | 46 |
if (`git remote`.split - %w[heroku]).empty? |
| 89 | 47 |
puts "You don't seem to have cantino/huginn set up as upstream repository." |
| 90 |
- if yes?("Would you like me to set this work tree up for you?")
|
|
| 48 |
+ if yes?("Would you like me to set this working tree up for you?")
|
|
| 91 | 49 |
if system('git remote add origin https://github.com/cantino/huginn.git') &&
|
| 92 |
- system('git remote update origin')
|
|
| 50 |
+ system('git remote update origin')
|
|
| 93 | 51 |
rebase_command = "git rebase #{root_id} --onto origin/master"
|
| 94 | 52 |
if system(rebase_command) |
| 95 | 53 |
puts "Done!" |
| 96 | 54 |
else |
| 97 | 55 |
system('git rebase --abort')
|
| 98 |
- puts "Rebasing your work tree onto the upstream master failed." |
|
| 56 |
+ puts "Rebasing your working tree onto the upstream master failed." |
|
| 99 | 57 |
puts "Please run the following command and merge your local changes by yourself." |
| 100 | 58 |
puts "\t#{rebase_command}"
|
| 101 | 59 |
exit 1 |
@@ -107,20 +65,11 @@ if (root_id = `git rev-list --max-parents=0 HEAD`.chomp) != '620acffa5a302c6a271 |
||
| 107 | 65 |
end |
| 108 | 66 |
end |
| 109 | 67 |
|
| 68 |
+app_name = info.scan(/https?:\/\/([\w\d-]+)\.herokuapp\.com/).flatten.first |
|
| 69 |
+confirm_app_name app_name |
|
| 110 | 70 |
grab_heroku_config! |
| 111 |
- |
|
| 112 |
-if $config.length > 0 |
|
| 113 |
- puts |
|
| 114 |
- puts "Your current Heroku config:" |
|
| 115 |
- $config.each do |key, value| |
|
| 116 |
- puts ' ' + key + ' ' * (25 - [key.length, 25].min) + '= ' + value |
|
| 117 |
- end |
|
| 118 |
-end |
|
| 119 |
- |
|
| 120 |
-unless $config['APP_SECRET_TOKEN'] |
|
| 121 |
- puts "Setting up APP_SECRET_TOKEN..." |
|
| 122 |
- puts capture("heroku config:set APP_SECRET_TOKEN=`rake secret`")
|
|
| 123 |
-end |
|
| 71 |
+print_config |
|
| 72 |
+set_defaults! |
|
| 124 | 73 |
|
| 125 | 74 |
unless $config['DOMAIN'] |
| 126 | 75 |
set_value 'DOMAIN', "#{app_name}.herokuapp.com", force: false
|
@@ -130,17 +79,6 @@ end |
||
| 130 | 79 |
set_value 'BUILDPACK_URL', "https://github.com/ddollar/heroku-buildpack-multi.git" |
| 131 | 80 |
set_value 'PROCFILE_PATH', "deployment/heroku/Procfile.heroku", force: false |
| 132 | 81 |
set_value 'ON_HEROKU', "true" |
| 133 |
-set_value 'FORCE_SSL', "true" |
|
| 134 |
-set_value 'USE_GRAPHVIZ_DOT', 'dot' |
|
| 135 |
- |
|
| 136 |
-unless $config['INVITATION_CODE'] |
|
| 137 |
- puts "You need to set an invitation code for your Huginn instance. If you plan to share this instance, you will" |
|
| 138 |
- puts "tell this code to anyone who you'd like to invite. If you won't share it, then just set this to something" |
|
| 139 |
- puts "that people will not guess." |
|
| 140 |
- |
|
| 141 |
- invitation_code = nag("What code would you like to use?")
|
|
| 142 |
- set_value 'INVITATION_CODE', invitation_code |
|
| 143 |
-end |
|
| 144 | 82 |
|
| 145 | 83 |
unless $config['SMTP_DOMAIN'] && $config['SMTP_USER_NAME'] && $config['SMTP_PASSWORD'] && $config['SMTP_SERVER'] && $config['EMAIL_FROM_ADDRESS'] |
| 146 | 84 |
puts "Okay, let's setup outgoing email settings. The simplest solution is to use the free sendgrid Heroku addon." |
@@ -210,6 +148,8 @@ if first_time |
||
| 210 | 148 |
end |
| 211 | 149 |
puts |
| 212 | 150 |
puts "\t#{$config['INVITATION_CODE']}"
|
| 151 |
+ puts |
|
| 152 |
+ puts "We recommend that you read https://github.com/cantino/huginn/wiki/Run-Huginn-for-free-on-Heroku and setup Pingdom to keep your app awake!" |
|
| 213 | 153 |
end |
| 214 | 154 |
|
| 215 | 155 |
puts |
@@ -0,0 +1,150 @@ |
||
| 1 |
+#!/usr/bin/env ruby |
|
| 2 |
+require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'setup_tools')) |
|
| 3 |
+include SetupTools |
|
| 4 |
+ |
|
| 5 |
+if ARGV.length > 0 |
|
| 6 |
+ mode = ARGV.shift |
|
| 7 |
+else |
|
| 8 |
+ mode = '' |
|
| 9 |
+end |
|
| 10 |
+ |
|
| 11 |
+unless `which rhc` =~ /rhc/ |
|
| 12 |
+ puts "It looks like the 'rhc' command line tool hasn't been installed yet. Please install" |
|
| 13 |
+ puts "it with 'gem install rhc', run 'rhc setup', and then run this script again." |
|
| 14 |
+ exit 1 |
|
| 15 |
+end |
|
| 16 |
+ |
|
| 17 |
+def grab_openshift_config! |
|
| 18 |
+ grab_config_with_cmd!("rhc env list")
|
|
| 19 |
+end |
|
| 20 |
+ |
|
| 21 |
+def set_env(key, value) |
|
| 22 |
+ capture("rhc env set #{key}=#{value}")
|
|
| 23 |
+end |
|
| 24 |
+ |
|
| 25 |
+def check_login! |
|
| 26 |
+ token_file = Dir[File.join(File.expand_path('~/.openshift'), 'token_*')].first
|
|
| 27 |
+ unless token_file |
|
| 28 |
+ 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', then run bin/setup_openshift again." |
|
| 29 |
+ exit 1 |
|
| 30 |
+ end |
|
| 31 |
+ |
|
| 32 |
+ unless (Time.now - File.stat(token_file).mtime).to_i < 60 * 60 * 24 * 5 |
|
| 33 |
+ puts "Please run 'rhc logout' and then 'rhc account' to refresh your session, then run bin/setup_openshift again." |
|
| 34 |
+ exit 1 |
|
| 35 |
+ end |
|
| 36 |
+ |
|
| 37 |
+ puts "Welcome #{`rhc account`.scan(/Login (.*?) on /).first.first}! It looks like you're logged into OpenShift."
|
|
| 38 |
+ puts |
|
| 39 |
+end |
|
| 40 |
+ |
|
| 41 |
+check_login! |
|
| 42 |
+ |
|
| 43 |
+info = capture("rhc app show")
|
|
| 44 |
+just_made = false |
|
| 45 |
+if info =~ /must specify an application/i |
|
| 46 |
+ foreman_cartridge = 'http://cartreflect-claytondev.rhcloud.com/reflect?github=cantino/huginn-openshift-foreman-cartridge' |
|
| 47 |
+ cmd = "rhc app create huginn ruby-2.0 mysql-5.5 #{foreman_cartridge} -s -r tmp-huginn"
|
|
| 48 |
+ puts "It looks like you don't have an OpenShift app set up yet for this repo. I can make one for you." |
|
| 49 |
+ if yes?("Would you like me to create an OpenShift app for you now in this repo?")
|
|
| 50 |
+ puts "Okay, this may take a moment..." |
|
| 51 |
+ puts `#{cmd}`
|
|
| 52 |
+ |
|
| 53 |
+ git_config = capture("git config --list -f tmp-huginn/.git/config").split("\n")
|
|
| 54 |
+ git_config.grep(/^rhc\./).each do |line| |
|
| 55 |
+ path, value = line.split('=')
|
|
| 56 |
+ puts `git config #{path} #{value}`
|
|
| 57 |
+ end |
|
| 58 |
+ |
|
| 59 |
+ url = git_config.grep(/^remote\.origin\.url/).first.split('=').last
|
|
| 60 |
+ puts "Adding remote #{url}"
|
|
| 61 |
+ puts `git remote add openshift #{url}`
|
|
| 62 |
+ |
|
| 63 |
+ puts "Removing tmp OpenShift repo" |
|
| 64 |
+ puts `rm -rf ./tmp-huginn` |
|
| 65 |
+ |
|
| 66 |
+ puts "Updating git" |
|
| 67 |
+ puts `git fetch openshift` |
|
| 68 |
+ |
|
| 69 |
+ info = capture("rhc app show")
|
|
| 70 |
+ just_made = true |
|
| 71 |
+ else |
|
| 72 |
+ puts "Okay, exiting so you can do it." |
|
| 73 |
+ exit 0 |
|
| 74 |
+ end |
|
| 75 |
+elsif info =~ /Application '.*?' not found/ |
|
| 76 |
+ puts "It looks like you've deleted your OpenShift app. If that's the case, you should" |
|
| 77 |
+ puts "edit .git/config and remove the sections under [rhc] and under [remote \"openshift\"]." |
|
| 78 |
+ exit 1 |
|
| 79 |
+end |
|
| 80 |
+ |
|
| 81 |
+app_name, app_url = info.scan(/^([\w\d]+) @ https?:\/\/([^\/ ]+)/i).flatten |
|
| 82 |
+confirm_app_name app_name unless just_made |
|
| 83 |
+grab_openshift_config! |
|
| 84 |
+print_config |
|
| 85 |
+set_defaults! |
|
| 86 |
+ |
|
| 87 |
+first_time = mode =~ /^first/i |
|
| 88 |
+unless $config['DOMAIN'] |
|
| 89 |
+ set_value 'DOMAIN', app_url, force: false |
|
| 90 |
+ first_time = true |
|
| 91 |
+end |
|
| 92 |
+ |
|
| 93 |
+set_value 'BUNDLE_WITHOUT', 'development:test' |
|
| 94 |
+puts `rhc ssh huginn 'gem install bundler'` |
|
| 95 |
+ |
|
| 96 |
+puts |
|
| 97 |
+puts "To setup outbound email, we suggest using Gmail. See the 'Outgoing email settings' section in .env.example." |
|
| 98 |
+puts "You'll need to set those environment variables in OpenShift using 'rhc env set VARIABLE=VALUE'" |
|
| 99 |
+puts |
|
| 100 |
+ |
|
| 101 |
+branch = capture("git rev-parse --abbrev-ref HEAD")
|
|
| 102 |
+if first_time || yes?("Should I push your current branch (#{branch}) to OpenShift?")
|
|
| 103 |
+ puts "This may take a moment..." |
|
| 104 |
+ puts capture("git push openshift #{branch}:master -f")
|
|
| 105 |
+end |
|
| 106 |
+ |
|
| 107 |
+if first_time |
|
| 108 |
+ puts "Restarting..." |
|
| 109 |
+ puts capture("rhc app restart")
|
|
| 110 |
+ puts capture("rhc cartridge restart foreman")
|
|
| 111 |
+ puts "Done!" |
|
| 112 |
+ puts |
|
| 113 |
+ puts |
|
| 114 |
+ puts "I can make an admin user on your new Huginn instance and setup some example Agents." |
|
| 115 |
+ if yes?("Should I create a new admin user and some example Agents?")
|
|
| 116 |
+ done = false |
|
| 117 |
+ while !done |
|
| 118 |
+ seed_email = nag "Okay, what is your email address?" |
|
| 119 |
+ seed_username = nag "And what username would you like to login as?" |
|
| 120 |
+ seed_password = nag "Finally, what password would you like to use?", noecho: true |
|
| 121 |
+ puts "\nJust a moment..." |
|
| 122 |
+ |
|
| 123 |
+ 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}'")
|
|
| 124 |
+ puts result |
|
| 125 |
+ if result =~ /Validation failed/ |
|
| 126 |
+ puts "ERROR:" |
|
| 127 |
+ puts |
|
| 128 |
+ puts result |
|
| 129 |
+ puts |
|
| 130 |
+ else |
|
| 131 |
+ done = true |
|
| 132 |
+ end |
|
| 133 |
+ end |
|
| 134 |
+ puts |
|
| 135 |
+ puts |
|
| 136 |
+ puts "Okay, you should be all set! Visit http://#{app_url} and login as '#{seed_username}' with your password."
|
|
| 137 |
+ puts |
|
| 138 |
+ puts "If you'd like to make more users, you can visit http://#{app_url}/users/sign_up and use the invitation code:"
|
|
| 139 |
+ else |
|
| 140 |
+ puts |
|
| 141 |
+ puts "Visit https://#{app_url}/users/sign_up and use the invitation code shown below:"
|
|
| 142 |
+ end |
|
| 143 |
+ puts |
|
| 144 |
+ puts "\t#{$config['INVITATION_CODE']}"
|
|
| 145 |
+ puts |
|
| 146 |
+ puts "We recommend that you read https://github.com/cantino/huginn/wiki/Run-Huginn-for-free-on-OpenShift and setup Pingdom to keep your app awake!" |
|
| 147 |
+end |
|
| 148 |
+ |
|
| 149 |
+puts |
|
| 150 |
+puts "Done!" |
@@ -20,7 +20,7 @@ module Huginn |
||
| 20 | 20 |
|
| 21 | 21 |
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. |
| 22 | 22 |
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. |
| 23 |
- config.time_zone = ENV['TIMEZONE'].present? ? ENV['TIMEZONE'] : "Pacific Time (US & Canada)" |
|
| 23 |
+ config.time_zone = ENV['TIMEZONE'].presence || "Pacific Time (US & Canada)" |
|
| 24 | 24 |
|
| 25 | 25 |
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. |
| 26 | 26 |
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
@@ -1,37 +1,37 @@ |
||
| 1 | 1 |
development: |
| 2 |
- adapter: <%= ENV['DATABASE_ADAPTER'] || "mysql2" %> |
|
| 3 |
- encoding: <%= ENV['DATABASE_ENCODING'] || "utf8" %> |
|
| 4 |
- reconnect: <%= ENV['DATABASE_RECONNECT'] || "true" %> |
|
| 5 |
- database: <%= ENV['DATABASE_NAME'] || "huginn_development" %> |
|
| 6 |
- pool: <%= ENV['DATABASE_POOL'] || "5" %> |
|
| 7 |
- username: <%= ENV['DATABASE_USERNAME'] || "root" %> |
|
| 2 |
+ adapter: <%= ENV['DATABASE_ADAPTER'].presence || "mysql2" %> |
|
| 3 |
+ encoding: <%= ENV['DATABASE_ENCODING'].presence || "utf8" %> |
|
| 4 |
+ reconnect: <%= ENV['DATABASE_RECONNECT'].presence || "true" %> |
|
| 5 |
+ database: <%= ENV['DATABASE_NAME'].presence || "huginn_development" %> |
|
| 6 |
+ pool: <%= ENV['DATABASE_POOL'].presence || "5" %> |
|
| 7 |
+ username: <%= ENV['DATABASE_USERNAME'].presence || "root" %> |
|
| 8 | 8 |
password: <%= ENV['DATABASE_PASSWORD'] || "" %> |
| 9 | 9 |
host: <%= ENV['DATABASE_HOST'] || "" %> |
| 10 | 10 |
port: <%= ENV['DATABASE_PORT'] || "" %> |
| 11 |
- socket: <%= ENV['DATABASE_SOCKET'] || ["/var/run/mysqld/mysqld.sock", "/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock"].find{ |path| File.exist? path } %>
|
|
| 11 |
+ socket: <%= ENV['DATABASE_SOCKET'] || ["/var/run/mysqld/mysqld.sock", "/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock"].find { |path| File.exist? path } %>
|
|
| 12 | 12 |
|
| 13 | 13 |
# Warning: The database defined as "test" will be erased and |
| 14 | 14 |
# re-generated from your development database when you run "rake". |
| 15 | 15 |
# Do not set this db to the same as development or production. |
| 16 | 16 |
test: |
| 17 |
- adapter: <%= ENV['DATABASE_ADAPTER'] || "mysql2" %> |
|
| 18 |
- database: <%= ENV['TEST_DATABASE_NAME'] || "huginn_test" %> |
|
| 19 |
- username: <%= ENV['DATABASE_USERNAME'] || "root" %> |
|
| 20 |
- password: <%= ENV['DATABASE_PASSWORD'] || "" %> |
|
| 21 |
- socket: <%= ENV['DATABASE_SOCKET'] || ["/var/run/mysqld/mysqld.sock", "/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock"].find{ |path| File.exist? path } %>
|
|
| 22 |
- encoding: <%= ENV['DATABASE_ENCODING'] || "utf8" %> |
|
| 23 |
- reconnect: <%= ENV['DATABASE_RECONNECT'] || "true" %> |
|
| 17 |
+ adapter: <%= ENV['DATABASE_ADAPTER'].presence || "mysql2" %> |
|
| 18 |
+ encoding: <%= ENV['DATABASE_ENCODING'].presence || "utf8" %> |
|
| 19 |
+ reconnect: <%= ENV['DATABASE_RECONNECT'].presence || "true" %> |
|
| 20 |
+ database: <%= ENV['TEST_DATABASE_NAME'].presence || "huginn_test" %> |
|
| 21 |
+ pool: <%= ENV['DATABASE_POOL'].presence || "5" %> |
|
| 22 |
+ username: <%= ENV['DATABASE_USERNAME'].presence || "root" %> |
|
| 23 |
+ password: <%= ENV['DATABASE_PASSWORD'].presence || "" %> |
|
| 24 |
+ socket: <%= ENV['DATABASE_SOCKET'] || ["/var/run/mysqld/mysqld.sock", "/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock"].find { |path| File.exist? path } %>
|
|
| 24 | 25 |
port: <%= ENV['DATABASE_PORT'] || "" %> |
| 25 |
- pool: <%= ENV['DATABASE_POOL'] || "5" %> |
|
| 26 | 26 |
|
| 27 | 27 |
production: |
| 28 |
- adapter: <%= ENV['DATABASE_ADAPTER'] || "mysql2" %> |
|
| 29 |
- encoding: <%= ENV['DATABASE_ENCODING'] || "utf8" %> |
|
| 30 |
- reconnect: <%= ENV['DATABASE_RECONNECT'] || "true" %> |
|
| 31 |
- database: <%= ENV['DATABASE_NAME'] || "huginn_production" %> |
|
| 32 |
- pool: <%= ENV['DATABASE_POOL'] || "5" %> |
|
| 33 |
- username: <%= ENV['DATABASE_USERNAME'] || "root" %> |
|
| 34 |
- password: <%= ENV['DATABASE_PASSWORD'] || "password" %> |
|
| 28 |
+ adapter: <%= ENV['DATABASE_ADAPTER'].presence || "mysql2" %> |
|
| 29 |
+ encoding: <%= ENV['DATABASE_ENCODING'].presence || "utf8" %> |
|
| 30 |
+ reconnect: <%= ENV['DATABASE_RECONNECT'].presence || "true" %> |
|
| 31 |
+ database: <%= ENV['DATABASE_NAME'].presence || "huginn_production" %> |
|
| 32 |
+ pool: <%= ENV['DATABASE_POOL'].presence || "5" %> |
|
| 33 |
+ username: <%= ENV['DATABASE_USERNAME'].presence || "root" %> |
|
| 34 |
+ password: <%= ENV['DATABASE_PASSWORD'].presence || "password" %> |
|
| 35 | 35 |
host: <%= ENV['DATABASE_HOST'] || "" %> |
| 36 | 36 |
port: <%= ENV['DATABASE_PORT'] || "" %> |
| 37 | 37 |
socket: <%= ENV['DATABASE_SOCKET'] || ["/var/run/mysqld/mysqld.sock", "/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock"].find{ |path| File.exist? path } %>
|
@@ -41,7 +41,7 @@ Huginn::Application.configure do |
||
| 41 | 41 |
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx |
| 42 | 42 |
|
| 43 | 43 |
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. |
| 44 |
- config.force_ssl = ENV['FORCE_SSL'].present? && ENV['FORCE_SSL'] == 'true' ? true : false |
|
| 44 |
+ config.force_ssl = ENV['FORCE_SSL'] == 'true' |
|
| 45 | 45 |
|
| 46 | 46 |
# See everything in the log (default is :info) |
| 47 | 47 |
# config.log_level = :debug |
@@ -18,7 +18,7 @@ Thread.new do |
||
| 18 | 18 |
sleep 45 |
| 19 | 19 |
|
| 20 | 20 |
if ENV['DOMAIN'] |
| 21 |
- force_ssl = ENV['FORCE_SSL'].present? && ENV['FORCE_SSL'] == 'true' |
|
| 21 |
+ force_ssl = ENV['FORCE_SSL'] == 'true' |
|
| 22 | 22 |
Net::HTTP.get_response(URI((force_ssl ? "https://" : "http://") + ENV['DOMAIN'])) |
| 23 | 23 |
end |
| 24 | 24 |
|
@@ -106,7 +106,7 @@ class HuginnScheduler |
||
| 106 | 106 |
end |
| 107 | 107 |
|
| 108 | 108 |
def run! |
| 109 |
- tzinfo_friendly_timezone = ActiveSupport::TimeZone::MAPPING[ENV['TIMEZONE'].present? ? ENV['TIMEZONE'] : "Pacific Time (US & Canada)"] |
|
| 109 |
+ tzinfo_friendly_timezone = ActiveSupport::TimeZone::MAPPING[ENV['TIMEZONE'].presence || "Pacific Time (US & Canada)"] |
|
| 110 | 110 |
|
| 111 | 111 |
# Schedule event propagation. |
| 112 | 112 |
@rufus_scheduler.every '1m' do |
@@ -0,0 +1,89 @@ |
||
| 1 |
+require 'open3' |
|
| 2 |
+require 'io/console' |
|
| 3 |
+require 'securerandom' |
|
| 4 |
+ |
|
| 5 |
+module SetupTools |
|
| 6 |
+ def capture(cmd, opts = {})
|
|
| 7 |
+ if opts.delete(:no_stderr) |
|
| 8 |
+ o, s = Open3.capture2(cmd, opts) |
|
| 9 |
+ else |
|
| 10 |
+ o, s = Open3.capture2e(cmd, opts) |
|
| 11 |
+ end |
|
| 12 |
+ o.strip |
|
| 13 |
+ end |
|
| 14 |
+ |
|
| 15 |
+ def grab_config_with_cmd!(cmd, opts = {})
|
|
| 16 |
+ config_data = capture(cmd, opts) |
|
| 17 |
+ $config = {}
|
|
| 18 |
+ if config_data !~ /has no config vars/ |
|
| 19 |
+ config_data.split("\n").map do |line|
|
|
| 20 |
+ next if line =~ /^\s*(#|$)/ # skip comments and empty lines |
|
| 21 |
+ first_equal_sign = line.index('=')
|
|
| 22 |
+ raise "Invalid line found in config: #{line}" unless first_equal_sign
|
|
| 23 |
+ $config[line.slice(0, first_equal_sign)] = line.slice(first_equal_sign + 1, line.length) |
|
| 24 |
+ end |
|
| 25 |
+ end |
|
| 26 |
+ end |
|
| 27 |
+ |
|
| 28 |
+ def print_config |
|
| 29 |
+ if $config.length > 0 |
|
| 30 |
+ puts |
|
| 31 |
+ puts "Your current config:" |
|
| 32 |
+ $config.each do |key, value| |
|
| 33 |
+ puts ' ' + key + ' ' * (25 - [key.length, 25].min) + '= ' + value |
|
| 34 |
+ end |
|
| 35 |
+ end |
|
| 36 |
+ end |
|
| 37 |
+ |
|
| 38 |
+ def set_defaults! |
|
| 39 |
+ unless $config['APP_SECRET_TOKEN'] |
|
| 40 |
+ puts "Setting up APP_SECRET_TOKEN..." |
|
| 41 |
+ set_value 'APP_SECRET_TOKEN', SecureRandom.hex(64) |
|
| 42 |
+ end |
|
| 43 |
+ set_value 'RAILS_ENV', "production" |
|
| 44 |
+ set_value 'FORCE_SSL', "true" |
|
| 45 |
+ set_value 'USE_GRAPHVIZ_DOT', 'dot' |
|
| 46 |
+ unless $config['INVITATION_CODE'] |
|
| 47 |
+ puts "You need to set an invitation code for your Huginn instance. If you plan to share this instance, you will" |
|
| 48 |
+ puts "tell this code to anyone who you'd like to invite. If you won't share it, then just set this to something" |
|
| 49 |
+ puts "that people will not guess." |
|
| 50 |
+ |
|
| 51 |
+ invitation_code = nag("What code would you like to use?")
|
|
| 52 |
+ set_value 'INVITATION_CODE', invitation_code |
|
| 53 |
+ end |
|
| 54 |
+ end |
|
| 55 |
+ |
|
| 56 |
+ def confirm_app_name(app_name) |
|
| 57 |
+ unless yes?("Your app name is '#{app_name}'. Is this correct?")
|
|
| 58 |
+ puts "Well, then I'm not sure what to do here, sorry." |
|
| 59 |
+ exit 1 |
|
| 60 |
+ end |
|
| 61 |
+ end |
|
| 62 |
+ |
|
| 63 |
+ # expects set_env(key, value) to be defined. |
|
| 64 |
+ def set_value(key, value, options = {})
|
|
| 65 |
+ if $config[key].nil? || $config[key] == '' || ($config[key] != value && options[:force] != false) |
|
| 66 |
+ puts "Setting #{key} to #{value}" unless options[:silent]
|
|
| 67 |
+ puts set_env(key, value) |
|
| 68 |
+ $config[key] = value |
|
| 69 |
+ end |
|
| 70 |
+ end |
|
| 71 |
+ |
|
| 72 |
+ def ask(question, opts = {})
|
|
| 73 |
+ print question + " " |
|
| 74 |
+ STDOUT.flush |
|
| 75 |
+ (opts[:noecho] ? STDIN.noecho(&:gets) : gets).strip |
|
| 76 |
+ end |
|
| 77 |
+ |
|
| 78 |
+ def nag(question, opts = {})
|
|
| 79 |
+ answer = '' |
|
| 80 |
+ while answer.length == 0 |
|
| 81 |
+ answer = ask(question, opts) |
|
| 82 |
+ end |
|
| 83 |
+ answer |
|
| 84 |
+ end |
|
| 85 |
+ |
|
| 86 |
+ def yes?(question) |
|
| 87 |
+ ask(question + " (y/n)") =~ /^y/i |
|
| 88 |
+ end |
|
| 89 |
+end |
@@ -74,13 +74,13 @@ shared_examples_for WebRequestConcern do |
||
| 74 | 74 |
ENV['DEFAULT_HTTP_USER_AGENT'] = @default_http_user_agent |
| 75 | 75 |
end |
| 76 | 76 |
|
| 77 |
- it "should have the default value set by Faraday" do |
|
| 78 |
- expect(agent.user_agent).to eq(Faraday.new.headers[:user_agent]) |
|
| 77 |
+ it "should have the default value of Huginn" do |
|
| 78 |
+ expect(agent.user_agent).to eq('Huginn - https://github.com/cantino/huginn')
|
|
| 79 | 79 |
end |
| 80 | 80 |
|
| 81 | 81 |
it "should be overridden by the environment variable if present" do |
| 82 |
- ENV['DEFAULT_HTTP_USER_AGENT'] = 'Huginn - https://github.com/cantino/huginn' |
|
| 83 |
- expect(agent.user_agent).to eq('Huginn - https://github.com/cantino/huginn')
|
|
| 82 |
+ ENV['DEFAULT_HTTP_USER_AGENT'] = 'Something' |
|
| 83 |
+ expect(agent.user_agent).to eq('Something')
|
|
| 84 | 84 |
end |
| 85 | 85 |
|
| 86 | 86 |
it "should be overriden by the value in options if present" do |