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
@@ -52,7 +52,9 @@ module ChefFS
52
52
  child_paths[name].each do |path|
53
53
  Dir.mkdir(path)
54
54
  end
55
- make_child_entry(name)
55
+ child = make_child_entry(name)
56
+ @children << child
57
+ child
56
58
  end
57
59
 
58
60
  def json_class
@@ -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
- args.map do |arg|
96
- if !@chef_fs_config.base_path && !ChefFS::PathUtils.is_absolute?(arg)
97
- # Check if chef repo path is specified to give a better error message
98
- @chef_fs_config.require_chef_repo_path
99
- ui.error("Attempt to use relative path '#{arg}' when current directory is outside the repository path")
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
@@ -1,3 +1,3 @@
1
1
  module ChefFS
2
- VERSION = "1.4"
2
+ VERSION = "1.5"
3
3
  end
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'
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