def get(self): """ Get the Manager's REST configuration :return: Manager's REST configuration data """ request_args = request.args.to_dict(flat=False) current_app.logger.info( 'Retrieving Manager REST config. filter: {0}'.format(request_args)) result = dict() filter_by = request_args.get('filter', []) for key in filter_by: try: result[key] = config.instance.to_dict()[key] except KeyError as ke: current_app.logger.error('KeyError thrown: {0}'.format( str(ke))) raise CommandExecutionException(command='manager.config.get', error=str(ke), code=400, output=None) if not filter_by: current_app.logger.debug('Retrieving Manager REST config without a' ' filter') result = config.instance.to_dict() return result
def run(self, command, execution_env=None): self.logger.debug('run: {0}'.format(command)) command_env = os.environ.copy() # we're running on the old agent - don't pass our celery config to the # new one for env_var in CELERY_CONFIG_ENV_VARS: command_env.pop(env_var, None) command_env.update(execution_env or {}) p = subprocess.Popen(_shlex_split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=command_env) out, err = p.communicate() if p.returncode != 0: if out: out = out.rstrip() if err: err = err.rstrip() self.logger.error('Command {0} failed.'.format(command)) self.logger.error('Stdout:') self.logger.error(out) self.logger.error('Stderr:') self.logger.error(err) raise CommandExecutionException(command, err, out, p.returncode)
def run(self, command, exit_on_failure=True, stdout_pipe=True, stderr_pipe=True, cwd=None, execution_env=None, encoding='utf-8'): """ Runs local commands. :param command: The command to execute. :param exit_on_failure: False to ignore failures. :param stdout_pipe: False to not pipe the standard output. :param stderr_pipe: False to not pipe the standard error. :param cwd: the working directory the command will run from. :param execution_env: dictionary of environment variables that will be present in the command scope. :return: A wrapper object for all valuable info from the execution. :rtype: cloudify.utils.CommandExecutionResponse """ if isinstance(command, list): popen_args = command else: popen_args = _shlex_split(command) self.logger.debug('[{0}] run: {1}'.format(self.host, popen_args)) stdout = subprocess.PIPE if stdout_pipe else None stderr = subprocess.PIPE if stderr_pipe else None command_env = os.environ.copy() command_env.update(execution_env or {}) p = subprocess.Popen(args=popen_args, stdout=stdout, stderr=stderr, cwd=cwd, env=command_env) out, err = p.communicate() if out is not None: out = out.rstrip().decode(encoding, 'replace') if err is not None: err = err.rstrip().decode(encoding, 'replace') if p.returncode != 0: error = CommandExecutionException(command=command, error=err, output=out, code=p.returncode) if exit_on_failure: raise error else: self.logger.error(error) return CommandExecutionResponse(command=command, std_out=out, std_err=err, return_code=p.returncode)
def execute_and_log(cmd, clean_env=False, deployment_workdir=None, no_log=False, ignore_errors=False): """ Execute a command and log each line of its output as it is printed to stdout Taken from here: https://stackoverflow.com/a/4417735/978089 :param cmd: The command to execute :param clean_env: If set to true we pop LOCAL_REST_CERT_FILE from the subprocess' env. This is because we're running in the agent worker's env and this env var is set there, but when we're calling a CLI command from the subprocess, we're using a CLI profile in which the cert is already set, and this creates a conflict. :param deployment_workdir: If set to true instead of using the default .cloudify folder, we use a folder that depends on the deployment ID :param no_log: If set to True the output will logged to the DEBUG logger :param ignore_errors: Don't raise an exception on errors if True """ env = os.environ.copy() if clean_env: env.pop('LOCAL_REST_CERT_FILE', None) if deployment_workdir: env['CFY_WORKDIR'] = deployment_workdir try: ctx.logger.debug('Running command: {0}'.format(cmd)) proc = _run_process(cmd, env) except OSError as e: if ignore_errors: ctx.logger.debug( 'Failed running command `{0}` with error: {1}'.format( cmd, e ) ) return raise output = _process_output(proc, not no_log) return_code = _return_code(proc) if return_code and not ignore_errors: raise CommandExecutionException( cmd, error=output, output=output, code=return_code ) return output
def run(self, command, exit_on_failure=True, stdout_pipe=True, stderr_pipe=True): """ Runs local commands. :param command: The command to execute. :param exit_on_failure: False to ignore failures. :param stdout_pipe: False to not pipe the standard output. :param stderr_pipe: False to not pipe the standard error. :return: A wrapper object for all valuable info from the execution. :rtype: CommandExecutionResponse """ self.logger.info('[{0}] run: {1}'.format(self.host, command)) shlex_split = _shlex_split(command) stdout = subprocess.PIPE if stdout_pipe else None stderr = subprocess.PIPE if stderr_pipe else None p = subprocess.Popen(shlex_split, stdout=stdout, stderr=stderr) out, err = p.communicate() if p.returncode == 0: if out: self.logger.info('[{0}] out: {1}'.format(self.host, out)) else: error = CommandExecutionException( command=command, code=p.returncode, error=err, output=out) self.logger.error(error) if exit_on_failure: raise error return CommandExecutionResponse(command=command, std_out=out, std_err=err, return_code=p.returncode)
def put_file(self, src, dst=None, sudo=False, **attributes): """ Copies a file from the src path to the dst path. :param src: Path to a local file. :param dst: The remote path the file will copied to. :param sudo: indicates that this operation will require sudo permissions :param attributes: custom attributes passed directly to fabric's run command :return: the destination path """ if dst: self.verify_dir_exists(os.path.dirname(dst)) else: basename = os.path.basename(src) tempdir = self.mkdtemp() dst = os.path.join(tempdir, basename) command = "rsync -av --blocking-io --rsync-path= --rsh='{0}' " \ "{1} rsync:{2}".format(self._conn_cmd, src, dst) output = subprocess.check_output(shlex.split(command)) # TODO: Is this return code valid? if not output: raise CommandExecutionException( command=command, error='Failed uploading {0} to {1}' .format(src, dst), code=-1, output=None ) dir_name, file_name = os.path.split(os.path.abspath(dst)) self.run('mv {0} {1}/{2}'.format(file_name, dir_name, file_name)) return dst
def run(self, command, check_return_code=True, **attributes): try: child = subprocess.Popen(shlex.split(self._conn_cmd + ' ' + self._sh_cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) # TODO: Should control env stdout, stderr = child.communicate(input=command) if check_return_code: return_code = child.returncode else: return_code = 0 if return_code != 0: raise CommandExecutionException( command=command, error=stderr, output=None, code=return_code ) return CommandExecutionResponse( command=command, std_out=stdout, std_err=None, return_code=return_code ) except CommandExecutionException: raise except BaseException as e: raise CommandExecutionError( command=command, error=str(e) )