Exemplo n.º 1
0
    def test_mdadm_stop_retry_exhausted(self, mock_sleep):
        device = "/dev/md/37"
        retries = 60
        self._set_sys_path(device)
        self.mock_util_load_file.side_effect = iter([
            "resync", "max",
            "proc/mdstat output",
        ] * retries)
        self.mock_util_subp.side_effect = iter([
            util.ProcessExecutionError(),
        ] * retries)
        # sometimes we fail to modify sysfs attrs
        self.mock_util_write_file.side_effect = iter([
            "", IOError()] * retries)

        with self.assertRaises(OSError):
            mdadm.mdadm_stop(device)

        expected_calls = [
            call(["mdadm", "--manage", "--stop", device], capture=True),
        ] * retries
        self.mock_util_subp.assert_has_calls(expected_calls)

        expected_reads = [
            call(self.sys_path + '/sync_action'),
            call(self.sys_path + '/sync_max'),
            call('/proc/mdstat'),
        ] * retries
        self.mock_util_load_file.assert_has_calls(expected_reads)

        expected_writes = [
            call(self.sys_path + '/sync_action', content='idle'),
            call(self.sys_path + '/sync_max', content='0'),
        ] * retries
        self.mock_util_write_file.assert_has_calls(expected_writes)
Exemplo n.º 2
0
    def test_disconnect_target_disk_raises_runtime_error(self, mock_logout):
        """Test iscsi raises RuntimeError if we fail to logout"""
        sessions = [
            'curtin-53ab23ff-a887-449a-80a8-288151208091',
        ]
        connection = '10.245.168.20,16395,1'
        self._setup_nodes(sessions, connection)
        self.mock_iscsi_sessions.return_value = "\n".join(sessions)
        mock_logout.side_effect = util.ProcessExecutionError()

        with self.assertRaises(RuntimeError):
            iscsi.disconnect_target_disks(self.target_path)

        expected_calls = []
        for session in sessions:
            (host, port, _) = connection.split(',')
            disconnect = self._fmt_disconnect(session, "%s:%s" % (host, port))
            calls = [
                mock.call(['sync']),
                mock.call(disconnect, capture=True, log_captured=True),
                mock.call(['udevadm', 'settle']),
            ]
            expected_calls.extend(calls)

        self.mock_subp.assert_has_calls([], any_order=True)
Exemplo n.º 3
0
    def test_export_armour_missingkey(self, mock_subp):
        key = 'DEADBEEF'
        mock_subp.side_effect = iter([util.ProcessExecutionError()])

        expected_armour = gpg.export_armour(key)
        mock_subp.assert_called_with(["gpg", "--export", "--armour", key],
                                     capture=True)
        self.assertEqual(None, expected_armour)
Exemplo n.º 4
0
 def test_info_returns_partial_dictionary(self):
     """dasdinfo returns partial dictionary on error."""
     device_id = random_device_id()
     self.m_subp.side_effect = (
         util.ProcessExecutionError(stdout=self.info_no_serial,
                                    stderr=self.random_string(),
                                    exit_code=random.randint(1, 255),
                                    cmd=self.random_string()))
     expected = util.load_shell_content(self.info_no_serial)
     self.assertDictEqual(expected, dasd.dasdinfo(device_id))
Exemplo n.º 5
0
 def test_info_raise_error_if_strict(self):
     """dasdinfo raises ProcessEdecutionError if strict is True."""
     device_id = random_device_id()
     self.m_subp.side_effect = (
         util.ProcessExecutionError(stdout=self.random_string(),
                                    stderr=self.random_string(),
                                    exit_code=random.randint(1, 255),
                                    cmd=self.random_string()))
     with self.assertRaises(util.ProcessExecutionError):
         dasd.dasdinfo(device_id, strict=True)
Exemplo n.º 6
0
 def test_info_raises_on_failure(self):
     """dasdinfo raises if the process invocation fails."""
     device_id = random_device_id()
     expected_stdout = self.random_string()
     expected_stderr = self.random_string()
     self.m_subp.side_effect = (util.ProcessExecutionError(
         stdout=expected_stdout,
         stderr=expected_stderr,
         exit_code=random.randint(1, 255),
         cmd=self.random_string()))
     with self.assertRaises(util.ProcessExecutionError):
         dasd.dasdinfo(device_id)
Exemplo n.º 7
0
 def test_sfdisk_info_returns_empty_on_subp_error(self):
     """verify sfdisk_info returns empty dict on subp errors."""
     self.m_subp.side_effect = (util.ProcessExecutionError(
         stdout="",
         stderr="sfdisk: cannot open /dev/vdb: Permission denied",
         exit_code=1))
     self.assertEqual({}, block.sfdisk_info(self.device))
     self.assertEqual([mock.call(self.device)],
                      self.m_get_blockdev_for_partition.call_args_list)
     self.assertEqual(
         [mock.call(['sfdisk', '--json', self.disk], capture=True)],
         self.m_subp.call_args_list)
     self.assertEqual([], self.m_load_json.call_args_list)
