Class: RuboCop::Cop::Chef::RedundantCode::ServiceGuardOnStopDisable
- Extended by:
- AutoCorrector
- Includes:
- RangeHelp, RuboCop::Chef::CookbookHelpers
- Defined in:
- lib/rubocop/cop/chef/redundant/service_guard_on_stop_disable.rb
Overview
The :stop and :disable actions of the service resource are already no-ops when the service
isn't installed, so guarding them with a check for the init script or unit file adds nothing. The
base provider only converges these actions when current_resource.running/current_resource.enabled
is set, and the platform providers never set that state for a service they can't find.
The guard is also actively harmful because it hardcodes a single path while the provider searches
several. A guard on /usr/local/etc/rc.d/snmpd skips a FreeBSD host running the service out of
/etc/rc.d, and the run then reports success while leaving the service enabled.
This cop only fires when every action is :stop or :disable. Actions like :start, :enable,
:restart, and :reload are asserted against the init script, so a guard there is meaningful. The
systemd_unit resource shells out unconditionally, so its guards are meaningful as well and are
never flagged.
Constant Summary collapse
- MSG =
'A service resource that only stops or disables a service does not need a guard checking for the init script or unit file. Chef Infra Client already skips these actions when the service does not exist, and hardcoding a single path can silently skip services installed elsewhere.'- NO_OP_ACTIONS =
actions that Chef Infra Client treats as no-ops when the service can't be found
%i(stop disable).freeze
- INIT_SCRIPT_PATH =
the directories the various service providers search for init scripts and unit files
%r{/(?:etc/init\.d|etc/rc\.d|usr/local/etc/rc\.d|etc/sv|systemd/system)/}.freeze
Instance Method Summary collapse
Methods included from RuboCop::Chef::CookbookHelpers
#each_action_symbol, #match_property_in_resource?, #match_resource_type?, #method_arg_ast_to_string, #resource_block_name_if_string
Methods inherited from Base
Instance Method Details
#on_block(node) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rubocop/cop/chef/redundant/service_guard_on_stop_disable.rb', line 68 def on_block(node) match_property_in_resource?(:service, %i(only_if not_if), node) do |guard| # a string guard like `only_if 'test -f /etc/init.d/foo'` isn't a Ruby block next unless guard.block_type? next unless only_no_op_actions?(node) # `guard.body` is only a bare send when the block does nothing but the existence check. # Anything more (a `&&`, a second statement) is a guard we shouldn't touch. path = file_exist_check(guard.body) next unless path && INIT_SCRIPT_PATH.match?(path.source) add_offense(guard, severity: :refactor) do |corrector| corrector.remove(range_by_whole_lines(guard.source_range, include_final_newline: true)) end end end |