views.py 19.7 KB
Newer Older
1
# -*- coding: utf-8 -*-
Marco Mariani's avatar
Marco Mariani committed
2
# vim: set et sts=2:
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
##############################################################################
#
# Copyright (c) 2010, 2011, 2012 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################

Łukasz Nowak's avatar
Łukasz Nowak committed
31
from lxml import etree
Marco Mariani's avatar
Marco Mariani committed
32
import sqlite3
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
33
from slapos.slap.slap import Computer, ComputerPartition, \
34
    SoftwareRelease, SoftwareInstance, NotFoundError
Marco Mariani's avatar
Marco Mariani committed
35
from slapos.proxy.db_version import DB_VERSION
Łukasz Nowak's avatar
Łukasz Nowak committed
36

Marco Mariani's avatar
Marco Mariani committed
37 38
from flask import g, Flask, request, abort
import xml_marshaller
Łukasz Nowak's avatar
Łukasz Nowak committed
39 40
app = Flask(__name__)

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
41

Łukasz Nowak's avatar
Łukasz Nowak committed
42 43 44
class UnauthorizedError(Exception):
  pass

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
45

Łukasz Nowak's avatar
Łukasz Nowak committed
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
def xml2dict(xml):
  result_dict = {}
  if xml is not None and xml != '':
    tree = etree.fromstring(xml.encode('utf-8'))
    for element in tree.iter(tag=etree.Element):
      if element.tag == 'parameter':
        key = element.get('id')
        value = result_dict.get(key, None)
        if value is not None:
          value = value + ' ' + element.text
        else:
          value = element.text
        result_dict[key] = value
  return result_dict

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
61

62
def dict2xml(dictionary):
Łukasz Nowak's avatar
Łukasz Nowak committed
63
  instance = etree.Element('instance')
64
  for parameter_id, parameter_value in dictionary.iteritems():
Łukasz Nowak's avatar
Łukasz Nowak committed
65 66 67
    # cast everything to string
    parameter_value = str(parameter_value)
    etree.SubElement(instance, "parameter",
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
68
                     attrib={'id': parameter_id}).text = parameter_value
69 70 71 72
  return etree.tostring(instance,
                        pretty_print=True,
                        xml_declaration=True,
                        encoding='utf-8')
Łukasz Nowak's avatar
Łukasz Nowak committed
73

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
74

Łukasz Nowak's avatar
Łukasz Nowak committed
75
def partitiondict2partition(partition):
76 77 78
  for key, value in partition.iteritems():
    if type(value) is unicode:
      partition[key] = value.encode()
Łukasz Nowak's avatar
Łukasz Nowak committed
79 80
  slap_partition = ComputerPartition(app.config['computer_id'],
      partition['reference'])
81 82 83
  slap_partition._software_release_document = None
  slap_partition._requested_state = 'destroyed'
  slap_partition._need_modification = 0
84
  slap_partition._instance_guid = partition['reference']
85

Łukasz Nowak's avatar
Łukasz Nowak committed
86 87
  if partition['software_release']:
    slap_partition._need_modification = 1
88
    slap_partition._requested_state = partition['requested_state']
89 90 91 92 93 94 95 96 97
    slap_partition._parameter_dict = xml2dict(partition['xml'])
    address_list = []
    for address in execute_db('partition_network',
                              'SELECT * FROM %s WHERE partition_reference=?',
                              [partition['reference']]):
      address_list.append((address['reference'], address['address']))
    slap_partition._parameter_dict['ip_list'] = address_list
    slap_partition._parameter_dict['slap_software_type'] = \
        partition['software_type']
98
    if partition['slave_instance_list'] is not None:
99 100
      slap_partition._parameter_dict['slave_instance_list'] = \
          xml_marshaller.xml_marshaller.loads(partition['slave_instance_list'])
101 102
    else:
      slap_partition._parameter_dict['slave_instance_list'] = []
