cnf_lib/environment/
host.rs

1// Copyright (C) 2023 Andreas Hartmann <hartan@7x.de>
2// GNU General Public License v3.0+ (https://www.gnu.org/licenses/gpl-3.0.txt)
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5//! # Host Environment Handler.
6//!
7//! This module handles command-not-found errors that occur while executing on the host OS.
8//! Currently this means that the command is forwarded to a Toolbx container of choice, preferrably
9//! one specified in the configuration file or the default one otherwise.
10use super::prelude::*;
11
12#[derive(PartialEq, Eq, Debug, PartialOrd, Ord, Serialize, Deserialize)]
13pub struct Host {}
14
15impl fmt::Display for Host {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        write!(f, "host")
18    }
19}
20
21impl Host {
22    pub fn new() -> Host {
23        Host {}
24    }
25}
26
27impl std::default::Default for Host {
28    fn default() -> Self {
29        Self::new()
30    }
31}
32
33#[async_trait]
34impl environment::IsEnvironment for Host {
35    type Err = std::convert::Infallible;
36
37    async fn exists(&self) -> bool {
38        true
39    }
40
41    async fn execute(&self, command: CommandLine) -> Result<Command, Self::Err> {
42        debug!("preparing execution: {}", command);
43        let mut cmd: Command;
44
45        match environment::current() {
46            Environment::Host(_) => {
47                if command.get_privileged() {
48                    if cfg!(unix) {
49                        cmd = Command::new("sudo");
50                        cmd.arg("-S");
51                        if !command.get_interactive() {
52                            cmd.arg("-n");
53                        }
54                    } else {
55                        unimplemented!("cannot escalate privileges yet for platforms not Unix");
56                    }
57
58                    cmd.arg(command.command());
59                } else {
60                    cmd = Command::new(command.command());
61                }
62
63                cmd.args(command.args());
64            }
65            Environment::Toolbx(_) | Environment::Distrobox(_) => {
66                // flatpak-spawn --host ARGS
67                cmd = Command::new("flatpak-spawn");
68                cmd.arg("--host");
69
70                // Preserve environment
71                for env in environment::read_env_vars() {
72                    cmd.arg(format!("--env={}", env));
73                }
74
75                if command.get_privileged() {
76                    if cfg!(unix) {
77                        cmd.args(["sudo", "-S", "-E"]);
78                        if !command.get_interactive() {
79                            cmd.arg("-n");
80                        }
81                    } else {
82                        unimplemented!("cannot escalate privileges yet for platforms not Unix");
83                    }
84                }
85
86                cmd.arg(command.command());
87                cmd.args(command.args());
88            }
89            #[cfg(test)]
90            Environment::Mock(_) => {
91                unimplemented!()
92            }
93        }
94
95        trace!("full command: {:?}", cmd);
96        Ok(cmd)
97    }
98}