Beispiel #1
0
    def _flash_image(self, file_name_no_extension):
        """
        Flash the new bootloader and image

        Args:
            file_name_no_extension (str):
                Image name without the extension (eg. edison-image.ext4 ->
                    edison-image)

        Returns:
            True

        Raises:
            errors.aft.AFTDeviceError if flashing fails
        """
        self._power_cycle()

        try:
            self._flash_partitions(file_name_no_extension)
        except errors.AFTPotentiallyBrokenBootloader as err:
            # if the bootloader is broken, the device is bricked until it is
            # recovered through recovery flashing.

            logger.critical("Bootloader might be broken " +
                            "(Note: This could be a false positive)")
            raise errors.AFTDeviceError(
                "Bootloader might be broken " +
                "(Note: This could be a false positive)")

        return True
Beispiel #2
0
    def _wait_for_device(self, timeout=15):
        """
        Wait until the testing harness detects the Edison after boot

        Args:
            timeout (integer): Timeout for the detection process

        Returns:
            None

        Raises:
            aft.errors.AFTDeviceError on timeout
        """
        start = time.time()
        while time.time() - start < timeout:
            output = subprocess32.check_output(
                ["dfu-util", "-l", "-d", self._EDISON_DEV_ID])
            output_lines = output.decode().split("\n")

            fitting_lines = [
                line for line in output_lines
                if 'path="' + self._usb_path + '"' in line
            ]

            if fitting_lines:
                return
            else:
                continue

        err_str = "Could not find the device in DFU-mode in " + str(timeout) + \
            " seconds."
        logger.critical(err_str)
        raise errors.AFTDeviceError(err_str)
Beispiel #3
0
 def _deploy_file(self, payload, user, timeout, device):
     """
     Deploys a file to the target device.
     """
     #  Test for presence of the file
     full_path_to_payload = os.path.join(self._TEST_DATA_PATH, payload)
     if not os.path.isfile(full_path_to_payload):
         self.output = "Error: media file \"{0}\" not found.".\
             format(full_path_to_payload)
         return False
     #  Push the file to the device
     self.output = device.push(source=full_path_to_payload,
                               destination=self._DUT_TMP,
                               user=user)
     if self.output != None:
         logger.critical("Couldn't copy " + str(full_path_to_payload) + " to " +
                          str(self._DUT_TMP) + ".\n" + str(self.output)
                          .format(full_path_to_payload, self._DUT_TMP,
                                  self.output))
         return False
     self.output = device.execute(
         environment=self._MEDIA_ENV,
         command=('chown', '-R', self.user,
                  os.path.join(self._DUT_TMP, payload)),
         user="******", timeout=timeout)
     return True
Beispiel #4
0
    def _wait_for_device(self, timeout=15):
        """
        Wait until the testing harness detects the Edison after boot

        Args:
            timeout (integer): Timeout for the detection process

        Returns:
            None

        Raises:
            aft.errors.AFTDeviceError on timeout
        """
        start = time.time()
        while time.time() - start < timeout:
            output = subprocess32.check_output(
                ["dfu-util", "-l", "-d", self._EDISON_DEV_ID])
            output_lines = output.split("\n")

            fitting_lines = [
                line for line in output_lines
                if 'path="' + self._usb_path + '"' in line]

            if fitting_lines:
                return
            else:
                continue

        err_str = "Could not find the device in DFU-mode in " + str(timeout) + \
            " seconds."
        logger.critical(err_str)
        raise errors.AFTDeviceError(err_str)
