#
import re
-
from types import StringTypes
from PLC.Faults import *
from PLC.Filter import Filter
from PLC.Table import Row, Table
-from PLC.ForeignNodes import ForeignNodes,ForeignNode
+from PLC.Nodes import Nodes,Node
+from PLC.Slices import Slices,Slice
class Peer (Row):
"""
'peername' : Parameter (str, "Peer name"),
'peer_url' : Parameter (str, "Peer API url"),
'person_id' : Parameter (int, "Person_id of the account storing credentials - temporary"),
- 'node_ids' : Parameter ([int], "This peer's nodes ids")
+ 'node_ids' : Parameter ([int], "This peer's nodes ids"),
+ 'slice_ids' : Parameter ([int], "This peer's slices ids"),
}
def validate_peer_url (self, url):
raise invalid_url
return url
- def manage_node (self, foreign_node, add_if_true_del_if_false=True, commit=True):
- """
- Add foreign node to a peer
- """
-
- assert 'peer_id' in self
- assert 'node_id' in foreign_node
-
- peer_id = self['peer_id']
- node_id = foreign_node ['node_id']
-
- if add_if_true_del_if_false:
- ### ADDING
- sql = "INSERT INTO peer_node VALUES (%d,%d)" % (peer_id,node_id)
- self.api.db.do(sql)
- if self['node_ids'] is None:
- self['node_ids']=[node_id,]
- self['node_ids'].append(node_id)
- ### DELETING
- else:
- sql = "DELETE FROM peer_node WHERE peer_id=%d AND node_id=%d" % (peer_id,node_id)
- self.api.db.do(sql)
- self['node_ids'].remove(node_id)
-
- if commit:
- self.api.db.commit()
-
- def refresh_nodes (self, current_peer_nodes):
- """
- refreshes the foreign_nodes and peer_node tables
- expected input is the current list of nodes as returned by GetNodes
-
- returns the number of new nodes on this peer (can be negative)
- """
-
- peer_id = self['peer_id']
-
- # we get the whole table just in case
- # a host would have switched from one plc to the other
- local_foreign_nodes = ForeignNodes (self.api)
- # new to index it by hostname for searching later
- local_foreign_nodes.hostname_index()
-
- ### mark entries for this peer outofdate
- old_count=0;
- for foreign_node in local_foreign_nodes:
- if foreign_node['peer_id'] == peer_id:
- foreign_node.uptodate=False
- old_count += 1
-
- ### these fields get copied through
- ### xxx need to figure how to revert unix timestamp to db timestamp format
- remote_fields = ['boot_state','model','version','date_created','last_updated']
-
-
- ### scan the new entries, and mark them uptodate
- for node in current_peer_nodes:
- hostname = node['hostname']
- try:
- foreign_node = local_foreign_nodes.hostname_locate(hostname)
- if foreign_node['peer_id'] != peer_id:
- ### the node has changed its plc, needs to update peer_node
- old_peer_id = foreign_node['peer_id']
- old_peers=Peers(self.api,[peer_id])
- assert old_peer[0]
- old_peers[0].manage_node(foreign_node,False)
- self.manage_node(foreign_node,True)
- foreign_node['peer_id'] = peer_id
- ### update it anyway: copy other relevant fields
- for field in remote_fields:
- foreign_node[field]=node[field]
- # this row is now valid
- foreign_node.uptodate=True
- foreign_node.sync()
- except:
- new_foreign_node = ForeignNode(self.api, {'hostname':hostname})
- for field in remote_fields:
- new_foreign_node[field]=node[field]
- ### need to sync so we get a node_id
- new_foreign_node.sync()
- new_foreign_node.uptodate = True
- self.manage_node(new_foreign_node,True)
- local_foreign_nodes.hostname_add_by(new_foreign_node)
-
-
- ### delete entries that are not uptodate
- for foreign_node in local_foreign_nodes:
- if not foreign_node.uptodate:
- foreign_node.delete()
-
- return len(current_peer_nodes)-old_count
-
-
def delete (self, commit=True):
"""
Delete peer
assert 'peer_id' in self
+ # remove nodes depending on this peer
+ for foreign_node in Nodes (self.api, self['node_ids']):
+ foreign_node.delete(commit)
+
+ # remove the peer
self['deleted'] = True
self.sync(commit)