diff options
author | Mary Jinglewski <mjinglewski@chef.io> | 2019-04-11 16:14:52 -0400 |
---|---|---|
committer | Tim Smith <tsmith@chef.io> | 2019-04-23 16:53:22 -0700 |
commit | 02b2e2c9fcbdfcb4ccb14265e454611bddc3f782 (patch) | |
tree | 614681bf32ce99d7d3f528c90b07e635c4793a52 | |
parent | 6e906e0ec25a5041ce05960d278be507d0793c4e (diff) | |
download | chef-02b2e2c9fcbdfcb4ccb14265e454611bddc3f782.tar.gz |
Copyedits, part 2
Signed-off-by: Mary Jinglewski <mjinglewski@chef.io>
9 files changed, 97 insertions, 148 deletions
diff --git a/docs/dev/design_documents/data_collector.md b/docs/dev/design_documents/data_collector.md index f99dc13241..cb2b0cb406 100644 --- a/docs/dev/design_documents/data_collector.md +++ b/docs/dev/design_documents/data_collector.md @@ -35,7 +35,7 @@ All payloads will be sent to the Data Collector server via HTTP POST to the URL Optionally, payloads may also be written out to multiple HTTP endpoints or JSON files on the local filesystem (of the node running `chef-client`) by specifying the `data_collector_output_locations` configuration parameter. -For the initial implementation, transmissions to the Data Collector server can optionally be authenticated with the use of a pre-shared token which will be sent in a HTTP header. Given that the receiver is not the Chef Server, existing methods of using a Chef `client` key to authenticate the request are unavailable. +For the initial implementation, transmissions to the Data Collector server can optionally be authenticated with the use of a pre-shared token, which will be sent in a HTTP header. Given that the receiver is not the Chef Server, existing methods of using a Chef `client` key to authenticate the request are unavailable. #### Configuration @@ -467,8 +467,7 @@ The remainder of document will focus entirely on the nuts and bolts of the Data ### Action Collection Integration Most of the work is done by a separate Action Collection to track the actions of Chef resources. -If the Data Collector is not enabled, it never registers with the Action Collection and -no work will be done by the Action Collection to track resources. +If the Data Collector is not enabled, it never registers with the Action Collection and no work will be done by the Action Collection to track resources. ### Additional Collected Information @@ -479,7 +478,7 @@ The Data Collector also collects: - the node - formatted error output for exceptions -Most of this is done through hooking events directly in the Data Collector itself. The ErrorHandlers module is broken out into a module, which is directly mixed into the Data Collector to separate that concern out into a different file. This ErrorHandlers module is straightforward with fairly little state, but involves just a lot of hooked methods. +Most of this is done through hooking events directly in the Data Collector itself. The ErrorHandlers module is broken out into a module, which is directly mixed into the Data Collector, to separate that concern out into a different file. This ErrorHandlers module is straightforward with fairly little state, but involves a lot of hooked methods. ### Basic Configuration Modes @@ -508,38 +507,39 @@ Chef::Config[:data_collector][:token] = "mytoken" This works for chef-clients, which are configured to hit a Chef server, but use a custom non-Chef-Automate endpoint for reporting, or for chef-solo/zero users. -XXX: There is also the `Chef::Config[:data_collector][:output_locations] = { uri: [ "https://chef.acme.local/myendpoint.html" ] }` method -- which will behave -differently, particularly on non-chef-solo use cases. In that case, the Data Collector `server_url` will still be automatically derived from the `chef_server_url` and -the Data Collector will attempt to contact that endpoint, but with the token being supplied it will use that and will not use Chef Server authentication, and the -server should 403 back, and if `raise_on_failure` is left to the default of false then it will simply drop that failure and continue without raising, which will -appear to work, and output will be send to the configured `output_locations`. Note that the presence of a token flips all external URIs to using the token so that -it is **not** possible to use this feature to talk to both a Chef Automate endpoint and a custom URI reporting endpoint (which would seem to be the most useful of an -incredibly marginally useful feature and it does not work). But given how hopelessly complicated this is, the recommendation is to use the `server_url` and to avoid -using any `url` options in the `output_locations` since that feature is fairly poorly designed at this point in time. +XXX: There is also the `Chef::Config[:data_collector][:output_locations] = { uri: [ "https://chef.acme.local/myendpoint.html" ] }` method, which will behave differently, particularly on non-chef-solo use cases. +In that case, the Data Collector `server_url` will still be automatically derived from the `chef_server_url` and the Data Collector will attempt to contact that endpoint. +But with the token being supplied, the Data Collector will use that token and will not use Chef Server authentication. +Thus, the server should 403 back. +Also, if `raise_on_failure` is left to the default of `false`, then the Data Collector will simply drop that failure and continue without raising, which will appear to work, and output will be send to the configured `output_locations`. +Note that the presence of a token flips all external URIs to using the token. So it is **not** possible to use this feature to talk to both a Chef Automate endpoint and a custom URI reporting endpoint. +This would seem to be the most useful of an incredibly marginally useful feature and it does not work. +But given how hopelessly complicated this is, the recommendation is to use the `server_url` and to avoid using any `url` options in the `output_locations` since that feature is fairly poorly designed at this point in time. ### Resiliency to Failures -The Data Collector in Chef >= 15.0 is resilient to failures that occur anywhere in the main loop of the `Chef::Client#run` method. In order to do this there is a lot -of defensive coding around internal data structures that may be `nil`. (e.g. failures before the node is loaded will result in the node being nil). The spec tests for -the Data Collector now run through a large sequence of events (which must, unfortunately, be manually kept in sync with the events in the Chef::Client if those events -are ever 'moved' around) which should catch any issues in the Data Collector with early failures. The specs should also serve as documentation for what the messages -will look like under different failure conditions. The goal was to keep the format of the messages to look as near as possible to the same schema as possible even -in the presence of failures. But some data structures will be entirely empty. +The Data Collector in Chef >= 15.0 is resilient to failures that occur anywhere in the main loop of the `Chef::Client#run` method. +In order to do this, there is a lot of defensive coding around internal data structures that may be `nil`. (e.g. failures before the node is loaded will result in the node being nil.) +The spec tests for the Data Collector now run through a large sequence of events -- which must, unfortunately, be manually kept in sync with the events in the Chef::Client if those events are ever 'moved' around -- which should catch any issues in the Data Collector with early failures. +The specs should also serve as documentation for what the messages will look like under different failure conditions. +The goal was to keep the format of the messages to look as near as possible to the same schema as possible, even in the presence of failures, but some data structures will be entirely empty. -When the Data Collector fails extraordinarily early it still sends both a start and an end message. This will happen if it fails so early that it would not normally -have sent a start message. +When the Data Collector fails extraordinarily early, it still sends both a start and an end message. +This will happen if it fails so early that it would not normally have sent a start message. ### Decision to Be Enabled This is complicated due to over-design and is encapsulated in the `#should_be_enabled?` method and the ConfigValidation module. The `#should_be_enabled?` message and -ConfigValidation should probably be merged into one renamed Config module to isolate the concern of processing the Chef::Config options and doing the correct thing. +ConfigValidation should probably be merged into one renamed Config module to isolate the concern of processing the Chef::Config options and of doing the correct thing. ### Run Start and Run End Message modules -These are separated out into their own modules, which are very deliberately not mixed into the main Data Collector. They use the Data Collector and Action Collection -public interfaces. They are stateless themselves. This keeps the collaboration between them and the Data Collector very easy to understand. The start message is -relatively simple and straightforwards. The complication of the end message is mostly due to walking through the Action Collection and all the collected action -records from the entire run, along with a lot of defensive programming to deal with early errors. +These are separated out into their own modules, which are very deliberately not mixed into the main Data Collector. +They use the Data Collector and Action Collection public interfaces. +They are stateless themselves. +This keeps the collaboration between them and the Data Collector very easy to understand. +The start message is relatively simple and straightforwards. +The complication of the end message is mostly due to walking through the Action Collection and all the collected action records from the entire run, along with a lot of defensive programming to deal with early errors. ### Relevant Event Sequence @@ -560,7 +560,7 @@ As it happens in the actual chef-client run: * failures during cookbook resolution will cause `events.cookbook_resolution_failed(node, exception)` here and skip to #13 * failures during cookbook synch will cause `events.cookbook_sync_failed(node, exception)` and skip to #13 10. `events.cookbook_compilation_start(run_context)` -11. < the resource events happen here which hit the Action Collection, may throw any of the other failure events > +11. < the resource events happen here, which hit the Action Collection, may throw any of the other failure events > 12. `events.converge_complete` or `events.converge_failed(exception)` 13. `run_status.stop_clock` 14. `run_status.exception = exception` if it failed diff --git a/docs/dev/design_documents/ohai_cookbook_segment.md b/docs/dev/design_documents/ohai_cookbook_segment.md index 09c2dcbf69..4cbc387aac 100644 --- a/docs/dev/design_documents/ohai_cookbook_segment.md +++ b/docs/dev/design_documents/ohai_cookbook_segment.md @@ -15,7 +15,7 @@ Ohai plugins in all synchronized cookbooks after cookbook synchronization. As a Chef User, I want my Ohai plugins synchronized with my cookbooks, - So that I don't incure more unavoidable round-trips to the Chef Server. + So that I don't incur more unavoidable round-trips to the Chef Server. As a Chef Developer, I want Ohai plugins as a first-class object, @@ -23,14 +23,14 @@ Ohai plugins in all synchronized cookbooks after cookbook synchronization. ## Specification -The "segments" of a cookbook will be extended to include an "ohai" segment. In this segment there will be plugins which are intended to be copied to the Ohai `plugin_path`. All files in this segment will be copied, recursively, maintaining directory structure. +The "segments" of a cookbook will be extended to include an "ohai" segment. In this segment, there will be plugins, which are intended to be copied to the Ohai `plugin_path`. All files in this segment will be copied, recursively, maintaining directory structure. -In the `Chef::RunContext::CookbookCompiler#compile` method a phase will be added after `compile_libraries` and before `compile_attributes` which will copy the Ohai plugins from the cookbook segment and will load all of the discovered plugins. +In the `Chef::RunContext::CookbookCompiler#compile` method, a phase will be added after `compile_libraries` and before `compile_attributes`, which will copy the Ohai plugins from the cookbook segment and will load all of the discovered plugins. -The plugins will be copied from `<cookbookname>/ohai` into `/etc/chef/ohai/cookbook-plugins/<cookbookname>` as their top level directory (recursively). The state of the entire +The plugins will be copied from `<cookbookname>/ohai` into `/etc/chef/ohai/cookbook-plugins/<cookbookname>` as their top level directory (recursively). The state of the entire subdirectory tree under `/etc/chef/ohai/cookbook-plugins` will be managed fully by chef-client so that any files which are not synchronized by chef-client will be removed, so that removal of a plugin from a cookbook or removal of the cookbook from `run_list` will result in the plugin being removed on the target host. -The plugins directory will work similarly to libraries and other directions in that there will be no control over the inclusion of plugins below the level of the inclusion of the cookbook itself in the `run_list`. +The plugins directory will work similarly to libraries and other directions, in that there will be no control over the inclusion of plugins below the level of the inclusion of the cookbook itself in the `run_list`. -When plugins override other plugins on loading, and in particular when cookbook plugins override core plugins, they should WARN the user. This will address the case where a user has included a custom plugin and Ohai is later extended with similar functionality in the same namespace. The custom plugin should take precedence for backwards compatibility. There should be a way to silence the warning with a DSL method added to the custom plugin.
\ No newline at end of file +When plugins override other plugins on loading, and in particular when cookbook plugins override core plugins, they should WARN the user. This will address the case where a user has included a custom plugin and Ohai is later extended with similar functionality in the same namespace. The custom plugin should take precedence for backwards compatibility. There should be a way to silence the warning with a DSL method added to the custom plugin.
\ No newline at end of file diff --git a/docs/dev/design_documents/resource_before_notifications.md b/docs/dev/design_documents/resource_before_notifications.md index 35828036b6..cfae566289 100644 --- a/docs/dev/design_documents/resource_before_notifications.md +++ b/docs/dev/design_documents/resource_before_notifications.md @@ -13,20 +13,20 @@ Let users trigger another resource prior to an action happening. So that I don't unnecessarily run my preconditions on every single Chef run. As a Chef user, - I want Chef to run me an action if a resource updates, + I want Chef to run an action if a resource updates, So that I don't have to implement the resource test logic in my recipe. ## Specification -We add a new :before timing which causes a notification to happen +We add a new `:before` timing which causes a notification to happen *before* the resource actually updates. If the resource will not actually update, this event does not fire. The events you can specify would become: -- :before - before the resource updates, but *only* if an update will occur. -- :immediately - after the resource updates, but *only* if an update occurred. -- :delayed - after the resource updates, at the end of the run. +- `:before` - before the resource updates, but *only* if an update will occur. +- `:immediately` - after the resource updates, but *only* if an update occurred. +- `:delayed` - after the resource updates, at the end of the run. ```ruby package "foo" do @@ -39,18 +39,18 @@ service "blah" do end ``` -This will work for both subscribes and notifies. +This will work for both `subscribes` and `notifies`. ### Backwards Compatibility -This will only affect resources which have :before on them, and will +This will only affect resources, which have `:before` on them, and will not modify any existing resources or recipes. ### Implementation -There is a tricky implementation detail here, because both the test ("is my -package version lower than the latest?") and the set ("call rpm and update the -package") part of a resource are both part of the action. Chef only runs one +There is a tricky implementation detail here, because both the test part -- "is my +package version lower than the latest?" -- and the set part -- "call rpm and update the +package"-- of a resource are both part of the action. Chef only runs one action to run at a time, and it seems ill-advised to change that without a lot of extra thinking. @@ -67,11 +67,11 @@ end The execution of the package upgrade looks like this: -1. If :before events are on the resource: - a. raise an error if the resource does not support why-run. - b. Turn on why-run temporarily. +1. If `:before` events are on the resource: + a. raise an error if the resource does not support `why-run`. + b. Turn on `why-run` temporarily. c. Run the action. - d. Send the notification if updated_by_last_action? is true. - e. Turn off why-run. + d. Send the notification if `updated_by_last_action?` is true. + e. Turn off `why-run`. 2. Run the action (for real!). -3. Send :immediate or :delayed notifications if updated_by_last_action? is true. +3. Send `:immediate` or `:delayed` notifications if `updated_by_last_action?` is true. diff --git a/docs/dev/design_documents/resource_file_content_verification.md b/docs/dev/design_documents/resource_file_content_verification.md index a67c8a5786..0ddcfeb439 100644 --- a/docs/dev/design_documents/resource_file_content_verification.md +++ b/docs/dev/design_documents/resource_file_content_verification.md @@ -8,15 +8,15 @@ user-supplied instructions before deploying the new content. The `verify` attribute of the `file`, `template`, `cookbook_file`, and `remote_file` resources will take a user-provided block or string. At converge time, a block will be passed the path to a temporary file -holding the proposed content for the file. If the block returns `true` +holding the proposed content for the file. If the block returns `true`, the provider will continue to update the file on disk as -appropriate. If the block returns false, the provider will raise an +appropriate. If the block returns `false`, the provider will raise an error. If a string argument to verify is passed, it will then be executed as -a system command. If the command's return code indicates success (0 on -unix-like system) the provider will continue to update the file on -disk as appropriate. If the command's return code indicates failure, +a system command. If the command's return code indicates success -- 0 on +unix-like system -- the provider will continue to update the file on +disk as appropriate. If the command's return code indicates failure, the provider will raise an error. The path to the temporary file with the proposed content will be @@ -24,12 +24,12 @@ available by using Ruby's sprinf formatting: "%{path}" -other variables may be made available to commands in the future. +Other variables may be made available to commands in the future. If no verification block or string is supplied by the user, the provider assumes the content is valid. -Multiple verify blocks may be provided by the user. All given verify +Multiple verify blocks may be provided by the user. All given verify block must pass before the content is deployed. As an example: @@ -72,7 +72,7 @@ template "/tmp/bat" do end ``` -Users could use this feature to shell out to tools which check the +Users could use this feature to shell out to tools, which check the configuration: ```ruby @@ -81,7 +81,7 @@ template "/etc/nginx.conf" do end ``` -Chef may ship built-in verifiers for common checks such as +Chef may ship built-in verifiers for common checks, such as content-type verification. Built-in verifiers can be used by passing well-known symbols to the verify attribute: @@ -95,7 +95,7 @@ end Typos and bugs in a template can lead Chef to render invalid configuration files on a node. In some cases, this will cause the -related service to fail a notified restart, bringing down the user's +related service to fail a notified restart and bring down the user's application. One hopes to catch such errors in testing, but that is not always possible. diff --git a/docs/dev/design_documents/resource_guard_interpreters.md b/docs/dev/design_documents/resource_guard_interpreters.md index 06eb37343a..4367cc8a34 100755 --- a/docs/dev/design_documents/resource_guard_interpreters.md +++ b/docs/dev/design_documents/resource_guard_interpreters.md @@ -2,8 +2,8 @@ The *guard interpreter* is a feature of Chef resources that allows authors to specify their choice of Chef resource classes to evaluate a guard expression (i.e. `only_if` or -`not_if` block). The goal of this capability is to reduce the complexity in both number of languages -and boilerplate code found within a Chef recipe. +`not_if` block). The goal of this capability is to reduce the complexity in both the number of languages +and the boilerplate code found within a Chef recipe. Guard interpreter customization makes the Chef DSL *Delightful(tm)*. @@ -13,7 +13,7 @@ The original impetus for guard interpreters involved a common user expectation that when guard expressions were present in a `script` resource, the same interpreter used to evaluate the `script` resource (e.g. `bash`, `csh`, `powershell`) would be used to evaluate the guard expression. It turns out -this is not the case (more on this later) and thus user expectations were not +this is not the case -- more on this later -- and thus user expectations were not being met. An open source ticket for the Chef project describes a typical instance of @@ -78,9 +78,7 @@ These definitions are used throughout the discussion: ## Overview Guard expressions for all resources have been extended to include an attribute named `guard_interpreter` that takes the short name symbol of a Chef resource to be -used to evaluate script guards. This is -useful for testing conditions to ensure idempotence for non-idempotent resources such as script -resources. The goals in doing this are: +used to evaluate script guards. This is useful for testing conditions to ensure idempotence for non-idempotent resources such as script resources. The goals in doing this are: * To address [CHEF-4553](https://tickets.opscode.com/browse/CHEF-4553) -- simplify convoluted expressions such as that below for Windows users @@ -94,13 +92,11 @@ not_if 'powershell -noninteractive -noprofile -command "exit [int32]((Get-Execut users of the OS as possible ## Behavioral impact on Chef resources -At a high level, here are the changes proposed and now accepted to simplify conditional -execution of resource actions: +At a high level, here are the changes proposed and now accepted to simplify conditional execution of resource actions: * Add a `guard_interpreter` attribute to the `Chef::Resource` class that can take a symbol that corresponds to the name of a Chef resource derived from - `Chef::Resource::Script`. This guard interpreter resource will be used to evaluate the script - command passed to the guard. + `Chef::Resource::Script`. This guard interpreter resource will be used to evaluate the script command passed to the guard. * Truth or falsehood of such a guard is determined by whether the resource evaluating the script guard is updated, i.e. runs the script without raising an exception and without the script returning a non-success code (0 is the @@ -222,32 +218,23 @@ end The documented behavior for guards can be found at <http://docs.chef.io/resource_common.html>. Guards are expressed via the optional -`not_if` and `only_if` attributes -- the expression following the attribute +`not_if` and `only_if` attributes. The expression following the attribute may be either a block or a string. ### Guard conditional semantics overview -Guards allow for conditional execution of a resource. Before executing the action for the -resource, Chef will evaluate the expression to produce a Ruby `true` or +Guards allow for conditional execution of a resource. Before executing the action for the resource, Chef will evaluate the expression to produce a Ruby `true` or `false` value that is utilized in determining whether to execute the resource's action or to skip it: -1. If the **guard_interpreter resource** is **not** specified for the resource, when a string is passed to a guard, the existing implementation executes the `/bin/sh` interpreter on Unix or -`cmd.exe` on Windows with that string to be evaluated as a script by the -interpreter. Chef will execute the interpreter with the code supplied to the -string; if the interpreter exits with a 0 (success) code, this is -interpreted as a Ruby `true` value, otherwise it is `false`. -2. When a block is passed to a guard, the code in the block will be executed, + 1. If the **guard_interpreter resource** is **not** specified for the resource, when a string is passed to a guard, the existing implementation executes the `/bin/sh` interpreter on Unix or `cmd.exe` on Windows with that string to be evaluated as a script by the interpreter. Chef will execute the interpreter with the code supplied to the string; if the interpreter exits with a 0 (success) code, this is interpreted as a Ruby `true` value, otherwise it is `false`. + 2. When a block is passed to a guard, the code in the block will be executed, and the value of the last line of code executed by the block will be the Boolean value of the block, converted to a Boolean value in a manner consistent with the Ruby `!!` operator, resulting in either the value `true` or `false`. -3. If the aforementioned string or block expression was supplied to an -`only_if` attribute, the action of the resource containing the attribute will be skipped if -the expression evaluated to `false` and executed if it evaluated to `true`. -4. If the expression was supplied to a `not_if` attribute, the behavior of the -resource is the inverse of that for `only_if`; the resource action is executed -if the expression evaluated to `false` and skipped if it evaluated to `true`. + 3. If the aforementioned string or block expression was supplied to an `only_if` attribute, the action of the resource containing the attribute will be skipped if the expression evaluated to `false` and executed if it evaluated to `true`. + 4. If the expression was supplied to a `not_if` attribute, the behavior of the resource is the inverse of that for `only_if`; the resource action is executed if the expression evaluated to `false` and skipped if it evaluated to `true`. This specification of guard behavior is accurate without the inclusion of `guard_interpreter` features described in this document. The @@ -257,43 +244,21 @@ than `/bin/sh` or `cmd.exe` and is described below. ### Conditional semantics with the guard_interpreter attribute In Chef Client versions 11.12.0 and later, the `guard_interpreter` attribute -was introduced which provides the following behavior: - -1. When the `guard_interpreter` attribute is specified in the resource as a value -other than `:default`, a **guard interpreter resource** of the type specified in the -`guard_interpreter` attribute is created with its `code` attribute set to the -value of the string passed to the guard attribute. The guard interpreter resource's action -will be executed to produce a truth value. -2. If the resource action updates the resource, the value is `true`. - Resources can only be updated if the interpreter used by the resource - specified in the `guard_interpreter` attribute returns a success code, `0` - by default, though this can be overridden in attributes specified to the - resource as guard arguments. Anything other than a success code results in - the guard evaluating as `false`. +was introduced, which provides the following behavior: + + 1. When the `guard_interpreter` attribute is specified in the resource as a value other than `:default`, a **guard interpreter resource** of the type specified in the `guard_interpreter` attribute is created with its `code` attribute set to the value of the string passed to the guard attribute. The guard interpreter resource's action will be executed to produce a truth value. + 2. If the resource action updates the resource, the value is `true`. Resources can only be updated if the interpreter used by the resource specified in the `guard_interpreter` attribute returns a success code, `0` by default, though this can be overridden in attributes specified to the resource as guard arguments. Anything other than a success code results in the guard evaluating as `false`. ### script resource conditional semantics -To enable the usage as guard resources of resources derived from `Chef::Resource::Script`, -known colloquially as script resources, all such resources when executed as -guard resources will handle the exception `Mixlib::Shellout::ShellCommandFailed`. +To enable the usage as guard resources of resources derived from `Chef::Resource::Script`, known colloquially as script resources, all such resources when executed as guard resources will handle the exception `Mixlib::Shellout::ShellCommandFailed`. -By doing this, usage of script resources has the same conditional and -exception behavior as the case described earlier when a string is passed to a -`not_if` or `only_if` guard attribute since this exception is raised precisely -in the case where a string passed as a guard would have been evaluated by -/bin/sh or cmd.exe as exiting with a failure status code. +By doing this, usage of script resources has the same conditional and exception behavior as the case described earlier when a string is passed to a `not_if` or `only_if` guard attribute since this exception is raised precisely in the case where a string passed as a guard would have been evaluated by /bin/sh or cmd.exe as exiting with a failure status code. -This gives any script resource, for example bash, the ability to behave -like the string argument usage for guards except that an alternative -interpreter to `/bin/sh` is used to execute the command. This extends the range of shell -script languages that may be used in guard expressions. +This gives any script resource -- for example, bash -- the ability to behave like the string argument usage for guards, except that an alternative interpreter to `/bin/sh` is used to execute the command. This extends the range of shell script languages that may be used in guard expressions. ### `powershell_script` guard_interpreter example -Use of `guard_interpreter` for the `powershell_script` resource addresses -[CHEF-4553](https://tickets.opscode.com/browse/CHEF-4553). Without -`guard_interpreter`, a user of the `powershell_script` resource who would like to use the same PowerShell -language in the expression passed to the guard resource to the following -cumbersome solution: +Use of `guard_interpreter` for the `powershell_script` resource addresses [CHEF-4553](https://tickets.opscode.com/browse/CHEF-4553). Without `guard_interpreter`, a user of the `powershell_script` resource who would like to use the same PowerShell language in the expression passed to the guard resource to the following cumbersome solution: ```ruby # Yuk. Let me look up all the right cli args to powershell.exe. @@ -305,9 +270,7 @@ powershell_script "oldguard" do end ``` -With the `guard_interpreter` attribute, we have -the following more concise, less cumbersome, and less error-prone expression -for the same `powershell_script` use case given above: +With the `guard_interpreter` attribute, we have the following more concise, less cumbersome, and less error-prone expression for the same `powershell_script` use case given above: ```ruby # So PowerShell. Such short. @@ -319,20 +282,13 @@ end ``` ### Guard attribute inheritance -A new change is that a resource used within the context of a guard may inherit -some attributes from the resource that contains the guard. +A new change is that a resource used within the context of a guard may inherit some attributes from the resource that contains the guard. Inheritance follows these rules: -* An attribute in a guard interpreter resource is inherited from the parent resource only if the - attribute is in a set of inheritable attributes defined by the type of the - guard resource -* To be inherited from the parent, the attribute must not have been specified as a parameter to the guard - command -- whatever is passed to the guard command will override any parent - specification of the attribute. -* The Chef `script` resource, i.e. `Chef::Resource::Script`, and all resources derived from it, - including `bash`, `python`, and `powershell_script`, inherit the following - attributes from the parent resource: +* An attribute in a guard interpreter resource is inherited from the parent resource only if the attribute is in a set of inheritable attributes defined by the type of the guard resource +* To be inherited from the parent, the attribute must not have been specified as a parameter to the guard command -- whatever is passed to the guard command will override any parent specification of the attribute. +* The Chef `script` resource, i.e. `Chef::Resource::Script`, and all resources derived from it, including `bash`, `python`, and `powershell_script`, inherit the following attributes from the parent resource: `:cwd` `:environment` @@ -341,16 +297,9 @@ Inheritance follows these rules: `:user` `:umask` -* Resource types may define additional rules for inheritance -- the - `powershell_script` resource has additional behaviors described in a - subsequent section. +* Resource types may define additional rules for inheritance -- the `powershell_script` resource has additional behaviors described in a subsequent section. -In general, the utility of inheritance derives from a common case where setting system -configuration through a Chef resource requires some external state such as an -environment variable, alternate user identity, or current directory, and -testing the current state to ensure idempotence through a guard requires the -same state. Inheritance allows that state to be expressed no more than once -through the Chef DSL. +In general, the utility of inheritance derives from a common case where setting system configuration through a Chef resource requires some external state such as an environment variable, alternate user identity, or current directory, and testing the current state to ensure idempotence through a guard requires the same state. Inheritance allows that state to be expressed no more than once through the Chef DSL. ### Simplification through attribute inheritance diff --git a/docs/dev/design_documents/resource_load_and_converge_methods.md b/docs/dev/design_documents/resource_load_and_converge_methods.md index e08eddb399..b7046d1892 100644 --- a/docs/dev/design_documents/resource_load_and_converge_methods.md +++ b/docs/dev/design_documents/resource_load_and_converge_methods.md @@ -22,7 +22,7 @@ blessed way to get the actual value of the resource. This proposal adds ### `load_current_value`: in-place resource load -When using `action`, one needs a way to load the *actual* system value of the resource, so that it can be compared to the desired value and a decision made as to whether to change anything. +When using `action`, one needs a way to load the *actual* system value of the resource, so that it can be compared to the desired value, and a decision made as to whether to change anything. When the resource writer defines `load_current_value` on the resource class, it can be called to load the real system value into the resource. Before any action runs, this will be used by `load_current_resource` to load the resource. `action` will do some important work before calling the new method: @@ -60,9 +60,9 @@ end #### Non-existence -To appropriately handle actual value loading, the user needs a way to specify that the actual value legitimately does not exist (rather than simply not filling in the object and getting `nil`s in it). If `load_current_value` raises `Chef::Exceptions::ActualValueDoesNotExist`, the new resource will be discarded and `current_resource` becomes `nil`. The `current_value_does_not_exist!` method can be called to raise this. +To appropriately handle actual value loading, the user needs a way to specify that the actual value legitimately does not exist, rather than simply not filling in the object and getting `nil`s in it. If `load_current_value` raises `Chef::Exceptions::ActualValueDoesNotExist`, the new resource will be discarded and `current_resource` becomes `nil`. The `current_value_does_not_exist!` method can be called to raise this. -NOTE: The alternative was to have users return `false` if the resource does not exist; but I didn't want users to be forced into the ceremony of a trailing `true` line. +NOTE: The alternative was to have users return `false` if the resource does not exist, but I didn't want users to be forced into the ceremony of a trailing `true` line. ```ruby load_current_value do @@ -173,7 +173,7 @@ end > The easiest way to write a resource must be the most correct one. -There is a subtle pitfall when updating a resource, where the user has set *some* values, but not all. One can easily end up writing a resource which will overwrite perfectly good system properties with their defaults, which can cause instability. If the user does not specify a property, it is generally preferable to preserve its existing value rather than overwrite it. +There is a subtle pitfall when updating a resource, where the user has set *some* values, but not all. One can easily end up writing a resource, which will overwrite perfectly good system properties with their defaults, and can cause instability. If the user does not specify a property, it is generally preferable to preserve its existing value rather than overwrite it. To prevent this, referencing the bare property in an `action` will now yield the *actual* value if load_current_value succeeded, and the *default* value if we are creating a new resource (if `load_current_value` raised `ActualValueDoesNotExist`). @@ -210,7 +210,7 @@ There are no backwards-compatibility issues with this because it only applies to #### Compound Resource Convergence -Some resources perform several different (possibly expensive) operations depending on what is set. `converge_if_changed :attribute1, :attribute2, ... do` allows the user to target different groups of changes based on exactly which attributes have changed: +Some resources perform several different (possibly expensive) operations, depending on what is set. `converge_if_changed :attribute1, :attribute2, ... do` allows the user to target different groups of changes based on exactly which attributes have changed: ```ruby class File < Chef::Resource diff --git a/docs/dev/design_documents/resource_property_validation_messaging.md b/docs/dev/design_documents/resource_property_validation_messaging.md index 36a1ac92cb..20ead5e625 100644 --- a/docs/dev/design_documents/resource_property_validation_messaging.md +++ b/docs/dev/design_documents/resource_property_validation_messaging.md @@ -1,6 +1,6 @@ # Resource Validation Messaging -Custom resources provide multiple property validators allowing authors to control property input beyond just simple data types. Authors can expect strings to match predefined strings, match a regex, or return true from a callback method. This gives the author great control over the input data, but doesn't provide the consumer with much information when the validator fails. This RFC provides the author with the ability control the error text when the validator fails. +Custom resources provide multiple property validators, allowing authors to control property input beyond just simple data types. Authors can expect strings to match predefined strings, match a regex, or return true from a callback method. This gives the author great control over the input data, but doesn't provide the consumer with much information when the validator fails. This RFC provides the author with the ability to control the error text when the validator fails. ## Motivation diff --git a/docs/dev/design_documents/self_documenting_resources.md b/docs/dev/design_documents/self_documenting_resources.md index d1aa2282f6..d18d86111d 100644 --- a/docs/dev/design_documents/self_documenting_resources.md +++ b/docs/dev/design_documents/self_documenting_resources.md @@ -1,6 +1,6 @@ # Self Documenting Resources -Chef has allowed organizations to embrace infrastructure as code, but with codified infrastructure comes the need for accurate documentation for that codebase. This RFC aims to improve the ability to document resources within Chef code so that we can ensure documentation is accurate and automatically generated. This is applicable to both resources within chef-client and those which ship in cookbooks. +Chef has allowed organizations to embrace infrastructure as code, but with codified infrastructure comes the need for accurate documentation for that codebase. This RFC aims to improve the ability to document resources within Chef code, so that we can ensure documentation is accurate and automatically generated. This is applicable to both resources within chef-client and those which ship in cookbooks. ## Motivation @@ -20,7 +20,7 @@ so that I can easily write cookbooks utilizing custom resources ## Specification -This dessign specifies 4 documentation methods in custom resources: +This design specifies 4 documentation methods in custom resources: ### description (resource level) @@ -28,7 +28,7 @@ Description is a String value that allows the user to describe the resource and ### introduced (resource level) -Introduced is a String value that documents when the resource was introduced. In a cookbook this would be a particular cookbook release. In the chef-client itself this would be a chef-client release. +Introduced is a String value that documents when the resource was introduced. In a cookbook, this would be a particular cookbook release. In the chef-client itself, this would be a chef-client release. ### examples (resource level) @@ -77,4 +77,4 @@ end ## Reasons for not using YARD -The goal of introducing minimal DSL changes is to extend the existing data already contained within each resource to include the necessary information to fully document resources. Documenting resources in YARD would require significant duplication of documentation, which most users probably won't do. Out of the box even without these new DSL extensions we can already document resources fairly well. These new extensions incentivize users to provide us with a small amount of addition information that would fully fill out the resource documentation. Within our own configuration management industry other projects have gone different routes to document their equivalence of resources. One project uses a hybrid comment / code method, which feels bolted on and overly complex. The other project fully documents code in comments which results in near 100% duplication of effort. Simple DSL extensions seem like they are more likely to be utilized and provide a better user experience.
\ No newline at end of file +The goal of introducing minimal DSL changes is to extend the existing data already contained within each resource to include the necessary information to fully document resources. Documenting resources in YARD would require significant duplication of documentation, which most users probably won't do. Out of the box, even without these new DSL extensions, we can already document resources fairly well. These new extensions incentivize users to provide us with a small amount of additional information that would fully fill out the resource documentation. Within our own configuration management industry, other projects have gone different routes to document their equivalence of resources. One project uses a hybrid comment / code method, which feels bolted on and overly complex. The other project fully documents code in comments, which results in near 100% duplication of effort. Simple DSL extensions seem like they are more likely to be utilized and provide a better user experience.
\ No newline at end of file diff --git a/docs/dev/design_documents/server_enforced_recipes.md b/docs/dev/design_documents/server_enforced_recipes.md index be81f4a9b5..3441c43621 100644 --- a/docs/dev/design_documents/server_enforced_recipes.md +++ b/docs/dev/design_documents/server_enforced_recipes.md @@ -39,7 +39,7 @@ secondary run list for several reasons: * Cookbooks are Chef Server objects that are organization-scoped and subject to authorization restrictions. Allowing some cookbooks to be global requires - additional complexity which is not needed for the intended uses. + additional complexity, which is not needed for the intended uses. * Cookbooks have versions and dependencies, which have to be solved. There are several ways this could be addressed, but all options introduce unneeded complexity into the solution. @@ -47,7 +47,7 @@ secondary run list for several reasons: the enforced recipe code may have no control over the node data, roles, JSON files, or policyfiles used by the nodes being managed. * Other cookbook features, such as libraries and the various flavors of - resources and providers set ruby constants which could interfere with the + resources and providers, set ruby constants, which could interfere with the correct operation of the end user's cookbooks. * Templates and cookbook files would be useful, but expert practitioners will be able to be effective without them. |