Exemple #1
0
 def _requestComputerPartition(self, request_dict):
   try:
     xml = self._connection_helper.POST('/requestComputerPartition', request_dict)
   except ResourceNotReady:
     return ComputerPartition(
       request_dict=request_dict,
       connection_helper=self._connection_helper,
     )
   software_instance = xml_marshaller.loads(xml)
   computer_partition = ComputerPartition(
     software_instance.slap_computer_id.encode('UTF-8'),
     software_instance.slap_computer_partition_id.encode('UTF-8'),
     connection_helper=self._connection_helper,
   )
   # Hack to give all object attributes to the ComputerPartition instance
   # XXX Should be removed by correctly specifying difference between
   # ComputerPartition and SoftwareInstance
   computer_partition.__dict__ = dict(computer_partition.__dict__.items() +
                                      software_instance.__dict__.items())
   # XXX not generic enough.
   if xml_marshaller.loads(request_dict['shared_xml']):
     computer_partition._synced = True
     computer_partition._connection_dict = software_instance._connection_dict
     computer_partition._parameter_dict = software_instance._parameter_dict
   return computer_partition
Exemple #2
0
def parseRequestComputerPartitionForm(form):
  """
  Parse without intelligence a form from a request(), return it.
  """
  parsed_dict = {}
  parsed_dict['software_release'] = form['software_release'].encode()
  parsed_dict['software_type'] = form.get('software_type').encode()
  parsed_dict['partition_reference'] = form.get('partition_reference', '').encode()
  parsed_dict['partition_id'] = form.get('computer_partition_id', '').encode()
  parsed_dict['partition_parameter_kw'] = loads(form.get('partition_parameter_xml', EMPTY_DICT_XML).encode())
  parsed_dict['filter_kw'] = loads(form.get('filter_xml', EMPTY_DICT_XML).encode())
  # Note: currently ignored for slave instance (slave instances
  # are always started).
  parsed_dict['requested_state'] = loads(form.get('state').encode())

  return parsed_dict
Exemple #3
0
 def request(self, software_release, partition_reference,
     partition_parameter_kw=None, software_type=None, filter_kw=None,
     state=None, shared=False):
   if partition_parameter_kw is None:
     partition_parameter_kw = {}
   if filter_kw is None:
     filter_kw = {}
   request_dict = {
       'software_release': software_release,
       'partition_reference': partition_reference,
       'partition_parameter_xml': xml_marshaller.dumps(partition_parameter_kw),
       'filter_xml': xml_marshaller.dumps(filter_kw),
       'state': xml_marshaller.dumps(state),
       'shared_xml': xml_marshaller.dumps(shared),
     }
   if software_type is not None:
     request_dict['software_type'] = software_type
   try:
     self._connection_helper.POST('/requestComputerPartition', request_dict)
   except ResourceNotReady:
     return ComputerPartition(request_dict=request_dict)
   else:
     xml = self._connection_helper.response.read()
     software_instance = xml_marshaller.loads(xml)
     return ComputerPartition(
       software_instance.slap_computer_id.encode('UTF-8'),
       software_instance.slap_computer_partition_id.encode('UTF-8'))
Exemple #4
0
 def getFullHostingIpAddressList(self):
   xml = self._connection_helper.GET('getHostingSubscriptionIpList',
           params={
               'computer_id': self._computer_id,
               'computer_partition_id': self._partition_id,
               }
           )
   return xml_marshaller.loads(xml)
Exemple #5
0
 def getStatus(self):
   xml = self._connection_helper.GET('getComputerPartitionStatus',
           params={
               'computer_id': self._computer_id,
               'computer_partition_id': self._partition_id,
               }
           )
   return xml_marshaller.loads(xml)
Exemple #6
0
 def requestComputer(self, computer_reference):
   """
   Requests a computer.
   """
   xml = self._connection_helper.POST('/requestComputer',
     {'computer_title': computer_reference})
   computer = xml_marshaller.loads(xml)
   computer._connection_helper = self._connection_helper
   return computer
