Skip to content

Commit

Permalink
src/*: implement features
Browse files Browse the repository at this point in the history
Fixes: #1177
Signed-off-by: Sohan Kunkerkar <[email protected]>
  • Loading branch information
sohankunkerkar committed Jun 20, 2023
1 parent 7da99fb commit 2ed1f0b
Show file tree
Hide file tree
Showing 8 changed files with 401 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ dist-luarock: $(LUACRUN_ROCK)
endif

crun_CFLAGS = -I $(abs_top_builddir)/libocispec/src -I $(abs_top_srcdir)/libocispec/src -D CRUN_LIBDIR="\"$(CRUN_LIBDIR)\""
crun_SOURCES = src/crun.c src/run.c src/delete.c src/kill.c src/pause.c src/unpause.c src/spec.c \
crun_SOURCES = src/crun.c src/run.c src/delete.c src/kill.c src/pause.c src/unpause.c src/features.c src/spec.c \
src/exec.c src/list.c src/create.c src/start.c src/state.c src/update.c src/ps.c \
src/checkpoint.c src/restore.c src/libcrun/cloned_binary.c

Expand All @@ -143,7 +143,7 @@ endif

EXTRA_DIST = COPYING COPYING.libcrun README.md NEWS SECURITY.md rpm/crun.spec.in autogen.sh \
src/crun.h src/list.h src/run.h src/delete.h src/kill.h src/pause.h src/unpause.h \
src/create.h src/start.h src/state.h src/exec.h src/spec.h src/update.h src/ps.h \
src/create.h src/start.h src/state.h src/exec.h src/features.h src/spec.h src/update.h src/ps.h \
src/checkpoint.h src/restore.h src/libcrun/seccomp_notify.h src/libcrun/seccomp_notify_plugin.h \
src/libcrun/container.h src/libcrun/seccomp.h src/libcrun/ebpf.h \
src/libcrun/cgroup.h src/libcrun/cgroup-cgroupfs.h \
Expand Down
4 changes: 4 additions & 0 deletions src/crun.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "spec.h"
#include "pause.h"
#include "unpause.h"
#include "features.h"
#include "ps.h"
#include "checkpoint.h"
#include "restore.h"
Expand Down Expand Up @@ -137,6 +138,7 @@ enum
COMMAND_UPDATE,
COMMAND_PAUSE,
COMMAND_UNPAUSE,
COMMAND_FEATURES,
COMMAND_PS,
COMMAND_CHECKPOINT,
COMMAND_RESTORE,
Expand All @@ -155,6 +157,7 @@ struct commands_s commands[] = { { COMMAND_CREATE, "create", crun_command_create
{ COMMAND_UPDATE, "update", crun_command_update },
{ COMMAND_PAUSE, "pause", crun_command_pause },
{ COMMAND_UNPAUSE, "resume", crun_command_unpause },
{ COMMAND_FEATURES, "features", crun_command_features },
#if HAVE_CRIU && HAVE_DLOPEN
{ COMMAND_CHECKPOINT, "checkpoint", crun_command_checkpoint },
{ COMMAND_RESTORE, "restore", crun_command_restore },
Expand All @@ -170,6 +173,7 @@ static char doc[] = "\nCOMMANDS:\n"
"\tcreate - create a container\n"
"\tdelete - remove definition for a container\n"
"\texec - exec a command in a running container\n"
"\tfeatures - show the enabled features\n"
"\tlist - list known containers\n"
"\tkill - send a signal to the container init process\n"
"\tps - show the processes in the container\n"
Expand Down
191 changes: 191 additions & 0 deletions src/features.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
/*
* crun - OCI runtime written in C
*
* crun is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* crun is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with crun. If not, see <http://www.gnu.org/licenses/>.
*/

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <argp.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <yajl/yajl_tree.h>
#include <yajl/yajl_gen.h>

#include "crun.h"
#include "libcrun/container.h"
#include "libcrun/utils.h"

static char doc[] = "OCI runtime";

static struct argp_option options[] = { {0} };

static char args_doc[] = "features";

static error_t
parse_opt (int key, char *arg arg_unused, struct argp_state *state arg_unused)
{
if (key != ARGP_KEY_NO_ARGS) {
return ARGP_ERR_UNKNOWN;
}

return 0;
}

static struct argp run_argp = { options, parse_opt, args_doc, doc, NULL, NULL, NULL };

