diff --git a/manifests/unit_file.pp b/manifests/unit_file.pp index 0654936..1cfa487 100644 --- a/manifests/unit_file.pp +++ b/manifests/unit_file.pp @@ -1,116 +1,122 @@ # @summary Creates a systemd unit file # # @api public # # @see systemd.unit(5) # # @param name [Pattern['^[^/]+\.(service|socket|device|mount|automount|swap|target|path|timer|slice|scope)$']] # The target unit file to create # # @param ensure # The state of the unit file to ensure # # @param path # The main systemd configuration path # # @param content # The full content of the unit file # # * Mutually exclusive with ``$source`` # # @param source # The ``File`` resource compatible ``source`` # # * Mutually exclusive with ``$content`` # # @param target # If set, will force the file to be a symlink to the given target # # * Mutually exclusive with both ``$source`` and ``$content`` # # @param owner # The owner to set on the unit file # # @param group # The group to set on the unit file # # @param mode # The mode to set on the unit file # # @param show_diff # Whether to show the diff when updating unit file # # @param enable # If set, will manage the unit enablement status. # # @param active # If set, will manage the state of the unit. # # @param restart # Specify a restart command manually. If left unspecified, a standard Puppet service restart happens. # define systemd::unit_file ( Enum['present', 'absent', 'file'] $ensure = 'present', Stdlib::Absolutepath $path = '/etc/systemd/system', Optional[Variant[String, Sensitive[String], Deferred]] $content = undef, Optional[String] $source = undef, Optional[Stdlib::Absolutepath] $target = undef, String $owner = 'root', String $group = 'root', String $mode = '0444', Boolean $show_diff = true, Optional[Variant[Boolean, Enum['mask']]] $enable = undef, Optional[Boolean] $active = undef, Optional[String] $restart = undef, ) { include systemd assert_type(Systemd::Unit, $name) - if $target { + if $enable == 'mask' { + $_target = '/dev/null' + } else { + $_target = $target + } + + if $_target { $_ensure = 'link' } else { $_ensure = $ensure ? { 'present' => 'file', default => $ensure, } } file { "${path}/${name}": ensure => $_ensure, content => $content, source => $source, - target => $target, + target => $_target, owner => $owner, group => $group, mode => $mode, show_diff => $show_diff, } if $enable != undef or $active != undef { service { $name: ensure => $active, enable => $enable, restart => $restart, provider => 'systemd', } if $ensure == 'absent' { if $enable or $active { fail("Can't ensure the unit file is absent and activate/enable the service at the same time") } Service[$name] -> File["${path}/${name}"] } else { File["${path}/${name}"] ~> Service[$name] } } else { # Work around https://tickets.puppetlabs.com/browse/PUP-9473 # and react to changes on static unit files (ie: .service triggered by .timer) exec { "${name}-systemctl-daemon-reload": command => 'systemctl daemon-reload', refreshonly => true, path => $facts['path'], subscribe => File["${path}/${name}"], } } } diff --git a/spec/defines/unit_file_spec.rb b/spec/defines/unit_file_spec.rb index 1561b38..622e945 100644 --- a/spec/defines/unit_file_spec.rb +++ b/spec/defines/unit_file_spec.rb @@ -1,115 +1,125 @@ # frozen_string_literal: true require 'spec_helper' describe 'systemd::unit_file' do context 'supported operating systems' do on_supported_os.each do |os, facts| context "on #{os}" do let(:facts) { facts } let(:title) { 'test.service' } let(:params) { { content: 'random stuff' } } it { is_expected.to compile.with_all_deps } context 'with non-sensitive Content' do let(:params) { { content: 'non-sensitive Content' } } it do expect(subject).to create_file("/etc/systemd/system/#{title}"). with_ensure('file'). with_content(params[:content]). with_mode('0444') end end context 'with sensitive Content' do let(:params) { { content: sensitive('sensitive Content') } } it do resource = catalogue.resource("File[/etc/systemd/system/#{title}]") expect(resource[:content]).to eq(params[:content].unwrap) expect(subject).to contain_file("/etc/systemd/system/#{title}"). with({ content: sensitive('sensitive Content') }) end end context 'with a bad unit type' do let(:title) { 'test.badtype' } it { is_expected.to compile.and_raise_error(%r{expects a match for Systemd::Unit}) } end context 'with a bad unit type containing a slash' do let(:title) { 'test/unit.service' } it { is_expected.to compile.and_raise_error(%r{expects a match for Systemd::Unit}) } end context 'with enable => true and active => true' do let(:params) do super().merge( enable: true, active: true ) end it { is_expected.to compile.with_all_deps } it do expect(subject).to contain_service('test.service'). with_ensure(true). with_enable(true). with_provider('systemd'). that_subscribes_to("File[/etc/systemd/system/#{title}]") end end context 'ensure => absent' do let(:params) { super().merge(ensure: 'absent') } context 'with enable => true' do let(:params) { super().merge(enable: true) } it { is_expected.to compile.and_raise_error(%r{Can't ensure the unit file is absent and activate}) } end context 'with active => true' do let(:params) { super().merge(active: true) } it { is_expected.to compile.and_raise_error(%r{Can't ensure the unit file is absent and activate}) } end context 'with enable => false and active => false' do let(:params) do super().merge( enable: false, active: false ) end it { is_expected.to compile.with_all_deps } it do expect(subject).to contain_service('test.service'). with_ensure(false). with_enable(false). with_provider('systemd'). that_comes_before("File[/etc/systemd/system/#{title}]") end end end + context 'enable => mask' do + let(:params) { { enable: 'mask' } } + + it do + expect(subject).to create_file("/etc/systemd/system/#{title}"). + with_ensure('link'). + with_target('/dev/null') + end + end + context 'when using default values for enable and active' do it { expect(subject).to create_exec("#{title}-systemctl-daemon-reload").with( command: 'systemctl daemon-reload', refreshonly: true ) } end end end end end