Beispiel #5
0
    def _enter_mode(self, target, keystrokes):
        """
        Try to put the device into the specified mode.
        Args:
            keystrokes (string): Path to keystrokes file for booting
            target (string): Boot target: 'test_mode' or 'service_mode'
        Raises:
            aft.errors.AFTDeviceError if device fails to enter the mode or if
            keyboard emulator fails to connect
        """
        if not (target == "test_mode" or target == "service_mode"):
            raise errors.AFTDeviceError(
                "Bad argument: target=" + target +
                " for pcdevice.py: _enter_mode function")

        # Sometimes booting to a mode fails.
        logger.info("Trying to enter " + target + " up to " +
                    str(self._RETRY_ATTEMPTS) + " times.")

        for _ in range(self._RETRY_ATTEMPTS):
            try:
                self._power_cycle()

                if self.kb_emulator:
                    logger.info("Using " + type(self.kb_emulator).__name__ +
                                " to send keyboard sequence " + keystrokes)

                    self.kb_emulator.send_keystrokes(keystrokes)

                else:
                    logger.warning(
                        "No keyboard emulator defined for the device")

                ip_address = self._wait_for_responsive_ip()

                if ip_address:
                    if target == "test_mode" and not \
                      self._verify_mode(self._service_mode_name):
                        logger.info("Correctly booted target image")
                        return
                    if target == "service_mode" and \
                      self._verify_mode(self._service_mode_name):
                        logger.info("Correctly booted support image")
                        return
                else:
                    logger.warning("Failed entering " + target + ".")

            except KeyboardInterrupt:
                raise

            except:
                _err = sys.exc_info()
                logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1]))

        logger.critical("Unable to get the device in mode " + target)

        raise errors.AFTDeviceError("Could not set the device in mode " +
                                    target)
Beispiel #6
0
    def _enter_mode(self, target, keystrokes):
        """
        Try to put the device into the specified mode.
        Args:
            keystrokes (string): Path to keystrokes file for booting
            target (string): Boot target: 'test_mode' or 'service_mode'
        Raises:
            aft.errors.AFTDeviceError if device fails to enter the mode or if
            keyboard emulator fails to connect
        """
        if not (target=="test_mode" or target=="service_mode"):
            raise errors.AFTDeviceError("Bad argument: target=" + target +
            " for pcdevice.py: _enter_mode function")

        # Sometimes booting to a mode fails.
        logger.info("Trying to enter " + target + " up to " +
                    str(self._RETRY_ATTEMPTS) + " times.")

        for _ in range(self._RETRY_ATTEMPTS):
            try:
                self._power_cycle()

                if self.kb_emulator:
                    logger.info("Using " + type(self.kb_emulator).__name__ +
                                " to send keyboard sequence " + keystrokes)

                    self.kb_emulator.send_keystrokes(keystrokes)

                else:
                    logger.warning("No keyboard emulator defined for the device")

                ip_address = self._wait_for_responsive_ip()

                if ip_address:
                    if target == "test_mode" and not \
                      self._verify_mode(self._service_mode_name):
                        logger.info("Correctly booted target image")
                        return
                    if target == "service_mode" and \
                      self._verify_mode(self._service_mode_name):
                        logger.info("Correctly booted support image")
                        return
                else:
                    logger.warning("Failed entering " + target + ".")

            except KeyboardInterrupt:
                raise

            except:
                _err = sys.exc_info()
                logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1]))

        logger.critical(
            "Unable to get the device in mode " + target)

        raise errors.AFTDeviceError(
            "Could not set the device in mode " + target)
Beispiel #7
0
def log_subprocess32_error_and_abort(err):
    """
    Log subprocess32 error cleanly and abort

    Args:
        err (subprocess32.CalledProcessError): The exception
    """
    logger.critical(str(err.cmd) + " failed with error code: " +
                     str(err.returncode) + " and output: " + str(err.output))
    logger.critical("Aborting")
    sys.exit(1)
Beispiel #8
0
    def _enter_mode(self, mode):
        """
        Try to put the device into the specified mode.

        Args:
            mode (Dictionary):
                Dictionary that contains the mode specific information

        Returns:
            None

        Raises:
            aft.errors.AFTDeviceError if device fails to enter the mode or if
            keyboard emulator fails to connect
        """
        # Sometimes booting to a mode fails.
        logger.info("Trying to enter " + mode["name"] + " mode up to " +
                    str(self._RETRY_ATTEMPTS) + " times.")

        for _ in range(self._RETRY_ATTEMPTS):
            try:
                self._power_cycle()

                if self.kb_emulator:
                    logger.info("Using " + type(self.kb_emulator).__name__ +
                                " to send keyboard sequence " +
                                mode["sequence"])

                    self.kb_emulator.send_keystrokes(mode["sequence"])

                else:
                    logger.warning(
                        "No keyboard emulator defined for the device")

                ip_address = self._wait_for_responsive_ip()

                if ip_address:
                    if self._verify_mode(mode["name"]):
                        return
                else:
                    logger.warning("Failed entering " + mode["name"] +
                                   " mode.")

            except KeyboardInterrupt:
                raise

            except:
                _err = sys.exc_info()
                logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1]))

        logger.critical("Unable to get the device in mode " + mode["name"])

        raise errors.AFTDeviceError("Could not set the device in mode " +
                                    mode["name"])
Beispiel #9
0
def log_subprocess32_error_and_abort(err):
    """
    Log subprocess32 error cleanly and abort

    Args:
        err (subprocess32.CalledProcessError): The exception
    """
    logger.critical(
        str(err.cmd) + " failed with error code: " + str(err.returncode) +
        " and output: " + str(err.output))
    logger.critical("Aborting")
    sys.exit(1)
Beispiel #10
0
    def recovery_flash(self):
        """
        Execute the flashing of device-side DFU-tools

        Aborts if the flashing fails

        Note that only one Edison should be powered on when doing the recovery
        flashing

        Returns:
            None
        """
        logger.info("Recovery flashing.")
        try:
            # This can cause race condition if multiple devices are booted at
            # the same time!
            attempts = 0


            xfstk_parameters = ["xfstk-dldr-solo",
                                "--gpflags", "0x80000007",
                                "--osimage", os.path.join(
                                    self._MODULE_DATA_PATH,
                                    "u-boot-edison.img"),
                                "--fwdnx", os.path.join(
                                    self._MODULE_DATA_PATH,
                                    "edison_dnx_fwr.bin"),
                                "--fwimage", os.path.join(
                                    self._MODULE_DATA_PATH,
                                    "edison_ifwi-dbg-00.bin"),
                                "--osdnx", os.path.join(
                                    self._MODULE_DATA_PATH,
                                    "edison_dnx_osr.bin")]
            self._power_cycle()
            while subprocess32.call(xfstk_parameters) and attempts < 10:
                logger.info(
                    "Rebooting and trying recovery flashing again. "
                    + str(attempts))
                self._power_cycle()
                time.sleep(random.randint(10, 30))
                attempts += 1

        except subprocess32.CalledProcessError as err:
            common.log_subprocess32_error_and_abort(err)
        except OSError as err:
            logger.critical("Failed recovery flashing, errno = " +
                             str(err.errno) + ". Is the xFSTK tool installed?")
            sys.exit(1)
Beispiel #11
0
 def gst_playback(self, device, timeout=_DEFAULT_GST_PLAYBACK_TIMEOUT):
     """
     Attempts to play a media file through the gstreamer interface.
     """
     media_file = self.parameters
     if not self._deploy_file(payload=media_file, user=self.user,
                              timeout=timeout, device=device):
         logger.critical("Failed to deploy file: " + str(media_file))
         return False
     # Play the media with gstreamer
     self.output = device.execute(
         environment=self._MEDIA_ENV,
         command=('sudo', '-u', self.user, 'gst-play-1.0',
                  os.path.join(self._DUT_TMP, media_file)),
         user="******", timeout=timeout)
     return self._check_for_success()
Beispiel #12
0
    def _enter_mode(self, mode):
        """
        Try to put the device into the specified mode.

        Args:
            mode (Dictionary):
                Dictionary that contains the mode specific information

        Returns:
            None

        Raises:
            aft.errors.AFTDeviceError if device fails to enter the mode or if
            PEM fails to connect

        """
        # Sometimes booting to a mode fails.

        logger.info(
            "Trying to enter " + mode["name"] + " mode up to " +
            str(self._RETRY_ATTEMPTS) + " times.")

        for _ in range(self._RETRY_ATTEMPTS):
            self._power_cycle()

            logger.info(
                "Executing PEM with keyboard sequence " + mode["sequence"])

            self._send_PEM_keystrokes(mode["sequence"])

            ip_address = self._wait_for_responsive_ip()

            if ip_address:
                if self._verify_mode(mode["name"]):
                    return
            else:
                logger.warning("Failed entering " + mode["name"] + " mode.")

        logger.critical(
            "Unable to get device " + self.dev_id + " in mode " +
            mode["name"])

        raise errors.AFTDeviceError(
            "Could not set the device in mode " + mode["name"])
Beispiel #13
0
    def _flash_image(self, file_name_no_extension):
        """
        Flash the new bootloader and image

        Args:
            file_name_no_extension (str):
                Image name without the extension (eg. edison-image.ext4 ->
                    edison-image)

        Returns:
            True

        Raises:
            errors.aft.AFTDeviceError if flashing fails
        """
        self._power_cycle()

        try:
            self._flash_partitions(file_name_no_extension)
        except errors.AFTPotentiallyBrokenBootloader as err:
            # if the bootloader is broken, the device is bricked until it is
            # recovered through recovery flashing. As only one device can be
            # powered on during recovery flashing, we just blacklist the device
            # and recover it later

            logger.critical(
                "Bootloader might be broken - blacklisting the " +
                "device as a precaution (Note: This could be a false positive)"
            )

            common.blacklist_device(
                self._configuration["id"], self._configuration["name"],
                "Bootloader might be broken - recovery flashing " +
                "will be performed as a precaution (Note: This could be a " +
                "false positive")

            self._recover_edison()

            raise errors.AFTDeviceError(
                "Bootloader might be broken - blacklisting the " +
                "device as a precaution (Note: This could be a false positive)"
            )

        return True
Beispiel #14
0
    def _flash_image(self, file_name_no_extension):
        """
        Flash the new bootloader and image

        Args:
            file_name_no_extension (str):
                Image name without the extension (eg. edison-image.ext4 ->
                    edison-image)

        Returns:
            True

        Raises:
            errors.aft.AFTDeviceError if flashing fails
        """
        self._power_cycle()

        try:
            self._flash_partitions(file_name_no_extension)
        except errors.AFTPotentiallyBrokenBootloader as err:
            # if the bootloader is broken, the device is bricked until it is
            # recovered through recovery flashing. As only one device can be
            # powered on during recovery flashing, we just blacklist the device
            # and recover it later

            logger.critical(
                "Bootloader might be broken - blacklisting the " +
                "device as a precaution (Note: This could be a false positive)")

            common.blacklist_device(
                self._configuration["id"],
                self._configuration["name"],
                "Bootloader might be broken - recovery flashing " +
                "will be performed as a precaution (Note: This could be a " +
                "false positive")

            self._recover_edison()

            raise errors.AFTDeviceError(
                "Bootloader might be broken - blacklisting the " +
                "device as a precaution (Note: This could be a false positive)")

        return True
Beispiel #15
0
    def recovery_flash(self):
        """
        Execute the flashing of device-side DFU-tools

        Aborts if the flashing fails

        Note that only one Edison should be powered on when doing the recovery
        flashing

        Returns:
            None
        """
        logger.info("Recovery flashing.")
        try:
            # This can cause race condition if multiple devices are booted at
            # the same time!
            attempts = 0

            xfstk_parameters = [
                "xfstk-dldr-solo", "--gpflags", "0x80000007", "--osimage",
                os.path.join(self._MODULE_DATA_PATH,
                             "u-boot-edison.img"), "--fwdnx",
                os.path.join(self._MODULE_DATA_PATH,
                             "edison_dnx_fwr.bin"), "--fwimage",
                os.path.join(self._MODULE_DATA_PATH, "edison_ifwi-dbg-00.bin"),
                "--osdnx",
                os.path.join(self._MODULE_DATA_PATH, "edison_dnx_osr.bin")
            ]
            self._power_cycle()
            while subprocess32.call(xfstk_parameters) and attempts < 10:
                logger.info("Rebooting and trying recovery flashing again. " +
                            str(attempts))
                self._power_cycle()
                time.sleep(random.randint(10, 30))
                attempts += 1

        except subprocess32.CalledProcessError as err:
            common.log_subprocess32_error_and_abort(err)
        except OSError as err:
            logger.critical("Failed recovery flashing, errno = " +
                            str(err.errno) + ". Is the xFSTK tool installed?")
            sys.exit(1)
Beispiel #16
0
    def _enter_mode(self, mode):
        """
        Try to put the device into the specified mode.

        Args:
            mode (Dictionary):
                Dictionary that contains the mode specific information

        Returns:
            None

        Raises:
            aft.errors.AFTDeviceError if device fails to enter the mode or if
            PEM fails to connect

        """
        # Sometimes booting to a mode fails.

        logger.info("Trying to enter " + mode["name"] + " mode up to " +
                    str(self._RETRY_ATTEMPTS) + " times.")

        for _ in range(self._RETRY_ATTEMPTS):
            self._power_cycle()

            logger.info("Executing PEM with keyboard sequence " +
                        mode["sequence"])

            self._send_PEM_keystrokes(mode["sequence"])

            ip_address = self._wait_for_responsive_ip()

            if ip_address:
                if self._verify_mode(mode["name"]):
                    return
            else:
                logger.warning("Failed entering " + mode["name"] + " mode.")

        logger.critical("Unable to get device " + self.dev_id + " in mode " +
                        mode["name"])

        raise errors.AFTDeviceError("Could not set the device in mode " +
                                    mode["name"])
Beispiel #17
0
    def _do_reserve(self, devices, name, timeout):
        """
        Try to reserve and lock a device from devices list.
        """
        if len(devices) == 0:
            raise errors.AFTConfigurationError(
                "No device configurations when reserving " + name +
                " - check that given machine type or name is correct ")

        start = time.time()
        while time.time() - start < timeout:
            for device in devices:
                logger.info("Attempting to acquire " + device.name)
                try:
                    # This is a non-atomic operation which may cause trouble
                    # Using a locking database system could be a viable fix.
                    lockfile = os.fdopen(
                        os.open(
                            os.path.join(config.LOCK_FILE, "daft_dut_lock"),
                            os.O_WRONLY | os.O_CREAT, 0o660), "w")
                    fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)

                    logger.info("Device acquired.")

                    self._lockfiles.append(("daft_dut_lock", lockfile))

                    atexit.register(self.release, device)
                    return device
                except IOError as err:
                    if err.errno in {errno.EACCES, errno.EAGAIN}:
                        logger.info("Device busy.")
                    else:
                        logger.critical("Cannot obtain lock file.")
                        sys.exit(-1)
            logger.info(
                "All devices busy ... waiting 10 seconds and trying again.")
            time.sleep(10)
        raise errors.AFTTimeoutError("Could not reserve " + name + " in " +
                                     str(timeout) + " seconds.")
Beispiel #18
0
    def _do_reserve(self, devices, name, timeout):
        """
        Try to reserve and lock a device from devices list.
        """
        if len(devices) == 0:
            raise errors.AFTConfigurationError(
                "No device configurations when reserving " + name +
                " - check that given machine type or name is correct")

        start = time.time()
        while time.time() - start < timeout:
            for device in devices:
                logger.info("Attempting to acquire " + device.name)
                try:
                    # This is a non-atomic operation which may cause trouble
                    # Using a locking database system could be a viable fix.
                    lockfile = os.fdopen(os.open(os.path.join(config.LOCK_FILE,
                                                                    "aft_" + device.dev_id),
                                                       os.O_WRONLY | os.O_CREAT, 0660), "w")
                    fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)

                    logger.info("Device acquired.")

                    self._lockfiles.append((device.dev_id, lockfile))


                    atexit.register(self.release, device)
                    return device
                except IOError as err:
                    if err.errno in {errno.EACCES, errno.EAGAIN}:
                        logger.info("Device busy.")
                    else:
                        logger.critical("Cannot obtain lock file.")
                        sys.exit(-1)
            logger.info("All devices busy ... waiting 10 seconds and trying again.")
            time.sleep(10)
        raise errors.AFTTimeoutError("Could not reserve " + name +
                                     " in " + str(timeout) + " seconds.")
