canonical / canonical/cloud-init
Puppet module reports failure for success, and success for failure
- Dominant language
- Python
- Stars
- 3.8k
- Forks
- 1.1k
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 18
Description
# Bug report
If the puppet module operates correctly and successfully gets and applies a catalog, it will exit with exit-code 2 as per https://www.puppet.com/docs/puppet/8/man/agent#usage-notes
> 0: The run succeeded with no changes or failures; the system was already in the desired state.
> 1: The run failed, or wasn't attempted due to another run already in progress.
> 2: The run succeeded, and some resources were changed.
> 4: The run succeeded, and some resources failed.
> 6: The run succeeded, and included both changes and failures.
Cloud-init reports this as a failure.
If Puppet doesn't create a certificate, get a catalog, or apply any changes (which is hard to fathom as the desired state of a cloud-init run) then it will exit with 0 -- which cloud-init reports as success.
Interestingly so, the integration test specifically avoids checking for success and instead just searches that the command was run https://github.com/canonical/cloud-init/blob/c9dce94d316028b15d9f2781fee959da745aea52/tests/integration_tests/modules/test_puppet.py#L43-L46
## Steps to reproduce the problem
1. A puppet server that will provide a catalog for the node
2. Any valid puppet module configuration for cloud-init that gets the catalog from the server
## Environment details
- Cloud-init version: ALL
- Operating System Distribution: testing on RHEL8/RHEL9 but it's a problem in the puppet module code common to every OS
- Cloud provider, platform or installer type: I'm currently using NoCloud for building MaaS images, but this is replicable on any cloud-init
## cloud-init logs
```
2024-09-26 18:48:18,927 - util.py[DEBUG]: Running module puppet () failed
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/cloudinit/config/modules.py", line 256, in _run_modules
run_name, mod.handle, func_args, freq=freq
File "/usr/lib/python3.6/site-packages/cloudinit/cloud.py", line 60, in run
return self._runners.run(name, functor, args, freq, clear_on_fail)
File "/usr/lib/python3.6/site-packages/cloudinit/helpers.py", line 172, in run
results = functor(**args)
File "/usr/lib/python3.6/site-packages/cloudinit/config/cc_puppet.py", line 366, in handle
subp.subp(cmd, capture=False)
File "/usr/lib/python3.6/site-packages/cloudinit/subp.py", line 323, in subp
stdout=out, stderr=err, exit_code=rc, cmd=args
cloudinit.subp.ProcessExecutionError: Unexpected error while running command.
Command: ['/opt/puppetlabs/bin/puppet', 'agent', '--test']
Exit code: 2
Reason: -
Stdout: -
Stderr: -
```
## Desired fix
I think it would be fantastic if the exit codes were customizable, or at least a toggle. I've worked in places where any failure in the Puppet code we'd want the install to fail, but a lot of places would want the Puppet run to be considered a success from cloud-init's point of view if a single resource failed. Resource apply errors would be tracked via logs or PuppetDB or ... so exit-codes 4 and 6 might be desirable to many if not most users as "success"
Contributor guide
Assessment
This issue has not been assessed yet.