diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2019-05-29 15:56:20 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2019-05-29 16:20:17 -0700 |
commit | deea4f3b00a6bd18beba85c05ddec93a143cdb8b (patch) | |
tree | 80514eafa5ed418ed047117b058a0ced7548c792 | |
parent | b6488236ef24b9c44295deac78b7bd2498e372ba (diff) | |
download | chef-deea4f3b00a6bd18beba85c05ddec93a143cdb8b.tar.gz |
Target mode for systemd service helper
Makes it so that local cookbook can bounce a remote service over
train/ssh/whatever. Works at least for ubuntu.
Introduces a fairly rudimentary TrainHelpers class, using some
inspiration from ohbye.
Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
-rw-r--r-- | lib/chef/mixin/shell_out.rb | 3 | ||||
-rw-r--r-- | lib/chef/mixin/train_helpers.rb | 44 | ||||
-rw-r--r-- | lib/chef/node_map.rb | 2 | ||||
-rw-r--r-- | lib/chef/platform/service_helpers.rb | 31 | ||||
-rw-r--r-- | lib/chef/provider/service/systemd.rb | 3 | ||||
-rw-r--r-- | lib/chef/resource/service.rb | 1 |
6 files changed, 65 insertions, 19 deletions
diff --git a/lib/chef/mixin/shell_out.rb b/lib/chef/mixin/shell_out.rb index 6c2db85dfe..9f7b18eace 100644 --- a/lib/chef/mixin/shell_out.rb +++ b/lib/chef/mixin/shell_out.rb @@ -17,7 +17,6 @@ require "mixlib/shellout" unless defined?(Mixlib::ShellOut::DEFAULT_READ_TIMEOUT) require_relative "path_sanity" -require "shellwords" unless defined?(Shellwords) class Chef module Mixin @@ -160,7 +159,7 @@ class Chef def self.shell_out_command(*args, **options) if Chef::Config.target_mode? - FakeShellOut.new(args, options, transport_connection.run_command(Shellwords.join(" "))) # FIXME: train should accept run_command(*args) + FakeShellOut.new(args, options, transport_connection.run_command(args.join(" "))) # FIXME: train should accept run_command(*args) else cmd = if options.empty? Mixlib::ShellOut.new(*args) diff --git a/lib/chef/mixin/train_helpers.rb b/lib/chef/mixin/train_helpers.rb new file mode 100644 index 0000000000..b37511bdea --- /dev/null +++ b/lib/chef/mixin/train_helpers.rb @@ -0,0 +1,44 @@ +#-- +# Author:: Lamont Granquist <lamont@chef.io> +# Copyright:: Copyright 2010-2018, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require "stringio" unless defined?(StringIO) + +class Chef + module Mixin + module TrainHelpers + def file_exist?(*args) + if Chef::Config.target_mode? + Chef.run_context.transport_connection.file(args[0]).exist? + else + File.exist?(*args) + end + end + + # XXX: modifications to the StringIO won't get written back + def file_open(*args, &block) + if Chef::Config.target_mode? + content = Chef.run_context.transport_connection.file(args[0]).content + string_io = StringIO.new content + yield string_io if block_given? + string_io + else + File.open(*args, &block) + end + end + end + end +end diff --git a/lib/chef/node_map.rb b/lib/chef/node_map.rb index 01f9d215cb..f54b3dc6bb 100644 --- a/lib/chef/node_map.rb +++ b/lib/chef/node_map.rb @@ -287,8 +287,6 @@ class Chef # "provides" lines with identical filters sort by class name (ascending). # def compare_matchers(key, new_matcher, matcher) - cmp = compare_matcher_properties(new_matcher[:target_mode], matcher[:target_mode]) - return cmp if cmp != 0 cmp = compare_matcher_properties(new_matcher[:block], matcher[:block]) return cmp if cmp != 0 cmp = compare_matcher_properties(new_matcher[:platform_version], matcher[:platform_version]) diff --git a/lib/chef/platform/service_helpers.rb b/lib/chef/platform/service_helpers.rb index c469b3fe62..2faec6fc8a 100644 --- a/lib/chef/platform/service_helpers.rb +++ b/lib/chef/platform/service_helpers.rb @@ -17,11 +17,14 @@ # require_relative "../chef_class" +require_relative "../mixin/train_helpers" class Chef class Platform class ServiceHelpers class << self + include Chef::Mixin::TrainHelpers + # This helper is mostly used to sort out the mess of different # linux mechanisms that can be used to start services. It does # not necessarily need to linux-specific, but currently all our @@ -38,19 +41,19 @@ class Chef def service_resource_providers providers = [] - if ::File.exist?(Chef.path_to("/usr/sbin/update-rc.d")) + if file_exist?(Chef.path_to("/usr/sbin/update-rc.d")) providers << :debian end - if ::File.exist?(Chef.path_to("/usr/sbin/invoke-rc.d")) + if file_exist?(Chef.path_to("/usr/sbin/invoke-rc.d")) providers << :invokercd end - if ::File.exist?(Chef.path_to("/sbin/initctl")) + if file_exist?(Chef.path_to("/sbin/initctl")) providers << :upstart end - if ::File.exist?(Chef.path_to("/sbin/insserv")) + if file_exist?(Chef.path_to("/sbin/insserv")) providers << :insserv end @@ -58,7 +61,7 @@ class Chef providers << :systemd end - if ::File.exist?(Chef.path_to("/sbin/chkconfig")) + if file_exist?(Chef.path_to("/sbin/chkconfig")) providers << :redhat end @@ -68,23 +71,23 @@ class Chef def config_for_service(service_name) configs = [] - if ::File.exist?(Chef.path_to("/etc/init.d/#{service_name}")) + if file_exist?(Chef.path_to("/etc/init.d/#{service_name}")) configs += [ :initd, :systemd ] end - if ::File.exist?(Chef.path_to("/etc/init/#{service_name}.conf")) + if file_exist?(Chef.path_to("/etc/init/#{service_name}.conf")) configs << :upstart end - if ::File.exist?(Chef.path_to("/etc/xinetd.d/#{service_name}")) + if file_exist?(Chef.path_to("/etc/xinetd.d/#{service_name}")) configs << :xinetd end - if ::File.exist?(Chef.path_to("/etc/rc.d/#{service_name}")) + if file_exist?(Chef.path_to("/etc/rc.d/#{service_name}")) configs << :etc_rcd end - if ::File.exist?(Chef.path_to("/usr/local/etc/rc.d/#{service_name}")) + if file_exist?(Chef.path_to("/usr/local/etc/rc.d/#{service_name}")) configs << :usr_local_etc_rcd end @@ -98,13 +101,13 @@ class Chef private def systemd_is_init? - ::File.exist?(Chef.path_to("/proc/1/comm")) && - ::File.open(Chef.path_to("/proc/1/comm")).gets.chomp == "systemd" + file_exist?(Chef.path_to("/proc/1/comm")) && + file_open(Chef.path_to("/proc/1/comm")).gets.chomp == "systemd" end def has_systemd_service_unit?(svc_name) %w{ /etc /usr/lib /lib /run }.any? do |load_path| - ::File.exist?( + file_exist?( Chef.path_to("#{load_path}/systemd/system/#{svc_name.gsub(/@.*$/, '@')}.service") ) end @@ -113,7 +116,7 @@ class Chef def has_systemd_unit?(svc_name) # TODO: stop supporting non-service units with service resource %w{ /etc /usr/lib /lib /run }.any? do |load_path| - ::File.exist?(Chef.path_to("#{load_path}/systemd/system/#{svc_name}")) + file_exist?(Chef.path_to("#{load_path}/systemd/system/#{svc_name}")) end end end diff --git a/lib/chef/provider/service/systemd.rb b/lib/chef/provider/service/systemd.rb index 4cb564e8c0..46541bac73 100644 --- a/lib/chef/provider/service/systemd.rb +++ b/lib/chef/provider/service/systemd.rb @@ -26,7 +26,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple include Chef::Mixin::Which - provides :service, os: "linux" do |node| + provides :service, os: "linux", target_mode: true do |node| Chef::Platform::ServiceHelpers.service_resource_providers.include?(:systemd) end @@ -77,6 +77,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple def get_systemctl_options_args if new_resource.user + raise NotImplementedError, "#{new_resource} does not support the user property on a target_mode host (yet)" if Chef::Config.target_mode? uid = Etc.getpwnam(new_resource.user).uid options = { environment: { diff --git a/lib/chef/resource/service.rb b/lib/chef/resource/service.rb index e13f237481..508ef8e643 100644 --- a/lib/chef/resource/service.rb +++ b/lib/chef/resource/service.rb @@ -24,6 +24,7 @@ require_relative "../dist" class Chef class Resource class Service < Chef::Resource + provides :service, target_mode: true identity_attr :service_name description "Use the service resource to manage a service." |