Beispiel #19
0
    def _wait_until_ssh_visible(self, timeout=180):
        """
        Wait until the DUT answers to ssh

        Args:
            timeout (integer): The timeout value in seconds
        Returns:
            None

        Raises:
            aft.errors.AFTConnectionError on timeout
        """
        start = time.time()
        while time.time() - start < timeout:
            if ssh.test_ssh_connectivity(self.get_ip()):
                return
        logger.critical("Failed to establish ssh-connection in " +
                        str(timeout) +
                        " seconds after enabling the network interface.")

        raise errors.AFTConnectionError(
            "Failed to establish ssh-connection in " + str(timeout) +
            " seconds after enabling the network interface.")
Beispiel #20
0
    def _wait_until_ssh_visible(self, timeout=180):
        """
        Wait until the DUT answers to ssh

        Args:
            timeout (integer): The timeout value in seconds
        Returns:
            None

        Raises:
            aft.errors.AFTConnectionError on timeout

        """
        start = time.time()
        while time.time() - start < timeout:
            if ssh.test_ssh_connectivity(self.get_ip()):
                return
        logger.critical(
            "Failed to establish ssh-connection in " + str(timeout) +
            " seconds after enabling the network interface.")

        raise errors.AFTConnectionError(
            "Failed to establish ssh-connection in " + str(timeout) +
            " seconds after enabling the network interface.")
Beispiel #21
0
    def _add_usb_networking(self):
        """
        Inject USB-networking service files

        Returns:
            None
        """
        logger.info("Injecting USB-networking service.")
        source_file = os.path.join(self._MODULE_DATA_PATH,
                                   self._DUT_USB_SERVICE_FILE)
        target_file = os.path.join(os.curdir, self._LOCAL_MOUNT_DIR,
                                   self._DUT_USB_SERVICE_LOCATION,
                                   self._DUT_USB_SERVICE_FILE)
        shutil.copy(source_file, target_file)

        # Copy UID and GID
        source_stat = os.stat(source_file)
        os.chown(target_file, source_stat.st_uid, source_stat.st_gid)

        # Set symlink to start the service at the end of boot
        try:
            os.symlink(
                os.path.join(os.sep, self._DUT_USB_SERVICE_LOCATION,
                             self._DUT_USB_SERVICE_FILE),
                os.path.join(os.curdir, self._LOCAL_MOUNT_DIR,
                             self._DUT_USB_SERVICE_LOCATION,
                             "multi-user.target.wants",
                             self._DUT_USB_SERVICE_FILE))
        except OSError as err:
            if err.errno == 17:
                logger.critical(
                    "The image file was not replaced. USB-networking service "
                    + "already exists.")
                print("The image file was not replaced! The symlink for "
                      "usb-networking service already exists.")

                # print "Aborting."
                # sys.exit(1)
            else:
                raise err

        # Create the service configuration file
        config_directory = os.path.join(os.curdir, self._LOCAL_MOUNT_DIR,
                                        self._DUT_USB_SERVICE_CONFIG_DIR)
        common.make_directory(config_directory)
        config_file = os.path.join(config_directory,
                                   self._DUT_USB_SERVICE_CONFIG_FILE)

        # Service configuration options
        config_stream = open(config_file, 'w')
        config_options = [
            "Interface=usb0", "Address=" + self._dut_ip, "MaskSize=30",
            "Broadcast=" + self._broadcast_ip, "Gateway=" + self._gateway_ip
        ]
        for line in config_options:
            config_stream.write(line + "\n")
        config_stream.close()

        # Ignore usb0 in connman
        original_connman = os.path.join(os.curdir, self._LOCAL_MOUNT_DIR,
                                        self._DUT_CONNMAN_SERVICE_FILE)
        output_file = os.path.join(os.curdir, self._LOCAL_MOUNT_DIR,
                                   self._DUT_CONNMAN_SERVICE_FILE + "_temp")
        connman_in = open(original_connman, "r")
        connman_out = open(output_file, "w")
        for line in connman_in:
            if "ExecStart=/usr/sbin/connmand" in line:
                line = line[0:-1] + " -I usb0 \n"
            connman_out.write(line)
        connman_in.close()
        connman_out.close()
        shutil.copy(output_file, original_connman)
        os.remove(output_file)
Beispiel #22
0
    def _add_usb_networking(self):
        """
        Inject USB-networking service files

        Returns:
            None
        """
        logger.info("Injecting USB-networking service.")
        source_file = os.path.join(self._MODULE_DATA_PATH,
                                   self._DUT_USB_SERVICE_FILE)
        target_file = os.path.join(os.curdir,
                                   self._LOCAL_MOUNT_DIR,
                                   self._DUT_USB_SERVICE_LOCATION,
                                   self._DUT_USB_SERVICE_FILE)
        shutil.copy(source_file, target_file)

        # Copy UID and GID
        source_stat = os.stat(source_file)
        os.chown(target_file, source_stat.st_uid, source_stat.st_gid)

        # Set symlink to start the service at the end of boot
        try:
            os.symlink(os.path.join(os.sep,
                                    self._DUT_USB_SERVICE_LOCATION,
                                    self._DUT_USB_SERVICE_FILE),
                       os.path.join(os.curdir,
                                    self._LOCAL_MOUNT_DIR,
                                    self._DUT_USB_SERVICE_LOCATION,
                                    "multi-user.target.wants",
                                    self._DUT_USB_SERVICE_FILE))
        except OSError as err:
            if err.errno == 17:
                logger.critical(
                    "The image file was not replaced. USB-networking service " +
                     "already exists.")
                print("The image file was not replaced! The symlink for "
                    "usb-networking service already exists.")

                # print "Aborting."
                # sys.exit(1)
            else:
                raise err

        # Create the service configuration file
        config_directory = os.path.join(os.curdir,
                                        self._LOCAL_MOUNT_DIR,
                                        self._DUT_USB_SERVICE_CONFIG_DIR)
        common.make_directory(config_directory)
        config_file = os.path.join(config_directory,
                                   self._DUT_USB_SERVICE_CONFIG_FILE)

        # Service configuration options
        config_stream = open(config_file, 'w')
        config_options = ["Interface=usb0",
                          "Address=" + self._dut_ip,
                          "MaskSize=30",
                          "Broadcast=" + self._broadcast_ip,
                          "Gateway=" + self._gateway_ip]
        for line in config_options:
            config_stream.write(line + "\n")
        config_stream.close()

        # Ignore usb0 in connman
        original_connman = os.path.join(os.curdir,
                                        self._LOCAL_MOUNT_DIR,
                                        self._DUT_CONNMAN_SERVICE_FILE)
        output_file = os.path.join(os.curdir,
                                   self._LOCAL_MOUNT_DIR,
                                   self._DUT_CONNMAN_SERVICE_FILE + "_temp")
        connman_in = open(original_connman, "r")
        connman_out = open(output_file, "w")
        for line in connman_in:
            if "ExecStart=/usr/sbin/connmand" in line:
                line = line[0:-1] + " -I usb0 \n"
            connman_out.write(line)
        connman_in.close()
        connman_out.close()
        shutil.copy(output_file, original_connman)
        os.remove(output_file)