Repository: ansible-collections/community.general

Issue:
puppet: add support for waitforlock
### Summary

Often the puppet module can fail on puppet runs if puppet is already running.  Puppet has the option [`--waitforlock`](https://www.puppet.com/docs/puppet/8/configuration#maxwaitforlock) which ensures puppet will wait a specific amount of time for the lock to free before throwing an error.  Allowing users to specify larger failures for this would be very useful 

### Issue Type

Feature Idea

### Component Name

puppet

### Additional Information

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)

```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:

Resolving patch:
diff --git a/plugins/module_utils/puppet.py b/plugins/module_utils/puppet.py
--- a/plugins/module_utils/puppet.py
+++ b/plugins/module_utils/puppet.py
@@ -103,6 +103,7 @@ def execute_func(execute, manifest):
             modulepath=cmd_runner_fmt.as_opt_eq_val("--modulepath"),
             _execute=cmd_runner_fmt.as_func(execute_func),
             summarize=cmd_runner_fmt.as_bool("--summarize"),
+            waitforlock=cmd_runner_fmt.as_opt_val("--waitforlock"),
             debug=cmd_runner_fmt.as_bool("--debug"),
             verbose=cmd_runner_fmt.as_bool("--verbose"),
         ),
diff --git a/plugins/modules/puppet.py b/plugins/modules/puppet.py
--- a/plugins/modules/puppet.py
+++ b/plugins/modules/puppet.py
@@ -101,6 +101,12 @@
       - Whether to print a transaction summary.
     type: bool
     default: false
+  waitforlock:
+    description:
+     - The maximum amount of time C(puppet) should wait for an already running C(puppet) agent to finish before starting.
+     - If a number without unit is provided, it is assumed to be a number of seconds. Allowed units are V(m) for minutes and V(h) for hours.
+    type: str
+    version_added: 9.0.0
   verbose:
     description:
       - Print extra information.
@@ -159,6 +165,14 @@
     skip_tags:
     - service
 
+- name: Wait 30 seconds for any current puppet runs to finish
+  community.general.puppet:
+    waitforlock: 30
+
+- name: Wait 5 minutes for any current puppet runs to finish
+  community.general.puppet:
+    waitforlock: 5m
+
 - name: Run puppet agent in noop mode
   community.general.puppet:
     noop: true
@@ -214,6 +228,7 @@ def main():
             skip_tags=dict(type='list', elements='str'),
             execute=dict(type='str'),
             summarize=dict(type='bool', default=False),
+            waitforlock=dict(type='str'),
             debug=dict(type='bool', default=False),
             verbose=dict(type='bool', default=False),
             use_srv_records=dict(type='bool'),
@@ -247,11 +262,11 @@ def main():
     runner = puppet_utils.puppet_runner(module)
 
     if not p['manifest'] and not p['execute']:
-        args_order = "_agent_fixed puppetmaster show_diff confdir environment tags skip_tags certname noop use_srv_records"
+        args_order = "_agent_fixed puppetmaster show_diff confdir environment tags skip_tags certname noop use_srv_records waitforlock"
         with runner(args_order) as ctx:
             rc, stdout, stderr = ctx.run()
     else:
-        args_order = "_apply_fixed logdest modulepath environment certname tags skip_tags noop _execute summarize debug verbose"
+        args_order = "_apply_fixed logdest modulepath environment certname tags skip_tags noop _execute summarize debug verbose waitforlock"
         with runner(args_order) as ctx:
             rc, stdout, stderr = ctx.run(_execute=[p['execute'], p['manifest']])
 


Test patch:
diff --git a/tests/unit/plugins/modules/test_puppet.yaml b/tests/unit/plugins/modules/test_puppet.yaml
--- a/tests/unit/plugins/modules/test_puppet.yaml
+++ b/tests/unit/plugins/modules/test_puppet.yaml
@@ -190,3 +190,35 @@
       rc: 0
       out: ""
       err: ""
+- id: puppet_agent_waitforlock
+  input:
+    waitforlock: 30
+  output:
+    changed: false
+  run_command_calls:
+    - command: [/testbin/puppet, config, print, agent_disabled_lockfile]
+      environ: *env-def
+      rc: 0
+      out: "blah, anything"
+      err: ""
+    - command:
+        - /testbin/timeout
+        - -s
+        - "9"
+        - 30m
+        - /testbin/puppet
+        - agent
+        - --onetime
+        - --no-daemonize
+        - --no-usecacheonfailure
+        - --no-splay
+        - --detailed-exitcodes
+        - --verbose
+        - --color
+        - "0"
+        - --waitforlock
+        - "30"
+      environ: *env-def
+      rc: 0
+      out: ""
+      err: ""