103 104
    slap_partition._connection_dict = xml2dict(partition['connection_xml'])
    slap_partition._software_release_document = SoftwareRelease(
Łukasz Nowak's avatar
Łukasz Nowak committed
105 106
      software_release=partition['software_release'],
      computer_guid=app.config['computer_id'])
107

Łukasz Nowak's avatar
Łukasz Nowak committed
108 109
  return slap_partition

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
110

Łukasz Nowak's avatar
Łukasz Nowak committed
111 112 113 114 115 116 117 118 119 120
def execute_db(table, query, args=(), one=False):
  try:
    cur = g.db.execute(query % (table + DB_VERSION,), args)
  except:
    app.logger.error('There was some issue during processing query %r on table %r with args %r' % (query, table, args))
    raise
  rv = [dict((cur.description[idx][0], value)
    for idx, value in enumerate(row)) for row in cur.fetchall()]
  return (rv[0] if rv else None) if one else rv

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
121

Łukasz Nowak's avatar
Łukasz Nowak committed
122 123 124
def connect_db():
  return sqlite3.connect(app.config['DATABASE_URI'])

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
125

Łukasz Nowak's avatar
Łukasz Nowak committed
126 127 128 129
@app.before_request
def before_request():
  g.db = connect_db()
  schema = app.open_resource('schema.sql')
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
130
  schema = schema.read() % dict(version=DB_VERSION)
Łukasz Nowak's avatar
Łukasz Nowak committed
131 132 133
  g.db.cursor().executescript(schema)
  g.db.commit()

134

Łukasz Nowak's avatar
Łukasz Nowak committed
135 136 137 138 139 140 141 142
@app.after_request
def after_request(response):
  g.db.commit()
  g.db.close()
  return response

@app.route('/getComputerInformation', methods=['GET'])
def getComputerInformation():
Cédric de Saint Martin's avatar
Cédric de Saint Martin committed
143 144
  # Kept only for backward compatiblity
  return getFullComputerInformation()
145 146 147

@app.route('/getFullComputerInformation', methods=['GET'])
def getFullComputerInformation():
Łukasz Nowak's avatar
Łukasz Nowak committed
148 149 150 151 152 153 154 155 156 157 158 159 160
  computer_id = request.args['computer_id']
  if app.config['computer_id'] == computer_id:
    slap_computer = Computer(computer_id)
    slap_computer._software_release_list = []
    for sr in execute_db('software', 'select * from %s'):
      slap_computer._software_release_list.append(SoftwareRelease(
        software_release=sr['url'], computer_guid=computer_id))
    slap_computer._computer_partition_list = []
    for partition in execute_db('partition', 'SELECT * FROM %s'):
      slap_computer._computer_partition_list.append(partitiondict2partition(
        partition))
    return xml_marshaller.xml_marshaller.dumps(slap_computer)
  else:
Marco Mariani's avatar
Marco Mariani committed
161
    raise NotFoundError('Only accept request for: %s' % app.config['computer_id'])
Łukasz Nowak's avatar
Łukasz Nowak committed
162 163 164

@app.route('/setComputerPartitionConnectionXml', methods=['POST'])
def setComputerPartitionConnectionXml():
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
165
  slave_reference = request.form['slave_reference'].encode()
Łukasz Nowak's avatar
Łukasz Nowak committed
166 167 168
  computer_partition_id = request.form['computer_partition_id']
  connection_xml = request.form['connection_xml']
  connection_dict = xml_marshaller.xml_marshaller.loads(
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
169
                                            connection_xml.encode())
Łukasz Nowak's avatar
Łukasz Nowak committed
170
  connection_xml = dict2xml(connection_dict)
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
171 172 173 174 175 176 177 178 179 180 181
  if slave_reference == 'None':
    query = 'UPDATE %s SET connection_xml=? WHERE reference=?'
    argument_list = [connection_xml, computer_partition_id.encode()]
    execute_db('partition', query, argument_list)
    return 'done'
  else:
    query = 'UPDATE %s SET connection_xml=? , hosted_by=? WHERE reference=?'
    argument_list = [connection_xml, computer_partition_id.encode(),
                     slave_reference]
    execute_db('slave', query, argument_list)
    return 'done'
Łukasz Nowak's avatar
Łukasz Nowak committed
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206

@app.route('/buildingSoftwareRelease', methods=['POST'])
def buildingSoftwareRelease():
  return 'Ignored'

@app.route('/availableSoftwareRelease', methods=['POST'])
def availableSoftwareRelease():
  return 'Ignored'

@app.route('/softwareReleaseError', methods=['POST'])
def softwareReleaseError():
  return 'Ignored'

@app.route('/buildingComputerPartition', methods=['POST'])
def buildingComputerPartition():
  return 'Ignored'

@app.route('/availableComputerPartition', methods=['POST'])
def availableComputerPartition():
  return 'Ignored'

@app.route('/softwareInstanceError', methods=['POST'])
def softwareInstanceError():
  return 'Ignored'

207 208 209 210
@app.route('/softwareInstanceBang', methods=['POST'])
def softwareInstanceBang():
  return 'Ignored'

Łukasz Nowak's avatar
Łukasz Nowak committed
211 212 213 214 215 216 217 218 219 220 221 222
@app.route('/startedComputerPartition', methods=['POST'])
def startedComputerPartition():
  return 'Ignored'

@app.route('/stoppedComputerPartition', methods=['POST'])
def stoppedComputerPartition():
  return 'Ignored'

@app.route('/destroyedComputerPartition', methods=['POST'])
def destroyedComputerPartition():
  return 'Ignored'

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
@app.route('/useComputer', methods=['POST'])
def useComputer():
  return 'Ignored'

@app.route('/loadComputerConfigurationFromXML', methods=['POST'])
def loadComputerConfigurationFromXML():
  xml = request.form['xml']
  computer_dict = xml_marshaller.xml_marshaller.loads(str(xml))
  if app.config['computer_id'] == computer_dict['reference']:
    execute_db('computer', 'INSERT OR REPLACE INTO %s values(:address, :netmask)',
        computer_dict)
    for partition in computer_dict['partition_list']:

      execute_db('partition', 'INSERT OR IGNORE INTO %s (reference) values(:reference)', partition)
      execute_db('partition_network', 'DELETE FROM %s WHERE partition_reference = ?', [partition['reference']])
      for address in partition['address_list']:
        address['reference'] = partition['tap']['name']
        address['partition_reference'] = partition['reference']
        execute_db('partition_network', 'INSERT OR REPLACE INTO %s (reference, partition_reference, address, netmask) values(:reference, :partition_reference, :addr, :netmask)', address)

    return 'done'
  else:
Marco Mariani's avatar
Marco Mariani committed
245
    raise UnauthorizedError('Only accept request for: %s' % app.config['computer_id'])
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
246 247 248 249 250 251 252 253 254 255 256 257 258

@app.route('/registerComputerPartition', methods=['GET'])
def registerComputerPartition():
  computer_reference = request.args['computer_reference']
  computer_partition_reference = request.args['computer_partition_reference']
  if app.config['computer_id'] == computer_reference:
    partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=?',
      [computer_partition_reference.encode()], one=True)
    if partition is None:
      raise UnauthorizedError
    return xml_marshaller.xml_marshaller.dumps(
        partitiondict2partition(partition))
  else:
Marco Mariani's avatar
Marco Mariani committed
259
    raise UnauthorizedError('Only accept request for: %s' % app.config['computer_id'])
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
260 261 262 263 264 265

@app.route('/supplySupply', methods=['POST'])
def supplySupply():
  url = request.form['url']
  computer_id = request.form['computer_id']
  if app.config['computer_id'] == computer_id:
266 267 268 269
    if request.form['state'] == 'destroyed':
      execute_db('software', 'DELETE FROM %s WHERE url = ?', [url])
    else:
      execute_db('software', 'INSERT OR REPLACE INTO %s VALUES(?)', [url])
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
270
  else:
Marco Mariani's avatar
Marco Mariani committed
271
    raise UnauthorizedError('Only accept request for: %s' % app.config['computer_id'])
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
272 273 274
  return '%r added' % url


Łukasz Nowak's avatar
Łukasz Nowak committed
275 276
@app.route('/requestComputerPartition', methods=['POST'])
def requestComputerPartition():
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
277
  shared_xml = request.form.get('shared_xml')
278
  share = xml_marshaller.xml_marshaller.loads(shared_xml.encode())
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
279 280 281 282 283
  if not share:
    return request_not_shared()
  else:
    return request_slave()

Marco Mariani's avatar
Marco Mariani committed
284 285 286 287 288 289 290 291 292 293

@app.route('/softwareInstanceRename', methods=['POST'])
def softwareInstanceRename():
  new_name = request.form['new_name'].encode()
  computer_partition_id = request.form['computer_partition_id'].encode()

  q = 'UPDATE %s SET partition_reference = ? WHERE reference = ?'
  execute_db('partition', q, [new_name, computer_partition_id])
  return 'done'

294 295 296 297 298
@app.route('/getComputerPartitionStatus', methods=['GET'])
def getComputerPartitionStatus():
  # XXX: not implemented
  return xml_marshaller.xml_marshaller.dumps('')

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
299
def request_not_shared():
Łukasz Nowak's avatar
Łukasz Nowak committed
300 301
  software_release = request.form['software_release'].encode()
  # some supported parameters
302
  software_type = request.form.get('software_type').encode()
Łukasz Nowak's avatar
Łukasz Nowak committed
303 304 305
  partition_reference = request.form.get('partition_reference', '').encode()
  partition_id = request.form.get('computer_partition_id', '').encode()
  partition_parameter_kw = request.form.get('partition_parameter_xml', None)
306
  requested_state = xml_marshaller.xml_marshaller.loads(request.form.get('state').encode())
Łukasz Nowak's avatar
Łukasz Nowak committed
307 308 309 310 311
  if partition_parameter_kw:
    partition_parameter_kw = xml_marshaller.xml_marshaller.loads(
                                              partition_parameter_kw.encode())
  else:
    partition_parameter_kw = {}
312

Łukasz Nowak's avatar
Łukasz Nowak committed
313 314 315
  instance_xml = dict2xml(partition_parameter_kw)
  args = []
  a = args.append
316 317
  q = 'SELECT * FROM %s WHERE partition_reference=?'
  a(partition_reference)
318

Łukasz Nowak's avatar
Łukasz Nowak committed
319
  partition = execute_db('partition', q, args, one=True)
320 321 322 323 324

  args = []
  a = args.append
  q = 'UPDATE %s SET slap_state="busy"'

325 326 327 328
  if requested_state:
    q += ', requested_state=?'
    a(requested_state)

329
  # If partition doesn't exist: create it and insert parameters
Łukasz Nowak's avatar
Łukasz Nowak committed
330 331 332 333 334
  if partition is None:
    partition = execute_db('partition',
        'SELECT * FROM %s WHERE slap_state="free"', (), one=True)
    if partition is None:
      app.logger.warning('No more free computer partition')
335
      abort(404)
336 337 338 339 340 341 342 343
    q += ' ,software_release=?'
    a(software_release)
    if partition_reference:
      q += ' ,partition_reference=?'
      a(partition_reference)
    if partition_id:
      q += ' ,requested_by=?'
      a(partition_id)
344 345 346 347 348 349 350 351 352
    if not software_type:
      software_type = 'RootSoftwareInstance'

  #
  # XXX change software_type when requested
  #
  if software_type:
    q += ' ,software_type=?'
    a(software_type)
