Пример #1
0
  def run(self, args, login_credentials = None, extra_env = None,
          no_output = False, raise_error = False, error_message = None):
    check.check_string_seq(args)
    check.check_dict(extra_env, allow_none = True)
    check.check_bool(raise_error)
    check.check_string(error_message, allow_none = True)

    self._log.log_method_d()
    exe = vmware_app.vmrun_exe_path()
    auth_args = self._make_vmrun_auth_args(login_credentials)
    vmrun_args = [ exe ] + auth_args + list(args)
    self._log.log_d('run: vmrun_args={}'.format(vmrun_args))
    env = os_env.clone_current_env(d = extra_env)
    process = subprocess.Popen(vmrun_args,
                               stdout = subprocess.PIPE,
                               stderr = subprocess.STDOUT,
                               shell = False,
                               env = env)
    if no_output:
      output = None
    else:
      output_bytes, _ = process.communicate()
      output = codecs.decode(output_bytes, 'utf-8')
      
    exit_code = process.wait()
    self._log.log_d('run: exit_code={} output="{}"'.format(exit_code, output))
    if exit_code != 0 and raise_error:
      if not error_message:
        args_flat = ' '.join(vmrun_args)
        error_message = 'vmrun command failed: {}\n{}'.format(args_flat, output)
      raise vmware_error(error_message, status_code = exit_code)
    result = self._run_result(output, exit_code, vmrun_args)
    self._log.log_d('run: result: {} - {}'.format(result.exit_code, result.output))
    return result
Пример #2
0
 def call_pyinstaller(clazz, args, build_dir = None, replace_env = None):
   check.check_string_seq(args)
   check.check_string(build_dir, allow_none = True)
   check.check_dict(replace_env, check.STRING_TYPES, check.STRING_TYPES)
   
   cmd = command_line.parse_args(args)
   replace_env = replace_env or {}
   env = os_env.clone_current_env(d = {})
   env.update(replace_env)
   clazz._log.log_d('using env: {}'.format(pprint.pformat(env)))
   clazz._log.log_d('calling pyinstaller: {}'.format(' '.join(cmd)))
   if build_dir:
     file_util.mkdir(build_dir)
   dist_dir = path.join(build_dir, 'dist')
   work_dir = path.join(build_dir, 'work')
   spec_dir = path.join(build_dir, 'spec')
   args = args[:]
   args.extend([ '--distpath', dist_dir ])
   args.extend([ '--workpath', work_dir ])
   args.extend([ '--specpath', spec_dir ])
   try:
     with env_override(env = env) as _:
       PyInstaller_run(pyi_args = args, pyi_config = None)
   except Exception as ex:
     raise pyinstaller_error(str(ex))
Пример #3
0
    def _call_softwareupdate(clazz, args, verbose):
        check.check_string_seq(args)
        check.check_bool(verbose)

        command_line.check_args_type(args)
        args = object_util.listify(args)

        exe = which.which('softwareupdate')
        if not exe:
            raise softwareupdater_error('softwareupdate not found')

        clazz._log.log_d('_call_softwareupdate: exe={} args={}'.format(
            exe, args))

        cmd = [exe] + args
        env = os_env.clone_current_env()
        rv = execute.execute(cmd,
                             env=env,
                             stderr_to_stdout=True,
                             raise_error=False,
                             non_blocking=verbose)
        if rv.exit_code != 0:
            cmd_flat = ' '.join(cmd)
            msg = 'softwareupdate command failed: {} - {}\n{}'.format(
                cmd, rv.exit_code, rv.stdout)
            raise softwareupdater_error(msg, status_code=rv.exit_code)
        return rv
Пример #4
0
    def call_pkgutil(clazz, args, msg=None, use_sudo=False):
        check.check_string_seq(args)
        check.check_string(msg, allow_none=True)
        check.check_bool(use_sudo)

        env = os_env.clone_current_env(d={})
        rv = pkgutil_command.call_command(args,
                                          raise_error=False,
                                          env=env,
                                          use_sudo=use_sudo)
        if rv.exit_code != 0:
            if not msg:
                cmd_flat = ' '.join(args)
                msg = 'pkgutil command failed: {}\n{}'.format(
                    cmd_flat, rv.stdout)
            raise pkgutil_error(msg)
        return rv
