Esempio n. 1
0
  def install(self):
    """ Fetches buildout configuration from the server, run buildout with
    it. If it fails, we notify the server.
    """
    self.logger.info("Installing software release %s..." % self.url)
    root_stat_info = os.stat(self.software_root)
    os.environ = utils.getCleanEnvironment(pwd.getpwuid(root_stat_info.st_uid
      ).pw_dir)
    if not os.path.isdir(self.software_path):
      os.mkdir(self.software_path)
    extends_cache = tempfile.mkdtemp()
    if os.getuid() == 0:
      # In case when running as root copy ownership, to simplify logic
      for path in [self.software_path, extends_cache]:
        path_stat_info = os.stat(path)
        if root_stat_info.st_uid != path_stat_info.st_uid or\
             root_stat_info.st_gid != path_stat_info.st_gid:
            os.chown(path, root_stat_info.st_uid,
                root_stat_info.st_gid)
    try:
      buildout_parameter_list = [
        'buildout:extends-cache=%s' % extends_cache,
        'buildout:directory=%s' % self.software_path,]

      if self.signature_private_key_file or \
          self.upload_cache_url or \
            self.upload_dir_url is not None:
        buildout_parameter_list.append('buildout:networkcache-section=networkcache')
      for  buildout_option, value in (
         ('%ssignature-private-key-file=%s', self.signature_private_key_file),
         ('%supload-cache-url=%s', self.upload_cache_url),
         ('%supload-dir-url=%s', self.upload_dir_url),
         ('%sshacache-cert-file=%s', self.shacache_cert_file),
         ('%sshacache-key-file=%s', self.shacache_key_file),
         ('%sshadir-cert-file=%s', self.shadir_cert_file),
         ('%sshadir-key-file=%s', self.shadir_key_file),
         ):
        if value:
          buildout_parameter_list.append( \
              buildout_option % ('networkcache:', value))

      buildout_parameter_list.extend(['-c', self.url])
      utils.bootstrapBuildout(self.software_path, self.buildout,
          additional_buildout_parametr_list=buildout_parameter_list,
          console=self.console)
      utils.launchBuildout(self.software_path,
                     os.path.join(self.software_path, 'bin', 'buildout'),
                     additional_buildout_parametr_list=buildout_parameter_list,
                     console=self.console)
    finally:
      shutil.rmtree(extends_cache)
Esempio n. 2
0
  def install(self):
    """ Creates configuration file from template in software_path, then
    installs the software partition with the help of buildout
    """
    # XXX: Shall be no op in case if revision had not changed
    #      It requires implementation of revision on server
    self.logger.info("Installing Computer Partition %s..." \
        % self.computer_partition.getId())
    # Checks existence and permissions of Partition directory
    # Note : Partitions have to be created and configured before running slapgrid
    if not os.path.isdir(self.instance_path):
      raise PathDoesNotExistError('Please create partition directory %s'
                                           % self.instance_path)
    instance_stat_info = os.stat(self.instance_path)
    permission = oct(stat.S_IMODE(instance_stat_info.st_mode))
    if permission != REQUIRED_COMPUTER_PARTITION_PERMISSION:
      raise WrongPermissionError('Wrong permissions in %s : actual ' \
                                          'permissions are : %s, wanted ' \
                                          'are %s' %
                                          (self.instance_path, permission,
                                            REQUIRED_COMPUTER_PARTITION_PERMISSION))
    os.environ = utils.getCleanEnvironment(pwd.getpwuid(
      instance_stat_info.st_uid).pw_dir)
    # Generates buildout part from template
    # TODO how to fetch the good template? Naming conventions?
    template_location = os.path.join(self.software_path, 'template.cfg')
    config_location = os.path.join(self.instance_path, 'buildout.cfg')
    self.logger.debug("Coping %r to %r" % (template_location, config_location))
    shutil.copy(template_location, config_location)
    # fill generated buildout with additional information
    buildout_text = open(config_location).read()
    buildout_text += '\n\n' + pkg_resources.resource_string(__name__,
        'templates/buildout-tail.cfg.in') % dict(
      computer_id=self.computer_id,
      partition_id=self.partition_id,
      server_url=self.server_url,
      software_release_url=self.software_release_url,
      key_file=self.key_file,
      cert_file=self.cert_file
    )
    open(config_location, 'w').write(buildout_text)
    os.chmod(config_location, 0640)
    # Try to find the best possible buildout:
    #  *) if software_root/bin/bootstrap exists use this one to bootstrap
    #     locally
    #  *) as last resort fallback to buildout binary from software_path
    bootstrap_candidate_dir = os.path.abspath(os.path.join(self.software_path,
      'bin'))
    if os.path.isdir(bootstrap_candidate_dir):
      bootstrap_candidate_list = [q for q in os.listdir(bootstrap_candidate_dir)
        if q.startswith('bootstrap')]
    else:
      bootstrap_candidate_list = []
    uid, gid = self.getUserGroupId()
    os.chown(config_location, -1, int(gid))
    if len(bootstrap_candidate_list) == 0:
      buildout_binary = os.path.join(self.software_path, 'bin', 'buildout')
      self.logger.warning("Falling back to default buildout %r" %
        buildout_binary)
    else:
      if len(bootstrap_candidate_list) != 1:
        raise ValueError('More then one bootstrap candidate found.')
      # Reads uid/gid of path, launches buildout with thoses privileges
      bootstrap_file = os.path.abspath(os.path.join(bootstrap_candidate_dir,
        bootstrap_candidate_list[0]))

      file = open(bootstrap_file, 'r')
      line = file.readline()
      file.close()
      invocation_list = []
      if line.startswith('#!'):
        invocation_list = line[2:].split()
      invocation_list.append(bootstrap_file)
      self.logger.debug('Invoking %r in %r' % (' '.join(invocation_list),
        self.instance_path))
      kw = dict()
      if not self.console:
        kw.update(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
      process_handler = utils.SlapPopen(invocation_list,
        preexec_fn=lambda: utils.dropPrivileges(uid, gid), cwd=self.instance_path,
        env=utils.getCleanEnvironment(pwd.getpwuid(uid).pw_dir), **kw)
      result_std = process_handler.communicate()[0]
      if self.console:
        result_std = 'Please consult messages above.'
      if process_handler.returncode is None or process_handler.returncode != 0:
        message = 'Failed to bootstrap buildout in %r:\n%s\n' % (
            self.instance_path, result_std)
        raise BuildoutFailedError(message)
      buildout_binary = os.path.join(self.instance_path, 'sbin', 'buildout')

    if not os.path.exists(buildout_binary):
      # use own buildout generation
      utils.bootstrapBuildout(self.instance_path, self.buildout,
        ['buildout:bin-directory=%s'% os.path.join(self.instance_path,
        'sbin')], console=self.console)
      buildout_binary = os.path.join(self.instance_path, 'sbin', 'buildout')
    # Launches buildout
    utils.launchBuildout(self.instance_path,
                   buildout_binary, console=self.console)
    # Generates supervisord configuration file from template
    self.logger.info("Generating supervisord config file from template...")
    # check if CP/etc/run exists and it is a directory
    # iterate over each file in CP/etc/run
    # if at least one is not 0750 raise -- partition has something funny
    runner_list = []
    if os.path.exists(self.run_path):
      if os.path.isdir(self.run_path):
        runner_list = os.listdir(self.run_path)
    if len(runner_list) == 0:
      self.logger.warning('No runners found for partition %r' %
          self.partition_id)
      if os.path.exists(self.supervisord_partition_configuration_path):
        os.unlink(self.supervisord_partition_configuration_path)
    else:
      partition_id = self.computer_partition.getId()
      program_partition_template = pkg_resources.resource_stream(__name__,
          'templates/program_partition_supervisord.conf.in').read()
      group_partition_template = pkg_resources.resource_stream(__name__,
          'templates/group_partition_supervisord.conf.in').read()
      partition_supervisor_configuration = group_partition_template % dict(
          instance_id=partition_id,
          program_list=','.join(['_'.join([partition_id, runner])
            for runner in runner_list]))
      for runner in runner_list:
        partition_supervisor_configuration += '\n' + \
            program_partition_template % dict(
          program_id='_'.join([partition_id, runner]),
          program_directory=self.instance_path,
          program_command=os.path.join(self.run_path, runner),
          program_name=runner,
          instance_path=self.instance_path,
          user_id=uid,
          group_id=gid,
          # As supervisord has no environment to inherit setup minimalistic one
          HOME=pwd.getpwuid(uid).pw_dir,
          USER=pwd.getpwuid(uid).pw_name,
        )
      utils.updateFile(self.supervisord_partition_configuration_path,
          partition_supervisor_configuration)
    self.updateSupervisor()