text: # Copyright 2015 Hewlett-Packard Development Company, L.P.
  #
  # Licensed under the Apache License, Version 2.0 (the "License"); you may
  # not use this file except in compliance with the License. You may obtain
  # a copy of the License at
  #
  #      http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  # License for the specific language governing permissions and limitations
  # under the License.
  
  import os
  import shutil
  import sys
  
  from cliff import command
  from oslo_config import generator
  from oslo_log import log as logging
  from six import moves
  from testrepository import commands
  
  from tempest.cmd import workspace
  
  LOG = logging.getLogger(__name__)
  
  TESTR_CONF = """[DEFAULT]
  test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \\
      OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \\
      OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-500} \\
      ${PYTHON:-python} -m subunit.run discover -t %s %s $LISTOPT $IDOPTION
  test_id_option=--load-list $IDFILE
  test_list_option=--list
  group_regex=([^\.]*\.)*
  """
  
  
  def get_tempest_default_config_dir():
      """Get default config directory of tempest
  
      There are 3 dirs that get tried in priority order. First is /etc/tempest,
      if that doesn't exist it looks for a tempest dir in the XDG_CONFIG_HOME
      dir (defaulting to ~/.config/tempest) and last it tries for a
      ~/.tempest/etc directory. If none of these exist a ~/.tempest/etc
      directory will be created.
  
      :return: default config dir
      """
      global_conf_dir = '/etc/tempest'
      xdg_config = os.environ.get('XDG_CONFIG_HOME',
                                  os.path.expanduser('~/.config'))
      user_xdg_global_path = os.path.join(xdg_config, 'tempest')
      user_global_path = os.path.join(os.path.expanduser('~'), '.tempest/etc')
      if os.path.isdir(global_conf_dir):
          return global_conf_dir
      elif os.path.isdir(user_xdg_global_path):
          return user_xdg_global_path
      elif os.path.isdir(user_global_path):
          return user_global_path
      else:
          os.makedirs(user_global_path)
          return user_global_path
  
  
  class TempestInit(command.Command):
      """Setup a local working environment for running tempest"""
  
      def get_parser(self, prog_name):
          parser = super(TempestInit, self).get_parser(prog_name)
          parser.add_argument('dir', nargs='?', default=os.getcwd(),
                              help="The path to the workspace directory. If you "
                              "omit this argument, the workspace directory is "
                              "your current directory")
          parser.add_argument('--config-dir', '-c', default=None)
          parser.add_argument('--show-global-config-dir', '-s',
                              action='store_true', dest='show_global_dir',
                              help="Print the global config dir location, "
                                   "then exit")
          parser.add_argument('--name', help="The workspace name", default=None)
          parser.add_argument('--workspace-path', default=None,
                              help="The path to the workspace file, the default "
                                   "is ~/.tempest/workspace.yaml")
          return parser
  
      def generate_testr_conf(self, local_path):
          testr_conf_path = os.path.join(local_path, '.testr.conf')
          top_level_path = os.path.dirname(os.path.dirname(__file__))
          discover_path = os.path.join(top_level_path, 'test_discover')
          testr_conf = TESTR_CONF % (top_level_path, discover_path)
          with open(testr_conf_path, 'w+') as testr_conf_file:
              testr_conf_file.write(testr_conf)
  
      def get_configparser(self, conf_path):
          config_parse = moves.configparser.ConfigParser()
          config_parse.optionxform = str
          # get any existing values if a config file already exists
          if os.path.isfile(conf_path):
              # use read() for Python 2 and 3 compatibility
              config_parse.read(conf_path)
          return config_parse
  
      def update_local_conf(self, conf_path, lock_dir, log_dir):
          config_parse = self.get_configparser(conf_path)
          # Set local lock_dir in tempest conf
          if not config_parse.has_section('oslo_concurrency'):
              config_parse.add_section('oslo_concurrency')
          config_parse.set('oslo_concurrency', 'lock_path', lock_dir)
          # Set local log_dir in tempest conf
          config_parse.set('DEFAULT', 'log_dir', log_dir)
          # Set default log filename to tempest.log
          config_parse.set('DEFAULT', 'log_file', 'tempest.log')
  
          # write out a new file with the updated configurations
          with open(conf_path, 'w+') as conf_file:
              config_parse.write(conf_file)
  
      def copy_config(self, etc_dir, config_dir):
          if os.path.isdir(config_dir):
              shutil.copytree(config_dir, etc_dir)
          else:
              LOG.warning("Global config dir %s can't be found" % config_dir)
  
      def generate_sample_config(self, local_dir):
          conf_generator = os.path.join(os.path.dirname(__file__),
                                        'config-generator.tempest.conf')
          output_file = os.path.join(local_dir, 'etc/tempest.conf.sample')
          if os.path.isfile(conf_generator):
              generator.main(['--config-file', conf_generator, '--output-file',
                              output_file])
          else:
              LOG.warning("Skipping sample config generation because global "
                          "config file %s can't be found" % conf_generator)
  
      def create_working_dir(self, local_dir, config_dir):
          # make sure we are working with abspath however tempest init is called
          local_dir = os.path.abspath(local_dir)
          # Create local dir if missing
          if not os.path.isdir(local_dir):
              LOG.debug('Creating local working dir: %s' % local_dir)
              os.mkdir(local_dir)
          elif not os.listdir(local_dir) == []:
              raise OSError("Directory you are trying to initialize already "
                            "exists and is not empty: %s" % local_dir)
  
          lock_dir = os.path.join(local_dir, 'tempest_lock')
          etc_dir = os.path.join(local_dir, 'etc')
          config_path = os.path.join(etc_dir, 'tempest.conf')
          log_dir = os.path.join(local_dir, 'logs')
          testr_dir = os.path.join(local_dir, '.testrepository')
          # Create lock dir
          if not os.path.isdir(lock_dir):
              LOG.debug('Creating lock dir: %s' % lock_dir)
              os.mkdir(lock_dir)
          # Create log dir
          if not os.path.isdir(log_dir):
              LOG.debug('Creating log dir: %s' % log_dir)
              os.mkdir(log_dir)
          # Create and copy local etc dir
          self.copy_config(etc_dir, config_dir)
          # Generate the sample config file
          self.generate_sample_config(local_dir)
          # Update local confs to reflect local paths
          self.update_local_conf(config_path, lock_dir, log_dir)
          # Generate a testr conf file
          self.generate_testr_conf(local_dir)
          # setup local testr working dir
          if not os.path.isdir(testr_dir):
              commands.run_argv(['testr', 'init', '-d', local_dir], sys.stdin,
                                sys.stdout, sys.stderr)
  
      def take_action(self, parsed_args):
          workspace_manager = workspace.WorkspaceManager(
              parsed_args.workspace_path)
          name = parsed_args.name or parsed_args.dir.split(os.path.sep)[-1]
          config_dir = parsed_args.config_dir or get_tempest_default_config_dir()
          if parsed_args.show_global_dir:
              print("Global config dir is located at: %s" % config_dir)
              sys.exit(0)
          self.create_working_dir(parsed_args.dir, config_dir)
          workspace_manager.register_new_workspace(
              name, parsed_args.dir, init=True)
  