Exemple #7
0
 def requestComputer(self, computer_reference):
   """
   Requests a computer.
   """
   xml = self._connection_helper.POST('requestComputer', data={'computer_title': computer_reference})
   computer = xml_marshaller.loads(xml)
   computer._connection_helper = self._connection_helper
   computer._hateoas_navigator = self._hateoas_navigator
   return computer
Exemple #8
0
 def registerComputerPartition(self, computer_guid, partition_id):
   """
   Registers connected representation of computer partition and
   returns Computer Partition class object
   """
   self._connection_helper.GET('/registerComputerPartition?' \
       'computer_reference=%s&computer_partition_reference=%s' % (
         computer_guid, partition_id))
   xml = self._connection_helper.response.read()
   return xml_marshaller.loads(xml)
Exemple #9
0
def forwardRequestToExternalMaster(master_url, request_form):
  """
  Forward instance request to external SlapOS Master.
  """
  master_entry = app.config.get('multimaster').get(master_url, {})
  key_file = master_entry.get('key')
  cert_file = master_entry.get('cert')
  if master_url.startswith('https') and (not key_file or not cert_file):
    app.logger.warning('External master %s configuration did not specify key or certificate.' % master_url)
    abort(404)
  if master_url.startswith('https') and not master_url.startswith('https') and (key_file or cert_file):
    app.logger.warning('External master %s configurqtion specifies key or certificate but is using plain http.' % master_url)
    abort(404)

  slap = slapos.slap.slap()
  if key_file:
    slap.initializeConnection(master_url, key_file=key_file, cert_file=cert_file)
  else:
    slap.initializeConnection(master_url)

  partition_reference = request_form['partition_reference'].encode()
  # Store in database
  execute_db('forwarded_partition_request', 'INSERT OR REPLACE INTO %s values(:partition_reference, :master_url)',
             {'partition_reference':partition_reference, 'master_url': master_url})

  new_request_form = request_form.copy()
  filter_kw = loads(new_request_form['filter_xml'].encode())
  filter_kw['source_instance_id'] = partition_reference
  new_request_form['filter_xml'] = dumps(filter_kw)

  xml = slap._connection_helper.POST('/requestComputerPartition', data=new_request_form)
  if type(xml) is unicode:
    xml = str(xml)
    xml.encode('utf-8')
  partition = loads(xml)

  # XXX move to other end
  partition._master_url = master_url

  return dumps(partition)
Exemple #10
0
  def request(self, software_release, software_type, partition_reference,
              shared=False, partition_parameter_kw=None, filter_kw=None,
              state=None):
    if partition_parameter_kw is None:
      partition_parameter_kw = {}
    elif not isinstance(partition_parameter_kw, dict):
      raise ValueError("Unexpected type of partition_parameter_kw '%s'" % \
                       partition_parameter_kw)

    if filter_kw is None:
      filter_kw = {}
    elif not isinstance(filter_kw, dict):
      raise ValueError("Unexpected type of filter_kw '%s'" % \
                       filter_kw)

    # Let enforce a default software type
    if software_type is None:
      software_type = DEFAULT_SOFTWARE_TYPE

    request_dict = { 'computer_id': self._computer_id,
        'computer_partition_id': self._partition_id,
        'software_release': software_release,
        'software_type': software_type,
        'partition_reference': partition_reference,
        'shared_xml': xml_marshaller.dumps(shared),
        'partition_parameter_xml': xml_marshaller.dumps(
                                        partition_parameter_kw),
        'filter_xml': xml_marshaller.dumps(filter_kw),
        'state': xml_marshaller.dumps(state),
      }
    try:
      self._connection_helper.POST('/requestComputerPartition', request_dict)
    except ResourceNotReady:
      return ComputerPartition(
        request_dict=request_dict,
        connection_helper=self._connection_helper,
      )
    else:
      xml = self._connection_helper.response.read()
      software_instance = xml_marshaller.loads(xml)
      computer_partition = ComputerPartition(
        software_instance.slap_computer_id.encode('UTF-8'),
        software_instance.slap_computer_partition_id.encode('UTF-8'),
        connection_helper=self._connection_helper,
      )
      if shared:
        computer_partition._synced = True
        computer_partition._connection_dict = getattr(software_instance,
          '_connection_dict', None)
        computer_partition._parameter_dict = getattr(software_instance,
          '_parameter_dict', None)
      return computer_partition
