Пример #1
0
def verifyDependencies():
  """
  Verify that we have no dependency issues in package manager. Dependency issues could appear because of aborted or terminated
  package installation process or invalid packages state after manual modification of packages list on the host
   :return True if no dependency issues found, False if dependency issue present
  :rtype bool
  """
  check_str = None
  cmd = None

  if OSCheck.is_redhat_family():
    cmd = ['/usr/bin/yum', '-d', '0', '-e', '0', 'check', 'dependencies']
    check_str = "has missing requires|Error:"
  elif OSCheck.is_suse_family():
    cmd = ['/usr/bin/zypper', '--quiet', '--non-interactive' 'verify', '--dry-run']
    check_str = "\d+ new package(s)? to install"
  elif OSCheck.is_ubuntu_family():
    cmd = ['/usr/bin/apt-get', '-qq', 'check']
    check_str = "has missing dependency|E:"

  if check_str is None or cmd is None:
    raise Fail("Unsupported OSFamily on the Agent Host")

  code, out = rmf_shell.checked_call(cmd, sudo=True)

  output_regex = re.compile(check_str)

  if code or (out and output_regex.search(out)):
    err_msg = Logger.filter_text("Failed to verify package dependencies. Execution of '%s' returned %s. %s" % (cmd, code, out))
    Logger.error(err_msg)
    return False

  return True
Пример #2
0
def get_user_call_output(command,
                         user,
                         quiet=False,
                         is_checked_call=True,
                         **call_kwargs):
    """
  This function eliminates only output of command inside the su, ignoring the su ouput itself.
  This is useful since some users have motd messages setup by default on su -l. 
  
  @return: code, stdout, stderr
  """
    command_string = shell.string_cmd_from_args_list(command) if isinstance(
        command, (list, tuple)) else command
    out_files = []

    try:
        out_files.append(tempfile.NamedTemporaryFile())
        out_files.append(tempfile.NamedTemporaryFile())

        # other user should be able to write to it
        for f in out_files:
            os.chmod(f.name, 0666)

        command_string += " 1>" + out_files[0].name
        command_string += " 2>" + out_files[1].name

        code, _ = shell.call(shell.as_user(command_string, user),
                             quiet=quiet,
                             **call_kwargs)

        files_output = []
        for f in out_files:
            files_output.append(f.read().decode("utf-8").strip('\n'))

        if code:
            all_output = files_output[1] + '\n' + files_output[0]
            err_msg = Logger.filter_text(
                ("Execution of '%s' returned %d. %s") %
                (command_string, code, all_output))

            if is_checked_call:
                raise Fail(err_msg)
            else:
                Logger.warning(err_msg)

        result = code, files_output[0], files_output[1]

        caller_filename = sys._getframe(1).f_code.co_filename
        is_internal_call = shell.NOT_LOGGED_FOLDER in caller_filename
        if quiet == False or (quiet == None and not is_internal_call):
            log_msg = "{0} returned {1}".format(get_user_call_output.__name__,
                                                result)
            Logger.info(log_msg)

        return result
    finally:
        for f in out_files:
            f.close()
Пример #3
0
    def service_check(self, env):
        import params

        # If Ambari IS managing Kerberos identities (kerberos-env/manage_identities = true), it is
        # expected that a (smoke) test principal and its associated keytab file is available for use
        # **  If not available, this service check will fail
        # **  If available, this service check will execute
        #
        # If Ambari IS NOT managing Kerberos identities (kerberos-env/manage_identities = false), the
        # smoke test principal and its associated keytab file may not be available
        # **  If not available, this service check will execute
        # **  If available, this service check will execute

        if ((params.smoke_test_principal is not None)
                and (params.smoke_test_keytab_file is not None)
                and os.path.isfile(params.smoke_test_keytab_file)):
            print "Performing kinit using %s" % params.smoke_test_principal

            ccache_file_name = HASH_ALGORITHM("{0}|{1}".format(
                params.smoke_test_principal,
                params.smoke_test_keytab_file)).hexdigest()
            ccache_file_path = "{0}{1}kerberos_service_check_cc_{2}".format(
                params.tmp_dir, os.sep, ccache_file_name)

            kinit_path_local = functions.get_kinit_path(
                default('/configurations/kerberos-env/executable_search_paths',
                        None))
            kinit_command = "{0} -c {1} -kt {2} {3}".format(
                kinit_path_local, ccache_file_path,
                params.smoke_test_keytab_file, params.smoke_test_principal)

            try:
                # kinit
                Execute(kinit_command,
                        user=params.smoke_user,
                        wait_for_finish=True,
                        tries=params.service_check_retry_count,
                        try_sleep=params.service_check_retry_period_sec)
            finally:
                File(
                    ccache_file_path,
                    # Since kinit might fail to write to the cache file for various reasons, an existence check should be done before cleanup
                    action="delete",
                )
        elif params.manage_identities:
            err_msg = Logger.filter_text(
                "Failed to execute kinit test due to principal or keytab not found or available"
            )
            raise Fail(err_msg)
        else:
            # Ambari is not managing identities so if the smoke user does not exist, indicate why....
            print "Skipping this service check since Ambari is not managing Kerberos identities and the smoke user " \
                  "credentials are not available. To execute this service check, the smoke user principal name " \
                  "and keytab file location must be set in the cluster_env and the smoke user's keytab file must" \
                  "exist in the configured location."
