Example #1
0
def do_format(conf):
  random_delay(conf)

  if conf.input_definition_file:
    computer = parse_computer_definition(conf, conf.input_definition_file)
  else:
    # no definition file, figure out computer
    computer = parse_computer_xml(conf, conf.computer_xml)

  computer.instance_root = conf.instance_root
  computer.software_root = conf.software_root
  conf.logger.info('Updating computer')
  address = computer.getAddress(conf.create_tap)
  computer.address = address['addr']
  computer.netmask = address['netmask']

  if conf.output_definition_file:
    write_computer_definition(conf, computer)

  computer.construct(alter_user=conf.alter_user,
                     alter_network=conf.alter_network,
                     create_tap=conf.create_tap)

  if getattr(conf, 'certificate_repository_path', None):
    mkdir_p(conf.certificate_repository_path, mode=0o700)

  # Dumping and sending to the erp5 the current configuration
  if not conf.dry_run:
    computer.dump(path_to_xml=conf.computer_xml,
                  path_to_json=conf.computer_json,
                  logger=conf.logger)
  conf.logger.info('Posting information to %r' % conf.master_url)
  computer.send(conf)
  conf.logger.info('slapos successfully prepared the computer.')
Example #2
0
  def run(self):
    """
      Run the promise
      
      This will first load the promise module (which will update process sys.path)
    """
    try:
      os.chdir(self.partition_folder)
      promise_started = False
      if self.uid and self.gid:
        dropPrivileges(self.uid, self.gid, logger=self.logger)
      mkdir_p(self.cache_folder)
      if self.wrap_promise:
        promise_instance = WrapPromise(self.argument_dict)
      else:
        self._createInitFile()
        promise_module = self._loadPromiseModule()
        promise_instance = promise_module.RunPromise(self.argument_dict)

      if not hasattr(promise_instance, 'isAnomalyDetected') or not \
          hasattr(promise_instance, 'isTested') or \
          (promise_instance.isAnomalyDetected() and self.check_anomaly) or \
          (promise_instance.isTested() and not self.check_anomaly):
        # if the promise will run, we save execution timestamp
        promise_started = True
      self.updatePromiseCache(
        WrapPromise if self.wrap_promise else promise_module.RunPromise,
        promise_instance,
        started=promise_started)
      promise_instance.run(self.check_anomaly, self.allow_bang)
    except Exception:
      self.logger.error(traceback.format_exc())
      raise
Example #3
0
def writeFile(name, folder, date_scope, rows):
    folder = os.path.join(folder, date_scope)
    f = os.path.join(folder, "dump_%s.csv" % name)
    if os.path.exists(f):
        # File already exists, no reason to recreate it.
        return
    mkdir_p(folder, 0o755)
    with open(f, "w") as file_io:
        csv.writer(file_io).writerows(rows)
Example #4
0
  def start(self):
    """
      run all promises in sequential ways
    """
    if self.config.pid_path:
      if os.path.exists(self.config.pid_path):
        # Check if another run promise is running
        with open(self.config.pid_path) as fpid:
          try:
            pid = int(fpid.read(6))
          except ValueError:
            pid = None
          if pid and os.path.exists("/proc/" + str(pid)):
            self.logger.warning("A process is already running with pid " + str(pid))
            return []

      with open(self.config.pid_path, 'w') as fpid:
        fpid.write(str(os.getpid()))

    if not self.config.partition_folder:
      raise ValueError("Partition folder is not specified")

    parameter_dict = {
      'promise-timeout': self.config.promise_timeout or promise_timeout,
      'promise-folder': os.path.join(self.config.partition_folder, 'etc', 'plugin'),
      'legacy-promise-folder': os.path.join(self.config.partition_folder, 'etc', 'promise'),
      'partition-folder': self.config.partition_folder,
      'master-url': self.config.master_url,
      'partition-cert': self.config.partition_cert,
      'partition-key': self.config.partition_key,
      'partition-id': self.config.partition_id,
      'computer-id': self.config.computer_id,
      'debug': self.config.debug,
      'check-anomaly': self.config.check_anomaly,
      'force': self.config.force,
      'run-only-promise-list': [x for x in self.config.run_only.split(' ') if x]
    }
    if self.config.log_folder:
      parameter_dict['log-folder'] = self.config.log_folder
    else:
      parameter_dict['log-folder'] = os.path.join(self.config.partition_folder,
                                                  PROMISE_LOG_FOLDER_NAME)
      mkdir_p(parameter_dict['log-folder'])

    promise_launcher = PromiseLauncher(
      config=parameter_dict,
      logger=self.logger,
      dry_run=self.config.dry_run
    )

    self.logger.info("Checking promises...")
    exit_code = 0
    try:
      promise_launcher.run()
    except PromiseError, e:
      # error was already logged
      exit_code = 1
Example #5
0
def do_configure_client(logger, master_url_web, token, config_path, master_url):
    while not token:
        token = input('Credential security token: ').strip()

    # Check for existence of previous configuration, certificate or key files
    # where we expect to create them. If so, ask the use to manually remove them.

    if os.path.exists(config_path):
        logger.critical('There is a file in %s. '
                        'Please remove it before creating a new configuration.', config_path)
        sys.exit(1)

    basedir = os.path.dirname(config_path)
    if not os.path.isdir(basedir):
        logger.debug('Creating directory %s', basedir)
        mkdir_p(basedir, mode=0o700)

    cert_path = os.path.join(basedir, 'client.crt')
    if os.path.exists(cert_path):
        logger.critical('There is a file in %s. '
                        'Please remove it before creating a new certificate.', cert_path)
        sys.exit(1)

    key_path = os.path.join(basedir, 'client.key')
    if os.path.exists(key_path):
        logger.critical('There is a file in %s. '
                        'Please remove it before creating a new key.', key_path)
        sys.exit(1)

    # retrieve a template for the configuration file

    cfg = fetch_configuration_template()

    cfg = re.sub('master_url = .*', 'master_url = %s' % master_url, cfg)
    cfg = re.sub('cert_file = .*', 'cert_file = %s' % cert_path, cfg)
    cfg = re.sub('key_file = .*', 'key_file = %s' % key_path, cfg)

    # retrieve and parse the certicate and key

    certificate, key = get_certificate_key_pair(logger, master_url_web, token)

    # write everything

    with os.fdopen(os.open(config_path, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o600), 'w') as fout:
        logger.debug('Writing configuration to %s', config_path)
        fout.write(cfg)

    with os.fdopen(os.open(cert_path, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o600), 'w') as fout:
        logger.debug('Writing certificate to %s', cert_path)
        fout.write(certificate)

    with os.fdopen(os.open(key_path, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o600), 'w') as fout:
        logger.debug('Writing key to %s', key_path)
        fout.write(key)

    logger.info('SlapOS client configuration written to %s', config_path)
Example #6
0
def writeFile(name, folder, date_scope, rows):
  if os.path.exists(
      os.path.join(folder, "%s/dump_%s.csv" % (date_scope, name))):
    # File already exists, no reason to recreate it.
    return
  mkdir_p(os.path.join(folder, date_scope), 0o755)
  file_io = open(os.path.join(folder, "%s/dump_%s.csv" % (date_scope, name)), "w")
  csv_output = csv.writer(file_io)
  csv_output.writerows(rows)
  file_io.close()
Example #7
0
def writeFile(name, folder, date_scope, rows):
    if os.path.exists(
            os.path.join(folder, "%s/dump_%s.csv" % (date_scope, name))):
        # File already exists, no reason to recreate it.
        return
    mkdir_p(os.path.join(folder, date_scope), 0o755)
    file_io = open(os.path.join(folder, "%s/dump_%s.csv" % (date_scope, name)),
                   "w")
    csv_output = csv.writer(file_io)
    csv_output.writerows(rows)
    file_io.close()
Example #8
0
  def _configureLogger(self):
    self.logger = logging.getLogger(self.__name)
    for handler in self.logger.handlers:
      self.logger.removeHandler(handler)
    if self.__log_folder is None:
      self.__logger_buffer = six.StringIO()
      logger_handler = logging.StreamHandler(self.__logger_buffer)
      self.__log_file = None
    else:
      mkdir_p(self.__log_folder)
      self.__log_file = os.path.join(
        self.__log_folder,
        '%s.log' % self.__title
      )
      logger_handler = logging.FileHandler(self.__log_file)

    self.logger.setLevel(logging.DEBUG if self.__debug else logging.INFO)
    logger_handler.setFormatter(
      fmt=logging.Formatter("%(asctime)s - %(levelname)s - " +
          self.__transaction_id + " - %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S")
    )
    self.logger.addHandler(logger_handler)
