pvcglue 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +91 -0
  6. data/Rakefile +1 -0
  7. data/bin/pvc +13 -0
  8. data/lib/pvcglue.rb +43 -0
  9. data/lib/pvcglue/all_the_things.rb +7 -0
  10. data/lib/pvcglue/bootstrap.rb +8 -0
  11. data/lib/pvcglue/capistrano.rb +35 -0
  12. data/lib/pvcglue/cli.rb +150 -0
  13. data/lib/pvcglue/cloud.rb +278 -0
  14. data/lib/pvcglue/configuration.rb +157 -0
  15. data/lib/pvcglue/db.rb +145 -0
  16. data/lib/pvcglue/deploy.rb +4 -0
  17. data/lib/pvcglue/env.rb +141 -0
  18. data/lib/pvcglue/manager.rb +137 -0
  19. data/lib/pvcglue/nodes.rb +29 -0
  20. data/lib/pvcglue/packages.rb +47 -0
  21. data/lib/pvcglue/packages/bootstrap.rb +92 -0
  22. data/lib/pvcglue/packages/env.rb +80 -0
  23. data/lib/pvcglue/packages/firewall.rb +48 -0
  24. data/lib/pvcglue/packages/manager.rb +102 -0
  25. data/lib/pvcglue/packages/nginx.rb +10 -0
  26. data/lib/pvcglue/packages/nodejs.rb +17 -0
  27. data/lib/pvcglue/packages/passenger.rb +28 -0
  28. data/lib/pvcglue/packages/postgresql.rb +10 -0
  29. data/lib/pvcglue/packages/role_db.rb +47 -0
  30. data/lib/pvcglue/packages/role_lb.rb +64 -0
  31. data/lib/pvcglue/packages/role_memcached.rb +14 -0
  32. data/lib/pvcglue/packages/role_web.rb +60 -0
  33. data/lib/pvcglue/packages/rvm.rb +75 -0
  34. data/lib/pvcglue/packages/timezone.rb +17 -0
  35. data/lib/pvcglue/packages/ubuntu.rb +100 -0
  36. data/lib/pvcglue/railtie.rb +11 -0
  37. data/lib/pvcglue/ssl.rb +37 -0
  38. data/lib/pvcglue/templates/20auto-upgrades.erb +2 -0
  39. data/lib/pvcglue/templates/authorized_keys.erb +3 -0
  40. data/lib/pvcglue/templates/capfile.erb +20 -0
  41. data/lib/pvcglue/templates/database.yml.erb +57 -0
  42. data/lib/pvcglue/templates/denial_of_service.erb +3 -0
  43. data/lib/pvcglue/templates/deploy.rb.erb +81 -0
  44. data/lib/pvcglue/templates/gemrc.erb +1 -0
  45. data/lib/pvcglue/templates/hosts.erb +9 -0
  46. data/lib/pvcglue/templates/lb.nginx.conf.erb +88 -0
  47. data/lib/pvcglue/templates/lb.sites-enabled.erb +74 -0
  48. data/lib/pvcglue/templates/maintenance_mode.erb +46 -0
  49. data/lib/pvcglue/templates/memcached.conf.erb +55 -0
  50. data/lib/pvcglue/templates/passenger.list.erb +2 -0
  51. data/lib/pvcglue/templates/pg_hba.conf.erb +101 -0
  52. data/lib/pvcglue/templates/postgresql.conf.erb +557 -0
  53. data/lib/pvcglue/templates/sshd_config.erb +91 -0
  54. data/lib/pvcglue/templates/stage-deploy.rb.erb +33 -0
  55. data/lib/pvcglue/templates/timezone.erb +1 -0
  56. data/lib/pvcglue/templates/ufw.rules.erb +42 -0
  57. data/lib/pvcglue/templates/ufw.rules6.erb +25 -0
  58. data/lib/pvcglue/templates/web.bashrc.erb +120 -0
  59. data/lib/pvcglue/templates/web.env.erb +3 -0
  60. data/lib/pvcglue/templates/web.nginx.conf.erb +82 -0
  61. data/lib/pvcglue/templates/web.sites-enabled.erb +8 -0
  62. data/lib/pvcglue/toml_pvc_dumper.rb +53 -0
  63. data/lib/pvcglue/version.rb +3 -0
  64. data/pvcglue.gemspec +33 -0
  65. metadata +296 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZTRmZThlNzQ0YTkxNWI2Njg4NGNjZmUwMzdjN2VkMDMyYzdiYWVhZA==
