425 lines
15 KiB
Diff
425 lines
15 KiB
Diff
From d766442be1dca15cff162671f367fa867ba74c94 Mon Sep 17 00:00:00 2001
|
|
From: liuhao <liuhao27@huawei.com>
|
|
Date: Thu, 2 May 2019 11:23:50 +0800
|
|
Subject: [PATCH 093/139] optimize isulad_kit operator
|
|
|
|
parse group add start container
|
|
|
|
Signed-off-by: liuhao <liuhao27@huawei.com>
|
|
Signed-off-by: LiFeng <lifeng68@huawei.com>
|
|
---
|
|
src/lxc/Makefile.am | 2 +
|
|
src/lxc/json/container_start_generate_config.c | 245 +++++++++++++++++++++++++
|
|
src/lxc/json/container_start_generate_config.h | 43 +++++
|
|
src/lxc/tools/lxc_start.c | 58 ++++++
|
|
4 files changed, 348 insertions(+)
|
|
create mode 100644 src/lxc/json/container_start_generate_config.c
|
|
create mode 100644 src/lxc/json/container_start_generate_config.h
|
|
|
|
diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
|
|
index 698f8f9..4ec2081 100644
|
|
--- a/src/lxc/Makefile.am
|
|
+++ b/src/lxc/Makefile.am
|
|
@@ -45,6 +45,7 @@ noinst_HEADERS = attach.h \
|
|
storage/storage_utils.h \
|
|
json/defs.h \
|
|
json/json_common.h \
|
|
+ json/container_start_generate_config.h \
|
|
json/oci_runtime_hooks.h \
|
|
json/oci_runtime_spec.h \
|
|
json/logger_json_file.h \
|
|
@@ -152,6 +153,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \
|
|
json/oci_runtime_hooks.c json/oci_runtime_hooks.h \
|
|
json/logger_json_file.c json/logger_json_file.h \
|
|
json/oci_runtime_spec.c json/oci_runtime_spec.h \
|
|
+ json/container_start_generate_config.c json/container_start_generate_config.h \
|
|
json/read-file.c json/read-file.h \
|
|
$(LSM_SOURCES)
|
|
|
|
diff --git a/src/lxc/json/container_start_generate_config.c b/src/lxc/json/container_start_generate_config.c
|
|
new file mode 100644
|
|
index 0000000..5ec8311
|
|
--- /dev/null
|
|
+++ b/src/lxc/json/container_start_generate_config.c
|
|
@@ -0,0 +1,245 @@
|
|
+// Generated from start-generate-config.json. Do not edit!
|
|
+#ifndef _GNU_SOURCE
|
|
+#define _GNU_SOURCE
|
|
+#endif
|
|
+#include <string.h>
|
|
+#include "read-file.h"
|
|
+#include "container_start_generate_config.h"
|
|
+
|
|
+container_start_generate_config *make_container_start_generate_config(yajl_val tree, struct parser_context *ctx, parser_error *err) {
|
|
+ container_start_generate_config *ret = NULL;
|
|
+ *err = 0;
|
|
+ if (tree == NULL)
|
|
+ return ret;
|
|
+ ret = safe_malloc(sizeof(*ret));
|
|
+ {
|
|
+ yajl_val val = get_val(tree, "uid", yajl_t_number);
|
|
+ if (val != NULL) {
|
|
+ int invalid = common_safe_uint(YAJL_GET_NUMBER(val), (unsigned int *)&ret->uid);
|
|
+ if (invalid) {
|
|
+ if (asprintf(err, "Invalid value '%s' with type 'UID' for key 'uid': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0)
|
|
+ *err = safe_strdup("error allocating memory");
|
|
+ free_container_start_generate_config(ret);
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ {
|
|
+ yajl_val val = get_val(tree, "gid", yajl_t_number);
|
|
+ if (val != NULL) {
|
|
+ int invalid = common_safe_uint(YAJL_GET_NUMBER(val), (unsigned int *)&ret->gid);
|
|
+ if (invalid) {
|
|
+ if (asprintf(err, "Invalid value '%s' with type 'GID' for key 'gid': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0)
|
|
+ *err = safe_strdup("error allocating memory");
|
|
+ free_container_start_generate_config(ret);
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ {
|
|
+ yajl_val tmp = get_val(tree, "additionalGids", yajl_t_array);
|
|
+ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) {
|
|
+ size_t i;
|
|
+ ret->additional_gids_len = YAJL_GET_ARRAY(tmp)->len;
|
|
+ ret->additional_gids = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->additional_gids));
|
|
+ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) {
|
|
+ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i];
|
|
+ if (val != NULL) {
|
|
+ int invalid = common_safe_uint(YAJL_GET_NUMBER(val), (unsigned int *)&ret->additional_gids[i]);
|
|
+ if (invalid) {
|
|
+ if (asprintf(err, "Invalid value '%s' with type 'GID' for key 'additionalGids': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0)
|
|
+ *err = safe_strdup("error allocating memory");
|
|
+ free_container_start_generate_config(ret);
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) {
|
|
+ int i;
|
|
+ for (i = 0; i < tree->u.object.len; i++)
|
|
+ if (strcmp(tree->u.object.keys[i], "uid") &&
|
|
+ strcmp(tree->u.object.keys[i], "gid") &&
|
|
+ strcmp(tree->u.object.keys[i], "additionalGids")) {
|
|
+ if (ctx->stderr > 0)
|
|
+ fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]);
|
|
+ }
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+void free_container_start_generate_config(container_start_generate_config *ptr) {
|
|
+ if (ptr == NULL)
|
|
+ return;
|
|
+ free(ptr->additional_gids);
|
|
+ ptr->additional_gids = NULL;
|
|
+ free(ptr);
|
|
+}
|
|
+
|
|
+yajl_gen_status gen_container_start_generate_config(yajl_gen g, container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err) {
|
|
+ yajl_gen_status stat = yajl_gen_status_ok;
|
|
+ *err = 0;
|
|
+ stat = reformat_start_map(g);
|
|
+ if (yajl_gen_status_ok != stat)
|
|
+ GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->uid)) {
|
|
+ long long unsigned int num = 0;
|
|
+ stat = reformat_map_key(g, "uid", strlen("uid"));
|
|
+ if (yajl_gen_status_ok != stat)
|
|
+ GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
+ if (ptr != NULL && ptr->uid) {
|
|
+ num = (long long unsigned int)ptr->uid;
|
|
+ }
|
|
+ stat = reformat_uint(g, num);
|
|
+ if (yajl_gen_status_ok != stat)
|
|
+ GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
+ }
|
|
+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->gid)) {
|
|
+ long long unsigned int num = 0;
|
|
+ stat = reformat_map_key(g, "gid", strlen("gid"));
|
|
+ if (yajl_gen_status_ok != stat)
|
|
+ GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
+ if (ptr != NULL && ptr->gid) {
|
|
+ num = (long long unsigned int)ptr->gid;
|
|
+ }
|
|
+ stat = reformat_uint(g, num);
|
|
+ if (yajl_gen_status_ok != stat)
|
|
+ GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
+ }
|
|
+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->additional_gids != NULL)) {
|
|
+ size_t len = 0, i;
|
|
+ stat = reformat_map_key(g, "additionalGids", strlen("additionalGids"));
|
|
+ if (yajl_gen_status_ok != stat)
|
|
+ GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
+ if (ptr != NULL && ptr->additional_gids != NULL) {
|
|
+ len = ptr->additional_gids_len;
|
|
+ }
|
|
+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY))
|
|
+ yajl_gen_config(g, yajl_gen_beautify, 0);
|
|
+ stat = reformat_start_array(g);
|
|
+ if (yajl_gen_status_ok != stat)
|
|
+ GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
+ for (i = 0; i < len; i++) {
|
|
+ stat = reformat_uint(g, ptr->additional_gids[i]);
|
|
+ if (yajl_gen_status_ok != stat)
|
|
+ GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
+ }
|
|
+ stat = reformat_end_array(g);
|
|
+ if (yajl_gen_status_ok != stat)
|
|
+ GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY))
|
|
+ yajl_gen_config(g, yajl_gen_beautify, 1);
|
|
+ }
|
|
+ stat = reformat_end_map(g);
|
|
+ if (yajl_gen_status_ok != stat)
|
|
+ GEN_SET_ERROR_AND_RETURN(stat, err);
|
|
+ return yajl_gen_status_ok;
|
|
+}
|
|
+
|
|
+
|
|
+container_start_generate_config *container_start_generate_config_parse_file(const char *filename, struct parser_context *ctx, parser_error *err) {
|
|
+ container_start_generate_config *ptr = NULL;
|
|
+ size_t filesize;
|
|
+ char *content = NULL;
|
|
+
|
|
+ if (filename == NULL || err == NULL)
|
|
+ return NULL;
|
|
+
|
|
+ *err = NULL;
|
|
+ content = read_file(filename, &filesize);
|
|
+ if (content == NULL) {
|
|
+ if (asprintf(err, "cannot read the file: %s", filename) < 0)
|
|
+ *err = safe_strdup("error allocating memory");
|
|
+ return NULL;
|
|
+ }
|
|
+ ptr = container_start_generate_config_parse_data(content, ctx, err);
|
|
+ free(content);
|
|
+ return ptr;
|
|
+}
|
|
+
|
|
+container_start_generate_config *container_start_generate_config_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err) {
|
|
+ container_start_generate_config *ptr = NULL;
|
|
+ size_t filesize;
|
|
+ char *content = NULL ;
|
|
+
|
|
+ if (stream == NULL || err == NULL)
|
|
+ return NULL;
|
|
+
|
|
+ *err = NULL;
|
|
+ content = fread_file(stream, &filesize);
|
|
+ if (content == NULL) {
|
|
+ *err = safe_strdup("cannot read the file");
|
|
+ return NULL;
|
|
+ }
|
|
+ ptr = container_start_generate_config_parse_data(content, ctx, err);
|
|
+ free(content);
|
|
+ return ptr;
|
|
+}
|
|
+
|
|
+container_start_generate_config *container_start_generate_config_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err) {
|
|
+ container_start_generate_config *ptr = NULL;
|
|
+ yajl_val tree;
|
|
+ char errbuf[1024];
|
|
+ struct parser_context tmp_ctx;
|
|
+
|
|
+ if (jsondata == NULL || err == NULL)
|
|
+ return NULL;
|
|
+
|
|
+ *err = NULL;
|
|
+ if (ctx == NULL) {
|
|
+ ctx = &tmp_ctx;
|
|
+ (void)memset(&tmp_ctx, 0, sizeof(tmp_ctx));
|
|
+ }
|
|
+ tree = yajl_tree_parse(jsondata, errbuf, sizeof(errbuf));
|
|
+ if (tree == NULL) {
|
|
+ if (asprintf(err, "cannot parse the data: %s", errbuf) < 0)
|
|
+ *err = safe_strdup("error allocating memory");
|
|
+ return NULL;
|
|
+ }
|
|
+ ptr = make_container_start_generate_config(tree, ctx, err);
|
|
+ yajl_tree_free(tree);
|
|
+ return ptr;
|
|
+}
|
|
+char *container_start_generate_config_generate_json(container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err) {
|
|
+ yajl_gen g = NULL;
|
|
+ struct parser_context tmp_ctx;
|
|
+ const unsigned char *gen_buf = NULL;
|
|
+ char *json_buf = NULL;
|
|
+ size_t gen_len = 0;
|
|
+
|
|
+ if (ptr == NULL || err == NULL)
|
|
+ return NULL;
|
|
+
|
|
+ *err = NULL;
|
|
+ if (ctx == NULL) {
|
|
+ ctx = &tmp_ctx;
|
|
+ (void)memset(&tmp_ctx, 0, sizeof(tmp_ctx));
|
|
+ }
|
|
+
|
|
+ if (!json_gen_init(&g, ctx)) {
|
|
+ *err = safe_strdup("Json_gen init failed");
|
|
+ goto out;
|
|
+ }
|
|
+ if (yajl_gen_status_ok != gen_container_start_generate_config(g, ptr, ctx, err)) {
|
|
+ if (*err == NULL)
|
|
+ *err = safe_strdup("Failed to generate json");
|
|
+ goto free_out;
|
|
+ }
|
|
+ yajl_gen_get_buf(g, &gen_buf, &gen_len);
|
|
+ if (gen_buf == NULL) {
|
|
+ *err = safe_strdup("Error to get generated json");
|
|
+ goto free_out;
|
|
+ }
|
|
+
|
|
+ json_buf = safe_malloc(gen_len + 1);
|
|
+ (void)memcpy(json_buf, gen_buf, gen_len);
|
|
+ json_buf[gen_len] = '\0';
|
|
+
|
|
+free_out:
|
|
+ yajl_gen_clear(g);
|
|
+ yajl_gen_free(g);
|
|
+out:
|
|
+ return json_buf;
|
|
+}
|
|
diff --git a/src/lxc/json/container_start_generate_config.h b/src/lxc/json/container_start_generate_config.h
|
|
new file mode 100644
|
|
index 0000000..e1dcf56
|
|
--- /dev/null
|
|
+++ b/src/lxc/json/container_start_generate_config.h
|
|
@@ -0,0 +1,43 @@
|
|
+// Generated from start-generate-config.json. Do not edit!
|
|
+#ifndef CONTAINER_START_GENERATE_CONFIG_SCHEMA_H
|
|
+#define CONTAINER_START_GENERATE_CONFIG_SCHEMA_H
|
|
+
|
|
+#include <sys/types.h>
|
|
+#include <stdint.h>
|
|
+#include "json_common.h"
|
|
+#include "defs.h"
|
|
+
|
|
+#ifdef __cplusplus
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+typedef struct {
|
|
+ uid_t uid;
|
|
+
|
|
+ gid_t gid;
|
|
+
|
|
+ gid_t *additional_gids;
|
|
+ size_t additional_gids_len;
|
|
+
|
|
+}
|
|
+container_start_generate_config;
|
|
+
|
|
+void free_container_start_generate_config(container_start_generate_config *ptr);
|
|
+
|
|
+container_start_generate_config *make_container_start_generate_config(yajl_val tree, struct parser_context *ctx, parser_error *err);
|
|
+
|
|
+yajl_gen_status gen_container_start_generate_config(yajl_gen g, container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err);
|
|
+
|
|
+container_start_generate_config *container_start_generate_config_parse_file(const char *filename, struct parser_context *ctx, parser_error *err);
|
|
+
|
|
+container_start_generate_config *container_start_generate_config_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err);
|
|
+
|
|
+container_start_generate_config *container_start_generate_config_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err);
|
|
+
|
|
+char *container_start_generate_config_generate_json(container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err);
|
|
+
|
|
+#ifdef __cplusplus
|
|
+}
|
|
+#endif
|
|
+
|
|
+#endif
|
|
diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c
|
|
index af63f58..4069204 100644
|
|
--- a/src/lxc/tools/lxc_start.c
|
|
+++ b/src/lxc/tools/lxc_start.c
|
|
@@ -50,6 +50,7 @@
|
|
#include "confile.h"
|
|
#include "log.h"
|
|
#include "utils.h"
|
|
+#include "container_start_generate_config.h"
|
|
|
|
lxc_log_define(lxc_start, lxc);
|
|
|
|
@@ -213,6 +214,57 @@ static int ensure_path(char **confpath, const char *path)
|
|
return 0;
|
|
}
|
|
|
|
+static int set_start_extral_configs(const char *lxcpath, const char *name, struct lxc_container *c)
|
|
+{
|
|
+#define START_GENERATE_CONFIG "start_generate_config.json"
|
|
+ char fpath[PATH_MAX] = {0};
|
|
+ parser_error jerr = NULL;
|
|
+ int ret = -1;
|
|
+ container_start_generate_config *start_conf = NULL;
|
|
+ struct lxc_conf *lconf = c->lxc_conf;
|
|
+ size_t i = 0;
|
|
+
|
|
+ if (sprintf(fpath, "%s/%s/%s", lxcpath, name, START_GENERATE_CONFIG) < 0) {
|
|
+ ERROR("Sprintf config path failed");
|
|
+ return -1;
|
|
+ }
|
|
+ if (!file_exists(fpath)) {
|
|
+ return 0;
|
|
+ }
|
|
+ start_conf = container_start_generate_config_parse_file(fpath, NULL, &jerr);
|
|
+ if (start_conf == NULL) {
|
|
+ ERROR("Parse start generate config file: %s failed", fpath);
|
|
+ goto out;
|
|
+ }
|
|
+ if (start_conf->uid != 0) {
|
|
+ lconf->init_uid = start_conf->uid;
|
|
+ }
|
|
+ if (start_conf->gid != 0) {
|
|
+ lconf->init_gid = start_conf->gid;
|
|
+ }
|
|
+ if (start_conf->additional_gids != NULL && start_conf->additional_gids_len > 0) {
|
|
+ gid_t *tmp;
|
|
+ tmp = realloc(lconf->init_groups, (lconf->init_groups_len + start_conf->additional_gids_len) * sizeof(gid_t));
|
|
+ if (tmp == NULL) {
|
|
+ ERROR("Out of memory");
|
|
+ goto out;
|
|
+ }
|
|
+ lconf->init_groups = tmp;
|
|
+ for (; i < start_conf->additional_gids_len; i++) {
|
|
+ tmp[lconf->init_groups_len] = start_conf->additional_gids[i];
|
|
+ lconf->init_groups_len++;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ret = 0;
|
|
+out:
|
|
+ free(jerr);
|
|
+ if (start_conf != NULL) {
|
|
+ free_container_start_generate_config(start_conf);
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
int main(int argc, char *argv[])
|
|
{
|
|
const char *lxcpath;
|
|
@@ -358,6 +410,12 @@ int main(int argc, char *argv[])
|
|
}
|
|
}
|
|
|
|
+ /* isulad: load extral config for start container */
|
|
+ if (set_start_extral_configs(lxcpath, my_args.name, c) != 0) {
|
|
+ ERROR("Failed to load extral config for container");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
/* isulad: fifo used to monitor state of monitor process */
|
|
if (my_args.exit_monitor_fifo != NULL) {
|
|
c->exit_fifo = strdup(my_args.exit_monitor_fifo);
|
|
--
|
|
1.8.3.1
|
|
|