Пример #5
0
 def call_docker(clazz, args, cwd=None, non_blocking=True, shell=False):
     exe = which.which('docker')
     if not exe:
         raise docker_error('docker not found')
     cmd = [exe] + command_line.parse_args(args)
     env = os_env.clone_current_env(d={})
     rv = execute.execute(cmd,
                          env=env,
                          shell=shell,
                          cwd=cwd,
                          stderr_to_stdout=True,
                          non_blocking=non_blocking,
                          raise_error=False)
     if rv.exit_code != 0:
         cmd_flag = ' '.join(cmd)
         msg = 'docker command failed: {}\n{}'.format(cmd_flag, rv.stdout)
         raise docker_error(msg)
     return rv
Пример #6
0
    def call_sudo(clazz, args, options=None):
        check.check_sudo_cli_options(options, allow_none=True)

        command_line.check_args_type(args)
        args = object_util.listify(args)
        options = options or sudo_cli_options()

        exe = which.which('sudo')
        if not exe:
            raise sudo_error('sudo not found')

        clazz._log.log_d('sudo: exe={} args={} options={}'.format(
            exe, args, options))

        cmd = [exe]
        tmp_askpass = None
        askpass_env = {}
        if options.password:
            tmp_askpass = clazz._make_temp_askpass(options.password)
            askpass_env = {'SUDO_ASKPASS': tmp_askpass}
            cmd.append('--askpass')
        if options.prompt:
            cmd.extend(['--prompt', '"{}"'.format(options.prompt)])
        cmd.extend(args)
        env = os_env.clone_current_env(d=askpass_env)
        try:
            rv = execute.execute(cmd,
                                 env=env,
                                 cwd=options.working_dir,
                                 stderr_to_stdout=True,
                                 raise_error=False,
                                 non_blocking=options.verbose)
            if rv.exit_code != 0:
                if options.error_message:
                    msg = options.error_message
                else:
                    cmd_flat = ' '.join(cmd)
                    msg = 'sudo command failed: {}\n{}'.format(
                        cmd_flat, rv.stdout)
                raise sudo_error(msg)
            return rv
        finally:
            if tmp_askpass:
                file_util.remove(tmp_askpass)
Пример #7
0
  def call_program(self, args, **kargs):
    'Call a program with the right environment'
    command_line.check_args_type(args)

    kargs = copy.deepcopy(kargs)
    
    self._log.log_method_d()
    self._log.log_d('call_program: args={}'.format(args))

    parsed_args = command_line.parse_args(args)
    self._log.log_d('call_program: parsed_args={}'.format(parsed_args))

    env = os_env.clone_current_env()
    env.update(self.env)
    PATH = env_var(env, 'PATH')
    PYTHONPATH = env_var(env, 'PYTHONPATH')
    
    if 'env' in kargs:
      kargs_env = kargs['env']
      del kargs['env']
      if 'PATH' in kargs_env:
        PATH.append(kargs_env['PATH'])
        del kargs_env['PATH']
      if 'PYTHONPATH' in kargs_env:
        PYTHONPATH.append(kargs_env['PYTHONPATH'])
        del kargs_env['PYTHONPATH']
      env.update(kargs_env)

    PATH.prepend(self.PATH)
    PYTHONPATH.prepend(self.PYTHONPATH)
    kargs['env'] = env
    self._log.log_d('call_program: env={}'.format(env))

    kargs['shell'] = True
    kargs['check_python_script'] = False

    for key, value in sorted(env.items()):
      self._log.log_d('call_program({}): ENV: {}={}'.format(args[0], key, value))
    
    return execute.execute(parsed_args, **kargs)
Пример #8
0
    def test_env_override_push_pop(self):
        original_env = os_env.clone_current_env()
        with env_override() as env:
            env.push()
            env.set('FOO', '666')
            self.assertEqual(self._dict_combine(original_env, {'FOO': '666'}),
                             os_env.clone_current_env())
            env.push()
            env.set('BAR', '667')
            self.assertEqual(
                self._dict_combine(original_env, {
                    'FOO': '666',
                    'BAR': '667'
                }), os_env.clone_current_env())
            env.pop()
            self.assertEqual(self._dict_combine(original_env, {'FOO': '666'}),
                             os_env.clone_current_env())
            env.pop()
            self.assertEqual(original_env, os_env.clone_current_env())

        self.assertEqual(original_env, os_env.clone_current_env())
