knife-essentials 1.4 → 1.5
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.
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'chef_fs/knife'
|
|
2
|
+
|
|
3
|
+
class Chef
|
|
4
|
+
class Knife
|
|
5
|
+
remove_const(:Converge) if const_defined?(:Converge) && Converge.name == 'Chef::Knife::Converge' # override Chef's version
|
|
6
|
+
class Converge < ::ChefFS::Knife
|
|
7
|
+
ChefFS = ::ChefFS
|
|
8
|
+
banner "knife converge [PATTERN1 ... PATTERNn]"
|
|
9
|
+
|
|
10
|
+
deps do
|
|
11
|
+
require 'chef'
|
|
12
|
+
require 'chef/log'
|
|
13
|
+
require 'chef/application/client'
|
|
14
|
+
require 'chef_fs/file_system'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
option :port,
|
|
18
|
+
:short => '-p',
|
|
19
|
+
:long => '--port=PORT',
|
|
20
|
+
:description => "Port to listen on (default: 8889)"
|
|
21
|
+
|
|
22
|
+
attr_accessor :exit_code
|
|
23
|
+
|
|
24
|
+
def configure_chef
|
|
25
|
+
super
|
|
26
|
+
|
|
27
|
+
self.exit_code = 0
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def run
|
|
31
|
+
self.exit_code = 0
|
|
32
|
+
# Figure out the run list based on the passed-in objects
|
|
33
|
+
run_list = get_run_list(name_args)
|
|
34
|
+
|
|
35
|
+
if exit_code != 0
|
|
36
|
+
exit exit_code
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Configure and run chef client
|
|
40
|
+
if config[:config_file]
|
|
41
|
+
dot_chef = File.dirname(config[:config_file])
|
|
42
|
+
if File.basename(dot_chef) == '.chef'
|
|
43
|
+
# Override default locations to go in the .chef directory, since we are knife.
|
|
44
|
+
Chef::Config[:client_key] = File.join(dot_chef, 'client.pem') if !Chef::Config[:client_key] || Chef::Config[:client_key] == Chef::Config.platform_specific_path("/etc/chef/client.pem")
|
|
45
|
+
Chef::Config[:file_cache_path] = File.join(dot_chef, 'cache') if Chef::Config[:file_cache_path] == Chef::Config.platform_specific_path("/var/chef/cache")
|
|
46
|
+
Chef::Config[:file_backup_path] = File.join(dot_chef, 'backups') if Chef::Config[:file_backup_path] == Chef::Config.platform_specific_path("/var/chef/backup")
|
|
47
|
+
Chef::Config[:file_checksum_path] = File.join(dot_chef, 'checksums') if Chef::Config[:file_checksum_cache] == "/var/chef/checksums"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
client = Chef::Application::Client.new
|
|
51
|
+
if run_list != ''
|
|
52
|
+
client.config[:override_runlist] = run_list
|
|
53
|
+
end
|
|
54
|
+
client.configure_logging # Bypass configure_chef, which we've already done adequately.
|
|
55
|
+
client.setup_application
|
|
56
|
+
client.run_application
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def get_run_list(args)
|
|
60
|
+
result = []
|
|
61
|
+
args.each do |arg|
|
|
62
|
+
if arg.start_with?('recipe[') || arg.start_with?('role[')
|
|
63
|
+
result += arg.split(',')
|
|
64
|
+
|
|
65
|
+
else
|
|
66
|
+
begin
|
|
67
|
+
ChefFS::FileSystem.list(chef_fs, pattern_arg_from(arg)).each do |entry|
|
|
68
|
+
if entry.parent && entry.parent.path == '/cookbooks'
|
|
69
|
+
result << "recipe[#{entry.name}]"
|
|
70
|
+
|
|
71
|
+
elsif entry.parent && entry.parent.name == 'recipes' &&
|
|
72
|
+
entry.parent.parent && entry.parent.parent.parent && entry.parent.parent.parent.name == 'cookbooks' &&
|
|
73
|
+
entry.name[-3..-1] == '.rb'
|
|
74
|
+
cookbook_name = entry.parent.parent.name
|
|
75
|
+
recipe_name = entry.name[0..-4]
|
|
76
|
+
result << "recipe[#{cookbook_name}::#{recipe_name}]"
|
|
77
|
+
|
|
78
|
+
elsif entry.parent && entry.parent.name == 'roles'
|
|
79
|
+
result << "role[#{entry.name}]"
|
|
80
|
+
|
|
81
|
+
else
|
|
82
|
+
ui.error "arguments must be cookbooks, recipes or roles! #{format_path{e.entry}} is not a cookbook, recipe or role."
|
|
83
|
+
self.exit_code = 1
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
rescue ChefFS::FileSystem::OperationFailedError => e
|
|
87
|
+
"#{format_path_with_root(e.entry)} #{e.reason}."
|
|
88
|
+
self.exit_code = 1
|
|
89
|
+
rescue ChefFS::FileSystem::NotFoundError => e
|
|
90
|
+
ui.error "#{format_path(e.entry)}: No such file or directory"
|
|
91
|
+
self.exit_code = 1
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
result.join(',')
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
data/lib/chef_fs/knife.rb
CHANGED
|
@@ -67,6 +67,13 @@ module ChefFS
|
|
|
67
67
|
@chef_fs_config = ChefFS::Config.new(Chef::Config)
|
|
68
68
|
|
|
69
69
|
ChefFS::Parallelizer.threads = (Chef::Config[:concurrency] || 10) - 1
|
|
70
|
+
|
|
71
|
+
if Chef::Config[:chef_server_url].to_sym == :local
|
|
72
|
+
local_url = start_local_server
|
|
73
|
+
Chef::Config[:chef_server_url] = local_url
|
|
74
|
+
Chef::Config[:client_key] = nil
|
|
75
|
+
Chef::Config[:validation_key] = nil
|
|
76
|
+
end
|
|
70
77
|
end
|
|
71
78
|
|
|
72
79
|
def chef_fs
|
|
@@ -90,17 +97,19 @@ module ChefFS
|
|
|
90
97
|
end
|
|
91
98
|
|
|
92
99
|
def pattern_args_from(args)
|
|
100
|
+
args.map { |arg| pattern_arg_from(arg) }
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def pattern_arg_from(arg)
|
|
93
104
|
# TODO support absolute file paths and not just patterns? Too much?
|
|
94
105
|
# Could be super useful in a world with multiple repo paths
|
|
95
|
-
|
|
96
|
-
if
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
exit(1)
|
|
101
|
-
end
|
|
102
|
-
ChefFS::FilePattern.relative_to(@chef_fs_config.base_path, arg)
|
|
106
|
+
if !@chef_fs_config.base_path && !ChefFS::PathUtils.is_absolute?(arg)
|
|
107
|
+
# Check if chef repo path is specified to give a better error message
|
|
108
|
+
@chef_fs_config.require_chef_repo_path
|
|
109
|
+
ui.error("Attempt to use relative path '#{arg}' when current directory is outside the repository path")
|
|
110
|
+
exit(1)
|
|
103
111
|
end
|
|
112
|
+
ChefFS::FilePattern.relative_to(@chef_fs_config.base_path, arg)
|
|
104
113
|
end
|
|
105
114
|
|
|
106
115
|
def format_path(entry)
|
|
@@ -110,5 +119,67 @@ module ChefFS
|
|
|
110
119
|
def parallelize(inputs, options = {}, &block)
|
|
111
120
|
ChefFS::Parallelizer.parallelize(inputs, options, &block)
|
|
112
121
|
end
|
|
122
|
+
|
|
123
|
+
def locate_config_file
|
|
124
|
+
super
|
|
125
|
+
if !config[:config_file]
|
|
126
|
+
# If the config file doesn't already exist, find out where it should be,
|
|
127
|
+
# and create it.
|
|
128
|
+
repo_dir = discover_repo_dir(Dir.pwd)
|
|
129
|
+
if repo_dir
|
|
130
|
+
dot_chef = File.join(repo_dir, ".chef")
|
|
131
|
+
if !File.directory?(dot_chef)
|
|
132
|
+
Dir.mkdir(dot_chef)
|
|
133
|
+
end
|
|
134
|
+
knife_rb = File.join(dot_chef, "knife.rb")
|
|
135
|
+
if !File.exist?(knife_rb)
|
|
136
|
+
ui.warn("No configuration found. Creating .chef/knife.rb in #{repo_dir} ...")
|
|
137
|
+
File.open(knife_rb, "w") do |file|
|
|
138
|
+
file.write <<EOM
|
|
139
|
+
chef_server_url 'local'
|
|
140
|
+
chef_repo_path File.dirname(File.dirname(__FILE__))
|
|
141
|
+
cookbook_path File.join(chef_repo_path, "cookbooks")
|
|
142
|
+
EOM
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
config[:config_file] = knife_rb
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def discover_repo_dir(dir)
|
|
151
|
+
%w(.chef cookbooks data_bags environments roles).each do |subdir|
|
|
152
|
+
return dir if File.directory?(File.join(dir, subdir))
|
|
153
|
+
end
|
|
154
|
+
# If this isn't it, check the parent
|
|
155
|
+
parent = File.dirname(dir)
|
|
156
|
+
if parent && parent != dir
|
|
157
|
+
discover_repo_dir(parent)
|
|
158
|
+
else
|
|
159
|
+
nil
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def start_local_server
|
|
164
|
+
begin
|
|
165
|
+
require 'chef_zero/server'
|
|
166
|
+
rescue LoadError
|
|
167
|
+
STDERR.puts <<EOM
|
|
168
|
+
ERROR: chef-zero must be installed to use local-server mode! To install:
|
|
169
|
+
|
|
170
|
+
gem install chef-zero
|
|
171
|
+
|
|
172
|
+
EOM
|
|
173
|
+
exit(1)
|
|
174
|
+
end
|
|
175
|
+
require 'chef_fs/chef_fs_data_store'
|
|
176
|
+
server_options = {}
|
|
177
|
+
server_options[:data_store] = ChefFS::ChefFSDataStore.new(local_fs)
|
|
178
|
+
server_options[:log_level] = Chef::Log.level
|
|
179
|
+
server_options[:port] = 8889
|
|
180
|
+
server = ChefZero::Server.new(server_options)
|
|
181
|
+
server.start_background
|
|
182
|
+
server.url
|
|
183
|
+
end
|
|
113
184
|
end
|
|
114
185
|
end
|
data/lib/chef_fs/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: knife-essentials
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '1.
|
|
4
|
+
version: '1.5'
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -118,6 +118,7 @@ files:
|
|
|
118
118
|
- LICENSE
|
|
119
119
|
- README.rdoc
|
|
120
120
|
- Rakefile
|
|
121
|
+
- lib/chef/knife/converge_essentials.rb
|
|
121
122
|
- lib/chef/knife/delete_essentials.rb
|
|
122
123
|
- lib/chef/knife/deps_essentials.rb
|
|
123
124
|
- lib/chef/knife/diff_essentials.rb
|