1010#include " linyaps_box/utils/log.h"
1111#include " linyaps_box/utils/process.h"
1212#include " linyaps_box/utils/session.h"
13+ #include " nlohmann/json.hpp"
1314
1415#include < csignal> // IWYU pragma: keep
1516#include < utility>
1617
1718#include < unistd.h>
1819
19- linyaps_box::container_ref::container_ref (const status_directory & status_dir, std::string id)
20+ linyaps_box::container_ref::container_ref (status_directory status_dir, std::string id)
2021 : id_(std::move(id))
21- , status_dir_(status_dir)
22+ , status_dir_(std::move( status_dir) )
2223{
2324}
2425
2526linyaps_box::container_ref::~container_ref () noexcept = default ;
2627
2728linyaps_box::container_status_t linyaps_box::container_ref::status () const
2829{
29- return this -> status_dir_ .read (this -> id_ );
30+ return status_dir_.read ();
3031}
3132
3233void linyaps_box::container_ref::kill (int signal) const
@@ -47,7 +48,6 @@ auto linyaps_box::container_ref::exec(exec_container_option option) -> int
4748{
4849 auto target = std::to_string (this ->status ().PID );
4950
50- // TODO: support detach later
5151 std::ignore = utils::prctl (PR_SET_CHILD_SUBREAPER , 1 , 0 , 0 , 0 );
5252
5353 std::optional<unix_socket> recv_socketpair;
@@ -63,31 +63,45 @@ auto linyaps_box::container_ref::exec(exec_container_option option) -> int
6363 }
6464
6565 if (child == 0 ) {
66- // TODO: create terminal after rewrite exec. it should be created in the container namespace
6766 if (option.console_socket ) {
6867 utils::setsid ();
6968 auto [master, slave] = create_pty_pair ();
7069
7170 slave.setup_stdio ();
72- // TODO: use fchown after we implement exec option `--user`
7371 slave.set_size ({ });
7472
7573 option.console_socket ->send_fd (std::move (master).take ());
7674 option.console_socket .reset ();
7775 }
7876
79- std::vector<const char *> argv{
80- " nsenter" ,
81- " --target" ,
82- target.c_str (),
83- " --user" ,
84- " --mount" ,
85- " --pid" ,
86- // FIXME:
87- // Old nsenter command do not support --wdns,
88- // so we have to implement nsenter by ourself in the future.
89- " --preserve-credentials" ,
90- };
77+ std::vector<const char *> argv{ " nsenter" , " --target" , target.c_str () };
78+
79+ auto config_str = status_dir_.read_config ();
80+ auto config = nlohmann::json::parse (config_str);
81+ const auto &linux = config.at (" linux" );
82+ assert (!linux.is_null ());
83+
84+ // FIXME: we assume that container always unshare some namespaces for now
85+ // support exec commands without setns in the future
86+ for (const auto &ns : linux.at (" namespaces" )) {
87+ const auto &type = ns.at (" type" );
88+ if (type == " pid" ) {
89+ argv.push_back (" --pid" );
90+ } else if (type == " mount" ) {
91+ argv.push_back (" --mount" );
92+ } else if (type == " uts" ) {
93+ argv.push_back (" --uts" );
94+ } else if (type == " ipc" ) {
95+ argv.push_back (" --ipc" );
96+ } else if (type == " network" ) {
97+ argv.push_back (" --net" );
98+ } else if (type == " user" ) {
99+ argv.push_back (" --user" );
100+ } else if (type == " cgroup" ) {
101+ argv.push_back (" --cgroup" );
102+ }
103+ }
104+ argv.push_back (" --preserve-credentials" );
91105
92106 for (const auto &arg : option.proc .args ) {
93107 argv.push_back (arg.c_str ());
@@ -101,20 +115,6 @@ auto linyaps_box::container_ref::exec(exec_container_option option) -> int
101115 }
102116 c_env.push_back (nullptr );
103117
104- // FIXME:
105- // We only handle the command arguments for now
106- // here are some other fields in process we need to consider:
107- // terminal
108- // console.height
109- // console.width
110- // cwd
111- // env
112- // rlimits
113- // apparmor_profile
114- // capabilities
115- // no_new_privileges
116- // oom_score_adj
117-
118118 ::execvpe (" nsenter" , const_cast <char **>(argv.data()), const_cast<char **>(c_env.data()));
119119 _exit (EXIT_FAILURE );
120120 }
@@ -148,10 +148,10 @@ auto linyaps_box::container_ref::exec(exec_container_option option) -> int
148148
149149const linyaps_box::status_directory &linyaps_box::container_ref::status_dir () const
150150{
151- return this -> status_dir_ ;
151+ return status_dir_;
152152}
153153
154154const std::string &linyaps_box::container_ref::get_id () const
155155{
156- return this -> id_ ;
156+ return id_;
157157}
0 commit comments