diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 8cfbc366..43c42631 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -38,9 +38,15 @@ jobs:
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: rustfmt, clippy
+
+ - name: typos-action
+ uses: crate-ci/typos@v1.14.12
+
- uses: taiki-e/install-action@just
+
- name: Install requirements
run: just ci-prepare
+
- name: Check formatting and lints
run: just lint
diff --git a/.typos.toml b/.typos.toml
new file mode 100644
index 00000000..e8782456
--- /dev/null
+++ b/.typos.toml
@@ -0,0 +1,20 @@
+# Configuration Reference:
+# - https://github.com/crate-ci/typos/blob/927308c726b1fba730f7aaa8bde602148b82004d/docs/reference.md
+
+[files]
+extend-exclude = [
+ "**/*.svg",
+]
+
+[default.extend-identifiers]
+# This is a cgroup slice ID used in examples. It is easier to ignore this
+# instance than write a regex.
+569d5ce3afe1074769f67 = "569d5ce3afe1074769f67"
+
+[type.rust.extend-words]
+ser = "ser"
+flate = "flate"
+clos = "clos"
+Setted = "Setted"
+hve = "hve"
+
diff --git a/crates/libcgroups/src/common.rs b/crates/libcgroups/src/common.rs
index b5d71544..3b905dd2 100644
--- a/crates/libcgroups/src/common.rs
+++ b/crates/libcgroups/src/common.rs
@@ -137,7 +137,7 @@ impl Display for CgroupSetup {
}
}
-/// FreezerState is given freezer contoller
+/// FreezerState is given freezer controller
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum FreezerState {
/// Tasks in cgroup are undefined
@@ -157,7 +157,7 @@ pub struct ControllerOpt<'a> {
pub disable_oom_killer: bool,
/// Specify an oom_score_adj for container.
pub oom_score_adj: Option,
- /// FreezerState is given to freezer contoller for suspending process.
+ /// FreezerState is given to freezer controller for suspending process.
pub freezer_state: Option,
}
diff --git a/crates/libcgroups/src/stats.rs b/crates/libcgroups/src/stats.rs
index 37142f8f..de9491eb 100644
--- a/crates/libcgroups/src/stats.rs
+++ b/crates/libcgroups/src/stats.rs
@@ -335,7 +335,7 @@ pub enum ParseNestedKeyedDataError {
DoesNotConform { path: PathBuf },
}
-/// Parses a file that is structed according to the nested keyed format
+/// Parses a file that is structured according to the nested keyed format
pub fn parse_nested_keyed_data(
file_path: &Path,
) -> Result>, ParseNestedKeyedDataError> {
diff --git a/crates/libcgroups/src/systemd/cpuset.rs b/crates/libcgroups/src/systemd/cpuset.rs
index 9b03cf07..33b73b99 100644
--- a/crates/libcgroups/src/systemd/cpuset.rs
+++ b/crates/libcgroups/src/systemd/cpuset.rs
@@ -13,7 +13,7 @@ pub const ALLOWED_NODES: &str = "AllowedMemoryNodes";
#[derive(thiserror::Error, Debug)]
pub enum SystemdCpuSetError {
- #[error("setting cpuset restrictions requires systemd version greather than 243")]
+ #[error("setting cpuset restrictions requires systemd version greater than 243")]
OldSystemd,
#[error("could not create bitmask for cpus: {0}")]
CpusBitmask(BitmaskError),
diff --git a/crates/libcgroups/src/v1/util.rs b/crates/libcgroups/src/v1/util.rs
index a33a109f..050967a7 100644
--- a/crates/libcgroups/src/v1/util.rs
+++ b/crates/libcgroups/src/v1/util.rs
@@ -51,7 +51,7 @@ pub fn get_subsystem_mount_point(subsystem: &ControllerType) -> Result {
pub use_systemd: bool,
/// Id of the container
pub container_id: String,
- /// OCI complient runtime spec
+ /// OCI compliant runtime spec
pub spec: &'a Spec,
/// Root filesystem of the container
pub rootfs: PathBuf,
diff --git a/crates/libcontainer/src/hooks.rs b/crates/libcontainer/src/hooks.rs
index 0a8bd3ab..f12cc603 100644
--- a/crates/libcontainer/src/hooks.rs
+++ b/crates/libcontainer/src/hooks.rs
@@ -40,7 +40,7 @@ pub fn run_hooks(hooks: Option<&Vec>, container: Option<&Container>) -> Re
// Based on OCI spec, the first argument of the args vector is the
// arg0, which can be different from the path. For example, path
// may be "/usr/bin/true" and arg0 is set to "true". However, rust
- // command differenciates arg0 from args, where rust command arg
+ // command differentiates arg0 from args, where rust command arg
// doesn't include arg0. So we have to make the split arg0 from the
// rest of args.
if let Some((arg0, args)) = hook.args().as_ref().and_then(|a| a.split_first()) {
diff --git a/crates/libcontainer/src/process/args.rs b/crates/libcontainer/src/process/args.rs
index f54a691b..44258975 100644
--- a/crates/libcontainer/src/process/args.rs
+++ b/crates/libcontainer/src/process/args.rs
@@ -18,7 +18,7 @@ pub struct ContainerArgs<'a> {
pub container_type: ContainerType,
/// Interface to operating system primitives
pub syscall: &'a dyn Syscall,
- /// OCI complient runtime spec
+ /// OCI compliant runtime spec
pub spec: &'a Spec,
/// Root filesystem of the container
pub rootfs: &'a PathBuf,
diff --git a/crates/libcontainer/src/process/container_main_process.rs b/crates/libcontainer/src/process/container_main_process.rs
index 64d83f9b..29d8f558 100644
--- a/crates/libcontainer/src/process/container_main_process.rs
+++ b/crates/libcontainer/src/process/container_main_process.rs
@@ -267,7 +267,7 @@ mod tests {
#[test]
#[serial]
- fn setup_gid_mapping_should_successed() -> Result<()> {
+ fn setup_gid_mapping_should_succeed() -> Result<()> {
let gid_mapping = LinuxIdMappingBuilder::default()
.host_id(getgid())
.container_id(0u32)
diff --git a/crates/libcontainer/src/process/seccomp_listener.rs b/crates/libcontainer/src/process/seccomp_listener.rs
index 9f737678..608ff725 100644
--- a/crates/libcontainer/src/process/seccomp_listener.rs
+++ b/crates/libcontainer/src/process/seccomp_listener.rs
@@ -80,7 +80,7 @@ fn sync_seccomp_send_msg(listener_path: &Path, msg: &[u8], fd: i32) -> Result<()
tracing::error!(
?err,
?listener_path,
- "failed to connect to seccomp notify listerner path"
+ "failed to connect to seccomp notify listener path"
);
SeccompListenerError::UnixOther(err)
})?;
diff --git a/crates/libcontainer/src/rootfs/rootfs.rs b/crates/libcontainer/src/rootfs/rootfs.rs
index fd3b92dd..edd36fe4 100644
--- a/crates/libcontainer/src/rootfs/rootfs.rs
+++ b/crates/libcontainer/src/rootfs/rootfs.rs
@@ -46,8 +46,8 @@ impl RootFS {
Some("shared") => flags |= MsFlags::MS_SHARED,
Some("private") => flags |= MsFlags::MS_PRIVATE,
Some("slave" | "unbindable") | None => flags |= MsFlags::MS_SLAVE,
- Some(uknown) => {
- return Err(RootfsError::UnknownRootfsPropagation(uknown.to_string()));
+ Some(unknown) => {
+ return Err(RootfsError::UnknownRootfsPropagation(unknown.to_string()));
}
}
diff --git a/crates/libcontainer/src/rootfs/utils.rs b/crates/libcontainer/src/rootfs/utils.rs
index d92f7d31..f1aaa884 100644
--- a/crates/libcontainer/src/rootfs/utils.rs
+++ b/crates/libcontainer/src/rootfs/utils.rs
@@ -11,7 +11,7 @@ pub struct MountOptionConfig {
/// Mount data applied to the mount.
pub data: String,
- /// RecAttr represents mount properties to be applied recrusively.
+ /// RecAttr represents mount properties to be applied recursively.
pub rec_attr: Option,
}
diff --git a/crates/libcontainer/src/utils.rs b/crates/libcontainer/src/utils.rs
index 91e7d654..27f735df 100644
--- a/crates/libcontainer/src/utils.rs
+++ b/crates/libcontainer/src/utils.rs
@@ -189,7 +189,7 @@ pub fn open>(path: P) -> Result {
pub enum MkdirWithModeError {
#[error("IO error")]
Io(#[from] std::io::Error),
- #[error("metada doesn't match the expected attributes")]
+ #[error("metadata doesn't match the expected attributes")]
MetadataMismatch,
}
diff --git a/crates/youki/src/commands/run.rs b/crates/youki/src/commands/run.rs
index d5b087fa..3a7c83d9 100644
--- a/crates/youki/src/commands/run.rs
+++ b/crates/youki/src/commands/run.rs
@@ -194,7 +194,7 @@ mod tests {
fn test_foreground_exit() -> Result<()> {
// The setup is similar to `handle_foreground`, but instead of
// forwarding signal, the container init process will exit. Again, we
- // use `sleep` to simulate the conditions to aovid fine grained
+ // use `sleep` to simulate the conditions to avoid fine grained
// synchronization for now.
match unsafe { unistd::fork()? } {
unistd::ForkResult::Parent { child } => {
diff --git a/docs/doc-draft.md b/docs/doc-draft.md
index 762cae9d..2e92db41 100644
--- a/docs/doc-draft.md
+++ b/docs/doc-draft.md
@@ -25,7 +25,7 @@ sequenceDiagram
participant U as User
participant D as Docker
participant Y_Main as Youki(Main Process)
-participant Y_Intermediate as Youki(Intermeidate Process)
+participant Y_Intermediate as Youki(Intermediate Process)
participant Y_init as Youki(Init Process)
@@ -122,5 +122,7 @@ This contains functionality regarding pausing and resuming container. Pausing a
- [cgroups man page](https://man7.org/linux/man-pages/man7/cgroups.7.html)
- [freezer cgroup kernel documentation](https://www.kernel.org/doc/Documentation/cgroup-v1/freezer-subsystem.txt)
-[oci runtime specification]: https://github.com/opencontainers/runtime-spec/blob/master/runtime.md
-[runc man pages]: (https://github.com/opencontainers/runc/blob/master/man/runc.8.md)
+## Other references
+
+- [oci runtime specification](https://github.com/opencontainers/runtime-spec/blob/master/runtime.md)
+- [runc man pages](https://github.com/opencontainers/runc/blob/master/man/runc.8.md)
diff --git a/docs/src/developer/libcgroups.md b/docs/src/developer/libcgroups.md
index 6300ed14..a1f66678 100644
--- a/docs/src/developer/libcgroups.md
+++ b/docs/src/developer/libcgroups.md
@@ -16,7 +16,7 @@ This crates exposes several functions and modules that can be used to work with
- CPU stats including usage and throttling
- Memory stats including usage of normal and swap memory, usage of kernel memory, page cache in bytes etc
- - Pid stat including current active pids nd maximum allowed pids
+ - Pid stat including current active pids and maximum allowed pids
- Block IO stats such as number of bytest transferred to/from a device in the cgroup, io operations performed by a device in the cgroup, amount of time cgroup had access to a device etc
- Huge TLB stats such as usage and maximum usage etc.
- Function to get pid stats
diff --git a/docs/src/developer/youki.md b/docs/src/developer/youki.md
index 15aad63c..478e82a8 100644
--- a/docs/src/developer/youki.md
+++ b/docs/src/developer/youki.md
@@ -8,7 +8,7 @@ The simple control flow of youki can be explained as :
-When given the create command, Youki will load the specification, configuration, sockets etc., and use clone syscall to create an intermediate process. This process will set the cgroups and capabilities, and then fork to the init process. Reason to create this intermediate prcoess is that the clone syscall cannot enter into existing pid namespace that has been created for the container. Thus first we need to make a transition to that namespace in the intermediate process and fork that to the container process. After that the main youki process is requested the uid and gid mappings, and after receiving them the intermediate process sets these mapping, fork the init process and return pid of this init process to the main youki process before exiting.
+When given the create command, Youki will load the specification, configuration, sockets etc., and use clone syscall to create an intermediate process. This process will set the cgroups and capabilities, and then fork to the init process. Reason to create this intermediate process is that the clone syscall cannot enter into existing pid namespace that has been created for the container. Thus first we need to make a transition to that namespace in the intermediate process and fork that to the container process. After that the main youki process is requested the uid and gid mappings, and after receiving them the intermediate process sets these mapping, fork the init process and return pid of this init process to the main youki process before exiting.
The init process then transition completely into the new namespace setup for the container (the init process only transitions the pid namespace). It changes the root mountpoint for the process using [pivot_root](https://man7.org/linux/man-pages/man2/pivot_root.2.html), so that the container process can get impression that it has a complete root path access. After that the init process sets up the capabilities and seccomp, and sends the seccomp notify fd to the main youki process. When the seccomp agent running on the host system sets up the seccomp profile, it notifies the init process, after which it can execute the programto be executed inside the container. Thus the init process then sends ready notification to the main youki process, and waits for the start signal.
diff --git a/docs/src/user/basic_usage.md b/docs/src/user/basic_usage.md
index 6fbc14ce..b7400b68 100644
--- a/docs/src/user/basic_usage.md
+++ b/docs/src/user/basic_usage.md
@@ -143,7 +143,7 @@ sudo ./youki list
sudo ./youki delete tutorial_container
```
-The example above shows how to run Youki in a 'rootful' way. To run it without root permissions, that is, in rootless mode, few chagnes are required.
+The example above shows how to run Youki in a 'rootful' way. To run it without root permissions, that is, in rootless mode, few changes are required.
First, after exporting the rootfs from docker, while generating the config, you will need to pass the rootless flag. This will generate the config withe the options needed for rootless operation of the container.
diff --git a/docs/src/user/webassembly.md b/docs/src/user/webassembly.md
index 8646292f..456dce02 100644
--- a/docs/src/user/webassembly.md
+++ b/docs/src/user/webassembly.md
@@ -10,15 +10,19 @@ There are 3 things you need to do to run a WebAssembly module with youki.
- Run `build.sh` with `-f wasm-wasmedge` option.
- ```console
+ ```bash
./scripts/build.sh -o . -r -f wasm-wasmedge
```
- > The `wasm-wasmedge` feature will install WasmEdge Runtime library in the `$HOME/.wasmedge` directory.
- > To make the library avaible in your system, run the following command:
+
+ > The `wasm-wasmedge` feature will install WasmEdge Runtime library in the `$HOME/.wasmedge` directory.
+ > To make the library available in your system, run the following command:
+ >
> ```bash
> export LD_LIBRARY_PATH=$HOME/.wasmedge/lib
> ```
+ >
> or
+ >
> ```bash
> source $HOME/.wasmedge/env
> ```
@@ -26,34 +30,35 @@ There are 3 things you need to do to run a WebAssembly module with youki.
- Run `build.sh` with `-f wasm-wasmer` option.
- ```console
+ ```bash
./scripts/build.sh -o . -r -f wasm-wasmer
```
## Build a container image with the WebAssembly module
-If you want to run a webassembly module with youki, your config.json has to include either **runc.oci.handler** or **module.wasm.image/variant=compat"**.
-
-It also needs to specifiy a valid .wasm (webassembly binary) or .wat (webassembly test) module as entrypoint for the container. If a wat module is specified it will be compiled to a wasm module by youki before it is executed. The module also needs to be available in the root filesystem of the container obviously.
+If you want to run a webassembly module with youki, your config.json has to include either **runc.oci.handler** or **module.wasm.image/variant=compat"**.
+It also needs to specify a valid .wasm (webassembly binary) or .wat (webassembly test) module as entrypoint for the container. If a wat module is specified it will be compiled to a wasm module by youki before it is executed. The module also needs to be available in the root filesystem of the container obviously.
```json
"ociVersion": "1.0.2-dev",
"annotations": {
- "run.oci.handler": "wasm"
+ "run.oci.handler": "wasm"
},
"process": {
"args": [
- "hello.wasm",
- "hello",
+ "hello.wasm",
+ "hello",
"world"
- ],
+ ],
+...
+}
...
```
### Compile a sample wasm module
-A simple wasm module can be created by running
+A simple wasm module can be created by running
```console
rustup target add wasm32-wasi
@@ -75,7 +80,9 @@ fn main() {
}
}
```
+
Then compile the program to WASI.
+
```console
cargo build --target wasm32-wasi
```
@@ -104,7 +111,7 @@ sudo buildah build --annotation "module.wasm.image/variant=compat" -t wasm-modul
Run podman with youki as runtime. [^1]
-```console
+```bash
sudo podman --runtime /PATH/WHARE/YOU/BUILT/WITH/WASM-WASMER/youki run localhost/wasm-module 1 2 3
```
diff --git a/hack/stress_cargo_test.sh b/hack/stress_cargo_test.sh
index b9c4bb46..20923452 100755
--- a/hack/stress_cargo_test.sh
+++ b/hack/stress_cargo_test.sh
@@ -1,4 +1,5 @@
-#!/bin/bash -ue
+#!/usr/bin/env bash
+set -euo pipefail
# This is a simple script to stress test `cargo test` to rule out flaky tests.
diff --git a/justfile b/justfile
index 4fe221d2..21aa49fa 100644
--- a/justfile
+++ b/justfile
@@ -38,7 +38,7 @@ unittest:
cd ./crates
LD_LIBRARY_PATH=${HOME}/.wasmedge/lib cargo test --all --all-targets --all-features
-# run purmutated faeture compilation tests
+# run purmutated feature compilation tests
featuretest:
./scripts/features_test.sh
@@ -70,6 +70,10 @@ lint:
cargo fmt --all -- --check
cargo clippy --all --all-targets --all-features -- -D warnings
+# run spellcheck
+spellcheck:
+ typos
+
# run format on project
format:
cargo fmt --all
@@ -78,6 +82,10 @@ format:
clean:
./scripts/clean.sh {{ ROOT }}
+# install tools used in dev
+dev-prepare:
+ cargo install typos-cli
+
ci-prepare:
#!/usr/bin/env bash
set -euo pipefail
diff --git a/scripts/oci_integration_tests.sh b/scripts/oci_integration_tests.sh
index 9539824f..c96a110e 100755
--- a/scripts/oci_integration_tests.sh
+++ b/scripts/oci_integration_tests.sh
@@ -108,7 +108,7 @@ done
for case in "${test_cases[@]}"; do
if ! check_environment $case; then
- echo "Skip $case bacause your environment doesn't support this test case"
+ echo "Skip $case because your environment doesn't support this test case"
continue
fi
@@ -122,7 +122,7 @@ for case in "${test_cases[@]}"; do
sudo RUST_BACKTRACE=1 RUNTIME=${RUNTIME} ${OCI_TEST_DIR}/validation/$case >$logfile 2>&1 || (cat $logfile && exit 1)
if [ 0 -ne $(grep "not ok" $logfile | wc -l ) ]; then
if [ 0 -eq $(grep "# cgroupv2 is not supported yet " $logfile | wc -l ) ]; then
- echo "Skip $case bacause oci-runtime-tools doesn't support cgroup v2"
+ echo "Skip $case because oci-runtime-tools doesn't support cgroup v2"
continue;
fi
cat $logfile
diff --git a/tests/rust-integration-tests/integration_test/src/tests/cgroups/cpu/v2.rs b/tests/rust-integration-tests/integration_test/src/tests/cgroups/cpu/v2.rs
index 3b215d8c..0ecc5e4e 100644
--- a/tests/rust-integration-tests/integration_test/src/tests/cgroups/cpu/v2.rs
+++ b/tests/rust-integration-tests/integration_test/src/tests/cgroups/cpu/v2.rs
@@ -143,7 +143,7 @@ fn test_cpu_quota_valid_set() -> TestResult {
})
}
-/// Tests if the cpu quota is the defalt value (max) if a cpu quota of zero has been specified
+/// Tests if the cpu quota is the default value (max) if a cpu quota of zero has been specified
fn test_cpu_quota_zero_default_set() -> TestResult {
let cpu_quota = 0;
let cpu = test_result!(LinuxCpuBuilder::default()
diff --git a/tests/rust-integration-tests/runtimetest/README.md b/tests/rust-integration-tests/runtimetest/README.md
index 45b66d54..33651f1e 100644
--- a/tests/rust-integration-tests/runtimetest/README.md
+++ b/tests/rust-integration-tests/runtimetest/README.md
@@ -17,7 +17,7 @@ There is currently no convention of explicit indication of tests passing, the pa
This package must be compiled as a statically linked binary, as otherwise the rust compile will make it dynamically link to /lib64/ld-linux-x86-64.so , which is not available inside the container, and thus making the binary not usable inside the container process.
-**Note** that the dynamically linked binary does not give a `segmentation fault` or similar error when tried to run inside the container, but instead gives `no such file or directory found` or `executable not found` error, even though the executable exists in the container. This made this tricky to debug correctly when originally developing, so if you decide on chaing the compilation or configuration of this , please make absolutely sure that the changes work and do not accidentally break something.
+**Note** that the dynamically linked binary does not give a `segmentation fault` or similar error when tried to run inside the container, but instead gives `no such file or directory found` or `executable not found` error, even though the executable exists in the container. This made this tricky to debug correctly when originally developing, so if you decide on chaining the compilation or configuration of this , please make absolutely sure that the changes work and do not accidentally break something.
you can use
@@ -32,8 +32,8 @@ Reading the Readme of integration tests can be helpful to understand how the int
see
-https://stackoverflow.com/questions/31770604/how-to-generate-statically-linked-executables
-https://superuser.com/questions/248512/why-do-i-get-command-not-found-when-the-binary-file-exists
-https://doc.rust-lang.org/cargo/reference/config.html
+
+
+
for more info
diff --git a/tests/rust-integration-tests/runtimetest/src/tests.rs b/tests/rust-integration-tests/runtimetest/src/tests.rs
index 62459939..b5abb028 100644
--- a/tests/rust-integration-tests/runtimetest/src/tests.rs
+++ b/tests/rust-integration-tests/runtimetest/src/tests.rs
@@ -195,7 +195,7 @@ pub fn validate_mounts_recursive(spec: &Spec) {
let rest =
utils::test_device_unaccess(mount.destination().to_str().unwrap());
if rest.is_ok() {
- // beacuse /rnodev/null device not access,so rest is err
+ // because /rnodev/null device not access,so rest is err
eprintln!("error in testing rnodev recursive mounting");
}
}
diff --git a/tests/rust-integration-tests/runtimetest/src/utils.rs b/tests/rust-integration-tests/runtimetest/src/utils.rs
index a843c9b5..42784f36 100644
--- a/tests/rust-integration-tests/runtimetest/src/utils.rs
+++ b/tests/rust-integration-tests/runtimetest/src/utils.rs
@@ -166,8 +166,8 @@ pub fn test_device_unaccess(path: &str) -> Result<(), std::io::Error> {
// change time (ctime).
// case:
// 1. create test.txt file, get one atime
-// 2. cat a.txt, get two atime; check atime wheather update, conditions are met atime less than or equal mtime or ctime
-// 3. cat a.txt, get three atime, check now two atime wheather equal three atime
+// 2. cat a.txt, get two atime; check atime whether update, conditions are met atime less than or equal mtime or ctime
+// 3. cat a.txt, get three atime, check now two atime whether equal three atime
pub fn test_mount_releatime_option(path: &str) -> Result<(), std::io::Error> {
let test_file_path = PathBuf::from(path).join("test.txt");
Command::new("touch")
@@ -231,8 +231,8 @@ pub fn test_mount_releatime_option(path: &str) -> Result<(), std::io::Error> {
// case: because filesystem having relatime option
// 1. create test.txt file, get one atime
-// 2. cat a.txt, get two atime; check atime wheather update
-// 3. cat a.txt, get three atime, check now two atime wheather equal three atime
+// 2. cat a.txt, get two atime; check atime whether update
+// 3. cat a.txt, get three atime, check now two atime whether equal three atime
pub fn test_mount_noreleatime_option(path: &str) -> Result<(), std::io::Error> {
let test_file_path = PathBuf::from(path).join("noreleatime.txt");
Command::new("touch")
@@ -299,7 +299,7 @@ pub fn test_mount_noreleatime_option(path: &str) -> Result<(), std::io::Error> {
// Do not update access times for (all types of) files on this mount.
// case:
// 1. touch rnoatime.txt file, get atime
-// 2. cat rnoatime.txt, check atime wheather update, if update return error, else return Ok
+// 2. cat rnoatime.txt, check atime whether update, if update return error, else return Ok
pub fn test_mount_rnoatime_option(path: &str) -> Result<(), std::io::Error> {
let test_file_path = PathBuf::from(path).join("rnoatime.txt");
Command::new("touch")