pvcglue 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +91 -0
- data/Rakefile +1 -0
- data/bin/pvc +13 -0
- data/lib/pvcglue.rb +43 -0
- data/lib/pvcglue/all_the_things.rb +7 -0
- data/lib/pvcglue/bootstrap.rb +8 -0
- data/lib/pvcglue/capistrano.rb +35 -0
- data/lib/pvcglue/cli.rb +150 -0
- data/lib/pvcglue/cloud.rb +278 -0
- data/lib/pvcglue/configuration.rb +157 -0
- data/lib/pvcglue/db.rb +145 -0
- data/lib/pvcglue/deploy.rb +4 -0
- data/lib/pvcglue/env.rb +141 -0
- data/lib/pvcglue/manager.rb +137 -0
- data/lib/pvcglue/nodes.rb +29 -0
- data/lib/pvcglue/packages.rb +47 -0
- data/lib/pvcglue/packages/bootstrap.rb +92 -0
- data/lib/pvcglue/packages/env.rb +80 -0
- data/lib/pvcglue/packages/firewall.rb +48 -0
- data/lib/pvcglue/packages/manager.rb +102 -0
- data/lib/pvcglue/packages/nginx.rb +10 -0
- data/lib/pvcglue/packages/nodejs.rb +17 -0
- data/lib/pvcglue/packages/passenger.rb +28 -0
- data/lib/pvcglue/packages/postgresql.rb +10 -0
- data/lib/pvcglue/packages/role_db.rb +47 -0
- data/lib/pvcglue/packages/role_lb.rb +64 -0
- data/lib/pvcglue/packages/role_memcached.rb +14 -0
- data/lib/pvcglue/packages/role_web.rb +60 -0
- data/lib/pvcglue/packages/rvm.rb +75 -0
- data/lib/pvcglue/packages/timezone.rb +17 -0
- data/lib/pvcglue/packages/ubuntu.rb +100 -0
- data/lib/pvcglue/railtie.rb +11 -0
- data/lib/pvcglue/ssl.rb +37 -0
- data/lib/pvcglue/templates/20auto-upgrades.erb +2 -0
- data/lib/pvcglue/templates/authorized_keys.erb +3 -0
- data/lib/pvcglue/templates/capfile.erb +20 -0
- data/lib/pvcglue/templates/database.yml.erb +57 -0
- data/lib/pvcglue/templates/denial_of_service.erb +3 -0
- data/lib/pvcglue/templates/deploy.rb.erb +81 -0
- data/lib/pvcglue/templates/gemrc.erb +1 -0
- data/lib/pvcglue/templates/hosts.erb +9 -0
- data/lib/pvcglue/templates/lb.nginx.conf.erb +88 -0
- data/lib/pvcglue/templates/lb.sites-enabled.erb +74 -0
- data/lib/pvcglue/templates/maintenance_mode.erb +46 -0
- data/lib/pvcglue/templates/memcached.conf.erb +55 -0
- data/lib/pvcglue/templates/passenger.list.erb +2 -0
- data/lib/pvcglue/templates/pg_hba.conf.erb +101 -0
- data/lib/pvcglue/templates/postgresql.conf.erb +557 -0
- data/lib/pvcglue/templates/sshd_config.erb +91 -0
- data/lib/pvcglue/templates/stage-deploy.rb.erb +33 -0
- data/lib/pvcglue/templates/timezone.erb +1 -0
- data/lib/pvcglue/templates/ufw.rules.erb +42 -0
- data/lib/pvcglue/templates/ufw.rules6.erb +25 -0
- data/lib/pvcglue/templates/web.bashrc.erb +120 -0
- data/lib/pvcglue/templates/web.env.erb +3 -0
- data/lib/pvcglue/templates/web.nginx.conf.erb +82 -0
- data/lib/pvcglue/templates/web.sites-enabled.erb +8 -0
- data/lib/pvcglue/toml_pvc_dumper.rb +53 -0
- data/lib/pvcglue/version.rb +3 -0
- data/pvcglue.gemspec +33 -0
- 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
data/Gemfile
ADDED
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,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
|
data/lib/pvcglue/cli.rb
ADDED
@@ -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
|