2016-01-16 22:00:15 -05:00
|
|
|
import os, subprocess, dotbot
|
2014-03-19 23:07:30 -04:00
|
|
|
|
2016-01-16 22:00:15 -05:00
|
|
|
class Shell(dotbot.Plugin):
|
2014-03-19 23:07:30 -04:00
|
|
|
'''
|
|
|
|
Run arbitrary shell commands.
|
|
|
|
'''
|
|
|
|
|
2014-04-24 15:41:34 -04:00
|
|
|
_directive = 'shell'
|
|
|
|
|
2014-03-19 23:07:30 -04:00
|
|
|
def can_handle(self, directive):
|
2014-04-24 15:41:34 -04:00
|
|
|
return directive == self._directive
|
2014-03-19 23:07:30 -04:00
|
|
|
|
|
|
|
def handle(self, directive, data):
|
2014-04-24 15:41:34 -04:00
|
|
|
if directive != self._directive:
|
2016-01-16 22:00:15 -05:00
|
|
|
raise ValueError('Shell cannot handle directive %s' %
|
2014-03-19 23:07:30 -04:00
|
|
|
directive)
|
|
|
|
return self._process_commands(data)
|
|
|
|
|
|
|
|
def _process_commands(self, data):
|
|
|
|
success = True
|
2016-03-02 20:53:19 -05:00
|
|
|
defaults = self._context.defaults().get('shell', {})
|
2014-03-19 23:07:30 -04:00
|
|
|
with open(os.devnull, 'w') as devnull:
|
2015-02-03 11:53:05 -05:00
|
|
|
for item in data:
|
|
|
|
stdin = stdout = stderr = devnull
|
|
|
|
if isinstance(item, dict):
|
|
|
|
cmd = item['command']
|
|
|
|
msg = item.get('description', None)
|
2016-03-02 20:53:19 -05:00
|
|
|
if item.get('stdin', defaults.get('stdin', False)) is True:
|
2015-02-03 11:53:05 -05:00
|
|
|
stdin = None
|
2016-03-02 20:53:19 -05:00
|
|
|
if item.get('stdout', defaults.get('stdout', False)) is True:
|
2015-02-03 11:53:05 -05:00
|
|
|
stdout = None
|
2016-03-02 20:53:19 -05:00
|
|
|
if item.get('stderr', defaults.get('stderr', False)) is True:
|
2015-02-03 11:53:05 -05:00
|
|
|
stderr = None
|
|
|
|
elif isinstance(item, list):
|
|
|
|
cmd = item[0]
|
|
|
|
msg = item[1] if len(item) > 1 else None
|
|
|
|
else:
|
|
|
|
cmd = item
|
|
|
|
msg = None
|
|
|
|
if msg is None:
|
|
|
|
self._log.lowinfo(cmd)
|
|
|
|
else:
|
|
|
|
self._log.lowinfo('%s [%s]' % (msg, cmd))
|
2016-10-19 11:25:45 -04:00
|
|
|
executable = os.environ.get('SHELL')
|
2015-04-24 18:26:20 -04:00
|
|
|
ret = subprocess.call(cmd, shell=True, stdin=stdin, stdout=stdout,
|
2016-10-19 11:25:45 -04:00
|
|
|
stderr=stderr, cwd=self._context.base_directory(),
|
|
|
|
executable=executable)
|
2014-03-19 23:07:30 -04:00
|
|
|
if ret != 0:
|
|
|
|
success = False
|
|
|
|
self._log.warning('Command [%s] failed' % cmd)
|
|
|
|
if success:
|
|
|
|
self._log.info('All commands have been executed')
|
|
|
|
else:
|
2015-01-26 10:36:11 -05:00
|
|
|
self._log.error('Some commands were not successfully executed')
|
2014-03-19 23:07:30 -04:00
|
|
|
return success
|