def stale_pv(tmp_storage): dev_size = 1 * 1024**3 good_pv_name = tmp_storage.create_device(dev_size) stale_pv_name = tmp_storage.create_device(dev_size) vg_name = str(uuid.uuid4()) lvm.set_read_only(False) # Create VG with 2 PVs. lvm.createVG(vg_name, [good_pv_name, stale_pv_name], "initial-tag", 128) # Reload the cache. pvs = sorted(pv.name for pv in lvm.getAllPVs()) assert pvs == sorted([good_pv_name, stale_pv_name]) # Simulate removal of the second PV on another host, leaving stale PV in # the cache. commands.run([ "vgreduce", "--config", tmp_storage.lvm_config(), vg_name, stale_pv_name, ]) commands.run([ "pvremove", "--config", tmp_storage.lvm_config(), stale_pv_name, ]) # We still report both devies. pvs = sorted(pv.name for pv in lvm.getAllPVs()) assert pvs == sorted([good_pv_name, stale_pv_name]) return vg_name, good_pv_name, stale_pv_name
def webhookDelete(url): command = [_glusterEventsApi.cmd, "webhook-del", url] try: commands.run(command) except cmdutils.Error as e: raise ge.GlusterWebhookDeleteException(rc=e.rc, err=e.err) return True
def webhookSync(): command = [_glusterEventsApi.cmd, "sync"] try: commands.run(command) except cmdutils.Error as e: raise ge.GlusterWebhookSyncException(rc=e.rc, err=e.err) return True
def removeMapping(deviceName): if os.geteuid() != 0: return supervdsm.getProxy().devicemapper_removeMapping(deviceName) log.info("Removing device mapping %s", deviceName) cmd = [EXT_DMSETUP, "remove", deviceName] commands.run(cmd)
def zero_dm_device(): """ Create test device mapper mapping backed by zero target. Zero target is used for tests and it acts similarly to /dev/zero - writes are discarded and reads return nothing (binary zero). For now, the size of the device is fixed to 1 GiB (1 GiB = 2097152 * 512 B sectors). The tests using this fixture need to be run with the root privileges, as dmsetup utility requires root. """ device_name = str(uuid.uuid4()) cmd = [EXT_DMSETUP, "create", device_name, "--table", "0 2097152 zero"] try: commands.run(cmd) except cmdutils.Error as e: raise Error("Could not create mapping {!r}: {}".format(device_name, e)) try: yield device_name finally: # If the test didn't do the cleanup, remove the mapping. device_path = "{}{}".format(DMPATH_PREFIX, device_name) if os.path.exists(device_path): cmd = [EXT_DMSETUP, "remove", device_name] try: commands.run(cmd) except cmdutils.Error as e: raise Error("Could not remove mapping {!r}: {}".format( device_name, e))
def stale_vg(tmp_storage): dev_size = 1 * 1024**3 dev1 = tmp_storage.create_device(dev_size) dev2 = tmp_storage.create_device(dev_size) good_vg_name = str(uuid.uuid4()) stale_vg_name = str(uuid.uuid4()) lvm.set_read_only(False) # Create 1 VGs lvm.createVG(good_vg_name, [dev1], "initial-tag", 128) lvm.createVG(stale_vg_name, [dev2], "initial-tag", 128) # Reload the cache. vgs = sorted(vg.name for vg in lvm.getAllVGs()) assert vgs == sorted([good_vg_name, stale_vg_name]) # Simulate removal of the second VG on another host, leaving stale VG in # the cache. commands.run([ "vgremove", "--config", tmp_storage.lvm_config(), stale_vg_name, ]) # We still report both vgs. vgs = sorted(vg.name for vg in lvm.getAllVGs()) assert vgs == sorted([good_vg_name, stale_vg_name]) return good_vg_name, stale_vg_name
def test_protect_log_passwords(self, monkeypatch): monkeypatch.setattr(commands, "log", fakelib.FakeLogger()) secret = ProtectedPassword("top-secret") args = ["echo", "-n", secret] commands.run(args) for level, msg, kwargs in commands.log.messages: assert str(secret.value) not in msg
def test_run_error_data(self): with pytest.raises(cmdutils.Error) as e: args = ["sh", "-c", "echo -n out >&1; echo -n err >&2; exit 1"] commands.run(args) assert e.value.rc == 1 assert e.value.out == b"out" assert e.value.err == b"err"
def test_reload_lvs_with_stale_lv(tmp_storage): dev_size = 10 * 1024**3 dev1 = tmp_storage.create_device(dev_size) dev2 = tmp_storage.create_device(dev_size) vg_name = str(uuid.uuid4()) lv1 = "lv1" lv2 = "lv2" # Creating VG and LV requires read-write mode. lvm.set_read_only(False) lvm.createVG(vg_name, [dev1, dev2], "initial-tag", 128) # Create the LVs. lvm.createLV(vg_name, lv1, 1024) lvm.createLV(vg_name, lv2, 1024) # Make sure that LVs are in the cache. expected_lv1 = lvm.getLV(vg_name, lv1) expected_lv2 = lvm.getLV(vg_name, lv2) # Simulate LV removed on the SPM while this host keeps it in the cache. commands.run([ "lvremove", "-f", "--config", tmp_storage.lvm_config(), "{}/{}".format(vg_name, lv2) ]) # Test removing staled LVs in LVMCache._reloadlvs() which can be invoked # e.g. by calling lvm.getLv(vg_name). lvs = lvm.getLV(vg_name) # And verify that first LV is still correctly reported. assert expected_lv1 in lvs assert expected_lv2 not in lvs
def removeConf(): if passwd_isconfigured() == YES: try: commands.run( [_SASLPASSWD2.cmd, '-p', '-a', 'libvirt', '-d', SASL_USERNAME]) except cmdutils.Error as e: raise RuntimeError("Remove password failed: {}".format(e))
def _generate_cert_file(csr_file, key_file): with tempfile.NamedTemporaryFile(suffix=".crt") as cert_file: commands.run([ "openssl", "x509", "-req", "-days", "365", "-in", csr_file.name, "-signkey", key_file.name, "-out", cert_file.name ]) yield cert_file
def _generate_csr_file(key_file): with tempfile.NamedTemporaryFile(suffix=".csr") as csr_file: commands.run([ "openssl", "req", "-new", "-key", key_file.name, "-out", csr_file.name, "-subj", "/C=US/ST=Bar/L=Foo/O=Dis/CN=::1" ]) yield csr_file
def stale_lv(tmp_storage): dev_size = 1 * 1024**3 dev = tmp_storage.create_device(dev_size) vg_name = str(uuid.uuid4()) good_lv_name = "good" stale_lv_name = "stale" lvm.set_read_only(False) # Create VG with 2 lvs. lvm.createVG(vg_name, [dev], "initial-tag", 128) for lv_name in (good_lv_name, stale_lv_name): lvm.createLV(vg_name, lv_name, 128, activate=False) # Reload the cache. good_lv = lvm.getLV(vg_name, good_lv_name) stale_lv = lvm.getLV(vg_name, stale_lv_name) # Simulate removal of the second LV on another host, leaving stale LV in # the cache. commands.run([ "lvremove", "--config", tmp_storage.lvm_config(), "{}/{}".format(vg_name, stale_lv_name), ]) # The cache still keeps both lvs. assert lvm._lvminfo._lvs == { (vg_name, good_lv_name): good_lv, (vg_name, stale_lv_name): stale_lv, } return vg_name, good_lv_name, stale_lv_name
def _remove_device_vg(self, device): conf = self.lvm_config() cmd = [ "vgs", "-o", "name", "--noheadings", "--config", conf, "--select", "pv_name = %s" % device.path ] vg_name = commands.run(cmd).strip().decode() if vg_name: errors = [] cmds = [ ["vgchange", "-an", "--config", conf, vg_name], ["lvremove", "-ff", "--config", conf, vg_name], ["vgremove", "-ff", "--config", conf, vg_name], ] # run all the commands even if some of them fail for cmd in cmds: try: commands.run(cmd) except cmdutils.Error as e: errors.append(e) # but report error if there is any failure if errors: raise CleanupError("Errors removing vg %s" % vg_name, errors)
def remove_vnc_password(username): if os.geteuid() != 0: return supervdsm.getProxy().saslpasswd2_remove_vnc_password(username) commands.run([ SASL_COMMAND, "-a", SASL_APP_NAME, "-f", SASL_PASSWORD_DB, "-d", username ])
def snapshotScheduleDisable(): command = [_snapSchedulerPath.cmd, "disable_force"] try: commands.run(command) except cmdutils.Error as e: if e.rc != SNAP_SCHEDULER_ALREADY_DISABLED_RC: raise ge.GlusterDisableSnapshotScheduleFailedException(e.rc) return True
def configure_passwd(): args = [_SASLPASSWD2.cmd, '-p', '-a', 'libvirt', SASL_USERNAME] password = libvirt_password().encode("utf-8") try: commands.run(args, input=password) except cmdutils.Error as e: raise RuntimeError("Set password failed: {}".format(e))
def _configure_groups(): try: commands.run([ '/usr/sbin/usermod', '-a', '-G', ','.join(REQUIRED_GROUPS), constants.SANLOCK_USER ]) except cmdutils.Error as e: raise RuntimeError("Failed to perform sanlock config: {}".format(e))
def _validate_module(name): if not os.path.exists('/sys/module/' + name): cmd_modprobe = [modprobe.cmd, name] try: commands.run(cmd_modprobe, sudo=True) except cmdutils.Error as e: raise SkipTest("This test requires %s module " "(failed to load module: %s)" % (name, e))
def test_service_down(self): service_stop('vdsmd') vdsm_version = commands.run(['rpm', '-q', 'vdsm']) downgrade_vdsm(el7_ovirt36_repo) upgrade_vdsm() assert commands.run(['rpm', '-q', 'vdsm']) == vdsm_version assert service_status('vdsmd') == 1
def testConnectWithCertificateSucceeds(self): """ Verify that the connection with a valid client certificate works correctly. """ args = ["openssl", "s_client", "-connect", "%s:%d" % self.address, "-cert", self.certfile, "-key", self.keyfile] commands.run(args)
def configure(): """ Set up the multipath daemon configuration to the known and supported state. The original configuration, if any, is saved """ if os.path.exists(_CONF_FILE): backup = _CONF_FILE + '.' + time.strftime("%Y%m%d%H%M") shutil.copyfile(_CONF_FILE, backup) sys.stdout.write("Backup previous multipath.conf to %r\n" % backup) with tempfile.NamedTemporaryFile(mode="wb", prefix=os.path.basename(_CONF_FILE) + ".tmp", dir=os.path.dirname(_CONF_FILE), delete=False) as f: try: f.write(_CONF_DATA.encode('utf-8')) f.flush() selinux.restorecon(f.name) os.chmod(f.name, 0o644) os.rename(f.name, _CONF_FILE) except: os.unlink(f.name) raise # We want to handle these cases: # # 1. multipathd is not running and the kernel module is not loaded. We # don't have any online multipath devices, so there is nothing to # reconfigure, but we want to make sure that multipathd is happy with # new multipath configuration. # # 2. multipathd is not running but the kernel module is loaded. We may have # online devices that need reconfiguration. # # 3. multipathd is running with older configuration not compatible with # vdsm configuration. # # 4. multipathd is running with older vdsm configuration. Reloading is # needed to update devices with new configuration. # # When we have online devices using incompatible configuration, they may # use "user friendly" names (/dev/mapper/mpath{N}) instead of consistent # names (/dev/mapper/{WWID}). Restarting multipathd with the new # configuration will rename the devices, however due to multipathd bug, # these devices may not pick all configuration changes. Reconfiguring # multipathd ensures that all configurations changes are applied. # # To simplify handing of all cases, we first start multipathd service. This # eliminates cases 1 and 2. Case 3 and 4 are handled by reconfiguring # multipathd. # # If any of those steps fails, we want to fail the configuration. service.service_start("multipathd") commands.run([_MULTIPATHD.cmd, "reconfigure"])
def remove_vnc_password(username): if os.geteuid() != 0: return supervdsm.getProxy().saslpasswd2_remove_vnc_password(username) commands.run([SASL_COMMAND, "-a", SASL_APP_NAME, "-f", SASL_PASSWORD_DB, "-d", username])
def _inject_unit_requirement(unit, required_unit): requirements_dir_name = _SYSTEMD_REQUIREMENT_PATH_TEMPLATE.format(unit) os.makedirs(requirements_dir_name, mode=0o755, exist_ok=True) try: os.symlink(os.path.join(_SYSTEMD_UNITS_PATH, required_unit), os.path.join(requirements_dir_name, required_unit)) except FileExistsError: pass commands.run([systemctl.SYSTEMCTL, "daemon-reload"])
def test_limit_rss(): # This should fail to allocate about 100 MiB. script = "s = 100 * 1024**2 * 'x'" cmd = ["python", "-c", script] cmd = cmdutils.prlimit(cmd, address_space=100 * MiB) with pytest.raises(cmdutils.Error) as e: commands.run(cmd) assert e.value.rc == 1 assert b"MemoryError" in e.value.err
def testConnectWithoutCertificateFails(self): """ Verify that the connection without a client certificate fails. """ with self.assertRaises(cmdutils.Error): args = ["openssl", "s_client", "-connect", "%s:%d" % self.address] commands.run(args)
def _exec_vdsm_gencerts(): try: commands.run([ os.path.join(constants.P_VDSM_EXEC, 'vdsm-gencerts.sh'), pki.CA_FILE, pki.KEY_FILE, pki.CERT_FILE ]) except cmdutils.Error as e: msg = "Failed to perform vdsm-gencerts action: {}".format(e) raise RuntimeError(msg)
def removeMapping(deviceName): if os.geteuid() != 0: return supervdsm.getProxy().devicemapper_removeMapping(deviceName) cmd = [EXT_DMSETUP, "remove", deviceName] try: commands.run(cmd) except cmdutils.Error as e: raise Error("Could not remove mapping {!r}: {}".format(deviceName, e))
def webhookUpdate(url, bearerToken=None): command = [_glusterEventsApi.cmd, "webhook-mod", url] if bearerToken: command.append('--bearer_token=%s' % bearerToken) try: commands.run(command) except cmdutils.Error as e: raise ge.GlusterWebhookUpdateException(rc=e.rc, err=e.err) return True
def sparsify_inplace(vol_path): """ Sparsify the volume in place (without copying from an input disk to an output disk) :param vol_path: path to the volume """ cmd = [_VIRTSPARSIFY.cmd, '--machine-readable', '--in-place', vol_path] commands.run(cmd)
def test_panic(self): test_path = os.path.realpath(__file__) dir_name = os.path.dirname(test_path) panic_helper = os.path.join(dir_name, "..", "panic_helper.py") cmd = [sys.executable, panic_helper] with self.assertRaises(cmdutils.Error) as cm: commands.run(cmd) self.assertEqual(cm.exception.rc, -9)
def __assertSudoerPermissions(): with tempfile.NamedTemporaryFile() as dst: # This cmd choice is arbitrary to validate that sudoers.d/50_vdsm file # is read properly cmd = [constants.EXT_CHOWN, "%s:%s" % (constants.VDSM_USER, constants.QEMU_PROCESS_GROUP), dst.name] try: commands.run(cmd, sudo=True) except cmdutils.Error as e: msg = ("Vdsm user could not manage to run sudo operation: " "(stderr: %s). Verify sudoer rules configuration" % e.err) raise FatalError(msg)
def test_run_should_log_result(self, monkeypatch): monkeypatch.setattr(commands, "log", fakelib.FakeLogger()) monkeypatch.setattr(cmdutils, "command_log_line", mock.MagicMock()) monkeypatch.setattr(cmdutils, "retcode_log_line", mock.MagicMock()) cmdutils.command_log_line.return_value = "log line" cmdutils.retcode_log_line.return_value = "error line" args = ["exit 1"] try: commands.run(args) except cmdutils.Error: pass assert (logging.DEBUG, "log line", {}) in commands.log.messages assert (logging.DEBUG, "error line", {}) in commands.log.messages
def removeConf(): if passwd_isconfigured() == YES: try: commands.run([ str(_SASLPASSWD2), '-p', '-a', 'libvirt', '-d', SASL_USERNAME ]) except cmdutils.Error as e: raise RuntimeError("Remove password failed: {}".format(e))
def set_vnc_password(username, passwd): if os.geteuid() != 0: return supervdsm.getProxy().saslpasswd2_set_vnc_password(username, passwd) # Call to Popen.communicate needs string in Python2 and bytes in Python 3 # string.encode returns string in Python2 and bytes in Python3 # How convenient! commands.run([SASL_COMMAND, "-a", SASL_APP_NAME, "-f", SASL_PASSWORD_DB, "-p", username], input=passwd.encode())
def configure(): """ Configure sanlock process groups """ try: commands.run([ '/usr/sbin/usermod', '-a', '-G', ','.join(SANLOCK_GROUPS), constants.SANLOCK_USER ]) except cmdutils.Error as e: raise RuntimeError("Failed to perform sanlock config: {}".format(e))
def configure_passwd(): args = [ str(_SASLPASSWD2), '-p', '-a', 'libvirt', SASL_USERNAME ] password = libvirt_password().encode("utf-8") try: commands.run(args, input=password) except cmdutils.Error as e: raise RuntimeError("Set password failed: {}".format(e))
def test_setsid(self): args = [sys.executable, '-c', 'from __future__ import print_function;' 'import os;' 'print(os.getsid(os.getpid()))'] out = commands.run(args, setsid=True) assert int(out) != os.getsid(os.getpid())
def discard(device): """ Discards a block device. Arguments: device (str): The path to the block device to discard. Raises: cmdutils.Error if an error has occurred in blkdiscard. """ cmd = [ _blkdiscard.cmd, "--step", "%d" % OPTIMAL_DISCARD_STEP, ] cmd.append(device) commands.run(cmd)
def test_lv_refresh(tmp_storage, read_only): dev_size = 20 * 1024**3 dev = tmp_storage.create_device(dev_size) vg_name = str(uuid.uuid4()) lv_name = str(uuid.uuid4()) lv_fullname = "{}/{}".format(vg_name, lv_name) lvm.set_read_only(False) lvm.createVG(vg_name, [dev], "initial-tag", 128) lvm.createLV(vg_name, lv_name, 1024) lvm.set_read_only(read_only) # Simulate extending the LV on the SPM. commands.run([ "lvextend", "--config", tmp_storage.lvm_config(), "-L+1g", lv_fullname ]) # Refreshing LV invalidates the cache to pick up changes from storage. lvm.refreshLVs(vg_name, [lv_name]) lv = lvm.getLV(vg_name, lv_name) assert int(lv.size) == 2 * 1024**3 # Simulate extending the LV on the SPM. commands.run([ "lvextend", "--config", tmp_storage.lvm_config(), "-L+1g", lv_fullname ]) # Activate active LV refreshes it. lvm.activateLVs(vg_name, [lv_name]) lv = lvm.getLV(vg_name, lv_name) assert int(lv.size) == 3 * 1024**3
def configure(): """ Set up the multipath daemon configuration to the known and supported state. The original configuration, if any, is saved """ if os.path.exists(_CONF_FILE): backup = _CONF_FILE + '.' + time.strftime("%Y%m%d%H%M") shutil.copyfile(_CONF_FILE, backup) sys.stdout.write("Backup previous multipath.conf to %r\n" % backup) with tempfile.NamedTemporaryFile( mode="wb", prefix=os.path.basename(_CONF_FILE) + ".tmp", dir=os.path.dirname(_CONF_FILE), delete=False) as f: try: f.write(_CONF_DATA) f.flush() selinux.restorecon(f.name) os.chmod(f.name, 0o644) os.rename(f.name, _CONF_FILE) except: os.unlink(f.name) raise # Flush all unused multipath device maps. 'multipath' # returns 1 if any of the devices is in use and unable to flush. try: commands.run([constants.EXT_MULTIPATH, "-F"]) except cmdutils.Error: pass try: service.service_reload("multipathd") except service.ServiceOperationError: status = service.service_status("multipathd", False) if status == 0: raise
def sparsify(src_vol, tmp_vol, dst_vol, src_format=None, dst_format=None): """ Sparsify the 'src_vol' volume (src_format) to 'dst_vol' volume (dst_format) using libguestfs virt-sparsify src_vol: path of base volume tmp_vol: path of temporary volume created with src_vol as backing volume dst_vol: path of destination volume src_format: format of base volume ('raw' or `qcow2') src_format: format of destination volume ('raw' or `qcow2') """ cmd = [_VIRTSPARSIFY.cmd, '--tmp', 'prebuilt:' + tmp_vol] if src_format: cmd.extend(("--format", src_format)) if dst_format: cmd.extend(("--convert", dst_format)) cmd.extend((src_vol, dst_vol)) commands.run(cmd)
def run_helper(sub_cmd, cmd_input=None): if os.geteuid() != 0: return supervdsm.getProxy().managedvolume_run_helper( sub_cmd, cmd_input=cmd_input) try: if cmd_input: cmd_input = json.dumps(cmd_input).encode("utf-8") result = commands.run([HELPER, sub_cmd], input=cmd_input) except cmdutils.Error as e: raise se.ManagedVolumeHelperFailed("Error executing helper: %s" % e) try: return json.loads(result) except ValueError as e: raise se.ManagedVolumeHelperFailed("Error loading result: %s" % e)
def passwd_isconfigured(): try: out = commands.run([ str(_SASLDBLISTUSERS2), '-f', _LIBVIRT_SASLDB ]) username = SASL_USERNAME.encode("utf-8") for user in out.splitlines(): if username in user: return YES # TODO: why errors here were always ignored? except cmdutils.Error: pass return NO
def autonuma_status(): ''' Query system for autonuma status. Returns one of following: AUTONUMA_STATUS_DISABLE = 0 AUTONUMA_STATUS_ENABLE = 1 AUTONUMA_STATUS_UNKNOWN = 2 ''' out = commands.run([_SYSCTL.cmd, '-n', '-e', 'kernel.numa_balancing']) if not out: return AUTONUMA_STATUS_UNKNOWN elif out[0] == '0': return AUTONUMA_STATUS_DISABLE elif out[0] == '1': return AUTONUMA_STATUS_ENABLE else: return AUTONUMA_STATUS_UNKNOWN
def test_child_terminated(self): p = commands.start(["sleep", "1"]) commands.run(["kill", "-%d" % signal.SIGTERM, "%d" % p.pid]) assert p.wait() == -signal.SIGTERM
def teardown_method(self, method): commands.run(['yum-config-manager', '--disable', '*ovirt-3.6*']) commands.run(['yum-config-manager', '--enable', 'localsync']) # make sure vdsm is installed and running commands.run(['yum', 'install', '-y', 'vdsm']) service_start('vdsmd')
def test_protect_password_error(self): secret = ProtectedPassword("top-secret") args = ["false", secret] with pytest.raises(cmdutils.Error) as e: commands.run(args) assert secret.value not in str(e.value)
def upgrade_vdsm(): commands.run(['yum-config-manager', '--enable', 'localsync']) commands.run(['yum', 'update', '-y', 'vdsm'])
def test_run(self): assert commands.run(["true"]) == b""
def _run_silent(self, cmd): try: return commands.run(cmd).strip().decode() except cmdutils.Error as e: log.exception("%s", e) return None
def downgrade_vdsm(url): commands.run(['yum-config-manager', '--add-repo', url]) commands.run(['yum', 'swap', '--', 'erase', '-y', 'vdsm\*', '--', 'install', '-y', 'vdsm-4.17.10.1-0.el7.centos.noarch'])
def setup_method(self, test_method): commands.run(['yum-config-manager', '--disable', 'localsync'])
def test_run_sudo(self): assert commands.run(["whoami"], sudo=True) == b"root\n"