Example #1
0
class native_package_base(with_metaclass(ABCMeta, object)):
    def __init__(self, bl):
        bl = bl or blurber()
        check.check_blurber(bl)
        self._blurber = bl

    @abstractmethod
    def installed_packages(self):
        'Return a list of packages on this computer.'
        raise NotImplemented('installed_packages')

    @abstractmethod
    def package_files(self, package_name):
        'Return a list of files installed for package.'
        raise NotImplemented('package_files')

    @abstractmethod
    def package_dirs(self, package_name):
        'Return a list of dirs installed for package.'
        raise NotImplemented('package_dirs')

    @abstractmethod
    def is_installed(self, package_name):
        'Return True if package is installed.'
        raise NotImplemented('is_installed')

    @abstractmethod
    def owner(self, filename):
        'Return the package that owns filename.'
        raise NotImplemented('owner')

    @abstractmethod
    def package_info(self, filename):
        'Return info structure about the package.'
        raise NotImplemented('package_info')

    @abstractmethod
    def remove(self, package_name, force_package_root):
        'Remove a package.'
        raise NotImplemented('remove')

    @abstractmethod
    def install(self, package_filename):
        'Install a package.'
        raise NotImplemented('install')

    def has_package(self, package_name):
        'Return True if package_name is installed.'
        check.check_string(package_name)

        return package_name in self.installed_packages()

    def has_any_package(self, package_names):
        'Return True if any of package_names is installed.'
        check.check_string_seq(package_names)

        for package_name in package_names:
            if self.has_package(package_name):
                return True
        return False
Example #2
0
class computer_setup_task(with_metaclass(_computer_setup_register_meta,
                                         object)):
    @abstractmethod
    def name(self):
        'Name for task.'
        raise NotImplemented('name')

    @abstractmethod
    def description(self):
        'Description for task.'
        raise NotImplemented('description')

    @abstractmethod
    def average_duration(self):
        'Average duration in seconds.'
        raise NotImplemented('average_duration')

    @abstractmethod
    def is_needed(self):
        'Return True of the task needs to run.'
        raise NotImplemented('is_needed')

    @abstractmethod
    def run(self, options):
        'Run the task.'
        raise NotImplemented('run')
class vmware_command_interpreter(
        with_metaclass(_command_interpreter_register_meta, object)):
    @abstractmethod
    def name(self):
        'Name for this interpreter.'
        raise NotImplemented('name')

    @abstractmethod
    def is_default(self):
        'Return True if this command interpreter is the default.'
        raise NotImplemented('is_default')

    @abstractmethod
    def supported_systems(self):
        'Return a tuple of supported systems.'
        raise NotImplemented('supported_systems')

    @abstractmethod
    def full_path(self):
        'Return the full path of the interpreter in the vm'
        raise NotImplemented('interpreter_path')

    command = namedtuple('command', 'interpreter_path, script_text')

    @abstractmethod
    def build_command(self, script_text):
        'Build a command and return a command object for it'
        raise NotImplemented('build_command')
Example #4
0
class filesystem_base(with_metaclass(ABCMeta, object)):
    'Abstract interface for dealing with system specific non portable filesystem stuff.'

    @classmethod
    @abstractmethod
    def free_disk_space(self, directory):
        'Return the free space for directory in bytes.'
        raise NotImplemented('free_disk_space')

    @classmethod
    @abstractmethod
    def sync(self):
        'Sync the filesystem.  Only works for both unix and windows in python3.  Otherwise only unix.'
        raise NotImplemented('sync')

    @classmethod
    @abstractmethod
    def has_symlinks(self):
        'Return True if this system has support for symlinks.'
        raise NotImplemented('has_symlinks')

    @classmethod
    @abstractmethod
    def remove_directory(self, d):
        'Recursively remove a directory.'
        raise NotImplemented('remove_directory')
class archive_operation_base(with_metaclass(ABCMeta, object)):
  'An archive operation interface.'

  @abstractmethod
  def execute(self, temp_dir):
    'Execute this operation in a temp_dir of the unpacked archive.'
    raise NotImplementedError()
Example #6
0
class recipe_load_env_base(with_metaclass(ABCMeta, object)):

  @abstractmethod
  def get_build_target(self):
    raise NotImplementedError

  @abstractmethod
  def get_downloads_manager(self):
    raise NotImplementedError

  @abstractmethod
  def get_source_finder(self):
    raise NotImplementedError

  @property
  def build_target(self):
    return self.get_build_target()

  @property
  def downloads_manager(self):
    return self.get_downloads_manager()

  @property
  def source_finder(self):
    return self.get_source_finder()
Example #7
0
class credentials_source(with_metaclass(ABCMeta, object)):
    @abstractmethod
    def is_valid(self):
        pass

    @abstractmethod
    def credentials(self):
        pass