Пример #9
0
    def call_git(clazz,
                 root,
                 args,
                 raise_error=True,
                 extra_env=None,
                 num_tries=None,
                 retry_wait_seconds=None):
        check.check_string(root)
        command_line.check_args_type(args)
        check.check_bool(raise_error)
        check.check_dict(extra_env,
                         check.STRING_TYPES,
                         check.STRING_TYPES,
                         allow_none=True)
        check.check_int(num_tries, allow_none=True)
        check.check_float(retry_wait_seconds, allow_none=True)
        #print('args={}'.format(args))
        if isinstance(args, (list, tuple)):
            parsed_args = list(args)
        else:
            parsed_args = command_line.parse_args(args)

        num_tries = num_tries if num_tries != None else clazz._DEFAULT_NUM_TRIES
        retry_wait_seconds = retry_wait_seconds if retry_wait_seconds != None else clazz._DEFAULT_RETRY_WAIT_SECONDS

        if num_tries < 1 or num_tries >= clazz._MAX_NUM_TRIES:
            raise git_error(
                'num_tries should be between 1 and {} instead of "{}"'.format(
                    clazz._DEFAULT_NUM_TRIES, num_tries))

        if retry_wait_seconds < clazz._MIN_RETRY_WAIT_SECONDS or retry_wait_seconds >= clazz._MAX_RETRY_WAIT_SECONDS:
            raise git_error(
                'retry_wait_seconds should be between {} and {} instead of "{}"'
                .format(clazz._MIN_RETRY_WAIT_SECONDS,
                        clazz._MAX_RETRY_WAIT_SECONDS, retry_wait_seconds))

        if not hasattr(clazz, '_git_exe'):
            git_exe = clazz.find_git_exe()
            if not git_exe:
                raise git_error('git exe not found in: {}'.format(' '.join(
                    os.environ['PATH'].split(os.pathsep))))
            setattr(clazz, '_git_exe', git_exe)
        git_exe = getattr(clazz, '_git_exe')
        cmd = [git_exe] + parsed_args
        clazz.log.log_d('root=%s; cmd=%s' % (root, ' '.join(cmd)))
        extra_env = extra_env or {}
        env = os_env.clone_current_env(d=extra_env, prepend=True)

        last_try_exception = None
        num_failed_attempts = 0
        rv = None
        for i in range(0, num_tries):
            try:
                clazz.log.log_d('call_git: attempt {} of {}: {}'.format(
                    i + 1, num_tries, ' '.join(cmd)))
                rv = execute.execute(cmd, cwd=root, raise_error=False, env=env)
                if rv.exit_code == 0:
                    clazz.log.log_i('call_git: success {} of {}: {}'.format(
                        i + 1, num_tries, ' '.join(cmd)))
                    break
                else:
                    clazz.log.log_i('call_git: failed {} of {}: {}'.format(
                        i + 1, num_tries, ' '.join(cmd)))

            except Exception as ex:
                num_failed_attempts += 1
                clazz.log.log_w('call_git: failed {} of {}: {}'.format(
                    i + 1, num_tries, ' '.join(cmd)))
                clazz.log.log_d('call_git: exception: {}'.format(str(ex)))
                clazz.log.log_d(
                    'call_git: sleeping {} seconds'.format(retry_wait_seconds))
                time.sleep(retry_wait_seconds)
                last_try_exception = ex

        if not rv:
            message = 'git command attempt failed {} times: {} in {}'.format(
                num_tries, ' '.join(cmd), root)
            clazz.log.log_w('call_git: {}'.format(message))
            raise git_error(message, execute_result=None)

        # first handle the retry failure
        if num_tries > 1 and num_failed_attempts == num_tries and last_try_exception:
            message = 'git command attempt failed {} times: {} in {}\n{}\n{}\n{}'.format(
                num_tries, ' '.join(cmd), root, str(last_try_exception),
                rv.stderr, rv.stdout)
            clazz.log.log_w('call_git: {}'.format(message))
            raise git_error(message, execute_result=rv)

        # handle raise_error if needed
        if rv.exit_code != 0 and raise_error:
            message = 'git command failed: {} in {}\n{}\n{}\n{}'.format(
                ' '.join(cmd), root, str(last_try_exception), rv.stderr,
                rv.stdout)
            clazz.log.log_w('call_git: {}'.format(message))
            raise git_error(message, execute_result=rv)
        #print('rv={}'.format(rv))
        return rv
