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::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 {

View File

@ -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()))

View File

@ -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<ConsoleSocket> {
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!(

View File

@ -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<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> {
let (stream, _addr) = self.listener.accept()?;
Ok(stream)

View File

@ -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> {
Spec::load(path).map_err(other_error!(e, "read spec file"))
}
pub fn new_temp_console_socket() -> crate::Result<ConsoleSocket> {
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<Path>, 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

View File

@ -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<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
where
Self: Sized,