Пример #4
0
  def test_kinit(identity, user=None):
    principal = get_property_value(identity, 'principal')
    kinit_path_local = functions.get_kinit_path(default('/configurations/kerberos-env/executable_search_paths', None))
    kdestroy_path_local = functions.get_kdestroy_path(default('/configurations/kerberos-env/executable_search_paths', None))

    if principal is not None:
      keytab_file = get_property_value(identity, 'keytab_file')
      keytab = get_property_value(identity, 'keytab')
      password = get_property_value(identity, 'password')

      # If a test keytab file is available, simply use it
      if (keytab_file is not None) and (os.path.isfile(keytab_file)):
        command = '%s -k -t %s %s' % (kinit_path_local, keytab_file, principal)
        Execute(command,
          user = user,
        )
        return shell.checked_call(kdestroy_path_local)

      # If base64-encoded test keytab data is available; then decode it, write it to a temporary file
      # use it, and then remove the temporary file
      elif keytab is not None:
        (fd, test_keytab_file) = tempfile.mkstemp()
        os.write(fd, base64.b64decode(keytab))
        os.close(fd)

        try:
          command = '%s -k -t %s %s' % (kinit_path_local, test_keytab_file, principal)
          Execute(command,
            user = user,
          )
          return shell.checked_call(kdestroy_path_local)
        except:
          raise
        finally:
          if test_keytab_file is not None:
            os.remove(test_keytab_file)

      # If no keytab data is available and a password was supplied, simply use it.
      elif password is not None:
        process = subprocess.Popen([kinit_path_local, principal], stdin=subprocess.PIPE)
        stdout, stderr = process.communicate(password)
        if process.returncode:
          err_msg = Logger.filter_text("Execution of kinit returned %d. %s" % (process.returncode, stderr))
          raise Fail(err_msg)
        else:
          return shell.checked_call(kdestroy_path_local)
      else:
        return 0, ''
    else:
      return 0, ''
Пример #5
0
def get_user_call_output(command,
                         user,
                         quiet=False,
                         is_checked_call=True,
                         **call_kwargs):
    """
  This function eliminates only output of command inside the su, ignoring the su ouput itself.
  This is useful since some users have motd messages setup by default on su -l. 
  
  @return: code, stdout, stderr
  """
    command_string = shell.string_cmd_from_args_list(command) if isinstance(
        command, (list, tuple)) else command
    out_files = []

    try:
        out_files.append(tempfile.NamedTemporaryFile())
        out_files.append(tempfile.NamedTemporaryFile())

        # other user should be able to write to it
        for f in out_files:
            os.chmod(f.name, 0666)

        command_string += " 1>" + out_files[0].name
        command_string += " 2>" + out_files[1].name

        code, _ = shell.call(shell.as_user(command_string, user),
                             quiet=quiet,
                             **call_kwargs)

        files_output = []
        for f in out_files:
            files_output.append(f.read().strip('\n'))

        if code:
            all_output = files_output[1] + '\n' + files_output[0]
            err_msg = Logger.filter_text(
                ("Execution of '%s' returned %d. %s") %
                (command_string, code, all_output))

            if is_checked_call:
                raise Fail(err_msg)
            else:
                Logger.warning(err_msg)

        return code, files_output[0], files_output[1]
    finally:
        for f in out_files:
            f.close()
Пример #6
0
  def install_package(self, name, use_repos=[], skip_repos=[], is_upgrade=False):
    if is_upgrade or use_repos or not self._check_existence(name):
      cmd = INSTALL_CMD[self.get_logoutput()]
      copied_sources_files = []
      is_tmp_dir_created = False
      if use_repos:
        is_tmp_dir_created = True
        apt_sources_list_tmp_dir = tempfile.mkdtemp(suffix="-ambari-apt-sources-d")
        Logger.info("Temporal sources directory was created: %s" % apt_sources_list_tmp_dir)
        if 'base' not in use_repos:
          cmd = cmd + ['-o', 'Dir::Etc::SourceList=%s' % EMPTY_FILE]
        for repo in use_repos:
          if repo != 'base':
            new_sources_file = os.path.join(apt_sources_list_tmp_dir, repo + '.list')
            Logger.info("Temporal sources file will be copied: %s" % new_sources_file)
            sudo.copy(os.path.join(APT_SOURCES_LIST_DIR, repo + '.list'), new_sources_file)
            copied_sources_files.append(new_sources_file)
        cmd = cmd + ['-o', 'Dir::Etc::SourceParts=%s' % apt_sources_list_tmp_dir]

      cmd = cmd + [name]
      Logger.info("Installing package %s ('%s')" % (name, string_cmd_from_args_list(cmd)))
      code, out = self.call_with_retries(cmd, sudo=True, env=INSTALL_CMD_ENV, logoutput=self.get_logoutput())
      
      if self.is_locked_output(out):
        err_msg = Logger.filter_text("Execution of '%s' returned %d. %s" % (cmd, code, out))
        raise Fail(err_msg)
      
      # apt-get update wasn't done too long maybe?
      if code:
        Logger.info("Execution of '%s' returned %d. %s" % (cmd, code, out))
        Logger.info("Failed to install package %s. Executing `%s`" % (name, string_cmd_from_args_list(REPO_UPDATE_CMD)))
        code, out = self.call_with_retries(REPO_UPDATE_CMD, sudo=True, logoutput=self.get_logoutput())
        
        if code:
          Logger.info("Execution of '%s' returned %d. %s" % (REPO_UPDATE_CMD, code, out))
          
        Logger.info("Retrying to install package %s" % (name))
        self.checked_call_with_retries(cmd, sudo=True, env=INSTALL_CMD_ENV, logoutput=self.get_logoutput())

      if is_tmp_dir_created:
        for temporal_sources_file in copied_sources_files:
          Logger.info("Removing temporal sources file: %s" % temporal_sources_file)
          os.remove(temporal_sources_file)
        Logger.info("Removing temporal sources directory: %s" % apt_sources_list_tmp_dir)
        os.rmdir(apt_sources_list_tmp_dir)
    else:
      Logger.info("Skipping installation of existing package %s" % (name))
Пример #7
0
  def install_package(self, name, use_repos=[], skip_repos=[], is_upgrade=False):
    if is_upgrade or use_repos or not self._check_existence(name):
      cmd = INSTALL_CMD[self.get_logoutput()]
      copied_sources_files = []
      is_tmp_dir_created = False
      if use_repos:
        is_tmp_dir_created = True
        apt_sources_list_tmp_dir = tempfile.mkdtemp(suffix="-ambari-apt-sources-d")
        Logger.info("Temporal sources directory was created: %s" % apt_sources_list_tmp_dir)
        if 'base' not in use_repos:
          cmd = cmd + ['-o', 'Dir::Etc::SourceList=%s' % EMPTY_FILE]
        for repo in use_repos:
          if repo != 'base':
            new_sources_file = os.path.join(apt_sources_list_tmp_dir, repo + '.list')
            Logger.info("Temporal sources file will be copied: %s" % new_sources_file)
            sudo.copy(os.path.join(APT_SOURCES_LIST_DIR, repo + '.list'), new_sources_file)
            copied_sources_files.append(new_sources_file)
        cmd = cmd + ['-o', 'Dir::Etc::SourceParts=%s' % apt_sources_list_tmp_dir]

      cmd = cmd + [name]
      Logger.info("Installing package %s ('%s')" % (name, string_cmd_from_args_list(cmd)))
      code, out = self.call_until_not_locked(cmd, sudo=True, env=INSTALL_CMD_ENV, logoutput=self.get_logoutput())
      
      if self.is_locked_output(out):
        err_msg = Logger.filter_text("Execution of '%s' returned %d. %s" % (cmd, code, out))
        raise Fail(err_msg)
      
      # apt-get update wasn't done too long maybe?
      if code:
        Logger.info("Execution of '%s' returned %d. %s" % (cmd, code, out))
        Logger.info("Failed to install package %s. Executing `%s`" % (name, string_cmd_from_args_list(REPO_UPDATE_CMD)))
        code, out = self.call_until_not_locked(REPO_UPDATE_CMD, sudo=True, logoutput=self.get_logoutput())
        
        if code:
          Logger.info("Execution of '%s' returned %d. %s" % (REPO_UPDATE_CMD, code, out))
          
        Logger.info("Retrying to install package %s" % (name))
        self.checked_call_until_not_locked(cmd, sudo=True, env=INSTALL_CMD_ENV, logoutput=self.get_logoutput())

      if is_tmp_dir_created:
        for temporal_sources_file in copied_sources_files:
          Logger.info("Removing temporal sources file: %s" % temporal_sources_file)
          os.remove(temporal_sources_file)
        Logger.info("Removing temporal sources directory: %s" % apt_sources_list_tmp_dir)
        os.rmdir(apt_sources_list_tmp_dir)
    else:
      Logger.info("Skipping installation of existing package %s" % (name))
Пример #8
0
  def verify_dependencies(self):
    """
    Verify that we have no dependency issues in package manager. Dependency issues could appear because of aborted or terminated
    package installation process or invalid packages state after manual modification of packages list on the host

    :return True if no dependency issues found, False if dependency issue present
    :rtype bool
    """
    code, out = self.checked_call(VERIFY_DEPENDENCY_CMD, sudo=True)
    pattern = re.compile("\d+ new package(s)? to install")

    if code or (out and pattern.search(out)):
      err_msg = Logger.filter_text("Failed to verify package dependencies. Execution of '%s' returned %s. %s" % (VERIFY_DEPENDENCY_CMD, code, out))
      Logger.error(err_msg)
      return False

    return True
Пример #9
0
  def verify_dependencies(self):
    """
    Verify that we have no dependency issues in package manager. Dependency issues could appear because of aborted or terminated
    package installation process or invalid packages state after manual modification of packages list on the host

    :return True if no dependency issues found, False if dependency issue present
    :rtype bool
    """
    r = shell.subprocess_executor(self.properties.verify_dependency_cmd)
    pattern = re.compile("\d+ new package(s)? to install")

    if r.code or (r.out and pattern.search(r.out)):
      err_msg = Logger.filter_text("Failed to verify package dependencies. Execution of '{0}' returned {1}. {2}".format(
        self.properties.verify_dependency_cmd, r.code, r.out))
      Logger.error(err_msg)
      return False

    return True
Пример #10
0
    def verify_dependencies(self):
        """
    Verify that we have no dependency issues in package manager. Dependency issues could appear because of aborted or terminated
    package installation process or invalid packages state after manual modification of packages list on the host

    :return True if no dependency issues found, False if dependency issue present
    :rtype bool
    """
        r = shell.subprocess_executor(self.properties.verify_dependency_cmd)
        pattern = re.compile("has missing dependency|E:")

        if r.code or (r.out and pattern.search(r.out)):
            err_msg = Logger.filter_text(
                "Failed to verify package dependencies. Execution of '%s' returned %s. %s"
                % (VERIFY_DEPENDENCY_CMD, code, out))
            Logger.error(err_msg)
            return False

        return True
Пример #11
0
def as_sudo(command, env=None, auto_escape=True):
  """
  command - list or tuple of arguments.
  env - when run as part of Execute resource, this SHOULD NOT be used.
  It automatically gets replaced later by call, checked_call. This should be used in not_if, only_if
  """
  if isinstance(command, (list, tuple)):
    command = string_cmd_from_args_list(command, auto_escape=auto_escape)
  else:
    # Since ambari user sudoer privileges may be restricted,
    # without having /bin/bash permission, and /bin/su permission.
    # Running interpreted shell commands in scope of 'sudo' is not possible.
    #   
    # In that case while passing string,
    # any bash symbols eventually added to command like && || ; < > | << >> would cause problems.
    err_msg = Logger.filter_text(("String command '%s' cannot be run as sudo. Please supply the command as a tuple of arguments") % (command))
    raise Fail(err_msg)

  env = _get_environment_str(_add_current_path_to_env(env)) if env else ENV_PLACEHOLDER
  return "{0} {1} -H -E {2}".format(_get_sudo_binary(), env, command)
Пример #12
0
def as_sudo(command, env=None, auto_escape=True):
  """
  command - list or tuple of arguments.
  env - when run as part of Execute resource, this SHOULD NOT be used.
  It automatically gets replaced later by call, checked_call. This should be used in not_if, only_if
  """
  if isinstance(command, (list, tuple)):
    command = string_cmd_from_args_list(command, auto_escape=auto_escape)
  else:
    # Since ambari user sudoer privileges may be restricted,
    # without having /bin/bash permission, and /bin/su permission.
    # Running interpreted shell commands in scope of 'sudo' is not possible.
    #   
    # In that case while passing string,
    # any bash symbols eventually added to command like && || ; < > | << >> would cause problems.
    err_msg = Logger.filter_text(("String command '%s' cannot be run as sudo. Please supply the command as a tuple of arguments") % (command))
    raise Fail(err_msg)

  env = _get_environment_str(_add_current_path_to_env(env)) if env else ENV_PLACEHOLDER
  return "{0} {1} -H -E {2}".format(_get_sudo_binary(), env, command)
def get_user_call_output(command, user, quiet=False, is_checked_call=True, **call_kwargs):
  """
  This function eliminates only output of command inside the su, ignoring the su ouput itself.
  This is useful since some users have motd messages setup by default on su -l. 
  
  @return: code, stdout, stderr
  """
  command_string = shell.string_cmd_from_args_list(command) if isinstance(command, (list, tuple)) else command
  out_files = []
  
  try:
    out_files.append(tempfile.NamedTemporaryFile())
    out_files.append(tempfile.NamedTemporaryFile())
    
    # other user should be able to write to it
    for f in out_files:
      os.chmod(f.name, 0666)
    
    command_string += " 1>" + out_files[0].name
    command_string += " 2>" + out_files[1].name
    
    code, _ = shell.call(shell.as_user(command_string, user), quiet=quiet, **call_kwargs)
    
    files_output = []
    for f in out_files:
      files_output.append(f.read().strip('\n'))
      
    if code:
      all_output = files_output[1] + '\n' + files_output[0]
      err_msg = Logger.filter_text(("Execution of '%s' returned %d. %s") % (command_string, code, all_output))
      
      if is_checked_call:
        raise Fail(err_msg)
      else:
        Logger.warning(err_msg)      
    
    return code, files_output[0], files_output[1]
  finally:
    for f in out_files:
      f.close()
Пример #14
0
      proc.wait()

  finally:
    for fp in files_to_close:
      fp.close()
      
  out = fd_to_string[proc.stdout].strip('\n')
  err = fd_to_string[proc.stderr].strip('\n')
  all_output = all_output.strip('\n')
  
  if timeout: 
    if not timeout_event.is_set():
      t.cancel()
    # timeout occurred
    else:
      err_msg = Logger.filter_text(("Execution of '%s' was killed due timeout after %d seconds") % (command_alias, timeout))
      raise ExecuteTimeoutException(err_msg)
   
  code = proc.returncode
  
  if throw_on_failure and code:
    err_msg = Logger.filter_text(("Execution of '%s' returned %d. %s") % (command_alias, code, all_output))
    raise Fail(err_msg)
  
  # if separate stderr is enabled (by default it's redirected to out)
  if stderr == subprocess.PIPE:
    return code, out, err
  
  return code, out

def as_sudo(command, env=None, auto_escape=True):
Пример #15
0
        os.close(master_fd)

    proc.wait()
    out = out.strip('\n')

    if timeout:
        if not timeout_event.is_set():
            t.cancel()
        # timeout occurred
        else:
            raise ExecuteTimeoutException()

    code = proc.returncode

    if throw_on_failure and code:
        err_msg = Logger.filter_text(
            ("Execution of '%s' returned %d. %s") % (command_alias, code, out))
        raise Fail(err_msg)

    return code, out


def as_sudo(command, env=None):
    """
  command - list or tuple of arguments.
  env - when run as part of Execute resource, this SHOULD NOT be used.
  It automatically gets replaced later by call, checked_call. This should be used in not_if, only_if
  """
    if isinstance(command, (list, tuple)):
        command = string_cmd_from_args_list(command)
    else:
        # Since ambari user sudoer privileges may be restricted,
Пример #16
0
    all_output = all_output.strip('\n')

    if timeout:
        if not timeout_event.is_set():
            t.cancel()
        # timeout occurred
        else:
            err_msg = "Execution of '{0}' was killed due timeout after {1} seconds".format(
                command, timeout)
            raise ExecuteTimeoutException(err_msg)

    code = proc.returncode

    if throw_on_failure and code:
        err_msg = Logger.filter_text(
            "Execution of '{0}' returned {1}. {2}".format(
                command_alias, code, all_output))
        raise ExecutionFailed(err_msg, code, out, err)

    # if separate stderr is enabled (by default it's redirected to out)
    if stderr == subprocess.PIPE:
        return code, out, err

    return code, out


def as_sudo(command, env=None, auto_escape=True):
    """
  command - list or tuple of arguments.
  env - when run as part of Execute resource, this SHOULD NOT be used.
  It automatically gets replaced later by call, checked_call. This should be used in not_if, only_if
Пример #17
0
def _call(command,
          logoutput=None,
          throw_on_failure=True,
          stdout=subprocess32.PIPE,
          stderr=subprocess32.STDOUT,
          cwd=None,
          env=None,
          preexec_fn=preexec_fn,
          user=None,
          wait_for_finish=True,
          timeout=None,
          on_timeout=None,
          path=None,
          sudo=False,
          on_new_line=None,
          tries=1,
          try_sleep=0,
          timeout_kill_strategy=TerminateStrategy.TERMINATE_PARENT,
          returns=[0]):
    """
  Execute shell command
  
  @param command: list/tuple of arguments (recommended as more safe - don't need to escape) 
  or string of the command to execute
  @param logoutput: boolean, whether command output should be logged of not
  @param throw_on_failure: if true, when return code is not zero exception is thrown
  @param stdout,stderr: 
    subprocess32.PIPE - enable output to variable
    subprocess32.STDOUT - redirect to stdout
    None - disable output to variable, and output to Python out straightly (even if logoutput is False)
    {int fd} - redirect to file with descriptor.
    {string filename} - redirects to a file with name.
  """
    command_alias = Logger.format_command_for_output(command)
    command_alias = string_cmd_from_args_list(command_alias) if isinstance(
        command_alias, (list, tuple)) else command_alias

    # Append current PATH to env['PATH']
    env = _add_current_path_to_env(env)

    # Append path to env['PATH']
    if path:
        path = os.pathsep.join(path) if isinstance(path,
                                                   (list, tuple)) else path
        env['PATH'] = os.pathsep.join([env['PATH'], path])

    if sudo and user:
        raise ValueError(
            "Only one from sudo or user argument could be set to True")

    # prepare command cmd
    if sudo:
        command = as_sudo(command, env=env)
    elif user:
        command = as_user(command, user, env=env)

    # convert to string and escape
    if isinstance(command, (list, tuple)):
        command = string_cmd_from_args_list(command)

    # replace placeholder from as_sudo / as_user if present
    env_str = _get_environment_str(env)
    for placeholder, replacement in PLACEHOLDERS_TO_STR.iteritems():
        command = command.replace(placeholder,
                                  replacement.format(env_str=env_str))

    # --noprofile is used to preserve PATH set for ambari-agent
    subprocess32_command = [
        "/bin/bash", "--login", "--noprofile", "-c", command
    ]

    files_to_close = []
    if isinstance(stdout, basestring):
        stdout = open(stdout, 'wb')
        files_to_close.append(stdout)
    if isinstance(stderr, basestring):
        stderr = open(stderr, 'wb')
        files_to_close.append(stderr)

    try:
        proc = subprocess32.Popen(subprocess32_command,
                                  stdout=stdout,
                                  stderr=stderr,
                                  cwd=cwd,
                                  env=env,
                                  shell=False,
                                  close_fds=True,
                                  preexec_fn=preexec_fn)

        if timeout:
            timeout_event = threading.Event()
            timer = threading.Timer(
                timeout, _on_timeout,
                [proc, timeout_event, timeout_kill_strategy])
            timer.start()

        if not wait_for_finish:
            return proc

        # in case logoutput == False, never log.
        logoutput = logoutput is True and Logger.logger.isEnabledFor(
            logging.INFO) or logoutput is None and Logger.logger.isEnabledFor(
                logging.DEBUG)
        read_set = []

        if stdout == subprocess32.PIPE:
            read_set.append(proc.stdout)
        if stderr == subprocess32.PIPE:
            read_set.append(proc.stderr)

        fd_to_string = {proc.stdout: "", proc.stderr: ""}
        all_output = ""

        while read_set:

            is_proccess_running = proc.poll() is None
            ready, _, _ = select.select(read_set, [], [], 1)

            if not is_proccess_running and not ready:
                break

            for out_fd in read_set:
                if out_fd in ready:
                    line = os.read(out_fd.fileno(), 1024)

                    if not line:
                        read_set = copy.copy(read_set)
                        read_set.remove(out_fd)
                        out_fd.close()
                        continue

                    fd_to_string[out_fd] += line
                    all_output += line

                    if on_new_line:
                        try:
                            on_new_line(line, out_fd == proc.stderr)
                        except Exception:
                            err_msg = "Caused by on_new_line function failed with exception for input argument '{0}':\n{1}".format(
                                line, traceback.format_exc())
                            raise Fail(err_msg)

                    if logoutput:
                        sys.stdout.write(line)
                        sys.stdout.flush()

        # Wait for process to terminate
        if not timeout or not timeout_event.is_set():
            proc.wait()

    finally:
        for fp in files_to_close:
            fp.close()

    out = fd_to_string[proc.stdout].strip('\n')
    err = fd_to_string[proc.stderr].strip('\n')
    all_output = all_output.strip('\n')

    if timeout:
        if not timeout_event.is_set():
            timer.cancel()
        # timeout occurred
        else:
            err_msg = "Execution of '{0}' was killed due timeout after {1} seconds".format(
                command, timeout)
            raise ExecuteTimeoutException(err_msg)

    code = proc.returncode

    if throw_on_failure and not code in returns:
        err_msg = Logger.filter_text(
            "Execution of '{0}' returned {1}. {2}".format(
                command_alias, code, all_output))
        raise ExecutionFailed(err_msg, code, out, err)

    # if separate stderr is enabled (by default it's redirected to out)
    if stderr == subprocess32.PIPE:
        return code, out, err

    return code, out
Пример #18
0
  out = fd_to_string[proc.stdout].strip('\n')
  err = fd_to_string[proc.stderr].strip('\n')
  all_output = all_output.strip('\n')
  
  if timeout: 
    if not timeout_event.is_set():
      t.cancel()
    # timeout occurred
    else:
      err_msg = "Execution of '{0}' was killed due timeout after {1} seconds".format(command, timeout)
      raise ExecuteTimeoutException(err_msg)
   
  code = proc.returncode
  
  if throw_on_failure and code:
    err_msg = Logger.filter_text("Execution of '{0}' returned {1}. {2}".format(command_alias, code, all_output))
    raise Fail(err_msg)
  
  # if separate stderr is enabled (by default it's redirected to out)
  if stderr == subprocess.PIPE:
    return code, out, err
  
  return code, out

def as_sudo(command, env=None, auto_escape=True):
  """
  command - list or tuple of arguments.
  env - when run as part of Execute resource, this SHOULD NOT be used.
  It automatically gets replaced later by call, checked_call. This should be used in not_if, only_if
  """
  if isinstance(command, (list, tuple)):
Пример #19
0
    os.close(master_fd)

  proc.wait()  
  out = out.strip('\n')
  
  if timeout: 
    if not timeout_event.is_set():
      t.cancel()
    # timeout occurred
    else:
      raise ExecuteTimeoutException()
   
  code = proc.returncode
  
  if throw_on_failure and code:
    err_msg = Logger.filter_text(("Execution of '%s' returned %d. %s") % (command_alias, code, out))
    raise Fail(err_msg)
  
  return code, out

def as_sudo(command, env=None, auto_escape=True):
  """
  command - list or tuple of arguments.
  env - when run as part of Execute resource, this SHOULD NOT be used.
  It automatically gets replaced later by call, checked_call. This should be used in not_if, only_if
  """
  if isinstance(command, (list, tuple)):
    command = string_cmd_from_args_list(command, auto_escape=auto_escape)
  else:
    # Since ambari user sudoer privileges may be restricted,
    # without having /bin/bash permission, and /bin/su permission.