screwcap 0.3 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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