Example #9
0
    def fetch_parameter_dict(self, options, instance_root):
        slap = slapos.slap.slap()
        slap.initializeConnection(
            options['url'],
            options.get('key'),
            options.get('cert'),
        )
        computer_partition = slap.registerComputerPartition(
            options['computer'],
            options['partition'],
        )
        parameter_dict = computer_partition.getInstanceParameterDict()
        options['instance-state'] = computer_partition.getState()
        # XXX: those are not partition parameters, strictly speaking.
        # Make them available as individual section keys.
        for his_key in (
                'slap_software_type',
                'slap_computer_partition_id',
                'slap_computer_id',
                'slap_software_release_url',
                'slave_instance_list',
                'timestamp',
        ):
            try:
                value = parameter_dict.pop(his_key)
            except KeyError:
                pass
            else:
                options[his_key.replace('_', '-')] = value
        ipv4_set = set()
        v4_add = ipv4_set.add
        ipv6_set = set()
        v6_add = ipv6_set.add
        tap_set = set()
        tap_add = tap_set.add
        route_gw_set = set()
        route_gw_add = route_gw_set.add
        route_mask_set = set()
        route_mask_add = route_mask_set.add
        route_ipv4_set = set()
        route_v4_add = route_ipv4_set.add
        route_network_set = set()
        route_net_add = route_network_set.add
        for tap, ip in parameter_dict.pop('ip_list'):
            tap_add(tap)
            if valid_ipv4(ip):
                v4_add(ip)
            elif valid_ipv6(ip):
                v6_add(ip)
            # XXX: emit warning on unknown address type ?

        if 'full_ip_list' in parameter_dict:
            for item in parameter_dict.pop('full_ip_list'):
                if len(item) == 5:
                    tap, ip, gw, netmask, network = item
                    if tap.startswith('route_'):
                        if valid_ipv4(gw):
                            route_gw_add(gw)
                        if valid_ipv4(netmask):
                            route_mask_add(netmask)
                        if valid_ipv4(ip):
                            route_v4_add(ip)
                        if valid_ipv4(network):
                            route_net_add(network)

        options['ipv4'] = ipv4_set
        options['ipv6'] = ipv6_set

        # also export single ip values for those recipes that don't support sets.
        if ipv4_set:
            options['ipv4-random'] = list(ipv4_set)[0].encode('UTF-8')
        if ipv6_set:
            options['ipv6-random'] = list(ipv6_set)[0].encode('UTF-8')
        if route_ipv4_set:
            options['tap-ipv4'] = list(route_ipv4_set)[0].encode('UTF-8')
            options['tap-network-information-dict'] = dict(
                ipv4=route_ipv4_set,
                netmask=route_mask_set,
                gateway=route_gw_set,
                network=route_network_set)
        else:
            options['tap-network-information-dict'] = {}
        if route_gw_set:
            options['tap-gateway'] = list(route_gw_set)[0].encode('UTF-8')
        if route_mask_set:
            options['tap-netmask'] = list(route_mask_set)[0].encode('UTF-8')
        if route_network_set:
            options['tap-network'] = list(route_network_set)[0].encode('UTF-8')

        storage_home = options.get('storage-home')
        storage_dict = {}
        if storage_home and os.path.exists(storage_home) and \
                                    os.path.isdir(storage_home):
            for filename in os.listdir(storage_home):
                storage_path = os.path.join(
                    storage_home, filename,
                    options['slap-computer-partition-id'])
                if os.path.exists(storage_path) and os.path.isdir(
                        storage_path):
                    storage_link = os.path.join(instance_root, 'DATA',
                                                filename)
                    mkdir_p(os.path.join(instance_root, 'DATA'))
                    if not os.path.lexists(storage_link):
                        os.symlink(storage_path, storage_link)
                    storage_dict[filename] = storage_link
        options['storage-dict'] = storage_dict

        options['tap'] = tap_set
        return self._expandParameterDict(options, parameter_dict)
Example #10
0
def do_collect(conf):
  """
  Main function
  The idea here is to poll system every so many seconds
  For each poll, we get a list of Snapshots, holding informations about
  processes. We iterate over that list to store datas on a per user basis:
    Each user object is a dict, indexed on timestamp. We add every snapshot
    matching the user so that we get informations for each users
  """
  try:
    collected_date, collected_time = _get_time()
    user_dict = get_user_list(conf)
    try:
      for snapshot in current_state(user_dict):
        if snapshot:
          user_dict[snapshot.username].append(snapshot)
    except (KeyboardInterrupt, SystemExit, NoSuchProcess):
      raise
      
    log_directory = "%s/var/data-log" % conf.get("slapos", "instance_root")
    mkdir_p(log_directory, 0o755)
    
    consumption_report_directory = "%s/var/consumption-report" % \
                                        conf.get("slapos", "instance_root") 
    mkdir_p(consumption_report_directory, 0o755)

    xml_report_directory = "%s/var/xml_report/%s" % \
                    (conf.get("slapos", "instance_root"), 
                     conf.get("slapos", "computer_id"))
    mkdir_p(xml_report_directory, 0o755)

    if stat.S_IMODE(os.stat(log_directory).st_mode) != 0o755:
      os.chmod(log_directory, 0o755)    

    database = Database(log_directory)

    if conf.has_option("slapformat", "computer_model_id"):
      computer_model_id = conf.get("slapformat", 
                                  "computer_model_id")
 
    else:
      computer_model_id = "no_model"

    uptime = _get_uptime()
    if conf.has_option("slapformat", "heating_sensor_id"):
      heating_sensor_id = conf.get("slapformat", 
                                  "heating_sensor_id")
      database.connect()
      test_heating = uptime is not None and \
                     uptime > datetime.timedelta(seconds=86400) and \
                     database.getLastHeatingTestTime() > uptime
      database.close()

    else:
      heating_sensor_id = "no_sensor"
      test_heating = False

    computer = Computer(ComputerSnapshot(model_id=computer_model_id, 
                                     sensor_id = heating_sensor_id,
                                     test_heating=test_heating))

    computer.save(database, collected_date, collected_time)

    for user in user_dict.values():
      user.save(database, collected_date, collected_time)
    
    SystemCSVReporterDumper(database).dump(log_directory)
    RawCSVDumper(database).dump(log_directory)
    consumption_report = ConsumptionReport(
                      computer_id=conf.get("slapos", "computer_id"), 
                      user_list=get_user_list(conf), 
                      database=database,
                      location=consumption_report_directory)
    
    base = datetime.datetime.today()
    for x in range(1, 3):
      report_file = consumption_report.buildXMLReport(
          (base - datetime.timedelta(days=x)).strftime("%Y-%m-%d"))

      if report_file is not None:
        shutil.copy(report_file, xml_report_directory)

    compressLogFolder(log_directory)

    # Drop older entries already reported
    database.garbageCollect()

  except AccessDenied:
    print("You HAVE TO execute this script with root permission.")
Example #11
0
  def processComputerPartition(self, computer_partition):
    """
    Process a Computer Partition, depending on its state
    """
    computer_partition_id = computer_partition.getId()

    # Sanity checks before processing
    # Those values should not be None or empty string or any falsy value
    if not computer_partition_id:
      raise ValueError('Computer Partition id is empty.')

    # Check if we defined explicit list of partitions to process.
    # If so, if current partition not in this list, skip.
    if len(self.computer_partition_filter_list) > 0 and \
         (computer_partition_id not in self.computer_partition_filter_list):
      return

    self.logger.debug('Check if %s requires processing...' % computer_partition_id)

    instance_path = os.path.join(self.instance_root, computer_partition_id)

    # Try to get partition timestamp (last modification date)
    timestamp_path = os.path.join(
        instance_path,
        COMPUTER_PARTITION_TIMESTAMP_FILENAME
    )
    parameter_dict = computer_partition.getInstanceParameterDict()
    if 'timestamp' in parameter_dict:
      timestamp = parameter_dict['timestamp']
    else:
      timestamp = None

    try:
      software_url = computer_partition.getSoftwareRelease().getURI()
    except NotFoundError:
      # Problem with instance: SR URI not set.
      # Try to process it anyway, it may need to be deleted.
      software_url = None
    try:
      software_path = os.path.join(self.software_root, md5digest(software_url))
    except TypeError:
      # Problem with instance: SR URI not set.
      # Try to process it anyway, it may need to be deleted.
      software_path = None

    periodicity = self.maximum_periodicity
    if software_path:
      periodicity_path = os.path.join(software_path, 'periodicity')
      if os.path.exists(periodicity_path):
        try:
          periodicity = int(open(periodicity_path).read())
        except ValueError:
          os.remove(periodicity_path)
          self.logger.exception('')

    # Check if timestamp from server is more recent than local one.
    # If not: it's not worth processing this partition (nothing has
    # changed).
    if (computer_partition_id not in self.computer_partition_filter_list and
          not self.develop and os.path.exists(timestamp_path)):
      old_timestamp = open(timestamp_path).read()
      last_runtime = int(os.path.getmtime(timestamp_path))
      if timestamp:
        try:
          if periodicity == 0:
            os.remove(timestamp_path)
          elif int(timestamp) <= int(old_timestamp):
            # Check periodicity, i.e if periodicity is one day, partition
            # should be processed at least every day.
            if int(time.time()) <= (last_runtime + periodicity) or periodicity < 0:
              self.logger.debug('Partition already up-to-date, skipping.')
              return
            else:
              # Periodicity forced processing this partition. Removing
              # the timestamp file in case it fails.
              os.remove(timestamp_path)
        except ValueError:
          os.remove(timestamp_path)
          self.logger.exception('')

    # Include Partition Logging
    log_folder_path = "%s/.slapgrid/log" % instance_path
    mkdir_p(log_folder_path)
    partition_file_handler = logging.FileHandler(
                filename="%s/instance.log" % (log_folder_path)
            )
    stat_info = os.stat(instance_path)
    chownDirectory("%s/.slapgrid" % instance_path,
                   uid=stat_info.st_uid,
                   gid=stat_info.st_gid)

    formatter = logging.Formatter(
       '[%(asctime)s] %(levelname)-8s %(name)s %(message)s')
    partition_file_handler.setFormatter(formatter)
    self.logger.addHandler(partition_file_handler)

    try:
      self.logger.info('Processing Computer Partition %s.' % computer_partition_id)
      self.logger.info('  Software URL: %s' % software_url)
      self.logger.info('  Software path: %s' % software_path)
      self.logger.info('  Instance path: %s' % instance_path)

      filter_dict = getattr(computer_partition, '_filter_dict', None)
      if filter_dict:
        retention_delay = filter_dict.get('retention_delay', '0')
      else:
        retention_delay = '0'

      local_partition = Partition(
        software_path=software_path,
        instance_path=instance_path,
        supervisord_partition_configuration_path=os.path.join(
          _getSupervisordConfigurationDirectory(self.instance_root), '%s.conf' %
          computer_partition_id),
        supervisord_socket=self.supervisord_socket,
        computer_partition=computer_partition,
        computer_id=self.computer_id,
        partition_id=computer_partition_id,
        server_url=self.master_url,
        software_release_url=software_url,
        certificate_repository_path=self.certificate_repository_path,
        buildout=self.buildout,
        logger=self.logger,
        retention_delay=retention_delay,
        instance_min_free_space=self.instance_min_free_space,
        instance_storage_home=self.instance_storage_home,
        ipv4_global_network=self.ipv4_global_network,
      )
      computer_partition_state = computer_partition.getState()

      # XXX this line breaks 37 tests
      # self.logger.info('  Instance type: %s' % computer_partition.getType())
      self.logger.info('  Instance status: %s' % computer_partition_state)

      if computer_partition_state == COMPUTER_PARTITION_STARTED_STATE:
        local_partition.install()
        computer_partition.available()
        local_partition.start()
        self._checkPromises(computer_partition)
        computer_partition.started()
      elif computer_partition_state == COMPUTER_PARTITION_STOPPED_STATE:
        try:
          # We want to process the partition, even if stopped, because it should
          # propagate the state to children if any.
          local_partition.install()
          computer_partition.available()
        finally:
          # Instance has to be stopped even if buildout/reporting is wrong.
          local_partition.stop()
        computer_partition.stopped()
      elif computer_partition_state == COMPUTER_PARTITION_DESTROYED_STATE:
        local_partition.stop()
        try:
          computer_partition.stopped()
        except (SystemExit, KeyboardInterrupt):
          computer_partition.error(traceback.format_exc(), logger=self.logger)
          raise
        except Exception:
          pass
      else:
        error_string = "Computer Partition %r has unsupported state: %s" % \
          (computer_partition_id, computer_partition_state)
        computer_partition.error(error_string, logger=self.logger)
        raise NotImplementedError(error_string)
    finally:
       self.logger.removeHandler(partition_file_handler)

    # If partition has been successfully processed, write timestamp
    if timestamp:
      open(timestamp_path, 'w').write(timestamp)
Example #12
0
    def fetch_parameter_dict(self, options, instance_root):
        """Gather parameters about current computer and partition.

      Use two sources of truth
      1. SlapOS Master - for external computer/partition information
      2. format.Partition.resource_file - for partition specific details
      """
        slap = slapos.slap.slap()
        slap.initializeConnection(
            options['url'],
            options.get('key'),
            options.get('cert'),
        )
        computer_partition = slap.registerComputerPartition(
            options['computer'],
            options['partition'],
        )
        parameter_dict = computer_partition.getInstanceParameterDict()
        options['instance-state'] = computer_partition.getState()
        # XXX: those are not partition parameters, strictly speaking.
        # Make them available as individual section keys.
        for his_key in (
                'slap_software_type',
                'slap_computer_partition_id',
                'slap_computer_id',
                'slap_software_release_url',
                'slave_instance_list',
                'timestamp',
        ):
            try:
                value = parameter_dict.pop(his_key)
            except KeyError:
                pass
            else:
                options[his_key.replace('_', '-')] = value
        # Get Instance and root instance title or return UNKNOWN if not set
        options['instance-title'] = parameter_dict.pop('instance_title',
                                                       'UNKNOWN Instance')
        options['root-instance-title'] = parameter_dict.pop(
            'root_instance_title', 'UNKNOWN')
        options['instance-guid'] = computer_partition.getInstanceGuid()

        ipv4_set = set()
        v4_add = ipv4_set.add
        ipv6_set = set()
        v6_add = ipv6_set.add
        tap_set = set()
        tap_add = tap_set.add
        route_gw_set = set()
        route_gw_add = route_gw_set.add
        route_mask_set = set()
        route_mask_add = route_mask_set.add
        route_ipv4_set = set()
        route_v4_add = route_ipv4_set.add
        route_network_set = set()
        route_net_add = route_network_set.add
        for tap, ip in parameter_dict.pop('ip_list'):
            tap_add(tap)
            if valid_ipv4(ip):
                v4_add(ip)
            elif valid_ipv6(ip):
                v6_add(ip)
            # XXX: emit warning on unknown address type ?

        if 'full_ip_list' in parameter_dict:
            for item in parameter_dict.pop('full_ip_list'):
                if len(item) == 5:
                    tap, ip, gw, netmask, network = item
                    if tap.startswith('route_'):
                        if valid_ipv4(gw):
                            route_gw_add(gw)
                        if valid_ipv4(netmask):
                            route_mask_add(netmask)
                        if valid_ipv4(ip):
                            route_v4_add(ip)
                        if valid_ipv4(network):
                            route_net_add(network)

        options['ipv4'] = ipv4_set
        options['ipv6'] = ipv6_set

        # also export single ip values for those recipes that don't support sets.
        if ipv4_set:
            options['ipv4-random'] = min(ipv4_set)
        if ipv6_set:
            options['ipv6-random'] = min(ipv6_set)

        storage_home = options.get('storage-home')
        storage_dict = {}
        if storage_home and os.path.exists(storage_home) and \
                                    os.path.isdir(storage_home):
            for filename in os.listdir(storage_home):
                storage_path = os.path.join(
                    storage_home, filename,
                    options['slap-computer-partition-id'])
                if os.path.exists(storage_path) and os.path.isdir(
                        storage_path):
                    storage_link = os.path.join(instance_root, 'DATA',
                                                filename)
                    mkdir_p(os.path.join(instance_root, 'DATA'))
                    if not os.path.lexists(storage_link):
                        os.symlink(storage_path, storage_link)
                    storage_dict[filename] = storage_link
        options['storage-dict'] = storage_dict

        # The external information transfered from Slap Master has been processed
        # so we extend with information gathered from partition resource file
        if hasattr(slapformat.Partition, "resource_file"):
            resource_home = instance_root
            while not os.path.exists(
                    os.path.join(resource_home,
                                 slapformat.Partition.resource_file)):
                resource_home = os.path.normpath(
                    os.path.join(resource_home, '..'))
                if resource_home == "/":
                    break
            else:
                # no break happened - let's add partition resources into options
                logger.debug("Using partition resource file {}".format(
                    os.path.join(resource_home,
                                 slapformat.Partition.resource_file)))
                with open(
                        os.path.join(
                            resource_home,
                            slapformat.Partition.resource_file)) as fi:
                    partition_params = json.load(fi)
                # be very careful with overriding master's information
                for key, value in flatten_dict(partition_params).items():
                    if key not in options:
                        if six.PY2 and isinstance(value, unicode):
                            value = value.encode('UTF-8')
                        options[key] = value
        # print out augmented options to see what we are passing
        logger.debug(str(options))
        return self._expandParameterDict(options, parameter_dict)
Example #13
0
 def writeFile(self, name, folder, date_scope, rows):
   mkdir_p(os.path.join(folder, date_scope), 0o755)
   file_io = open(os.path.join(folder, "%s/dump_%s.csv" % (date_scope, name)), "w")
   csv_output = csv.writer(file_io)
   csv_output.writerows(rows)
   file_io.close()
Example #14
0
  def fetch_parameter_dict(self, options, instance_root):
      slap = slapos.slap.slap()
      slap.initializeConnection(
          options['url'],
          options.get('key'),
          options.get('cert'),
      )
      computer_partition = slap.registerComputerPartition(
          options['computer'],
          options['partition'],
      )
      parameter_dict = computer_partition.getInstanceParameterDict()
      options['instance-state'] = computer_partition.getState()
      # XXX: those are not partition parameters, strictly speaking.
      # Make them available as individual section keys.
      for his_key in (
                  'slap_software_type',
                  'slap_computer_partition_id',
                  'slap_computer_id',
                  'slap_software_release_url',
                  'slave_instance_list',
                  'timestamp',
              ):
          try:
              value = parameter_dict.pop(his_key)
          except KeyError:
              pass
          else:
              options[his_key.replace('_', '-')] = value
      ipv4_set = set()
      v4_add = ipv4_set.add
      ipv6_set = set()
      v6_add = ipv6_set.add
      tap_set = set()
      tap_add = tap_set.add
      route_gw_set = set()
      route_gw_add = route_gw_set.add
      route_mask_set = set()
      route_mask_add = route_mask_set.add
      route_ipv4_set = set()
      route_v4_add = route_ipv4_set.add
      route_network_set = set()
      route_net_add = route_network_set.add
      for tap, ip in parameter_dict.pop('ip_list'):
          tap_add(tap)
          if valid_ipv4(ip):
              v4_add(ip)
          elif valid_ipv6(ip):
              v6_add(ip)
          # XXX: emit warning on unknown address type ?

      if 'full_ip_list' in parameter_dict:
        for item in parameter_dict.pop('full_ip_list'):
          if len(item) == 5:
            tap, ip, gw, netmask, network = item
            if  tap.startswith('route_'):
              if valid_ipv4(gw):
                route_gw_add(gw)
              if valid_ipv4(netmask):
                route_mask_add(netmask)
              if valid_ipv4(ip):
                route_v4_add(ip)
              if valid_ipv4(network):
                route_net_add(network)

      options['ipv4'] = ipv4_set
      options['ipv6'] = ipv6_set

      # also export single ip values for those recipes that don't support sets.
      if ipv4_set:
          options['ipv4-random'] = list(ipv4_set)[0].encode('UTF-8')
      if ipv6_set:
          options['ipv6-random'] = list(ipv6_set)[0].encode('UTF-8')
      if route_ipv4_set:
        options['tap-ipv4'] = list(route_ipv4_set)[0].encode('UTF-8')
        options['tap-network-information-dict'] = dict(ipv4=route_ipv4_set,
                                    netmask=route_mask_set,
                                    gateway=route_gw_set,
                                    network=route_network_set)
      else:
        options['tap-network-information-dict'] = {}
      if route_gw_set:
        options['tap-gateway'] = list(route_gw_set)[0].encode('UTF-8')
      if route_mask_set:
        options['tap-netmask'] = list(route_mask_set)[0].encode('UTF-8')
      if route_network_set:
        options['tap-network'] = list(route_network_set)[0].encode('UTF-8')

      storage_home = options.get('storage-home')
      storage_dict = {}
      if storage_home and os.path.exists(storage_home) and \
                                  os.path.isdir(storage_home):
        for filename in os.listdir(storage_home):
          storage_path = os.path.join(storage_home, filename, 
                                    options['slap-computer-partition-id'])
          if os.path.exists(storage_path) and os.path.isdir(storage_path):
            storage_link = os.path.join(instance_root, 'DATA', filename)
            mkdir_p(os.path.join(instance_root, 'DATA'))
            if not os.path.lexists(storage_link):
              os.symlink(storage_path, storage_link)
            storage_dict[filename] = storage_link
      options['storage-dict'] = storage_dict

      options['tap'] = tap_set
      return self._expandParameterDict(options, parameter_dict)
