def file_download(client, params, user_data):
    """
    Callback for the "file_download" method which downloads a file from the
    cloud to the local system.
    """
    file_name = None
    file_path = None
    result = None
    timeout = 15
    blocking = user_data[1]
    if hasattr(config, "download_timeout"):
        timeout = config.download_timeout

    if params:
        file_name = params.get("file_name")
        file_path = params.get("file_path")

        if file_name and not file_path:
            file_path = abspath(
                os.path.join(user_data[0], "download", file_name))
        if file_path and not file_name:
            file_name = os.path.basename(file_path)
        if file_path.startswith('~'):
            result = iot.STATUS_BAD_PARAMETER
            message = "Paths cannot use '~' to reference a home directory"
        elif not os.path.isabs(file_path):
            file_path = abspath(
                os.path.join(user_data[0], "download", file_path))

        file_global = params.get("use_global_store", False)

    if result is None:
        if file_name and file_path:
            dir_path = os.path.dirname(file_path)
            if not os.path.exists(dir_path):
                try:
                    os.makedirs(dir_path)
                except (OSError, IOError) as e:
                    result = iot.STATUS_IO_ERROR
                    message = (
                        "Destination directory does not exist and could "
                        "not be created!")
                    client.error(message)
                    print(e)

            if result is None:
                client.log(iot.LOGINFO, "Downloading")
                result = client.file_download(file_name, file_path, \
                                              blocking=blocking, timeout=timeout, \
                                              file_global=file_global)
                if result == iot.STATUS_SUCCESS:
                    message = ""
                else:
                    message = iot.status_string(result)

        else:
            result = iot.STATUS_BAD_PARAMETER
            message = "No file name or destination given"

    return (result, message)
Exemplo n.º 2
0
def file_upload(client, params, user_data):
    """
    Callback for the "file_upload" method which uploads a file from the
    cloud to the local system. Wildcards in the file name are supported.
    """
    file_name = None
    file_path = None
    result = None
    if params:
        file_name = params.get("file_name")
        file_path = params.get("file_path")

        if file_name and not file_path:
            file_path = abspath(os.path.join(user_data[0], "upload", file_name))
        if file_path and not file_name:
            file_name = os.path.basename(file_path)
        if file_path.startswith('~'):
            result = iot.STATUS_BAD_PARAMETER
            message = "Paths cannot use '~' to reference a home directory"
        elif not os.path.isabs(file_path):
            file_path = abspath(os.path.join(user_data[0], "upload",
                                             file_path))

        file_global = params.get("use_global_store", False)

    if result is None:
        if file_name and file_path:
            client.log(iot.LOGINFO, "Uploading {}".format(file_name))
            result = client.file_upload(file_path, upload_name=file_name, \
                                        blocking=True, timeout=240, \
                                        file_global=file_global)
            if result == iot.STATUS_SUCCESS:
                message = ""
                if user_data[1] and file_path.startswith(user_data[0]):
                    os.remove(file_name)
            else:
                message = iot.status_string(result)
        else:
            result = iot.STATUS_BAD_PARAMETER
            message = "No file name or location given"

    return (result, message)
def file_upload(client, params, user_data):
    """
    Callback for the "file_upload" method which uploads a file from the
    cloud to the local system. Wildcards in the file name are supported.
    """
    file_name = None
    if params:
        file_name = params.get("file_name")
        if "dest_name" in params:
            dest_name = params.get("dest_name")
        else:
            dest_name = None

        file_global = params.get("global", False)

    if file_name:
        if not file_name.startswith('~'):
            if not file_name.startswith('/'):
                file_name = abspath(os.path.join(user_data[0], "upload", \
                                    file_name))
            client.log(iot.LOGINFO, "Uploading {}".format(file_name))
            result = client.file_upload(file_name, upload_name=dest_name, \
                                        blocking=True, timeout=240, \
                                        file_global=file_global)
            if result == iot.STATUS_SUCCESS:
                message = ""
            else:
                message = iot.status_string(result)
        else:
            message = "Paths cannot use '~' to reference a home directory"
            result = iot.STATUS_BAD_PARAMETER
    else:
        result = iot.STATUS_BAD_PARAMETER
        message = "No file name given"

    return (result, message)
def file_upload(client, params, user_data):
    """
    Callback for the "file_upload" method which uploads a file from the
    cloud to the local system. Wildcards in the file name are supported.
    """
    file_name = None
    file_path = None
    result = None
    tarfile_name = None

    # config parameters that are passed up
    runtime_dir = user_data[0]
    rm_on_success = user_data[1]
    upload_format_is_tar = user_data[2]
    blocking = user_data[3]

    if params:
        file_name = params.get("file_name")
        file_path = params.get("file_path")

        if file_name and not file_path:
            file_path = abspath(os.path.join(runtime_dir, "upload", file_name))
        if file_path and not file_name:
            file_name = os.path.basename(file_path)
        if file_path and os.path.isdir(file_path):
            file_path, file_name = file_upload_dir(user_data, file_path,
                                                   file_name)

            # when uploading a dir, we tar it off first.  Track the
            # name so that we can delete it.
            tarfile_name = file_path
        if not file_name and not file_path:
            file_path, file_name = file_upload_dir(user_data, file_path,
                                                   file_name)

            # when uploading a dir, we tar it off first.  Track the
            # name so that we can delete it.
            tarfile_name = file_path
        if file_path.startswith('~'):
            result = iot.STATUS_BAD_PARAMETER
            message = "Paths cannot use '~' to reference a home directory"
        elif not os.path.isabs(file_path):
            file_path = abspath(os.path.join(runtime_dir, "upload", file_path))

        file_global = params.get("use_global_store", False)

    if result is None:
        if file_name and file_path:
            client.log(iot.LOGINFO, "Uploading {}".format(file_name))
            result = client.file_upload(file_path, upload_name=file_name, \
                                        blocking=blocking, timeout=240, \
                                        file_global=file_global)
            if result == iot.STATUS_SUCCESS:
                message = ""
                # If upload_tar_file, delete tar file that was created
                if tarfile_name and blocking:
                    os.remove(tarfile_name)

                # Clean up files.  If the file_path has /upload/ in
                # it, clean up if requested
                if os.sep + "upload" + os.sep in file_path:
                    try:
                        # If upload_tar_file, delete associated files
                        if upload_format_is_tar:
                            base = os.path.dirname(file_path)
                            for fn in os.listdir(base):
                                if rm_on_success:
                                    os.remove(base + os.sep + fn)
                        # If all of runtime_dir/upload uploaded, delete all files
                        elif file_name == "upload":
                            for fn in os.listdir(file_path):
                                if rm_on_success:
                                    os.remove(file_path + os.sep + fn)
                        else:
                            if rm_on_success:
                                os.remove(file_path)

                    except (OSError, IOError) as err:
                        error = str(err)
                        print(error + ". Unable to remove file.")
            else:
                message = iot.status_string(result)
        else:
            result = iot.STATUS_BAD_PARAMETER
            message = "No file name or location given"

    return (result, message)
