pvcglue 0.1.39 → 0.9.0
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.
- 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
|
|