int crun_command_features(struct crun_global_arguments *global_args, int argc, char **argv, libcrun_error_t *err) {
argp_parse(&run_argp, argc, argv, 0, 0, &options);

// Call the function in features.c to gather the feature information
struct features_info_s info;
int result = libcrun_container_print_features(&info);
if (result != 0) {
libcrun_make_error(err, result, "Failed to gather features information.");
return result;
}

// Prepare the JSON output
yajl_gen jsonGen = yajl_gen_alloc(NULL);
yajl_gen_status status;

yajl_gen_config(jsonGen, yajl_gen_beautify, 1); // Optional: Enable pretty formatting

// Start building the JSON
yajl_gen_map_open(jsonGen);

// Add ociVersionMin field
yajl_gen_string(jsonGen, (const unsigned char *) "ociVersionMin", strlen("ociVersionMin"));
yajl_gen_string(jsonGen, (const unsigned char *) info.ociVersionMin, strlen(info.ociVersionMin));

// Add ociVersionMax field
yajl_gen_string(jsonGen, (const unsigned char *) "ociVersionMax", strlen("ociVersionMax"));
yajl_gen_string(jsonGen, (const unsigned char *) info.ociVersionMax, strlen(info.ociVersionMax));

// Add hooks array
yajl_gen_string(jsonGen, (const unsigned char *) "hooks", strlen("hooks"));
yajl_gen_array_open(jsonGen);

for (size_t i = 0; info.hooks[i] != NULL; i++) {
yajl_gen_string(jsonGen, (const unsigned char *) info.hooks[i], strlen(info.hooks[i]));
}

yajl_gen_array_close(jsonGen);

// Add mountOptions array
yajl_gen_string(jsonGen, (const unsigned char *) "mountOptions", strlen("mountOptions"));
yajl_gen_array_open(jsonGen);

for (size_t i = 0; info.mountOptions[i] != NULL; i++) {
yajl_gen_string(jsonGen, (const unsigned char *) info.mountOptions[i], strlen(info.mountOptions[i]));
}

yajl_gen_array_close(jsonGen);

yajl_gen_string(jsonGen, (const unsigned char *) "linux", strlen("linux"));
yajl_gen_map_open(jsonGen);

// Add namespaces array
yajl_gen_string(jsonGen, (const unsigned char *) "namespaces", strlen("namespaces"));
yajl_gen_array_open(jsonGen);

for (size_t i = 0; info.linux.namespaces[i] != NULL; i++) {
yajl_gen_string(jsonGen, (const unsigned char *) info.linux.namespaces[i], strlen(info.linux.namespaces[i]));
}

yajl_gen_array_close(jsonGen);

// Add capabilities array
yajl_gen_string(jsonGen, (const unsigned char *) "capabilities", strlen("capabilities"));
yajl_gen_array_open(jsonGen);

for (size_t i = 0; info.linux.capabilities[i] != NULL; i++) {
yajl_gen_string(jsonGen, (const unsigned char *) info.linux.capabilities[i], strlen(info.linux.capabilities[i]));
}

yajl_gen_array_close(jsonGen);

// Generate the "cgroup" field
yajl_gen_string(jsonGen, (const unsigned char *) "cgroup", strlen("cgroup"));
yajl_gen_map_open(jsonGen);

// Generate the "v1" field
yajl_gen_string(jsonGen, (const unsigned char *) "v1", strlen("v1"));
yajl_gen_bool(jsonGen, info.linux.cgroup.v1);

// Generate the "v2" field
yajl_gen_string(jsonGen, (const unsigned char *) "v2", strlen("v2"));
yajl_gen_bool(jsonGen, info.linux.cgroup.v2);

// Generate the "systemd" field
yajl_gen_string(jsonGen, (const unsigned char *) "systemd", strlen("systemd"));
yajl_gen_bool(jsonGen, info.linux.cgroup.systemd);

// Generate the "systemdUser" field
yajl_gen_string(jsonGen, (const unsigned char *) "systemdUser", strlen("systemdUser"));
yajl_gen_bool(jsonGen, info.linux.cgroup.systemdUser);

yajl_gen_map_close(jsonGen);

// Add seccomp field with TODO comment
yajl_gen_string(jsonGen, (const unsigned char *) "seccomp", strlen("seccomp"));
yajl_gen_map_open(jsonGen);

yajl_gen_string(jsonGen, (const unsigned char *) "/* TODO: */", strlen("/* TODO: */"));

yajl_gen_map_close(jsonGen);


// Generate the "apparmor" field
yajl_gen_string(jsonGen, (const unsigned char *) "apparmor", strlen("apparmor"));
yajl_gen_map_open(jsonGen);

// Generate the "enabled" field
yajl_gen_string(jsonGen, (const unsigned char *) "enabled", strlen("enabled"));
yajl_gen_bool(jsonGen, info.linux.apparmor.enabled);

yajl_gen_map_close(jsonGen);

// Generate the "selinux" field
yajl_gen_string(jsonGen, (const unsigned char *) "selinux", strlen("selinux"));
yajl_gen_map_open(jsonGen);

// Generate the "enabled" field
yajl_gen_string(jsonGen, (const unsigned char *) "enabled", strlen("enabled"));
yajl_gen_bool(jsonGen, info.linux.selinux.enabled);

yajl_gen_map_close(jsonGen);

// End for linux build
yajl_gen_map_close(jsonGen);

// End building the JSON
yajl_gen_map_close(jsonGen);

// Get the JSON as a string
const unsigned char *jsonString;
size_t jsonLength;
yajl_gen_get_buf(jsonGen, &jsonString, &jsonLength);

// Print the JSON output to stdout
printf("%s", (const char *)jsonString);

// Clean up
yajl_gen_free(jsonGen);

return 0;
}
25 changes: 25 additions & 0 deletions src/features.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* crun - OCI runtime written in C
*
* Copyright (C) 2017, 2018, 2019 Giuseppe Scrivano <[email protected]>
* crun is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* crun is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with crun. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FEATURES_H
#define FEATURES_H

#include "crun.h"

int crun_command_features (struct crun_global_arguments *global_args, int argc, char **argv, libcrun_error_t *error);

#endif
Loading

0 comments on commit 2ed1f0b

Please sign in to comment.