def _is_running(self): """Is there PostgreSQL instance running on a given host and port.""" LOG.debug('Checking if database is running at ' + self.host + ':' + str(self.port)) check_db = ['psql', '-U', self.user, '-c', 'SELECT version();', '-p', str(self.port), '-h', self.host, '-d', 'postgres'] err, code = util.call_command(check_db, self.run_env) return code == 0
def _initialize_database_data(self): """Initialize a PostgreSQL instance with initdb. """ LOG.debug('Initializing database at ' + self.path) init_db = ['initdb', '-U', self.user, '-D', self.path, '-E SQL_ASCII'] err, code = util.call_command(init_db, self.run_env) # logger -> print error return code == 0
def connect(self, init=False): """ Connect to a PostgreSQL instance with given path, host and port. """ LOG.debug("Connecting to database...") LOG.debug("Checking if database is running at [{0}:{1}]" .format(self.host, str(self.port))) if self.user: # Try to connect to a specific database # with a specific user. check_db = ['psql', '-h', self.host, '-p', str(self.port), '-U', self.user, '-d', self.database, '-c', 'SELECT version();'] else: # Try to connect with the default settings. check_db = ['psql', '-h', self.host, '-p', str(self.port), '-c', 'SELECT version();'] if not self.interactive: # Do not prompt for password in non-interactive mode. check_db.append('--no-password') # If the user has a password pre-specified, use that for the # 'psql' call! env = self.run_env if self.run_env else os.environ env = env.copy() if self.password: env['PGPASSWORD'] = self.password err, code = util.call_command(check_db, env) if code: LOG.debug(err) return DBStatus.FAILED_TO_CONNECT if init: if not self._create_schema(): return DBStatus.SCHEMA_INIT_ERROR return self.check_schema()
def _initialize_database_data(self): """Initialize a PostgreSQL instance with initdb. """ LOG.debug('Initializing database at ' + self.path) init_db = [ 'initdb', '-U', self.user, '-D', self.path, '-E', 'SQL_ASCII' ] err, code = util.call_command(init_db, self.run_env) if code != 0: LOG.error("Couldn't initialize database. Call to 'initdb' " "returned {0}.".format(code)) LOG.error(err) return code == 0
def create_dependencies(command, build_dir): """ Transforms the given original build 'command' to a command that, when executed, is able to generate a dependency list. """ def __eliminate_argument(arg_vect, opt_string, has_arg=False): """ This call eliminates the parameters matching the given option string, along with its argument coming directly after the opt-string if any, from the command. The argument can possibly be separated from the flag. """ while True: option_index = next( (i for i, c in enumerate(arg_vect) if c.startswith(opt_string)), None) if option_index: separate = 1 if has_arg and \ len(arg_vect[option_index]) == len(opt_string) else 0 arg_vect = arg_vect[0:option_index] + \ arg_vect[option_index + separate + 1:] else: break return arg_vect if 'CC_LOGGER_GCC_LIKE' not in os.environ: os.environ['CC_LOGGER_GCC_LIKE'] = 'gcc:g++:clang:clang++:cc:c++' if any(binary_substring in command[0] for binary_substring in os.environ['CC_LOGGER_GCC_LIKE'].split(':')): # gcc and clang can generate makefile-style dependency list. # If an output file is set, the dependency is not written to the # standard output but rather into the given file. # We need to first eliminate the output from the command. command = __eliminate_argument(command, '-o', True) command = __eliminate_argument(command, '--output', True) # Remove potential dependency-file-generator options from the string # too. These arguments found in the logged build command would derail # us and generate dependencies, e.g. into the build directory used. command = __eliminate_argument(command, '-MM') command = __eliminate_argument(command, '-MF', True) command = __eliminate_argument(command, '-MP') command = __eliminate_argument(command, '-MT', True) command = __eliminate_argument(command, '-MQ', True) command = __eliminate_argument(command, '-MD') command = __eliminate_argument(command, '-MMD') # Clang contains some extra options. command = __eliminate_argument(command, '-MJ', True) command = __eliminate_argument(command, '-MV') # Build out custom invocation for dependency generation. command = [command[0], '-E', '-M', '-MT', '__dummy'] + command[1:] # Remove empty arguments command = [i for i in command if i] LOG.debug("Crafting build dependencies from GCC or Clang!") # gcc does not have '--gcc-toolchain' argument it would fail if it is # kept there. # For clang it does not change the output, the include paths from # the gcc-toolchain are not added to the output. command = __eliminate_argument(command, '--gcc-toolchain') output, rc = util.call_command(command, env=os.environ, cwd=build_dir) output = codecs.decode(output, 'utf-8', 'replace') if rc == 0: # Parse 'Makefile' syntax dependency output. dependencies = output.replace('__dummy: ', '') \ .replace('\\', '') \ .replace(' ', '') \ .replace(' ', '\n') # The dependency list already contains the source file's path. return [dep for dep in dependencies.split('\n') if dep != ""] else: raise IOError("Failed to generate dependency list for " + ' '.join(command) + "\n\nThe original output was: " + output) else: raise ValueError("Cannot generate dependency list for build " "command '" + ' '.join(command) + "'")
def create_dependencies(action): """ Transforms the given original build 'command' to a command that, when executed, is able to generate a dependency list. """ def __eliminate_argument(arg_vect, opt_strings, num_args=0): """ This call eliminates the parameters matching the given option strings, along with the number of arguments coming directly after the opt-string from the command. """ option_index = next( (i for i, c in enumerate(arg_vect) if c in opt_strings), None) if option_index: arg_vect = arg_vect[0:option_index] + \ arg_vect[option_index + num_args + 1:] return arg_vect if 'CC_LOGGER_GCC_LIKE' not in os.environ: os.environ['CC_LOGGER_GCC_LIKE'] = 'gcc:g++:clang:clang++:cc:c++' command = action.original_command.split(' ') if any(binary_substring in command[0] for binary_substring in os.environ['CC_LOGGER_GCC_LIKE'].split(':')): # gcc and clang can generate makefile-style dependency list. # If an output file is set, the dependency is not written to the # standard output but rather into the given file. # We need to first eliminate the output from the command. command = __eliminate_argument(command, ['-o', '--output'], 1) # Remove potential dependency-file-generator options from the string # too. These arguments found in the logged build command would derail # us and generate dependencies, e.g. into the build directory used. command = __eliminate_argument(command, ['-MM']) command = __eliminate_argument(command, ['-MF'], 1) command = __eliminate_argument(command, ['-MP']) command = __eliminate_argument(command, ['-MT'], 1) command = __eliminate_argument(command, ['-MQ'], 1) command = __eliminate_argument(command, ['-MD']) command = __eliminate_argument(command, ['-MMD']) # Clang contains some extra options. command = __eliminate_argument(command, ['-MJ'], 1) command = __eliminate_argument(command, ['-MV']) # Build out custom invocation for dependency generation. command = [command[0], '-E', '-M', '-MT', '__dummy'] + command[1:] LOG.debug("Crafting build dependencies from GCC or Clang!") output, rc = util.call_command(command, env=os.environ, cwd=action.directory) output = codecs.decode(output, 'utf-8', 'replace') if rc == 0: # Parse 'Makefile' syntax dependency output. dependencies = output.replace('__dummy: ', '') \ .replace('\\', '') \ .replace(' ', '') \ .replace(' ', '\n') # The dependency list already contains the source file's path. return [dep for dep in dependencies.split('\n') if dep != ""] else: raise IOError("Failed to generate dependency list for " + ' '.join(command) + "\n\nThe original output was: " + output) else: raise ValueError("Cannot generate dependency list for build " "command '" + ' '.join(command) + "'")