Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 6.1.0 breaks disabling nonexistent services #386

Closed
levic opened this issue Jun 25, 2023 · 3 comments · Fixed by #387
Closed

Version 6.1.0 breaks disabling nonexistent services #386

levic opened this issue Jun 25, 2023 · 3 comments · Fixed by #387

Comments

@levic
Copy link

levic commented Jun 25, 2023

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: 5.5.22
  • Ruby: 3.0.2p107
  • Distribution: Ubuntu 22.04
  • Module version: 6.1.0

How to reproduce

With 6.1.0, the new $openldap::server::manage_policy_rc_d causes a /usr/sbin/policy-rc.d file to be created.

This then breaks puppet-nftables with a Error: /Stage[main]/Nftables/Service[firewalld]/enable: change from 'true' to 'false' failed: Could not disable firewalld: (corrective)

puppet-nftables is just one example of the failure. You will get the same behaviour with any other puppet module that tries to disable a non-existent service (in this case nftables disables firewalld whether it exists or not)

Minimal example script:

  class { 'openldap::server::install':
  } ->
  service { 'my-missing-service':
    enable => false,
  }

Without the openldap::server::install this works fine.

If I comment out the file { '/usr/sbin/policy-rc.d' declaration in openldap::server::install (and delete the /usr/sbin/policy-rc.d if it has already been created) then it also works fine.

What are you seeing

After openldap::server is included in the puppet config the /usr/sbin/policy-rc.d file is installed.

This changes the behaviour of /usr/sbin/invoke-rc.d which in turn causes puppet to attempt to disable nonexistent services on every run. Since those services don't exist puppet fails.

What behaviour did you expect instead

puppet-openldap should not break disabling of nonexistent services.

@levic levic changed the title 6.1.0 breaks puppet-nftables (and probably others) 6.1.0 breaks disabling nonexistent services Jun 25, 2023
@levic
Copy link
Author

levic commented Jun 25, 2023

Digging into this a bit further:

  • This appears to be the relevant puppet code: if a service is not managed by systemd (which is also the case for nonexistent services) then it falls back to checking with invoke-rc.d.
  • The Ubuntu 22.04 source for invoke-rc.d is here
  • The valid return codes for invoke-rc.d are here

I can fix the immediate problem by changing the 6.1.0 script to:

      $policy_rc_d = @(POLICY)
        #!/bin/sh
        if [ "$1" = "--quiet" ]; then
          shift
        fi
        if [ "$1" = "slapd" ]; then
          exit 101
        fi
        if ! [ -e "/etc/init.d/$1" ] ; then
          exit 100
        fi
        exit 0
        | POLICY
  • This correctly strips --quiet so that $1 is actually the daemon name
  • This checks whether the daemon actually exists or not and if it doesn't returns the 100 error code

This still doesn't fix the issue though that there may already be an existing policy-rc.d that the openldap module is clobbering (ideally debian would have provided a mechanism where the policy for each service is in a separate file, but it didn't)

@levic
Copy link
Author

levic commented Jun 26, 2023

A potential workaround that I've been using:

	exec {'mask-before-openldap-install':
		unless => "/usr/bin/test -e /etc/init.d/${openldap::server::service}",
		command => "/usr/bin/systemctl mask ${openldap::server::service}",
		creates => "/etc/systemd/system/${openldap::server::service}.service",
		before => [
			Package[$openldap::server::package],
			Service[$openldap::server::service],
		],
	}

If the package isn't yet installed (as determined by the test) it will manually invoke systemd to mask the daemon before installing the package (systemd will install a symlink at /etc/systemd/system/slapd.service pointing to /dev/null).

After the package is installed the normal puppet Service resource will unmask it.

At least on Ubuntu this works but I doubt it has general applicability (although the puppet code linked above is specific to debian family systems anyway). This also may not work in future if/when the slapd daemon control script is moved from an initv script into a native systemd service (the test would have to be updated to point to the new file)

@smortex
Copy link
Member

smortex commented Jun 28, 2023

Thank you for your report. I like the idea of masking the unit! It seems to work well on all supported OS according to the acceptance test suite, you can check this in #387.

@smortex smortex changed the title 6.1.0 breaks disabling nonexistent services Version 6.1.0 breaks disabling nonexistent services Jun 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants