screwcap 0.7.4 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
data/.gemtest ADDED
File without changes
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.7.4'
14
+ self.version = '0.8'
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']]
data/lib/screwcap.rb CHANGED
@@ -16,7 +16,7 @@ require 'screwcap/sequence'
16
16
  require 'screwcap/task_manager'
17
17
 
18
18
  module Screwcap
19
- VERSION='0.7.4'
19
+ VERSION='0.8'
20
20
 
21
21
  class TaskNotFound < RuntimeError; end
22
22
  class NoServersDefined < Exception; end
@@ -6,18 +6,15 @@ class Runner
6
6
  @@silent = options[:silent]
7
7
  @@verbose = options[:verbose]
8
8
  task = options[:task]
9
+ results = []
9
10
 
10
11
  if (task.__servers.nil? or task.__servers == [] or task.__servers.compact == []) and task.__built_commands.any? {|c| c[:type] == :remote or c[:type] == :scp }
11
12
  raise Screwcap::ConfigurationError, "The task #{task.name} includes remote commands, however no servers were defined for this task."
12
13
  end
13
14
 
14
15
  if options[:servers] and task.__servers
15
- begin
16
- servers = options[:servers].select {|s| task.__servers.include? s.__name }
17
- connections = servers.map {|server| server.connect! }.flatten
18
- rescue Net::SSH::AuthenticationFailed => e
19
- raise Net::SSH::AuthenticationFailed, "Authentication failed for server named #{server.name}. Please check your authentication credentials."
20
- end
16
+ servers = options[:servers].select {|s| task.__servers.include? s.__name }
17
+ connections = servers.map {|server| server.connect! }.flatten
21
18
  end
22
19
 
23
20
  _log "\nExecuting task #{task.name}\n", :color => :blue
@@ -25,20 +22,33 @@ class Runner
25
22
  task.__built_commands.each do |command|
26
23
  ret = case command[:type]
27
24
  when :remote
28
- threads = []
29
- if command[:parallel] == false
30
- connections.each { |connection| run_remote_command(command, connection, options) }
25
+ if command[:parallel] == false or command[:block]
26
+ connections.each do |connection|
27
+ results << run_remote_command(command, connection[:connection], options)
28
+ if command[:block]
29
+ opts = task.__options.clone.merge(:stderr => command[:stderr], :stdout => command[:stdout], :exit_code => command[:exit_code])
30
+ opts[:servers] = task.__servers
31
+ opts[:name] = "Run results"
32
+
33
+ inner_task = Task.new(opts, &command[:block])
34
+ inner_task.__build_commands(options[:tasks])
35
+ results << self.execute!(options.merge(:task => inner_task))
36
+ end
37
+ end
31
38
  else
39
+ threads = []
32
40
  connections.each do |connection|
33
41
  threads << Thread.new(connection) do |conn|
34
- run_remote_command(command, conn, options)
42
+ results << run_remote_command(command, conn[:connection], options)
35
43
  end
36
44
  end
37
45
  threads.each {|t| t.join }
38
46
  end
39
47
  when :local
40
- ret = `#{command[:command]}`
41
- command[:stdout] = ret
48
+ result = {}
49
+ result[:stdout] = `#{command[:command]}`
50
+ result[:exit_code] = $?.to_i
51
+ results << result
42
52
  if $?.to_i == 0
43
53
  if options[:verbose]
44
54
  _log " O: #{ret}\n", :color => :green
@@ -48,7 +58,6 @@ class Runner
48
58
  else
49
59
  _errorlog(" E: (local): #{command[:command]} return exit code: #{$?}\n", :color => :red) if $? != 0
50
60
  end
51
- ret
52
61
  when :scp
53
62
  threads = []
54
63
  servers.each do |server|
@@ -59,29 +68,30 @@ class Runner
59
68
  command[:block].call
60
69
  end
61
70
  end
62
- _log "\nComplete\n", :color => :blue
63
- task.__built_commands # for tests
71
+ _log "Complete\n", :color => :blue
72
+ results
64
73
  end
65
74
 
66
75
  private
