diff --git a/ci.nix b/ci.nix index 7feb34ce2..b0b4bbbb6 100644 --- a/ci.nix +++ b/ci.nix @@ -87,6 +87,7 @@ mkShell { RUST_BACKTRACE = if asan then "full" else null; shellHook = '' + export FIO="$(which fio 2> /dev/null)" ${pkgs.lib.optionalString (asan) "export LLVM_SYMBOLIZER_DIR=$(dirname $(realpath $(which llvm-symbolizer)))"} ${pkgs.lib.optionalString (asan) "echo 'AddressSanitizer is enabled, forcing nightly rustc.'"} @@ -101,7 +102,7 @@ mkShell { ${pkgs.lib.optionalString (asan) "echo"} echo 'FIO version :' $(fio --version 2> /dev/null) - echo 'FIO path :' $(which fio 2> /dev/null) + echo 'FIO path :' $FIO ${pkgs.lib.optionalString (!nospdk) "echo 'SPDK version :' $(echo $SPDK_PATH | sed 's/.*libspdk-//g')"} ${pkgs.lib.optionalString (!nospdk) "echo 'SPDK path :' $SPDK_PATH"} ${pkgs.lib.optionalString (!nospdk) "echo 'SPDK FIO plugin :' $FIO_SPDK"} @@ -123,5 +124,6 @@ mkShell { pre-commit install pre-commit install --hook commit-msg fi + export PATH=$PATH:$(pwd)/scripts/nix-sudo ''; } diff --git a/io-engine-tests/src/fio.rs b/io-engine-tests/src/fio.rs index 7b98c93d6..be96566a2 100644 --- a/io-engine-tests/src/fio.rs +++ b/io-engine-tests/src/fio.rs @@ -251,13 +251,11 @@ impl Fio { pub fn run(mut self) -> Self { if self.fio_binary.is_empty() { - self.fio_binary = "fio".to_string(); + self.fio_binary = "$FIO".to_string(); } - let cmd = format!( - "sudo -E LD_PRELOAD=$FIO_SPDK {fio}", - fio = self.fio_binary - ); + let cmd = + format!("sudo LD_PRELOAD=$FIO_SPDK {fio}", fio = self.fio_binary); let args = self .jobs diff --git a/scripts/nix-sudo/nix-sudo b/scripts/nix-sudo/nix-sudo new file mode 100755 index 000000000..d832640e7 --- /dev/null +++ b/scripts/nix-sudo/nix-sudo @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +BIN= +CMD='' +for arg in "$@"; do + arg="${arg//\\/\\\\}" + if [ -n "$BIN" ]; then + CMD="$CMD \"${arg//\"/\\\"}\"" + shift + continue + fi + case $1 in + *=*|-*) + CMD="$CMD \"${arg//\"/\\\"}\"" + shift;; + *) + BIN="$(which "$1")" + CMD="$CMD \"${BIN//\"/\\\"}\"" + shift;; + esac +done +bash -c "sudo -E $CMD" diff --git a/shell.nix b/shell.nix index 4275c5cf2..f2f95bc53 100644 --- a/shell.nix +++ b/shell.nix @@ -66,8 +66,9 @@ mkShell { IO_ENGINE_DIR = "target/debug"; shellHook = '' + export FIO="$(which fio 2> /dev/null)" echo 'FIO version :' $(fio --version 2> /dev/null) - echo 'FIO path :' $(which fio 2> /dev/null) + echo 'FIO path :' $FIO ${pkgs.lib.optionalString (!nospdk) "echo 'SPDK version :' $(echo $SPDK_PATH | sed 's/.*libspdk-//g')"} ${pkgs.lib.optionalString (!nospdk) "echo 'SPDK path :' $SPDK_PATH"} ${pkgs.lib.optionalString (!nospdk) "echo 'SPDK FIO plugin :' $FIO_SPDK"} @@ -86,5 +87,6 @@ mkShell { pre-commit install pre-commit install --hook commit-msg fi + export PATH=$PATH:$(pwd)/scripts/nix-sudo ''; } diff --git a/test/python/common/fio.py b/test/python/common/fio.py index ab4b06af5..335562919 100644 --- a/test/python/common/fio.py +++ b/test/python/common/fio.py @@ -20,7 +20,7 @@ def build(self): size = "--size={}".format(self.size) command = ( - "sudo fio --ioengine=linuxaio --direct=1 --bs=4k " + "nix-sudo fio --ioengine=linuxaio --direct=1 --bs=4k " "--time_based=1 {} --rw={} " "--group_reporting=1 --norandommap=1 --iodepth=64 " "--runtime={} --name={} --filename={} {}" diff --git a/test/python/common/fio_spdk.py b/test/python/common/fio_spdk.py index a3b291ec0..ce7550403 100644 --- a/test/python/common/fio_spdk.py +++ b/test/python/common/fio_spdk.py @@ -30,7 +30,7 @@ def build(self) -> str: spdk_path = os.getcwd() + "/../../spdk-rs/spdk/build" spdk_fio_path = "{}/fio/spdk_nvme".format(spdk_path) command = ( - "sudo LD_PRELOAD={} fio --ioengine=spdk " + "sudo LD_PRELOAD={} $FIO --ioengine=spdk " "--direct=1 --bs=4k --time_based=1 --runtime={} " "--thread=1 --rw={} --group_reporting=1 --norandommap=1 " "--iodepth=64 --name={} --filename={}" diff --git a/test/python/common/nvme.py b/test/python/common/nvme.py index 957af3f9b..d26455fa9 100644 --- a/test/python/common/nvme.py +++ b/test/python/common/nvme.py @@ -7,7 +7,7 @@ async def nvme_remote_connect_all(remote, host, port): - command = f"sudo nvme connect-all -t tcp -s {port} -a {host}" + command = f"nix-sudo nvme connect-all -t tcp -s {port} -a {host}" await run_cmd_async_at(remote, command) @@ -18,11 +18,13 @@ async def nvme_remote_connect(remote, uri): host = u.hostname nqn = u.path[1:] - command = "sudo nvme connect -t tcp -s {0} -a {1} -n {2}".format(port, host, nqn) + command = "nix-sudo nvme connect -t tcp -s {0} -a {1} -n {2}".format( + port, host, nqn + ) await run_cmd_async_at(remote, command) time.sleep(1) - command = "sudo nvme list -v -o json" + command = "nix-sudo nvme list -v -o json" discover = await run_cmd_async_at(remote, command) discover = json.loads(discover.stdout) @@ -41,7 +43,7 @@ async def nvme_remote_disconnect(remote, uri): u = urlparse(uri) nqn = u.path[1:] - command = "sudo nvme disconnect -n {0}".format(nqn) + command = "nix-sudo nvme disconnect -n {0}".format(nqn) await run_cmd_async_at(remote, command) @@ -51,7 +53,7 @@ async def nvme_remote_discover(remote, uri): port = u.port host = u.hostname - command = "sudo nvme discover -t tcp -s {0} -a {1}".format(port, host) + command = "nix-sudo nvme discover -t tcp -s {0} -a {1}".format(port, host) output = await run_cmd_async_at(remote, command).stdout if not u.path[1:] in str(output.stdout): raise ValueError("uri {} is not discovered".format(u.path[1:])) @@ -64,11 +66,11 @@ def nvme_connect(uri, delay=10, tmo=600): nqn = u.path[1:] command = ( - f"sudo nvme connect -t tcp -s {port} -a {host} -n {nqn} -c {delay} -l {tmo}" + f"nix-sudo nvme connect -t tcp -s {port} -a {host} -n {nqn} -c {delay} -l {tmo}" ) subprocess.run(command, check=True, shell=True, capture_output=False) time.sleep(1) - command = "sudo nvme list -v -o json" + command = "nix-sudo nvme list -v -o json" discover = json.loads( subprocess.run( command, shell=True, check=True, text=True, capture_output=True @@ -85,7 +87,7 @@ def nvme_connect(uri, delay=10, tmo=600): def nvme_id_ctrl(device): """Identify controller.""" - command = "sudo nvme id-ctrl {0} -o json".format(device) + command = "nix-sudo nvme id-ctrl {0} -o json".format(device) id_ctrl = json.loads( subprocess.run( command, shell=True, check=True, text=True, capture_output=True @@ -97,7 +99,7 @@ def nvme_id_ctrl(device): def nvme_resv_report(device): """Reservation report.""" - command = "sudo nvme resv-report {0} -c 1 -o json".format(device) + command = "nix-sudo nvme resv-report {0} -c 1 -o json".format(device) resv_report = json.loads( subprocess.run( command, shell=True, check=True, text=True, capture_output=True @@ -113,7 +115,7 @@ def nvme_discover(uri): port = u.port host = u.hostname - command = "sudo nvme discover -t tcp -s {0} -a {1}".format(port, host) + command = "nix-sudo nvme discover -t tcp -s {0} -a {1}".format(port, host) output = subprocess.run( command, check=True, shell=True, capture_output=True, encoding="utf-8" ) @@ -126,25 +128,25 @@ def nvme_disconnect(uri): u = urlparse(uri) nqn = u.path[1:] - command = "sudo nvme disconnect -n {0}".format(nqn) + command = "nix-sudo nvme disconnect -n {0}".format(nqn) subprocess.run(command, check=True, shell=True, capture_output=True) def nvme_disconnect_controller(name): """Disconnect the given NVMe controller on this host.""" - command = "sudo nvme disconnect -d {0}".format(name) + command = "nix-sudo nvme disconnect -d {0}".format(name) subprocess.run(command, check=True, shell=True, capture_output=True) def nvme_disconnect_all(): """Disconnect from all connected nvme subsystems""" - command = "sudo nvme disconnect-all" + command = "nix-sudo nvme disconnect-all" subprocess.run(command, check=True, shell=True, capture_output=True) def nvme_list_subsystems(device): """Retrieve information for NVMe subsystems""" - command = "sudo nvme list-subsys {} -o json".format(device) + command = "nix-sudo nvme list-subsys {} -o json".format(device) return json.loads( subprocess.run( command, check=True, shell=True, capture_output=True, encoding="utf-8" @@ -157,7 +159,7 @@ def nvme_list_subsystems(device): def identify_namespace(device): """Get properties of a namespace on this host""" - command = "sudo nvme id-ns {}".format(device) + command = "nix-sudo nvme id-ns {}".format(device) output = subprocess.run( command, check=True, shell=True, capture_output=True, encoding="utf-8" ) @@ -182,8 +184,8 @@ def nvme_delete_controller(device): p = "/sys/class/nvme/%s/delete_controller" % m.group(1) # Forcibly trigger controller removal. Note that operations must be executed - # with root privileges, hence sudo for python interpreter. + # with root privileges, hence nix-sudo for python interpreter. script = "\"f = open('%s', 'w'); f.write('1'); f.flush()\"" % p # Run privileged Python script. - command = "sudo python -c {} ".format(script) + command = "nix-sudo python -c {} ".format(script) subprocess.run(command, check=True, shell=True, capture_output=True) diff --git a/test/python/v1/pool/test_bdd_lvm.py b/test/python/v1/pool/test_bdd_lvm.py index abfb52a44..63502104d 100644 --- a/test/python/v1/pool/test_bdd_lvm.py +++ b/test/python/v1/pool/test_bdd_lvm.py @@ -74,11 +74,11 @@ def volgrp_with_losetup_disk(): capture_output=True, ) disk = out.stdout.decode("ascii").strip("\n") - run_cmd(f"sudo -E pvcreate '{disk}'", True) - run_cmd(f"sudo -E vgcreate '{name}' '{disk}'", True) + run_cmd(f"nix-sudo pvcreate '{disk}'", True) + run_cmd(f"nix-sudo vgcreate '{name}' '{disk}'", True) pytest.disk = disk yield name - run_cmd(f"sudo -E losetup -d '{disk}'", True) + run_cmd(f"nix-sudo losetup -d '{disk}'", True) run_cmd(f"rm -f '{file}'", True) diff --git a/test/python/v1/replica/test_bdd_lvm_replica.py b/test/python/v1/replica/test_bdd_lvm_replica.py index de8101972..308702471 100644 --- a/test/python/v1/replica/test_bdd_lvm_replica.py +++ b/test/python/v1/replica/test_bdd_lvm_replica.py @@ -83,7 +83,7 @@ def create(name, disks, pooltype): @pytest.fixture def volgrp_with_losetup_disk(container_mod): pool_name = "lvmpool" - p = subprocess.run(f"sudo vgs {pool_name}", shell=True, check=False) + p = subprocess.run(f"nix-sudo vgs {pool_name}", shell=True, check=False) file = "/tmp/ms0-disk0.img" # if volume group already exists then don't create it again if p.returncode != 0: @@ -96,10 +96,10 @@ def volgrp_with_losetup_disk(container_mod): capture_output=True, ) disk = out.stdout.decode("ascii").strip("\n") - run_cmd(f"sudo -E pvcreate '{disk}'", True) - run_cmd(f"sudo -E vgcreate '{pool_name}' '{disk}'", True) + run_cmd(f"nix-sudo pvcreate '{disk}'", True) + run_cmd(f"nix-sudo vgcreate '{pool_name}' '{disk}'", True) out = subprocess.run( - f"sudo -E pvs -opv_name --select=vg_name={pool_name} --noheadings", + f"nix-sudo pvs -opv_name --select=vg_name={pool_name} --noheadings", shell=True, check=True, capture_output=True, @@ -107,7 +107,7 @@ def volgrp_with_losetup_disk(container_mod): disk = out.stdout.decode("ascii").strip("\n").lstrip() pytest.disk = disk out = subprocess.run( - f"sudo -E vgs lvmpool -ovg_uuid --noheadings", + f"nix-sudo vgs lvmpool -ovg_uuid --noheadings", shell=True, check=True, capture_output=True, @@ -115,7 +115,7 @@ def volgrp_with_losetup_disk(container_mod): pytest.vg_uuid = out.stdout.decode("ascii").strip("\n").lstrip() yield pool_name try: - run_cmd(f"sudo -E vgremove -y {pool_name}", True) + run_cmd(f"nix-sudo vgremove -y {pool_name}", True) except: pass if p.returncode != 0: