From: Stephen Soltesz Date: Fri, 27 May 2011 21:12:22 +0000 (-0400) Subject: Add two new fields to Nodes & DB to track last run-time and last down-time X-Git-Tag: plcapi-5.0-33~1^2^2 X-Git-Url: http://git.onelab.eu/?p=plcapi.git;a=commitdiff_plain;h=7e1cc31ebbf14297f1b6e02c1b011cfd4cd0d243 Add two new fields to Nodes & DB to track last run-time and last down-time add fields: last_time_spent_online & last_time_spent_offline make BootUpdateNode conditional on parameters passed so these values are calculated only once per boot. bootmanager was also updated to enforce this limit in a separate patch. --- diff --git a/PLC/Methods/BootUpdateNode.py b/PLC/Methods/BootUpdateNode.py index 4e81845..06bdd78 100644 --- a/PLC/Methods/BootUpdateNode.py +++ b/PLC/Methods/BootUpdateNode.py @@ -83,14 +83,30 @@ class BootUpdateNode(Method): interface.update(interface_fields) interface.sync(commit = False) - # indicate that node has booted & contacted PLC. - node.update_last_contact() - node.update_last_boot() - current_time = int(time.time()) - # if last_pcu_reboot is within 20 minutes of current_time, accept that the PCU is responsible - if node['last_pcu_reboot'] and Timestamp.cast_long(node['last_pcu_reboot']) >= current_time - 60*20: - node.update_last_pcu_confirmation(commit=False) + + # ONLY UPDATE ONCE when the boot_state flag and ssh_rsa_key flag are NOT passed + if not node_fields.has_key('boot_state') and not node_fields.has_key('ssh_rsa_key'): + + # record times spent on and off line by comparing last_contact with previous value of last_boot + if node['last_boot'] and node['last_contact']: + # last_boot is when the machine last called this API function. + # last_contact is the last time NM or RLA pinged the API. + node['last_time_spent_online'] = node['last_contact'] - node['last_boot'] + node['last_time_spent_offline'] = current_time - Timestamp.cast_long(node['last_contact']) + + node.update_readonly_int('last_time_spent_online') + node.update_readonly_int('last_time_spent_offline') + changed_fields.append('last_time_spent_online') + changed_fields.append('last_time_spent_offline') + + # indicate that node has booted & contacted PLC. + node.update_last_contact() + node.update_last_boot() + + # if last_pcu_reboot is within 20 minutes of current_time, accept that the PCU is responsible + if node['last_pcu_reboot'] and Timestamp.cast_long(node['last_pcu_reboot']) >= current_time - 60*20: + node.update_last_pcu_confirmation(commit=False) node.sync(commit = True) diff --git a/PLC/Nodes.py b/PLC/Nodes.py index a7e2988..87789ea 100644 --- a/PLC/Nodes.py +++ b/PLC/Nodes.py @@ -58,6 +58,8 @@ class Node(Row): 'last_download': Parameter(int, "Date and time when node boot image was created", ro = True), 'last_pcu_reboot': Parameter(int, "Date and time when PCU reboot was attempted", ro = True), 'last_pcu_confirmation': Parameter(int, "Date and time when PCU reboot was confirmed", ro = True), + 'last_time_spent_online': Parameter(int, "Length of time the node was last online before shutdown/failure", ro = True), + 'last_time_spent_offline': Parameter(int, "Length of time the node was last offline after failure and before reboot", ro = True), 'verified': Parameter(bool, "Whether the node configuration is verified correct", ro=False), 'key': Parameter(str, "(Admin only) Node key", max = 256), 'session': Parameter(str, "(Admin only) Node session value", max = 256, ro = True), @@ -120,6 +122,15 @@ class Node(Row): validate_last_pcu_reboot = Row.validate_timestamp validate_last_pcu_confirmation = Row.validate_timestamp + def update_readonly_int(self, col_name, commit = True): + + assert 'node_id' in self + assert self.table_name + + self.api.db.do("UPDATE %s SET %s = %s" % (self.table_name, col_name, self[col_name]) + \ + " where node_id = %d" % (self['node_id']) ) + self.sync(commit) + def update_timestamp(self, col_name, commit = True): """ Update col_name field with current time diff --git a/migrations/105-down-timespent.sql b/migrations/105-down-timespent.sql new file mode 100644 index 0000000..d2d1f2c --- /dev/null +++ b/migrations/105-down-timespent.sql @@ -0,0 +1,60 @@ +ALTER TABLE nodes DROP COLUMN last_time_spent_online CASCADE; +ALTER TABLE nodes DROP COLUMN last_time_spent_offline CASCADE; + +DROP VIEW view_nodes; +CREATE OR REPLACE VIEW view_nodes AS +SELECT +nodes.node_id, +nodes.node_type, +nodes.hostname, +nodes.site_id, +nodes.boot_state, +nodes.run_level, +nodes.deleted, +nodes.model, +nodes.boot_nonce, +nodes.version, +nodes.verified, +nodes.ssh_rsa_key, +nodes.key, +CAST(date_part('epoch', nodes.date_created) AS bigint) AS date_created, +CAST(date_part('epoch', nodes.last_updated) AS bigint) AS last_updated, +CAST(date_part('epoch', nodes.last_contact) AS bigint) AS last_contact, +CAST(date_part('epoch', nodes.last_boot) AS bigint) AS last_boot, +CAST(date_part('epoch', nodes.last_download) AS bigint) AS last_download, +CAST(date_part('epoch', nodes.last_pcu_reboot) AS bigint) AS last_pcu_reboot, +CAST(date_part('epoch', nodes.last_pcu_confirmation) AS bigint) AS last_pcu_confirmation, +peer_node.peer_id, +peer_node.peer_node_id, +COALESCE((SELECT interface_ids FROM node_interfaces + WHERE node_interfaces.node_id = nodes.node_id), '{}') +AS interface_ids, +COALESCE((SELECT nodegroup_ids FROM node_nodegroups + WHERE node_nodegroups.node_id = nodes.node_id), '{}') +AS nodegroup_ids, +COALESCE((SELECT slice_ids FROM node_slices + WHERE node_slices.node_id = nodes.node_id), '{}') +AS slice_ids, +COALESCE((SELECT slice_ids_whitelist FROM node_slices_whitelist + WHERE node_slices_whitelist.node_id = nodes.node_id), '{}') +AS slice_ids_whitelist, +COALESCE((SELECT pcu_ids FROM node_pcus + WHERE node_pcus.node_id = nodes.node_id), '{}') +AS pcu_ids, +COALESCE((SELECT ports FROM node_pcus + WHERE node_pcus.node_id = nodes.node_id), '{}') +AS ports, +COALESCE((SELECT conf_file_ids FROM node_conf_files + WHERE node_conf_files.node_id = nodes.node_id), '{}') +AS conf_file_ids, +COALESCE((SELECT node_tag_ids FROM node_tags + WHERE node_tags.node_id = nodes.node_id), '{}') +AS node_tag_ids, +node_session.session_id AS session +FROM nodes +LEFT JOIN peer_node USING (node_id) +LEFT JOIN node_session USING (node_id); + +-------------------------------------------------------------------------------- + +UPDATE plc_db_version SET subversion = 104; diff --git a/migrations/105-up-timespent.sql b/migrations/105-up-timespent.sql new file mode 100644 index 0000000..2dbdfb9 --- /dev/null +++ b/migrations/105-up-timespent.sql @@ -0,0 +1,62 @@ +ALTER TABLE nodes ADD COLUMN last_time_spent_online integer; +ALTER TABLE nodes ADD COLUMN last_time_spent_offline integer; + +DROP VIEW view_nodes; +CREATE OR REPLACE VIEW view_nodes AS +SELECT +nodes.node_id, +nodes.node_type, +nodes.hostname, +nodes.site_id, +nodes.boot_state, +nodes.run_level, +nodes.deleted, +nodes.model, +nodes.boot_nonce, +nodes.version, +nodes.verified, +nodes.ssh_rsa_key, +nodes.key, +CAST(date_part('epoch', nodes.date_created) AS bigint) AS date_created, +CAST(date_part('epoch', nodes.last_updated) AS bigint) AS last_updated, +CAST(date_part('epoch', nodes.last_contact) AS bigint) AS last_contact, +CAST(date_part('epoch', nodes.last_boot) AS bigint) AS last_boot, +CAST(date_part('epoch', nodes.last_download) AS bigint) AS last_download, +CAST(date_part('epoch', nodes.last_pcu_reboot) AS bigint) AS last_pcu_reboot, +CAST(date_part('epoch', nodes.last_pcu_confirmation) AS bigint) AS last_pcu_confirmation, +nodes.last_time_spent_online, +nodes.last_time_spent_offline, +peer_node.peer_id, +peer_node.peer_node_id, +COALESCE((SELECT interface_ids FROM node_interfaces + WHERE node_interfaces.node_id = nodes.node_id), '{}') +AS interface_ids, +COALESCE((SELECT nodegroup_ids FROM node_nodegroups + WHERE node_nodegroups.node_id = nodes.node_id), '{}') +AS nodegroup_ids, +COALESCE((SELECT slice_ids FROM node_slices + WHERE node_slices.node_id = nodes.node_id), '{}') +AS slice_ids, +COALESCE((SELECT slice_ids_whitelist FROM node_slices_whitelist + WHERE node_slices_whitelist.node_id = nodes.node_id), '{}') +AS slice_ids_whitelist, +COALESCE((SELECT pcu_ids FROM node_pcus + WHERE node_pcus.node_id = nodes.node_id), '{}') +AS pcu_ids, +COALESCE((SELECT ports FROM node_pcus + WHERE node_pcus.node_id = nodes.node_id), '{}') +AS ports, +COALESCE((SELECT conf_file_ids FROM node_conf_files + WHERE node_conf_files.node_id = nodes.node_id), '{}') +AS conf_file_ids, +COALESCE((SELECT node_tag_ids FROM node_tags + WHERE node_tags.node_id = nodes.node_id), '{}') +AS node_tag_ids, +node_session.session_id AS session +FROM nodes +LEFT JOIN peer_node USING (node_id) +LEFT JOIN node_session USING (node_id); + +-------------------------------------------------------------------------------- + +UPDATE plc_db_version SET subversion = 105;