67
76
 
68
77
  def self.run_remote_command(command, ssh, options)
69
78
  stdout, stderr, exit_code, exit_signal = ssh_exec! ssh, command[:command]
70
- command[:stdout] = stdout
71
- command[:stderr] = stderr
72
- command[:exit_code] = exit_code
79
+ ret = {:command => command[:command]}
80
+ ret[:stdout] = command[:stdout] = stdout
81
+ ret[:stderr] = command[:stderr] = stderr
82
+ ret[:exit_code] = command[:exit_code] = exit_code
73
83
  if exit_code == 0
74
84
  if @@verbose
75
85
  _log(" I: #{command[:command]}\n", :color => :green)
76
86
  _log(" O: #{command[:stdout]}\n", :color => :green)
77
87
  else
78
88
  _log(".", :color => :green)
79
- $stdout.flush
80
89
  end
81
90
  else
82
- _errorlog(" E: (#{options[:address]}): #{command[:command]} return exit code: #{exit_code}\n", :color => :red) if exit_code != 0
91
+ _log(" I: #{command[:command]}\n", :color => :green)
92
+ _errorlog(" E: (exit code: #{exit_code}) #{command[:stderr]} \n", :color => :red)
83
93
  end
84
- exit_code
94
+ ret
85
95
  end
86
96
 
87
97
  # courtesy of flitzwald on stackoverflow
@@ -36,10 +36,18 @@ class Server < Screwcap::Base
36
36
 
37
37
  def connect!
38
38
  self.__addresses.each do |address|
39
- if self.__gateway
40
- self.__connections << __gateway.__get_gateway_connection.ssh(address, self.__user, options_for_net_ssh)
41
- else
42
- self.__connections << Net::SSH.start(address, self.__user, options_for_net_ssh)
39
+
40
+ # do not re-connect. return if we have already been connected
41
+ next if self.__connections.any? {|conn| conn[:address] == address }
42
+
43
+ begin
44
+ if self.__gateway
45
+ self.__connections << {:address => address, :connection => __gateway.__get_gateway_connection.ssh(address, self.__user, options_for_net_ssh) }
46
+ else
47
+ self.__connections << {:address => address, :connection => Net::SSH.start(address, self.__user, options_for_net_ssh) }
48
+ end
49
+ rescue Net::SSH::AuthenticationFailed => e
50
+ raise Net::SSH::AuthenticationFailed, "Authentication failed for server named #{self.name}. Please check your authentication credentials."
43
51
  end
44
52
  end
45
53
  self.__connections
data/lib/screwcap/task.rb CHANGED
@@ -47,11 +47,11 @@ class Task < Screwcap::Base
47
47
  # run "ls -l", :onfailure => :rollback
48
48
  # end
49
49
 
50
- def run arg, options = {}
50
+ def run arg, options = {}, &block
51
51
  if arg.class == Symbol
52
- self.__commands << options.merge({:command => self.send(arg), :type => :remote, :from => self.__name})
52
+ self.__commands << options.merge({:command => self.send(arg), :type => :remote, :from => self.__name, :block => block})
53
53
  else
54
- self.__commands << options.merge({:command => arg, :type => :remote, :from => self.__name})
54
+ self.__commands << options.merge({:command => arg, :type => :remote, :from => self.__name, :block => block})
55
55
  end
56
56
  end
57
57
 
@@ -221,6 +221,19 @@ class Task < Screwcap::Base
221
221
  self.__servers = [self.__servers] if self.__servers.class != Array
222
222
  end
223
223
 
224
+ # convenience function to look at the exit status of a parent task
225
+ def exit_code
226
+ self.__options[:exit_code]
227
+ end
228
+
229
+ def stdout
230
+ self.__options[:stdout]
231
+ end
232
+
233
+ def stderr
234
+ self.__options[:stderr]
235
+ end
236
+
224
237
  private
225
238
 
226
239
  def method_missing(m, *args) # :nodoc
@@ -182,7 +182,7 @@ class TaskManager < Screwcap::Base
182
182
  ret = []
183
183
  tasks_to_run.each do |task|
