chef-dk 0.2.1 → 0.3.0
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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +2 -2
- data/README.md +25 -0
- data/lib/chef-dk/builtin_commands.rb +4 -0
- data/lib/chef-dk/cli.rb +46 -0
- data/lib/chef-dk/command/base.rb +4 -0
- data/lib/chef-dk/command/generator_commands/template.rb +2 -1
- data/lib/chef-dk/command/install.rb +105 -0
- data/lib/chef-dk/command/push.rb +123 -0
- data/lib/chef-dk/cookbook_profiler/identifiers.rb +5 -0
- data/lib/chef-dk/exceptions.rb +38 -0
- data/lib/chef-dk/generator.rb +16 -1
- data/lib/chef-dk/helpers.rb +1 -1
- data/lib/chef-dk/policyfile/cookbook_location_specification.rb +4 -0
- data/lib/chef-dk/policyfile/cookbook_locks.rb +73 -0
- data/lib/chef-dk/policyfile/reports/install.rb +70 -0
- data/lib/chef-dk/policyfile/reports/table_printer.rb +58 -0
- data/lib/chef-dk/policyfile/reports/upload.rb +70 -0
- data/lib/chef-dk/policyfile/solution_dependencies.rb +102 -8
- data/lib/chef-dk/policyfile/uploader.rb +37 -6
- data/lib/chef-dk/policyfile_compiler.rb +19 -5
- data/lib/chef-dk/policyfile_lock.rb +122 -9
- data/lib/chef-dk/policyfile_services/install.rb +131 -0
- data/lib/chef-dk/policyfile_services/push.rb +121 -0
- data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +6 -4
- data/lib/chef-dk/ui.rb +50 -0
- data/lib/chef-dk/version.rb +1 -1
- data/spec/shared/a_file_generator.rb +4 -1
- data/spec/test_helpers.rb +21 -0
- data/spec/unit/cli_spec.rb +100 -1
- data/spec/unit/command/base_spec.rb +23 -0
- data/spec/unit/command/exec_spec.rb +2 -2
- data/spec/unit/command/install_spec.rb +159 -0
- data/spec/unit/command/push_spec.rb +203 -0
- data/spec/unit/command/shell_init_spec.rb +1 -1
- data/spec/unit/policyfile/cookbook_location_specification_spec.rb +7 -0
- data/spec/unit/policyfile/cookbook_locks_spec.rb +13 -2
- data/spec/unit/policyfile/reports/install_spec.rb +115 -0
- data/spec/unit/policyfile/reports/upload_spec.rb +96 -0
- data/spec/unit/policyfile/solution_dependencies_spec.rb +1 -1
- data/spec/unit/policyfile/uploader_spec.rb +9 -12
- data/spec/unit/policyfile_lock_serialization_spec.rb +292 -0
- data/spec/unit/policyfile_services/install_spec.rb +170 -0
- data/spec/unit/policyfile_services/push_spec.rb +202 -0
- metadata +48 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f843be984f4748b386cfc76d5b13fc53a015ffeb
|
4
|
+
data.tar.gz: ff6284980c5d4db06395d5264fae6de79dd858f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c7ebbe3baf7bae4ca25072f6f62da8ee3c6cf14aa38d4bf7af8632338bed6f3b9949c06ee0e7283b958b1a61e38178a9bec9bbf9f04b3e0ad672e1c18bf99bf
|
7
|
+
data.tar.gz: 0d0c18793a5a724ba719d4237a3f8e58ae1a6ed9bb07020277df9c9ce96caac5ba5632728004d6e91caa2a080fc0b150ef32906a305c2326d697889d202a6fd7
|
data/CONTRIBUTING.md
CHANGED
@@ -23,8 +23,8 @@ Chef is built to last. We strive to ensure high quality throughout the Chef expe
|
|
23
23
|
this, we require a couple of things for all pull requests to Chef:
|
24
24
|
|
25
25
|
1. **Tests:** To ensure high quality code and protect against future regressions, we require all the
|
26
|
-
code in Chef to have at least unit test coverage.
|
27
|
-
|
26
|
+
code in Chef to have at least unit test coverage. Run ```bundle exec rspec``` from the project root
|
27
|
+
to execute the tests.
|
28
28
|
2. **Green Travis Run:** We use [Travis CI](https://travis-ci.org/) in order to run our tests
|
29
29
|
continuously on all the pull requests. We require the Travis runs to succeed on every pull
|
30
30
|
request before being merged.
|
data/README.md
CHANGED
@@ -108,6 +108,29 @@ environment to make ChefDK your primary ruby. For more information to
|
|
108
108
|
help you decide if this is desirable and instructions, see "Using ChefDK
|
109
109
|
as Your Primary Development Environment" below.
|
110
110
|
|
111
|
+
### `chef install`
|
112
|
+
`chef install` reads a Policyfile.rb document, which contains a
|
113
|
+
`run_list` and optional cookbook version constraints, finds a set of
|
114
|
+
cookbooks that provide the desired recipes and meet dependency
|
115
|
+
constraints, and emits a Policyfile.lock.json describing the expanded
|
116
|
+
run list and locked cookbook set. The Policyfile.lock.json can be used
|
117
|
+
to install the cookbooks on another machine. The policy lock can be
|
118
|
+
uploaded to a Chef Server (via the `chef push` command) to apply the
|
119
|
+
expanded run list and locked cookbook set to nodes in your
|
120
|
+
infrastructure. The Policyfile feature is currently incomplete and of
|
121
|
+
beta quality; changes to the Chef Server APIs will need to be
|
122
|
+
implemented before the feature is production-ready. The feature
|
123
|
+
currently operates in a compatibility mode. See the POLICYFILE_README.md
|
124
|
+
for further details.
|
125
|
+
|
126
|
+
### `chef push`
|
127
|
+
`chef push POLICY_GROUP` uploads a Policyfile.lock.json along with the cookbooks it
|
128
|
+
references to a Chef Server. The policy lock is applied to a
|
129
|
+
`POLICY_GROUP`, which is a set of nodes that share the same run list and
|
130
|
+
cookbook set. This command operates in compatibility mode and has the
|
131
|
+
same caveats as `chef install`. See the POLICYFILE_README.md for further
|
132
|
+
details.
|
133
|
+
|
111
134
|
### Using ChefDK as Your Primary Development Environment
|
112
135
|
|
113
136
|
By default, ChefDK only adds a few select applications to your `PATH`
|
@@ -173,6 +196,8 @@ You can use `rpm` to uninstall Chef Development Kit on RHEL based systems:
|
|
173
196
|
```
|
174
197
|
rpm -qa *chefdk*
|
175
198
|
yum remove <package>
|
199
|
+
rm -rf /opt/chefdk
|
200
|
+
rm -rf ~/.chefdk
|
176
201
|
```
|
177
202
|
|
178
203
|
### Ubuntu
|
@@ -27,5 +27,9 @@ ChefDK.commands do |c|
|
|
27
27
|
|
28
28
|
c.builtin "shell-init", :ShellInit, desc: "Initialize your shell to use ChefDK as your primary ruby"
|
29
29
|
|
30
|
+
c.builtin "install", :Install, desc: "Install cookbooks from a Policyfile and generate a locked cookbook set"
|
31
|
+
|
32
|
+
c.builtin "push", :Push, desc: "Push a local policy lock to a policy group on the server"
|
33
|
+
|
30
34
|
c.builtin "verify", :Verify, desc: "Test the embedded ChefDK applications"
|
31
35
|
end
|
data/lib/chef-dk/cli.rb
CHANGED
@@ -20,6 +20,8 @@ require 'chef-dk/version'
|
|
20
20
|
require 'chef-dk/commands_map'
|
21
21
|
require 'chef-dk/builtin_commands'
|
22
22
|
require 'chef-dk/helpers'
|
23
|
+
require 'chef-dk/ui'
|
24
|
+
require 'chef/util/path_helper'
|
23
25
|
|
24
26
|
module ChefDK
|
25
27
|
class CLI
|
@@ -53,6 +55,8 @@ BANNER
|
|
53
55
|
end
|
54
56
|
|
55
57
|
def run
|
58
|
+
sanity_check!
|
59
|
+
|
56
60
|
subcommand_name, *subcommand_params = argv
|
57
61
|
|
58
62
|
#
|
@@ -70,6 +74,10 @@ BANNER
|
|
70
74
|
show_help
|
71
75
|
exit 1
|
72
76
|
end
|
77
|
+
rescue OptionParser::InvalidOption => e
|
78
|
+
err(e.message)
|
79
|
+
show_help
|
80
|
+
exit 1
|
73
81
|
end
|
74
82
|
|
75
83
|
# If no subcommand is given, then this class is handling the CLI request.
|
@@ -131,5 +139,43 @@ BANNER
|
|
131
139
|
end
|
132
140
|
end
|
133
141
|
|
142
|
+
# Find PATH or Path correctly if we are on Windows
|
143
|
+
def path_key
|
144
|
+
ENV.keys.grep(/\Apath\Z/i).first
|
145
|
+
end
|
146
|
+
|
147
|
+
# upcase drive letters for comparison since ruby has a String#capitalize function
|
148
|
+
def drive_upcase(path)
|
149
|
+
if Chef::Platform.windows? && path[0] =~ /^[A-Za-z]$/ && path[1,2] == ":\\"
|
150
|
+
path.capitalize
|
151
|
+
else
|
152
|
+
path
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def env
|
157
|
+
ENV
|
158
|
+
end
|
159
|
+
|
160
|
+
# catch the cases where users setup only the embedded_bin_dir in their path, or
|
161
|
+
# when they have the embedded_bin_dir before the omnibus_bin_dir -- both of which will
|
162
|
+
# defeat appbundler and interact very badly with our intent.
|
163
|
+
def sanity_check!
|
164
|
+
paths = env[path_key].split(File::PATH_SEPARATOR)
|
165
|
+
paths.map! { |p| drive_upcase(Chef::Util::PathHelper.cleanpath(p)) }
|
166
|
+
embed_index = paths.index(drive_upcase(Chef::Util::PathHelper.cleanpath(omnibus_embedded_bin_dir)))
|
167
|
+
bin_index = paths.index(drive_upcase(Chef::Util::PathHelper.cleanpath(omnibus_bin_dir)))
|
168
|
+
if embed_index
|
169
|
+
if bin_index
|
170
|
+
if embed_index < bin_index
|
171
|
+
msg("WARN: #{omnibus_embedded_bin_dir} is before #{omnibus_bin_dir} in your #{path_key}, please reverse that order.")
|
172
|
+
msg("WARN: consider using the correct `chef shell-init <shell>` command to setup your environment correctly.")
|
173
|
+
end
|
174
|
+
else
|
175
|
+
msg("WARN: only #{omnibus_embedded_bin_dir} is present in your path, you must add #{omnibus_bin_dir} before that directory.")
|
176
|
+
msg("WARN: consider using the correct `chef shell-init <shell>` command to setup your environment correctly.")
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
134
180
|
end
|
135
181
|
end
|
data/lib/chef-dk/command/base.rb
CHANGED
@@ -23,7 +23,7 @@ module ChefDK
|
|
23
23
|
# chef generate template [path/to/cookbook_root] name --source=source_file
|
24
24
|
class Template < CookbookCodeFile
|
25
25
|
|
26
|
-
option :
|
26
|
+
option :source,
|
27
27
|
:short => "-s SOURCE_FILE",
|
28
28
|
:long => "--source SOURCE_FILE",
|
29
29
|
:description => "Copy content from SOURCE_FILE"
|
@@ -38,6 +38,7 @@ module ChefDK
|
|
38
38
|
|
39
39
|
def setup_context
|
40
40
|
super
|
41
|
+
Generator.add_attr_to_context(:content_source, config[:source])
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'chef-dk/command/base'
|
19
|
+
require 'chef-dk/ui'
|
20
|
+
require 'chef-dk/policyfile_services/install'
|
21
|
+
|
22
|
+
module ChefDK
|
23
|
+
module Command
|
24
|
+
|
25
|
+
class Install < Base
|
26
|
+
|
27
|
+
banner(<<-E)
|
28
|
+
Usage: chef install [ POLICY_FILE ] [options]
|
29
|
+
|
30
|
+
`chef install` evaluates a `Policyfile.rb` to find a compatible set of
|
31
|
+
cookbooks for the policy's run_list and caches them locally. It emits a
|
32
|
+
Policyfile.lock.json describing the locked cookbook set. You can use the
|
33
|
+
lockfile to install the locked cookbooks on another machine. You can also push
|
34
|
+
the lockfile to a "policy group" on a Chef Server and apply that exact set of
|
35
|
+
cookbooks to nodes in your infrastructure.
|
36
|
+
|
37
|
+
The Policyfile feature is incomplete and beta quality. See our detailed README
|
38
|
+
for more information.
|
39
|
+
|
40
|
+
https://github.com/opscode/chef-dk/blob/master/POLICYFILE_README.md
|
41
|
+
|
42
|
+
Options:
|
43
|
+
|
44
|
+
E
|
45
|
+
|
46
|
+
option :debug,
|
47
|
+
short: "-D",
|
48
|
+
long: "--debug",
|
49
|
+
description: "Enable stacktraces and other debug output",
|
50
|
+
default: false
|
51
|
+
|
52
|
+
attr_reader :policyfile_relative_path
|
53
|
+
|
54
|
+
attr_accessor :ui
|
55
|
+
|
56
|
+
def initialize(*args)
|
57
|
+
super
|
58
|
+
@ui = UI.new
|
59
|
+
|
60
|
+
@policyfile_relative_path = nil
|
61
|
+
@installer = nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def run(params = [])
|
65
|
+
apply_params!(params)
|
66
|
+
installer.run
|
67
|
+
0
|
68
|
+
rescue PolicyfileServiceError => e
|
69
|
+
handle_error(e)
|
70
|
+
1
|
71
|
+
end
|
72
|
+
|
73
|
+
def installer
|
74
|
+
@installer ||= PolicyfileServices::Install.new(policyfile: policyfile_relative_path, ui: ui, root_dir: Dir.pwd)
|
75
|
+
end
|
76
|
+
|
77
|
+
def debug?
|
78
|
+
!!config[:debug]
|
79
|
+
end
|
80
|
+
|
81
|
+
def handle_error(error)
|
82
|
+
ui.err("Error: #{error.message}")
|
83
|
+
if error.respond_to?(:cause) && error.cause
|
84
|
+
cause = error.cause
|
85
|
+
ui.err("Reason: #{cause.class.name}")
|
86
|
+
ui.err("")
|
87
|
+
ui.err(cause.message)
|
88
|
+
ui.err(cause.backtrace.join("\n")) if debug?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def apply_params!(params)
|
93
|
+
remaining_args = parse_options(params)
|
94
|
+
if remaining_args.size > 1
|
95
|
+
ui.err(banner)
|
96
|
+
return 1
|
97
|
+
else
|
98
|
+
@policyfile_relative_path = remaining_args.first
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'chef-dk/command/base'
|
19
|
+
require 'chef-dk/ui'
|
20
|
+
require 'chef-dk/policyfile_services/push'
|
21
|
+
|
22
|
+
module ChefDK
|
23
|
+
module Command
|
24
|
+
|
25
|
+
class Push < Base
|
26
|
+
|
27
|
+
banner(<<-E)
|
28
|
+
Usage: chef push POLICY_GROUP [ POLICY_FILE ] [options]
|
29
|
+
|
30
|
+
`chef push` Uploads an existing Policyfile.lock.json to a Chef Server, along
|
31
|
+
with all the cookbooks contained in the policy lock. The policy lock is applied
|
32
|
+
to a specific POLICY_GROUP, which is a set of nodes that share the same
|
33
|
+
run_list and cookbooks.
|
34
|
+
|
35
|
+
The Policyfile feature is incomplete and beta quality. See our detailed README
|
36
|
+
for more information.
|
37
|
+
|
38
|
+
https://github.com/opscode/chef-dk/blob/master/POLICYFILE_README.md
|
39
|
+
|
40
|
+
Options:
|
41
|
+
|
42
|
+
E
|
43
|
+
|
44
|
+
option :config_file,
|
45
|
+
short: "-c CONFIG_FILE",
|
46
|
+
long: "--config CONFIG_FILE",
|
47
|
+
description: "Path to configuration file"
|
48
|
+
|
49
|
+
option :debug,
|
50
|
+
short: "-D",
|
51
|
+
long: "--debug",
|
52
|
+
description: "Enable stacktraces and other debug output",
|
53
|
+
default: false
|
54
|
+
|
55
|
+
attr_reader :policyfile_relative_path
|
56
|
+
attr_reader :policy_group
|
57
|
+
|
58
|
+
attr_accessor :ui
|
59
|
+
|
60
|
+
def initialize(*args)
|
61
|
+
super
|
62
|
+
@push = nil
|
63
|
+
@ui = nil
|
64
|
+
@policy_group = nil
|
65
|
+
@policyfile_relative_path = nil
|
66
|
+
@chef_config = nil
|
67
|
+
@ui = UI.new
|
68
|
+
end
|
69
|
+
|
70
|
+
def run(params = [])
|
71
|
+
return 1 unless apply_params!(params)
|
72
|
+
push.run
|
73
|
+
0
|
74
|
+
rescue PolicyfileServiceError => e
|
75
|
+
handle_error(e)
|
76
|
+
1
|
77
|
+
end
|
78
|
+
|
79
|
+
def debug?
|
80
|
+
!!config[:debug]
|
81
|
+
end
|
82
|
+
|
83
|
+
def chef_config
|
84
|
+
return @chef_config if @chef_config
|
85
|
+
Chef::WorkstationConfigLoader.new(config[:config_file]).load
|
86
|
+
@chef_config = Chef::Config
|
87
|
+
end
|
88
|
+
|
89
|
+
def push
|
90
|
+
@push ||= PolicyfileServices::Push.new(policyfile: policyfile_relative_path,
|
91
|
+
ui: ui,
|
92
|
+
policy_group: policy_group,
|
93
|
+
config: chef_config,
|
94
|
+
root_dir: Dir.pwd)
|
95
|
+
end
|
96
|
+
|
97
|
+
def handle_error(error)
|
98
|
+
ui.err("Error: #{error.message}")
|
99
|
+
if error.respond_to?(:cause) && error.cause
|
100
|
+
cause = error.cause
|
101
|
+
ui.err("Reason: #{cause.class.name}")
|
102
|
+
ui.err("")
|
103
|
+
ui.err(cause.message)
|
104
|
+
ui.err(cause.backtrace.join("\n")) if debug?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def apply_params!(params)
|
109
|
+
remaining_args = parse_options(params)
|
110
|
+
if remaining_args.size < 1 or remaining_args.size > 2
|
111
|
+
ui.err(banner)
|
112
|
+
return false
|
113
|
+
else
|
114
|
+
@policy_group = remaining_args[0]
|
115
|
+
@policyfile_relative_path = remaining_args[1]
|
116
|
+
end
|
117
|
+
true
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
@@ -15,10 +15,15 @@
|
|
15
15
|
# limitations under the License.
|
16
16
|
#
|
17
17
|
|
18
|
+
# TODO: Chef should require its dependency correctly.
|
19
|
+
require 'singleton'
|
18
20
|
require 'chef/cookbook/cookbook_version_loader'
|
19
21
|
require 'digest/sha1'
|
22
|
+
|
20
23
|
require 'chef/digester'
|
21
24
|
|
25
|
+
require 'chef-dk/exceptions'
|
26
|
+
|
22
27
|
module ChefDK
|
23
28
|
module CookbookProfiler
|
24
29
|
class Identifiers
|
data/lib/chef-dk/exceptions.rb
CHANGED
@@ -17,6 +17,40 @@
|
|
17
17
|
|
18
18
|
module ChefDK
|
19
19
|
|
20
|
+
# Base class for errors raised by ChefDK::PolicyfileServices objects. Don't
|
21
|
+
# raise this directly, create a descriptively-named subclass. You can rescue
|
22
|
+
# this to catch all errors from PolicyfileServices objects though.
|
23
|
+
class PolicyfileServiceError < StandardError
|
24
|
+
end
|
25
|
+
|
26
|
+
class PolicyfileNotFound < PolicyfileServiceError
|
27
|
+
end
|
28
|
+
|
29
|
+
class LockfileNotFound < PolicyfileServiceError
|
30
|
+
end
|
31
|
+
|
32
|
+
class PolicyfileInstallError < PolicyfileServiceError
|
33
|
+
|
34
|
+
attr_reader :cause
|
35
|
+
|
36
|
+
def initialize(message, cause)
|
37
|
+
super(message)
|
38
|
+
@cause = cause
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
class PolicyfilePushError < PolicyfileServiceError
|
44
|
+
|
45
|
+
attr_reader :cause
|
46
|
+
|
47
|
+
def initialize(message, cause)
|
48
|
+
super(message)
|
49
|
+
@cause = cause
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
20
54
|
class CachedCookbookNotFound < StandardError
|
21
55
|
end
|
22
56
|
|
@@ -58,4 +92,8 @@ module ChefDK
|
|
58
92
|
|
59
93
|
class MissingCookbookLockData < StandardError
|
60
94
|
end
|
95
|
+
|
96
|
+
class InvalidLockfile < StandardError
|
97
|
+
end
|
98
|
+
|
61
99
|
end
|