Merge pull request #566 from cantino/openshift2

OpenShift deployment

Andrew Cantino 10 anni fa
parent
commit
d59952dcf0

+ 7 - 0
.openshift/action_hooks/build

@@ -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"

+ 25 - 0
.openshift/action_hooks/deploy

@@ -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

+ 6 - 0
.openshift/action_hooks/post_deploy

@@ -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"

+ 16 - 0
.openshift/action_hooks/post_start_ruby-2.0

@@ -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"

+ 16 - 0
.openshift/action_hooks/post_stop_ruby-2.0

@@ -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"

+ 24 - 0
.openshift/action_hooks/pre_build

@@ -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

+ 21 - 0
.openshift/action_hooks/pre_start_ruby-2.0

@@ -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

+ 16 - 0
.openshift/action_hooks/pre_stop_ruby-2.0

@@ -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"

+ 22 - 0
.openshift/cron/README.cron

@@ -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
.openshift/cron/daily/.gitignore


+ 0 - 0
.openshift/cron/hourly/.gitignore


+ 0 - 0
.openshift/cron/minutely/.gitignore


+ 0 - 0
.openshift/cron/monthly/.gitignore


+ 16 - 0
.openshift/cron/weekly/README

@@ -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
+

+ 1 - 0
.openshift/cron/weekly/chrono.dat

@@ -0,0 +1 @@
1
+Time And Relative D...n In Execution (Open)Shift!

+ 3 - 0
.openshift/cron/weekly/chronograph

@@ -0,0 +1,3 @@
1
+#!/bin/bash
2
+
3
+echo "`date`: `cat $(dirname \"$0\")/chrono.dat`"

+ 12 - 0
.openshift/cron/weekly/jobs.allow

@@ -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
+

+ 7 - 0
.openshift/cron/weekly/jobs.deny

@@ -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
+

+ 8 - 0
.openshift/markers/README

@@ -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.

+ 1 - 1
app/concerns/web_request_concern.rb

@@ -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 - 1
app/mailers/system_mailer.rb

@@ -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]

+ 22 - 82
bin/setup_heroku

@@ -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

+ 150 - 0
bin/setup_openshift

@@ -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!"

+ 1 - 1
config/application.rb

@@ -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]

+ 22 - 22
config/database.yml

@@ -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 } %>

+ 1 - 1
config/environments/production.rb

@@ -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

+ 1 - 1
deployment/heroku/unicorn.rb

@@ -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
 

+ 1 - 1
lib/huginn_scheduler.rb

@@ -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

+ 89 - 0
lib/setup_tools.rb

@@ -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

+ 4 - 4
spec/support/shared_examples/web_request_concern.rb

@@ -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