1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
"""Action driver"""
import Bcfg2.Client.Tools
from Bcfg2.Utils import safe_input
from Bcfg2.Client import matches_white_list, passes_black_list
class Action(Bcfg2.Client.Tools.Tool):
"""Implement Actions"""
name = 'Action'
__handles__ = [('Action', None)]
__req__ = {'Action': ['name', 'timing', 'when', 'command', 'status']}
def _action_allowed(self, action):
""" Return true if the given action is allowed to be run by
the whitelist or blacklist """
if (Bcfg2.Options.setup.decision == 'whitelist' and
not matches_white_list(action,
Bcfg2.Options.setup.decision_list)):
self.logger.info("In whitelist mode: suppressing Action: %s" %
action.get('name'))
return False
if (Bcfg2.Options.setup.decision == 'blacklist' and
not passes_black_list(action,
Bcfg2.Options.setup.decision_list)):
self.logger.info("In blacklist mode: suppressing Action: %s" %
action.get('name'))
return False
return True
def RunAction(self, entry):
"""This method handles command execution and status return."""
shell = False
shell_string = ''
if entry.get('shell', 'false') == 'true':
shell = True
shell_string = '(in shell) '
if not Bcfg2.Options.setup.dryrun:
if Bcfg2.Options.setup.interactive:
prompt = ('Run Action %s%s, %s: (y/N): ' %
(shell_string, entry.get('name'),
entry.get('command')))
ans = safe_input(prompt)
if ans not in ['y', 'Y']:
return False
if Bcfg2.Options.setup.service_mode == 'build':
if entry.get('build', 'true') == 'false':
self.logger.debug("Action: Deferring execution of %s due "
"to build mode" % entry.get('command'))
return False
self.logger.debug("Running Action %s %s" %
(shell_string, entry.get('name')))
rv = self.cmd.run(entry.get('command'), shell=shell)
self.logger.debug("Action: %s got return code %s" %
(entry.get('command'), rv.retval))
entry.set('rc', str(rv.retval))
return entry.get('status', 'check') == 'ignore' or rv.success
else:
self.logger.debug("In dryrun mode: not running action: %s" %
(entry.get('name')))
return False
def VerifyAction(self, dummy, _):
"""Actions always verify true."""
return True
def InstallAction(self, entry):
"""Run actions as pre-checks for bundle installation."""
if entry.get('timing') != 'post':
return self.RunAction(entry)
return True
def BundleUpdated(self, bundle):
"""Run postinstalls when bundles have been updated."""
states = dict()
for action in bundle.findall("Action"):
if action.get('timing') in ['post', 'both']:
if not self._action_allowed(action):
continue
states[action] = self.RunAction(action)
return states
def BundleNotUpdated(self, bundle):
"""Run Actions when bundles have not been updated."""
states = dict()
for action in bundle.findall("Action"):
if (action.get('timing') in ['post', 'both'] and
action.get('when') != 'modified'):
if not self._action_allowed(action):
continue
states[action] = self.RunAction(action)
return states
|