vpsb 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +175 -0
- data/LICENSE.txt +22 -0
- data/README.md +62 -0
- data/Rakefile +2 -0
- data/bin/vpsb +10 -0
- data/lib/vpsb/ask_support.rb +27 -0
- data/lib/vpsb/base_ask_resource.rb +40 -0
- data/lib/vpsb/base_resource.rb +13 -0
- data/lib/vpsb/base_task.rb +32 -0
- data/lib/vpsb/commands/base.rb +68 -0
- data/lib/vpsb/commands/build.rb +61 -0
- data/lib/vpsb/commands/cook.rb +27 -0
- data/lib/vpsb/commands/deploy.rb +25 -0
- data/lib/vpsb/commands/help_messages.rb +23 -0
- data/lib/vpsb/commands/init.rb +52 -0
- data/lib/vpsb/commands/setup.rb +23 -0
- data/lib/vpsb/core.rb +41 -0
- data/lib/vpsb/helpers/file_replace.rb +20 -0
- data/lib/vpsb/helpers/ssh.rb +117 -0
- data/lib/vpsb/resources/app_bags_json.rb +38 -0
- data/lib/vpsb/resources/app_env_variables.rb +24 -0
- data/lib/vpsb/resources/app_host.rb +12 -0
- data/lib/vpsb/resources/app_name.rb +11 -0
- data/lib/vpsb/resources/app_nginx_use_ssl.rb +12 -0
- data/lib/vpsb/resources/base_path.rb +10 -0
- data/lib/vpsb/resources/db_postgres_json.rb +62 -0
- data/lib/vpsb/resources/db_postgres_pass.rb +11 -0
- data/lib/vpsb/resources/db_postgres_version.rb +21 -0
- data/lib/vpsb/resources/db_postgresql_bags_json.rb +20 -0
- data/lib/vpsb/resources/deploy_bags_json.rb +36 -0
- data/lib/vpsb/resources/deploy_config.rb +32 -0
- data/lib/vpsb/resources/deploy_keychain.rb +19 -0
- data/lib/vpsb/resources/deploy_pass.rb +11 -0
- data/lib/vpsb/resources/deploy_ssh_keys.rb +20 -0
- data/lib/vpsb/resources/deploy_to_known_hosts.rb +13 -0
- data/lib/vpsb/resources/do_api_key.rb +14 -0
- data/lib/vpsb/resources/do_client_id.rb +8 -0
- data/lib/vpsb/resources/do_droplet_ssh_key.rb +15 -0
- data/lib/vpsb/resources/do_host.rb +8 -0
- data/lib/vpsb/resources/do_host_ip.rb +8 -0
- data/lib/vpsb/resources/do_image.rb +16 -0
- data/lib/vpsb/resources/do_region.rb +16 -0
- data/lib/vpsb/resources/do_size.rb +16 -0
- data/lib/vpsb/resources/do_ssh_path.rb +15 -0
- data/lib/vpsb/resources/do_ssh_pub_path.rb +15 -0
- data/lib/vpsb/resources/es_cluster_name.rb +9 -0
- data/lib/vpsb/resources/es_json.rb +50 -0
- data/lib/vpsb/resources/es_memlock.rb +18 -0
- data/lib/vpsb/resources/es_node_name.rb +8 -0
- data/lib/vpsb/resources/es_nofile.rb +18 -0
- data/lib/vpsb/resources/es_version.rb +21 -0
- data/lib/vpsb/resources/has_do_account.rb +19 -0
- data/lib/vpsb/resources/hostname.rb +12 -0
- data/lib/vpsb/resources/knife_rb_path.rb +10 -0
- data/lib/vpsb/resources/local_ssh_path.rb +15 -0
- data/lib/vpsb/resources/local_ssh_pub.rb +13 -0
- data/lib/vpsb/resources/monit_role_json.rb +33 -0
- data/lib/vpsb/resources/newrelic_lic.rb +8 -0
- data/lib/vpsb/resources/node_json.rb +31 -0
- data/lib/vpsb/resources/packages_bags_json.rb +20 -0
- data/lib/vpsb/resources/packages_list.rb +18 -0
- data/lib/vpsb/resources/rails_app_path.rb +11 -0
- data/lib/vpsb/resources/read_do_api_access.rb +21 -0
- data/lib/vpsb/resources/ruby_version.rb +21 -0
- data/lib/vpsb/resources/server_app_path.rb +11 -0
- data/lib/vpsb/resources/ssh_helper.rb +10 -0
- data/lib/vpsb/resources/unicorn_worker_processes.rb +18 -0
- data/lib/vpsb/resources/unicorn_worker_timeout.rb +18 -0
- data/lib/vpsb/resources/web_role_json.rb +92 -0
- data/lib/vpsb/resources.rb +4 -0
- data/lib/vpsb/shell_support.rb +7 -0
- data/lib/vpsb/tasks/apps_bags.rb +33 -0
- data/lib/vpsb/tasks/create_droplet.rb +51 -0
- data/lib/vpsb/tasks/db_postgres_bags.rb +32 -0
- data/lib/vpsb/tasks/db_postgres_role.rb +32 -0
- data/lib/vpsb/tasks/deploy_bags.rb +32 -0
- data/lib/vpsb/tasks/deploy_config.rb +19 -0
- data/lib/vpsb/tasks/do_api_access.rb +52 -0
- data/lib/vpsb/tasks/droplet_ssh_keys.rb +22 -0
- data/lib/vpsb/tasks/droplet_ssh_update_config.rb +20 -0
- data/lib/vpsb/tasks/es_role.rb +32 -0
- data/lib/vpsb/tasks/monit_role.rb +32 -0
- data/lib/vpsb/tasks/node.rb +32 -0
- data/lib/vpsb/tasks/packages_bags.rb +32 -0
- data/lib/vpsb/tasks/web_role.rb +32 -0
- data/lib/vpsb/version.rb +3 -0
- data/lib/vpsb.rb +16 -0
- data/spec/spec_helper.rb +22 -0
- data/vpsb.gemspec +30 -0
- metadata +263 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class DoSize < BaseResource
|
4
|
+
include AskSupport
|
5
|
+
include ShellSupport
|
6
|
+
res :do_size
|
7
|
+
|
8
|
+
def call(core)
|
9
|
+
puts "Loading list of available disc sizes"
|
10
|
+
in_dir(core.get(:server_app_path), 'knife digital_ocean size list')
|
11
|
+
answer = ask { puts 'What size? Enter its id (default: 66)' }.strip
|
12
|
+
answer.empty? ? '66' : answer
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class EsJson < BaseResource
|
4
|
+
res :es_json
|
5
|
+
|
6
|
+
def call(data)
|
7
|
+
template(data)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def template(data)
|
13
|
+
{
|
14
|
+
name: "es",
|
15
|
+
description: "Elasticsearch Server Role",
|
16
|
+
chef_type: "role",
|
17
|
+
json_class: "Chef::Role",
|
18
|
+
default_attributes: {
|
19
|
+
java: {
|
20
|
+
|
21
|
+
install_flavor: "openjdk",
|
22
|
+
jdk_version: "7"
|
23
|
+
},
|
24
|
+
elasticsearch: {
|
25
|
+
version: data.get(:es_version),
|
26
|
+
cluster: { name: data.get(:es_cluster_name) },
|
27
|
+
limits: { nofile: data.get(:es_nofile).to_i, memlock: data.get(:es_memlock).to_i},
|
28
|
+
bootstrap: { mlockall: false},
|
29
|
+
discovery: { zen: { ping: { timeout: "3s" } } },
|
30
|
+
logging: { discovery: "TRACE", "index.indexing.slowlog" => "INFO, index_indexing_slow_log_file"},
|
31
|
+
"node.name" => data.get(:es_node_name),
|
32
|
+
"node.master" => true,
|
33
|
+
"node.data"=> true,
|
34
|
+
"http.port" => "9200",
|
35
|
+
"transport.tcp.port" => "9300",
|
36
|
+
"transport.tcp.compress" => "true",
|
37
|
+
"index.search.slowlog.threshold.query.trace" => "1ms"
|
38
|
+
}
|
39
|
+
},
|
40
|
+
run_list: [
|
41
|
+
"recipe[apt]",
|
42
|
+
"recipe[java]",
|
43
|
+
"recipe[vim]",
|
44
|
+
"recipe[elasticsearch]"
|
45
|
+
]
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class EsMemlock < BaseAskResource
|
4
|
+
res :es_memlock
|
5
|
+
question 'Elasticsearch memory limit (Default 256)?'
|
6
|
+
default '256'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def validate
|
11
|
+
Proc.new do |answer|
|
12
|
+
next true if answer.empty?
|
13
|
+
answer.to_i > 0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class EsNofile < BaseAskResource
|
4
|
+
res :es_nofile
|
5
|
+
question 'Elasticsearch open files limit (Default 1024)?'
|
6
|
+
default '1024'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def validate
|
11
|
+
Proc.new do |answer|
|
12
|
+
next true if answer.empty?
|
13
|
+
answer.to_i > 0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class EsVersion < BaseAskResource
|
4
|
+
res :es_version
|
5
|
+
question 'Elasticsearch version (Default 1.2.0)?'
|
6
|
+
default '1.2.0'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def validate
|
11
|
+
Proc.new do |answer|
|
12
|
+
next true if answer.strip.empty?
|
13
|
+
parts = answer.split('.')
|
14
|
+
next false if parts.length != 3
|
15
|
+
next false if (parts[0] + parts[1]).to_i <= 1
|
16
|
+
true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class HasDoAccount < BaseResource
|
4
|
+
include AskSupport
|
5
|
+
|
6
|
+
res :has_do_account
|
7
|
+
|
8
|
+
def call(core)
|
9
|
+
ask_to_confirm("Do you have account on DigitalOcean?") do |has_account|
|
10
|
+
unless has_account
|
11
|
+
ask { puts 'Create new account via link: https://www.digitalocean.com/?refcode=71281f14ac3c. Press Enter when ready to continue' }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class MonitRoleJson < BaseResource
|
4
|
+
res :monit_role_json
|
5
|
+
|
6
|
+
def call(data)
|
7
|
+
template(data)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def template(data)
|
13
|
+
{
|
14
|
+
name: "monit",
|
15
|
+
description: "Monit Server Role",
|
16
|
+
chef_type: "role",
|
17
|
+
json_class: "Chef::Role",
|
18
|
+
default_attributes: {
|
19
|
+
new_relic:{
|
20
|
+
license_key: data.get(:newrelic_lic),
|
21
|
+
hostname: data.get(:hostname),
|
22
|
+
keyserver:"keyserver.ubuntu.com"
|
23
|
+
}
|
24
|
+
},
|
25
|
+
run_list: [
|
26
|
+
"recipe[apt]",
|
27
|
+
"recipe[newrelic-sysmond]"
|
28
|
+
]
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class NodeJson < BaseResource
|
4
|
+
res :node_json
|
5
|
+
|
6
|
+
def call(data)
|
7
|
+
template(data)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def template(data)
|
13
|
+
{
|
14
|
+
chef_client:{
|
15
|
+
encrypted_data_bag_secret: "~/chef-solo/data_bag_key"
|
16
|
+
},
|
17
|
+
run_list: run_list(data)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def run_list(data)
|
22
|
+
list = %w{recipe[chef-solo-search] role[base]}
|
23
|
+
list << "role[es]" if data.present?(:es_json)
|
24
|
+
list << "role[db]" if data.present?(:db_postgres_json)
|
25
|
+
list << "role[web]"
|
26
|
+
list << "role[monit]" if data.present?(:monit_role_json)
|
27
|
+
list
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class PackagesBagsJson < BaseResource
|
4
|
+
res :packages_bags_json
|
5
|
+
|
6
|
+
def call(data)
|
7
|
+
template(data)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def template(data)
|
13
|
+
{
|
14
|
+
id: "packages",
|
15
|
+
apps: data.get(:packages_list)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class PackagesList < BaseAskResource
|
4
|
+
res :packages_list
|
5
|
+
question 'Package list to instalation from apt-get (example: mc, htop)?'
|
6
|
+
private
|
7
|
+
|
8
|
+
def finalize(answer)
|
9
|
+
return [] if answer.empty?
|
10
|
+
answer.split(',').join(' ').split(' ').compact.uniq
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate
|
14
|
+
Proc.new { true }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class ReadDoApiAccess < BaseResource
|
4
|
+
include AskSupport
|
5
|
+
|
6
|
+
res :read_do_api_access
|
7
|
+
|
8
|
+
def call(core)
|
9
|
+
if core.data[:do_client_id].nil? && core.data[:do_client_id].nil?
|
10
|
+
ask { puts 'Visit https://cloud.digitalocean.com/api_access and generate API access key' }
|
11
|
+
end
|
12
|
+
core.data[:do_client_id] = ask_loop { puts 'Paste your client id: ' }
|
13
|
+
core.data[:do_api_key] = ask_loop { puts 'Paste your api key: ' }
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class RubyVersion < BaseAskResource
|
4
|
+
res :ruby_version
|
5
|
+
question 'What version of ruby you want to install (Default 2.1.2)?'
|
6
|
+
default '2.1.2'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def validate
|
11
|
+
Proc.new do |answer|
|
12
|
+
next true if answer.strip.empty?
|
13
|
+
parts = answer.split('.')
|
14
|
+
next false if parts.length != 3
|
15
|
+
next false if (parts[0] + parts[1]).to_i < 18
|
16
|
+
true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class UnicornWorkerProcesses < BaseAskResource
|
4
|
+
res :unicorn_worker_processes
|
5
|
+
question 'How many unicorn worker processes setup (Default 4)?'
|
6
|
+
default '4'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def validate
|
11
|
+
Proc.new do |answer|
|
12
|
+
next true if answer.empty?
|
13
|
+
answer.to_i > 0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class UnicornWorkerTimeout < BaseAskResource
|
4
|
+
res :unicorn_worker_timeout
|
5
|
+
question 'What unicoren worker timeout setup (Default 30)?'
|
6
|
+
default '30'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def validate
|
11
|
+
Proc.new do |answer|
|
12
|
+
next true if answer.empty?
|
13
|
+
answer.to_i > 0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Vpsb
|
2
|
+
module Resources
|
3
|
+
class WebRoleJson < BaseResource
|
4
|
+
res :web_role_json
|
5
|
+
|
6
|
+
def call(data)
|
7
|
+
template(data)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def template(data)
|
13
|
+
{
|
14
|
+
name: "web",
|
15
|
+
description: "Web Server Role",
|
16
|
+
chef_type: "role",
|
17
|
+
json_class: "Chef::Role",
|
18
|
+
default_attributes: {
|
19
|
+
build_essential: {
|
20
|
+
compiletime: true
|
21
|
+
},
|
22
|
+
rvm:{
|
23
|
+
user_autolibs: "disabled",
|
24
|
+
rvm_gem_options: "--rdoc --ri",
|
25
|
+
default_ruby: data.get(:ruby_version),
|
26
|
+
rubies: [ data.get(:ruby_version) ],
|
27
|
+
user_installs:[
|
28
|
+
{
|
29
|
+
user: "deploy",
|
30
|
+
default_ruby: data.get(:ruby_version),
|
31
|
+
rubies: [ data.get(:ruby_version) ],
|
32
|
+
global_gems: [
|
33
|
+
{name: "bundler"},
|
34
|
+
{name: "rake"}
|
35
|
+
]
|
36
|
+
}
|
37
|
+
]
|
38
|
+
},
|
39
|
+
nginx:{
|
40
|
+
version: "1.4.1",
|
41
|
+
user: "www-data",
|
42
|
+
default_site_enabled: false,
|
43
|
+
source: {use_existing_user: true},
|
44
|
+
init_style: "init",
|
45
|
+
binary: "/opt/nginx/sbin",
|
46
|
+
modules: [
|
47
|
+
"http_stub_status_module",
|
48
|
+
"http_ssl_module",
|
49
|
+
"http_gzip_static_module"
|
50
|
+
],
|
51
|
+
gzip_types: [
|
52
|
+
"text/plain",
|
53
|
+
"text/html",
|
54
|
+
"text/css",
|
55
|
+
"text/xml",
|
56
|
+
"text/javascript",
|
57
|
+
"application/json",
|
58
|
+
"application/x-javascript",
|
59
|
+
"application/xml",
|
60
|
+
"application/xml+rss"
|
61
|
+
]
|
62
|
+
},
|
63
|
+
unicorn: {
|
64
|
+
options: { backlog: "64" },
|
65
|
+
preload_app: true,
|
66
|
+
worker_processes: data.get(:unicorn_worker_processes),
|
67
|
+
worker_timeout: data.get(:unicorn_worker_timeout)
|
68
|
+
}
|
69
|
+
},
|
70
|
+
run_list: [
|
71
|
+
"recipe[unattended-upgrades]",
|
72
|
+
"recipe[base]",
|
73
|
+
"recipe[nodejs]",
|
74
|
+
"recipe[nodejs::npm]",
|
75
|
+
"recipe[base::user_deploy]",
|
76
|
+
"recipe[apt]",
|
77
|
+
"recipe[build-essential]",
|
78
|
+
"recipe[rvm::user]",
|
79
|
+
"recipe[nginx]",
|
80
|
+
"recipe[nginx::source]",
|
81
|
+
"recipe[simple_iptables]",
|
82
|
+
"recipe[base::iptables]",
|
83
|
+
"recipe[runit]",
|
84
|
+
"recipe[unicorn]",
|
85
|
+
"recipe[base::webapps]",
|
86
|
+
"recipe[base::components]"
|
87
|
+
]
|
88
|
+
}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'json'
|
2
|
+
module Vpsb
|
3
|
+
module Tasks
|
4
|
+
class AppsBags < BaseTask
|
5
|
+
include AskSupport
|
6
|
+
PATH = 'bootstrap_server_app_in_do/data_bags/configs/webapps.json'
|
7
|
+
|
8
|
+
prepare_squence :app_name, :app_host, :unicorn_worker_processes, :unicorn_worker_timeout
|
9
|
+
prepare_squence :app_env_variables, :app_bags_json
|
10
|
+
|
11
|
+
def call
|
12
|
+
prepare
|
13
|
+
|
14
|
+
ask_loop(proc {|r| process(r)}) do
|
15
|
+
ap preparation_results
|
16
|
+
p "Save this configuration y[es]/n[o]?"
|
17
|
+
end
|
18
|
+
|
19
|
+
Vpsb::Helpers::FileReplace.replace_json(PATH, core.get(:app_bags_json))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def process(result)
|
25
|
+
return true if result[0].to_s.downcase == 'y'
|
26
|
+
reprepare
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|