canonical / canonical/cloud-init

Puppet module reports failure for success, and success for failure

Open
#5,747 4 comments 1 reaction 0 assignees View on GitHub
bug
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.