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 ( CREATE TABLE IF NOT EXISTS software%(version)s (
url VARCHAR(255), url VARCHAR(255),
computer_reference VARCHAR(255) DEFAULT '%(computer)s', computer_reference VARCHAR(255) DEFAULT '%(computer)s',
slap_state VARCHAR(255) DEFAULT 'available',
CONSTRAINT uniq PRIMARY KEY (url, computer_reference) CONSTRAINT uniq PRIMARY KEY (url, computer_reference)
); );
......
...@@ -225,8 +225,12 @@ def getFullComputerInformation(): ...@@ -225,8 +225,12 @@ def getFullComputerInformation():
slap_computer = Computer(computer_id) slap_computer = Computer(computer_id)
slap_computer._software_release_list = [] slap_computer._software_release_list = []
for sr in execute_db('software', 'select * from %s WHERE computer_reference=?', [computer_id]): for sr in execute_db('software', 'select * from %s WHERE computer_reference=?', [computer_id]):
slap_computer._software_release_list.append(SoftwareRelease( slap_computer._software_release_list.append(
software_release=sr['url'], computer_guid=computer_id)) SoftwareRelease(
software_release=sr['url'],
computer_guid=computer_id,
requested_state=sr['slap_state']
))
slap_computer._computer_partition_list = [] slap_computer._computer_partition_list = []
for partition in execute_db('partition', 'SELECT * FROM %s WHERE computer_reference=?', [computer_id]): for partition in execute_db('partition', 'SELECT * FROM %s WHERE computer_reference=?', [computer_id]):
slap_computer._computer_partition_list.append(partitiondict2partition( slap_computer._computer_partition_list.append(partitiondict2partition(
...@@ -252,15 +256,35 @@ def setComputerPartitionConnectionXml(): ...@@ -252,15 +256,35 @@ def setComputerPartitionConnectionXml():
@app.route('/buildingSoftwareRelease', methods=['POST']) @app.route('/buildingSoftwareRelease', methods=['POST'])
def buildingSoftwareRelease(): 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']) @app.route('/availableSoftwareRelease', methods=['POST'])
def availableSoftwareRelease(): 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']) @app.route('/softwareReleaseError', methods=['POST'])
def softwareReleaseError(): 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']) @app.route('/softwareInstanceError', methods=['POST'])
def softwareInstanceError(): def softwareInstanceError():
...@@ -319,11 +343,26 @@ def registerComputerPartition(): ...@@ -319,11 +343,26 @@ def registerComputerPartition():
def supplySupply(): def supplySupply():
url = request.form['url'] url = request.form['url']
computer_id = request.form['computer_id'] computer_id = request.form['computer_id']
if request.form['state'] == 'destroyed': state = request.form['state']
execute_db('software', 'DELETE FROM %s WHERE url = ? AND computer_reference=?', if state not in ('available', 'destroyed'):
[url, computer_id]) raise ValueError("Wrong state %s" % state)
else:
execute_db('software', 'INSERT OR REPLACE INTO %s VALUES(?, ?)', [url, computer_id]) 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 return '%r added' % url
......
...@@ -120,7 +120,7 @@ class SoftwareRelease(SlapDocument): ...@@ -120,7 +120,7 @@ class SoftwareRelease(SlapDocument):
Contains Software Release information 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 Makes easy initialisation of class parameters
...@@ -131,9 +131,10 @@ class SoftwareRelease(SlapDocument): ...@@ -131,9 +131,10 @@ class SoftwareRelease(SlapDocument):
self._software_instance_list = [] self._software_instance_list = []
self._software_release = software_release self._software_release = software_release
self._computer_guid = computer_guid self._computer_guid = computer_guid
self._requested_state = requested_state
def __getinitargs__(self): def __getinitargs__(self):
return (self._software_release, self._computer_guid, ) return (self._software_release, self._computer_guid, self._requested_state)
def getComputerId(self): def getComputerId(self):
if not self._computer_guid: if not self._computer_guid:
...@@ -173,7 +174,7 @@ class SoftwareRelease(SlapDocument): ...@@ -173,7 +174,7 @@ class SoftwareRelease(SlapDocument):
'computer_id': self.getComputerId()}) 'computer_id': self.getComputerId()})
def getState(self): def getState(self):
return getattr(self, '_requested_state', 'available') return self._requested_state
@implementer(interface.ISoftwareProductCollection) @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