Exemple #11
0
  def load(cls, path_to_xml, reference, ipv6_interface):
    """
    Create a computer object from a valid xml file.

    Arg:
      path_to_xml: String, a path to a valid file containing
          a valid configuration.

    Return:
      A Computer object.
    """

    dumped_dict = xml_marshaller.loads(open(path_to_xml).read())

    # Reconstructing the computer object from the xml
    computer = Computer(
        reference = reference,
        addr = dumped_dict['address'],
        netmask = dumped_dict['netmask'],
        ipv6_interface=ipv6_interface,
        software_user=dumped_dict.get('software_user', 'slapsoft'),
    )

    for partition_dict in dumped_dict['partition_list']:

      if partition_dict['user']:
        user = User(partition_dict['user']['name'])
      else:
        user = User('root')

      if partition_dict['tap']:
        tap = Tap(partition_dict['tap']['name'])
      else:
        tap = Tap(partition_dict['reference'])

      address_list = partition_dict['address_list']

      partition = Partition(
          reference = partition_dict['reference'],
          path = partition_dict['path'],
          user = user,
          address_list = address_list,
          tap = tap,
      )

      computer.partition_list.append(partition)

    return computer
Exemple #12
0
  def registerComputerPartition(self, computer_guid, partition_id):
    """
    Registers connected representation of computer partition and
    returns Computer Partition class object
    """
    if not computer_guid or not partition_id:
      # XXX-Cedric: should raise something smarter than NotFound
      raise NotFoundError

    xml = self._connection_helper.GET('/registerComputerPartition?' \
        'computer_reference=%s&computer_partition_reference=%s' % (
          computer_guid, partition_id))
    result = xml_marshaller.loads(xml)
    # XXX: dirty hack to make computer partition usable. xml_marshaller is too
    # low-level for our needs here.
    result._connection_helper = self._connection_helper
    return result
Exemple #13
0
  def getFullComputerInformation(self, computer_id):
    """
    Retrieve from SlapOS Master Computer instance containing all needed
    informations (Software Releases, Computer Partitions, ...).
    """
    method = '/getFullComputerInformation?computer_id=%s' % computer_id
    if not computer_id:
      # XXX-Cedric: should raise something smarter than "NotFound".
      raise NotFoundError(method)
    try:
      xml = self.GET(method)
    except NotFoundError:
      # XXX: This is a ugly way to keep backward compatibility,
      # We should stablise slap library soon.
      xml = self.GET('/getComputerInformation?computer_id=%s' % computer_id)

    return xml_marshaller.loads(xml)
Exemple #14
0
 def request(self, software_release, partition_reference,
     partition_parameter_kw=None, software_type=None, filter_kw=None,
     state=None, shared=False):
   if partition_parameter_kw is None:
     partition_parameter_kw = {}
   if filter_kw is None:
     filter_kw = {}
   request_dict = {
       'software_release': software_release,
       'partition_reference': partition_reference,
       'partition_parameter_xml': xml_marshaller.dumps(partition_parameter_kw),
       'filter_xml': xml_marshaller.dumps(filter_kw),
       # XXX Cedric: Why state and shared are marshalled? First is a string
       #             And second is a boolean.
       'state': xml_marshaller.dumps(state),
       'shared_xml': xml_marshaller.dumps(shared),
     }
   if software_type is not None:
     request_dict['software_type'] = software_type
   else:
     # Let's enforce a default software type
     request_dict['software_type'] = DEFAULT_SOFTWARE_TYPE
   try:
     self._connection_helper.POST('/requestComputerPartition', request_dict)
   except ResourceNotReady:
     return ComputerPartition(
       request_dict=request_dict,
       connection_helper=self._connection_helper,
     )
   else:
     xml = self._connection_helper.response.read()
     software_instance = xml_marshaller.loads(xml)
     computer_partition = ComputerPartition(
       software_instance.slap_computer_id.encode('UTF-8'),
       software_instance.slap_computer_partition_id.encode('UTF-8'),
       connection_helper=self._connection_helper,
     )
     if shared:
       computer_partition._synced = True
       computer_partition._connection_dict = software_instance._connection_dict
       computer_partition._parameter_dict = software_instance._parameter_dict
     return computer_partition