353 354

  # Else: only update partition_parameter_kw
Łukasz Nowak's avatar
Łukasz Nowak committed
355
  if instance_xml:
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
356
    q += ' ,xml=?'
Łukasz Nowak's avatar
Łukasz Nowak committed
357 358 359 360 361 362 363 364 365 366
    a(instance_xml)
  q += ' WHERE reference=?'
  a(partition['reference'].encode())
  execute_db('partition', q, args)
  args = []
  partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=?',
      [partition['reference'].encode()], one=True)
  address_list = []
  for address in execute_db('partition_network', 'SELECT * FROM %s WHERE partition_reference=?', [partition['reference']]):
    address_list.append((address['reference'], address['address']))
367

368 369
  if not requested_state:
    requested_state = 'started'
370
  # XXX it should be ComputerPartition, not a SoftwareInstance
371
  software_instance = SoftwareInstance(_connection_dict=xml2dict(partition['connection_xml']),
372
                                       _parameter_dict=xml2dict(partition['xml']),
Marco Mariani's avatar
Marco Mariani committed
373 374 375 376 377 378
                                       connection_xml=partition['connection_xml'],
                                       slap_computer_id=app.config['computer_id'],
                                       slap_computer_partition_id=partition['reference'],
                                       slap_software_release_url=partition['software_release'],
                                       slap_server_url='slap_server_url',
                                       slap_software_type=partition['software_type'],
379 380
                                       _instance_guid=partition['reference'],
                                       _requested_state=requested_state,
Marco Mariani's avatar
Marco Mariani committed
381 382 383
                                       ip_list=address_list)

  return xml_marshaller.xml_marshaller.dumps(software_instance)
Łukasz Nowak's avatar
Łukasz Nowak committed
384 385


Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
386 387
def request_slave():
  """
388 389 390 391 392
  Function to organise link between slave and master.
  Slave information are stored in places:
  1. slave table having information such as slave reference,
      connection information to slave (given by slave master),
      hosted_by and asked_by reference.
393
  2. A dictionary in slave_instance_list of selected slave master
394 395
      in which are stored slave_reference, software_type, slave_title and
      partition_parameter_kw stored as individual keys.
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
396 397 398 399 400 401
  """
  software_release = request.form['software_release'].encode()
  # some supported parameters
  software_type = request.form.get('software_type').encode()
  partition_reference = request.form.get('partition_reference', '').encode()
  partition_id = request.form.get('computer_partition_id', '').encode()
402
  # Contain slave parameters to be given to slave master
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
403
  partition_parameter_kw = request.form.get('partition_parameter_xml', None)
Marco Mariani's avatar
Marco Mariani committed
404
  if partition_parameter_kw:
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
405 406
    partition_parameter_kw = xml_marshaller.xml_marshaller.loads(
                                              partition_parameter_kw.encode())
Łukasz Nowak's avatar
Łukasz Nowak committed
407
  else:
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
408
    partition_parameter_kw = {}
409 410 411

  filter_kw = xml_marshaller.xml_marshaller.loads(request.form.get('filter_xml').encode())

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
412
  instance_xml = dict2xml(partition_parameter_kw)
413
  # We will search for a master corresponding to request
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
414 415 416 417 418 419 420
  args = []
  a = args.append
  q = 'SELECT * FROM %s WHERE software_release=?'
  a(software_release)
  if software_type:
    q += ' AND software_type=?'
    a(software_type)
421 422 423 424
  if 'instance_guid' in filter_kw:
    q += ' AND reference=?'
    a(filter_kw['instance_guid'])

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
425 426
  partition = execute_db('partition', q, args, one=True)
  if partition is None:
427
    app.logger.warning('No partition corresponding to slave request: %s' % args)
428
    abort(404)
429

