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)
Exemplo n.º 2
0
    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()
Exemplo n.º 3
0
    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()