Exemple #15
0
def requestComputerPartition():
  parsed_request_dict = parseRequestComputerPartitionForm(request.form)

  # Is it a slave instance?
  slave = loads(request.form.get('shared_xml', EMPTY_DICT_XML).encode())

  # Check first if instance is already allocated
  if slave:
    # XXX: change schema to include a simple "partition_reference" which
    # is name of the instance. Then, no need to do complex search here.
    slave_reference = parsed_request_dict['partition_id'] + '_' + parsed_request_dict['partition_reference']
    requested_computer_id = parsed_request_dict['filter_kw'].get('computer_guid', app.config['computer_id'])
    matching_partition = getAllocatedSlaveInstance(slave_reference, requested_computer_id)
  else:
    matching_partition = getAllocatedInstance(parsed_request_dict['partition_reference'])

  if matching_partition:
    # Then the instance is already allocated, just update it
    # XXX: split request and request slave into different update/allocate functions and simplify.
    # By default, ALWAYS request instance on default computer
    parsed_request_dict['filter_kw'].setdefault('computer_guid', app.config['computer_id'])
    if slave:
      software_instance = requestSlave(**parsed_request_dict)
    else:
      software_instance = requestNotSlave(**parsed_request_dict)
  else:
    # Instance is not yet allocated: try to do it.
    external_master_url = isRequestToBeForwardedToExternalMaster(parsed_request_dict)
    if external_master_url:
      return forwardRequestToExternalMaster(external_master_url, request.form)
    # XXX add support for automatic deployment on specific node depending on available SR and partitions on each Node.
    # Note: It only deploys on default node if SLA not specified
    # XXX: split request and request slave into different update/allocate functions and simplify.

    # By default, ALWAYS request instance on default computer
    parsed_request_dict['filter_kw'].setdefault('computer_guid', app.config['computer_id'])
    if slave:
      software_instance = requestSlave(**parsed_request_dict)
    else:
      software_instance = requestNotSlave(**parsed_request_dict)

  return dumps(software_instance)
Exemple #16
0
  def getFullComputerInformation(self, computer_id):
    """
    Retrieve from SlapOS Master Computer instance containing all needed
    informations (Software Releases, Computer Partitions, ...).
    """
    path = 'getFullComputerInformation'
    params = {'computer_id': computer_id}
    if not computer_id:
      # XXX-Cedric: should raise something smarter than "NotFound".
      raise NotFoundError('%r %r' % (path, params))
    try:
      xml = self.GET(path, params=params)
    except NotFoundError:
      # XXX: This is a ugly way to keep backward compatibility,
      # We should stablise slap library soon.
      xml = self.GET('getComputerInformation', params=params)

    if type(xml) is unicode:
      xml = str(xml)
      xml.encode('utf-8')
    return xml_marshaller.loads(xml)
Exemple #17
0
  def getSoftwareReleaseListFromSoftwareProduct(self,
      software_product_reference=None, software_release_url=None):
    url = 'getSoftwareReleaseListFromSoftwareProduct'
    params = {}
    if software_product_reference:
      if software_release_url is not None:
        raise AttributeError('Both software_product_reference and '
                             'software_release_url parameters are specified.')
      params['software_product_reference'] = software_product_reference
    else:
      if software_release_url is None:
        raise AttributeError('None of software_product_reference and '
                             'software_release_url parameters are specified.')
      params['software_release_url'] = software_release_url

    xml = self._connection_helper.GET(url, params=params)
    if type(xml) is unicode:
      xml = str(xml)
      xml.encode('utf-8')
    result = xml_marshaller.loads(xml)
    assert(type(result) == list)
    return result
