Skip to main content

reverie_process/
namespace.rs

1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9use std::str::FromStr;
10
11use serde::Deserialize;
12use serde::Serialize;
13
14bitflags::bitflags! {
15    /// A namespace that may be unshared with [`Command::unshare`].
16    ///
17    /// [`Command::unshare`]: super::Command::unshare
18    #[derive(Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
19    pub struct Namespace: i32 {
20        /// Cgroup namespace.
21        const CGROUP = libc::CLONE_NEWCGROUP;
22        /// IPC namespace.
23        const IPC = libc::CLONE_NEWIPC;
24        /// Network namespace.
25        const NETWORK = libc::CLONE_NEWNET;
26        /// Mount namespace.
27        const MOUNT = libc::CLONE_NEWNS;
28        /// PID namespace.
29        const PID = libc::CLONE_NEWPID;
30        /// User and group namespace.
31        const USER = libc::CLONE_NEWUSER;
32        /// UTS namespace.
33        const UTS = libc::CLONE_NEWUTS;
34    }
35}
36
37impl Default for Namespace {
38    fn default() -> Self {
39        Self::empty()
40    }
41}
42
43#[derive(Debug, Clone)]
44pub enum ParseNamespaceError {
45    InvalidNamespace(String),
46}
47
48impl std::error::Error for ParseNamespaceError {}
49
50impl core::fmt::Display for ParseNamespaceError {
51    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
52        match self {
53            ParseNamespaceError::InvalidNamespace(ns) => {
54                write!(f, "Invalid namespace: {}", ns)
55            }
56        }
57    }
58}
59
60impl FromStr for Namespace {
61    type Err = ParseNamespaceError;
62    fn from_str(s: &str) -> Result<Self, ParseNamespaceError> {
63        s.split(',').try_fold(Namespace::empty(), |ns, s| match s {
64            "cgroup" => Ok(ns | Namespace::CGROUP),
65            "ipc" => Ok(ns | Namespace::IPC),
66            "network" => Ok(ns | Namespace::NETWORK),
67            "pid" => Ok(ns | Namespace::PID),
68            "mount" => Ok(ns | Namespace::MOUNT),
69            "user" => Ok(ns | Namespace::USER),
70            "uts" => Ok(ns | Namespace::UTS),
71            "" | "none" => Ok(ns),
72            invalid_ns => Err(ParseNamespaceError::InvalidNamespace(invalid_ns.to_owned())),
73        })
74    }
75}