vpsb 1.0.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 +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,23 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Commands
|
|
3
|
+
class Setup
|
|
4
|
+
include AskSupport
|
|
5
|
+
attr_reader :core
|
|
6
|
+
|
|
7
|
+
def initialize(core)
|
|
8
|
+
@core = core
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def execute(params)
|
|
12
|
+
unless File.exist?(core.get(:knife_rb_path))
|
|
13
|
+
return puts "You did not run init script, because i cannot find knife.rb file in bootstrap server app. ;)"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Vpsb::Tasks::DoApiAccess.new(core).call
|
|
17
|
+
Vpsb::Tasks::DropletSshKeys.new(core).call
|
|
18
|
+
Vpsb::Tasks::CreateDroplet.new(core).call
|
|
19
|
+
Vpsb::Tasks::DropletSshUpdateConfig.new(core).call
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/vpsb/core.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
class Core
|
|
3
|
+
class MissingResourceError < StandardError; end
|
|
4
|
+
def get(name, opts={})
|
|
5
|
+
name = name.to_sym
|
|
6
|
+
return data[name] = resources[name].call(self) if opts[:force]
|
|
7
|
+
data[name] ||= get_resource(name, opts).call(self)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def present?(name)
|
|
11
|
+
!blank?(name)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def blank?(name)
|
|
15
|
+
data[name].nil?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def resources
|
|
19
|
+
@resources ||= {}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def data
|
|
23
|
+
@data ||= {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def register_resources(*resource_list)
|
|
27
|
+
resource_list.each{ |r| register_resource(r) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def register_resource(resource)
|
|
31
|
+
resources[resource.name] = resource
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def get_resource(name, opts)
|
|
37
|
+
raise MissingResourceError.new("Resource '#{name}', not found") unless resources[name]
|
|
38
|
+
resources[name]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'etc'
|
|
3
|
+
|
|
4
|
+
module Vpsb
|
|
5
|
+
module Helpers
|
|
6
|
+
class FileReplace
|
|
7
|
+
def self.replace_json(path, hash)
|
|
8
|
+
replace_text(path, hash.to_json)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.replace_text(path, text)
|
|
12
|
+
file_path = File.join(Dir.pwd, path)
|
|
13
|
+
FileUtils.rm(file_path) if File.exist?(file_path)
|
|
14
|
+
File.open(file_path,"w") do |f|
|
|
15
|
+
f.write(text)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'etc'
|
|
3
|
+
|
|
4
|
+
module Vpsb
|
|
5
|
+
module Helpers
|
|
6
|
+
class Ssh
|
|
7
|
+
include AskSupport
|
|
8
|
+
|
|
9
|
+
def generate_ssh(path)
|
|
10
|
+
return if path == local_ssh_path && local_ssh_pub
|
|
11
|
+
puts 'Start generating new keys'
|
|
12
|
+
system("ssh-keygen -t rsa -f #{path}/id_rsa")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def ask_for_ssh_path
|
|
16
|
+
Dir.mkdir(local_ssh_path) unless Dir.exist?(local_ssh_path)
|
|
17
|
+
|
|
18
|
+
return local_ssh_path unless local_ssh_pub # no ssh keys yet
|
|
19
|
+
return local_ssh_path if ask_to_confirm('You have local ssh keys. Do you want to use it? If no, new keys will be generated')
|
|
20
|
+
|
|
21
|
+
begin
|
|
22
|
+
ssh_folder = Dir.home + '/.ssh/' + ask { puts "In what folder keep your keys?" }
|
|
23
|
+
can_continue = true
|
|
24
|
+
|
|
25
|
+
if Dir.exist?(ssh_folder)
|
|
26
|
+
if ask_to_confirm("Folder #{ssh_folder} already taken. Overwrite?")
|
|
27
|
+
FileUtils.rm_rf ssh_folder
|
|
28
|
+
else
|
|
29
|
+
can_continue = false
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end until can_continue
|
|
33
|
+
|
|
34
|
+
Dir.mkdir ssh_folder
|
|
35
|
+
ssh_folder
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def add_host_to_config(host, ssh_path, user)
|
|
39
|
+
make_ssh_config_copy
|
|
40
|
+
original_config = file(config_path)
|
|
41
|
+
|
|
42
|
+
unless start_place = original_config =~ /Host #{host} ##{user}/
|
|
43
|
+
File.open(config_path, 'a') { |f| f << host_config(host, ssh_path, user) }
|
|
44
|
+
return remove_config_copy
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
return unless ask_to_confirm("Host #{host} already defined in your ssh config file. Update?")
|
|
48
|
+
|
|
49
|
+
next_host_start_place = original_config[start_place + 1, original_config.size] =~ /Host /
|
|
50
|
+
new_config = [
|
|
51
|
+
original_config[0, start_place - 1], "\n\n",
|
|
52
|
+
host_config(host, ssh_path, user), "\n",
|
|
53
|
+
(next_host_start_place.nil? ? '' : original_config[next_host_start_place + start_place, original_config.size])
|
|
54
|
+
].join(' ')
|
|
55
|
+
|
|
56
|
+
begin
|
|
57
|
+
File.open(config_path, 'w+') { |f| f.write(new_config) }
|
|
58
|
+
rescue => e
|
|
59
|
+
puts "Error occured when updaing ssh config. Message: #{e.message}"; restore_config_copy; puts "Original configuration restored"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
remove_config_copy
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def local_ssh_path
|
|
66
|
+
"#{Dir.home}/.ssh"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def local_ssh_pub
|
|
70
|
+
pub_key(local_ssh_path)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def pub_key(path)
|
|
74
|
+
path = path[-1] == '/' ? "#{path}id_rsa.pub" : "#{path}/id_rsa.pub"
|
|
75
|
+
file(path)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def config_path
|
|
81
|
+
"#{local_ssh_path}/config"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def config_copy_path
|
|
85
|
+
config_path + '_copy'
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def file(path)
|
|
89
|
+
File.open(path, 'r') { |f| f.read } rescue nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def host_config(host, ssh_path, user)
|
|
93
|
+
<<-EOS
|
|
94
|
+
Host #{host} ##{user}
|
|
95
|
+
HostName #{host}
|
|
96
|
+
IdentityFile #{ssh_path}
|
|
97
|
+
# User #{user}
|
|
98
|
+
EOS
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def make_ssh_config_copy
|
|
102
|
+
system("touch #{config_path}") unless Dir.exist?(config_path)
|
|
103
|
+
FileUtils.cp config_path, config_copy_path
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def remove_config_copy
|
|
107
|
+
if File.exist?(config_copy_path)
|
|
108
|
+
FileUtils.rm config_copy_path
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def restore_config_copy
|
|
113
|
+
FileUtils.cp config_copy_path, config_path
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class AppBagsJson < BaseResource
|
|
4
|
+
res :app_bags_json
|
|
5
|
+
|
|
6
|
+
def call(data)
|
|
7
|
+
template(data)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def template(data)
|
|
13
|
+
{
|
|
14
|
+
id: "webapps",
|
|
15
|
+
apps_base_dir: "/opt/www",
|
|
16
|
+
apps: [
|
|
17
|
+
{
|
|
18
|
+
name: data.get(:app_name),
|
|
19
|
+
type: "rails",
|
|
20
|
+
default_env: "production",
|
|
21
|
+
host: data.get(:app_host),
|
|
22
|
+
try_files: "/caches/$uri.html",
|
|
23
|
+
nginx: {
|
|
24
|
+
default: true,
|
|
25
|
+
nginx_use_ssl: false
|
|
26
|
+
},
|
|
27
|
+
unicorn: {
|
|
28
|
+
unicorn_workers: data.get(:unicorn_worker_processes),
|
|
29
|
+
unicorn_timeout: data.get(:unicorn_worker_timeout)
|
|
30
|
+
},
|
|
31
|
+
app_env_variables: data.get(:app_env_variables)
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class AppEnvVariables < BaseAskResource
|
|
4
|
+
res :app_env_variables
|
|
5
|
+
question 'What are aplication env variables (default: RAILS_ENV=production)?'
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def finalize(answer)
|
|
9
|
+
return { 'RAILS_ENV' => 'production' } if answer.empty?
|
|
10
|
+
answer.split(';').inject({}) do |h, i|
|
|
11
|
+
res = i.to_s.split('=')
|
|
12
|
+
key = res.shift.to_s.strip
|
|
13
|
+
next if key.empty?
|
|
14
|
+
h[key] = res.join('=').to_s.strip
|
|
15
|
+
h
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def validate
|
|
20
|
+
Proc.new { true }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DbPostgresJson < BaseResource
|
|
4
|
+
res :db_postgres_json
|
|
5
|
+
|
|
6
|
+
def call(data)
|
|
7
|
+
template(data)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def template(data)
|
|
13
|
+
version = data.get(:db_postgres_version)
|
|
14
|
+
{
|
|
15
|
+
name: "db",
|
|
16
|
+
description: "Database Server Role",
|
|
17
|
+
chef_type: "role",
|
|
18
|
+
json_class: "Chef::Role",
|
|
19
|
+
default_attributes: {
|
|
20
|
+
postgresql: {
|
|
21
|
+
version: version,
|
|
22
|
+
enable_pgdg_apt: true,
|
|
23
|
+
dir: "/etc/postgresql/#{version}/main",
|
|
24
|
+
config:{
|
|
25
|
+
data_directory: "/var/lib/postgresql/#{version}/main",
|
|
26
|
+
hba_file: "/etc/postgresql/#{version}/main/pg_hba.conf",
|
|
27
|
+
ident_file: "/etc/postgresql/#{version}/main/pg_ident.conf",
|
|
28
|
+
external_pid_file: "/var/run/postgresql/#{version}-main.pid",
|
|
29
|
+
ssl_cert_file: "/etc/ssl/certs/ssl-cert-snakeoil.pem",
|
|
30
|
+
ssl_key_file:"/etc/ssl/private/ssl-cert-snakeoil.key"
|
|
31
|
+
},
|
|
32
|
+
client: {
|
|
33
|
+
packages: [ "postgresql-client-#{version}" ]
|
|
34
|
+
},
|
|
35
|
+
server:{
|
|
36
|
+
service_name: "postgresql",
|
|
37
|
+
packages: [ "postgresql-common", "postgresql-#{version}", "postgresql-server-dev-#{version}", "libpq-dev"]
|
|
38
|
+
},
|
|
39
|
+
contrib:{
|
|
40
|
+
packages:["postgresql-contrib-#{version}"]
|
|
41
|
+
},
|
|
42
|
+
password: {
|
|
43
|
+
postgres: "postgres"
|
|
44
|
+
},
|
|
45
|
+
pg_hba: [
|
|
46
|
+
{ type: "local", db: "all", user: "postgres", addr: "", method: "ident" },
|
|
47
|
+
{ type: "local", db: "all", user: "all", addr: "", method: "trust" },
|
|
48
|
+
{ type: "host", db: "all", user: "all", addr: "127.0.0.1/32", method: "trust" },
|
|
49
|
+
{ type: "host", db: "all", user: "all", addr: "::1/128", method: "trust" },
|
|
50
|
+
{ type: "host", db: "all", user: "postgres", addr: "127.0.0.1/32", method: "trust" }
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
run_list: [
|
|
55
|
+
"recipe[postgresql::server]",
|
|
56
|
+
"recipe[postgresql::client]"
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DbPostgresVersion < BaseAskResource
|
|
4
|
+
res :db_postgres_version
|
|
5
|
+
question 'Postgres version (Default 9.3)?'
|
|
6
|
+
default '9.3'
|
|
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 != 2
|
|
15
|
+
next false if (parts[0] + parts[1]).to_i <= 7
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DbPostgresqlBagsJson < BaseResource
|
|
4
|
+
res :db_postgresql_bags_json
|
|
5
|
+
|
|
6
|
+
def call(data)
|
|
7
|
+
template(data)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def template(data)
|
|
13
|
+
{
|
|
14
|
+
id: "postgresql",
|
|
15
|
+
postgresql: data.get(:db_postgres_pass)
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DeployBagsJson < BaseResource
|
|
4
|
+
res :deploy_bags_json
|
|
5
|
+
|
|
6
|
+
def call(data)
|
|
7
|
+
template(data)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def template(data)
|
|
13
|
+
{
|
|
14
|
+
id: "deploy",
|
|
15
|
+
username: "deploy",
|
|
16
|
+
ssh_keys: data.get(:deploy_ssh_keys),
|
|
17
|
+
password: data.get(:deploy_pass),
|
|
18
|
+
groups: %w{www-data deploy},
|
|
19
|
+
uid: 1001,
|
|
20
|
+
shell: "/bin/bash",
|
|
21
|
+
home: "/home/deploy",
|
|
22
|
+
comment: "deployment user",
|
|
23
|
+
manage_home: true,
|
|
24
|
+
keychain: { id_dsa: "", "id_dsa.pub" => ""},
|
|
25
|
+
to_known_hosts: [],
|
|
26
|
+
www_dir: "/opt/www",
|
|
27
|
+
env_variables_for_rvm: true,
|
|
28
|
+
global_env_variables:{
|
|
29
|
+
APPS_DIR:"/opt/www",
|
|
30
|
+
RAILS_ENV: "production"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DeployConfig < BaseResource
|
|
4
|
+
res :deploy_config
|
|
5
|
+
|
|
6
|
+
def call(data)
|
|
7
|
+
template(data)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def template(data)
|
|
13
|
+
user = '#{user}'
|
|
14
|
+
domain = '#{domain}'
|
|
15
|
+
<<-EOF
|
|
16
|
+
set :stage, :production
|
|
17
|
+
set :rails_env, :production
|
|
18
|
+
fetch(:default_env).merge!(rails_env: :production)
|
|
19
|
+
|
|
20
|
+
domain = '#{data.get(:do_host_ip)}'
|
|
21
|
+
user = 'deploy'
|
|
22
|
+
|
|
23
|
+
role :app, "#{user}@#{domain}"
|
|
24
|
+
role :web, "#{user}@#{domain}"
|
|
25
|
+
role :db, "#{user}@#{domain}", primary: true
|
|
26
|
+
|
|
27
|
+
server domain, user: user, roles: %w{db web app}
|
|
28
|
+
EOF
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DeployKeychain < BaseAskResource
|
|
4
|
+
res :deploy_keychain
|
|
5
|
+
# TODO ask for ssh_keys from .ssh
|
|
6
|
+
question 'Enter id_dsa and id_dsa.pub for deploy (example: -----BEGIN RSA, ssh-rsa AB...)'
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def finalize(answer)
|
|
10
|
+
|
|
11
|
+
arr = answer.split(',').join(' ').split(' ').compact.uniq
|
|
12
|
+
{
|
|
13
|
+
id_dsa: arr.shift,
|
|
14
|
+
"id_dsa.pub" => arr.shift
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DeploySshKeys < BaseAskResource
|
|
4
|
+
res :deploy_ssh_keys
|
|
5
|
+
# TODO ask for ssh_keys from .ssh
|
|
6
|
+
# question 'Enter ssh_keys(id_rsa.pub) for deploy (example: ssh-rsa AA... , ssh-rsa AB...)'
|
|
7
|
+
|
|
8
|
+
def call(core)
|
|
9
|
+
[core.get(:ssh_helper).pub_key(core.get(:do_ssh_path))]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
# def finalize(answer)
|
|
15
|
+
# answer.split(',').join(' ').split(' ').compact.uniq
|
|
16
|
+
# end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DeployToKnownHosts < BaseAskResource
|
|
4
|
+
res :deploy_to_known_hosts
|
|
5
|
+
question 'Enter known hosts (example: bitbucket.org, github.com)?'
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def finalize(answer)
|
|
9
|
+
answer.split(',').join(' ').split(' ').compact.uniq
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DoApiKey < BaseResource
|
|
4
|
+
include AskSupport
|
|
5
|
+
res :do_api_key
|
|
6
|
+
|
|
7
|
+
def call(core)
|
|
8
|
+
puts
|
|
9
|
+
ask { puts 'Visit https://cloud.digitalocean.com/api_access and generate API access key. Press Enter when ready to continue' }
|
|
10
|
+
ask_loop { puts 'What is your DigitalOcean api key?' }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DoDropletSshKey < BaseResource
|
|
4
|
+
include AskSupport
|
|
5
|
+
include ShellSupport
|
|
6
|
+
res :do_droplet_ssh_key
|
|
7
|
+
|
|
8
|
+
def call(core)
|
|
9
|
+
puts "Loading list of available ssh keys"
|
|
10
|
+
in_dir(core.get(:server_app_path), 'knife digital_ocean sshkey list')
|
|
11
|
+
ask_loop { puts 'Which ssh key? Enter its id' }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DoImage < BaseResource
|
|
4
|
+
include AskSupport
|
|
5
|
+
include ShellSupport
|
|
6
|
+
res :do_image
|
|
7
|
+
|
|
8
|
+
def call(core)
|
|
9
|
+
puts "Loading list of available operating systems"
|
|
10
|
+
in_dir(core.get(:server_app_path), "knife digital_ocean image list -G | grep -i 'Ubuntu'")
|
|
11
|
+
answer = ask { puts 'Which system? Enter its id (default: 3101918)' }.strip
|
|
12
|
+
answer.empty? ? '3101918' : answer
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Vpsb
|
|
2
|
+
module Resources
|
|
3
|
+
class DoRegion < BaseResource
|
|
4
|
+
include AskSupport
|
|
5
|
+
include ShellSupport
|
|
6
|
+
res :do_region
|
|
7
|
+
|
|
8
|
+
def call(core)
|
|
9
|
+
puts "Loading list of available regions"
|
|
10
|
+
in_dir(core.get(:server_app_path), "knife digital_ocean region list")
|
|
11
|
+
answer = ask { puts 'Which region? Enter its id (default: 5)' }.strip
|
|
12
|
+
answer.empty? ? '5' : answer
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|