Example #15
0
  def fetch_parameter_dict(self, options, instance_root):
      """Gather parameters about current computer and partition.

      Use two sources of truth
      1. SlapOS Master - for external computer/partition information
      2. format.Partition.resource_file - for partition specific details
      """
      slap = slapos.slap.slap()
      slap.initializeConnection(
          options['url'],
          options.get('key'),
          options.get('cert'),
      )
      computer_partition = slap.registerComputerPartition(
          options['computer'],
          options['partition'],
      )
      parameter_dict = computer_partition.getInstanceParameterDict()
      options['instance-state'] = computer_partition.getState()
      # XXX: those are not partition parameters, strictly speaking.
      # Make them available as individual section keys.
      for his_key in (
                  'slap_software_type',
                  'slap_computer_partition_id',
                  'slap_computer_id',
                  'slap_software_release_url',
                  'slave_instance_list',
                  'timestamp',
              ):
          try:
              value = parameter_dict.pop(his_key)
          except KeyError:
              pass
          else:
              options[his_key.replace('_', '-')] = value
      # Get Instance and root instance title or return UNKNOWN if not set
      options['instance-title'] = parameter_dict.pop('instance_title',
                                            'UNKNOWN Instance').encode('UTF-8')
      options['root-instance-title'] = parameter_dict.pop('root_instance_title',
                                            'UNKNOWN').encode('UTF-8')
      options['instance-guid'] = computer_partition.getInstanceGuid() \
          .encode('UTF-8')

      ipv4_set = set()
      v4_add = ipv4_set.add
      ipv6_set = set()
      v6_add = ipv6_set.add
      tap_set = set()
      tap_add = tap_set.add
      route_gw_set = set()
      route_gw_add = route_gw_set.add
      route_mask_set = set()
      route_mask_add = route_mask_set.add
      route_ipv4_set = set()
      route_v4_add = route_ipv4_set.add
      route_network_set = set()
      route_net_add = route_network_set.add
      for tap, ip in parameter_dict.pop('ip_list'):
          tap_add(tap)
          if valid_ipv4(ip):
              v4_add(ip)
          elif valid_ipv6(ip):
              v6_add(ip)
          # XXX: emit warning on unknown address type ?

      if 'full_ip_list' in parameter_dict:
        for item in parameter_dict.pop('full_ip_list'):
          if len(item) == 5:
            tap, ip, gw, netmask, network = item
            if  tap.startswith('route_'):
              if valid_ipv4(gw):
                route_gw_add(gw)
              if valid_ipv4(netmask):
                route_mask_add(netmask)
              if valid_ipv4(ip):
                route_v4_add(ip)
              if valid_ipv4(network):
                route_net_add(network)

      options['ipv4'] = ipv4_set
      options['ipv6'] = ipv6_set

      # also export single ip values for those recipes that don't support sets.
      if ipv4_set:
          options['ipv4-random'] = list(ipv4_set)[0].encode('UTF-8')
      if ipv6_set:
          options['ipv6-random'] = list(ipv6_set)[0].encode('UTF-8')

      storage_home = options.get('storage-home')
      storage_dict = {}
      if storage_home and os.path.exists(storage_home) and \
                                  os.path.isdir(storage_home):
        for filename in os.listdir(storage_home):
          storage_path = os.path.join(storage_home, filename, 
                                    options['slap-computer-partition-id'])
          if os.path.exists(storage_path) and os.path.isdir(storage_path):
            storage_link = os.path.join(instance_root, 'DATA', filename)
            mkdir_p(os.path.join(instance_root, 'DATA'))
            if not os.path.lexists(storage_link):
              os.symlink(storage_path, storage_link)
            storage_dict[filename] = storage_link
      options['storage-dict'] = storage_dict

      # The external information transfered from Slap Master has been processed
      # so we extend with information gathered from partition resource file
      if hasattr(slapformat.Partition, "resource_file"):
        resource_home = instance_root
        while not os.path.exists(os.path.join(resource_home, slapformat.Partition.resource_file)):
          resource_home = os.path.normpath(os.path.join(resource_home, '..'))
          if resource_home == "/":
            break
        else:
          # no break happened - let's add partition resources into options
          logger.debug("Using partition resource file {}".format(
            os.path.join(resource_home, slapformat.Partition.resource_file)))
          with open(os.path.join(resource_home, slapformat.Partition.resource_file)) as fi:
            partition_params = json.load(fi)
          # be very careful with overriding master's information
          for key, value in flatten_dict(partition_params).items():
            if key not in options:
              if isinstance(value, unicode):
                value = value.encode('UTF-8')
              options[key] = value
      # print out augmented options to see what we are passing
      logger.debug(str(options))
      return self._expandParameterDict(options, parameter_dict)
