-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SHACK-141] Lookup cookbooks in repo for remote target execution #82
Changes from all commits
d165bf7
2aef8ae
2a15dbd
aa08031
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,6 +78,9 @@ commands: | |
<RECIPE>. For example: | ||
|
||
chef target converge myec2node path/to/cookbook/recipe.rb | ||
chef target converge myec2node path/to/cookbook | ||
chef target converge myec2node cookbook_name | ||
chef target converge myec2node cookbook_name::recipe_name | ||
|
||
ARGUMENTS: | ||
<TARGET> The host or IP address to converge. Can also be an SSH or WinRM URL | ||
|
@@ -90,7 +93,11 @@ commands: | |
the name of the user you wanted to create. | ||
<RECIPE> The recipe to converge. This can be provided as one of: | ||
1. Full path to a recipe file | ||
|
||
2. Cookbook name. First we check the working directory for this | ||
cookbook, then we check in the chef repository path. If a | ||
cookbook is found we run the default recipe. | ||
3. This behaves similarly to 'cookbook name' above, but it also allows | ||
you to specify which recipe to use from the cookbook. | ||
root_description: "Whether to use root permissions on the target. Defaults to true." | ||
identity_file: "SSH identity file to use when connecting." | ||
ssl: | ||
|
@@ -100,6 +107,8 @@ commands: | |
Use --ssl-no-verify when using SSL for WinRM and | ||
the remote host is using a self-signed certificate. | ||
Current default: %1 | ||
cookbook_repo_paths: | ||
desc: "Comma separated list of cookbook repository paths." | ||
|
||
|
||
# Status updates shared across commands. | ||
|
@@ -237,11 +246,36 @@ errors: | |
Property '%1' did not match the 'key=value' syntax required | ||
|
||
CHEFVAL004: | | ||
Please provide a recipe in the form 'path/to/recipe/file', 'cookbook_name', | ||
or 'cookbook_name::recipe_name'. | ||
Please provide a recipe in the form 'path/to/recipe/file.rb', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we require the '.rb'? If not, maybe file[.rb] in the usual CLI convention for optional things? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do require the |
||
'path/to/cookbook', 'cookbook_name' or 'cookbook_name::recipe_name'. | ||
|
||
You provided '%1'. | ||
|
||
CHEFVAL005: | | ||
The cookbook provided could not be loaded. Ensure it contains a valid | ||
'metadata.rb'. | ||
|
||
Cookbook path is '%1'. | ||
|
||
CHEFVAL006: | | ||
Cookbook '%1' could not be found in any of the following directorys | ||
|
||
%2 | ||
|
||
CHEFVAL007: | | ||
There is no default recipe in cookbook '%2'. Please provide the name of the recipe to run, for example: | ||
%2::some_recipe | ||
|
||
Cookbook path is '%1'. | ||
|
||
CHEFVAL008: | | ||
There is no recipe named '%2' in the cookbook '%4', which I found at '%1'. | ||
|
||
Please include the name of the recipe you wish to converge on the remote target. | ||
|
||
These are the available recipes in '%4': | ||
%3 | ||
|
||
# General errors/unknown errors are handled with CHEFINT | ||
CHEFINT001: | | ||
An unexpected error has occurred: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,14 +23,17 @@ | |
require "chef-workstation/ui/terminal" | ||
require "chef-workstation/log" | ||
require "chef-workstation/config" | ||
require "chef-workstation/recipe_lookup" | ||
require "chef-config/config" | ||
require "chef-config/logger" | ||
require "chef/log" | ||
|
||
module ChefWorkstation | ||
module Command | ||
class Target | ||
class Converge < ChefWorkstation::Command::Base | ||
T = ChefWorkstation::Text.commands.target.converge | ||
TS = ChefWorkstation::Text.status | ||
Config = ChefWorkstation::Config | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a pattern that we follow throughout the project. It reduces the visual noise of Name::Space::Goes::Here for frequently referenced modules in a class. Is there anything unhealthy about doing that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I got rid of this specific instance because it overlaps with I actually think long term we should rename the method |
||
|
||
option :root, | ||
:long => "--[no-]root", | ||
|
@@ -52,19 +55,26 @@ class Converge < ChefWorkstation::Command::Base | |
option :ssl, | ||
:long => "--[no-]ssl", | ||
:short => "-s", | ||
:description => T.ssl.desc(Config.connection.winrm.ssl), | ||
:description => T.ssl.desc(ChefWorkstation::Config.connection.winrm.ssl), | ||
:boolean => true, | ||
:default => Config.connection.winrm.ssl | ||
:default => ChefWorkstation::Config.connection.winrm.ssl | ||
|
||
option :ssl_verify, | ||
:long => "--[no-]ssl-verify", | ||
:short => "-s", | ||
:description => T.ssl.verify_desc(Config.connection.winrm.ssl_verify), | ||
:description => T.ssl.verify_desc(ChefWorkstation::Config.connection.winrm.ssl_verify), | ||
:boolean => true, | ||
:default => Config.connection.winrm.ssl_verify | ||
:default => ChefWorkstation::Config.connection.winrm.ssl_verify | ||
|
||
option :cookbook_repo_paths, | ||
:long => "--cookbook-repo-paths PATH", | ||
:description => T.cookbook_repo_paths.desc, | ||
:default => ChefWorkstation::Config.chef.cookbook_repo_paths, | ||
:proc => Proc.new { |paths| paths.split(",") } | ||
|
||
def run(params) | ||
validate_params(cli_arguments) | ||
configure_chef | ||
|
||
target = cli_arguments.shift | ||
|
||
|
@@ -109,6 +119,15 @@ def validate_params(params) | |
end | ||
end | ||
|
||
# Now that we are leveraging Chef locally we want to perform some initial setup of it | ||
def configure_chef | ||
ChefConfig.logger = ChefWorkstation::Log | ||
# Setting the config isn't enough, we need to ensure the logger is initialized | ||
# or automatic initialization will still go to stdout | ||
Chef::Log.init(ChefWorkstation::Log) | ||
Chef::Log.level = ChefWorkstation::Log.level | ||
end | ||
|
||
def format_properties(string_props) | ||
properties = {} | ||
string_props.each do |a| | ||
|
@@ -147,21 +166,22 @@ def parse_converge_args(converge_args, cli_arguments) | |
if recipe_strategy?(cli_arguments) | ||
recipe_specifier = cli_arguments.shift | ||
ChefWorkstation::Log.debug("Beginning to look for recipe specified as #{recipe_specifier}") | ||
|
||
# First, we check to see if the user has specified the full path (absolute or relative) | ||
# to a file. If they have, we assume that is a recipe they want to execute. | ||
if File.file?(recipe_specifier) | ||
ChefWorkstation::Log.debug("#{recipe_specifier} is a valid path to a recipe") | ||
converge_args[:recipe_path] = recipe_specifier | ||
spinner_msg = TS.converge.converging_recipe(recipe_specifier) | ||
recipe_path = recipe_specifier | ||
else | ||
raise "Cannot specify anything besides full path yet" | ||
rl = RecipeLookup.new(config[:cookbook_repo_paths]) | ||
cookbook_path_or_name, optional_recipe_name = rl.split(recipe_specifier) | ||
cookbook = rl.load_cookbook(cookbook_path_or_name) | ||
recipe_path = rl.find_recipe(cookbook, optional_recipe_name) | ||
end | ||
converge_args[:recipe_path] = recipe_path | ||
spinner_msg = TS.converge.converging_recipe(recipe_specifier) | ||
else | ||
resource = converge_args[:resource_type] = cli_arguments.shift | ||
resource_name = converge_args[:resource_name] = cli_arguments.shift | ||
converge_args[:resource_type] = cli_arguments.shift | ||
converge_args[:resource_name] = cli_arguments.shift | ||
converge_args[:properties] = format_properties(cli_arguments) | ||
full_rs_name = "#{resource}[#{resource_name}]" | ||
full_rs_name = "#{converge_args[:resource_type]}[#{converge_args[:resource_name]}]" | ||
ChefWorkstation::Log.debug("Converging resource #{full_rs_name} on target") | ||
spinner_msg = TS.converge.converging_resource(full_rs_name) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and below, s/repo/repository - we're trying to keep output very clear and explicit without abbreviations or shorthand.