Exemplo n.º 8
0
 def test_info_returns_rawoutput_on_partial_discovery(self):
     """dasdinfo returns stdout, stderr on error if rawoutput is True."""
     device_id = random_device_id()
     expected_stdout = self.random_string()
     expected_stderr = self.random_string()
     self.m_subp.side_effect = (
         util.ProcessExecutionError(stdout=expected_stdout,
                                    stderr=expected_stderr,
                                    exit_code=random.randint(1, 255),
                                    cmd=self.random_string()))
     (stdout, stderr) = dasd.dasdinfo(device_id, rawoutput=True)
     self.assertEqual(expected_stdout, stdout)
     self.assertEqual(expected_stderr, stderr)
Exemplo n.º 9
0
    def run(self):
        for cmdname in sorted(self.commands.keys()):
            cmd = self.commands[cmdname]
            if not cmd:
                continue
            cur_res = events.ReportEventStack(
                name=cmdname, description="running '%s'" % ' '.join(cmd),
                parent=self.reportstack, level="DEBUG")

            env = self.env.copy()
            env['CURTIN_REPORTSTACK'] = cur_res.fullname

            shell = not isinstance(cmd, list)
            with util.LogTimer(LOG.debug, cmdname):
                with cur_res:
                    try:
                        sp = subprocess.Popen(
                            cmd, stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT,
                            env=env, shell=shell)
                    except OSError as e:
                        LOG.warn("%s command failed", cmdname)
                        raise util.ProcessExecutionError(cmd=cmd, reason=e)

                    output = b""
                    while True:
                        data = sp.stdout.read(1)
                        if not data and sp.poll() is not None:
                            break
                        self.write(data)
                        output += data

                    rc = sp.returncode
                    if rc != 0:
                        LOG.warn("%s command failed", cmdname)
                        raise util.ProcessExecutionError(
                            stdout=output, stderr="",
                            exit_code=rc, cmd=cmd)
Exemplo n.º 10
0
def _extract_root_layered_fsimage(image_stack, target):
    mp_base = tempfile.mkdtemp()
    mps = []
    try:
        # Create a mount point for each image file and mount the image
        try:
            for img in image_stack:
                mp = os.path.join(mp_base, os.path.basename(img) + ".dir")
                os.mkdir(mp)
                util.subp(['mount', '-o', 'loop,ro', img, mp], capture=True)
                mps.insert(0, mp)
        except util.ProcessExecutionError as e:
            LOG.error("Failed to mount '%s' for extraction: %s", img, e)
            raise e

        # Prepare
        if len(mps) == 1:
            root_dir = mps[0]
        else:
            # Multiple image files, merge them with an overlay and do the copy
            root_dir = os.path.join(mp_base, "root.dir")
            os.mkdir(root_dir)
            try:
                util.subp([
                    'mount', '-t', 'overlay', 'overlay', '-o',
                    'lowerdir=' + ':'.join(mps), root_dir
                ],
                          capture=True)
                mps.append(root_dir)
            except util.ProcessExecutionError as e:
                LOG.error("overlay mount to %s failed: %s", root_dir, e)
                raise e

        copy_to_target(root_dir, target)
    finally:
        umount_err_mps = []
        for mp in reversed(mps):
            try:
                util.subp(['umount', mp], capture=True)
            except util.ProcessExecutionError as e:
                LOG.error("can't unmount %s: %e", mp, e)
                umount_err_mps.append(mp)
        if umount_err_mps:
            raise util.ProcessExecutionError("Failed to umount: %s",
                                             ", ".join(umount_err_mps))
        shutil.rmtree(mp_base)
Exemplo n.º 11
0
    def test_mount_fstab_data_does_not_swallow_subp_exception(self, m_subp):
        """verify that subp exception gets raised.

        The implementation there could/should change to raise the
        ProcessExecutionError directly.  Currently raises a RuntimeError."""
        my_error = util.ProcessExecutionError(stdout="",
                                              stderr="BOOM",
                                              exit_code=4)
        m_subp.side_effect = my_error

        mp = self.tmp_path("my-mountpoint")
        with self.assertRaisesRegexp(RuntimeError, r"Mount failed.*"):
            block_meta.mount_fstab_data(block_meta.FstabData(
                device="/dev/disk1", path="/var"),
                                        target=mp)
        # dir should be created before call to subp failed.
        self.assertTrue(os.path.isdir(mp))
