def device_reboot(): """ Callback for the "reboot_device" method which reboots the system. """ retval = osal.system_reboot() if retval == 0: status = iot.STATUS_SUCCESS message = "" elif retval == osal.NOT_SUPPORTED: status = iot.STATUS_NOT_SUPPORTED message = "Reboot not supported on this platform!" else: status = iot.STATUS_FAILURE message = "Reboot failed with return code: " + str(retval) return (status, message)
def _update_software(self, client, params, request): """ Main method that will run in a new thread and perform all the software updates """ status = iot.STATUS_BAD_PARAMETER update_data = None package_name = None override_ota_logfile_name = None client.log(iot.LOGINFO, "Started OTA Update") client.event_publish("OTA: Started OTA Update") client.action_progress_update(request.request_id, "Started OTA Update") package_dir = os.path.join(self._runtime_dir, OTA_PACKAGEDIR) # Cleanup last ota artifacts if os.path.isdir(package_dir): client.log(iot.LOGINFO, "Clean up previous update artifacts...") shutil.rmtree(package_dir) # get extra params extra_params = params.get("extra_params") client.log(iot.LOGINFO, "Extra parameters {}".format(extra_params)) if params: error_notified = False download_timeout = params.get("ota_timeout") if params.get("ota_logfile"): override_ota_logfile_name = self._scrub_file_name( client, params.get("ota_logfile")) client.log( iot.LOGINFO, "Override OTA logfile name {}".format( override_ota_logfile_name)) # 1. Download Package client.log(iot.LOGINFO, "Downloading Package...") client.event_publish("OTA: Downloading Package...") package_name = params.get("package") client.alarm_publish(ALARM_NAME, ALARM_STARTED, message="package: {}".format(package_name)) status = self._package_download(client, package_name, download_timeout) # 2. Unzip Package if status == iot.STATUS_SUCCESS or self.offline: client.log(iot.LOGINFO, "Download Phase Done!") client.event_publish("OTA: Download Successful!") client.log(iot.LOGINFO, "Unzipping Package...") client.event_publish("OTA: Unzipping Package...") status = self._package_unzip(package_name, package_dir) elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Download Failed!") client.event_publish("OTA: Download Failed!") # 3. Read Update Data from JSON File if status == iot.STATUS_SUCCESS: client.log(iot.LOGINFO, "Unzip Complete!") client.event_publish("OTA: Package Unzip Successful!") client.log(iot.LOGINFO, "Reading Update Data...") client.event_publish("OTA: Reading Update Data...") status, update_data = self._read_update_json(package_dir) elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Unzip Failed!") client.event_publish("OTA: Package Unzip Failed!") # 4. Run Pre-Install if status == iot.STATUS_SUCCESS: client.log(iot.LOGINFO, "Data Read Successful!") client.event_publish("OTA: Update Data Read Successfully!") client.log(iot.LOGINFO, "Running Pre-Install...") client.event_publish("OTA: Running Pre-Install...") client.action_progress_update(request.request_id, "Running Pre-Install") client.alarm_publish( ALARM_NAME, ALARM_PRE_INSTALL, message="package: {}".format(package_name)) if not update_data.get('pre_install', ""): status = iot.STATUS_SUCCESS client.log(iot.LOGINFO, "No Pre-Install specified! " "Continuing.") client.event_publish("OTA: No Pre-Install specified! " "Continuing.") else: status = self._execute(update_data['pre_install'], \ package_dir, extra_params) elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Data Read Failed!") client.event_publish("OTA: Failed to Read Update Data!") # 5. Run Install if status == iot.STATUS_SUCCESS: if update_data.get('pre_install', ""): client.log(iot.LOGINFO, "Pre-Install Complete!") client.event_publish("OTA: Pre-Install Successful!") client.action_progress_update(request.request_id, "Pre-Install Successful") client.log(iot.LOGINFO, "Running Install...") client.event_publish("OTA: Running Install...") client.action_progress_update(request.request_id, "Running Install") client.alarm_publish( ALARM_NAME, ALARM_INSTALL, message="package: {}".format(package_name)) status = self._execute(update_data['install'], package_dir, extra_params) elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Pre-Install Failed!") client.event_publish("OTA: Pre-Install Failed!") client.action_progress_update(request.request_id, "Pre-Install Failed") # 6. Run Post-Install if status == iot.STATUS_SUCCESS: client.log(iot.LOGINFO, "Install Complete!") client.event_publish("OTA: Install Successful!") client.action_progress_update(request.request_id, "Install Successful") client.log(iot.LOGINFO, "Running Post-Install...") client.event_publish("OTA: Running Post-Install...") client.action_progress_update(request.request_id, "Running Post-Install") client.alarm_publish( ALARM_NAME, ALARM_POST_INSTALL, message="package: {}".format(package_name)) if not update_data.get('post_install', ""): status = iot.STATUS_SUCCESS client.log(iot.LOGINFO, "No Post-Install specified! " "Continuing.") client.event_publish("OTA: No Post-Install specified! " "Continuing.") else: status = self._execute(update_data['post_install'], \ package_dir, extra_params) elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Install Failed!") client.event_publish("OTA: Install Failed!") client.action_progress_update(request.request_id, "Install Failed") if status == iot.STATUS_SUCCESS: if update_data.get('post_install', ""): client.log(iot.LOGINFO, "Post-Install Complete!") client.event_publish("OTA: Post-Install Successful!") client.action_progress_update(request.request_id, "Post-Install Successful") status = iot.STATUS_SUCCESS elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Post-Install Failed!") client.event_publish("OTA: Post-Install Failed!") client.action_progress_update(request.request_id, "Post-Install Failed") # 7. Report Final Status if status == iot.STATUS_SUCCESS: client.log(iot.LOGINFO, "OTA Successful!") client.event_publish("OTA: Update Successful!") client.action_progress_update(request.request_id, "Update Successful") client.alarm_publish(ALARM_NAME, ALARM_COMPLETE, message="package: {}".format(package_name)) status_string = "" else: if update_data and 'error_action' in update_data and \ update_data['error_action']: client.event_publish("OTA: Running install error action!") client.alarm_publish( ALARM_NAME, ALARM_INSTALL_ERROR, message="package: {}".format(package_name)) client.log(iot.LOGWARNING, "Running install error action!") self._execute(update_data['error_action'], package_dir, extra_params) client.log(iot.LOGERROR, "OTA Failed!") client.event_publish("OTA: Update Failed!") client.action_progress_update(request.request_id, "Update Failed") client.alarm_publish(ALARM_NAME, ALARM_FAILED, message="package: {}".format(package_name)) status_string = iot.status_string(status) # ----------------------------------------------------------------- # write the id,status to a file for when the agent is updated. The # device manager checks for a file "message_ids" and acks the # action. # ----------------------------------------------------------------- path = os.path.join(self._runtime_dir, "message_ids") open_mode = 'w' if os.path.exists(path): open_mode = 'a' with open(path, open_mode) as fh: fh.write("{},{}\n".format(request.request_id, status)) client.action_acknowledge(request.request_id, status, status_string) file_name = os.path.join(self._runtime_dir, "download", package_name) if os.path.isfile(file_name): client.log(iot.LOGWARNING, "removing file name %s" % file_name) os.remove(file_name) # Unlock the updater try: os.remove(os.path.join(self._runtime_dir, OTA_LOCKFILE)) except (OSError, IOError) as err: error = str(err) print( error + ". This file will block future OTA operations. Please remove it." ) client.log(iot.LOGINFO, \ "Update finished with status {}".format(iot.status_string(status))) stdout_log = os.path.abspath(os.path.join(package_dir, OTA_STDOUT_LOG)) client.log(iot.LOGINFO, "Logging stdout to file {}".format(stdout_log)) # print the stdout log to the client log # upload the stdout log to cloud if os.path.isfile(stdout_log): client.log(iot.LOGINFO, "OTA STDOUT log dump start") with open(stdout_log) as fh: while True: line = fh.readline() if line == "": break else: client.log(iot.LOGINFO, "{}".format(line.rstrip())) client.log(iot.LOGINFO, "OTA STDOUT log dump complete.") ts = datetime.utcnow().strftime("%Y-%m-%d-%S") client.log( iot.LOGINFO, "override_ota_logfile_name {} \n\n".format( override_ota_logfile_name)) if override_ota_logfile_name is not '': output_file = override_ota_logfile_name else: output_file = "ota_install-{}.log".format(ts) client.file_upload(stdout_log, upload_name=output_file, blocking=True, timeout=60, file_global=False), # Reboot if requested if update_data and 'reboot' in update_data and \ update_data['reboot'] == 'yes': osal.system_reboot()
def _update_software(self, client, params, request): """ Main method that will run in a new thread and perform all the software updates """ status = iot.STATUS_BAD_PARAMETER update_data = None client.alarm_publish(ALARM_NAME, ALARM_STARTED) client.log(iot.LOGINFO, "Started OTA Update") client.event_publish("OTA: Started OTA Update") client.action_progress_update(request.request_id, "Started OTA Update") package_dir = os.path.join(self._runtime_dir, OTA_PACKAGEDIR) if params: error_notified = False download_timeout = params.get("ota_timeout") # 1. Download Package client.log(iot.LOGINFO, "Downloading Package...") client.event_publish("OTA: Downloading Package...") package_name = params.get("package") status = self._package_download(client, package_name, download_timeout) # 2. Unzip Package if status == iot.STATUS_SUCCESS: client.log(iot.LOGINFO, "Download Phase Done!") client.event_publish("OTA: Download Successful!") client.log(iot.LOGINFO, "Unzipping Package...") client.event_publish("OTA: Unzipping Package...") status = self._package_unzip(package_name, package_dir) elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Download Failed!") client.event_publish("OTA: Download Failed!") # 3. Read Update Data from JSON File if status == iot.STATUS_SUCCESS: client.log(iot.LOGINFO, "Unzip Complete!") client.event_publish("OTA: Package Unzip Successful!") client.log(iot.LOGINFO, "Reading Update Data...") client.event_publish("OTA: Reading Update Data...") status, update_data = self._read_update_json(package_dir) elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Unzip Failed!") client.event_publish("OTA: Package Unzip Failed!") # 4. Run Pre-Install if status == iot.STATUS_SUCCESS: client.log(iot.LOGINFO, "Data Read Successful!") client.event_publish("OTA: Update Data Read Successfully!") client.log(iot.LOGINFO, "Running Pre-Install...") client.event_publish("OTA: Running Pre-Install...") client.action_progress_update(request.request_id, "Running Pre-Install") client.alarm_publish(ALARM_NAME, ALARM_PRE_INSTALL) if not update_data.get('pre_install', ""): status = iot.STATUS_SUCCESS client.log(iot.LOGINFO, "No Pre-Install specified! " "Continuing.") client.event_publish("OTA: No Pre-Install specified! " "Continuing.") else: status = self._execute(update_data['pre_install'], \ package_dir) elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Data Read Failed!") client.event_publish("OTA: Failed to Read Update Data!") # 5. Run Install if status == iot.STATUS_SUCCESS: if update_data.get('pre_install', ""): client.log(iot.LOGINFO, "Pre-Install Complete!") client.event_publish("OTA: Pre-Install Successful!") client.action_progress_update(request.request_id, "Pre-Install Successful") client.log(iot.LOGINFO, "Running Install...") client.event_publish("OTA: Running Install...") client.action_progress_update(request.request_id, "Running Install") client.alarm_publish(ALARM_NAME, ALARM_INSTALL) status = self._execute(update_data['install'], package_dir) elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Pre-Install Failed!") client.event_publish("OTA: Pre-Install Failed!") client.action_progress_update(request.request_id, "Pre-Install Failed") # 6. Run Post-Install if status == iot.STATUS_SUCCESS: client.log(iot.LOGINFO, "Install Complete!") client.event_publish("OTA: Install Successful!") client.action_progress_update(request.request_id, "Install Successful") client.log(iot.LOGINFO, "Running Post-Install...") client.event_publish("OTA: Running Post-Install...") client.action_progress_update(request.request_id, "Running Post-Install") client.alarm_publish(ALARM_NAME, ALARM_POST_INSTALL) if not update_data.get('post_install', ""): status = iot.STATUS_SUCCESS client.log(iot.LOGINFO, "No Post-Install specified! " "Continuing.") client.event_publish("OTA: No Post-Install specified! " "Continuing.") else: status = self._execute(update_data['post_install'], \ package_dir) elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Install Failed!") client.event_publish("OTA: Install Failed!") client.action_progress_update(request.request_id, "Install Failed") if status == iot.STATUS_SUCCESS: if update_data.get('post_install', ""): client.log(iot.LOGINFO, "Post-Install Complete!") client.event_publish("OTA: Post-Install Successful!") client.action_progress_update(request.request_id, "Post-Install Successful") status = iot.STATUS_SUCCESS elif not error_notified: error_notified = True client.log(iot.LOGERROR, "Post-Install Failed!") client.event_publish("OTA: Post-Install Failed!") client.action_progress_update(request.request_id, "Post-Install Failed") # 7. Report Final Status if status == iot.STATUS_SUCCESS: client.log(iot.LOGINFO, "OTA Successful!") client.event_publish("OTA: Update Successful!") client.action_progress_update(request.request_id, "Update Successful") client.alarm_publish(ALARM_NAME, ALARM_COMPLETE) status_string = "" else: if update_data and 'error_action' in update_data and \ update_data['error_action']: client.event_publish("OTA: Running install error action!") client.alarm_publish(ALARM_NAME, ALARM_INSTALL_ERROR) client.log(iot.LOGWARNING, "Running install error action!") self._execute(update_data['error_action'], package_dir) client.log(iot.LOGERROR, "OTA Failed!") client.event_publish("OTA: Update Failed!") client.action_progress_update(request.request_id, "Update Failed") client.alarm_publish(ALARM_NAME, ALARM_FAILED) status_string = iot.status_string(status) client.action_acknowledge(request.request_id, status, status_string) # Cleanup if os.path.isdir(package_dir): shutil.rmtree(package_dir) file_name = os.path.join(self._runtime_dir, "download", package_name) if os.path.isfile(file_name): os.remove(file_name) # Unlock the updater try: os.remove(os.path.join(self._runtime_dir, OTA_LOCKFILE)) except (OSError, IOError) as err: error = str(err) print( error + ". This file will block future OTA operations. Please remove it." ) client.log(iot.LOGINFO, \ "Update finished with status {}".format(iot.status_string(status))) # Reboot if requested if update_data and 'reboot' in update_data and \ update_data['reboot'] == 'yes': osal.system_reboot()