Example #8
0
class python_source_base(with_metaclass(ABCMeta, object)):
    '''
  Abstract interface for dealing with the source of a python exe
  and other platform specific python information
  '''
    @classmethod
    @abstractmethod
    def exe_source(clazz, exe):
        'Return the source of the python executable.  Stuff like brew, xcode, system, python.org.'
        raise NotImplemented('exe_source')

    @classmethod
    @abstractmethod
    def possible_python_bin_dirs(clazz):
        'Return a list of possible dirs where the python executable might be.'
        raise NotImplemented('possible_python_bin_dirs')

    @classmethod
    @abstractmethod
    def possible_python_exe_patterns(clazz):
        'Return a list of possible python exe fnmatch patters.'
        raise NotImplemented('possible_python_exe_patterns')

    @classmethod
    @abstractmethod
    def possible_python_dir_should_be_ignored(clazz, dirname):
        'Return True if dirname should be ignored as a possible python bin dir.'
        raise NotImplemented('possible_python_dir_should_be_ignored')

    @classmethod
    @abstractmethod
    def exe_name(clazz, exe):
        'Return the name of a python exe.  without possible extensions or absolute paths.'
        raise NotImplemented('exe_name')

    @classmethod
    @abstractmethod
    def possible_python_dot_org_installer_filenames(clazz, full_version):
        'Return a list of possible python.org installer filenames for full version.'
        raise NotImplemented('possible_python_dot_org_installer_filenames')

    @classmethod
    @abstractmethod
    def versioned_python_exe(clazz, root_dir, version):
        'Return the absolute path the python exe with major.minor version in a virtual env.'
        raise NotImplemented('versioned_python_exe')

    @classmethod
    @abstractmethod
    def python_exe(clazz, root_dir, version):
        'Return the absolute path the python exe with major version in a virtual env.'
        raise NotImplemented('python_exe')

    @classmethod
    @abstractmethod
    def activate_script(clazz, root_dir, variant):
        'Return the absolute path the the acitivate script of a virtual env.'
        raise NotImplemented('activate_script')
Example #9
0
class source_finder(with_metaclass(ABCMeta, object)):
    @abstractmethod
    def find_tarball(self, filename):
        pass

    @abstractmethod
    def ensure_source(self, filename):
        pass

    @classmethod
    def _find_by_filename(self, where, filename):
        return tarball_finder.find_by_filename(where, filename)
Example #10
0
class _file_mime_type_detector_base(with_metaclass(ABCMeta, object)):

  @classmethod
  @abstractmethod
  def is_supported(clazz):
    'Return True if this class is supported on the current platform.'
    raise NotImplemented('is_supported')
  
  @classmethod
  @abstractmethod
  def detect_mime_type(clazz, filename):
    'Detect the mime type for file.'
    raise NotImplemented('detect_mime_type')
Example #11
0
class process_lister_base(with_metaclass(ABCMeta, object)):
    'Abstract interface for listing processes.'

    @classmethod
    @abstractmethod
    def list_processes(clazz):
        'List all processes.'
        raise NotImplemented('list_processes')

    @classmethod
    @abstractmethod
    def open_files(clazz, pid):
        'Return a list of open files for pid or None if pid not found.'
        raise NotImplemented('open_files')
Example #12
0
class vmware_app_base(with_metaclass(ABCMeta, object)):
  'Abstract interface for interacting with the vmware workstation or fusion main application.'
  
  @classmethod
  @abstractmethod
  def is_installed(clazz):
    'Return True if vmware is installed.'
    raise NotImplemented('is_installed')

  @classmethod
  @abstractmethod
  def is_running(clazz):
    'Return True if vmware is running.'
    raise NotImplemented('is_running')

  @classmethod
  @abstractmethod
  def ensure_running(clazz):
    'Ensure vmware is running.'
    raise NotImplemented('ensure_running')

  @classmethod
  @abstractmethod
  def ensure_stopped(clazz):
    'Ensure vmware is stopped.'
    raise NotImplemented('ensure_stopped')

  @classmethod
  @abstractmethod
  def host_type(clazz):
    'Host type form vmrun authentication.'
    raise NotImplemented('host_type')

  @classmethod
  @abstractmethod
  def preferences_filename(clazz):
    'The full path to the preferences filename.'
    raise NotImplemented('preferences_filename')

  @classmethod
  @abstractmethod
  def inventory_filename(clazz):
    'The full path to the inventory filename.'
    raise NotImplemented('inventory_filename')
  
  @classmethod
  @abstractmethod
  def vmrun_exe_path(clazz):
    'The full path to the vmrun executable.'
    raise NotImplemented('vmrun_exe_path')
class file_metadata_getter_base(with_metaclass(ABCMeta, object)):
    @classmethod
    @abstractmethod
    def name(clazz):
        'Return the name of this getter.'
        raise NotImplemented('name')

    @abstractmethod
    def get_value(self, filename):
        'Get a metadata value from filename and return it encoded as bytes.'
        raise NotImplemented('get_value')

    @abstractmethod
    def decode_value(self, value):
        'Decode a value given as bytes.'
        raise NotImplemented('decode_value')
