diff --git a/crates/runc-shim/src/synchronous/runc.rs b/crates/runc-shim/src/synchronous/runc.rs index b8cf039..38f84f9 100644 --- a/crates/runc-shim/src/synchronous/runc.rs +++ b/crates/runc-shim/src/synchronous/runc.rs @@ -44,9 +44,7 @@ use shim::protos::protobuf::well_known_types::{Any, Timestamp}; use shim::protos::protobuf::{CodedInputStream, Message, RepeatedField}; use shim::protos::shim::oci::ProcessDetails; #[cfg(not(feature = "async"))] -use shim::util::{ - new_temp_console_socket, read_spec_from_file, write_options, write_runtime, IntoOption, -}; +use shim::util::{read_spec_from_file, write_options, write_runtime, IntoOption}; use shim::Console; use shim::{other, other_error}; @@ -166,7 +164,7 @@ impl Container for RuncContainer { }; let terminal = process.common.stdio.terminal; let socket = if terminal { - let s = new_temp_console_socket().map_err(other_error!(e, ""))?; + let s = ConsoleSocket::new()?; exec_opts.console_socket = Some(s.path.to_owned()); Some(s) } else { @@ -456,7 +454,7 @@ impl InitProcess { .no_new_keyring(self.no_new_key_ring) .detach(false); let socket = if terminal { - let s = new_temp_console_socket().map_err(other_error!(e, ""))?; + let s = ConsoleSocket::new()?; create_opts.console_socket = Some(s.path.to_owned()); Some(s) } else { diff --git a/crates/runc/src/utils.rs b/crates/runc/src/utils.rs index 95a9fb9..df52d02 100644 --- a/crates/runc/src/utils.rs +++ b/crates/runc/src/utils.rs @@ -61,8 +61,8 @@ where path_to_string(abs_path_buf(path)?) } -/// Fetches the value of environment variable "XDG_RUNTIME_DIR", returning a temporary directory -/// if the variable isn't set +/// Returns a temp dir. If the environment variable "XDG_RUNTIME_DIR" is set, return its value. +/// Otherwise if `std::env::temp_dir()` failed, return current dir or return the temp dir depended on OS. fn xdg_runtime_dir() -> String { env::var("XDG_RUNTIME_DIR") .unwrap_or_else(|_| abs_string(env::temp_dir()).unwrap_or_else(|_| ".".to_string())) diff --git a/crates/shim/src/asynchronous/console.rs b/crates/shim/src/asynchronous/console.rs index 8348779..160f0ba 100644 --- a/crates/shim/src/asynchronous/console.rs +++ b/crates/shim/src/asynchronous/console.rs @@ -14,7 +14,6 @@ limitations under the License. */ -use std::env; use std::path::{Path, PathBuf}; use log::warn; @@ -22,6 +21,7 @@ use tokio::net::{UnixListener, UnixStream}; use uuid::Uuid; use crate::asynchronous::util::mkdir; +use crate::util::xdg_runtime_dir; use crate::Error; use crate::Result; @@ -33,8 +33,7 @@ pub struct ConsoleSocket { impl ConsoleSocket { pub async fn new() -> Result { - let dir = env::var("XDG_RUNTIME_DIR") - .map(|runtime_dir| format!("{}/pty{}", runtime_dir, Uuid::new_v4(),))?; + let dir = format!("{}/pty{}", xdg_runtime_dir(), Uuid::new_v4()); mkdir(&dir, 0o711).await?; let file_name = Path::new(&dir).join("pty.sock"); let listener = UnixListener::bind(&file_name).map_err(io_error!( diff --git a/crates/shim/src/synchronous/console.rs b/crates/shim/src/synchronous/console.rs index eaa8a1b..dde9228 100644 --- a/crates/shim/src/synchronous/console.rs +++ b/crates/shim/src/synchronous/console.rs @@ -15,9 +15,14 @@ */ use std::os::unix::net::{UnixListener, UnixStream}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use log::warn; +use uuid::Uuid; + +use crate::util::{mkdir, xdg_runtime_dir}; +use crate::Error; +use crate::Result; pub struct ConsoleSocket { pub listener: UnixListener, @@ -26,6 +31,22 @@ pub struct ConsoleSocket { } impl ConsoleSocket { + pub fn new() -> Result { + let dir = format!("{}/pty{}", xdg_runtime_dir(), Uuid::new_v4()); + mkdir(&dir, 0o711)?; + let file_name = Path::new(&dir).join("pty.sock"); + let listener = UnixListener::bind(&file_name).map_err(io_error!( + e, + "bind socket {}", + file_name.display() + ))?; + Ok(ConsoleSocket { + listener, + path: file_name, + rmdir: true, + }) + } + pub fn accept(&self) -> std::io::Result { let (stream, _addr) = self.listener.accept()?; Ok(stream) diff --git a/crates/shim/src/synchronous/util.rs b/crates/shim/src/synchronous/util.rs index cb60579..ec8a6f9 100644 --- a/crates/shim/src/synchronous/util.rs +++ b/crates/shim/src/synchronous/util.rs @@ -14,21 +14,17 @@ limitations under the License. */ -use std::env; use std::fs::{rename, File, OpenOptions}; use std::io::{Read, Write}; -use std::os::unix::net::UnixListener; use std::path::Path; +use libc::mode_t; use log::warn; use nix::sys::stat::Mode; -use nix::unistd::mkdir; use oci_spec::runtime::Spec; -use uuid::Uuid; use containerd_shim_protos::shim::oci::Options; -use crate::console::ConsoleSocket; use crate::util::{JsonOptions, OPTIONS_FILE_NAME, RUNTIME_FILE_NAME}; use crate::Error; @@ -118,21 +114,13 @@ pub fn read_spec_from_file(bundle: &str) -> crate::Result { Spec::load(path).map_err(other_error!(e, "read spec file")) } -pub fn new_temp_console_socket() -> crate::Result { - let dir = env::var("XDG_RUNTIME_DIR") - .map(|runtime_dir| format!("{}/pty{}", runtime_dir, Uuid::new_v4(),))?; - mkdir(Path::new(&dir), Mode::from_bits(0o711).unwrap())?; - let file_name = Path::new(&dir).join("pty.sock"); - let listener = UnixListener::bind(file_name.as_path()).map_err(io_error!( - e, - "bind socket {}", - file_name.display() - ))?; - Ok(ConsoleSocket { - listener, - path: file_name, - rmdir: true, - }) +pub fn mkdir(path: impl AsRef, mode: mode_t) -> crate::Result<()> { + let path_buf = path.as_ref().to_path_buf(); + if !path_buf.as_path().exists() { + let mode = Mode::from_bits(mode).ok_or_else(|| other!("invalid dir mode {}", mode))?; + nix::unistd::mkdir(path_buf.as_path(), mode)?; + } + Ok(()) } /// A helper to help remove temperate file or dir when it became useless diff --git a/crates/shim/src/util.rs b/crates/shim/src/util.rs index 9562ee0..b7c7e05 100644 --- a/crates/shim/src/util.rs +++ b/crates/shim/src/util.rs @@ -14,6 +14,7 @@ limitations under the License. */ +use std::env; use std::os::unix::io::RawFd; use std::time::{SystemTime, UNIX_EPOCH}; @@ -155,6 +156,13 @@ pub fn any(event: impl Message) -> Result { Ok(any) } +/// Returns a temp dir. If the environment variable "XDG_RUNTIME_DIR" is set, return its value. +/// Otherwise if `std::env::temp_dir()` failed, return current dir or return the temp dir depended on OS. +pub(crate) fn xdg_runtime_dir() -> String { + env::var("XDG_RUNTIME_DIR") + .unwrap_or_else(|_| env::temp_dir().to_str().unwrap_or(".").to_string()) +} + pub trait IntoOption where Self: Sized,