screwcap 0.3 → 0.3.1
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.
- data/Manifest.txt +4 -0
- data/Rakefile +1 -1
- data/TODO +1 -0
- data/lib/screwcap/message_logger.rb +35 -0
- data/lib/screwcap/runner.rb +107 -0
- data/lib/screwcap.rb +1 -1
- data/screwcap.gemspec +1 -1
- data/test/config/real_world_recipe.rb +15 -0
- metadata +7 -2
data/Manifest.txt
CHANGED
@@ -5,11 +5,14 @@ History.txt
|
|
5
5
|
Manifest.txt
|
6
6
|
README.rdoc
|
7
7
|
Rakefile
|
8
|
+
TODO
|
8
9
|
bin/screwcap
|
9
10
|
lib/exts.rb
|
10
11
|
lib/screwcap.rb
|
11
12
|
lib/screwcap/base.rb
|
12
13
|
lib/screwcap/deployer.rb
|
14
|
+
lib/screwcap/message_logger.rb
|
15
|
+
lib/screwcap/runner.rb
|
13
16
|
lib/screwcap/sequence.rb
|
14
17
|
lib/screwcap/server.rb
|
15
18
|
lib/screwcap/task.rb
|
@@ -28,6 +31,7 @@ test/config/expect.rb
|
|
28
31
|
test/config/gateway.rb
|
29
32
|
test/config/no_server.rb
|
30
33
|
test/config/rails_tasks.rb
|
34
|
+
test/config/real_world_recipe.rb
|
31
35
|
test/config/simple_recipe.rb
|
32
36
|
test/config/undefined_command_set.rb
|
33
37
|
test/config/undefined_item.rb
|
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ Hoe.plugin :newgem
|
|
11
11
|
# Generate all the Rake tasks
|
12
12
|
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
13
13
|
$hoe = Hoe.spec 'screwcap' do
|
14
|
-
self.version = '0.3'
|
14
|
+
self.version = '0.3.1'
|
15
15
|
self.developer 'Grant Ammons', 'grant@pipelinedeals.com'
|
16
16
|
self.rubyforge_name = self.name # TODO this is default value
|
17
17
|
self.extra_deps = [['net-ssh','>= 2.0.23'],['net-ssh-gateway','>=1.0.1'], ['net-scp','>=1.0.4']]
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module MessageLogger
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
end
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def log(msg, options = {})
|
8
|
+
logmsg(msg, $stdout, options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def errorlog(msg, options = {})
|
12
|
+
logmsg(msg, $stderr, options)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def logmsg(msg, output, options)
|
18
|
+
return if @options and @options[:silent] == true
|
19
|
+
if @options and not @options[:nocolor] == true
|
20
|
+
case options[:color]
|
21
|
+
when :blue
|
22
|
+
output << "\033[0;36m#{msg}#{"\033[0m" if options[:clear]}"
|
23
|
+
when :bluebold
|
24
|
+
output << "\033[1;36m#{msg}#{"\033[0m" if options[:clear]}"
|
25
|
+
when :red
|
26
|
+
output << "\033[0;31m#{msg}#{"\033[0m" if options[:clear]}"
|
27
|
+
when :green
|
28
|
+
output << "\033[0;32m#{msg}#{"\033[0m" if options[:clear]}"
|
29
|
+
end
|
30
|
+
else
|
31
|
+
output << msg
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
class Runner
|
2
|
+
include MessageLogger
|
3
|
+
|
4
|
+
def self.execute! task, options
|
5
|
+
@task = task; @options = options
|
6
|
+
threads = []
|
7
|
+
@task.__servers.each do |_server|
|
8
|
+
_server.__addresses.each do |_address|
|
9
|
+
if task.__options[:parallel] == false
|
10
|
+
execute_on(_server, _address)
|
11
|
+
else
|
12
|
+
threads << Thread.new(_server, _address) { |server, address| execute_on(server, address) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
threads.each {|t| t.join }
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def self.execute_on(server, address)
|
22
|
+
begin
|
23
|
+
log "\n*** BEGIN executing task #{@task.__name} on #{server.name} with address #{address}\n", :color => :blue
|
24
|
+
|
25
|
+
server.__with_connection_for(address) do |ssh|
|
26
|
+
failed_command = nil
|
27
|
+
@task.__commands.each do |command|
|
28
|
+
if run_command(ssh, address, server, command) != 0 and command[:onfailure]
|
29
|
+
failed_command = command
|
30
|
+
break
|
31
|
+
end
|
32
|
+
end
|
33
|
+
if failed_command
|
34
|
+
@task.__commands = []
|
35
|
+
@task.send(failed_command[:onfailure])
|
36
|
+
@task.__commands.each { |command| run_command(ssh, address, server, command) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
rescue Net::SSH::AuthenticationFailed => e
|
40
|
+
raise Net::SSH::AuthenticationFailed, "Authentication failed for server named #{server.name}. Please check your authentication credentials."
|
41
|
+
#rescue Exception => e
|
42
|
+
# errorlog " F: (#{address}): #{e}", :color => :red
|
43
|
+
#ensure
|
44
|
+
# log "*** END executing task #{@task.__name} on #{server.name} with address #{address}\n\n", :color => :blue
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# courtesy of flitzwald on stackoverflow
|
49
|
+
# http://stackoverflow.com/questions/3386233/how-to-get-exit-status-with-rubys-netssh-library
|
50
|
+
def self.ssh_exec!(ssh, command)
|
51
|
+
stdout_data = ""
|
52
|
+
stderr_data = ""
|
53
|
+
exit_code = nil
|
54
|
+
exit_signal = nil
|
55
|
+
ssh.open_channel do |channel|
|
56
|
+
channel.exec(command) do |ch, success|
|
57
|
+
channel.on_data do |ch,data|
|
58
|
+
stdout_data+=data
|
59
|
+
end
|
60
|
+
|
61
|
+
channel.on_extended_data do |ch,type,data|
|
62
|
+
stderr_data+=data
|
63
|
+
end
|
64
|
+
|
65
|
+
channel.on_request("exit-status") do |ch,data|
|
66
|
+
exit_code = data.read_long
|
67
|
+
end
|
68
|
+
|
69
|
+
channel.on_request("exit-signal") do |ch, data|
|
70
|
+
exit_signal = data.read_long
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
ssh.loop
|
75
|
+
[stdout_data, stderr_data, exit_code, exit_signal]
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def self.run_command(ssh, address, server, command)
|
80
|
+
if command[:type] == :remote
|
81
|
+
log " I: (#{address}): #{command[:command]}\n", :color => :green
|
82
|
+
stdout, stderr, exit_code, exit_signal = ssh_exec! ssh, command[:command]
|
83
|
+
log(" O: (#{address}): #{stdout}", :color => :green) unless stdout.blank?
|
84
|
+
errorlog(" O: (#{address}): #{stderr}", :color => :red) unless stderr.blank?
|
85
|
+
errorlog(" E: (#{address}): #{command[:command]} return exit code: #{exit_code}\n", :color => :red) if exit_code != 0
|
86
|
+
return exit_code
|
87
|
+
elsif command[:type] == :local
|
88
|
+
ret = `#{command[:command]}`
|
89
|
+
if $?.to_i == 0
|
90
|
+
log " I: (local): #{command[:command]}\n", :color => :blue
|
91
|
+
log " O: (local): #{ret}\n", :color => :blue
|
92
|
+
else
|
93
|
+
log " I: (local): #{command[:command]}\n", :color => :blue
|
94
|
+
errorlog " O: (local): #{ret}\n", :color => :red
|
95
|
+
errorlog(" E: (local): #{command[:command]} return exit code: #{$?}\n", :color => :red) if $? != 0
|
96
|
+
end
|
97
|
+
return $?
|
98
|
+
elsif command[:type] == :scp
|
99
|
+
log " I: (#{address}): SCP #{command[:local]} to #{server.__user}@#{address}:#{command[:remote]}\n", :color => :green
|
100
|
+
server.__upload_to!(address, command[:local], command[:remote])
|
101
|
+
|
102
|
+
# this will need to be improved to allow for :onfailure
|
103
|
+
return 0
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
data/lib/screwcap.rb
CHANGED
data/screwcap.gemspec
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
addresses = []
|
2
|
+
addresses << "ec2-174-129-166-79.compute-1.amazonaws.com"
|
3
|
+
#addresses << "ec2-174-129-60-243.compute-1.amazonaws.com"
|
4
|
+
#addresses << "ec2-204-236-255-140.compute-1.amazonaws.com"
|
5
|
+
#gateway :dev_gateway, :address => "dev.pipelinedealsco.com", :user => "root", :keys => "~/.ssh/dev_key"
|
6
|
+
server :staging, :addresses => addresses, :user => "root", :keys => "~/.ssh/pipeline_key"
|
7
|
+
|
8
|
+
command_set :dofail do
|
9
|
+
run "echo 'failing yeah'"
|
10
|
+
end
|
11
|
+
|
12
|
+
task_for :task, :server => :staging, :parallel => false do
|
13
|
+
run "ruby -e 'Kernel.exit(0)'", :onfailure => :dofail
|
14
|
+
run "echo 'happy days'"
|
15
|
+
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: screwcap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Grant Ammons
|
@@ -118,11 +119,14 @@ files:
|
|
118
119
|
- Manifest.txt
|
119
120
|
- README.rdoc
|
120
121
|
- Rakefile
|
122
|
+
- TODO
|
121
123
|
- bin/screwcap
|
122
124
|
- lib/exts.rb
|
123
125
|
- lib/screwcap.rb
|
124
126
|
- lib/screwcap/base.rb
|
125
127
|
- lib/screwcap/deployer.rb
|
128
|
+
- lib/screwcap/message_logger.rb
|
129
|
+
- lib/screwcap/runner.rb
|
126
130
|
- lib/screwcap/sequence.rb
|
127
131
|
- lib/screwcap/server.rb
|
128
132
|
- lib/screwcap/task.rb
|
@@ -141,6 +145,7 @@ files:
|
|
141
145
|
- test/config/gateway.rb
|
142
146
|
- test/config/no_server.rb
|
143
147
|
- test/config/rails_tasks.rb
|
148
|
+
- test/config/real_world_recipe.rb
|
144
149
|
- test/config/simple_recipe.rb
|
145
150
|
- test/config/undefined_command_set.rb
|
146
151
|
- test/config/undefined_item.rb
|