diff options
author | Vikram Karve <vikram.karve@progress.com> | 2022-01-26 17:15:25 +0530 |
---|---|---|
committer | Vikram Karve <vikram.karve@progress.com> | 2022-01-27 10:48:26 +0530 |
commit | 75d4fb87007721487cb5f5ce56f768f98f6b514b (patch) | |
tree | 6d339974fb1d1cd4fbec929fc8f35c396da77448 | |
parent | 909e1e1177ca17f6e5ec0dff0920c4bfb9def0da (diff) | |
download | chef-75d4fb87007721487cb5f5ce56f768f98f6b514b.tar.gz |
Initial draft of knife developer guide
Signed-off-by: Vikram Karve <vikram.karve@progress.com>
-rw-r--r-- | knife/docs/dev/README.md | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/knife/docs/dev/README.md b/knife/docs/dev/README.md new file mode 100644 index 0000000000..76cab6a7be --- /dev/null +++ b/knife/docs/dev/README.md @@ -0,0 +1,45 @@ +# Developer's Guide to Knife + +## Overview + +knife is a command-line tool that provides an interface between a local Chef repository and the Chef Infra Server. Read more about knife [here](https://docs.chef.io/workstation/knife/). + +## Development setup + +To setup knife for development- +1. Fork and clone the [chef repository](https://github.com/chef/chef) in GitHub. +1. Ensure you have Ruby 3.x installed on your system. You will additionally need tools such as `make` and `gcc`. These are usually already present on most Linux distributions or on your macOS. +1. Navigate to chef/knife and run `bundle install`. +1. You can run knife commands in this setup by executing `bundle exec knife <subcommand> <argument> <options>`. +1. Refer to the article [Setting up Knife](https://docs.chef.io/workstation/knife_setup/) for help with necessary configuration. +1. byebug or your preferred Ruby debugger can be used to step through the execution flow. + +## Execution Flow + +The execution starts by instantiating the `Chef::Application::Knife` class with its `run` instance method being invoked. Ref [knife/bin/knife](https://github.com/chef/chef/blob/main/knife/bin/knife). The `Chef::Application` class helps work with CLI command options through the `Mixlib::CLI` module. This `run` instance method in turn invokes the `Chef::Knife`'s `run` class method. `Chef::Knife` acts as the base class for some of the classes associated with knife subcommands such as `Chef::Knife::NodeCreate`, `Chef::Knife::SupermarketList`, `Chef::Knife::Bootstrap`, etc. The role of `Chef::Knife` is summarized here: + +- Identify the subcommand supplied. +- Merge subcommand specific CLI options, if any. +- Load dependencies to help subclass perform subcommand action. +- Instantiate the associated subclass. +- Set up a local-mode Chef server if chef-zero is configured. +- Run the subcommand action. + +With this design, most classes associated with subcommands only need to implement the `run` instance method, while the setup and context is broadly taken care of by `Chef::Knife`. The `Chef::Knife::Bootstrap` class is somewhat of an exception here, as its functionality requires a rather elaborate set of methods and additional classes. That said, not all classes associated with subcommands directly inherit `Chef::Knife`. These inherit the `Chef::ChefFS::Knife` class of the `Chef::ChefFS` module. `Chef::ChefFS::Knife` happens to be a subclass of `Chef::Knife` to avoid redundancy. `Chef::ChefFS` [module](https://www.rubydoc.info/gems/chef/Chef/ChefFS) encapsulates classes and modules that help map the Chef server objects to the local chef repository using a file/directory analogy. It also employs a parallel thread utility to speed up command execution. Examples of such Knife classes are `Chef::Knife::Upload`, `Chef::Knife::Diff` & `Chef::Knife::List`. + +## Knife Bootstrap + +As `bootstrap` is a remote/distributed operation, there are several phases to it: +- Set up knife plugin, if needed. +- Validate if the specified protocol to connect to client node is supported. +- Validate if the transport and policy options are correct. +- Establish connection with the server where chef client is to be deployed. The connection is identified by a `Chef::Knife::Bootstrap::TrainConnector` instance. +- Define the `Chef::Node` instance that represents the server & update this object in Chef server. The class `Chef::Knife::Bootstrap::ClientBuilder` encapsulates this functionality. +- Update the Chef vault item(s) so the new node has access to those. The class `Chef::Knife::Bootstrap::ChefVaultHandler` encapsulates this functionality. +- Prepare the `bootstrap.bat` or `bootstrap.sh` script based on the bootstrap template. +- Copy and execute the bootstrap script on the remote server. + +## Knife Plugins + +The choice of mapping subcommand action to `Chef::Knife` subclass makes it easy to author knife custom plugins. These can help with extending knife capabilities for specific cloud platforms or customize knife behavior for a subset of subcommands. Follow the instructions [here](https://docs.chef.io/workstation/plugin_knife_custom/) to develop your own knife plugin. Detailed documentation on writing knife cloud plugins is available [here](https://github.com/chef/knife-cloud/blob/main/README.md). + |