From be5ae9bc9e198a00f2a790992b663dda374006ba Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Wed, 22 Nov 2023 10:54:32 -0800 Subject: Convert ProcessOutput to String explicitly The `filetype` provider executes `crontab` using Puppet's execution API, which returns ProcessOutput objects that inherit from String. See puppetlabs/puppet@732d450 The provider later uses String#gsub to strip off the HEADER. In Ruby 2.7, the gsub method returns a new instance of ProcessOutput: irb(main):002:0> Puppet::Util::Execution::ProcessOutput.new("# HEADER\n0 4 * * * /etc/init.d/script.sh\n", 0).gsub(/# HEADER/, '').class => Puppet::Util::Execution::ProcessOutput If you later serialize the crontab entries to YAML using `puppet resource`, then puppet warns about serializing unknown data types: # puppet resource cron --to_yaml Warning: Cron[unmanaged:/etc/init.d/script.sh-1]['command'] contains a Puppet::Util::Execution::ProcessOutput value. It will be converted to the String '/etc/init.d/script.sh' This wasn't an issue with Ruby 3.2, because String#gsub always returns a String: irb(main):002:0> Puppet::Util::Execution::ProcessOutput.new("# HEADER\n0 4 * * * /etc/init.d/script.sh\n", 0).gsub(/# HEADER/, '').class => String This commit explicitly converts the ProcessOutput to a String so the provider behaves consistently on all Ruby versions. Fixes #61 --- spec/unit/provider/cron/filetype_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'spec/unit/provider/cron') diff --git a/spec/unit/provider/cron/filetype_spec.rb b/spec/unit/provider/cron/filetype_spec.rb index bd579c1..8dc0c32 100644 --- a/spec/unit/provider/cron/filetype_spec.rb +++ b/spec/unit/provider/cron/filetype_spec.rb @@ -6,6 +6,7 @@ describe Puppet::Provider::Cron::FileType do shared_examples_for 'crontab provider' do let(:cron) { type.new('no_such_user') } let(:crontab) { File.read(my_fixture(crontab_output)) } + let(:managedtab) { File.read(my_fixture('managed_output')) } let(:options) { { failonfail: true, combine: true } } let(:uid) { 'no_such_user' } let(:user_options) { options.merge(uid: uid) } @@ -30,6 +31,11 @@ describe Puppet::Provider::Cron::FileType do expect(cron.read).to eq(crontab) end + it 'returns a String' do + expect(Puppet::Util::Execution).to receive(:execute).with(['crontab', '-l'], user_options).and_return(Puppet::Util::Execution::ProcessOutput.new(managedtab, 0)) + expect(cron.read).to be_an_instance_of(String) + end + it 'does not switch user if current user is the target user' do expect(Puppet::Util).to receive(:uid).with(uid).twice.and_return 9000 expect(Puppet::Util::SUIDManager).to receive(:uid).and_return 9000 -- cgit v1.2.3