Пример #10
0
  def main(self):
    p = argparse.ArgumentParser()
    vmware_options_cli_args.add_arguments(p)
    p.add_argument('--tail-log', action = 'store_true', default = False,
                   help = 'Tail the log [ False ]')
    p.add_argument('--dir', action = 'store', default = os.getcwd(),
                   dest = 'source_dir',
                   help = 'Directory to use for the package [ False ]')
    p.add_argument('-o', '--output', action = 'store', default = None,
                   dest = 'output_filename',
                   help = 'Output the log to filename instead of stdout [ False ]')
    p.add_argument('--clone-vm', action = 'store_true', default = False,
                   help = 'Run programs in a clone of the vm [ False ]')
    p.add_argument('vm_id', action = 'store', default = None,
                   help = 'The vmware vmx filename for the vm to test [ None ]')
    p.add_argument('entry_command_args', action = 'store', default = [], nargs = '*',
                   help = 'Optional entry command args [ ]')
    args = p.parse_args()

    self._debug = args.debug
    self._name = path.basename(sys.argv[0])
    tmp_dir = tempfile.mkdtemp()

    tar_util.copy_tree(args.source_dir,
                       tmp_dir,
                       excludes = self._PACKAGE_EXCLUDES)
    entry_command_path = path.join(tmp_dir, self._ENTRY_COMMAND_FILENAME)
    file_util.save(entry_command_path, content = self._ENTRY_COMMAND_CONTENT)

    env = os_env.clone_current_env(d = {
      'xBES_LOG': 'vmware=debug',
    })

    extra_args = []
    if args.debug:
      extra_args.append('--debug')
    if args.tty:
      extra_args.extend([ '--tty', tty ])
    if args.tail_log:
      extra_args.append('--tail-log')
    if args.clone_vm:
      extra_args.append('--clone-vm')
    if args.output_filename:
      extra_args.extend([ '--output', args.output_filename ])
    if args.config_filename:
      print(config_filename)
      extra_args.extend([ '--config', args.config_filename ])
    if args.vmrest_username:
      extra_args.extend([ '--vmrest-username', args.vmrest_username ])
    if args.vmrest_password:
      extra_args.extend([ '--vmrest-password', args.vmrest_password ])
    if args.vmrest_port:
      extra_args.extend([ '--vmrest-port', str(args.vmrest_port) ])
    if args.login_username:
      extra_args.extend([ '--login-username', args.login_username ])
    if args.login_password:
      extra_args.extend([ '--login-password', args.login_password ])
    cmd = [
      'bin/best.py',
      'vmware', 'vm_run_package',
    ] + extra_args + [
      args.vm_id,
      tmp_dir,
      self._ENTRY_COMMAND_FILENAME,
    ] + args.entry_command_args
    self._log.log_d('cmd={}'.format(' '.join([ str(x) for x in cmd ])))
    rv = execute.execute(cmd,
                         env = env,
                         raise_error = False,
                         shell = False,
                         non_blocking = True,
                         stderr_to_stdout = True)
    if rv.exit_code != 0:
      print(rv.stdout)
    return rv.exit_code
Пример #11
0
 def test_env_override_set(self):
     original_env = os_env.clone_current_env()
     with env_override() as env:
         env.set('FOO', '666')
         env.set('BAR', 'hi')
     self.assertEqual(original_env, os_env.clone_current_env())
Пример #12
0
 def test_env_override_init(self):
     original_env = os_env.clone_current_env()
     with env_override({'FOO': '666', 'BAR': 'hi'}) as env:
         pass
     self.assertEqual(original_env, os_env.clone_current_env())