Skip to content
This repository has been archived by the owner on Nov 12, 2024. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
zenchild committed Sep 24, 2010
0 parents commit 1f24cde
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 0 deletions.
26 changes: 26 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'winrm' can be used just like 'run'. For instance:

task :ipconfig, :roles => :winrm do
winrm 'ipconfig'
end

This will run ipconfig across all hosts in the :winrm role.

'winrm' will also accept a block exactly like 'run':

task :ipconfig, :roles => :winrm do
host_data = {}
winrm 'ipconfig' do |channel, stream, data|
host_data[channel[:host]] = "" unless host_data[channel[:host]].is_a?(String)
host_data[channel[:host]] << data
end

host_data.each_pair do |host,data|
puts "HOST: #{host}"
puts "---------------------------------------"
puts data
puts "---------------------------------------"
end
end


66 changes: 66 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
require 'rubygems'
require 'rake/clean'
require 'rake/gempackagetask'
require 'date'

CLEAN.include("pkg")
CLEAN.include("doc")

GEMSPEC = Gem::Specification.new do |gem|
gem.name = "capistrano_winrm"
gem.version = File.open('VERSION').readline.chomp
gem.date = Date.today.to_s
gem.platform = Gem::Platform::RUBY
gem.rubyforge_project = nil

gem.author = "Dan Wanek"
gem.email = "[email protected]"
gem.homepage = "http://github.com/zenchild/capistrano_winrm"

gem.summary = 'WinRM extensions for Capistrano'
gem.description = <<-EOF
WinRM extensions for Capistrano
EOF

gem.files = %w{ lib/capistrano_winrm.rb lib/capistrano_winrm/command.rb lib/capistrano_winrm/configuration/connections.rb lib/winrm_connection.rb }
gem.require_path = "lib"
gem.rdoc_options = %w(-x test/ -x examples/)
gem.extra_rdoc_files = %w(README)

gem.required_ruby_version = '>= 1.8.7'
gem.add_runtime_dependency 'capistrano'
gem.add_runtime_dependency 'winrm', '>=0.0.4'
end

Rake::GemPackageTask.new(GEMSPEC) do |pkg|
pkg.need_tar = true
end

task :default => [:buildgem]

desc "Build the gem without a version change"
task :buildgem => [:clean, :repackage]

desc "Build the gem, but increment the version first"
task :newrelease => [:versionup, :clean, :repackage]


desc "Increment the version by 1 minor release"
task :versionup do
ver = up_min_version
puts "New version: #{ver}"
end


def up_min_version
f = File.open('VERSION', 'r+')
ver = f.readline.chomp
v_arr = ver.split(/\./).map do |v|
v.to_i
end
v_arr[2] += 1
ver = v_arr.join('.')
f.rewind
f.write(ver)
ver
end
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.1
20 changes: 20 additions & 0 deletions lib/capistrano_winrm.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module CapistranoWinRM
def self.included(base)
base.send(:alias_method, :winrm, :winrm_run)
end

def winrm_run(cmd, options={}, &block)
set :winrm_running, true
options[:shell] = false
block ||= self.class.default_io_proc
tree = Capistrano::Command::Tree.new(self) { |t| t.else(cmd, &block) }
run_tree(tree, options)
set :winrm_running, false
end
end # CapistranoWinRM

Capistrano::Configuration.send(:include, CapistranoWinRM)

require 'winrm_connection'
require 'capistrano_winrm/command'
require 'capistrano_winrm/configuration/connections'
33 changes: 33 additions & 0 deletions lib/capistrano_winrm/command.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module Capistrano
class Command
# Processes the command in parallel on all specified hosts. If the command
# fails (non-zero return code) on any of the hosts, this will raise a
# Capistrano::CommandError.
def process!
if(@tree.configuration.variables[:winrm_running])
@channels.each do |ch|
ch.process_data do |c, stream, data|
c[:branch].callback[c, stream, data]
end
end
else
loop do
break unless process_iteration { @channels.any? { |ch| !ch[:closed] } }
end
end

logger.trace "command finished" if logger

if (failed = @channels.select { |ch| ch[:status] != 0 }).any?
commands = failed.inject({}) { |map, ch| (map[ch[:command]] ||= []) << ch[:server]; map }
message = commands.map { |command, list| "#{command.inspect} on #{list.join(',')}" }.join("; ")
error = CommandError.new("failed: #{message}")
error.hosts = commands.values.flatten
raise error
end

self
end

end # end Command
end # end Capistrano
35 changes: 35 additions & 0 deletions lib/capistrano_winrm/configuration/connections.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Capistrano
class Configuration
module Connections
class WinRMConnectionFactory #:nodoc:
def initialize(options)
@options = options
@winrm = WINRM.new(options[:winrm_user], options[:winrm_password], nil, options[:winrm_ssl_ca_store])
end

def connect_to(server)
@winrm.setup_connection(server, @options)
@winrm
end
end

# Returns the object responsible for establishing new SSH connections.
# The factory will respond to #connect_to, which can be used to
# establish connections to servers defined via ServerDefinition objects.
def connection_factory
@connection_factory ||= begin
if exists?(:gateway)
logger.debug "establishing connection to gateway `#{fetch(:gateway)}'"
GatewayConnectionFactory.new(fetch(:gateway), self)
elsif(exists?(:winrm_running))
logger.debug "establishing connection to WinRM"
WinRMConnectionFactory.new(self)
else
DefaultConnectionFactory.new(self)
end
end
end

end # Connections
end # Configuration
end # Capistrano
57 changes: 57 additions & 0 deletions lib/winrm_connection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
require 'winrm'

class WINRM
attr_reader :server
alias :xserver :server

def initialize(user, pass, endpoint = nil, ssl_ca_store = nil)
@user = user
@pass = pass
@endpoint = endpoint
@ssl_ca_store = ssl_ca_store
@int_hash = {}
end

def [](key)
@int_hash[key.to_sym]
end

def []=(key, value)
@int_hash[key.to_sym] = value
end

def setup_connection(server, options)
@server = server
@int_hash[:options] = options
@int_hash[:server] = server
end

def open_channel
yield self
end

def exec(cmd)
http_method = ( server.port.to_s=~/(443|5986)/ ? 'https' : 'http' )
endpoint = @endpoint ? @endpoint : "#{http_method}://#{server}/wsman"
WinRM::WinRM.endpoint = endpoint
WinRM::WinRM.set_auth(@user, @pass)
WinRM::WinRM.set_ca_trust_path(@ssl_ca_store) unless @ssl_ca_store.nil?
inst = WinRM::WinRM.instance
@ios = inst.cmd(cmd)
end

def process_data
@ios[:data].each do |ds|
key = ds.keys.first
stream = (key == :stdout) ? :out : :err
yield self, stream, ds[key]
end
self[:status] = @ios[:exitcode]
end

def on_data; self; end
def on_extended_data; self; end
def on_request(req_type); self; end
def on_close; self; end

end

0 comments on commit 1f24cde

Please sign in to comment.