in src/core/src/service_interfaces/LifecycleManagerArc.py [0:0]
def execution_start_check(self):
self.composite_logger.log_debug("\nExecution start check initiating...")
if self.execution_config.exec_auto_assess_only:
timer_start_time = self.env_layer.datetime.datetime_utcnow()
while True:
extension_sequence = self.read_extension_sequence()
core_sequence = self.read_core_sequence()
arc_core_sequence = self.read_arc_core_sequence()
# Timer evaluation
current_time = self.env_layer.datetime.datetime_utcnow()
elapsed_time_in_minutes = self.env_layer.datetime.total_minutes_from_time_delta(current_time - timer_start_time)
# Check for sequence number mismatches
if int(self.execution_config.sequence_number) != int(core_sequence['number']):
if int(self.execution_config.sequence_number) < int(extension_sequence['number']) or int(self.execution_config.sequence_number) < int(core_sequence['number']):
self.composite_logger.log_warning("Auto-assessment NOT STARTED as newer sequence number detected. [Attempted={0}][DetectedExt={1}][DetectedCore={2}]".format(str(self.execution_config.sequence_number), str(extension_sequence['number']), str(core_sequence['number'])))
elif int(self.execution_config.sequence_number) > int(extension_sequence['number']) or int(self.execution_config.sequence_number) > int(core_sequence['number']):
self.composite_logger.log_error("Auto-assessment NOT STARTED as an extension state anomaly was detected. [Attempted={0}][DetectedExt={1}][DetectedCore={2}]".format(str(self.execution_config.sequence_number), str(extension_sequence['number']), str(core_sequence['number'])))
self.composite_logger.file_logger.close()
self.env_layer.exit(0)
# DEFINITELY NOT SAFE TO START. ARC Assessment/Patch Operation is running. It is not required to start Auto-Assessment
if arc_core_sequence['completed'].lower() == 'false':
self.composite_logger.log_error("Auto-assessment NOT STARTED as arc extension is running. [Attempted={0}][ARCSequenceNo={1}]".format(str(self.execution_config.sequence_number), str(arc_core_sequence['number'])))
self.composite_logger.file_logger.close()
self.env_layer.exit(0)
# DEFINITELY SAFE TO START. Correct sequence number marked as completed
if core_sequence['completed'].lower() == 'true':
self.composite_logger.log("Auto-assessment is SAFE to start. Existing sequence number marked as COMPLETED.\n")
self.read_only_mode = False
break
# Check for active running processes if not completed
if len(self.identify_running_processes(core_sequence['processIds'])) != 0:
if os.getpid() in core_sequence['processIds']:
self.composite_logger.log("Auto-assessment is SAFE to start. Core sequence ownership is already established.\n")
self.read_only_mode = False
break
# DEFINITELY _NOT_ SAFE TO START. Possible reasons: full core operation is in progress (okay), some previous auto-assessment is still running (bad scheduling, adhoc run, or process stalled)
if elapsed_time_in_minutes > Constants.MAX_AUTO_ASSESSMENT_WAIT_FOR_MAIN_CORE_EXEC_IN_MINUTES: # will wait up to the max allowed
self.composite_logger.log_warning("Auto-assessment is NOT safe to start yet.TIMED-OUT waiting to Core to complete. EXITING. [LastHeartbeat={0}][Operation={1}]".format(str(core_sequence['lastHeartbeat']), str(core_sequence['action'])))
self.composite_logger.file_logger.close()
self.env_layer.exit(0)
else:
self.composite_logger.file_logger.flush()
self.composite_logger.log_warning("Auto-assessment is NOT safe to start yet. Waiting to retry (up to set timeout). [LastHeartbeat={0}][Operation={1}][ElapsedTimeInMinutes={2}][TotalWaitRequiredInMinutes={3}]".format(str(core_sequence['lastHeartbeat']), str(core_sequence['action']), str(elapsed_time_in_minutes), str(Constants.REBOOT_BUFFER_IN_MINUTES)))
self.composite_logger.file_logger.flush()
time.sleep(30)
continue
# MAYBE SAFE TO START. Safely timeout if wait for any core restart events (from a potential reboot) has exceeded the maximum reboot buffer
if elapsed_time_in_minutes > Constants.REBOOT_BUFFER_IN_MINUTES:
self.composite_logger.log_debug("Auto-assessment is now considered SAFE to start as Core timed-out in reporting completion mark. [LastHeartbeat={0}][Operation={1}]".format(str(core_sequence['lastHeartbeat']), str(core_sequence['action'])))
self.read_only_mode = False
break
# Briefly pause execution to re-check all states (including reboot buffer) again
self.composite_logger.file_logger.flush()
self.composite_logger.log_debug("Auto-assessment is waiting for Core state completion mark (up to set timeout). [LastHeartbeat={0}][Operation={1}][ElapsedTimeInMinutes={2}][TotalWaitRequiredInMinutes={3}]".format(str(core_sequence['lastHeartbeat']), str(core_sequence['action']), str(elapsed_time_in_minutes), str(Constants.REBOOT_BUFFER_IN_MINUTES)))
self.composite_logger.file_logger.flush()
time.sleep(30)
# Signalling take-over of core state by auto-assessment after safety checks for any competing process
self.update_core_sequence(completed=False)
# Refresh status file in memory to be up-to-date
self.status_handler.load_status_file_components()
else:
# Logic for all non-Auto-assessment operations
extension_sequence = self.read_extension_sequence()
core_sequence = self.read_core_sequence()
if int(extension_sequence['number']) == int(self.execution_config.sequence_number):
if core_sequence['completed'] is True:
# Block attempts to execute what last completed (fully) again
self.composite_logger.log_warning("LifecycleManager recorded false enable for completed sequence {0}.".format(str(extension_sequence['number'])))
self.composite_logger.file_logger.close()
self.env_layer.exit(0)
else:
# Incomplete current execution
self.composite_logger.log_debug("Restarting execution for incomplete sequence number: {0}.".format(str(self.execution_config.sequence_number)))
elif int(extension_sequence['number']) < int(self.execution_config.sequence_number):
# Allow this but log a warning
self.composite_logger.log_warning("Unexpected lower sequence number: {0} < {1}.".format(str(self.execution_config.sequence_number), str(extension_sequence['number'])))
else:
# New sequence number
self.composite_logger.log_debug("New sequence number accepted for execution: {0} > {1}.".format(str(self.execution_config.sequence_number), str(extension_sequence['number'])))
self.composite_logger.log_debug("Completed execution start check.")