Class: RightScale::Windows::ChefNodeServer

Inherits:
Object
  • Object
show all
Includes:
RightSupport::Ruby::EasySingleton
Defined in:
lib/chef/windows/chef_node_server.rb

Overview

Provides a server for a named pipe connection which serves data from a node structure organized as a hierarchy of hashes to privitives, arrays and subhashes. complex types can also appear but will be served out as hashes without type. caution should be used not to use complex types which have circular references.

Defined Under Namespace

Classes: CircularReferenceException, InvalidPathException

Constant Summary collapse

CHEF_NODE_PIPE_NAME =
'chef_node_D1D6B540-5125-4c00-8ABF-412417774DD5'
COMMAND_KEY =
"Command"
PATH_KEY =
"Path"
NODE_VALUE_KEY =
"NodeValue"

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#current_resourceObject

Returns the value of attribute current_resource.



46
47
48
# File 'lib/chef/windows/chef_node_server.rb', line 46

def current_resource
  @current_resource
end

#new_resourceObject

Returns the value of attribute new_resource.



47
48
49
# File 'lib/chef/windows/chef_node_server.rb', line 47

def new_resource
  @new_resource
end

#nodeObject (readonly)

Returns the value of attribute node.



45
46
47
# File 'lib/chef/windows/chef_node_server.rb', line 45

def node
  @node
end

Instance Method Details

#request_handler(request_data) ⇒ Object

Handler for data node requests. Expects complete requests and responses to appear serialized as JSON on individual lines (i.e. delimited by newlines). note that JSON text escapes newline characters within string values and normally only includes whitespace for human-readability.



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/chef/windows/chef_node_server.rb', line 99

def request_handler(request_data)
  # assume request_data is a single line with a possible newline trailing.
  request = JSON.load(request_data.chomp)
  if request.has_key?(COMMAND_KEY)
    handler = REQUEST_HANDLERS[request[COMMAND_KEY]]
    Log.debug("handler = #{handler}")
    return self.send(handler, request) if handler
  end
  raise "Invalid request"
rescue Exception => e
  return JSON.dump( { :Error => "#{e.class}: #{e.message}", :Detail => e.backtrace.join("\n") } ) + "\n"
end

#start(options) ⇒ Object

Starts the pipe server by creating an asynchronous named pipe. Returns control to the caller after adding the pipe to the event machine.

Parameters

options(Node)

Chef node, required

Return

true

If server was successfully started

false

Otherwise



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/chef/windows/chef_node_server.rb', line 58

def start(options)
  return true if @pipe_eventable # Idempotent

  Log.debug("[ChefNodeServer] - Starting")
  @node = options[:node] || {}
  @pipe_eventable = nil
  @current_resource = nil
  @new_resource = nil

  flags = ::Win32::Pipe::ACCESS_DUPLEX | ::Win32::Pipe::OVERLAPPED
  pipe  = PipeServer.new(CHEF_NODE_PIPE_NAME, 0, flags)
  res   = true
  begin
    options = {:target          => self,
               :request_handler => :request_handler,
               :pipe            => pipe}
    @pipe_eventable = EM.watch(pipe, PipeServerHandler, options)
    @pipe_eventable.notify_readable = true
  rescue Exception => e
    pipe.close rescue nil
    res = false
  end
  Log.debug("[ChefNodeServer] - Started = #{res}")
  res
end

#stopObject

Stops the pipe server by detaching the eventable from the event machine.

Return

true

Always return true



88
89
90
91
92
93
# File 'lib/chef/windows/chef_node_server.rb', line 88

def stop
  Log.debug("[ChefNodeServer] - Stopping - need to stop = #{!@pipe_eventable.nil?}")
  @pipe_eventable.force_detach if @pipe_eventable
  @pipe_eventable = nil
  true
end