class properties_file_formatter_base(with_metaclass(ABCMeta, object)):
    @abstractmethod
    def delimiter(self):
        raise NotImplemented('delimiter')

    @abstractmethod
    def parse_value(self, key, value):
        raise NotImplemented('parse_value')

    @abstractmethod
    def value_to_text(self, key, value):
        raise NotImplemented('value_to_text')

    @abstractmethod
    def key_value_to_text(self, key, value):
        raise NotImplemented('key_value_to_text')
Example #15
0
class criteria(with_metaclass(ABCMeta, object)):
    'criteria for finding files.'

    FILTER = 1
    STOP = 2

    VALID_ACTIONS = [FILTER, STOP]

    FILE = 0x1
    DIR = 0x2
    ANY = FILE | DIR

    VALID_TARGETS = [FILE, DIR, ANY]

    def __init__(self, action=FILTER, target=ANY):
        self.action = self.check_action(action)
        self.target = self.check_target(target)

    @abstractmethod
    def matches(self, variables):
        pass

    def targets_files(self):
        return (self.target & self.FILE) != 0

    def targets_dirs(self):
        return (self.target & self.DIR) != 0

    @classmethod
    def action_is_valid(clazz, action):
        return action in clazz.VALID_ACTIONS

    @classmethod
    def check_action(clazz, action):
        if not clazz.action_is_valid(action):
            raise ValueError('invalid action: %s' % (str(action)))
        return action

    @classmethod
    def target_is_valid(clazz, target):
        return target in clazz.VALID_TARGETS

    @classmethod
    def check_target(clazz, target):
        if not clazz.target_is_valid(target):
            raise ValueError('invalid target: %s' % (str(target)))
        return target
Example #16
0
class log_writer(with_metaclass(ABCMeta, object)):
    'Abstract base class for writing logs.'

    @abstractmethod
    def write(self, text):
        'same as file.write.'
        raise NotImplementedError('write')

    @abstractmethod
    def close(self):
        'same as file.close.'
        raise NotImplementedError('close')

    @abstractmethod
    def flush(self):
        'same as file.flush.'
        raise NotImplementedError('flush')
Example #17
0
class cli_options_base(with_metaclass(ABCMeta, object)):
    @classmethod
    @abstractmethod
    def default_values(clazz):
        'Return a dict of default values for these options.'
        raise NotImplemented('default_values')

    @classmethod
    @abstractmethod
    def sensitive_keys(clazz):
        'Return a tuple of keys that are secrets and should be protected from __str__.'
        raise NotImplemented('sensitive_keys')

    @classmethod
    @abstractmethod
    def value_type_hints(clazz):
        raise NotImplemented('morph_value_types')

    @classmethod
    @abstractmethod
    def config_file_key(clazz):
        raise NotImplemented('config_file_key')

    @classmethod
    @abstractmethod
    def config_file_env_var_name(clazz):
        raise NotImplemented('config_file_env_var_name')

    @classmethod
    @abstractmethod
    def config_file_section(clazz):
        raise NotImplemented('config_file_section')

    @classmethod
    @abstractmethod
    def error_class(clazz):
        raise NotImplemented('error_class')

    @abstractmethod
    def check_value_types(self):
        'Check the type of each option.'
        raise NotImplemented('check_value_types')

    @classmethod
    def ignore_config_file_variables(clazz):
        return False
Example #18
0
class vmware_command_interpreter_base(with_metaclass(ABCMeta, object)):
    'Abstract interface for dealing with command interpreters in vms.'

    @classmethod
    @abstractmethod
    def interpreters(clazz):
        'Return a tuple of all the available interpreters in the system'
        raise NotImplemented('interpreters')

    @classmethod
    @abstractmethod
    def default_interpreter(clazz):
        'Return the default interpreter'
        raise NotImplemented('default_interpreter')

    @classmethod
    @abstractmethod
    def interpreter_path(clazz, name):
        'Return the full path to the named interpreter'
        raise NotImplemented('interpreter_path')

    command = namedtuple('command', 'interpreter_path, script_text')

    @classmethod
    @abstractmethod
    def build_command(clazz, name, script_text):
        'Build a command and return a command object for it'
        raise NotImplemented('build_command')

    @classmethod
    def interpreter_is_valid(clazz, name):
        'Return True if this system interpreter is valid.'
        check.check_string(name)

        return name in clazz.interpreters()

    @classmethod
    def check_interpreter(clazz, name):
        'Raise an exception if the interpreter is not valid.'
        check.check_string(name)

        if not clazz.interpreter_is_valid(name):
            raise vmware_error(
                'Invalid interpreter: "{}"  Should be one of: {}"'.format(
                    name, ' '.join(clazz.interpreters())))
