pvcglue 0.1.39 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/README.md +12 -3
- data/bin/pvc +4 -2
- data/lib/pvcglue.rb +106 -21
- data/lib/pvcglue/bootstrap.rb +1 -1
- data/lib/pvcglue/cli.rb +28 -17
- data/lib/pvcglue/cloud.rb +243 -56
- data/lib/pvcglue/configuration.rb +43 -5
- data/lib/pvcglue/connection.rb +236 -0
- data/lib/pvcglue/custom_hashie.rb +3 -0
- data/lib/pvcglue/db.rb +19 -13
- data/lib/pvcglue/digital_ocean.rb +21 -0
- data/lib/pvcglue/env.rb +52 -28
- data/lib/pvcglue/manager.rb +38 -25
- data/lib/pvcglue/minion.rb +182 -0
- data/lib/pvcglue/nodes.rb +1 -1
- data/lib/pvcglue/{packages → old_packages}/bootstrap.rb +15 -15
- data/lib/pvcglue/{packages → old_packages}/env.rb +8 -8
- data/lib/pvcglue/old_packages/firewall.rb +48 -0
- data/lib/pvcglue/old_packages/manager.rb +116 -0
- data/lib/pvcglue/{packages → old_packages}/monit-bootstrap.rb +0 -0
- data/lib/pvcglue/{packages → old_packages}/monit-web.rb +0 -0
- data/lib/pvcglue/{packages → old_packages}/nginx.rb +0 -0
- data/lib/pvcglue/{packages → old_packages}/nodejs.rb +0 -0
- data/lib/pvcglue/{packages → old_packages}/passenger.rb +0 -0
- data/lib/pvcglue/old_packages/postgresql.rb +10 -0
- data/lib/pvcglue/{packages → old_packages}/role_db.rb +9 -9
- data/lib/pvcglue/{packages → old_packages}/role_lb.rb +6 -6
- data/lib/pvcglue/{packages → old_packages}/role_memcached.rb +0 -0
- data/lib/pvcglue/{packages → old_packages}/role_redis.rb +0 -0
- data/lib/pvcglue/{packages → old_packages}/role_web.rb +9 -9
- data/lib/pvcglue/old_packages/rvm.rb +78 -0
- data/lib/pvcglue/{packages → old_packages}/timezone.rb +0 -0
- data/lib/pvcglue/{packages → old_packages}/ubuntu.rb +0 -0
- data/lib/pvcglue/packages.rb +192 -71
- data/lib/pvcglue/packages/apt.rb +74 -0
- data/lib/pvcglue/packages/apt_repos.rb +48 -0
- data/lib/pvcglue/packages/apt_update.rb +18 -0
- data/lib/pvcglue/packages/apt_upgrade.rb +20 -0
- data/lib/pvcglue/packages/authorized_keys.rb +33 -0
- data/lib/pvcglue/packages/bundler.rb +14 -0
- data/lib/pvcglue/packages/dir_base.rb +16 -0
- data/lib/pvcglue/packages/dir_shared.rb +16 -0
- data/lib/pvcglue/packages/firewall.rb +30 -46
- data/lib/pvcglue/packages/load_balancer.rb +71 -0
- data/lib/pvcglue/packages/maintenance_mode.rb +28 -0
- data/lib/pvcglue/packages/manager.rb +101 -99
- data/lib/pvcglue/packages/postgresql.rb +36 -8
- data/lib/pvcglue/packages/roles.rb +23 -0
- data/lib/pvcglue/packages/ruby.rb +13 -0
- data/lib/pvcglue/packages/rvm.rb +18 -71
- data/lib/pvcglue/packages/secrets.rb +36 -0
- data/lib/pvcglue/packages/ssh_key_check.rb +11 -0
- data/lib/pvcglue/packages/ssl.rb +45 -0
- data/lib/pvcglue/packages/ssl_acme.rb +29 -0
- data/lib/pvcglue/packages/swap.rb +14 -0
- data/lib/pvcglue/packages/unattended_upgrades.rb +20 -0
- data/lib/pvcglue/packages/users.rb +20 -0
- data/lib/pvcglue/packages/web.rb +50 -0
- data/lib/pvcglue/stack.rb +166 -0
- data/lib/pvcglue/templates/50unattended-upgrades.erb +63 -0
- data/lib/pvcglue/templates/capfile.erb +4 -1
- data/lib/pvcglue/templates/deploy.rb.erb +3 -2
- data/lib/pvcglue/templates/lb.sites-enabled.erb +15 -9
- data/lib/pvcglue/templates/letsencrypt-webroot.erb +3 -0
- data/lib/pvcglue/templates/pg_hba.conf.erb +1 -2
- data/lib/pvcglue/templates/postgresql.conf.erb +376 -291
- data/lib/pvcglue/templates/stage-deploy.rb.erb +2 -2
- data/lib/pvcglue/templates/web.bashrc.erb +16 -5
- data/lib/pvcglue/templates/web.nginx.conf.erb +1 -1
- data/lib/pvcglue/templates/web.sites-enabled.erb +1 -1
- data/lib/pvcglue/version.rb +1 -1
- data/pvcglue.gemspec +17 -12
- metadata +125 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29094a42e1588de62c31f9259be0bc1d0f9d4c91
|
4
|
+
data.tar.gz: cc6c3e188893749c8082f821c751992168d1e02e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a87fabdd8819a42e894eaa53253f76585fadeb29edf55989e9e34df16ce720caed49205a425bdda95256b122b5a3cc8624db86cee24906cc95a0eb9950ded82
|
7
|
+
data.tar.gz: 2add0cab736ec4a2c00aef8e29717a7f3c603f4764f39ef2a3d40353557ec26675cb0bfef8aa722083666c8916d43725b0ea7a62517da824224e7e93b6a547d8
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pvcglue
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.4.0
|
data/README.md
CHANGED
@@ -14,14 +14,23 @@ An opinionated cloud application manager for Rails applications using your own s
|
|
14
14
|
|
15
15
|
Currently supported stack:
|
16
16
|
|
17
|
-
*
|
17
|
+
* SSL support: none, manual and automatic with Let's Encrypt
|
18
|
+
* Ubuntu 16.04 LTS
|
19
|
+
* Provision servers automatically on Digital Ocean (and Linode)
|
20
|
+
* No need to install anything on servers first (you just need SSH access)
|
18
21
|
* Ruby >= 1.9 (multiple versions supported on same server)
|
19
22
|
* Rails >= 3.2
|
20
23
|
* RVM
|
21
|
-
* Postgresql 9.
|
24
|
+
* Postgresql 9.6
|
22
25
|
* Nginx
|
23
|
-
* Passenger >
|
26
|
+
* Passenger > 5.0
|
24
27
|
* Memcached
|
28
|
+
* Redis
|
29
|
+
|
30
|
+
Workers:
|
31
|
+
|
32
|
+
* Delayed Job
|
33
|
+
* Rescue
|
25
34
|
|
26
35
|
# This is a work in progress
|
27
36
|
|
data/bin/pvc
CHANGED
@@ -9,6 +9,8 @@ if ARGV.count >= 2 && %w[local vmtest test alpha beta gamma delta preview produc
|
|
9
9
|
ARGV[0], ARGV[1] = ARGV[1], "--stage=#{ARGV[0]}"
|
10
10
|
end
|
11
11
|
|
12
|
-
|
12
|
+
Pvcglue.logger.info('Starting up...')
|
13
|
+
Pvcglue.logger.debug { ARGV.inspect }
|
13
14
|
# puts Benchmark.measure { Pvcglue::CLI.start }
|
14
|
-
|
15
|
+
# pvc_puts.warn("----- Done #{Benchmark.measure { Pvcglue::CLI.start }}")
|
16
|
+
Pvcglue.logger.info("----- Done #{Benchmark.measure { Pvcglue::CLI.start }}")
|
data/lib/pvcglue.rb
CHANGED
@@ -1,29 +1,114 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
1
|
+
require 'pvcglue/version'
|
2
|
+
require 'thor'
|
3
|
+
require 'pvcglue/configuration'
|
4
|
+
require 'pvcglue/manager'
|
5
|
+
require 'pvcglue/cloud'
|
6
|
+
require 'pvcglue/packages'
|
7
|
+
Dir[File.dirname(__FILE__) + '/pvcglue/packages/*.rb'].each { |file| require file }
|
8
|
+
require 'pvcglue/bootstrap'
|
9
|
+
require 'pvcglue/nodes'
|
10
|
+
require 'pvcglue/stack'
|
11
|
+
require 'pvcglue/env'
|
12
|
+
require 'pvcglue/deploy'
|
13
|
+
require 'pvcglue/capistrano'
|
14
|
+
require 'pvcglue/ssl'
|
15
|
+
require 'pvcglue/db'
|
16
|
+
require 'pvcglue/toml_pvc_dumper'
|
17
|
+
require 'pvcglue/local'
|
18
|
+
require 'pvcglue/monit'
|
19
|
+
require 'pvcglue/pvcify'
|
20
|
+
require 'tilt'
|
21
|
+
require 'awesome_print'
|
22
|
+
require 'hashie'
|
23
|
+
require 'pvcglue/custom_hashie'
|
24
|
+
require 'pvcglue/minion'
|
25
|
+
require 'droplet_kit'
|
26
|
+
require 'pvcglue/digital_ocean'
|
27
|
+
require 'logger'
|
28
|
+
require 'pvcglue/connection'
|
29
|
+
require 'paint'
|
30
|
+
require 'pry'
|
19
31
|
|
20
32
|
# puts File.join(File.dirname(__FILE__), 'pvcglue', 'packages', '*.rb')
|
33
|
+
# pvc manager bootstrap --cloud_manager_override=local_cloud.pvcglue.toml --save_before_upload=save --verbose
|
21
34
|
|
22
35
|
module Pvcglue
|
23
36
|
mattr_accessor :command_line_options do
|
24
37
|
{}
|
25
38
|
end
|
26
39
|
|
40
|
+
mattr_accessor :logger do
|
41
|
+
|
42
|
+
logger = Logger.new(STDOUT)
|
43
|
+
# logger.level = Logger::INFO # DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
|
44
|
+
logger.level = Logger::DEBUG # DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
|
45
|
+
# logger.warn('Starting up...')
|
46
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
47
|
+
minion_name = Pvcglue.logger_current_minion.try(:machine_name)
|
48
|
+
minion_name = "/#{minion_name}" if minion_name
|
49
|
+
description = Pvcglue.logger_package_description
|
50
|
+
if description
|
51
|
+
description = description.split('::').last || description
|
52
|
+
description = "/#{description.downcase}"
|
53
|
+
end
|
54
|
+
foreground = nil
|
55
|
+
# background = 'black'
|
56
|
+
background = nil
|
57
|
+
case severity[0..0]
|
58
|
+
when 'E'
|
59
|
+
foreground = 'red'
|
60
|
+
when 'W'
|
61
|
+
# foreground = 'black'
|
62
|
+
# background = 'yellow'
|
63
|
+
foreground = 'yellow'
|
64
|
+
when 'I'
|
65
|
+
foreground = 'purple'
|
66
|
+
when 'D'
|
67
|
+
foreground = 'cyan'
|
68
|
+
else
|
69
|
+
foreground = 'black'
|
70
|
+
background = 'red'
|
71
|
+
end
|
72
|
+
# case severity[0..0]
|
73
|
+
# when 'E'
|
74
|
+
# color = :redish
|
75
|
+
# when 'W'
|
76
|
+
# color = :yellowish
|
77
|
+
# when 'I'
|
78
|
+
# color = :purpleish
|
79
|
+
# when 'D'
|
80
|
+
# color = :cyanish
|
81
|
+
# else
|
82
|
+
# color = :yellowish
|
83
|
+
# end
|
84
|
+
# "#{severity[0..0]} [#{datetime.strftime('%H:%M:%S')}#{minion_name}#{description}] #{msg}\n".send(color)
|
85
|
+
Paint["#{severity[0..0]} [#{datetime.strftime('%H:%M:%S')}#{minion_name}#{description}] #{msg}\n", foreground, background]
|
86
|
+
end
|
87
|
+
logger
|
88
|
+
end
|
89
|
+
mattr_accessor :logger_package_description
|
90
|
+
mattr_accessor :logger_current_minion
|
91
|
+
|
92
|
+
def self.verbose?
|
93
|
+
return if @filtering_verbose
|
94
|
+
if Pvcglue.command_line_options[:verbose]
|
95
|
+
puts yield
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.filter_verbose
|
100
|
+
@filtering_verbose = true
|
101
|
+
begin
|
102
|
+
yield
|
103
|
+
ensure
|
104
|
+
@filtering_verbose = false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.reset_minion_state?
|
109
|
+
!!Pvcglue.command_line_options[:rebuild]
|
110
|
+
end
|
111
|
+
|
27
112
|
def self.gem_dir
|
28
113
|
Gem::Specification.find_by_name('pvcglue').gem_dir
|
29
114
|
end
|
@@ -33,8 +118,8 @@ module Pvcglue
|
|
33
118
|
end
|
34
119
|
|
35
120
|
def self.render_template(template, file_name = nil)
|
36
|
-
puts '-'*80
|
37
|
-
puts "---> render_template(template=#{template}, file_name=#{file_name}"
|
121
|
+
# puts '-'*80
|
122
|
+
# puts "---> render_template(template=#{template}, file_name=#{file_name}"
|
38
123
|
data = Tilt.new(Pvcglue.template_file_name(template)).render
|
39
124
|
if file_name
|
40
125
|
File.write(file_name, data)
|
@@ -47,7 +132,7 @@ module Pvcglue
|
|
47
132
|
# puts "Running `#{cmd}`"
|
48
133
|
|
49
134
|
unless system cmd
|
50
|
-
raise(
|
135
|
+
raise("Error: #{$?}")
|
51
136
|
end
|
52
137
|
true
|
53
138
|
end
|
data/lib/pvcglue/bootstrap.rb
CHANGED
@@ -2,7 +2,7 @@ module Pvcglue
|
|
2
2
|
class Bootstrap
|
3
3
|
def self.run(roles)
|
4
4
|
# puts "This is where it should bootstrap #{Pvcglue.cloud.stage_name}. :)"
|
5
|
-
Pvcglue::Packages.apply('bootstrap'.to_sym, :bootstrap, Pvcglue.cloud.
|
5
|
+
Pvcglue::Packages.apply('bootstrap'.to_sym, :bootstrap, Pvcglue.cloud.minions_filtered(roles), 'root')
|
6
6
|
end
|
7
7
|
end
|
8
8
|
end
|
data/lib/pvcglue/cli.rb
CHANGED
@@ -6,6 +6,11 @@ module Pvcglue
|
|
6
6
|
|
7
7
|
class CLI < Thor
|
8
8
|
class_option :cloud_manager_override
|
9
|
+
class_option :verbose
|
10
|
+
class_option :rebuild
|
11
|
+
class_option :save_before_upload
|
12
|
+
class_option :create_test_cert
|
13
|
+
class_option :force_cert
|
9
14
|
|
10
15
|
def initialize(args = [], local_options = {}, config = {})
|
11
16
|
super
|
@@ -48,22 +53,23 @@ module Pvcglue
|
|
48
53
|
method_option :stage, :required => true, :aliases => "-s"
|
49
54
|
|
50
55
|
def build(roles = 'all')
|
51
|
-
Pvcglue::
|
56
|
+
Pvcglue::Stack.build(Pvcglue.cloud.minions, roles)
|
52
57
|
end
|
53
58
|
|
54
59
|
desc "console", "open rails console"
|
55
60
|
method_option :stage, :required => true, :aliases => "-s"
|
56
61
|
|
57
62
|
def console(server='web')
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
# puts "*"*80
|
62
|
-
# puts node.inspect
|
63
|
-
puts "Connection to #{node_name} (#{node_data[:public_ip]}) as user 'deploy'..."
|
63
|
+
data = Pvcglue.cloud.minions_filtered(server)
|
64
|
+
minion_name = data.keys.first
|
65
|
+
minion = data.values.first
|
64
66
|
working_dir = Pvcglue.cloud.deploy_to_app_current_dir
|
65
|
-
|
67
|
+
Pvcglue.logger.warn("Opening Rails console on #{minion_name} (#{minion.public_ip}) as user '#{minion.remote_user_name}'...")
|
68
|
+
Pvcglue.logger.debug("Project root: #{working_dir}")
|
66
69
|
|
70
|
+
cmd = "cd #{working_dir} && bundle exec rails c #{options[:stage].downcase}"
|
71
|
+
# system(%(ssh -t deploy@#{node_data[:public_ip]} "cd #{working_dir} && echo 'Starting #{options[:stage].upcase} Rails console in #{working_dir}' && bundle exec rails c #{options[:stage].downcase}"))
|
72
|
+
minion.connection.ssh!(minion.remote_user_name, '-t', cmd)
|
67
73
|
end
|
68
74
|
|
69
75
|
desc "c", "shortcut for console"
|
@@ -96,8 +102,11 @@ module Pvcglue
|
|
96
102
|
|
97
103
|
def maintenance(mode)
|
98
104
|
raise(Thor::Error, "invalid maintenance mode :( (Hint: try on or off.)") unless mode.in?(%w(on off))
|
99
|
-
Pvcglue.cloud.maintenance_mode = mode
|
100
|
-
Pvcglue::Packages.apply(:maintenance_mode, :maintenance, Pvcglue.cloud.nodes_in_stage('lb'))
|
105
|
+
# Pvcglue.cloud.maintenance_mode = mode
|
106
|
+
# Pvcglue::Packages.apply(:maintenance_mode, :maintenance, Pvcglue.cloud.nodes_in_stage('lb'))
|
107
|
+
Pvcglue.cloud.minions_filtered('lb').each do |minioin_name, minion|
|
108
|
+
Pvcglue::Packages::MaintenanceMode.apply(minion, {maintenance_mode: mode})
|
109
|
+
end
|
101
110
|
end
|
102
111
|
|
103
112
|
desc "maint", "enable or disable maintenance mode"
|
@@ -120,7 +129,7 @@ module Pvcglue
|
|
120
129
|
def bypass(mode)
|
121
130
|
raise(Thor::Error, "invalid maintenance bypass mode :( (Hint: try on or off.)") unless mode.in?(%w(on off))
|
122
131
|
Pvcglue.cloud.bypass_mode = mode
|
123
|
-
Pvcglue::Packages.apply(:bypass_mode, :maintenance, Pvcglue.cloud.
|
132
|
+
Pvcglue::Packages.apply(:bypass_mode, :maintenance, Pvcglue.cloud.minions_filtered('lb'))
|
124
133
|
end
|
125
134
|
|
126
135
|
desc "b", "enable or disable maintenance mode bypass for developers"
|
@@ -135,13 +144,15 @@ module Pvcglue
|
|
135
144
|
method_option :stage, :required => true, :aliases => "-s"
|
136
145
|
|
137
146
|
def sh(server='web') # `shell` is a Thor reserved word
|
138
|
-
|
139
|
-
|
140
|
-
|
147
|
+
data = Pvcglue.cloud.minions_filtered(server)
|
148
|
+
minion_name = data.keys.first
|
149
|
+
minion = data.values.first
|
141
150
|
# puts "*"*80
|
142
151
|
# puts node.inspect
|
143
|
-
|
144
|
-
|
152
|
+
Pvcglue.logger.warn("Connecting to #{minion_name} (#{minion.public_ip}) as user '#{minion.remote_user_name}'...")
|
153
|
+
# puts "Connection to #{minion_name} (#{minion.public_ip}) as user '#{minion.remote_user_name}'..."
|
154
|
+
# system("ssh -p #{Pvcglue.cloud.port_in_context(:shell)} #{minion.remote_user_name}@#{minion[:public_ip]}")
|
155
|
+
minion.connection.ssh!(minion.remote_user_name, '', '')
|
145
156
|
end
|
146
157
|
|
147
158
|
desc "s", "shell"
|
@@ -163,7 +174,7 @@ module Pvcglue
|
|
163
174
|
|
164
175
|
def rake(*tasks)
|
165
176
|
if Pvcglue.cloud.stage_name == 'production'
|
166
|
-
|
177
|
+
# if Pvcglue.cloud.stage_name == 'local'
|
167
178
|
raise(Thor::Error, "\nDidn't think so!\n") unless yes?("\n\nStop! Think! Are you sure you want to do this on the #{Pvcglue.cloud.stage_name} stage? (y/N)")
|
168
179
|
end
|
169
180
|
Pvcglue::Capistrano.rake(tasks)
|
data/lib/pvcglue/cloud.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require "active_support"
|
2
2
|
require "active_support/core_ext" # for `with_indifferent_access`
|
3
3
|
|
4
|
-
|
5
4
|
module Pvcglue
|
6
5
|
class Cloud
|
7
6
|
attr_accessor :data
|
@@ -12,6 +11,7 @@ module Pvcglue
|
|
12
11
|
attr_accessor :stage_env
|
13
12
|
attr_accessor :passenger_ruby
|
14
13
|
attr_accessor :port_in_node_context
|
14
|
+
# attr_accessor :stage_secrets
|
15
15
|
|
16
16
|
def data
|
17
17
|
::Pvcglue::Manager.initialize_cloud_data unless @data
|
@@ -19,7 +19,10 @@ module Pvcglue
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def data=(data)
|
22
|
-
@data = data.with_indifferent_access # We may not want this dependency.
|
22
|
+
# @data = data.with_indifferent_access # We may not want this dependency.
|
23
|
+
# @data = data.to_dot # We may not want this dependency.
|
24
|
+
# @data = Hashie::Mash.new(data) # We may not want this dependency.
|
25
|
+
@data = ::SafeMash.new(data)
|
23
26
|
end
|
24
27
|
|
25
28
|
def current_node
|
@@ -57,11 +60,11 @@ module Pvcglue
|
|
57
60
|
@stage_name
|
58
61
|
end
|
59
62
|
|
60
|
-
def
|
61
|
-
# puts
|
62
|
-
# puts
|
63
|
-
# puts
|
64
|
-
|
63
|
+
def old_stage
|
64
|
+
# puts project.inspect
|
65
|
+
# puts project[:stages].inspect
|
66
|
+
# puts project[:stages][stage_name].inspect
|
67
|
+
project[:stages][stage_name]
|
65
68
|
end
|
66
69
|
|
67
70
|
def stage_roles
|
@@ -83,39 +86,56 @@ module Pvcglue
|
|
83
86
|
end
|
84
87
|
|
85
88
|
# find node by full node_name or by matching prefix of node_name
|
86
|
-
def
|
87
|
-
|
88
|
-
raise(
|
89
|
-
return {
|
90
|
-
|
91
|
-
|
92
|
-
puts key
|
93
|
-
return {key => value} if key.start_with?(node_name)
|
89
|
+
def find_minion_by_name(minion_name, raise_error = true)
|
90
|
+
# raise(Thor::Error, "Node not specified.") if node_name.nil? || node_name.empty?
|
91
|
+
raise('Minion not specified.') if minion_name.nil? || minion_name.empty?
|
92
|
+
return {minion_name => minions_filtered[minion_name]} if minions[minion_name]
|
93
|
+
minions.each do |key, value|
|
94
|
+
return {key => value} if key.start_with?(minion_name)
|
94
95
|
end
|
95
|
-
raise("Not found: #{
|
96
|
+
raise("Not found: #{minion_name} in #{stage_name}.") if raise_error
|
96
97
|
# raise(Thor::Error, "Not found: #{node_name} in #{stage_name}.")
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
|
101
|
+
# # find node by full node_name or by matching prefix of node_name
|
102
|
+
# def find_node(node_name, raise_error = true)
|
103
|
+
# # raise(Thor::Error, "Node not specified.") if node_name.nil? || node_name.empty?
|
104
|
+
# raise('Node not specified.') if node_name.nil? || node_name.empty?
|
105
|
+
# return {node_name => nodes_in_stage[node_name]} if nodes_in_stage[node_name]
|
106
|
+
# nodes_in_stage.each do |key, value|
|
107
|
+
# return {key => value} if key.start_with?(node_name)
|
108
|
+
# end
|
109
|
+
# raise("Not found: #{node_name} in #{stage_name}.") if raise_error
|
110
|
+
# # raise(Thor::Error, "Not found: #{node_name} in #{stage_name}.")
|
111
|
+
# end
|
112
|
+
#
|
113
|
+
def minions_filtered(role_filter = 'all')
|
114
|
+
# # puts (stage_roles.values.each_with_object({}) { |node, nodes| nodes.merge!(node) }).inspect
|
115
|
+
# # stage_roles.values.each_with_object({}) { |node, nodes| nodes.merge!(node) }
|
116
|
+
# nodes = stage_roles.each_with_object({}) do |(role, node), nodes|
|
117
|
+
# if role_filter == 'all' || role == role_filter
|
118
|
+
# nodes.merge!(node)
|
119
|
+
# end
|
120
|
+
# end
|
121
|
+
# # puts nodes.inspect
|
122
|
+
# # puts "nodes_in_stage: only first returned"+"!*"*80
|
123
|
+
# # out = {}
|
124
|
+
# # out["memcached"] = nodes["memcached"]
|
125
|
+
# # puts out.inspect
|
126
|
+
# # out
|
127
|
+
if role_filter == 'all'
|
128
|
+
minions
|
129
|
+
else
|
130
|
+
minions.select { |minion_name, minion| minion.has_role?(role_filter) }
|
106
131
|
end
|
107
|
-
|
108
|
-
# puts "nodes_in_stage: only first returned"+"!*"*80
|
109
|
-
# out = {}
|
110
|
-
# out["memcached"] = nodes["memcached"]
|
111
|
-
# puts out.inspect
|
112
|
-
# out
|
132
|
+
|
113
133
|
end
|
114
134
|
|
115
135
|
# ENV['PVC_DEPLOY_TO_BASE'] = stage_data[:deploy_to] || '/sites'
|
116
136
|
def deploy_to_base_dir
|
117
137
|
# stage[:deploy_to] || '/sites' # TODO: verify if server setup supports `:deploy_to` override
|
118
|
-
|
138
|
+
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.
|
119
139
|
end
|
120
140
|
|
121
141
|
# ENV['PVC_DEPLOY_TO_APP'] = "#{ENV['PVC_DEPLOY_TO_BASE']}/#{ENV['PVC_APP_NAME']}/#{ENV['PVC_STAGE']}"
|
@@ -172,28 +192,29 @@ module Pvcglue
|
|
172
192
|
end
|
173
193
|
|
174
194
|
def authorized_keys
|
175
|
-
|
195
|
+
project[:authorized_keys]
|
176
196
|
end
|
177
197
|
|
178
198
|
def ssh_ports
|
179
199
|
ports = []
|
180
|
-
from_all =
|
200
|
+
from_all = project[:ssh_allowed_from_all_port].to_i
|
181
201
|
ports << from_all if from_all > 0
|
182
202
|
ports
|
183
203
|
end
|
184
204
|
|
185
205
|
def timezone
|
186
|
-
|
206
|
+
project[:time_zone] || 'America/Los_Angeles'
|
187
207
|
end
|
188
208
|
|
189
209
|
def exclude_tables
|
190
|
-
|
210
|
+
project[:excluded_db_tables] || ['versions']
|
191
211
|
end
|
192
212
|
|
193
213
|
def firewall_allow_incoming_on_port
|
214
|
+
raise 'Not used currently > 0.9'
|
194
215
|
# These ports allow incoming connections from any ip address
|
195
216
|
ports = []
|
196
|
-
from_all =
|
217
|
+
from_all = project[:ssh_allowed_from_all_port].to_i
|
197
218
|
ports << from_all if from_all > 0
|
198
219
|
ports.concat [80, 443] if current_node.values.first[:allow_public_access]
|
199
220
|
ports.concat ["2000:3000"] if stage_name == 'local'
|
@@ -201,6 +222,7 @@ module Pvcglue
|
|
201
222
|
end
|
202
223
|
|
203
224
|
def firewall_allow_incoming_from_ip
|
225
|
+
raise 'Not used currently > 0.9'
|
204
226
|
# Incoming connections to any port are allowed from these ip addresses
|
205
227
|
addresses = dev_ip_addresses
|
206
228
|
addresses.concat(stage_internal_addresses)
|
@@ -213,11 +235,13 @@ module Pvcglue
|
|
213
235
|
end
|
214
236
|
|
215
237
|
def dev_ip_addresses
|
216
|
-
|
238
|
+
return ['127.0.0.1']
|
239
|
+
# TODO: Add this functionality back in later
|
240
|
+
project[:dev_ip_addresses].values.each_with_object([]) { |address, addresses| addresses << address }
|
217
241
|
end
|
218
242
|
|
219
243
|
def stage_internal_addresses
|
220
|
-
|
244
|
+
minions_filtered.values.each_with_object([]) do |value, addresses|
|
221
245
|
addresses << value[:public_ip]
|
222
246
|
addresses << value[:private_ip] if value[:private_ip]
|
223
247
|
end
|
@@ -244,6 +268,14 @@ module Pvcglue
|
|
244
268
|
stage[:ssl].to_sym || :none
|
245
269
|
end
|
246
270
|
|
271
|
+
def ssl_mode_override
|
272
|
+
@ssl_mode_override || ssl_mode
|
273
|
+
end
|
274
|
+
|
275
|
+
def set_ssl_mode_override(mode)
|
276
|
+
@ssl_mode_override = mode
|
277
|
+
end
|
278
|
+
|
247
279
|
def lb_nginx_load_balancing_method
|
248
280
|
stage[:lb_nginx_load_balancing_method]
|
249
281
|
end
|
@@ -253,51 +285,51 @@ module Pvcglue
|
|
253
285
|
end
|
254
286
|
|
255
287
|
def repo_url
|
256
|
-
|
288
|
+
project[:repo_url]
|
257
289
|
end
|
258
290
|
|
259
291
|
def dos_conn_limit_per_ip
|
260
|
-
|
292
|
+
project[:dos_conn_limit_per_ip] || stage[:dos_conn_limit_per_ip] || "10"
|
261
293
|
end
|
262
294
|
|
263
295
|
def dos_rate
|
264
|
-
|
296
|
+
project[:dos_rate] || stage[:dos_rate] || "1"
|
265
297
|
end
|
266
298
|
|
267
299
|
def dos_burst
|
268
|
-
|
300
|
+
project[:dos_burst] || stage[:dos_burst] || "30"
|
269
301
|
end
|
270
302
|
|
271
303
|
def additional_linked_dirs
|
272
|
-
|
304
|
+
project[:additional_linked_dirs] || stage[:additional_linked_dirs] || ""
|
273
305
|
end
|
274
306
|
|
275
307
|
def client_header_timeout
|
276
|
-
|
308
|
+
project[:client_header_timeout] || stage[:client_header_timeout] || "60s"
|
277
309
|
end
|
278
310
|
|
279
311
|
def client_body_timeout
|
280
|
-
|
312
|
+
project[:client_body_timeout] || stage[:client_body_timeout] || "60s"
|
281
313
|
end
|
282
314
|
|
283
315
|
def proxy_read_timeout
|
284
|
-
|
316
|
+
project[:proxy_read_timeout] || stage[:proxy_read_timeout] || "60s"
|
285
317
|
end
|
286
318
|
|
287
319
|
def proxy_send_timeout
|
288
|
-
|
320
|
+
project[:proxy_send_timeout] || stage[:proxy_send_timeout] || "60s"
|
289
321
|
end
|
290
322
|
|
291
323
|
def client_max_body_size
|
292
|
-
|
324
|
+
project[:client_max_body_size] || stage[:client_max_body_size] || "1m"
|
293
325
|
end
|
294
326
|
|
295
327
|
def swapfile_size
|
296
|
-
|
328
|
+
project[:swapfile_size] || stage[:swapfile_size] || 1024
|
297
329
|
end
|
298
330
|
|
299
331
|
def gems
|
300
|
-
|
332
|
+
project[:gems] || {}
|
301
333
|
end
|
302
334
|
|
303
335
|
def db_rebuild
|
@@ -309,7 +341,7 @@ module Pvcglue
|
|
309
341
|
end
|
310
342
|
|
311
343
|
def nginx_config_ssl_path
|
312
|
-
File.join(nginx_config_path, 'ssl')
|
344
|
+
File.join(nginx_config_path, 'ssl', "#{app_and_stage_name}")
|
313
345
|
end
|
314
346
|
|
315
347
|
def nginx_ssl_crt_file_name
|
@@ -333,7 +365,7 @@ module Pvcglue
|
|
333
365
|
when :bootstrap, :manager
|
334
366
|
port = "22"
|
335
367
|
when :env, :build, :shell, :deploy, :maintenance
|
336
|
-
port =
|
368
|
+
port = project[:ssh_allowed_from_all_port] || "22"
|
337
369
|
else
|
338
370
|
raise "Context not specified or invalid"
|
339
371
|
end
|
@@ -358,15 +390,170 @@ module Pvcglue
|
|
358
390
|
end
|
359
391
|
|
360
392
|
def monit_mailserver
|
361
|
-
|
393
|
+
project[:monit_mailserver] || ""
|
362
394
|
end
|
363
395
|
|
364
396
|
def monit_alert
|
365
|
-
|
397
|
+
project[:monit_alert] || ""
|
366
398
|
end
|
367
399
|
|
368
400
|
def monit_disk_usage_threshold
|
369
|
-
stage[:monit_disk_usage_threshold] ||
|
401
|
+
stage[:monit_disk_usage_threshold] || project[:monit_disk_usage_threshold] || "80%"
|
402
|
+
end
|
403
|
+
|
404
|
+
def minion_manager_user_name
|
405
|
+
'manager'
|
406
|
+
end
|
407
|
+
|
408
|
+
def letsencrypt_full
|
409
|
+
'/var/www/letsencrypt_root/.well-known/acme-challenge'
|
410
|
+
end
|
411
|
+
|
412
|
+
def letsencrypt_root
|
413
|
+
'/var/www/letsencrypt_root'
|
414
|
+
end
|
415
|
+
|
416
|
+
|
417
|
+
# ==============================================================================================
|
418
|
+
|
419
|
+
def manager_minion
|
420
|
+
@manager_minion ||= get_manager_minion
|
421
|
+
end
|
422
|
+
|
423
|
+
def get_manager_minion
|
424
|
+
minion = Pvcglue::Minion.new
|
425
|
+
minion.machine_name = 'pvcglue-manager'
|
426
|
+
minion.roles = ['manager']
|
427
|
+
minion.public_ip = Pvcglue.configuration.cloud_manager
|
428
|
+
minion.connection = Pvcglue::Connection.new(minion)
|
429
|
+
# minion.root_users = machine.root_users
|
430
|
+
# minion.users = machine.users
|
431
|
+
# minion.cloud_id = machine.cloud_id
|
432
|
+
minion.remote_user_name = minion_manager_user_name
|
433
|
+
# minion.all_data = data
|
434
|
+
# minion.project = project
|
435
|
+
# minion.stage = stage
|
436
|
+
# minion.cloud_provider = data.cloud_provider
|
437
|
+
# minion.cloud = ::Pvcglue.cloud
|
438
|
+
# minion.cloud_provider.name == 'not-supported'
|
439
|
+
minion
|
440
|
+
|
441
|
+
end
|
442
|
+
|
443
|
+
# def set_manager_as_project
|
444
|
+
#
|
445
|
+
# # raise('project already initialized') if @project
|
446
|
+
# # @project = find_or_raise(data.projects, 'pvcglue_manager')
|
447
|
+
# @app_name_override = 'pvcglue_manager'
|
448
|
+
# set_stage('manager')
|
449
|
+
# end
|
450
|
+
|
451
|
+
def reload_minions!
|
452
|
+
@data = nil
|
453
|
+
@project = nil
|
454
|
+
@stage = nil
|
455
|
+
@minions = nil
|
456
|
+
end
|
457
|
+
|
458
|
+
def web_app_base_dir
|
459
|
+
# '/sites'
|
460
|
+
"/home/#{minion_user_name}/www"
|
461
|
+
end
|
462
|
+
|
463
|
+
|
464
|
+
def minion_user_name_base
|
465
|
+
project[:user_name_base] || 'deploy'
|
466
|
+
end
|
467
|
+
|
468
|
+
def minion_user_name
|
469
|
+
"#{minion_user_name_base}-#{stage_name}"
|
470
|
+
end
|
471
|
+
|
472
|
+
|
473
|
+
def find_or_raise(data, name, key = 'name')
|
474
|
+
found = data.detect { |item| item[key] == name }
|
475
|
+
# raise(Thor::Error, "Error: #{name} not found.") unless found
|
476
|
+
unless found
|
477
|
+
puts "name=#{name}, key=#{key}, data="
|
478
|
+
ap data
|
479
|
+
raise("Error: #{name} not found.")
|
480
|
+
end
|
481
|
+
found
|
482
|
+
end
|
483
|
+
|
484
|
+
def project
|
485
|
+
@project ||= begin
|
486
|
+
get_project
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
def project_name
|
491
|
+
project.name
|
492
|
+
end
|
493
|
+
|
494
|
+
def get_project
|
495
|
+
find_or_raise(data.projects, @app_name_override || app_name)
|
496
|
+
end
|
497
|
+
|
498
|
+
def stage
|
499
|
+
@stage ||= begin
|
500
|
+
find_or_raise(project.stages, stage_name)
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
def minions
|
505
|
+
@minions ||= get_minions
|
506
|
+
end
|
507
|
+
|
508
|
+
def find_machine(name)
|
509
|
+
name.tr!('=', '') # "==dev-lb==" ==> "dev-lb"
|
510
|
+
find_or_raise(data.machines, name)
|
511
|
+
end
|
512
|
+
|
513
|
+
def get_minions
|
514
|
+
minions = ::SafeMash.new
|
515
|
+
stage.stack.each do |item|
|
516
|
+
# ap item
|
517
|
+
machine = find_machine(item.machine_name)
|
518
|
+
# ap machine
|
519
|
+
minion = minions[machine.name]
|
520
|
+
# ap minion
|
521
|
+
unless minion
|
522
|
+
# TODO: check for duplicate roles: ie. 2 web servers with the same id
|
523
|
+
minion = Pvcglue::Minion.new
|
524
|
+
minion.machine_name = item.machine_name
|
525
|
+
minion.roles = []
|
526
|
+
minion.private_ip = machine.private_ip
|
527
|
+
minion.public_ip = machine.public_ip
|
528
|
+
minion.connection = Pvcglue::Connection.new(minion)
|
529
|
+
minion.root_users = machine.root_users
|
530
|
+
minion.users = machine.users
|
531
|
+
minion.cloud_id = machine.cloud_id
|
532
|
+
minion.remote_user_name = minion_user_name
|
533
|
+
# TODO: sync all machine options here, automatically
|
534
|
+
end
|
535
|
+
# ap minion
|
536
|
+
# puts "*"*175
|
537
|
+
# ap minion.roles
|
538
|
+
# ap item.role
|
539
|
+
minion.roles << item.role
|
540
|
+
# ap minion.roles
|
541
|
+
|
542
|
+
# if item.role_index?
|
543
|
+
# minions
|
544
|
+
# end
|
545
|
+
# ap minion
|
546
|
+
|
547
|
+
minion.all_data = data
|
548
|
+
minion.project = project
|
549
|
+
minion.stage = stage
|
550
|
+
minion.cloud_provider = data.cloud_provider
|
551
|
+
minion.cloud = ::Pvcglue.cloud
|
552
|
+
|
553
|
+
minions[machine.name] = minion
|
554
|
+
end
|
555
|
+
# ap minions
|
556
|
+
minions
|
370
557
|
end
|
371
558
|
end
|
372
559
|
|