def run_guest_command(command, shell=True, pty=False, combine_stderr=True, sudo=False, user=None): """ Run command inside a guest container """ # Use a non-login shell _orig_shell = env.shell env.shell = "/bin/bash -c" # Use double quotes for the sudo prompt _orig_sudo_prefix = env.sudo_prefix env.sudo_prefix = 'sudo -S -p "%(sudo_prompt)s" ' # Try to cd to the user's home directory for consistency, # as the default directory is "/" with "vzctl exec2" if not env.cwd: env.command_prefixes.insert(0, "cd 2>/dev/null || true") # Build the guest command guest_command = _shell_wrap_inner( _prefix_commands(_prefix_env_vars(command), "remote"), True, _sudo_prefix(user) if sudo and user else None ) host_command = "vzctl exec2 %s '%s'" % (name_or_ctid, guest_command) # Restore env env.shell = _orig_shell env.sudo_prefix = _orig_sudo_prefix if not env.cwd: env.command_prefixes.pop(0) # Run host command as root return _run_host_command(host_command, shell=shell, pty=pty, combine_stderr=combine_stderr)
def nice_local(command, nice=0, capture=False, shell=None): """ Exactly like Fabric's local but with an optional nice argument """ from fabric.operations import _prefix_env_vars, _prefix_commands, _AttributeString from fabric.state import output, win32, env from fabric.utils import error given_command = command # Apply cd(), path() etc with_env = _prefix_env_vars(command, local=True) wrapped_command = _prefix_commands(with_env, 'local') if output.debug: print("[localhost] local: %s" % (wrapped_command)) elif output.running: print("[localhost] local: " + given_command) # Tie in to global output controls as best we can; our capture argument # takes precedence over the output settings. dev_null = None if capture: out_stream = subprocess.PIPE err_stream = subprocess.PIPE else: dev_null = open(os.devnull, 'w+') # Non-captured, hidden streams are discarded. out_stream = None if output.stdout else dev_null err_stream = None if output.stderr else dev_null try: cmd_arg = wrapped_command if win32 else [wrapped_command] p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, stderr=err_stream, executable=shell, preexec_fn=lambda: os.nice(nice), close_fds=(not win32)) (stdout, stderr) = p.communicate() finally: if dev_null is not None: dev_null.close() # Handle error condition (deal with stdout being None, too) out = _AttributeString(stdout.strip() if stdout else "") err = _AttributeString(stderr.strip() if stderr else "") out.command = given_command out.real_command = wrapped_command out.failed = False out.return_code = p.returncode out.stderr = err if p.returncode not in env.ok_ret_codes: out.failed = True msg = "local() encountered an error (return code %s) while executing '%s'" % ( p.returncode, command) error(message=msg, stdout=out, stderr=err) out.succeeded = not out.failed # If we were capturing, this will be a string; otherwise it will be None. return out
def local_logged(self, cmd): if not self.logging_on: # run without logging local(cmd) return with_env = operations._prefix_env_vars(cmd, local=True) wrapped_command = operations._prefix_commands(with_env, 'local') self.red.lpush(self.job_name + "-" + self.design_name, '> ' + wrapped_command + '\n') self.red.publish(self.job_name + "-" + self.design_name, '> ' + wrapped_command + '\n') s = subprocess.Popen(wrapped_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, executable=None, close_fds=True) for c in iter(lambda: s.stdout.read(1), ''): self.red.publish(self.job_name + "-" + self.design_name, c) self.red.lpush(self.job_name + "-" + self.design_name, c)
def sshagent_run(cmd): """ Helper function. Runs a command with SSH agent forwarding enabled. Note:: Fabric (and paramiko) can't forward your SSH agent. This helper uses your system's ssh to do so. """ # Handle context manager modifications wrapped_cmd = _prefix_commands(_prefix_env_vars(cmd), "remote") try: host, port = env.host_string.split(":") return local("ssh -p %s -A %s@%s '%s'" % (port, env.user, host, wrapped_cmd)) except ValueError: return local("ssh -A %s@%s '%s'" % (env.user, env.host_string, wrapped_cmd))
def sshagent_run(cmd): """ Helper function. Runs a command with SSH agent forwarding enabled. Note:: Fabric (and paramiko) can't forward your SSH agent. This helper uses your system's ssh to do so. """ # Handle context manager modifications wrapped_cmd = _prefix_commands(_prefix_env_vars(cmd), 'remote') try: host, port = env.host_string.split(':') return local("ssh -p %s -A %s@%s '%s'" % (port, env.user, host, wrapped_cmd)) except ValueError: return local("ssh -A %s@%s '%s'" % (env.user, env.host_string, wrapped_cmd))
def run_guest_command(command, shell=True, pty=True, combine_stderr=True, sudo=False, user=None, quiet=False, warn_only=False, stdout=None, stderr=None, group=None, timeout=None, **kwargs): """ Run command inside a guest container """ # Use a non-login shell _orig_shell = env.shell env.shell = '/bin/bash -c' # Use double quotes for the sudo prompt _orig_sudo_prefix = env.sudo_prefix env.sudo_prefix = 'sudo -S -p "%(sudo_prompt)s" ' # Try to cd to the user's home directory for consistency, # as the default directory is "/" with "vzctl exec2" if not env.cwd: env.command_prefixes.insert(0, 'cd 2>/dev/null || true') # Build the guest command guest_command = _shell_wrap_inner( _prefix_commands(_prefix_env_vars(command), 'remote'), True, _sudo_prefix(user) if sudo and user else None) host_command = "vzctl exec2 %s '%s'" % (name_or_ctid, guest_command) # Restore env env.shell = _orig_shell env.sudo_prefix = _orig_sudo_prefix if not env.cwd: env.command_prefixes.pop(0) # Run host command as root return _run_host_command(host_command, shell=shell, pty=pty, combine_stderr=combine_stderr)
def _blocal(command, capture=False): """ Slightly modified version of fabrics 'local' function designed to make the underlying subprocess.Popen call use bash. Taken from fabric operations.py file. """ given_command = command # Apply cd(), path() etc wrapped_command = _prefix_commands(_prefix_env_vars(command), 'local') if output.debug: print("[localhost] local: %s" % (wrapped_command)) elif output.running: print("[localhost] local: " + given_command) # Tie in to global output controls as best we can; our capture argument # takes precedence over the output settings. dev_null = None if capture: out_stream = subprocess.PIPE err_stream = subprocess.PIPE else: dev_null = open(os.devnull, 'w+') # Non-captured, hidden streams are discarded. out_stream = None if output.stdout else dev_null err_stream = None if output.stderr else dev_null try: cmd_arg = wrapped_command if win32 else [wrapped_command] p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, stderr=err_stream,executable="/bin/bash") (stdout, stderr) = p.communicate() finally: if dev_null is not None: dev_null.close() # Handle error condition (deal with stdout being None, too) out = _AttributeString(stdout.strip() if stdout else "") err = _AttributeString(stderr.strip() if stderr else "") out.failed = False out.return_code = p.returncode out.stderr = err if p.returncode != 0: out.failed = True msg = "local() encountered an error (return code %s) while executing '%s'" % (p.returncode, command) fabric.utils.error(message=msg, stdout=out, stderr=err) out.succeeded = not out.failed # If we were capturing, this will be a string; otherwise it will be None. return out
def sshagent_run(cmd, user=None): """ Helper function. Runs a command with SSH agent forwarding enabled. Note:: Fabric (and paramiko) can't forward your SSH agent. This helper uses your system's ssh to do so. """ # Handle context manager modifications wrapped_cmd = _prefix_commands(_prefix_env_vars(cmd), 'remote') if user is None: user = env.user try: host, port = env.host_string.split(':') return local("ssh -o StrictHostKeyChecking=no -p " "%s -A %s@%s '%s'" % (port, user, host, wrapped_cmd)) except ValueError: return local("ssh -o StrictHostKeyChecking=no -A " "%s@%s '%s'" % (user, env.host_string, wrapped_cmd))
def sshagent_run(cmd, user=None): """ Helper function. Runs a command with SSH agent forwarding enabled. Note:: Fabric (and paramiko) can't forward your SSH agent. This helper uses your system's ssh to do so. """ # Handle context manager modifications wrapped_cmd = _prefix_commands(_prefix_env_vars(cmd), 'remote') if user is None: user = env.user opts = ['-A', '-o ServerAliveInterval=60'] if env.disable_known_hosts: opts += ['-o StrictHostKeyChecking=no', '-o UserKnownHostsFile=/dev/null'] try: host, port = env.host_string.split(':') opts.append('-p %s' % port) except ValueError: host = env.host_string opts = ' '.join(opts) return local("ssh %s %s@%s '%s'" % (opts, user, host, wrapped_cmd))
def local(self, command, **kwargs): given_command = command # Apply cd(), path() etc with_env = _prefix_env_vars(command, local=True) wrapped_command = _prefix_commands(with_env, 'local') if kwargs.get('use_sudo'): #cmd = cmd.replace('"','\\"').replace('$','\\$') wrapped_command = 'sudo -E -S -p \'sudo password:\' /bin/bash -c "{0}"'.format(wrapped_command) wrapped_command = self.fmt(wrapped_command, **kwargs) print "[local]",wrapped_command try: hide = None warn_only = False if not state.output.stdout: hide = 'stdout' if self.env.warn_only: warn_only = True rs = invoke_run(wrapped_command, hide=hide, warn=warn_only) rs.succeeded = not rs.failed except invoke.exceptions.Failure as e: print red(e) rs = NoOp() return rs
def sshagent_run(cmd, user=None): """ Helper function. Runs a command with SSH agent forwarding enabled. Note:: Fabric (and paramiko) can't forward your SSH agent. This helper uses your system's ssh to do so. """ # Handle context manager modifications wrapped_cmd = _prefix_commands(_prefix_env_vars(cmd), 'remote') if user is None: user = env.user opts = ['-A', '-o ServerAliveInterval=60'] if env.disable_known_hosts: opts += [ '-o StrictHostKeyChecking=no', '-o UserKnownHostsFile=/dev/null' ] try: host, port = env.host_string.split(':') opts.append('-p %s' % port) except ValueError: host = env.host_string opts = ' '.join(opts) return local("ssh %s %s@%s '%s'" % (opts, user, host, wrapped_cmd))
def _run_command_local(command, shell=True, combine_stderr=True, sudo=False, user=None): ''' Local implementation of fabric.operations._run_command that uses subprocess to execute. ''' # Conditionally import error handling function, since different fabric # versions handle this differently try: from fabric.utils import error except ImportError: from fabric.operations import _handle_failure error = lambda msg=None, **kwargs: _handle_failure(msg) # Set up new var so original argument can be displayed verbatim later. given_command = command # Pick up cuisine sudo mode and password as appropriate if sudo and cuisine.sudo_password(): sudo_prefix = ('echo "%s" | %s -S -p ""' % (cuisine.sudo_password, env.sudo_prefix)) else: sudo_prefix = env.sudo_prefix # Handle context manager modifications, and shell wrapping with settings(sudo_prefix=sudo_prefix): wrapped_command = _shell_wrap( _prefix_commands(_prefix_env_vars(command), 'remote'), shell, _sudo_prefix(user) if sudo else None ) # Execute info line which = 'sudo' if sudo else 'run' if output.debug: print("[%s] %s: %s" % ('local', which, wrapped_command)) elif output.running: print("[%s] %s: %s" % ('local', which, given_command)) # Actual execution, stdin/stdout/stderr handling, and termination stdout, stderr, status = _execute_local(wrapped_command, shell=shell, combine_stderr=combine_stderr) # Assemble output string out = _AttributeString(stdout) err = _AttributeString(stderr) # Error handling out.failed = False if status != 0: out.failed = True msg = "%s() received nonzero return code %s while executing" % ( which, status ) if env.warn_only: msg += " '%s'!" % given_command else: msg += "!\n\nRequested: %s\nExecuted: %s" % ( given_command, wrapped_command ) error(message=msg, stdout=out, stderr=err) # Attach return code to output string so users who have set things to # warn only, can inspect the error code. out.return_code = status # Convenience mirror of .failed out.succeeded = not out.failed # Attach stderr for anyone interested in that. out.stderr = err return out
def bash_local(command, capture=False): """ Run a command on the local system. `local` is simply a convenience wrapper around the use of the builtin Python ``subprocess`` module with ``shell=True`` activated. If you need to do anything special, consider using the ``subprocess`` module directly. `local` is not currently capable of simultaneously printing and capturing output, as `~fabric.operations.run`/`~fabric.operations.sudo` do. The ``capture`` kwarg allows you to switch between printing and capturing as necessary, and defaults to ``False``. When ``capture=False``, the local subprocess' stdout and stderr streams are hooked up directly to your terminal, though you may use the global :doc:`output controls </usage/output_controls>` ``output.stdout`` and ``output.stderr`` to hide one or both if desired. In this mode, `~fabric.operations.local` returns None. When ``capture=True``, this function will return the contents of the command's stdout as a string-like object; as with `~fabric.operations.run` and `~fabric.operations.sudo`, this return value exhibits the ``return_code``, ``stderr``, ``failed`` and ``succeeded`` attributes. See `run` for details. `~fabric.operations.local` will honor the `~fabric.context_managers.lcd` context manager, allowing you to control its current working directory independently of the remote end (which honors `~fabric.context_managers.cd`). .. versionchanged:: 1.0 Added the ``succeeded`` and ``stderr`` attributes. .. versionchanged:: 1.0 Now honors the `~fabric.context_managers.lcd` context manager. .. versionchanged:: 1.0 Changed the default value of ``capture`` from ``True`` to ``False``. """ given_command = command # Apply cd(), path() etc wrapped_command = _prefix_commands(_prefix_env_vars(command), 'local') if output.debug: print("[localhost] local: %s" % (wrapped_command)) elif output.running: print("[localhost] local: " + given_command) # Tie in to global output controls as best we can; our capture argument # takes precedence over the output settings. dev_null = None if capture: out_stream = subprocess.PIPE err_stream = subprocess.PIPE else: dev_null = open(os.devnull, 'w+') # Non-captured, hidden streams are discarded. out_stream = None if output.stdout else dev_null err_stream = None if output.stderr else dev_null try: cmd_arg = wrapped_command if win32 else [wrapped_command] p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, stderr=err_stream, executable="/bin/bash") (stdout, stderr) = p.communicate() finally: if dev_null is not None: dev_null.close() # Handle error condition (deal with stdout being None, too) out = _AttributeString(stdout.strip() if stdout else "") err = _AttributeString(stderr.strip() if stderr else "") out.failed = False out.return_code = p.returncode out.stderr = err if p.returncode != 0: out.failed = True msg = "local() encountered an error (return code %s) while executing '%s'" % (p.returncode, command) error(message=msg, stdout=out, stderr=err) out.succeeded = not out.failed # If we were capturing, this will be a string; otherwise it will be None. return out
def local(command, capture=False, shell=None, ignore_errors=False, env=None): """ Run a command on the local system. `local` is simply a convenience wrapper around the use of the builtin Python ``subprocess`` module with ``shell=True`` activated. If you need to do anything special, consider using the ``subprocess`` module directly. ``shell`` is passed directly to `subprocess.Popen <http://docs.python.org/library/subprocess.html#subprocess.Popen>`_'s ``execute`` argument (which determines the local shell to use.) As per the linked documentation, on Unix the default behavior is to use ``/bin/sh``, so this option is useful for setting that value to e.g. ``/bin/bash``. `local` is not currently capable of simultaneously printing and capturing output, as `~fabric.operations.run`/`~fabric.operations.sudo` do. The ``capture`` kwarg allows you to switch between printing and capturing as necessary, and defaults to ``False``. When ``capture=False``, the local subprocess' stdout and stderr streams are hooked up directly to your terminal, though you may use the global :doc:`output controls </usage/output_controls>` ``output.stdout`` and ``output.stderr`` to hide one or both if desired. In this mode, the return value's stdout/stderr values are always empty. When ``capture=True``, you will not see any output from the subprocess in your terminal, but the return value will contain the captured stdout/stderr. In either case, as with `~fabric.operations.run` and `~fabric.operations.sudo`, this return value exhibits the ``return_code``, ``stderr``, ``failed``, ``succeeded``, ``command`` and ``real_command`` attributes. See `run` for details. `~fabric.operations.local` will honor the `~fabric.context_managers.lcd` context manager, allowing you to control its current working directory independently of the remote end (which honors `~fabric.context_managers.cd`). .. versionchanged:: 1.0 Added the ``succeeded`` and ``stderr`` attributes. .. versionchanged:: 1.0 Now honors the `~fabric.context_managers.lcd` context manager. .. versionchanged:: 1.0 Changed the default value of ``capture`` from ``True`` to ``False``. .. versionadded:: 1.9 The return value attributes ``.command`` and ``.real_command``. """ given_command = command # Apply cd(), path() etc with_env = _prefix_env_vars(command, local=True) wrapped_command = _prefix_commands(with_env, 'local') # if output.debug: # print("[localhost] local: %s" % (wrapped_command)) # elif output.running: # print("[localhost] local: " + given_command) # Tie in to global output controls as best we can; our capture argument # takes precedence over the output settings. dev_null = None if capture: out_stream = subprocess.PIPE err_stream = subprocess.PIPE else: dev_null = open(os.devnull, 'w+') # Non-captured, hidden streams are discarded. out_stream = None if output.stdout else dev_null err_stream = None if output.stderr else dev_null if env is None: env = os.environ try: cmd_arg = wrapped_command if win32 else [wrapped_command] p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, stderr=err_stream, executable=shell, close_fds=(not win32), env=env) (stdout, stderr) = p.communicate() finally: if dev_null is not None: dev_null.close() # Handle error condition (deal with stdout being None, too) out = _AttributeString(stdout.decode().strip() if stdout else "") err = _AttributeString(stderr.decode().strip() if stderr else "") out.command = given_command out.real_command = wrapped_command out.failed = False out.return_code = p.returncode out.stderr = err if p.returncode not in _env.ok_ret_codes and not ignore_errors: out.failed = True # msg = "local() encountered an error (return code %s) while executing '%s'" % (p.returncode, command) # print('\n\n') # if out: # print('{}'.format(out)) # print('\n') # if err: # print('{}'.format(err)) # sys.exit(1) raise CommandError(out) # error(message=msg, stdout=out, stderr=err) out.succeeded = not out.failed # If we were capturing, this will be a string; otherwise it will be None. return out
def _run_command_local(command, shell=True, combine_stderr=True, sudo=False, user=None): ''' Local implementation of fabric.operations._run_command that uses subprocess to execute. ''' # Conditionally import error handling function, since different fabric # versions handle this differently try: from fabric.utils import error except ImportError: from fabric.operations import _handle_failure error = lambda msg=None, **kwargs: _handle_failure(msg) # Set up new var so original argument can be displayed verbatim later. given_command = command # Pick up cuisine sudo mode and password as appropriate if sudo and cuisine.sudo_password(): sudo_prefix = ('echo "%s" | %s -S -p ""' % (cuisine.sudo_password, env.sudo_prefix)) else: sudo_prefix = env.sudo_prefix # Handle context manager modifications, and shell wrapping with settings(sudo_prefix=sudo_prefix): wrapped_command = _shell_wrap( _prefix_commands(_prefix_env_vars(command), 'remote'), shell, _sudo_prefix(user) if sudo else None) # Execute info line which = 'sudo' if sudo else 'run' if output.debug: print("[%s] %s: %s" % ('local', which, wrapped_command)) elif output.running: print("[%s] %s: %s" % ('local', which, given_command)) # Actual execution, stdin/stdout/stderr handling, and termination stdout, stderr, status = _execute_local(wrapped_command, shell=shell, combine_stderr=combine_stderr) # Assemble output string out = _AttributeString(stdout) err = _AttributeString(stderr) # Error handling out.failed = False if status != 0: out.failed = True msg = "%s() received nonzero return code %s while executing" % (which, status) if env.warn_only: msg += " '%s'!" % given_command else: msg += "!\n\nRequested: %s\nExecuted: %s" % (given_command, wrapped_command) error(message=msg, stdout=out, stderr=err) # Attach return code to output string so users who have set things to # warn only, can inspect the error code. out.return_code = status # Convenience mirror of .failed out.succeeded = not out.failed # Attach stderr for anyone interested in that. out.stderr = err return out