danarchy_deploy 0.1.4 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/Gemfile.lock +9 -20
- data/README.md +10 -9
- data/Rakefile +0 -4
- data/bin/danarchy_deploy +24 -10
- data/danarchy_deploy.gemspec +4 -3
- data/lib/danarchy_deploy.rb +186 -55
- data/lib/danarchy_deploy/applicator.rb +39 -0
- data/lib/danarchy_deploy/applicator/nginx.rb +86 -0
- data/lib/danarchy_deploy/applicator/phpfpm.rb +84 -0
- data/lib/danarchy_deploy/applicator/redmine.rb +40 -0
- data/lib/danarchy_deploy/applicator/ssl.rb +14 -0
- data/lib/danarchy_deploy/applicator/wordpress.rb +146 -0
- data/lib/danarchy_deploy/applicator/wordpress/wpcli.rb +67 -0
- data/lib/danarchy_deploy/applicator/wordpress/wpcli_install.sh +36 -0
- data/lib/danarchy_deploy/applicator/wordpress/wpconfig.rb +49 -0
- data/lib/danarchy_deploy/archiver.rb +9 -7
- data/lib/danarchy_deploy/archiver/svn.rb +17 -0
- data/lib/danarchy_deploy/hash_deep_merge.rb +9 -0
- data/lib/danarchy_deploy/helpers.rb +42 -10
- data/lib/danarchy_deploy/services.rb +12 -25
- data/lib/danarchy_deploy/services/init.rb +52 -0
- data/lib/danarchy_deploy/services/init/openrc.rb +72 -0
- data/lib/danarchy_deploy/services/init/systemd.rb +69 -0
- data/lib/danarchy_deploy/services/mongodb.rb +162 -0
- data/lib/danarchy_deploy/services/mysql.rb +58 -0
- data/lib/danarchy_deploy/services/mysql/new_server.rb +72 -0
- data/lib/danarchy_deploy/services/mysql/privileges.rb +35 -0
- data/lib/danarchy_deploy/system.rb +86 -0
- data/lib/danarchy_deploy/system/centos.rb +17 -0
- data/lib/danarchy_deploy/system/debian.rb +61 -0
- data/lib/danarchy_deploy/system/gentoo.rb +66 -0
- data/lib/danarchy_deploy/system/opensuse.rb +22 -0
- data/lib/danarchy_deploy/templater.rb +53 -13
- data/lib/danarchy_deploy/users.rb +28 -18
- data/lib/danarchy_deploy/version.rb +1 -1
- data/templates/deploy_template.json +3 -3
- metadata +34 -12
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
datetime=$(date +%F\ %T)
|
4
|
+
log='/danarchy/deploy/wpcli_install.log'
|
5
|
+
working_dir='/var/tmp'
|
6
|
+
|
7
|
+
echo "WP-CLI Install: ${datetime}" > ${log}
|
8
|
+
echo "Grabbing most recent wp-cli..." 2>&1 >> ${log}
|
9
|
+
curl -sk https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -o ${working_dir}/wp-cli.phar 2>&1 >> ${log}
|
10
|
+
|
11
|
+
success=''
|
12
|
+
if [[ -f "${working_dir}/wp-cli.phar" ]]; then
|
13
|
+
echo "WP-CLI downloaded."
|
14
|
+
chmod +x ${working_dir}/wp-cli.phar
|
15
|
+
|
16
|
+
if [[ -x '/usr/bin/php' ]]; then
|
17
|
+
/usr/bin/php ${working_dir}/wp-cli.phar --info --allow-root && success='true'
|
18
|
+
mv -v ${working_dir}/wp-cli.phar /usr/local/bin/wp
|
19
|
+
else
|
20
|
+
echo 'PHP is not installed!'
|
21
|
+
rm -v ${working_dir}/wp-cli.phar
|
22
|
+
success='false'
|
23
|
+
fi
|
24
|
+
else
|
25
|
+
echo "WP-CLI failed to download."
|
26
|
+
success='false'
|
27
|
+
fi 2>&1 >> ${log}
|
28
|
+
|
29
|
+
if [[ "${success}" = 'false' ]];then
|
30
|
+
echo -e "\nFailed to install WP-CLI!" 2>&1 >> ${log}
|
31
|
+
cat ${log} >&2
|
32
|
+
exit 1
|
33
|
+
else
|
34
|
+
echo -e "WP-CLI successfully installed!" 2>&1 >> ${log}
|
35
|
+
cat ${log}
|
36
|
+
fi
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module DanarchyDeploy
|
2
|
+
module Applicator
|
3
|
+
module WordPress
|
4
|
+
class WPConfig
|
5
|
+
def self.new(app, options)
|
6
|
+
puts "\n > Checking WordPress Configuration"
|
7
|
+
app = verify_generate_wp_salts(app, options)
|
8
|
+
wp_config(app, options)
|
9
|
+
app
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def self.wp_config(app, options)
|
15
|
+
target = app[:path] + '/wp-config.php'
|
16
|
+
source = options[:deploy_dir] + '/templates/applications/wordpress/wp-config.php.erb'
|
17
|
+
|
18
|
+
templates = [{ target: app[:path] + '/wp-config.php',
|
19
|
+
source: options[:deploy_dir] + '/templates/applications/wordpress/wp-config.php.erb',
|
20
|
+
variables: { db_host: app[:database][:db_host],
|
21
|
+
db_name: app[:database][:db_name],
|
22
|
+
db_user: app[:database][:db_user],
|
23
|
+
db_pass: app[:database][:db_pass],
|
24
|
+
table_prefix: app[:database][:table_prefix],
|
25
|
+
wp_keys_salts: app[:database][:salts],
|
26
|
+
file_perms: { owner: app[:username],
|
27
|
+
group: app[:username],
|
28
|
+
mode: '0644' } }
|
29
|
+
}]
|
30
|
+
|
31
|
+
DanarchyDeploy::Templater.new(templates, options)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.verify_generate_wp_salts(app, options)
|
35
|
+
puts "\n > Verifying WP authentication salts for #{app[:domain]}"
|
36
|
+
if app[:database][:salts]
|
37
|
+
puts ' |- Salts already exist! Using those.'
|
38
|
+
else
|
39
|
+
puts ' |+ Generating Auth Salts...'
|
40
|
+
uri = URI('https://api.wordpress.org/secret-key/1.1/salt/')
|
41
|
+
app[:database][:salts] = Net::HTTP.get(uri)
|
42
|
+
end
|
43
|
+
|
44
|
+
app
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative 'archiver/svn'
|
1
2
|
|
2
3
|
module DanarchyDeploy
|
3
4
|
class Archiver
|
@@ -8,18 +9,14 @@ module DanarchyDeploy
|
|
8
9
|
abort("No target destination set for archive: #{archive[:source]}!") if !archive[:target]
|
9
10
|
|
10
11
|
tmparchive = false
|
11
|
-
if !archive[:source]
|
12
|
+
if !archive[:source] && archive[:data]
|
12
13
|
archive[:source] = options[:deploy_dir] + "/.tmp_archive_#{DateTime.now.strftime("%Y%m%d_%H%M%S")}"
|
13
14
|
tmparchive = true
|
14
|
-
end
|
15
|
-
|
16
|
-
if archive[:data]
|
17
15
|
data = DanarchyDeploy::Helpers.decode_base64(archive[:data])
|
18
16
|
write_tmp_archive(archive[:source], data)
|
19
17
|
end
|
20
|
-
|
21
|
-
puts " > Extracting #{archive[:source]} to #{archive[:target]}"
|
22
18
|
|
19
|
+
puts " > Extracting #{archive[:source]} to #{archive[:target]}"
|
23
20
|
if !File.exist?(archive[:source])
|
24
21
|
puts " ! Source file not found!: #{archive[:source]}"
|
25
22
|
return false
|
@@ -32,10 +29,11 @@ module DanarchyDeploy
|
|
32
29
|
if archive_result[:stderr]
|
33
30
|
puts ' ! Archive extraction failed!'
|
34
31
|
abort("STDERR:\n#{archive_result[:stderr]}")
|
35
|
-
|
32
|
+
elsif archive_result[:stdout]
|
36
33
|
puts " |+ Archive extracted: #{archive[:source]}\n"
|
37
34
|
end
|
38
35
|
|
36
|
+
set_target_ownership(archive[:target], archive[:perms]) if archive[:perms]
|
39
37
|
cleanup_source_archive(archive[:source]) if tmparchive
|
40
38
|
end
|
41
39
|
end
|
@@ -63,6 +61,10 @@ module DanarchyDeploy
|
|
63
61
|
File.write(source, data)
|
64
62
|
end
|
65
63
|
|
64
|
+
def self.set_target_ownership(target, perms)
|
65
|
+
FileUtils.chown_R(perms[:uid], perms[:gid], target)
|
66
|
+
end
|
67
|
+
|
66
68
|
def self.cleanup_source_archive(source)
|
67
69
|
File.delete(source)
|
68
70
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
module DanarchyDeploy
|
3
|
+
class Archiver
|
4
|
+
class Svn
|
5
|
+
def initialize(options)
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def co(repo, path)
|
10
|
+
puts "Checking out '#{repo}' to '#{path}'"
|
11
|
+
cmd = 'svn --non-interactive --trust-server-cert ' +
|
12
|
+
"co #{repo} #{path}"
|
13
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class ::Hash
|
2
|
+
def deep_merge(second)
|
3
|
+
merger = proc do |key, v1, v2|
|
4
|
+
Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2
|
5
|
+
end
|
6
|
+
|
7
|
+
self.merge(second.to_h, &merger)
|
8
|
+
end
|
9
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'base64'
|
1
2
|
require 'open3'
|
2
3
|
|
3
4
|
module DanarchyDeploy
|
@@ -5,24 +6,55 @@ module DanarchyDeploy
|
|
5
6
|
def self.run_command(command, options)
|
6
7
|
pid, stdout, stderr = nil
|
7
8
|
printf("%14s %0s\n", 'Running:', "#{command}")
|
8
|
-
Open3.popen3(command) do |i, o, e, t|
|
9
|
-
pid = t.pid
|
10
|
-
(out, err) = o.read, e.read
|
11
|
-
stdout = !out.empty? ? out : nil
|
12
|
-
stderr = !err.empty? ? err : nil
|
13
|
-
end
|
14
9
|
|
15
|
-
if options[:
|
16
|
-
|
17
|
-
|
10
|
+
if options[:pretend] && !options[:dev_gem]
|
11
|
+
pretend_run(command)
|
12
|
+
else
|
13
|
+
Open3.popen3(command) do |i, o, e, t|
|
14
|
+
pid = t.pid
|
15
|
+
(out, err) = o.read, e.read
|
16
|
+
stdout = !out.empty? ? out : nil
|
17
|
+
stderr = !err.empty? ? err : nil
|
18
|
+
end
|
19
|
+
|
20
|
+
puts "------\nErrored at: #{caller_locations.first.label} Line: #{caller_locations.first.lineno}\nSTDERR: ", stderr, '------' if stderr
|
21
|
+
puts "------\nSTDOUT: ", stdout, '------' if stdout && options[:ssh_verbose]
|
18
22
|
end
|
19
23
|
|
20
24
|
{ pid: pid, stdout: stdout, stderr: stderr }
|
21
25
|
end
|
22
26
|
|
23
27
|
def self.decode_base64(data)
|
24
|
-
require 'base64'
|
25
28
|
Base64.decode64(data)
|
26
29
|
end
|
30
|
+
|
31
|
+
def self.encode_base64(data)
|
32
|
+
Base64.encode64(data)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def self.pretend_run(command)
|
37
|
+
puts "\tFake run: #{command}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.hash_except(hash, regex)
|
41
|
+
hash.dup.delete_if { |k,v| k.to_s =~ /#{regex}/ }
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.hash_symbols_to_strings(hash)
|
45
|
+
new_hash = Hash.new
|
46
|
+
hash.each do |key, val|
|
47
|
+
if val.class == Hash
|
48
|
+
new_hash[key.to_s] = Hash.new
|
49
|
+
val.each do |k, v|
|
50
|
+
new_hash[key.to_s][k.to_s] = v
|
51
|
+
end
|
52
|
+
else
|
53
|
+
new_hash[key.to_s] = val
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
new_hash
|
58
|
+
end
|
27
59
|
end
|
28
60
|
end
|
@@ -1,11 +1,16 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require_relative 'services/init'
|
3
|
+
require_relative 'services/mongodb'
|
4
|
+
require_relative 'services/mysql'
|
1
5
|
|
2
6
|
module DanarchyDeploy
|
3
|
-
|
7
|
+
module Services
|
4
8
|
def self.new(deployment, options)
|
5
9
|
puts "\n" + self.name
|
6
10
|
|
7
11
|
deployment[:services].each do |service, params|
|
8
|
-
|
12
|
+
next if service == :init
|
13
|
+
puts "\nConfiguring service: #{service}"
|
9
14
|
|
10
15
|
if params[:archives] && !params[:archives].empty?
|
11
16
|
puts "\n" + self.name
|
@@ -14,34 +19,16 @@ module DanarchyDeploy
|
|
14
19
|
end
|
15
20
|
|
16
21
|
if params[:templates] && !params[:templates].empty?
|
17
|
-
puts " >
|
22
|
+
puts " > Configuring templates for #{service}"
|
18
23
|
DanarchyDeploy::Templater.new(params[:templates], options)
|
19
24
|
end
|
20
|
-
end
|
21
|
-
|
22
|
-
deployment
|
23
|
-
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
puts "\n" + self.name
|
28
|
-
|
29
|
-
deployment[:services].each do |service, params|
|
30
|
-
next if !params[:init]
|
31
|
-
if options[:first_run] == false
|
32
|
-
puts " ! Not a first-time run! Setting actions to 'reload'.\n\tUse --first-run to run actions: #{params[:init].join(' ,')}\n"
|
33
|
-
params[:init] = ['reload']
|
26
|
+
if %w[mysql mariadb].include?(service.to_s)
|
27
|
+
DanarchyDeploy::Services::MySQL.new(deployment[:os], params, options)
|
34
28
|
end
|
35
29
|
|
36
|
-
|
37
|
-
|
38
|
-
command = "systemctl #{action} #{service}"
|
39
|
-
|
40
|
-
if options[:pretend]
|
41
|
-
puts " Fake run: #{command}\n"
|
42
|
-
else
|
43
|
-
DanarchyDeploy::Helpers.run_command(command, options)
|
44
|
-
end
|
30
|
+
if %[mongodb].include?(service.to_s)
|
31
|
+
DanarchyDeploy::Services::MongoDB.new(deployment[:os], params, options)
|
45
32
|
end
|
46
33
|
end
|
47
34
|
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative 'init/openrc'
|
2
|
+
require_relative 'init/systemd'
|
3
|
+
|
4
|
+
module DanarchyDeploy
|
5
|
+
module Services
|
6
|
+
class Init
|
7
|
+
def self.new(deployment, options)
|
8
|
+
puts "\n" + self.name
|
9
|
+
|
10
|
+
deployment[:services].each do |service, params|
|
11
|
+
next if ! params[:init]
|
12
|
+
orig_actions = params[:init]
|
13
|
+
puts "\n > Init actions for #{service}: #{params[:init].join(', ')}"
|
14
|
+
params[:init].each do |action|
|
15
|
+
puts " |+ Taking action: #{action} on #{service}"
|
16
|
+
if options[:pretend]
|
17
|
+
puts " Fake run: #{action} #{service}"
|
18
|
+
else
|
19
|
+
init_manager(deployment[:os], service, action, options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
params[:init] = orig_actions
|
24
|
+
end
|
25
|
+
|
26
|
+
deployment
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.init_manager(os, service, action, options)
|
30
|
+
init = if os == 'gentoo'
|
31
|
+
DanarchyDeploy::Services::Init::Openrc.new(service, options)
|
32
|
+
else
|
33
|
+
DanarchyDeploy::Services::Init::Systemd.new(service, options)
|
34
|
+
end
|
35
|
+
|
36
|
+
init_result = init.send(action)
|
37
|
+
|
38
|
+
if init_result[:stderr]
|
39
|
+
if init_result[:stderr].include?('unknown function')
|
40
|
+
puts " ! Action: #{action} not available for service: #{service}.\n" +
|
41
|
+
" ! A restart may be needed! Otherwise, remove this action from the deployment.\n" +
|
42
|
+
" ! Not taking any action here.\n"
|
43
|
+
else
|
44
|
+
abort(" ! Action: #{service} #{action} failed!")
|
45
|
+
end
|
46
|
+
else
|
47
|
+
puts " |+ Action: #{service} #{action} succeeded."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
|
2
|
+
module DanarchyDeploy
|
3
|
+
module Services
|
4
|
+
class Init
|
5
|
+
class Openrc
|
6
|
+
def initialize(service, options)
|
7
|
+
@service = service
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def status
|
12
|
+
cmd = "rc-service #{@service} status"
|
13
|
+
return { stdout: "Fake run: started", stderr: nil } if @options[:pretend]
|
14
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
cmd = "rc-service #{@service} start"
|
19
|
+
status = self.status
|
20
|
+
|
21
|
+
if status[:stdout].include?('started')
|
22
|
+
return status
|
23
|
+
else
|
24
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def stop
|
29
|
+
cmd = "rc-service #{@service} stop"
|
30
|
+
status = self.status
|
31
|
+
|
32
|
+
if status[:stdout].include?('stopped')
|
33
|
+
return status
|
34
|
+
else
|
35
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def reload
|
40
|
+
status = self.status
|
41
|
+
|
42
|
+
cmd = if status[:stderr]
|
43
|
+
# status[:stdout].include?('running')
|
44
|
+
# This used to check for status "running"; and previously "started".
|
45
|
+
# Too specific so I've disabled it since I don't remember what this exception was for, originally.
|
46
|
+
puts " |! Service: #{@service} is not running. Starting it up instead."
|
47
|
+
"rc-service #{@service} start"
|
48
|
+
else
|
49
|
+
"rc-service #{@service} reload"
|
50
|
+
end
|
51
|
+
|
52
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
53
|
+
end
|
54
|
+
|
55
|
+
def restart
|
56
|
+
cmd = "rc-service #{@service} restart"
|
57
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
58
|
+
end
|
59
|
+
|
60
|
+
def enable
|
61
|
+
cmd = "rc-update add #{@service} default"
|
62
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
63
|
+
end
|
64
|
+
|
65
|
+
def disable
|
66
|
+
cmd = "rc-update del #{@service} default"
|
67
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
module DanarchyDeploy
|
3
|
+
module Services
|
4
|
+
class Init
|
5
|
+
class Systemd
|
6
|
+
def initialize(service, options)
|
7
|
+
@service = service
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def status
|
12
|
+
cmd = "systemctl show #{@service} --no-page"
|
13
|
+
# return { stdout: "Fake run: started", stderr: nil } if @options[:pretend]
|
14
|
+
status = DanarchyDeploy::Helpers.run_command(cmd, @options)
|
15
|
+
status[:stdout].split(/\n/).grep(/ActiveState/).first.split('=').last
|
16
|
+
end
|
17
|
+
|
18
|
+
def start
|
19
|
+
cmd = "systemctl start #{@service}"
|
20
|
+
status = self.status
|
21
|
+
|
22
|
+
if status == 'active'
|
23
|
+
return status
|
24
|
+
else
|
25
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def stop
|
30
|
+
cmd = "systemctl #{@service} stop"
|
31
|
+
status = self.status
|
32
|
+
|
33
|
+
if status == 'inactive'
|
34
|
+
return status
|
35
|
+
else
|
36
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def reload
|
41
|
+
status = self.status
|
42
|
+
|
43
|
+
cmd = if status == 'inactive'
|
44
|
+
"systemctl start #{@service}"
|
45
|
+
else
|
46
|
+
"systemctl reload #{@service}"
|
47
|
+
end
|
48
|
+
|
49
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def restart
|
53
|
+
cmd = "systemctl restart #{@service}"
|
54
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
55
|
+
end
|
56
|
+
|
57
|
+
def enable
|
58
|
+
cmd = "systemctl enable #{@service}"
|
59
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
60
|
+
end
|
61
|
+
|
62
|
+
def disable
|
63
|
+
cmd = "systemctl enable #{@service}"
|
64
|
+
DanarchyDeploy::Helpers.run_command(cmd, @options)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|