chef 0.8.16 → 0.9.0.a3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of chef might be problematic. Click here for more details.
- data/bin/shef +1 -0
- data/distro/common/man/man1/chef-server-webui.1 +106 -0
- data/distro/common/man/man1/chef-server.1 +0 -1
- data/distro/common/man/man1/chef-solr-indexer.1 +55 -0
- data/distro/common/man/man1/chef-solr.1 +55 -0
- data/distro/common/man/man8/chef-client.8 +4 -2
- data/distro/common/man/man8/chef-solo.8 +1 -2
- data/distro/common/man/man8/chef-solr-rebuild.8 +37 -0
- data/distro/common/man/man8/knife.8 +668 -266
- data/distro/common/man/man8/shef.8 +45 -0
- data/distro/common/markdown/README +3 -0
- data/distro/common/markdown/knife.mkd +520 -0
- data/distro/debian/etc/default/chef-client +4 -0
- data/distro/debian/etc/default/chef-server +6 -0
- data/distro/debian/etc/default/chef-server-webui +6 -0
- data/distro/debian/etc/default/chef-solr +4 -0
- data/distro/debian/etc/default/chef-solr-indexer +4 -0
- data/distro/debian/etc/init.d/chef-client +41 -41
- data/distro/debian/etc/init.d/chef-server +10 -10
- data/distro/debian/etc/init.d/chef-server-webui +121 -0
- data/distro/debian/etc/init.d/chef-solr +177 -0
- data/distro/debian/etc/init.d/chef-solr-indexer +176 -0
- data/distro/redhat/etc/init.d/chef-client +76 -48
- data/distro/redhat/etc/init.d/chef-server +85 -51
- data/distro/redhat/etc/init.d/chef-server-webui +85 -51
- data/distro/redhat/etc/init.d/chef-solr +77 -49
- data/distro/redhat/etc/init.d/chef-solr-indexer +77 -48
- data/distro/redhat/etc/logrotate.d/chef-client +8 -0
- data/distro/redhat/etc/logrotate.d/chef-server +8 -0
- data/distro/redhat/etc/logrotate.d/chef-server-webui +8 -0
- data/distro/redhat/etc/logrotate.d/chef-solr +8 -0
- data/distro/redhat/etc/logrotate.d/chef-solr-indexer +8 -0
- data/distro/redhat/etc/sysconfig/chef-client +9 -4
- data/distro/redhat/etc/sysconfig/chef-server +10 -6
- data/distro/redhat/etc/sysconfig/chef-server-webui +10 -6
- data/distro/redhat/etc/sysconfig/chef-solr +3 -4
- data/distro/redhat/etc/sysconfig/chef-solr-indexer +3 -3
- data/lib/chef.rb +16 -5
- data/lib/chef/application/knife.rb +2 -2
- data/lib/chef/application/solo.rb +1 -7
- data/lib/chef/cache/checksum.rb +12 -5
- data/lib/chef/cache/file_cache_by_checksum.rb +52 -0
- data/lib/chef/checksum.rb +115 -0
- data/lib/chef/client.rb +193 -185
- data/lib/chef/config.rb +9 -1
- data/lib/chef/cookbook/cookbook_collection.rb +43 -0
- data/lib/chef/cookbook/file_system_file_vendor.rb +53 -0
- data/lib/chef/cookbook/file_vendor.rb +47 -0
- data/lib/chef/cookbook/metadata.rb +34 -35
- data/lib/chef/cookbook/metadata/version.rb +1 -1
- data/lib/chef/cookbook_loader.rb +70 -45
- data/lib/chef/cookbook_version.rb +760 -0
- data/lib/chef/couchdb.rb +8 -5
- data/lib/chef/data_bag_item.rb +5 -5
- data/lib/chef/exceptions.rb +10 -0
- data/lib/chef/file_access_control.rb +134 -0
- data/lib/chef/handler.rb +62 -0
- data/lib/chef/handler/json_file.rb +47 -0
- data/lib/chef/knife.rb +14 -2
- data/lib/chef/knife/bootstrap.rb +126 -0
- data/lib/chef/knife/cookbook_bulk_delete.rb +1 -1
- data/lib/chef/knife/cookbook_delete.rb +4 -4
- data/lib/chef/knife/cookbook_download.rb +57 -26
- data/lib/chef/knife/cookbook_metadata.rb +2 -2
- data/lib/chef/knife/cookbook_show.rb +30 -11
- data/lib/chef/knife/cookbook_upload.rb +113 -86
- data/lib/chef/knife/ec2_server_create.rb +146 -0
- data/lib/chef/knife/ec2_server_delete.rb +84 -0
- data/lib/chef/knife/ec2_server_list.rb +82 -0
- data/lib/chef/knife/status.rb +51 -0
- data/lib/chef/mixin/language_include_attribute.rb +16 -11
- data/lib/chef/mixin/language_include_recipe.rb +15 -16
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +17 -20
- data/lib/chef/mixin/shell_out.rb +38 -0
- data/lib/chef/mixins.rb +1 -1
- data/lib/chef/node.rb +190 -63
- data/lib/chef/node/attribute.rb +92 -78
- data/lib/chef/platform.rb +24 -4
- data/lib/chef/provider.rb +28 -10
- data/lib/chef/provider/breakpoint.rb +2 -2
- data/lib/chef/provider/cookbook_file.rb +96 -0
- data/lib/chef/provider/cron.rb +2 -2
- data/lib/chef/provider/deploy.rb +12 -10
- data/lib/chef/provider/env.rb +152 -0
- data/lib/chef/provider/env/windows.rb +75 -0
- data/lib/chef/provider/file.rb +10 -14
- data/lib/chef/provider/group.rb +15 -2
- data/lib/chef/provider/group/dscl.rb +17 -25
- data/lib/chef/provider/group/gpasswd.rb +6 -3
- data/lib/chef/provider/group/pw.rb +3 -7
- data/lib/chef/provider/group/windows.rb +79 -0
- data/lib/chef/provider/link.rb +4 -5
- data/lib/chef/provider/mdadm.rb +25 -18
- data/lib/chef/provider/mount/mount.rb +28 -27
- data/lib/chef/provider/package.rb +35 -35
- data/lib/chef/provider/package/dpkg.rb +13 -10
- data/lib/chef/provider/package/easy_install.rb +6 -6
- data/lib/chef/provider/package/freebsd.rb +17 -51
- data/lib/chef/provider/package/rpm.rb +1 -1
- data/lib/chef/provider/package/rubygems.rb +391 -74
- data/lib/chef/provider/package/yum.rb +2 -2
- data/lib/chef/provider/package/zypper.rb +2 -1
- data/lib/chef/provider/remote_directory.rb +60 -83
- data/lib/chef/provider/remote_file.rb +17 -66
- data/lib/chef/provider/script.rb +20 -9
- data/lib/chef/provider/service.rb +23 -30
- data/lib/chef/provider/service/arch.rb +3 -3
- data/lib/chef/provider/service/debian.rb +22 -17
- data/lib/chef/provider/service/freebsd.rb +4 -4
- data/lib/chef/provider/service/init.rb +2 -2
- data/lib/chef/provider/service/redhat.rb +14 -16
- data/lib/chef/provider/service/simple.rb +7 -3
- data/lib/chef/provider/service/solaris.rb +85 -0
- data/lib/chef/provider/service/upstart.rb +12 -7
- data/lib/chef/provider/service/windows.rb +2 -2
- data/lib/chef/provider/template.rb +133 -118
- data/lib/chef/provider/user.rb +34 -17
- data/lib/chef/provider/user/dscl.rb +117 -114
- data/lib/chef/provider/user/windows.rb +124 -0
- data/lib/chef/providers.rb +7 -0
- data/lib/chef/recipe.rb +39 -20
- data/lib/chef/resource.rb +47 -52
- data/lib/chef/resource/apt_package.rb +4 -4
- data/lib/chef/resource/bash.rb +4 -4
- data/lib/chef/resource/cookbook_file.rb +45 -0
- data/lib/chef/resource/cron.rb +3 -3
- data/lib/chef/resource/csh.rb +4 -4
- data/lib/chef/resource/deploy.rb +3 -3
- data/lib/chef/resource/directory.rb +4 -4
- data/lib/chef/resource/dpkg_package.rb +4 -4
- data/lib/chef/resource/easy_install_package.rb +3 -3
- data/lib/chef/resource/env.rb +58 -0
- data/lib/chef/resource/erl_call.rb +3 -3
- data/lib/chef/resource/execute.rb +3 -3
- data/lib/chef/resource/file.rb +3 -3
- data/lib/chef/resource/freebsd_package.rb +3 -3
- data/lib/chef/resource/gem_package.rb +17 -9
- data/lib/chef/resource/git.rb +3 -3
- data/lib/chef/resource/group.rb +3 -3
- data/lib/chef/resource/http_request.rb +4 -4
- data/lib/chef/resource/ifconfig.rb +3 -3
- data/lib/chef/resource/link.rb +3 -3
- data/lib/chef/resource/log.rb +2 -2
- data/lib/chef/resource/macports_package.rb +2 -2
- data/lib/chef/resource/mdadm.rb +3 -3
- data/lib/chef/resource/mount.rb +2 -2
- data/lib/chef/resource/package.rb +4 -4
- data/lib/chef/resource/pacman_package.rb +4 -4
- data/lib/chef/resource/perl.rb +4 -4
- data/lib/chef/resource/portage_package.rb +4 -4
- data/lib/chef/resource/python.rb +4 -4
- data/lib/chef/resource/remote_directory.rb +3 -3
- data/lib/chef/resource/remote_file.rb +26 -3
- data/lib/chef/resource/route.rb +3 -3
- data/lib/chef/resource/ruby.rb +3 -3
- data/lib/chef/resource/ruby_block.rb +3 -2
- data/lib/chef/resource/scm.rb +7 -5
- data/lib/chef/resource/script.rb +4 -4
- data/lib/chef/resource/service.rb +3 -3
- data/lib/chef/resource/subversion.rb +4 -2
- data/lib/chef/resource/template.rb +3 -3
- data/lib/chef/resource/user.rb +3 -3
- data/lib/chef/resource/yum_package.rb +3 -3
- data/lib/chef/resource_collection.rb +9 -5
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/rest.rb +4 -0
- data/lib/chef/role.rb +2 -0
- data/lib/chef/run_context.rb +108 -0
- data/lib/chef/run_list.rb +75 -98
- data/lib/chef/run_list/run_list_expansion.rb +156 -0
- data/lib/chef/run_list/run_list_item.rb +71 -0
- data/lib/chef/runner.rb +58 -61
- data/lib/chef/sandbox.rb +147 -0
- data/lib/chef/shef.rb +4 -3
- data/lib/chef/shef/ext.rb +12 -4
- data/lib/chef/shef/shef_session.rb +27 -23
- data/lib/chef/shell_out.rb +375 -0
- data/lib/chef/util/windows.rb +56 -0
- data/lib/chef/util/windows/net_group.rb +101 -0
- data/lib/chef/util/windows/net_user.rb +198 -0
- data/lib/chef/version.rb +20 -0
- metadata +112 -22
- data/lib/chef/compile.rb +0 -158
- data/lib/chef/cookbook.rb +0 -201
- data/lib/chef/mixin/generate_url.rb +0 -58
@@ -1,10 +1,15 @@
|
|
1
1
|
# Configuration file for the chef-client service
|
2
2
|
|
3
|
-
#PIDFILE=/var/run/chef/client.pid
|
4
3
|
#CONFIG=/etc/chef/client.rb
|
5
|
-
#
|
6
|
-
#
|
4
|
+
#PIDFILE=/var/run/chef/client.pid
|
5
|
+
#LOCKFILE=/var/lock/subsys/chef-client
|
6
|
+
#LOGFILE=/var/log/chef/client.log
|
7
|
+
# Sleep interval between runs.
|
8
|
+
# This value is in seconds.
|
7
9
|
#INTERVAL=1800
|
10
|
+
# Maximum amount of random delay before starting a run. Prevents every client
|
11
|
+
# from contacting the server at the exact same time.
|
12
|
+
# This value is in seconds.
|
8
13
|
#SPLAY=20
|
9
|
-
#
|
14
|
+
# Any additional chef-client options.
|
10
15
|
#OPTIONS=
|
@@ -1,10 +1,14 @@
|
|
1
1
|
# Configuration file for the chef-server service
|
2
2
|
|
3
|
-
#CHILDPIDFILES=/var/run/chef/server.%s.pid
|
4
|
-
#PIDFILE=/var/run/chef/server.pid
|
5
3
|
#CONFIG=/etc/chef/server.rb
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
4
|
+
#PIDFILE=/var/run/chef/server.pid
|
5
|
+
#LOCKFILE=/var/lock/subsys/chef-server
|
6
|
+
#LOGFILE=/var/log/chef/server.log
|
7
|
+
#PORT=4000
|
8
|
+
#ENVIRONMENT=production
|
9
|
+
#ADAPTER=thin
|
10
|
+
#CHILDPIDFILES=/var/run/chef/server.%s.pid
|
11
|
+
#SERVER_USER=chef
|
12
|
+
#SERVER_GROUP=chef
|
13
|
+
# Any additional chef-server options.
|
10
14
|
#OPTIONS=
|
@@ -1,10 +1,14 @@
|
|
1
1
|
# Configuration file for the chef-server-webui service
|
2
2
|
|
3
|
-
#
|
3
|
+
#CONFIG=/etc/chef/webui.rb
|
4
4
|
#PIDFILE=/var/run/chef/server-webui.pid
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
5
|
+
#LOCKFILE=/var/lock/subsys/chef-server-webui
|
6
|
+
#LOGFILE=/var/log/chef/server-webui.log
|
7
|
+
#PORT=4040
|
8
|
+
#ENVIRONMENT=production
|
9
|
+
#ADAPTER=thin
|
10
|
+
#CHILDPIDFILES=/var/run/chef/server-webui.%s.pid
|
11
|
+
#SERVER_USER=chef
|
12
|
+
#SERVER_GROUP=chef
|
13
|
+
# Any additional chef-server-webui options.
|
10
14
|
#OPTIONS=
|
@@ -1,9 +1,8 @@
|
|
1
1
|
# Configuration file for the chef-solr service
|
2
2
|
|
3
|
+
#CONFIG=/etc/chef/solr.rb
|
3
4
|
#PIDFILE=/var/run/chef/solr.pid
|
4
|
-
#
|
5
|
-
#CHEF_USER=chef
|
6
|
-
#CHEF_GROUP=chef
|
5
|
+
#LOCKFILE=/var/lock/subsys/chef-solr
|
7
6
|
#LOGFILE=/var/log/chef/solr.log
|
8
|
-
#
|
7
|
+
# Options for Java. Need to start with -j followed by options.
|
9
8
|
#OPTIONS="-j "
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Configuration file for the chef-solr-indexer service
|
2
2
|
|
3
3
|
#PIDFILE=/var/run/chef/solr-indexer.pid
|
4
|
-
#CONFIG=/etc/chef/
|
5
|
-
#CHEF_USER=chef
|
6
|
-
#CHEF_GROUP=chef
|
4
|
+
#CONFIG=/etc/chef/solr-indexer.rb
|
7
5
|
#LOGFILE=/var/log/chef/solr-indexer.log
|
6
|
+
# Any additional chef-solr-indexer options.
|
7
|
+
#OPTIONS=
|
data/lib/chef.rb
CHANGED
@@ -16,22 +16,22 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
+
require 'chef/version'
|
20
|
+
|
19
21
|
require 'extlib'
|
20
22
|
require 'chef/exceptions'
|
21
23
|
require 'chef/log'
|
22
24
|
require 'chef/config'
|
23
25
|
require 'chef/providers'
|
24
26
|
require 'chef/resources'
|
27
|
+
require 'chef/shell_out'
|
25
28
|
|
26
|
-
require 'chef/compile'
|
27
29
|
require 'chef/daemon'
|
28
|
-
require 'chef/runner'
|
29
30
|
require 'chef/webui_user'
|
30
31
|
require 'chef/openid_registration'
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
33
|
+
require 'chef/handler'
|
34
|
+
require 'chef/handler/json_file'
|
35
35
|
|
36
36
|
# Adds a Dir.glob to Ruby 1.8.5, for compat
|
37
37
|
if RUBY_VERSION < "1.8.6" || RUBY_PLATFORM =~ /mswin|mingw32|windows/
|
@@ -51,3 +51,14 @@ if RUBY_VERSION < "1.8.6" || RUBY_PLATFORM =~ /mswin|mingw32|windows/
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
54
|
+
|
55
|
+
|
56
|
+
# On ruby 1.9, Strings are aware of multibyte characters, so #size and length
|
57
|
+
# give the actual number of characters. In Chef::REST, we need the bytesize
|
58
|
+
# so we can correctly set the Content-Length headers, but ruby 1.8.6 and lower
|
59
|
+
# don't define String#bytesize. Monkey patching time!
|
60
|
+
class String
|
61
|
+
unless method_defined?(:bytesize)
|
62
|
+
alias :bytesize :size
|
63
|
+
end
|
64
|
+
end
|
@@ -36,7 +36,6 @@ class Chef::Application::Knife < Chef::Application
|
|
36
36
|
option :config_file,
|
37
37
|
:short => "-c CONFIG",
|
38
38
|
:long => "--config CONFIG",
|
39
|
-
:default => File.join(ENV['HOME'], '.chef', 'knife.rb'),
|
40
39
|
:description => "The configuration file to use"
|
41
40
|
|
42
41
|
option :log_level,
|
@@ -96,7 +95,7 @@ class Chef::Application::Knife < Chef::Application
|
|
96
95
|
:description => "Show the data after a destructive operation"
|
97
96
|
|
98
97
|
option :format,
|
99
|
-
:short => "-
|
98
|
+
:short => "-F FORMAT",
|
100
99
|
:long => "--format FORMAT",
|
101
100
|
:description => "Which format to use for output",
|
102
101
|
:default => "json"
|
@@ -114,6 +113,7 @@ class Chef::Application::Knife < Chef::Application
|
|
114
113
|
validate_and_parse_options
|
115
114
|
knife = Chef::Knife.find_command(ARGV, self.class.options)
|
116
115
|
knife.run
|
116
|
+
exit 0
|
117
117
|
end
|
118
118
|
|
119
119
|
private
|
@@ -95,12 +95,6 @@ class Chef::Application::Solo < Chef::Application
|
|
95
95
|
:description => "The splay time for running at intervals, in seconds",
|
96
96
|
:proc => lambda { |s| s.to_i }
|
97
97
|
|
98
|
-
option :json_attribs,
|
99
|
-
:short => "-j JSON_ATTRIBS",
|
100
|
-
:long => "--json-attributes JSON_ATTRIBS",
|
101
|
-
:description => "Load attributes from a JSON file or URL",
|
102
|
-
:proc => nil
|
103
|
-
|
104
98
|
option :recipe_url,
|
105
99
|
:short => "-r RECIPE_URL",
|
106
100
|
:long => "--recipe-url RECIPE_URL",
|
@@ -195,7 +189,7 @@ class Chef::Application::Solo < Chef::Application
|
|
195
189
|
sleep splay
|
196
190
|
end
|
197
191
|
|
198
|
-
@chef_solo.
|
192
|
+
@chef_solo.run
|
199
193
|
|
200
194
|
if Chef::Config[:interval]
|
201
195
|
Chef::Log.debug("Sleeping for #{Chef::Config[:interval]} seconds")
|
data/lib/chef/cache/checksum.rb
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
#
|
20
20
|
|
21
21
|
require 'chef/cache'
|
22
|
+
require 'digest/md5'
|
22
23
|
|
23
24
|
class Chef
|
24
25
|
class Cache
|
@@ -44,7 +45,7 @@ class Chef
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def generate_checksum(key, file, fstat)
|
47
|
-
checksum = checksum_file(file)
|
48
|
+
checksum = checksum_file(file, Digest::SHA256.new)
|
48
49
|
moneta.store(key, {"mtime" => fstat.mtime.to_f, "checksum" => checksum})
|
49
50
|
checksum
|
50
51
|
end
|
@@ -52,19 +53,25 @@ class Chef
|
|
52
53
|
def generate_key(file, group="chef")
|
53
54
|
"#{group}-file-#{file.gsub(/(#{File::SEPARATOR}|\.)/, '-')}"
|
54
55
|
end
|
55
|
-
|
56
|
+
|
57
|
+
def self.generate_md5_checksum_for_file(*args)
|
58
|
+
instance.generate_md5_checksum_for_file(*args)
|
59
|
+
end
|
60
|
+
|
61
|
+
def generate_md5_checksum_for_file(file)
|
62
|
+
checksum_file(file, Digest::MD5.new)
|
63
|
+
end
|
64
|
+
|
56
65
|
private
|
57
66
|
|
58
67
|
def file_unchanged?(cached, fstat)
|
59
68
|
cached["mtime"].to_f == fstat.mtime.to_f
|
60
69
|
end
|
61
70
|
|
62
|
-
def checksum_file(file)
|
63
|
-
digest = Digest::SHA256.new
|
71
|
+
def checksum_file(file, digest)
|
64
72
|
IO.foreach(file) {|line| digest.update(line) }
|
65
73
|
digest.hexdigest
|
66
74
|
end
|
67
|
-
|
68
75
|
end
|
69
76
|
end
|
70
77
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Tim Hinderliter (<tim@opscode.com>)
|
3
|
+
# Author:: Christopher Walters (<cw@opscode.com>)
|
4
|
+
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
class Chef
|
21
|
+
class Cache
|
22
|
+
class FileCacheByChecksum
|
23
|
+
attr_reader :basedir
|
24
|
+
|
25
|
+
def initialize(basedir = Chef::Config[:file_cache_path])
|
26
|
+
@basedir = basedir
|
27
|
+
end
|
28
|
+
|
29
|
+
# returns path
|
30
|
+
def get_path(checksum)
|
31
|
+
path = checksum_path(checksum)
|
32
|
+
|
33
|
+
File.exists?(path) ? path : nil
|
34
|
+
end
|
35
|
+
|
36
|
+
# path = path to tempfile as input
|
37
|
+
# returns destination path
|
38
|
+
def put(checksum, src_path)
|
39
|
+
dest_path = checksum_path(checksum)
|
40
|
+
FileUtils.mkdir_p(File.dirname(dest_path))
|
41
|
+
|
42
|
+
FileUtils.cp(src_path, dest_path)
|
43
|
+
|
44
|
+
dest_path
|
45
|
+
end
|
46
|
+
|
47
|
+
def checksum_path(checksum)
|
48
|
+
File.join(basedir, checksum[0..1], checksum)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Tim Hinderliter (<tim@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require 'chef/log'
|
19
|
+
require 'uuidtools'
|
20
|
+
|
21
|
+
|
22
|
+
# Checksum for an individual file; e.g., used for sandbox/cookbook uploading
|
23
|
+
# to track which files the system already manages.
|
24
|
+
class Chef
|
25
|
+
class Checksum
|
26
|
+
attr_accessor :checksum, :create_time
|
27
|
+
attr_accessor :couchdb_id, :couchdb_rev
|
28
|
+
|
29
|
+
DESIGN_DOCUMENT = {
|
30
|
+
"version" => 1,
|
31
|
+
"language" => "javascript",
|
32
|
+
"views" => {
|
33
|
+
"all" => {
|
34
|
+
"map" => <<-EOJS
|
35
|
+
function(doc) {
|
36
|
+
if (doc.chef_type == "checksum") {
|
37
|
+
emit(doc.checksum, doc);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
EOJS
|
41
|
+
},
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
# Creates a new Chef::Checksum object.
|
46
|
+
#
|
47
|
+
# === Returns
|
48
|
+
# object<Chef::Checksum>:: Duh. :)
|
49
|
+
def initialize(checksum=nil, couchdb=nil)
|
50
|
+
@create_time = Time.now.iso8601
|
51
|
+
@checksum = checksum
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_json(*a)
|
55
|
+
result = {
|
56
|
+
:checksum => checksum,
|
57
|
+
:create_time => create_time,
|
58
|
+
:json_class => self.class.name,
|
59
|
+
:chef_type => 'checksum',
|
60
|
+
|
61
|
+
# For Chef::CouchDB (id_to_name, name_to_id)
|
62
|
+
:name => checksum
|
63
|
+
}
|
64
|
+
result.to_json(*a)
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.json_create(o)
|
68
|
+
checksum = new(o['checksum'])
|
69
|
+
checksum.create_time = o['create_time']
|
70
|
+
|
71
|
+
if o.has_key?('_rev')
|
72
|
+
checksum.couchdb_rev = o["_rev"]
|
73
|
+
o.delete("_rev")
|
74
|
+
end
|
75
|
+
if o.has_key?("_id")
|
76
|
+
checksum.couchdb_id = o["_id"]
|
77
|
+
o.delete("_id")
|
78
|
+
end
|
79
|
+
checksum
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Couchdb
|
84
|
+
##
|
85
|
+
|
86
|
+
def self.create_design_document(couchdb=nil)
|
87
|
+
(couchdb || Chef::CouchDB.new).create_design_document("checksums", DESIGN_DOCUMENT)
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.cdb_list(inflate=false, couchdb=nil)
|
91
|
+
rs = (couchdb || Chef::CouchDB.new).list("checksums", inflate)
|
92
|
+
lookup = (inflate ? "value" : "key")
|
93
|
+
rs["rows"].collect { |r| r[lookup] }
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.cdb_all_checksums(couchdb = nil)
|
97
|
+
rs = (couchdb || Chef::CouchDB.new).list("checksums", true)
|
98
|
+
rs["rows"].inject({}) { |hash_result, r| hash_result[r['key']] = 1; hash_result }
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.cdb_load(checksum, couchdb=nil)
|
102
|
+
# Probably want to look for a view here at some point
|
103
|
+
(couchdb || Chef::CouchDB.new).load("checksum", checksum)
|
104
|
+
end
|
105
|
+
|
106
|
+
def cdb_destroy(couchdb=nil)
|
107
|
+
(couchdb || Chef::CouchDB.new).delete("checksum", checksum, @couchdb_rev)
|
108
|
+
end
|
109
|
+
|
110
|
+
def cdb_save(couchdb=nil)
|
111
|
+
@couchdb_rev = (couchdb || Chef::CouchDB.new).store("checksum", checksum, self)["rev"]
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
data/lib/chef/client.rb
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
# Author:: Adam Jacob (<adam@opscode.com>)
|
3
3
|
# Author:: Christopher Walters (<cw@opscode.com>)
|
4
4
|
# Author:: Christopher Brown (<cb@opscode.com>)
|
5
|
-
#
|
5
|
+
# Author:: Tim Hinderliter (<tim@opscode.com>)
|
6
|
+
# Copyright:: Copyright (c) 2008-2010 Opscode, Inc.
|
6
7
|
# License:: Apache License, Version 2.0
|
7
8
|
#
|
8
9
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -19,25 +20,24 @@
|
|
19
20
|
|
20
21
|
require 'chef/config'
|
21
22
|
require 'chef/mixin/params_validate'
|
22
|
-
require 'chef/mixin/generate_url'
|
23
|
-
require 'chef/mixin/checksum'
|
24
23
|
require 'chef/log'
|
25
24
|
require 'chef/rest'
|
26
25
|
require 'chef/platform'
|
27
26
|
require 'chef/node'
|
28
27
|
require 'chef/role'
|
29
28
|
require 'chef/file_cache'
|
30
|
-
require 'chef/
|
29
|
+
require 'chef/run_context'
|
31
30
|
require 'chef/runner'
|
31
|
+
require 'chef/cookbook/cookbook_collection'
|
32
|
+
require 'chef/cookbook/file_vendor'
|
33
|
+
require 'chef/cookbook/file_system_file_vendor'
|
32
34
|
require 'ohai'
|
33
35
|
|
34
36
|
class Chef
|
35
37
|
class Client
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
attr_accessor :node, :registration, :json_attribs, :node_name, :ohai, :rest
|
38
|
+
# TODO: timh/cw: 5-19-2010: json_attribs should be moved to RunContext?
|
39
|
+
attr_accessor :node, :registration, :json_attribs, :node_name, :ohai, :rest, :runner
|
40
|
+
attr_reader :node_exists
|
41
41
|
|
42
42
|
# Creates a new Chef::Client.
|
43
43
|
def initialize()
|
@@ -46,72 +46,95 @@ class Chef
|
|
46
46
|
@json_attribs = nil
|
47
47
|
@node_name = nil
|
48
48
|
@node_exists = true
|
49
|
+
@runner = nil
|
49
50
|
@ohai = Ohai::System.new
|
50
51
|
Chef::Log.verbose = Chef::Config[:verbose_logging]
|
51
52
|
Mixlib::Authentication::Log.logger = Ohai::Log.logger = Chef::Log.logger
|
52
53
|
@ohai_has_run = false
|
53
|
-
@rest = if File.exists?(Chef::Config[:client_key])
|
54
|
-
Chef::REST.new(Chef::Config[:chef_server_url])
|
55
|
-
else
|
56
|
-
Chef::REST.new(Chef::Config[:chef_server_url], nil, nil)
|
57
|
-
end
|
58
54
|
end
|
59
55
|
|
60
56
|
# Do a full run for this Chef::Client. Calls:
|
61
|
-
#
|
57
|
+
#
|
58
|
+
# * run_ohai - Collect information about the system
|
62
59
|
# * build_node - Get the last known state, merge with local changes
|
63
|
-
# * register -
|
64
|
-
# *
|
65
|
-
# *
|
66
|
-
# * sync_provider_files - Populate the local cache with all the provider files
|
67
|
-
# * sync_resource_files - Populate the local cache with all the resource files
|
68
|
-
# * sync_attribute_files - Populate the local cache with all the attribute files
|
69
|
-
# * sync_definitions - Populate the local cache with all the definitions
|
70
|
-
# * sync_recipes - Populate the local cache with all the recipes
|
71
|
-
# * do_attribute_files - Populate the local cache with all attributes, and execute them
|
72
|
-
# * save_node - Store the new node configuration
|
73
|
-
# * converge - Bring this system up to date, based on the local cache
|
74
|
-
# * save_node - Store the node again, in case convergence altered future state
|
60
|
+
# * register - If not in solo mode, make sure the server knows about this client
|
61
|
+
# * sync_cookbooks - If not in solo mode, populate the local cache with the node's cookbooks
|
62
|
+
# * converge - Bring this system up to date
|
75
63
|
#
|
76
64
|
# === Returns
|
77
65
|
# true:: Always returns true.
|
78
66
|
def run
|
79
|
-
|
80
|
-
|
81
|
-
|
67
|
+
self.runner = nil
|
68
|
+
run_context = nil
|
69
|
+
|
70
|
+
run_ohai
|
82
71
|
determine_node_name
|
83
|
-
register
|
84
|
-
build_node
|
85
|
-
save_node
|
86
|
-
sync_cookbooks
|
87
|
-
converge
|
88
|
-
save_node
|
72
|
+
register unless Chef::Config[:solo]
|
73
|
+
build_node
|
89
74
|
|
90
|
-
|
91
|
-
|
92
|
-
|
75
|
+
begin
|
76
|
+
start_time = Time.now
|
77
|
+
Chef::Log.info("Starting Chef Run")
|
78
|
+
|
79
|
+
if Chef::Config[:solo]
|
80
|
+
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest) }
|
81
|
+
run_context = Chef::RunContext.new(node, Chef::CookbookCollection.new(Chef::CookbookLoader.new))
|
82
|
+
assert_cookbook_path_not_empty(run_context)
|
83
|
+
converge(run_context)
|
84
|
+
else
|
85
|
+
save_node
|
86
|
+
|
87
|
+
# Note: When we move to lazily loading all cookbook files,
|
88
|
+
# replace sync_cookbooks with a method that simply gets the
|
89
|
+
# cookbook manifests from the remote server (and their
|
90
|
+
# download URLs) from the server and feeds them to
|
91
|
+
# RemoteFileVendors. [cw/tim-5/11/2010, 5/23/2010]
|
92
|
+
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest) }
|
93
|
+
# Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest) }
|
94
|
+
sync_cookbooks
|
95
|
+
run_context = Chef::RunContext.new(node, Chef::CookbookCollection.new(Chef::CookbookLoader.new))
|
96
|
+
assert_cookbook_path_not_empty(run_context)
|
97
|
+
save_node
|
98
|
+
|
99
|
+
converge(run_context)
|
100
|
+
save_node
|
101
|
+
end
|
102
|
+
|
103
|
+
end_time = Time.now
|
104
|
+
elapsed_time = end_time - start_time
|
105
|
+
Chef::Log.info("Chef Run complete in #{elapsed_time} seconds")
|
106
|
+
run_report_handlers(start_time, end_time, elapsed_time)
|
107
|
+
true
|
108
|
+
rescue Exception => e
|
109
|
+
run_exception_handlers(node, runner ? runner : run_context, start_time, end_time, elapsed_time, e)
|
110
|
+
Chef::Log.error("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}")
|
111
|
+
raise
|
112
|
+
end
|
93
113
|
end
|
94
|
-
|
95
|
-
# Similar to Chef::Client#run, but instead of talking to the Chef server,
|
96
|
-
# simply runs in a standalone ("solo") mode.
|
97
|
-
#
|
98
|
-
# Someday, we'll have chef_chewbacca.
|
99
|
-
#
|
100
|
-
# === Returns
|
101
|
-
# true:: Always returns true.
|
102
|
-
def run_solo
|
103
|
-
start_time = Time.now
|
104
|
-
Chef::Log.info("Starting Chef Solo Run")
|
105
114
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
115
|
+
def run_report_handlers(start_time, end_time, elapsed_time)
|
116
|
+
if Chef::Config[:report_handlers].length > 0
|
117
|
+
Chef::Log.info("Running report handlers")
|
118
|
+
Chef::Config[:report_handlers].each do |handler|
|
119
|
+
handler.report(node, runner, start_time, end_time, elapsed_time)
|
120
|
+
end
|
121
|
+
Chef::Log.info("Report handlers complete")
|
122
|
+
end
|
113
123
|
end
|
114
124
|
|
125
|
+
def run_exception_handlers(node, runner, start_time, end_time, elapsed_time, exception)
|
126
|
+
if Chef::Config[:exception_handlers].length > 0
|
127
|
+
end_time ||= Time.now
|
128
|
+
elapsed_time ||= end_time - start_time
|
129
|
+
Chef::Log.error("Received exception: #{exception.message}")
|
130
|
+
Chef::Log.error("Running exception handlers")
|
131
|
+
Chef::Config[:exception_handlers].each do |handler|
|
132
|
+
handler.report(node, runner, start_time, end_time, elapsed_time, exception)
|
133
|
+
end
|
134
|
+
Chef::Log.error("Exception handlers complete")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
115
138
|
def run_ohai
|
116
139
|
if ohai.keys
|
117
140
|
ohai.refresh_plugins
|
@@ -121,55 +144,53 @@ class Chef
|
|
121
144
|
end
|
122
145
|
|
123
146
|
def determine_node_name
|
124
|
-
run_ohai
|
125
147
|
unless node_name
|
126
148
|
if Chef::Config[:node_name]
|
127
|
-
|
149
|
+
self.node_name = Chef::Config[:node_name]
|
128
150
|
else
|
129
|
-
|
130
|
-
Chef::Config[:node_name] =
|
151
|
+
self.node_name = ohai[:fqdn] ? ohai[:fqdn] : ohai[:hostname]
|
152
|
+
Chef::Config[:node_name] = node_name
|
131
153
|
end
|
154
|
+
|
155
|
+
raise RuntimeError, "Unable to determine node name from ohai" unless node_name
|
132
156
|
end
|
133
|
-
|
157
|
+
node_name
|
134
158
|
end
|
135
|
-
|
159
|
+
|
136
160
|
# Builds a new node object for this client. Starts with querying for the FQDN of the current
|
137
161
|
# host (unless it is supplied), then merges in the facts from Ohai.
|
138
162
|
#
|
139
|
-
# === Parameters
|
140
|
-
# node_name<String>:: The name of the node to build - defaults to nil
|
141
|
-
#
|
142
163
|
# === Returns
|
143
164
|
# node<Chef::Node>:: Returns the created node object, also stored in @node
|
144
|
-
def build_node
|
145
|
-
|
146
|
-
raise RuntimeError, "Unable to determine node name from ohai" unless node_name
|
147
|
-
Chef::Log.debug("Building node object for #{@node_name}")
|
148
|
-
|
149
|
-
unless solo
|
150
|
-
@node = begin
|
151
|
-
rest.get_rest("nodes/#{@node_name}")
|
152
|
-
rescue Net::HTTPServerException => e
|
153
|
-
raise unless e.message =~ /^404/
|
154
|
-
end
|
155
|
-
end
|
165
|
+
def build_node
|
166
|
+
Chef::Log.debug("Building node object for #{node_name}")
|
156
167
|
|
157
|
-
unless
|
158
|
-
|
159
|
-
|
160
|
-
|
168
|
+
unless Chef::Config[:solo]
|
169
|
+
self.node = begin
|
170
|
+
rest.get_rest("nodes/#{node_name}")
|
171
|
+
rescue Net::HTTPServerException => e
|
172
|
+
raise unless e.message =~ /^404/
|
173
|
+
end
|
161
174
|
end
|
162
175
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
@node[field] = value
|
176
|
+
unless node
|
177
|
+
@node_exists = false
|
178
|
+
self.node = Chef::Node.new
|
179
|
+
node.name(node_name)
|
168
180
|
end
|
169
|
-
|
181
|
+
|
182
|
+
node.consume_attributes(json_attribs)
|
183
|
+
|
184
|
+
node.automatic_attrs = ohai.data
|
185
|
+
|
186
|
+
platform, version = Chef::Platform.find_platform_and_version(node)
|
170
187
|
Chef::Log.debug("Platform is #{platform} version #{version}")
|
171
|
-
@node[:platform] = platform
|
172
|
-
@node[:platform_version] = version
|
188
|
+
@node.automatic_attrs[:platform] = platform
|
189
|
+
@node.automatic_attrs[:platform_version] = version
|
190
|
+
# We clear defaults and overrides, so that any deleted attributes between runs are
|
191
|
+
# still gone.
|
192
|
+
@node.default_attrs = Mash.new
|
193
|
+
@node.override_attrs = Mash.new
|
173
194
|
@node
|
174
195
|
end
|
175
196
|
|
@@ -181,10 +202,10 @@ class Chef
|
|
181
202
|
Chef::Log.debug("Client key #{Chef::Config[:client_key]} is present - skipping registration")
|
182
203
|
else
|
183
204
|
Chef::Log.info("Client key #{Chef::Config[:client_key]} is not present - registering")
|
184
|
-
Chef::REST.new(Chef::Config[:client_url], Chef::Config[:validation_client_name], Chef::Config[:validation_key]).register(
|
205
|
+
Chef::REST.new(Chef::Config[:client_url], Chef::Config[:validation_client_name], Chef::Config[:validation_key]).register(node_name, Chef::Config[:client_key])
|
185
206
|
end
|
186
207
|
# We now have the client key, and should use it from now on.
|
187
|
-
self.rest = Chef::REST.new(Chef::Config[:chef_server_url])
|
208
|
+
self.rest = Chef::REST.new(Chef::Config[:chef_server_url], node_name, Chef::Config[:client_key])
|
188
209
|
end
|
189
210
|
|
190
211
|
# Update the file caches for a given cache segment. Takes a segment name
|
@@ -194,71 +215,52 @@ class Chef
|
|
194
215
|
# === Parameters
|
195
216
|
# segment<String>:: The cache segment to update
|
196
217
|
# remote_list<Hash>:: A cookbooks/_attribute_files style remote file listing
|
197
|
-
def
|
198
|
-
Chef::Log.debug("Synchronizing cookbook #{
|
218
|
+
def sync_cookbook_file_cache(cookbook)
|
219
|
+
Chef::Log.debug("Synchronizing cookbook #{cookbook.name}")
|
199
220
|
|
200
|
-
|
221
|
+
filenames_seen = Hash.new
|
201
222
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
# just laying about.
|
223
|
+
Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
|
224
|
+
cookbook.manifest[segment].each do |manifest_record|
|
225
|
+
# segment = cookbook segment
|
226
|
+
# remote_list = list of file hashes
|
227
|
+
#
|
228
|
+
# We need the list of known good attribute files, so we can delete any that are
|
229
|
+
# just laying about.
|
210
230
|
|
211
|
-
|
212
|
-
|
213
|
-
file_canonical[cache_file] = true
|
231
|
+
cache_filename = File.join("cookbooks", cookbook.name, manifest_record['path'])
|
232
|
+
filenames_seen[cache_filename] = true
|
214
233
|
|
215
|
-
# For back-compat between older clients and new chef servers
|
216
|
-
rf['checksum'] ||= nil
|
217
|
-
|
218
234
|
current_checksum = nil
|
219
|
-
if Chef::FileCache.has_key?(
|
220
|
-
current_checksum =
|
235
|
+
if Chef::FileCache.has_key?(cache_filename)
|
236
|
+
current_checksum = Chef::CookbookVersion.checksum_cookbook_file(Chef::FileCache.load(cache_filename, false))
|
221
237
|
end
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
)
|
231
|
-
|
232
|
-
changed = true
|
233
|
-
begin
|
234
|
-
raw_file = rest.get_rest(rf_url, true)
|
235
|
-
rescue Net::HTTPRetriableError => e
|
236
|
-
if e.response.kind_of?(Net::HTTPNotModified)
|
237
|
-
changed = false
|
238
|
-
Chef::Log.debug("Cache file #{cache_file} is unchanged")
|
239
|
-
else
|
240
|
-
raise e
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
if changed
|
245
|
-
Chef::Log.info("Storing updated #{cache_file} in the cache.")
|
246
|
-
Chef::FileCache.move_to(raw_file.path, cache_file)
|
247
|
-
end
|
238
|
+
|
239
|
+
# If the checksums are different between on-disk (current) and on-server
|
240
|
+
# (remote, per manifest), do the update. This will also execute if there
|
241
|
+
# is no current checksum.
|
242
|
+
if current_checksum != manifest_record['checksum']
|
243
|
+
raw_file = rest.get_rest(manifest_record[:url], true)
|
244
|
+
|
245
|
+
Chef::Log.info("Storing updated #{cache_filename} in the cache.")
|
246
|
+
Chef::FileCache.move_to(raw_file.path, cache_filename)
|
247
|
+
else
|
248
248
|
end
|
249
249
|
end
|
250
|
-
|
251
250
|
end
|
252
251
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
252
|
+
filenames_seen
|
253
|
+
end
|
254
|
+
|
255
|
+
def cleanup_file_cache(valid_cache_entries)
|
256
|
+
# Delete each file in the cache that we didn't encounter in the
|
257
|
+
# manifest.
|
258
|
+
Chef::FileCache.list.each do |cache_filename|
|
259
|
+
unless valid_cache_entries[cache_filename]
|
260
|
+
Chef::Log.info("Removing #{cache_filename} from the cache; it is no longer on the server.")
|
261
|
+
Chef::FileCache.delete(cache_filename)
|
259
262
|
end
|
260
263
|
end
|
261
|
-
|
262
264
|
end
|
263
265
|
|
264
266
|
# Synchronizes all the cookbooks from the chef-server.
|
@@ -267,8 +269,10 @@ class Chef
|
|
267
269
|
# true:: Always returns true
|
268
270
|
def sync_cookbooks
|
269
271
|
Chef::Log.debug("Synchronizing cookbooks")
|
270
|
-
cookbook_hash = rest.get_rest("nodes/#{
|
272
|
+
cookbook_hash = rest.get_rest("nodes/#{node_name}/cookbooks")
|
271
273
|
Chef::Log.debug("Cookbooks to load: #{cookbook_hash.inspect}")
|
274
|
+
|
275
|
+
# Remove all cookbooks no longer relevant to this node
|
272
276
|
Chef::FileCache.list.each do |cache_file|
|
273
277
|
if cache_file =~ /^cookbooks\/(.+?)\//
|
274
278
|
unless cookbook_hash.has_key?($1)
|
@@ -277,9 +281,17 @@ class Chef
|
|
277
281
|
end
|
278
282
|
end
|
279
283
|
end
|
280
|
-
|
281
|
-
|
284
|
+
|
285
|
+
# Synchronize each of the node's cookbooks
|
286
|
+
valid_cache_entries = cookbook_hash.values.inject({}) do |memo, cookbook|
|
287
|
+
memo.merge!(sync_cookbook_file_cache(cookbook))
|
288
|
+
memo
|
282
289
|
end
|
290
|
+
|
291
|
+
cleanup_file_cache(valid_cache_entries)
|
292
|
+
|
293
|
+
# register the file cache path in the cookbook path so that CookbookLoader actually picks up the synced cookbooks
|
294
|
+
Chef::Config[:cookbook_path] = File.join(Chef::Config[:file_cache_path], "cookbooks")
|
283
295
|
end
|
284
296
|
|
285
297
|
# Updates the current node configuration on the server.
|
@@ -287,31 +299,39 @@ class Chef
|
|
287
299
|
# === Returns
|
288
300
|
# true:: Always returns true
|
289
301
|
def save_node
|
290
|
-
Chef::Log.debug("Saving the current state of node #{
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
end
|
299
|
-
rescue
|
300
|
-
nil
|
301
|
-
end
|
302
|
+
Chef::Log.debug("Saving the current state of node #{node_name}")
|
303
|
+
self.node = if node_exists
|
304
|
+
rest.put_rest("nodes/#{node_name}", node)
|
305
|
+
else
|
306
|
+
result = rest.post_rest("nodes", node)
|
307
|
+
@node_exists = true
|
308
|
+
rest.get_rest(result['uri'])
|
309
|
+
end
|
302
310
|
end
|
303
|
-
|
304
|
-
#
|
305
|
-
# Chef::Runner.converge.
|
311
|
+
|
312
|
+
# Converges the node.
|
306
313
|
#
|
307
314
|
# === Returns
|
308
315
|
# true:: Always returns true
|
309
|
-
def converge(
|
310
|
-
Chef::Log.debug("
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
316
|
+
def converge(run_context)
|
317
|
+
Chef::Log.debug("Converging node #{node_name}")
|
318
|
+
self.runner = Chef::Runner.new(run_context)
|
319
|
+
runner.converge
|
320
|
+
true
|
321
|
+
end
|
322
|
+
|
323
|
+
private
|
324
|
+
|
325
|
+
def directory_not_empty?(path)
|
326
|
+
File.exists?(path) && (Dir.entries(path).size > 2)
|
327
|
+
end
|
328
|
+
|
329
|
+
def is_last_element?(index, object)
|
330
|
+
object.kind_of?(Array) ? index == object.size - 1 : true
|
331
|
+
end
|
332
|
+
|
333
|
+
def assert_cookbook_path_not_empty(run_context)
|
334
|
+
if Chef::Config[:solo]
|
315
335
|
# Check for cookbooks in the path given
|
316
336
|
# Chef::Config[:cookbook_path] can be a string or an array
|
317
337
|
# if it's an array, go through it and check each one, raise error at the last one if no files are found
|
@@ -325,23 +345,11 @@ class Chef
|
|
325
345
|
raise Chef::Exceptions::CookbookNotFound, msg if is_last_element?(index, Chef::Config[:cookbook_path])
|
326
346
|
end
|
327
347
|
end
|
348
|
+
else
|
349
|
+
Chef::Log.warn("Node #{node_name} has an empty run list.") if run_context.node.run_list.empty?
|
328
350
|
end
|
329
|
-
compile = Chef::Compile.new(@node)
|
330
|
-
|
331
|
-
Chef::Log.debug("Converging node #{@node_name}")
|
332
|
-
Chef::Runner.new(@node, compile.collection, compile.definitions, compile.cookbook_loader).converge
|
333
|
-
true
|
334
|
-
end
|
335
|
-
|
336
|
-
private
|
337
|
-
|
338
|
-
def directory_not_empty?(path)
|
339
|
-
File.exists?(path) && (Dir.entries(path).size > 2)
|
340
|
-
end
|
341
|
-
|
342
|
-
def is_last_element?(index, object)
|
343
|
-
object.kind_of?(Array) ? index == object.size - 1 : true
|
344
|
-
end
|
345
351
|
|
352
|
+
end
|
346
353
|
end
|
347
354
|
end
|
355
|
+
|