-
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 3 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 repo path. If a cookbook | ||
is found we run the default recipe. | ||
3. Cookbook and recipe name. Same as 2 but we run the specified | ||
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. Suggest: |
||
recipe instead of the default recipe. | ||
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: "Location of the Chef repo containing cookbooks to execute on targets. Comma seperated list of paths" | ||
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. Suggest: |
||
|
||
|
||
# Status updates shared across commands. | ||
|
@@ -237,11 +246,35 @@ 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: | | ||
Cookbook provided could not be loaded. Ensure it contains a valid | ||
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. "The cookbook provided..." |
||
'metadata.rb' or a single recipe file named 'recipe.rb' only. | ||
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. If we don't need to give them a choice, let's not. I'm more in favor of concise actionable messages than exhaustive ones - if they want more info, they can look up the error online which will give us a good place to expand on details. In a future iteration, we could probably inspect the location and determine specifically the thing that is missing? 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.
Yeah, I'm a fan of this |
||
|
||
Cookbook path is '%1'. | ||
|
||
CHEFVAL006: | | ||
Cookbook '%1' could not be found in any of the following directorys | ||
|
||
%2 | ||
|
||
CHEFVAL007: | | ||
Cookbook '%2' did not contain a default recipe and you did not specify | ||
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. Suggest:
|
||
a named recipe to run. Specify a valid recipe path or name. | ||
|
||
Cookbook path is '%1'. | ||
|
||
CHEFVAL008: | | ||
Could not find a recipe named '%2' in your cookbook. Please specify | ||
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. Suggest:
|
||
a valid recipe name. | ||
|
||
Cookbook path is '%1'. | ||
Available recipes are: %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.