Example #19
0
class library_base(with_metaclass(ABCMeta, object)):

  def __init__(self):
    pass
  
  @abstractmethod
  def is_shared_library(self, filename):
    'Return True if filename is a shared library.'
    pass

  @abstractmethod
  def is_static_library(self, filename):
    'Return True if filename is a shared library.'
    pass

  @abstractmethod
  def dependencies(self, filename):
    'Return a list of dependencies for filename (executable or shared lib) or None if not applicable.'
    pass

  @abstractmethod
  def shared_extension(self):
    'Return the shared library extension.'
    pass

  @abstractmethod
  def static_extension(self):
    'Return the static library extension.'
    pass

  @abstractmethod
  def shared_prefix(self):
    'Return the shared library prefix.'
    pass

  @abstractmethod
  def static_prefix(self):
    'Return the static library prefix.'
    pass

  @abstractmethod
  def binary_format_name(self):
    'The name of the binary format (usually elf or macho).'
    pass
Example #20
0
class file_cache_item_base(with_metaclass(ABCMeta, object)):
    @abstractmethod
    def __init__(self):
        pass

    @abstractmethod
    def save(self, info):
        assert False, 'not implemented'

    @abstractmethod
    def load(self, cached_filename):
        assert False, 'not implemented'

    @abstractmethod
    def name(self):
        assert False, 'not implemented'

    @abstractmethod
    def checksum(self):
        assert False, 'not implemented'
Example #21
0
class something_base(with_metaclass(ABCMeta, object)):
    def __init__(self):
        pass

    @abstractmethod
    def creator(self):
        'Return the creator name.'
        pass

    @abstractmethod
    def suck_level(self):
        'Return a number between 0 and 10 indicating how much this something sucks.'
        pass


#  @abstractmethod

    def caca(self):
        'Return a number between 0 and 10 indicating how much this something sucks.'
        pass
Example #22
0
class dependency_provider(with_metaclass(ABCMeta, object)):
    def __init__(self):
        pass

    @abstractmethod
    def provided(self):
        'Return a list of dependencies provided by this provider.'
        pass

    @classmethod
    def determine_provided(clazz, o):
        'Determine the list of dependencies provided by o if it is a single or list of dependency provider(s).'
        if check.is_dependency_provider(o):
            return o.provided()
        elif check.is_dependency_provider_seq(o):
            #assert False
            result = []
            for item in o:
                result.extend(item.provided())
            return result
        else:
            return []
class native_package_manager_base(with_metaclass(ABCMeta, object)):
    def __init__(self):
        pass

    @abstractmethod
    def installed_packages(self, interface):
        'Return a list of packages on this computer.'
        pass

    @abstractmethod
    def package_files(self, package_name):
        'Return a list of installed files for the given package.'
        pass

    @abstractmethod
    def package_dirs(self, package_name):
        'Return a list of installed dirs for the given package.'
        pass

    @abstractmethod
    def package_contents(self, package_name):
        'Return a list of contents for the given package.'
        pass

    @abstractmethod
    def is_installed(self, package_name):
        'Return True if package is installed.'
        pass

    @abstractmethod
    def owner(self, filename):
        'Return the package that owns filename.'
        pass

    @abstractmethod
    def package_info(self, filename):
        'Return info structure about the package.'
        pass
class platform_determiner_base(with_metaclass(ABCMeta, object)):
    'Abstract base class for determining what platform we are on.'

    @abstractmethod
    def system(self):
        'system.'
        pass

    @abstractmethod
    def distro(self):
        'distro.'
        pass

    @abstractmethod
    def codename(self):
        'codename.'
        pass

    @abstractmethod
    def family(self):
        'distro family.'
        pass

    @abstractmethod
    def version_major(self):
        'distro version major number.'
        pass

    @abstractmethod
    def version_minor(self):
        'distro version minor number.'
        pass

    @abstractmethod
    def arch(self):
        'arch.'
        pass
