summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/chef.rb2
-rw-r--r--lib/chef/compile.rb1
-rw-r--r--lib/chef/config.rb6
-rw-r--r--lib/chef/cookbook.rb1
-rw-r--r--lib/chef/cookbook_loader.rb6
-rw-r--r--lib/chef/file_store.rb99
-rw-r--r--lib/chef/mixin/params_validate.rb2
-rw-r--r--lib/chef/node.rb32
-rw-r--r--lib/chef/queue.rb109
-rw-r--r--lib/chef/resource.rb26
-rw-r--r--lib/chef/resource_collection.rb20
-rw-r--r--lib/chef/search_index.rb70
12 files changed, 356 insertions, 18 deletions
diff --git a/lib/chef.rb b/lib/chef.rb
index dc61e950a0..18e34e0ffb 100644
--- a/lib/chef.rb
+++ b/lib/chef.rb
@@ -19,7 +19,7 @@
require 'rubygems'
-Dir[File.join(File.dirname(__FILE__), 'chef/**/*.rb')].sort.each { |lib| require lib }
+Dir[File.join(File.dirname(__FILE__), 'chef/**/*.rb')].sort.each { |lib| require lib unless lib =~ /server/ }
class Chef
VERSION = '0.0.1'
diff --git a/lib/chef/compile.rb b/lib/chef/compile.rb
index e974852426..5cd200b098 100644
--- a/lib/chef/compile.rb
+++ b/lib/chef/compile.rb
@@ -35,6 +35,7 @@ class Chef
end
def load_node(name)
+ Chef::Log.debug("Loading Chef Node #{name}")
@node = Chef::Node.find(name)
end
diff --git a/lib/chef/config.rb b/lib/chef/config.rb
index 4793011fb4..807631aedb 100644
--- a/lib/chef/config.rb
+++ b/lib/chef/config.rb
@@ -39,6 +39,8 @@ class Chef
@configuration = {
:cookbook_path => [ "/etc/chef/site-cookbook", "/etc/chef/cookbook" ],
:node_path => "/etc/chef/node",
+ :file_store_path => "/var/lib/chef/store",
+ :search_index_path => "/var/lib/chef/search_index",
:log_level => :info,
:log_location => STDOUT
}
@@ -61,6 +63,10 @@ class Chef
def []=(config_option, value)
@configuration[config_option.to_sym] = value
end
+
+ def has_key?(key)
+ @configuration.has_key?(key.to_sym)
+ end
def method_missing(method_symbol, *args)
if @configuration.has_key?(method_symbol)
diff --git a/lib/chef/cookbook.rb b/lib/chef/cookbook.rb
index 39013069ca..ed9b75a1d9 100644
--- a/lib/chef/cookbook.rb
+++ b/lib/chef/cookbook.rb
@@ -47,6 +47,7 @@ class Chef
def load_definitions
results = Hash.new
@definition_files.each do |file|
+ Chef::Log.debug("Loading cookbook #{name}'s definitions from #{file}")
resourcedef = Chef::ResourceDefinition.new
resourcedef.from_file(file)
results[resourcedef.name] = resourcedef
diff --git a/lib/chef/cookbook_loader.rb b/lib/chef/cookbook_loader.rb
index 24ec01e574..95edecfab8 100644
--- a/lib/chef/cookbook_loader.rb
+++ b/lib/chef/cookbook_loader.rb
@@ -72,7 +72,11 @@ class Chef
end
def [](cookbook)
- @cookbook[cookbook.to_sym]
+ if @cookbook.has_key?(cookbook.to_sym)
+ @cookbook[cookbook.to_sym]
+ else
+ raise ArgumentError, "Cannot find a cookbook named #{cookbook.to_s}"
+ end
end
def each
diff --git a/lib/chef/file_store.rb b/lib/chef/file_store.rb
new file mode 100644
index 0000000000..b834624090
--- /dev/null
+++ b/lib/chef/file_store.rb
@@ -0,0 +1,99 @@
+require File.join(File.dirname(__FILE__), "mixin", "params_validate")
+require 'digest/sha2'
+require 'json'
+
+class Chef
+ class FileStore
+ class << self
+ include Chef::Mixin::ParamsValidate
+
+ def store(obj_type, name, object)
+ validate(
+ {
+ :obj_type => obj_type,
+ :name => name,
+ :object => object,
+ },
+ {
+ :object => { :respond_to => :to_json },
+ }
+ )
+
+ store_path = create_store_path(obj_type, name)
+ io = File.open(store_path, "w")
+ io.puts object.to_json
+ io.close
+ end
+
+ def load(obj_type, name)
+ validate(
+ {
+ :obj_type => obj_type,
+ :name => name,
+ },
+ {
+ :obj_type => { :kind_of => String },
+ :name => { :kind_of => String },
+ }
+ )
+ store_path = create_store_path(obj_type, name)
+ raise "Cannot find #{store_path} for #{obj_type} #{name}!" unless File.exists?(store_path)
+
+ object = JSON.parse(IO.read(store_path))
+ end
+
+ def delete(obj_type, name)
+ validate(
+ {
+ :obj_type => obj_type,
+ :name => name,
+ },
+ {
+ :obj_type => { :kind_of => String },
+ :name => { :kind_of => String },
+ }
+ )
+ store_path = create_store_path(obj_type, name)
+ if File.exists?(store_path)
+ File.unlink(store_path)
+ end
+ end
+
+ def list(obj_type)
+ validate(
+ {
+ :obj_type => obj_type,
+ },
+ {
+ :obj_type => { :kind_of => String }
+ }
+ )
+ keys = Array.new
+ Dir[File.join(Chef::Config[:file_store_path], obj_type, '**', '*')].each do |f|
+ if File.file?(f)
+ keys << File.basename(f)
+ end
+ end
+ keys
+ end
+
+ def create_store_path(obj_type, key)
+ shadigest = Digest::SHA2.hexdigest("#{obj_type}#{key}")
+
+ file_path = [
+ Chef::Config[:file_store_path],
+ obj_type,
+ shadigest[0,1],
+ shadigest[1,3]
+ ]
+ file_path.each_index do |i|
+ create_path = File.join(file_path[0, i + 1])
+ Dir.mkdir(create_path) unless File.directory?(create_path)
+ end
+ file_path << key
+ File.join(*file_path)
+ end
+
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/chef/mixin/params_validate.rb b/lib/chef/mixin/params_validate.rb
index 741e932006..2f6e432024 100644
--- a/lib/chef/mixin/params_validate.rb
+++ b/lib/chef/mixin/params_validate.rb
@@ -155,7 +155,7 @@ class Chef
def _pv_respond_to(opts, key, method_name_list)
value = _pv_opts_lookup(opts, key)
if value != nil
- method_name_list.to_a.each do |method_name|
+ [ method_name_list ].flatten.each do |method_name|
unless value.respond_to?(method_name)
raise ArgumentError, "Option #{key} must have a #{method_name} method!"
end
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index f8adf5983f..236bd2f9e1 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -165,21 +165,29 @@ class Chef
end
end
- # Serialize this Node as json
- def to_json()
- result_object = {
+ # Serialize this object as a hash
+ def to_json(*a)
+ attributes = Hash.new
+ recipes = Array.new
+ {
"name" => @name,
- "type" => "Chef::Node",
- "attributes" => Hash.new,
- "recipes" => Array.new
- }
- each_attribute do |a,v|
- result_object["attributes"][a] = v
+ 'json_class' => self.class.name,
+ "attributes" => @attribute,
+ "recipes" => @recipe_list,
+ }.to_json(*a)
+ end
+
+ def self.json_create(o)
+ node = new
+ node.name(o["name"])
+ o["attributes"].each do |k,v|
+ node[k] = v
end
- recipes.each do |r|
- result_object["recipes"] << r
+ o["recipes"].each do |r|
+ node.recipes << r
end
- result_object.to_json
+
+ node
end
# As a string
diff --git a/lib/chef/queue.rb b/lib/chef/queue.rb
new file mode 100644
index 0000000000..795670d79a
--- /dev/null
+++ b/lib/chef/queue.rb
@@ -0,0 +1,109 @@
+#
+# Author:: Adam Jacob (<adam@hjksolutions.com>)
+# Copyright:: Copyright (c) 2008 HJK Solutions, LLC
+# License:: GNU General Public License version 2 or later
+#
+# This program and entire repository is free software; you can
+# redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+require File.join(File.dirname(__FILE__), "mixin", "params_validate")
+
+class Chef
+ class Queue
+ require 'stomp'
+
+ @client = nil
+
+ class << self
+ include Chef::Mixin::ParamsValidate
+
+ def connect
+ @client = Stomp::Connection.open(
+ Chef::Config.has_key?(:queue_user) ? Chef::Config[:queue_user] : "",
+ Chef::Config.has_key?(:queue_password) ? Chef::Config[:queue_password] : "",
+ Chef::Config.has_key?(:queue_host) ? Chef::Config[:queue_host] : "localhost",
+ Chef::Config.has_key?(:queue_port) ? Chef::Config[:queue_port] : 61613,
+ false
+ )
+ end
+
+ def make_url(type, name)
+ validate(
+ {
+ :queue_type => type.to_sym,
+ :queue_name => name.to_sym,
+ },
+ {
+ :queue_type => {
+ :equal_to => [ :topic, :queue ],
+ },
+ :queue_name => {
+ :kind_of => [ String, Symbol ],
+ }
+ }
+ )
+ queue_url = "/#{type}/chef/#{name}"
+ end
+
+ def subscribe(type, name)
+ queue_url = make_url(type, name)
+ Chef::Log.debug("Subscribing to #{queue_url}")
+ connect if @client == nil
+ @client.subscribe(queue_url)
+ end
+
+ def send_msg(type, name, msg)
+ validate(
+ {
+ :message => msg,
+ },
+ {
+ :message => {
+ :respond_to => :to_json
+ }
+ }
+ )
+ queue_url = make_url(type, name)
+ json = msg.to_json
+ connect if @client == nil
+ Chef::Log.debug("Sending to #{queue_url}: #{json}")
+ @client.send(queue_url, json)
+ end
+
+ def receive_msg
+ connect if @client == nil
+ raw_msg = @client.receive()
+ Chef::Log.debug("Received Message from #{raw_msg.headers["destination"]} containing: #{raw_msg.body}")
+ msg = JSON.parse(raw_msg.body)
+ return msg, raw_msg.headers
+ end
+
+ def poll_msg
+ connect if @client == nil
+ raw_msg = @client.poll()
+ if raw_msg
+ msg = JSON.parse(raw_msg.body)
+ else
+ nil
+ end
+ end
+
+ def disconnect
+ raise ArgumentError, "You must call connect before you can disconnect!" unless @client
+ @client.disconnect
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index afff713ba6..705738fe59 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -28,8 +28,8 @@ class Chef
include Chef::Mixin::CheckHelper
include Chef::Mixin::ParamsValidate
- attr_accessor :tag, :actions, :params, :provider, :updated, :allowed_actions
- attr_reader :resource_name, :collection
+ attr_accessor :actions, :params, :provider, :updated, :allowed_actions
+ attr_reader :resource_name, :collection, :source_line
def initialize(name, collection=nil)
@name = name
@@ -38,7 +38,6 @@ class Chef
else
@collection = Chef::ResourceCollection.new()
end
- @tag = [ name.to_s ]
@noop = nil
@before = nil
@actions = Hash.new
@@ -47,6 +46,7 @@ class Chef
@allowed_actions = [ :nothing ]
@action = :nothing
@updated = false
+ @source_line = caller(4).shift.gsub!(/^(.+):(.+):.+$/, '\1 line \2')
end
def action(arg=nil)
@@ -118,6 +118,26 @@ class Chef
"#{@resource_name}[#{@name}]"
end
+ # Serialize this object as a hash
+ def to_json(*a)
+ instance_vars = Hash.new
+ self.instance_variables.each do |iv|
+ instance_vars[iv] = self.instance_variable_get(iv) unless iv == "@collection"
+ end
+ {
+ 'json_class' => self.class.name,
+ 'instance_vars' => instance_vars
+ }.to_json(*a)
+ end
+
+ def self.json_create(o)
+ resource = self.new(o["instance_vars"]["@name"])
+ o["instance_vars"].each do |k,v|
+ resource.instance_variable_set(k.to_sym, v)
+ end
+ resource
+ end
+
private
def check_timing(timing)
diff --git a/lib/chef/resource_collection.rb b/lib/chef/resource_collection.rb
index 5728fdd3e9..362781ea0e 100644
--- a/lib/chef/resource_collection.rb
+++ b/lib/chef/resource_collection.rb
@@ -111,6 +111,26 @@ class Chef
flat_results = results.flatten
flat_results.length == 1 ? flat_results[0] : flat_results
end
+
+ # Serialize this object as a hash
+ def to_json(*a)
+ instance_vars = Hash.new
+ self.instance_variables.each do |iv|
+ instance_vars[iv] = self.instance_variable_get(iv)
+ end
+ {
+ 'json_class' => self.class.name,
+ 'instance_vars' => instance_vars
+ }.to_json(*a)
+ end
+
+ def self.json_create(o)
+ collection = self.new()
+ o["instance_vars"].each do |k,v|
+ collection.instance_variable_set(k.to_sym, v)
+ end
+ collection
+ end
private
diff --git a/lib/chef/search_index.rb b/lib/chef/search_index.rb
new file mode 100644
index 0000000000..6af408b68c
--- /dev/null
+++ b/lib/chef/search_index.rb
@@ -0,0 +1,70 @@
+#
+# Author:: Adam Jacob (<adam@hjksolutions.com>)
+# Copyright:: Copyright (c) 2008 HJK Solutions, LLC
+# License:: GNU General Public License version 2 or later
+#
+# This program and entire repository is free software; you can
+# redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+require File.join(File.dirname(__FILE__), "mixin", "params_validate")
+require 'ferret'
+
+class Chef
+ class SearchIndex
+
+ def initialize
+ @index = Ferret::Index::Index.new(
+ :path => Chef::Config[:search_index_path],
+ :key => [ :id ]
+ )
+ end
+
+ def add(to_index)
+ type = check_type(to_index)
+ result = self.send("_prepare_#{type}", to_index)
+ Chef::Log.debug("Indexing #{type} with #{result.inspect}")
+ @index.add_document(result)
+ end
+
+ def delete(index_obj)
+ type = check_type(index_obj)
+ to_index = self.send("_prepare_#{type}", index_obj)
+ Chef::Log.debug("Removing #{type} with #{to_index.inspect}")
+ @index.delete(:id => "#{to_index[:id]}")
+ end
+
+ private
+
+ def check_type(to_check)
+ type = nil
+ case to_check
+ when Chef::Node
+ type = "node"
+ end
+ end
+
+ def _prepare_node(node)
+ result = Hash.new
+ result[:id] = "node-#{node.name}"
+ result[:type] = "node"
+ result[:name] = node.name
+ node.each_attribute do |k,v|
+ result[k.to_sym] = v
+ end
+ result[:recipe] = node.recipes
+ result
+ end
+ end
+end \ No newline at end of file