5
+ data.tar.gz: !binary |-
6
+ Mjg3ODk4M2ZmZTc4NzAwY2NhNTYyYTgyZGJjMGMzNzI2YzBjMDgzYw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ N2RiMTUyZDhiMTlkZmM5OWM4ODRlMDBiOTM0MmQ1NDY5MDQ4NjRlZmU4NDU2
10
+ MTE5MmY5OTU4MzhkNGZiMmE5MTY4MzhkZDEzMTMyMmY5MTFkMGJjZTgyNWMx
11
+ Nzc2Y2E2YmRmNjNjYzJjYjA2YjFmNDY5NDc3M2NjMDE5OTMwOWU=
12
+ data.tar.gz: !binary |-
13
+ Zjk0YWNkYjE3YmYyZmYxZjFiMDBjYWIwZDdmMDk4ZmNiOTBjYWM0MjViNDM4
14
+ ODYxYTc5MjdmOTAxNGQ3OTkxOTBhOGYxYWI4M2FkNmM1MTg4ODAzNWYyMTc0
15
+ OGE4MzE2OGQ5MWNhZTcxMTNmOGNkZDg5MmI0MTdjYTI4MGZmNzQ=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pvcglue.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Andrew Lyric
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # Basic Usage
2
+
3
+ pvc manager init # only once per machine
4
+ pvc manger build # only once
5
+ # create or edit configuration
6
+ pvc manager push # save the config
7
+ pvc <stage> build # anytime the config is changed
8
+ pvc <stage> env set KEY=value[, KEY2=value]
9
+ pvc <stage> capify
10
+ pvc <stage> deploy
11
+
12
+ # Pvcglue
13
+
14
+ Commands:
15
+ pvc bootstrap -s, --stage=STAGE # bootstrap...
16
+ pvc build -s, --stage=STAGE # build...
17
+ pvc c -s, --stage=STAGE # shortcut for console
18
+ pvc capify -s, --stage=STAGE # update capistrano configuration
19
+ pvc console -s, --stage=STAGE # open rails console
20
+ pvc db SUBCOMMAND ...ARGS # db utils
21
+ pvc deploy -s, --stage=STAGE # deploy the app
22
+ pvc env SUBCOMMAND ...ARGS -s, --stage=STAGE # manage stage environment
23
+ pvc help [COMMAND] # Describe available commands or one specific c...
24
+ pvc info # show the pvcglue version and cloud settings
25
+ pvc m -s, --stage=STAGE # enable or disable maintenance mode
26
+ pvc maint -s, --stage=STAGE # enable or disable maintenance mode
27
+ pvc maintenance -s, --stage=STAGE # enable or disable maintenance mode
28
+ pvc manager SUBCOMMAND ...ARGS # manage manager
29
+ pvc s -s, --stage=STAGE # shell
30
+ pvc sh -s, --stage=STAGE # run interactive shell on node
31
+ pvc ssl SUBCOMMAND ...ARGS -s, --stage=STAGE # manage ssl certificates
32
+ pvc version # show the version of PVC...
33
+
34
+ https://github.com/radar/guides/blob/master/gem-development.md
35
+
36
+ ## Installation
37
+
38
+ Add this line to your application's Gemfile:
39
+
40
+ group :development do
41
+ gem 'pvcglue', "~> 0.1.0", :github => 'talyric/pvcglue', :branch => 'master', :require => false
42
+
43
+ # This should be used once gem is 'official' :)
44
+ #gem 'pvcglue'
45
+ end
46
+
47
+ gem 'pvcglue_dbutils', "~> 0.5.1", :github => 'talyric/pvcglue_dbutils', :branch => 'master' # must be available in all environments
48
+
49
+ And then execute:
50
+
51
+ $ bundle
52
+
53
+ Or install it yourself as:
54
+
55
+ $ gem install pvcglue
56
+
57
+ ## Usage
58
+
59
+ TODO: Write usage instructions here
60
+
61
+ ## Contributing
62
+
63
+ 1. Fork it
64
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
65
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
66
+ 4. Push to the branch (`git push origin my-new-feature`)
67
+ 5. Create new Pull Request
68
+
69
+ License
70
+ -------
71
+
72
+ MIT License
73
+
74
+ Permission is hereby granted, free of charge, to any person obtaining
75
+ a copy of this software and associated documentation files (the
76
+ "Software"), to deal in the Software without restriction, including
77
+ without limitation the rights to use, copy, modify, merge, publish,
78
+ distribute, sublicense, and/or sell copies of the Software, and to
79
+ permit persons to whom the Software is furnished to do so, subject to
80
+ the following conditions:
81
+
82
+ The above copyright notice and this permission notice shall be
83
+ included in all copies or substantial portions of the Software.
84
+
85
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
88
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
89
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
90
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
91
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/pvc ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pvcglue/cli'
3
+
4
+ # Allow use of Capistrano style environment syntax and convert to 'standard' syntax
5
+ # Example: `pvc production bootstrap` ==> `pvc bootstrap --stage=production`
6
+ # TODO: refactor to use a list of user specified environments
7
+ if ARGV.count >= 2 && %w[alpha beta gamma delta preview production staging all].include?(ARGV[0])
8
+ ARGV[0], ARGV[1] = ARGV[1], "--stage=#{ARGV[0]}"
9
+ end
10
+
11
+ # puts ARGV.inspect
12
+
13
+ Pvcglue::CLI.start
data/lib/pvcglue.rb ADDED
@@ -0,0 +1,43 @@
1
+ require "pvcglue/version"
2
+ require "thor"
3
+ require "pvcglue/configuration"
4
+ require "pvcglue/manager"
5
+ require "pvcglue/cloud"
6
+ require "pvcglue/packages"
7
+ require "pvcglue/bootstrap"
8
+ require "pvcglue/nodes"
9
+ require "pvcglue/env"
10
+ require "pvcglue/deploy"
11
+ require "pvcglue/capistrano"
12
+ require "pvcglue/ssl"
13
+ require "pvcglue/db"
14
+ require "pvcglue/toml_pvc_dumper.rb"
15
+ require "tilt"
16
+
17
+ # puts File.join(File.dirname(__FILE__), 'pvcglue', 'packages', '*.rb')
18
+
19
+ module Pvcglue
20
+
21
+ def self.gem_dir
22
+ Gem::Specification.find_by_name('pvcglue').gem_dir
23
+ end
24
+
25
+ def self.template_file_name(template)
26
+ File.join(Pvcglue::gem_dir, 'lib', 'pvcglue', 'templates', template)
27
+ end
28
+
29
+ def self.render_template(template, file_name = nil)
30
+ data = Tilt.new(Pvcglue.template_file_name(template)).render
31
+ if file_name
32
+ File.write(file_name, data)
33
+ end
34
+ data
35
+ end
36
+
37
+ class Version
38
+ def self.version
39
+ VERSION
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,7 @@
1
+ require "orca/extensions/apt"
2
+ require "orca/extensions/file_sync"
3
+ #/home/andrew/projects/pvcglue/lib/pvcglue/packages
4
+ #/home/andrew/projects/pvcglue/lib/pvcglue/packages/bootstrap_manager.rb
5
+ #/home/andrew/projects/pvcglue
6
+ #puts Pvcglue::gem_dir
7
+ #Dir[File.join(Pvcglue::gem_dir,'lib', 'pvcglue', 'packages', '*.rb')].each { |file| puts "#{file}*********************************************************"; require file }
@@ -0,0 +1,8 @@
1
+ module Pvcglue
2
+ class Bootstrap
3
+ def self.run(roles)
4
+ # puts "This is where it should bootstrap #{Pvcglue.cloud.stage_name}. :)"
5
+ Pvcglue::Packages.apply('bootstrap'.to_sym, :bootstrap, Pvcglue.cloud.nodes_in_stage(roles), 'root')
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,35 @@
1
+ module Pvcglue
2
+ class Capistrano
3
+ # TODO: Add requirements to gem file: capistrano-rails, etc.
4
+ def self.capify
5
+ Pvcglue.render_template('capfile.erb', capfile_file_name)
6
+ Pvcglue.render_template('deploy.rb.erb', common_deploy_file_name)
7
+ Pvcglue.render_template('stage-deploy.rb.erb', stage_deploy_file_name)
8
+ end
9
+
10
+ def self.capfile_file_name
11
+ File.join(Pvcglue.configuration.application_dir, 'Capfile')
12
+ end
13
+
14
+ def self.application_config_dir
15
+ File.join(Pvcglue.configuration.application_dir, 'config')
16
+ end
17
+
18
+ def self.common_deploy_file_name
19
+ File.join(application_config_dir, 'deploy.rb')
20
+ end
21
+
22
+ def self.stage_deploy_dir
23
+ File.join(application_config_dir, 'deploy')
24
+ end
25
+
26
+ def self.stage_deploy_file_name
27
+ `mkdir -p #{stage_deploy_dir}`
28
+ File.join(stage_deploy_dir, "#{Pvcglue.cloud.stage_name_validated}.rb")
29
+ end
30
+
31
+ def self.deploy
32
+ system("cap #{Pvcglue.cloud.stage_name} deploy")
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,150 @@
1
+ require 'thor'
2
+ require 'orca'
3
+ require 'pvcglue'
4
+
5
+ module Pvcglue
6
+
7
+ class CLI < Thor
8
+
9
+ def initialize(args = [], local_options = {}, config = {})
10
+ super
11
+ Pvcglue.cloud.set_stage(options[:stage])
12
+ # puts "/\\"*80
13
+ # puts options.inspect
14
+ # puts "*"*80
15
+ end
16
+
17
+ desc "version", "show the version of PVC..."
18
+
19
+ def version
20
+ puts Pvcglue::Version.version
21
+ end
22
+
23
+ desc "info", "show the pvcglue version and cloud settings"
24
+
25
+ def info
26
+ puts "Pvcglue version #{Pvcglue::Version.version}"
27
+ puts " Manager settings:"
28
+ Pvcglue.configuration.options.each { |k, v| puts " #{k}=#{v}" }
29
+ end
30
+
31
+ desc "show", "show the pvcglue version and cloud settings"
32
+
33
+ def show
34
+ info
35
+ end
36
+
37
+ desc "bootstrap", "bootstrap..."
38
+ method_option :stage, :required => true, :aliases => "-s"
39
+
40
+ def bootstrap(roles = 'all')
41
+ Pvcglue::Bootstrap.run(roles)
42
+ end
43
+
44
+ desc "build", "build..."
45
+ method_option :stage, :required => true, :aliases => "-s"
46
+
47
+ def build(roles = 'all')
48
+ Pvcglue::Nodes.build(roles)
49
+ end
50
+
51
+ desc "console", "open rails console"
52
+ method_option :stage, :required => true, :aliases => "-s"
53
+
54
+ def console(server='web')
55
+ node = Pvcglue.cloud.find_node(server)
56
+ node_name = node.keys.first
57
+ node_data = node.values.first
58
+ # puts "*"*80
59
+ # puts node.inspect
60
+ puts "Connection to #{node_name} (#{node_data[:public_ip]}) as user 'deploy'..."
61
+ working_dir = Pvcglue.cloud.deploy_to_app_current_dir
62
+ system(%(ssh -t deploy@#{node_data[:public_ip]} "cd #{working_dir} && echo 'Starting #{options[:stage].upcase} Rails console in #{working_dir}' && RAILS_ENV=#{options[:stage].downcase} script/rails c"))
63
+
64
+ end
65
+
66
+ desc "c", "shortcut for console"
67
+ method_option :stage, :required => true, :aliases => "-s"
68
+
69
+ def c(server='web')
70
+ console(server)
71
+ end
72
+
73
+ desc "manager SUBCOMMAND ...ARGS", "manage manager"
74
+ #banner 'manager'
75
+ subcommand "manager", Manager
76
+
77
+ desc "env SUBCOMMAND ...ARGS", "manage stage environment"
78
+ method_option :stage, :required => true, :aliases => "-s"
79
+ #banner 'manager'
80
+ subcommand "env", Env
81
+
82
+ desc "db SUBCOMMAND ...ARGS", "db utils"
83
+ method_option :stage, :aliases => "-s"
84
+ subcommand "db", Db
85
+
86
+ desc "ssl SUBCOMMAND ...ARGS", "manage ssl certificates"
87
+ method_option :stage, :required => true, :aliases => "-s"
88
+ subcommand "ssl", Ssl
89
+
90
+
91
+ desc "maintenance", "enable or disable maintenance mode"
92
+ method_option :stage, :required => true, :aliases => "-s"
93
+
94
+ def maintenance(mode)
95
+ raise(Thor::Error, "invalid maintenance mode :( (Hint: try on or off.)") unless mode.in?(%w(on off))
96
+ Pvcglue.cloud.maintenance_mode = mode
97
+ Pvcglue::Packages.apply(:maintenance_mode, :maintenance, Pvcglue.cloud.nodes_in_stage('lb'))
98
+ end
99
+
100
+ desc "maint", "enable or disable maintenance mode"
101
+ method_option :stage, :required => true, :aliases => "-s"
102
+
103
+ def maint(mode)
104
+ maintenance(mode)
105
+ end
106
+
107
+ desc "m", "enable or disable maintenance mode"
108
+ method_option :stage, :required => true, :aliases => "-s"
109
+
110
+ def m(mode)
111
+ maintenance(mode)
112
+ end
113
+
114
+ desc "sh", "run interactive shell on node"
115
+ method_option :stage, :required => true, :aliases => "-s"
116
+
117
+ def sh(server='web') # `shell` is a Thor reserved word
118
+ node = Pvcglue.cloud.find_node(server)
119
+ node_name = node.keys.first
120
+ node_data = node.values.first
121
+ # puts "*"*80
122
+ # puts node.inspect
123
+ puts "Connection to #{node_name} (#{node_data[:public_ip]}) as user 'deploy'..."
124
+ system("ssh -p #{Pvcglue.cloud.port_in_context(:shell)} deploy@#{node_data[:public_ip]}")
125
+ end
126
+
127
+ desc "s", "shell"
128
+ method_option :stage, :required => true, :aliases => "-s"
129
+
130
+ def s(server='web')
131
+ sh(server)
132
+ end
133
+
134
+ desc "pvcify", "update capistrano, database.yml and other configurations"
135
+ method_option :stage, :required => true, :aliases => "-s"
136
+
137
+ def pvcify
138
+ Pvcglue::Capistrano.capify
139
+ Pvcglue::Db.configure_database_yml
140
+ end
141
+
142
+ desc "deploy", "deploy the app"
143
+ method_option :stage, :required => true, :aliases => "-s"
144
+
145
+ def deploy
146
+ Pvcglue::Capistrano.deploy
147
+ end
148
+ end
149
+
150
+ end
@@ -0,0 +1,278 @@
1
+ require "active_support/core_ext" # for `with_indifferent_access`
2
+
3
+
4
+ module Pvcglue
5
+ class Cloud
6
+ attr_accessor :data
7
+ attr_accessor :current_node
8
+ attr_accessor :current_hostname
9
+ attr_accessor :maintenance_mode
10
+ attr_accessor :stage_env
11
+ attr_accessor :passenger_ruby
12
+ attr_accessor :port_in_node_context
13
+
14
+ def data
15
+ ::Pvcglue::Manager.initialize_cloud_data unless @data
16
+ @data
17
+ end
18
+
19
+ def data=(data)
20
+ @data = data.with_indifferent_access # We may not want this dependency.
21
+ end
22
+
23
+ def current_node
24
+ raise "Current node not set." if @current_node.nil?
25
+ @current_node
26
+ end
27
+
28
+ def current_hostname
29
+ raise "Current current_hostname not set." if @current_hostname.nil?
30
+ @current_hostname
31
+ end
32
+
33
+ def set_stage(stage)
34
+ @stage_name = stage
35
+ @stage_name.downcase! if @stage_name
36
+ end
37
+
38
+ def stage_name
39
+ @stage_name
40
+ end
41
+
42
+ def stage_name_validated
43
+ # TODO: Document better or fix root cause
44
+ # Work-around for orca file packages that are loaded when required, but stage_name is not going to be used
45
+ # raise "stage_name is required in this context" unless @stage_name
46
+ @stage_name
47
+ end
48
+
49
+ def stage
50
+ # puts data[app_name].inspect
51
+ # puts data[app_name][:stages].inspect
52
+ # puts data[app_name][:stages][stage_name].inspect
53
+ data[app_name][:stages][stage_name]
54
+ end
55
+
56
+ def stage_roles
57
+ raise(Thor::Error, "Stage not defined: #{stage_name}.") if stage.nil?
58
+ stage[:roles]
59
+ end
60
+
61
+ def local_file_name
62
+ File.join(application_dir, Pvcglue::Manager.cloud_data_file_name_base)
63
+ end
64
+
65
+ def env_local_file_name
66
+ File.join(application_dir, Pvcglue::Env.stage_env_file_name_base)
67
+ end
68
+
69
+ def application_dir
70
+ Pvcglue.configuration.application_dir
71
+ end
72
+
73
+ # find node by full node_name or by matching prefix of node_name
74
+ def find_node(node_name)
75
+ puts "*"*80
76
+ raise(Thor::Error, "Node not specified.") if node_name.nil? || node_name.empty?
77
+ return {node_name => nodes_in_stage[node_name]} if nodes_in_stage[node_name]
78
+ puts "-"*80
79
+ nodes_in_stage.each do |key, value|
80
+ puts key
81
+ return {key => value} if key.start_with?(node_name)
82
+ end
83
+ raise(Thor::Error, "Not found: #{node_name} in #{stage_name}.")
84
+ end
85
+
86
+ def nodes_in_stage(role_filter = 'all')
87
+ # puts (stage_roles.values.each_with_object({}) { |node, nodes| nodes.merge!(node) }).inspect
88
+ # stage_roles.values.each_with_object({}) { |node, nodes| nodes.merge!(node) }
89
+ nodes = stage_roles.each_with_object({}) do |(role, node), nodes|
90
+ if role_filter == 'all' || role == role_filter
91
+ nodes.merge!(node)
92
+ end
93
+ end
94
+ # puts nodes.inspect
95
+ # puts "nodes_in_stage: only first returned"+"!*"*80
96
+ # out = {}
97
+ # out["memcached"] = nodes["memcached"]
98
+ # puts out.inspect
99
+ # out
100
+ end
101
+
102
+ # ENV['PVC_DEPLOY_TO_BASE'] = stage_data[:deploy_to] || '/sites'
103
+ def deploy_to_base_dir
104
+ # stage[:deploy_to] || '/sites' # TODO: verify if server setup supports `:deploy_to` override
105
+ Pvcglue.configuration.web_app_base_dir # TODO: server setup does not yet support `:deploy_to` override, and would have to be refactored at a higher level than stage.
106
+ end
107
+
108
+ # ENV['PVC_DEPLOY_TO_APP'] = "#{ENV['PVC_DEPLOY_TO_BASE']}/#{ENV['PVC_APP_NAME']}/#{ENV['PVC_STAGE']}"
109
+ def deploy_to_app_dir
110
+ File.join(deploy_to_base_dir, app_name, stage_name)
111
+ end
112
+
113
+ def deploy_to_app_current_dir
114
+ File.join(deploy_to_app_dir, 'current')
115
+ end
116
+
117
+ def deploy_to_app_shared_dir
118
+ File.join(deploy_to_app_dir, 'shared')
119
+ end
120
+
121
+ def env_file_name
122
+ File.join(deploy_to_app_shared_dir, ".env.#{stage_name_validated}")
123
+ end
124
+
125
+ def deploy_to_app_current_public_dir
126
+ File.join(deploy_to_app_current_dir, 'public')
127
+ end
128
+
129
+ def maintenance_files_dir
130
+ File.join(deploy_to_app_dir, 'maintenance')
131
+ end
132
+
133
+ def maintenance_mode_file_name
134
+ File.join(maintenance_files_dir, 'maintenance.on')
135
+ end
136
+
137
+ def deploy_to_app_current_temp_dir
138
+ File.join(deploy_to_app_current_dir, 'tmp')
139
+ end
140
+
141
+ def restart_txt_file_name
142
+ File.join(deploy_to_app_current_temp_dir, 'restart.txt')
143
+ end
144
+
145
+ def app_name
146
+ Pvcglue.configuration.application_name
147
+ end
148
+
149
+ def authorized_keys
150
+ data[app_name][:authorized_keys]
151
+ end
152
+
153
+ def ssh_ports
154
+ ports = []
155
+ from_all = data[app_name][:ssh_allowed_from_all_port].to_i
156
+ ports << from_all if from_all > 0
157
+ ports
158
+ end
159
+
160
+ def timezone
161
+ data[app_name][:time_zone] || 'America/Los_Angeles'
162
+ end
163
+
164
+ def firewall_allow_incoming_on_port
165
+ # These ports allow incoming connections from any ip address
166
+ ports = []
167
+ from_all = data[app_name][:ssh_allowed_from_all_port].to_i
168
+ ports << from_all if from_all > 0
169
+ ports.concat [80, 443] if current_node.values.first[:allow_public_access]
170
+ ports
171
+ end
172
+
173
+ def firewall_allow_incoming_from_ip
174
+ # Incoming connections to any port are allowed from these ip addresses
175
+ addresses = dev_ip_addresses
176
+ addresses.concat(stage_internal_addresses)
177
+ # puts addresses.inspect
178
+ addresses
179
+ end
180
+
181
+ def dev_ip_addresses
182
+ data[app_name][:dev_ip_addresses].values.each_with_object([]) { |address, addresses| addresses << address }
183
+ end
184
+
185
+ def stage_internal_addresses
186
+ nodes_in_stage.values.each_with_object([]) do |value, addresses|
187
+ addresses << value[:public_ip]
188
+ addresses << value[:private_ip] if value[:private_ip]
189
+ end
190
+ end
191
+
192
+ # app_stage_name = "#{ENV['PVC_APP_NAME']}_#{ENV['PVC_STAGE']}".downcase
193
+ def app_and_stage_name
194
+ "#{app_name}_#{stage_name}".downcase
195
+ end
196
+
197
+ def domains
198
+ stage[:domains]
199
+ end
200
+
201
+ def ssl_mode
202
+ stage[:ssl].to_sym || :none
203
+ end
204
+
205
+ def delayed_job_args
206
+ stage[:delayed_job_args]
207
+ end
208
+
209
+ def repo_url
210
+ data[app_name][:repo_url]
211
+ end
212
+
213
+ def swapfile_size
214
+ data[app_name][:swapfile_size] || stage[:swapfile_size] || 1024
215
+ end
216
+
217
+ def gems
218
+ data[app_name][:gems]
219
+ end
220
+
221
+ def db_rebuild
222
+ !!stage[:db_rebuild]
223
+ end
224
+
225
+ def nginx_config_path
226
+ '/etc/nginx'
227
+ end
228
+
229
+ def nginx_config_ssl_path
230
+ File.join(nginx_config_path, 'ssl')
231
+ end
232
+
233
+ def nginx_ssl_crt_file_name
234
+ File.join(nginx_config_ssl_path, "#{app_and_stage_name}.crt")
235
+ end
236
+
237
+ def nginx_ssl_key_file_name
238
+ File.join(nginx_config_ssl_path, "#{app_and_stage_name}.key")
239
+ end
240
+
241
+ def ssl_crt
242
+ stage[:ssl_crt]
243
+ end
244
+
245
+ def ssl_key
246
+ stage[:ssl_key]
247
+ end
248
+
249
+ def port_in_context(context)
250
+ case context
251
+ when :bootstrap, :manager
252
+ port = "22"
253
+ when :env, :build, :shell, :deploy
254
+ port = data[app_name][:ssh_allowed_from_all_port] || "22"
255
+ else
256
+ raise "Context not specified or invalid"
257
+ end
258
+ puts "Setting port to #{port}"
259
+ @port_in_node_context = port
260
+ end
261
+
262
+ def port_in_node_context
263
+ raise "Context not specified or invalid" if @port_in_node_context.nil?
264
+ puts "Setting port_in_node_context to #{@port_in_node_context}"
265
+ @port_in_node_context
266
+ end
267
+ end
268
+
269
+ def self.cloud
270
+ @cloud ||= Cloud.new
271
+ end
272
+
273
+ def self.cloud=(config)
274
+ @cloud = config
275
+ end
276
+
277
+
278
+ end