184
184
  ret << task.__build_commands(self.__tasks)
185
- Runner.execute!(:task => task, :servers => self.__servers, :silent => self.__options[:silent], :verbose => self.__options[:verbose])
185
+ Runner.execute!(:task => task, :tasks => self.__tasks, :servers => self.__servers, :silent => self.__options[:silent], :verbose => self.__options[:verbose])
186
186
  end
187
187
 
188
188
  $stdout << "\033[0m"
data/screwcap.gemspec CHANGED
@@ -6,7 +6,7 @@ require 'bundler/version'
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "screwcap"
9
- s.version = "0.7.4"
9
+ s.version = "0.8"
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.author = "Grant Ammons"
12
12
  s.email = ["grant@pipelinedealsco.com"]
data/spec/runner_spec.rb CHANGED
@@ -64,4 +64,38 @@ describe "The Runner" do
64
64
  :silent => true
65
65
  @@testvar.should == :bango
66
66
  end
67
+
68
+ it "should yield a run block" do
69
+ Runner.stubs(:ssh_exec!).returns(["ok\n","",0,nil]).then.returns(["","no\n",1,nil])
70
+ revert_task = Task.new :name => :revert do
71
+ run "revert" do |results|
72
+ if results.exit_code != 0
73
+ run "failed"
74
+ else
75
+ run "succeeded"
76
+ end
77
+ end
78
+ end
79
+ task = Task.new :name => :runblock, :server => :server do
80
+ run "do_something" do |results|
81
+ revert
82
+ end
83
+ end
84
+ task.__build_commands
85
+ task.validate([@server])
86
+ commands = Runner.execute! :name => :runblock, :task => task, :tasks => [task, revert_task], :servers => [@server], :silent => true
87
+ command_names(commands).should == %w(do_something revert failed)
88
+ end
89
+ end
90
+
91
+ def command_names(commands)
92
+ ret = []
93
+ commands.each do |command|
94
+ if command.class == Hash
95
+ ret << command[:command]
96
+ elsif command.class == Array
97
+ ret << command_names(command)
98
+ end
99
+ end
100
+ ret.flatten
67
101
  end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: screwcap
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 7
9
- - 4
10
- version: 0.7.4
8
+ - 8
9
+ version: "0.8"
11
10
  platform: ruby
12
11
  authors:
13
12
  - Grant Ammons
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2011-03-30 00:00:00 -04:00
17
+ date: 2011-04-16 00:00:00 -07:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -67,37 +66,21 @@ dependencies:
67
66
  type: :runtime
68
67
  version_requirements: *id003
69
68
  - !ruby/object:Gem::Dependency
70
- name: rubyforge
69
+ name: hoe
71
70
  prerelease: false
72
71
  requirement: &id004 !ruby/object:Gem::Requirement
73
72
  none: false
74
73
  requirements:
75
74
  - - ">="
76
75
  - !ruby/object:Gem::Version
77
- hash: 7
76
+ hash: 35
78
77
  segments:
79
78
  - 2
80
- - 0
79
+ - 9
81
80
  - 4
82
- version: 2.0.4
81
+ version: 2.9.4
83
82
  type: :development
84
83
  version_requirements: *id004
85
- - !ruby/object:Gem::Dependency
86
- name: hoe
87
- prerelease: false
88
- requirement: &id005 !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ">="
92
- - !ruby/object:Gem::Version
93
- hash: 19
94
- segments:
95
- - 2
96
- - 7
97
- - 0
98
- version: 2.7.0
99
- type: :development
100
- version_requirements: *id005
101
84
  description: Screwcap is a library that wraps Net::SSH and makes it easy to perform actions on remote servers.
102
85
  email:
103
86
  - grant@pipelinedeals.com
@@ -150,6 +133,7 @@ files:
150
133
  - test/config/upload.rb
151
134
  - test/config/use.rb
152
135
  - test/config/use2.rb
136
+ - .gemtest
153
137
  has_rdoc: true
154
138
  homepage: http://gammons.github.com/screwcap
155
139
  licenses: []