mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-14 16:44:39 +00:00
configd - add optional cache_ttl for script_output actions, closes https://github.com/opnsense/core/issues/7515
Add a generic time based cache option for configd sscript action events, example usage: [action] command:/path/to/my/command type:script_output cache_ttl=5 cache_ttl is specified in seconds after last started execution.
This commit is contained in:
parent
0dc1f2186a
commit
06d507704e
@ -42,6 +42,10 @@ class BaseAction:
|
||||
self.parameters = action_parameters.get('parameters', None)
|
||||
self.message = action_parameters.get('message', None)
|
||||
self.description = action_parameters.get('description', '')
|
||||
if action_parameters.get('cache_ttl', '').isdigit():
|
||||
self.cache_ttl = int(action_parameters['cache_ttl'])
|
||||
else:
|
||||
self.cache_ttl = None
|
||||
self.allowed_groups = set()
|
||||
for item in action_parameters.get('allowed_groups', '').split(','):
|
||||
if item:
|
||||
|
||||
@ -23,7 +23,12 @@
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
import fcntl
|
||||
import glob
|
||||
import hashlib
|
||||
import os
|
||||
import tempfile
|
||||
import time
|
||||
import traceback
|
||||
import subprocess
|
||||
from .. import syslog_error
|
||||
@ -31,16 +36,43 @@ from .base import BaseAction
|
||||
|
||||
|
||||
class Action(BaseAction):
|
||||
temp_prefix = 'tmpcfd_'
|
||||
cached_results = None
|
||||
def execute(self, parameters, message_uuid, *args, **kwargs):
|
||||
super().execute(parameters, message_uuid, *args, **kwargs)
|
||||
try:
|
||||
script_command = self._cmd_builder(parameters)
|
||||
script_hash = hashlib.sha256(script_command.encode()).hexdigest() if self.cache_ttl else None
|
||||
except TypeError as e:
|
||||
return str(e)
|
||||
|
||||
if Action.cached_results is None:
|
||||
# cache cleanup on startup (first executed script_output action)
|
||||
for filename in glob.glob("%s/%s*"% (tempfile.gettempdir(), Action.temp_prefix)):
|
||||
os.remove(filename)
|
||||
Action.cached_results = {}
|
||||
elif self.cache_ttl is not None and len(Action.cached_results) > 0:
|
||||
# cache expire
|
||||
now = time.time()
|
||||
for key in list(Action.cached_results.keys()):
|
||||
if Action.cached_results[key]['expire'] < now:
|
||||
del Action.cached_results[key]
|
||||
|
||||
try:
|
||||
if script_hash in Action.cached_results and os.path.isfile(Action.cached_results[script_hash]['filename']):
|
||||
with open(Action.cached_results[script_hash]['filename']) as output_stream:
|
||||
fcntl.flock(output_stream, fcntl.LOCK_EX)
|
||||
output_stream.seek(0)
|
||||
return output_stream.read()
|
||||
with tempfile.NamedTemporaryFile() as error_stream:
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
tparm = {'prefix': Action.temp_prefix, 'delete': script_hash is None}
|
||||
with tempfile.NamedTemporaryFile(**tparm) as output_stream:
|
||||
fcntl.flock(output_stream, fcntl.LOCK_EX)
|
||||
if script_hash:
|
||||
Action.cached_results[script_hash] = {
|
||||
'filename': output_stream.name,
|
||||
'expire': time.time() + self.cache_ttl
|
||||
}
|
||||
subprocess.check_call(script_command, env=self.config_environment, shell=True,
|
||||
stdout=output_stream, stderr=error_stream)
|
||||
output_stream.seek(0)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user