summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--History.txt5
-rw-r--r--examples/config/cookbooks/fakefile/attributes/first.rb2
-rw-r--r--examples/config/cookbooks/fakefile/recipes/default.rb15
-rw-r--r--examples/config/cookbooks/fakefile/templates/default/somefile.erb3
-rw-r--r--examples/config/cookbooks/tempfile/attributes/second.rb1
-rw-r--r--lib/chef/client.rb34
-rw-r--r--lib/chef/compile.rb14
-rw-r--r--lib/chef/config.rb2
-rw-r--r--lib/chef/cookbook.rb4
-rw-r--r--lib/chef/cookbook_loader.rb14
-rw-r--r--lib/chef/platform.rb1
-rw-r--r--lib/chef/provider/template.rb69
-rw-r--r--lib/chef/recipe.rb2
-rw-r--r--lib/chef/resource.rb2
-rw-r--r--lib/chef/resource/template.rb52
-rw-r--r--lib/chef_server/controllers/cookbook_templates.rb29
-rw-r--r--lib/chef_server/controllers/cookbooks.rb33
-rw-r--r--lib/chef_server/init.rb8
-rw-r--r--lib/chef_server/public/stylesheets/master.css145
-rw-r--r--lib/chef_server/views/cookbooks/_attribute_file.html.haml2
-rw-r--r--lib/chef_server/views/cookbooks/attribute_files.html.haml4
-rw-r--r--lib/chef_server/views/cookbooks/index.html.haml7
-rw-r--r--lib/chef_server/views/cookbooks/show.html.haml18
-rw-r--r--lib/chef_server/views/layout/application.html.haml2
-rw-r--r--lib/chef_server/views/nodes/_action.html.haml2
-rw-r--r--spec/lib/chef/resource/cat.rb4
-rw-r--r--spec/lib/chef/resource/zen_master.rb4
-rw-r--r--spec/spec_helper.rb2
-rw-r--r--spec/unit/log/formatter_spec.rb2
-rw-r--r--spec/unit/resource/template_spec.rb44
-rw-r--r--spec/unit/rest_spec.rb12
-rw-r--r--spec/unit/search_index_spec.rb12
-rw-r--r--spec/unit/search_spec.rb (renamed from spec/unit/search.rb)14
33 files changed, 530 insertions, 34 deletions
diff --git a/History.txt b/History.txt
index edd3311c47..5080d3f7fb 100644
--- a/History.txt
+++ b/History.txt
@@ -7,4 +7,7 @@ Sun Apr 27 20:30:43 PDT 2008
* Compiled first full recipes, and actually passed them to a provider. :)
Mon Jun 9 01:57:58 PDT 2008
- * Compiled first full recipes over a network, with registration and authorization. \ No newline at end of file
+ * Compiled first full recipes over a network, with registration and authorization.
+
+Thu Jul 10 19:59:46 PDT 2008
+ * Search support functional! \ No newline at end of file
diff --git a/examples/config/cookbooks/fakefile/attributes/first.rb b/examples/config/cookbooks/fakefile/attributes/first.rb
new file mode 100644
index 0000000000..c0a6dd1e90
--- /dev/null
+++ b/examples/config/cookbooks/fakefile/attributes/first.rb
@@ -0,0 +1,2 @@
+puts "woot"
+puts "woot woot"
diff --git a/examples/config/cookbooks/fakefile/recipes/default.rb b/examples/config/cookbooks/fakefile/recipes/default.rb
index 7f44e5686b..2ee933716a 100644
--- a/examples/config/cookbooks/fakefile/recipes/default.rb
+++ b/examples/config/cookbooks/fakefile/recipes/default.rb
@@ -1,4 +1,5 @@
+
file "/tmp/foo" do
owner "adam"
mode 0644
@@ -6,10 +7,20 @@ file "/tmp/foo" do
notifies :delete, resources(:file => "/tmp/glen"), :delayed
end
+template "/tmp/foo-template" do
+ owner "adam"
+ mode 0644
+ template "template"
+ variables({
+ :one => 'two',
+ :el_che => 'rhymefest'
+ })
+end
+
link "/tmp/foo" do
link_type :symbolic
target_file "/tmp/xmen"
-end
+end
0.upto(1000) do |n|
file "/tmp/somefile#{n}" do
@@ -35,4 +46,4 @@ search(:user, "*") do |u|
mode 0755
action :create
end
-end \ No newline at end of file
+end
diff --git a/examples/config/cookbooks/fakefile/templates/default/somefile.erb b/examples/config/cookbooks/fakefile/templates/default/somefile.erb
new file mode 100644
index 0000000000..8c7ffed237
--- /dev/null
+++ b/examples/config/cookbooks/fakefile/templates/default/somefile.erb
@@ -0,0 +1,3 @@
+Here you go!
+
+<%= @some_variable %>
diff --git a/examples/config/cookbooks/tempfile/attributes/second.rb b/examples/config/cookbooks/tempfile/attributes/second.rb
new file mode 100644
index 0000000000..df791b8429
--- /dev/null
+++ b/examples/config/cookbooks/tempfile/attributes/second.rb
@@ -0,0 +1 @@
+monkey "poots" \ No newline at end of file
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index 0ae7ef70e6..681260eee2 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -28,6 +28,7 @@ class Chef
attr_accessor :node, :registration, :safe_name
+ # Creates a new Chef::Client.
def initialize()
@node = nil
@safe_name = nil
@@ -35,14 +36,27 @@ class Chef
@rest = Chef::REST.new(Chef::Config[:registration_url])
end
+ # Do a full run for this Chef::Client. Calls:
+ #
+ # * build_node
+ # * register
+ # * authenticate
+ # * do_attribute_files
+ # * save_node
+ # * converge
+ #
+ # In that order.
def run
build_node
register
authenticate
+ do_attribute_files
save_node
converge
end
+ # Builds a new node object for this client. Starts with querying for the FQDN of the current
+ # host, then merges in the facts from Facter.
def build_node(node_name=nil)
node_name ||= Facter["fqdn"].value ? Facter["fqdn"].value : Facter["hostname"].value
@safe_name = node_name.gsub(/\./, '_')
@@ -63,6 +77,10 @@ class Chef
@node
end
+ # If this node has been registered before, this method will fetch the current registration
+ # data.
+ #
+ # If it has not, we register it by calling create_registration.
def register
@registration = nil
begin
@@ -81,12 +99,15 @@ class Chef
end
end
+ # Generates a random secret, stores it in the Chef::Filestore with the "registration" key,
+ # and posts our nodes registration information to the server.
def create_registration
@secret = random_password(40)
Chef::FileStore.store("registration", @safe_name, { "secret" => @secret })
@rest.post_rest("registrations", { :id => @safe_name, :password => @secret })
end
+ # Authenticates the node via OpenID.
def authenticate
response = @rest.post_rest('openid/consumer/start', {
"openid_identifier" => "#{Chef::Config[:openid_url]}/openid/server/node/#{@safe_name}",
@@ -98,10 +119,22 @@ class Chef
)
end
+ # Gets all the attribute files included in all the cookbooks available on the server,
+ # and executes them.
+ def do_attribute_files
+ af_list = @rest.get_rest('cookbooks/_attribute_files')
+ af_list.each do |af|
+ @node.instance_eval(af["contents"], "#{af['cookbook']}/#{af['name']}", 1)
+ end
+ end
+
+ # Updates the current node configuration on the server.
def save_node
@rest.put_rest("nodes/#{@safe_name}", @node)
end
+ # Compiles the full list of recipes for the server, and passes it to an instance of
+ # Chef::Runner.converge.
def converge
results = @rest.get_rest("nodes/#{@safe_name}/compile")
results["collection"].resources.each do |r|
@@ -112,6 +145,7 @@ class Chef
end
protected
+ # Generates a random password of "len" length.
def random_password(len)
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
newpass = ""
diff --git a/lib/chef/compile.rb b/lib/chef/compile.rb
index 800d89c6b0..83192d4f26 100644
--- a/lib/chef/compile.rb
+++ b/lib/chef/compile.rb
@@ -27,6 +27,8 @@ class Chef
attr_accessor :node, :cookbook_loader, :collection, :definitions
+ # Creates a new Chef::Compile object. This object gets used by the Chef Server to generate
+ # a fully compiled recipe list for a node.
def initialize()
@node = nil
@cookbook_loader = Chef::CookbookLoader.new
@@ -34,6 +36,10 @@ class Chef
@definitions = Hash.new
end
+ # Looks up the node via the "name" argument, first from CouchDB, then by calling
+ # Chef::Node.find_file(name)
+ #
+ # The first step in compiling the catalog. Results available via the node accessor.
def load_node(name)
Chef::Log.debug("Loading Chef Node #{name} from CouchDB")
@node = Chef::Node.load(name)
@@ -42,6 +48,10 @@ class Chef
@node
end
+ # Load all the definitions, from every cookbook, so they are available when we process
+ # the recipes.
+ #
+ # Results available via the definitions accessor.
def load_definitions()
@cookbook_loader.each do |cookbook|
hash = cookbook.load_definitions
@@ -49,6 +59,10 @@ class Chef
end
end
+ # Load all the recipes specified in the node data (loaded via load_node, above.)
+ #
+ # The results are available via the collection accessor (which returns a Chef::ResourceCollection
+ # object)
def load_recipes
@node.recipes.each do |recipe|
rmatch = recipe.match(/(.+?)::(.+)/)
diff --git a/lib/chef/config.rb b/lib/chef/config.rb
index 5ad4cdb2af..cf4faf727e 100644
--- a/lib/chef/config.rb
+++ b/lib/chef/config.rb
@@ -50,6 +50,8 @@ class Chef
:couchdb_url => "http://localhost:5984",
:registration_url => "http://localhost:4000",
:openid_url => "http://localhost:4001",
+ :template_url => "http://localhost:4000",
+ :remotefile_url => "http://localhost:4000",
:couchdb_database => "chef",
:openid_store_path => "/var/chef/openid/db",
:openid_cstore_path => "/var/chef/openid/cstore",
diff --git a/lib/chef/cookbook.rb b/lib/chef/cookbook.rb
index 75ab8f4ad6..b7c6506a99 100644
--- a/lib/chef/cookbook.rb
+++ b/lib/chef/cookbook.rb
@@ -21,13 +21,15 @@
class Chef
class Cookbook
- attr_accessor :attribute_files, :definition_files, :name
+ attr_accessor :attribute_files, :definition_files, :template_files, :remote_files, :name
attr_reader :recipe_files
def initialize(name)
@name = name
@attribute_files = Array.new
@definition_files = Array.new
+ @template_files = Array.new
+ @remote_files = Array.new
@recipe_files = Array.new
@recipe_names = Hash.new
@loaded_attributes = false
diff --git a/lib/chef/cookbook_loader.rb b/lib/chef/cookbook_loader.rb
index 95edecfab8..ee4e1891e3 100644
--- a/lib/chef/cookbook_loader.rb
+++ b/lib/chef/cookbook_loader.rb
@@ -42,6 +42,8 @@ class Chef
:attribute_files => Array.new,
:definition_files => Array.new,
:recipe_files => Array.new,
+ :template_files => Array.new,
+ :remote_files => Array.new,
}
end
ignore_regexes = load_ignore_file(File.join(cookbook, "ignore"))
@@ -61,6 +63,16 @@ class Chef
cookbook_settings[cookbook_name][:recipe_files],
cookbook_settings[cookbook_name][:ignore_regexes]
)
+ load_files_unless_basename(
+ File.join(cookbook, "templates", "*.erb"),
+ cookbook_settings[cookbook_name][:template_files],
+ cookbook_settings[cookbook_name][:ignore_regexes]
+ )
+ load_files_unless_basename(
+ File.join(cookbook, "files", "*"),
+ cookbook_settings[cookbook_name][:remote_files],
+ cookbook_settings[cookbook_name][:ignore_regexes]
+ )
end
end
cookbook_settings.each_key do |cookbook|
@@ -68,6 +80,8 @@ class Chef
@cookbook[cookbook].attribute_files = cookbook_settings[cookbook][:attribute_files]
@cookbook[cookbook].definition_files = cookbook_settings[cookbook][:definition_files]
@cookbook[cookbook].recipe_files = cookbook_settings[cookbook][:recipe_files]
+ @cookbook[cookbook].template_files = cookbook_settings[cookbook][:template_files]
+ @cookbook[cookbook].remote_files = cookbook_settings[cookbook][:remote_files]
end
end
diff --git a/lib/chef/platform.rb b/lib/chef/platform.rb
index 55e85ae354..4114d5960b 100644
--- a/lib/chef/platform.rb
+++ b/lib/chef/platform.rb
@@ -35,6 +35,7 @@ class Chef
:file => Chef::Provider::File,
:directory => Chef::Provider::Directory,
:link => Chef::Provider::Link,
+ :template => Chef::Provider::Template,
}
}
diff --git a/lib/chef/provider/template.rb b/lib/chef/provider/template.rb
new file mode 100644
index 0000000000..47ffc810bf
--- /dev/null
+++ b/lib/chef/provider/template.rb
@@ -0,0 +1,69 @@
+#
+# 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__), "file")
+require 'uri'
+
+class Chef
+ class Provider
+ class Template < Chef::Provider::File
+
+ def action_create
+ r = Chef::REST.new(Chef::Config[:template_url])
+ template_url = nil
+ if @new_resource.template =~ /^http/
+ template_url = @new_resource.template
+ else
+ template_url = "cookbooks/#{@new_resource.cookbook_name}/templates/#{@new_resource.template}"
+ end
+ template = r.get_rest(template_url)
+
+
+ unless ::File.exists?(@new_resource.path)
+ Chef::Log.info("Creating #{@new_resource} at #{@new_resource.path}")
+ ::File.open(@new_resource.path, "w+") { |f| }
+ @new_resource.updated = true
+ end
+ set_owner if @new_resource.owner != nil
+ set_group if @new_resource.group != nil
+ set_mode if @new_resource.mode != nil
+ end
+
+ def action_delete
+ if ::File.exists?(@new_resource.path) && ::File.writable?(@new_resource.path)
+ Chef::Log.info("Deleting #{@new_resource} at #{@new_resource.path}")
+ ::File.delete(@new_resource.path)
+ @new_resource.updated = true
+ else
+ raise "Cannot delete #{@new_resource} at #{@new_resource_path}!"
+ end
+ end
+
+ def action_touch
+ action_create
+ time = Time.now
+ Chef::Log.info("Updating #{@new_resource} with new atime/mtime of #{time}")
+ ::File.utime(time, time, @new_resource.path)
+ @new_resource.updated = true
+ end
+
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/chef/recipe.rb b/lib/chef/recipe.rb
index 47a194eda7..c161bbdae6 100644
--- a/lib/chef/recipe.rb
+++ b/lib/chef/recipe.rb
@@ -105,6 +105,8 @@ class Chef
args << @collection
args << @node
resource = eval(rname).new(*args)
+ resource.cookbook_name = @cookbook_name
+ resource.recipe_name = @recipe_name
resource.params = @params
resource.instance_eval(&block)
rescue Exception => e
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index e42b791b1d..40d711f969 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -28,7 +28,7 @@ class Chef
include Chef::Mixin::CheckHelper
include Chef::Mixin::ParamsValidate
- attr_accessor :actions, :params, :provider, :updated, :allowed_actions, :collection
+ attr_accessor :actions, :params, :provider, :updated, :allowed_actions, :collection, :cookbook_name, :recipe_name
attr_reader :resource_name, :source_line, :node
def initialize(name, collection=nil, node=nil)
diff --git a/lib/chef/resource/template.rb b/lib/chef/resource/template.rb
new file mode 100644
index 0000000000..25df8c712d
--- /dev/null
+++ b/lib/chef/resource/template.rb
@@ -0,0 +1,52 @@
+#
+# 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
+#
+
+
+class Chef
+ class Resource
+ class Template < Chef::Resource::File
+
+ def initialize(name, collection=nil, node=nil)
+ @resource_name = :template
+ super(name, collection, node)
+ @action = "create"
+ @template = nil
+ @variables = Hash.new
+ end
+
+ def template(file=nil)
+ set_or_return(
+ :template,
+ file,
+ :kind_of => [ String ]
+ )
+ end
+
+ def variables(args=nil)
+ set_or_return(
+ :vars,
+ args,
+ :kind_of => [ Hash ]
+ )
+ end
+
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/chef_server/controllers/cookbook_templates.rb b/lib/chef_server/controllers/cookbook_templates.rb
new file mode 100644
index 0000000000..56338ac3f5
--- /dev/null
+++ b/lib/chef_server/controllers/cookbook_templates.rb
@@ -0,0 +1,29 @@
+class CookbookTemplates < Application
+
+ provides :html, :json
+
+ def load_cookbook(with_content=false)
+ @cl = Chef::CookbookLoader.new
+ @cookbook = @cl[params[:cookbook_id]]
+ raise NotFound unless @cookbook
+ @templates = Hash.new
+ @cookbook.template_files.each do |tf|
+ @templates[File.basename(tf)] = {
+ :file => tf,
+ }
+ @templates[File.basename(tf)][:contents] = File.read(tf) if with_content
+ end
+ end
+
+ def index
+ load_cookbook(false)
+ display @templates
+ end
+
+ def show
+ load_cookbook(true)
+ @template = @templates[params[:id]]
+ display @template
+ end
+
+end
diff --git a/lib/chef_server/controllers/cookbooks.rb b/lib/chef_server/controllers/cookbooks.rb
new file mode 100644
index 0000000000..d18b3506a2
--- /dev/null
+++ b/lib/chef_server/controllers/cookbooks.rb
@@ -0,0 +1,33 @@
+class Cookbooks < Application
+
+ provides :html, :json
+
+ def index
+ @cl = Chef::CookbookLoader.new
+ display @cl
+ end
+
+ def show
+ @cl = Chef::CookbookLoader.new
+ @cookbook = @cl[params[:id]]
+ raise NotFound unless @cookbook
+ display @cookbook
+ end
+
+ def attribute_files
+ cl = Chef::CookbookLoader.new
+ @attribute_files = Array.new
+ cl.each do |cookbook|
+ cookbook.attribute_files.each do |af|
+ @attribute_files << {
+ :cookbook => cookbook.name,
+ :name => File.basename(af),
+ :path => af,
+ :contents => File.read(af)
+ }
+ end
+ end
+ display @attribute_files
+ end
+
+end
diff --git a/lib/chef_server/init.rb b/lib/chef_server/init.rb
index ca1692b6cf..cf1d17e224 100644
--- a/lib/chef_server/init.rb
+++ b/lib/chef_server/init.rb
@@ -90,6 +90,7 @@ Merb.push_path(:helper, File.join(File.dirname(__FILE__), "helpers"))
Merb.push_path(:public, File.join(File.dirname(__FILE__), "public"))
require 'merb-haml'
+require 'uv'
#
@@ -137,7 +138,12 @@ Merb::Router.prepare do |r|
r.resources :nodes, :member => { :compile => :get }
r.resources :search do |res|
res.resources :entries, :controller => "search_entries"
- end
+ end
+
+ r.match("/cookbooks/_attribute_files").to(:controller => "cookbooks", :action => "attribute_files")
+ r.resources :cookbooks do |cookbooks|
+ cookbooks.resources :templates, :controller => "cookbook_templates"
+ end
#r.resources :openid do |res|
# res.resources :register, :controller => "openid_register"
diff --git a/lib/chef_server/public/stylesheets/master.css b/lib/chef_server/public/stylesheets/master.css
index 70580148a7..13bdffbe1b 100644
--- a/lib/chef_server/public/stylesheets/master.css
+++ b/lib/chef_server/public/stylesheets/master.css
@@ -1,4 +1,4 @@
-body {
+/* body {
font-family: Arial, Verdana, sans-serif;
font-size: 12px;
background-color: #fff;
@@ -7,7 +7,7 @@ body {
html {
height: 100%;
margin-bottom: 1px;
-}
+}
#container {
width: 80%;
text-align: left;
@@ -150,4 +150,143 @@ div.node {
margin: 10px;
padding: 5px;
border: 1px solid #999;
-} \ No newline at end of file
+}
+*/
+
+pre.twilight .DiffInserted {
+ background-color: #253B22;
+ color: #F8F8F8;
+}
+pre.twilight .DiffHeader {
+ background-color: #0E2231;
+ color: #F8F8F8;
+ font-style: italic;
+}
+pre.twilight .CssPropertyValue {
+ color: #F9EE98;
+}
+pre.twilight .CCCPreprocessorDirective {
+ color: #AFC4DB;
+}
+pre.twilight .Constant {
+ color: #CF6A4C;
+}
+pre.twilight .DiffChanged {
+ background-color: #4A410D;
+ color: #F8F8F8;
+}
+pre.twilight .EmbeddedSource {
+ background-color: #A3A6AD;
+}
+pre.twilight .Support {
+ color: #9B859D;
+}
+pre.twilight .MarkupList {
+ color: #F9EE98;
+}
+pre.twilight .CssConstructorArgument {
+ color: #8F9D6A;
+}
+pre.twilight .Storage {
+ color: #F9EE98;
+}
+pre.twilight .line-numbers {
+ background-color: #DDF0FF;
+ color: #000000;
+}
+pre.twilight .CssClass {
+ color: #9B703F;
+}
+pre.twilight .StringConstant {
+ color: #DDF2A4;
+}
+pre.twilight .CssAtRule {
+ color: #8693A5;
+}
+pre.twilight .MetaTagInline {
+ color: #E0C589;
+}
+pre.twilight .MarkupHeading {
+ color: #CF6A4C;
+}
+pre.twilight .CssTagName {
+ color: #CDA869;
+}
+pre.twilight .SupportConstant {
+ color: #CF6A4C;
+}
+pre.twilight .DiffDeleted {
+ background-color: #420E09;
+ color: #F8F8F8;
+}
+pre.twilight .CCCPreprocessorLine {
+ color: #8996A8;
+}
+pre.twilight .StringRegexpSpecial {
+ color: #CF7D34;
+}
+pre.twilight .EmbeddedSourceBright {
+ background-color: #9C9EA4;
+}
+pre.twilight .InvalidIllegal {
+ background-color: #241A24;
+ color: #F8F8F8;
+}
+pre.twilight .SupportFunction {
+ color: #DAD085;
+}
+pre.twilight .CssAdditionalConstants {
+ color: #CA7840;
+}
+pre.twilight .MetaTagAll {
+ color: #AC885B;
+}
+pre.twilight .StringRegexp {
+ color: #E9C062;
+}
+pre.twilight .StringEmbeddedSource {
+ color: #DAEFA3;
+}
+pre.twilight .EntityInheritedClass {
+ color: #9B5C2E;
+ font-style: italic;
+}
+pre.twilight .CssId {
+ color: #8B98AB;
+}
+pre.twilight .CssPseudoClass {
+ color: #8F9D6A;
+}
+pre.twilight .StringVariable {
+ color: #8A9A95;
+}
+pre.twilight .String {
+ color: #8F9D6A;
+}
+pre.twilight .Keyword {
+ color: #CDA869;
+}
+pre.twilight {
+ background-color: #141414;
+ color: #F8F8F8;
+}
+pre.twilight .CssPropertyName {
+ color: #C5AF75;
+}
+pre.twilight .DoctypeXmlProcessing {
+ color: #494949;
+}
+pre.twilight .InvalidDeprecated {
+ color: #D2A8A1;
+ font-style: italic;
+}
+pre.twilight .Variable {
+ color: #7587A6;
+}
+pre.twilight .Entity {
+ color: #9B703F;
+}
+pre.twilight .Comment {
+ color: #5F5A60;
+ font-style: italic;
+}
diff --git a/lib/chef_server/views/cookbooks/_attribute_file.html.haml b/lib/chef_server/views/cookbooks/_attribute_file.html.haml
new file mode 100644
index 0000000000..cfe773f3d1
--- /dev/null
+++ b/lib/chef_server/views/cookbooks/_attribute_file.html.haml
@@ -0,0 +1,2 @@
+%h3= name
+= Uv.parse(contents, "xhtml", "ruby", true, "twilight") \ No newline at end of file
diff --git a/lib/chef_server/views/cookbooks/attribute_files.html.haml b/lib/chef_server/views/cookbooks/attribute_files.html.haml
new file mode 100644
index 0000000000..56fdcf7bee
--- /dev/null
+++ b/lib/chef_server/views/cookbooks/attribute_files.html.haml
@@ -0,0 +1,4 @@
+%h1 All Attribute Files
+- @attribute_files.each do |af_hash|
+ %h2= "#{af_hash[:cookbook]}"
+ = partial(:attribute_file, :name => af_hash[:name], :contents => af_hash[:contents]) \ No newline at end of file
diff --git a/lib/chef_server/views/cookbooks/index.html.haml b/lib/chef_server/views/cookbooks/index.html.haml
new file mode 100644
index 0000000000..008f74765c
--- /dev/null
+++ b/lib/chef_server/views/cookbooks/index.html.haml
@@ -0,0 +1,7 @@
+%h1 Cookbooks
+- @cl.each do |cookbook|
+ .index
+ %table
+ %tr
+ %td
+ %a{ :href => url(:cookbook, { :id => cookbook.name }) }= cookbook.name
diff --git a/lib/chef_server/views/cookbooks/show.html.haml b/lib/chef_server/views/cookbooks/show.html.haml
new file mode 100644
index 0000000000..58175c298c
--- /dev/null
+++ b/lib/chef_server/views/cookbooks/show.html.haml
@@ -0,0 +1,18 @@
+%h1= "Cookbook #{h @cookbook.name}"
+.cookbook
+- if @cookbook.attribute_files.length > 0
+ - @cookbook.attribute_files.each do |af|
+ = partial(:attribute_file, :name => File.basename(af), :contents => File.read(af))
+
+- if @cookbook.definition_files.length > 0
+ - @cookbook.definition_files.each do |df|
+ %h2 Definition Files
+ %h3= File.basename(df)
+ = Uv.parse(File.read(df), "xhtml", "ruby", true, "twilight")
+
+- if @cookbook.recipe_files.length > 0
+ - @cookbook.recipe_files.each do |rf|
+ %h2 Recipe Files
+ %h3= File.basename(rf)
+ = Uv.parse(File.read(rf), "xhtml", "ruby", true, "twilight")
+ \ No newline at end of file
diff --git a/lib/chef_server/views/layout/application.html.haml b/lib/chef_server/views/layout/application.html.haml
index 4e4d235e78..8e84c09006 100644
--- a/lib/chef_server/views/layout/application.html.haml
+++ b/lib/chef_server/views/layout/application.html.haml
@@ -11,6 +11,8 @@
|
%a{:href => url(:nodes) } Nodes
|
+ %a{:href => url(:cookbooks) } Cookbooks
+ |
%a{:href => url(:registrations)} Registrations
- if session[:openid]
|
diff --git a/lib/chef_server/views/nodes/_action.html.haml b/lib/chef_server/views/nodes/_action.html.haml
index a809a6d70c..8adb39338d 100644
--- a/lib/chef_server/views/nodes/_action.html.haml
+++ b/lib/chef_server/views/nodes/_action.html.haml
@@ -10,4 +10,4 @@
%td
- resource_hash[rk].each do |resource|
= partial(:resource, :resource => resource)
- \ No newline at end of file
+ \ No newline at end of file
diff --git a/spec/lib/chef/resource/cat.rb b/spec/lib/chef/resource/cat.rb
index a0456d6b45..e651c44512 100644
--- a/spec/lib/chef/resource/cat.rb
+++ b/spec/lib/chef/resource/cat.rb
@@ -23,9 +23,9 @@ class Chef
attr_accessor :action
- def initialize(name, collection=nil)
+ def initialize(name, collection=nil, node=nil)
@resource_name = :cat
- super(name, collection)
+ super(name, collection, node)
@action = "sell"
end
diff --git a/spec/lib/chef/resource/zen_master.rb b/spec/lib/chef/resource/zen_master.rb
index 91ae87b246..8b4225fbd4 100644
--- a/spec/lib/chef/resource/zen_master.rb
+++ b/spec/lib/chef/resource/zen_master.rb
@@ -22,9 +22,9 @@ class Chef
class ZenMaster < Chef::Resource
attr_reader :peace
- def initialize(name, collection=nil)
+ def initialize(name, collection=nil, node=nil)
@resource_name = :zen_master
- super(name, collection)
+ super(name, collection, node)
end
def peace(tf)
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 05dbd247ae..9120b2876c 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -20,4 +20,4 @@
require File.join(File.dirname(__FILE__), "..", "lib", "chef")
Dir[File.join(File.dirname(__FILE__), 'lib', '**', '*.rb')].sort.each { |lib| require lib }
-Chef::Config.log_level(:fatal)
+Chef::Config.log_level(:error)
diff --git a/spec/unit/log/formatter_spec.rb b/spec/unit/log/formatter_spec.rb
index 6651feab2e..899ae724a8 100644
--- a/spec/unit/log/formatter_spec.rb
+++ b/spec/unit/log/formatter_spec.rb
@@ -41,7 +41,7 @@ describe Chef::Log::Formatter do
it "should return a formatted string with call" do
time = Time.new
- @formatter.call("monkey", Time.new, "test", "mos def").should == "[#{time.rfc2822}] monkey: mos def\n"
+ @formatter.call("monkey", time, "test", "mos def").should == "[#{time.rfc2822}] monkey: mos def\n"
end
it "should allow you to turn the time on and off in the output" do
diff --git a/spec/unit/resource/template_spec.rb b/spec/unit/resource/template_spec.rb
new file mode 100644
index 0000000000..4bf1f1ace9
--- /dev/null
+++ b/spec/unit/resource/template_spec.rb
@@ -0,0 +1,44 @@
+# 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.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
+
+describe Chef::Resource::Template do
+
+ before(:each) do
+ @resource = Chef::Resource::Template.new("fakey_fakerton")
+ end
+
+ it "should create a new Chef::Resource::Template" do
+ @resource.should be_a_kind_of(Chef::Resource)
+ @resource.should be_a_kind_of(Chef::Resource::File)
+ @resource.should be_a_kind_of(Chef::Resource::Template)
+ end
+
+ it "should accept a string for the template name" do
+ @resource.template "something"
+ @resource.template.should eql("something")
+ end
+
+ it "should accept a hash for the variable list" do
+ @resource.variables({ :reluctance => :awkward })
+ @resource.variables.should == { :reluctance => :awkward }
+ end
+
+end \ No newline at end of file
diff --git a/spec/unit/rest_spec.rb b/spec/unit/rest_spec.rb
index 96238a6c2c..fea42da6bf 100644
--- a/spec/unit/rest_spec.rb
+++ b/spec/unit/rest_spec.rb
@@ -112,6 +112,8 @@ describe Chef::REST, "run_request method" do
@data_mock.stub!(:to_json).and_return('{ "one": "two" }')
@request_mock = mock("Request", :null_object => true)
@request_mock.stub!(:body=).and_return(true)
+ @request_mock.stub!(:method).and_return(true)
+ @request_mock.stub!(:path).and_return(true)
@http_mock.stub!(:request).and_return(@http_response_mock)
end
@@ -143,8 +145,8 @@ describe Chef::REST, "run_request method" do
it "should build a new HTTP GET request" do
Net::HTTP::Get.should_receive(:new).with("/?foo=bar",
- { 'Accept' => 'application/json', "Content-Type" => 'application/json' }
- ).and_return(true)
+ { 'Accept' => 'application/json' }
+ ).and_return(@request_mock)
do_run_request
end
@@ -164,8 +166,8 @@ describe Chef::REST, "run_request method" do
it "should build a new HTTP DELETE request" do
Net::HTTP::Delete.should_receive(:new).with("/?foo=bar",
- { 'Accept' => 'application/json', "Content-Type" => 'application/json' }
- ).and_return(true)
+ { 'Accept' => 'application/json' }
+ ).and_return(@request_mock)
do_run_request(:DELETE)
end
@@ -191,7 +193,7 @@ describe Chef::REST, "run_request method" do
it "should call run_request again on a Redirect response" do
@http_response_mock.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(false)
@http_response_mock.stub!(:kind_of?).with(Net::HTTPRedirection).and_return(true)
- @http_response_mock.stub!(:[]).with('location').and_return(@url_mock)
+ @http_response_mock.stub!(:[]).with('location').and_return(@url_mock.path)
lambda { do_run_request(method=:GET, data=false, limit=1) }.should raise_error(ArgumentError)
end
diff --git a/spec/unit/search_index_spec.rb b/spec/unit/search_index_spec.rb
index 93b16364e5..b04ff12db3 100644
--- a/spec/unit/search_index_spec.rb
+++ b/spec/unit/search_index_spec.rb
@@ -39,7 +39,7 @@ describe Chef::SearchIndex, "create_index_object method" do
@mf = mock("Ferret::Index::Index", :null_object => true)
@fakeobj = mock("ToIndex", :null_object => true)
@the_pigeon = { :index_name => "bird", :id => "pigeon" }
- @fakeobj.stub!(:responds_to?).with(:to_index).and_return(true)
+ @fakeobj.stub!(:respond_to?).with(:to_index).and_return(true)
@fakeobj.stub!(:to_index).and_return(@the_pigeon)
Ferret::Index::Index.stub!(:new).and_return(@mf)
end
@@ -50,13 +50,13 @@ describe Chef::SearchIndex, "create_index_object method" do
end
it "should call to_index if the passed object responds to it" do
- @fakeobj.should_receive(:responds_to?).with(:to_index).and_return(true)
+ @fakeobj.should_receive(:respond_to?).with(:to_index).and_return(true)
@fakeobj.should_receive(:to_index).and_return(@the_pigeon)
do_create_index_object
end
it "should use a hash if the passed argument does not have to_index (but is a hash)" do
- @fakeobj.stub!(:responds_to?).with(:to_index).and_return(false)
+ @fakeobj.stub!(:respond_to?).with(:to_index).and_return(false)
@fakeobj.should_receive(:kind_of?).with(Hash).and_return(true)
do_create_index_object
end
@@ -77,7 +77,7 @@ describe Chef::SearchIndex, "add method" do
@mf = mock("Ferret::Index::Index", :null_object => true)
@fakeobj = mock("ToIndex", :null_object => true)
@the_pigeon = { :index_name => "bird", :id => "pigeon" }
- @fakeobj.stub!(:responds_to?).with(:to_index).and_return(true)
+ @fakeobj.stub!(:respond_to?).with(:to_index).and_return(true)
@fakeobj.stub!(:to_index).and_return(@the_pigeon)
Ferret::Index::Index.stub!(:new).and_return(@mf)
end
@@ -98,7 +98,7 @@ describe Chef::SearchIndex, "delete method" do
@mf = mock("Ferret::Index::Index", :null_object => true)
@fakeobj = mock("ToIndex", :null_object => true)
@the_pigeon = { :index_name => "bird", :id => "pigeon" }
- @fakeobj.stub!(:responds_to?).with(:to_index).and_return(true)
+ @fakeobj.stub!(:respond_to?).with(:to_index).and_return(true)
@fakeobj.stub!(:to_index).and_return(@the_pigeon)
Ferret::Index::Index.stub!(:new).and_return(@mf)
end
@@ -109,7 +109,7 @@ describe Chef::SearchIndex, "delete method" do
end
it "should delete the resulting hash to the index" do
- @mf.should_receive(:delete).with({ :id => @the_pigeon[:id] })
+ @mf.should_receive(:delete).with(@the_pigeon[:id])
do_delete(@fakeobj)
end
end
diff --git a/spec/unit/search.rb b/spec/unit/search_spec.rb
index 702997a565..900cd97a75 100644
--- a/spec/unit/search.rb
+++ b/spec/unit/search_spec.rb
@@ -58,19 +58,19 @@ describe Chef::Search, "search method" do
cs.search(:node, "tag:monkey")
end
- it "should call search_each if a block is given" do
- cp = lambda { |n| "noting to do here" }
- @mf.should_receive(:search_each).with("index_name:node AND (tag:monkey)", &cp)
+ it "should call search_each with the custom block if a block is given" do
+ cp = lambda { |n,u| "noting to do here" }
+ @mf.should_receive(:search_each).with("index_name:node AND (tag:monkey)", { :limit => :all }, &cp)
do_search(:node, "tag:monkey", &cp)
end
- it "should call search if a block is not given" do
- @mf.should_receive(:search).with("index_name:node AND (tag:monkey)")
+ it "should call search_each if a block is not given" do
+ @mf.should_receive(:search_each).with("index_name:node AND (tag:monkey)", {:limit => :all})
do_search(:node, "tag:monkey")
end
it "should return the search results" do
- @mf.should_receive(:search).with("index_name:node AND (tag:monkey)").and_return(true)
- do_search(:node, "tag:monkey").should eql(true)
+ @mf.should_receive(:search_each).with("index_name:node AND (tag:monkey)", :limit => :all).and_return(true)
+ do_search(:node, "tag:monkey").should eql([])
end
end \ No newline at end of file