Example #25
0
class python_installer_base(with_metaclass(ABCMeta, object)):

  _log = logger('python_installer')
  
  def __init__(self, options):
    check.check_python_installer_options(options)

    self.options = options
  
  @abstractmethod
  def available_versions(self, num):
    'Return a list of python versions available to install.'
    raise NotImplemented('available_versions')
  
  @abstractmethod
  def installed_versions(self):
    'Return a list of installed python versions.'
    raise NotImplemented('installed_versions')

  @abstractmethod
  def install(self, version):
    'Install the major.minor.revision or major.minor version of python.'
    raise NotImplemented('install')

  @abstractmethod
  def update(self, version):
    'Update to the latest major.minor version of python.'
    raise NotImplemented('update')

  @abstractmethod
  def needs_update(self, version):
    'Return True if python version major.minor needs update.'
    raise NotImplemented('needs_update')
  
  @abstractmethod
  def install_package(self, package_filename):
    'Install a python package directly.  Not always supported.'
    raise NotImplemented('install_package')
  
  @abstractmethod
  def uninstall(self, full_version):
    'Uninstall the major.minor.revision full version of python.'
    raise NotImplemented('uninstall_full_version')

  @abstractmethod
  def download(self, full_version):
    'Download the major.minor.revision full version of python to a temporary file.'
    raise NotImplemented('download')

  @abstractmethod
  def supports_full_version(self):
    'Return True if this installer supports installing by full version.'
    raise NotImplemented('supports_full_version')
  
  def blurb(self, message, output = None, fit = False):
    'Print a blurb'
    self.options.blurber.blurb(message, output = output, fit = fit)

  def blurb_verbose(self, message, output = None, fit = False):
    'Print a blurb but only in verbose mode'
    self.options.blurber.blurb_verbose(message, output = output, fit = fit)
    
  def installed_versions_matching(self, version):
    'Return installed versions matching version only.'
    version = python_version.check_version_or_full_version(version)

    installed_versions = self.installed_versions()
    self._log.log_d('installed_versions_matching: installed_versions: {}'.format(installed_versions.to_string()))

    matching_versions = installed_versions.filter_by_version(version)
    matching_versions.sort()
    self._log.log_d('installed_versions_matching: matching_versions: {}'.format(matching_versions.to_string()))
    return matching_versions
  
  def is_installed(self, version):
    'Return True if a python matching version is installed.'
    version = python_version.check_version_or_full_version(version)
    self._log.log_d('is_installed: version={}'.format(version))
    matching_versions = self.installed_versions_matching(version)
    self._log.log_d('is_installed: matching_versions={}'.format(matching_versions))
    result = len(matching_versions) > 0
    self._log.log_d('is_installed: result={}'.format(result))
    return result
Example #26
0
class step(with_metaclass(step_register_meta, object)):

  result = step_result
  
  def __init__(self):
    self._recipe = None
    self._args = {}
    self._values = None

  @property
  def values(self):
    if self._values is None:
      raise ValueError('values have not been set yet.')
    return self._values

  @values.setter
  def values(self, values):
    check.check_dict(values)
    if self._values is not None:
      raise ValueError('values can only be set once.')
    self._values = values
  
  @classmethod
  def args_definition(clazz):
    if not hasattr(clazz, '_args_definition'):
      setattr(clazz, '_args_definition', clazz._determine_args_definition())
    return getattr(clazz, '_args_definition')

  @classmethod
  def _determine_args_definition(clazz):
    defs = clazz.define_args()
    if check.is_string(defs):
      try:
        defs = value_definition.parse_many(defs)
      except RuntimeError as ex:
        filename = inspect.getfile(clazz.define_args)
        line_number = inspect.getsourcelines(clazz.define_args)[1]
        raise RuntimeError('%s: %s:%s' % (ex.message, filename, line_number))
      check.check_dict(defs)
    return defs

  @abstractmethod
  def execute(self, script, env, values, inputs):
    'Execute the step.'
    pass
 
  def on_tag_changed(self):
    'Called when the tag changes.'
    pass

  @classmethod
  @abstractmethod
  def define_args(clazz):
    'Return a list of arg specs.'
    return {}
  
  def update_args(self, args):
    dict_util.update(self.args, args)

  @property
  def recipe(self):
    assert self._recipe != None
    return self._recipe

  @recipe.setter
  def recipe(self, recipe):
    assert recipe != None
    assert self._recipe == None
    self._recipe = recipe
    
  @property
  def tag(self):
    return self.bes_log_tag__

  @tag.setter
  def tag(self, tag):
    log.add_logging(self, tag)
    build_blurb.add_blurb(self, tag)
    self.on_tag_changed()

  @property
  def args(self):
    return self._args

  @args.setter
  def args(self, args):
    if not isinstance(args, dict):
      raise RuntimeError('args needs to be a dict')
    self._args = args

  @classmethod
  def create_command_env(clazz, script):
    env = os_env.make_clean_env(keep_keys = [ 'PYTHONPATH' ])

    STATIC = True
    export_compilation_flags_requirements = clazz.export_compilation_flags_requirements(script, script.build_target.system)
    if STATIC:
      env['REBBE_PKG_CONFIG_STATIC'] = '1'
      
    if export_compilation_flags_requirements:
      cflags, libs = script.requirements_manager.compilation_flags(export_compilation_flags_requirements, static = STATIC)
    else:
      cflags = []
      libs = []

    cflags += script.descriptor.extra_cflags(script.build_target.system)

    env['REBUILD_REQUIREMENTS_CFLAGS'] = ' '.join(cflags)
    env['REBUILD_REQUIREMENTS_CXXFLAGS'] = ' '.join(cflags)
    env['REBUILD_REQUIREMENTS_LDFLAGS'] = ' '.join(libs)

    env.update(script.substitutions)
    tool_deps = script.resolve_deps(['TOOL'], False)
    run_build_deps = script.resolve_deps(['RUN', 'BUILD'], False)
    env = script.env.tools_manager.transform_env(env, tool_deps)
    env = script.requirements_manager.transform_env(env, run_build_deps.names())
    staged_files_env = os_env.make_shell_env(script.staged_files_dir)
    os_env.update(env, staged_files_env)
    
    env['REBUILD_PYTHON_VERSION'] = '2.7'
    env['PYTHON'] = 'python%s' % (env['REBUILD_PYTHON_VERSION'])
    
    tc = toolchain.get_toolchain(script.build_target)
    compiler_flags = tc.compiler_flags()
    env['REBUILD_COMPILE_CFLAGS'] = ' '.join(compiler_flags.get('CFLAGS', []))
    env['REBUILD_COMPILE_LDFLAGS'] = ' '.join(compiler_flags.get('LDFLAGS', []))
    env['REBUILD_COMPILE_CXXFLAGS'] = ' '.join(compiler_flags.get('CXXFLAGS', []))
    env['REBUILD_COMPILE_ARCH_FLAGS'] = ' '.join(compiler_flags.get('REBUILD_COMPILE_ARCH_FLAGS', []))
    env['REBUILD_COMPILE_OPT_FLAGS'] = ' '.join(compiler_flags.get('REBUILD_COMPILE_OPT_FLAGS', []))

    ce = tc.compiler_environment()
    os_env.update(env, ce)
    env['REBUILD_COMPILE_ENVIRONMENT'] = toolchain.flatten_for_shell(ce)

    return env

  @classmethod
  def env_dump(clazz, env, package_name, label):
    for key, value in sorted(env.items()):
      build_blurb.blurb_verbose('rebuild', '%s(%s): %s=%s' % (label, package_name, key, value))
  
  @classmethod
  def call_shell(clazz, command, script, env, shell_env = None, save_logs = None, execution_dir = None):
    command = execute.listify_command(command)
    command = [ part for part in command if part ]
    shell_env = shell_env or key_value_list()
    save_logs = save_logs or []
    check.check_key_value_list(shell_env)
    
    log.log_i('rebuild', 'call_shell(command=%s)' % (command))
    build_blurb.blurb_verbose('rebuild', 'call_shell(cmd=%s, shell_env=%s)' % (command, shell_env))

    env = clazz.create_command_env(script)

    env.update(shell_env)

    #clazz.env_dump(env, script.descriptor.name, 'PRE ENVIRONMENT')

    clazz._env_substitite(env)

    rogue_key = clazz._env_find_roque_dollar_sign(env)
    if rogue_key:
      raise RuntimeError('Rogue dollar sign (\"$\") found in %s: %s' % (rogue_key, env[rogue_key]))

    command = [ variable.substitute(part, env) for part in object_util.listify(command) ]

    # Check that no rogue dollar signs are in the command
    for part in command:
      if variable.has_rogue_dollar_signs(part):
        raise RuntimeError('Rogue dollar sign (\"$\") found in: %s' % (part))
      
    build_blurb.blurb('rebuild', '%s - %s' % (script.descriptor.name, ' '.join(command)))

