bugfix: return a tmp dir when 'XDG_RUNTIME_DIR' was not set

Signed-off-by: Zhang Tianyang <burning9699@gmail.com>
This commit is contained in:
Zhang Tianyang 2022-03-09 19:11:02 +08:00
parent 74ac192726
commit 3ff1fc0a6d
6 changed files with 45 additions and 31 deletions

View File

@ -44,9 +44,7 @@ use shim::protos::protobuf::well_known_types::{Any, Timestamp};
use shim::protos::protobuf::{CodedInputStream, Message, RepeatedField}; use shim::protos::protobuf::{CodedInputStream, Message, RepeatedField};
use shim::protos::shim::oci::ProcessDetails; use shim::protos::shim::oci::ProcessDetails;
#[cfg(not(feature = "async"))] #[cfg(not(feature = "async"))]
use shim::util::{ use shim::util::{read_spec_from_file, write_options, write_runtime, IntoOption};
new_temp_console_socket, read_spec_from_file, write_options, write_runtime, IntoOption,
};
use shim::Console; use shim::Console;
use shim::{other, other_error}; use shim::{other, other_error};
@ -166,7 +164,7 @@ impl Container for RuncContainer {
}; };
let terminal = process.common.stdio.terminal; let terminal = process.common.stdio.terminal;
let socket = if 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()); exec_opts.console_socket = Some(s.path.to_owned());
Some(s) Some(s)
} else { } else {
@ -456,7 +454,7 @@ impl InitProcess {
.no_new_keyring(self.no_new_key_ring) .no_new_keyring(self.no_new_key_ring)
.detach(false); .detach(false);
let socket = if terminal { 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()); create_opts.console_socket = Some(s.path.to_owned());
Some(s) Some(s)
} else { } else {

View File

@ -61,8 +61,8 @@ where
path_to_string(abs_path_buf(path)?) path_to_string(abs_path_buf(path)?)
} }
/// Fetches the value of environment variable "XDG_RUNTIME_DIR", returning a temporary directory /// Returns a temp dir. If the environment variable "XDG_RUNTIME_DIR" is set, return its value.
/// if the variable isn't set /// Otherwise if `std::env::temp_dir()` failed, return current dir or return the temp dir depended on OS.
fn xdg_runtime_dir() -> String { fn xdg_runtime_dir() -> String {
env::var("XDG_RUNTIME_DIR") env::var("XDG_RUNTIME_DIR")
.unwrap_or_else(|_| abs_string(env::temp_dir()).unwrap_or_else(|_| ".".to_string())) .unwrap_or_else(|_| abs_string(env::temp_dir()).unwrap_or_else(|_| ".".to_string()))

View File

@ -14,7 +14,6 @@
limitations under the License. limitations under the License.
*/ */
use std::env;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use log::warn; use log::warn;
@ -22,6 +21,7 @@ use tokio::net::{UnixListener, UnixStream};
use uuid::Uuid; use uuid::Uuid;
use crate::asynchronous::util::mkdir; use crate::asynchronous::util::mkdir;
use crate::util::xdg_runtime_dir;
use crate::Error; use crate::Error;
use crate::Result; use crate::Result;
@ -33,8 +33,7 @@ pub struct ConsoleSocket {
impl ConsoleSocket { impl ConsoleSocket {
pub async fn new() -> Result<ConsoleSocket> { pub async fn new() -> Result<ConsoleSocket> {
let dir = env::var("XDG_RUNTIME_DIR") let dir = format!("{}/pty{}", xdg_runtime_dir(), Uuid::new_v4());
.map(|runtime_dir| format!("{}/pty{}", runtime_dir, Uuid::new_v4(),))?;
mkdir(&dir, 0o711).await?; mkdir(&dir, 0o711).await?;
let file_name = Path::new(&dir).join("pty.sock"); let file_name = Path::new(&dir).join("pty.sock");
let listener = UnixListener::bind(&file_name).map_err(io_error!( let listener = UnixListener::bind(&file_name).map_err(io_error!(

View File

@ -15,9 +15,14 @@
*/ */
use std::os::unix::net::{UnixListener, UnixStream}; use std::os::unix::net::{UnixListener, UnixStream};
use std::path::PathBuf; use std::path::{Path, PathBuf};
use log::warn; use log::warn;
use uuid::Uuid;
use crate::util::{mkdir, xdg_runtime_dir};
use crate::Error;
use crate::Result;
pub struct ConsoleSocket { pub struct ConsoleSocket {
pub listener: UnixListener, pub listener: UnixListener,
@ -26,6 +31,22 @@ pub struct ConsoleSocket {
} }
impl ConsoleSocket { impl ConsoleSocket {
pub fn new() -> Result<ConsoleSocket> {
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<UnixStream> { pub fn accept(&self) -> std::io::Result<UnixStream> {
let (stream, _addr) = self.listener.accept()?; let (stream, _addr) = self.listener.accept()?;
Ok(stream) Ok(stream)

View File

@ -14,21 +14,17 @@
limitations under the License. limitations under the License.
*/ */
use std::env;
use std::fs::{rename, File, OpenOptions}; use std::fs::{rename, File, OpenOptions};
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::os::unix::net::UnixListener;
use std::path::Path; use std::path::Path;
use libc::mode_t;
use log::warn; use log::warn;
use nix::sys::stat::Mode; use nix::sys::stat::Mode;
use nix::unistd::mkdir;
use oci_spec::runtime::Spec; use oci_spec::runtime::Spec;
use uuid::Uuid;
use containerd_shim_protos::shim::oci::Options; use containerd_shim_protos::shim::oci::Options;
use crate::console::ConsoleSocket;
use crate::util::{JsonOptions, OPTIONS_FILE_NAME, RUNTIME_FILE_NAME}; use crate::util::{JsonOptions, OPTIONS_FILE_NAME, RUNTIME_FILE_NAME};
use crate::Error; use crate::Error;
@ -118,21 +114,13 @@ pub fn read_spec_from_file(bundle: &str) -> crate::Result<Spec> {
Spec::load(path).map_err(other_error!(e, "read spec file")) Spec::load(path).map_err(other_error!(e, "read spec file"))
} }
pub fn new_temp_console_socket() -> crate::Result<ConsoleSocket> { pub fn mkdir(path: impl AsRef<Path>, mode: mode_t) -> crate::Result<()> {
let dir = env::var("XDG_RUNTIME_DIR") let path_buf = path.as_ref().to_path_buf();
.map(|runtime_dir| format!("{}/pty{}", runtime_dir, Uuid::new_v4(),))?; if !path_buf.as_path().exists() {
mkdir(Path::new(&dir), Mode::from_bits(0o711).unwrap())?; let mode = Mode::from_bits(mode).ok_or_else(|| other!("invalid dir mode {}", mode))?;
let file_name = Path::new(&dir).join("pty.sock"); nix::unistd::mkdir(path_buf.as_path(), mode)?;
let listener = UnixListener::bind(file_name.as_path()).map_err(io_error!( }
e, Ok(())
"bind socket {}",
file_name.display()
))?;
Ok(ConsoleSocket {
listener,
path: file_name,
rmdir: true,
})
} }
/// A helper to help remove temperate file or dir when it became useless /// A helper to help remove temperate file or dir when it became useless

View File

@ -14,6 +14,7 @@
limitations under the License. limitations under the License.
*/ */
use std::env;
use std::os::unix::io::RawFd; use std::os::unix::io::RawFd;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
@ -155,6 +156,13 @@ pub fn any(event: impl Message) -> Result<Any> {
Ok(any) 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 pub trait IntoOption
where where
Self: Sized, Self: Sized,