Class: ChefApply::Action::Base
- Inherits:
-
Object
- Object
- ChefApply::Action::Base
- Defined in:
- lib/chef_apply/action/base.rb
Overview
Derive new Actions from Action::Base “target_host” is a TargetHost that the action is being applied to. May be nil
if the action does not require a target.
“config” is hash containing any options that your command may need
Implement perform_action to perform whatever action your class is intended to do. Run time will be captured via telemetry and categorized under “:action” with the unqualified class name of your Action.
Direct Known Subclasses
ConvergeTarget, GenerateLocalPolicy, GenerateTempCookbook, InstallChef::Base
Constant Summary collapse
- PATH_MAPPING =
{ chef_client: { windows: "cmd /c C:/opscode/chef/bin/chef-client", other: "/opt/chef/bin/chef-client", }, cache_path: { windows: '#{ENV[\'APPDATA\']}/chef-workstation', other: "/var/chef-workstation", }, read_chef_report: { windows: "type #{run_report}", other: "cat /var/chef-workstation/cache/run-report.json", }, delete_chef_report: { windows: "If (Test-Path #{run_report}){ Remove-Item -Force -Path #{run_report} }", other: "rm -f /var/chef-workstation/cache/run-report.json", }, tempdir: { windows: "%TEMP%", other: "$TMPDIR", }, mkdir: { windows: "New-Item -ItemType Directory -Force -Path ", other: "mkdir -p ", }, # TODO this is duplicating some stuff in the install_chef folder # TODO maybe we start to break these out into actual functions, so # we don't have to try and make really long one-liners mktemp: { windows: "$parent = [System.IO.Path]::GetTempPath(); [string] $name = [System.Guid]::NewGuid(); $tmp = New-Item -ItemType Directory -Path (Join-Path $parent $name); $tmp.FullName", other: "bash -c 'd=$(mktemp -d -p${TMPDIR:-/tmp} chef_XXXXXX); chmod 777 $d; echo $d'" }, delete_folder: { windows: "Remove-Item -Recurse -Force –Path", other: "rm -rf", } }
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#target_host ⇒ Object
readonly
Returns the value of attribute target_host.
Instance Method Summary collapse
-
#escape_windows_path(p) ⇒ Object
Trying to perform File or Pathname operations on a Windows path with ‘' characters in it fails.
-
#initialize(config = {}) ⇒ Base
constructor
A new instance of Base.
- #name ⇒ Object
- #notify(action, *args) ⇒ Object
- #perform_action ⇒ Object
- #run(&block) ⇒ Object
-
#run_chef(working_dir, config, policy) ⇒ Object
Chef will try ‘downloading’ the policy from the internet unless we pass it a valid, local file in the working directory.
Constructor Details
#initialize(config = {}) ⇒ Base
Returns a new instance of Base.
34 35 36 37 38 39 |
# File 'lib/chef_apply/action/base.rb', line 34 def initialize(config = {}) c = config.dup @target_host = c.delete :target_host # Remaining options are for child classes to make use of. @config = c end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
32 33 34 |
# File 'lib/chef_apply/action/base.rb', line 32 def config @config end |
#target_host ⇒ Object (readonly)
Returns the value of attribute target_host.
32 33 34 |
# File 'lib/chef_apply/action/base.rb', line 32 def target_host @target_host end |
Instance Method Details
#escape_windows_path(p) ⇒ Object
Trying to perform File or Pathname operations on a Windows path with ‘' characters in it fails. So lets convert them to ’/‘ which these libraries handle better.
110 111 112 113 114 115 |
# File 'lib/chef_apply/action/base.rb', line 110 def escape_windows_path(p) if family == :windows p = p.tr("\\", "/") end p end |
#name ⇒ Object
134 135 136 |
# File 'lib/chef_apply/action/base.rb', line 134 def name self.class.name.split("::").last end |
#notify(action, *args) ⇒ Object
142 143 144 145 146 |
# File 'lib/chef_apply/action/base.rb', line 142 def notify(action, *args) return if @notification_handler.nil? ChefApply::Log.debug("[#{self.class.name}] Action: #{action}, Action Data: #{args}") @notification_handler.call(action, args) if @notification_handler end |
#perform_action ⇒ Object
138 139 140 |
# File 'lib/chef_apply/action/base.rb', line 138 def perform_action raise NotImplemented end |
#run(&block) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/chef_apply/action/base.rb', line 117 def run(&block) @notification_handler = block Telemeter.timed_action_capture(self) do begin perform_action rescue StandardError => e # Give the caller a chance to clean up - if an exception is # raised it'll otherwise get routed through the executing thread, # providing no means of feedback for the caller's current task. notify(:error, e) @error = e end end # Raise outside the block to ensure that the telemetry cpature completes raise @error unless @error.nil? end |
#run_chef(working_dir, config, policy) ⇒ Object
Chef will try ‘downloading’ the policy from the internet unless we pass it a valid, local file in the working directory. By pointing it at a local file it will just copy it instead of trying to download it.
Chef 13 on Linux requires full path specifiers for –config and –recipe-url while on Chef 13 and 14 on Windows must use relative specifiers to prevent URI from causing an error (github.com/chef/chef/pull/7223/files).
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/chef_apply/action/base.rb', line 91 def run_chef(working_dir, config, policy) case family when :windows "Set-Location -Path #{working_dir}; " + # We must 'wait' for chef-client to finish before changing directories and Out-Null does that "chef-client -z --config #{config} --recipe-url #{policy} | Out-Null; " + # We have to leave working dir so we don't hold a lock on it, which allows us to delete this tempdir later "Set-Location C:/; " + "exit $LASTEXITCODE" else # cd is shell a builtin, so much call bash. This also means all commands are executed # with sudo (as long as we are hardcoding our sudo use) "bash -c 'cd #{working_dir}; chef-client -z --config #{File.join(working_dir, config)} --recipe-url #{File.join(working_dir, policy)}'" end end |