#    file_util.mkdir(script.build_dir)
    retry_script = clazz._write_retry_script(command, env, script)

    #clazz.env_dump(env, script.descriptor.name, clazz.__name__ + ' : ' + 'POST ENVIRONMENT')

    for k,v in env.items():
      if string_util.is_quoted(v):
        env[k] = string_util.unquote(v)

    if execution_dir:
      cwd = path.join(script.build_dir, execution_dir)
    else:
      cwd = script.build_dir

    rv = execute.execute(command,
                         cwd = cwd,
                         env = env,
                         shell = True,
                         non_blocking = build_blurb.verbose,
                         stderr_to_stdout = build_blurb.verbose,
                         raise_error = False)
    message = rv.stdout
    if rv.stderr:
      message = message + '\n' + rv.stderr
    result = step_result(rv.exit_code == 0, message)
    clazz.save_build_dir_logs(script, save_logs)
    return result

  RETRY_SCRIPT_FILENAME = 'rebbe_retry.sh'

  @classmethod
  def _write_retry_script(clazz, command, env, script):
    from bes.compat import StringIO
    s = StringIO()
    s.write('#!/bin/bash\n')
    s.write('mkdir -p %s\n' % (script.staged_files_dir))
    items = sorted(env.items())
    last_item = items.pop(-1)

    def _item_str(key, value, slash):
      return '%s=\"%s\"%s\n' % (key, value, slash)

    for key, value in items:
      s.write(_item_str(key, value, '\\'))

    s.write(_item_str(last_item[0], last_item[1], ''))

    if string_util.is_string(command):
      s.write(command)
    else:
      s.write(' '.join(command))
    content = s.getvalue()
    file_path = path.join(script.build_dir, clazz.RETRY_SCRIPT_FILENAME)
    file_util.save(file_path, content = content, mode = 0o755)
    return file_path

  @classmethod
  def call_hooks(clazz, hooks, script, env):
    check.check_value_hook_list(hooks)
    for hook in hooks:
      rv = hook.execute(script, env)
      check.is_hook_result(rv)
      if not rv.success:
        return step_result(rv.success, rv.message)
    return step_result(True, None)
  
  @classmethod
  def save_build_dir_logs(clazz, env, filenames):
    'Save any logs that exists to the logs/ dir'
    for filename in filenames:
      src = path.join(env.build_dir, filename)
      dst = path.join(env.logs_dir, path.basename(src))
      if path.isfile(src):
        file_util.copy(src, dst)

  @classmethod
  def export_compilation_flags_requirements(clazz, script, system):
    config = script.descriptor.properties.get('export_compilation_flags_requirements', [])
    if config:
      if check.is_masked_value_list(config):
        resolved = config.resolve(system, value_type.STRING_LIST)
      else:
        raise RuntimeError('not a valid masked_value_list: %s' % (config))
    else:
      resolved = []
    requirements = script.descriptor.requirements.filter_by_hardness(['RUN', 'BUILD']).filter_by_system(system)
    deps_names = requirements.names()
    export_names = resolved
    if export_names == dependency_resolver.ALL_DEPS:
      export_names = deps_names
    delta = (set(export_names) - set(deps_names))
    if delta:
      raise RuntimeError('Trying to export deps that are not specified by %s: %s' % (script.descriptor.name, ' '.join(delta)))
    return export_names
        
  @classmethod
  def _env_find_roque_dollar_sign(clazz, env):
    for key in sorted(env.keys()):
      if variable.has_rogue_dollar_signs(env[key]):
        return key
    return None

  @classmethod
  def _env_substitite(clazz, env):
    for key in sorted(env.keys()):
      env[key] = variable.substitute(str(env[key]), env)