Example #16
0
  def __init__(self, config=None, logger=None, dry_run=False):
    """
      Promise launcher will run promises

      @param config_file: A file containing configurations
      @param dry_run: Only run all promises without save the result
      @param logger: Set the logger to use, if None a logger will be configured
        to console.
      @param config: A configuration dict to use. Values send here will
        overwrite configs from `config_file`. Expected values in config are:
        promise-timeout
          Maximum promise execution time before timeout. Default: 20
        partition-folder
          Base path of the partition
        promise-folder
          Promises folder, all promises scripts will be imported from that folder
        legacy-promise-folder
          Legacy promises folder, where to find bash, shell and standard promises
        log-folder
          Folder where promises will write logs. Can be None
        check-anomaly
          Ask to check anomaly instead of test. Default: False
        debug
          Configure loggin in debug mode. Default: True
        master-url
          SlapOS Master service URL
        partition-cert
          Computer Partition Certificate file
        partition-key
          Computer Partition key file
        partition-id
          Computer Partition ID, ex: slappart13
        computer-id
          Computer ID, ex: COMP-1234
        uid
          User UID
        gid
          User GID
        debug
          If True, show Promise consumption and execution time information, etc
        run-only-promise-list
          A list of promise from plugins directory that will be executed
        force
          Set to True if force run promises without check their periodicity
    """

    self.dry_run = dry_run
    self.__config = {
      'promise-timeout': 20,
      'promise-folder': None,
      'legacy-promise-folder': None,
      'log-folder': None,
      'partition-folder': None,
      'debug': False,
      'uid': None,
      'gid': None,
      'master-url': None,
      'partition-cert': None,
      'partition-key': None,
      'partition-id': None,
      'computer-id': None,
      'check-anomaly': False,
      'force': False,
      'run-only-promise-list': None
    }
    if config is not None:
      self.__config.update(config)

    for key, value in self.__config.items():
      setattr(self, key.replace('-', '_'), value or None)

    if self.promise_folder is None:
      raise ValueError("Promise folder is missing in configuration!")
    if self.partition_folder is None:
      raise ValueError("Partition folder is missing in configuration!")

    if logger is None:
      self.logger = logging.getLogger(__name__)
      self.logger.setLevel(logging.DEBUG if self.debug else logging.INFO)
      if len(self.logger.handlers) == 0 or \
          not isinstance(self.logger.handlers[0], logging.StreamHandler):
        handler = logging.StreamHandler()
        handler.setFormatter(
          logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
        )
        self.logger.addHandler(handler)
    else:
      self.logger = logger

    self.queue_result = MQueue()
    self.bang_called = False
    self._skipped_amount = 0

    self.promise_output_dir = os.path.join(
      self.partition_folder,
      PROMISE_RESULT_FOLDER_NAME
    )
    if not os.path.exists(self.promise_output_dir):
      mkdir_p(self.promise_output_dir)
      self._updateFolderOwner()