runa-chef 0.8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +201 -0
- data/README.rdoc +136 -0
- data/bin/chef-client +26 -0
- data/bin/chef-solo +26 -0
- data/bin/knife +27 -0
- data/bin/shef +45 -0
- data/distro/README +2 -0
- data/distro/common/man/man1/chef-indexer.1 +42 -0
- data/distro/common/man/man1/chef-server.1 +108 -0
- data/distro/common/man/man8/chef-client.8 +61 -0
- data/distro/common/man/man8/chef-solo.8 +58 -0
- data/distro/common/man/man8/knife.8 +359 -0
- data/distro/debian/etc/init.d/chef-client +175 -0
- data/distro/debian/etc/init.d/chef-indexer +175 -0
- data/distro/debian/etc/init.d/chef-server +120 -0
- data/distro/redhat/etc/init.d/chef-client +78 -0
- data/distro/redhat/etc/init.d/chef-indexer +76 -0
- data/distro/redhat/etc/init.d/chef-server +78 -0
- data/distro/redhat/etc/sysconfig/chef-client +10 -0
- data/distro/redhat/etc/sysconfig/chef-indexer +8 -0
- data/distro/redhat/etc/sysconfig/chef-server +10 -0
- data/distro/suse/etc/init.d/chef-client +121 -0
- data/lib/chef.rb +49 -0
- data/lib/chef/api_client.rb +269 -0
- data/lib/chef/application.rb +98 -0
- data/lib/chef/application/agent.rb +18 -0
- data/lib/chef/application/client.rb +214 -0
- data/lib/chef/application/knife.rb +138 -0
- data/lib/chef/application/server.rb +19 -0
- data/lib/chef/application/solo.rb +214 -0
- data/lib/chef/cache.rb +61 -0
- data/lib/chef/cache/checksum.rb +70 -0
- data/lib/chef/certificate.rb +154 -0
- data/lib/chef/client.rb +323 -0
- data/lib/chef/compile.rb +158 -0
- data/lib/chef/config.rb +195 -0
- data/lib/chef/cookbook.rb +198 -0
- data/lib/chef/cookbook/metadata.rb +487 -0
- data/lib/chef/cookbook/metadata/version.rb +87 -0
- data/lib/chef/cookbook_loader.rb +180 -0
- data/lib/chef/couchdb.rb +273 -0
- data/lib/chef/daemon.rb +170 -0
- data/lib/chef/data_bag.rb +216 -0
- data/lib/chef/data_bag_item.rb +227 -0
- data/lib/chef/exceptions.rb +39 -0
- data/lib/chef/file_cache.rb +205 -0
- data/lib/chef/knife.rb +300 -0
- data/lib/chef/knife/client_bulk_delete.rb +41 -0
- data/lib/chef/knife/client_create.rb +55 -0
- data/lib/chef/knife/client_delete.rb +37 -0
- data/lib/chef/knife/client_edit.rb +37 -0
- data/lib/chef/knife/client_list.rb +40 -0
- data/lib/chef/knife/client_reregister.rb +48 -0
- data/lib/chef/knife/client_show.rb +42 -0
- data/lib/chef/knife/configure.rb +84 -0
- data/lib/chef/knife/cookbook_bulk_delete.rb +47 -0
- data/lib/chef/knife/cookbook_delete.rb +41 -0
- data/lib/chef/knife/cookbook_download.rb +57 -0
- data/lib/chef/knife/cookbook_list.rb +41 -0
- data/lib/chef/knife/cookbook_metadata.rb +87 -0
- data/lib/chef/knife/cookbook_show.rb +75 -0
- data/lib/chef/knife/cookbook_upload.rb +173 -0
- data/lib/chef/knife/data_bag_create.rb +43 -0
- data/lib/chef/knife/data_bag_delete.rb +43 -0
- data/lib/chef/knife/data_bag_edit.rb +49 -0
- data/lib/chef/knife/data_bag_list.rb +42 -0
- data/lib/chef/knife/data_bag_show.rb +40 -0
- data/lib/chef/knife/ec2_instance_data.rb +46 -0
- data/lib/chef/knife/node_bulk_delete.rb +44 -0
- data/lib/chef/knife/node_create.rb +39 -0
- data/lib/chef/knife/node_delete.rb +36 -0
- data/lib/chef/knife/node_edit.rb +36 -0
- data/lib/chef/knife/node_from_file.rb +42 -0
- data/lib/chef/knife/node_list.rb +41 -0
- data/lib/chef/knife/node_run_list_add.rb +64 -0
- data/lib/chef/knife/node_run_list_remove.rb +45 -0
- data/lib/chef/knife/node_show.rb +46 -0
- data/lib/chef/knife/role_bulk_delete.rb +45 -0
- data/lib/chef/knife/role_create.rb +44 -0
- data/lib/chef/knife/role_delete.rb +36 -0
- data/lib/chef/knife/role_edit.rb +37 -0
- data/lib/chef/knife/role_from_file.rb +46 -0
- data/lib/chef/knife/role_list.rb +40 -0
- data/lib/chef/knife/role_show.rb +43 -0
- data/lib/chef/knife/search.rb +94 -0
- data/lib/chef/log.rb +39 -0
- data/lib/chef/mixin/check_helper.rb +31 -0
- data/lib/chef/mixin/checksum.rb +32 -0
- data/lib/chef/mixin/command.rb +390 -0
- data/lib/chef/mixin/convert_to_class_name.rb +57 -0
- data/lib/chef/mixin/create_path.rb +56 -0
- data/lib/chef/mixin/deep_merge.rb +33 -0
- data/lib/chef/mixin/find_preferred_file.rb +92 -0
- data/lib/chef/mixin/from_file.rb +50 -0
- data/lib/chef/mixin/generate_url.rb +58 -0
- data/lib/chef/mixin/language.rb +107 -0
- data/lib/chef/mixin/language_include_attribute.rb +56 -0
- data/lib/chef/mixin/language_include_recipe.rb +53 -0
- data/lib/chef/mixin/params_validate.rb +197 -0
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +79 -0
- data/lib/chef/mixin/template.rb +94 -0
- data/lib/chef/nanite.rb +100 -0
- data/lib/chef/node.rb +463 -0
- data/lib/chef/node/attribute.rb +412 -0
- data/lib/chef/openid_registration.rb +181 -0
- data/lib/chef/platform.rb +268 -0
- data/lib/chef/provider.rb +101 -0
- data/lib/chef/provider/breakpoint.rb +36 -0
- data/lib/chef/provider/cron.rb +184 -0
- data/lib/chef/provider/deploy.rb +314 -0
- data/lib/chef/provider/deploy/revision.rb +70 -0
- data/lib/chef/provider/deploy/timestamped.rb +33 -0
- data/lib/chef/provider/directory.rb +72 -0
- data/lib/chef/provider/erl_call.rb +72 -0
- data/lib/chef/provider/execute.rb +58 -0
- data/lib/chef/provider/file.rb +195 -0
- data/lib/chef/provider/git.rb +203 -0
- data/lib/chef/provider/group.rb +120 -0
- data/lib/chef/provider/group/dscl.rb +128 -0
- data/lib/chef/provider/group/gpasswd.rb +50 -0
- data/lib/chef/provider/group/groupadd.rb +78 -0
- data/lib/chef/provider/group/pw.rb +88 -0
- data/lib/chef/provider/group/usermod.rb +57 -0
- data/lib/chef/provider/http_request.rb +106 -0
- data/lib/chef/provider/ifconfig.rb +131 -0
- data/lib/chef/provider/link.rb +157 -0
- data/lib/chef/provider/mdadm.rb +88 -0
- data/lib/chef/provider/mount.rb +117 -0
- data/lib/chef/provider/mount/mount.rb +208 -0
- data/lib/chef/provider/package.rb +160 -0
- data/lib/chef/provider/package/apt.rb +110 -0
- data/lib/chef/provider/package/dpkg.rb +109 -0
- data/lib/chef/provider/package/easy_install.rb +106 -0
- data/lib/chef/provider/package/freebsd.rb +153 -0
- data/lib/chef/provider/package/macports.rb +105 -0
- data/lib/chef/provider/package/portage.rb +124 -0
- data/lib/chef/provider/package/rpm.rb +99 -0
- data/lib/chef/provider/package/rubygems.rb +136 -0
- data/lib/chef/provider/package/yum-dump.py +125 -0
- data/lib/chef/provider/package/yum.rb +175 -0
- data/lib/chef/provider/package/zypper.rb +132 -0
- data/lib/chef/provider/remote_directory.rb +126 -0
- data/lib/chef/provider/remote_file.rb +141 -0
- data/lib/chef/provider/route.rb +118 -0
- data/lib/chef/provider/ruby_block.rb +33 -0
- data/lib/chef/provider/script.rb +42 -0
- data/lib/chef/provider/service.rb +135 -0
- data/lib/chef/provider/service/debian.rb +64 -0
- data/lib/chef/provider/service/freebsd.rb +156 -0
- data/lib/chef/provider/service/gentoo.rb +54 -0
- data/lib/chef/provider/service/init.rb +71 -0
- data/lib/chef/provider/service/redhat.rb +62 -0
- data/lib/chef/provider/service/simple.rb +114 -0
- data/lib/chef/provider/subversion.rb +156 -0
- data/lib/chef/provider/template.rb +175 -0
- data/lib/chef/provider/user.rb +170 -0
- data/lib/chef/provider/user/dscl.rb +280 -0
- data/lib/chef/provider/user/pw.rb +113 -0
- data/lib/chef/provider/user/useradd.rb +108 -0
- data/lib/chef/recipe.rb +105 -0
- data/lib/chef/resource.rb +380 -0
- data/lib/chef/resource/apt_package.rb +34 -0
- data/lib/chef/resource/bash.rb +33 -0
- data/lib/chef/resource/breakpoint.rb +35 -0
- data/lib/chef/resource/cron.rb +179 -0
- data/lib/chef/resource/csh.rb +33 -0
- data/lib/chef/resource/deploy.rb +359 -0
- data/lib/chef/resource/deploy_revision.rb +35 -0
- data/lib/chef/resource/directory.rb +76 -0
- data/lib/chef/resource/dpkg_package.rb +34 -0
- data/lib/chef/resource/easy_install_package.rb +41 -0
- data/lib/chef/resource/erl_call.rb +83 -0
- data/lib/chef/resource/execute.rb +127 -0
- data/lib/chef/resource/file.rb +84 -0
- data/lib/chef/resource/gem_package.rb +41 -0
- data/lib/chef/resource/git.rb +36 -0
- data/lib/chef/resource/group.rb +70 -0
- data/lib/chef/resource/http_request.rb +52 -0
- data/lib/chef/resource/ifconfig.rb +134 -0
- data/lib/chef/resource/link.rb +78 -0
- data/lib/chef/resource/macports_package.rb +29 -0
- data/lib/chef/resource/mdadm.rb +82 -0
- data/lib/chef/resource/mount.rb +135 -0
- data/lib/chef/resource/package.rb +80 -0
- data/lib/chef/resource/perl.rb +33 -0
- data/lib/chef/resource/portage_package.rb +33 -0
- data/lib/chef/resource/python.rb +33 -0
- data/lib/chef/resource/remote_directory.rb +91 -0
- data/lib/chef/resource/remote_file.rb +60 -0
- data/lib/chef/resource/route.rb +135 -0
- data/lib/chef/resource/ruby.rb +33 -0
- data/lib/chef/resource/ruby_block.rb +39 -0
- data/lib/chef/resource/scm.rb +137 -0
- data/lib/chef/resource/script.rb +51 -0
- data/lib/chef/resource/service.rb +134 -0
- data/lib/chef/resource/subversion.rb +34 -0
- data/lib/chef/resource/template.rb +60 -0
- data/lib/chef/resource/timestamped_deploy.rb +31 -0
- data/lib/chef/resource/user.rb +101 -0
- data/lib/chef/resource_collection.rb +212 -0
- data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
- data/lib/chef/resource_definition.rb +67 -0
- data/lib/chef/rest.rb +298 -0
- data/lib/chef/role.rb +301 -0
- data/lib/chef/run_list.rb +164 -0
- data/lib/chef/runner.rb +130 -0
- data/lib/chef/search/query.rb +71 -0
- data/lib/chef/shef.rb +220 -0
- data/lib/chef/shef/ext.rb +297 -0
- data/lib/chef/shef/shef_session.rb +175 -0
- data/lib/chef/streaming_cookbook_uploader.rb +185 -0
- data/lib/chef/tasks/chef_repo.rake +245 -0
- data/lib/chef/util/file_edit.rb +125 -0
- data/lib/chef/util/fileedit.rb +121 -0
- data/lib/chef/webui_user.rb +231 -0
- metadata +398 -0
data/lib/chef/nanite.rb
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2008 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
|
+
|
|
19
|
+
require 'chef'
|
|
20
|
+
require 'chef/config'
|
|
21
|
+
require 'chef/mixin/params_validate'
|
|
22
|
+
require 'json'
|
|
23
|
+
|
|
24
|
+
# The client doesn't use this class, so we are cool without having it
|
|
25
|
+
begin
|
|
26
|
+
require 'nanite'
|
|
27
|
+
require 'uuidtools'
|
|
28
|
+
rescue LoadError
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class Chef
|
|
32
|
+
class Nanite
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
|
|
36
|
+
def start_mapper(config={})
|
|
37
|
+
Chef::Log.info("Running the Nanite Mapper")
|
|
38
|
+
::Nanite::Log.logger = Chef::Log.logger
|
|
39
|
+
identity = get_identity
|
|
40
|
+
::Nanite.start_mapper(
|
|
41
|
+
:host => Chef::Config[:nanite_host],
|
|
42
|
+
:user => Chef::Config[:nanite_user],
|
|
43
|
+
:pass => Chef::Config[:nanite_pass],
|
|
44
|
+
:vhost => Chef::Config[:nanite_vhost],
|
|
45
|
+
:identity => identity,
|
|
46
|
+
:format => :json,
|
|
47
|
+
:log_level => Chef::Config[:log_level]
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def get_identity(type="mapper")
|
|
52
|
+
id = nil
|
|
53
|
+
if Chef::Config[:nanite_persistent_mapper]
|
|
54
|
+
if Chef::FileCache.has_key?("nanite-#{type}-identity")
|
|
55
|
+
id = Chef::FileCache.load("nanite-#{type}-identity")
|
|
56
|
+
else
|
|
57
|
+
id = UUIDTools::UUID.random_create.to_s
|
|
58
|
+
Chef::FileCache.store("nanite-#{type}-identity", id)
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
id = Chef::Config[:nanite_identity] ? "#{Chef::Config[:nanite_identity]}-#{UUIDTools::UUID.random_create.to_s}" : UUIDTools::UUID.random_create.to_s
|
|
62
|
+
end
|
|
63
|
+
id
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def request(*args)
|
|
67
|
+
in_event do
|
|
68
|
+
::Nanite.request(*args)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def push(*args)
|
|
73
|
+
in_event do
|
|
74
|
+
::Nanite.push(*args)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def in_event(&block)
|
|
79
|
+
if EM.reactor_running?
|
|
80
|
+
begin
|
|
81
|
+
::Nanite.ensure_mapper
|
|
82
|
+
rescue ::Nanite::MapperNotRunning
|
|
83
|
+
start_mapper
|
|
84
|
+
end
|
|
85
|
+
block.call
|
|
86
|
+
else
|
|
87
|
+
Chef::Log.warn("Starting Event Machine Loop")
|
|
88
|
+
Thread.new do
|
|
89
|
+
EM.run do
|
|
90
|
+
start_mapper
|
|
91
|
+
block.call
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
end
|
data/lib/chef/node.rb
ADDED
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2008 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
|
+
|
|
19
|
+
require 'chef/config'
|
|
20
|
+
require 'chef/mixin/check_helper'
|
|
21
|
+
require 'chef/mixin/params_validate'
|
|
22
|
+
require 'chef/mixin/from_file'
|
|
23
|
+
require 'chef/mixin/language_include_attribute'
|
|
24
|
+
require 'chef/couchdb'
|
|
25
|
+
require 'chef/rest'
|
|
26
|
+
require 'chef/run_list'
|
|
27
|
+
require 'chef/node/attribute'
|
|
28
|
+
require 'extlib'
|
|
29
|
+
require 'json'
|
|
30
|
+
|
|
31
|
+
class Chef
|
|
32
|
+
class Node
|
|
33
|
+
|
|
34
|
+
attr_accessor :attribute, :recipe_list, :couchdb_rev, :couchdb_id, :run_state, :run_list, :override_attrs, :default_attrs, :cookbook_loader
|
|
35
|
+
|
|
36
|
+
include Chef::Mixin::CheckHelper
|
|
37
|
+
include Chef::Mixin::FromFile
|
|
38
|
+
include Chef::Mixin::ParamsValidate
|
|
39
|
+
include Chef::Mixin::LanguageIncludeAttribute
|
|
40
|
+
|
|
41
|
+
DESIGN_DOCUMENT = {
|
|
42
|
+
"version" => 9,
|
|
43
|
+
"language" => "javascript",
|
|
44
|
+
"views" => {
|
|
45
|
+
"all" => {
|
|
46
|
+
"map" => <<-EOJS
|
|
47
|
+
function(doc) {
|
|
48
|
+
if (doc.chef_type == "node") {
|
|
49
|
+
emit(doc.name, doc);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
EOJS
|
|
53
|
+
},
|
|
54
|
+
"all_id" => {
|
|
55
|
+
"map" => <<-EOJS
|
|
56
|
+
function(doc) {
|
|
57
|
+
if (doc.chef_type == "node") {
|
|
58
|
+
emit(doc.name, doc.name);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
EOJS
|
|
62
|
+
},
|
|
63
|
+
"status" => {
|
|
64
|
+
"map" => <<-EOJS
|
|
65
|
+
function(doc) {
|
|
66
|
+
if (doc.chef_type == "node") {
|
|
67
|
+
var to_emit = { "name": doc.name };
|
|
68
|
+
if (doc["attributes"]["fqdn"]) {
|
|
69
|
+
to_emit["fqdn"] = doc["attributes"]["fqdn"];
|
|
70
|
+
} else {
|
|
71
|
+
to_emit["fqdn"] = "Undefined";
|
|
72
|
+
}
|
|
73
|
+
if (doc["attributes"]["ipaddress"]) {
|
|
74
|
+
to_emit["ipaddress"] = doc["attributes"]["ipaddress"];
|
|
75
|
+
} else {
|
|
76
|
+
to_emit["ipaddress"] = "Undefined";
|
|
77
|
+
}
|
|
78
|
+
if (doc["attributes"]["ohai_time"]) {
|
|
79
|
+
to_emit["ohai_time"] = doc["attributes"]["ohai_time"];
|
|
80
|
+
} else {
|
|
81
|
+
to_emit["ohai_time"] = "Undefined";
|
|
82
|
+
}
|
|
83
|
+
if (doc["attributes"]["uptime"]) {
|
|
84
|
+
to_emit["uptime"] = doc["attributes"]["uptime"];
|
|
85
|
+
} else {
|
|
86
|
+
to_emit["uptime"] = "Undefined";
|
|
87
|
+
}
|
|
88
|
+
if (doc["attributes"]["platform"]) {
|
|
89
|
+
to_emit["platform"] = doc["attributes"]["platform"];
|
|
90
|
+
} else {
|
|
91
|
+
to_emit["platform"] = "Undefined";
|
|
92
|
+
}
|
|
93
|
+
if (doc["attributes"]["platform_version"]) {
|
|
94
|
+
to_emit["platform_version"] = doc["attributes"]["platform_version"];
|
|
95
|
+
} else {
|
|
96
|
+
to_emit["platform_version"] = "Undefined";
|
|
97
|
+
}
|
|
98
|
+
if (doc["run_list"]) {
|
|
99
|
+
to_emit["run_list"] = doc["run_list"];
|
|
100
|
+
} else {
|
|
101
|
+
to_emit["run_list"] = "Undefined";
|
|
102
|
+
}
|
|
103
|
+
emit(doc.name, to_emit);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
EOJS
|
|
107
|
+
},
|
|
108
|
+
"by_run_list" => {
|
|
109
|
+
"map" => <<-EOJS
|
|
110
|
+
function(doc) {
|
|
111
|
+
if (doc.chef_type == "node") {
|
|
112
|
+
if (doc['run_list']) {
|
|
113
|
+
for (var i=0; i < doc.run_list.length; i++) {
|
|
114
|
+
emit(doc['run_list'][i], doc.name);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
EOJS
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# Create a new Chef::Node object.
|
|
125
|
+
def initialize
|
|
126
|
+
@name = nil
|
|
127
|
+
|
|
128
|
+
@attribute = Mash.new
|
|
129
|
+
@override_attrs = Mash.new
|
|
130
|
+
@default_attrs = Mash.new
|
|
131
|
+
@run_list = Chef::RunList.new
|
|
132
|
+
|
|
133
|
+
@couchdb_rev = nil
|
|
134
|
+
@couchdb_id = nil
|
|
135
|
+
@couchdb = Chef::CouchDB.new
|
|
136
|
+
|
|
137
|
+
@run_state = {
|
|
138
|
+
:template_cache => Hash.new,
|
|
139
|
+
:seen_recipes => Hash.new,
|
|
140
|
+
:seen_attributes => Hash.new
|
|
141
|
+
}
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Find a recipe for this Chef::Node by fqdn. Will search first for
|
|
145
|
+
# Chef::Config["node_path"]/fqdn.rb, then hostname.rb, then default.rb.
|
|
146
|
+
#
|
|
147
|
+
# Returns a new Chef::Node object.
|
|
148
|
+
#
|
|
149
|
+
# Raises an ArgumentError if it cannot find the node.
|
|
150
|
+
def find_file(fqdn)
|
|
151
|
+
node_file = nil
|
|
152
|
+
host_parts = fqdn.split(".")
|
|
153
|
+
hostname = host_parts[0]
|
|
154
|
+
|
|
155
|
+
if File.exists?(File.join(Chef::Config[:node_path], "#{fqdn}.rb"))
|
|
156
|
+
node_file = File.join(Chef::Config[:node_path], "#{fqdn}.rb")
|
|
157
|
+
elsif File.exists?(File.join(Chef::Config[:node_path], "#{hostname}.rb"))
|
|
158
|
+
node_file = File.join(Chef::Config[:node_path], "#{hostname}.rb")
|
|
159
|
+
elsif File.exists?(File.join(Chef::Config[:node_path], "default.rb"))
|
|
160
|
+
node_file = File.join(Chef::Config[:node_path], "default.rb")
|
|
161
|
+
end
|
|
162
|
+
unless node_file
|
|
163
|
+
raise ArgumentError, "Cannot find a node matching #{fqdn}, not even with default.rb!"
|
|
164
|
+
end
|
|
165
|
+
self.from_file(node_file)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Set the name of this Node, or return the current name.
|
|
169
|
+
def name(arg=nil)
|
|
170
|
+
if arg != nil
|
|
171
|
+
validate(
|
|
172
|
+
{ :name => arg },
|
|
173
|
+
{
|
|
174
|
+
:name => {
|
|
175
|
+
:kind_of => String
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
@name = arg
|
|
180
|
+
else
|
|
181
|
+
@name
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Return an attribute of this node. Returns nil if the attribute is not found.
|
|
186
|
+
def [](attrib)
|
|
187
|
+
attrs = Chef::Node::Attribute.new(@attribute, @default_attrs, @override_attrs)
|
|
188
|
+
attrs[attrib]
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Set an attribute of this node
|
|
192
|
+
def []=(attrib, value)
|
|
193
|
+
attrs = Chef::Node::Attribute.new(@attribute, @default_attrs, @override_attrs)
|
|
194
|
+
attrs[attrib] = value
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def store(attrib, value)
|
|
198
|
+
self[attrib] = value
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Set an attribute of this node, but auto-vivifiy any Mashes that might
|
|
202
|
+
# be missing
|
|
203
|
+
def set
|
|
204
|
+
attrs = Chef::Node::Attribute.new(@attribute, @default_attrs, @override_attrs)
|
|
205
|
+
attrs.auto_vivifiy_on_read = true
|
|
206
|
+
attrs
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Set an attribute of this node, auto-vivifiying any mashes that are
|
|
210
|
+
# missing, but if the final value already exists, don't set it
|
|
211
|
+
def set_unless
|
|
212
|
+
attrs = Chef::Node::Attribute.new(@attribute, @default_attrs, @override_attrs)
|
|
213
|
+
attrs.auto_vivifiy_on_read = true
|
|
214
|
+
attrs.set_unless_value_present = true
|
|
215
|
+
attrs
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
alias_method :default, :set_unless
|
|
219
|
+
|
|
220
|
+
# Return true if this Node has a given attribute, false if not. Takes either a symbol or
|
|
221
|
+
# a string.
|
|
222
|
+
#
|
|
223
|
+
# Only works on the top level. Preferred way is to use the normal [] style
|
|
224
|
+
# lookup and call attribute?()
|
|
225
|
+
def attribute?(attrib)
|
|
226
|
+
attrs = Chef::Node::Attribute.new(@attribute, @default_attrs, @override_attrs)
|
|
227
|
+
attrs.attribute?(attrib)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Yield each key of the top level to the block.
|
|
231
|
+
def each(&block)
|
|
232
|
+
attrs = Chef::Node::Attribute.new(@attribute, @default_attrs, @override_attrs)
|
|
233
|
+
attrs.each(&block)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Iterates over each attribute, passing the attribute and value to the block.
|
|
237
|
+
def each_attribute(&block)
|
|
238
|
+
attrs = Chef::Node::Attribute.new(@attribute, @default_attrs, @override_attrs)
|
|
239
|
+
attrs.each_attribute(&block)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Set an attribute based on the missing method. If you pass an argument, we'll use that
|
|
243
|
+
# to set the attribute values. Otherwise, we'll wind up just returning the attributes
|
|
244
|
+
# value.
|
|
245
|
+
def method_missing(symbol, *args)
|
|
246
|
+
attrs = Chef::Node::Attribute.new(@attribute, @default_attrs, @override_attrs)
|
|
247
|
+
attrs.send(symbol, *args)
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Returns true if this Node expects a given recipe, false if not.
|
|
251
|
+
def recipe?(recipe_name)
|
|
252
|
+
if @run_list.include?(recipe_name)
|
|
253
|
+
true
|
|
254
|
+
else
|
|
255
|
+
if @run_state[:seen_recipes].include?(recipe_name)
|
|
256
|
+
true
|
|
257
|
+
else
|
|
258
|
+
false
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# Returns an Array of recipes. If you call it with arguments, they will become the new
|
|
264
|
+
# list of recipes.
|
|
265
|
+
def recipes(*args)
|
|
266
|
+
if args.length > 0
|
|
267
|
+
@run_list.reset(args)
|
|
268
|
+
else
|
|
269
|
+
@run_list
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# Returns true if this Node expects a given role, false if not.
|
|
274
|
+
def role?(role_name)
|
|
275
|
+
@run_list.include?("role[#{role_name}]")
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# Returns an Array of roles and recipes, in the order they will be applied.
|
|
279
|
+
# If you call it with arguments, they will become the new list of roles and recipes.
|
|
280
|
+
def run_list(*args)
|
|
281
|
+
if args.length > 0
|
|
282
|
+
@run_list.reset(args)
|
|
283
|
+
else
|
|
284
|
+
@run_list
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Returns true if this Node expects a given role, false if not.
|
|
289
|
+
def run_list?(item)
|
|
290
|
+
@run_list.detect { |r| r == item } ? true : false
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def consume_attributes(attrs)
|
|
294
|
+
attrs ||= {}
|
|
295
|
+
Chef::Log.debug("Adding JSON Attributes")
|
|
296
|
+
attrs.each do |key, value|
|
|
297
|
+
if ["recipes", "run_list"].include?(key)
|
|
298
|
+
append_recipes(value)
|
|
299
|
+
else
|
|
300
|
+
Chef::Log.debug("JSON Attribute: #{key} - #{value.inspect}")
|
|
301
|
+
store(key, value)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
self[:tags] = Array.new unless attribute?(:tags)
|
|
305
|
+
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# Transform the node to a Hash
|
|
309
|
+
def to_hash
|
|
310
|
+
index_hash = Hash.new
|
|
311
|
+
self.each do |k, v|
|
|
312
|
+
index_hash[k] = v
|
|
313
|
+
end
|
|
314
|
+
index_hash["chef_type"] = "node"
|
|
315
|
+
index_hash["name"] = @name
|
|
316
|
+
index_hash["recipe"] = @run_list.recipes if @run_list.recipes.length > 0
|
|
317
|
+
index_hash["role"] = @run_list.roles if @run_list.roles.length > 0
|
|
318
|
+
index_hash["run_list"] = @run_list.run_list if @run_list.run_list.length > 0
|
|
319
|
+
index_hash
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# Serialize this object as a hash
|
|
323
|
+
def to_json(*a)
|
|
324
|
+
result = {
|
|
325
|
+
"name" => @name,
|
|
326
|
+
'json_class' => self.class.name,
|
|
327
|
+
"attributes" => @attribute,
|
|
328
|
+
"chef_type" => "node",
|
|
329
|
+
"defaults" => @default_attrs,
|
|
330
|
+
"overrides" => @override_attrs,
|
|
331
|
+
"run_list" => @run_list.run_list,
|
|
332
|
+
}
|
|
333
|
+
result["_rev"] = @couchdb_rev if @couchdb_rev
|
|
334
|
+
result.to_json(*a)
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# Create a Chef::Node from JSON
|
|
338
|
+
def self.json_create(o)
|
|
339
|
+
node = new
|
|
340
|
+
node.name(o["name"])
|
|
341
|
+
o["attributes"].each do |k,v|
|
|
342
|
+
node[k] = v
|
|
343
|
+
end
|
|
344
|
+
if o.has_key?("defaults")
|
|
345
|
+
node.default_attrs = Mash.new(o["defaults"])
|
|
346
|
+
end
|
|
347
|
+
if o.has_key?("overrides")
|
|
348
|
+
node.override_attrs = Mash.new(o["overrides"])
|
|
349
|
+
end
|
|
350
|
+
if o.has_key?("run_list")
|
|
351
|
+
node.run_list.reset(o["run_list"])
|
|
352
|
+
else
|
|
353
|
+
o["recipes"].each { |r| node.recipes << r }
|
|
354
|
+
end
|
|
355
|
+
node.couchdb_rev = o["_rev"] if o.has_key?("_rev")
|
|
356
|
+
node.couchdb_id = o["_id"] if o.has_key?("_id")
|
|
357
|
+
node
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
# List all the Chef::Node objects in the CouchDB. If inflate is set to true, you will get
|
|
361
|
+
# the full list of all Nodes, fully inflated.
|
|
362
|
+
def self.cdb_list(inflate=false)
|
|
363
|
+
couchdb = Chef::CouchDB.new
|
|
364
|
+
rs = couchdb.list("nodes", inflate)
|
|
365
|
+
if inflate
|
|
366
|
+
rs["rows"].collect { |r| r["value"] }
|
|
367
|
+
else
|
|
368
|
+
rs["rows"].collect { |r| r["key"] }
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def self.list(inflate=false)
|
|
373
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
374
|
+
if inflate
|
|
375
|
+
response = Hash.new
|
|
376
|
+
Chef::Search::Query.new.search(:node) do |n|
|
|
377
|
+
response[n.name] = n unless n.nil?
|
|
378
|
+
end
|
|
379
|
+
response
|
|
380
|
+
else
|
|
381
|
+
r.get_rest("nodes")
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# Load a node by name from CouchDB
|
|
386
|
+
def self.cdb_load(name)
|
|
387
|
+
couchdb = Chef::CouchDB.new
|
|
388
|
+
couchdb.load("node", name)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
# Load a node by name
|
|
392
|
+
def self.load(name)
|
|
393
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
394
|
+
r.get_rest("nodes/#{escape_node_id(name)}")
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
# Remove this node from the CouchDB
|
|
398
|
+
def cdb_destroy
|
|
399
|
+
@couchdb.delete("node", @name, @couchdb_rev)
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
# Remove this node via the REST API
|
|
403
|
+
def destroy
|
|
404
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
405
|
+
r.delete_rest("nodes/#{Chef::Node.escape_node_id(@name)}")
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
# Save this node to the CouchDB
|
|
409
|
+
def cdb_save
|
|
410
|
+
results = @couchdb.store("node", @name, self)
|
|
411
|
+
@couchdb_rev = results["rev"]
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
# Save this node via the REST API
|
|
415
|
+
def save
|
|
416
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
417
|
+
begin
|
|
418
|
+
r.put_rest("nodes/#{Chef::Node.escape_node_id(@name)}", self)
|
|
419
|
+
rescue Net::HTTPServerException => e
|
|
420
|
+
if e.response.code == "404"
|
|
421
|
+
r.post_rest("nodes", self)
|
|
422
|
+
else
|
|
423
|
+
raise e
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
self
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
# Create the node via the REST API
|
|
430
|
+
def create
|
|
431
|
+
r = Chef::REST.new(Chef::Config[:chef_server_url])
|
|
432
|
+
r.post_rest("nodes", self)
|
|
433
|
+
self
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
# Set up our CouchDB design document
|
|
437
|
+
def self.create_design_document
|
|
438
|
+
couchdb = Chef::CouchDB.new
|
|
439
|
+
couchdb.create_design_document("nodes", DESIGN_DOCUMENT)
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
# As a string
|
|
443
|
+
def to_s
|
|
444
|
+
"node[#{@name}]"
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
private
|
|
448
|
+
|
|
449
|
+
def append_recipes(recipes_to_append=[])
|
|
450
|
+
recipes_to_append.each do |recipe|
|
|
451
|
+
unless recipes.include?(recipe)
|
|
452
|
+
Chef::Log.debug("Adding recipe #{recipe}")
|
|
453
|
+
recipes << recipe
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
def self.escape_node_id(arg=nil)
|
|
459
|
+
arg.gsub(/\./, '_')
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
end
|
|
463
|
+
end
|