Exemple #18
0
  def registerComputerPartition(self, computer_guid, partition_id):
    """
    Registers connected representation of computer partition and
    returns Computer Partition class object
    """
    if not computer_guid or not partition_id:
      # XXX-Cedric: should raise something smarter than NotFound
      raise NotFoundError

    xml = self._connection_helper.GET('registerComputerPartition',
            params = {
                'computer_reference': computer_guid,
                'computer_partition_reference': partition_id,
                }
            )
    if type(xml) is unicode:
      xml = str(xml)
      xml.encode('utf-8')
    result = xml_marshaller.loads(xml)
    # XXX: dirty hack to make computer partition usable. xml_marshaller is too
    # low-level for our needs here.
    result._connection_helper = self._connection_helper
    result._hateoas_navigator = self._hateoas_navigator
    return result
Exemple #19
0
  def request(self, software_release, software_type, partition_reference,
              shared=False, partition_parameter_kw=None, filter_kw=None,
              state=None):
    if partition_parameter_kw is None:
      partition_parameter_kw = {}
    elif not isinstance(partition_parameter_kw, dict):
      raise ValueError("Unexpected type of partition_parameter_kw '%s'" % \
                       partition_parameter_kw)

    if filter_kw is None:
      filter_kw = {}
    elif not isinstance(filter_kw, dict):
      raise ValueError("Unexpected type of filter_kw '%s'" % \
                       filter_kw)

    request_dict = { 'computer_id': self._computer_id,
        'computer_partition_id': self._partition_id,
        'software_release': software_release,
        'software_type': software_type,
        'partition_reference': partition_reference,
        'shared_xml': xml_marshaller.dumps(shared),
        'partition_parameter_xml': xml_marshaller.dumps(
                                        partition_parameter_kw),
        'filter_xml': xml_marshaller.dumps(filter_kw),
        'state': xml_marshaller.dumps(state),
      }
    try:
      self._connection_helper.POST('/requestComputerPartition', request_dict)
    except ResourceNotReady:
      return ComputerPartition(request_dict=request_dict)
    else:
      xml = self._connection_helper.response.read()
      software_instance = xml_marshaller.loads(xml)
      return ComputerPartition(
        software_instance.slap_computer_id.encode('UTF-8'),
        software_instance.slap_computer_partition_id.encode('UTF-8'))
Exemple #20
0
 def getCertificate(self):
   self._connection_helper.GET(
       '/getComputerPartitionCertificate?computer_id=%s&'
       'computer_partition_id=%s' % (self._computer_id, self._partition_id))
   return xml_marshaller.loads(self._connection_helper.response.read())
Exemple #21
0
 def getStatus(self):
   self._connection_helper.GET(
       '/getComputerStatus?computer_id=%s' % self._computer_id)
   return xml_marshaller.loads(self._connection_helper.response.read())
Exemple #22
0
 def getComputerInformation(self, computer_id):
   xml = self.GET('/getComputerInformation?computer_id=%s' % computer_id)
   return xml_marshaller.loads(xml)
Exemple #23
0
 def getStatus(self):
   xml = self._connection_helper.GET(
       '/getComputerPartitionStatus?computer_id=%s&'
       'computer_partition_id=%s' % (self._computer_id, self._partition_id))
   return xml_marshaller.loads(xml)
Exemple #24
0
 def generateCertificate(self):
   xml = self._connection_helper.POST('/generateComputerCertificate', {
     'computer_id': self._computer_id})
   return xml_marshaller.loads(xml)
Exemple #25
0
 def getStatus(self):
   xml = self._connection_helper.GET(
       '/getComputerStatus?computer_id=%s' % self._computer_id)
   return xml_marshaller.loads(xml)
Exemple #26
0
 def getComputerInformation(self, computer_id):
   xml = self.GET('getComputerInformation', params={'computer_id': computer_id})
   return xml_marshaller.loads(xml)
Exemple #27
0
 def getComputerInformation(self, computer_id):
   self.GET('/getComputerInformation?computer_id=%s' % computer_id)
   return xml_marshaller.loads(self.response.read())