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 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']]
data/TODO ADDED
@@ -0,0 +1 @@
1
+ * validate if a gateway exists if declared with server
@@ -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
@@ -17,7 +17,7 @@ require 'screwcap/sequence'
17
17
  require 'screwcap/deployer'
18
18
 
19
19
  module Screwcap
20
- VERSION='0.3'
20
+ VERSION='0.3.1'
21
21
 
22
22
  class TaskNotFound < RuntimeError; end
23
23
  class NoServersDefined < Exception; end
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.3"
9
+ s.version = "0.3.1"
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.author = "Grant Ammons"
12
12
  s.email = ["grant@pipelinedealsco.com"]
@@ -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: 13
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- version: "0.3"
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