feat(ll-box): initial implementation of `list` and `kill`

Signed-off-by: black-desk <me@black-desk.cn>
This commit is contained in:
black-desk 2024-04-23 16:35:24 +08:00
parent 2728b0f3bb
commit 5998dd3e79
No known key found for this signature in database
GPG Key ID: 761EE6143999AE8B
3 changed files with 76 additions and 6 deletions

View File

@ -35,4 +35,27 @@ void writeContainerJson(const std::string &bundle, const std::string &id, pid_t
assert(false);
}
}
nlohmann::json readAllContainerJson() noexcept
{
nlohmann::json result = nlohmann::json::array();
auto dir =
std::filesystem::path("/run") / "user" / std::to_string(getuid()) / "linglong" / "box";
for (auto entry : std::filesystem::directory_iterator{ dir }) {
std::ifstream containerInfo = entry.path();
if (!containerInfo.is_open()) {
continue;
}
try {
nlohmann::json j = nlohmann::json::parse(containerInfo);
result.push_back(j);
} catch (const std::exception &e) {
logErr() << "parse" << entry.path() << "failed" << e.what();
}
}
return result;
}
} // namespace linglong

View File

@ -6,9 +6,11 @@
#ifndef LINGLONG_BOX_CONTAINER_HELPER_H_
#define LINGLONG_BOX_CONTAINER_HELPER_H_
#include <nlohmann/json.hpp>
#include <string>
namespace linglong {
void writeContainerJson(const std::string &bundle, const std::string &id, pid_t pid);
};
nlohmann::json readAllContainerJson() noexcept;
}; // namespace linglong
#endif

View File

@ -5,12 +5,14 @@
*/
#include "container/container.h"
#include "container/helper.h"
#include "util/logger.h"
#include "util/message_reader.h"
#include "util/oci_runtime.h"
#include <argp.h>
#include <csignal>
#include <iostream>
#include <fcntl.h>
@ -46,7 +48,7 @@ int parse_opt(int key, char *arg, struct argp_state *state)
return 0;
}
argp_failure(state, 1, 0, "invalid cgroup manager", arg);
argp_failure(state, 1, 0, "invalid cgroup manager %s", arg);
return -1;
case 'b':
@ -59,6 +61,9 @@ int parse_opt(int key, char *arg, struct argp_state *state)
config = arg;
return 0;
case 'f':
return 0;
case ARGP_KEY_ARG:
if (!command) {
@ -138,8 +143,9 @@ int parse_opt(int key, char *arg, struct argp_state *state)
int list() noexcept
{
logErr() << "Not implemented yet";
return -1;
auto containers = linglong::readAllContainerJson();
std::cout << containers.dump() << std::endl;
return 0;
}
int exec() noexcept
@ -166,6 +172,25 @@ try {
return -1;
}
int kill() noexcept
{
auto containers = linglong::readAllContainerJson();
auto id = container.value();
for (auto container : containers) {
if (container["id"] != id) {
continue;
}
auto pid = container["pid"].get<pid_t>();
// FIXME: parse signal
return ::kill(pid, SIGTERM);
}
return -1;
}
} // namespace
int main(int argc, char **argv)
@ -212,19 +237,35 @@ int main(int argc, char **argv)
.doc = "Override the configuration file to use. The default value is config.json",
.group = 2,
},
{
.name = nullptr,
.key = 0,
.arg = nullptr,
.flags = 0,
.doc = "List options",
.group = 3,
},
{
.name = "format",
.key = 'f',
.arg = "FORMAT",
.flags = 0,
.doc = "Output format (default \"json\")",
.group = 3,
},
{ nullptr },
};
argp argp = {
.options = options,
.parser = parse_opt,
.args_doc = R"(list
.args_doc = R"(list -f json
run <CONTAINER>
exec <CONTAINER> <CMD>
kill <CONTAINER> <SIGNAL>)",
};
if (argp_parse(&argp, argc, argv, 0, nullptr, nullptr) != 0) {
if (argp_parse(&argp, argc, argv, ARGP_NO_EXIT, nullptr, nullptr) != 0) {
return -1;
}
@ -240,5 +281,9 @@ kill <CONTAINER> <SIGNAL>)",
return exec();
}
if (command == "kill") {
return kill();
}
return -1;
}