diff --git a/CI/.DS_Store b/CI/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a07aec6c4b84218a4641da70ec073168f46d857c Binary files /dev/null and b/CI/.DS_Store differ diff --git a/CI/install_devmapper.sh b/CI/install_devmapper.sh index ad0d6b31d013923921faddecd61584026209e643..d85af8a935cbda83eca23351f726a12701827ae1 100755 --- a/CI/install_devmapper.sh +++ b/CI/install_devmapper.sh @@ -28,9 +28,6 @@ lvremove -f isulad/thinpoolmeta vgremove -f isulad pvremove -f $dev_disk -# If udev do not sync in time, do remove force -rm -rf /dev/isulad - echo y | mkfs.ext4 $dev_disk mkdir -p /etc/lvm/profile touch /etc/lvm/profile/isulad-thinpool.profile diff --git a/CI/test_cases/.DS_Store b/CI/test_cases/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..033326062ae090404c8ad0fcaad5d8eefeb5ac99 Binary files /dev/null and b/CI/test_cases/.DS_Store differ diff --git a/CI/test_cases/helpers.sh b/CI/test_cases/helpers.sh index 27f04749ddc50355e0f4268adf2040e22578295e..d40e61d92b3dc3e8db715f61e8a2f3beaf49e92e 100755 --- a/CI/test_cases/helpers.sh +++ b/CI/test_cases/helpers.sh @@ -212,9 +212,6 @@ function do_install_thinpool() pvremove -f $dev_disk [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - pvremove failed" && ((ret++)) - # If udev do not sync in time, do remove force - rm -rf /dev/isulad - mount | grep $dev_disk | grep /var/lib/isulad if [ x"$?" == x"0" ]; then umount /var/lib/isulad diff --git a/CI/test_cases/metrics_cases/mem_cpu_metrics.sh b/CI/test_cases/metrics_cases/mem_cpu_metrics.sh deleted file mode 100755 index 46380ed12e6d23ec3ac251c1625512a280873bff..0000000000000000000000000000000000000000 --- a/CI/test_cases/metrics_cases/mem_cpu_metrics.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -# -# attributes: isulad mem metrics test -# concurrent: NA -# spend time: 10 - -####################################################################### -##- @Copyright (c) KylinSoft Co., Ltd. 2021. 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. -##- @Description:CI -##- @Author: xiapin -##- @Create: 2021-08-18 -####################################################################### - -declare -r curr_path=$(dirname $(readlink -f "$0")) -source ../helpers.sh - -function test_mem() -{ - local ret=0 - local test="container stats test => (${FUNCNAME[@]})" - local metrics_log=/tmp/metrics.log - local image="busybox" - msg_info "${test} starting..." - - check_valgrind_log - [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to stop isulad" && return ${FAILURE} - - start_isulad_with_valgrind - [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to start isulad" && return ${FAILURE} - - # iSulad is started by valgrind, netstat cannot find the 'isulad' process name - # 127.0.0.0:9090 - metric_server=$(netstat -antp | grep 9090 | awk '{print $4}') - [[ -z $metric_server ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to find metrics http server" && ((ret++)) - - local cont_id=$(isula create -t $image | cut -b 1-4) - [[ -z $cont_id ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to create cont with img $image" && ((ret++)) - - isula start $cont_id - fn_check_eq "$?" "0" "start failed" - - #mem info (get base cpu info) - curl -i $metric_server/metrics/type/mem_cpu >> $metrics_log - [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to run curl" && ((ret++)) - - cat $metrics_log | grep "isula_container_mem_stat" | grep $cont_id - [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to get mem metrics info" && ((ret++)) - - #cpu info - curl -i $metric_server/metrics/type/cpu >> $metrics_log - [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to run curl" && ((ret++)) - - cat $metrics_log | grep "isula_container_cpu_stat" | grep $cont_id - [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to get cpu metrics info" && ((ret++)) - - isula stop $cont_id - isula rm $cont_id - #rm -rf $metrics_log - msg_info "${test} finished with return ${ret}..." - return ${ret} -} - -declare -i ans=0 - -test_mem || ((ans++)) - -show_result ${ans} "${curr_path}/${0}" diff --git a/CI/test_cases/metrics_cases/server.sh b/CI/test_cases/metrics_cases/server.sh deleted file mode 100755 index 5adac2d03a1d2ccbdf10c54c741249a3089f9570..0000000000000000000000000000000000000000 --- a/CI/test_cases/metrics_cases/server.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -# -# attributes: isulad metrics port test -# concurrent: NA -# spend time: 1 - -####################################################################### -##- @Copyright (c) KylinSoft Co., Ltd. 2021. 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. -##- @Description:CI -##- @Author: xiapin -##- @Create: 2021-08-18 -####################################################################### - -declare -r curr_path=$(dirname $(readlink -f "$0")) -source ../helpers.sh - -function test_server() -{ - local ret=0 - local test="container stats test => (${FUNCNAME[@]})" - local req_cnt=0 - local metrics_log=/tmp/metrics.log - msg_info "${test} starting..." - - check_valgrind_log - [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to stop isulad" && return ${FAILURE} - - start_isulad_with_valgrind - [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to start isulad" && return ${FAILURE} - - # iSulad is started by valgrind, netstat cannot find the 'isulad' process name - # 127.0.0.0:9090 - local metric_server=$(netstat -antp | grep 9090 | awk '{print $4}') - [[ -z $metric_server ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to find metrics http server" && ((ret++)) - - curl -i $metric_server/metrics/type >> $metrics_log - [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to run curl" && ((ret++)) - - head -n1 $metrics_log | cut -d ' ' -f2 | grep 200 - [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - metric server response error" && ((ret++)) - - req_cnt=$(cat $metrics_log | grep isula_metrics_http_req_count | tail -n1 | awk '{print $2}') - [[ $req_cnt -eq 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - metric server response not correctly" && ((ret++)) - - rm -rf $metrics_log - msg_info "${test} finished with return ${ret}..." - return ${ret} -} - -declare -i ans=0 - -test_server || ((ans++)) - -show_result ${ans} "${curr_path}/${0}" diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cc1fca70b38288fd31846c4f4f341797e0597a4..752d85579b4e5e72ab22301181d1c311fdf3b46f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,8 +103,6 @@ if (CMAKE_INSTALL_SYSCONFDIR) endif() install(FILES src/contrib/config/daemon.json DESTINATION ${conf_prefix}/isulad PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE) -install(FILES src/contrib/config/daemon_constants.json - DESTINATION ${conf_prefix}/isulad PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE) install(FILES src/contrib/config/config.json src/contrib/config/systemcontainer_config.json DESTINATION ${conf_prefix}/default/isulad PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE) install(FILES src/contrib/config/seccomp_default.json diff --git a/README.md b/README.md index 39e23de1bb16920056e72fe94da46675c71b8fdc..41077d66887bde38fd252bb78a52d10ef7a40494 100644 --- a/README.md +++ b/README.md @@ -1,284 +1,11 @@ -iSulad +# 为iSulad添加checkpoint,restore功能 +- [x] checkpoint create +- [x] checkpoint ls +- [x] checkpoint rm +- [x] checkpoint restore on external rootfs +- [x] checkpoint-dir -## iSulad +- [ ] checkpoint restore in start +- [ ] move checkpoint from isula to isulad -`iSulad` is a lightweight container runtime daemon which is designed for IOT and Cloud infrastructure.`iSulad` has the characteristics of light, fast and not limited by hardware specifications and architecture, and can be applied more widely. -## Documentation - -- [en build guide](./docs/build_guide.md) -- [cn build guide](./docs/build_guide_zh.md) -- [more usage guide](https://openeuler.org/zh/docs/20.09/docs/Container/iSula%E5%AE%B9%E5%99%A8%E5%BC%95%E6%93%8E.html) - -## Getting Started - -### Installing - -To install iSulad, you can use `rpm` or `yum` package manager command with `openEuler` repository. - -Or write repository file by hand: - -```sh -cat << EOF > /etc/yum.repos.d/openEuler.repo -[openEuler] -baseurl=https://repo.openeuler.org/openEuler-20.03-LTS/OS/\$basearch -enabled=1 -EOF -``` - -Install iSulad with yum: - -```sh -yum install -y iSulad -``` - -if you found this error -``` -Repository 'openEuler' is missing name in configuration, using id. - -You have enabled checking of packages via GPG keys. This is a good thing. -However, you do not have any GPG public keys installed. You need to download -the keys for packages you wish to install and install them. -You can do that by running the command: - rpm --import public.gpg.key - - -Alternatively you can specify the url to the key you would like to use -for a repository in the 'gpgkey' option in a repository section and YUM -will install it for you. - -For more information contact your distribution or package provider. - -``` - -you should run `rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler` first - - -### Configure - -Configure the container image registry address, for example "docker.io" or other registry addrss. - -```sh -# cat /etc/isulad/daemon.json -..... - "registry-mirrors": [ - "docker.io" - ], -..... -``` - -### Run - -We provide `systemd` service to start `iSulad`: -```sh -systemctl restart isulad # restart the server with systemd command -``` - -You can use direct command to start `iSulad` server: -```sh -$ sudo isulad # run the server with default socket name and default log level and images manage function -``` -### Operations on containers: - -For more informations on how to use `iSulad`, please refer to the [guide](https://openeuler.org/en/docs/20.03_LTS/docs/Container/isulad-container-engine.html) - -`iSulad` provides two operate interfaces to manager images and containers. - -- CLI, `iSulad` provides `isula` as client CLI - - Here are some sample commands to manager containers. - - List all containers in your own environment: - ```sh - # list containers - $ sudo isula ps -a - ``` - - Create a container with busybox named `test`: - ```sh - # create a container 'test' with image busybox - $ sudo isula create -t -n test busybox - ``` - - Start this container `test`: - ```sh - # start the container 'test' - $ sudo isula start test - ``` - Kill the container `test`: - ```sh - # kill the container 'test': - $ sudo isula kill test - ``` - Remove the container `test`: - ```sh - # remove the container 'test' - $ sudo isula rm test - ``` - -- CRI interface, `iSulad` can be integrated with `kubernetes` through CRI interface - - How to integrate with `kubernetes` please refer to [integration.md](./docs/integration.md) - - -### Build from source -Build requirements for developers are listed in [build_guide](./docs/build_guide.md) - -## Performance - -#### Machine configuration - -X86 machine: - -| Configuration | Information | -| ------------- | -------------------------------------------- | -| OS | Fedora32 X86_64 | -| Kernel | linux 5.7.10-201.fc32.x86_64 | -| CPU | 48 cores,Intel Xeon CPU E5-2695 v2 @ 2.4GHZ | -| Memory | 132 GB | - -ARM machine: - -| Configuration | Information | -| ------------- | ------------- | -| OS | openEuler | -| Kernel | linux 4.19.90 | -| CPU | 64 cores | -| Memory | 196 GB | - -#### Version of Softwares - -| Name | Version | -| --------- | ---------------------------------------------------------------------- | -| iSulad | Version: 2.0.3 , Git commit: 3bb24761f07cc0ac399e1cb783053db8b33b263d | -| docker | Version: 19.03.11, Git commit: 42e35e6 | -| podman | version 2.0.3 | -| CRI-O | v1.15.4 | -| kubelet | v1.15.0 | -| cri-tools | v1.15.0 | - -#### Design of testcase - -![design of performance test](./docs/design/performan_test_design.png) - -About code of test - -- [x] Now, we use shell to finish test cases of performance; - -- [ ] Future, we should have a repository which store all test cases for iSula. Such as, performance tests, validation tests and so on... [It's coming soon](https://gitee.com/openeuler/iSulad/wikis/2020-%E4%B8%8B%E5%8D%8A%E5%B9%B4%E7%89%B9%E6%80%A7%E8%B7%AF%E6%A0%87?sort_id=2471417)... - -#### Compare with other container engines - -##### run operator once - -###### X86 - -base operators of client - -| operator (ms) | Docker | Podman | iSulad | vs Docker | vs Podman | -| ------------- | ------ | ------ | ------ | --------- | --------- | -| create | 287 | 180 | 87 | -69.69% | -51.67% | -| start | 675 | 916 | 154 | -77.19% | -83.19% | -| stop | 349 | 513 | 274 | -21.49% | -46.59% | -| rm | 72 | 187 | 60 | -16.67% | -67.91% | -| run | 866 | 454 | 195 | -77.48% | -57.05% | - -base operators of CRI - -| operator (ms) | Docker | CRIO | iSulad | vs Docker | vs CRIO | -| ------------- | ------ | ---- | ------ | --------- | ------- | -| runp | 681 | 321 | 186 | -72.69% | -42.06% | -| stopp | 400 | 356 | 169 | -57.75% | -52.53% | - -###### ARM - -base operators of client - -| operator (ms) | Docker | Podman | iSulad | vs Docker | vs Podman | -| ------------- | ------ | ------ | ------ | --------- | --------- | -| create | 401 | 361 | 61 | -84.79% | -83.10% | -| start | 1160 | 1143 | 232 | -80.00% | -79.70% | -| stop | 634 | 576 | 243 | -61.67% | -57.81% | -| rm | 105 | 398 | 46 | -56.19% | -88.44% | -| run | 1261 | 1071 | 258 | -79.54% | -75.91% | - -base operators of CRI - -| operator (ms) | Docker | CRIO | iSulad | vs Docker | vs CRIO | -| ------------- | ------ | ---- | ------ | --------- | ------- | -| runp | 1339 | 2366 | 179 | -86.63% | -92.43% | -| stopp | 443 | 419 | 117 | -73.59% | -72.08% | - -##### parallel to run operator 100 times - -###### X86 - -base operator of client - -| operator (ms) | Docker | Podman | iSulad | vs Docker | vs Podman | -| ------------- | ------ | ------ | ------ | --------- | --------- | -| 100 * create | 4995 | 3993 | 829 | -83.40% | -79.24% | -| 100 * start | 10126 | 5537 | 1425 | -85.93% | -74.26% | -| 100 * stop | 8066 | 11100 | 2273 | -71.82% | -79.52% | -| 100 * rm | 3220 | 4319 | 438 | -86.40% | -89.86% | -| 100 * run | 9822 | 5979 | 2117 | -78.45% | -64.59% | - -base operators of CRI - -| operator (ms) | Docker | CRIO | iSulad | vs Docker | vs CRIO | -| ------------- | ------ | ---- | ------ | --------- | ------- | -| 100 * runp | 13998 | 4946 | 2825 | -79.82% | -42.88% | -| 100 * stopp | 8402 | 4834 | 4543 | -45.93% | -6.02% | - -###### ARM - -base operator of client - -| operator (ms) | Docker | Podman | iSulad | vs Docker | vs Podman | -| ------------- | ------ | ------ | ------ | --------- | --------- | -| 100 * create | 14563 | 12081 | 538 | -96.31% | -95.55% | -| 100 * start | 23420 | 15370 | 1841 | -92.14% | -88.02% | -| 100 * stop | 22234 | 16973 | 930 | -95.82% | -94.52% | -| 100 * rm | 937 | 10493 | 233 | -75.13% | -97.78% | -| 100 * run | 28091 | 16280 | 2320 | -91.74% | -85.75% | - -base operators of CRI - -| operator (ms) | Docker | CRIO | iSulad | vs Docker | vs CRIO | -| ------------- | ------ | ----- | ------ | --------- | ------- | -| 100 * runp | 27802 | 29197 | 2398 | -91.37% | -91.79% | -| 100 * stopp | 14429 | 11173 | 1170 | -91.89% | -89.53% | - -## Try to Use iSulad - -If you want to experience iSulad right now, you can try to use it at: - -- https://lab.huaweicloud.com/testdetail_498 - -It is the experiment about iSulad. In this experiment you can install iSulad easily. And then you can pull image, run container, analyse iSulad's performance and compare it with performance of Docker. - -## How to Contribute - -We always welcome new contributors. And we are happy to provide guidance for the new contributors. -iSulad follows the kernel coding conventions. You can find a detailed introduction at: - -- https://www.kernel.org/doc/html/v4.10/process/coding-style.html - -You can get more information about iSulad from our wikis, including roadmap, feature design documents, etc: - -- https://gitee.com/openeuler/iSulad/wikis - -## Licensing - -iSulad is licensed under the Mulan PSL v2. - -## Related Resouces - -- [bilibili videos](https://space.bilibili.com/527064077/video?keyword=iSulad) -- [如何在openEuler树莓派镜像上部署k8s+iSula集群](https://my.oschina.net/openeuler/blog/4774838) -- [基于openEuler搭建部署k8s](https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=94271) - -## Join us -You can join us on any of the following channels: -* Join our [mailing list](https://mailweb.openeuler.org/postorius/lists/isulad.openeuler.org/) -* Join our Biweekly meeting at 16:30 pm on Tuesday (meeting link will be mailed at mailing list) \ No newline at end of file diff --git a/cmake/checker.cmake b/cmake/checker.cmake index 7f3ef888c5b3a18b52c49e23faf1fd3bfa3dcb1e..38e50d01a121dba4ffdd79bbb134dfbff93a8a75 100644 --- a/cmake/checker.cmake +++ b/cmake/checker.cmake @@ -162,9 +162,7 @@ if (GRPC_CONNECTOR) find_library(CLIBCNI_LIBRARY clibcni HINTS ${PC_CLIBCNI_LIBDIR} ${PC_CLIBCNI_LIBRARY_DIRS}) _CHECK(CLIBCNI_LIBRARY "CLIBCNI_LIBRARY-NOTFOUND" "libclibcni.so") -endif() - -if ((NOT GRPC_CONNECTOR) OR (GRPC_CONNECTOR AND ENABLE_METRICS)) +else() pkg_check_modules(PC_EVENT "event>=2.1.8") find_path(EVENT_INCLUDE_DIR event.h HINTS ${PC_EVENT_INCLUDEDIR} ${PC_EVENT_INCLUDE_DIRS}) diff --git a/cmake/options.cmake b/cmake/options.cmake index 4795f553a6a7aefd99d01e33d280c967d5f89d88..8f19113b8e9084046e5d331d2294f79a78c3db52 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -73,8 +73,3 @@ if (ENABLE_SHIM_V2 STREQUAL "ON") set(ENABLE_SHIM_V2 1) endif() -option(ENABLE_METRICS "enable metrics" ON) -if (ENABLE_METRICS STREQUAL "ON") - add_definitions(-DENABLE_METRICS) - set(ENABLE_METRICS 1) -endif() diff --git a/cmake/protoc.cmake b/cmake/protoc.cmake index fa4422af916aa873698d1b96b0cd3edc1ecf4334..ba36515dec67b18943d669524349c2832900183d 100644 --- a/cmake/protoc.cmake +++ b/cmake/protoc.cmake @@ -4,6 +4,7 @@ set(GRPC_OUT_PRE_PATH ${CMAKE_BINARY_DIR}/grpc) set(CONTAINER_PROTOS_OUT_PATH ${GRPC_OUT_PRE_PATH}/src/api/services/containers) set(IMAGE_PROTOS_OUT_PATH ${GRPC_OUT_PRE_PATH}/src/api/services/images) set(VOLUME_PROTOS_OUT_PATH ${GRPC_OUT_PRE_PATH}/src/api/services/volumes) +set(CHECKPOINT_PROTOS_OUT_PATH ${GRPC_OUT_PRE_PATH}/src/api/services/checkpoints) set(CRI_PROTOS_OUT_PATH ${GRPC_OUT_PRE_PATH}/src/api/services/cri) set(IMAGE_SERVICE_PROTOS_OUT_PATH ${GRPC_OUT_PRE_PATH}/src/api/image_client) @@ -12,6 +13,7 @@ if (GRPC_CONNECTOR) execute_process(COMMAND mkdir -p ${CONTAINER_PROTOS_OUT_PATH}) execute_process(COMMAND mkdir -p ${IMAGE_PROTOS_OUT_PATH}) execute_process(COMMAND mkdir -p ${VOLUME_PROTOS_OUT_PATH}) + execute_process(COMMAND mkdir -p ${CHECKPOINT_PROTOS_OUT_PATH}) execute_process(COMMAND mkdir -p ${CRI_PROTOS_OUT_PATH}) execute_process(COMMAND ${CMD_PROTOC} -I ${PROTOS_PATH}/containers --cpp_out=${CONTAINER_PROTOS_OUT_PATH} ${PROTOS_PATH}/containers/container.proto ERROR_VARIABLE containers_err) @@ -50,6 +52,18 @@ if (GRPC_CONNECTOR) message(FATAL_ERROR ${volumes_err}) endif() + execute_process(COMMAND ${CMD_PROTOC} -I ${PROTOS_PATH}/checkpoints --cpp_out=${CHECKPOINT_PROTOS_OUT_PATH} ${PROTOS_PATH}/checkpoints/checkpoints.proto ERROR_VARIABLE checkpoints_err) + if (checkpoints_err) + message("Parse checkpoints.proto failed: ") + message(FATAL_ERROR ${checkpoints_err}) + endif() + + execute_process(COMMAND ${CMD_PROTOC} -I ${PROTOS_PATH}/checkpoints --grpc_out=${CHECKPOINT_PROTOS_OUT_PATH} --plugin=protoc-gen-grpc=${CMD_GRPC_CPP_PLUGIN} ${PROTOS_PATH}/checkpoints/checkpoints.proto ERROR_VARIABLE checkpoints_err) + if (checkpoints_err) + message("Parse checkpoints.proto plugin failed: ") + message(FATAL_ERROR ${checkpoints_err}) + endif() + execute_process(COMMAND ${CMD_PROTOC} -I ${PROTOS_PATH}/cri --cpp_out=${CRI_PROTOS_OUT_PATH} ${PROTOS_PATH}/cri/api.proto ERROR_VARIABLE cri_err) if (cri_err) diff --git a/docs/build_guide.md b/docs/build_guide.md index d5e337cc64f835d5d2f6e62b3dda64ebea7d3d8e..1b481a11e6df349e180b6fa0863370b173bac78c 100644 --- a/docs/build_guide.md +++ b/docs/build_guide.md @@ -76,35 +76,6 @@ $ sudo -E make install $ sudo -E ldconfig ``` -### build and install libevent - -```bash -$ git clone https://gitee.com/src-openeuler/libevent.git -$ cd libevent -$ git checkout -b openEuler-20.03-LTS-tag openEuler-20.03-LTS-tag -$ tar -xzvf libevent-2.1.11-stable.tar.gz -$ cd libevent-2.1.11-stable && ./autogen.sh && ./configure -$ sudo -E make -j $(nproc) -$ sudo -E make install -$ sudo -E ldconfig -``` - -### build and install libevhtp - -```bash -$ git clone https://gitee.com/src-openeuler/libevhtp.git -$ cd libevhtp && git checkout -b openEuler-20.03-LTS-tag openEuler-20.03-LTS-tag -$ tar -xzvf libevhtp-1.2.16.tar.gz -$ cd libevhtp-1.2.16 -$ patch -p1 -F1 -s < ../0001-support-dynamic-threads.patch -$ patch -p1 -F1 -s < ../0002-close-openssl.patch -$ rm -rf build && mkdir build && cd build -$ sudo -E cmake -D EVHTP_BUILD_SHARED=on -D EVHTP_DISABLE_SSL=on ../ -$ sudo -E make -j $(nproc) -$ sudo -E make install -$ sudo -E ldconfig -``` - ### build and install http-parser ```bash $ git clone https://gitee.com/src-openeuler/http-parser.git diff --git a/docs/build_guide_zh.md b/docs/build_guide_zh.md index e0aa15bdca092a7f232657d1af600f938cb3821c..f088d9ec292cd6501088c6cc6a7d2bdc275647ec 100644 --- a/docs/build_guide_zh.md +++ b/docs/build_guide_zh.md @@ -88,37 +88,7 @@ $ sudo -E make install $ sudo -E ldconfig ``` -### 编译安装libevent - -```bash -$ git clone https://gitee.com/src-openeuler/libevent.git -$ cd libevent -$ git checkout -b openEuler-20.03-LTS-tag openEuler-20.03-LTS-tag -$ tar -xzvf libevent-2.1.11-stable.tar.gz -$ cd libevent-2.1.11-stable && ./autogen.sh && ./configure -$ sudo -E make -j $(nproc) -$ sudo -E make install -$ sudo -E ldconfig -``` - -### 编译安装libevhtp - -```bash -$ git clone https://gitee.com/src-openeuler/libevhtp.git -$ cd libevhtp && git checkout -b openEuler-20.03-LTS-tag openEuler-20.03-LTS-tag -$ tar -xzvf libevhtp-1.2.16.tar.gz -$ cd libevhtp-1.2.16 -$ patch -p1 -F1 -s < ../0001-support-dynamic-threads.patch -$ patch -p1 -F1 -s < ../0002-close-openssl.patch -$ rm -rf build && mkdir build && cd build -$ sudo -E cmake -D EVHTP_BUILD_SHARED=on -D EVHTP_DISABLE_SSL=on ../ -$ sudo -E make -j $(nproc) -$ sudo -E make install -$ sudo -E ldconfig -``` - ### 编译安装http-parser - ```bash $ git clone https://gitee.com/src-openeuler/http-parser.git $ cd http-parser diff --git a/docs/install_iSulad_on_Ubuntu_20_04_LTS.sh b/docs/install_iSulad_on_Ubuntu_20_04_LTS.sh index 4f27244ea81948e0a6a8cdc9bcbce9bcec7b94a7..630febe186de3e19b126a46f62d4adc794519441 100644 --- a/docs/install_iSulad_on_Ubuntu_20_04_LTS.sh +++ b/docs/install_iSulad_on_Ubuntu_20_04_LTS.sh @@ -18,6 +18,7 @@ mkdir -p $BUILD_DIR cd $BUILD_DIR git clone https://gitee.com/src-openeuler/lxc.git cd lxc +tar -zxf lxc-4.0.3.tar.gz ./apply-patches cd lxc-4.0.3 ./autogen.sh diff --git a/docs/integration.md b/docs/integration.md index 00a742d2a0930bc8d4ff72f6a4206b4e687f5c3e..ae7c6e4bfa4a922f38138c4a933e03ff6a41cf11 100644 --- a/docs/integration.md +++ b/docs/integration.md @@ -13,7 +13,7 @@ Configure the `endpoint`of `isulad`: ```json - "hosts": [ + "hosts" : [ "unix:///var/run/isulad.sock" ] ``` diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b2297c4d036395d6935947451d699314b3739547 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 034190a394579ebb3919d65d9d04b6510a8a5843..103454d26f1f1d305bb9469d4aa34f3e68a0cc10 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -79,6 +79,7 @@ target_link_libraries(libisula ${LIBTAR_LIBRARY} ${WEBSOCKET_LIBRARY} ${CRYPTO_LIBRARY} + liblxc.so ) if (ENABLE_SHIM_V2) @@ -93,6 +94,9 @@ if (GRPC_CONNECTOR) else() target_link_libraries(libisula ${EVHTP_LIBRARY} ${EVENT_LIBRARY} ${ZLIB_LIBRARY} -ldl libhttpclient) endif() + + + # ------ build libisula finish ----- add_subdirectory(cmd) @@ -110,7 +114,7 @@ add_executable(isulad-shim ${SHARED_SRCS} ) target_include_directories(isulad-shim PUBLIC ${ISULAD_SHIM_INCS} ${SHARED_INCS}) -target_link_libraries(isulad-shim ${LIBYAJL_LIBRARY} ${ISULA_LIBUTILS_LIBRARY} ${LIBARCHIVE_LIBRARY} ${LIBTAR_LIBRARY} ${ZLIB_LIBRARY} ${CRYPTO_LIBRARY} -lpthread) +target_link_libraries(isulad-shim ${LIBYAJL_LIBRARY} ${ISULA_LIBUTILS_LIBRARY} ${LIBARCHIVE_LIBRARY} ${LIBTAR_LIBRARY} ${ZLIB_LIBRARY} ${CRYPTO_LIBRARY} -lpthread liblxc.so) # ------ build isula-shim finish ------- @@ -134,7 +138,7 @@ target_include_directories(isulad PUBLIC target_link_libraries(isulad ${LIBYAJL_LIBRARY} ${SYSTEMD_LIBRARY} ${SELINUX_LIBRARY} ${LIBARCHIVE_LIBRARY} ${LIBTAR_LIBRARY} ${WEBSOCKET_LIBRARY} ${CRYPTO_LIBRARY}) -target_link_libraries(isulad -ldl ${ZLIB_LIBRARY} ${ISULA_LIBUTILS_LIBRARY} -lpthread libhttpclient) +target_link_libraries(isulad -ldl ${ZLIB_LIBRARY} ${ISULA_LIBUTILS_LIBRARY} -lpthread libhttpclient liblxc.so) if (ENABLE_SHIM_V2) target_link_libraries(isulad ${LIBSHIM_V2_LIBRARY}) @@ -155,10 +159,6 @@ else() target_link_libraries(isulad ${EVHTP_LIBRARY} ${EVENT_LIBRARY}) endif() -if (GRPC_CONNECTOR AND ENABLE_METRICS) - target_link_libraries(isulad ${EVHTP_LIBRARY} ${EVENT_LIBRARY}) -endif() - if (ENABLE_OCI_IMAGE) target_link_libraries(isulad -Wl,--as-needed -lstdc++) target_link_libraries(isulad -Wl,--as-needed -ldevmapper) @@ -172,6 +172,8 @@ if (ISULAD_GCOV) target_link_libraries(isulad -lgcov) endif() + + # ------ build isulad finish ------- # ------ install binary -------- @@ -183,3 +185,5 @@ install(TARGETS isulad-shim RUNTIME DESTINATION bin PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE) install(TARGETS isulad RUNTIME DESTINATION bin PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE) + + diff --git a/src/api/services/checkpoints/checkpoints.proto b/src/api/services/checkpoints/checkpoints.proto new file mode 100644 index 0000000000000000000000000000000000000000..714399072cf5c903656b112832a7f500615911a5 --- /dev/null +++ b/src/api/services/checkpoints/checkpoints.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; +option optimize_for = CODE_SIZE; + +package checkpoint; + +service CheckpointService { + //list + rpc List(ListCheckpointRequest) returns (ListCheckpointResponse); + //remove + rpc Remove(RemoveCheckpointRequest) returns (RemoveCheckpointResponse); + //create + rpc Create(CreateCheckpointRequest) returns (CreateCheckpointResponse); + //create + rpc Restore(RestoreCheckpointRequest) returns (RestoreCheckpointResponse); +} + +message Checkpoint{ + string name =1; + string dir = 2; +} + +message ListCheckpointRequest { + string dir=1; +} + +message ListCheckpointResponse { + repeated Checkpoint checkpoints = 1; + uint32 cc = 2; + string errmsg = 3; +} + +message RemoveCheckpointRequest { + string container = 1; + string dir = 2; +} + +message RemoveCheckpointResponse { + uint32 cc = 1; + string errmsg = 2; +} + +message CreateCheckpointRequest { + string container =1; + string dir =2; +} + +message CreateCheckpointResponse { + string container =1; + uint32 cc = 2; + string errmsg = 3; +} + +message RestoreCheckpointRequest { + string container =1; + string dir =2; +} + +message RestoreCheckpointResponse { + string container =1; + uint32 cc = 2; + string errmsg = 3; +} + diff --git a/src/client/connect/CMakeLists.txt b/src/client/connect/CMakeLists.txt index e9b0cc4ddf8611e1410e7498d406ba8436063ae5..6abcc4ae1edcd278e94338519d8d6d5d44f540dc 100644 --- a/src/client/connect/CMakeLists.txt +++ b/src/client/connect/CMakeLists.txt @@ -12,8 +12,9 @@ if (GRPC_CONNECTOR) aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/services/containers CONNECT_API_CONTAINERS) aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/services/images CONNECT_API_IMAGES) aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/services/volumes CONNECT_API_VOLUMES) + aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/services/checkpoints CONNECT_API_CHECKPOINTS) aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/services/cri CONNECT_API_CRI) - set(CONNECT_API ${CONNECT_API_CONTAINERS} ${CONNECT_API_IMAGES} ${CONNECT_API_VOLUMES} ${CONNECT_API_CRI}) + set(CONNECT_API ${CONNECT_API_CONTAINERS} ${CONNECT_API_IMAGES} ${CONNECT_API_VOLUMES} ${CONNECT_API_CHECKPOINTS} ${CONNECT_API_CRI}) list(APPEND local_client_connect_srcs ${CONNECT_API}) list(APPEND local_client_connect_incs ${CMAKE_CURRENT_SOURCE_DIR}/grpc) @@ -21,6 +22,7 @@ if (GRPC_CONNECTOR) ${CMAKE_BINARY_DIR}/grpc/src/api/services/containers ${CMAKE_BINARY_DIR}/grpc/src/api/services/images ${CMAKE_BINARY_DIR}/grpc/src/api/services/volumes + ${CMAKE_BINARY_DIR}/grpc/src/api/services/checkpoints ${CMAKE_BINARY_DIR}/grpc/src/api/services/cri ) diff --git a/src/client/connect/grpc/CMakeLists.txt b/src/client/connect/grpc/CMakeLists.txt index 5be06642c60ce250ffcd17f183565104909bd7d1..310aff94d4a5dc00be604677e9ad4d4fb790a2ab 100644 --- a/src/client/connect/grpc/CMakeLists.txt +++ b/src/client/connect/grpc/CMakeLists.txt @@ -4,6 +4,7 @@ if (GRPC_CONNECTOR) ${CMAKE_CURRENT_SOURCE_DIR}/grpc_containers_client.cc ${CMAKE_CURRENT_SOURCE_DIR}/grpc_images_client.cc ${CMAKE_CURRENT_SOURCE_DIR}/grpc_volumes_client.cc + ${CMAKE_CURRENT_SOURCE_DIR}/grpc_checkpoints_client.cc PARENT_SCOPE ) endif() diff --git a/src/client/connect/grpc/client_base.h b/src/client/connect/grpc/client_base.h index 5d1e7f0c542bfe453e01b7ef0fab94992fb28fde..3d410ce0a483f042fd095446588638ccdea1cde5 100644 --- a/src/client/connect/grpc/client_base.h +++ b/src/client/connect/grpc/client_base.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "certificate.h" #include "connect.h" @@ -84,11 +85,15 @@ public: virtual void unpackStatus(Status &status, RP *response) { + openlog("isula",LOG_CONS | LOG_PID,LOG_LOCAL2); + syslog(LOG_DEBUG,"unpackStatus\n"); + closelog(); if (!status.error_message().empty() && (status.error_code() == grpc::StatusCode::UNKNOWN || status.error_code() == grpc::StatusCode::PERMISSION_DENIED || status.error_code() == grpc::StatusCode::INTERNAL)) { response->errmsg = util_strdup_s(status.error_message().c_str()); } else { + response->errmsg = util_strdup_s(errno_to_error_message(ISULAD_ERR_CONNECT)); } @@ -102,6 +107,9 @@ public: gRP reply; ClientContext context; Status status; + openlog("isula",LOG_CONS | LOG_PID,LOG_LOCAL2); + syslog(LOG_DEBUG,"client run\n"); + closelog(); // Set deadline for GRPC client if (deadline > 0) { diff --git a/src/client/connect/grpc/grpc_checkpoints_client.cc b/src/client/connect/grpc/grpc_checkpoints_client.cc new file mode 100644 index 0000000000000000000000000000000000000000..3004ee4a3b2b3da99d0f6cb24620f86e37136a2c --- /dev/null +++ b/src/client/connect/grpc/grpc_checkpoints_client.cc @@ -0,0 +1,248 @@ +#include "grpc_checkpoints_client.h" + +#include + +#include "api.grpc.pb.h" +#include "client_base.h" +#include "checkpoints.grpc.pb.h" +#include "utils.h" + +using namespace checkpoint; + +using grpc::ClientContext; +using grpc::Status; + + +class CheckpointCreate : public + ClientBase { +public: + explicit CheckpointCreate(void *args) + : ClientBase(args) + { + } + ~CheckpointCreate() = default; + CheckpointCreate(const CheckpointCreate &) = delete; + CheckpointCreate &operator=(const CheckpointCreate &) = delete; + + auto request_to_grpc(const isula_create_checkpoint_request *request, CreateCheckpointRequest *grequest) -> int override + { + if (request == nullptr) { + return -1; + } + + if (request->container != nullptr) { + grequest->set_container(request->container); + } + if (request->dir != nullptr) { + grequest->set_dir(request->dir); + } + + return 0; + } + + auto response_from_grpc(CreateCheckpointResponse *gresponse, isula_create_checkpoint_response *response) -> int override + { + response->server_errono = static_cast(gresponse->cc()); + + if (!gresponse->errmsg().empty()) { + response->errmsg = util_strdup_s(gresponse->errmsg().c_str()); + } + response->container=util_strdup_s(gresponse->container().c_str()); + + return 0; + } + + auto grpc_call(ClientContext *context, const CreateCheckpointRequest &req, CreateCheckpointResponse *reply) -> Status override + { + + + return stub_->Create(context, req, reply); + } +}; + +class CheckpointRemove : public + ClientBase { +public: + explicit CheckpointRemove(void *args) + : ClientBase(args) + { + } + ~CheckpointRemove() = default; + CheckpointRemove(const CheckpointRemove &) = delete; + CheckpointRemove &operator=(const CheckpointRemove &) = delete; + + auto request_to_grpc(const isula_remove_checkpoint_request *request, RemoveCheckpointRequest *grequest) -> int override + { + if (request == nullptr) { + return -1; + } + + if (request->container != nullptr) { + grequest->set_container(request->container); + } + if (request->dir != nullptr) { + grequest->set_dir(request->dir); + } + + return 0; + } + + auto response_from_grpc(RemoveCheckpointResponse *gresponse, isula_remove_checkpoint_response *response) -> int override + { + response->server_errono = static_cast(gresponse->cc()); + + if (!gresponse->errmsg().empty()) { + response->errmsg = util_strdup_s(gresponse->errmsg().c_str()); + } + + + return 0; + } + + auto grpc_call(ClientContext *context, const RemoveCheckpointRequest &req, RemoveCheckpointResponse *reply) -> Status override + { + + + return stub_->Remove(context, req, reply); + } +}; + +class CheckpointList : public + ClientBase { +public: + explicit CheckpointList(void *args) + : ClientBase(args) + { + } + ~CheckpointList() = default; + CheckpointList(const CheckpointList &) = delete; + CheckpointList &operator=(const CheckpointList &) = delete; + + auto request_to_grpc(const isula_list_checkpoint_request *request, ListCheckpointRequest *grequest) -> int override + { + if (request == nullptr) { + return -1; + } + + if (request->dir != nullptr) { + grequest->set_dir(request->dir); + } + + return 0; + } + + auto response_from_grpc(ListCheckpointResponse *gresponse, isula_list_checkpoint_response *response) -> int override + { + int num = gresponse->checkpoints_size(); + if(num<=0){ + response->checkpoints = nullptr; + response->checkpoints_len = 0; + response->server_errono = gresponse->cc(); + if (!gresponse->errmsg().empty()) { + response->errmsg = util_strdup_s(gresponse->errmsg().c_str()); + } + return 0; + } + + response->checkpoints_len = 0; + + if (static_cast(num) > SIZE_MAX / sizeof(struct isula_checkpoint_info)) { + ERROR("Too many volume"); + response->cc = ISULAD_ERR_MEMOUT; + return -1; + } + + auto checkpoints = static_cast( + util_common_calloc_s(sizeof(struct isula_checkpoint_info) * static_cast(num))); + if (checkpoints == nullptr) { + ERROR("out of memory"); + response->cc = ISULAD_ERR_MEMOUT; + return -1; + } + + for (int i {}; i < num; i++) { + const Checkpoint &checkpoint = gresponse->checkpoints(i); + const char *dir = !checkpoint.dir().empty() ? checkpoint.dir().c_str() : "-"; + checkpoints[i].dir = util_strdup_s(dir); + const char *name = !checkpoint.name().empty() ? checkpoint.name().c_str() : "-"; + checkpoints[i].name = util_strdup_s(name); + } + + response->checkpoints = checkpoints; + response->checkpoints_len = static_cast(num); + response->server_errono = gresponse->cc(); + if (!gresponse->errmsg().empty()) { + response->errmsg = util_strdup_s(gresponse->errmsg().c_str()); + } + + return 0; + } + + auto grpc_call(ClientContext *context, const ListCheckpointRequest &req, ListCheckpointResponse *reply) -> Status override + { + return stub_->List(context, req, reply); + } +}; + +class CheckpointRestore : public + ClientBase { +public: + explicit CheckpointRestore(void *args) + : ClientBase(args) + { + } + ~CheckpointRestore() = default; + CheckpointRestore(const CheckpointRestore &) = delete; + CheckpointRestore &operator=(const CheckpointRestore &) = delete; + + auto request_to_grpc(const isula_restore_checkpoint_request *request, RestoreCheckpointRequest *grequest) -> int override + { + if (request == nullptr) { + return -1; + } + if (request->container != nullptr) { + grequest->set_container(request->container); + } + if (request->dir != nullptr) { + grequest->set_dir(request->dir); + } + + return 0; + } + + auto response_from_grpc(RestoreCheckpointResponse *gresponse, isula_restore_checkpoint_response *response) -> int override + { + response->server_errono = static_cast(gresponse->cc()); + + if (!gresponse->errmsg().empty()) { + response->errmsg = util_strdup_s(gresponse->errmsg().c_str()); + return -1; + } + response->container=util_strdup_s(gresponse->container().c_str()); + + return 0; + } + + auto grpc_call(ClientContext *context, const RestoreCheckpointRequest &req, RestoreCheckpointResponse *reply) -> Status override + { + return stub_->Restore(context, req, reply); + } +}; + +auto grpc_checkpoints_client_ops_init(isula_connect_ops *ops) -> int +{ + + if (ops == nullptr) { + return -1; + } + ops->checkpoint.create = container_func; + ops->checkpoint.remove = container_func; + ops->checkpoint.list = container_func; + ops->checkpoint.restore = container_func; + + return 0; +} diff --git a/src/client/connect/grpc/grpc_checkpoints_client.h b/src/client/connect/grpc/grpc_checkpoints_client.h new file mode 100644 index 0000000000000000000000000000000000000000..93583a8715450ec4cdeff6de59561db948b46acc --- /dev/null +++ b/src/client/connect/grpc/grpc_checkpoints_client.h @@ -0,0 +1,16 @@ +#ifndef CLIENT_CONNECT_GRPC_GRPC_CHECKPOINTS_CLIENT_H +#define CLIENT_CONNECT_GRPC_GRPC_CHECKPOINTS_CLIENT_H + +#include "isula_connect.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int grpc_checkpoints_client_ops_init(isula_connect_ops *ops); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/src/client/connect/grpc/grpc_client.cc b/src/client/connect/grpc/grpc_client.cc index 18a849c22d4ffdede3c1462ce050c19ae6740b31..5f5aa3b488b9b13b2e3b828e51d841923fc62f17 100644 --- a/src/client/connect/grpc/grpc_client.cc +++ b/src/client/connect/grpc/grpc_client.cc @@ -17,6 +17,7 @@ #include "grpc_containers_client.h" #include "grpc_images_client.h" #include "grpc_volumes_client.h" +#include "grpc_checkpoints_client.h" int grpc_ops_init(isula_connect_ops *ops) { @@ -33,6 +34,9 @@ int grpc_ops_init(isula_connect_ops *ops) if (grpc_volumes_client_ops_init(ops) != 0) { return -1; } + if (grpc_checkpoints_client_ops_init(ops) != 0) { + return -1; + } return 0; } diff --git a/src/client/connect/grpc/grpc_volumes_client.cc b/src/client/connect/grpc/grpc_volumes_client.cc index d8eb74b270c80506d06611dfa185265cd32943b3..6382c1f9a7750c3e29402772d8260cdf535c7402 100644 --- a/src/client/connect/grpc/grpc_volumes_client.cc +++ b/src/client/connect/grpc/grpc_volumes_client.cc @@ -195,3 +195,6 @@ auto grpc_volumes_client_ops_init(isula_connect_ops *ops) -> int return 0; } + + + diff --git a/src/client/connect/isula_connect.h b/src/client/connect/isula_connect.h index d433d727377e52a06eb928d7174af30cbb06ea4a..6263cbbe60511725c5974c28086f199c2bcc532f 100644 --- a/src/client/connect/isula_connect.h +++ b/src/client/connect/isula_connect.h @@ -104,6 +104,23 @@ typedef struct { void *arg); } volume_ops; +typedef struct { + int (*list)(const struct isula_list_checkpoint_request *request, struct isula_list_checkpoint_response *response, + void *arg); + + int (*remove)(const struct isula_remove_checkpoint_request *request, struct isula_remove_checkpoint_response *response, + void *arg); + + int (*create)(const struct isula_create_checkpoint_request *request, struct isula_create_checkpoint_response *response, + void *arg); + + int (*restore)(const struct isula_restore_checkpoint_request *request, struct isula_restore_checkpoint_response *response, + void *arg); + + + +} checkpoint_ops; + typedef struct { int (*check)(const struct isula_health_check_request *request, struct isula_health_check_response *response, void *arg); @@ -113,6 +130,7 @@ typedef struct { container_ops container; image_ops image; volume_ops volume; + checkpoint_ops checkpoint; health_ops health; } isula_connect_ops; diff --git a/src/client/connect/protocol_type.c b/src/client/connect/protocol_type.c index 3e5dafb1d0ab9db6cc69d97ab47abcc832533288..27b50acce21ddaa4f5840cf269839a0a2cce8545 100644 --- a/src/client/connect/protocol_type.c +++ b/src/client/connect/protocol_type.c @@ -1388,3 +1388,16 @@ void isula_prune_volume_response_free(struct isula_prune_volume_response *respon free(response); return; } + +void isula_remove_checkpoint_response_free(struct isula_remove_checkpoint_response *response) +{ + if (response == NULL) { + return; + } + + free(response->errmsg); + response->errmsg = NULL; + + free(response); + return; +} diff --git a/src/client/connect/protocol_type.h b/src/client/connect/protocol_type.h index 62208d98f48127577adf87f87efe9421377ad590..7d40242b803666e58431026cb433e1549f24fa61 100644 --- a/src/client/connect/protocol_type.h +++ b/src/client/connect/protocol_type.h @@ -589,6 +589,8 @@ struct isula_volume_info { char *name; }; + + struct isula_list_volume_response { size_t volumes_len; struct isula_volume_info *volumes; @@ -619,6 +621,62 @@ struct isula_prune_volume_response { char *errmsg; }; + + + +struct isula_create_checkpoint_request { + char* container; + char* dir; +}; + +struct isula_create_checkpoint_response { + char* container; + uint32_t cc; + uint32_t server_errono; + char *errmsg; +}; + +struct isula_restore_checkpoint_request { + char* container; + char* dir; +}; + +struct isula_restore_checkpoint_response { + char* container; + uint32_t cc; + uint32_t server_errono; + char *errmsg; +}; + +struct isula_list_checkpoint_request { + char* dir; +}; + +struct isula_checkpoint_info{ + char *name; + char *dir; +}; + +struct isula_list_checkpoint_response { + size_t checkpoints_len; + struct isula_checkpoint_info *checkpoints; + uint32_t cc; + uint32_t server_errono; + char *errmsg; +}; + +struct isula_remove_checkpoint_request { + char* container; + char* dir; +}; + +struct isula_remove_checkpoint_response { + char* container; + uint32_t cc; + uint32_t server_errono; + char *errmsg; +}; + void container_events_format_free(container_events_format_t *value); struct isula_filters *isula_filters_parse_args(const char **array, size_t len); diff --git a/src/cmd/.DS_Store b/src/cmd/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ddd715fb7e45d33ff5490b854151551c7a0daebf Binary files /dev/null and b/src/cmd/.DS_Store differ diff --git a/src/cmd/command_parser.c b/src/cmd/command_parser.c index e925aa3285c2804a59040f113f98393093d56eda..3a80d9e852a10ed60f77ea4df60b647d25dad1bd 100644 --- a/src/cmd/command_parser.c +++ b/src/cmd/command_parser.c @@ -135,12 +135,20 @@ void subcommand_init(command_t *self, command_option_t *opts, int opts_len, int { (void)memset(self, 0, sizeof(command_t)); self->name = util_string_join(" ", argv, 2); + //printf("name:%s\n",self->name); self->argc = argc - 3; + //printf("argc:%d\n",self->argc); self->argv = argv + 3; + //printf("argv[0]:%s\n",self->argv[0]); + //printf("argv[1]:%s\n",self->argv[1]); self->usage = usage; + //printf("usage:%s\n",self->usage); self->description = description; + //printf("description:%s\n",self->description); self->options = opts; + //printf("options:%s\n",opts->description); self->option_count = opts_len; + //printf(":%s\n",self->name); } void command_option(command_t *self, command_option_type_t type, void *data, int small, const char *large, @@ -328,23 +336,33 @@ static int command_parse_short_arg(command_t *self, const char *arg) static int command_parse_long_arg(command_t *self, const char *arg) { int j = 0; + //printf("type:%s\n",(char *)self->options->large); + //printf("usage:%s\n",(char *)self->usage); if (strcmp(arg, "help") == 0) { command_help(self); exit(0); } + //printf("option_count=%d\n",self->option_count); for (j = 0; j < self->option_count; ++j) { + + //printf("j=%d\n",j); command_option_t *opt = &self->options[j]; + //printf("%s\n",opt->name); const char *opt_arg = NULL; opt->hasdata = false; if (opt->large == NULL) { continue; } - + //printf("arg:%s\n",arg); + //printf("opt->large:%s\n",opt->large); opt_arg = util_str_skip_str(arg, opt->large); + + if (opt_arg == NULL) { + continue; } @@ -372,16 +390,19 @@ static int command_parse_long_arg(command_t *self, const char *arg) int command_parse_args(command_t *self, int *argc, char * const **argv) { + //printf("command_parse_args\n"); int ret = 0; for (; self->argc; self->argc--, self->argv++) { const char *arg_opt = self->argv[0]; + //printf("%c\n",arg_opt[1]); if (arg_opt[0] != '-' || !arg_opt[1]) { break; } // short option if (arg_opt[1] != '-') { + //printf("short\n"); arg_opt = arg_opt + 1; ret = command_parse_short_arg(self, arg_opt); if (!ret) { @@ -399,6 +420,7 @@ int command_parse_args(command_t *self, int *argc, char * const **argv) // long option arg_opt = arg_opt + 2; + //printf("long\n"); ret = command_parse_long_arg(self, arg_opt); if (ret == 0) { continue; diff --git a/src/cmd/isula/CMakeLists.txt b/src/cmd/isula/CMakeLists.txt index c7bf2f85603645ed3a4f1adbb50998ac2b84d445..573835241e5b034d2667733e01dffe21182933e1 100644 --- a/src/cmd/isula/CMakeLists.txt +++ b/src/cmd/isula/CMakeLists.txt @@ -5,6 +5,7 @@ add_subdirectory(extend) add_subdirectory(stream) add_subdirectory(images) add_subdirectory(volume) +add_subdirectory(checkpoint) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} isula_srcs) set(CMD_ISULA_SRCS @@ -15,6 +16,7 @@ set(CMD_ISULA_SRCS ${ISULA_VOLUME_SRCS} ${ISULA_INFORMATION_SRCS} ${ISULA_STREAM_SRCS} + ${ISULA_CHECKPOINT_SRCS} PARENT_SCOPE ) @@ -26,5 +28,6 @@ set(CMD_ISULA_INCS ${CMAKE_CURRENT_SOURCE_DIR}/volume ${CMAKE_CURRENT_SOURCE_DIR}/information ${CMAKE_CURRENT_SOURCE_DIR}/stream + ${CMAKE_CURRENT_SOURCE_DIR}/checkpoint PARENT_SCOPE ) diff --git a/src/cmd/isula/checkpoint/CMakeLists.txt b/src/cmd/isula/checkpoint/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e0960b70cc86e1f3fba54ccddf5f2d8001158dd6 --- /dev/null +++ b/src/cmd/isula/checkpoint/CMakeLists.txt @@ -0,0 +1,7 @@ +# get current directory sources files +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} isula_checkpoint_srcs) + +set(ISULA_CHECKPOINT_SRCS + ${isula_checkpoint_srcs} + PARENT_SCOPE + ) diff --git a/src/cmd/isula/checkpoint/checkpoint.c b/src/cmd/isula/checkpoint/checkpoint.c new file mode 100644 index 0000000000000000000000000000000000000000..4c9b64f4a5f7027d416e96d1a45c32ce54dd5bfd --- /dev/null +++ b/src/cmd/isula/checkpoint/checkpoint.c @@ -0,0 +1,65 @@ + +#include "checkpoint.h" + +#include "isula_commands.h" +#include "isula_libutils/log.h" +#include "utils.h" +#include "cpcreate.h" + +#include "cpremove.h" +#include "cplist.h" +#include "cprestore.h" + +const char g_cmd_checkpoint_desc[] = "Manage checkpoints"; +const char g_cmd_checkpoint_usage[] = "isula checkpoint COMMAND"; + + +struct command g_checkpoint_commands[] = { + { + // `checkpoint ls` sub-command + "ls", false, cmd_checkpoint_ls_main, g_cmd_checkpoint_ls_desc, NULL, &g_cmd_checkpoint_ls_args + }, + + { + // `checkpoint create` sub-command + "create", false, cmd_checkpoint_create_main, g_cmd_checkpoint_create_desc, NULL, &g_cmd_checkpoint_create_args + }, + + { + // `checkpoint rm` sub-command + "rm", false, cmd_checkpoint_rm_main, g_cmd_checkpoint_rm_desc, NULL, &g_cmd_checkpoint_rm_args + }, + { + // `checkpoint restore` sub-command + "restore", false, cmd_checkpoint_restore_main, g_cmd_checkpoint_restore_desc, NULL, &g_cmd_checkpoint_restore_args + }, + { NULL, false, NULL, NULL, NULL, NULL } // End of the list +}; + + +int cmd_checkpoint_main(int argc, const char **argv) +{ + const struct command *command = NULL; + char *program = NULL; + + program = util_string_join(" ", argv, 2); + + if (argc == 2) { + return command_subcmd_help(program, g_checkpoint_commands, argc - 2, (const char **)(argv + 2)); + } + + if (strcmp(argv[2], "--help") == 0) { + // isula checkpoint help command format: isula checkpoint --help + return command_subcmd_help(program, g_checkpoint_commands, argc - 3, (const char **)(argv + 3)); + } + + command = command_by_name(g_checkpoint_commands, argv[2]); + if (command != NULL) { + return command->executor(argc, (const char **)argv); + } + + printf("%s: command \"%s\" not found\n", program, argv[2]); + printf("Run `%s --help` for a list of sub-commands\n", program); + return 1; +} + diff --git a/src/cmd/isula/checkpoint/checkpoint.h b/src/cmd/isula/checkpoint/checkpoint.h new file mode 100644 index 0000000000000000000000000000000000000000..ef1fbd916eb1268494318784e4cdfac622006c6d --- /dev/null +++ b/src/cmd/isula/checkpoint/checkpoint.h @@ -0,0 +1,17 @@ + +#ifndef CMD_ISULA_CHECKPOINT_H +#define CMD_ISULA_CHECKPOINT_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern const char g_cmd_checkpoint_desc[]; +extern const char g_cmd_checkpoint_usage[]; +int cmd_checkpoint_main(int argc, const char **argv); + +#ifdef __cplusplus +} +#endif + +#endif // CMD_ISULA_CHECKPOINT_H diff --git a/src/cmd/isula/checkpoint/cpcreate.c b/src/cmd/isula/checkpoint/cpcreate.c new file mode 100644 index 0000000000000000000000000000000000000000..22db8877e04c96a0084ff21a3dd1bc680d5c2e1b --- /dev/null +++ b/src/cmd/isula/checkpoint/cpcreate.c @@ -0,0 +1,134 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2020. 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: wangfengtu + * Create: 2020-09-04 + * Description: provide checkpoint remove functions + ******************************************************************************/ +#include "cpcreate.h" + +#include +#include +#include +#include + +#include "utils.h" +#include "client_arguments.h" +#include "isula_connect.h" +#include "isula_libutils/log.h" +#include "connect.h" +#include "protocol_type.h" +#include + +const char g_cmd_checkpoint_create_desc[] = + "Create a checkpoint from a running container"; +const char g_cmd_checkpoint_create_usage[] = "create [OPTIONS] CONTAINER"; + +struct client_arguments g_cmd_checkpoint_create_args; + +#define CREATE_OPTIONS(cmdargs) \ + { CMD_OPT_TYPE_STRING, false, "checkpoint-dir", 0, &(cmdargs).checkpoint_dir, "Use a custom checkpoint storage directory", NULL }, + + +static int client_checkpoint_create(const struct client_arguments *args, char ***checkpoints, size_t *checkpoints_len){ + + isula_connect_ops *ops =NULL; + struct isula_create_checkpoint_request request ={0}; + struct isula_create_checkpoint_response *response =NULL; + client_connect_config_t config ={0}; + int ret = 0; + + response = util_common_calloc_s(sizeof(struct isula_create_checkpoint_response)); + if (response==NULL){ + ERROR("Out of memory"); + return -1; + } + request.container = args->name; + request.dir=args->checkpoint_dir; + + + ops = get_connect_client_ops(); + + if(ops==NULL || ops->checkpoint.create==NULL){ + ERROR("Unimplemented ops"); + ret=-1; + goto out; + } + //把参数放到了config里 + config = get_connect_config(args); + + ret=ops->checkpoint.create(&request,response,&config); + + if(ret!=0){ + client_print_error(response->cc,response->server_errono,response->errmsg); + if(response->server_errono){ + ret=ESERVERERROR; + } + + goto out; + } + printf("%s\n",args->name); + +out: + //isula_create_checkpoint_response_free(response); + + return ret; +} + +int cmd_checkpoint_create_main(int argc, const char **argv) +{ + //int i = 0; + struct isula_libutils_log_config lconf = { 0 }; + int exit_code = 1; + command_t cmd; + char **checkpoints = NULL; + size_t checkpoints_len = 0; + // char ch = 'n'; + struct command_option options[] = { + CREATE_OPTIONS(g_cmd_checkpoint_create_args) + }; + //printf("%s",options[0]) + + if (client_arguments_init(&g_cmd_checkpoint_create_args)) { + COMMAND_ERROR("client arguments init failed"); + exit(ECOMMON); + } + g_cmd_checkpoint_create_args.progname = util_string_join(" ", argv, 2); + isula_libutils_default_log_config(argv[0], &lconf); + subcommand_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv, g_cmd_checkpoint_create_desc, + g_cmd_checkpoint_create_usage); + + if (command_parse_args(&cmd, &g_cmd_checkpoint_create_args.argc, &g_cmd_checkpoint_create_args.argv)) { + exit(exit_code); + } + + //printf("%s\n",g_cmd_checkpoint_create_args.checkpoint_dir); + if (isula_libutils_log_enable(&lconf)) { + COMMAND_ERROR("checkpoint create: log init failed"); + exit(exit_code); + } + + + g_cmd_checkpoint_create_args.name=g_cmd_checkpoint_create_args.argv[0]; + + if(g_cmd_checkpoint_create_args.argc>1){ + g_cmd_checkpoint_create_args.checkpoint_dir=g_cmd_checkpoint_create_args.argv[1]; + } + + //printf("%s\n",g_cmd_checkpoint_create_args.name); + if (client_checkpoint_create(&g_cmd_checkpoint_create_args, &checkpoints, &checkpoints_len) != 0) { + ERROR("Create checkpoints failed"); + exit(exit_code); + } + + + exit(EXIT_SUCCESS); + +} diff --git a/src/cmd/isula/checkpoint/cpcreate.h b/src/cmd/isula/checkpoint/cpcreate.h new file mode 100644 index 0000000000000000000000000000000000000000..38135e820e7a929531b549b6d9e1228c1c6c3b12 --- /dev/null +++ b/src/cmd/isula/checkpoint/cpcreate.h @@ -0,0 +1,24 @@ + +#ifndef CMD_ISULA_CHECKPOINT_CREATE_H +#define CMD_ISULA_CHECKPOINT_CREATE_H + +#include +#include + +#include "client_arguments.h" +#include "command_parser.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const char g_cmd_checkpoint_create_desc[]; +extern const char g_cmd_checkpoint_create_usage[]; +extern struct client_arguments g_cmd_checkpoint_create_args; +int cmd_checkpoint_create_main(int argc, const char **argv); + +#ifdef __cplusplus +} +#endif + +#endif // CMD_ISULA_CHECKPOINT_CREATE_H diff --git a/src/cmd/isula/checkpoint/cplist.c b/src/cmd/isula/checkpoint/cplist.c new file mode 100644 index 0000000000000000000000000000000000000000..43b91f394fde4cf25a65daec0d2dfc51a685ad81 --- /dev/null +++ b/src/cmd/isula/checkpoint/cplist.c @@ -0,0 +1,179 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2020. 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: wangfengtu + * Create: 2020-09-04 + * Description: provide checkpoint remove functions + ******************************************************************************/ +#include "cplist.h" + +#include +#include +#include +#include +#include +#include "utils.h" +#include "client_arguments.h" +#include "isula_connect.h" +#include "isula_libutils/log.h" +#include "connect.h" +#include "protocol_type.h" + +const char g_cmd_checkpoint_ls_desc[] = + "List checkpoints for a container"; +const char g_cmd_checkpoint_ls_usage[] = "ls [OPTIONS]"; + +struct client_arguments g_cmd_checkpoint_ls_args; + +#define LS_OPTIONS(cmdargs) \ + { CMD_OPT_TYPE_STRING, false, "checkpoint-dir", 0, &(cmdargs).checkpoint_dir, "Use a custom checkpoint storage directory", NULL }, + + +struct lengths { + unsigned int name_length; + unsigned int dir_length; +}; +/* list print table */ +static void list_print_table(const struct isula_list_checkpoint_response *resp, const struct lengths *length) +{ + size_t i = 0; + + /* print header */ + printf("%-*s ", (int)length->name_length, "CHECKPOINT"); + printf("%-*s ", (int)length->dir_length, "CHECKPOINT_DIR"); + printf("\n"); + + for (i = 0; i < resp->checkpoints_len; i++) { + printf("%-*s ", (int)length->name_length, resp->checkpoints[i].name); + printf("%-*s ", (int)length->dir_length, resp->checkpoints[i].dir); + printf("\n"); + } +} + +static void checkpoint_info_print(const struct isula_list_checkpoint_response *response) +{ + struct lengths max_len = { + .name_length = 10, + .dir_length = 10, + }; + + list_print_table(response, &max_len); +} + +static int client_checkpoint_ls(const struct client_arguments *args, char ***checkpoints, size_t *checkpoints_len){ + //printf("args->checkpoint_dir:%s\n",args->checkpoint_dir); + isula_connect_ops *ops =NULL; + struct isula_list_checkpoint_request request ={0}; + struct isula_list_checkpoint_response *response =NULL; + client_connect_config_t config ={0}; + int ret = 0; + + response = util_common_calloc_s(sizeof(struct isula_list_checkpoint_response)); + if (response==NULL){ + ERROR("Out of memory"); + return -1; + } + + if(args->checkpoint_dir){ + request.dir=args->checkpoint_dir; + }else{ + request.dir="/tmp/isula-criu/"; + } + + + ops = get_connect_client_ops(); + + if(ops==NULL || ops->checkpoint.list==NULL){ + ERROR("Unimplemented ops"); + ret=-1; + goto out; + } + //把参数放到了config里 + config = get_connect_config(args); + + ret=ops->checkpoint.list(&request,response,&config); + + if(ret!=0){ + + client_print_error(response->cc,response->server_errono,response->errmsg); + if(response->server_errono){ + ret=ESERVERERROR; + } + goto out; + } + + checkpoint_info_print(response); + +out: + //isula_create_checkpoint_response_free(response); + return ret; + + +} + +int cmd_checkpoint_ls_main(int argc, const char **argv) +{ + //int i = 0; + struct isula_libutils_log_config lconf = { 0 }; + int exit_code = 1; + command_t cmd; + + char **checkpoints = NULL; + size_t checkpoints_len = 0; + // char ch = 'n'; + + struct command_option options[] = { + LS_OPTIONS(g_cmd_checkpoint_ls_args) + }; + //printf("%s",options[0]) + + + if (client_arguments_init(&g_cmd_checkpoint_ls_args)) { + COMMAND_ERROR("client arguments init failed"); + exit(ECOMMON); + } + //printf("%d\n",cmd.option_count); + g_cmd_checkpoint_ls_args.progname = util_string_join(" ", argv, 2); + isula_libutils_default_log_config(argv[0], &lconf); + subcommand_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv, g_cmd_checkpoint_ls_desc, + g_cmd_checkpoint_ls_usage); + //here failed + //printf("%d\n",cmd.option_count); + if (command_parse_args(&cmd, &g_cmd_checkpoint_ls_args.argc, &g_cmd_checkpoint_ls_args.argv)) { + exit(exit_code); + } + //printf("%s\n",cmd.options->large); + //printf("%s\n",g_cmd_checkpoint_ls_args.checkpoint_dir); + + if (isula_libutils_log_enable(&lconf)) { + COMMAND_ERROR("checkpoint ls: log init failed"); + exit(exit_code); + } + + + //printf("%s\n",g_cmd_checkpoint_ls_args.argv[0]); + if (g_cmd_checkpoint_ls_args.argc != 0) { + + COMMAND_ERROR("%s: \"checkpoint ls\" requires exactly 0 arguments.", g_cmd_checkpoint_ls_args.progname); + exit(exit_code); + } + + //printf("%s\n","name"); + //g_cmd_checkpoint_ls_args.name=g_cmd_checkpoint_ls_args.argv[0]; + //printf("%s\n",g_cmd_checkpoint_ls_args.name); + if (client_checkpoint_ls(&g_cmd_checkpoint_ls_args, &checkpoints, &checkpoints_len) != 0) { + ERROR("Create checkpoints failed"); + exit(exit_code); + } + + + exit(EXIT_SUCCESS); + +} diff --git a/src/daemon/entry/connect/metrics/metrics_service.h b/src/cmd/isula/checkpoint/cplist.h similarity index 57% rename from src/daemon/entry/connect/metrics/metrics_service.h rename to src/cmd/isula/checkpoint/cplist.h index 426bfd2b49ca5ad09d30e1348ac14bdd6d55abd0..349ea95fefb66aec74f4aeac513398775cfcf7de 100644 --- a/src/daemon/entry/connect/metrics/metrics_service.h +++ b/src/cmd/isula/checkpoint/cplist.h @@ -1,7 +1,6 @@ /****************************************************************************** - * Copyright (c) KylinSoft Co., Ltd. 2021. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2020. 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 @@ -9,29 +8,26 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: xiapin - * Create: 2021-08-17 - * Description: provide metric service definition + * Author: wangfengtu + * Create: 2020-09-05 + * Description: provide list CHECKPOINT definition ******************************************************************************/ -#ifndef DAEMON_ENTRY_CONNECT_METRICS_METRICS_SERVICE_H -#define DAEMON_ENTRY_CONNECT_METRICS_METRICS_SERVICE_H +#ifndef CMD_ISULA_CHECKPOINT_LIST_H +#define CMD_ISULA_CHECKPOINT_LIST_H -#include +#include "client_arguments.h" #ifdef __cplusplus extern "C" { #endif -#define METRIC_GET_BY_TYPE "/metrics/type" - -void metrics_get_by_type_cb(evhtp_request_t *req, void *arg); - -int metrics_service_init(int port); - -void metrics_service_shutdown(); +extern const char g_cmd_checkpoint_ls_desc[]; +extern const char g_cmd_checkpoint_ls_usage[]; +extern struct client_arguments g_cmd_checkpoint_ls_args; +int cmd_checkpoint_ls_main(int argc, const char **argv); #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif // CMD_ISULA_CHECKPOINT_LIST_H diff --git a/src/cmd/isula/checkpoint/cpremove.c b/src/cmd/isula/checkpoint/cpremove.c new file mode 100644 index 0000000000000000000000000000000000000000..72110394f9bf7808e819154f0735a520315a63af --- /dev/null +++ b/src/cmd/isula/checkpoint/cpremove.c @@ -0,0 +1,149 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2020. 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: wangfengtu + * rm: 2020-09-04 + * Description: provide checkpoint remove functions + ******************************************************************************/ +#include "cpremove.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include "utils.h" +#include "client_arguments.h" +#include "isula_connect.h" +#include "isula_libutils/log.h" +#include "connect.h" +#include "protocol_type.h" + +const char g_cmd_checkpoint_rm_desc[] = + "Remove a checkpoint"; +const char g_cmd_checkpoint_rm_usage[] = "rm [OPTIONS] CONTAINER"; + +struct client_arguments g_cmd_checkpoint_rm_args; + +#define REMOVE_OPTIONS(cmdargs) \ + { CMD_OPT_TYPE_STRING, false, "checkpoint-dir", 0, &(cmdargs).checkpoint_dir, "Use a custom checkpoint storage directory", NULL }, + + + + + + +static int client_checkpoint_rm(const struct client_arguments *args, char ***checkpoints, size_t *checkpoints_len){ + // printf("args->checkpoint_dir:%s\n",args->checkpoint_dir); + isula_connect_ops *ops =NULL; + struct isula_remove_checkpoint_request request ={0}; + struct isula_remove_checkpoint_response *response =NULL; + client_connect_config_t config ={0}; + int ret = 0; + + response = util_common_calloc_s(sizeof(struct isula_remove_checkpoint_response)); + if (response==NULL){ + ERROR("Out of memory"); + return -1; + } + + request.container = args->name; + request.dir=args->checkpoint_dir; + + + + + ops = get_connect_client_ops(); + + if(ops==NULL || ops->checkpoint.remove==NULL){ + ERROR("Unimplemented ops"); + ret=-1; + goto out; + } + //把参数放到了config里 + config = get_connect_config(args); + + ret=ops->checkpoint.remove(&request,response,&config); + if(ret!=0){ + client_print_error(response->cc,response->server_errono,response->errmsg); + if(response->server_errono){ + ret=ESERVERERROR; + } + goto out; + } + printf("%s\n",args->name); + +out: + //isula_remove_checkpoint_response_free(response); + return ret; +} + +int cmd_checkpoint_rm_main(int argc, const char **argv) +{ + //int i = 0; + struct isula_libutils_log_config lconf = { 0 }; + int exit_code = 1; + command_t cmd; + char **checkpoints = NULL; + size_t checkpoints_len = 0; + // char ch = 'n'; + struct command_option options[] = { LOG_OPTIONS(lconf) COMMON_OPTIONS(g_cmd_checkpoint_rm_args) + REMOVE_OPTIONS(g_cmd_checkpoint_rm_args) + }; + //printf("%s",options[0]) + + if (client_arguments_init(&g_cmd_checkpoint_rm_args)) { + COMMAND_ERROR("client arguments init failed"); + exit(ECOMMON); + } + g_cmd_checkpoint_rm_args.progname = util_string_join(" ", argv, 2); + isula_libutils_default_log_config(argv[0], &lconf); + subcommand_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv, g_cmd_checkpoint_rm_desc, + g_cmd_checkpoint_rm_usage); + + if (command_parse_args(&cmd, &g_cmd_checkpoint_rm_args.argc, &g_cmd_checkpoint_rm_args.argv)) { + exit(exit_code); + } + if (isula_libutils_log_enable(&lconf)) { + COMMAND_ERROR("checkpoint rm: log init failed"); + exit(exit_code); + } + + + + if (g_cmd_checkpoint_rm_args.argc != 1) { + + COMMAND_ERROR("%s: \"checkpoint rm\" requires exactly 1 arguments.", g_cmd_checkpoint_rm_args.progname); + exit(exit_code); + } + + //printf("%s\n","name"); + g_cmd_checkpoint_rm_args.name=g_cmd_checkpoint_rm_args.argv[0]; + if(g_cmd_checkpoint_rm_args.argc>1){ + g_cmd_checkpoint_rm_args.checkpoint_dir=g_cmd_checkpoint_rm_args.argv[1]; + } + //printf("%s\n",g_cmd_checkpoint_rm_args.name); + if (client_checkpoint_rm(&g_cmd_checkpoint_rm_args, &checkpoints, &checkpoints_len) != 0) { + ERROR("rm checkpoints failed"); + exit(exit_code); + } + + + exit(EXIT_SUCCESS); + +} diff --git a/src/daemon/executor/metrics_cb/metrics_cb.h b/src/cmd/isula/checkpoint/cpremove.h similarity index 54% rename from src/daemon/executor/metrics_cb/metrics_cb.h rename to src/cmd/isula/checkpoint/cpremove.h index bfe2a11d2135027a3b881914c172bb1ad2a1d8b2..5655c9ae7763da4915f869199565d88c61343ff0 100644 --- a/src/daemon/executor/metrics_cb/metrics_cb.h +++ b/src/cmd/isula/checkpoint/cpremove.h @@ -1,31 +1,33 @@ /****************************************************************************** - * Copyright (c) KylinSoft Co., Ltd. 2021. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2020. 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: xiapin - * Create: 2021-08-17 - * Description: provide metric callback function definition + * See the Mulan PSL v2 for more detairm. + * Author: wangfengtu + * Create: 2020-09-05 + * Description: provide list CHECKPOINT definition ******************************************************************************/ -#ifndef DAEMON_EXECUTOR_METRICS_CB_METRICS_CB_H -#define DAEMON_EXECUTOR_METRICS_CB_METRICS_CB_H +#ifndef CMD_ISULA_CHECKPOINT_REMOVE_H +#define CMD_ISULA_CHECKPOINT_REMOVE_H -#include "callback.h" +#include "client_arguments.h" #ifdef __cplusplus extern "C" { #endif -void metrics_callback_init(service_metrics_callback_t *cb); +extern const char g_cmd_checkpoint_rm_desc[]; +extern const char g_cmd_checkpoint_rm_usage[]; +extern struct client_arguments g_cmd_checkpoint_rm_args; +int cmd_checkpoint_rm_main(int argc, const char **argv); #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif // CMD_ISULA_CHECKPOINT_REMOVE_H diff --git a/src/cmd/isula/checkpoint/cprestore.c b/src/cmd/isula/checkpoint/cprestore.c new file mode 100644 index 0000000000000000000000000000000000000000..e152ba26769720046002a1c590ac483d57a29447 --- /dev/null +++ b/src/cmd/isula/checkpoint/cprestore.c @@ -0,0 +1,139 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2020. 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: wangfengtu + * restore: 2020-09-04 + * Description: provide checkpoint remove functions + ******************************************************************************/ +#include "cprestore.h" + +#include +#include +#include +#include +#include +#include "utils.h" +#include "client_arguments.h" +#include "isula_connect.h" +#include "isula_libutils/log.h" +#include "connect.h" +#include "protocol_type.h" + +const char g_cmd_checkpoint_restore_desc[] = + "Restore a checkpoint"; +const char g_cmd_checkpoint_restore_usage[] = "restore [OPTIONS] checkpoint"; + +struct client_arguments g_cmd_checkpoint_restore_args; + +#define RESTORE_OPTIONS(cmdargs) \ + { CMD_OPT_TYPE_STRING, false, "checkpoint-dir", 0, &(cmdargs).checkpoint_dir, "Use a custom checkpoint storage directory", NULL }, + + + + +static int client_checkpoint_restore(const struct client_arguments *args, char ***checkpoints, size_t *checkpoints_len){ + // printf("args->checkpoint_dir:%s\n",args->checkpoint_dir); + isula_connect_ops *ops =NULL; + struct isula_restore_checkpoint_request request ={0}; + struct isula_restore_checkpoint_response *response =NULL; + client_connect_config_t config ={0}; + int ret = 0; + + response = util_common_calloc_s(sizeof(struct isula_restore_checkpoint_response)); + if (response==NULL){ + ERROR("Out of memory"); + return -1; + } + request.container = args->name; + request.dir=args->checkpoint_dir; + + ops = get_connect_client_ops(); + + if(ops==NULL || ops->checkpoint.restore==NULL){ + ERROR("Unimplemented ops"); + ret=-1; + goto out; + } + //把参数放到了config里 + config = get_connect_config(args); + //把config传递给了grpc,不知道行不行呢 + ret=ops->checkpoint.restore(&request,response,&config); + + if(ret!=0){ + client_print_error(response->cc,response->server_errono,response->errmsg); + if(response->server_errono){ + ret=ESERVERERROR; + } + goto out; + } + printf("%s\n",args->name); + +out: + + //isula_restore_checkpoint_response_free(response); + return ret; + + +} + +int cmd_checkpoint_restore_main(int argc, const char **argv) +{ + //int i = 0; + struct isula_libutils_log_config lconf = { 0 }; + int exit_code = 1; + command_t cmd; + char **checkpoints = NULL; + size_t checkpoints_len = 0; + // char ch = 'n'; + struct command_option options[] = { LOG_OPTIONS(lconf) COMMON_OPTIONS(g_cmd_checkpoint_restore_args) + RESTORE_OPTIONS(g_cmd_checkpoint_restore_args) + }; + //printf("%s",options[0]) + + if (client_arguments_init(&g_cmd_checkpoint_restore_args)) { + COMMAND_ERROR("client arguments init failed"); + exit(ECOMMON); + } + g_cmd_checkpoint_restore_args.progname = util_string_join(" ", argv, 2); + isula_libutils_default_log_config(argv[0], &lconf); + subcommand_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv, g_cmd_checkpoint_restore_desc, + g_cmd_checkpoint_restore_usage); + + if (command_parse_args(&cmd, &g_cmd_checkpoint_restore_args.argc, &g_cmd_checkpoint_restore_args.argv)) { + exit(exit_code); + } + if (isula_libutils_log_enable(&lconf)) { + COMMAND_ERROR("checkpoint restore: log init failed"); + exit(exit_code); + } + + + + if (g_cmd_checkpoint_restore_args.argc != 1) { + + COMMAND_ERROR("%s: \"checkpoint restore\" requires exactly 1 arguments.", g_cmd_checkpoint_restore_args.progname); + exit(exit_code); + } + + //printf("%s\n","name"); + g_cmd_checkpoint_restore_args.name=g_cmd_checkpoint_restore_args.argv[0]; + if(g_cmd_checkpoint_restore_args.argc>1){ + g_cmd_checkpoint_restore_args.checkpoint_dir=g_cmd_checkpoint_restore_args.argv[1]; + } + //printf("%s\n",g_cmd_checkpoint_restore_args.name); + if (client_checkpoint_restore(&g_cmd_checkpoint_restore_args, &checkpoints, &checkpoints_len) != 0) { + ERROR("restore checkpoints failed"); + exit(exit_code); + } + + + exit(EXIT_SUCCESS); + +} diff --git a/src/daemon/entry/connect/rest/rest_metrics_service.h b/src/cmd/isula/checkpoint/cprestore.h similarity index 52% rename from src/daemon/entry/connect/rest/rest_metrics_service.h rename to src/cmd/isula/checkpoint/cprestore.h index 8adee5c8a578412ee09125221b251fe7277f638a..fb192154b48242ef098f50154dcadcded365b042 100644 --- a/src/daemon/entry/connect/rest/rest_metrics_service.h +++ b/src/cmd/isula/checkpoint/cprestore.h @@ -1,31 +1,33 @@ /****************************************************************************** - * Copyright (c) KylinSoft Co., Ltd. 2021. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2020. 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: xiapin - * Create: 2021-08-17 - * Description: provide metric restful service definition + * See the Mulan PSL v2 for more detairestore. + * Author: wangfengtu + * Create: 2020-09-05 + * Description: provide list CHECKPOINT definition ******************************************************************************/ -#ifndef DAEMON_ENTRY_CONNECT_REST_REST_METRICS_SERVICE_H -#define DAEMON_ENTRY_CONNECT_REST_REST_METRICS_SERVICE_H +#ifndef CMD_ISULA_CHECKPOINT_RESTORE_H +#define CMD_ISULA_CHECKPOINT_RESTORE_H -#include +#include "client_arguments.h" #ifdef __cplusplus extern "C" { #endif -int rest_register_metrics_handler(evhtp_t *htp); +extern const char g_cmd_checkpoint_restore_desc[]; +extern const char g_cmd_checkpoint_restore_usage[]; +extern struct client_arguments g_cmd_checkpoint_restore_args; +int cmd_checkpoint_restore_main(int argc, const char **argv); #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif // CMD_ISULA_CHECKPOINT_RESTORE_H diff --git a/src/cmd/isula/client_arguments.h b/src/cmd/isula/client_arguments.h index 6bd99cb0aef56696ca6626b87b4bee84a89995dd..b95335b9916b7af4cb7a297a95e4943e0019af16 100644 --- a/src/cmd/isula/client_arguments.h +++ b/src/cmd/isula/client_arguments.h @@ -337,6 +337,8 @@ struct client_arguments { char *password; char *server; bool password_stdin; + //checkpoint + char *checkpoint_dir; /* extra environment variables used in exec */ char **extra_env; diff --git a/src/cmd/isula/extend/stats.c b/src/cmd/isula/extend/stats.c index 35458f146a13e22d14fc190dc20a6557a81619ca..b35156a6a7e8fa7793468d50413f676b8eb42d6b 100644 --- a/src/cmd/isula/extend/stats.c +++ b/src/cmd/isula/extend/stats.c @@ -137,8 +137,6 @@ static void stats_print(const struct isula_container_info *stats) if (d_sys_use > 0 && stats->online_cpus > 0) { cpu_percent = ((double)d_cpu_use / d_sys_use) * stats->online_cpus * PERCENT; } - - break; } } diff --git a/src/cmd/isula/main.c b/src/cmd/isula/main.c index a69df5d52d20f4165eb206d13f1b44935b57a4ac..bdf3167eef310bf08e6b8f9c45b9f5b4b6493b84 100644 --- a/src/cmd/isula/main.c +++ b/src/cmd/isula/main.c @@ -55,6 +55,10 @@ #include "remove.h" #include "prune.h" #include "list.h" +#include "checkpoint.h" +#include "cplist.h" +#include "cpcreate.h" +#include "cpremove.h" // The list of our supported commands struct command g_commands[] = { @@ -94,6 +98,10 @@ struct command g_commands[] = { // `unpause` sub-command "unpause", false, cmd_resume_main, g_cmd_resume_desc, NULL, &g_cmd_resume_args }, + { + // `volume` sub-command + "checkpoint", true, cmd_checkpoint_main, g_cmd_checkpoint_desc, NULL, NULL + }, #ifdef ENABLE_OCI_IMAGE { // `stats` sub-command diff --git a/src/cmd/isulad-shim/process.c b/src/cmd/isulad-shim/process.c index b3014d7a3423cf49e884c34bf9ee08a5fbb5f5ad..fa7242eec8ff9a039d4c74259015cd262d74500a 100644 --- a/src/cmd/isulad-shim/process.c +++ b/src/cmd/isulad-shim/process.c @@ -533,7 +533,7 @@ static void *task_console_accept(void *data) } /* p.state.resize_fifo------>runtime.console */ - ret = connect_to_isulad(ac->p, EXEC_RESIZE, ac->p->state->resize_fifo, recv_fd); + ret = connect_to_isulad(ac->p, EXEC_RESIZE, ac->p->state->exit_fifo, recv_fd); if (ret != SHIM_OK) { goto out; } diff --git a/src/cmd/isulad/isulad_commands.h b/src/cmd/isulad/isulad_commands.h index 843f23ecfb3c4c46e14b6fd34e4d59383fc01759..02007f3c013902914686dd92d2d9d03b4ff3998c 100644 --- a/src/cmd/isulad/isulad_commands.h +++ b/src/cmd/isulad/isulad_commands.h @@ -37,18 +37,6 @@ int update_hosts(struct service_arguments *args); int update_default_ulimit(struct service_arguments *args); int command_default_ulimit_append(command_option_t *option, const char *arg); -#if (defined GRPC_CONNECTOR) && (defined ENABLE_METRICS) -#define METRICS_PORT_OPT(cmdargs) \ - { CMD_OPT_TYPE_CALLBACK, \ - false, "metrics-port", 0, &(cmdargs)->json_confs->metrics_port, \ - "The metric service listening port (default 9090)", \ - command_convert_uint \ - }, \ - -#else -#define METRICS_PORT_OPT(cmdargs) -#endif - #define ISULAD_OPTIONS(cmdargs) \ { CMD_OPT_TYPE_CALLBACK, \ false, \ @@ -278,8 +266,7 @@ int command_default_ulimit_append(command_option_t *option, const char *arg); { CMD_OPT_TYPE_BOOL, \ false, "selinux-enabled", 0, &(cmdargs)->json_confs->selinux_enabled, \ "Enable selinux support", NULL \ - }, \ - METRICS_PORT_OPT(cmdargs) + } #ifdef __cplusplus } diff --git a/src/cmd/isulad/main.c b/src/cmd/isulad/main.c index 22500e110f43cabf6a13f03a38530d400b0774c8..47bd6e2c2761eec70d72ca39c5dabd7c3848c473 100644 --- a/src/cmd/isulad/main.c +++ b/src/cmd/isulad/main.c @@ -784,7 +784,7 @@ static int overlay_supports_selinux(bool *supported) char sym_type[KALLSYMS_ITEM_MAX_LEN] = { 0 }; char sym_name[KALLSYMS_ITEM_MAX_LEN] = { 0 }; - if (sscanf(buf, "%99s %99s %99s", sym_addr, sym_type, sym_name) != 3) { + if (sscanf(buf, "%s %s %s", sym_addr, sym_type, sym_name) != 3) { ERROR("sscanf buffer failed"); ret = -1; goto out; @@ -1292,7 +1292,7 @@ static int isulad_server_init_service() #else INFO("Creating rest server..."); #endif - if (server_common_init(args, daemon_shutdown)) { + if (server_common_init(args)) { ERROR("Failed to init service"); goto unlock_out; } @@ -1419,11 +1419,6 @@ static int pre_init_daemon(int argc, char **argv, char **msg) goto out; } - if (init_isulad_daemon_constants() != 0) { - *msg = "Failed to parse isulad daemon constants"; - goto out; - } - /* note: daemonize will close all fds */ if (daemonize()) { *msg = "Failed to become a daemon"; diff --git a/src/common/constants.h b/src/common/constants.h index 94640fa593d09dce9f3ea22432b87b4621090342..dd2f3e5ee38e453759d01947df75b457f95b0729 100644 --- a/src/common/constants.h +++ b/src/common/constants.h @@ -67,7 +67,6 @@ extern "C" { #define ISULAD_CONFIG "/etc/isulad" #define ISULAD_DAEMON_JSON_CONF_FILE ISULAD_CONFIG "/daemon.json" -#define ISULAD_DAEMON_CONSTANTS_JSON_CONF_FILE ISULAD_CONFIG "/daemon_constants.json" #define DEFAULT_CA_FILE "ca.pem" #define DEFAULT_KEY_FILE "key.pem" diff --git a/src/contrib/.DS_Store b/src/contrib/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..62dd824b5ab4625caa5a2ff4a4c35861a15fde21 Binary files /dev/null and b/src/contrib/.DS_Store differ diff --git a/src/contrib/completion/isula b/src/contrib/completion/isula index 3bac63a54647c6f12b9a89e752dcdeb02551f6cd..a2adc083c2792d7cb8f9e8145df6fae4ac74d0aa 100644 --- a/src/contrib/completion/isula +++ b/src/contrib/completion/isula @@ -86,7 +86,7 @@ _isula_isula_list_images_with_tag() images_with_tag=($(isula images |awk 'NR>1{printf "%s:%s\n",$1,$2}')) ;; esac - + COMPREPLY=( $( compgen -W "${images_with_tag[*]}" -- "$cur" ) ) } @@ -105,502 +105,12 @@ _isula_isula_images() _isula_isula_list_images_with_tag } -_isula_isula_pull() -{ - _isula_isula_list_images_with_tag -} - -__isula_containers(){ - local format - format='{{.Names}}' - isula ps --format "$format" "$@" -} - -__isula_complete_containers() { - COMPREPLY=( $(compgen -W "$(__isula_containers "$@")" -- "$cur") ) -} - -__isula_containers_all() { - __isula_complete_containers "$@" --all -} - -__isula_containers_removable() { - - COMPREPLY=( $(compgen -W "$(__isula_containers --filter status=created) $(__isula_containers --filter status=exited)" -- "$cur") ) -} - -__isula_containers_running(){ - __isula_complete_containers "$@" --filter status=running -} - -__isula_containers_unpause(){ - __isula_complete_containers "$@" --filter status=paused -} - -__isula_containers_stopped(){ - __isula_complete_containers "$@" --filter status=exited -} - -__isula_container_run_and_create(){ - local all_options_with_args=" - --add-host - --annotation - --blkio-weight - --blkio-weight-device - --cap-add - --cap-drop - --cgroup-parent - --cpu-period - --cpu-quota - --cpu-rt-period - --cpu-rt-runtime - --cpu-shares - --cpus - --cpuset-cpus - --cpuset-mems - --debug -D - --detach -d - --device - --device-cgroup-rule - --device-read-bps - --device-read-iops - --device-write-bps - --device-write-iops - --dns - --dns-opt - --dns-search - --entrypoint - --env -e - --env-file - --env-target-file - --external-rootfs - --files-limit - --group-add - --health-cmd - --health-exit-on-unhealthy - --health-interval - --health-retries - --health-start-period - --health-timeout - --help - --hook-spec - --host -H - --host-channel - --hostname -h - --hugetlb-limit - --interactive -i - --ipc - --kernel-memory - --label -l - --label-file - --log-driver - --log-opt - --memory -m - --memory-reservation - --memory-swap - --memory-swappiness - --mount - --name -n - --net - --no-healthcheck - --ns-change-opt - --oom-kill-disable - --oom-score-adj - --pid - --pids-limit - --privileged - --pull - --read-only - --restart - --rm - --runtime -R - --security-opt - --shm-size - --stop-signal - --storage-opt - --sysctl - --system-container - --tls - --tlscacert - --tlscert - --tlskey - --tlsverify - --tmpfs - --tty -t - --ulimit - --user -u - --user-remap - --uts - --volume -v - --volumes-from - --workdir - " - case "$prev" in - --add-host) - return - ;; - --cap-add) - return - ;; - --cap-drop) - return - ;; - --device) - return - ;; - --env|-e) - COMPREPLY=( $( compgen -e -- "$cur" ) ) - return - ;; - --log-driver|--log-opt) - return - ;; - --user|-u) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$all_options_with_args" -- "$cur" ) ) - ;; - *) - _isula_isula_list_images_with_tag - ;; - esac -} - -_isula_isula_attach(){ - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --help --host -H --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_running - esac -} - -_isula_isula_create(){ - __isula_container_run_and_create -} - -_isula_isula_run(){ - __isula_container_run_and_create -} - -_isula_isula_exec(){ - local all_options_with_args=" - --debug -D - --detach -d - --env -e - --help - --host -H - --interactive -i - --tls - --tlscacert - --tlscert - --tlskey - --tlsverify - --tty -t - --user -u - --workdir - " - - case "$prev" in - --env|-e) - return - ;; - --user|-u) - return - ;; - --workdir|-w) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$all_options_with_args" -- "$cur" ) ) - ;; - *) - __isula_containers_running - ;; - esac -} - -_isula_isula_export(){ - case "$prev" in - --output|-o) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --help --host -H --output -o --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_all - ;; - esac -} - -_isula_isula_inspect(){ - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --format -f --help --host -H --time -t --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W " $(__isula_containers --all) $(isula images |awk 'NR>1{printf "%s:%s\n",$1,$2}')" -- "$cur" ) ) - ;; - esac -} - -_isula_isula_kill(){ - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --help --host -H --signal -s --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_running - ;; - esac -} - -_isula_isula_logs(){ - case "$prev" in - --tail) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --follow -f --help --host -H --tail --timestamps -t --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_all - ;; - esac -} - -_isula_isula_pause(){ - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --help --host -H --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_running - ;; - esac -} - -_isula_isula_ps(){ - case "$prev" in - --filter|-f) - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --debug -D --filter -f --format --help --host -H --no-trunc -q --quiet --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - esac -} - -_isula_isula_rename(){ - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --help --host -H --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_all - ;; - esac -} - -_isula_isula_restart(){ - case "$prev" in - --time|-t) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --help --host -H --time -t --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_all - ;; - esac -} - -_isula_isula_start(){ - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--attach -a --debug -D --help --host -H --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_stopped - ;; - esac -} - -_isula_isula_stats(){ - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --debug -D --help --host -H --no-stream --original --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_running - ;; - esac - -} - -_isula_isula_stop(){ - case "$prev" in - --time|-t) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --force -f --help --host -H --time -t --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_running - ;; - esac -} - -_isula_isula_top(){ - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --help --host -H --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_running - ;; - esac -} - -_isula_isula_unpause(){ - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --help --host -H --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_unpause - ;; - esac -} - -_isula_isula_update(){ - local all_options_with_args=" - --blkio-weight - --cpu-period - --cpu-quota - --cpu-rt-period - --cpu-rt-runtime - --cpus - --cpuset-cpus - --cpuset-mems - --kernel-memory - --memory -m - --memory-reservation - --memory-swap - --restart - --debug -D - --help - --host -H - --kernel-memory - --tls - --tlscacert - --tlscert - --tlskey - --tlsverify - " - - case "$prev" in - --blkio-weight|\ - --cpu-period|\ - --cpu-quota|\ - --cpu-rt-period|\ - --cpu-rt-runtime|\ - --cpus|\ - --cpuset-cpus|\ - --cpuset-mems|\ - --kernel-memory|\ - --memory|-m|\ - --memory-reservation|\ - --memory-swap|\ - --restart) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$all_options_with_args" -- "$cur" ) ) - ;; - *) - __isula_containers_all - ;; - esac -} - -_isula_isula_wait(){ - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --help --host -H --tls --tlscacert --tlscert --tlskey --tlsverify" -- "$cur" ) ) - ;; - *) - __isula_containers_all - ;; - esac -} - -_isula_isula_rm() -{ - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--debug -D --force --help -f --host -H --tls --tlscacert --tlscert --tlskey --tlsverify --volumes -v" -- "$cur" ) ) - ;; - *) - for arg in "${COMP_WORDS[@]}"; do - case "$arg" in - --force|-f) - __isula_containers_all - return - ;; - esac - done - __isula_containers_removable - ;; - esac -} - _isula() { COMPREPLY=() - local words=(${COMP_WORDS[*]}) - local cword=$COMP_CWORD - local cur="${words[$cword]}" - local prev="${words[$cword-1]}" + local cur prev words cword + _get_comp_words_by_ref -n : cur prev words cword local command='isula' if [ $cword -gt 1 ] ; then command="isula_${words[1]}" diff --git a/src/contrib/config/daemon_constants.json b/src/contrib/config/daemon_constants.json deleted file mode 100644 index 39ac541aae4a4c3e865b9444220225e1de2155a0..0000000000000000000000000000000000000000 --- a/src/contrib/config/daemon_constants.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "default-host": "docker.io", - "registry-transformation":{ - "docker.io": "registry-1.docker.io", - "index.docker.io": "registry-1.docker.io" - } -} diff --git a/src/contrib/config/seccomp_default.json b/src/contrib/config/seccomp_default.json index 7218b99c12736f43326a9d80996e1bbb2888b728..728355cd1d1f57248190e8a95a378cfef07951db 100644 --- a/src/contrib/config/seccomp_default.json +++ b/src/contrib/config/seccomp_default.json @@ -500,8 +500,7 @@ }, { "names": [ - "modify_ldt", - "clone3" + "modify_ldt" ], "action": "SCMP_ACT_ALLOW", "args": [ diff --git a/src/daemon/.DS_Store b/src/daemon/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8d8fbc8f806179251c13768301f96d9d20b6f9e4 Binary files /dev/null and b/src/daemon/.DS_Store differ diff --git a/src/daemon/config/isulad_config.c b/src/daemon/config/isulad_config.c index 209f87e7b91a68b8bad43b8238e97c813ba0df0a..314545faa4376e1759cfe209437fbf74fc1475bd 100644 --- a/src/daemon/config/isulad_config.c +++ b/src/daemon/config/isulad_config.c @@ -47,7 +47,6 @@ static struct isulad_conf g_isulad_conf; static double g_jiffy = 0.0; -static isulad_daemon_constants *g_isulad_daemon_constants = NULL; /* tick to ns */ static inline unsigned long long tick_to_ns(uint64_t tick) @@ -1572,75 +1571,8 @@ int merge_json_confs_into_global(struct service_arguments *args) args->json_confs->selinux_enabled = tmp_json_confs->selinux_enabled; #endif -#ifdef ENABLE_METRICS - args->json_confs->metrics_port = tmp_json_confs->metrics_port; -#endif - out: free(err); free_isulad_daemon_configs(tmp_json_confs); return ret; } - -static bool valid_isulad_daemon_constants(isulad_daemon_constants *config) -{ - json_map_string_string *registry_transformation = NULL; - size_t i = 0; - - if (config == NULL) { - return false; - } - - if (config->registry_transformation != NULL) { - registry_transformation = config->registry_transformation; - for (i = 0; i < registry_transformation->len; i++) { - if (!util_valid_host_name(registry_transformation->keys[i]) || - !util_valid_host_name(registry_transformation->values[i])) { - ERROR("invalid hostname, key:%s value:%s", registry_transformation->keys[i], - registry_transformation->values[i]); - return false; - } - } - } - - if (config->default_host != NULL) { - if (!util_valid_host_name(config->default_host)) { - ERROR("invalid hostname %s", config->default_host); - return false; - } - } - - return true; -} - -int init_isulad_daemon_constants() -{ - parser_error err = NULL; - int ret = 0; - - g_isulad_daemon_constants = isulad_daemon_constants_parse_file(ISULAD_DAEMON_CONSTANTS_JSON_CONF_FILE, NULL, &err); - if (g_isulad_daemon_constants == NULL) { - ERROR("Load isulad constants json config failed: %s", err); - ret = -1; - goto out; - } - - if (!valid_isulad_daemon_constants(g_isulad_daemon_constants)) { - ret = -1; - goto out; - } - -out: - free(err); - - if (ret != 0) { - free_isulad_daemon_constants(g_isulad_daemon_constants); - g_isulad_daemon_constants = NULL; - } - return ret; -} - -isulad_daemon_constants *get_isulad_daemon_constants() -{ - return g_isulad_daemon_constants; -} diff --git a/src/daemon/config/isulad_config.h b/src/daemon/config/isulad_config.h index a2bc361eade78360be5a20065ce3db12c7ebe71f..fb523e5d9ead04a73982c843d09629232b893664 100644 --- a/src/daemon/config/isulad_config.h +++ b/src/daemon/config/isulad_config.h @@ -23,7 +23,6 @@ #include "daemon_arguments.h" #include "isula_libutils/oci_runtime_spec.h" #include "isula_libutils/isulad_daemon_configs.h" -#include "isula_libutils/isulad_daemon_constants.h" #ifdef __cplusplus extern "C" { @@ -100,9 +99,6 @@ int parse_log_opts(struct service_arguments *args, const char *key, const char * char *conf_get_isulad_monitor_fifo_path(); -int init_isulad_daemon_constants(); -isulad_daemon_constants *get_isulad_daemon_constants(); - #ifdef __cplusplus } #endif diff --git a/src/daemon/entry/connect/CMakeLists.txt b/src/daemon/entry/connect/CMakeLists.txt index 6b7af6fe89754189322d3270c76241951edd8103..4e3765c56c9227ee57649fad1d84806a4985eca7 100644 --- a/src/daemon/entry/connect/CMakeLists.txt +++ b/src/daemon/entry/connect/CMakeLists.txt @@ -13,25 +13,21 @@ else() list(APPEND local_server_connect_incs ${CMAKE_CURRENT_SOURCE_DIR}/rest) endif() -if (ENABLE_METRICS) - add_subdirectory(metrics) - list(APPEND local_server_connect_srcs ${METRICS_SERVICE_SRCS}) - list(APPEND local_server_connect_incs ${CMAKE_CURRENT_SOURCE_DIR}/metrics) -endif() - if (GRPC_CONNECTOR) # GRPC aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/services/containers CONNECT_API_CONTAINERS) aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/services/images CONNECT_API_IMAGES) aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/services/volumes CONNECT_API_VOLUMES) + aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/services/checkpoints CONNECT_API_CHECKPOINTS) aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/services/cri CONNECT_API_CRI) - set(CONNECT_API ${CONNECT_API_CONTAINERS} ${CONNECT_API_IMAGES} ${CONNECT_API_VOLUMES} ${CONNECT_API_CRI}) + set(CONNECT_API ${CONNECT_API_CONTAINERS} ${CONNECT_API_IMAGES} ${CONNECT_API_VOLUMES} ${CONNECT_API_CHECKPOINTS} ${CONNECT_API_CRI}) list(APPEND local_server_connect_srcs ${CONNECT_API}) list(APPEND local_server_connect_incs ${CMAKE_BINARY_DIR}/grpc/src/api/services/containers ${CMAKE_BINARY_DIR}/grpc/src/api/services/images ${CMAKE_BINARY_DIR}/grpc/src/api/services/volumes + ${CMAKE_BINARY_DIR}/grpc/src/api/services/checkpoints ${CMAKE_BINARY_DIR}/grpc/src/api/services/cri ) endif() diff --git a/src/daemon/entry/connect/grpc/grpc_checkpoints_service.cc b/src/daemon/entry/connect/grpc/grpc_checkpoints_service.cc new file mode 100644 index 0000000000000000000000000000000000000000..b9e66c6eb76d1f68b4600e8a9cc180f90214f023 --- /dev/null +++ b/src/daemon/entry/connect/grpc/grpc_checkpoints_service.cc @@ -0,0 +1,368 @@ +#include "grpc_checkpoints_service.h" + +#include +#include +#include +#include +#include +#include + +#include "isula_libutils/log.h" +#include "utils.h" +#include "grpc_server_tls_auth.h" + + + +//获取请求 +int CheckpointServiceImpl::checkpoint_create_request_from_grpc(const CreateCheckpointRequest *grequest, + checkpoint_create_checkpoint_request **request) +{ + + printf("checkpoint_create_request_from_grpc\n"); + printf("dir:%s\n",grequest->dir().c_str()); + checkpoint_create_checkpoint_request *tmpreq = + static_cast(util_common_calloc_s(sizeof(checkpoint_create_checkpoint_request))); + if (tmpreq == nullptr) { + printf("tmpreq == nullptr?:%d\n",tmpreq == nullptr); + ERROR("Out of memory"); + return -1; + } + + + if (!grequest->container().empty()) { + tmpreq->container = util_strdup_s(grequest->container().c_str()); + } + if (!grequest->dir().empty()) { + tmpreq->dir = util_strdup_s(grequest->dir().c_str()); + } + *request = tmpreq; + + return 0; +} + +//发送响应 +int CheckpointServiceImpl::checkpoint_create_response_to_grpc(checkpoint_create_checkpoint_response *response, + CreateCheckpointResponse *gresponse) +{ + printf("发送响应\n"); + if (response == nullptr) { + gresponse->set_cc(ISULAD_ERR_MEMOUT); + return 0; + } + + gresponse->set_cc(response->cc); + if (response->errmsg != nullptr) { + gresponse->set_errmsg(response->errmsg); + } + + + return 0; +} + + +//处理逻辑 +Status CheckpointServiceImpl::Create(ServerContext *context, const CreateCheckpointRequest *request, CreateCheckpointResponse *reply) +{ + printf("server contianer is null:%d\n",request->container().empty()); + //tls认证 + auto status = GrpcServerTlsAuth::auth(context, "checkpoint_create"); + if (!status.ok()) { + openlog("isula",LOG_CONS | LOG_PID,LOG_LOCAL2); + syslog(LOG_DEBUG,"tls认证失败\n"); + closelog(); + return status; + } + //获取服务执行器 + service_executor_t *cb = get_service_executor(); + //获取为空 + if (cb == nullptr || cb->checkpoint.create == nullptr) { + return Status(StatusCode::UNIMPLEMENTED, "Unimplemented callback"); + } + //声明请求 + checkpoint_create_checkpoint_request *checkpoint_req = nullptr; + //填充请求 + int tret = checkpoint_create_request_from_grpc(request, &checkpoint_req); + if (tret != 0) { + ERROR("Failed to transform grpc request"); + reply->set_cc(ISULAD_ERR_INPUT); + return Status::OK; + } + + //声明响应 + checkpoint_create_checkpoint_response *checkpoint_res = nullptr; + //填充响应 + int ret = cb->checkpoint.create(checkpoint_req, &checkpoint_res); + //发送响应 + tret = checkpoint_create_response_to_grpc(checkpoint_res, reply); + free(checkpoint_req); + free(checkpoint_res); + if (tret != 0) { + openlog("isula",LOG_CONS | LOG_PID,LOG_LOCAL2); + syslog(LOG_DEBUG,"发送响应失败\n"); + closelog(); + reply->set_errmsg(util_strdup_s(errno_to_error_message(ISULAD_ERR_INTERNAL))); + reply->set_cc(ISULAD_ERR_INPUT); + ERROR("Failed to translate response to grpc, operation is %s", ret ? "failed" : "success"); + } + + return Status::OK; +} + +//获取请求 +int CheckpointServiceImpl::checkpoint_restore_request_from_grpc(const RestoreCheckpointRequest *grequest, + checkpoint_restore_checkpoint_request **request) +{ + + printf("checkpoint_restore_request_from_grpc\n"); + checkpoint_restore_checkpoint_request *tmpreq = + static_cast(util_common_calloc_s(sizeof(checkpoint_restore_checkpoint_request))); + if (tmpreq == nullptr) { + printf("tmpreq == nullptr?:%d\n",tmpreq == nullptr); + ERROR("Out of memory"); + return -1; + } + printf("container is empty:%d\n",grequest->container().empty()); + + if (!grequest->container().empty()) { + tmpreq->container = util_strdup_s(grequest->container().c_str()); + } + if (!grequest->dir().empty()) { + tmpreq->dir = util_strdup_s(grequest->dir().c_str()); + } + *request = tmpreq; + + return 0; +} + +//发送响应 +int CheckpointServiceImpl::checkpoint_restore_response_to_grpc(checkpoint_restore_checkpoint_response *response, + RestoreCheckpointResponse *gresponse) +{ + printf("发送响应\n"); + if (response == nullptr) { + gresponse->set_cc(ISULAD_ERR_MEMOUT); + return 0; + } + + gresponse->set_cc(response->cc); + if (response->errmsg != nullptr) { + gresponse->set_errmsg(response->errmsg); + } + + // for (size_t i {}; i < response->checkpoints_len; i++) { + // gresponse->add_checkpoints(response->checkpoints[i]); + //} + + return 0; +} + + +//处理逻辑 +Status CheckpointServiceImpl::Restore(ServerContext *context, const RestoreCheckpointRequest *request, RestoreCheckpointResponse *reply) +{ + printf("server contianer is null:%d\n",request->container().empty()); + //tls认证 + auto status = GrpcServerTlsAuth::auth(context, "checkpoint_restore"); + if (!status.ok()) { + openlog("isula",LOG_CONS | LOG_PID,LOG_LOCAL2); + syslog(LOG_DEBUG,"tls认证失败\n"); + closelog(); + return status; + } + //获取服务执行器 + service_executor_t *cb = get_service_executor(); + //获取为空 + if (cb == nullptr || cb->checkpoint.restore == nullptr) { + return Status(StatusCode::UNIMPLEMENTED, "Unimplemented callback"); + } + //声明请求 + checkpoint_restore_checkpoint_request *checkpoint_req = nullptr; + //填充请求 + int tret = checkpoint_restore_request_from_grpc(request, &checkpoint_req); + if (tret != 0) { + ERROR("Failed to transform grpc request"); + reply->set_cc(ISULAD_ERR_INPUT); + return Status::OK; + } + + //声明响应 + checkpoint_restore_checkpoint_response *checkpoint_res = nullptr; + //填充响应 + int ret = cb->checkpoint.restore(checkpoint_req, &checkpoint_res); + //发送响应 + tret = checkpoint_restore_response_to_grpc(checkpoint_res, reply); + free(checkpoint_req); + free(checkpoint_res); + if (tret != 0) { + openlog("isula",LOG_CONS | LOG_PID,LOG_LOCAL2); + syslog(LOG_DEBUG,"发送响应失败\n"); + closelog(); + reply->set_errmsg(util_strdup_s(errno_to_error_message(ISULAD_ERR_INTERNAL))); + reply->set_cc(ISULAD_ERR_INPUT); + ERROR("Failed to translate response to grpc, operation is %s", ret ? "failed" : "success"); + } + + return Status::OK; +} + +//获取请求 +int CheckpointServiceImpl::checkpoint_remove_request_from_grpc(const RemoveCheckpointRequest *grequest, + checkpoint_remove_checkpoint_request **request) +{ + + checkpoint_remove_checkpoint_request *tmpreq = + static_cast(util_common_calloc_s(sizeof(checkpoint_remove_checkpoint_request))); + if (tmpreq == nullptr) { + ERROR("Out of memory"); + return -1; + } + + + if (!grequest->container().empty()) { + tmpreq->container = util_strdup_s(grequest->container().c_str()); + } + if (!grequest->dir().empty()) { + tmpreq->dir = util_strdup_s(grequest->dir().c_str()); + } + + *request = tmpreq; + + return 0; +} + + +//处理逻辑 +Status CheckpointServiceImpl::Remove(ServerContext *context, const RemoveCheckpointRequest *request, RemoveCheckpointResponse *reply) +{ + + //tls认证 + auto status = GrpcServerTlsAuth::auth(context, "checkpoint_create"); + if (!status.ok()) { + return status; + } + //获取服务执行器 + service_executor_t *cb = get_service_executor(); + //获取为空 + if (cb == nullptr || cb->checkpoint.remove == nullptr) { + return Status(StatusCode::UNIMPLEMENTED, "Unimplemented callback"); + } + //声明请求 + checkpoint_remove_checkpoint_request *checkpoint_req = nullptr; + + //填充请求 + int tret = checkpoint_remove_request_from_grpc(request, &checkpoint_req); + if (tret != 0) { + ERROR("Failed to transform grpc request"); + reply->set_cc(ISULAD_ERR_INPUT); + return Status::OK; + } + + //声明响应 + checkpoint_remove_checkpoint_response *checkpoint_res = nullptr; + //填充响应 + int ret = cb->checkpoint.remove(checkpoint_req, &checkpoint_res); + + //发送响应 + tret = response_to_grpc(checkpoint_res, reply); + free(checkpoint_req); + free(checkpoint_res); + if (tret != 0) { + + reply->set_errmsg(util_strdup_s(errno_to_error_message(ISULAD_ERR_INTERNAL))); + reply->set_cc(ISULAD_ERR_INPUT); + ERROR("Failed to translate response to grpc, operation is %s", ret ? "failed" : "success"); + } + + return Status::OK; +} + +//获取请求 +int CheckpointServiceImpl::checkpoint_list_request_from_grpc(const ListCheckpointRequest *grequest, + checkpoint_list_checkpoint_request **request) +{ + checkpoint_list_checkpoint_request *tmpreq = + static_cast(util_common_calloc_s(sizeof(checkpoint_list_checkpoint_request))); + if (tmpreq == nullptr) { + ERROR("Out of memory"); + return -1; + } + + if (!grequest->dir().empty()) { + tmpreq->dir = util_strdup_s(grequest->dir().c_str()); + } + + + *request = tmpreq; + + return 0; +} + +//发送响应 +int CheckpointServiceImpl::checkpoint_list_response_to_grpc(checkpoint_list_checkpoint_response *response, + ListCheckpointResponse *gresponse) +{ + if (response == nullptr) { + gresponse->set_cc(ISULAD_ERR_MEMOUT); + return 0; + } + + gresponse->set_cc(response->cc); + if (response->errmsg != nullptr) { + gresponse->set_errmsg(response->errmsg); + } + for (size_t i {}; i < response->checkpoints_len; i++) { + auto checkpoint = gresponse->add_checkpoints(); + if (response->checkpoints[i]->dir != nullptr) { + checkpoint->set_dir(response->checkpoints[i]->dir); + } + if (response->checkpoints[i]->name != nullptr) { + checkpoint->set_name(response->checkpoints[i]->name); + } + } + + return 0; +} + + +//处理逻辑 +Status CheckpointServiceImpl::List(ServerContext *context, const ListCheckpointRequest *request, ListCheckpointResponse *reply) +{ + //tls认证 + auto status = GrpcServerTlsAuth::auth(context, "checkpoint_list"); + if (!status.ok()) { + return status; + } + //获取服务执行器 + service_executor_t *cb = get_service_executor(); + + //获取为空 + if (cb == nullptr || cb->checkpoint.list == nullptr) { + return Status(StatusCode::UNIMPLEMENTED, "Unimplemented callback"); + } + //声明请求 + checkpoint_list_checkpoint_request *checkpoint_req = nullptr; + //填充请求 + int tret = checkpoint_list_request_from_grpc(request, &checkpoint_req); + if (tret != 0) { + ERROR("Failed to transform grpc request"); + reply->set_cc(ISULAD_ERR_INPUT); + return Status::OK; + } + + //声明响应 + checkpoint_list_checkpoint_response *checkpoint_res = nullptr; + //填充响应 + int ret = cb->checkpoint.list(checkpoint_req, &checkpoint_res); + //发送响应 + tret = checkpoint_list_response_to_grpc(checkpoint_res, reply); + free(checkpoint_req); + free(checkpoint_res); + if (tret != 0) { + reply->set_errmsg(util_strdup_s(errno_to_error_message(ISULAD_ERR_INTERNAL))); + reply->set_cc(ISULAD_ERR_INPUT); + ERROR("Failed to translate response to grpc, operation is %s", ret ? "failed" : "success"); + } + + return Status::OK; +} + diff --git a/src/daemon/entry/connect/grpc/grpc_checkpoints_service.h b/src/daemon/entry/connect/grpc/grpc_checkpoints_service.h new file mode 100644 index 0000000000000000000000000000000000000000..1f5045ac648c7f78a3f5659d2dc4f2c87d13c583 --- /dev/null +++ b/src/daemon/entry/connect/grpc/grpc_checkpoints_service.h @@ -0,0 +1,63 @@ +#ifndef DAEMON_ENTRY_CONNECT_GRPC_GRPC_CHECKPOINTS_SERVICE_H +#define DAEMON_ENTRY_CONNECT_GRPC_GRPC_CHECKPOINTS_SERVICE_H + +#include + + +#include "callback.h" +#include "error.h" +#include "checkpoints.grpc.pb.h" + +using grpc::ServerContext; +using grpc::Status; + +using namespace checkpoint; + + + +// Implement of checkpoint service +class CheckpointServiceImpl final : public CheckpointService::Service { +public: + CheckpointServiceImpl() = default; + CheckpointServiceImpl(const CheckpointServiceImpl &) = delete; + CheckpointServiceImpl &operator=(const CheckpointServiceImpl &) = delete; + virtual ~CheckpointServiceImpl() = default; + + Status Create(ServerContext *context, const CreateCheckpointRequest *request, CreateCheckpointResponse *reply) override; + Status Remove(ServerContext *context, const RemoveCheckpointRequest *request, RemoveCheckpointResponse *reply) override; + Status List(ServerContext *context, const ListCheckpointRequest *request, ListCheckpointResponse *reply) override; + Status Restore(ServerContext *context, const RestoreCheckpointRequest *request, RestoreCheckpointResponse *reply) override; + +private: + template + int response_to_grpc(const T1 *response, T2 *gresponse) + { + if (response == nullptr) { + gresponse->set_cc(ISULAD_ERR_MEMOUT); + return 0; + } + gresponse->set_cc(response->cc); + if (response->errmsg != nullptr) { + gresponse->set_errmsg(response->errmsg); + } + return 0; + } + + int checkpoint_create_request_from_grpc(const CreateCheckpointRequest *grequest, checkpoint_create_checkpoint_request **request); + + int checkpoint_create_response_to_grpc(checkpoint_create_checkpoint_response *response, CreateCheckpointResponse *gresponse); + + int checkpoint_remove_request_from_grpc(const RemoveCheckpointRequest *grequest, checkpoint_remove_checkpoint_request **request); + + int checkpoint_remove_response_to_grpc(checkpoint_remove_checkpoint_response *response, RemoveCheckpointResponse *gresponse); + + int checkpoint_list_request_from_grpc(const ListCheckpointRequest *grequest, checkpoint_list_checkpoint_request **request); + + int checkpoint_list_response_to_grpc(checkpoint_list_checkpoint_response *response, ListCheckpointResponse *gresponse); + + int checkpoint_restore_request_from_grpc(const RestoreCheckpointRequest *grequest, checkpoint_restore_checkpoint_request **request); + + int checkpoint_restore_response_to_grpc(checkpoint_restore_checkpoint_response *response, RestoreCheckpointResponse *gresponse); +}; + +#endif // DAEMON_ENTRY_CONNECT_GRPC_GRPC_CHECKPOINTS_SERVICE_H diff --git a/src/daemon/entry/connect/grpc/grpc_containers_service.cc b/src/daemon/entry/connect/grpc/grpc_containers_service.cc index 54529998da96e23c6959b6e4f38eb184c03fcb61..ffba31e42700f18854d2352c0db2725ca1e0ffa5 100644 --- a/src/daemon/entry/connect/grpc/grpc_containers_service.cc +++ b/src/daemon/entry/connect/grpc/grpc_containers_service.cc @@ -768,6 +768,7 @@ Status ContainerServiceImpl::Inspect(ServerContext *context, const InspectContai Status ContainerServiceImpl::List(ServerContext *context, const ListRequest *request, ListResponse *reply) { + int tret; service_executor_t *cb = nullptr; container_list_request *container_req = nullptr; @@ -783,6 +784,7 @@ Status ContainerServiceImpl::List(ServerContext *context, const ListRequest *req } tret = list_request_from_grpc(request, &container_req); + printf("tret = list_request_from_grpc(request, &container_req);\n"); if (tret != 0) { ERROR("Failed to transform grpc request"); reply->set_cc(ISULAD_ERR_INPUT); diff --git a/src/daemon/entry/connect/grpc/grpc_service.cc b/src/daemon/entry/connect/grpc/grpc_service.cc index ab3e32ab0ac4ab15169d74d979f93f7697da27df..729e73f56c859277187211406d160ca63909ab72 100644 --- a/src/daemon/entry/connect/grpc/grpc_service.cc +++ b/src/daemon/entry/connect/grpc/grpc_service.cc @@ -20,9 +20,11 @@ #include #include #include +#include #include "grpc_containers_service.h" #include "grpc_images_service.h" #include "grpc_volumes_service.h" +#include "grpc_checkpoints_service.h" #include "runtime_runtime_service.h" #include "runtime_image_service.h" #include "isula_libutils/log.h" @@ -72,6 +74,7 @@ public: m_builder.RegisterService(&m_containerService); m_builder.RegisterService(&m_imagesService); m_builder.RegisterService(&m_volumeService); + m_builder.RegisterService(&m_checkpointService); m_builder.RegisterService(&m_runtimeRuntimeService); m_builder.RegisterService(&m_runtimeImageService); @@ -184,6 +187,7 @@ private: ContainerServiceImpl m_containerService; ImagesServiceImpl m_imagesService; VolumeServiceImpl m_volumeService; + CheckpointServiceImpl m_checkpointService; RuntimeRuntimeServiceImpl m_runtimeRuntimeService; RuntimeImageServiceImpl m_runtimeImageService; ServerBuilder m_builder; @@ -196,6 +200,10 @@ GRPCServerImpl *g_grpcserver { nullptr }; int grpc_server_init(const struct service_arguments *args) { + openlog("isula",LOG_CONS | LOG_PID,LOG_LOCAL2); + syslog(LOG_DEBUG,"grpc_server_init\n"); + closelog(); + if (args == nullptr) { return -1; } diff --git a/src/daemon/entry/connect/metrics/CMakeLists.txt b/src/daemon/entry/connect/metrics/CMakeLists.txt deleted file mode 100644 index d59427760ed26f463190ec8ba9fc967b48935d70..0000000000000000000000000000000000000000 --- a/src/daemon/entry/connect/metrics/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# get current directory sources files -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_metrics_service_srcs) - -set(METRICS_SERVICE_SRCS - ${local_metrics_service_srcs} - PARENT_SCOPE - ) -set(METRICS_SERVICE_INCS - ${CMAKE_CURRENT_SOURCE_DIR} - PARENT_SCOPE - ) \ No newline at end of file diff --git a/src/daemon/entry/connect/metrics/metrics_service.c b/src/daemon/entry/connect/metrics/metrics_service.c deleted file mode 100644 index 2ecf4be1a8918fbb5c79b4c006bdcf8464008700..0000000000000000000000000000000000000000 --- a/src/daemon/entry/connect/metrics/metrics_service.c +++ /dev/null @@ -1,167 +0,0 @@ -/****************************************************************************** - * Copyright (c) KylinSoft Co., Ltd. 2021. 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: xiapin - * Create: 2021-08-17 - * Description: provide metric service functions. - ******************************************************************************/ -#include "metrics_service.h" -#include -#include - -#include "utils.h" -#include "isula_libutils/log.h" -#include "callback.h" - -#define METRIC_RESPONSE_OK 200 -#define METRIC_RESPONSE_FAIL 401 -#define METRIC_NOT_IMPL 501 -#define METRIC_DEFAULT_IP "127.0.0.1" -#define METRIC_DEFAULT_PORT 9090 -#define BACK_LOG_SIZE 1024 - -#if (defined GRPC_CONNECTOR) && (defined ENABLE_METRICS) -typedef struct metrics_server_param { - int32_t port; - evbase_t *ev_base; - evhtp_t *ev_http; -} metrics_server_param_t; - -static struct metrics_server_param *g_metrics_htp_param = NULL; -#endif - -void metrics_get_by_type_cb(evhtp_request_t *req, void *arg) -{ - char *metrics = NULL; - int ret_code = METRIC_RESPONSE_OK; - int len = 0; - const char *req_type = NULL; - service_executor_t *cb = NULL; - - cb = get_service_executor(); - if (cb == NULL || cb->metrics.export_metrics_by_type == NULL) { - ret_code = METRIC_NOT_IMPL; - goto out; - } - - req_type = req->uri->path->full + strlen(req->uri->path->path); /* full path include request url */ - (void)cb->metrics.export_metrics_by_type(req_type, &metrics, &len); - if (metrics == NULL || len == 0) { - ret_code = METRIC_RESPONSE_FAIL; - goto out; - } - - evhtp_headers_add_header(req->headers_out, - evhtp_header_new("Content-Type", "text/plain; verion:0.0.4; charset=utf-8", 0, 0)); - evbuffer_add(req->buffer_out, metrics, len); - free(metrics); - metrics = NULL; - -out: - evhtp_send_reply(req, ret_code); -} - -#if (defined GRPC_CONNECTOR) && (defined ENABLE_METRICS) -void *metrics_server_thrd(void *args) -{ - int def_port = 0; - - prctl(PR_SET_NAME, __func__); - pthread_detach(pthread_self()); - - g_metrics_htp_param->ev_base = event_base_new(); - if (g_metrics_htp_param->ev_base == NULL) { - ERROR("failed to new event base!\n"); - goto success; - } - - g_metrics_htp_param->ev_http = evhtp_new(g_metrics_htp_param->ev_base, NULL); - if (g_metrics_htp_param->ev_http == NULL) { - ERROR("failed to new ev http!\n"); - goto clean_evbase; - } - - evhtp_set_cb(g_metrics_htp_param->ev_http, METRIC_GET_BY_TYPE, metrics_get_by_type_cb, NULL); - evhtp_use_dynamic_threads(g_metrics_htp_param->ev_http, NULL, NULL, 0, 0, 0, NULL); - - def_port = g_metrics_htp_param->port != 0 ? g_metrics_htp_param->port : METRIC_DEFAULT_PORT; - /* if no default port config, we will use 9090 as default metrics port */ - if (evhtp_bind_socket(g_metrics_htp_param->ev_http, METRIC_DEFAULT_IP, def_port, BACK_LOG_SIZE) < 0) { - ERROR("evhtp_bind_socket failed"); - goto clean_evhtp; - } - - event_base_loop(g_metrics_htp_param->ev_base, 0); - - goto success; - -clean_evhtp: - evhtp_free(g_metrics_htp_param->ev_http); - g_metrics_htp_param->ev_http = NULL; -clean_evbase: - event_base_free(g_metrics_htp_param->ev_base); - g_metrics_htp_param->ev_base = NULL; -success: - return NULL; -} - -int metrics_service_init(int port) -{ - pthread_t metric_thrd_t = -1; - if (g_metrics_htp_param != NULL) { - return -1; - } - - g_metrics_htp_param = (metrics_server_param_t *)util_common_calloc_s(sizeof(metrics_server_param_t)); - if (g_metrics_htp_param == NULL) { - ERROR("out of memory!"); - return -1; - } - - g_metrics_htp_param->port = port; - - /* When gRPC is used by default server, the evhtp can't rcv event(Multiplexing of network), - therefore, an additional thread is used to create the service */ - if (pthread_create(&metric_thrd_t, NULL, metrics_server_thrd, NULL) != 0) { - ERROR("pthread create failed"); - free(g_metrics_htp_param); - g_metrics_htp_param = NULL; - return -1; - } - - return 0; -} - -void metrics_service_shutdown() -{ - if (g_metrics_htp_param == NULL) { - return; - } - - if (g_metrics_htp_param->ev_http != NULL) { - evhtp_unbind_socket(g_metrics_htp_param->ev_http); - evhtp_free(g_metrics_htp_param->ev_http); - g_metrics_htp_param->ev_http = NULL; - } - - if (g_metrics_htp_param->ev_base != NULL) { - /* Abort the active event_base_loop() immediately */ - event_base_loopbreak(g_metrics_htp_param->ev_base); - event_base_free(g_metrics_htp_param->ev_base); - g_metrics_htp_param->ev_base = NULL; - } - - free(g_metrics_htp_param); - g_metrics_htp_param = NULL; - - DEBUG("metrics service shutdown ok.\n"); -} -#endif diff --git a/src/daemon/entry/connect/rest/rest_metrics_service.c b/src/daemon/entry/connect/rest/rest_metrics_service.c deleted file mode 100644 index 4282ab14e53dcca38226a0c398343d37a9f6e515..0000000000000000000000000000000000000000 --- a/src/daemon/entry/connect/rest/rest_metrics_service.c +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** - * Copyright (c) KylinSoft Co., Ltd. 2021. 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: xiapin - * Create: 2021-08-17 - * Description: provide metric restful service function - ******************************************************************************/ -#ifdef ENABLE_METRICS -#include "rest_metrics_service.h" -#include "metrics_service.h" -#include "isula_libutils/log.h" - -#include "callback.h" - -int rest_register_metrics_handler(evhtp_t *htp) -{ - if (evhtp_set_cb(htp, METRIC_GET_BY_TYPE, metrics_get_by_type_cb, NULL) == NULL) { - ERROR("Failed to register metrics get callback"); - return -1; - } - - return 0; -} -#endif \ No newline at end of file diff --git a/src/daemon/entry/connect/rest/rest_service.c b/src/daemon/entry/connect/rest/rest_service.c index 613c17f8d4b3c532a127e0df548b21a54f7d48e6..8281538e02be09a54010bab1476526e3b23229c2 100644 --- a/src/daemon/entry/connect/rest/rest_service.c +++ b/src/daemon/entry/connect/rest/rest_service.c @@ -22,17 +22,12 @@ #include "utils.h" #include "rest_containers_service.h" #include "rest_images_service.h" -#ifdef ENABLE_METRICS -#include "rest_metrics_service.h" -#endif #define REST_PTHREAD_NUM 100 #define BACKLOG 2048 static char *g_socketpath = NULL; static evbase_t *g_evbase = NULL; static evhtp_t *g_htp = NULL; -static struct event *g_signal_event = NULL; -daemon_shutdown_cb_t g_shutdown_cb; /* rest server free */ static void rest_server_free() @@ -41,11 +36,6 @@ static void rest_server_free() free(g_socketpath); g_socketpath = NULL; } - - if (g_signal_event != NULL) { - evsignal_del(g_signal_event); - } - if (g_evbase != NULL) { event_base_free(g_evbase); g_evbase = NULL; @@ -67,11 +57,6 @@ static int rest_register_handler(evhtp_t *g_htp) return -1; } -#ifdef ENABLE_METRICS - if (rest_register_metrics_handler(g_htp) != 0) { - return -1; - } -#endif return 0; } @@ -94,24 +79,10 @@ static void libevent_log_cb(int severity, const char *msg) } } -static void signal_cb(evutil_socket_t sig, short events, void *user_data) -{ - struct event_base *base = (struct event_base *)user_data; - - if (base != NULL) { - event_base_loopbreak(base); - } - - if (g_shutdown_cb != NULL) { - g_shutdown_cb(); - } -} - /* rest server init */ -int rest_server_init(const char *socket, daemon_shutdown_cb_t shutdown_cb) +int rest_server_init(const char *socket) { g_socketpath = util_strdup_s(socket); - g_shutdown_cb = shutdown_cb; event_set_log_callback(libevent_log_cb); @@ -120,13 +91,6 @@ int rest_server_init(const char *socket, daemon_shutdown_cb_t shutdown_cb) ERROR("Failed to init rest server"); goto error_out; } - - g_signal_event = evsignal_new(g_evbase, SIGTERM, signal_cb, (void *)g_evbase); - if (g_signal_event == NULL || event_add(g_signal_event, NULL) < 0) { - ERROR("rest add signal event failed"); - goto error_out; - } - g_htp = evhtp_new(g_evbase, NULL); if (g_htp == NULL) { ERROR("Failed to init rest server"); @@ -171,3 +135,4 @@ void rest_server_shutdown(void) } } } + diff --git a/src/daemon/entry/connect/rest/rest_service.h b/src/daemon/entry/connect/rest/rest_service.h index 056406d07c4b90c2335c8dc3e159f3e511a1e077..0b748e6b38832d554603e45c181e6888cd6aa761 100644 --- a/src/daemon/entry/connect/rest/rest_service.h +++ b/src/daemon/entry/connect/rest/rest_service.h @@ -19,9 +19,7 @@ extern "C" { #endif -typedef void (*daemon_shutdown_cb_t)(void); - -int rest_server_init(const char *socket, daemon_shutdown_cb_t shutdown_cb); +int rest_server_init(const char *socket); void rest_server_wait(void); diff --git a/src/daemon/entry/connect/service_common.c b/src/daemon/entry/connect/service_common.c index cf1aa03c25467ceaef734e2478de2f2c23aed07a..d8aefe9c53e63a6a6233221d5d42081da5187a47 100644 --- a/src/daemon/entry/connect/service_common.c +++ b/src/daemon/entry/connect/service_common.c @@ -16,36 +16,34 @@ #include "service_common.h" #include +#include #include "daemon_arguments.h" #ifdef GRPC_CONNECTOR #include "grpc_service.h" -#ifdef ENABLE_METRICS -#include "metrics_service.h" -#endif #else #include "rest_service.h" #include "isula_libutils/log.h" #endif /* server common init */ -int server_common_init(const struct service_arguments *args, daemon_shutdown_cb_t shutdown_cb) +int server_common_init(const struct service_arguments *args) { + openlog("isula",LOG_CONS | LOG_PID,LOG_LOCAL2); + syslog(LOG_DEBUG,"server_common_init\n"); + closelog(); if (args == NULL || args->hosts == NULL) { return -1; } #ifdef GRPC_CONNECTOR -#ifdef ENABLE_METRICS - metrics_service_init(args->json_confs->metrics_port); -#endif return grpc_server_init(args); #else if (args->hosts_len > 1) { ERROR("Rest server dest not support multiple hosts"); return -1; } - return rest_server_init(args->hosts[0], shutdown_cb); + return rest_server_init(args->hosts[0]); #endif } @@ -64,9 +62,6 @@ void server_common_shutdown(void) { #ifdef GRPC_CONNECTOR grpc_server_shutdown(); -#ifdef ENABLE_METRICS - metrics_service_shutdown(); -#endif #else rest_server_shutdown(); #endif diff --git a/src/daemon/entry/connect/service_common.h b/src/daemon/entry/connect/service_common.h index a1ff66b906655d2bd3e89b91b654a681d4556290..add33281d4eb1c14f595aa6581423e1664d03d12 100644 --- a/src/daemon/entry/connect/service_common.h +++ b/src/daemon/entry/connect/service_common.h @@ -17,17 +17,11 @@ #include "daemon_arguments.h" -#ifndef GRPC_CONNECTOR -#include "rest_service.h" -#else -typedef void (*daemon_shutdown_cb_t)(void); -#endif - #ifdef __cplusplus extern "C" { #endif -int server_common_init(const struct service_arguments *args, daemon_shutdown_cb_t shutdown_cb); +int server_common_init(const struct service_arguments *args); void server_common_start(void); diff --git a/src/daemon/entry/cri/cri_container_manager_service_impl.cc b/src/daemon/entry/cri/cri_container_manager_service_impl.cc index ff98df9bc4287c8d390ed81863e377e929b5cfe3..e7e56fc553541bfea004a614c8f6feec14d3057f 100644 --- a/src/daemon/entry/cri/cri_container_manager_service_impl.cc +++ b/src/daemon/entry/cri/cri_container_manager_service_impl.cc @@ -224,8 +224,7 @@ void ContainerManagerServiceImpl::MakeContainerConfig(const runtime::v1alpha2::C } auto ContainerManagerServiceImpl::GenerateCreateContainerCustomConfig( - const std::string &containerName, const std::string &realPodSandboxID, - const runtime::v1alpha2::ContainerConfig &containerConfig, + const std::string &realPodSandboxID, const runtime::v1alpha2::ContainerConfig &containerConfig, const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, Errors &error) -> container_config * { container_config *custom_config = (container_config *)util_common_calloc_s(sizeof(container_config)); @@ -271,7 +270,6 @@ auto ContainerManagerServiceImpl::GenerateCreateContainerCustomConfig( error.SetError("Append map string string failed"); goto cleanup; } - if (append_json_map_string_string(custom_config->annotations, CRIHelpers::Constants::SANDBOX_ID_ANNOTATION_KEY.c_str(), realPodSandboxID.c_str()) != 0) { @@ -279,45 +277,6 @@ auto ContainerManagerServiceImpl::GenerateCreateContainerCustomConfig( goto cleanup; } - if (podSandboxConfig.has_metadata()) { - if (append_json_map_string_string(custom_config->annotations, - CRIHelpers::Constants::SANDBOX_NAME_ANNOTATION_KEY.c_str(), - podSandboxConfig.metadata().name().c_str()) != 0) { - error.SetError("Append sandbox name into annotation failed"); - goto cleanup; - } - if (append_json_map_string_string(custom_config->annotations, - CRIHelpers::Constants::SANDBOX_NAMESPACE_ANNOTATION_KEY.c_str(), - podSandboxConfig.metadata().namespace_().c_str()) != 0) { - error.SetError("Append sandbox namespace into annotation failed"); - goto cleanup; - } - } - - if (containerConfig.has_metadata()) { - if (append_json_map_string_string(custom_config->annotations, - CRIHelpers::Constants::CONTAINER_NAME_ANNOTATION_KEY.c_str(), - containerConfig.metadata().name().c_str()) != 0) { - error.SetError("Append container name into annotation failed"); - goto cleanup; - } - if (append_json_map_string_string(custom_config->annotations, - CRIHelpers::Constants::CONTAINER_ATTEMPT_ANNOTATION_KEY.c_str(), - std::to_string(containerConfig.metadata().attempt()).c_str()) != 0) { - error.SetError("Append container attempt into annotation failed"); - goto cleanup; - } - } - - if (!containerConfig.image().image().empty()) { - if (append_json_map_string_string(custom_config->annotations, - CRIHelpers::Constants::IMAGE_NAME_ANNOTATION_KEY.c_str(), - containerConfig.image().image().c_str()) != 0) { - error.SetError("Append image name into annotation failed"); - goto cleanup; - } - } - if (append_json_map_string_string(custom_config->labels, CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY.c_str(), realPodSandboxID.c_str()) != 0) { error.SetError("Append map string string failed"); @@ -373,7 +332,7 @@ ContainerManagerServiceImpl::GenerateCreateContainerRequest(const std::string &r hostconfig->cgroup_parent = util_strdup_s(podSandboxConfig.linux().cgroup_parent().c_str()); } - custom_config = GenerateCreateContainerCustomConfig(cname, realPodSandboxID, containerConfig, podSandboxConfig, error); + custom_config = GenerateCreateContainerCustomConfig(realPodSandboxID, containerConfig, podSandboxConfig, error); if (error.NotEmpty()) { goto cleanup; } @@ -614,15 +573,17 @@ void ContainerManagerServiceImpl::ListContainersToGRPC(container_list_response * container->set_created_at(response->containers[i]->created); + if (response->containers[i]->name != nullptr) { + CRINaming::ParseContainerName(response->containers[i]->name, container->mutable_metadata(), error); + if (error.NotEmpty()) { + return; + } + } + CRIHelpers::ExtractLabels(response->containers[i]->labels, *container->mutable_labels()); CRIHelpers::ExtractAnnotations(response->containers[i]->annotations, *container->mutable_annotations()); - CRINaming::ParseContainerName(container->annotations(), container->mutable_metadata(), error); - if (error.NotEmpty()) { - return; - } - if (response->containers[i]->labels != nullptr) { for (size_t j = 0; j < response->containers[i]->labels->len; j++) { if (strcmp(response->containers[i]->labels->keys[j], @@ -1006,13 +967,15 @@ void ContainerManagerServiceImpl::ContainerStatusToGRPC(container_inspect *inspe contStatus->set_started_at(startedAt); contStatus->set_finished_at(finishedAt); + if (inspect->name != nullptr) { + CRINaming::ParseContainerName(inspect->name, contStatus->mutable_metadata(), error); + if (error.NotEmpty()) { + return; + } + } PackContainerImageToStatus(inspect, contStatus, error); UpdateBaseStatusFromInspect(inspect, createdAt, startedAt, finishedAt, contStatus); PackLabelsToStatus(inspect, contStatus); - CRINaming::ParseContainerName(contStatus->annotations(), contStatus->mutable_metadata(), error); - if (error.NotEmpty()) { - return; - } ConvertMountsToStatus(inspect, contStatus); } diff --git a/src/daemon/entry/cri/cri_container_manager_service_impl.h b/src/daemon/entry/cri/cri_container_manager_service_impl.h index 805ef100cde244a43c2cc0ccb3b3c45693a82d66..d08d9124cf2138697aef16603d3244edced43b2f 100644 --- a/src/daemon/entry/cri/cri_container_manager_service_impl.h +++ b/src/daemon/entry/cri/cri_container_manager_service_impl.h @@ -81,7 +81,7 @@ private: Errors &error) -> container_create_request *; auto GenerateCreateContainerHostConfig(const runtime::v1alpha2::ContainerConfig &containerConfig, Errors &error) -> host_config *; - auto GenerateCreateContainerCustomConfig(const std::string &containerName, const std::string &realPodSandboxID, + auto GenerateCreateContainerCustomConfig(const std::string &realPodSandboxID, const runtime::v1alpha2::ContainerConfig &containerConfig, const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, Errors &error) -> container_config *; diff --git a/src/daemon/entry/cri/cri_helpers.cc b/src/daemon/entry/cri/cri_helpers.cc index 137726e65921d144a2593591442bfb5c4b2dd28c..ca156e60ebab7c9bc3996ae811c6272cf070e3ff 100644 --- a/src/daemon/entry/cri/cri_helpers.cc +++ b/src/daemon/entry/cri/cri_helpers.cc @@ -34,6 +34,7 @@ #include "service_container_api.h" namespace CRIHelpers { +const std::string Constants::DEFAULT_RUNTIME_NAME { "lcr" }; const std::string Constants::POD_NETWORK_ANNOTATION_KEY { "network.alpha.kubernetes.io/network" }; const std::string Constants::CONTAINER_TYPE_LABEL_KEY { "cri.isulad.type" }; const std::string Constants::CONTAINER_TYPE_LABEL_SANDBOX { "podsandbox" }; @@ -49,21 +50,14 @@ const std::string Constants::RUNTIME_READY { "RuntimeReady" }; const std::string Constants::NETWORK_READY { "NetworkReady" }; const std::string Constants::POD_CHECKPOINT_KEY { "cri.sandbox.isulad.checkpoint" }; const std::string Constants::CONTAINER_TYPE_ANNOTATION_KEY { "io.kubernetes.cri.container-type" }; -const std::string Constants::CONTAINER_NAME_ANNOTATION_KEY { "io.kubernetes.cri.container-name" }; -const std::string Constants::CONTAINER_ATTEMPT_ANNOTATION_KEY { "io.kubernetes.cri.container-attempt" }; const std::string Constants::CONTAINER_TYPE_ANNOTATION_CONTAINER { "container" }; const std::string Constants::CONTAINER_TYPE_ANNOTATION_SANDBOX { "sandbox" }; const std::string Constants::SANDBOX_ID_ANNOTATION_KEY { "io.kubernetes.cri.sandbox-id" }; -const std::string Constants::SANDBOX_NAMESPACE_ANNOTATION_KEY { "io.kubernetes.cri.sandbox-namespace" }; -const std::string Constants::SANDBOX_NAME_ANNOTATION_KEY { "io.kubernetes.cri.sandbox-name" }; -const std::string Constants::SANDBOX_UID_ANNOTATION_KEY { "io.kubernetes.cri.sandbox-uid" }; -const std::string Constants::SANDBOX_ATTEMPT_ANNOTATION_KEY { "io.kubernetes.cri.sandbox-attempt" }; const std::string Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE { "pod-cidr-change" }; const std::string Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR { "pod-cidr" }; const std::string Constants::CNI_MUTL_NET_EXTENSION_KEY { "extension.network.kubernetes.io/cni" }; const std::string Constants::CNI_MUTL_NET_EXTENSION_ARGS_KEY { "CNI_MUTLINET_EXTENSION" }; const std::string Constants::CNI_ARGS_EXTENSION_PREFIX_KEY { "extension.network.kubernetes.io/cniargs/" }; -const std::string Constants::IMAGE_NAME_ANNOTATION_KEY { "io.kubernetes.cri.image-name" }; const char *InternalLabelKeys[] = { CRIHelpers::Constants::CONTAINER_TYPE_LABEL_KEY.c_str(), CRIHelpers::Constants::CONTAINER_LOGPATH_LABEL_KEY.c_str(), diff --git a/src/daemon/entry/cri/cri_helpers.h b/src/daemon/entry/cri/cri_helpers.h index 450c899c806f3795c2b18f135b72879d1104ac58..e3ded54b355695302d7a4731c12a221a335b39e3 100644 --- a/src/daemon/entry/cri/cri_helpers.h +++ b/src/daemon/entry/cri/cri_helpers.h @@ -32,6 +32,7 @@ namespace CRIHelpers { class Constants { public: + static const std::string DEFAULT_RUNTIME_NAME; static const std::string POD_NETWORK_ANNOTATION_KEY; static const std::string CONTAINER_TYPE_LABEL_KEY; static const std::string CONTAINER_TYPE_LABEL_SANDBOX; @@ -50,23 +51,15 @@ public: static const std::string POD_CHECKPOINT_KEY; static const size_t MAX_CHECKPOINT_KEY_LEN { 250 }; static const std::string CONTAINER_TYPE_ANNOTATION_KEY; - static const std::string CONTAINER_NAME_ANNOTATION_KEY; - static const std::string CONTAINER_ATTEMPT_ANNOTATION_KEY; static const std::string CONTAINER_TYPE_ANNOTATION_CONTAINER; static const std::string CONTAINER_TYPE_ANNOTATION_SANDBOX; static const std::string SANDBOX_ID_ANNOTATION_KEY; - static const std::string SANDBOX_NAMESPACE_ANNOTATION_KEY; - static const std::string SANDBOX_NAME_ANNOTATION_KEY; - static const std::string SANDBOX_UID_ANNOTATION_KEY; - static const std::string SANDBOX_ATTEMPT_ANNOTATION_KEY; static const std::string NET_PLUGIN_EVENT_POD_CIDR_CHANGE; static const std::string NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR; static const std::string CNI_MUTL_NET_EXTENSION_KEY; static const std::string CNI_MUTL_NET_EXTENSION_ARGS_KEY; static const std::string CNI_ARGS_EXTENSION_PREFIX_KEY; - - static const std::string IMAGE_NAME_ANNOTATION_KEY; }; auto GetDefaultSandboxImage(Errors &err) -> std::string; diff --git a/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.cc b/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.cc index 8801bea69dc4108e55294f9be610c45fa954be16..e7f06a73e3ebaca9fa43d797480e0417bff2dc86 100644 --- a/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.cc +++ b/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.cc @@ -123,32 +123,6 @@ void PodSandboxManagerServiceImpl::MakeSandboxIsuladConfig(const runtime::v1alph error.SetError("Append container type into annotation failed"); return; } - if (c.has_metadata()) { - if (append_json_map_string_string(custom_config->annotations, - CRIHelpers::Constants::SANDBOX_NAMESPACE_ANNOTATION_KEY.c_str(), - c.metadata().namespace_().c_str()) != 0) { - error.SetError("Append sandbox namespace into annotation failed"); - return; - } - if (append_json_map_string_string(custom_config->annotations, - CRIHelpers::Constants::SANDBOX_NAME_ANNOTATION_KEY.c_str(), - c.metadata().name().c_str()) != 0) { - error.SetError("Append sandbox name into annotation failed"); - return; - } - if (append_json_map_string_string(custom_config->annotations, - CRIHelpers::Constants::SANDBOX_UID_ANNOTATION_KEY.c_str(), - c.metadata().uid().c_str()) != 0) { - error.SetError("Append sandbox uid into annotation failed"); - return; - } - if (append_json_map_string_string(custom_config->annotations, - CRIHelpers::Constants::SANDBOX_ATTEMPT_ANNOTATION_KEY.c_str(), - std::to_string(c.metadata().attempt()).c_str()) != 0) { - error.SetError("Append sandbox attempt into annotation failed"); - return; - } - } if (!c.hostname().empty()) { custom_config->hostname = util_strdup_s(c.hostname().c_str()); @@ -960,17 +934,20 @@ out: auto PodSandboxManagerServiceImpl::GetIPsFromPlugin(const container_inspect *inspect, const std::string &networkInterface, - const runtime::v1alpha2::PodSandboxMetadata &metadata, Errors &error) -> std::vector { std::vector ret; + runtime::v1alpha2::PodSandboxMetadata metadata; std::string defaultInterface = networkInterface; if (inspect == nullptr || inspect->id == nullptr || inspect->name == nullptr) { error.SetError("Empty arguments"); return ret; } - + CRINaming::ParseSandboxName(inspect->name, metadata, error); + if (error.NotEmpty()) { + return ret; + } if (defaultInterface.empty()) { defaultInterface = Network::DEFAULT_NETWORK_INTERFACE_NAME; } @@ -993,8 +970,7 @@ auto PodSandboxManagerServiceImpl::GetIPsFromPlugin(const container_inspect *ins } void PodSandboxManagerServiceImpl::GetIPs(const std::string &podSandboxID, const container_inspect *inspect, - const std::string &networkInterface, std::vector &ips, - const runtime::v1alpha2::PodSandboxMetadata &metadata, Errors &error) + const std::string &networkInterface, std::vector &ips, Errors &error) { if (inspect == nullptr) { return; @@ -1012,7 +988,7 @@ void PodSandboxManagerServiceImpl::GetIPs(const std::string &podSandboxID, const } error.Clear(); - auto tmpIPs = GetIPsFromPlugin(inspect, networkInterface, metadata, error); + auto tmpIPs = GetIPsFromPlugin(inspect, networkInterface, error); if (error.Empty()) { for (const auto &iter : tmpIPs) { ips.push_back(iter); @@ -1037,7 +1013,7 @@ void PodSandboxManagerServiceImpl::SetSandboxStatusNetwork(const container_inspe std::vector ips; size_t i; - GetIPs(podSandboxID, inspect, Network::DEFAULT_NETWORK_INTERFACE_NAME, ips, podStatus->metadata(), error); + GetIPs(podSandboxID, inspect, Network::DEFAULT_NETWORK_INTERFACE_NAME, ips, error); if (ips.size() == 0) { return; } @@ -1073,16 +1049,9 @@ void PodSandboxManagerServiceImpl::PodSandboxStatusToGRPC(const container_inspec podStatus->set_state(runtime::v1alpha2::SANDBOX_NOTREADY); } - if (inspect->config == nullptr) { - ERROR("Invalid container information! Must include config info"); - return; - } - - CRIHelpers::ExtractLabels(inspect->config->labels, *podStatus->mutable_labels()); - CRIHelpers::ExtractAnnotations(inspect->config->annotations, *podStatus->mutable_annotations()); - CRINaming::ParseSandboxName(podStatus->annotations(), *podStatus->mutable_metadata(), error); - if (error.NotEmpty()) { - return; + if (inspect->config != nullptr) { + CRIHelpers::ExtractLabels(inspect->config->labels, *podStatus->mutable_labels()); + CRIHelpers::ExtractAnnotations(inspect->config->annotations, *podStatus->mutable_annotations()); } options = podStatus->mutable_linux()->mutable_namespaces()->mutable_options(); @@ -1097,6 +1066,13 @@ void PodSandboxManagerServiceImpl::PodSandboxStatusToGRPC(const container_inspec ERROR("Set network status failed: %s", error.GetCMessage()); return; } + + if (inspect->name != nullptr) { + CRINaming::ParseSandboxName(inspect->name, *podStatus->mutable_metadata(), error); + if (error.NotEmpty()) { + return; + } + } } std::unique_ptr @@ -1189,12 +1165,14 @@ void PodSandboxManagerServiceImpl::ListPodSandboxToGRPC(container_list_response } pod->set_created_at(response->containers[i]->created); + if (response->containers[i]->name != nullptr) { + CRINaming::ParseSandboxName(response->containers[i]->name, *pod->mutable_metadata(), error); + } + CRIHelpers::ExtractLabels(response->containers[i]->labels, *pod->mutable_labels()); CRIHelpers::ExtractAnnotations(response->containers[i]->annotations, *pod->mutable_annotations()); - CRINaming::ParseSandboxName(pod->annotations(), *pod->mutable_metadata(), error); - if (filterOutReadySandboxes && pod->state() == runtime::v1alpha2::SANDBOX_READY) { continue; } diff --git a/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.h b/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.h index fa5d153c39f77e9e213c71d487f8cae4188d98db..c297de9055a3dddd16229e3668ea8967c4175ab5 100644 --- a/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.h +++ b/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.h @@ -105,10 +105,8 @@ private: void SetSandboxStatusNetwork(const container_inspect *inspect, const std::string &podSandboxID, std::unique_ptr &podStatus, Errors &error); void GetIPs(const std::string &podSandboxID, const container_inspect *inspect, - const std::string &networkInterface, std::vector &ips, - const runtime::v1alpha2::PodSandboxMetadata &metadata, Errors &error); + const std::string &networkInterface, std::vector &ips, Errors &error); auto GetIPsFromPlugin(const container_inspect *inspect, const std::string &networkInterface, - const runtime::v1alpha2::PodSandboxMetadata &metadata, Errors &error) -> std::vector; void GetFormatIPsForMultNet(const container_inspect *inspect, const std::string &defaultInterface, const runtime::v1alpha2::PodSandboxMetadata &metadata, diff --git a/src/daemon/entry/cri/naming.cc b/src/daemon/entry/cri/naming.cc index 682f2e5223bd283c233f5f8ae1a1ffdc4a9cf8de..61f51d891a8fb1803136db61e7d28bc09d6d6b81 100644 --- a/src/daemon/entry/cri/naming.cc +++ b/src/daemon/entry/cri/naming.cc @@ -21,14 +21,41 @@ #include #include "cri_constants.h" -#include "cri_helpers.h" #include "isula_libutils/log.h" #include "utils.h" namespace CRINaming { +static int parseName(const std::string &name, std::vector &items, unsigned int &attempt, Errors &err) +{ + std::istringstream f(name); + std::string part; + + while (getline(f, part, CRI::Constants::nameDelimiterChar)) { + items.push_back(part); + } + + if (items.size() != 6) { + err.Errorf("failed to parse the sandbox name: %s", name.c_str()); + return -1; + } + + if (items[0] != CRI::Constants::kubePrefix) { + err.Errorf("container is not managed by kubernetes: %s", name.c_str()); + return -1; + } + + if (util_safe_uint(items[5].c_str(), &attempt)) { + err.Errorf("failed to parse the sandbox name %s: %s", name.c_str(), strerror(errno)); + return -1; + } + + return 0; +} + std::string MakeSandboxName(const runtime::v1alpha2::PodSandboxMetadata &metadata) { std::string sname; + sname.append(CRI::Constants::kubePrefix); sname.append(CRI::Constants::nameDelimiter); sname.append(CRI::Constants::sandboxContainerName); @@ -44,34 +71,21 @@ std::string MakeSandboxName(const runtime::v1alpha2::PodSandboxMetadata &metadat return sname; } -void ParseSandboxName(const google::protobuf::Map &annotations, - runtime::v1alpha2::PodSandboxMetadata &metadata, Errors &err) +void ParseSandboxName(const std::string &name, runtime::v1alpha2::PodSandboxMetadata &metadata, Errors &err) { - if (annotations.count(CRIHelpers::Constants::SANDBOX_NAME_ANNOTATION_KEY) == 0) { - err.Errorf("annotation don't contains the sandbox name, failed to parse it"); - return; - } - - if (annotations.count(CRIHelpers::Constants::SANDBOX_NAMESPACE_ANNOTATION_KEY) == 0) { - err.Errorf("annotation don't contains the sandbox namespace, failed to parse it"); - return; - } + int ret {}; + std::vector items; + unsigned int attempt; - if (annotations.count(CRIHelpers::Constants::SANDBOX_UID_ANNOTATION_KEY) == 0) { - err.Errorf("annotation don't contains the sandbox uid, failed to parse it"); + ret = parseName(name, items, attempt, err); + if (ret != 0) { return; } - if (annotations.count(CRIHelpers::Constants::SANDBOX_ATTEMPT_ANNOTATION_KEY) == 0) { - err.Errorf("annotation don't contains the sandbox attempt, failed to parse it"); - return; - } - - metadata.set_name(annotations.at(CRIHelpers::Constants::SANDBOX_NAME_ANNOTATION_KEY)); - metadata.set_namespace_(annotations.at(CRIHelpers::Constants::SANDBOX_NAMESPACE_ANNOTATION_KEY)); - metadata.set_uid(annotations.at(CRIHelpers::Constants::SANDBOX_UID_ANNOTATION_KEY)); - auto sandboxAttempt = annotations.at(CRIHelpers::Constants::SANDBOX_ATTEMPT_ANNOTATION_KEY); - metadata.set_attempt(static_cast(std::stoul(sandboxAttempt))); + metadata.set_name(items[2]); + metadata.set_namespace_(items[3]); + metadata.set_uid(items[4]); + metadata.set_attempt(attempt); } std::string MakeContainerName(const runtime::v1alpha2::PodSandboxConfig &s, const runtime::v1alpha2::ContainerConfig &c) @@ -93,21 +107,19 @@ std::string MakeContainerName(const runtime::v1alpha2::PodSandboxConfig &s, cons return sname; } -void ParseContainerName(const google::protobuf::Map &annotations, - runtime::v1alpha2::ContainerMetadata *metadata, Errors &err) +void ParseContainerName(const std::string &name, runtime::v1alpha2::ContainerMetadata *metadata, Errors &err) { - if (annotations.count(CRIHelpers::Constants::CONTAINER_NAME_ANNOTATION_KEY) == 0) { - err.Errorf("annotation don't contains the container name, failed to parse it"); - return; - } - metadata->set_name(annotations.at(CRIHelpers::Constants::CONTAINER_NAME_ANNOTATION_KEY)); + int ret {}; + std::vector items; + unsigned int attempt; - std::string containerAttempt = "0"; - if (annotations.count(CRIHelpers::Constants::CONTAINER_ATTEMPT_ANNOTATION_KEY) != 0) { - containerAttempt = annotations.at(CRIHelpers::Constants::CONTAINER_ATTEMPT_ANNOTATION_KEY); + ret = parseName(name, items, attempt, err); + if (ret != 0) { + return; } - metadata->set_attempt(static_cast(std::stoul(containerAttempt))); + metadata->set_name(items[1]); + metadata->set_attempt(attempt); } } // namespace CRINaming diff --git a/src/daemon/entry/cri/naming.h b/src/daemon/entry/cri/naming.h index 7eab41d308432ed90da4d1034e1d4b358b26681e..a507747dcd3c4e4609d91cb1e202773f4c319cae 100644 --- a/src/daemon/entry/cri/naming.h +++ b/src/daemon/entry/cri/naming.h @@ -26,11 +26,9 @@ std::string MakeSandboxName(const runtime::v1alpha2::PodSandboxMetadata &metadat std::string MakeContainerName(const runtime::v1alpha2::PodSandboxConfig &s, const runtime::v1alpha2::ContainerConfig &c); -void ParseSandboxName(const google::protobuf::Map &annotations, - runtime::v1alpha2::PodSandboxMetadata &metadata, Errors &err); +void ParseSandboxName(const std::string &name, runtime::v1alpha2::PodSandboxMetadata &metadata, Errors &err); -void ParseContainerName(const google::protobuf::Map &annotations, - runtime::v1alpha2::ContainerMetadata *metadata, Errors &err); +void ParseContainerName(const std::string &name, runtime::v1alpha2::ContainerMetadata *metadata, Errors &err); } // namespace CRINaming #endif // DAEMON_ENTRY_CRI_NAMING_H diff --git a/src/daemon/entry/cri/request_cache.cc b/src/daemon/entry/cri/request_cache.cc index 4ff284ab257b26042d5c690264e81611685f86a6..46fef28949dfb4dd7ca870630922d4f439288e65 100644 --- a/src/daemon/entry/cri/request_cache.cc +++ b/src/daemon/entry/cri/request_cache.cc @@ -179,41 +179,4 @@ runtime::v1alpha2::AttachRequest RequestCache::ConsumeAttachRequest(const std::s } return ele.attachRequest.at(0); -} - -std::string RequestCache::GetExecContainerIDByToken(const std::string &token) -{ - std::lock_guard lock(m_mutex); - - if (m_tokens.count(token) == 0 || m_tokens[token].execRequest.size() == 0) { - ERROR("Invalid token"); - return ""; - } - - return m_tokens[token].execRequest.at(0).container_id(); -} - -std::string RequestCache::GetAttachContainerIDByToken(const std::string &token) -{ - std::lock_guard lock(m_mutex); - - if (m_tokens.count(token) == 0 || m_tokens[token].attachRequest.size() == 0) { - ERROR("Invalid token"); - return ""; - } - - return m_tokens[token].attachRequest.at(0).container_id(); -} - -std::string RequestCache::GetContainerIDByToken(const std::string &method, const std::string &token) -{ - if (method == "exec") { - return GetExecContainerIDByToken(token); - } else if (method == "attach") { - return GetAttachContainerIDByToken(token); - } - - ERROR("Invalid method: %s", method.c_str()); - - return ""; -} +} \ No newline at end of file diff --git a/src/daemon/entry/cri/request_cache.h b/src/daemon/entry/cri/request_cache.h index d44b4d788e047e4cb745982ef95f0c2ec9cbee29..0f86a85e1c07f27ba09111888f4980b3f60bd54c 100644 --- a/src/daemon/entry/cri/request_cache.h +++ b/src/daemon/entry/cri/request_cache.h @@ -53,14 +53,11 @@ public: std::string InsertAttachRequest(const runtime::v1alpha2::AttachRequest &req); runtime::v1alpha2::ExecRequest ConsumeExecRequest(const std::string &token); runtime::v1alpha2::AttachRequest ConsumeAttachRequest(const std::string &token); - std::string GetContainerIDByToken(const std::string &method, const std::string &token); bool IsValidToken(const std::string &token); private: void GarbageCollection(); std::string UniqueToken(); - std::string GetExecContainerIDByToken(const std::string &token); - std::string GetAttachContainerIDByToken(const std::string &token); private: RequestCache() = default; diff --git a/src/daemon/entry/cri/websocket/service/attach_serve.cc b/src/daemon/entry/cri/websocket/service/attach_serve.cc index cda63c45104cf1a1538f3f1950e226a2dc48d723..ec2edc8bba68352da1ea6f8dfe792d5f38f1ea0f 100644 --- a/src/daemon/entry/cri/websocket/service/attach_serve.cc +++ b/src/daemon/entry/cri/websocket/service/attach_serve.cc @@ -16,39 +16,44 @@ #include "attach_serve.h" #include "utils.h" -int AttachServe::Execute(session_data *lws_ctx, const std::string &token) +int AttachServe::Execute(lwsContext lws_ctx, const std::string &token, int read_pipe_fd) { - if (lws_ctx == nullptr) { - return -1; - } - prctl(PR_SET_NAME, "AttachServe"); service_executor_t *cb = get_service_executor(); if (cb == nullptr || cb->container.attach == nullptr) { - sem_post(lws_ctx->sync_close_sem); + sem_post(lws_ctx.sync_close_sem); return -1; } container_attach_request *container_req = nullptr; if (GetContainerRequest(token, &container_req) != 0) { ERROR("Failed to get contaner request"); - sem_post(lws_ctx->sync_close_sem); + sem_post(lws_ctx.sync_close_sem); + return -1; + } + + // attach operation is non-blocking and cannot pass a local variable in + // free memory when close websocket session in closeWsConnect + lwsContext *lws_context = new (std::nothrow)lwsContext(lws_ctx); + if (lws_context == nullptr) { + ERROR("Out of memory"); + sem_post(lws_ctx.sync_close_sem); return -1; } struct io_write_wrapper stringWriter = { 0 }; - stringWriter.context = (void *)(lws_ctx); + stringWriter.context = (void *)(lws_context); stringWriter.write_func = WsWriteStdoutToClient; stringWriter.close_func = closeWsConnect; container_req->attach_stderr = false; container_attach_response *container_res = nullptr; - int ret = cb->container.attach(container_req, &container_res, container_req->attach_stdin ? lws_ctx->pipes.at(0) : -1, + int ret = cb->container.attach(container_req, &container_res, container_req->attach_stdin ? read_pipe_fd : -1, container_req->attach_stdout ? &stringWriter : nullptr, nullptr); if (ret != 0) { ERROR("Failed to attach container: %s", container_req->container_id); - sem_post(lws_ctx->sync_close_sem); + sem_post(lws_ctx.sync_close_sem); } free_container_attach_request(container_req); diff --git a/src/daemon/entry/cri/websocket/service/attach_serve.h b/src/daemon/entry/cri/websocket/service/attach_serve.h index f7b8a017c6ea78425ef02d9d385047e2bed833ba..0d29f35b8ba0b765ad768c42150b1cc2eb9aa9c2 100644 --- a/src/daemon/entry/cri/websocket/service/attach_serve.h +++ b/src/daemon/entry/cri/websocket/service/attach_serve.h @@ -33,7 +33,7 @@ public: AttachServe(const AttachServe &) = delete; AttachServe &operator=(const AttachServe &) = delete; virtual ~AttachServe() = default; - int Execute(session_data *lws_ctx, const std::string &token) override; + int Execute(lwsContext lws_ctx, const std::string &token, int read_pipe_fd) override; private: int RequestFromCri(const runtime::v1alpha2::AttachRequest &grequest, container_attach_request **request); diff --git a/src/daemon/entry/cri/websocket/service/exec_serve.cc b/src/daemon/entry/cri/websocket/service/exec_serve.cc index 0054f1af65de3106509e34f6f3d7cd56e9e99f5f..ecad26f084ca4b235e7c0d15241e76d44bf230df 100644 --- a/src/daemon/entry/cri/websocket/service/exec_serve.cc +++ b/src/daemon/entry/cri/websocket/service/exec_serve.cc @@ -18,37 +18,40 @@ #include "utils.h" #include "cri_helpers.h" -int ExecServe::Execute(session_data *lws_ctx, const std::string &token) +int ExecServe::Execute(lwsContext lws_ctx, const std::string &token, int read_pipe_fd) { - if (lws_ctx == nullptr) { - return -1; - } - service_executor_t *cb = get_service_executor(); if (cb == nullptr || cb->container.exec == nullptr) { - sem_post(lws_ctx->sync_close_sem); + sem_post(lws_ctx.sync_close_sem); return -1; } container_exec_request *container_req = nullptr; - if (GetContainerRequest(token, lws_ctx->suffix, &container_req) != 0) { + if (GetContainerRequest(token, &container_req) != 0) { ERROR("Failed to get contaner request"); - sem_post(lws_ctx->sync_close_sem); + sem_post(lws_ctx.sync_close_sem); + return -1; + } + + lwsContext *lws_context = new (std::nothrow)lwsContext(lws_ctx); + if (lws_context == nullptr) { + ERROR("Out of memory"); + sem_post(lws_ctx.sync_close_sem); return -1; } struct io_write_wrapper StdoutstringWriter = { 0 }; - StdoutstringWriter.context = (void *)lws_ctx; + StdoutstringWriter.context = (void *)lws_context; StdoutstringWriter.write_func = WsWriteStdoutToClient; // the close function of StderrstringWriter is preferred unless StderrstringWriter is nullptr - StdoutstringWriter.close_func = nullptr; + StdoutstringWriter.close_func = container_req->attach_stderr ? nullptr : closeWsStream; struct io_write_wrapper StderrstringWriter = { 0 }; - StderrstringWriter.context = (void *)lws_ctx; + StderrstringWriter.context = (void *)lws_context; StderrstringWriter.write_func = WsWriteStderrToClient; - StderrstringWriter.close_func = nullptr; + StderrstringWriter.close_func = container_req->attach_stderr ? closeWsStream : nullptr; container_exec_response *container_res = nullptr; - int ret = cb->container.exec(container_req, &container_res, container_req->attach_stdin ? lws_ctx->pipes.at(0) : -1, + int ret = cb->container.exec(container_req, &container_res, container_req->attach_stdin ? read_pipe_fd : -1, container_req->attach_stdout ? &StdoutstringWriter : nullptr, container_req->attach_stderr ? &StderrstringWriter : nullptr); if (ret != 0) { @@ -58,28 +61,27 @@ int ExecServe::Execute(session_data *lws_ctx, const std::string &token) } else { message = "Failed to call exec container callback. "; } - WsWriteStdoutToClient(lws_ctx, message.c_str(), message.length()); + WsWriteStdoutToClient(lws_context, message.c_str(), message.length()); } if (container_res != nullptr && container_res->exit_code != 0) { std::string exit_info = "Exit code :" + std::to_string((int)container_res->exit_code) + "\n"; - WsWriteStdoutToClient(lws_ctx, exit_info.c_str(), exit_info.length()); + WsWriteStdoutToClient(lws_context, exit_info.c_str(), exit_info.length()); } free_container_exec_request(container_req); free_container_exec_response(container_res); - closeWsConnect((void*)lws_ctx, nullptr); + closeWsConnect((void*)lws_context, nullptr); return ret; } -int ExecServe::GetContainerRequest(const std::string &token, const std::string &suffix, - container_exec_request **container_req) +int ExecServe::GetContainerRequest(const std::string &token, container_exec_request **container_req) { RequestCache *cache = RequestCache::GetInstance(); auto request = cache->ConsumeExecRequest(token); - int ret = RequestFromCri(request, suffix, container_req); + int ret = RequestFromCri(request, container_req); if (ret != 0) { ERROR("Failed to transform grpc request!"); } @@ -87,8 +89,7 @@ int ExecServe::GetContainerRequest(const std::string &token, const std::string & return ret; } -int ExecServe::RequestFromCri(const runtime::v1alpha2::ExecRequest &grequest, const std::string &suffix, - container_exec_request **request) +int ExecServe::RequestFromCri(const runtime::v1alpha2::ExecRequest &grequest, container_exec_request **request) { container_exec_request *tmpreq = nullptr; @@ -125,7 +126,12 @@ int ExecServe::RequestFromCri(const runtime::v1alpha2::ExecRequest &grequest, co tmpreq->argv_len = (size_t)grequest.cmd_size(); } - tmpreq->suffix = util_strdup_s(suffix.c_str()); + tmpreq->suffix = CRIHelpers::GenerateExecSuffix(); + if (tmpreq->suffix == nullptr) { + ERROR("Failed to generate exec suffix(id)"); + free_container_exec_request(tmpreq); + return -1; + } *request = tmpreq; return 0; diff --git a/src/daemon/entry/cri/websocket/service/exec_serve.h b/src/daemon/entry/cri/websocket/service/exec_serve.h index 5cccdee86f708e289c9b7e0395a18ea2c2b586fb..093f076af7bfe23540f76f555459d3e0f5299fa3 100644 --- a/src/daemon/entry/cri/websocket/service/exec_serve.h +++ b/src/daemon/entry/cri/websocket/service/exec_serve.h @@ -37,11 +37,10 @@ public: ExecServe(const ExecServe &) = delete; ExecServe &operator=(const ExecServe &) = delete; virtual ~ExecServe() = default; - int Execute(session_data *lws_ctx, const std::string &token) override; + int Execute(lwsContext lws_ctx, const std::string &token, int read_pipe_fd) override; private: - int RequestFromCri(const runtime::v1alpha2::ExecRequest &grequest, const std::string &suffix, - container_exec_request **request); - int GetContainerRequest(const std::string &token, const std::string &suffix, container_exec_request **request); + int RequestFromCri(const runtime::v1alpha2::ExecRequest &grequest, container_exec_request **request); + int GetContainerRequest(const std::string &token, container_exec_request **request); }; #endif // DAEMON_ENTRY_CRI_WEBSOCKET_SERVICE_EXEC_SERVE_H diff --git a/src/daemon/entry/cri/websocket/service/route_callback_register.h b/src/daemon/entry/cri/websocket/service/route_callback_register.h index 909c552be979986b22d1179c7f7fa4780a8ab3fc..ebf77e420c5b084466ef8aa96a7c171d20219363 100644 --- a/src/daemon/entry/cri/websocket/service/route_callback_register.h +++ b/src/daemon/entry/cri/websocket/service/route_callback_register.h @@ -24,7 +24,11 @@ #include #include "isula_libutils/log.h" -struct session_data; +struct lwsContext { + int fd; + sem_t *sync_close_sem; + bool *close; +}; class StreamingServeInterface { public: @@ -32,7 +36,7 @@ public: StreamingServeInterface(const StreamingServeInterface &) = delete; StreamingServeInterface &operator=(const StreamingServeInterface &) = delete; virtual ~StreamingServeInterface() = default; - virtual int Execute(session_data *lws_ctx, const std::string &token) = 0; + virtual int Execute(lwsContext lws_ctx, const std::string &token, int read_pipe_fd) = 0; }; class RouteCallbackRegister { @@ -46,14 +50,14 @@ public: return static_cast(m_registeredcallbacks.count(method)); } - int HandleCallback(session_data *lws_ctx, const std::string &method, - const std::string &token) + int HandleCallback(lwsContext lws_ctx, const std::string &method, + const std::string &token, int read_pipe_fd) { auto it = m_registeredcallbacks.find(method); if (it != m_registeredcallbacks.end()) { std::shared_ptr callback = it->second; if (callback) { - return callback->Execute(lws_ctx, token); + return callback->Execute(lws_ctx, token, read_pipe_fd); } } ERROR("invalid method!"); @@ -72,22 +76,24 @@ private: class StreamTask { public: - StreamTask(RouteCallbackRegister *invoker, session_data *lws_ctx, + StreamTask(RouteCallbackRegister *invoker, lwsContext lws_ctx, const std::string &method, - const std::string &token) - : m_invoker(invoker), m_lws_ctx(lws_ctx), m_method(method), m_token(token) {} + const std::string &token, int read_pipe_fd) + : m_invoker(invoker), m_lws_ctx(lws_ctx), m_method(method), m_token(token), + m_read_pipe_fd(read_pipe_fd) {} StreamTask(const StreamTask &) = delete; StreamTask &operator=(const StreamTask &) = delete; virtual ~StreamTask() = default; int Run() { - return m_invoker->HandleCallback(m_lws_ctx, m_method, m_token); + return m_invoker->HandleCallback(m_lws_ctx, m_method, m_token, m_read_pipe_fd); } private: RouteCallbackRegister *m_invoker{ nullptr }; - session_data *m_lws_ctx; + lwsContext m_lws_ctx; std::string m_method; std::string m_token; + int m_read_pipe_fd; }; #endif // DAEMON_ENTRY_CRI_WEBSOCKET_SERVICE_ROUTE_CALLBACK_REGISTER_H diff --git a/src/daemon/entry/cri/websocket/service/ws_server.cc b/src/daemon/entry/cri/websocket/service/ws_server.cc index 26d842f7eb7d85c0039f89636a61261efa96fbf0..6fc5ca1d483b5fa251c0016cb93e1e9d1c467114 100644 --- a/src/daemon/entry/cri/websocket/service/ws_server.cc +++ b/src/daemon/entry/cri/websocket/service/ws_server.cc @@ -25,13 +25,11 @@ #include "request_cache.h" #include "constants.h" #include "isulad_config.h" -#include "callback.h" -#include "cri_helpers.h" struct lws_context *WebsocketServer::m_context = nullptr; std::atomic WebsocketServer::m_instance; RWMutex WebsocketServer::m_mutex; -std::unordered_map WebsocketServer::m_wsis; +std::unordered_map WebsocketServer::m_wsis; WebsocketServer *WebsocketServer::GetInstance() noexcept { @@ -47,7 +45,7 @@ WebsocketServer *WebsocketServer::GetInstance() noexcept WebsocketServer::WebsocketServer() { m_force_exit = 0; - m_wsis.reserve(SESSION_CAPABILITY); + m_wsis.clear(); } WebsocketServer::~WebsocketServer() @@ -60,6 +58,11 @@ url::URLDatum WebsocketServer::GetWebsocketUrl() return m_url; } +std::unordered_map &WebsocketServer::GetWsisData() +{ + return m_wsis; +} + void WebsocketServer::ReadLockAllWsSession() { m_mutex.rdlock(); @@ -155,12 +158,11 @@ void WebsocketServer::CloseAllWsSession() { WriteGuard lock(m_mutex); for (auto it = m_wsis.begin(); it != m_wsis.end(); ++it) { - it->second->EraseAllMessage(); - close(it->second->pipes.at(0)); - close(it->second->pipes.at(1)); - (void)sem_destroy(it->second->sync_close_sem); - delete it->second->session_mutex; - delete it->second; + it->second.EraseAllMessage(); + close(it->second.pipes.at(0)); + close(it->second.pipes.at(1)); + delete it->second.buf_mutex; + delete it->second.close; } m_wsis.clear(); } @@ -169,80 +171,51 @@ void WebsocketServer::CloseWsSession(int socketID) { auto it = m_wsis.find(socketID); if (it != m_wsis.end()) { - it->second->CloseSession(); - it->second->EraseAllMessage(); + *(it->second.close) = true; + it->second.EraseAllMessage(); // close the pipe write endpoint first, make sure io copy thread exit, // otherwise epoll will trigger EOF - if (it->second->pipes.at(1) >= 0) { - close(it->second->pipes.at(1)); - it->second->pipes.at(1) = -1; + if (it->second.pipes.at(1) >= 0) { + close(it->second.pipes.at(1)); + it->second.pipes.at(1) = -1; } - (void)sem_wait(it->second->sync_close_sem); - (void)sem_destroy(it->second->sync_close_sem); - close(it->second->pipes.at(0)); - delete it->second->session_mutex; - it->second->session_mutex = nullptr; - delete it->second; - it->second = nullptr; + (void)sem_wait(it->second.sync_close_sem); + (void)sem_destroy(it->second.sync_close_sem); + close(it->second.pipes.at(0)); + delete it->second.buf_mutex; + it->second.buf_mutex = nullptr; + delete it->second.close; + it->second.close = nullptr; m_wsis.erase(it); } } -int WebsocketServer::GenerateSessionData(session_data *session, const std::string containerID) noexcept +int WebsocketServer::GenerateSessionData(session_data &session) noexcept { - char *suffix = nullptr; - int read_pipe_fd[PIPE_FD_NUM] = {-1, -1}; - std::mutex *buf_mutex = nullptr; - sem_t *sync_close_sem = nullptr; - - suffix = CRIHelpers::GenerateExecSuffix(); - if (suffix == nullptr) { - ERROR("Failed to generate suffix(id)"); - return -1; - } - + int read_pipe_fd[PIPE_FD_NUM]; if (InitRWPipe(read_pipe_fd) < 0) { ERROR("failed to init read/write pipe!"); - goto out; + return -1; } - buf_mutex = new std::mutex; - sync_close_sem = new sem_t; + std::mutex *buf_mutex = new std::mutex; + sem_t *sync_close_sem = new sem_t; if (sem_init(sync_close_sem, 0, 0) != 0) { ERROR("Semaphore initialization failed"); - goto out; - } - - session->pipes = std::array { read_pipe_fd[0], read_pipe_fd[1] }; - session->session_mutex = buf_mutex; - session->sync_close_sem = sync_close_sem; - session->close = false; - session->container_id = containerID; - session->suffix = std::string(suffix); - - free(suffix); - - return 0; - -out: - if (suffix != nullptr) { - free(suffix); - } - if (read_pipe_fd[1] >= 0) { close(read_pipe_fd[1]); - } - if (read_pipe_fd[0] >= 0) { close(read_pipe_fd[0]); - } - if (buf_mutex != nullptr) { delete buf_mutex; - } - if (sync_close_sem) { delete sync_close_sem; + return -1; } - return -1; + session.pipes = std::array { read_pipe_fd[0], read_pipe_fd[1] }; + session.buf_mutex = buf_mutex; + session.sync_close_sem = sync_close_sem; + session.close = new bool(false); + + return 0; } int WebsocketServer::RegisterStreamTask(struct lws *wsi) noexcept @@ -265,41 +238,22 @@ int WebsocketServer::RegisterStreamTask(struct lws *wsi) noexcept return -1; } - int socketID = lws_get_socket_fd(wsi); - if (m_wsis.count(socketID) != 0) { - ERROR("socketID already exist!"); - return -1; - } - - if (m_wsis.size() > MAX_SESSION_NUM) { - WARN("too many connection sessions"); - } - - std::string containerID = cache->GetContainerIDByToken(vec.at(1), vec.at(2)); - if (containerID.empty()) { - ERROR("Failed to get container id from %s request", vec.at(1).c_str()); - return -1; - } - - session_data *session = new (std::nothrow) session_data; - if (session == nullptr) { - ERROR("Out of memory"); - return -1; - } - if (GenerateSessionData(session, containerID) != 0) { + session_data session; + if (GenerateSessionData(session) != 0) { ERROR("failed to fill generate session data"); return -1; } - std::string suffixID = session->suffix; - auto insertRet = m_wsis.insert(std::make_pair(socketID, session)); - if (!insertRet.second) { - ERROR("failed to insert session data to map"); - return -1; - } + int socketID = lws_get_socket_fd(wsi); + m_wsis.insert(std::make_pair(socketID, std::move(session))); + lwsContext lwsCtx = { + .fd = socketID, + .sync_close_sem = m_wsis[socketID].sync_close_sem, + .close = m_wsis[socketID].close, + }; std::thread streamTh([ = ]() { - StreamTask(&m_handler, session, vec.at(1), vec.at(2)).Run(); + StreamTask(&m_handler, lwsCtx, vec.at(1), vec.at(2), m_wsis[socketID].pipes.at(0)).Run(); }); streamTh.detach(); @@ -349,99 +303,20 @@ int WebsocketServer::Wswrite(struct lws *wsi, const unsigned char *message) return 0; } -int WebsocketServer::parseTerminalSize(const char *jsonData, size_t len, uint16_t &width, uint16_t &height) -{ - int ret = 0; - parser_error err = nullptr; - cri_terminal_size *terminalSize = nullptr; - - if (jsonData == nullptr || len == 0) { - return -1; - } - - // No terminator is included in json data, and len contains a character occupied by channal - std::string jsonDataStr { jsonData, len - 1 }; - - // parse json data. eg: {"Width":xx,"Height":xx} - terminalSize = cri_terminal_size_parse_data(jsonDataStr.c_str(), nullptr, &err); - if (terminalSize == nullptr) { - ERROR("Failed to parse json: %s", err); - ret = -1; - } else { - width = terminalSize->width; - height = terminalSize->height; - } - - free(err); - free_cri_terminal_size(terminalSize); - - return ret; -} - -int WebsocketServer::ResizeTerminal( - int socketID, const char *jsonData, size_t len, - const std::string &containerID, - const std::string &suffix) -{ - int ret; - service_executor_t *cb = nullptr; - struct isulad_container_resize_request *req = nullptr; - struct isulad_container_resize_response *res = nullptr; - uint16_t width = 0; - uint16_t height = 0; - - cb = get_service_executor(); - if (cb == nullptr || cb->container.resize == nullptr) { - return -1; - } - - if (parseTerminalSize(jsonData, len, width, height) != 0) { - return -1; - } - - req = (struct isulad_container_resize_request *)util_common_calloc_s( - sizeof(struct isulad_container_resize_request)); - if (req == nullptr) { - ERROR("Out of memory"); - return -1; - } - - req->id = util_strdup_s(containerID.c_str()); - req->suffix = util_strdup_s(suffix.c_str()); - req->height = height; - req->width = width; - - ret = cb->container.resize(req, &res); - - isulad_container_resize_request_free(req); - isulad_container_resize_response_free(res); - - - return ret; -} - void WebsocketServer::Receive(int socketID, void *in, size_t len) { - auto it = m_wsis.find(socketID); - if (it == m_wsis.end()) { + if (m_wsis.find(socketID) == m_wsis.end()) { ERROR("invailed websocket session!"); return; } - if (*static_cast(in) == WebsocketChannel::RESIZECHANNEL) { - std::string containerID = it->second->container_id; - std::string suffix = it->second->suffix; - if (ResizeTerminal(socketID, (char *)in + 1, len, containerID, suffix) != 0) { - ERROR("Failed to resize terminal tty"); - return; - } - } else if (*static_cast(in) == WebsocketChannel::STDINCHANNEL) { - if (write(m_wsis[socketID]->pipes.at(1), (void *)((char *)in + 1), len - 1) < 0) { - ERROR("sub write over!"); - return; - } - } else { - ERROR("invalid data: %s", (char *)in); + if (*static_cast(in) != WebsocketChannel::STDINCHANNEL) { + ERROR("recevice date from client: %s", (char *)in + 1); + return; + } + + if (write(m_wsis[socketID].pipes.at(1), (void *)((char *)in + 1), len - 1) < 0) { + ERROR("sub write over!"); return; } } @@ -480,13 +355,12 @@ int WebsocketServer::Callback(struct lws *wsi, enum lws_callback_reasons reason, return -1; } - auto isSessionClosed = it->second->IsClosed(); - while (!it->second->buffer.empty()) { - unsigned char *message = it->second->FrontMessage(); + while (!it->second.buffer.empty()) { + unsigned char *message = it->second.FrontMessage(); // send success! free it and erase for list if (WebsocketServer::GetInstance()->Wswrite(wsi, (const unsigned char *)message) == 0) { free(message); - it->second->PopMessage(); + it->second.PopMessage(); } else { // Another case ret > 0, send fail! keep message and send it again! // Or maybe the client was shut down abnormally @@ -494,8 +368,7 @@ int WebsocketServer::Callback(struct lws *wsi, enum lws_callback_reasons reason, } } - // avoid: push message to buffer and set closed true - if (isSessionClosed) { + if (*(it->second.close)) { DEBUG("websocket session disconnected"); return -1; } @@ -560,7 +433,7 @@ void WebsocketServer::Wait() namespace { -void DoWriteToClient(session_data *session, +void DoWriteToClient(int fd, session_data *session, const void *data, size_t len, WebsocketChannel channel) { unsigned char *buf = (unsigned char *)util_common_calloc_s(LWS_PRE + MAX_BUFFER_SIZE + 1); @@ -582,51 +455,64 @@ void DoWriteToClient(session_data *session, ssize_t WsWriteToClient(void *context, const void *data, size_t len, WebsocketChannel channel) { - auto *lwsCtx = static_cast(context); - - // CloseWsSession wait IOCopy finished, and then delete session in m_wsis - // So don't need rdlock m_wsis here - if (lwsCtx->IsClosed()) { + auto *lwsCtx = static_cast(context); + int fd = lwsCtx->fd; + if (lwsCtx->close == nullptr || *(lwsCtx->close)) { + return 0; + } + WebsocketServer *server = WebsocketServer::GetInstance(); + auto itor = server->GetWsisData().find(fd); + if (itor == server->GetWsisData().end()) { + ERROR("invalid session!"); return 0; } - DoWriteToClient(lwsCtx, data, len, channel); + DoWriteToClient(fd, &itor->second, data, len, channel); + return static_cast(len); } }; ssize_t WsWriteStdoutToClient(void *context, const void *data, size_t len) { - if (context == nullptr) { - ERROR("websocket session context empty"); - return -1; - } - return WsWriteToClient(context, data, len, STDOUTCHANNEL); } ssize_t WsWriteStderrToClient(void *context, const void *data, size_t len) { - if (context == nullptr) { - ERROR("websocket session context empty"); - return -1; - } - return WsWriteToClient(context, data, len, STDERRCHANNEL); } int closeWsConnect(void *context, char **err) { (void)err; + auto *lwsCtx = static_cast(context); + + if (lwsCtx->sync_close_sem != nullptr) { + (void)sem_post(lwsCtx->sync_close_sem); + } - if (context == nullptr) { - ERROR("websocket session context empty"); + WebsocketServer *server = WebsocketServer::GetInstance(); + server->ReadLockAllWsSession(); + auto it = server->GetWsisData().find(lwsCtx->fd); + if (it == server->GetWsisData().end()) { + server->UnlockAllWsSession(); + ERROR("websocket session not exist"); + delete lwsCtx; return -1; } + // will close websocket session on LWS_CALLBACK_SERVER_WRITEABLE polling + *(it->second.close) = true; + server->UnlockAllWsSession(); - auto *lwsCtx = static_cast(context); + delete lwsCtx; + return 0; +} - lwsCtx->CloseSession(); +int closeWsStream(void *context, char **err) +{ + (void)err; + auto *lwsCtx = static_cast(context); if (lwsCtx->sync_close_sem != nullptr) { (void)sem_post(lwsCtx->sync_close_sem); diff --git a/src/daemon/entry/cri/websocket/service/ws_server.h b/src/daemon/entry/cri/websocket/service/ws_server.h index d4ea96cb3e61b0f07da17923c91bd92ee1a5cb7a..249acab67a02a5786655c2527118c92f1c7f9ab9 100644 --- a/src/daemon/entry/cri/websocket/service/ws_server.h +++ b/src/daemon/entry/cri/websocket/service/ws_server.h @@ -29,7 +29,6 @@ #include "url.h" #include "errors.h" #include "read_write_lock.h" -#include "isula_libutils/cri_terminal_size.h" #define MAX_ECHO_PAYLOAD 4096 #define MAX_ARRAY_LEN 2 @@ -42,112 +41,62 @@ #define LWS_TIMEOUT 50 // io copy maximum single transfer 4K, let max total buffer size: 1GB #define FIFO_LIST_BUFFER_MAX_LEN 262144 -#define SESSION_CAPABILITY 300 -#define MAX_SESSION_NUM 120 enum WebsocketChannel { STDINCHANNEL = 0, STDOUTCHANNEL, - STDERRCHANNEL, - ERRORCHANNEL, - RESIZECHANNEL + STDERRCHANNEL }; struct session_data { std::array pipes; - volatile bool close; - std::mutex *session_mutex; + bool *close; + std::mutex *buf_mutex; sem_t *sync_close_sem; std::list buffer; - std::string container_id; - std::string suffix; unsigned char *FrontMessage() { unsigned char *message = nullptr; - if (session_mutex == nullptr) { - return nullptr; - } - - session_mutex->lock(); + buf_mutex->lock(); message = buffer.front(); - session_mutex->unlock(); + buf_mutex->unlock(); return message; } void PopMessage() { - if (session_mutex == nullptr) { - return; - } - - session_mutex->lock(); + buf_mutex->lock(); buffer.pop_front(); - session_mutex->unlock(); + buf_mutex->unlock(); } int PushMessage(unsigned char *message) { - if (session_mutex == nullptr) { - return -1; - } - - session_mutex->lock(); - // In extreme scenarios, websocket data cannot be processed, // ignore the data coming in later to prevent iSulad from getting stuck - if (close || buffer.size() >= FIFO_LIST_BUFFER_MAX_LEN) { + if (*close || buffer.size() >= FIFO_LIST_BUFFER_MAX_LEN) { free(message); - session_mutex->unlock(); return -1; } - + buf_mutex->lock(); buffer.push_back(message); - session_mutex->unlock(); - return 0; - } - - bool IsClosed() - { - bool c = false; - - if (session_mutex == nullptr) { - return true; - } - - session_mutex->lock(); - c = close; - session_mutex->unlock(); - - return c; - } + buf_mutex->unlock(); - void CloseSession() - { - if (session_mutex == nullptr) { - return; - } - - session_mutex->lock(); - close = true; - session_mutex->unlock(); + return 0; } void EraseAllMessage() { - if (session_mutex == nullptr) { - return; - } - - session_mutex->lock(); + buf_mutex->lock(); for (auto iter = buffer.begin(); iter != buffer.end();) { free(*iter); *iter = NULL; iter = buffer.erase(iter); } - session_mutex->unlock(); + buf_mutex->unlock(); } }; @@ -160,6 +109,7 @@ public: void Shutdown(); void RegisterCallback(const std::string &path, std::shared_ptr callback); url::URLDatum GetWebsocketUrl(); + std::unordered_map &GetWsisData(); void SetLwsSendedFlag(int socketID, bool sended); void ReadLockAllWsSession(); void UnlockAllWsSession(); @@ -177,15 +127,12 @@ private: int Wswrite(struct lws *wsi, const unsigned char *message); inline void DumpHandshakeInfo(struct lws *wsi) noexcept; int RegisterStreamTask(struct lws *wsi) noexcept; - int GenerateSessionData(session_data *session, const std::string containerID) noexcept; + int GenerateSessionData(session_data &session) noexcept; static int Callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); void ServiceWorkThread(int threadid); void CloseWsSession(int socketID); void CloseAllWsSession(); - int ResizeTerminal(int socketID, const char *jsonData, size_t len, - const std::string &containerID, const std::string &suffix); - int parseTerminalSize(const char *jsonData, size_t len, uint16_t &width, uint16_t &height); private: static RWMutex m_mutex; @@ -193,11 +140,11 @@ private: volatile int m_force_exit = 0; std::thread m_pthread_service; const struct lws_protocols m_protocols[MAX_PROTOCOL_NUM] = { - { "channel.k8s.io", Callback, 0, MAX_ECHO_PAYLOAD, }, - { nullptr, nullptr, 0, 0 } + { "channel.k8s.io", Callback, 0, MAX_ECHO_PAYLOAD, }, + { NULL, NULL, 0, 0 } }; RouteCallbackRegister m_handler; - static std::unordered_map m_wsis; + static std::unordered_map m_wsis; url::URLDatum m_url; int m_listenPort; }; @@ -205,6 +152,7 @@ private: ssize_t WsWriteStdoutToClient(void *context, const void *data, size_t len); ssize_t WsWriteStderrToClient(void *context, const void *data, size_t len); int closeWsConnect(void *context, char **err); +int closeWsStream(void *context, char **err); #endif // DAEMON_ENTRY_CRI_WEBSOCKET_SERVICE_WS_SERVER_H diff --git a/src/daemon/executor/CMakeLists.txt b/src/daemon/executor/CMakeLists.txt index 20883a9877d302a39b995785d6c1aa7da3ec6e5b..ca28a7841b710f6eb60ddc9d7a77a557ea11b2cf 100644 --- a/src/daemon/executor/CMakeLists.txt +++ b/src/daemon/executor/CMakeLists.txt @@ -15,11 +15,9 @@ add_subdirectory(volume_cb) list(APPEND local_executor_srcs ${VOLUME_CB_SRCS}) list(APPEND local_executor_incs ${VOLUME_CB_INCS}) -if (ENABLE_METRICS) - add_subdirectory(metrics_cb) - list(APPEND local_executor_srcs ${METRICS_CB_SRCS}) - list(APPEND local_executor_incs ${METRICS_CB_INCS}) -endif() +add_subdirectory(checkpoint_cb) +list(APPEND local_executor_srcs ${CHECKPOINT_CB_SRCS}) +list(APPEND local_executor_incs ${CHECKPOINT_CB_INCS}) set(EXECUTOR_SRCS ${local_executor_srcs} @@ -29,3 +27,4 @@ set(EXECUTOR_INCS ${local_executor_incs} PARENT_SCOPE ) + diff --git a/src/daemon/executor/callback.c b/src/daemon/executor/callback.c index 24f5e948f4f1456970fd4fc9cd1b317384c1d58d..a75f6d223f9a2b08f6432dc9f9b70c1ae8012934 100644 --- a/src/daemon/executor/callback.c +++ b/src/daemon/executor/callback.c @@ -19,9 +19,8 @@ #include "image_cb.h" #include "execution.h" #include "volume_cb.h" -#ifdef ENABLE_METRICS -#include "metrics_cb.h" -#endif +#include "checkpoint_cb.h" +#include service_executor_t g_isulad_service_executor; @@ -160,9 +159,7 @@ int service_callback_init(void) container_callback_init(&g_isulad_service_executor.container); image_callback_init(&g_isulad_service_executor.image); volume_callback_init(&g_isulad_service_executor.volume); -#ifdef ENABLE_METRICS - metrics_callback_init(&g_isulad_service_executor.metrics); -#endif + checkpoint_callback_init(&g_isulad_service_executor.checkpoint); return 0; } diff --git a/src/daemon/executor/callback.h b/src/daemon/executor/callback.h index a86b48649f4152460cd37911d257337cf60e6de0..c79675889c4f076a375c593e31f888a3f9f25da9 100644 --- a/src/daemon/executor/callback.h +++ b/src/daemon/executor/callback.h @@ -88,7 +88,6 @@ #include "events_format.h" #include "stream_wrapper.h" #include "utils_timestamp.h" - #ifdef __cplusplus extern "C" { #endif @@ -272,19 +271,78 @@ typedef struct { int (*prune)(const volume_prune_volume_request *request, volume_prune_volume_response **response); } service_volume_callback_t; -#ifdef ENABLE_METRICS + typedef struct { - int (*export_metrics_by_type)(const char *metric_type, char **data, int *len); -} service_metrics_callback_t; -#endif + char* container; + char* dir; +}checkpoint_create_checkpoint_request; + +typedef struct{ + char* container; + uint32_t cc; + uint32_t server_errono; + char *errmsg; +}checkpoint_create_checkpoint_response; + +typedef struct { + char* container; + char* dir; +}checkpoint_restore_checkpoint_request; + +typedef struct{ + char* container; + uint32_t cc; + uint32_t server_errono; + char *errmsg; +}checkpoint_restore_checkpoint_response; + +typedef struct { + char* container; + char* dir; +}checkpoint_remove_checkpoint_request; + +typedef struct{ + char* container; + uint32_t cc; + uint32_t server_errono; + char *errmsg; +}checkpoint_remove_checkpoint_response; + +typedef struct { + char* dir; +}checkpoint_list_checkpoint_request; + +struct isula_checkpoint_info{ + char *name; + char *dir; +}; +typedef struct { + char *dir; + + char *name; +}checkpoint_checkpoint; + +typedef struct{ + size_t checkpoints_len; + checkpoint_checkpoint **checkpoints; + uint32_t cc; + uint32_t server_errono; + char *errmsg; +}checkpoint_list_checkpoint_response; + +typedef struct{ + int (*create)(const checkpoint_create_checkpoint_request *request,checkpoint_create_checkpoint_response **response); + int (*remove)(const checkpoint_remove_checkpoint_request *request,checkpoint_remove_checkpoint_response **response); + int (*list)(const checkpoint_list_checkpoint_request *request,checkpoint_list_checkpoint_response **response); + int (*restore)(const checkpoint_restore_checkpoint_request *request,checkpoint_restore_checkpoint_response **response); + +}service_checkpoint_callback_t; typedef struct { service_container_callback_t container; service_image_callback_t image; service_volume_callback_t volume; -#ifdef ENABLE_METRICS - service_metrics_callback_t metrics; -#endif + service_checkpoint_callback_t checkpoint; } service_executor_t; int service_callback_init(void); diff --git a/src/daemon/executor/checkpoint_cb/CMakeLists.txt b/src/daemon/executor/checkpoint_cb/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..63ffc6bf5a3773beef97f1b2daa4249c8c2989b4 --- /dev/null +++ b/src/daemon/executor/checkpoint_cb/CMakeLists.txt @@ -0,0 +1,12 @@ +# get current directory sources files +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_checkpoint_cb_srcs) + +set(CHECKPOINT_CB_SRCS + ${local_checkpoint_cb_srcs} + PARENT_SCOPE + ) + +set(CHECKPOINT_CB_INCS + ${CMAKE_CURRENT_SOURCE_DIR} + PARENT_SCOPE + ) diff --git a/src/daemon/executor/checkpoint_cb/checkpoint_cb.c b/src/daemon/executor/checkpoint_cb/checkpoint_cb.c new file mode 100644 index 0000000000000000000000000000000000000000..de6ff4abaec573ae8892b8db96c3c311432e4725 --- /dev/null +++ b/src/daemon/executor/checkpoint_cb/checkpoint_cb.c @@ -0,0 +1,285 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2020. 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: wangfengtu + * Create: 2020-09-03 + * Description: provide checkpoint functions + *********************************************************************************/ + +#include +#include +#include +#include + +#include "callback.h" +#include +#include +#include +#include + +#include "checkpoint_cb.h" +#include "utils.h" +#include "error.h" +#include "err_msg.h" +#include "isula_libutils/log.h" +#include "checkpoint_api.h" +#include "container_api.h" + + +/* checkpoint create cb */ +static int checkpoint_create_cb(const checkpoint_create_checkpoint_request *request, checkpoint_create_checkpoint_response **response) +{ + uint32_t cc = ISULAD_SUCCESS; + + container_t *cont = NULL; + DAEMON_CLEAR_ERRMSG(); + + if (request == NULL || request->container==NULL || response == NULL) { + ERROR("Invalid input arguments"); + return EINVALIDARGS; + } + + *response = util_common_calloc_s(sizeof(checkpoint_create_checkpoint_response)); + if (*response == NULL) { + ERROR("Out of memory"); + cc = ISULAD_ERR_MEMOUT; + goto out; + } + + EVENT("Checkpoint Event: {Object: create checkpoint, Type: Create}"); + + cont = containers_store_get(request->container); + if (cont == NULL) { + cc = ISULAD_ERR_EXEC; + ERROR("No such container:%s", request->container); + isulad_set_error_message("No such container:%s", request->container); + goto out; + } + + + char* id = cont->common_config->id; + + + if (checkpoint_create(id,request->dir)!=0) { + cc = ISULAD_ERR_EXEC; + goto out; + } + + + + + EVENT("Checkpoint Event: {Object: create checkpoints, Type: Created"); + +out: + if (*response != NULL) { + (*response)->cc = cc; + if (g_isulad_errmsg != NULL) { + (*response)->errmsg = util_strdup_s(g_isulad_errmsg); + DAEMON_CLEAR_ERRMSG(); + } + } + + + return (cc != ISULAD_SUCCESS) ? ECOMMON : 0; +} + +static int checkpoint_restore_cb(const checkpoint_restore_checkpoint_request *request, checkpoint_restore_checkpoint_response **response) +{ + uint32_t cc = ISULAD_SUCCESS; +container_t *cont = NULL; + + DAEMON_CLEAR_ERRMSG(); + + if (request == NULL || request->container==NULL || response == NULL) { + ERROR("Invalid input arguments"); + return EINVALIDARGS; + } + + *response = util_common_calloc_s(sizeof(checkpoint_restore_checkpoint_response)); + if (*response == NULL) { + ERROR("Out of memory"); + cc = ISULAD_ERR_MEMOUT; + goto out; + } + + EVENT("Checkpoint Event: {Object: restore checkpoint, Type: Create}"); + + cont = containers_store_get(request->container); + if (cont == NULL) { + cc = ISULAD_ERR_EXEC; + ERROR("No such container:%s", request->container); + isulad_set_error_message("No such container:%s", request->container); + goto out; + } + + + char* id = cont->common_config->id; + + + if (checkpoint_restore(id,request->dir)!=0) { + cc = ISULAD_ERR_EXEC; + goto out; + } + + + + + EVENT("Checkpoint Event: {Object: restore checkpoints, Type: Created"); + +out: + if (*response != NULL) { + (*response)->cc = cc; + if (g_isulad_errmsg != NULL) { + (*response)->errmsg = util_strdup_s(g_isulad_errmsg); + DAEMON_CLEAR_ERRMSG(); + } + } + + + return (cc != ISULAD_SUCCESS) ? ECOMMON : 0; +} + +static int checkpoint_remove_cb(const checkpoint_remove_checkpoint_request *request, checkpoint_remove_checkpoint_response **response) +{ + uint32_t cc = ISULAD_SUCCESS; + + container_t *cont = NULL; + DAEMON_CLEAR_ERRMSG(); + + if (request == NULL || request->container==NULL || response == NULL) { + ERROR("Invalid input arguments"); + return EINVALIDARGS; + } + + + + + *response = util_common_calloc_s(sizeof(checkpoint_remove_checkpoint_response)); + if (*response == NULL) { + ERROR("Out of memory"); + cc = ISULAD_ERR_MEMOUT; + goto out; + } + + cont = containers_store_get(request->container); + if (cont == NULL) { + cc = ISULAD_ERR_EXEC; + isulad_set_error_message("No such container:%s", request->container); + ERROR("No such container:%s", request->container); + goto out; + } + + EVENT("Checkpoint Event: {Object: remove checkpoint, Type: Removing}"); + + + char* id = cont->common_config->id; + + if(checkpoint_remove(id,request->dir)!=0){ + cc = ISULAD_ERR_EXEC; + goto out; + } + + + EVENT("Checkpoint Event: {Object: remove checkpoints, Type: Deleted"); + +out: + if (*response != NULL) { + (*response)->cc = cc; + if (g_isulad_errmsg != NULL) { + (*response)->errmsg = util_strdup_s(g_isulad_errmsg); + DAEMON_CLEAR_ERRMSG(); + } + } + + return (cc != ISULAD_SUCCESS) ? ECOMMON : 0; +} + +static int checkpoint_list_cb(const checkpoint_list_checkpoint_request *request, checkpoint_list_checkpoint_response **response) +{ + uint32_t cc = ISULAD_SUCCESS; + struct checkpoints *list = NULL; + size_t i=0; + checkpoint_checkpoint *che = NULL; + + DAEMON_CLEAR_ERRMSG(); + + if (request == NULL || response == NULL) { + ERROR("Invalid input arguments"); + return EINVALIDARGS; + } + + *response = util_common_calloc_s(sizeof(checkpoint_list_checkpoint_response)); + if (*response == NULL) { + ERROR("Out of memory"); + cc = ISULAD_ERR_MEMOUT; + goto out; + } + + EVENT("Checkpoint Event: {Object: list checkpoint, Type: listing}"); + printf("request->dir:%s\n",request->dir); + list = checkpoint_list(request->dir); + if (list == NULL) { + cc = ISULAD_ERR_EXEC; + goto out; + } + if (list->ches_len == 0) { + goto out; + } + + (*response)->checkpoints = util_smart_calloc_s(sizeof(checkpoint_checkpoint *), list->ches_len); + if ((*response)->checkpoints == NULL) { + ERROR("out of memory"); + cc = ISULAD_ERR_MEMOUT; + goto err_out; + } + for (i = 0; i < list->ches_len; i++) { + che = util_common_calloc_s(sizeof(checkpoint_checkpoint)); + if (che == NULL) { + ERROR("out of memory"); + cc = ISULAD_ERR_MEMOUT; + goto err_out; + } + che->dir = util_strdup_s(list->ches[i]->dir); + che->name = util_strdup_s(list->ches[i]->name); + (*response)->checkpoints[i] = che; + (*response)->checkpoints_len++; + } + + +out: + EVENT("Checkpoint Event: {Object: list checkpoints, Type: listed"); + +err_out: + if (*response != NULL) { + (*response)->cc = cc; + if (g_isulad_errmsg != NULL) { + (*response)->errmsg = util_strdup_s(g_isulad_errmsg); + DAEMON_CLEAR_ERRMSG(); + } + } + + + return (cc != ISULAD_SUCCESS) ? ECOMMON : 0; +} + + +/* checkpoint callback init */ +void checkpoint_callback_init(service_checkpoint_callback_t *cb) +{ + if (cb == NULL) { + ERROR("Invalid input arguments"); + return; + } + + cb->create = checkpoint_create_cb; + cb->remove = checkpoint_remove_cb; + cb->list = checkpoint_list_cb; + cb->restore= checkpoint_restore_cb; +} diff --git a/src/daemon/executor/checkpoint_cb/checkpoint_cb.h b/src/daemon/executor/checkpoint_cb/checkpoint_cb.h new file mode 100644 index 0000000000000000000000000000000000000000..602d21e9f55a5c90bef6b5d03889ecc450e88cd0 --- /dev/null +++ b/src/daemon/executor/checkpoint_cb/checkpoint_cb.h @@ -0,0 +1,16 @@ +#ifndef DAEMON_EXECUTOR_CHECKPOINT_CB_CHECKPOINT_CB_H +#define DAEMON_EXECUTOR_CHECKPOINT_CB_CHECKPOINT_CB_H + +#include "callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void checkpoint_callback_init(service_checkpoint_callback_t *cb); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/src/daemon/executor/container_cb/execution.c b/src/daemon/executor/container_cb/execution.c index 68d0d8d6537c634633937641d25719bfc0dc1a81..2723e7a457f3f4c3df0021294204c98b44b42400 100644 --- a/src/daemon/executor/container_cb/execution.c +++ b/src/daemon/executor/container_cb/execution.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -395,12 +396,13 @@ static int container_start_cb(const container_start_request *request, container_ goto pack_response; } + //容器启动准备 if (container_start_prepare(cont, request, stdinfd, stdout_handler, stderr_handler, &fifopath, fifos, &sync_fd, &thread_id) != 0) { cc = ISULAD_ERR_EXEC; goto pack_response; } - + //容器启动 if (start_container(cont, (const char **)fifos, true) != 0) { cc = ISULAD_ERR_EXEC; goto pack_response; diff --git a/src/daemon/executor/container_cb/execution_create.c b/src/daemon/executor/container_cb/execution_create.c index 05c0fd78b3b87ac82b924923fb1660ce5ca4c6c6..818885c73b4c909b6ff963598fbf4fa31b674b62 100644 --- a/src/daemon/executor/container_cb/execution_create.c +++ b/src/daemon/executor/container_cb/execution_create.c @@ -101,9 +101,12 @@ unlock_out: ret = -1; } out: - if (strcmp(name, "runc") == 0 || strcmp(name, "lcr") == 0 || strcmp(name, "kata-runtime") == 0) { + if (strcmp(name, "runc") == 0 || strcmp(name, "lcr") == 0) { + *runtime_res = true; + } + + if (strcmp(name, "kata-runtime") == 0) { *runtime_res = true; - return ret; } if (convert_v2_runtime(name, NULL) == 0) { diff --git a/src/daemon/executor/container_cb/execution_stream.c b/src/daemon/executor/container_cb/execution_stream.c index 4b6cdb1045646c6a70d8e2d4df4600240dae2f4d..7d165fb9d70738f015e6d4b348949e6ef8ba0cdb 100644 --- a/src/daemon/executor/container_cb/execution_stream.c +++ b/src/daemon/executor/container_cb/execution_stream.c @@ -719,12 +719,8 @@ static ssize_t extract_stream_to_io_read(void *content, void *buf, size_t buf_le struct isulad_copy_to_container_data copy = { 0 }; if (!stream->read_func(stream->reader, ©)) { - // Call gRPC ServerReaderWriter in grpc_copy_to_container_read_function, - // if stream->Read returns false, it means that the transmission has ended - // or the gRPC connection has been disconnected. If the gRPC connection exits - // due to an exception, gRPC will have an internal mechanism to ensure positioning - INFO("Streaming completed"); - return 0; + ERROR("Failed to read data from stream, grpc Client may exited"); + return -1; } if (copy.data_len > buf_len) { free(copy.data); diff --git a/src/daemon/executor/metrics_cb/CMakeLists.txt b/src/daemon/executor/metrics_cb/CMakeLists.txt deleted file mode 100644 index 6b08e0ee35e6c7927baad7c973abc6d10a4d0729..0000000000000000000000000000000000000000 --- a/src/daemon/executor/metrics_cb/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# get current directory sources files -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_metrics_srcs) - -set(METRICS_CB_SRCS - ${local_metrics_srcs} - PARENT_SCOPE - ) - -set(METRICS_CB_INCS - ${CMAKE_CURRENT_SOURCE_DIR} - PARENT_SCOPE - ) diff --git a/src/daemon/executor/metrics_cb/metrics_cb.c b/src/daemon/executor/metrics_cb/metrics_cb.c deleted file mode 100644 index 9d5ca7250c347f40e7826b3f5f9d2ec2bb5f05e4..0000000000000000000000000000000000000000 --- a/src/daemon/executor/metrics_cb/metrics_cb.c +++ /dev/null @@ -1,362 +0,0 @@ -/****************************************************************************** - * Copyright (c) KylinSoft Co., Ltd. 2021. 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: xiapin - * Create: 2021-08-17 - * Description: provide metric callback function - ******************************************************************************/ -#define _GNU_SOURCE -#include "metrics_cb.h" -#include -#include - -#include "callback.h" -#include "utils.h" -#include "isula_libutils/log.h" - -typedef enum { - COUNTER = 0, - GAUGE, - HISTOGRAM, - SUMMARY, - - METRIC_TYPE_BUTT, -} Isula_Metrics_Type; - -typedef struct isula_metrics { - /* To match request-url type, if url is null, default export. */ - const char *url; - /* The metric name */ - const char *name; - Isula_Metrics_Type metrics_type; - /* The metric help info */ - const char *descripe; - /* The metric data, the format is independent of the type */ - int (*metrics_data_get)(const char *name, char *buf, int size); -} isula_metrics_t; - -#define METRIC_RESPONSE_OK 200 -#define METRIC_RESPONSE_FAIL 401 - -#define ISULA_PREFIX "isula_" -#define HELP_HEAD "# HELP " -#define TYPE_HEAD "# TYPE " -#define METRICS_BUF_SIZE (1024 * 1024) - -/* metric name, no spaces allowed */ -#define METRICS_REQUEST_COUNT ISULA_PREFIX "metrics_http_req_count" -#define ISULA_DAEMON_MEM_STAT ISULA_PREFIX "daemon_mem_stat" -#define ISULA_CONT_MEM_STAT ISULA_PREFIX "container_mem_stat" -#define ISULA_CONT_CPU_STAT ISULA_PREFIX "container_cpu_stat" -#define ISULA_CONT_PIDS ISULA_PREFIX "container_pids" -#define DAEMON_CALLOC_TOTAL ISULA_PREFIX "daemon_calloced_memory_total" - -/* metric help info */ -static const char g_isula_daemon_mem_desc[] = "is isula daemon memory occupied"; -static const char g_mem_stat_desc[] = "is containers's memory occupied stats"; -static const char g_cpu_stat_desc[] = "is containers's cpu stats"; -static const char g_req_count_desc[] = "is metrics server accepted request count"; -static const char g_cont_pids_desc[] = "is containers's pid count"; -static const char g_daemon_calloc_desc[] = "is isula deamon calloced total"; - -static unsigned long long g_mem_alloced_total; - -const char *get_metric_name(Isula_Metrics_Type e) -{ - if (e < COUNTER || e >= METRIC_TYPE_BUTT) { - return NULL; - } - - const char *metric_type_name[] = { - "counter", - "gauge", - "histogram", - "summary", - }; - - return metric_type_name[e]; -} - -static int metrics_get_isulad_mem_stat(const char *name, char *buffer, int size) -{ - FILE *fp = NULL; - int vm_size = 0; - int vm_rss = 0; - int share_page = 0; - int text_size = 0; - int unused = 0; - int stack_size = 0; - - fp = util_fopen("/proc/self/statm", "r"); - if (fp == NULL) { - return -1; - } - - if (fscanf(fp, "%d %d %d %d %d %d %d", &vm_size, &vm_rss, &share_page, &text_size, - &unused, &stack_size, &unused) <= 0) { - fclose(fp); - return -1; - } - - int len = snprintf(buffer, size, - "%s{section=\"vmsize\"} %d\n" - "%s{section=\"vmrss\"} %d\n" - "%s{section=\"share_page\"} %d\n" - "%s{section=\"text_size\"} %d\n" - "%s{section=\"stack_size\"} %d\n", - name, vm_size * 4, name, vm_rss * 4, name, - share_page * 4, name, text_size * 4, name, stack_size * 4); - - fclose(fp); - - return len; -} - -static int metrics_get_container_info(container_stats_response **response) -{ - int ret = -1; - container_stats_request *request = NULL; - - if (response == NULL) { - goto out; - } - - request = (container_stats_request*)util_common_calloc_s(sizeof(container_stats_request)); - if (request == NULL) { - ERROR("Out of memory"); - goto out; - } - - ret = get_service_executor()->container.stats((const container_stats_request *)request, response); - - free(request); - -out: - return ret; -} - -static int metrics_containers_mem_stats(const char *name, char *buffer, int size) -{ - int ret = 0; - int i = 0; - int len = 0; - container_stats_response *response = NULL; - - if (metrics_get_container_info(&response) != 0 || response == NULL) { - ret = -1; - goto out; - } - - for (i = 0; i < response->container_stats_len; i++) { - len = snprintf(buffer + ret, size - ret, - "%s{container_id=\"%4.4s\",limit=\"%ld Kb\"} %ld\n", - name, response->container_stats[i]->id, response->container_stats[i]->mem_limit / 1024, - response->container_stats[i]->mem_used); - if (len < 0 || (size_t)len >= size - ret) { - break; - } - - ret += len; - } - - free_container_stats_response(response); - -out: - return ret; -} - -static float generate_cpu_info(container_info *stats, container_stats_response *old_stat) -{ - double cpu_percent = 0.0; - int i = 0; - unsigned long long d_sys_use = 0; - unsigned long long d_cpu_use = 0; - - for (i = 0; i < old_stat->container_stats_len; i++) { - if (strcmp(stats->id, old_stat->container_stats[i]->id) != 0) { - continue; - } - if (stats->cpu_system_use > old_stat->container_stats[i]->cpu_system_use) { - d_sys_use = stats->cpu_system_use - old_stat->container_stats[i]->cpu_system_use; - } - if (stats->cpu_use_nanos > old_stat->container_stats[i]->cpu_use_nanos) { - d_cpu_use = stats->cpu_use_nanos - old_stat->container_stats[i]->cpu_use_nanos; - } - - if (d_sys_use > 0 && stats->online_cpus > 0) { - cpu_percent = ((double)d_cpu_use / d_sys_use) * stats->online_cpus * 100; - } - break; - } - - return cpu_percent; -} - -static int metrics_containers_cpu_stats(const char *name, char *buffer, int size) -{ - int ret = 0; - int i = 0; - int len = 0; - container_stats_response *response = NULL; - static container_stats_response *old_stat = NULL; - - if (metrics_get_container_info(&response) != 0 || response == NULL) { - goto out; - } - - if (old_stat == NULL) { - old_stat = response; - goto out; - } - - for (i = 0; i < response->container_stats_len; i++) { - len = snprintf(buffer + ret, size - ret, "%s{container_id=\"%4.4s\"} %-10.2f\n", - name, response->container_stats[i]->id, - generate_cpu_info(response->container_stats[i], old_stat)); - if (len < 0 || (size_t)len >= size - ret) { - break; - } - - ret += len; - } - - free_container_stats_response(old_stat); - old_stat = response; - -out: - return ret; -} - -static int metrics_http_req_count_info(const char *name, char *buffer, int size) -{ - static unsigned int req_count = 0; - int len = 0; - - req_count++; - len = snprintf(buffer, size, "%s %u\n", name, req_count); - - return len; -} - -static int metrics_containers_pids(const char *name, char *buffer, int size) -{ - int ret = 0; - int i = 0; - int len = 0; - container_stats_response *response = NULL; - - if (metrics_get_container_info(&response) != 0 || response == NULL) { - goto out; - } - - for (i = 0; i < response->container_stats_len; i++) { - len = snprintf(buffer + ret, size - ret, - "%s{container_id=\"%4.4s\"} %ld\n", - name, response->container_stats[i]->id, response->container_stats[i]->pids_current); - if (len < 0 || (size_t)len >= size - ret) { - break; - } - - ret += len; - } - - free_container_stats_response(response); - -out: - return ret; -} - -void metrics_add_calloced_mem(unsigned size) -{ - g_mem_alloced_total += size; -} - -static int metrics_daemon_alloced_mem_total(const char *name, char *buffer, int size) -{ - static unsigned int req_count = 0; - int len = 0; - - len = snprintf(buffer, size, "%s %llu\n", name, g_mem_alloced_total); - req_count++; - - return len; -} - -static isula_metrics_t g_metrics[] = { - {NULL, METRICS_REQUEST_COUNT, COUNTER, g_req_count_desc, metrics_http_req_count_info}, /* export default */ - {"sys", ISULA_DAEMON_MEM_STAT, GAUGE, g_isula_daemon_mem_desc, metrics_get_isulad_mem_stat}, - {"mem", ISULA_CONT_MEM_STAT, GAUGE, g_mem_stat_desc, metrics_containers_mem_stats}, - {"cpu", ISULA_CONT_CPU_STAT, GAUGE, g_cpu_stat_desc, metrics_containers_cpu_stats}, - {"pids", ISULA_CONT_PIDS, GAUGE, g_cont_pids_desc, metrics_containers_pids}, - {"sys", DAEMON_CALLOC_TOTAL, COUNTER, g_daemon_calloc_desc, metrics_daemon_alloced_mem_total}, -}; - -static int metrics_msg_get_by_type(const char *url, char **metrics, int *len) -{ -#define E_SIZE (512 * 1024) - char *msg = NULL; - char *element = NULL; - int msg_len = 0; - int i = 0; - bool export_all = false; - - if (url == NULL) { - ERROR("invalid request url"); - return -1; - } - - export_all = !strcmp(url, "all"); - msg = (char *)util_common_calloc_s(METRICS_BUF_SIZE); - if (msg == NULL) { - ERROR("Out of memory"); - return -1; - } - - element = (char *)util_common_calloc_s(E_SIZE); - if (element == NULL) { - ERROR("Out of memory"); - free(msg); - return -1; - } - - for (i = 0; i < sizeof(g_metrics) / sizeof(g_metrics[0]); i++) { - if (g_metrics[i].metrics_data_get == NULL) { - continue; - } - - if (g_metrics[i].url != NULL && strcasestr(url, g_metrics[i].url) == NULL && !export_all) { - continue; - } - - if (g_metrics[i].metrics_data_get(g_metrics[i].name, element, E_SIZE) <= 0) { - continue; - } - int tmp = snprintf(msg + msg_len, METRICS_BUF_SIZE - msg_len, - HELP_HEAD "%s %s\n" - TYPE_HEAD "%s %s\n" - "%s\n", g_metrics[i].name, g_metrics[i].descripe, g_metrics[i].name, - get_metric_name(g_metrics[i].metrics_type), element); - if (tmp < 0 || (size_t)tmp >= METRICS_BUF_SIZE - msg_len) { - break; - } - msg_len += tmp; - } - - free(element); - *len = msg_len; - *metrics = msg; - return 0; -} - -void metrics_callback_init(service_metrics_callback_t *cb) -{ - cb->export_metrics_by_type = metrics_msg_get_by_type; -} diff --git a/src/daemon/modules/CMakeLists.txt b/src/daemon/modules/CMakeLists.txt index c5b6987cde50edbbb1eb292253333900a752e113..28dcd3cbf73ccc82dec7c3ee3977f16c8f3e5309 100644 --- a/src/daemon/modules/CMakeLists.txt +++ b/src/daemon/modules/CMakeLists.txt @@ -12,6 +12,7 @@ add_subdirectory(events_sender) add_subdirectory(service) add_subdirectory(api) add_subdirectory(volume) +add_subdirectory(checkpoint) set(local_modules_srcs ${modules_top_srcs} @@ -25,6 +26,7 @@ set(local_modules_srcs ${EVENTS_SENDER_SRCS} ${SERVICE_SRCS} ${VOLUME_SRCS} + ${CHECKPOINT_SRCS} ) set(local_modules_incs @@ -40,6 +42,7 @@ set(local_modules_incs ${SERVICE_INCS} ${MODULES_API_INCS} ${VOLUME_INCS} + ${CHECKPOINT_INCS} ) set(MODULES_SRCS diff --git a/src/daemon/modules/api/checkpoint_api.h b/src/daemon/modules/api/checkpoint_api.h new file mode 100644 index 0000000000000000000000000000000000000000..dfa359ea0fd6847ab9bbe8a0855801968cc00126 --- /dev/null +++ b/src/daemon/modules/api/checkpoint_api.h @@ -0,0 +1,34 @@ +#ifndef DAEMON_MODULES_API_CHECKPOINT_API_H +#define DAEMON_MODULES_API_CHECKPOINT_API_H + +#include +#ifdef __cplusplus +extern "C" { +#endif + +struct checkpoint { + char *dir; + char *name; +}; + +struct checkpoints { + struct checkpoint **ches; + size_t ches_len; +}; + + + +int checkpoint_create(char* container,char* dir); + +int checkpoint_restore(char* container,char* dir); + +int checkpoint_remove(char* container,char* dir); + +struct checkpoints* checkpoint_list(char* dir); + + +#ifdef __cplusplus +} +#endif + +#endif // DAEMON_MODULES_API_CHECKPOINT_API_H diff --git a/src/daemon/modules/checkpoint/CMakeLists.txt b/src/daemon/modules/checkpoint/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1012035591139ea62900e0e7744ddb789e6247bf --- /dev/null +++ b/src/daemon/modules/checkpoint/CMakeLists.txt @@ -0,0 +1,12 @@ +# get current directory sources files +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_checkpoint_srcs) + +set(CHECKPOINT_SRCS + ${local_checkpoint_srcs} + PARENT_SCOPE + ) + +set(CHECKPOINT_INCS + ${CMAKE_CURRENT_SOURCE_DIR} + PARENT_SCOPE + ) \ No newline at end of file diff --git a/src/daemon/modules/checkpoint/checkpoint.c b/src/daemon/modules/checkpoint/checkpoint.c new file mode 100644 index 0000000000000000000000000000000000000000..efc784cd285260a22da96e6d34deabfa5477a6ba --- /dev/null +++ b/src/daemon/modules/checkpoint/checkpoint.c @@ -0,0 +1,306 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "isula_libutils/log.h" +#include "volume_api.h" +#include "utils.h" +#include "map.h" +#include "local.h" +#include "err_msg.h" +#include "utils_file.h" +#include +#include "container_api.h" +#include "image_api.h" +#include "checkpoint_api.h" + +/* + * 根据容器Id,checkpoint Id,以及checkpoint路径去创建一个checkpoint + */ + +//判断是否为目录 +bool is_dir(const char *path) +{ + struct stat statbuf; + if(lstat(path, &statbuf) ==0)//lstat返回文件的信息,文件信息存放在stat结构中 + { + return S_ISDIR(statbuf.st_mode) != 0;//S_ISDIR宏,判断文件类型是否为目录 + } + return false; +} + +//判断是否为常规文件 +bool is_file(const char *path) +{ + struct stat statbuf; + if(lstat(path, &statbuf) ==0) + return S_ISREG(statbuf.st_mode) != 0;//判断文件是否为常规文件 + return false; +} + +//判断是否是特殊目录 +bool is_special_dir(const char *path) +{ + return strcmp(path, ".") == 0 || strcmp(path, "..") == 0; +} + +//生成完整的文件路径 +void get_file_path(const char *path, const char *file_name, char *file_path) +{ + strcpy(file_path, path); + if(file_path[strlen(path) - 1] != '/') + strcat(file_path, "/"); + strcat(file_path, file_name); +} + +int delete_file(const char *path) +{ + printf(" delete_file\n"); + DIR *dir; + struct dirent *dir_info; + char file_path[1000]; + + if(is_file(path)) + { + remove(path); + return 0; + }else if(is_dir(path)) + { + if((dir = opendir(path)) == NULL) + return -1; + + while((dir_info = readdir(dir)) != NULL) + { + get_file_path(path, dir_info->d_name, file_path); + if(is_special_dir(dir_info->d_name)) + continue; + delete_file(file_path); + rmdir(file_path); + } + rmdir(path); + }else{ + return -1; + } + return 0; +} +int checkpoint_remove(char* container,char* dir) +{ + + if(!dir){ + dir="/tmp/isula-criu/"; + } + char checkpoint_path[1000]={0}; + strcat(checkpoint_path,dir); + strcat(checkpoint_path,container); + + if(delete_file(checkpoint_path)!=0){ + printf("sdelete fail\n"); + isulad_set_error_message("Checkpointing remove %s failed",container); + return -1; + } + printf("delete success\n"); + return 0; +} + + + +int checkpoint_create(char* container,char* dir) +{ + + struct lxc_container *c; + c=lxc_container_new(container,"/var/lib/isulad/engines/lcr/"); + //无法获取容器 + if (!c) { + isulad_set_error_message("System error loading %s\n", container); + return -1; + } + //容器未定义 + if (!c->is_defined(c)) { + isulad_set_error_message("(deamon modules)Error response from daemon: No such container:%s\n",container); + return -1; + } + //容器未运行 + if (!c->is_running(c)) { + isulad_set_error_message("%s not running, not checkpointing\n", container); + return -1; + } + + //如果自定义了路径就使用自定义路径,否则使用默认路径 + if(!dir){ + dir="/tmp/isula-criu/"; + } + + char checkpoint_path[1000]={0}; + strcat(checkpoint_path,dir); + strcat(checkpoint_path,container); + bool res; +printf("checkpoint_path:%s\n",checkpoint_path); + res = c->checkpoint(c,checkpoint_path,true,false); + + if(!res){ + printf("checkpoint_path:%s\n",checkpoint_path); + isulad_set_error_message("Checkpointing %s failed",container); + return -1; + } + return 0; +} + +int checkpoint_restore(char* container,char* dir) +{ + container_t *cont=NULL; + cont = containers_store_get(container); + im_mount_container_rootfs(cont->common_config->image_type, cont->common_config->image, container); + struct lxc_container *c; + c=lxc_container_new(container,"/var/lib/isulad/engines/lcr/"); + if (!c) { + isulad_set_error_message("System error loading %s\n", container); + return -1; + } + if (!c->is_defined(c)) { + isulad_set_error_message("Error response from daemon: No such container:%s\n", container); + return -1; + } + if (c->is_running(c)) { + isulad_set_error_message("%s is running, not restoring\n", container); + return -1; + } + + if(!dir){ + dir="/tmp/isula-criu/"; + } + + char checkpoint_path[1000]={0}; + strcat(checkpoint_path,dir); + strcat(checkpoint_path,container); + bool res; + + res = c->restore(c,checkpoint_path,true); + + + if (!res){ + isulad_set_error_message("Restoring %s failed\n",container); + return -1; + } + + pid_ppid_info_t pid_info = { 0 }; + container_state_set_running(cont->state, &pid_info, true); + container_state_reset_has_been_manual_stopped(cont->state); + container_init_health_monitor(cont->common_config->id); + if (container_state_to_disk(cont)) { + isulad_set_error_message("Failed to save container \"%s\" to disk", cont->common_config->id); + return -1; + } + + return 0; +} + +static struct checkpoints *new_empty_checkpoints(int size) +{ + struct checkpoints *ches = NULL; + + ches = util_common_calloc_s(sizeof(struct checkpoints)); + if (ches == NULL) { + ERROR("out of memory"); + return NULL; + } + + if (size == 0) { + return ches; + } + + ches->ches = util_common_calloc_s(sizeof(struct checkpoint*) * size); + if (ches->ches == NULL) { + ERROR("out of memory"); + free(ches); + return NULL; + } + + return ches; +} + +static struct checkpoint * dup_checkpoint(char *name, char *dir) +{ + struct checkpoint *che = NULL; + + che = util_common_calloc_s(sizeof(struct checkpoint)); + if (che == NULL) { + ERROR("out of memory"); + return NULL; + } + + che->dir = util_strdup_s(dir); + che->name = util_strdup_s(name); + return che; +} + + +struct checkpoints * checkpoint_list(char* dir){ + + + struct checkpoints *ches = NULL; + DIR *dirp; + struct dirent *dp; + if(!dir){ + dir="/tmp/isula-criu/"; + } + dirp=opendir(dir); + if(dirp==NULL){ + isulad_set_error_message("checkpoint_dir is NULL"); + return NULL; + } + + + int sum=0; + while((dp=readdir(dirp))!=NULL){ + if(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0){ + continue; + } + if(containers_store_get(dp->d_name)==NULL){ + continue; + } + sum++; + printf("%s\n",dp->d_name); + } + + + ches = new_empty_checkpoints(sum); + + if (ches == NULL) { + ERROR("out of memory"); + return NULL; + } + + + dirp=opendir(dir); + + while((dp=readdir(dirp))!=NULL){ + if(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0){ + continue; + } + if(containers_store_get(dp->d_name)==NULL){ + continue; + } + sum++; + + struct checkpoint *che = dup_checkpoint(dp->d_name,dir); + if (che == NULL) { + ERROR("out of memory"); + goto out; + } + ches->ches[ches->ches_len] = che; + ches->ches_len++; + } + + +out: + (void)closedir(dirp); + return ches; +} + + + diff --git a/src/daemon/modules/events/collector.c b/src/daemon/modules/events/collector.c index d9068747efd17f5738e6a9a673fd5054d6a86a09..1a86735491c6df3d3b64aba9b1d069881f344fb5 100644 --- a/src/daemon/modules/events/collector.c +++ b/src/daemon/modules/events/collector.c @@ -246,7 +246,7 @@ static int supplement_exitcode_for_container_msg(const container_t *cont, const return 0; } - nret = snprintf(info, sizeof(info), "exitCode=%d", exit_code); + nret = snprintf(info, sizeof(info), "exitCode=%u", exit_code); if (nret < 0 || nret >= sizeof(info)) { return -1; } diff --git a/src/daemon/modules/image/CMakeLists.txt b/src/daemon/modules/image/CMakeLists.txt index 86b7d8a6ff5ad0cec9185e3f42628c48c93d10f3..00a096e3bbfa1ed25b6083e31f8687800ffa6ea4 100644 --- a/src/daemon/modules/image/CMakeLists.txt +++ b/src/daemon/modules/image/CMakeLists.txt @@ -96,8 +96,7 @@ target_link_libraries(${LIB_ISULAD_IMG} ${DEVMAPPER_LIBRARY} ${LIBTAR_LIBRARY} ${SELINUX_LIBRARY} - ${LIBARCHIVE_LIBRARY} - -lpthread -lcrypto -lz libhttpclient) + -lpthread -lcrypto -larchive -lz libhttpclient) target_compile_definitions(${LIB_ISULAD_IMG} PRIVATE LIB_ISULAD_IMG_SO) diff --git a/src/daemon/modules/image/oci/oci_image.c b/src/daemon/modules/image/oci/oci_image.c index 036b50cda9cf8b7290e0dcb73de7302b992fa5c3..c0e8110537bdcfcc077e06d48f3b2ea0826835f7 100644 --- a/src/daemon/modules/image/oci/oci_image.c +++ b/src/daemon/modules/image/oci/oci_image.c @@ -526,9 +526,9 @@ int oci_tag(const im_tag_request *request) goto out; } dest_name = oci_normalize_image_name(request->dest_name.image); - if (dest_name == NULL) { + if (src_name == NULL) { ret = -1; - ERROR("Failed to resolve dest image name"); + ERROR("Failed to resolve source image name"); goto out; } diff --git a/src/daemon/modules/image/oci/registry/registry.c b/src/daemon/modules/image/oci/registry/registry.c index 52ad7bb5c586a7a177477443252fd5bfaf7d1739..cc5f680581c71483f1196dcf3dda6522089b7d12 100644 --- a/src/daemon/modules/image/oci/registry/registry.c +++ b/src/daemon/modules/image/oci/registry/registry.c @@ -1813,30 +1813,16 @@ out: static void update_host(pull_descriptor *desc) { - size_t i = 0; - isulad_daemon_constants *config = get_isulad_daemon_constants(); - json_map_string_string *registry_transformation = NULL; - - if (desc == NULL || config == NULL) { + if (desc == NULL) { ERROR("Invalid NULL param"); return; } - registry_transformation = config->registry_transformation; - if (registry_transformation == NULL) { - return; - } - - // replace specific registry to another due to compatability reason - for (i = 0; i < registry_transformation->len; i++) { - if (registry_transformation->keys[i] == NULL || registry_transformation->values[i] == NULL) { - continue; - } - if (strcmp(desc->host, registry_transformation->keys[i]) == 0) { - free(desc->host); - desc->host = util_strdup_s(registry_transformation->values[i]); - break; - } + // registry-1.docker.io is the real docker.io's registry. index.docker.io is V1 registry, we do not support + // V1 registry, try use registry-1.docker.io. + if (!strcmp(desc->host, DOCKER_HOSTNAME) || !strcmp(desc->host, DOCKER_V1HOSTNAME)) { + free(desc->host); + desc->host = util_strdup_s(DOCKER_REGISTRY); } return; diff --git a/src/daemon/modules/image/oci/storage/image_store/image_store.c b/src/daemon/modules/image/oci/storage/image_store/image_store.c index d295611439c4e57720689d4a13b50059c5f0cdd7..9db158d4c034a93ce2d94882055115daa0ad0a38 100644 --- a/src/daemon/modules/image/oci/storage/image_store/image_store.c +++ b/src/daemon/modules/image/oci/storage/image_store/image_store.c @@ -2887,11 +2887,11 @@ static int do_append_image(storage_image *im) return 0; } -static void strip_host_prefix(char **name) +static void strip_dockerio_prefix(char **name) { char *new_image_name = NULL; - new_image_name = oci_strip_host_prefix(*name); + new_image_name = oci_strip_dockerio_prefix(*name); if (new_image_name == NULL) { return; } @@ -2902,64 +2902,23 @@ static void strip_host_prefix(char **name) return; } -static int deduplicate_names(storage_image *im) -{ - char **unique_names = NULL; - size_t unique_names_len = 0; - - if (im == NULL) { - ERROR("invalid NULL param"); - return -1; - } - - if (im->names_len == 0) { - return 0; - } - - if (util_string_array_unique((const char **)im->names, im->names_len, &unique_names, &unique_names_len) != 0) { - ERROR("Failed to unique names"); - return -1; - } - - util_free_array_by_len(im->names, im->names_len); - im->names = unique_names; - im->names_len = unique_names_len; - - return 0; -} - static int strip_default_hostname(storage_image *im) { int ret = 0; size_t i = 0; bool striped = false; - char *hostname_to_strip = NULL; - - hostname_to_strip = get_hostname_to_strip(); - if (hostname_to_strip == NULL) { - return 0; - } for (i = 0; i < im->names_len; i++) { - if (util_has_prefix(im->names[i], hostname_to_strip) || util_has_prefix(im->names[i], REPO_PREFIX_TO_STRIP)) { - strip_host_prefix(&im->names[i]); + if (util_has_prefix(im->names[i], HOSTNAME_TO_STRIP) || util_has_prefix(im->names[i], REPO_PREFIX_TO_STRIP)) { + strip_dockerio_prefix(&im->names[i]); striped = true; } } - if (deduplicate_names(im) != 0) { - ret = -1; - goto out; - } - if (striped) { ret = save_image(im); } -out: - - free(hostname_to_strip); - return ret; } diff --git a/src/daemon/modules/image/oci/utils_images.c b/src/daemon/modules/image/oci/utils_images.c index 415f2004bf0f2a4fc6c5a5d4f9886c214952fc0c..ece37d2ec7958844f8dbe4bd7c22aaea03debd3e 100644 --- a/src/daemon/modules/image/oci/utils_images.c +++ b/src/daemon/modules/image/oci/utils_images.c @@ -168,14 +168,14 @@ char *oci_add_host(const char *host, const char *name) return with_host; } -// normalize strip the prefix if necessary +// normalize strip the docker.io/library prefix if necessary // and add default latest tag if no tag found char *oci_normalize_image_name(const char *name) { char *with_tag = oci_default_tag(name); char *result = NULL; - result = oci_strip_host_prefix(with_tag); + result = oci_strip_dockerio_prefix(with_tag); free(with_tag); return result; @@ -220,53 +220,24 @@ int oci_split_image_name(const char *image_name, char **host, char **name, char return 0; } -char *get_hostname_to_strip() -{ - char *name = NULL; - - isulad_daemon_constants *config = get_isulad_daemon_constants(); - if (config == NULL || config->default_host == NULL) { - return NULL; - } - - name = (char *)util_common_calloc_s(strlen(config->default_host) + 2); // +2 means "/" and "\0" - if (name == NULL) { - ERROR("out of memory"); - return NULL; - } - - (void)strcat(name, config->default_host); - (void)strcat(name, "/"); - - return name; -} - -char *oci_strip_host_prefix(const char *name) +char *oci_strip_dockerio_prefix(const char *name) { const char *striped = name; - char *hostname_to_strip = NULL; if (name == NULL) { ERROR("NULL image name"); return NULL; } - hostname_to_strip = get_hostname_to_strip(); - if (hostname_to_strip == NULL) { - return util_strdup_s(name); - } - - // Strip host prefix - if (util_has_prefix(name, hostname_to_strip)) { - striped += strlen(hostname_to_strip); + // Strip docker.io/ + if (util_has_prefix(name, HOSTNAME_TO_STRIP)) { + striped += strlen(HOSTNAME_TO_STRIP); } // Strip library/ if (util_has_prefix(striped, REPO_PREFIX_TO_STRIP)) { striped += strlen(REPO_PREFIX_TO_STRIP); } - free(hostname_to_strip); - return util_strdup_s(striped); } diff --git a/src/daemon/modules/image/oci/utils_images.h b/src/daemon/modules/image/oci/utils_images.h index 2fa8b29dc16d55af8f65a37868d3551715945f7c..4e13c76cebabbd80345a7502be8bd3b602ec8c76 100644 --- a/src/daemon/modules/image/oci/utils_images.h +++ b/src/daemon/modules/image/oci/utils_images.h @@ -35,6 +35,7 @@ extern "C" { #define HTTP_PREFIX "http://" #define DEFAULT_TAG ":latest" +#define HOSTNAME_TO_STRIP "docker.io/" #define REPO_PREFIX_TO_STRIP "library/" #define MAX_ID_BUF_LEN 256 @@ -44,7 +45,7 @@ char *oci_default_tag(const char *name); char *oci_add_host(const char *domain, const char *name); char *oci_normalize_image_name(const char *name); int oci_split_image_name(const char *image_name, char **host, char **name, char **tag); -char *oci_strip_host_prefix(const char *name); +char *oci_strip_dockerio_prefix(const char *name); char *make_big_data_base_name(const char *key); char *oci_calc_diffid(const char *file); void free_items_not_inherit(docker_image_config_v2 *config); @@ -54,7 +55,6 @@ bool oci_valid_time(char *time); char *oci_get_isulad_tmpdir(const char *root_dir); int makesure_isulad_tmpdir_perm_right(const char *root_dir); -char *get_hostname_to_strip(); #ifdef __cplusplus } diff --git a/src/daemon/modules/runtime/isula/isula_rt_ops.c b/src/daemon/modules/runtime/isula/isula_rt_ops.c index 42f1cda6672921b17e89c6bf82be5abc454988fd..d3ac4643c1eb3a9dc5a4e25b665a235e4503322e 100644 --- a/src/daemon/modules/runtime/isula/isula_rt_ops.c +++ b/src/daemon/modules/runtime/isula/isula_rt_ops.c @@ -1094,7 +1094,7 @@ int rt_isula_exec(const char *id, const char *runtime, const rt_exec_params_t *p p.isulad_stdin = (char *)params->console_fifos[0]; p.isulad_stdout = (char *)params->console_fifos[1]; p.isulad_stderr = (char *)params->console_fifos[2]; - p.resize_fifo = resize_fifo_dir; + p.exit_fifo = resize_fifo_dir; p.runtime_args = (char **)runtime_args; p.runtime_args_len = runtime_args_len; copy_process(&p, process); @@ -1281,7 +1281,7 @@ int rt_isula_exec_resize(const char *id, const char *runtime, const rt_exec_resi return -1; } - if (snprintf(data, sizeof(data), "%u %u", params->width, params->height) < 0) { + if (snprintf(data, sizeof(data), "%d %d", params->width, params->height) < 0) { ERROR("failed to write resize data"); return -1; } diff --git a/src/daemon/modules/service/service_container.c b/src/daemon/modules/service/service_container.c index d994a8325d9ed224a3848c065a5fc8672d320736..1a471374234170f855c9f9b3fa287a1d50b06d17 100644 --- a/src/daemon/modules/service/service_container.c +++ b/src/daemon/modules/service/service_container.c @@ -60,6 +60,8 @@ #include "utils_verify.h" #include "volume_api.h" +#include + #define KATA_RUNTIME "kata-runtime" int set_container_to_removal(const container_t *cont) @@ -658,9 +660,39 @@ static int verify_mounts(const container_t *cont) return 0; } - +/* +static int checkpoint_restore_container(char* container){ + struct lxc_container *c; + c=lxc_container_new(container,"/var/lib/isulad/engines/lcr/"); + if (!c) { + printf("System error loading %s\n", container); + return 0; + } + if (!c->is_defined(c)) { + printf("Error response from daemon: No such container:%s\n", container); + return 0; + } + if (c->is_running(c)) { + printf("%s is running, not restoring\n", container); + return 0; + } + char checkpoint_dir[1000]="/tmp/isula-criu/"; + strcat(checkpoint_dir,container); + bool res; + + res = c->restore(c,checkpoint_dir,false); + if (!res){ + printf("Restoring %s failed\n",args->name); + }else{ + printf("%s\n",args->name); + } + + return res; +} +*/ static int do_start_container(container_t *cont, const char *console_fifos[], bool reset_rm, pid_ppid_info_t *pid_info) { + printf("do_start_container\n"); int ret = 0; int nret = 0; int exit_fifo_fd = -1; @@ -726,12 +758,48 @@ static int do_start_container(container_t *cont, const char *console_fifos[], bo goto close_exit_fd; } + //挂载文件系统 nret = im_mount_container_rootfs(cont->common_config->image_type, cont->common_config->image, id); + printf("容器挂在文件系统:%d\n",nret); + //return ret; if (nret != 0) { ERROR("Failed to mount rootfs for container %s", id); ret = -1; goto close_exit_fd; } +/* + //restore流程 + struct lxc_container *c; + //char *container = id; + c=lxc_container_new(id,"/var/lib/isulad/engines/lcr/"); + if (!c) { + + printf("System error loading %s\n", id); + + } + if (!c->is_defined(c)) { + printf("Error response from daemon: No such container:%s\n", id); + + } + if (c->is_running(c)) { + printf("%s is running, not restoring\n", id); + + } + char checkpoint_dir[1000]="/tmp/isula-criu/"; + strcat(checkpoint_dir,c->name); + bool res; + res = c->restore(c,checkpoint_dir,false); + + if(!res){ + printf("restore fail\n"); + } + if(res){ + printf("restore success\n"); + }*/ + //goto close_exit_fd; + + //restore + //checkpoint_restore_container(cont) // embedded conainter is readonly, create mtab link will fail // kata-runtime container's qemu donot support to create mtab in host @@ -879,12 +947,14 @@ int start_container(container_t *cont, const char *console_fifos[], bool reset_r } ret = do_start_container(cont, console_fifos, reset_rm, &pid_info); + if (ret != 0) { ERROR("Runtime start container failed"); ret = -1; goto set_stopped; } else { container_state_set_running(cont->state, &pid_info, true); + //return ret; container_state_reset_has_been_manual_stopped(cont->state); container_init_health_monitor(cont->common_config->id); goto save_container; diff --git a/src/daemon/modules/volume/volume.c b/src/daemon/modules/volume/volume.c index 9d496594be41fbe93adca529144fbd219ad5f970..45e82cdc096dca82c7cccf68a6b652cc08064dcc 100644 --- a/src/daemon/modules/volume/volume.c +++ b/src/daemon/modules/volume/volume.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "isula_libutils/log.h" #include "volume_api.h" @@ -472,11 +473,13 @@ out: struct volumes * volume_list(void) { + struct volumes *vols = NULL; mutex_lock(&g_vs.mutex); vols = list_all_driver_volumes(); mutex_unlock(&g_vs.mutex); + ERROR("struct volumes * volume_list(void)\n"); return vols; } @@ -639,6 +642,7 @@ void free_volume(struct volume *vol) void free_volumes(struct volumes *vols) { + size_t i = 0; if (vols == NULL) { return; diff --git a/src/utils/.DS_Store b/src/utils/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..02241848cb0c7500445d1bc8d917cd224ff6f7a8 Binary files /dev/null and b/src/utils/.DS_Store differ diff --git a/src/utils/cutils/utils.c b/src/utils/cutils/utils.c index f037b06088e2f0a6456ecc8d7bc8822ee6d9bc35..a3e192fe1ea0399ed59adb2b47309615973324fe 100644 --- a/src/utils/cutils/utils.c +++ b/src/utils/cutils/utils.c @@ -1362,7 +1362,7 @@ int util_normalized_host_os_arch(char **host_os, char **host_arch, char **host_v *host_arch = util_strdup_s("arm64"); } else if ((strcasecmp("armhf", uts.machine) == 0) || (strcasecmp("armel", uts.machine) == 0)) { *host_arch = util_strdup_s("arm"); - } else if ((strcasecmp("mips64le", uts.machine) == 0) || (strcasecmp("mips64el", uts.machine) == 0)) { + } else if ((strcasecmp("mips64le", uts.machine) == 0) || (strcasecmp("mips64el", uts.machine) == 0)) { *host_arch = util_strdup_s("mips64le"); } else { *host_arch = util_strdup_s(uts.machine); diff --git a/src/utils/cutils/utils_string.c b/src/utils/cutils/utils_string.c index 7e5043264828a1865589282353bb87c1d19fa94c..01d5d9ead020f00d92d963779dd1d4d9d74722db 100644 --- a/src/utils/cutils/utils_string.c +++ b/src/utils/cutils/utils_string.c @@ -463,6 +463,7 @@ err_out: const char *util_str_skip_str(const char *str, const char *skip) { + //printf("%s,%s\n",str,skip); if (str == NULL || skip == NULL) { return NULL; } diff --git a/src/utils/http/http.c b/src/utils/http/http.c index 2a8ccee6cd263d00be935ce96c423625309e14d6..0dcbcd513e3e92803fa45cd51bfc4a21f664268a 100644 --- a/src/utils/http/http.c +++ b/src/utils/http/http.c @@ -429,10 +429,7 @@ int http_request(const char *url, struct http_get_options *options, long *respon /* provide a buffer to store errors in */ curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, errbuf); curl_easy_setopt(curl_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); - /* libcurl support option CURLOPT_SUPPRESS_CONNECT_HEADERS when version >= 7.54.0 - * #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) - * CURL_VERSION_BITS(7,54,0) = 0x073600 */ -#if (LIBCURL_VERSION_NUM >= 0x073600) +#if defined(CURLOPT_SUPPRESS_CONNECT_HEADERS) curl_easy_setopt(curl_handle, CURLOPT_SUPPRESS_CONNECT_HEADERS, 1L); #endif diff --git a/src/utils/http/mediatype.h b/src/utils/http/mediatype.h index ff04b4d1d557f8f791861a53dad033234487afda..72b99b6edf5a956a41af8378c2795314b95a4a89 100644 --- a/src/utils/http/mediatype.h +++ b/src/utils/http/mediatype.h @@ -67,6 +67,9 @@ #define MediaTypeJson "application/json" +#define DOCKER_HOSTNAME "docker.io" +#define DOCKER_V1HOSTNAME "index.docker.io" +#define DOCKER_REGISTRY "registry-1.docker.io" #define DOCKER_MANIFEST_SCHEMA2_JSON "application/vnd.docker.distribution.manifest.v2+json" #define DOCKER_MANIFEST_SCHEMA2_LIST "application/vnd.docker.distribution.manifest.list.v2+json" #define DOCKER_MANIFEST_SCHEMA1_JSON "application/vnd.docker.distribution.manifest.v1+json" diff --git a/src/utils/tar/util_archive.c b/src/utils/tar/util_archive.c index 7d64e3aac35532cfe80489f0043fe40b17709f0c..a75220364372c3d72e00e26cb9f55d321fb5ab27 100644 --- a/src/utils/tar/util_archive.c +++ b/src/utils/tar/util_archive.c @@ -649,7 +649,7 @@ child_out: ret = util_wait_for_pid(pid); if (ret != 0) { - ERROR("Wait archive_untar_handler failed with error:%s", strerror(errno)); + ERROR("Wait archive_untar_handler failed"); fcntl(pipe_stderr[0], F_SETFL, O_NONBLOCK); if (read(pipe_stderr[0], errbuf, BUFSIZ) < 0) { ERROR("read error message from child failed"); diff --git a/test/.DS_Store b/test/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a6bc27cd0de3aa6ad8e16fbe3e299ea6da2cf501 Binary files /dev/null and b/test/.DS_Store differ diff --git a/test/cmd/.DS_Store b/test/cmd/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2be367865a2fdd1f4f35eb8ffd1944b2f3a9bc76 Binary files /dev/null and b/test/cmd/.DS_Store differ diff --git a/test/cutils/.DS_Store b/test/cutils/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..be9f935d9a7ac49e5a28bb199307984adb146194 Binary files /dev/null and b/test/cutils/.DS_Store differ diff --git a/test/image/oci/registry/CMakeLists.txt b/test/image/oci/registry/CMakeLists.txt index 9ff075db55adefd7ae6e84bd9bf5cba223bc0022..cfc7da8736f8005825a9e8a886f1d38db3a0a063 100644 --- a/test/image/oci/registry/CMakeLists.txt +++ b/test/image/oci/registry/CMakeLists.txt @@ -32,8 +32,6 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry/certs.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry/auths.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry/aes.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/config/isulad_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/config/daemon_arguments.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks/storage_mock.cc ${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks/oci_image_mock.cc ${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks/http_mock.cc diff --git a/test/mocks/isulad_config_mock.cc b/test/mocks/isulad_config_mock.cc index a333c17687137b3933d7f23557129e83b4a46cec..82729263b8d0ebc685ad7aa859a1e56c9cc43888 100644 --- a/test/mocks/isulad_config_mock.cc +++ b/test/mocks/isulad_config_mock.cc @@ -15,8 +15,6 @@ #include "isulad_config_mock.h" -static isulad_daemon_constants g_isulad_daemon_constants = {0}; - namespace { MockIsuladConf *g_isulad_conf_mock = nullptr; } @@ -154,19 +152,3 @@ bool conf_get_use_decrypted_key_flag() } return true; } - -int init_isulad_daemon_constants() -{ - if (g_isulad_conf_mock != nullptr) { - return g_isulad_conf_mock->InitIsuladDaemonConstants(); - } - return 0; -} - -isulad_daemon_constants *get_isulad_daemon_constants() -{ - if (g_isulad_conf_mock != nullptr) { - return g_isulad_conf_mock->GetIsuladDaemonConstants(); - } - return &g_isulad_daemon_constants; -} diff --git a/test/mocks/isulad_config_mock.h b/test/mocks/isulad_config_mock.h index b91b54653a9357ad08fd0e04243d55393744e7db..03af3cc95f0d65650943bd4b0cc5ff6a22bd6949 100644 --- a/test/mocks/isulad_config_mock.h +++ b/test/mocks/isulad_config_mock.h @@ -18,7 +18,6 @@ #include #include "isulad_config.h" -#include "isula_libutils/isulad_daemon_constants.h" class MockIsuladConf { public: @@ -37,8 +36,6 @@ public: MOCK_METHOD0(GetMonitordPath, char *(void)); MOCK_METHOD0(ConfGetISuladRootDir, char *(void)); MOCK_METHOD0(ConfGetUseDecryptedKeyFlag, bool (void)); - MOCK_METHOD0(InitIsuladDaemonConstants, int (void)); - MOCK_METHOD0(GetIsuladDaemonConstants, isulad_daemon_constants * (void)); }; void MockIsuladConf_SetMock(MockIsuladConf *mock); diff --git a/test/runtime/.DS_Store b/test/runtime/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e2288114dfa259e61af8ecf7794ba69263355191 Binary files /dev/null and b/test/runtime/.DS_Store differ diff --git a/test/specs/.DS_Store b/test/specs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..89956a15a22787976fd21e926513cbcf367af2f8 Binary files /dev/null and b/test/specs/.DS_Store differ