Exemplo n.º 5
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.º 6
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()
Exemplo n.º 7
0
def file_download(client, params, user_data):
    """
    Callback for the "file_download" method which downloads a file from the
    cloud to the local system.
    """
    file_name = None
    file_path = None
    result = None
    blocking = True
    timeout = 15
    message = "AWS provisioning completed"

    if params:
        file_name = params.get("file_name")
        file_path = params.get("file_path", "/install.tar.gz")

        if file_name and not file_path:
            file_path = abspath(
                os.path.join(user_data[0], "download", file_name))
        if file_path and not file_name:
            file_name = os.path.basename(file_path)
        if file_path.startswith('~'):
            result = iot.STATUS_BAD_PARAMETER
            message = "Paths cannot use '~' to reference a home directory"
        elif not os.path.isabs(file_path):
            file_path = abspath(
                os.path.join(user_data[0], "download", file_path))

        file_global = params.get("use_global_store", False)

    if result is None:
        if file_name and file_path:
            dir_path = os.path.dirname(file_path)
            if not os.path.exists(dir_path):
                try:
                    os.makedirs(dir_path)
                except (OSError, IOError) as e:
                    result = iot.STATUS_IO_ERROR
                    message = (
                        "Destination directory does not exist and could "
                        "not be created!")
                    client.error(message)
                    print(e)

            if result is None:
                client.log(iot.LOGINFO, "Downloading")
                result = client.file_download(file_name, file_path, \
                                              blocking=blocking, timeout=timeout, \
                                              file_global=file_global)
                if result != iot.STATUS_SUCCESS:
                    message = iot.status_string(result)

        else:
            result = iot.STATUS_BAD_PARAMETER
            message = "No file name or destination given"

    if result == iot.STATUS_SUCCESS:
        cmd = "./provision_gg"
        output = {}
        try:
            p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
            out, err = p.communicate()
            i = 0
            for line in out.split(os.linesep):
                i = i + 1
                output["%03d" % i] = line
        except Exception as e:
            print("Error in run_cmd: %s" % e)
        return (iot.STATUS_SUCCESS, "", output)

    return (result, message)
def file_upload(client, params, user_data):
    """
    Callback for the "file_upload" method which uploads a file from the
    cloud to the local system. Wildcards in the file name are supported.
    """
    file_name = None
    file_path = None
    result = None
    if params:
        file_name = params.get("file_name")
        file_path = params.get("file_path")

        if file_name and not file_path:
            file_path = abspath(os.path.join(user_data[0], "upload",
                                             file_name))
        if file_path and not file_name:
            file_name = os.path.basename(file_path)
        if not file_name and not file_path:
            file_path = abspath(os.path.join(user_data[0], "upload"))
            file_name = "upload"
            if user_data[2]:
                file_name = (file_path + ".tar").replace("/", "")
                with tarfile.open((file_path + os.sep + file_name),
                                  "w") as tar:
                    for fn in os.listdir(file_path):
                        tar.add((file_path + os.sep + fn), arcname=fn)
                file_path = abspath(os.path.join(file_path, file_name))
        if file_path.startswith('~'):
            result = iot.STATUS_BAD_PARAMETER
            message = "Paths cannot use '~' to reference a home directory"
        elif not os.path.isabs(file_path):
            file_path = abspath(os.path.join(user_data[0], "upload",
                                             file_path))

        file_global = params.get("use_global_store", False)

    if result is None:
        if file_name and file_path:
            client.log(iot.LOGINFO, "Uploading {}".format(file_name))
            result = client.file_upload(file_path, upload_name=file_name, \
                                        blocking=True, timeout=240, \
                                        file_global=file_global)
            if result == iot.STATUS_SUCCESS:
                message = ""
                if ".tar" in file_name:
                    os.remove(file_path)
                if user_data[1] and "upload" in file_path:
                    try:
                        if ".tar" in file_name:
                            base = os.path.dirname(file_path)
                            for fn in os.listdir(base):
                                os.remove(base + os.sep + fn)
                        elif file_name == "upload":
                            for fn in os.listdir(file_path):
                                os.remove(file_path + os.sep + fn)
                        else:
                            os.remove(file_path)

                    except (OSError, IOError) as err:
                        error = str(err)
                        print(error + ". Unable to remove file.")
            else:
                message = iot.status_string(result)
        else:
            result = iot.STATUS_BAD_PARAMETER
            message = "No file name or location given"

    return (result, message)