1515
1616
1717class ActionModule (ActionBase ):
18-
1918 # Keep internal params away from user interactions
20- _VALID_ARGS = frozenset ((' path' , ' state' , ' table' , ' noflush' , ' counters' , ' modprobe' , ' ip_version' , ' wait' ))
19+ _VALID_ARGS = frozenset ((" path" , " state" , " table" , " noflush" , " counters" , " modprobe" , " ip_version" , " wait" ))
2120 DEFAULT_SUDOABLE = True
2221
2322 @staticmethod
@@ -27,7 +26,8 @@ def msg_error__async_and_poll_not_zero(task_poll, task_async, max_timeout):
2726 "is set to 'restored'. To enable its rollback feature (that needs the "
2827 "module to run asynchronously on the remote), please set task attribute "
2928 f"'poll' (={ task_poll } ) to 0, and 'async' (={ task_async } ) to a value >2 and not greater than "
30- f"'ansible_timeout' (={ max_timeout } ) (recommended)." )
29+ f"'ansible_timeout' (={ max_timeout } ) (recommended)."
30+ )
3131
3232 @staticmethod
3333 def msg_warning__no_async_is_no_rollback (task_poll , task_async , max_timeout ):
@@ -37,7 +37,8 @@ def msg_warning__no_async_is_no_rollback(task_poll, task_async, max_timeout):
3737 "regain it before fixing firewall rules through a serial console, or any "
3838 f"other way except SSH. Please set task attribute 'poll' (={ task_poll } ) to 0, and "
3939 f"'async' (={ task_async } ) to a value >2 and not greater than 'ansible_timeout' (={ max_timeout } ) "
40- "(recommended)." )
40+ "(recommended)."
41+ )
4142
4243 @staticmethod
4344 def msg_warning__async_greater_than_timeout (task_poll , task_async , max_timeout ):
@@ -46,44 +47,48 @@ def msg_warning__async_greater_than_timeout(task_poll, task_async, max_timeout):
4647 "but with settings that will lead this rollback to happen AFTER that the "
4748 "controller will reach its own timeout. Please set task attribute 'poll' "
4849 f"(={ task_poll } ) to 0, and 'async' (={ task_async } ) to a value >2 and not greater than "
49- f"'ansible_timeout' (={ max_timeout } ) (recommended)." )
50+ f"'ansible_timeout' (={ max_timeout } ) (recommended)."
51+ )
5052
5153 def _async_result (self , async_status_args , task_vars , timeout ):
52- '''
54+ """
5355 Retrieve results of the asynchronous task, and display them in place of
5456 the async wrapper results (those with the ansible_job_id key).
55- '''
57+ """
5658 async_status = self ._task .copy ()
5759 async_status .args = async_status_args
58- async_status .action = ' ansible.builtin.async_status'
60+ async_status .action = " ansible.builtin.async_status"
5961 async_status .async_val = 0
6062 async_action = self ._shared_loader_obj .action_loader .get (
61- async_status .action , task = async_status , connection = self ._connection ,
62- play_context = self ._play_context , loader = self ._loader , templar = self ._templar ,
63- shared_loader_obj = self ._shared_loader_obj )
64-
65- if async_status .args ['mode' ] == 'cleanup' :
63+ async_status .action ,
64+ task = async_status ,
65+ connection = self ._connection ,
66+ play_context = self ._play_context ,
67+ loader = self ._loader ,
68+ templar = self ._templar ,
69+ shared_loader_obj = self ._shared_loader_obj ,
70+ )
71+
72+ if async_status .args ["mode" ] == "cleanup" :
6673 return async_action .run (task_vars = task_vars )
6774
6875 # At least one iteration is required, even if timeout is 0.
6976 for dummy in range (max (1 , timeout )):
7077 async_result = async_action .run (task_vars = task_vars )
71- if async_result .get (' finished' , 0 ) == 1 :
78+ if async_result .get (" finished" , 0 ) == 1 :
7279 break
7380 time .sleep (min (1 , timeout ))
7481
7582 return async_result
7683
7784 def run (self , tmp = None , task_vars = None ):
78-
7985 self ._supports_check_mode = True
8086 self ._supports_async = True
8187
8288 result = super ().run (tmp , task_vars )
8389 del tmp # tmp no longer has any effect
8490
85- if not result .get ('skipped' ):
86-
91+ if not result .get ("skipped" ):
8792 # FUTURE: better to let _execute_module calculate this internally?
8893 wrap_async = self ._task .async_val and not self ._connection .has_native_async
8994
@@ -98,51 +103,48 @@ def run(self, tmp=None, task_vars=None):
98103 starter_cmd = None
99104 confirm_cmd = None
100105
101- if module_args .get (' state' , None ) == ' restored' :
106+ if module_args .get (" state" , None ) == " restored" :
102107 if not wrap_async :
103108 if not check_mode :
104- display .warning (self .msg_error__async_and_poll_not_zero (
105- task_poll ,
106- task_async ,
107- max_timeout ))
109+ display .warning (self .msg_error__async_and_poll_not_zero (task_poll , task_async , max_timeout ))
108110 elif task_poll :
109- raise AnsibleActionFail (self .msg_warning__no_async_is_no_rollback (
110- task_poll ,
111- task_async ,
112- max_timeout ))
111+ raise AnsibleActionFail (
112+ self .msg_warning__no_async_is_no_rollback (task_poll , task_async , max_timeout )
113+ )
113114 else :
114115 if task_async > max_timeout and not check_mode :
115- display .warning (self .msg_warning__async_greater_than_timeout (
116- task_poll ,
117- task_async ,
118- max_timeout ))
116+ display .warning (
117+ self .msg_warning__async_greater_than_timeout (task_poll , task_async , max_timeout )
118+ )
119119
120120 # inject the async directory based on the shell option into the
121121 # module args
122- async_dir = self .get_shell_option (' async_dir' , default = "~/.ansible_async" )
122+ async_dir = self .get_shell_option (" async_dir" , default = "~/.ansible_async" )
123123
124124 # Bind the loop max duration to consistent values on both
125125 # remote and local sides (if not the same, make the loop
126126 # longer on the controller); and set a backup file path.
127- module_args [' _timeout' ] = task_async
128- module_args [' _back' ] = f' { async_dir } /iptables.state'
129- async_status_args = dict (mode = ' status' )
127+ module_args [" _timeout" ] = task_async
128+ module_args [" _back" ] = f" { async_dir } /iptables.state"
129+ async_status_args = dict (mode = " status" )
130130 confirm_cmd = f"rm -f { module_args ['_back' ]} "
131131 starter_cmd = f"touch { module_args ['_back' ]} .starter"
132132 remaining_time = max (task_async , max_timeout )
133133
134134 # do work!
135- result = merge_hash (result , self ._execute_module (module_args = module_args , task_vars = task_vars , wrap_async = wrap_async ))
135+ result = merge_hash (
136+ result , self ._execute_module (module_args = module_args , task_vars = task_vars , wrap_async = wrap_async )
137+ )
136138
137139 # Then the 3-steps "go ahead or rollback":
138140 # 1. Catch early errors of the module (in asynchronous task) if any.
139141 # Touch a file on the target to signal the module to process now.
140142 # 2. Reset connection to ensure a persistent one will not be reused.
141143 # 3. Confirm the restored state by removing the backup on the remote.
142144 # Retrieve the results of the asynchronous task to return them.
143- if ' _back' in module_args :
144- async_status_args [' jid' ] = result .get (' ansible_job_id' , None )
145- if async_status_args [' jid' ] is None :
145+ if " _back" in module_args :
146+ async_status_args [" jid" ] = result .get (" ansible_job_id" , None )
147+ if async_status_args [" jid" ] is None :
146148 raise AnsibleActionFail ("Unable to get 'ansible_job_id'." )
147149
148150 # Catch early errors due to missing mandatory option, bad
@@ -156,7 +158,7 @@ def run(self, tmp=None, task_vars=None):
156158
157159 # As the main command is not yet executed on the target, here
158160 # 'finished' means 'failed before main command be executed'.
159- if not result [' finished' ]:
161+ if not result [" finished" ]:
160162 try :
161163 self ._connection .reset ()
162164 except AttributeError :
@@ -178,16 +180,16 @@ def run(self, tmp=None, task_vars=None):
178180 result = merge_hash (result , self ._async_result (async_status_args , task_vars , remaining_time ))
179181
180182 # Cleanup async related stuff and internal params
181- for key in (' ansible_job_id' , ' results_file' , ' started' , ' finished' ):
183+ for key in (" ansible_job_id" , " results_file" , " started" , " finished" ):
182184 if result .get (key ):
183185 del result [key ]
184186
185- if result .get (' invocation' , {}).get (' module_args' ):
186- for key in (' _back' , ' _timeout' , ' _async_dir' , ' jid' ):
187- if result [' invocation' ][ ' module_args' ].get (key ):
188- del result [' invocation' ][ ' module_args' ][key ]
187+ if result .get (" invocation" , {}).get (" module_args" ):
188+ for key in (" _back" , " _timeout" , " _async_dir" , " jid" ):
189+ if result [" invocation" ][ " module_args" ].get (key ):
190+ del result [" invocation" ][ " module_args" ][key ]
189191
190- async_status_args [' mode' ] = ' cleanup'
192+ async_status_args [" mode" ] = " cleanup"
191193 dummy = self ._async_result (async_status_args , task_vars , 0 )
192194
193195 if not wrap_async :
0 commit comments