Test Failed
Push — develop ( abf64f...1d1151 )
by Nicolas
02:59
created

glances/actions.py (12 issues)

1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# Copyright (C) 2019 Nicolargo <[email protected]>
6
#
7
# Glances is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU Lesser General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Glances is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Lesser General Public License for more details.
16
#
17
# You should have received a copy of the GNU Lesser General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
"""Manage on alert actions."""
21
22
from subprocess import Popen
0 ignored issues
show
import missing from __future__ import absolute_import
Loading history...
23
24
from glances.logger import logger
0 ignored issues
show
import missing from __future__ import absolute_import
Loading history...
25
from glances.timer import Timer
0 ignored issues
show
import missing from __future__ import absolute_import
Loading history...
26
27
try:
28
    import pystache
0 ignored issues
show
import missing from __future__ import absolute_import
Loading history...
29
except ImportError:
30
    logger.debug("Pystache library not found (action scripts won't work)")
31
    pystache_tag = False
0 ignored issues
show
Coding Style Naming introduced by
The name pystache_tag does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
32
else:
33
    pystache_tag = True
0 ignored issues
show
Coding Style Naming introduced by
The name pystache_tag does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
34
35
36
class GlancesActions(object):
37
38
    """This class manage action if an alert is reached."""
39
40
    def __init__(self, args=None):
41
        """Init GlancesActions class."""
42
        # Dict with the criticity status
43
        # - key: stat_name
44
        # - value: criticity
45
        # Goal: avoid to execute the same command twice
46
        self.status = {}
47
48
        # Add a timer to avoid any trigger when Glances is started (issue#732)
49
        # Action can be triggered after refresh * 2 seconds
50
        if hasattr(args, 'time'):
51
            self.start_timer = Timer(args.time * 2)
52
        else:
53
            self.start_timer = Timer(3)
54
55
    def get(self, stat_name):
56
        """Get the stat_name criticity."""
57
        try:
58
            return self.status[stat_name]
59
        except KeyError:
60
            return None
61
62
    def set(self, stat_name, criticity):
63
        """Set the stat_name to criticity."""
64
        self.status[stat_name] = criticity
65
66
    def run(self, stat_name, criticity, commands, repeat, mustache_dict=None):
0 ignored issues
show
Too many arguments (6/5)
Loading history...
67
        """Run the commands (in background).
68
69
        - stats_name: plugin_name (+ header)
70
        - criticity: criticity of the trigger
71
        - commands: a list of command line with optional {{mustache}}
72
        - If True, then repeat the action
73
        - mustache_dict: Plugin stats (can be use within {{mustache}})
74
75
        Return True if the commands have been ran.
76
        """
77
        if (self.get(stat_name) == criticity and not repeat) or \
78
           not self.start_timer.finished():
79
            # Action already executed => Exit
80
            return False
81
82
        logger.debug("{} action {} for {} ({}) with stats {}".format(
0 ignored issues
show
Use formatting in logging functions and pass the parameters as arguments
Loading history...
83
            "Repeat" if repeat else "Run",
84
            commands, stat_name, criticity, mustache_dict))
85
86
        # Run all actions in background
87
        for cmd in commands:
88
            # Replace {{arg}} by the dict one (Thk to {Mustache})
89
            if pystache_tag:
90
                cmd_full = pystache.render(cmd, mustache_dict)
91
            else:
92
                cmd_full = cmd
93
            # Execute the action
94
            logger.info("Action triggered for {} ({}): {}".format(stat_name,
0 ignored issues
show
Use formatting in logging functions and pass the parameters as arguments
Loading history...
95
                                                                  criticity,
96
                                                                  cmd_full))
97
            logger.debug("Stats value for the trigger: {}".format(
0 ignored issues
show
Use formatting in logging functions and pass the parameters as arguments
Loading history...
98
                mustache_dict))
99
            try:
100
                Popen(cmd_full, shell=True)
101
            except OSError as e:
0 ignored issues
show
Coding Style Naming introduced by
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
102
                logger.error("Can't execute the action ({})".format(e))
0 ignored issues
show
Use formatting in logging functions and pass the parameters as arguments
Loading history...
103
104
        self.set(stat_name, criticity)
105
106
        return True
107