Exemplo n.º 12
0
    def test_recv_key_retry_works(self, mock_under_subp, mock_sleep):
        key = 'DEADBEEF'
        keyserver = 'keyserver.ubuntu.com'
        nr_calls = 2
        mock_under_subp.side_effect = iter([
            util.ProcessExecutionError(),  # 1
            ("", ""),
        ])

        gpg.recv_key(key, keyserver, retries=[1])

        print("_subp calls: %s" % mock_under_subp.call_args_list)
        print("sleep calls: %s" % mock_sleep.call_args_list)
        expected_calls = nr_calls * [
            call(["gpg", "--keyserver", keyserver, "--recv", key],
                 capture=True)]
        mock_under_subp.assert_has_calls(expected_calls)
        mock_sleep.assert_has_calls([call(1)])
Exemplo n.º 13
0
    def test_recv_key_retry_raises(self, mock_under_subp, mock_sleep):
        key = 'DEADBEEF'
        keyserver = 'keyserver.ubuntu.com'
        retries = (1, 2, 5, 10)
        nr_calls = 5
        mock_under_subp.side_effect = iter([
            util.ProcessExecutionError()] * nr_calls)

        with self.assertRaises(ValueError):
            gpg.recv_key(key, keyserver, retries=retries)

        print("_subp calls: %s" % mock_under_subp.call_args_list)
        print("sleep calls: %s" % mock_sleep.call_args_list)
        expected_calls = nr_calls * [
            call(["gpg", "--keyserver", keyserver, "--recv", key],
                 capture=True)]
        mock_under_subp.assert_has_calls(expected_calls)

        expected_calls = [call(1), call(2), call(5), call(10)]
        mock_sleep.assert_has_calls(expected_calls)
Exemplo n.º 14
0
    def test_mdadm_stop_retry_sysfs_write_fail(self, mock_sleep):
        device = "/dev/md126"
        self._set_sys_path(device)
        self.mock_util_load_file.side_effect = iter([
            "resync", "max",
            "proc/mdstat output",
            "idle", "0",
        ])
        self.mock_util_subp.side_effect = iter([
            util.ProcessExecutionError(),
            ("mdadm stopped %s" % device, ''),
        ])
        # sometimes we fail to modify sysfs attrs
        self.mock_util_write_file.side_effect = iter([
            "",         # write to sync_action OK
            IOError(),  # write to sync_max FAIL
        ])

        mdadm.mdadm_stop(device)

        expected_calls = [
            call(["mdadm", "--manage", "--stop", device], capture=True),
            call(["mdadm", "--manage", "--stop", device], capture=True)
        ]
        self.mock_util_subp.assert_has_calls(expected_calls)

        expected_reads = [
            call(self.sys_path + '/sync_action'),
            call(self.sys_path + '/sync_max'),
            call('/proc/mdstat'),
            call(self.sys_path + '/sync_action'),
            call(self.sys_path + '/sync_max'),
        ]
        self.mock_util_load_file.assert_has_calls(expected_reads)

        expected_writes = [
            call(self.sys_path + '/sync_action', content='idle'),
        ]
        self.mock_util_write_file.assert_has_calls(expected_writes)
Exemplo n.º 15
0
 def _raise_pexec_error(*args, **kwargs):
     raise util.ProcessExecutionError()
Exemplo n.º 16
0
 def test_udevadm_info_path_not_exists(self, m_subp):
     """ udevadm_info raises ProcessExecutionError for invalid path value"""
     mypath = self.random_string()
     m_subp.side_effect = util.ProcessExecutionError()
     with self.assertRaises(util.ProcessExecutionError):
         udevadm_info(mypath)
Exemplo n.º 17
0
 def doraise(*args, **kwargs):
     raise util.ProcessExecutionError("foo")
Exemplo n.º 18
0
 def test_zkey_supported_returns_false_zkey_error(self, m_kmod, m_subp):
     m_subp.side_effect = (util.ProcessExecutionError(
         stdout=self.random_string(),
         stderr=self.random_string(),
         exit_code=2))
     self.assertFalse(block.zkey_supported())
Exemplo n.º 19
0
 def test_check_vtoc_signature_returns_false_with_no_sig(self):
     self.m_subp.side_effect = iter(
         [util.ProcessExecutionError(stdout="", stderr="", exit_code=1)])
     self.assertFalse(block.check_vtoc_signature(self.blockdev))
Exemplo n.º 20
0
 def setUp(self):
     super(TestPartTableSignature, self).setUp()
     self.add_patch('curtin.util.subp', 'm_subp')
     self.m_subp.side_effect = iter(
         [util.ProcessExecutionError(stdout="", stderr="", exit_code=1)])
Exemplo n.º 21
0
 def test__returns_none_on_error(self):
     self.mock_subp.side_effect = util.ProcessExecutionError()
     self.assertIsNone(curthooks.get_flash_kernel_pkgs('arm64', False))
     self.mock_subp.assert_called_with(
         ['list-flash-kernel-packages'], capture=True)