Example #27
0
class file_checksum_getter_base(with_metaclass(ABCMeta, object)):
    @abstractmethod
    def checksum(self, algorithm, filename):
        'Return the checksum for filename using algorithm.'
        pass
Example #28
0
class system_command(with_metaclass(ABCMeta, object)):
  'Abstract base class for dealing with system commands.'

  _log = logger('system_command')
  
  @classmethod
  @abstractmethod
  def exe_name(clazz):
    'The name of the executable.'
    raise NotImplemented('exe_name')

  @classmethod
  @abstractmethod
  def extra_path(clazz):
    'List of extra paths where to find the command.'
    raise NotImplemented('extra_path')

  @classmethod
  @abstractmethod
  def error_class(clazz):
    'The error exception class to raise when errors happen.'
    raise NotImplemented('error_class')

  @classmethod
  @abstractmethod
  def static_args(clazz):
    'List of static arg for all calls of the command.'
    raise NotImplemented('static_args')

  @classmethod
  @abstractmethod
  def supported_systems(clazz):
    'Return a list of supported systems.'
    raise NotImplemented('supported_systems')
  
  @classmethod
  def _find_exe(clazz):
    'Find the exe'
    extra_path = clazz.extra_path()
    exe_name = clazz.exe_name()
    if path.isabs(exe_name):
      exe = exe_name
    else:
      exe = which.which(exe_name, extra_path = clazz.extra_path())
    if exe:
      return exe
    error_class = clazz.error_class()
    if not isinstance(error_class, Exception.__class__):
      raise TypeError('Return value of error_clas() should be an Exception type: {} - {}'.format(error_class,
                                                                                                 type(error_class)))
      
    raise error_class('Failed to find {}'.format(exe_name))

  @classmethod
  def call_command(clazz,
                   args,
                   raise_error = True,
                   env = None,
                   use_sudo = False,
                   stderr_to_stdout = False,
                   check_python_script = True,
                   input_data = None,
                   non_blocking = False,
                   output_encoding = None,
                   output_function = None):
    'Call the command'
    check.check_string_seq(args)
    check.check_bool(raise_error)
    check.check_dict(env, check.STRING_TYPES, check.STRING_TYPES, allow_none = True)
    check.check_bool(use_sudo)
    check.check_bytes(input_data, allow_none = True)
    check.check_bool(non_blocking)
    check.check_string(output_encoding, allow_none = True)
    check.check_callable(output_function, allow_none = True)

    clazz.check_supported()

    clazz._log.log_d('call_command: args={}'.format(' '.join(args)))
    
    if isinstance(args, ( list, tuple )):
      parsed_args = list(args)
    elif isinstance(args, compat.STRING_TYPES):
      parsed_args = command_line.parse_args(args)
    else:
      raise TypeError('Invalid args type.  Should be tuple, list or string: {} - {}'.format(args,
                                                                                            type(args)))
    clazz._log.log_d('call_command: parsed_args={}'.format(' '.join(parsed_args)))

    exe = clazz._find_exe()
    static_args = clazz.static_args() or []
    if not isinstance(static_args, ( list, tuple )):
      raise TypeError('Return value of static_args() should be list or tuple: {} - {}'.format(static_args,
                                                                                              type(static_args)))
    cmd = []
    if use_sudo:
      cmd.append('sudo')
    cmd.append(exe)
    cmd.extend(list(static_args))
    cmd.extend(args)
    clazz._log.log_d('call_command: cmd={} env={}'.format(' '.join(cmd), env))
    return execute.execute(cmd,
                           raise_error = raise_error,
                           env = env,
                           stderr_to_stdout = stderr_to_stdout,
                           check_python_script = check_python_script,
                           input_data = input_data,
                           non_blocking = non_blocking,
                           output_encoding = output_encoding)

  @classmethod
  def call_command_parse_lines(clazz, args, sort = False):
    'Call a command that returns a list of lines'
    rv = clazz.call_command(args, raise_error = True)
    result = clazz.split_lines(rv.stdout)
    if sort:
      result = sorted(result)
    return result

  @classmethod
  def is_supported(clazz):
    'Return True if this command is support on the current system'
    return host.SYSTEM in clazz.supported_systems()
  
  @classmethod
  def check_supported(clazz):
    'Check that the current system supports this command otherwise raise an error'
    if clazz.is_supported():
      return
    raise clazz.error_class('{} is not supported on {} - only {}'.format(clazz.exe_name(),
                                                                         host.SYSTEM,
                                                                         ' '.join(clazz.supported_systems())))
  
  @classmethod
  def has_command(clazz):
    'Return True if the command is found'
    if not clazz.is_supported():
      return False
    try:
      exe = clazz._find_exe()
      return True
    except clazz.error_class() as ex:
      pass
    return False
  
  @classmethod
  def split_lines(clazz, text):
    lines = text.splitlines()
    lines = [ line.strip() for line in lines ]
    return [ line for line in lines if line ]

  @classmethod
  def split_by_white_space(clazz, line):
    parts = []
    for part in re.split(r'\s+', line):
      part = part.strip()
      if part:
        parts.append(part)
    return parts

  @classmethod
  def check_result(clazz, result, message = None):
    'Check that a result is successful or raise an exceptions from it.'
    check.check_string(message, allow_none = True)
    check.check_execute_result(result)
    
    if result.exit_code == 0:
      return
    message = message or 'Failed to execute: {}'.format(' '.join(result.command))
    outputs = [ o.strip() for o in [ result.stdout, result.stderr ] if o.strip() ]
    error_message = '{} - {}'.format(message, ' - '.join(outputs))
    raise clazz.error_class()(error_message)
