def apply_simulated_actions(self): """ used in executor code (check mode only) to imply all commands were run when they were only simulated """ self.actions_taken = self.actions_planned changed = False if len(self.actions_taken) > 0: changed = True return Result(provider=self, changed=changed)
def do_apply(self, provider): """ Once a provider has a plan generated, see if we need to run the plan. """ from opsmop.callbacks.callbacks import Callbacks # some simple providers - like Echo, do not have a planning step # we will always run the apply step for them. For others, we will only # run the apply step if we have computed a plan if not provider.has_planned_actions(): if not provider.skip_plan_stage(): return Result(provider=provider, changed=False, data=None) # indicate we are about take some actions Callbacks().on_apply(provider) # take them result = provider.apply() Callbacks().on_taken_actions(provider, provider.actions_taken) # all Provider apply() methods need to return Result objects or raise # exceptions assert issubclass(type(result), Result) # the 'register' feature saves results into variable scope resource = provider.resource # determine if there was a failure fatal = False cond = resource.failed_when if cond is not None: if issubclass(type(cond), Lookup): fatal = cond.evaluate(resource) result.reason = cond elif callable(cond): fatal = cond(result) else: fatal = cond elif result.fatal: fatal = True result.fatal = fatal result.changed = provider.has_changed() # TODO: eliminate the actions class if result.changed: result.actions = [x.do for x in provider.actions_taken] else: result.actions = [] Callbacks().on_result(provider, result) return result
def execute(self): """ Execute a command (a list or string) with input_text as input, appending the output of all commands to the build log. This code was derived from http://vespene.io/ though is slightly different because there are no database objects. """ Callbacks().on_execute_command(self.provider, self) command = self.cmd timeout_cmd = self.get_timeout() shell = True if type(command) == list: if self.timeout and timeout_cmd: command.insert(0, self.timeout) command.insert(0, timeout_cmd) shell = False else: if self.timeout and timeout_cmd: command = "%s %s %s" % (timeout_cmd, self.timeout, command) # keep SSH-agent working for executed commands sock = os.environ.get('SSH_AUTH_SOCK', None) if self.env and sock: self.env['SSH_AUTH_SOCK'] = sock process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=shell, env=self.env) if self.input_text is None: self.input_text = "" stdin = io.TextIOWrapper( process.stdin, encoding='utf-8', line_buffering=True, ) stdout = io.TextIOWrapper( process.stdout, encoding='utf-8', ) stdin.write(self.input_text) stdin.close() output = "" for line in stdout: if (self.echo or self.loud) and (not self.ignore_lines or not self.should_ignore(line)): Callbacks().on_command_echo(self.provider, line) output = output + line if output.strip() == "": Callbacks().on_command_echo(self.provider, "(no output)") process.wait() res = None rc = process.returncode if rc != 0: res = Result(self.provider, rc=rc, data=output, fatal=self.fatal, primary=self.primary) else: res = Result(self.provider, rc=rc, data=output, fatal=False, primary=self.primary) # this callback will, depending on implementation, usually note fatal result objects and raise an exception Callbacks().on_command_result(self.provider, res) return res
def fatal(self, msg): """ shortcut to return a failed result from .apply() """ return Result(self, fatal=True, message=msg)
def ok(self, data=None): """ shortcut to return an ok result from .apply() """ return Result(self, data=data)