Commit 03abf2af authored by Jérome Perrin's avatar Jérome Perrin

proxy: support for software destruction

This introduces a new `state` column in `software` table.

Because node already has support for reporting various states of software
lifetime, this implementation stores the actual state of the software
installation.
What's not clear is that maybe it should store the requested state and the current state.

```plantuml
@startuml
start
repeat
  -> client request software in state available \n ""supplySupply?state="available""";
  if (already available ?) then (yes)
    :available;
  else (no )
    :install_requested;
    -> node starts building \n ""buildingSoftwareRelease"";
    :building;
    if ( build result? ) then ( node report build successful \n ""availableSoftwareRelease"" )
      :available;
    else (node report build error \n ""softwareReleaseError"" )
      :error;
    endif
  endif
repeat while ()

-> client request software in state destroyed \n ""supplySupply?state="destroyed""";;
:destroyed;
-> node notify software is deleted \n""destroyedSoftwareRelease"";
stop
@enduml
```
parent 60a7dd72
--version:11
--version:12
CREATE TABLE IF NOT EXISTS software%(version)s (
url VARCHAR(255),
computer_reference VARCHAR(255) DEFAULT '%(computer)s',
slap_state VARCHAR(255) DEFAULT 'available',
CONSTRAINT uniq PRIMARY KEY (url, computer_reference)
);
......
......@@ -225,8 +225,12 @@ def getFullComputerInformation():
slap_computer = Computer(computer_id)
slap_computer._software_release_list = []
for sr in execute_db('software', 'select * from %s WHERE computer_reference=?', [computer_id]):
slap_computer._software_release_list.append(SoftwareRelease(
software_release=sr['url'], computer_guid=computer_id))
slap_computer._software_release_list.append(
SoftwareRelease(
software_release=sr['url'],
computer_guid=computer_id,
requested_state=sr['slap_state']
))
slap_computer._computer_partition_list = []
for partition in execute_db('partition', 'SELECT * FROM %s WHERE computer_reference=?', [computer_id]):
slap_computer._computer_partition_list.append(partitiondict2partition(
......@@ -252,15 +256,35 @@ def setComputerPartitionConnectionXml():
@app.route('/buildingSoftwareRelease', methods=['POST'])
def buildingSoftwareRelease():
return 'Ignored'
execute_db(
'software',
'INSERT OR REPLACE INTO %s VALUES(?, ?, "building")',
[request.form['url'], request.form['computer_id']])
return 'OK'
@app.route('/destroyedSoftwareRelease', methods=['POST'])
def destroyedSoftwareRelease():
execute_db(
'software',
'DELETE FROM %s WHERE url = ? and computer_reference=? ',
[request.form['url'], request.form['computer_id']])
return 'OK'
@app.route('/availableSoftwareRelease', methods=['POST'])
def availableSoftwareRelease():
return 'Ignored'
execute_db(
'software',
'UPDATE %s SET slap_state="available" WHERE url=? AND computer_reference=?',
[request.form['url'], request.form['computer_id']])
return 'OK'
@app.route('/softwareReleaseError', methods=['POST'])
def softwareReleaseError():
return 'Ignored'
execute_db(
'software',
'INSERT OR REPLACE INTO %s VALUES(?, ?, "error")',
[request.form['url'], request.form['computer_id']])
return 'OK'
@app.route('/softwareInstanceError', methods=['POST'])
def softwareInstanceError():
......@@ -319,11 +343,26 @@ def registerComputerPartition():
def supplySupply():
url = request.form['url']
computer_id = request.form['computer_id']
if request.form['state'] == 'destroyed':
execute_db('software', 'DELETE FROM %s WHERE url = ? AND computer_reference=?',
[url, computer_id])
else:
execute_db('software', 'INSERT OR REPLACE INTO %s VALUES(?, ?)', [url, computer_id])
state = request.form['state']
if state not in ('available', 'destroyed'):
raise ValueError("Wrong state %s" % state)
if state == 'available':
software = execute_db(
'software',
'SELECT slap_state FROM %s WHERE url=? and computer_reference=?',
[url, computer_id], one=True)
if software and software['slap_state'] == 'available':
return '%r already available' % url
state = 'install_requested'
execute_db(
'software',
'INSERT OR REPLACE INTO %s VALUES(?, ?, ?)',
[url, computer_id, state])
if state == 'destroyed':
return '%r destroyed' % url
return '%r added' % url
......
......@@ -120,7 +120,7 @@ class SoftwareRelease(SlapDocument):
Contains Software Release information
"""
def __init__(self, software_release=None, computer_guid=None, **kw):
def __init__(self, software_release=None, computer_guid=None, requested_state='available', **kw):
"""
Makes easy initialisation of class parameters
......@@ -131,9 +131,10 @@ class SoftwareRelease(SlapDocument):
self._software_instance_list = []
self._software_release = software_release
self._computer_guid = computer_guid
self._requested_state = requested_state
def __getinitargs__(self):
return (self._software_release, self._computer_guid, )
return (self._software_release, self._computer_guid, self._requested_state)
def getComputerId(self):
if not self._computer_guid:
......@@ -173,7 +174,7 @@ class SoftwareRelease(SlapDocument):
'computer_id': self.getComputerId()})
def getState(self):
return getattr(self, '_requested_state', 'available')
return self._requested_state
@implementer(interface.ISoftwareProductCollection)
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment