!318 bionic adaptation

From: @chegJH 
Reviewed-by: @duguhaotian 
Signed-off-by: @duguhaotian
This commit is contained in:
openeuler-ci-bot 2022-05-07 09:31:19 +00:00 committed by Gitee
commit 5c77d76ca2
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 939 additions and 7 deletions

View File

@ -1,7 +1,7 @@
From c0900d0bb68cb29484f670a67412447df316ff6e Mon Sep 17 00:00:00 2001 From c0900d0bb68cb29484f670a67412447df316ff6e Mon Sep 17 00:00:00 2001
From: zhangxiaoyu <zhangxiaoyu58@huawei.com> From: zhangxiaoyu <zhangxiaoyu58@huawei.com>
Date: Tue, 19 Apr 2022 18:33:16 +0800 Date: Tue, 19 Apr 2022 18:33:16 +0800
Subject: [PATCH 1/3] cleancode: http request Subject: [PATCH 1/5] cleancode: http request
Signed-off-by: zhangxiaoyu <zhangxiaoyu58@huawei.com> Signed-off-by: zhangxiaoyu <zhangxiaoyu58@huawei.com>
--- ---
@ -207,5 +207,5 @@ index 2ed7fbe8..0b53cf1e 100644
static void close_file(FILE *pagefile) static void close_file(FILE *pagefile)
-- --
2.25.1 2.32.0 (Apple Git-132)

View File

@ -1,7 +1,7 @@
From b58453982016f9a2f707b51ad54f12583aa21929 Mon Sep 17 00:00:00 2001 From b58453982016f9a2f707b51ad54f12583aa21929 Mon Sep 17 00:00:00 2001
From: wujing <wujing50@huawei.com> From: wujing <wujing50@huawei.com>
Date: Wed, 20 Apr 2022 10:52:30 +0800 Date: Wed, 20 Apr 2022 10:52:30 +0800
Subject: [PATCH 2/3] refactor mount parse in spec module Subject: [PATCH 2/5] refactor mount parse in spec module
Signed-off-by: wujing <wujing50@huawei.com> Signed-off-by: wujing <wujing50@huawei.com>
--- ---
@ -231,5 +231,5 @@ index 5644b21e..c89f077f 100644
if (tmpfs == NULL) { if (tmpfs == NULL) {
return NULL; return NULL;
-- --
2.25.1 2.32.0 (Apple Git-132)

View File

@ -1,7 +1,7 @@
From e0c13b23ddee161a6196ca2e0c970704e4bbef0e Mon Sep 17 00:00:00 2001 From e0c13b23ddee161a6196ca2e0c970704e4bbef0e Mon Sep 17 00:00:00 2001
From: WangFengTu <wangfengtu@huawei.com> From: WangFengTu <wangfengtu@huawei.com>
Date: Sun, 24 Apr 2022 14:18:26 +0800 Date: Sun, 24 Apr 2022 14:18:26 +0800
Subject: [PATCH 3/3] support isula wait even if it's not oci image Subject: [PATCH 3/5] support isula wait even if it's not oci image
Signed-off-by: WangFengTu <wangfengtu@huawei.com> Signed-off-by: WangFengTu <wangfengtu@huawei.com>
--- ---
@ -26,5 +26,5 @@ index 0e5b845c..2deb862c 100644
// `logs` sub-command // `logs` sub-command
"logs", false, cmd_logs_main, g_cmd_logs_desc, NULL, &g_cmd_logs_args "logs", false, cmd_logs_main, g_cmd_logs_desc, NULL, &g_cmd_logs_args
-- --
2.25.1 2.32.0 (Apple Git-132)

View File

@ -0,0 +1,267 @@
From 0f05484cceb58117f165bcc402156194289ea9c3 Mon Sep 17 00:00:00 2001
From: chengzrz <czrzrichard@gmail.com>
Date: Thu, 28 Apr 2022 19:11:46 +0800
Subject: [PATCH 4/5] add isula import restful mode
Signed-off-by: chengzrz <czrzrichard@gmail.com>
---
src/api/services/images/rest/image.rest.h | 3 +
src/client/connect/rest/rest_images_client.c | 107 ++++++++++++++++++
.../entry/connect/rest/rest_images_service.c | 89 +++++++++++++++
3 files changed, 199 insertions(+)
diff --git a/src/api/services/images/rest/image.rest.h b/src/api/services/images/rest/image.rest.h
index 6ebdc109..a61a285f 100644
--- a/src/api/services/images/rest/image.rest.h
+++ b/src/api/services/images/rest/image.rest.h
@@ -31,6 +31,8 @@
#include "isula_libutils/image_logout_response.h"
#include "isula_libutils/image_tag_image_request.h"
#include "isula_libutils/image_tag_image_response.h"
+#include "isula_libutils/image_import_request.h"
+#include "isula_libutils/image_import_response.h"
#ifndef RestHttpHead
#define RestHttpHead "http://localhost"
@@ -44,6 +46,7 @@
#define ImagesServiceLogin "/ImagesService/Login"
#define ImagesServiceLogout "/ImagesService/Logout"
#define ImagesServiceTag "/ImagesService/Tag"
+#define ImagesServiceImport "/ImagesService/Import"
#endif
diff --git a/src/client/connect/rest/rest_images_client.c b/src/client/connect/rest/rest_images_client.c
index ae754f76..3deeeead 100644
--- a/src/client/connect/rest/rest_images_client.c
+++ b/src/client/connect/rest/rest_images_client.c
@@ -858,6 +858,112 @@ out:
return ret;
}
+/* image import request to rest */
+static int image_import_request_to_rest(const struct isula_import_request *request, char **body, size_t *body_len)
+{
+ image_import_request *crequest = NULL;
+ parser_error err = NULL;
+ int ret = 0;
+
+ crequest = util_common_calloc_s(sizeof(image_import_request));
+ if (crequest == NULL) {
+ ERROR("Out of memory");
+ return -1;
+ }
+ crequest->file = util_strdup_s(request->file);
+ crequest->tag = util_strdup_s(request->tag);
+
+ *body = image_import_request_generate_json(crequest, NULL, &err);
+ if (*body == NULL) {
+ ERROR("Failed to generate image import request json:%s", err);
+ ret = -1;
+ goto out;
+ }
+ *body_len = strlen(*body) + 1;
+
+out:
+ free(err);
+ free_image_import_request(crequest);
+
+ return ret;
+}
+
+/* unpack image import response */
+static int unpack_image_import_response(const struct parsed_http_message *message, void *arg)
+{
+ struct isula_import_response *c_import_response = (struct isula_import_response *)arg;
+ image_import_response *import_response = NULL;
+ parser_error err = NULL;
+ int ret = 0;
+
+ ret = check_status_code(message->status_code);
+ if (ret != 0) {
+ ERROR("Tag image check status code failed.\n");
+ goto out;
+ }
+
+ import_response = image_import_response_parse_data(message->body, NULL, &err);
+ if (import_response == NULL) {
+ ERROR("Invalid import image response:%s", err);
+ ret = -1;
+ goto out;
+ }
+
+ c_import_response->server_errono = import_response->cc;
+ c_import_response->errmsg = util_strdup_s(import_response->errmsg);
+ c_import_response->id = util_strdup_s(import_response->id);
+
+ ret = (import_response->cc == ISULAD_SUCCESS) ? 0 : -1;
+ if (message->status_code == RESTFUL_RES_SERVERR) {
+ ret = -1;
+ }
+
+out:
+ free(err);
+ free_image_import_response(import_response);
+
+ return ret;
+}
+
+/* rest image import */
+static int rest_image_import(const struct isula_import_request *request, struct isula_import_response *response,
+ void *arg)
+{
+
+ client_connect_config_t *connect_config = (client_connect_config_t *)arg;
+ const char *socketname = (const char *)(connect_config->socket);
+ char *body = NULL;
+ Buffer *output = NULL;
+ int ret = 0;
+ size_t len = 0;
+
+ ret = image_import_request_to_rest(request, &body, &len);
+ if (ret != 0) {
+ goto out;
+ }
+
+ ret = rest_send_requst(socketname, RestHttpHead ImagesServiceImport, body, len, &output);
+ if (ret != 0) {
+ ERROR("Send import request failed.");
+ response->errmsg = util_strdup_s(errno_to_error_message(ISULAD_ERR_CONNECT));
+ response->cc = ISULAD_ERR_EXEC;
+ goto out;
+ }
+
+ ret = get_response(output, unpack_image_import_response, (void *)response);
+ if (ret != 0) {
+ ERROR("Get import response failed.");
+ goto out;
+ }
+
+out:
+ buffer_free(output);
+ put_body(body);
+
+ return ret;
+}
+
+
/* rest images client ops init */
int rest_images_client_ops_init(isula_connect_ops *ops)
{
@@ -873,6 +979,7 @@ int rest_images_client_ops_init(isula_connect_ops *ops)
ops->image.login = &rest_image_login;
ops->image.logout = &rest_image_logout;
ops->image.tag = &rest_image_tag;
+ ops->image.import = &rest_image_import;
return 0;
}
diff --git a/src/daemon/entry/connect/rest/rest_images_service.c b/src/daemon/entry/connect/rest/rest_images_service.c
index 39a3bd6c..7107d255 100644
--- a/src/daemon/entry/connect/rest/rest_images_service.c
+++ b/src/daemon/entry/connect/rest/rest_images_service.c
@@ -797,6 +797,90 @@ out:
free_image_tag_image_response(cresponse);
}
+/* image import request from rest */
+static int image_import_request_from_rest(evhtp_request_t *req, image_import_request **crequest)
+{
+ int ret = 0;
+ size_t body_len;
+ char *body = NULL;
+ parser_error err = NULL;
+
+ if (get_body(req, &body_len, &body) != 0) {
+ ERROR("Failed to get body");
+ return -1;
+ }
+
+ *crequest = image_import_request_parse_data(body, NULL, &err);
+ if (*crequest == NULL) {
+ ERROR("Invalid import request body:%s", err);
+ ret = -1;
+ goto out;
+ }
+
+out:
+ put_body(body);
+ free(err);
+
+ return ret;
+}
+
+/* evhtp send image import repsponse */
+static void evhtp_send_image_import_repsponse(evhtp_request_t *req, image_import_response *response, int rescode)
+{
+ parser_error err = NULL;
+ char *response_data = NULL;
+
+ response_data = image_import_response_generate_json(response, NULL, &err);
+ if (response_data != NULL) {
+ evhtp_send_response(req, response_data, rescode);
+ goto out;
+ }
+
+ ERROR("Import: failed to generate request json:%s", err);
+ evhtp_send_reply(req, RESTFUL_RES_ERROR);
+
+out:
+ free(response_data);
+ free(err);
+}
+
+/* rest image import cb */
+static void rest_image_import_cb(evhtp_request_t *req, void *arg)
+{
+ int tret;
+ service_executor_t *cb = NULL;
+ image_import_request *crequest = NULL;
+ image_import_response *cresponse = NULL;
+
+ // only deal with POST request
+ if (evhtp_request_get_method(req) != htp_method_POST) {
+ evhtp_send_reply(req, RESTFUL_RES_NOTIMPL);
+ return;
+ }
+
+ cb = get_service_executor();
+ if (cb == NULL || cb->image.import == NULL) {
+ ERROR("Unimplemented import callback");
+ evhtp_send_reply(req, RESTFUL_RES_NOTIMPL);
+ return;
+ }
+
+ tret = image_import_request_from_rest(req, &crequest);
+ if (tret < 0) {
+ ERROR("Bad request");
+ evhtp_send_reply(req, RESTFUL_RES_SERVERR);
+ goto out;
+ }
+
+ (void)cb->image.import(crequest, &cresponse);
+ evhtp_send_image_import_repsponse(req, cresponse, RESTFUL_RES_OK);
+
+out:
+ free_image_import_request(crequest);
+ free_image_import_response(cresponse);
+}
+
+
/* rest register images handler */
int rest_register_images_handler(evhtp_t *htp)
{
@@ -840,5 +924,10 @@ int rest_register_images_handler(evhtp_t *htp)
return -1;
}
+ if (evhtp_set_cb(htp, ImagesServiceImport, rest_image_import_cb, NULL) == NULL) {
+ ERROR("Failed to register image logout callback");
+ return -1;
+ }
+
return 0;
}
--
2.32.0 (Apple Git-132)

View File

@ -0,0 +1,657 @@
From 1d768559f42375eb3bbb3ad0de52a6b49535e40c Mon Sep 17 00:00:00 2001
From: chegJH <hejunjie10@huawei.com>
Date: Thu, 7 Apr 2022 17:33:06 +0800
Subject: [PATCH 5/5] Adapt to bionic libc, parser for passwd and group object
Signed-off-by: chegJH <hejunjie10@huawei.com>
---
.../modules/image/image_rootfs_handler.c | 25 ++
src/utils/cutils/utils_pwgr.c | 317 ++++++++++++++++++
src/utils/cutils/utils_pwgr.h | 33 ++
test/cutils/CMakeLists.txt | 1 +
test/cutils/utils_pwgr/CMakeLists.txt | 29 ++
test/cutils/utils_pwgr/group_sample | 8 +
test/cutils/utils_pwgr/passwd_sample | 11 +
test/cutils/utils_pwgr/utils_pwgr_ut.cc | 101 ++++++
8 files changed, 525 insertions(+)
create mode 100644 src/utils/cutils/utils_pwgr.c
create mode 100644 src/utils/cutils/utils_pwgr.h
create mode 100644 test/cutils/utils_pwgr/CMakeLists.txt
create mode 100644 test/cutils/utils_pwgr/group_sample
create mode 100644 test/cutils/utils_pwgr/passwd_sample
create mode 100644 test/cutils/utils_pwgr/utils_pwgr_ut.cc
diff --git a/src/daemon/modules/image/image_rootfs_handler.c b/src/daemon/modules/image/image_rootfs_handler.c
index f7bc9bc9..960d52c7 100644
--- a/src/daemon/modules/image/image_rootfs_handler.c
+++ b/src/daemon/modules/image/image_rootfs_handler.c
@@ -33,6 +33,7 @@
#include "path.h"
#include "utils_convert.h"
#include "utils_file.h"
+#include "utils_pwgr.h"
#define MINUID 0
#define MAXUID (((1LL << 31) - 1))
@@ -88,7 +89,11 @@ static int proc_by_fpasswd(FILE *f_passwd, const char *user, defs_process_user *
struct passwd *pwbufp = NULL;
if (f_passwd != NULL) {
+#ifdef __ANDROID__
+ errval = util_getpwent_r(f_passwd, &pw, buf, sizeof(buf), &pwbufp);
+#else
errval = fgetpwent_r(f_passwd, &pw, buf, sizeof(buf), &pwbufp);
+#endif
while (errval == 0 && pwbufp != NULL) {
userfound = b_user_found(user, pwbufp);
@@ -102,7 +107,11 @@ static int proc_by_fpasswd(FILE *f_passwd, const char *user, defs_process_user *
*matched_username = util_strdup_s(pwbufp->pw_name);
break;
}
+#ifdef __ANDROID__
+ errval = util_getpwent_r(f_passwd, &pw, buf, sizeof(buf), &pwbufp);
+#else
errval = fgetpwent_r(f_passwd, &pw, buf, sizeof(buf), &pwbufp);
+#endif
}
}
@@ -212,14 +221,22 @@ static int do_proc_by_froup(FILE *f_group, const char *group, defs_process_user
return 0;
}
+#ifdef __ANDROID__
+ errval = util_getgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
+#else
errval = fgetgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
+#endif
while (errval == 0 && gbufp != NULL) {
// Treat numeric group as valid GID
if (group == NULL) {
if (search_group_list(gbufp, matched_username, puser) != 0) {
return -1;
}
+#ifdef __ANDROID__
+ errval = util_getgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
+#else
errval = fgetgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
+#endif
continue;
}
@@ -229,7 +246,11 @@ static int do_proc_by_froup(FILE *f_group, const char *group, defs_process_user
puser->gid = gbufp->gr_gid;
*groupcnt = 1;
}
+#ifdef __ANDROID__
+ errval = util_getgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
+#else
errval = fgetgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
+#endif
}
return 0;
@@ -363,7 +384,11 @@ static int get_additional_groups(char **additional_groups, size_t additional_gro
struct group *gbufp = NULL;
struct group *groups = NULL;
+#ifdef __ANDROID__
+ while (f_group != NULL && util_getgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp) == 0) {
+#else
while (f_group != NULL && fgetgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp) == 0) {
+#endif
for (i = 0; i < additional_groups_len; i++) {
if (!group_matched(additional_groups[i], gbufp)) {
continue;
diff --git a/src/utils/cutils/utils_pwgr.c b/src/utils/cutils/utils_pwgr.c
new file mode 100644
index 00000000..f4588268
--- /dev/null
+++ b/src/utils/cutils/utils_pwgr.c
@@ -0,0 +1,317 @@
+/******************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
+ * iSulad licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Author: hejunjie
+ * Create: 2022-04-08
+ * Description: Provide line parser for android
+ *******************************************************************************/
+
+#define _GNU_SOURCE
+#include "utils_pwgr.h"
+
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio_ext.h>
+
+#include "isula_libutils/log.h"
+#include "utils_string.h"
+#include "utils_convert.h"
+#include "utils_file.h"
+#include "utils.h"
+
+static int hold_int(const char delim, bool required, char **src, unsigned int *dst)
+{
+ long long res = 0;
+ char *walker = *src;
+ char *err_str = NULL;
+
+ if (**src == '\0') {
+ ERROR("Empty subject on given entrie is not allowed.");
+ return -1;
+ }
+
+ while (*walker != delim) {
+ if (*walker == '\0') {
+ break;
+ }
+ ++walker;
+ }
+
+ if (*walker == **src) {
+ if (required) { // deafult 0 while required full content but integer part is missing
+ *dst = 0;
+ *src = walker + 1;
+ return 0;
+ }
+ ERROR("Integer part is missing.");
+ ++(*src);
+ return -1;
+ }
+
+ res = strtoll(*src, &err_str, 0);
+ if (errno == ERANGE) {
+ ERROR("Parse int from string failed.");
+ return -1;
+ }
+ if (res < 0) {
+ ERROR("Gid uid shall not be negative.");
+ return -1;
+ }
+
+ if (sizeof(void *) > 4 && res > UINT_MAX) { // make sure 64-bit platform behave same as 32-bit
+ res = UINT_MAX;
+ }
+ res = res & UINT_MAX;
+ *dst = (uint32_t)res;
+ *src = err_str + 1; // update src to next valid context in line.
+
+ return 0;
+}
+
+static int hold_string(const char delim, char **src, char **dst)
+{
+ if (**src == delim) { // if src point to deliminator, content parsing is skiped.
+ *dst = "";
+ *src = *src + 1;
+ return 0;
+ }
+
+ if (**src == '\0') {
+ return 0;
+ }
+
+ for (*dst = *src; **src != delim; ++(*src)) {
+ if (**src == '\0') {
+ break;
+ }
+ }
+ if (**src == delim) {
+ **src = '\0';
+ ++(*src);
+ }
+
+ return 0;
+}
+
+static int parse_line_pw(const char delim, char *line, struct passwd *result)
+{
+ int ret = 0;
+ bool required = false;
+
+ ret = hold_string(delim, &line, &result->pw_name);
+ if (ret != 0) {
+ ERROR("Parse name error.");
+ return ret;
+ }
+
+ required = (result->pw_name[0] == '+' || result->pw_name[0] == '-') ? true : false;
+
+ ret = hold_string(delim, &line, &result->pw_passwd);
+ if (ret != 0) {
+ ERROR("Parse passwd error.");
+ return ret;
+ }
+
+ ret = hold_int(delim, required, &line, &result->pw_uid);
+ if (ret != 0) {
+ // a legitimate line must have uid
+ ERROR("Parse uid error.");
+ return ret;
+ }
+ ret = hold_int(delim, required, &line, &result->pw_gid);
+ if (ret != 0) {
+ // it's ok to not provide gid
+ ERROR("Parse gid error.");
+ }
+
+ ret = hold_string(delim, &line, &result->pw_gecos);
+ if (ret != 0) {
+ ERROR("Parse gecos error.");
+ return ret;
+ }
+
+ ret = hold_string(delim, &line, &result->pw_dir);
+ if (ret != 0) {
+ ERROR("Parse dir error.");
+ return ret;
+ }
+
+ ret = hold_string(delim, &line, &result->pw_shell);
+ if (ret != 0) {
+ ERROR("Parse shell error.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static char **hold_string_list(char **line, char *buf_start, char *buf_end, const char terminator)
+{
+ char **result = NULL;
+ char **walker = NULL;
+
+ if (**line == '\0') {
+ return 0;
+ }
+ // For ultimate space usage, the blank area from buffer which was allocated from stack is used
+ buf_start += __alignof__(char *) - 1;
+ // align the starting position of the buffer to use it as a 2d array
+ buf_start -= (buf_start - (char *)0) % __alignof__(char *);
+ // record the starting position for latter return
+ result = (char **)buf_start;
+ // set stop edge for the buffer
+ walker = result;
+
+ for (; walker < (char **)buf_end; ++walker) {
+ (void)util_trim_space(*line);
+ if (hold_string(',', line, walker) != 0) {
+ ERROR("Parse string list error.");
+ return NULL;
+ }
+
+ if ((char *)(walker + 2) > buf_end) {
+ return NULL;
+ }
+
+ if (**line == '\0') {
+ return result;
+ }
+ }
+
+ return result;
+}
+
+static int parse_line_gr(const char delim, char *line, size_t buflen, struct group *result)
+{
+ int ret = 0;
+ bool rf = false;
+ char *freebuff = line + 1 + strlen(line);
+ char *buffend = line + buflen;
+
+ ret = hold_string(delim, &line, &result->gr_name);
+ if (ret != 0) {
+ ERROR("Parse name error.");
+ return ret;
+ }
+
+ ret = hold_string(delim, &line, &result->gr_passwd);
+ if (ret != 0) {
+ ERROR("Parse gecos error.");
+ return ret;
+ }
+ if (result->gr_name[0] == '+' || result->gr_name[0] == '-') {
+ rf = true;
+ }
+
+ ret = hold_int(delim, rf, &line, &result->gr_gid);
+ if (ret != 0) {
+ ERROR("Parse gid error.");
+ return ret;
+ }
+
+ result->gr_mem = hold_string_list(&line, freebuff, buffend, ',');
+
+ return 0;
+}
+
+int util_getpwent_r(FILE *stream, struct passwd *resbuf, char *buffer, size_t buflen, struct passwd **result)
+{
+ const char delim = ':';
+
+ if (stream == NULL || resbuf == NULL || buffer == NULL) {
+ ERROR("Password obj, params is NULL.");
+ return -1;
+ }
+
+ if (buflen <= 1) {
+ ERROR("Inadiquate buffer length was given.");
+ return -1;
+ }
+
+ if (*result != NULL) {
+ ERROR("Result shall point to null to start.");
+ return -1;
+ }
+
+ __fsetlocking(stream, FSETLOCKING_BYCALLER);
+ buffer[buflen - 1] = '\0';
+
+ if (feof(stream)) {
+ *result = NULL;
+ return ENOENT;
+ }
+
+ while (fgets(buffer, buflen, stream) != NULL) {
+ (void)util_trim_space(buffer);
+ if (buffer[0] == '\0' || buffer[0] == '#' || strlen(buffer) < 1) {
+ continue;
+ }
+
+ if (parse_line_pw(delim, buffer, resbuf) == 0) {
+ break;
+ }
+
+ if (buffer[buflen - 1] != '\0') {
+ *result = NULL;
+ return ERANGE;
+ }
+ }
+ *result = resbuf;
+
+ return 0;
+}
+
+int util_getgrent_r(FILE *stream, struct group *resbuf, char *buffer, size_t buflen, struct group **result)
+{
+ const char delim = ':';
+
+ if (stream == NULL || resbuf == NULL || buffer == NULL) {
+ ERROR("Group obj, params is NULL.");
+ return -1;
+ }
+
+ if (buflen <= 1) {
+ ERROR("Inadiquate buffer length was given.");
+ return -1;
+ }
+
+ if (*result != NULL) {
+ ERROR("Result shall point to null to start.");
+ return -1;
+ }
+
+ __fsetlocking(stream, FSETLOCKING_BYCALLER);
+ buffer[buflen - 1] = '\0';
+
+ if (feof(stream)) {
+ *result = NULL;
+ return ENOENT;
+ }
+
+ while (fgets(buffer, buflen, stream) != NULL) {
+ (void)util_trim_space(buffer);
+ if (buffer[0] == '\0' || buffer[0] == '#' || strlen(buffer) < 1) {
+ continue;
+ }
+
+ if (parse_line_gr(delim, buffer, buflen, resbuf) == 0) {
+ break;
+ }
+
+ if (buffer[buflen - 1] != '\0') {
+ *result = NULL;
+ return ERANGE;
+ }
+ }
+ *result = resbuf;
+
+ return 0;
+}
\ No newline at end of file
diff --git a/src/utils/cutils/utils_pwgr.h b/src/utils/cutils/utils_pwgr.h
new file mode 100644
index 00000000..45e38059
--- /dev/null
+++ b/src/utils/cutils/utils_pwgr.h
@@ -0,0 +1,33 @@
+/******************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
+ * iSulad licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Author: hejunjie
+ * Create: 2022-04-08
+ * Description: Provide line parser for android
+ *******************************************************************************/
+#ifndef UTILS_CUTILS_UTILS_PWGR_H
+#define UTILS_CUTILS_UTILS_PWGR_H
+
+#include <stdio.h>
+#include <pwd.h>
+#include <grp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int util_getpwent_r(FILE *stream, struct passwd *resbuf, char *buffer, size_t buflen, struct passwd **result);
+
+int util_getgrent_r(FILE *stream, struct group *resbuf, char *buffer, size_t buflen, struct group **result);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // UTILS_CUTILS_UTILS_PWGR_H
diff --git a/test/cutils/CMakeLists.txt b/test/cutils/CMakeLists.txt
index 826255cd..b549f844 100644
--- a/test/cutils/CMakeLists.txt
+++ b/test/cutils/CMakeLists.txt
@@ -4,3 +4,4 @@ add_subdirectory(utils_string)
add_subdirectory(utils_convert)
add_subdirectory(utils_array)
add_subdirectory(utils_base64)
+add_subdirectory(utils_pwgr)
diff --git a/test/cutils/utils_pwgr/CMakeLists.txt b/test/cutils/utils_pwgr/CMakeLists.txt
new file mode 100644
index 00000000..548718da
--- /dev/null
+++ b/test/cutils/utils_pwgr/CMakeLists.txt
@@ -0,0 +1,29 @@
+project(iSulad_UT)
+
+SET(EXE utils_pwgr_ut)
+
+add_executable(${EXE}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_string.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_array.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_file.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_convert.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_verify.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_regex.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_pwgr.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/sha256/sha256.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map/map.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map/rb_tree.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/path.c
+ utils_pwgr_ut.cc)
+
+target_include_directories(${EXE} PUBLIC
+ ${GTEST_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/common
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/sha256
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils
+ )
+target_link_libraries(${EXE} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${ISULA_LIBUTILS_LIBRARY} -lcrypto -lyajl -lz)
+add_test(NAME ${EXE} COMMAND ${EXE} --gtest_output=xml:${EXE}-Results.xml)
diff --git a/test/cutils/utils_pwgr/group_sample b/test/cutils/utils_pwgr/group_sample
new file mode 100644
index 00000000..c73883cc
--- /dev/null
+++ b/test/cutils/utils_pwgr/group_sample
@@ -0,0 +1,8 @@
+root:x:0:
+#bin:x:1:
+
+-adm:x:4:
++adm:x:4:
+adm:x:4:a,list,of,users
+adm:x:4:are,split,by,comma
+adm:x:4:root,john, boob,jason
\ No newline at end of file
diff --git a/test/cutils/utils_pwgr/passwd_sample b/test/cutils/utils_pwgr/passwd_sample
new file mode 100644
index 00000000..d4f3250d
--- /dev/null
+++ b/test/cutils/utils_pwgr/passwd_sample
@@ -0,0 +1,11 @@
+root:x:0:0:root:/root:/bin/bash
+bin:x:1:1:bin:/bin:/sbin/nologin
+bin:x:-1:1:bin:/bin:/sbin/nologin
+uidonly:x:1::bin:/bin:/sbin/nologin
+::::1:1:bin:/bin:/sbin/nologin
+
+#npt:*:66:77::/etc/ntp:/sbin/nologin
+npt:*:66:77::/etc/ntp:/sbin/nologin
+npt:*:66:77::/etc/ntp:/sbin/nologin:some:extra:context:added
++npt:*::::/etc/ntp:/sbin/nologin
+-npt:*::::/etc/ntp:/sbin/nologin
\ No newline at end of file
diff --git a/test/cutils/utils_pwgr/utils_pwgr_ut.cc b/test/cutils/utils_pwgr/utils_pwgr_ut.cc
new file mode 100644
index 00000000..1a121f88
--- /dev/null
+++ b/test/cutils/utils_pwgr/utils_pwgr_ut.cc
@@ -0,0 +1,101 @@
+/******************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
+ * iSulad licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Author: hejunjie
+ * Create: 2022-04-08
+ * Description: utils_pwgr unit test
+ *******************************************************************************/
+
+#include <gtest/gtest.h>
+#include "utils_pwgr.h"
+
+TEST(utils_pwgr, test_getpwent_r)
+{
+ std::string path = "../../../../test/cutils/utils_pwgr/passwd_sample";
+ FILE *f_pw = fopen(path.c_str(), "r");
+ ASSERT_NE(f_pw, nullptr);
+
+ struct passwd pw;
+ struct passwd *ppw = nullptr;
+ char buf[BUFSIZ];
+
+ std::vector<std::tuple<std::string, std::string, int, int, std::string, std::string, std::string>> testcase = {
+ std::make_tuple("root", "x", 0, 0, "root", "/root", "/bin/bash"),
+ std::make_tuple("bin", "x", 1, 1, "bin", "/bin", "/sbin/nologin"),
+ std::make_tuple("uidonly", "x", 1, 0, "bin", "/bin", "/sbin/nologin"),
+ std::make_tuple("npt", "*", 66, 77, "", "/etc/ntp", "/sbin/nologin"),
+ std::make_tuple("npt", "*", 66, 77, "", "/etc/ntp", "/sbin/nologin"),
+ std::make_tuple("+npt", "*", 0, 0, "", "/etc/ntp", "/sbin/nologin"),
+ std::make_tuple("-npt", "*", 0, 0, "", "/etc/ntp", "/sbin/nologin")
+ };
+
+ for (const auto &elem : testcase) {
+ ASSERT_EQ(util_getpwent_r(f_pw, &pw, buf, sizeof(buf), &ppw), 0);
+ ASSERT_STREQ(pw.pw_name, std::get<0>(elem).c_str());
+ ASSERT_STREQ(pw.pw_passwd, std::get<1>(elem).c_str());
+ ASSERT_EQ(pw.pw_uid, std::get<2>(elem));
+ ASSERT_EQ(pw.pw_gid, std::get<3>(elem));
+ ASSERT_STREQ(pw.pw_gecos, std::get<4>(elem).c_str());
+ ASSERT_STREQ(pw.pw_dir, std::get<5>(elem).c_str());
+ ASSERT_STREQ(pw.pw_shell, std::get<6>(elem).c_str());
+ EXPECT_TRUE(ppw == &pw);
+ ppw = nullptr;
+ pw = {0};
+ }
+
+ fclose(f_pw);
+}
+
+TEST(utils_pwgr, test_getgrent_r)
+{
+ std::string path = "../../../../test/cutils/utils_pwgr/group_sample";
+ FILE *f_gr = fopen(path.c_str(), "r");
+ ASSERT_NE(f_gr, nullptr);
+
+ struct group gr{0};
+ struct group *pgr = nullptr;
+ char buf[BUFSIZ];
+ size_t i = 0;
+ size_t j = 0;
+ std::vector<std::vector<std::string>> string_list{
+ {}, {}, {},
+ {"a", "list", "of", "users"},
+ {"are", "split", "by", "comma"},
+ {"root", "john", "boob", "jason"}
+ };
+
+ std::vector<std::tuple<std::string, std::string, int>> testcase = {
+ std::make_tuple("root", "x", 0),
+ std::make_tuple("-adm", "x", 4),
+ std::make_tuple("+adm", "x", 4),
+ std::make_tuple("adm", "x", 4),
+ std::make_tuple("adm", "x", 4),
+ std::make_tuple("adm", "x", 4),
+ };
+
+ for (; i < string_list.size(); ++i) {
+ ASSERT_EQ(util_getgrent_r(f_gr, &gr, buf, sizeof(buf), &pgr), 0);
+ ASSERT_STREQ(gr.gr_name, std::get<0>(testcase[i]).c_str());
+ ASSERT_STREQ(gr.gr_passwd, std::get<1>(testcase[i]).c_str());
+ ASSERT_EQ(gr.gr_gid, std::get<2>(testcase[i]));
+ if (string_list[i].size()) {
+ for (j = 0; j < string_list[i].size(); ++j) {
+ EXPECT_TRUE(strcmp(gr.gr_mem[j], string_list[i][j].c_str()) == 0);
+ }
+ } else {
+ EXPECT_TRUE(gr.gr_mem == nullptr);
+ }
+ EXPECT_TRUE(pgr == &gr);
+ gr = {0};
+ pgr = nullptr;
+ }
+
+ fclose(f_gr);
+}
\ No newline at end of file
--
2.32.0 (Apple Git-132)

View File

@ -1,5 +1,5 @@
%global _version 2.0.13 %global _version 2.0.13
%global _release 2 %global _release 3
%global is_systemd 1 %global is_systemd 1
%global enable_shimv2 1 %global enable_shimv2 1
%global is_embedded 1 %global is_embedded 1
@ -16,6 +16,8 @@ BuildRoot: {_tmppath}/iSulad-%{version}
Patch0001: 0001-cleancode-http-request.patch Patch0001: 0001-cleancode-http-request.patch
Patch0002: 0002-refactor-mount-parse-in-spec-module.patch Patch0002: 0002-refactor-mount-parse-in-spec-module.patch
Patch0003: 0003-support-isula-wait-even-if-it-s-not-oci-image.patch Patch0003: 0003-support-isula-wait-even-if-it-s-not-oci-image.patch
Patch0004: 0004-add-isula-import-restful-mode.patch
Patch0005: 0005-Adapt-to-bionic-libc-parser-for-passwd-and-group-obj.patch
%ifarch x86_64 aarch64 %ifarch x86_64 aarch64
Provides: libhttpclient.so()(64bit) Provides: libhttpclient.so()(64bit)
@ -243,6 +245,12 @@ fi
%endif %endif
%changelog %changelog
* Mon May 5 2022 hejunjie<hejunjie10@huawei.com> - 2.0.13-3
- Type: enhancement
- ID: NA
- SUG: NA
- DESC: bionic adaptation for pwgr obj parser
* Mon Apr 25 2022 zhangxiaoyu <zhangxiaoyu58@huawei.com> - 2.0.13-2 * Mon Apr 25 2022 zhangxiaoyu <zhangxiaoyu58@huawei.com> - 2.0.13-2
- Type: bugfix - Type: bugfix
- ID: NA - ID: NA