Marco Mariani's avatar
Marco Mariani committed
430
  # We set slave dictionary as described in docstring
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
431 432 433 434 435
  new_slave = {}
  slave_reference = partition_id + '_' + partition_reference
  new_slave['slave_title'] = slave_reference
  new_slave['slap_software_type'] = software_type
  new_slave['slave_reference'] = slave_reference
436

437 438
  for key in partition_parameter_kw:
    if partition_parameter_kw[key] is not None:
439
      new_slave[key] = partition_parameter_kw[key]
Łukasz Nowak's avatar
Łukasz Nowak committed
440

441
  # Add slave to partition slave_list if not present else replace information
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
442
  slave_instance_list = partition['slave_instance_list']
443
  if slave_instance_list is None:
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
444
    slave_instance_list = []
Łukasz Nowak's avatar
Łukasz Nowak committed
445
  else:
446
    slave_instance_list = xml_marshaller.xml_marshaller.loads(slave_instance_list.encode())
447 448 449 450 451
    for x in slave_instance_list:
      if x['slave_reference'] == slave_reference:
        slave_instance_list.remove(x)

  slave_instance_list.append(new_slave)
Łukasz Nowak's avatar
Łukasz Nowak committed
452

453
  # Update slave_instance_list in database
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
454 455 456 457 458 459 460 461 462 463 464 465 466 467
  args = []
  a = args.append
  q = 'UPDATE %s SET slave_instance_list=?'
  a(xml_marshaller.xml_marshaller.dumps(slave_instance_list))
  q += ' WHERE reference=?'
  a(partition['reference'].encode())
  execute_db('partition', q, args)
  args = []
  partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=?',
      [partition['reference'].encode()], one=True)

  # Add slave to slave table if not there
  slave = execute_db('slave', 'SELECT * FROM %s WHERE reference=?',
                     [slave_reference], one=True)
468
  if slave is None:
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
469
    execute_db('slave',
470
               'INSERT OR IGNORE INTO %s (reference,asked_by,hosted_by) values(:reference,:asked_by,:hosted_by)',
471 472 473
               [slave_reference, partition_id, partition['reference']])
    slave = execute_db('slave', 'SELECT * FROM %s WHERE reference=?',
                       [slave_reference], one=True)
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
474 475 476 477 478 479

  address_list = []
  for address in execute_db('partition_network',
                            'SELECT * FROM %s WHERE partition_reference=?',
                            [partition['reference']]):
    address_list.append((address['reference'], address['address']))
480 481

  # XXX it should be ComputerPartition, not a SoftwareInstance
Marco Mariani's avatar
Marco Mariani committed
482
  software_instance = SoftwareInstance(_connection_dict=xml2dict(slave['connection_xml']),
483
                                       _parameter_dict=xml2dict(instance_xml),
Marco Mariani's avatar
Marco Mariani committed
484 485 486 487 488 489 490 491
                                       slap_computer_id=app.config['computer_id'],
                                       slap_computer_partition_id=slave['hosted_by'],
                                       slap_software_release_url=partition['software_release'],
                                       slap_server_url='slap_server_url',
                                       slap_software_type=partition['software_type'],
                                       ip_list=address_list)

  return xml_marshaller.xml_marshaller.dumps(software_instance)
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509


@app.route('/getSoftwareReleaseListFromSoftwareProduct', methods=['GET'])
def getSoftwareReleaseListFromSoftwareProduct():
  software_product_reference = request.args.get('software_product_reference')
  software_release_url = request.args.get('software_release_url')

  if software_release_url:
    assert(software_product_reference is None)
    raise NotImplementedError('software_release_url parameter is not supported yet.')
  else:
    assert(software_product_reference is not None)
    if app.config['software_product_list'].has_key(software_product_reference):
      software_release_url_list =\
          [app.config['software_product_list'][software_product_reference]]
    else:
      software_release_url_list =[]
    return xml_marshaller.xml_marshaller.dumps(software_release_url_list)