Example #29
0
class value_hook(with_metaclass(hook_register_meta, value_base)):

    result = hook_result

    def __init__(self, origin=None, properties=None):
        'Create a new hook.'
        super(value_hook, self).__init__(origin, properties=properties)

    def __eq__(self, other):
        return self.filename == other.filename

    #@abstractmethod
    def value_to_string(self, quote, include_properties=True):
        buf = StringIO()
        buf.write(self.__class__.__name__)
        self._append_properties_string(buf, include_properties)
        return buf.getvalue()

    @classmethod
    #@abstractmethod
    def default_value(clazz, class_name):
        'Return the default value to use for this class.'
        return value_hook_list()

    @property
    def filename(self):
        filename = getattr(self, '__load_file__', None)
        if not filename:
            raise RuntimeError('filename not set')
        return path.abspath(filename)

    #@abstractmethod
    def sources(self, recipe_env):
        'Return a list of sources this caca provides or None if no sources.'
        return [self.filename]

    #@abstractmethod
    def substitutions_changed(self):
        pass

    @classmethod
    #@abstractmethod
    def parse(clazz, origin, value, node):
        if origin:
            check.check_value_origin(origin)
        check.check_node(node)
        hook_name, _, rest = string_util.partition_by_white_space(value)
        hook_class = hook_registry.get(hook_name)
        if not hook_class:
            raise TypeError('%s: hook class not found: %s' %
                            (origin, hook_name))
        properties = clazz.parse_properties(rest)
        hook_instance = hook_class(origin=origin, properties=properties)
        return hook_instance

    @classmethod
    #@abstractmethod
    def resolve(clazz, values, class_name):
        check.check_value_hook_seq(values)
        assert class_name == value_type.HOOK_LIST
        result_hooks = []
        for value in values:
            check.check_value_hook(value)
            result_hooks.append(value)
        result = value_hook_list(values=result_hooks)
        result.remove_dups()
        return result

    @abstractmethod
    def execute(self, script, env):
        'Execute the hook.  Same semantics as step.execute.'
        pass
Example #30
0
class deleter(with_metaclass(ABCMeta, object)):
    @abstractmethod
    def delete_file(self, filename):
        'Delete a file or directory.'
        raise NotImplementedError('not implemented')