From 2556c6e04c83958a5f0681f9228a8f25054247b4 Mon Sep 17 00:00:00 2001 From: dogsheng <960055655@qq.com> Date: Wed, 25 Dec 2019 15:50:34 +0800 Subject: [PATCH] Package init --- CMakeLists.txt | 32 +- README.md | 8 - cmake/options.cmake | 2 +- docs/developer_guide.md | 81 -- docs/install_guide.md | 180 --- docs/limitations.md | 0 iSulad.spec | 6 +- lcrd.pc.in | 2 +- src/CMakeLists.txt | 28 +- src/api/image_client/isula_image.proto | 541 +++++++++ src/api/services/containers/container.proto | 16 + .../services/containers/rest/container.rest.h | 1 + src/api/services/cri/api.proto | 194 ++- src/api/services/health/health.proto | 14 + src/api/services/images/images.proto | 16 +- src/api/services/images/rest/image.rest.h | 1 + src/api/types/descriptor.proto | 14 + src/cmd/commander.h | 1 + src/cmd/lcrc/arguments.c | 6 +- src/cmd/lcrc/arguments.h | 11 +- src/cmd/lcrc/base/create.c | 183 ++- src/cmd/lcrc/base/create.h | 3 + src/cmd/lcrc/base/kill.c | 1 + src/cmd/lcrc/base/kill.h | 1 + src/cmd/lcrc/base/rename.c | 1 + src/cmd/lcrc/base/rename.h | 1 + src/cmd/lcrc/base/restart.c | 1 + src/cmd/lcrc/base/restart.h | 1 + src/cmd/lcrc/base/rm.h | 1 + src/cmd/lcrc/base/run.c | 2 +- src/cmd/lcrc/base/run.h | 1 + src/cmd/lcrc/base/start.h | 1 + src/cmd/lcrc/base/stop.c | 1 + src/cmd/lcrc/base/stop.h | 1 + src/cmd/lcrc/commands.h | 1 + src/cmd/lcrc/extend/events.c | 1 + src/cmd/lcrc/extend/events.h | 1 + src/cmd/lcrc/extend/export.c | 3 +- src/cmd/lcrc/extend/export.h | 3 +- src/cmd/lcrc/extend/pause.c | 1 + src/cmd/lcrc/extend/pause.h | 1 + src/cmd/lcrc/extend/resume.c | 5 +- src/cmd/lcrc/extend/resume.h | 1 + src/cmd/lcrc/extend/stats.h | 1 + src/cmd/lcrc/extend/update.c | 1 + src/cmd/lcrc/extend/update.h | 1 + src/cmd/lcrc/images/images.c | 98 +- src/cmd/lcrc/images/images.h | 3 +- src/cmd/lcrc/images/load.h | 3 +- src/cmd/lcrc/images/login.c | 2 +- src/cmd/lcrc/images/login.h | 3 +- src/cmd/lcrc/images/logout.c | 2 +- src/cmd/lcrc/images/logout.h | 3 +- src/cmd/lcrc/images/pull.c | 2 +- src/cmd/lcrc/images/pull.h | 5 +- src/cmd/lcrc/images/rmi.h | 3 +- src/cmd/lcrc/information/health.c | 1 + src/cmd/lcrc/information/health.h | 1 + src/cmd/lcrc/information/info.h | 1 + src/cmd/lcrc/information/inspect.c | 63 +- src/cmd/lcrc/information/inspect.h | 1 + src/cmd/lcrc/information/logs.c | 3 +- src/cmd/lcrc/information/logs.h | 1 + src/cmd/lcrc/information/ps.c | 810 +++++++++++-- src/cmd/lcrc/information/ps.h | 7 +- src/cmd/lcrc/information/top.h | 1 + src/cmd/lcrc/information/version.h | 1 + src/cmd/lcrc/information/wait.c | 1 + src/cmd/lcrc/information/wait.h | 1 + src/cmd/lcrc/main.c | 11 + src/cmd/lcrc/stream/attach.c | 1 + src/cmd/lcrc/stream/attach.h | 1 + src/cmd/lcrc/stream/cp.c | 3 +- src/cmd/lcrc/stream/cp.h | 3 +- src/cmd/lcrc/stream/exec.c | 1 + src/cmd/lcrc/stream/exec.h | 5 +- src/cmd/lcrd/arguments.c | 4 +- src/cmd/lcrd/arguments.h | 5 +- src/cmd/lcrd/commands.c | 8 + src/cmd/lcrd/commands.h | 7 +- src/cmd/lcrd/main.c | 328 +----- src/config/lcrd_config.c | 56 +- src/config/lcrd_config.h | 7 + src/connect/CMakeLists.txt | 5 + src/connect/client/CMakeLists.txt | 22 +- src/connect/client/connect.h | 6 +- src/connect/client/grpc/CMakeLists.txt | 20 +- src/connect/client/grpc/client_base.h | 18 +- src/connect/client/grpc/grpc_client.cc | 1 + src/connect/client/grpc/grpc_client.h | 1 + .../client/grpc/grpc_containers_client.cc | 12 +- .../client/grpc/grpc_containers_client.h | 1 + src/connect/client/grpc/grpc_images_client.cc | 30 +- src/connect/client/grpc/grpc_images_client.h | 1 + .../client/grpc/grpc_isula_image_client.cc | 1041 +++++++++++++++++ .../client/grpc/grpc_isula_image_client.h | 30 + src/connect/client/isula_image_connect.c | 495 ++++++++ src/connect/client/isula_image_connect.h | 367 ++++++ src/connect/client/lcrc_connect.c | 1 + src/connect/client/lcrc_connect.h | 1 + src/connect/client/rest/rest_client.c | 1 + src/connect/client/rest/rest_client.h | 1 + .../client/rest/rest_containers_client.c | 1 - .../client/rest/rest_containers_client.h | 1 + src/connect/client/rest/rest_images_client.h | 1 + .../service/grpc/grpc_containers_service.h | 3 +- .../grpc/grpc_containers_service_private.cc | 6 +- .../service/grpc/grpc_images_service.cc | 62 +- .../service/grpc/grpc_images_service.h | 3 +- .../service/grpc/grpc_server_tls_auth.cc | 3 +- .../service/grpc/grpc_server_tls_auth.h | 3 +- src/connect/service/grpc/grpc_service.cc | 1 + src/connect/service/grpc/grpc_service.h | 1 + .../service/grpc/runtime_image_service.cc | 33 +- .../service/grpc/runtime_image_service.h | 23 +- .../service/grpc/runtime_runtime_service.cc | 104 +- .../service/grpc/runtime_runtime_service.h | 94 +- .../service/rest/rest_containers_service.h | 1 + .../service/rest/rest_images_service.h | 1 + src/connect/service/rest/rest_service.c | 1 + src/connect/service/rest/rest_service.h | 1 + .../service/rest/rest_service_common.c | 1 + .../service/rest/rest_service_common.h | 1 + src/connect/service/service_common.c | 1 + src/connect/service/service_common.h | 1 + src/console/console.c | 1 + src/console/console.h | 1 + src/constants.h | 1 + src/contrib/config/config.json | 1 + src/contrib/config/daemon.json | 2 +- .../config/systemcontainer_config.json | 1 + src/contrib/docker | 2 +- src/contrib/env_checkconfig | 19 +- src/contrib/generate_certificate.bash | 88 -- src/contrib/init/lcrd.init | 14 - src/contrib/init/lcrd.service | 1 - src/contrib/sysmonitor/isulad-check.sh | 291 ++--- src/cpputils/cxxutils.cc | 3 +- src/cpputils/cxxutils.h | 3 +- src/cpputils/stoppable_thread.cc | 3 +- src/cpputils/stoppable_thread.h | 2 +- src/cpputils/url.cc | 5 +- src/cpputils/url.h | 3 +- src/cutils/util_atomic.c | 1 + src/cutils/util_atomic.h | 5 +- src/cutils/utils.c | 14 +- src/cutils/utils.h | 16 +- src/cutils/utils_array.c | 15 + src/cutils/utils_array.h | 2 + src/cutils/utils_convert.h | 1 + src/cutils/utils_file.h | 1 + src/cutils/utils_regex.c | 140 +++ .../oci_image_load.h => cutils/utils_regex.h} | 21 +- src/cutils/utils_string.c | 44 + src/cutils/utils_string.h | 5 + src/cutils/utils_verify.c | 62 +- src/cutils/utils_verify.h | 6 +- src/engines/engine.c | 1 + src/engines/engine.h | 38 +- src/engines/lcr/lcr_engine.c | 22 +- src/engines/lcr/lcr_engine.h | 1 + src/error.c | 1 + src/error.h | 1 + src/filters.c | 6 +- src/filters.h | 1 + src/http/buffer.c | 1 + src/http/buffer.h | 1 + src/http/certificate.c | 3 +- src/http/certificate.h | 3 +- src/http/http.c | 1 + src/http/http.h | 31 +- src/http/mediatype.h | 1 + src/http/parser.h | 1 + src/http/rest_common.c | 1 + src/http/rest_common.h | 1 + src/image/CMakeLists.txt | 4 +- src/image/embedded/db/db_all.h | 1 + src/image/embedded/db/db_common.h | 3 +- src/image/embedded/db/db_images_common.h | 1 + src/image/embedded/db/sqlite_common.c | 1 + src/image/embedded/db/sqlite_common.h | 1 + src/image/embedded/embedded_config_merge.h | 1 + src/image/embedded/embedded_image.c | 55 +- src/image/embedded/embedded_image.h | 24 +- src/image/embedded/lim.c | 5 + src/image/embedded/lim.h | 1 + src/image/embedded/load.c | 3 +- src/image/embedded/snapshot/embedded.c | 1 + src/image/embedded/snapshot/embedded.h | 1 + src/image/embedded/snapshot/snapshot.c | 1 + src/image/embedded/snapshot/snapshot.h | 1 + src/image/embedded/snapshot/snapshot_def.h | 1 + src/image/external/ext_image.c | 72 +- src/image/external/ext_image.h | 27 +- src/image/image.c | 715 ++++++++++- src/image/image.h | 164 ++- src/image/oci/CMakeLists.txt | 1 + src/image/oci/global_config.c | 264 +++++ src/image/oci/global_config.h | 65 + src/image/oci/isula_container_export.c | 108 ++ src/image/oci/isula_container_export.h | 30 + src/image/oci/isula_container_fs_usage.c | 108 ++ src/image/oci/isula_container_fs_usage.h | 28 + src/image/oci/isula_containers_list.c | 70 ++ ...ner_fs_usage.h => isula_containers_list.h} | 22 +- src/image/oci/isula_health_check.c | 64 + src/image/oci/isula_health_check.h | 29 + src/image/oci/isula_helper.c | 55 + src/image/oci/isula_helper.h | 32 + src/image/oci/isula_image.c | 534 +++++++++ src/image/oci/isula_image.h | 57 + src/image/oci/isula_image_fs_info.c | 150 +++ .../{oci_logout.h => isula_image_fs_info.h} | 17 +- src/image/oci/isula_image_load.c | 201 ++++ src/image/oci/isula_image_load.h | 28 + src/image/oci/isula_image_pull.c | 168 +++ .../oci/{oci_login.h => isula_image_pull.h} | 18 +- src/image/oci/isula_image_rmi.c | 100 ++ src/image/oci/isula_image_rmi.h | 30 + src/image/oci/isula_image_status.c | 156 +++ src/image/oci/isula_image_status.h | 30 + src/image/oci/isula_images_list.c | 184 +++ ...{oci_images_list.h => isula_images_list.h} | 19 +- src/image/oci/isula_imtool_interface.c | 818 ------------- src/image/oci/isula_imtool_interface.h | 58 - src/image/oci/isula_login.c | 108 ++ src/image/oci/isula_login.h | 30 + src/image/oci/isula_logout.c | 100 ++ src/image/oci/isula_logout.h | 30 + src/image/oci/isula_rootfs_mount.c | 88 ++ src/image/oci/isula_rootfs_mount.h | 28 + src/image/oci/isula_rootfs_prepare.c | 146 +++ src/image/oci/isula_rootfs_prepare.h | 33 + src/image/oci/isula_rootfs_remove.c | 101 ++ src/image/oci/isula_rootfs_remove.h | 28 + src/image/oci/isula_rootfs_umount.c | 94 ++ src/image/oci/isula_rootfs_umount.h | 30 + src/image/oci/isula_storage_status.c | 81 ++ src/image/oci/isula_storage_status.h | 30 + src/image/oci/oci_auth.c | 2 +- src/image/oci/oci_auth.h | 3 +- src/image/oci/oci_common_operators.c | 839 +++++++++++++ src/image/oci/oci_common_operators.h | 47 + src/image/oci/oci_config_merge.c | 28 +- src/image/oci/oci_config_merge.h | 1 + src/image/oci/oci_container_fs_usage.c | 76 -- src/image/oci/oci_fs_info.c | 119 -- src/image/oci/oci_fs_info.h | 39 - src/image/oci/oci_image.c | 732 ------------ src/image/oci/oci_image.h | 53 - src/image/oci/oci_image_load.c | 170 --- src/image/oci/oci_image_pull.c | 190 --- src/image/oci/oci_image_pull.h | 47 - src/image/oci/oci_image_remove.c | 105 -- src/image/oci/oci_image_status.c | 171 --- src/image/oci/oci_image_status.h | 49 - src/image/oci/oci_image_type.h | 1 + src/image/oci/oci_image_unix.c | 1 + src/image/oci/oci_image_unix.h | 1 + src/image/oci/oci_images_list.c | 112 -- src/image/oci/oci_images_store.c | 46 +- src/image/oci/oci_images_store.h | 2 + src/image/oci/oci_login.c | 118 -- src/image/oci/oci_logout.c | 99 -- src/image/oci/oci_rootfs_export.c | 146 --- src/image/oci/oci_rootfs_export.h | 43 - src/image/oci/oci_rootfs_mount.c | 154 --- src/image/oci/oci_rootfs_mount.h | 42 - src/image/oci/oci_rootfs_prepare.c | 180 --- src/image/oci/oci_rootfs_prepare.h | 54 - src/image/oci/oci_rootfs_remove.c | 151 --- src/image/oci/oci_rootfs_remove.h | 42 - src/image/oci/oci_rootfs_umount.c | 143 --- src/image/oci/oci_rootfs_umount.h | 42 - src/image/oci/run_image_server.c | 462 ++++++++ src/image/oci/run_image_server.h | 38 + src/json/oci_runtime_hooks.c | 1 + src/json/oci_runtime_hooks.h | 1 + src/json/parse_common.c | 3 +- src/json/parse_common.h | 3 +- .../schema/schema/container/exec-request.json | 5 +- .../schema/container/exec-response.json | 3 - src/json/schema/schema/container/inspect.json | 3 + src/json/schema/schema/cri/pod_network.json | 4 +- .../schema/image/list-images-request.json | 4 +- src/json/schema/schema/imagetool/image.json | 2 +- .../schema/imagetool/prepare-response.json | 2 +- .../schema/schema/isulad-daemon-configs.json | 5 +- src/json/schema/src/common_h.py | 8 +- src/json/schema/src/generate.py | 230 ++-- src/json/schema/src/headers.py | 86 +- src/json/schema/src/helpers.py | 76 +- src/json/schema/src/read_file.c | 1 + src/json/schema/src/read_file.h | 1 + src/json/schema/src/sources.py | 355 +++--- src/liblcrc.h | 14 +- src/liblcrd.c | 1 + src/liblcrd.h | 14 +- src/linked_list.h | 3 + src/log.c | 125 +- src/log.h | 121 +- src/mainloop.c | 1 + src/mainloop.h | 1 + src/map/map.h | 1 + src/map/rb_tree.c | 5 +- src/map/rb_tree.h | 1 + src/namespace.c | 1 + src/namespace.h | 1 + src/pack_config.c | 2 +- src/pack_config.h | 1 + src/path.c | 104 ++ src/path.h | 5 + src/plugin/plugin.c | 3 +- src/plugin/plugin.h | 1 + src/plugin/pspec.h | 1 + src/runtime/CMakeLists.txt | 23 + src/runtime/lcr/CMakeLists.txt | 7 + src/runtime/lcr/lcr_rt_ops.c | 396 +++++++ src/runtime/lcr/lcr_rt_ops.h | 43 + src/runtime/runtime.c | 308 +++++ src/runtime/runtime.h | 151 +++ src/services/CMakeLists.txt | 2 +- src/services/callback.c | 1 + src/services/callback.h | 1 + src/services/cri/checkpoint_handler.cc | 4 +- src/services/cri/checkpoint_handler.h | 2 +- src/services/cri/cni_network_plugin.cc | 21 +- src/services/cri/cni_network_plugin.h | 2 +- src/services/cri/cri_container.cc | 246 ++-- src/services/cri/cri_helpers.cc | 79 +- src/services/cri/cri_helpers.h | 28 +- src/services/cri/cri_image_service.cc | 107 +- src/services/cri/cri_image_service.h | 33 +- src/services/cri/cri_runtime_service.cc | 21 +- src/services/cri/cri_runtime_service.h | 154 +-- src/services/cri/cri_sandbox.cc | 286 +++-- src/services/cri/cri_security_context.cc | 229 ++-- src/services/cri/cri_security_context.h | 6 +- src/services/cri/cri_services.h | 66 +- src/services/cri/errors.h | 6 +- src/services/cri/naming.cc | 10 +- src/services/cri/naming.h | 11 +- src/services/cri/network_plugin.cc | 24 +- src/services/cri/network_plugin.h | 37 +- src/services/cri/request_cache.cc | 2 - src/services/cri/request_cache.h | 5 +- src/services/execution/events/collector.c | 5 +- src/services/execution/events/collector.h | 1 + .../execution/events/events_handler.c | 3 +- .../execution/events/events_handler.h | 1 + src/services/execution/execute/execution.c | 161 +-- src/services/execution/execute/execution.h | 1 + .../execution/execute/execution_create.c | 12 +- .../execution/execute/execution_create.h | 1 + .../execution/execute/execution_extend.c | 84 +- .../execution/execute/execution_extend.h | 1 + .../execution/execute/execution_information.c | 124 +- .../execution/execute/execution_information.h | 1 + .../execution/execute/execution_network.c | 37 +- .../execution/execute/execution_network.h | 1 + .../execution/execute/execution_stream.c | 311 +++-- src/services/execution/execute/list.c | 19 +- src/services/execution/execute/list.h | 1 + .../execution/execute/runtime_interface.c | 248 ---- .../execution/execute/runtime_interface.h | 43 - src/services/execution/log_gather.h | 1 + .../execution/manager/container_state.c | 32 +- .../execution/manager/container_state.h | 1 + .../execution/manager/container_unix.c | 2 +- .../execution/manager/container_unix.h | 1 + .../execution/manager/containers_gc.c | 21 +- .../execution/manager/containers_gc.h | 1 + .../execution/manager/containers_store.c | 4 +- .../execution/manager/containers_store.h | 1 + src/services/execution/manager/monitord.c | 3 +- src/services/execution/manager/monitord.h | 1 + .../execution/manager/restartmanager.c | 12 +- .../execution/manager/restartmanager.h | 1 + src/services/execution/manager/restore.c | 54 +- src/services/execution/manager/supervisor.c | 5 +- src/services/execution/spec/specs.c | 4 +- src/services/execution/spec/specs.h | 1 + src/services/execution/spec/specs_extend.c | 29 +- src/services/execution/spec/specs_extend.h | 1 + src/services/execution/spec/specs_mount.c | 108 +- src/services/execution/spec/specs_security.h | 1 + src/services/execution/spec/sysinfo.h | 1 + src/services/execution/spec/verify.c | 1 + src/services/execution/spec/verify.h | 1 + src/services/graphdriver/driver.c | 89 +- src/services/graphdriver/driver.h | 3 +- .../graphdriver/overlay2/driver_overlay2.c | 2 +- .../graphdriver/overlay2/driver_overlay2.h | 3 +- src/services/image/image_cb.c | 178 ++- src/services/image/image_cb.h | 1 + src/sha256/sha256.c | 1 + src/sha256/sha256.h | 1 + src/sysctl_tools.c | 1 + src/sysctl_tools.h | 1 + src/tar/lcrdtar.c | 25 - src/types_def.c | 44 +- src/types_def.h | 8 +- src/websocket/service/attach_serve.cc | 5 +- src/websocket/service/attach_serve.h | 7 +- src/websocket/service/exec_serve.cc | 4 +- src/websocket/service/exec_serve.h | 7 +- .../service/route_callback_register.h | 5 +- src/websocket/service/stream_server.cc | 1 + src/websocket/service/stream_server.h | 3 +- src/websocket/service/ws_server.cc | 1 + src/websocket/service/ws_server.h | 4 +- test/GTest-Run.xsl | 92 ++ test/cutils/utils_array/CMakeLists.txt | 1 + test/cutils/utils_array/utils_array_llt.cc | 2 +- test/cutils/utils_convert/CMakeLists.txt | 1 + .../cutils/utils_convert/utils_convert_llt.cc | 2 +- test/cutils/utils_string/CMakeLists.txt | 1 + test/cutils/utils_string/utils_string_llt.cc | 11 +- test/image/oci/CMakeLists.txt | 5 - .../image/oci/oci_config_merge/CMakeLists.txt | 4 +- .../oci/oci_config_merge/imagetool_image.json | 4 +- .../oci_config_merge/oci_config_merge_llt.cc | 83 +- test/image/oci/oci_llt_common.cc | 19 +- test/image/oci/oci_llt_common.h | 23 +- .../oci/oci_rootfs_export/CMakeLists.txt | 60 - .../oci_rootfs_export_llt.cc | 180 --- .../image/oci/oci_rootfs_mount/CMakeLists.txt | 60 - .../oci_rootfs_mount/oci_rootfs_mount_llt.cc | 167 --- .../oci/oci_rootfs_prepare/CMakeLists.txt | 62 - .../oci_rootfs_prepare_llt.cc | 268 ----- .../oci_rootfs_prepare/prepare_response.json | 1 - .../oci/oci_rootfs_remove/CMakeLists.txt | 60 - .../oci_rootfs_remove_llt.cc | 173 --- .../oci/oci_rootfs_umount/CMakeLists.txt | 60 - .../oci_rootfs_umount_llt.cc | 162 --- test/include/mock.h | 11 +- test/llt.sh | 365 +++--- test/path/CMakeLists.txt | 1 + test/path/path_llt.cc | 2 +- tools/static_check | 2 +- update-version.bash | 2 +- 441 files changed, 14359 insertions(+), 8892 deletions(-) delete mode 100644 docs/developer_guide.md delete mode 100644 docs/install_guide.md delete mode 100644 docs/limitations.md create mode 100644 src/api/image_client/isula_image.proto create mode 100644 src/connect/client/grpc/grpc_isula_image_client.cc create mode 100644 src/connect/client/grpc/grpc_isula_image_client.h create mode 100644 src/connect/client/isula_image_connect.c create mode 100644 src/connect/client/isula_image_connect.h delete mode 100644 src/contrib/generate_certificate.bash create mode 100644 src/cutils/utils_regex.c rename src/{image/oci/oci_image_load.h => cutils/utils_regex.h} (66%) create mode 100644 src/image/oci/global_config.c create mode 100644 src/image/oci/global_config.h create mode 100644 src/image/oci/isula_container_export.c create mode 100644 src/image/oci/isula_container_export.h create mode 100644 src/image/oci/isula_container_fs_usage.c create mode 100644 src/image/oci/isula_container_fs_usage.h create mode 100644 src/image/oci/isula_containers_list.c rename src/image/oci/{oci_container_fs_usage.h => isula_containers_list.h} (61%) create mode 100644 src/image/oci/isula_health_check.c create mode 100644 src/image/oci/isula_health_check.h create mode 100644 src/image/oci/isula_helper.c create mode 100644 src/image/oci/isula_helper.h create mode 100644 src/image/oci/isula_image.c create mode 100644 src/image/oci/isula_image.h create mode 100644 src/image/oci/isula_image_fs_info.c rename src/image/oci/{oci_logout.h => isula_image_fs_info.h} (65%) create mode 100644 src/image/oci/isula_image_load.c create mode 100644 src/image/oci/isula_image_load.h create mode 100644 src/image/oci/isula_image_pull.c rename src/image/oci/{oci_login.h => isula_image_pull.h} (64%) create mode 100644 src/image/oci/isula_image_rmi.c create mode 100644 src/image/oci/isula_image_rmi.h create mode 100644 src/image/oci/isula_image_status.c create mode 100644 src/image/oci/isula_image_status.h create mode 100644 src/image/oci/isula_images_list.c rename src/image/oci/{oci_images_list.h => isula_images_list.h} (62%) delete mode 100644 src/image/oci/isula_imtool_interface.c delete mode 100644 src/image/oci/isula_imtool_interface.h create mode 100644 src/image/oci/isula_login.c create mode 100644 src/image/oci/isula_login.h create mode 100644 src/image/oci/isula_logout.c create mode 100644 src/image/oci/isula_logout.h create mode 100644 src/image/oci/isula_rootfs_mount.c create mode 100644 src/image/oci/isula_rootfs_mount.h create mode 100644 src/image/oci/isula_rootfs_prepare.c create mode 100644 src/image/oci/isula_rootfs_prepare.h create mode 100644 src/image/oci/isula_rootfs_remove.c create mode 100644 src/image/oci/isula_rootfs_remove.h create mode 100644 src/image/oci/isula_rootfs_umount.c create mode 100644 src/image/oci/isula_rootfs_umount.h create mode 100644 src/image/oci/isula_storage_status.c create mode 100644 src/image/oci/isula_storage_status.h create mode 100644 src/image/oci/oci_common_operators.c create mode 100644 src/image/oci/oci_common_operators.h delete mode 100644 src/image/oci/oci_container_fs_usage.c delete mode 100644 src/image/oci/oci_fs_info.c delete mode 100644 src/image/oci/oci_fs_info.h delete mode 100644 src/image/oci/oci_image.c delete mode 100644 src/image/oci/oci_image.h delete mode 100644 src/image/oci/oci_image_load.c delete mode 100644 src/image/oci/oci_image_pull.c delete mode 100644 src/image/oci/oci_image_pull.h delete mode 100644 src/image/oci/oci_image_remove.c delete mode 100644 src/image/oci/oci_image_status.c delete mode 100644 src/image/oci/oci_image_status.h delete mode 100644 src/image/oci/oci_images_list.c delete mode 100644 src/image/oci/oci_login.c delete mode 100644 src/image/oci/oci_logout.c delete mode 100644 src/image/oci/oci_rootfs_export.c delete mode 100644 src/image/oci/oci_rootfs_export.h delete mode 100644 src/image/oci/oci_rootfs_mount.c delete mode 100644 src/image/oci/oci_rootfs_mount.h delete mode 100644 src/image/oci/oci_rootfs_prepare.c delete mode 100644 src/image/oci/oci_rootfs_prepare.h delete mode 100644 src/image/oci/oci_rootfs_remove.c delete mode 100644 src/image/oci/oci_rootfs_remove.h delete mode 100644 src/image/oci/oci_rootfs_umount.c delete mode 100644 src/image/oci/oci_rootfs_umount.h create mode 100644 src/image/oci/run_image_server.c create mode 100644 src/image/oci/run_image_server.h create mode 100644 src/runtime/CMakeLists.txt create mode 100644 src/runtime/lcr/CMakeLists.txt create mode 100644 src/runtime/lcr/lcr_rt_ops.c create mode 100644 src/runtime/lcr/lcr_rt_ops.h create mode 100644 src/runtime/runtime.c create mode 100644 src/runtime/runtime.h delete mode 100644 src/services/execution/execute/runtime_interface.c delete mode 100644 src/services/execution/execute/runtime_interface.h create mode 100644 test/GTest-Run.xsl delete mode 100644 test/image/oci/oci_rootfs_export/CMakeLists.txt delete mode 100644 test/image/oci/oci_rootfs_export/oci_rootfs_export_llt.cc delete mode 100644 test/image/oci/oci_rootfs_mount/CMakeLists.txt delete mode 100644 test/image/oci/oci_rootfs_mount/oci_rootfs_mount_llt.cc delete mode 100644 test/image/oci/oci_rootfs_prepare/CMakeLists.txt delete mode 100644 test/image/oci/oci_rootfs_prepare/oci_rootfs_prepare_llt.cc delete mode 100644 test/image/oci/oci_rootfs_prepare/prepare_response.json delete mode 100644 test/image/oci/oci_rootfs_remove/CMakeLists.txt delete mode 100644 test/image/oci/oci_rootfs_remove/oci_rootfs_remove_llt.cc delete mode 100644 test/image/oci/oci_rootfs_umount/CMakeLists.txt delete mode 100644 test/image/oci/oci_rootfs_umount/oci_rootfs_umount_llt.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index b0cc2cc..20569ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,31 +56,27 @@ configure_file( "${CMAKE_BINARY_DIR}/conf/lcrd.pc" ) -if (GRPC_CONNECTOR) - # parse .proto files - include(cmake/protoc.cmake) -endif() - -# enable embedded image -if (ENABLE_EMBEDDED) - add_definitions(-DENABLE_EMBEDDED_IMAGE=1) -endif() - -# disable oci image -if (NOT DISABLE_OCI) - add_definitions(-DENABLE_OCI_IMAGE=1) -endif() +# parse .proto files +include(cmake/protoc.cmake) # llt and coverage SET(CMAKE_VERBOSE_MAKEFILE OFF) -OPTION(ENABLE_COVERAGE "coverage switch" OFF) IF(ENABLE_COVERAGE) MESSAGE(STATUS "Enable coverage compile option") - SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -fprofile-arcs -ftest-coverage") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -fprofile-arcs -ftest-coverage -fkeep-inline-functions -fkeep-static-functions") - SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -g -fprofile-arcs -ftest-coverage -lgcov") + SET(COVERAGE_C_OPTION "${COVERAGE_OPTION} -fprofile-arcs -ftest-coverage -fkeep-inline-functions -fkeep-static-functions") + SET(COVERAGE_CXX_OPTION "${COVERAGE_OPTION} -fprofile-arcs -ftest-coverage") ENDIF(ENABLE_COVERAGE) +IF(ENABLE_ASAN) + MESSAGE(STATUS "Enable asan compile option") + SET(ASAN_OPTIONS "${ASAN_OPTION} -fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer") +ENDIF(ENABLE_ASAN) + +IF(CMAKE_BUILD_TYPE STREQUAL Debug) + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${COVERAGE_C_OPTION} ${ASAN_OPTIONS}") + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COVERAGE_CXX_OPTION} ${ASAN_OPTIONS}") +ENDIF() + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src) OPTION(ENABLE_LLT "llt switch" OFF) IF(ENABLE_LLT) diff --git a/README.md b/README.md index 976a5bc..0475907 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,6 @@ iSulad follows the kernel coding conventions. You can find a detailed introducti - https://www.kernel.org/doc/html/v4.10/process/coding-style.html -## Building - -Without considering distribution specific details a simple - - mkdir -p build && cd ./build && cmake .. && make && sudo make install - -is usually sufficient. - ## Licensing iSulad is licensed under the Mulan PSL v1. diff --git a/cmake/options.cmake b/cmake/options.cmake index 49183da..60b040c 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -33,7 +33,7 @@ endif() option(VERSION "set lcrd version" ON) if (VERSION STREQUAL "ON") - set(LCRD_VERSION "1.0.33") + set(LCRD_VERSION "1.1.1") endif() option(DEBUG "set lcrd gcc option" ON) diff --git a/docs/developer_guide.md b/docs/developer_guide.md deleted file mode 100644 index 5166f66..0000000 --- a/docs/developer_guide.md +++ /dev/null @@ -1,81 +0,0 @@ -# 警告 - -本文档专为开发人员编写:不适用于最终用户。 - -# 假设 - -- 您正工作在一台正常运转的测试或开发机器上。 - -# 创建开发环境 - -您可以使用下面两种方式创建开发环境。 - -## 在主机上安装iSulad - -推荐的方式是在您的主机上[安装iSulad的依赖组件](http://code.huawei.com/containers/iSulad/blob/cri/documentation/install_guide.md),安装手册将指导您安装所有iSulad必须的组件,包括protobuf、gRPC、lxc、lcr、iSulad等。 - -## 在容器中安装iSulad - -### 依赖 - -在主机上安装docker。 - -下载[crictl-1.0.0-alpha.1](https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.0.0-alpha.1/crictl-1.0.0-alpha.1-linux-amd64.tar.gz)并放置于`/root/golang`路径下。 - -```sh -$ ls /root/golang/ -crictl-1.0.0-alpha.1-linux-amd64.tar.gz -``` - -您可能还需要配置insecure-registry以下载dockerhub的镜像。 - -- 对于centos,在` /etc/sysconfig/docker`文件中添加`OPTIONS='--insecure-registry rnd-dockerhub.huawei.com'` -- 对于ubuntu,在` /etc/docker/daemon.json`中添加`{\"insecure-registries\":[\"rnd-dockerhub.huawei.com\"]}` - -### 安装 - -```sh -$ ./CI/prepare_compile_env.sh -``` - -脚本执行完后,将运行一个名为`isulad-compile-env-$commit`的容器,您可以执行`docker exec -it isulad-compile-env-$commit /bin/bash`命令进入该容器,iSulad的源码在容器内的根目录`/isulad`下。 - -# 编码风格 - -首先您应该安装[Artistic Style](http://astyle.sourceforge.net)。 - -## 检查代码风格 - -修改完代码后,通过以下命令查看是否存在代码风格问题。 - -```sh -$ ./tools/check-syntax -``` - -## 修复代码风格 - -修改完代码后,通过以下命令尝试修复代码风格问题。 - -```sh -$ ./tools/check-syntax -f -``` - -# 修改Proto文件 - -如果涉及gRPC接口变更,需修改`./src/api/services/`下的[Proto](https://developers.google.com/protocol-buffers/docs/proto3)文件。修改完成后,重新[编译iSulad](http://code.huawei.com/containers/iSulad/blob/cri/documentation/install_guide.md#build-lcrd)。 - -# 添加json-schema文件 - -当您需要解析新的json文件时,要在`src/json/schema/schema`路径下添加[json-schema](http://json-schema.org)文件,具体要求参考[iSula_C-json反射脚本使用说明](http://code.huawei.com/iSula/MayTheForceBeWithYou/blob/master/isulad/iSula%20C-Json%E5%8F%8D%E5%B0%84%E8%84%9A%E6%9C%AC%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.docx)。 - -# 如何写commit message - -如果提交了测试脚本的MR,需要在iSulad的commit信息中,添加测试脚本MR的信息。在commit信息的reason后面,添加一行,command: "测试脚本MR的路径和分支"。示例如下: - -```sh -isulad: xxxxx - -DTS/AR: XXXX -reason: xxxxx -command: "git fetch http://code-sh.rnd.huawei.com/xxxxxxxxx/isula_testcases.git console" -``` diff --git a/docs/install_guide.md b/docs/install_guide.md deleted file mode 100644 index 177962c..0000000 --- a/docs/install_guide.md +++ /dev/null @@ -1,180 +0,0 @@ -## Dependencies - -This project depends on gRPC (need protobuf at least v3.1.0, gRPC at least v1.1.0) or REST (need libevent 2.1.8, libcurl at least 7.40, http-parser at least 2.6.2, local modified libevhtp), LCR. Other version are not tested, nor supported. - -## Installation steps: - -### Initialization - -```sh -$ sudo yum install -y go gcc gcc-c++ autoconf libtool unzip automake cmake curl zlib-devel libcap-devel libseccomp-devel \ -$ yajl-devel sqlite-devel libwebsockets-devel openssl-devel c-ares-devel zlib-devel python3-devel python3-setuptools libsecurec-devel -$ sudo sh -c "echo /usr/local/lib >> /etc/ld.so.conf" -$ sudo sh -c 'echo "export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH" >> /etc/bashrc' -``` - -### protobuf v3.5.0 - -Compile protobuf from source code: -```sh -$ git clone http://dgggit09-rd.huawei.com/a/euleros/third_party/open_source/userspace/protobuf -$ cd protobuf -$ git checkout -b open origin/next_openeuler -$ tar -xf v3.5.0.tar.gz -$ cp googlemock-1.7.0.tar.gz googletest-1.7.0.tar.gz 0001-fix-build-on-s390x.patch protobuf-3.5.0 -$ cd protobuf-3.5.0 -$ tar -xf googlemock-1.7.0.tar.gz -$ tar -xf googletest-1.7.0.tar.gz -$ mv googlemock-release-1.7.0 gmock -$ tar -xf googletest-1.7.0.tar.gz -C gmock -$ mv gmock/googletest-release-1.7.0 gmock/gtest -$ patch -p1 < 0001-fix-build-on-s390x.patch -$ ./autogen.sh -$ ./configure -$ make -j -$ sudo make install -$ sudo ldconfig -``` - -### gRPC v1.17.1 - -Compile the gRPC C Core library -```sh -$ git clone http://dgggit09-rd.huawei.com/a/euleros/third_party/open_source/userspace/grpc -$ cd grpc -$ git checkout -b open origin/next_openeuler -$ tar xf v1.17.1.tar.gz -$ cd grpc-1.17.1 -$ patch -p1 < ../0001-enforce-system-crypto-policies.patch -$ patch -p1 < ../0002-patch-from-15532.patch -$ patch -p1 < ../0003-Do-not-build-the-Ruby-plugin.patch -$ patch -p1 < ../0001-cxx-Arg-List-Too-Long.patch -$ make -j -$ sudo make install -$ sudo ldconfig -``` - -### clibcni - -Compile clibcni from source code: -```sh -$ git clone http://dgggit09-rd.huawei.com/a/euleros/self_src/userspace/clibcni -$ cd clibcni -$ git checkout -b open origin/next_openeuler -$ rm -rf build -$ mkdir build && cd build -$ cmake .. -$ make -j -$ sudo make install -$ sudo ldconfig -``` - -### containernetworking plugins - -Compile containernetworking plugins from source code: -```sh -$ git clone http://code-sh.rnd.huawei.com/containers/plugins/plugins.git -$ cd plugins -$ git checkout critest -$ ./build.sh -$ mkdir -p /opt/cni/bin -$ cp bin/* /opt/cni/bin/ -``` - -### iSulad-kit - -Compile iSulad-kit from source code: -```sh -$ yum install -y gpgme-devel -$ git clone http://dgggit09-rd.huawei.com/a/euleros/self_src/userspace/iSulad-kit -$ cd iSulad-kit -$ git checkout -b open origin/next_openeuler -# apply the patchs -$ cp ./patch/* ./ -$ cat series-patch.conf | while read line - do - if [[ $line == '' || $line =~ ^\s*# ]]; then - continue - fi - patch -p1 -F1 -s < $line - done -$ make -j -$ sudo make install -``` - -### LXC - -Compile lxc from source code: -```sh -$ git clone http://dgggit09-rd.huawei.com/a/euleros/third_party/open_source/userspace/lxc -$ cd lxc -$ git checkout -b open origin/next_openeuler -$ tar xf lxc-3.0.3.tar.gz -$ cd lxc-3.0.3 -$ mv ../*.patch . -# official patch -$ for var in $(ls lxc-*.patch | sort -n) - do - patch -p1 < ${var} - done - # self-developing patch -$ for var in $(ls *.patch | grep -v "^lxc-" | sort -n) - do - patch -p1 < ${var} - done -$ ./autogen.sh -$ ./configure -$ make -j # If the GCC version on the system is greater than 7, please add CFLAGS="-Wno-error" option -$ sudo make install -$ sudo ldconfig -``` - -### LCR - -Compile lcr from source code: -```sh -$ git clone http://dgggit09-rd.huawei.com/a/euleros/self_src/userspace/lcr -$ cd lcr -$ git checkout -b open origin/next_openeuler -$ mkdir -p build -$ cd build -$ cmake ../ -$ make -j -$ sudo make install -$ sudo ldconfig -``` - -## Build iSulad - -```sh -$ yum install -y libcurl-devel http-parser-devel systemd-devel libevent-devel libevhtp-devel -$ git clone http://dgggit09-rd.huawei.com/a/euleros/self_src/userspace/iSulad -$ cd iSulad -$ git checkout -b open origin/next_openeuler -$ mkdir -p build && cd build -# To enable gRPC, configure iSulad by default -$ cmake ../ -$ make -j # If the GCC version on the system is greater than 7, please add CFLAGS="-Wno-error" option -$ sudo make install -$ sudo ldconfig -``` - -## Run - -### Start daemon - -You should have built and installed lcrd and lcrc. To run the daemon: -```sh -$ sudo lcrd # run the iSulad server with default socket name and default log level and images manage function -``` - -### Operations on containers: - -```sh -$ sudo lcrc ps -a # list containers -# create a container 'test' with image busybox -$ sudo lcrc create -t -n test busybox -$ sudo lcrc start test # start the container 'test' -$ sudo lcrc kill test # kill the container 'test' -$ sudo lcrc rm test # remove the container 'test' -``` diff --git a/docs/limitations.md b/docs/limitations.md deleted file mode 100644 index e69de29..0000000 diff --git a/iSulad.spec b/iSulad.spec index 94772ca..7df4c38 100644 --- a/iSulad.spec +++ b/iSulad.spec @@ -1,5 +1,5 @@ -%global _version 1.0.33 -%global _release 20190930.052413.gitd2956279 +%global _version 1.1.1 +%global _release 20191222.225449.gitaa7147bf %global is_systemd 1 %global debug_package %{nil} @@ -8,7 +8,7 @@ Version: %{_version} Release: %{_release} Summary: Lightweight Container Runtime Daemon License: Mulan PSL v1 -URL: http://code.huawei.com/containers/lcrd +URL: lcrd Source: iSulad-1.0.tar.gz BuildRoot: {_tmppath}/iSulad-%{version} ExclusiveArch: x86_64 aarch64 diff --git a/lcrd.pc.in b/lcrd.pc.in index 48b72c0..9973208 100644 --- a/lcrd.pc.in +++ b/lcrd.pc.in @@ -6,7 +6,7 @@ includedir=@CMAKE_INSTALL_PREFIX@/include Name: liblcrc Description: light-weighted container runtime daemon library Version: @LCRD_VERSION@ -URL: http://code.huawei.com/containers/iSulad +URL: iSulad Libs: -L@CMAKE_INSTALL_PREFIX@/lib -llcrc Cflags: -I@CMAKE_INSTALL_PREFIX@/include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2eff80a..87d7ed6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -146,6 +146,24 @@ target_link_libraries(lcrc liblcrc -lpthread) # ------ build lcrd ------- add_subdirectory(services) add_subdirectory(image) +add_subdirectory(runtime) + +if (ENABLE_OCI_IMAGE) + aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/types CONNECT_API_TYPES) + aux_source_directory(${CMAKE_BINARY_DIR}/grpc/src/api/image_client/ IMAGE_CLIENT_SRCS) + + list(APPEND IMAGE_SRCS + ${ISULA_IMAGE_CLIENT_SRCS} + ${CONNECT_API_TYPES} ${IMAGE_CLIENT_SRCS} + ) + list(APPEND IMAGE_INCS + ${CMAKE_BINARY_DIR}/grpc/src/api/types + ${CMAKE_BINARY_DIR}/grpc/src/api/image_client + ${GRPC_INCLUDE_DIR} + ${ISULA_IMAGE_CLIENT_INCS} + ) +endif() + add_subdirectory(engines) add_subdirectory(plugin) @@ -158,6 +176,7 @@ add_executable(lcrd ${HTTP_SRCS} ${ENGINES_SRCS} ${IMAGE_SRCS} + ${RUNTIME_SRCS} ${PLUGIN_SRCS} ${MAP_SRCS} ${CONFIG_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/filters.c @@ -172,6 +191,7 @@ target_include_directories(lcrd PUBLIC ${CONNECT_SOCKET_INCS} ${SERVICES_INCS} ${IMAGE_INCS} + ${RUNTIME_INCS} ${ENGINES_INCS} ${LCRD_INCS} ${CMAKE_CURRENT_SOURCE_DIR}/plugin @@ -183,7 +203,7 @@ target_include_directories(lcrd PUBLIC target_link_libraries(lcrd ${LIBYAJL_LIBRARY} ${LIBSECUREC_LIBRARY} ${SYSTEMD_LIBRARY}) target_link_libraries(lcrd -ldl ${ZLIB_LIBRARY} -lpthread libhttpclient) -if (ENABLE_EMBEDDED) +if (ENABLE_EMBEDDED_IMAGE) target_link_libraries(lcrd ${SQLITE3_LIBRARY}) endif() @@ -198,6 +218,12 @@ else() target_link_libraries(lcrd ${EVHTP_LIBRARY} ${EVENT_LIBRARY}) endif() +if (ENABLE_OCI_IMAGE) + target_link_libraries(lcrd -Wl,--as-needed -lstdc++) + target_link_libraries(lcrd -Wl,--as-needed ${PROTOBUF_LIBRARY}) + target_link_libraries(lcrd -Wl,--no-as-needed ${GRPC_PP_REFLECTION_LIBRARY} ${GRPC_PP_LIBRARY} ${GRPC_LIBRARY} ${GPR_LIBRARY}) +endif() + if (ISULAD_GCOV) target_link_libraries(lcrc -lgcov) target_link_libraries(liblcrc -lgcov) diff --git a/src/api/image_client/isula_image.proto b/src/api/image_client/isula_image.proto new file mode 100644 index 0000000..df84870 --- /dev/null +++ b/src/api/image_client/isula_image.proto @@ -0,0 +1,541 @@ +// ####################################################################### +// ##- @Copyright (C) Huawei Technologies., Ltd. 2019. All rights reserved. +// # - iSulad licensed under the Mulan PSL v1. +// # - You can use this software according to the terms and conditions of the Mulan PSL v1. +// # - You may obtain a copy of Mulan PSL v1 at: +// # - http://license.coscl.org.cn/MulanPSL +// # - 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 v1 for more details. +// ##- @Description: generate grpc +// ##- @Author: wujing +// ##- @Create: 2019-04-25 +// ####################################################################### +// To regenerate api.pb.go run hack/update-generated-runtime.sh +syntax = 'proto3'; + +package isula; + +// ImageService defines the public APIs for managing images. +service ImageService { + // ListImages lists existing images. + rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {} + // ImageStatus returns the status of the image. If the image is not + // present, returns a response with ImageStatusResponse.Image set to + // nil. + rpc ImageStatus(ImageStatusRequest) returns (ImageStatusResponse) {} + // Get image information + rpc ImageInfo(ImageInfoRequest) returns (ImageInfoResponse) {} + // PullImage pulls an image with authentication config. + rpc PullImage(PullImageRequest) returns (PullImageResponse) {} + // RemoveImage removes the image. + // This call is idempotent, and must not return an error if the image has + // already been removed. + rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {} + // ImageFSInfo returns information of the filesystem that is used to store images. + rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {} + // Load image from file + rpc LoadImage(LoadImageRequest) returns (LoadImageResponose) {} + + // isulad image services + // get all Container rootfs + rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {} + // create rootfs for container + rpc ContainerPrepare(ContainerPrepareRequest) returns (ContainerPrepareResponse) {} + // remove rootfs of container + rpc ContainerRemove(ContainerRemoveRequest) returns (ContainerRemoveResponse) {} + // mount rwlayer for container + rpc ContainerMount(ContainerMountRequest) returns (ContainerMountResponse) {} + // umount rwlayer of container + rpc ContainerUmount(ContainerUmountRequest) returns (ContainerUmountResponse) {} + // export container rootfs + rpc ContainerExport(ContainerExportRequest) returns (ContainerExportResponse) {} + + // get filesystem usage of container + rpc ContainerFsUsage(ContainerFsUsageRequest) returns (ContainerFsUsageResponse) {} + + // get status of graphdriver + rpc GraphdriverStatus(GraphdriverStatusRequest) returns (GraphdriverStatusResponse) {} + + // login registry + rpc Login(LoginRequest) returns (LoginResponse) {} + // logout registry + rpc Logout(LogoutRequest) returns (LogoutResponse) {} + + // health check service + rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse) {} +} + +message HealthCheckRequest {} + +message HealthCheckResponse { + string errmsg = 1; + uint32 cc = 2; +} + +message LoginRequest { + string server = 1; + string username = 2; + string password = 3; +} + +message LoginResponse { + string errmsg = 1; + uint32 cc = 2; +} + +message LogoutRequest { + string server = 1; +} + +message LogoutResponse { + string errmsg = 1; + uint32 cc = 2; +} + +message ContainerExportRequest { + string name_id = 1; + string output = 2; + uint32 uid = 3; + uint32 gid = 4; + uint32 offset = 5; +} + +message ContainerExportResponse { + string errmsg = 1; + uint32 cc = 2; +} + +message LoadImageRequest { + string file = 1; + string tag = 2; +} + +message LoadImageResponose { + string outmsg = 1; + string errmsg = 2; + uint32 cc = 3; +} + +message GraphdriverStatusRequest {} + +message GraphdriverStatusResponse { + string backing_fs = 1; + bool supports_d_type = 2; + bool native_overlay_diff = 3; + string errmsg = 4; + uint32 cc = 5; +} + +message ContainerFsUsageRequest { + string name_id = 1; +} + +message ContainerFsUsageResponse { + string usage = 1; + string errmsg = 2; + uint32 cc = 3; +} + +message ContainerUmountRequest { + string name_id = 1; + bool force = 2; +} + +message ContainerUmountResponse { + string errmsg = 1; + uint32 cc = 2; +} + +message ContainerMountRequest { + string name_id = 1; +} + +message ContainerMountResponse { + string errmsg = 1; + uint32 cc = 2; +} + +message ContainerRemoveRequest { + string name_id = 1; +} + +message ContainerRemoveResponse { + string errmsg = 1; + uint32 cc = 2; +} + +message ContainerPrepareRequest { + string image = 1; + string id = 2; + string name = 3; + repeated string storage_opts = 4; +} + +message ContainerPrepareResponse { + string mount_point = 1; + string image_conf = 2; + string errmsg = 3; + uint32 cc = 4; +} + +message ListContainersRequest {} + +message ListContainersResponse { + map containers = 1; + string errmsg = 2; + uint32 cc = 3; +} + +// DNSConfig specifies the DNS servers and search domains of a sandbox. +message DNSConfig { + // List of DNS servers of the cluster. + repeated string servers = 1; + // List of DNS search domains of the cluster. + repeated string searches = 2; + // List of DNS options. See https://linux.die.net/man/5/resolv.conf + // for all available options. + repeated string options = 3; +} + +enum Protocol { + TCP = 0; + UDP = 1; +} + +// PortMapping specifies the port mapping configurations of a sandbox. +message PortMapping { + // Protocol of the port mapping. + Protocol protocol = 1; + // Port number within the container. Default: 0 (not specified). + int32 container_port = 2; + // Port number on the host. Default: 0 (not specified). + int32 host_port = 3; + // Host IP. + string host_ip = 4; +} + +enum MountPropagation { + // No mount propagation ("private" in Linux terminology). + PROPAGATION_PRIVATE = 0; + // Mounts get propagated from the host to the container ("rslave" in Linux). + PROPAGATION_HOST_TO_CONTAINER = 1; + // Mounts get propagated from the host to the container and from the + // container to the host ("rshared" in Linux). + PROPAGATION_BIDIRECTIONAL = 2; +} + +// Mount specifies a host volume to mount into a container. +message Mount { + // Path of the mount within the container. + string container_path = 1; + // Path of the mount on the host. + string host_path = 2; + // If set, the mount is read-only. + bool readonly = 3; + // If set, the mount needs SELinux relabeling. + bool selinux_relabel = 4; + // Requested propagation mode. + MountPropagation propagation = 5; +} + +// NamespaceOption provides options for Linux namespaces. +message NamespaceOption { + // If set, use the host's network namespace. + bool host_network = 1; + // If set, use the host's PID namespace. + bool host_pid = 2; + // If set, use the host's IPC namespace. + bool host_ipc = 3; +} + +// Int64Value is the wrapper of int64. +message Int64Value { + // The value. + int64 value = 1; +} + +// SELinuxOption are the labels to be applied to the container. +message SELinuxOption { + string user = 1; + string role = 2; + string type = 3; + string level = 4; +} +// LinuxSandboxSecurityContext holds linux security configuration that will be +// applied to a sandbox. Note that: +// 1) It does not apply to containers in the pods. +// 2) It may not be applicable to a PodSandbox which does not contain any running +// process. +message LinuxSandboxSecurityContext { + // Configurations for the sandbox's namespaces. + // This will be used only if the PodSandbox uses namespace for isolation. + NamespaceOption namespace_options = 1; + // Optional SELinux context to be applied. + SELinuxOption selinux_options = 2; + // UID to run sandbox processes as, when applicable. + Int64Value run_as_user = 3; + // If set, the root filesystem of the sandbox is read-only. + bool readonly_rootfs = 4; + // List of groups applied to the first process run in the sandbox, in + // addition to the sandbox's primary GID. + repeated int64 supplemental_groups = 5; + // Indicates whether the sandbox will be asked to run a privileged + // container. If a privileged container is to be executed within it, this + // MUST be true. + // This allows a sandbox to take additional security precautions if no + // privileged containers are expected to be run. + bool privileged = 6; + // Seccomp profile for the sandbox, candidate values are: + // * docker/default: the default profile for the docker container runtime + // * unconfined: unconfined profile, ie, no seccomp sandboxing + // * localhost/: the profile installed on the node. + // is the full path of the profile. + // Default: "", which is identical with unconfined. + string seccomp_profile_path = 7; +} + +// LinuxPodSandboxConfig holds platform-specific configurations for Linux +// host platforms and Linux-based containers. +message LinuxPodSandboxConfig { + // Parent cgroup of the PodSandbox. + // The cgroupfs style syntax will be used, but the container runtime can + // convert it to systemd semantics if needed. + string cgroup_parent = 1; + // LinuxSandboxSecurityContext holds sandbox security attributes. + LinuxSandboxSecurityContext security_context = 2; + // Sysctls holds linux sysctls config for the sandbox. + map sysctls = 3; +} + +// PodSandboxMetadata holds all necessary information for building the sandbox name. +// The container runtime is encouraged to expose the metadata associated with the +// PodSandbox in its user interface for better user experience. For example, +// the runtime can construct a unique PodSandboxName based on the metadata. +message PodSandboxMetadata { + // Pod name of the sandbox. Same as the pod name in the PodSpec. + string name = 1; + // Pod UID of the sandbox. Same as the pod UID in the PodSpec. + string uid = 2; + // Pod namespace of the sandbox. Same as the pod namespace in the PodSpec. + string namespace = 3; + // Attempt number of creating the sandbox. Default: 0. + uint32 attempt = 4; +} + +// PodSandboxConfig holds all the required and optional fields for creating a +// sandbox. +message PodSandboxConfig { + // Metadata of the sandbox. This information will uniquely identify the + // sandbox, and the runtime should leverage this to ensure correct + // operation. The runtime may also use this information to improve UX, such + // as by constructing a readable name. + PodSandboxMetadata metadata = 1; + // Hostname of the sandbox. + string hostname = 2; + // Path to the directory on the host in which container log files are + // stored. + // By default the log of a container going into the LogDirectory will be + // hooked up to STDOUT and STDERR. However, the LogDirectory may contain + // binary log files with structured logging data from the individual + // containers. For example, the files might be newline separated JSON + // structured logs, systemd-journald journal files, gRPC trace files, etc. + // E.g., + // PodSandboxConfig.LogDirectory = `/var/log/pods//` + // ContainerConfig.LogPath = `containerName_Instance#.log` + // + // WARNING: Log management and how kubelet should interface with the + // container logs are under active discussion in + // https://issues.k8s.io/24677. There *may* be future change of direction + // for logging as the discussion carries on. + string log_directory = 3; + // DNS config for the sandbox. + DNSConfig dns_config = 4; + // Port mappings for the sandbox. + repeated PortMapping port_mappings = 5; + // Key-value pairs that may be used to scope and select individual resources. + map labels = 6; + // Unstructured key-value map that may be set by the kubelet to store and + // retrieve arbitrary metadata. This will include any annotations set on a + // pod through the Kubernetes API. + // + // Annotations MUST NOT be altered by the runtime; the annotations stored + // here MUST be returned in the PodSandboxStatus associated with the pod + // this PodSandboxConfig creates. + // + // In general, in order to preserve a well-defined interface between the + // kubelet and the container runtime, annotations SHOULD NOT influence + // runtime behaviour. + // + // Annotations can also be useful for runtime authors to experiment with + // new features that are opaque to the Kubernetes APIs (both user-facing + // and the CRI). Whenever possible, however, runtime authors SHOULD + // consider proposing new typed fields for any new features instead. + map annotations = 7; + // Optional configurations specific to Linux hosts. + LinuxPodSandboxConfig linux = 8; +} +// ImageSpec is an internal representation of an image. Currently, it wraps the +// value of a Container's Image field (e.g. imageID or imageDigest), but in the +// future it will include more detailed information about the different image types. +message ImageSpec { + string image = 1; +} + +message ImageFilter { + // Spec of the image. + ImageSpec image = 1; +} + +message ListImagesRequest { + // Filter to list images. + ImageFilter filter = 1; + bool check = 2; +} + +// Basic information about a container image. +message Image { + // ID of the image. + string id = 1; + // Other names by which this image is known. + repeated string repo_tags = 2; + // Digests by which this image is known. + repeated string repo_digests = 3; + // Size of the image in bytes. Must be > 0. + uint64 size = 4; + // UID that will run the command(s). This is used as a default if no user is + // specified when creating the container. UID and the following user name + // are mutually exclusive. + Int64Value uid = 5; + // User name that will run the command(s). This is used if UID is not set + // and no user is specified when creating container. + string username = 6; + + // Create time of image + string created = 7; + + // Load time of image + string loaded = 8; + + // oci image spec + ImageSpec spec = 9; +} + +message ListImagesResponse { + // List of images. + repeated Image images = 1; + + string errmsg = 2; + uint32 cc = 3; +} + +message ImageStatusRequest { + // Spec of the image. + ImageSpec image = 1; + // Verbose indicates whether to return extra information about the image. + bool verbose = 2; +} + +message ImageStatusResponse { + // Status of the image. + Image image = 1; + // Info is extra information of the Image. The key could be abitrary string, and + // value should be in json format. The information could include anything useful + // for debug, e.g. image config for oci image based container runtime. + // It should only be returned non-empty when Verbose is true. + map info = 2; + + string errmsg = 3; + uint32 cc = 4; +} + +message ImageInfoRequest { + ImageSpec image = 1; +} + +message ImageInfoResponse { + string spec = 1; + string errmsg = 2; + uint32 cc = 3; +} + +// AuthConfig contains authorization information for connecting to a registry. +message AuthConfig { + string username = 1; + string password = 2; + string auth = 3; + string server_address = 4; + // IdentityToken is used to authenticate the user and get + // an access token for the registry. + string identity_token = 5; + // RegistryToken is a bearer token to be sent to a registry + string registry_token = 6; +} + +message PullImageRequest { + // Spec of the image. + ImageSpec image = 1; + // Authentication configuration for pulling the image. + AuthConfig auth = 2; + // Config of the PodSandbox, which is used to pull image in PodSandbox context. + PodSandboxConfig sandbox_config = 3; +} + +message PullImageResponse { + // Reference to the image in use. For most runtimes, this should be an + // image ID or digest. + string image_ref = 1; + string errmsg = 2; + uint32 cc = 3; +} + +message RemoveImageRequest { + // Spec of the image to remove. + ImageSpec image = 1; + + bool force = 2; +} + +message RemoveImageResponse { + string errmsg = 1; + uint32 cc = 2; +} + +message ImageFsInfoRequest {} + +// UInt64Value is the wrapper of uint64. +message UInt64Value { + // The value. + uint64 value = 1; +} + +// StorageIdentifier uniquely identify the storage.. +message StorageIdentifier{ + // UUID of the device. + string uuid = 1; +} + +// FilesystemUsage provides the filesystem usage information. +message FilesystemUsage { + // Timestamp in nanoseconds at which the information were collected. Must be > 0. + int64 timestamp = 1; + // The underlying storage of the filesystem. + StorageIdentifier storage_id = 2; + // UsedBytes represents the bytes used for images on the filesystem. + // This may differ from the total bytes used on the filesystem and may not + // equal CapacityBytes - AvailableBytes. + UInt64Value used_bytes = 3; + // InodesUsed represents the inodes used by the images. + // This may not equal InodesCapacity - InodesAvailable because the underlying + // filesystem may also be used for purposes other than storing images. + UInt64Value inodes_used = 4; +} + +message ImageFsInfoResponse { + // Information of image filesystem(s). + repeated FilesystemUsage image_filesystems = 1; + + string errmsg = 2; + uint32 cc = 3; +} diff --git a/src/api/services/containers/container.proto b/src/api/services/containers/container.proto index a42dea4..69ea47c 100644 --- a/src/api/services/containers/container.proto +++ b/src/api/services/containers/container.proto @@ -1,3 +1,17 @@ +// ####################################################################### +// ##- @Copyright (C) Huawei Technologies., Ltd. 2019. All rights reserved. +// # - iSulad licensed under the Mulan PSL v1. +// # - You can use this software according to the terms and conditions of the Mulan PSL v1. +// # - You may obtain a copy of Mulan PSL v1 at: +// # - http://license.coscl.org.cn/MulanPSL +// # - 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 v1 for more details. +// ##- @Description: generate grpc +// ##- @Author: wujing +// ##- @Create: 2019-04-25 +// ####################################################################### syntax = "proto3"; option optimize_for = CODE_SIZE; @@ -50,6 +64,7 @@ message Container { string runtime = 15; string name = 16; string health_state = 17; + int64 created = 18; } message Container_info { @@ -297,6 +312,7 @@ message ExecRequest { string stderr = 9; repeated string argv = 10; repeated string env = 11; + string user = 12; } message ExecResponse { int32 pid = 1; diff --git a/src/api/services/containers/rest/container.rest.h b/src/api/services/containers/rest/container.rest.h index ce50c73..4bf3baf 100644 --- a/src/api/services/containers/rest/container.rest.h +++ b/src/api/services/containers/rest/container.rest.h @@ -82,3 +82,4 @@ "/ContainerService/Attach", */ #endif + diff --git a/src/api/services/cri/api.proto b/src/api/services/cri/api.proto index d0fefba..5166276 100644 --- a/src/api/services/cri/api.proto +++ b/src/api/services/cri/api.proto @@ -1,17 +1,32 @@ +// ####################################################################### +// ##- @Copyright (C) Huawei Technologies., Ltd. 2019. All rights reserved. +// # - iSulad licensed under the Mulan PSL v1. +// # - You can use this software according to the terms and conditions of the Mulan PSL v1. +// # - You may obtain a copy of Mulan PSL v1 at: +// # - http://license.coscl.org.cn/MulanPSL +// # - 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 v1 for more details. +// ##- @Description: generate grpc +// ##- @Author: wujing +// ##- @Create: 2019-04-25 +// ####################################################################### // To regenerate api.pb.go run hack/update-generated-runtime.sh syntax = 'proto3'; -package runtime; +package runtime.v1alpha2; +option go_package = "v1alpha2"; -//import "gogo.proto"; +// import "github.com/gogo/protobuf/gogoproto/gogo.proto"; -//option (gogoproto.goproto_stringer_all) = false; -//option (gogoproto.stringer_all) = true; -//option (gogoproto.goproto_getters_all) = true; -//option (gogoproto.marshaler_all) = true; -//option (gogoproto.sizer_all) = true; -//option (gogoproto.unmarshaler_all) = true; -//option (gogoproto.goproto_unrecognized_all) = false; +// option (gogoproto.goproto_stringer_all) = false; +// option (gogoproto.stringer_all) = true; +// option (gogoproto.goproto_getters_all) = true; +// option (gogoproto.marshaler_all) = true; +// option (gogoproto.sizer_all) = true; +// option (gogoproto.unmarshaler_all) = true; +// option (gogoproto.goproto_unrecognized_all) = false; // Runtime service defines the public APIs for remote container runtimes service RuntimeService { @@ -49,7 +64,7 @@ service RuntimeService { // StopContainer stops a running container with a grace period (i.e., timeout). // This call is idempotent, and must not return an error if the container has // already been stopped. - // Note: what must the runtime do after the grace period is reached? + // TODO: what must the runtime do after the grace period is reached? rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {} // RemoveContainer removes the container. If the container is running, the // container must be forcibly removed. @@ -63,6 +78,12 @@ service RuntimeService { rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {} // UpdateContainerResources updates ContainerConfig of the container. rpc UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {} + // ReopenContainerLog asks runtime to reopen the stdout/stderr log file + // for the container. This is often called after the log file has been + // rotated. If the container is not running, container runtime can choose + // to either create a new log file and return nil, or return an error. + // Once it returns error, new container log file MUST NOT be created. + rpc ReopenContainerLog(ReopenContainerLogRequest) returns (ReopenContainerLogResponse) {} // ExecSync runs a command in a container synchronously. rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {} @@ -136,6 +157,7 @@ message DNSConfig { enum Protocol { TCP = 0; UDP = 1; + SCTP = 2; } // PortMapping specifies the port mapping configurations of a sandbox. @@ -164,7 +186,9 @@ enum MountPropagation { message Mount { // Path of the mount within the container. string container_path = 1; - // Path of the mount on the host. + // Path of the mount on the host. If the hostPath doesn't exist, then runtimes + // should report error. If the hostpath is a symbolic link, runtimes should + // follow the symlink and mount the real destination to container. string host_path = 2; // If set, the mount is read-only. bool readonly = 3; @@ -174,14 +198,39 @@ message Mount { MountPropagation propagation = 5; } +// A NamespaceMode describes the intended namespace configuration for each +// of the namespaces (Network, PID, IPC) in NamespaceOption. Runtimes should +// map these modes as appropriate for the technology underlying the runtime. +enum NamespaceMode { + // A POD namespace is common to all containers in a pod. + // For example, a container with a PID namespace of POD expects to view + // all of the processes in all of the containers in the pod. + POD = 0; + // A CONTAINER namespace is restricted to a single container. + // For example, a container with a PID namespace of CONTAINER expects to + // view only the processes in that container. + CONTAINER = 1; + // A NODE namespace is the namespace of the Kubernetes node. + // For example, a container with a PID namespace of NODE expects to view + // all of the processes on the host running the kubelet. + NODE = 2; +} + // NamespaceOption provides options for Linux namespaces. message NamespaceOption { - // If set, use the host's network namespace. - bool host_network = 1; - // If set, use the host's PID namespace. - bool host_pid = 2; - // If set, use the host's IPC namespace. - bool host_ipc = 3; + // Network namespace for this container/sandbox. + // Note: There is currently no way to set CONTAINER scoped network in the Kubernetes API. + // Namespaces currently set by the kubelet: POD, NODE + NamespaceMode network = 1; + // PID namespace for this container/sandbox. + // Note: The CRI default is POD, but the v1.PodSpec default is CONTAINER. + // The kubelet's runtime manager will set this to CONTAINER explicitly for v1 pods. + // Namespaces currently set by the kubelet: POD, CONTAINER, NODE + NamespaceMode pid = 2; + // IPC namespace for this container/sandbox. + // Note: There is currently no way to set CONTAINER scoped IPC in the Kubernetes API. + // Namespaces currently set by the kubelet: POD, NODE + NamespaceMode ipc = 3; } // Int64Value is the wrapper of int64. @@ -203,6 +252,9 @@ message LinuxSandboxSecurityContext { SELinuxOption selinux_options = 2; // UID to run sandbox processes as, when applicable. Int64Value run_as_user = 3; + // GID to run sandbox processes as, when applicable. run_as_group should only + // be specified when run_as_user is specified; otherwise, the runtime MUST error. + Int64Value run_as_group = 8; // If set, the root filesystem of the sandbox is read-only. bool readonly_rootfs = 4; // List of groups applied to the first process run in the sandbox, in @@ -215,7 +267,7 @@ message LinuxSandboxSecurityContext { // privileged containers are expected to be run. bool privileged = 6; // Seccomp profile for the sandbox, candidate values are: - // * docker/default: the default profile for the docker container runtime + // * runtime/default: the default profile for the container runtime // * unconfined: unconfined profile, ie, no seccomp sandboxing // * localhost/: the profile installed on the node. // is the full path of the profile. @@ -259,7 +311,8 @@ message PodSandboxConfig { // operation. The runtime may also use this information to improve UX, such // as by constructing a readable name. PodSandboxMetadata metadata = 1; - // Hostname of the sandbox. + // Hostname of the sandbox. Hostname could only be empty when the pod + // network namespace is NODE. string hostname = 2; // Path to the directory on the host in which container log files are // stored. @@ -270,7 +323,7 @@ message PodSandboxConfig { // structured logs, systemd-journald journal files, gRPC trace files, etc. // E.g., // PodSandboxConfig.LogDirectory = `/var/log/pods//` - // ContainerConfig.LogPath = `containerName_Instance#.log` + // ContainerConfig.LogPath = `containerName/Instance#.log` // // WARNING: Log management and how kubelet should interface with the // container logs are under active discussion in @@ -307,6 +360,12 @@ message PodSandboxConfig { message RunPodSandboxRequest { // Configuration for creating a PodSandbox. PodSandboxConfig config = 1; + // Named runtime configuration to use for this PodSandbox. + // If the runtime handler is unknown, this request should be rejected. An + // empty string should select the default handler, equivalent to the + // behavior before this feature was added. + // See https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md + string runtime_handler = 2; } message RunPodSandboxResponse { @@ -339,10 +398,6 @@ message PodSandboxStatusRequest { message PodSandboxNetworkStatus { // IP address of the PodSandbox. string ip = 1; - // Name of the interface inside the pod - string name = 2; - // Name of the attached network - string network = 3; } // Namespace contains paths to the namespaces. @@ -372,8 +427,8 @@ message PodSandboxStatus { PodSandboxState state = 3; // Creation timestamp of the sandbox in nanoseconds. Must be > 0. int64 created_at = 4; - // Networks contains all plane network status if network is handled by the runtime. - repeated PodSandboxNetworkStatus networks = 5; + // Network contains network status if network is handled by the runtime. + PodSandboxNetworkStatus network = 5; // Linux-specific status to a pod sandbox. LinuxPodSandboxStatus linux = 6; // Labels are key-value pairs that may be used to scope and select individual resources. @@ -383,12 +438,14 @@ message PodSandboxStatus { // MUST be identical to that of the corresponding PodSandboxConfig used to // instantiate the pod sandbox this status represents. map annotations = 8; + // runtime configuration used for this PodSandbox. + string runtime_handler = 9; } message PodSandboxStatusResponse { // Status of the PodSandbox. PodSandboxStatus status = 1; - // Info is extra information of the PodSandbox. The key could be abitrary string, and + // Info is extra information of the PodSandbox. The key could be arbitrary string, and // value should be in json format. The information could include anything useful for // debug, e.g. network namespace for linux container based container runtime. // It should only be returned non-empty when Verbose is true. @@ -437,6 +494,8 @@ message PodSandbox { // MUST be identical to that of the corresponding PodSandboxConfig used to // instantiate this PodSandbox. map annotations = 6; + // runtime configuration used for this PodSandbox. + string runtime_handler = 7; } message ListPodSandboxResponse { @@ -458,7 +517,7 @@ message KeyValue { // LinuxContainerResources specifies Linux specific configuration for // resources. -// Note: Consider using Resources from opencontainers/runtime-spec/specs-go +// TODO: Consider using Resources from opencontainers/runtime-spec/specs-go // directly. message LinuxContainerResources { // CPU CFS (Completely Fair Scheduler) period. Default: 0 (not specified). @@ -523,6 +582,10 @@ message LinuxContainerSecurityContext { // UID to run the container process as. Only one of run_as_user and // run_as_username can be specified at a time. Int64Value run_as_user = 5; + // GID to run the container process as. run_as_group should only be specified + // when run_as_user or run_as_username is specified; otherwise, the runtime + // MUST error. + Int64Value run_as_group = 12; // User name to run the container process as. If specified, the user MUST // exist in the container image (i.e. in the /etc/passwd inside the image), // and be resolved there by the runtime; otherwise, the runtime MUST error. @@ -540,7 +603,7 @@ message LinuxContainerSecurityContext { // http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference string apparmor_profile = 9; // Seccomp profile for the container, candidate values are: - // * docker/default: the default profile for the docker container runtime + // * runtime/default: the default profile for the container runtime // * unconfined: unconfined profile, ie, no seccomp sandboxing // * localhost/: the profile installed on the node. // is the full path of the profile. @@ -549,6 +612,12 @@ message LinuxContainerSecurityContext { // no_new_privs defines if the flag for no_new_privs should be set on the // container. bool no_new_privs = 11; + // masked_paths is a slice of paths that should be masked by the container + // runtime, this can be passed directly to the OCI spec. + repeated string masked_paths = 13; + // readonly_paths is a slice of paths that should be set as readonly by the + // container runtime, this can be passed directly to the OCI spec. + repeated string readonly_paths = 14; } // LinuxContainerConfig contains platform-specific configuration for @@ -560,6 +629,36 @@ message LinuxContainerConfig { LinuxContainerSecurityContext security_context = 2; } +// WindowsContainerSecurityContext holds windows security configuration that will be applied to a container. +message WindowsContainerSecurityContext { + // User name to run the container process as. If specified, the user MUST + // exist in the container image and be resolved there by the runtime; + // otherwise, the runtime MUST return error. + string run_as_username = 1; +} + +// WindowsContainerConfig contains platform-specific configuration for +// Windows-based containers. +message WindowsContainerConfig { + // Resources specification for the container. + WindowsContainerResources resources = 1; + // WindowsContainerSecurityContext configuration for the container. + WindowsContainerSecurityContext security_context = 2; +} + +// WindowsContainerResources specifies Windows specific configuration for +// resources. +message WindowsContainerResources { + // CPU shares (relative weight vs. other containers). Default: 0 (not specified). + int64 cpu_shares = 1; + // Number of CPUs available to the container. Default: 0 (not specified). + int64 cpu_count = 2; + // Specifies the portion of processor cycles that this container can use as a percentage times 100. + int64 cpu_maximum = 3; + // Memory limit in bytes. Default: 0 (not specified). + int64 memory_limit_in_bytes = 4; +} + // ContainerMetadata holds all necessary information for building the container // name. The container runtime is encouraged to expose the metadata in its user // interface for better user experience. E.g., runtime can construct a unique @@ -629,7 +728,7 @@ message ContainerConfig { // the log (STDOUT and STDERR) on the host. // E.g., // PodSandboxConfig.LogDirectory = `/var/log/pods//` - // ContainerConfig.LogPath = `containerName_Instance#.log` + // ContainerConfig.LogPath = `containerName/Instance#.log` // // WARNING: Log management and how kubelet should interface with the // container logs are under active discussion in @@ -639,7 +738,7 @@ message ContainerConfig { // Variables for interactive containers, these have very specialized // use-cases (e.g. debugging). - // Note: Determine if we need to continue supporting these fields that are + // TODO: Determine if we need to continue supporting these fields that are // part of Kubernetes's Container Spec. bool stdin = 12; bool stdin_once = 13; @@ -647,6 +746,8 @@ message ContainerConfig { // Configuration specific to Linux containers. LinuxContainerConfig linux = 15; + // Configuration specific to Windows containers. + WindowsContainerConfig windows = 16; } message CreateContainerRequest { @@ -804,7 +905,7 @@ message ContainerStatus { message ContainerStatusResponse { // Status of the container. ContainerStatus status = 1; - // Info is extra information of the Container. The key could be abitrary string, and + // Info is extra information of the Container. The key could be arbitrary string, and // value should be in json format. The information could include anything useful for // debug, e.g. pid for linux container based container runtime. // It should only be returned non-empty when Verbose is true. @@ -945,7 +1046,7 @@ message ImageStatusRequest { message ImageStatusResponse { // Status of the image. Image image = 1; - // Info is extra information of the Image. The key could be abitrary string, and + // Info is extra information of the Image. The key could be arbitrary string, and // value should be in json format. The information could include anything useful // for debug, e.g. image config for oci image based container runtime. // It should only be returned non-empty when Verbose is true. @@ -988,7 +1089,8 @@ message RemoveImageRequest { message RemoveImageResponse {} message NetworkConfig { - // CIDR to use for pod IP addresses. + // CIDR to use for pod IP addresses. If the CIDR is empty, runtimes + // should omit it. string pod_cidr = 1; } @@ -1040,7 +1142,7 @@ message StatusRequest { message StatusResponse { // Status of the Runtime. RuntimeStatus status = 1; - // Info is extra information of the Runtime. The key could be abitrary string, and + // Info is extra information of the Runtime. The key could be arbitrary string, and // value should be in json format. The information could include anything useful for // debug, e.g. plugins used by the container runtime. // It should only be returned non-empty when Verbose is true. @@ -1055,18 +1157,18 @@ message UInt64Value { uint64 value = 1; } -// StorageIdentifier uniquely identify the storage.. -message StorageIdentifier{ - // UUID of the device. - string uuid = 1; +// FilesystemIdentifier uniquely identify the filesystem. +message FilesystemIdentifier{ + // Mountpoint of a filesystem. + string mountpoint = 1; } // FilesystemUsage provides the filesystem usage information. message FilesystemUsage { // Timestamp in nanoseconds at which the information were collected. Must be > 0. int64 timestamp = 1; - // The underlying storage of the filesystem. - StorageIdentifier storage_id = 2; + // The unique identifier of the filesystem. + FilesystemIdentifier fs_id = 2; // UsedBytes represents the bytes used for images on the filesystem. // This may differ from the total bytes used on the filesystem and may not // equal CapacityBytes - AvailableBytes. @@ -1138,7 +1240,7 @@ message ContainerStats { CpuUsage cpu = 2; // Memory usage gathered from the container. MemoryUsage memory = 3; - // Usage of the writeable layer. + // Usage of the writable layer. FilesystemUsage writable_layer = 4; } @@ -1157,3 +1259,11 @@ message MemoryUsage { // The amount of working set memory in bytes. UInt64Value working_set_bytes = 2; } + +message ReopenContainerLogRequest { + // ID of the container for which to reopen the log. + string container_id = 1; +} + +message ReopenContainerLogResponse{ +} diff --git a/src/api/services/health/health.proto b/src/api/services/health/health.proto index 7a1de11..aeebc72 100644 --- a/src/api/services/health/health.proto +++ b/src/api/services/health/health.proto @@ -1,3 +1,17 @@ +// ####################################################################### +// ##- @Copyright (C) Huawei Technologies., Ltd. 2019. All rights reserved. +// # - iSulad licensed under the Mulan PSL v1. +// # - You can use this software according to the terms and conditions of the Mulan PSL v1. +// # - You may obtain a copy of Mulan PSL v1 at: +// # - http://license.coscl.org.cn/MulanPSL +// # - 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 v1 for more details. +// ##- @Description: generate grpc +// ##- @Author: wujing +// ##- @Create: 2019-04-25 +// ####################################################################### syntax = "proto3"; option optimize_for = CODE_SIZE; diff --git a/src/api/services/images/images.proto b/src/api/services/images/images.proto index b9db443..9863688 100644 --- a/src/api/services/images/images.proto +++ b/src/api/services/images/images.proto @@ -1,3 +1,17 @@ +// ####################################################################### +// ##- @Copyright (C) Huawei Technologies., Ltd. 2019. All rights reserved. +// # - iSulad licensed under the Mulan PSL v1. +// # - You can use this software according to the terms and conditions of the Mulan PSL v1. +// # - You may obtain a copy of Mulan PSL v1 at: +// # - http://license.coscl.org.cn/MulanPSL +// # - 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 v1 for more details. +// ##- @Description: generate grpc +// ##- @Author: wujing +// ##- @Create: 2019-04-25 +// ####################################################################### syntax = "proto3"; option optimize_for = CODE_SIZE; @@ -71,7 +85,7 @@ message ListImagesRequest { // filters[0] or filters[1] or ... or filters[n-1] or filters[n] // // If filters is zero-length or nil, all items will be returned. - repeated string filters = 1; + map filters = 1; } message ListImagesResponse { diff --git a/src/api/services/images/rest/image.rest.h b/src/api/services/images/rest/image.rest.h index d1598aa..872a132 100644 --- a/src/api/services/images/rest/image.rest.h +++ b/src/api/services/images/rest/image.rest.h @@ -34,3 +34,4 @@ #define ImagesServiceInspect "/ImagesService/Inspect" #endif + diff --git a/src/api/types/descriptor.proto b/src/api/types/descriptor.proto index 198473e..089ab6b 100644 --- a/src/api/types/descriptor.proto +++ b/src/api/types/descriptor.proto @@ -1,3 +1,17 @@ +// ####################################################################### +// ##- @Copyright (C) Huawei Technologies., Ltd. 2019. All rights reserved. +// # - iSulad licensed under the Mulan PSL v1. +// # - You can use this software according to the terms and conditions of the Mulan PSL v1. +// # - You may obtain a copy of Mulan PSL v1 at: +// # - http://license.coscl.org.cn/MulanPSL +// # - 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 v1 for more details. +// ##- @Description: generate grpc +// ##- @Author: wujing +// ##- @Create: 2019-04-25 +// ####################################################################### syntax = "proto3"; option optimize_for = CODE_SIZE; diff --git a/src/cmd/commander.h b/src/cmd/commander.h index 62e96f0..775456e 100644 --- a/src/cmd/commander.h +++ b/src/cmd/commander.h @@ -113,3 +113,4 @@ int check_default_ulimit_type(const char *type); void free_default_ulimit(host_config_ulimits_element **default_ulimit); #endif /* COMMANDER_H */ + diff --git a/src/cmd/lcrc/arguments.c b/src/cmd/lcrc/arguments.c index 98e08bb..3c5ff3d 100644 --- a/src/cmd/lcrc/arguments.c +++ b/src/cmd/lcrc/arguments.c @@ -116,7 +116,10 @@ int client_arguments_init(struct client_arguments *args) } args->name = NULL; args->create_rootfs = NULL; - args->log_file = "none"; + args->log_file = NULL; + // maximum number of rotate files : 7 + args->log_file_rotate = 7; + args->log_file_size = "30KB"; args->argc = 0; args->argv = NULL; host = getenv("ISULAD_HOST"); @@ -270,3 +273,4 @@ void client_print_error(uint32_t cc, uint32_t server_errono, const char *errmsg) break; } } + diff --git a/src/cmd/lcrc/arguments.h b/src/cmd/lcrc/arguments.h index 764bd54..4d8bd98 100644 --- a/src/cmd/lcrc/arguments.h +++ b/src/cmd/lcrc/arguments.h @@ -36,10 +36,13 @@ struct custom_configs { /* environment variables */ char **env; + /* environment variables file */ + char **env_file; + /* hugepage limits */ char **hugepage_limits; - /* group add*/ + /* group add */ char **group_add; /* hook-spec file */ @@ -225,7 +228,7 @@ struct client_arguments { char *log_file_size; unsigned int log_file_rotate; - /* notes: we should free the mem in custom_conf by hand*/ + /* notes: we should free the mem in custom_conf by hand */ struct custom_configs custom_conf; // lcrc run; @@ -250,6 +253,7 @@ struct client_arguments { bool dispname; bool list_all; char **filters; + bool no_trunc; // inspect char *format; @@ -343,4 +347,5 @@ extern void client_print_error(uint32_t cc, uint32_t server_errono, const char * extern client_connect_config_t get_connect_config(const struct client_arguments *args); -#endif /*__LCRC_ARGUMENTS_H*/ +#endif /* __LCRC_ARGUMENTS_H */ + diff --git a/src/cmd/lcrc/base/create.c b/src/cmd/lcrc/base/create.c index c2dba48..b7a133e 100644 --- a/src/cmd/lcrc/base/create.c +++ b/src/cmd/lcrc/base/create.c @@ -231,7 +231,16 @@ static int request_pack_custom_env(struct client_arguments *args, lcrc_container char *pe = NULL; if (args->custom_conf.env != NULL) { - conf->env = args->custom_conf.env; + size_t i; + for (i = 0; i < util_array_len((const char **)(args->custom_conf.env)); i++) { + if (util_array_append(&conf->env, args->custom_conf.env[i]) != 0) { + COMMAND_ERROR("Failed to append custom config env list"); + ret = -1; + goto out; + } + } + util_free_array(args->custom_conf.env); + args->custom_conf.env = conf->env; /* make sure args->custom_conf.env point to valid memory. */ conf->env_len = util_array_len((const char **)(conf->env)); } @@ -244,7 +253,6 @@ static int request_pack_custom_env(struct client_arguments *args, lcrc_container goto out; } } - args->custom_conf.env = conf->env; /* make sure args->custom_conf.env point to valid memory. */ conf->env_len = util_array_len((const char **)(conf->env)); @@ -262,6 +270,149 @@ out: return ret; } +static int validate_env(const char *env, char **dst) +{ + int ret = 0; + char *value = NULL; + char **arr = util_string_split_multi(env, '='); + if (arr == NULL) { + ERROR("Failed to split env string"); + return -1; + } + if (strlen(arr[0]) == 0) { + ERROR("Invalid environment variable: %s", env); + ret = -1; + goto out; + } + + if (util_array_len((const char **)arr) > 1) { + *dst = util_strdup_s(env); + goto out; + } + + value = getenv(env); + if (value == NULL) { + *dst = util_strdup_s(env); + goto out; + } else { + size_t len = strlen(env) + 1 + strlen(value) + 1; + *dst = (char *)util_common_calloc_s(len); + if (*dst == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + if (sprintf_s(*dst, len, "%s=%s", env, value) < 0) { + ERROR("Failed to compose env string"); + ret = -1; + goto out; + } + } + +out: + util_free_array(arr); + return ret; +} + +static int read_env_from_file(const char *path, size_t file_size, lcrc_container_config_t *conf) +{ + int ret = 0; + FILE *fp = NULL; + char *buf = NULL; + char *new_env = NULL; + + if (file_size == 0) { + return 0; + } + fp = util_fopen(path, "r"); + if (fp == NULL) { + ERROR("Failed to open '%s'", path); + return -1; + } + buf = (char *)util_common_calloc_s(file_size + 1); + if (buf == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + while (fgets(buf, (int)file_size + 1, fp) != NULL) { + size_t len = strlen(buf); + if (len == 1) { + continue; + } + buf[len - 1] = '\0'; + if (validate_env(buf, &new_env) != 0) { + ret = -1; + goto out; + } + if (new_env == NULL) { + continue; + } + if (util_array_append(&conf->env, new_env) != 0) { + ERROR("Failed to append environment variable"); + ret = -1; + goto out; + } + free(new_env); + new_env = NULL; + } + +out: + fclose(fp); + free(buf); + free(new_env); + return ret; +} + +static int append_env_variables_to_conf(const char *env_file, lcrc_container_config_t *conf) +{ + int ret = 0; + size_t file_size; + + if (!util_file_exists(env_file)) { + COMMAND_ERROR("env file not exists: %s", env_file); + ret = -1; + goto out; + } + file_size = util_file_size(env_file); + if (file_size > REGULAR_FILE_SIZE) { + COMMAND_ERROR("env file '%s', size exceed limit: %lld", env_file, REGULAR_FILE_SIZE); + ret = -1; + goto out; + } + + if (read_env_from_file(env_file, file_size, conf) != 0) { + COMMAND_ERROR("failed to read env from file: %s", env_file); + ret = -1; + goto out; + } + +out: + return ret; +} + +static int request_pack_custom_env_file(const struct client_arguments *args, lcrc_container_config_t *conf) +{ + int ret = 0; + size_t i; + char **env_files = args->custom_conf.env_file; + size_t env_files_size = util_array_len((const char **)env_files); + if (env_files_size == 0) { + return 0; + } + + for (i = 0; i < env_files_size; i++) { + if (append_env_variables_to_conf(env_files[i], conf) != 0) { + ret = -1; + goto out; + } + } + conf->env_len = util_array_len((const char **)(conf->env)); + +out: + return ret; +} + static void request_pack_custom_user(const struct client_arguments *args, lcrc_container_config_t *conf) { if (args->custom_conf.user != NULL) { @@ -295,7 +446,7 @@ static void request_pack_custom_system_container(const struct client_arguments * conf->system_container = true; } - /*ns change opt*/ + /* ns change opt */ if (!args->custom_conf.privileged) { if (args->custom_conf.ns_change_opt != NULL) { conf->ns_change_opt = args->custom_conf.ns_change_opt; @@ -420,7 +571,12 @@ static int request_pack_custom_conf(struct client_arguments *args, lcrc_containe return -1; } - /* environment variables */ + /* append environment variables from env file */ + if (request_pack_custom_env_file(args, conf) != 0) { + return -1; + } + + /* Make sure --env has higher priority than --env-file */ if (request_pack_custom_env(args, conf) != 0) { return -1; } @@ -638,7 +794,7 @@ static void request_pack_host_devices(const struct client_arguments *args, lcrc_ static void request_pack_host_hugepage_limits(const struct client_arguments *args, lcrc_host_config_t *hostconfig) { - /* hugepage limits*/ + /* hugepage limits */ if (args->custom_conf.hugepage_limits != NULL) { hostconfig->hugetlbs_len = util_array_len((const char **)(args->custom_conf.hugepage_limits)); hostconfig->hugetlbs = args->custom_conf.hugepage_limits; @@ -790,8 +946,7 @@ static int request_pack_host_config(const struct client_arguments *args, lcrc_ho #define IMAGE_NOT_FOUND_ERROR "No such image" static int do_client_create(const struct client_arguments *args, const lcrc_connect_ops *ops, - const struct lcrc_create_request *request, - struct lcrc_create_response *response) + const struct lcrc_create_request *request, struct lcrc_create_response *response) { int ret = 0; client_connect_config_t config = get_connect_config(args); @@ -947,6 +1102,7 @@ static int log_opt_parse_options(struct client_arguments *args, const char *optk ret = 0; } else if (strcmp(optkey, "disable-log") == 0) { if (strcmp(value, "true") == 0) { + args->log_file = util_strdup_s("none"); ret = 0; } else if (strcmp(value, "false") == 0) { args->log_file = NULL; @@ -1855,8 +2011,7 @@ static bool do_create_check_sysctl(const char *sysctl) *p = '\0'; if (strcmp("kernel.pid_max", sysctl) == 0) { if (!pid_max_kernel_namespaced()) { - COMMAND_ERROR("Sysctl '%s' is not kernel namespaced, it cannot be changed", - sysctl); + COMMAND_ERROR("Sysctl '%s' is not kernel namespaced, it cannot be changed", sysctl); restore_to_equate(p); return false; } else { @@ -1913,13 +2068,8 @@ static int create_check_env_target_file(const struct client_arguments *args) COMMAND_ERROR("external rootfs not specified"); return 0; } - env_path = util_path_join(args->external_rootfs, env_target_file); - if (env_path == NULL) { - COMMAND_ERROR("join env target file path error"); - return -1; - } - if (strncmp(env_path, args->external_rootfs, strlen(args->external_rootfs)) != 0) { - COMMAND_ERROR("env target file path must be under rootfs '%s'", args->external_rootfs); + if (realpath_in_scope(args->external_rootfs, env_target_file, &env_path) < 0) { + COMMAND_ERROR("env target file '%s' real path must be under '%s'", env_target_file, args->external_rootfs); ret = -1; goto out; } @@ -1932,6 +2082,7 @@ static int create_check_env_target_file(const struct client_arguments *args) ret = -1; goto out; } + out: free(env_path); return ret; diff --git a/src/cmd/lcrc/base/create.h b/src/cmd/lcrc/base/create.h index 667b2c1..9bcaf5b 100644 --- a/src/cmd/lcrc/base/create.h +++ b/src/cmd/lcrc/base/create.h @@ -47,6 +47,8 @@ "Add a host device to the container", command_append_array }, \ { CMD_OPT_TYPE_CALLBACK, false, "env", 'e', &(cmdargs).custom_conf.env, \ "Set environment variables", command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, false, "env-file", 0, &(cmdargs).custom_conf.env_file, \ + "Read in a file of environment variables", command_append_array }, \ { CMD_OPT_TYPE_STRING_DUP, false, "entrypoint", 0, &(cmdargs).custom_conf.entrypoint, \ "Entrypoint to run when starting the container", NULL }, \ { CMD_OPT_TYPE_STRING, false, "external-rootfs", 0, &(cmdargs).external_rootfs, \ @@ -168,3 +170,4 @@ int callback_annotation(command_option_t *option, const char *value); int cmd_create_main(int argc, const char **argv); #endif /* __CMD_CREATE_H */ + diff --git a/src/cmd/lcrc/base/kill.c b/src/cmd/lcrc/base/kill.c index de34ed0..c95942a 100644 --- a/src/cmd/lcrc/base/kill.c +++ b/src/cmd/lcrc/base/kill.c @@ -137,3 +137,4 @@ int cmd_kill_main(int argc, const char **argv) exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/base/kill.h b/src/cmd/lcrc/base/kill.h index fbb1edd..605b225 100644 --- a/src/cmd/lcrc/base/kill.h +++ b/src/cmd/lcrc/base/kill.h @@ -27,3 +27,4 @@ extern const char g_cmd_kill_usage[]; extern struct client_arguments g_cmd_kill_args; int cmd_kill_main(int argc, const char **argv); #endif + diff --git a/src/cmd/lcrc/base/rename.c b/src/cmd/lcrc/base/rename.c index a2857fc..be1ab60 100644 --- a/src/cmd/lcrc/base/rename.c +++ b/src/cmd/lcrc/base/rename.c @@ -96,3 +96,4 @@ int cmd_rename_main(int argc, const char **argv) exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/base/rename.h b/src/cmd/lcrc/base/rename.h index f09f271..9f921f7 100644 --- a/src/cmd/lcrc/base/rename.h +++ b/src/cmd/lcrc/base/rename.h @@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_rename_args; int cmd_rename_main(int argc, const char **argv); #endif + diff --git a/src/cmd/lcrc/base/restart.c b/src/cmd/lcrc/base/restart.c index 0ec9018..d79ac66 100644 --- a/src/cmd/lcrc/base/restart.c +++ b/src/cmd/lcrc/base/restart.c @@ -117,3 +117,4 @@ int cmd_restart_main(int argc, const char **argv) exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/base/restart.h b/src/cmd/lcrc/base/restart.h index d226847..1af6a22 100644 --- a/src/cmd/lcrc/base/restart.h +++ b/src/cmd/lcrc/base/restart.h @@ -25,3 +25,4 @@ extern struct client_arguments g_cmd_restart_args; int cmd_restart_main(int argc, const char **argv); #endif /* __CMD_RESTART_H */ + diff --git a/src/cmd/lcrc/base/rm.h b/src/cmd/lcrc/base/rm.h index 8e95cfa..5f6ee08 100644 --- a/src/cmd/lcrc/base/rm.h +++ b/src/cmd/lcrc/base/rm.h @@ -29,3 +29,4 @@ extern struct client_arguments g_cmd_delete_args; int cmd_delete_main(int argc, const char **argv); #endif /* __CMD_DELETE_H */ + diff --git a/src/cmd/lcrc/base/run.c b/src/cmd/lcrc/base/run.c index bf5eafd..7cec120 100644 --- a/src/cmd/lcrc/base/run.c +++ b/src/cmd/lcrc/base/run.c @@ -200,7 +200,7 @@ static int run_checker(struct client_arguments *args) goto out; } - /* Make detach option a high priority than terminal*/ + /* Make detach option a high priority than terminal */ if (args->detach) { args->custom_conf.attach_stdin = false; args->custom_conf.attach_stdout = false; diff --git a/src/cmd/lcrc/base/run.h b/src/cmd/lcrc/base/run.h index 2b4edbc..e080fe3 100644 --- a/src/cmd/lcrc/base/run.h +++ b/src/cmd/lcrc/base/run.h @@ -31,3 +31,4 @@ extern struct client_arguments g_cmd_run_args; int cmd_run_main(int argc, const char **argv); #endif /* __CMD_RUN_H */ + diff --git a/src/cmd/lcrc/base/start.h b/src/cmd/lcrc/base/start.h index e6c6575..b584000 100644 --- a/src/cmd/lcrc/base/start.h +++ b/src/cmd/lcrc/base/start.h @@ -29,3 +29,4 @@ int client_start(const struct client_arguments *args, bool *reset_tty, struct te struct command_fifo_config **console_fifos); int cmd_start_main(int argc, const char **argv); #endif /* __CMD_START_H */ + diff --git a/src/cmd/lcrc/base/stop.c b/src/cmd/lcrc/base/stop.c index 241b516..74c01d2 100644 --- a/src/cmd/lcrc/base/stop.c +++ b/src/cmd/lcrc/base/stop.c @@ -121,3 +121,4 @@ int cmd_stop_main(int argc, const char **argv) exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/base/stop.h b/src/cmd/lcrc/base/stop.h index c389a1b..f2f1dbc 100644 --- a/src/cmd/lcrc/base/stop.h +++ b/src/cmd/lcrc/base/stop.h @@ -29,3 +29,4 @@ extern struct client_arguments g_cmd_stop_args; int cmd_stop_main(int argc, const char **argv); #endif /* __CMD_STOP_H */ + diff --git a/src/cmd/lcrc/commands.h b/src/cmd/lcrc/commands.h index b6dc103..a96e1b3 100644 --- a/src/cmd/lcrc/commands.h +++ b/src/cmd/lcrc/commands.h @@ -70,3 +70,4 @@ int commmand_default_help(const char * const program_name, int run_command(struct command *commands, int argc, const char **argv); #endif /* __COMMAND_H */ + diff --git a/src/cmd/lcrc/extend/events.c b/src/cmd/lcrc/extend/events.c index 974a58b..8525c56 100644 --- a/src/cmd/lcrc/extend/events.c +++ b/src/cmd/lcrc/extend/events.c @@ -170,3 +170,4 @@ int cmd_events_main(int argc, const char **argv) exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/extend/events.h b/src/cmd/lcrc/extend/events.h index 775e370..76f4982 100644 --- a/src/cmd/lcrc/extend/events.h +++ b/src/cmd/lcrc/extend/events.h @@ -31,3 +31,4 @@ extern struct client_arguments g_cmd_events_args; int cmd_events_main(int argc, const char **argv); #endif /* __CMD_EVENT_H */ + diff --git a/src/cmd/lcrc/extend/export.c b/src/cmd/lcrc/extend/export.c index 17ffa09..214c597 100644 --- a/src/cmd/lcrc/extend/export.c +++ b/src/cmd/lcrc/extend/export.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -131,3 +131,4 @@ int cmd_export_main(int argc, const char **argv) exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/extend/export.h b/src/cmd/lcrc/extend/export.h index 2b2a4d6..5209504 100644 --- a/src/cmd/lcrc/extend/export.h +++ b/src/cmd/lcrc/extend/export.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -26,3 +26,4 @@ extern struct client_arguments g_cmd_export_args; int cmd_export_main(int argc, const char **argv); #endif + diff --git a/src/cmd/lcrc/extend/pause.c b/src/cmd/lcrc/extend/pause.c index 47bba33..3a7cc8d 100644 --- a/src/cmd/lcrc/extend/pause.c +++ b/src/cmd/lcrc/extend/pause.c @@ -116,3 +116,4 @@ int cmd_pause_main(int argc, const char **argv) exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/extend/pause.h b/src/cmd/lcrc/extend/pause.h index 7cd43f1..8b75807 100644 --- a/src/cmd/lcrc/extend/pause.h +++ b/src/cmd/lcrc/extend/pause.h @@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_pause_args; int cmd_pause_main(int argc, const char **argv); #endif + diff --git a/src/cmd/lcrc/extend/resume.c b/src/cmd/lcrc/extend/resume.c index 5478693..da4fb5c 100644 --- a/src/cmd/lcrc/extend/resume.c +++ b/src/cmd/lcrc/extend/resume.c @@ -19,8 +19,8 @@ #include "log.h" #include "lcrc_connect.h" -const char g_cmd_resume_desc[] = "resume container"; -const char g_cmd_resume_usage[] = "resume [command options] --name=NAME"; +const char g_cmd_resume_desc[] = "Unpause all processes within one or more containers"; +const char g_cmd_resume_usage[] = "unpause [OPTIONS] CONTAINER [CONTAINER...]"; struct client_arguments g_cmd_resume_args = {}; @@ -116,3 +116,4 @@ int cmd_resume_main(int argc, const char **argv) exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/extend/resume.h b/src/cmd/lcrc/extend/resume.h index 5847650..655b3fe 100644 --- a/src/cmd/lcrc/extend/resume.h +++ b/src/cmd/lcrc/extend/resume.h @@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_resume_args; int cmd_resume_main(int argc, const char **argv); #endif + diff --git a/src/cmd/lcrc/extend/stats.h b/src/cmd/lcrc/extend/stats.h index 40b4165..8f14b91 100644 --- a/src/cmd/lcrc/extend/stats.h +++ b/src/cmd/lcrc/extend/stats.h @@ -31,3 +31,4 @@ extern struct client_arguments g_cmd_stats_args; int cmd_stats_main(int argc, const char **argv); #endif /* __CMD_STATS_H */ + diff --git a/src/cmd/lcrc/extend/update.c b/src/cmd/lcrc/extend/update.c index e533e96..46557f1 100644 --- a/src/cmd/lcrc/extend/update.c +++ b/src/cmd/lcrc/extend/update.c @@ -164,3 +164,4 @@ int update_checker(const struct client_arguments *args) return ret; } + diff --git a/src/cmd/lcrc/extend/update.h b/src/cmd/lcrc/extend/update.h index 7b57747..9628f04 100644 --- a/src/cmd/lcrc/extend/update.h +++ b/src/cmd/lcrc/extend/update.h @@ -46,3 +46,4 @@ int cmd_update_main(int argc, const char **argv); int update_checker(const struct client_arguments *args); #endif /* __CMD_UPDATE_H */ + diff --git a/src/cmd/lcrc/images/images.c b/src/cmd/lcrc/images/images.c index 89739e7..5ef0eed 100644 --- a/src/cmd/lcrc/images/images.c +++ b/src/cmd/lcrc/images/images.c @@ -25,8 +25,11 @@ #include "lcrc_connect.h" #include "log.h" -#define IMAGES_OPTIONS(cmdargs) \ - { CMD_OPT_TYPE_BOOL, false, "quiet", 'q', &((cmdargs).dispname), "Only display image names", NULL } +#define IMAGES_OPTIONS(cmdargs) \ + { CMD_OPT_TYPE_BOOL, false, "quiet", 'q', &((cmdargs).dispname), "Only display image names", NULL }, \ + { CMD_OPT_TYPE_CALLBACK, false, "filter", 'f', &(cmdargs).filters, \ + "Filter output based on conditions provided", command_append_array } + #define CREATED_DISPLAY_FORMAT "YYYY-MM-DD HH:MM:SS" #define SHORT_DIGEST_LEN 12 @@ -37,7 +40,8 @@ const char g_cmd_images_usage[] = "images"; struct client_arguments g_cmd_images_args = {}; /* keep track of field widths for printing. */ struct lengths { - unsigned int ref_length; + unsigned int registry_length; + unsigned int tag_length; unsigned int digest_length; unsigned int created_length; unsigned int size_length; @@ -78,14 +82,33 @@ static void list_print_table(struct lcrc_image_info *images_list, const size_t s return; } /* print header */ - printf("%-*s ", (int)length->ref_length, "REF"); + printf("%-*s ", (int)length->registry_length, "REPOSITORY"); + printf("%-*s ", (int)length->tag_length, "TAG"); printf("%-*s ", (int)length->digest_length, "IMAGE ID"); printf("%-*s ", (int)length->created_length, "CREATED"); printf("%-*s ", (int)length->size_length, "SIZE"); printf("\n"); for (i = 0, in = images_list; i < size && in != NULL; i++, in++) { - printf("%-*s ", (int)length->ref_length, in->imageref ? in->imageref : "-"); + if (in->imageref == NULL || strcmp(in->imageref, "-") == 0) { + printf("%-*s ", (int)length->registry_length, ""); + printf("%-*s ", (int)length->tag_length, ""); + } else { + char *copy_name = util_strdup_s(in->imageref); + char *tag_pos = util_tag_pos(copy_name); + if (tag_pos == NULL) { + printf("%-*s ", (int)length->registry_length, copy_name); + printf("%-*s ", (int)length->tag_length, ""); + } else { + *tag_pos = '\0'; + tag_pos++; + printf("%-*s ", (int)length->registry_length, copy_name); + printf("%-*s ", (int)length->tag_length, tag_pos); + tag_pos--; + *tag_pos = ':'; + } + free(copy_name); + } digest = util_short_digest(in->digest); printf("%-*s ", (int)length->digest_length, digest ? digest : "-"); @@ -103,6 +126,39 @@ static void list_print_table(struct lcrc_image_info *images_list, const size_t s } } +static int update_image_ref_width(const struct lcrc_image_info *in, struct lengths *l) +{ + size_t len; + char *copy_name = util_strdup_s(in->imageref); + char *tag_pos = util_tag_pos(copy_name); + if (tag_pos == NULL) { + len = strlen(copy_name); + if (len > l->registry_length) { + l->registry_length = (unsigned int)len; + } + len = strlen(""); + if (len > l->tag_length) { + l->tag_length = (unsigned int)len; + } + } else { + *tag_pos = '\0'; + tag_pos++; + len = strlen(copy_name); + if (len > l->registry_length) { + l->registry_length = (unsigned int)len; + } + len = strlen(tag_pos); + if (len > l->tag_length) { + l->tag_length = (unsigned int)len; + } + tag_pos--; + *tag_pos = ':'; + } + free(copy_name); + + return 0; +} + /* list field width */ static void list_field_width(const struct lcrc_image_info *images_list, const size_t size, struct lengths *l) { @@ -114,9 +170,8 @@ static void list_field_width(const struct lcrc_image_info *images_list, const si size_t len; int slen; if (in->imageref) { - len = strlen(in->imageref); - if (len > l->ref_length) { - l->ref_length = (unsigned int)len; + if (update_image_ref_width(in, l) != 0) { + return; } } if (in->digest) { @@ -149,7 +204,8 @@ static void list_field_width(const struct lcrc_image_info *images_list, const si static void images_info_print(const struct lcrc_list_images_response *response) { struct lengths max_len = { - .ref_length = 30, /* ref */ + .registry_length = 30, /* registry */ + .tag_length = 10, /* tag */ .digest_length = 20, /* digest */ .created_length = 20, /* created */ .size_length = 10, /* size */ @@ -162,16 +218,14 @@ static void images_info_print(const struct lcrc_list_images_response *response) /* images info print quiet */ static void images_info_print_quiet(const struct lcrc_list_images_response *response) { - struct lengths max_len = { - .ref_length = 30, /* ref */ - }; - const struct lcrc_image_info *in = NULL; size_t i = 0; for (i = 0, in = response->images_list; in != NULL && i < response->images_num; i++, in++) { - printf("%-*s ", (int)(max_len.ref_length), in->imageref ? in->imageref : "-"); + char *digest = util_short_digest(in->digest); + printf("%-*s ", SHORT_DIGEST_LEN, digest ? digest : ""); printf("\n"); + free(digest); } } @@ -212,7 +266,15 @@ static int list_images(const struct client_arguments *args) ret = -1; goto out; } - + if (args->filters != NULL) { + request.filters = lcrc_filters_parse_args((const char **)args->filters, + util_array_len((const char **)(args->filters))); + if (request.filters == NULL) { + ERROR("Failed to parse filters args"); + ret = -1; + goto out; + } + } config = get_connect_config(args); ret = ops->image.list(&request, response, &config); if (ret != 0) { @@ -232,6 +294,7 @@ static int list_images(const struct client_arguments *args) } out: + lcrc_filters_free(request.filters); lcrc_list_images_response_free(response); return ret; } @@ -265,11 +328,6 @@ int cmd_images_main(int argc, const char **argv) exit(exit_code); } - if (g_cmd_images_args.argc > 0) { - COMMAND_ERROR("%s: \"images\" requires 0 arguments.", g_cmd_images_args.progname); - exit(exit_code); - } - if (list_images(&g_cmd_images_args)) { ERROR("Can not list any images"); exit(exit_code); diff --git a/src/cmd/lcrc/images/images.h b/src/cmd/lcrc/images/images.h index c415642..5fd55dd 100644 --- a/src/cmd/lcrc/images/images.h +++ b/src/cmd/lcrc/images/images.h @@ -22,4 +22,5 @@ extern const char g_cmd_images_usage[]; extern struct client_arguments g_cmd_images_args; int cmd_images_main(int argc, const char **argv); -#endif /*__CMD_IMAGES_LIST_H*/ +#endif /* __CMD_IMAGES_LIST_H */ + diff --git a/src/cmd/lcrc/images/load.h b/src/cmd/lcrc/images/load.h index 7eb7861..e6f5555 100644 --- a/src/cmd/lcrc/images/load.h +++ b/src/cmd/lcrc/images/load.h @@ -29,4 +29,5 @@ extern const char g_cmd_load_desc[]; extern struct client_arguments g_cmd_load_args; int cmd_load_main(int argc, const char **argv); -#endif /*__CMD_LOAD_H*/ +#endif /* __CMD_LOAD_H */ + diff --git a/src/cmd/lcrc/images/login.c b/src/cmd/lcrc/images/login.c index 5b02317..36f2997 100644 --- a/src/cmd/lcrc/images/login.c +++ b/src/cmd/lcrc/images/login.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: diff --git a/src/cmd/lcrc/images/login.h b/src/cmd/lcrc/images/login.h index 23a95c0..e50c28e 100644 --- a/src/cmd/lcrc/images/login.h +++ b/src/cmd/lcrc/images/login.h @@ -28,4 +28,5 @@ extern const char g_cmd_login_usage[]; extern struct client_arguments g_cmd_login_args; int cmd_login_main(int argc, const char **argv); -#endif /*__CMD_LOGIN_H*/ +#endif /* __CMD_LOGIN_H */ + diff --git a/src/cmd/lcrc/images/logout.c b/src/cmd/lcrc/images/logout.c index 56b86f2..9bf4711 100644 --- a/src/cmd/lcrc/images/logout.c +++ b/src/cmd/lcrc/images/logout.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: diff --git a/src/cmd/lcrc/images/logout.h b/src/cmd/lcrc/images/logout.h index 85930e9..7100f83 100644 --- a/src/cmd/lcrc/images/logout.h +++ b/src/cmd/lcrc/images/logout.h @@ -21,4 +21,5 @@ extern const char g_cmd_logout_usage[]; extern struct client_arguments g_cmd_logout_args; int cmd_logout_main(int argc, const char **argv); -#endif /*__CMD_LOGOUT_H*/ +#endif /* __CMD_LOGOUT_H */ + diff --git a/src/cmd/lcrc/images/pull.c b/src/cmd/lcrc/images/pull.c index fe9153d..42e32d4 100644 --- a/src/cmd/lcrc/images/pull.c +++ b/src/cmd/lcrc/images/pull.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: diff --git a/src/cmd/lcrc/images/pull.h b/src/cmd/lcrc/images/pull.h index 9ce3c0e..728ec4e 100644 --- a/src/cmd/lcrc/images/pull.h +++ b/src/cmd/lcrc/images/pull.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -25,4 +25,5 @@ int client_pull(const struct client_arguments *args); int cmd_pull_main(int argc, const char **argv); -#endif /*__CMD_PULL_IMAGE_H*/ +#endif /* __CMD_PULL_IMAGE_H */ + diff --git a/src/cmd/lcrc/images/rmi.h b/src/cmd/lcrc/images/rmi.h index b8f1813..bc8ec80 100644 --- a/src/cmd/lcrc/images/rmi.h +++ b/src/cmd/lcrc/images/rmi.h @@ -25,4 +25,5 @@ extern const char g_cmd_rmi_usage[]; extern struct client_arguments g_cmd_rmi_args; int cmd_rmi_main(int argc, const char **argv); -#endif /*__CMD_REMOVE_IMAGE_H*/ +#endif /* __CMD_REMOVE_IMAGE_H */ + diff --git a/src/cmd/lcrc/information/health.c b/src/cmd/lcrc/information/health.c index bdbb7ae..070d3c1 100644 --- a/src/cmd/lcrc/information/health.c +++ b/src/cmd/lcrc/information/health.c @@ -101,3 +101,4 @@ int cmd_health_check_main(int argc, const char **argv) printf("LCRD with socket name '%s' is SERVING\n", g_cmd_health_check_args.socket); exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/information/health.h b/src/cmd/lcrc/information/health.h index 5bbb535..e9d4908 100644 --- a/src/cmd/lcrc/information/health.h +++ b/src/cmd/lcrc/information/health.h @@ -26,3 +26,4 @@ extern struct client_arguments g_cmd_health_check_args; int cmd_health_check_main(int argc, const char **argv); #endif + diff --git a/src/cmd/lcrc/information/info.h b/src/cmd/lcrc/information/info.h index c419bbd..f358f9d 100644 --- a/src/cmd/lcrc/information/info.h +++ b/src/cmd/lcrc/information/info.h @@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_info_args; int cmd_info_main(int argc, const char **argv); #endif /* __CMD_INFO_H */ + diff --git a/src/cmd/lcrc/information/inspect.c b/src/cmd/lcrc/information/inspect.c index 3db2a76..5a5374c 100644 --- a/src/cmd/lcrc/information/inspect.c +++ b/src/cmd/lcrc/information/inspect.c @@ -51,7 +51,7 @@ typedef struct { } container_tree_t; static yajl_val inspect_get_json_info(yajl_val element, char *key_string); -static void print_json_aux(yajl_val element, int indent, int flags); +static void print_json_aux(yajl_val element, int indent, int flags, bool json_format); /* * Parse text into a JSON tree. If text is valid JSON, returns a @@ -300,13 +300,15 @@ out: return ret; } -static void print_json_string(yajl_val element, int flags) +static void print_json_string(yajl_val element, int flags, bool json_format) { const char *str = YAJL_GET_STRING(element); const char *hexchars = "0123456789ABCDEF"; char hex[7] = { '\\', 'u', '0', '0', '\0', '\0', '\0' }; - putchar('"'); + if (json_format) { + putchar('"'); + } if (str == NULL) { goto out; } @@ -351,7 +353,9 @@ static void print_json_string(yajl_val element, int flags) } out: - putchar('"'); + if (json_format) { + putchar('"'); + } if (!IS_LAST_ELEMENT((unsigned int)flags)) { putchar(','); } @@ -406,7 +410,7 @@ static void print_json_indent(int indent, bool new_line) } } -static void print_json_object(yajl_val element, int indent, int flags) +static void print_json_object(yajl_val element, int indent, int flags, bool json_format) { size_t size = 0; const char *objkey = NULL; @@ -440,9 +444,9 @@ static void print_json_object(yajl_val element, int indent, int flags) printf("\"%s\": ", objkey); if ((i + 1) == size) { - print_json_aux(value, indent + PRINTF_TAB_LEN, LAST_ELEMENT); + print_json_aux(value, indent + PRINTF_TAB_LEN, LAST_ELEMENT, json_format); } else { - print_json_aux(value, indent + PRINTF_TAB_LEN, NOT_LAST_ELEMENT); + print_json_aux(value, indent + PRINTF_TAB_LEN, NOT_LAST_ELEMENT, json_format); } } @@ -455,7 +459,7 @@ static void print_json_object(yajl_val element, int indent, int flags) } } -static void print_json_array(yajl_val element, int indent, int flags) +static void print_json_array(yajl_val element, int indent, int flags, bool json_format) { size_t i = 0; size_t size = 0; @@ -488,9 +492,9 @@ static void print_json_array(yajl_val element, int indent, int flags) value = element->u.array.values[i]; if ((i + 1) == size) { - print_json_aux(value, indent + PRINTF_TAB_LEN, LAST_ELEMENT); + print_json_aux(value, indent + PRINTF_TAB_LEN, LAST_ELEMENT, json_format); } else { - print_json_aux(value, indent + PRINTF_TAB_LEN, NOT_LAST_ELEMENT); + print_json_aux(value, indent + PRINTF_TAB_LEN, NOT_LAST_ELEMENT, json_format); } } print_json_indent(indent, true); @@ -502,7 +506,7 @@ static void print_json_array(yajl_val element, int indent, int flags) } } -static void print_json_aux(yajl_val element, int indent, int flags) +static void print_json_aux(yajl_val element, int indent, int flags, bool json_format) { if (element == NULL) { return; @@ -510,13 +514,13 @@ static void print_json_aux(yajl_val element, int indent, int flags) switch (YAJL_TYPEOF(element)) { case yajl_t_object: - print_json_object(element, indent, flags); + print_json_object(element, indent, flags, json_format); break; case yajl_t_array: - print_json_array(element, indent, flags); + print_json_array(element, indent, flags, json_format); break; case yajl_t_string: - print_json_string(element, flags); + print_json_string(element, flags, json_format); break; case yajl_t_number: print_json_number(element, flags); @@ -540,16 +544,16 @@ static void print_json_aux(yajl_val element, int indent, int flags) /* * Print yajl tree as JSON format. */ -static void print_json(yajl_val tree, int indent) +static void print_json(yajl_val tree, int indent, bool json_format) { if (tree == NULL) { return; } - print_json_aux(tree, indent, LAST_ELEMENT | TOP_LEVEL_OBJ); + print_json_aux(tree, indent, LAST_ELEMENT | TOP_LEVEL_OBJ, json_format); } -static void inspect_show_result(int show_nums, const container_tree_t *tree_array, const char *format) +static void inspect_show_result(int show_nums, const container_tree_t *tree_array, const char *format, bool json_format) { int i = 0; yajl_val tree = NULL; @@ -569,7 +573,7 @@ static void inspect_show_result(int show_nums, const container_tree_t *tree_arra for (i = 0; i < show_nums; i++) { tree = tree_array[i].tree_print; - print_json(tree, indent); + print_json(tree, indent, json_format); if ((i + 1) != show_nums) { if (format == NULL) { @@ -639,7 +643,7 @@ out: #define MATCH_NUM 1 #define CHECK_FAILED (-1) -#define JSON_ARGS "^\\s*\\{\\s*\\{\\s*json\\s+[^\\s]+\\s*.*\\}\\s*\\}\\s*$" +#define JSON_ARGS "^\\s*\\{\\s*\\{\\s*(json)?\\s+[^\\s]+\\s*.*\\}\\s*\\}\\s*$" static int inspect_check(const char *json_str, const char *regex) { @@ -665,7 +669,7 @@ static int inspect_check(const char *json_str, const char *regex) return 0; } -static int inspect_check_format_f(const char *json_str) +static int inspect_check_format_f(const char *json_str, bool *json_format) { int ret = 0; @@ -675,8 +679,11 @@ static int inspect_check_format_f(const char *json_str) } /* check "{{json .xxx.xxx}}" */ - ret = inspect_check(json_str, "^\\s*\\{\\s*\\{\\s*json\\s+(\\.\\w+)+\\s*\\}\\s*\\}\\s*$"); + ret = inspect_check(json_str, "^\\s*\\{\\s*\\{\\s*(json\\s+)?(\\.\\w+)+\\s*\\}\\s*\\}\\s*$"); if (ret == 0) { + if (inspect_check(json_str, "^\\s*\\{\\s*\\{\\s*json\\s+(\\.\\w+)+\\s*\\}\\s*\\}\\s*$") != 0) { + *json_format = false; + } return 0; } @@ -688,17 +695,16 @@ static int inspect_check_format_f(const char *json_str) } /* json args. */ - ret = inspect_check(json_str, "^\\s*\\{\\s*\\{\\s*json\\s*\\}\\s*\\}\\s*$"); + ret = inspect_check(json_str, "^\\s*\\{\\s*\\{\\s*(json)?\\s*\\}\\s*\\}\\s*$"); if (ret == 0) { COMMAND_ERROR("Executing \"\" at : wrong number of args for json: want 1 got 0."); goto out; } /* check "{{json... }}" */ - ret = inspect_check(json_str, "^\\s*\\{\\s*\\{\\s*json\\W.*\\s*\\}\\s*\\}\\s*$"); + ret = inspect_check(json_str, "^\\s*\\{\\s*\\{\\s*(json)?\\W.*\\s*\\}\\s*\\}\\s*$"); if (ret != 0) { - COMMAND_ERROR("Output mode error," - "support function \"json\" only. E.g \"{{json ... }}\" is right."); + COMMAND_ERROR("Output mode error, E.g \"{{json ... }}\" or \"{{ ... }}\" is right."); goto out; } @@ -727,6 +733,7 @@ int cmd_inspect_main(int argc, const char **argv) container_tree_t *tree_array = NULL; size_t array_size = 0; command_t cmd; + bool json_format = true; set_default_command_log_config(argv[0], &lconf); if (client_arguments_init(&g_cmd_inspect_args)) { @@ -773,7 +780,7 @@ int cmd_inspect_main(int argc, const char **argv) if (g_cmd_inspect_args.format != NULL) { int ret; - ret = inspect_check_format_f(g_cmd_inspect_args.format); + ret = inspect_check_format_f(g_cmd_inspect_args.format, &json_format); if (ret != 0) { free(tree_array); tree_array = NULL; @@ -781,7 +788,6 @@ int cmd_inspect_main(int argc, const char **argv) } filter_string = inspect_pause_filter(g_cmd_inspect_args.format); - if (filter_string == NULL) { COMMAND_ERROR("Inspect format parameter invalid: %s", g_cmd_inspect_args.format); free(tree_array); @@ -801,7 +807,7 @@ int cmd_inspect_main(int argc, const char **argv) } if (tree_array != NULL) { - inspect_show_result(success_counts, tree_array, g_cmd_inspect_args.format); + inspect_show_result(success_counts, tree_array, g_cmd_inspect_args.format, json_format); inspect_free_trees(success_counts, tree_array); } free(tree_array); @@ -812,3 +818,4 @@ int cmd_inspect_main(int argc, const char **argv) } exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/information/inspect.h b/src/cmd/lcrc/information/inspect.h index b4a12fe..c83d3ec 100644 --- a/src/cmd/lcrc/information/inspect.h +++ b/src/cmd/lcrc/information/inspect.h @@ -29,3 +29,4 @@ extern struct client_arguments g_cmd_inspect_args; int cmd_inspect_main(int argc, const char **argv); #endif /* __CMD_INSPECT_H */ + diff --git a/src/cmd/lcrc/information/logs.c b/src/cmd/lcrc/information/logs.c index 7985d66..f394796 100644 --- a/src/cmd/lcrc/information/logs.c +++ b/src/cmd/lcrc/information/logs.c @@ -47,7 +47,7 @@ static int do_logs(const struct client_arguments *args) client_connect_config_t config = { 0 }; int ret = 0; - response = util_common_calloc_s(sizeof(struct lcrc_container_conf_response)); + response = util_common_calloc_s(sizeof(struct lcrc_logs_response)); if (response == NULL) { ERROR("Log: Out of memory"); return -1; @@ -150,3 +150,4 @@ int cmd_logs_main(int argc, const char **argv) } return 0; } + diff --git a/src/cmd/lcrc/information/logs.h b/src/cmd/lcrc/information/logs.h index ee94c82..c92314b 100644 --- a/src/cmd/lcrc/information/logs.h +++ b/src/cmd/lcrc/information/logs.h @@ -29,3 +29,4 @@ extern struct client_arguments g_cmd_logs_args; int callback_tail(command_option_t *option, const char *arg); int cmd_logs_main(int argc, const char **argv); #endif /* __CMD_LOGS_H */ + diff --git a/src/cmd/lcrc/information/ps.c b/src/cmd/lcrc/information/ps.c index 224f432..eae9639 100644 --- a/src/cmd/lcrc/information/ps.c +++ b/src/cmd/lcrc/information/ps.c @@ -12,7 +12,12 @@ * Create: 2018-11-08 * Description: provide container ps functions ******************************************************************************/ +#include +#include +#include #include +#include +#include #include #include "securec.h" #include "arguments.h" @@ -26,31 +31,103 @@ const char g_cmd_list_usage[] = "ps [command options]"; #define COMMAND_LENGTH_MAX 22 #define TIME_DURATION_MAX_LEN 32 +#define MAX_TIMESTAMP_LEN 128 struct client_arguments g_cmd_list_args = { .dispname = false, .list_all = false, + .no_trunc = false, }; /* keep track of field widths for printing. */ struct lengths { + /* basic info */ unsigned int id_length; - unsigned int state_length; unsigned int image_length; unsigned int command_length; + unsigned int created_length; + unsigned int status_length; + unsigned int ports_length; + unsigned int name_length; + /* external info */ + unsigned int state_length; unsigned int init_length; unsigned int exit_length; unsigned int rscont_length; unsigned int startat_length; unsigned int finishat_length; unsigned int runtime_length; - unsigned int name_length; }; const char * const g_containerstatusstr[] = { "unknown", "inited", "starting", "running", "exited", "paused", "restarting" }; +struct filter_field { + char *name; + bool is_field; +}; + +struct filters { + struct filter_field **fields; + size_t field_len; +}; + +static void free_filter_field(struct filter_field *field) +{ + if (field == NULL) { + return; + } + free(field->name); + field->name = NULL; + + free(field); +} + +static void free_filters(struct filters *f) +{ + size_t i; + if (f == NULL) { + return; + } + for (i = 0; i < f->field_len; i++) { + free_filter_field(f->fields[i]); + f->fields[i] = NULL; + } + free(f->fields); + f->fields = NULL; + free(f); +} + +static int append_field(struct filters *ff, struct filter_field *field) +{ + struct filter_field **tmp_fields = NULL; + size_t old_size, new_size; + + if (field == NULL) { + return 0; + } + + if (ff->field_len > SIZE_MAX / sizeof(struct filters) - 1) { + ERROR("Too many filter conditions"); + return -1; + } + + old_size = ff->field_len * sizeof(struct filters); + new_size = old_size + sizeof(struct filters); + + if (mem_realloc((void **)(&tmp_fields), new_size, ff->fields, old_size) != 0) { + ERROR("Out of memory"); + return -1; + } + ff->fields = tmp_fields; + + ff->fields[ff->field_len] = field; + ff->field_len++; + + return 0; +} + static const char *lcrc_lcrsta2str(Container_Status sta) { if (sta >= CONTAINER_STATUS_MAX_STATE) { @@ -78,116 +155,322 @@ static void list_print_quiet(struct lcrc_container_summary_info **info, const si } } -static int mix_container_status(const struct lcrc_container_summary_info *in, char *status, size_t len) +static int mix_container_state(const struct lcrc_container_summary_info *in, char *state, size_t len) { int ret = 0; const char *container_status = NULL; container_status = lcrc_lcrsta2str(in->status); if (container_status == NULL) { - ret = strcpy_s(status, len, "-"); + ret = strcpy_s(state, len, "-"); if (ret < 0) { ERROR("Failed to copy string"); ret = -1; goto out; } } else { - if (strcpy_s(status, len, container_status) != EOK) { + if (strcpy_s(state, len, container_status) != EOK) { ERROR("Failed to copy string"); ret = -1; goto out; } - if (in->health_state != NULL) { - if (strcat_s(status, len, in->health_state) != EOK) { - ERROR("Failed to cat string"); - ret = -1; - goto out; - } - } } out: return ret; } -static void ps_print_header(struct lengths *length) +static int handle_running_status(const char *start_at, const struct lcrc_container_summary_info *in, + char *status, size_t len) { - /* print header */ - printf("%-*s ", (int)length->state_length, "STATUS"); - printf("%-*s ", (int)length->init_length, "PID"); - printf("%-*s ", (int)length->image_length, "IMAGE"); - if (length->command_length > COMMAND_LENGTH_MAX) { - printf("%-*s ", COMMAND_LENGTH_MAX, "COMMAND"); - length->command_length = COMMAND_LENGTH_MAX; + int ret = 0; + + if (in->health_state != NULL) { + if (sprintf_s(status, len, "Up %s %s", start_at, in->health_state) < 0) { + ERROR("Failed to compose string"); + ret = -1; + goto out; + } } else { - printf("%-*s ", (int)length->command_length, "COMMAND"); + if (sprintf_s(status, len, "Up %s", start_at) < 0) { + ERROR("Failed to compose string"); + ret = -1; + goto out; + } } - printf("%-*s ", (int)length->exit_length, "EXIT_CODE"); - printf("%-*s ", (int)length->rscont_length, "RESTART_COUNT"); - printf("%-*s ", (int)length->startat_length, "STARTAT"); - printf("%-*s ", (int)length->finishat_length, "FINISHAT"); - printf("%-*s ", (int)length->runtime_length, "RUNTIME"); - printf("%-*s ", (int)length->id_length, "ID"); - printf("%-*s ", (int)length->name_length, "NAMES"); - printf("\n"); + +out: + return ret; } -static void ps_print_container_info_pre(const struct lcrc_container_summary_info *in, const char *status, - const struct lengths *length) +static int mix_container_status(const struct lcrc_container_summary_info *in, char *status, size_t len) { - const char *cmd = (in->command != NULL) ? in->command : "-"; - int cmd_len = (int)strlen(cmd); - - printf("%-*s ", (int)length->state_length, status); - if (in->has_pid) { - printf("%-*u ", (int)length->init_length, in->pid); - } else { - printf("%-*s ", (int)length->init_length, "-"); - } - printf("%-*s ", (int)length->image_length, in->image ? in->image : "none"); - if (cmd_len > COMMAND_LENGTH_MAX - 2) { - printf("\"%-*.*s...\" ", COMMAND_LENGTH_MAX - 5, COMMAND_LENGTH_MAX - 5, cmd); - } else { - int space_len = ((int)(length->command_length) - cmd_len) - 2; - printf("\"%-*.*s\"%*s ", cmd_len, cmd_len, cmd, space_len, (space_len == 0) ? "" : " "); - } -} - -static void ps_print_container_info(const struct lcrc_container_summary_info *in, const char *status, - const struct lengths *length) -{ - char finishat_duration[TIME_DURATION_MAX_LEN] = { 0 }; + int ret = -1; char startat_duration[TIME_DURATION_MAX_LEN] = { 0 }; - - ps_print_container_info_pre(in, status, length); - - printf("%-*u ", (int)length->exit_length, in->exit_code); - printf("%-*u ", (int)length->rscont_length, in->restart_count); + char finishat_duration[TIME_DURATION_MAX_LEN] = { 0 }; + char *start_at = NULL; + char *finish_at = NULL; time_format_duration(in->startat, startat_duration, sizeof(startat_duration)); - printf("%-*s ", (int)length->startat_length, in->startat ? startat_duration : "-"); - time_format_duration(in->finishat, finishat_duration, sizeof(finishat_duration)); - printf("%-*s ", (int)length->finishat_length, in->finishat ? finishat_duration : "-"); - printf("%-*s ", (int)length->runtime_length, in->runtime ? in->runtime : "lcr"); - printf("%-*.*s ", (int)length->id_length, (int)length->id_length, in->id ? in->id : "-"); - printf("%-*s ", (int)length->name_length, in->name ? in->name : "-"); + time_format_duration_ago(in->finishat, finishat_duration, sizeof(finishat_duration)); + start_at = in->startat ? startat_duration : "-"; + finish_at = in->finishat ? finishat_duration : "-"; + + if (in->status == CONTAINER_STATUS_RUNNING) { + if (handle_running_status(start_at, in, status, len) != 0) { + goto out; + } + } else if (in->status == CONTAINER_STATUS_CREATED) { + if (sprintf_s(status, len, "Created") < 0) { + goto out; + } + } else if (in->status == CONTAINER_STATUS_RESTARTING) { + if (sprintf_s(status, len, "Restarting (%d) %s", (int)in->exit_code, finish_at) < 0) { + goto out; + } + } else if (in->status == CONTAINER_STATUS_PAUSED) { + if (sprintf_s(status, len, "Up %s (Paused)", start_at) < 0) { + goto out; + } + } else if (in->status == CONTAINER_STATUS_STARTING) { + if (sprintf_s(status, len, "Starting %s", start_at) < 0) { + goto out; + } + } else { + if (sprintf_s(status, len, "Exited (%d) %s", (int)in->exit_code, finish_at) < 0) { + goto out; + } + } + + ret = 0; + +out: + return ret; +} + +static void printf_enable_interpretation_of_backslash_escapes(const char *str) +{ + unsigned char ch; + char const *s = str; + + if (str == NULL) { + return; + } + + ch = *s++; + while (ch != '\0') { + if (*s != '\0' && ch == '\\') { + ch = *s++; + switch (ch) { + case 'n': + ch = '\n'; + break; + case 't': + ch = '\t'; + break; + case '\\': + break; + default: + putchar('\\'); + break; + } + } + putchar(ch); + ch = *s++; + } +} + +static bool should_print_table_header(const struct filters *ff) +{ + return ff != NULL && ff->field_len != 0 && ff->fields[0]->name != NULL && + strcmp(ff->fields[0]->name, "table") == 0 && ff->fields[0]->is_field; +} + +static void print_table_header_item(const char *name, struct lengths *length) +{ + if (strcmp(name, "ID") == 0) { + printf("%-*s", (int)length->id_length, "CONTAINER ID"); + } else if (strcmp(name, "Image") == 0) { + printf("%-*s", (int)length->image_length, "IMAGE"); + } else if (strcmp(name, "Status") == 0) { + printf("%-*s", (int)length->status_length, "STATUS"); + } else if (strcmp(name, "Pid") == 0) { + printf("%-*s", (int)length->init_length, "PID"); + } else if (strcmp(name, "Command") == 0) { + if (length->command_length > COMMAND_LENGTH_MAX) { + printf("%-*s", COMMAND_LENGTH_MAX, "COMMAND"); + length->command_length = COMMAND_LENGTH_MAX; + } else { + printf("%-*s", (int)length->command_length, "COMMAND"); + } + } else if (strcmp(name, "ExitCode") == 0) { + printf("%-*s", (int)length->exit_length, "EXIT_CODE"); + } else if (strcmp(name, "RestartCount") == 0) { + printf("%-*s", (int)length->rscont_length, "RESTART_COUNT"); + } else if (strcmp(name, "StartAt") == 0) { + printf("%-*s", (int)length->startat_length, "STARTAT"); + } else if (strcmp(name, "FinishAt") == 0) { + printf("%-*s", (int)length->finishat_length, "FINISHAT"); + } else if (strcmp(name, "Runtime") == 0) { + printf("%-*s", (int)length->runtime_length, "RUNTIME"); + } else if (strcmp(name, "Names") == 0) { + printf("%-*s", (int)length->name_length, "NAMES"); + } else if (strcmp(name, "Created") == 0) { + printf("%-*s", (int)length->created_length, "CREATED"); + } else if (strcmp(name, "Ports") == 0) { + printf("%-*s", (int)length->ports_length, "PORTS"); + } else if (strcmp(name, "State") == 0) { + printf("%-*s", (int)length->state_length, "STATE"); + } +} + +static void ps_print_header(struct lengths *length, const struct filters *ff) +{ + size_t i; + + if (!should_print_table_header(ff)) { + return; + } + + /* print header */ + for (i = 1; i < ff->field_len; i++) { + if (ff->fields[i]->is_field) { + print_table_header_item(ff->fields[i]->name, length); + } else { + printf_enable_interpretation_of_backslash_escapes(ff->fields[i]->name); + } + } printf("\n"); } -static void list_print_table(struct lcrc_container_summary_info **info, const size_t size, struct lengths *length) +static int get_created_time_buffer(int64_t created, char *timebuffer, size_t len) { + types_timestamp_t timestamp; + + if (!unix_nanos_to_timestamp(created, ×tamp)) { + ERROR("Failed to get timestamp"); + return -1; + } + if (!get_time_buffer(×tamp, timebuffer, len)) { + ERROR("Failed to get timebuffer from timestamp"); + return -1; + } + + return 0; +} +static void print_created_field(int64_t created, unsigned int length) +{ + char timebuffer[MAX_TIMESTAMP_LEN] = { 0 }; + char created_duration[TIME_DURATION_MAX_LEN] = { 0 }; + + if (get_created_time_buffer(created, timebuffer, MAX_TIMESTAMP_LEN) != 0) { + return; + } + if (time_format_duration_ago(timebuffer, created_duration, sizeof(created_duration)) != 0) { + return; + } + printf("%-*s", (int)length, created_duration); +} + +static void print_basic_container_info_item(const struct lcrc_container_summary_info *in, const char *status, + const char *name, const struct lengths *length) +{ + if (strcmp(name, "ID") == 0) { + printf("%-*.*s", (int)length->id_length, (int)length->id_length, in->id ? in->id : "-"); + } else if (strcmp(name, "Image") == 0) { + printf("%-*s", (int)length->image_length, in->image ? in->image : "none"); + } else if (strcmp(name, "Status") == 0) { + printf("%-*s", (int)length->status_length, status); + } else if (strcmp(name, "Pid") == 0) { + if (in->has_pid) { + printf("%-*u", (int)length->init_length, in->pid); + } else { + printf("%-*s", (int)length->init_length, "-"); + } + } else if (strcmp(name, "Command") == 0) { + const char *cmd = (in->command != NULL) ? in->command : "-"; + int cmd_len = (int)strlen(cmd); + if (cmd_len > COMMAND_LENGTH_MAX - 2) { + printf("\"%-*.*s...\" ", COMMAND_LENGTH_MAX - 5, COMMAND_LENGTH_MAX - 5, cmd); + } else { + int space_len = ((int)(length->command_length) - cmd_len) - 2; + printf("\"%-*.*s\"%*s", cmd_len, cmd_len, cmd, space_len, (space_len == 0) ? "" : " "); + } + } else if (strcmp(name, "Created") == 0) { + print_created_field(in->created, length->created_length); + } else if (strcmp(name, "Ports") == 0) { + printf("%-*s", (int)length->ports_length, " "); + } +} + + +static void print_extern_container_info_item(const struct lcrc_container_summary_info *in, const char *state, + const char *name, const struct lengths *length) +{ + if (strcmp(name, "ExitCode") == 0) { + printf("%-*u", (int)length->exit_length, in->exit_code); + } else if (strcmp(name, "RestartCount") == 0) { + printf("%-*u", (int)length->rscont_length, in->restart_count); + } else if (strcmp(name, "StartAt") == 0) { + char startat_duration[TIME_DURATION_MAX_LEN] = { 0 }; + time_format_duration(in->startat, startat_duration, sizeof(startat_duration)); + printf("%-*s", (int)length->startat_length, in->startat ? startat_duration : "-"); + } else if (strcmp(name, "FinishAt") == 0) { + char finishat_duration[TIME_DURATION_MAX_LEN] = { 0 }; + time_format_duration(in->finishat, finishat_duration, sizeof(finishat_duration)); + printf("%-*s", (int)length->finishat_length, in->finishat ? finishat_duration : "-"); + } else if (strcmp(name, "Runtime") == 0) { + printf("%-*s", (int)length->runtime_length, in->runtime ? in->runtime : "lcr"); + } else if (strcmp(name, "Names") == 0) { + printf("%-*s", (int)length->name_length, in->name ? in->name : "-"); + } else if (strcmp(name, "State") == 0) { + printf("%-*s", (int)length->state_length, state); + } +} +static void print_container_info_item(const struct lcrc_container_summary_info *in, const char *state, + const char *status, const char *name, const struct lengths *length) +{ + print_basic_container_info_item(in, status, name, length); + print_extern_container_info_item(in, state, name, length); +} + +static void ps_print_container_info(const struct lcrc_container_summary_info *in, const char *state, + const char *status, const struct lengths *length, const struct filters *ff) +{ + size_t i = should_print_table_header(ff) ? 1 : 0; + + for (; i < ff->field_len; i++) { + if (ff->fields[i]->is_field) { + print_container_info_item(in, state, status, ff->fields[i]->name, length); + } else { + printf_enable_interpretation_of_backslash_escapes(ff->fields[i]->name); + } + } + printf("\n"); +} + +static void list_print_table(struct lcrc_container_summary_info **info, const size_t size, + struct lengths *length, const struct filters *ff) +{ +#define MAX_STATE_LEN 32 +#define MAX_STATUS_LEN 100 const struct lcrc_container_summary_info *in = NULL; size_t i = 0; - char status[32] = { 0 }; - ps_print_header(length); + char state[MAX_STATE_LEN] = { 0 }; + char status[MAX_STATUS_LEN] = { 0 }; + ps_print_header(length, ff); for (i = 0; i < size; i++) { in = info[i]; - if (mix_container_status(in, status, sizeof(status))) { + if (mix_container_state(in, state, sizeof(state))) { + ERROR("Failed to mix container state"); return; } - - ps_print_container_info(in, status, length); + if (mix_container_status(in, status, sizeof(status))) { + ERROR("Failed to mix container status"); + return; + } + ps_print_container_info(in, state, status, length, ff); } } @@ -207,12 +490,26 @@ static void calculate_str_length(const char *str, unsigned int *length) static void calculate_status_str_length(const struct lcrc_container_summary_info *in, unsigned int *length) { - const char *status = NULL; +#define MAX_STATUS_LEN 100 + size_t len; + char status[MAX_STATUS_LEN] = { 0 }; + if (mix_container_status(in, status, sizeof(status))) { + return; + } + len = strlen(status); + if (len > (*length)) { + *length = (unsigned int)len; + } +} - status = lcrc_lcrsta2str(in->status); - if (status != NULL) { +static void calculate_state_str_length(const struct lcrc_container_summary_info *in, unsigned int *length) +{ + const char *state = NULL; + + state = lcrc_lcrsta2str(in->status); + if (state != NULL) { size_t len; - len = strlen(status); + len = strlen(state); if (in->health_state != NULL) { len += strlen(in->health_state); } @@ -221,7 +518,6 @@ static void calculate_status_str_length(const struct lcrc_container_summary_info } } } - static void calculate_uint_str_length(uint32_t data, unsigned int *length) { int len = 0; @@ -242,15 +538,27 @@ static void calculate_time_str_length(const char *str, unsigned int *length) size_t len = 0; char time_duration[TIME_DURATION_MAX_LEN]; - if (time_format_duration(str, time_duration, sizeof(time_duration)) < 0) { + if (time_format_duration_ago(str, time_duration, sizeof(time_duration)) < 0) { ERROR("Format time duration failed"); } + len = strlen(time_duration); if (len > (*length)) { *length = (unsigned int)len; } } +static void calculate_created_str_length(int64_t created, unsigned int *length) +{ + char timebuffer[MAX_TIMESTAMP_LEN] = { 0 }; + + if (get_created_time_buffer(created, timebuffer, MAX_TIMESTAMP_LEN) != 0) { + return; + } + + calculate_time_str_length(timebuffer, length); +} + static void list_field_width(struct lcrc_container_summary_info **info, const size_t size, struct lengths *l) { size_t i = 0; @@ -262,14 +570,11 @@ static void list_field_width(struct lcrc_container_summary_info **info, const si for (i = 0; i < size; i++, in++) { in = info[i]; - calculate_str_length(in->name, &l->name_length); - calculate_str_length(in->runtime, &l->runtime_length); - calculate_status_str_length(in, &l->state_length); - if (in->pid != -1) { - calculate_uint_str_length(in->pid, &l->init_length); + if (g_cmd_list_args.no_trunc) { + calculate_str_length(in->id, &l->id_length); } - calculate_str_length(in->image, &l->image_length); + calculate_created_str_length(in->created, &l->created_length); if (in->command != NULL) { size_t cmd_len; cmd_len = strlen(in->command) + 2; @@ -278,6 +583,14 @@ static void list_field_width(struct lcrc_container_summary_info **info, const si } } + calculate_str_length(in->name, &l->name_length); + calculate_str_length(in->runtime, &l->runtime_length); + calculate_status_str_length(in, &l->status_length); + calculate_state_str_length(in, &l->state_length); + if (in->pid != -1) { + calculate_uint_str_length(in->pid, &l->init_length); + } + calculate_uint_str_length(in->exit_code, &l->exit_length); calculate_uint_str_length(in->restart_count, &l->rscont_length); @@ -304,7 +617,7 @@ static inline int lcrc_container_cmp(struct lcrc_container_summary_info **first, /* * Create a list request message and call RPC */ -static int client_list(const struct client_arguments *args) +static int client_list(const struct client_arguments *args, const struct filters *ff) { lcrc_connect_ops *ops = NULL; struct lcrc_list_request request = { 0 }; @@ -312,16 +625,20 @@ static int client_list(const struct client_arguments *args) client_connect_config_t config = { 0 }; int ret = 0; struct lengths max_len = { - .name_length = 5, /* NAMES */ - .id_length = 12, /* ID */ - .state_length = 5, /* STATE */ + .id_length = 12, /* CONTAINER ID */ .image_length = 5, /* IMAGE */ .command_length = 7, /* COMMAND */ + .created_length = 7, /* CREATED */ + .status_length = 6, /* STATUS */ + .ports_length = 5, /* PORTS */ + .name_length = 5, /* NAMES */ + + .state_length = 5, /* STATE */ .init_length = 3, /* PID */ - .exit_length = 9, /* EXIT_CODE*/ - .rscont_length = 13, /* RESTART_COUNT*/ - .startat_length = 7, /* STARTAT*/ - .finishat_length = 8, /* FINISHAT*/ + .exit_length = 9, /* EXIT_CODE */ + .rscont_length = 13, /* RESTART_COUNT */ + .startat_length = 7, /* STARTAT */ + .finishat_length = 8, /* FINISHAT */ .runtime_length = 7, /* RUNTIME */ }; @@ -332,7 +649,7 @@ static int client_list(const struct client_arguments *args) } ops = get_connect_client_ops(); - if (ops == NULL || !ops->container.list) { + if (ops == NULL || ops->container.list == NULL) { ERROR("Unimplemented ops"); ret = -1; goto out; @@ -341,7 +658,7 @@ static int client_list(const struct client_arguments *args) if (args->filters != NULL) { request.filters = lcrc_filters_parse_args((const char **)args->filters, util_array_len((const char **)(args->filters))); - if (!request.filters) { + if (request.filters == NULL) { ERROR("Failed to parse filters args"); ret = -1; goto out; @@ -363,7 +680,7 @@ static int client_list(const struct client_arguments *args) list_print_quiet(response->container_summary, response->container_num, &max_len); } else { list_field_width(response->container_summary, response->container_num, &max_len); - list_print_table(response->container_summary, response->container_num, &max_len); + list_print_table(response->container_summary, response->container_num, &max_len, ff); } out: @@ -372,10 +689,300 @@ out: return ret; } +static int append_header_field(const char **index, struct filters *ff) +{ + int ret = 0; + struct filter_field *tmp = NULL; + + if (strncmp(*index, "table", strlen("table")) != 0) { + return 0; + } + + tmp = (struct filter_field *)util_common_calloc_s(sizeof(struct filter_field)); + if (tmp == NULL) { + ERROR("Out of memory"); + return -1; + } + tmp->name = util_strdup_s("table"); + tmp->is_field = true; + if (append_field(ff, tmp) != 0) { + ret = -1; + goto out; + } + *index += strlen("table"); + tmp = NULL; + +out: + free_filter_field(tmp); + return ret; +} + +static int append_first_non_header_field(const char *index, struct filters *ff) +{ + int ret = 0; + char *prefix = strstr(index, "{{"); + struct filter_field *tmp = NULL; + char *first_non_field = NULL; + + if (prefix == NULL) { + return 0; + } + + first_non_field = util_sub_string(index, 0, prefix - index); + if (util_is_space_string(first_non_field)) { + goto out; + } + tmp = (struct filter_field *)util_common_calloc_s(sizeof(struct filter_field)); + if (tmp == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + tmp->name = first_non_field; + tmp->is_field = false; + if (append_field(ff, tmp) != 0) { + ERROR("Failed to append field"); + ret = -1; + goto out; + } + tmp = NULL; + first_non_field = NULL; + +out: + free_filter_field(tmp); + free(first_non_field); + return ret; +} + +static int get_header_field(const char *patten, struct filters *ff) +{ + const char *index = patten; + + if (append_header_field(&index, ff) != 0) { + ERROR("Failed to append header field"); + return -1; + } + + if (append_first_non_header_field(index, ff) != 0) { + ERROR("Failed to append first non header field"); + return -1; + } + + return 0; +} + +static int format_field_check(const char *source, const char *patten) +{ +#define MATCH_NUM 1 +#define CHECK_FAILED (-1) + int status = 0; + regmatch_t pmatch[MATCH_NUM] = { { 0 } }; + regex_t reg; + + if (source == NULL) { + ERROR("Filter string is NULL."); + return CHECK_FAILED; + } + + regcomp(®, patten, REG_EXTENDED); + + status = regexec(®, source, MATCH_NUM, pmatch, 0); + regfree(®); + + if (status != 0) { + return CHECK_FAILED; + } + + return 0; +} + +/* arg string format: "{{json .State.Running}}" + * ret_string should be free outside by free(). + */ +static char *get_filter_string(const char *arg) +{ + char *input_str = NULL; + char *p = NULL; + char *ret_string = NULL; + char *next_context = NULL; + + input_str = util_strdup_s(arg); + + p = strtok_s(input_str, ".", &next_context); + if (p == NULL) { + goto out; + } + + p = next_context; + if (p == NULL) { + goto out; + } + + p = strtok_s(p, " }", &next_context); + if (p == NULL) { + goto out; + } + + ret_string = util_strdup_s(p); + +out: + free(input_str); + return ret_string; +} + +static bool valid_format_field(const char *field) +{ + size_t i; + const char *support_field[] = { + "ID", "Image", "Command", "Created", "Status", "Ports", "Names", // basic info + "Pid", "ExitCode", "RestartCount", "StartAt", "FinishAt", "Runtime", "State" // external info + }; + + for (i = 0; i < sizeof(support_field) / sizeof(char *); i++) { + if (strcmp(field, support_field[i]) == 0) { + return true; + } + } + + return false; +} + +static int append_header_item_field(const char *index, const char *prefix, const char *suffix, struct filters *ff) +{ +#define SINGLE_PATTEN "\\{\\{\\s*\\.\\w+\\s*\\}\\}" + int ret = 0; + char *filter_string = NULL; + struct filter_field *field = NULL; + char *sub_patten = util_sub_string(index, prefix - index, suffix - prefix + 2); + + if (format_field_check(sub_patten, SINGLE_PATTEN) != 0) { + COMMAND_ERROR("invalid format field: %s", sub_patten); + ret = -1; + goto out; + } + + filter_string = get_filter_string(sub_patten); + if (filter_string == NULL) { + ERROR("Invalid filter: %s", sub_patten); + ret = -1; + goto out; + } + + field = (struct filter_field *)util_common_calloc_s(sizeof(struct filter_field)); + if (field == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + if (!valid_format_field(filter_string)) { + COMMAND_ERROR("--format not support the field: %s", filter_string); + ret = -1; + goto out; + } + field->name = filter_string; + field->is_field = true; + if (append_field(ff, field) != 0) { + ERROR("Failed to append field"); + ret = -1; + goto out; + } + + field = NULL; + filter_string = NULL; + +out: + free(sub_patten); + free(filter_string); + free_filter_field(field); + return ret; +} + +static int append_non_header_item_field(const char *prefix, const char *non_field, struct filters *ff) +{ + int ret = 0; + char *non_field_string = NULL; + struct filter_field *field = NULL; + + if (prefix == NULL) { + non_field_string = util_strdup_s(non_field); + } else { + non_field_string = util_sub_string(non_field, 0, prefix - non_field); + } + field = (struct filter_field *)util_common_calloc_s(sizeof(struct filter_field)); + if (field == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + field->name = non_field_string; + field->is_field = false; + if (append_field(ff, field) != 0) { + ERROR("Failed to append field"); + ret = -1; + goto out; + } + non_field_string = NULL; + field = NULL; + +out: + free_filter_field(field); + free(non_field_string); + return ret; +} + +static int get_filter_field(const char *patten, struct filters *ff) +{ +#define SINGLE_PATTEN "\\{\\{\\s*\\.\\w+\\s*\\}\\}" +#define DEFAULT_CONTAINER_TABLE_FORMAT "table {{.ID}}\t{{.Image}}\t{{.Command}}\t" \ + "{{.Created}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}" + const char *prefix = NULL; + const char *suffix = NULL; + const char *index = patten; + + if (patten == NULL || strcmp(index, "table") == 0) { + index = DEFAULT_CONTAINER_TABLE_FORMAT; + } + + if (get_header_field(index, ff) != 0) { + ERROR("failed to get header field"); + return -1; + } + prefix = strstr(index, "{{"); + if (prefix == NULL) { + return 0; + } + + suffix = strstr(index, "}}"); + while (prefix != NULL && suffix != NULL) { + if (append_header_item_field(index, prefix, suffix, ff) != 0) { + ERROR("failed to append header item field"); + return -1; + } + if (strlen(suffix + 2) == 0) { + return 0; + } + prefix = strstr(suffix + 2, "{{"); + if (append_non_header_item_field(prefix, suffix + 2, ff) != 0) { + ERROR("failed to append non-header item field"); + return -1; + } + + index = prefix; + if (index != NULL) { + suffix = strstr(index, "}}"); + } else { + suffix = NULL; + } + } + + return 0; +} + int cmd_list_main(int argc, const char **argv) { struct log_config lconf = { 0 }; command_t cmd; + struct filters *ff = NULL; set_default_command_log_config(argv[0], &lconf); if (client_arguments_init(&g_cmd_list_args)) { @@ -403,11 +1010,26 @@ int cmd_list_main(int argc, const char **argv) COMMAND_ERROR("%s: \"ps\" requires 0 arguments.", g_cmd_list_args.progname); exit(ECOMMON); } - if (client_list(&g_cmd_list_args)) { + + ff = (struct filters *)util_common_calloc_s(sizeof(struct filters)); + if (ff == NULL) { + ERROR("Out of memory"); + exit(EXIT_FAILURE); + } + + if (get_filter_field(g_cmd_list_args.format, ff) != 0) { + free_filters(ff); + COMMAND_ERROR("Failed to get filter field"); + exit(EXIT_FAILURE); + } + + if (client_list(&g_cmd_list_args, ff)) { + free_filters(ff); ERROR("Can not ps any containers"); exit(ECOMMON); } + free_filters(ff); exit(EXIT_SUCCESS); } diff --git a/src/cmd/lcrc/information/ps.h b/src/cmd/lcrc/information/ps.h index e7d2bf4..65b77d0 100644 --- a/src/cmd/lcrc/information/ps.h +++ b/src/cmd/lcrc/information/ps.h @@ -22,7 +22,11 @@ "Display all containers (default shows just running)", NULL }, \ { CMD_OPT_TYPE_BOOL, false, "quiet", 'q', &(cmdargs).dispname, "Only display numeric IDs", NULL }, \ { CMD_OPT_TYPE_CALLBACK, false, "filter", 'f', &(cmdargs).filters, \ - "Filter output based on conditions provided", command_append_array } + "Filter output based on conditions provided", command_append_array }, \ + { CMD_OPT_TYPE_BOOL, false, "no-trunc", 0, &(cmdargs).no_trunc, \ + "Don't truncate output", NULL }, \ + { CMD_OPT_TYPE_STRING, false, "format", 0, &(cmdargs).format, \ + "Format the output using the given go template", NULL } extern const char g_cmd_list_desc[]; extern const char g_cmd_list_usage[]; @@ -30,3 +34,4 @@ extern struct client_arguments g_cmd_list_args; int cmd_list_main(int argc, const char **argv); #endif /* __CMD_LIST_H */ + diff --git a/src/cmd/lcrc/information/top.h b/src/cmd/lcrc/information/top.h index 9da190c..f96d780 100644 --- a/src/cmd/lcrc/information/top.h +++ b/src/cmd/lcrc/information/top.h @@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_top_args; int cmd_top_main(int argc, const char **argv); #endif /* __CMD_TOP_H */ + diff --git a/src/cmd/lcrc/information/version.h b/src/cmd/lcrc/information/version.h index fa6291b..e8bab52 100644 --- a/src/cmd/lcrc/information/version.h +++ b/src/cmd/lcrc/information/version.h @@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_version_args; int cmd_version_main(int argc, const char **argv); #endif /* __CMD_VERSION_H */ + diff --git a/src/cmd/lcrc/information/wait.c b/src/cmd/lcrc/information/wait.c index 9b29281..de6b88f 100644 --- a/src/cmd/lcrc/information/wait.c +++ b/src/cmd/lcrc/information/wait.c @@ -131,3 +131,4 @@ int cmd_wait_main(int argc, const char **argv) exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/information/wait.h b/src/cmd/lcrc/information/wait.h index 658f73e..b9f89c2 100644 --- a/src/cmd/lcrc/information/wait.h +++ b/src/cmd/lcrc/information/wait.h @@ -24,3 +24,4 @@ int cmd_wait_main(int argc, const char **argv); int client_wait(const struct client_arguments *args, unsigned int *exit_code); #endif /* __CMD_WAIT_H */ + diff --git a/src/cmd/lcrc/main.c b/src/cmd/lcrc/main.c index 6fe1590..8e32e70 100644 --- a/src/cmd/lcrc/main.c +++ b/src/cmd/lcrc/main.c @@ -30,6 +30,8 @@ #include "rmi.h" #include "wait.h" #include "restart.h" +#include "pause.h" +#include "resume.h" #include "logs.h" #include "kill.h" #include "load.h" @@ -78,6 +80,14 @@ struct command g_commands[] = { // `inspect` sub-command "inspect", cmd_inspect_main, g_cmd_inspect_desc, NULL, &g_cmd_inspect_args }, + { + // `pause` sub-command + "pause", cmd_pause_main, g_cmd_pause_desc, NULL, &g_cmd_pause_args + }, + { + // `unpause` sub-command + "unpause", cmd_resume_main, g_cmd_resume_desc, NULL, &g_cmd_resume_args + }, #ifdef ENABLE_OCI_IMAGE { // `stats` sub-command @@ -186,3 +196,4 @@ int main(int argc, char **argv) } return run_command(g_commands, argc, (const char **)argv); } + diff --git a/src/cmd/lcrc/stream/attach.c b/src/cmd/lcrc/stream/attach.c index 05706d7..c28c241 100644 --- a/src/cmd/lcrc/stream/attach.c +++ b/src/cmd/lcrc/stream/attach.c @@ -387,3 +387,4 @@ int cmd_attach_main(int argc, const char **argv) out: exit((exit_code != 0) ? (int)exit_code : ret); } + diff --git a/src/cmd/lcrc/stream/attach.h b/src/cmd/lcrc/stream/attach.h index e83a89f..41147d0 100644 --- a/src/cmd/lcrc/stream/attach.h +++ b/src/cmd/lcrc/stream/attach.h @@ -25,3 +25,4 @@ extern struct client_arguments g_cmd_attach_args; int inspect_container(const struct client_arguments *args, container_inspect **inspect_data); int cmd_attach_main(int argc, const char **argv); #endif /* __CMD_ATTACH_H */ + diff --git a/src/cmd/lcrc/stream/cp.c b/src/cmd/lcrc/stream/cp.c index ae5a10f..2aa8f44 100644 --- a/src/cmd/lcrc/stream/cp.c +++ b/src/cmd/lcrc/stream/cp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -348,3 +348,4 @@ int cmd_cp_main(int argc, const char **argv) exit(EXIT_SUCCESS); } + diff --git a/src/cmd/lcrc/stream/cp.h b/src/cmd/lcrc/stream/cp.h index 4a22dbe..c94a694 100644 --- a/src/cmd/lcrc/stream/cp.h +++ b/src/cmd/lcrc/stream/cp.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_cp_args; int cmd_cp_main(int argc, const char **argv); #endif /* __CMD_COPY_H */ + diff --git a/src/cmd/lcrc/stream/exec.c b/src/cmd/lcrc/stream/exec.c index 29ea7ea..313022d 100644 --- a/src/cmd/lcrc/stream/exec.c +++ b/src/cmd/lcrc/stream/exec.c @@ -64,6 +64,7 @@ static int client_exec(const struct client_arguments *args, const struct command request.stderr = fifos->stderr_name; } + request.user = args->custom_conf.user; request.argc = args->argc; request.argv = (char **)args->argv; diff --git a/src/cmd/lcrc/stream/exec.h b/src/cmd/lcrc/stream/exec.h index 76f3387..37e4cd6 100644 --- a/src/cmd/lcrc/stream/exec.h +++ b/src/cmd/lcrc/stream/exec.h @@ -24,7 +24,9 @@ { CMD_OPT_TYPE_BOOL, false, "detach", 'd', &(cmdargs).detach, "Run container in background", NULL }, \ { CMD_OPT_TYPE_BOOL, false, "tty", 't', &(cmdargs).custom_conf.tty, "Allocate a pseudo-TTY", NULL }, \ { CMD_OPT_TYPE_BOOL, false, "interactive", 'i', &(cmdargs).custom_conf.open_stdin, \ - "Keep STDIN open even if not attached", NULL } + "Keep STDIN open even if not attached", NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "user", 'u', &(cmdargs).custom_conf.user, \ + "Username or UID (format: [:])", NULL } extern const char g_cmd_exec_desc[]; extern const char g_cmd_exec_usage[]; @@ -32,3 +34,4 @@ extern struct client_arguments g_cmd_exec_args; int cmd_exec_main(int argc, const char **argv); #endif /* __CMD_EXEC_H */ + diff --git a/src/cmd/lcrd/arguments.c b/src/cmd/lcrd/arguments.c index 4567999..4105ae4 100644 --- a/src/cmd/lcrd/arguments.c +++ b/src/cmd/lcrd/arguments.c @@ -141,6 +141,7 @@ int service_arguments_init(struct service_arguments *args) args->json_confs->native_umask = util_strdup_s(UMASK_SECURE); args->json_confs->image_service = true; args->json_confs->image_layer_check = false; + args->json_confs->image_server_sock_addr = util_strdup_s(DEFAULT_IM_SERVER_SOCK_ADDR); args->json_confs->use_decrypted_key = (bool *)util_common_calloc_s(sizeof(bool)); if (args->json_confs->use_decrypted_key == NULL) { goto free_out; @@ -148,7 +149,7 @@ int service_arguments_init(struct service_arguments *args) *(args->json_confs->use_decrypted_key) = true; args->json_confs->insecure_skip_verify_enforce = false; - args->im_opt_timeout = 5 * 60; // default image operation timeout 300s + args->image_opt_timeout = 5 * 60; // default image operation timeout 300s if (set_daemon_default_tls_options(args) != 0) { goto free_out; } @@ -242,3 +243,4 @@ out: free(tmp); return ret; } + diff --git a/src/cmd/lcrd/arguments.h b/src/cmd/lcrd/arguments.h index 0021411..d1e37ef 100644 --- a/src/cmd/lcrd/arguments.h +++ b/src/cmd/lcrd/arguments.h @@ -46,7 +46,7 @@ struct service_arguments { oci_runtime_spec_hooks *hooks; unsigned int start_timeout; - unsigned int im_opt_timeout; + unsigned int image_opt_timeout; /* log-opts */ unsigned int log_file_mode; @@ -68,4 +68,5 @@ int service_arguments_init(struct service_arguments *args); void service_arguments_free(struct service_arguments *args); int server_log_opt_parser(struct service_arguments *args, const char *option); -#endif /*__LCRD_ARGUMENTS_H*/ +#endif /* __LCRD_ARGUMENTS_H */ + diff --git a/src/cmd/lcrd/commands.c b/src/cmd/lcrd/commands.c index 4a8f8d4..a5d1e39 100644 --- a/src/cmd/lcrd/commands.c +++ b/src/cmd/lcrd/commands.c @@ -266,6 +266,14 @@ int check_args(struct service_arguments *args) goto out; } +#ifdef ENABLE_OCI_IMAGE + if (!util_validate_unix_socket(args->json_confs->image_server_sock_addr)) { + COMMAND_ERROR("Invalid image server socket: %s", args->json_confs->image_server_sock_addr); + ret = -1; + goto out; + } +#endif + /* validate statepath format */ if (check_args_state_path(args) != 0) { ret = -1; diff --git a/src/cmd/lcrd/commands.h b/src/cmd/lcrd/commands.h index 9038d2f..3f99805 100644 --- a/src/cmd/lcrd/commands.h +++ b/src/cmd/lcrd/commands.h @@ -68,9 +68,11 @@ int update_default_ulimit(struct service_arguments *args); "Set parent cgroup for all containers", NULL }, \ { CMD_OPT_TYPE_STRING_DUP, false, "pod-sandbox-image", 0, &(cmdargs)->json_confs->pod_sandbox_image, \ "The image whose network/ipc namespaces containers in each pod will use. " \ - "(default \"rnd-dockerhub.huawei.com/library/pause-${machine}:3.0\")", NULL }, \ - { CMD_OPT_TYPE_STRING_DUP, false, "image-opt-timeout", 0, &(cmdargs)->json_confs->im_opt_timeout, \ + "(default \"pause-${machine}:3.0\")", NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "image-opt-timeout", 0, &(cmdargs)->json_confs->image_opt_timeout, \ "Max timeout(default 5m) for image operation", NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "image_server_sock_addr", 0, &(cmdargs)->json_confs->image_server_sock_addr, \ + "Set isula image remote server socket address, Default: unix:///var/run/lcrd/isula_image.sock", NULL }, \ { CMD_OPT_TYPE_STRING_DUP, false, "network-plugin", 0, &(cmdargs)->json_confs->network_plugin, \ "Set network plugin, default is null, suppport null and cni", NULL }, \ { CMD_OPT_TYPE_STRING_DUP, false, "cni-bin-dir", 0, &(cmdargs)->json_confs->cni_bin_dir, \ @@ -100,3 +102,4 @@ int update_default_ulimit(struct service_arguments *args); "Default ulimits for containers (default [])", command_default_ulimit_append } #endif /* __COMMAND_H */ + diff --git a/src/cmd/lcrd/main.c b/src/cmd/lcrd/main.c index 3defc8d..d46cbdb 100644 --- a/src/cmd/lcrd/main.c +++ b/src/cmd/lcrd/main.c @@ -71,8 +71,6 @@ #endif sem_t g_daemon_shutdown_sem; -sem_t g_print_backtrace_sem; -int g_backtrace_log_fd = -1; static int create_client_run_path(const char *group) { @@ -193,10 +191,57 @@ static void umount_daemon_mntpoint() } #endif +static inline bool unlink_ignore_enoent(const char *fname) +{ + return unlink(fname) && errno != ENOENT; +} + +static void clean_residual_files() +{ + char *checked_flag = NULL; + char *fname = NULL; + + /* remove image checked file */ + checked_flag = conf_get_graph_check_flag_file(); + if (checked_flag == NULL) { + ERROR("Failed to get image checked flag file path"); + } else if (unlink_ignore_enoent(checked_flag)) { + ERROR("Unlink file: %s error: %s", checked_flag, strerror(errno)); + } + free(checked_flag); + + /* remove pid file */ + fname = conf_get_lcrd_pidfile(); + if (fname == NULL) { + ERROR("Failed to get LCRD pid file path"); + } else if (unlink(fname) && errno != ENOENT) { + WARN("Unlink file: %s error: %s", fname, strerror(errno)); + } + free(fname); + +#ifdef ENABLE_OCI_IMAGE + /* remove image server socket file */ + fname = conf_get_im_server_sock_addr(); + if (fname != NULL && unlink_ignore_enoent(fname + strlen(UNIX_SOCKET_PREFIX))) { + WARN("Unlink file: %s error: %s", fname + strlen(UNIX_SOCKET_PREFIX), strerror(errno)); + } + free(fname); + +#define ISULAD_KIT_PID_FILE "/var/run/isula_image.pid" +#define ISULAD_KIT_INFO_FILE "/var/run/isula_image.info" + if (unlink_ignore_enoent(ISULAD_KIT_PID_FILE)) { + WARN("Unlink file: %s error: %s", ISULAD_KIT_PID_FILE, strerror(errno)); + } + if (unlink_ignore_enoent(ISULAD_KIT_INFO_FILE)) { + WARN("Unlink file: %s error: %s", ISULAD_KIT_INFO_FILE, strerror(errno)); + } +#endif +} + static void daemon_shutdown() { - char *pidfile = NULL; - char *checked_flag = NULL; + /* clean resource first, left time to wait finish */ + image_module_exit(); #ifdef ENABLE_EMBEDDED_IMAGE /* shutdown db */ @@ -210,25 +255,7 @@ static void daemon_shutdown() umount_daemon_mntpoint(); #endif - /* remove image checked file */ - checked_flag = conf_get_graph_check_flag_file(); - if (checked_flag == NULL) { - ERROR("Failed to get image checked flag file path"); - } else if (unlink(checked_flag) && errno != ENOENT) { - ERROR("Unlink file: %s error: %s", checked_flag, strerror(errno)); - } - free(checked_flag); - checked_flag = NULL; - - /* remove pid file */ - pidfile = conf_get_lcrd_pidfile(); - if (pidfile == NULL) { - ERROR("Failed to get LCRD pid file path"); - } else if (unlink(pidfile) && errno != ENOENT) { - WARN("Unlink file: %s error: %s", pidfile, strerror(errno)); - } - free(pidfile); - pidfile = NULL; + clean_residual_files(); } static void sigint_handler(int x) @@ -243,197 +270,6 @@ static void sigterm_handler(int signo) sem_post(&g_daemon_shutdown_sem); } -#define BT_BUF_SIZE 100 -#define MAX_BT_SIZE (3 * 1024) -static void print_callstack(void) -{ - int j = 0; - int nptrs = 0; - int nret = 0; - void *buffer[BT_BUF_SIZE] = { NULL }; - char msg[MAX_BT_SIZE] = { 0 }; - char tname[16] = { 0 }; - char **strings = NULL; - pid_t tid = 0; - size_t avalid_size = 0; - - prctl(PR_GET_NAME, tname); - tid = (pid_t)syscall(__NR_gettid); - - nptrs = backtrace(buffer, BT_BUF_SIZE); - strings = backtrace_symbols(buffer, nptrs); - if (strings == NULL) { - ERROR("backtrace_symbols return nothing"); - goto out; - } - - nret = sprintf_s(msg, MAX_BT_SIZE, "[%s] tid:%d backtrace:\n", tname, tid); - if (nret < 0 || nret > MAX_BT_SIZE) { - ERROR("Failed to print [%s] tid:%d backtrace headinfo", tname, tid); - goto out; - } - - for (j = 0; j < nptrs; j++) { - avalid_size = MAX_BT_SIZE - strlen(msg); - if ((strlen(strings[j]) + strlen(" \n")) <= (avalid_size - 1)) { - nret = sprintf_s(msg + strlen(msg), avalid_size, " %s\n", strings[j]); - if (nret < 0 || (size_t)nret > avalid_size) { - ERROR("Failed to print backtrace %s", strings[j]); - goto out; - } - } else { - break; - } - } - nret = (int)write(g_backtrace_log_fd, msg, strlen(msg)); - if (nret < 0) { - ERROR("Failed to write backtrace info: %s", strerror(errno)); - goto out; - } - -out: - if (sem_wait(&g_print_backtrace_sem) == -1) { - ERROR("Failed to wait"); - } - - free(strings); - return; -} - -static void sigusr1_handler(int signo) -{ - INFO("Got SIGUSER1; print back trace"); - print_callstack(); - return; -} - -static int create_isulad_monitor_log_file() -{ - int ret = 0; - int tmp_fd = -1; - char *root_dir = NULL; - struct tm *tm_now = NULL; - time_t currtime = time(0); - char log_file[PATH_MAX] = { 0 }; - char fn[PATH_MAX] = { 0 }; - - root_dir = conf_get_lcrd_rootdir(); - if (root_dir == NULL) { - ERROR("Get rootpath failed"); - ret = -1; - goto out; - } - - tm_now = localtime(&currtime); - if (tm_now == NULL) { - ERROR("Failed to get current time"); - ret = -1; - goto out; - } - - if (strftime(log_file, sizeof(log_file), "%Y%m%d%H%M%S", tm_now) == 0) { - ret = -1; - goto out; - } - - ret = sprintf_s(fn, sizeof(fn), "%s/%s/%s", root_dir, "isulad-monitor", log_file); - if (ret < 0) { - ERROR("Failed to print string"); - ret = -1; - goto out; - } - - ret = util_build_dir(fn); - if (ret < 0) { - WARN("Failed to create directory for log file: %s", fn); - ret = -1; - goto out; - } - - tmp_fd = util_open(fn, O_RDWR | O_CREAT, DEFAULT_SECURE_FILE_MODE); - if (tmp_fd < 0) { - WARN("Failed to open log file: %s", fn); - ret = -1; - goto out; - } - - if (g_backtrace_log_fd != -1) { - close(g_backtrace_log_fd); - } - g_backtrace_log_fd = tmp_fd; - - ret = 0; - -out: - free(root_dir); - return ret; -} - -static void send_dump_req(void) -{ - int ret = 0; - size_t subdir_num = 0; - size_t i = 0; - char **subdir = NULL; - pid_t tid = 0; - pid_t pid = 0; - - ret = create_isulad_monitor_log_file(); - if (ret != 0) { - goto out; - } - - ret = util_list_all_subdir("/proc/self/task", &subdir); - if (ret < 0) { - ERROR("Failed to read /proc/self/task' subdirectory"); - goto out; - } - subdir_num = util_array_len((const char **)subdir); - if (subdir_num == 0) { - goto out; - } - - pid = getpid(); - if (pid < 0) { - goto out; - } - - ret = sem_init(&g_print_backtrace_sem, 0, (unsigned int)subdir_num); - if (ret != 0) { - goto out; - } - - for (i = 0; i < subdir_num; i++) { - ret = util_safe_int(subdir[i], &tid); - if (ret < 0) { - (void)sem_wait(&g_print_backtrace_sem); - continue; - } - ret = (int)syscall(SYS_tgkill, pid, tid, SIGUSR1); - if (ret < 0) { - ERROR("Failed to send SIGUSR1 to thread id:%d in process:%d", tid, pid); - (void)sem_wait(&g_print_backtrace_sem); - } - } - -out: - util_free_array(subdir); - return; -} - -static void sigrtmin_handler(int signo) -{ - int tmp_sval = 0; - - if (sem_getvalue(&g_print_backtrace_sem, &tmp_sval) == 0) { - if (tmp_sval == 0) { - send_dump_req(); - } - } - - return; -} - static int ignore_signals() { struct sigaction sa; @@ -460,6 +296,10 @@ static int ignore_signals() return -1; } + if (sigaction(SIGUSR1, &sa, NULL) < 0) { + ERROR("Failed to ignore SIGUSR1"); + return -1; + } return 0; } @@ -501,44 +341,6 @@ static int add_shutdown_signal_handler() return 0; } -static int add_print_bt_handler() -{ - struct sigaction sa; - - if (memset_s(&sa, sizeof(struct sigaction), 0, sizeof(struct sigaction)) != EOK) { - ERROR("Failed to set memory"); - return -1; - } - - if (sem_init(&g_print_backtrace_sem, 0, 0) == -1) { - ERROR("Failed to init"); - return -1; - } - - sa.sa_handler = sigusr1_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - if (sigaction(SIGUSR1, &sa, NULL) < 0) { - ERROR("Failed to add handler for SIGUSR1"); - return -1; - } - - if (memset_s(&sa, sizeof(struct sigaction), 0, sizeof(struct sigaction)) != EOK) { - ERROR("Failed to set memory"); - return -1; - } - - sa.sa_handler = sigrtmin_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - if (sigaction(SIGRTMIN, &sa, NULL) < 0) { - ERROR("Failed to add handler for SIGRTMIN"); - return -1; - } - - return 0; -} - static int add_sighandler() { if (ignore_signals() != 0) { @@ -551,11 +353,6 @@ static int add_sighandler() return -1; } - if (add_print_bt_handler() != 0) { - ERROR("Failed to add print back trace signals"); - return -1; - } - return 0; } @@ -974,8 +771,8 @@ static int parse_conf_time_duration(struct service_arguments *args) } /* parse image opt timeout */ - if (args->json_confs->im_opt_timeout != NULL && - parse_time_duration(args->json_confs->im_opt_timeout, &args->im_opt_timeout)) { + if (args->json_confs->image_opt_timeout != NULL && + parse_time_duration(args->json_confs->image_opt_timeout, &args->image_opt_timeout)) { ret = -1; goto out; } @@ -1253,16 +1050,16 @@ static int lcrd_server_init_common() goto unlock_out; } -#ifdef ENABLE_OCI_IMAGE - /* update status of graphdriver before init image module */ - update_graphdriver_status(&(args->driver)); -#endif - if (image_module_init(args->json_confs->graph)) { ERROR("Failed to init image manager"); goto unlock_out; } +#ifdef ENABLE_OCI_IMAGE + /* update status of graphdriver after image server running */ + update_graphdriver_status(&(args->driver)); +#endif + if (containers_store_init()) { ERROR("Failed to init containers store"); goto unlock_out; @@ -1551,6 +1348,9 @@ static int start_daemon_threads(char **msg) containers_restore(); + /* sync containers list with remote */ + im_sync_containers_isuladkit(); + if (start_gchandler()) { *msg = "Failed to start garbage collecotor handler"; goto out; diff --git a/src/config/lcrd_config.c b/src/config/lcrd_config.c index 9100f57..1dcd854 100644 --- a/src/config/lcrd_config.c +++ b/src/config/lcrd_config.c @@ -1170,13 +1170,63 @@ unsigned int conf_get_im_opt_timeout() goto out; } - ret = conf->im_opt_timeout; + ret = conf->image_opt_timeout; out: (void)lcrd_server_conf_unlock(); return ret; } +char *conf_get_im_server_sock_addr() +{ + struct service_arguments *conf = NULL; + char *result = NULL; + + if (lcrd_server_conf_rdlock() != 0) { + ERROR("BUG conf_rdlock failed"); + return NULL; + } + + conf = conf_get_server_conf(); + if (conf == NULL || conf->json_confs == NULL) { + goto out; + } + + result = util_strdup_s(conf->json_confs->image_server_sock_addr); + +out: + (void)lcrd_server_conf_unlock(); + return result; +} + +bool conf_update_im_server_sock_addr(const char *new_sock_addr) +{ + struct service_arguments *conf = NULL; + bool result = true; + + if (new_sock_addr == NULL) { + return false; + } + + if (lcrd_server_conf_rdlock() != 0) { + ERROR("BUG conf_rdlock failed"); + return false; + } + + conf = conf_get_server_conf(); + if (conf == NULL || conf->json_confs == NULL) { + result = false; + goto out; + } + + free(conf->json_confs->image_server_sock_addr); + conf->json_confs->image_server_sock_addr = util_strdup_s(new_sock_addr); + +out: + (void)lcrd_server_conf_unlock(); + return result; +} + char *conf_get_enable_plugins() { struct service_arguments *conf = NULL; @@ -1699,7 +1749,8 @@ int merge_json_confs_into_global(struct service_arguments *args) override_string_value(&args->json_confs->cgroup_parent, &tmp_json_confs->cgroup_parent); override_string_value(&args->json_confs->rootfsmntdir, &tmp_json_confs->rootfsmntdir); override_string_value(&args->json_confs->start_timeout, &tmp_json_confs->start_timeout); - override_string_value(&args->json_confs->im_opt_timeout, &tmp_json_confs->im_opt_timeout); + override_string_value(&args->json_confs->image_opt_timeout, &tmp_json_confs->image_opt_timeout); + override_string_value(&args->json_confs->image_server_sock_addr, &tmp_json_confs->image_server_sock_addr); override_string_value(&args->json_confs->pod_sandbox_image, &tmp_json_confs->pod_sandbox_image); override_string_value(&args->json_confs->network_plugin, &tmp_json_confs->network_plugin); override_string_value(&args->json_confs->cni_bin_dir, &tmp_json_confs->cni_bin_dir); @@ -1752,3 +1803,4 @@ out: free_isulad_daemon_configs(tmp_json_confs); return ret; } + diff --git a/src/config/lcrd_config.h b/src/config/lcrd_config.h index a00710e..3c33895 100644 --- a/src/config/lcrd_config.h +++ b/src/config/lcrd_config.h @@ -24,6 +24,8 @@ extern "C" { #endif +#define DEFAULT_IM_SERVER_SOCK_ADDR "unix:///var/run/lcrd/isula_image.sock" + struct lcrd_conf { pthread_rwlock_t lcrd_conf_rwlock; struct service_arguments *server_conf; @@ -87,6 +89,10 @@ char *conf_get_lcrd_cgroup_parent(); unsigned int conf_get_im_opt_timeout(); +char *conf_get_im_server_sock_addr(); + +bool conf_update_im_server_sock_addr(const char *new_sock_addr); + char *conf_get_graph_check_flag_file(); bool conf_get_image_layer_check_flag(); @@ -102,3 +108,4 @@ int parse_log_opts(struct service_arguments *args, const char *key, const char * #endif #endif /* __LCRD_CONF_H */ + diff --git a/src/connect/CMakeLists.txt b/src/connect/CMakeLists.txt index 5e4d5a2..7ec6a1e 100644 --- a/src/connect/CMakeLists.txt +++ b/src/connect/CMakeLists.txt @@ -6,3 +6,8 @@ set(CONNECTOR_INCS ${CONNECT_CLIENT_INCS} PARENT_SCOPE) add_subdirectory(service) set(CONNECT_SOCKET ${CONNECT_SERVICE_SRCS} PARENT_SCOPE) set(CONNECT_SOCKET_INCS ${CONNECT_SERVICE_INCS} PARENT_SCOPE) + +if (ENABLE_OCI_IMAGE) + set(ISULA_IMAGE_CLIENT_SRCS ${CONNECT_ISULA_IMAGE_CLIENT_SRCS} PARENT_SCOPE) + set(ISULA_IMAGE_CLIENT_INCS ${CONNECT_ISULA_IMAGE_CLIENT_INCS} PARENT_SCOPE) +endif() diff --git a/src/connect/client/CMakeLists.txt b/src/connect/client/CMakeLists.txt index 96ec225..9cc25c0 100644 --- a/src/connect/client/CMakeLists.txt +++ b/src/connect/client/CMakeLists.txt @@ -1,10 +1,12 @@ -# get current directory sources files -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} client_srcs) +set(client_srcs + ${CMAKE_CURRENT_SOURCE_DIR}/lcrc_connect.c + ) set(incs ${CMAKE_CURRENT_SOURCE_DIR}) +add_subdirectory(grpc) + if (GRPC_CONNECTOR) - add_subdirectory(grpc) list(APPEND client_srcs ${CLIENT_GRPC_SRCS}) list(APPEND incs ${CMAKE_CURRENT_SOURCE_DIR}/grpc) else() @@ -13,6 +15,18 @@ else() list(APPEND incs ${CMAKE_CURRENT_SOURCE_DIR}/rest) endif() - set(CONNECT_CLIENT_SRCS ${client_srcs} PARENT_SCOPE) set(CONNECT_CLIENT_INCS ${incs} PARENT_SCOPE) + +if (ENABLE_OCI_IMAGE) + set(CONNECT_ISULA_IMAGE_CLIENT_SRCS + ${ISUAL_IMAGE_GRPC_SRCS} + ${CMAKE_CURRENT_SOURCE_DIR}/isula_image_connect.c + PARENT_SCOPE + ) + set(CONNECT_ISULA_IMAGE_CLIENT_INCS + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/grpc + PARENT_SCOPE + ) +endif() diff --git a/src/connect/client/connect.h b/src/connect/client/connect.h index 38e8681..4476ada 100644 --- a/src/connect/client/connect.h +++ b/src/connect/client/connect.h @@ -1,5 +1,5 @@ /****************************************************************************** -* Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -15,11 +15,14 @@ #ifndef __ISULAD_CLIENT_CONNECT_H #define __ISULAD_CLIENT_CONNECT_H +#include + #ifdef __cplusplus extern "C" { #endif typedef struct { + unsigned int deadline; char *socket; // gRPC tls config bool tls; @@ -33,3 +36,4 @@ typedef struct { } #endif #endif + diff --git a/src/connect/client/grpc/CMakeLists.txt b/src/connect/client/grpc/CMakeLists.txt index 4fadef1..e27e852 100644 --- a/src/connect/client/grpc/CMakeLists.txt +++ b/src/connect/client/grpc/CMakeLists.txt @@ -1,7 +1,15 @@ -# get current directory sources files -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_client_grpc_srcs) +if (ENABLE_OCI_IMAGE) + set(ISUAL_IMAGE_GRPC_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/grpc_isula_image_client.cc + PARENT_SCOPE + ) +endif() -set(CLIENT_GRPC_SRCS - ${local_client_grpc_srcs} - PARENT_SCOPE - ) +if (GRPC_CONNECTOR) + set(CLIENT_GRPC_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/grpc_client.cc + ${CMAKE_CURRENT_SOURCE_DIR}/grpc_containers_client.cc + ${CMAKE_CURRENT_SOURCE_DIR}/grpc_images_client.cc + PARENT_SCOPE + ) +endif() diff --git a/src/connect/client/grpc/client_base.h b/src/connect/client/grpc/client_base.h index b92a072..40aee71 100644 --- a/src/connect/client/grpc/client_base.h +++ b/src/connect/client/grpc/client_base.h @@ -49,6 +49,8 @@ public: std::string socket_address = arguments->socket; const std::string tcp_prefix = "tcp://"; + deadline = arguments->deadline; + if (socket_address.compare(0, tcp_prefix.length(), tcp_prefix) == 0) { socket_address.erase(0, tcp_prefix.length()); } @@ -105,6 +107,12 @@ public: ClientContext context; Status status; + // Set deadline for GRPC client + if (deadline > 0) { + auto tDeadline = std::chrono::system_clock::now() + std::chrono::seconds(deadline); + context.set_deadline(tDeadline); + } + // Set common name from cert.perm char common_name_value[ClientBaseConstants::COMMON_NAME_LEN] = { 0 }; ret = get_common_name_from_tls_cert(m_certFile.c_str(), common_name_value, @@ -190,6 +198,8 @@ protected: std::unique_ptr stub_; std::string m_tlsMode { ClientBaseConstants::TLS_OFF }; std::string m_certFile { "" }; + + unsigned int deadline; }; template @@ -200,8 +210,14 @@ int container_func(const REQUEST *request, RESPONSE *response, void *arg) noexce return -1; } - std::unique_ptr client(new FUNC(arg)); + std::unique_ptr client(new (std::nothrow) FUNC(arg)); + if (client == nullptr) { + ERROR("Out of memory"); + return -1; + } + return client->run(request, response); } #endif /* __CLIENT_BASH_H */ + diff --git a/src/connect/client/grpc/grpc_client.cc b/src/connect/client/grpc/grpc_client.cc index 700cac1..6a565cd 100644 --- a/src/connect/client/grpc/grpc_client.cc +++ b/src/connect/client/grpc/grpc_client.cc @@ -32,3 +32,4 @@ int grpc_ops_init(lcrc_connect_ops *ops) return 0; } + diff --git a/src/connect/client/grpc/grpc_client.h b/src/connect/client/grpc/grpc_client.h index 0d6c33e..c0e1c66 100644 --- a/src/connect/client/grpc/grpc_client.h +++ b/src/connect/client/grpc/grpc_client.h @@ -28,3 +28,4 @@ int grpc_ops_init(lcrc_connect_ops *ops); #endif #endif /* __GRPC_CLIENT_H */ + diff --git a/src/connect/client/grpc/grpc_containers_client.cc b/src/connect/client/grpc/grpc_containers_client.cc index 808e907..268f6cc 100644 --- a/src/connect/client/grpc/grpc_containers_client.cc +++ b/src/connect/client/grpc/grpc_containers_client.cc @@ -773,6 +773,9 @@ public: for (size_t i = 0; i < request->env_len; i++) { grequest->add_env(request->env[i]); } + if (request->user != nullptr) { + grequest->set_user(request->user); + } return 0; } @@ -780,7 +783,6 @@ public: int response_from_grpc(ExecResponse *gresponse, lcrc_exec_response *response) override { response->server_errono = gresponse->cc(); - response->pid = (uint32_t)gresponse->pid(); response->exit_code = gresponse->exit_code(); if (!gresponse->errmsg().empty()) { response->errmsg = util_strdup_s(gresponse->errmsg().c_str()); @@ -904,11 +906,6 @@ out: auto tmpstr = std::string(cc->second.data(), cc->second.length()); response->server_errono = (uint32_t)std::stoul(tmpstr, nullptr, 0); } - auto pid = metadata.find("pid"); - if (pid != metadata.end()) { - auto tmpstr = std::string(pid->second.data(), pid->second.length()); - response->pid = (uint32_t)std::stoul(tmpstr, nullptr, 0); - } auto exit_code = metadata.find("exit_code"); if (exit_code != metadata.end()) { auto tmpstr = std::string(exit_code->second.data(), exit_code->second.length()); @@ -1174,7 +1171,7 @@ private: response->container_summary[index]->exit_code = in.exit_code(); response->container_summary[index]->restart_count = (uint32_t)(in.restartcount()); - + response->container_summary[index]->created = (int64_t)in.created(); std::string healthState { "" }; if (!in.health_state().empty()) { healthState = "(" + in.health_state() + ")"; @@ -1919,6 +1916,7 @@ public: if (ret != 0) { ERROR("Failed to translate request to grpc"); response->server_errono = LCRD_ERR_INPUT; + delete ctx; return -1; } diff --git a/src/connect/client/grpc/grpc_containers_client.h b/src/connect/client/grpc/grpc_containers_client.h index 547654e..e15878e 100644 --- a/src/connect/client/grpc/grpc_containers_client.h +++ b/src/connect/client/grpc/grpc_containers_client.h @@ -28,3 +28,4 @@ int grpc_containers_client_ops_init(lcrc_connect_ops *ops); #endif #endif + diff --git a/src/connect/client/grpc/grpc_images_client.cc b/src/connect/client/grpc/grpc_images_client.cc index 1bba43d..ab92f15 100644 --- a/src/connect/client/grpc/grpc_images_client.cc +++ b/src/connect/client/grpc/grpc_images_client.cc @@ -13,6 +13,7 @@ * Description: provide grpc container service functions ******************************************************************************/ #include "grpc_images_client.h" +#include #include "securec.h" #include "images.grpc.pb.h" #include "api.grpc.pb.h" @@ -43,7 +44,13 @@ public: if (request == nullptr) { return -1; } - + if (request->filters != nullptr) { + google::protobuf::Map *map; + map = grequest->mutable_filters(); + for (size_t i = 0; i < request->filters->len; i++) { + (*map)[request->filters->keys[i]] = request->filters->values[i]; + } + } return 0; } @@ -57,6 +64,9 @@ public: response->images_list = nullptr; response->images_num = 0; response->server_errono = gresponse->cc(); + if (!gresponse->errmsg().empty()) { + response->errmsg = util_strdup_s(gresponse->errmsg().c_str()); + } return 0; } @@ -217,8 +227,9 @@ public: } }; -class ImagesPull : public ClientBase { +class ImagesPull : public + ClientBase { public: explicit ImagesPull(void *args) : ClientBase(args) @@ -226,14 +237,14 @@ public: } ~ImagesPull() = default; - int request_to_grpc(const lcrc_pull_request *request, runtime::PullImageRequest *grequest) override + int request_to_grpc(const lcrc_pull_request *request, runtime::v1alpha2::PullImageRequest *grequest) override { if (request == nullptr) { return -1; } if (request->image_name != nullptr) { - runtime::ImageSpec *image_spec = new (std::nothrow) runtime::ImageSpec; + runtime::v1alpha2::ImageSpec *image_spec = new (std::nothrow) runtime::v1alpha2::ImageSpec; if (image_spec == nullptr) { return -1; } @@ -244,7 +255,7 @@ public: return 0; } - int response_from_grpc(runtime::PullImageResponse *gresponse, lcrc_pull_response *response) override + int response_from_grpc(runtime::v1alpha2::PullImageResponse *gresponse, lcrc_pull_response *response) override { if (!gresponse->image_ref().empty()) { response->image_ref = util_strdup_s(gresponse->image_ref().c_str()); @@ -253,7 +264,7 @@ public: return 0; } - int check_parameter(const runtime::PullImageRequest &req) override + int check_parameter(const runtime::v1alpha2::PullImageRequest &req) override { if (req.image().image().empty()) { ERROR("Missing image name in the request"); @@ -263,8 +274,8 @@ public: return 0; } - Status grpc_call(ClientContext *context, const runtime::PullImageRequest &req, - runtime::PullImageResponse *reply) override + Status grpc_call(ClientContext *context, const runtime::v1alpha2::PullImageRequest &req, + runtime::v1alpha2::PullImageResponse *reply) override { return stub_->PullImage(context, req, reply); } @@ -461,4 +472,3 @@ int grpc_images_client_ops_init(lcrc_connect_ops *ops) return 0; } - diff --git a/src/connect/client/grpc/grpc_images_client.h b/src/connect/client/grpc/grpc_images_client.h index 4fc88a6..eff36b8 100644 --- a/src/connect/client/grpc/grpc_images_client.h +++ b/src/connect/client/grpc/grpc_images_client.h @@ -28,3 +28,4 @@ int grpc_images_client_ops_init(lcrc_connect_ops *ops); #endif #endif + diff --git a/src/connect/client/grpc/grpc_isula_image_client.cc b/src/connect/client/grpc/grpc_isula_image_client.cc new file mode 100644 index 0000000..b9b42a6 --- /dev/null +++ b/src/connect/client/grpc/grpc_isula_image_client.cc @@ -0,0 +1,1041 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-12 +* Description: provide lcrc connect command definition +*******************************************************************************/ +#include "grpc_isula_image_client.h" +#include +#include +#include "isula_image.grpc.pb.h" +#include "isula_image.pb.h" +#include "utils.h" +#include "client_base.h" +#include "liblcrd.h" + +namespace { +int copy_image_tags_metadata(const isula::Image &gimage, struct image_metadata *metadata) +{ + int len; + + len = gimage.repo_tags_size(); + if (len > 0) { + metadata->repo_tags = (char **)util_smart_calloc_s(sizeof(char *), static_cast(len)); + if (metadata->repo_tags == nullptr) { + ERROR("Out of memory"); + return -1; + } + for (int i = 0; i < len; i++) { + metadata->repo_tags[i] = util_strdup_s(gimage.repo_tags(i).c_str()); + metadata->repo_tags_len++; + } + } + + return 0; +} + +int copy_image_digests_metadata(const isula::Image &gimage, struct image_metadata *metadata) +{ + int len; + + len = gimage.repo_digests_size(); + if (len > 0) { + metadata->repo_digests = (char **)util_smart_calloc_s(sizeof(char *), static_cast(len)); + if (metadata->repo_digests == nullptr) { + ERROR("Out of memory"); + return -1; + } + for (int i = 0; i < len; i++) { + metadata->repo_digests[i] = util_strdup_s(gimage.repo_digests(i).c_str()); + metadata->repo_digests_len++; + } + metadata->size = static_cast(gimage.size()); + metadata->uid = static_cast(gimage.uid().value()); + } + + return 0; +} + +int copy_image_metadata(const isula::Image &gimage, struct image_metadata **metadata) +{ + struct image_metadata *tmp_data = (struct image_metadata *)util_common_calloc_s(sizeof(struct image_metadata)); + + if (tmp_data == nullptr) { + ERROR("Out of memory"); + return -1; + } + if (!gimage.id().empty()) { + tmp_data->id = util_strdup_s(gimage.id().c_str()); + } + + if (copy_image_tags_metadata(gimage, tmp_data) != 0) { + goto err_out; + } + + if (copy_image_digests_metadata(gimage, tmp_data) != 0) { + goto err_out; + } + + if (!gimage.username().empty()) { + tmp_data->username = util_strdup_s(gimage.username().c_str()); + } + + if (!gimage.created().empty()) { + tmp_data->created = util_strdup_s(gimage.created().c_str()); + } + + if (!gimage.loaded().empty()) { + tmp_data->loaded = util_strdup_s(gimage.loaded().c_str()); + } + + if (gimage.has_spec() && !gimage.spec().image().empty()) { + tmp_data->oci_spec = util_strdup_s(gimage.spec().image().c_str()); + } + *metadata = tmp_data; + return 0; +err_out: + free_image_metadata(tmp_data); + return -1; +} +} // namespace + +class ISulaContainerPrepare : public ClientBase { +public: + explicit ISulaContainerPrepare(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_prepare_request *req, isula::ContainerPrepareRequest *grequest) override + { + if (req == nullptr) { + return -1; + } + if (req->image != nullptr) { + grequest->set_image(req->image); + } + if (req->id != nullptr) { + grequest->set_id(req->id); + } + if (req->name != nullptr) { + grequest->set_name(req->name); + } + if (req->storage_opts != nullptr) { + for (size_t i = 0; i < req->storage_opts_len; i++) { + grequest->add_storage_opts(req->storage_opts[i]); + } + } + return 0; + } + + int response_from_grpc(isula::ContainerPrepareResponse *gresp, isula_prepare_response *resp) override + { + if (!gresp->mount_point().empty()) { + resp->mount_point = util_strdup_s(gresp->mount_point().c_str()); + } + if (!gresp->image_conf().empty()) { + resp->image_conf = util_strdup_s(gresp->image_conf().c_str()); + } + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + int check_parameter(const isula::ContainerPrepareRequest &req) override + { + if (req.image().empty()) { + ERROR("Need set image to prepare container"); + return -1; + } + if (req.id().empty()) { + ERROR("Need set id for container"); + return -1; + } + return 0; + } + + Status grpc_call(ClientContext *context, const isula::ContainerPrepareRequest &req, + isula::ContainerPrepareResponse *reply) override + { + return stub_->ContainerPrepare(context, req, reply); + } +}; + +class ISulaContainerRemove : public ClientBase { +public: + explicit ISulaContainerRemove(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_remove_request *req, isula::ContainerRemoveRequest *grequest) override + { + if (req == nullptr) { + return -1; + } + if (req->name_id != nullptr) { + grequest->set_name_id(req->name_id); + } + return 0; + } + + int response_from_grpc(isula::ContainerRemoveResponse *gresp, isula_remove_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + int check_parameter(const isula::ContainerRemoveRequest &req) override + { + if (req.name_id().empty()) { + ERROR("Empty container id"); + return -1; + } + return 0; + } + + Status grpc_call(ClientContext *context, const isula::ContainerRemoveRequest &req, + isula::ContainerRemoveResponse *reply) override + { + return stub_->ContainerRemove(context, req, reply); + } +}; + +class ISulaContainerMount : public ClientBase { +public: + explicit ISulaContainerMount(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_mount_request *req, isula::ContainerMountRequest *grequest) override + { + if (req == nullptr) { + return -1; + } + if (req->name_id != nullptr) { + grequest->set_name_id(req->name_id); + } + return 0; + } + + int response_from_grpc(isula::ContainerMountResponse *gresp, isula_mount_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + int check_parameter(const isula::ContainerMountRequest &req) override + { + if (req.name_id().empty()) { + ERROR("Empty container id"); + return -1; + } + return 0; + } + + Status grpc_call(ClientContext *context, const isula::ContainerMountRequest &req, + isula::ContainerMountResponse *reply) override + { + return stub_->ContainerMount(context, req, reply); + } +}; + +class ISulaContainerUmount : public ClientBase { +public: + explicit ISulaContainerUmount(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_umount_request *req, isula::ContainerUmountRequest *grequest) override + { + if (req == nullptr) { + return -1; + } + if (req->name_id != nullptr) { + grequest->set_name_id(req->name_id); + } + return 0; + } + + int response_from_grpc(isula::ContainerUmountResponse *gresp, isula_umount_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + int check_parameter(const isula::ContainerUmountRequest &req) override + { + if (req.name_id().empty()) { + ERROR("Empty container id"); + return -1; + } + return 0; + } + + Status grpc_call(ClientContext *context, const isula::ContainerUmountRequest &req, + isula::ContainerUmountResponse *reply) override + { + return stub_->ContainerUmount(context, req, reply); + } +}; + +class ISulaContainersList : public ClientBase { +public: + explicit ISulaContainersList(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_containers_list_request *req, isula::ListContainersRequest *grequest) override + { + if (req == nullptr) { + return -1; + } + return 0; + } + + int response_from_grpc(isula::ListContainersResponse *gresp, isula_containers_list_response *resp) override + { + int containers_len = gresp->containers_size(); + if (containers_len > 0) { + resp->containers = (json_map_string_bool *)util_common_calloc_s(sizeof(json_map_string_bool)); + if (resp->containers == nullptr) { + ERROR("Out of memory"); + return -1; + } + for (const auto &iter : gresp->containers()) { + if (append_json_map_string_bool(resp->containers, iter.first.c_str(), iter.second) != 0) { + ERROR("Out of memory"); + return -1; + } + } + } + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + Status grpc_call(ClientContext *context, const isula::ListContainersRequest &req, + isula::ListContainersResponse *reply) override + { + return stub_->ListContainers(context, req, reply); + } +}; + +class ISulaImagePull : public ClientBase { +public: + explicit ISulaImagePull(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_pull_request *req, isula::PullImageRequest *grequest) override + { + if (req == nullptr) { + return -1; + } + + if (req->image != nullptr && req->image->image != nullptr) { + isula::ImageSpec *image_spec = new (std::nothrow) isula::ImageSpec; + if (image_spec == nullptr) { + return -1; + } + image_spec->set_image(req->image->image); + grequest->set_allocated_image(image_spec); + } + + if (req->auth != nullptr) { + isula::AuthConfig *auth = new (std::nothrow) isula::AuthConfig; + if (auth == nullptr) { + return -1; + } + if (req->auth->username != nullptr) { + auth->set_username(req->auth->username); + } + if (req->auth->password != nullptr) { + auth->set_password(req->auth->password); + } + if (req->auth->auth != nullptr) { + auth->set_auth(req->auth->auth); + } + if (req->auth->server_address != nullptr) { + auth->set_server_address(req->auth->server_address); + } + if (req->auth->identity_token != nullptr) { + auth->set_identity_token(req->auth->identity_token); + } + if (req->auth->registry_token != nullptr) { + auth->set_registry_token(req->auth->registry_token); + } + + grequest->set_allocated_auth(auth); + } + return 0; + } + + int response_from_grpc(isula::PullImageResponse *gresp, isula_pull_response *resp) override + { + if (!gresp->image_ref().empty()) { + resp->image_ref = util_strdup_s(gresp->image_ref().c_str()); + } + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + int check_parameter(const isula::PullImageRequest &req) override + { + if (req.image().image().empty()) { + ERROR("Missing image name in the request."); + return -1; + } + return 0; + } + + Status grpc_call(ClientContext *context, const isula::PullImageRequest &req, + isula::PullImageResponse *reply) override + { + return stub_->PullImage(context, req, reply); + } +}; + +class ISulaImageStatus : public ClientBase { +public: + explicit ISulaImageStatus(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_status_request *req, isula::ImageStatusRequest *grequest) override + { + if (req == nullptr) { + return -1; + } + if (req->image != nullptr && req->image->image != nullptr) { + isula::ImageSpec *image_spec = new (std::nothrow) isula::ImageSpec; + if (image_spec == nullptr) { + return -1; + } + image_spec->set_image(req->image->image); + grequest->set_allocated_image(image_spec); + } + grequest->set_verbose(req->verbose); + return 0; + } + + int response_from_grpc(isula::ImageStatusResponse *gresp, isula_status_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + + if (gresp->has_image()) { + if (copy_image_metadata(gresp->image(), &(resp->image)) != 0) { + return -1; + } + } + if (gresp->info_size() > 0) { + resp->info = (json_map_string_string *)util_common_calloc_s(sizeof(json_map_string_string)); + if (resp->info == nullptr) { + ERROR("Out of memory"); + return -1; + } + auto iter = gresp->info().cbegin(); + while (iter != gresp->info().cend()) { + if (append_json_map_string_string(resp->info, iter->first.c_str(), iter->second.c_str()) != 0) { + ERROR("Out of memory"); + return -1; + } + ++iter; + } + } + + return 0; + } + + int check_parameter(const isula::ImageStatusRequest &req) override + { + if (!req.has_image()) { + ERROR("Empty image name"); + return -1; + } + return 0; + } + + Status grpc_call(ClientContext *context, const isula::ImageStatusRequest &req, + isula::ImageStatusResponse *reply) override + { + return stub_->ImageStatus(context, req, reply); + } +}; + +class ISulaListImages : public ClientBase { +public: + explicit ISulaListImages(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_list_request *req, isula::ListImagesRequest *grequest) override + { + if (req == nullptr) { + return -1; + } + if (req->filter != nullptr) { + std::unique_ptr filter(new (std::nothrow) isula::ImageFilter); + if (filter == nullptr) { + ERROR("Out of memory"); + return -1; + } + std::unique_ptr image(new (std::nothrow) isula::ImageSpec); + if (image == nullptr) { + ERROR("Out of memory"); + return -1; + } + image->set_image(req->filter); + filter->set_allocated_image(image.release()); + grequest->set_allocated_filter(filter.release()); + } + grequest->set_check(req->check); + return 0; + } + + int response_from_grpc(isula::ListImagesResponse *gresp, isula_list_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + + int len = gresp->images_size(); + if (len <= 0) { + return 0; + } + + resp->images = (struct image_metadata **)util_smart_calloc_s( + sizeof(struct image_metadata *), static_cast(len)); + if (resp->images == nullptr) { + ERROR("Out of memory"); + return -1; + } + for (int i {}; i < len; i++) { + if (copy_image_metadata(gresp->images(i), &(resp->images[i])) != 0) { + return -1; + } + resp->images_len++; + } + + return 0; + } + + Status grpc_call(ClientContext *context, const isula::ListImagesRequest &req, + isula::ListImagesResponse *reply) override + { + return stub_->ListImages(context, req, reply); + } +}; + +class ISulaRmi : public ClientBase { +public: + explicit ISulaRmi(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_rmi_request *req, isula::RemoveImageRequest *grequest) override + { + if (req == nullptr) { + return -1; + } + if (req->image == nullptr || req->image->image == nullptr) { + return 0; + } + isula::ImageSpec *image = new (std::nothrow) isula::ImageSpec; + if (image == nullptr) { + ERROR("Out of memory"); + return -1; + } + image->set_image(req->image->image); + grequest->set_allocated_image(image); + grequest->set_force(req->force); + return 0; + } + + int response_from_grpc(isula::RemoveImageResponse *gresp, isula_rmi_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + int check_parameter(const isula::RemoveImageRequest &req) override + { + if (req.has_image() && !req.image().image().empty()) { + return 0; + } + ERROR("Image name is required."); + return -1; + } + + Status grpc_call(ClientContext *context, const isula::RemoveImageRequest &req, + isula::RemoveImageResponse *reply) override + { + return stub_->RemoveImage(context, req, reply); + } +}; + +class ISulaLoad : public ClientBase { +public: + explicit ISulaLoad(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_load_request *req, isula::LoadImageRequest *grequest) override + { + if (req == nullptr) { + return -1; + } + if (req->file != nullptr) { + grequest->set_file(req->file); + } + if (req->tag != nullptr) { + grequest->set_tag(req->tag); + } + return 0; + } + + int response_from_grpc(isula::LoadImageResponose *gresp, isula_load_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + if (!gresp->outmsg().empty()) { + resp->outmsg = util_strdup_s(gresp->outmsg().c_str()); + } + return 0; + } + + int check_parameter(const isula::LoadImageRequest &req) override + { + if (req.file().empty()) { + ERROR("Load image requires input file path"); + lcrd_set_error_message("Load image requires input file path"); + return -1; + } + if (!req.tag().empty()) { + if (util_valid_image_name(req.tag().c_str()) != true) { + ERROR("Invalid tag %s", req.tag().c_str()); + lcrd_try_set_error_message("Invalid tag:%s", req.tag().c_str()); + return -1; + } + } + return 0; + } + + Status grpc_call(ClientContext *context, const isula::LoadImageRequest &req, + isula::LoadImageResponose *reply) override + { + return stub_->LoadImage(context, req, reply); + } +}; + +class ISulaLogin : public ClientBase { +public: + explicit ISulaLogin(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_login_request *req, isula::LoginRequest *grequest) override + { + if (req == nullptr) { + lcrd_set_error_message("invalid login request"); + return -1; + } + if (req->server != nullptr) { + grequest->set_server(req->server); + } + if (req->username != nullptr) { + grequest->set_username(req->username); + } + if (req->password != nullptr) { + grequest->set_password(req->password); + } + return 0; + } + + int response_from_grpc(isula::LoginResponse *gresp, isula_login_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + int check_parameter(const isula::LoginRequest &req) override + { + if (req.server().empty()) { + lcrd_set_error_message("Login requires server address"); + return -1; + } + if (req.username().empty() || req.password().empty()) { + lcrd_set_error_message("Missing username or password"); + return -1; + } + return 0; + } + + Status grpc_call(ClientContext *context, const isula::LoginRequest &req, + isula::LoginResponse *reply) override + { + return stub_->Login(context, req, reply); + } +}; + +class ISulaLogout : public ClientBase { +public: + explicit ISulaLogout(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_logout_request *req, isula::LogoutRequest *grequest) override + { + if (req == nullptr) { + lcrd_set_error_message("invalid logout request"); + return -1; + } + if (req->server != nullptr) { + grequest->set_server(req->server); + } + return 0; + } + + int response_from_grpc(isula::LogoutResponse *gresp, isula_logout_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + int check_parameter(const isula::LogoutRequest &req) override + { + if (req.server().empty()) { + lcrd_set_error_message("Logout requires server address"); + return -1; + } + return 0; + } + + Status grpc_call(ClientContext *context, const isula::LogoutRequest &req, + isula::LogoutResponse *reply) override + { + return stub_->Logout(context, req, reply); + } +}; + +class ISulaExport : public ClientBase { +public: + explicit ISulaExport(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_export_request *req, isula::ContainerExportRequest *grequest) override + { + if (req == nullptr) { + lcrd_set_error_message("unvalid export request"); + return -1; + } + if (req->name_id != nullptr) { + grequest->set_name_id(req->name_id); + } + if (req->output != nullptr) { + grequest->set_output(req->output); + } + grequest->set_uid(req->uid); + grequest->set_gid(req->gid); + grequest->set_offset(req->offset); + return 0; + } + + int response_from_grpc(isula::ContainerExportResponse *gresp, isula_export_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + int check_parameter(const isula::ContainerExportRequest &req) override + { + if (req.name_id().empty()) { + lcrd_set_error_message("Export rootfs requires container name"); + return -1; + } + if (req.output().empty()) { + lcrd_set_error_message("Export rootfs requires output file path"); + return -1; + } + return 0; + } + + Status grpc_call(ClientContext *context, const isula::ContainerExportRequest &req, + isula::ContainerExportResponse *reply) override + { + return stub_->ContainerExport(context, req, reply); + } +}; + +class ISulaStorageStatus : public + ClientBase { +public: + explicit ISulaStorageStatus(void *args) : ClientBase(args) + { + } + + int response_from_grpc(isula::GraphdriverStatusResponse *gresp, isula_storage_status_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + + if (!gresp->backing_fs().empty()) { + resp->backing_fs = util_strdup_s(gresp->backing_fs().c_str()); + } + resp->supports_d_type = gresp->supports_d_type(); + resp->native_overlay_diff = gresp->native_overlay_diff(); + return 0; + } + + Status grpc_call(ClientContext *context, const isula::GraphdriverStatusRequest &req, + isula::GraphdriverStatusResponse *reply) override + { + return stub_->GraphdriverStatus(context, req, reply); + } +}; + +class ISulaContainerFsUsage : public + ClientBase { +public: + explicit ISulaContainerFsUsage(void *args) : ClientBase(args) + { + } + + int request_to_grpc(const isula_container_fs_usage_request *req, isula::ContainerFsUsageRequest *grequest) override + { + if (req == nullptr) { + lcrd_set_error_message("invalid containerfsusage request"); + return -1; + } + if (req->name_id != nullptr) { + grequest->set_name_id(req->name_id); + } + return 0; + } + + int response_from_grpc(isula::ContainerFsUsageResponse *gresp, isula_container_fs_usage_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + + if (!gresp->usage().empty()) { + resp->usage = util_strdup_s(gresp->usage().c_str()); + } + return 0; + } + + int check_parameter(const isula::ContainerFsUsageRequest &req) override + { + if (req.name_id().empty()) { + lcrd_set_error_message("Required container id"); + return -1; + } + + return 0; + } + + Status grpc_call(ClientContext *context, const isula::ContainerFsUsageRequest &req, + isula::ContainerFsUsageResponse *reply) override + { + return stub_->ContainerFsUsage(context, req, reply); + } +}; + +class ISulaImageFsInfo : public ClientBase { +public: + explicit ISulaImageFsInfo(void *args) : ClientBase(args) + { + } + + int response_from_grpc(isula::ImageFsInfoResponse *gresp, isula_image_fs_info_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + resp->image_filesystems_len = 0; + + if (gresp->image_filesystems_size() <= 0) { + return 0; + } + + size_t len = static_cast(gresp->image_filesystems_size()); + resp->image_filesystems = (struct filesystem_usage **)util_smart_calloc_s( + sizeof(struct filesystem_usage *), len); + if (resp->image_filesystems == nullptr) { + ERROR("Out of memory"); + return -1; + } + for (int i = 0; i < gresp->image_filesystems_size(); i++) { + struct filesystem_usage *tmp = nullptr; + if (parse_filesystem_usage(gresp->image_filesystems(i), &tmp) != 0) { + return -1; + } + resp->image_filesystems[i] = tmp; + (resp->image_filesystems_len)++; + } + + return 0; + } + + Status grpc_call(ClientContext *context, const isula::ImageFsInfoRequest &req, + isula::ImageFsInfoResponse *reply) override + { + return stub_->ImageFsInfo(context, req, reply); + } + +private: + int parse_filesystem_usage(const isula::FilesystemUsage &gusage, struct filesystem_usage **cusage) + { + struct filesystem_usage *tmp_cusage = nullptr; + + tmp_cusage = (struct filesystem_usage *)util_common_calloc_s(sizeof(struct filesystem_usage)); + if (tmp_cusage == nullptr) { + ERROR("Out of memory"); + return -1; + } + tmp_cusage->timestamp = gusage.timestamp(); + if (gusage.has_storage_id()) { + tmp_cusage->uuid = util_strdup_s(gusage.storage_id().uuid().c_str()); + } + if (gusage.has_used_bytes()) { + tmp_cusage->used_bytes = (uint64_t *)util_common_calloc_s(sizeof(uint64_t)); + if (tmp_cusage->used_bytes == nullptr) { + ERROR("Out of memory"); + free_filesystem_usage(tmp_cusage); + return -1; + } + *(tmp_cusage->used_bytes) = gusage.used_bytes().value(); + } + if (gusage.has_inodes_used()) { + tmp_cusage->inodes_used = (uint64_t *)util_common_calloc_s(sizeof(uint64_t)); + if (tmp_cusage->inodes_used == nullptr) { + ERROR("Out of memory"); + free_filesystem_usage(tmp_cusage); + return -1; + } + *(tmp_cusage->inodes_used) = gusage.inodes_used().value(); + } + *cusage = tmp_cusage; + return 0; + } +}; + +class ISulaHealthCheck : public ClientBase { +public: + explicit ISulaHealthCheck(void *args) : ClientBase(args) + { + } + + int response_from_grpc(isula::HealthCheckResponse *gresp, isula_health_check_response *resp) override + { + if (!gresp->errmsg().empty()) { + resp->errmsg = util_strdup_s(gresp->errmsg().c_str()); + } + resp->server_errono = gresp->cc(); + return 0; + } + + Status grpc_call(ClientContext *context, const isula::HealthCheckRequest &req, + isula::HealthCheckResponse *reply) override + { + return stub_->HealthCheck(context, req, reply); + } +}; + +int grpc_isula_image_client_ops_init(isula_image_ops *ops) +{ + if (ops == nullptr) { + return -1; + } + + ops->pull = container_func; + ops->rmi = container_func; + ops->load = container_func; + ops->login = container_func; + ops->logout = container_func; + ops->image_fs_info = container_func; + + ops->prepare = container_func; + ops->remove = container_func; + ops->mount = container_func; + ops->umount = container_func; + ops->containers_list = + container_func; + ops->container_export = container_func; + ops->container_fs_usage = + container_func; + + ops->list = container_func; + ops->status = container_func; + + ops->storage_status = container_func; + + ops->health_check = container_func; + + return 0; +} diff --git a/src/connect/client/grpc/grpc_isula_image_client.h b/src/connect/client/grpc/grpc_isula_image_client.h new file mode 100644 index 0000000..f4c9bd0 --- /dev/null +++ b/src/connect/client/grpc/grpc_isula_image_client.h @@ -0,0 +1,30 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-12 +* Description: provide lcrc connect command definition +*******************************************************************************/ +#ifndef __GRPC_ISULA_IMAGE_CONNECT_H +#define __GRPC_ISULA_IMAGE_CONNECT_H + +#include "isula_image_connect.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int grpc_isula_image_client_ops_init(isula_image_ops *ops); + +#ifdef __cplusplus +} +#endif + +#endif /* __GRPC_ISULA_IMAGE_CONNECT_H */ diff --git a/src/connect/client/isula_image_connect.c b/src/connect/client/isula_image_connect.c new file mode 100644 index 0000000..c70429f --- /dev/null +++ b/src/connect/client/isula_image_connect.c @@ -0,0 +1,495 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-12 +* Description: provide isula image connect command definition +*******************************************************************************/ +#include "isula_image_connect.h" + +#include "securec.h" +#include "utils.h" +#include "grpc_isula_image_client.h" + +static isula_image_ops g_image_ops; + +int isula_image_ops_init(void) +{ + errno_t ret; + + ret = memset_s(&g_image_ops, sizeof(isula_image_ops), 0, sizeof(isula_image_ops)); + if (ret != EOK) { + return -1; + } + + return grpc_isula_image_client_ops_init(&g_image_ops); +} + +isula_image_ops *get_isula_image_ops(void) +{ + return &g_image_ops; +} + +void free_image_spec(struct image_spec *spec) +{ + if (spec == NULL) { + return; + } + free(spec->image); + spec->image = NULL; + free(spec); +} + +void free_isula_auth_config(struct isula_auth_config *auth) +{ + if (auth == NULL) { + return; + } + free_sensitive_string(auth->username); + auth->username = NULL; + free_sensitive_string(auth->password); + auth->password = NULL; + free_sensitive_string(auth->auth); + auth->auth = NULL; + free_sensitive_string(auth->server_address); + auth->server_address = NULL; + free_sensitive_string(auth->identity_token); + auth->identity_token = NULL; + free_sensitive_string(auth->registry_token); + auth->registry_token = NULL; + free(auth); +} + +void free_isula_pull_request(struct isula_pull_request *req) +{ + if (req == NULL) { + return; + } + free_image_spec(req->image); + req->image = NULL; + free_isula_auth_config(req->auth); + req->auth = NULL; + free(req); +} + +void free_isula_pull_response(struct isula_pull_response *resp) +{ + if (resp == NULL) { + return; + } + free(resp->image_ref); + resp->image_ref = NULL; + free(resp->errmsg); + resp->errmsg = NULL; + resp->cc = 0; + free(resp); +} + +void free_isula_prepare_request(struct isula_prepare_request *req) +{ + if (req == NULL) { + return; + } + free(req->id); + req->id = NULL; + free(req->name); + req->name = NULL; + free(req->image); + req->image = NULL; + util_free_array(req->storage_opts); + req->storage_opts = NULL; + req->storage_opts_len = 0; + free(req); +} + +void free_isula_prepare_response(struct isula_prepare_response *resp) +{ + if (resp == NULL) { + return; + } + free(resp->mount_point); + resp->mount_point = NULL; + free(resp->image_conf); + resp->image_conf = NULL; + free(resp->errmsg); + resp->errmsg = NULL; + resp->cc = 0; + free(resp); +} + +void free_isula_remove_request(struct isula_remove_request *req) +{ + if (req == NULL) { + return; + } + free(req->name_id); + req->name_id = NULL; + free(req); +} + +void free_isula_remove_response(struct isula_remove_response *resp) +{ + if (resp == NULL) { + return; + } + free(resp->errmsg); + resp->errmsg = NULL; + resp->cc = 0; + free(resp); +} + +void free_isula_mount_request(struct isula_mount_request *req) +{ + if (req == NULL) { + return; + } + free(req->name_id); + req->name_id = NULL; + free(req); +} + +void free_isula_mount_response(struct isula_mount_response *resp) +{ + if (resp == NULL) { + return; + } + free(resp->errmsg); + resp->errmsg = NULL; + resp->cc = 0; + free(resp); +} + +void free_isula_umount_request(struct isula_umount_request *req) +{ + if (req == NULL) { + return; + } + free(req->name_id); + req->name_id = NULL; + free(req); +} + +void free_isula_umount_response(struct isula_umount_response *resp) +{ + if (resp == NULL) { + return; + } + free(resp->errmsg); + resp->errmsg = NULL; + resp->cc = 0; + free(resp); +} + +void free_isula_containers_list_request(struct isula_containers_list_request *req) +{ + if (req == NULL) { + return; + } + free(req); +} + +void free_isula_containers_list_response(struct isula_containers_list_response *resp) +{ + if (resp == NULL) { + return; + } + + free_json_map_string_bool(resp->containers); + + free(resp->errmsg); + resp->errmsg = NULL; + resp->cc = 0; + free(resp); +} + +void free_image_metadata(struct image_metadata *data) +{ + if (data == NULL) { + return; + } + free(data->id); + data->id = NULL; + util_free_array(data->repo_tags); + data->repo_tags = NULL; + data->repo_tags_len = 0; + util_free_array(data->repo_digests); + data->repo_digests = NULL; + data->repo_digests_len = 0; + free(data->username); + data->username = NULL; + free(data->created); + data->created = NULL; + free(data->loaded); + data->loaded = NULL; + free(data->oci_spec); + data->oci_spec = NULL; + free(data); +} + +void free_isula_status_request(struct isula_status_request *req) +{ + if (req == NULL) { + return; + } + free_image_spec(req->image); + req->image = NULL; + free(req); +} + +void free_isula_status_response(struct isula_status_response *resp) +{ + if (resp == NULL) { + return; + } + free_image_metadata(resp->image); + resp->image = NULL; + free_json_map_string_string(resp->info); + resp->info = NULL; + free(resp->errmsg); + resp->errmsg = NULL; + free(resp); +} + +void free_isula_list_request(struct isula_list_request *req) +{ + if (req == NULL) { + return; + } + free(req->filter); + req->filter = NULL; + free(req); +} + +void free_isula_list_response(struct isula_list_response *resp) +{ + size_t i = 0; + + if (resp == NULL) { + return; + } + for (; i < resp->images_len; i++) { + free_image_metadata(resp->images[i]); + resp->images[i] = NULL; + } + free(resp->images); + resp->images = NULL; + resp->images_len = 0; + free(resp->errmsg); + resp->errmsg = NULL; + free(resp); +} + +void free_isula_rmi_request(struct isula_rmi_request *ptr) +{ + if (ptr == NULL) { + return; + } + free_image_spec(ptr->image); + ptr->image = NULL; + free(ptr); +} + +void free_isula_rmi_response(struct isula_rmi_response *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->errmsg); + ptr->errmsg = NULL; + free(ptr); +} + +void free_isula_load_request(struct isula_load_request *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->file); + ptr->file = NULL; + free(ptr->tag); + ptr->tag = NULL; + free(ptr); +} + +void free_isula_load_response(struct isula_load_response *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->outmsg); + ptr->outmsg = NULL; + free(ptr->errmsg); + ptr->errmsg = NULL; + free(ptr); +} + +void free_isula_login_request(struct isula_login_request *ptr) +{ + if (ptr == NULL) { + return; + } + free_sensitive_string(ptr->password); + ptr->password = NULL; + free_sensitive_string(ptr->username); + ptr->username = NULL; + free(ptr->server); + ptr->server = NULL; + free(ptr); +} + +void free_isula_login_response(struct isula_login_response *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->errmsg); + ptr->errmsg = NULL; + free(ptr); +} + +void free_isula_logout_request(struct isula_logout_request *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->server); + ptr->server = NULL; + free(ptr); +} +void free_isula_logout_response(struct isula_logout_response *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->errmsg); + ptr->errmsg = NULL; + free(ptr); +} + +void free_filesystem_usage(struct filesystem_usage *usage) +{ + if (usage == NULL) { + return; + } + free(usage->uuid); + usage->uuid = NULL; + free(usage->used_bytes); + usage->used_bytes = NULL; + free(usage->inodes_used); + usage->inodes_used = NULL; + free(usage); +} + +void free_isula_image_fs_info_request(struct isula_image_fs_info_request *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr); +} + +void free_isula_image_fs_info_response(struct isula_image_fs_info_response *ptr) +{ + size_t i = 0; + + if (ptr == NULL) { + return; + } + for (; i < ptr->image_filesystems_len; i++) { + free_filesystem_usage(ptr->image_filesystems[i]); + ptr->image_filesystems[i] = NULL; + } + ptr->image_filesystems_len = 0; + free(ptr->image_filesystems); + ptr->image_filesystems = NULL; + free(ptr); +} + +void free_isula_export_request(struct isula_export_request *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->name_id); + ptr->name_id = NULL; + free(ptr->output); + ptr->output = NULL; + free(ptr); +} + +void free_isula_export_response(struct isula_export_response *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->errmsg); + ptr->errmsg = NULL; + free(ptr); +} + +void free_isula_container_fs_usage_request(struct isula_container_fs_usage_request *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->name_id); + ptr->name_id = NULL; + free(ptr); +} + +void free_isula_container_fs_usage_response(struct isula_container_fs_usage_response *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->usage); + ptr->usage = NULL; + free(ptr->errmsg); + ptr->errmsg = NULL; + free(ptr); +} + +void free_isula_storage_status_request(struct isula_storage_status_request *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr); +} + +void free_isula_storage_status_response(struct isula_storage_status_response *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->backing_fs); + ptr->backing_fs = NULL; + free(ptr->errmsg); + ptr->errmsg = NULL; + free(ptr); +} + +void free_isula_health_check_request(struct isula_health_check_request *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr); +} + +void free_isula_health_check_response(struct isula_health_check_response *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->errmsg); + ptr->errmsg = NULL; + free(ptr); +} diff --git a/src/connect/client/isula_image_connect.h b/src/connect/client/isula_image_connect.h new file mode 100644 index 0000000..8a2fa79 --- /dev/null +++ b/src/connect/client/isula_image_connect.h @@ -0,0 +1,367 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-12 +* Description: provide isula image connect command definition +*******************************************************************************/ +#ifndef __ISULA_IMAGE_CONNECT_H +#define __ISULA_IMAGE_CONNECT_H + +#include +#include + +#include "json_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct image_spec { + char *image; +}; + +struct isula_auth_config { + char *username; + char *password; + char *auth; + char *server_address; + char *identity_token; + char *registry_token; +}; + +struct isula_pull_request { + struct image_spec *image; + struct isula_auth_config *auth; +}; + +struct isula_pull_response { + char *image_ref; + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_prepare_request { + char *image; + char *id; + char *name; + char **storage_opts; + size_t storage_opts_len; +}; + +struct isula_prepare_response { + char *mount_point; + char *image_conf; + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_remove_request { + char *name_id; +}; + +struct isula_remove_response { + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_mount_request { + char *name_id; +}; + +struct isula_mount_response { + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_umount_request { + char *name_id; + bool force; +}; + +struct isula_umount_response { + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct image_metadata { + char *id; + + char **repo_tags; + size_t repo_tags_len; + + char **repo_digests; + size_t repo_digests_len; + + uint64_t size; + + int64_t uid; + + char *username; + + char *created; + + char *loaded; + + char *oci_spec; +}; + +struct isula_status_request { + struct image_spec *image; + bool verbose; +}; + +struct isula_status_response { + struct image_metadata *image; + json_map_string_string *info; + + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_list_request { + char *filter; + bool check; +}; + +struct isula_list_response { + struct image_metadata **images; + size_t images_len; + + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_rmi_request { + struct image_spec *image; + bool force; +}; + +struct isula_rmi_response { + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_load_request { + char *file; + char *tag; +}; + +struct isula_load_response { + char *outmsg; + + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_login_request { + char *server; + char *username; + char *password; +}; + +struct isula_login_response { + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_logout_request { + char *server; +}; + +struct isula_logout_response { + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_export_request { + char *name_id; + char *output; + uint32_t uid; + uint32_t gid; + uint32_t offset; +}; + +struct isula_export_response { + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_containers_list_request { + char unuseful; +}; + +struct isula_containers_list_response { + json_map_string_bool *containers; + + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_storage_status_request { + char unuseful; +}; + +struct isula_storage_status_response { + char *backing_fs; + bool supports_d_type; + bool native_overlay_diff; + + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_container_fs_usage_request { + char *name_id; +}; + +struct isula_container_fs_usage_response { + char *usage; + + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_image_fs_info_request { + char unuseful; +}; + +struct filesystem_usage { + int64_t timestamp; + char *uuid; + uint64_t *used_bytes; + uint64_t *inodes_used; +}; + +struct isula_image_fs_info_response { + struct filesystem_usage **image_filesystems; + size_t image_filesystems_len; + + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +struct isula_health_check_request { + char unuseful; +}; + +struct isula_health_check_response { + char *errmsg; + uint32_t cc; + uint32_t server_errono; +}; + +typedef struct { + int (*pull)(const struct isula_pull_request *req, struct isula_pull_response *resp, void *arg); + int (*rmi)(const struct isula_rmi_request *req, struct isula_rmi_response *resp, void *arg); + int (*load)(const struct isula_load_request *req, struct isula_load_response *resp, void *arg); + int (*login)(const struct isula_login_request *req, struct isula_login_response *resp, void *arg); + int (*logout)(const struct isula_logout_request *req, struct isula_logout_response *resp, void *arg); + int (*image_fs_info)(const struct isula_image_fs_info_request *req, struct isula_image_fs_info_response *resp, + void *arg); + + int (*prepare)(const struct isula_prepare_request *req, struct isula_prepare_response *resp, void *arg); + int (*remove)(const struct isula_remove_request *req, struct isula_remove_response *resp, void *arg); + int (*mount)(const struct isula_mount_request *req, struct isula_mount_response *resp, void *arg); + int (*umount)(const struct isula_umount_request *req, struct isula_umount_response *resp, void *arg); + int (*containers_list)(const struct isula_containers_list_request *req, struct isula_containers_list_response *resp, + void *arg); + int (*container_export)(const struct isula_export_request *req, struct isula_export_response *resp, void *arg); + int (*container_fs_usage)(const struct isula_container_fs_usage_request *req, + struct isula_container_fs_usage_response *resp, void *arg); + + int (*status)(const struct isula_status_request *req, struct isula_status_response *resp, void *arg); + int (*list)(const struct isula_list_request *req, struct isula_list_response *resp, void *arg); + + int (*storage_status)(const struct isula_storage_status_request *req, struct isula_storage_status_response *resp, + void *arg); + + int (*health_check)(const struct isula_health_check_request *req, + struct isula_health_check_response *resp, void *arg); +} isula_image_ops; + + +/* init isula image function pointer */ +int isula_image_ops_init(void); + +/* return initilized isula image ops */ +isula_image_ops *get_isula_image_ops(void); + +void free_image_spec(struct image_spec *spec); +void free_isula_auth_config(struct isula_auth_config *auth); +void free_isula_pull_request(struct isula_pull_request *req); +void free_isula_pull_response(struct isula_pull_response *resp); +void free_isula_prepare_request(struct isula_prepare_request *req); +void free_isula_prepare_response(struct isula_prepare_response *resp); +void free_isula_remove_request(struct isula_remove_request *req); +void free_isula_remove_response(struct isula_remove_response *resp); +void free_isula_mount_request(struct isula_mount_request *req); +void free_isula_mount_response(struct isula_mount_response *resp); +void free_isula_umount_request(struct isula_umount_request *req); +void free_isula_umount_response(struct isula_umount_response *resp); + +void free_isula_containers_list_request(struct isula_containers_list_request *req); +void free_isula_containers_list_response(struct isula_containers_list_response *resp); + +void free_image_metadata(struct image_metadata *data); +void free_isula_status_request(struct isula_status_request *req); +void free_isula_status_response(struct isula_status_response *resp); +void free_isula_list_request(struct isula_list_request *req); +void free_isula_list_response(struct isula_list_response *resp); + +void free_isula_rmi_request(struct isula_rmi_request *ptr); +void free_isula_rmi_response(struct isula_rmi_response *ptr); + +void free_isula_load_request(struct isula_load_request *ptr); +void free_isula_load_response(struct isula_load_response *ptr); + +void free_isula_login_request(struct isula_login_request *ptr); +void free_isula_login_response(struct isula_login_response *ptr); + +void free_isula_logout_request(struct isula_logout_request *ptr); +void free_isula_logout_response(struct isula_logout_response *ptr); + +void free_filesystem_usage(struct filesystem_usage *usage); +void free_isula_image_fs_info_request(struct isula_image_fs_info_request *ptr); +void free_isula_image_fs_info_response(struct isula_image_fs_info_response *ptr); + +void free_isula_export_request(struct isula_export_request *ptr); +void free_isula_export_response(struct isula_export_response *ptr); + +void free_isula_container_fs_usage_request(struct isula_container_fs_usage_request *ptr); +void free_isula_container_fs_usage_response(struct isula_container_fs_usage_response *ptr); + +void free_isula_storage_status_request(struct isula_storage_status_request *ptr); +void free_isula_storage_status_response(struct isula_storage_status_response *ptr); + +void free_isula_health_check_request(struct isula_health_check_request *ptr); +void free_isula_health_check_response(struct isula_health_check_response *ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* __ISULA_IMAGE_CONNECT_H */ diff --git a/src/connect/client/lcrc_connect.c b/src/connect/client/lcrc_connect.c index bac7aa9..ad4d60c 100644 --- a/src/connect/client/lcrc_connect.c +++ b/src/connect/client/lcrc_connect.c @@ -49,3 +49,4 @@ lcrc_connect_ops *get_connect_client_ops(void) { return &g_connect_ops; } + diff --git a/src/connect/client/lcrc_connect.h b/src/connect/client/lcrc_connect.h index 6dc3ee6..b18e3a5 100644 --- a/src/connect/client/lcrc_connect.h +++ b/src/connect/client/lcrc_connect.h @@ -143,3 +143,4 @@ lcrc_connect_ops *get_connect_client_ops(void); #endif #endif /* __LCRC_CONNECT_H */ + diff --git a/src/connect/client/rest/rest_client.c b/src/connect/client/rest/rest_client.c index 1f72d45..8942b37 100644 --- a/src/connect/client/rest/rest_client.c +++ b/src/connect/client/rest/rest_client.c @@ -32,3 +32,4 @@ int rest_ops_init(lcrc_connect_ops *ops) return 0; } + diff --git a/src/connect/client/rest/rest_client.h b/src/connect/client/rest/rest_client.h index 9a8476d..e5f2eb2 100644 --- a/src/connect/client/rest/rest_client.h +++ b/src/connect/client/rest/rest_client.h @@ -28,3 +28,4 @@ int rest_ops_init(lcrc_connect_ops *ops); #endif #endif + diff --git a/src/connect/client/rest/rest_containers_client.c b/src/connect/client/rest/rest_containers_client.c index 8b82f02..1e5b9bc 100644 --- a/src/connect/client/rest/rest_containers_client.c +++ b/src/connect/client/rest/rest_containers_client.c @@ -1808,7 +1808,6 @@ static int unpack_exec_response(const struct parsed_http_message *message, void goto out; } response->server_errono = cresponse->cc; - response->pid = cresponse->pid; response->exit_code = cresponse->exit_code; if (cresponse->errmsg != NULL) { response->errmsg = util_strdup_s(cresponse->errmsg); diff --git a/src/connect/client/rest/rest_containers_client.h b/src/connect/client/rest/rest_containers_client.h index 3de2503..a083646 100644 --- a/src/connect/client/rest/rest_containers_client.h +++ b/src/connect/client/rest/rest_containers_client.h @@ -28,3 +28,4 @@ int rest_containers_client_ops_init(lcrc_connect_ops *ops); #endif #endif + diff --git a/src/connect/client/rest/rest_images_client.h b/src/connect/client/rest/rest_images_client.h index e5e294f..7226d6d 100644 --- a/src/connect/client/rest/rest_images_client.h +++ b/src/connect/client/rest/rest_images_client.h @@ -28,3 +28,4 @@ int rest_images_client_ops_init(lcrc_connect_ops *ops); #endif #endif + diff --git a/src/connect/service/grpc/grpc_containers_service.h b/src/connect/service/grpc/grpc_containers_service.h index 727239b..4d903cc 100644 --- a/src/connect/service/grpc/grpc_containers_service.h +++ b/src/connect/service/grpc/grpc_containers_service.h @@ -222,4 +222,5 @@ private: int logs_request_from_grpc(const LogsRequest *grequest, struct lcrd_logs_request **request); }; -#endif /*_GRPC_CONTAINER_SERVICE_H_*/ +#endif /* _GRPC_CONTAINER_SERVICE_H_ */ + diff --git a/src/connect/service/grpc/grpc_containers_service_private.cc b/src/connect/service/grpc/grpc_containers_service_private.cc index 04104a4..4454a84 100644 --- a/src/connect/service/grpc/grpc_containers_service_private.cc +++ b/src/connect/service/grpc/grpc_containers_service_private.cc @@ -403,6 +403,9 @@ int ContainerServiceImpl::exec_request_from_grpc(const ExecRequest *grequest, co tmpreq->env_len = grequest->env_size(); } + if (!grequest->user().empty()) { + tmpreq->user = util_strdup_s(grequest->user().c_str()); + } *request = tmpreq; return 0; } @@ -415,7 +418,6 @@ int ContainerServiceImpl::exec_response_to_grpc(const container_exec_response *r } gresponse->set_cc(response->cc); - gresponse->set_pid(response->pid); gresponse->set_exit_code(response->exit_code); if (response->errmsg != nullptr) { gresponse->set_errmsg(response->errmsg); @@ -567,6 +569,7 @@ int ContainerServiceImpl::list_response_to_grpc(const container_list_response *r if (response->containers[i]->health_state != nullptr) { container->set_health_state(response->containers[i]->health_state); } + container->set_created(response->containers[i]->created); } return 0; } @@ -908,7 +911,6 @@ void ContainerServiceImpl::add_exec_trailing_metadata(ServerContext *context, co return; } context->AddTrailingMetadata("cc", std::to_string(response->cc)); - context->AddTrailingMetadata("pid", std::to_string(response->pid)); context->AddTrailingMetadata("exit_code", std::to_string(response->exit_code)); if (response->errmsg != nullptr) { context->AddTrailingMetadata("errmsg", response->errmsg); diff --git a/src/connect/service/grpc/grpc_images_service.cc b/src/connect/service/grpc/grpc_images_service.cc index 9874378..f313140 100644 --- a/src/connect/service/grpc/grpc_images_service.cc +++ b/src/connect/service/grpc/grpc_images_service.cc @@ -29,15 +29,64 @@ int ImagesServiceImpl::image_list_request_from_grpc(const ListImagesRequest *grequest, image_list_images_request **request) { + size_t len = 0; image_list_images_request *tmpreq = (image_list_images_request *)util_common_calloc_s( sizeof(image_list_images_request)); if (tmpreq == nullptr) { ERROR("Out of memory"); return -1; } - *request = tmpreq; + len = (size_t)grequest->filters_size(); + if (len == 0) { + *request = tmpreq; + return 0; + } + if (len > SIZE_MAX / sizeof(char *)) { + ERROR("invalid filters size"); + goto cleanup; + } + + tmpreq->filters = (defs_filters *)util_common_calloc_s(sizeof(defs_filters)); + if (tmpreq->filters == nullptr) { + ERROR("Out of memory"); + goto cleanup; + } + + tmpreq->filters->keys = (char **)util_common_calloc_s(len * sizeof(char *)); + if (tmpreq->filters->keys == nullptr) { + goto cleanup; + } + tmpreq->filters->values = (json_map_string_bool **)util_common_calloc_s(len * sizeof(json_map_string_bool *)); + if (tmpreq->filters->values == nullptr) { + free(tmpreq->filters->keys); + tmpreq->filters->keys = nullptr; + goto cleanup; + } + + for (auto &iter : grequest->filters()) { + tmpreq->filters->values[tmpreq->filters->len] = (json_map_string_bool *) + util_common_calloc_s(sizeof(json_map_string_bool)); + if (tmpreq->filters->values[tmpreq->filters->len] == nullptr) { + ERROR("Out of memory"); + goto cleanup; + } + if (append_json_map_string_bool(tmpreq->filters->values[tmpreq->filters->len], + iter.second.empty() ? "" : iter.second.c_str(), true)) { + free(tmpreq->filters->values[tmpreq->filters->len]); + tmpreq->filters->values[tmpreq->filters->len] = nullptr; + ERROR("Append failed"); + goto cleanup; + } + tmpreq->filters->keys[tmpreq->filters->len] = util_strdup_s(iter.first.empty() ? "" : iter.first.c_str()); + tmpreq->filters->len++; + } + *request = tmpreq; return 0; + +cleanup: + free_image_list_images_request(tmpreq); + return -1; } int ImagesServiceImpl::image_list_response_to_grpc(image_list_images_response *response, ListImagesResponse *gresponse) @@ -273,6 +322,11 @@ Status ImagesServiceImpl::Inspect(ServerContext *context, const InspectImageRequ image_inspect_request *image_req = nullptr; image_inspect_response *image_res = nullptr; + Status status = GrpcServerTlsAuth::auth(context, "image_inspect"); + if (!status.ok()) { + return status; + } + cb = get_service_callback(); if (cb == nullptr || cb->image.inspect == nullptr) { return Status(StatusCode::UNIMPLEMENTED, "Unimplemented callback"); @@ -285,11 +339,6 @@ Status ImagesServiceImpl::Inspect(ServerContext *context, const InspectImageRequ return Status::OK; } - Status status = GrpcServerTlsAuth::auth(context, "image_inspect"); - if (!status.ok()) { - return status; - } - ret = cb->image.inspect(image_req, &image_res); tret = inspect_response_to_grpc(image_res, reply); @@ -419,3 +468,4 @@ Status ImagesServiceImpl::Logout(ServerContext *context, const LogoutRequest *re return Status::OK; } + diff --git a/src/connect/service/grpc/grpc_images_service.h b/src/connect/service/grpc/grpc_images_service.h index b41111a..e0950d9 100644 --- a/src/connect/service/grpc/grpc_images_service.h +++ b/src/connect/service/grpc/grpc_images_service.h @@ -88,4 +88,5 @@ private: int image_logout_request_from_grpc(const LogoutRequest *grequest, image_logout_request **request); }; -#endif /*_GRPC_IMAGES_SERVICE_H_*/ +#endif /* _GRPC_IMAGES_SERVICE_H_ */ + diff --git a/src/connect/service/grpc/grpc_server_tls_auth.cc b/src/connect/service/grpc/grpc_server_tls_auth.cc index 41ca235..19c205d 100644 --- a/src/connect/service/grpc/grpc_server_tls_auth.cc +++ b/src/connect/service/grpc/grpc_server_tls_auth.cc @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -58,3 +58,4 @@ Status auth(ServerContext *context, std::string action) return Status::OK; } } // namespace GrpcServerTlsAuth + diff --git a/src/connect/service/grpc/grpc_server_tls_auth.h b/src/connect/service/grpc/grpc_server_tls_auth.h index 02c247d..6163ede 100644 --- a/src/connect/service/grpc/grpc_server_tls_auth.h +++ b/src/connect/service/grpc/grpc_server_tls_auth.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -31,3 +31,4 @@ Status auth(ServerContext *context, std::string action); }; #endif /* _GRPC_SERVER_TLS_AUTH_H_ */ + diff --git a/src/connect/service/grpc/grpc_service.cc b/src/connect/service/grpc/grpc_service.cc index b0498d2..af39ece 100644 --- a/src/connect/service/grpc/grpc_service.cc +++ b/src/connect/service/grpc/grpc_service.cc @@ -231,3 +231,4 @@ void grpc_server_shutdown(void) { g_grpcserver->Shutdown(); } + diff --git a/src/connect/service/grpc/grpc_service.h b/src/connect/service/grpc/grpc_service.h index f9261b4..637d8a1 100644 --- a/src/connect/service/grpc/grpc_service.h +++ b/src/connect/service/grpc/grpc_service.h @@ -33,3 +33,4 @@ void grpc_server_shutdown(void); #endif #endif /* __GRPC_SERVICE_H */ + diff --git a/src/connect/service/grpc/runtime_image_service.cc b/src/connect/service/grpc/runtime_image_service.cc index c2b217b..10a0a87 100644 --- a/src/connect/service/grpc/runtime_image_service.cc +++ b/src/connect/service/grpc/runtime_image_service.cc @@ -22,8 +22,8 @@ #include "log.h" grpc::Status RuntimeImageServiceImpl::PullImage(grpc::ServerContext *context, - const runtime::PullImageRequest *request, - runtime::PullImageResponse *reply) + const runtime::v1alpha2::PullImageRequest *request, + runtime::v1alpha2::PullImageResponse *reply) { Errors error; std::string imageRef = rService.PullImage(request->image(), request->auth(), error); @@ -35,10 +35,10 @@ grpc::Status RuntimeImageServiceImpl::PullImage(grpc::ServerContext *context, } grpc::Status RuntimeImageServiceImpl::ListImages(grpc::ServerContext *context, - const runtime::ListImagesRequest *request, - runtime::ListImagesResponse *reply) + const runtime::v1alpha2::ListImagesRequest *request, + runtime::v1alpha2::ListImagesResponse *reply) { - std::vector> images; + std::vector> images; Errors error; rService.ListImages(request->filter(), &images, error); @@ -47,7 +47,7 @@ grpc::Status RuntimeImageServiceImpl::ListImages(grpc::ServerContext *context, } for (auto iter = images.begin(); iter != images.end(); iter++) { - runtime::Image *image = reply->add_images(); + runtime::v1alpha2::Image *image = reply->add_images(); if (image == nullptr) { return grpc::Status(grpc::StatusCode::UNKNOWN, "Out of memory"); } @@ -57,10 +57,10 @@ grpc::Status RuntimeImageServiceImpl::ListImages(grpc::ServerContext *context, } grpc::Status RuntimeImageServiceImpl::ImageStatus(grpc::ServerContext *context, - const runtime::ImageStatusRequest *request, - runtime::ImageStatusResponse *reply) + const runtime::v1alpha2::ImageStatusRequest *request, + runtime::v1alpha2::ImageStatusResponse *reply) { - std::unique_ptr image_info = nullptr; + std::unique_ptr image_info = nullptr; Errors error; image_info = rService.ImageStatus(request->image(), error); @@ -69,7 +69,7 @@ grpc::Status RuntimeImageServiceImpl::ImageStatus(grpc::ServerContext *context, } if (image_info != nullptr) { - runtime::Image *image = reply->mutable_image(); + runtime::v1alpha2::Image *image = reply->mutable_image(); *image = *image_info; } @@ -77,10 +77,10 @@ grpc::Status RuntimeImageServiceImpl::ImageStatus(grpc::ServerContext *context, } grpc::Status RuntimeImageServiceImpl::ImageFsInfo(grpc::ServerContext *context, - const runtime::ImageFsInfoRequest *request, - runtime::ImageFsInfoResponse *reply) + const runtime::v1alpha2::ImageFsInfoRequest *request, + runtime::v1alpha2::ImageFsInfoResponse *reply) { - std::vector> usages; + std::vector> usages; Errors error; rService.ImageFsInfo(&usages, error); @@ -89,7 +89,7 @@ grpc::Status RuntimeImageServiceImpl::ImageFsInfo(grpc::ServerContext *context, } for (auto iter = usages.begin(); iter != usages.end(); ++iter) { - runtime::FilesystemUsage *fs_info = reply->add_image_filesystems(); + runtime::v1alpha2::FilesystemUsage *fs_info = reply->add_image_filesystems(); if (fs_info == nullptr) { return grpc::Status(grpc::StatusCode::UNKNOWN, "Out of memory"); } @@ -99,8 +99,8 @@ grpc::Status RuntimeImageServiceImpl::ImageFsInfo(grpc::ServerContext *context, } grpc::Status RuntimeImageServiceImpl::RemoveImage(grpc::ServerContext *context, - const runtime::RemoveImageRequest *request, - runtime::RemoveImageResponse *reply) + const runtime::v1alpha2::RemoveImageRequest *request, + runtime::v1alpha2::RemoveImageResponse *reply) { Errors error; @@ -111,3 +111,4 @@ grpc::Status RuntimeImageServiceImpl::RemoveImage(grpc::ServerContext *context, return grpc::Status::OK; } + diff --git a/src/connect/service/grpc/runtime_image_service.h b/src/connect/service/grpc/runtime_image_service.h index 17001f8..e5b5ac9 100644 --- a/src/connect/service/grpc/runtime_image_service.h +++ b/src/connect/service/grpc/runtime_image_service.h @@ -22,27 +22,28 @@ // Implement of runtime RuntimeService class RuntimeImageServiceImpl: public - runtime::ImageService::Service { + runtime::v1alpha2::ImageService::Service { public: grpc::Status PullImage(grpc::ServerContext *context, - const runtime::PullImageRequest *request, - runtime::PullImageResponse *reply) override; + const runtime::v1alpha2::PullImageRequest *request, + runtime::v1alpha2::PullImageResponse *reply) override; grpc::Status ListImages(grpc::ServerContext *context, - const runtime::ListImagesRequest *request, - runtime::ListImagesResponse *reply) override; + const runtime::v1alpha2::ListImagesRequest *request, + runtime::v1alpha2::ListImagesResponse *reply) override; grpc::Status ImageStatus(grpc::ServerContext *context, - const runtime::ImageStatusRequest *request, - runtime::ImageStatusResponse *reply) override; + const runtime::v1alpha2::ImageStatusRequest *request, + runtime::v1alpha2::ImageStatusResponse *reply) override; grpc::Status ImageFsInfo(grpc::ServerContext *context, - const runtime::ImageFsInfoRequest *request, - runtime::ImageFsInfoResponse *reply) override; + const runtime::v1alpha2::ImageFsInfoRequest *request, + runtime::v1alpha2::ImageFsInfoResponse *reply) override; grpc::Status RemoveImage(grpc::ServerContext *context, - const runtime::RemoveImageRequest *request, - runtime::RemoveImageResponse *reply) override; + const runtime::v1alpha2::RemoveImageRequest *request, + runtime::v1alpha2::RemoveImageResponse *reply) override; private: CRIImageServiceImpl rService; }; #endif /* _RUNTIME_IMAGE_SERVICES_IMPL_H_ */ + diff --git a/src/connect/service/grpc/runtime_runtime_service.cc b/src/connect/service/grpc/runtime_runtime_service.cc index 440eadd..51f0cce 100644 --- a/src/connect/service/grpc/runtime_runtime_service.cc +++ b/src/connect/service/grpc/runtime_runtime_service.cc @@ -49,8 +49,9 @@ void RuntimeRuntimeServiceImpl::Shutdown() websocket_server_shutdown(); } -grpc::Status RuntimeRuntimeServiceImpl::Version(grpc::ServerContext *context, const runtime::VersionRequest *request, - runtime::VersionResponse *reply) +grpc::Status RuntimeRuntimeServiceImpl::Version(grpc::ServerContext *context, + const runtime::v1alpha2::VersionRequest *request, + runtime::v1alpha2::VersionResponse *reply) { Errors error; rService.Version(request->version(), reply, error); @@ -62,8 +63,8 @@ grpc::Status RuntimeRuntimeServiceImpl::Version(grpc::ServerContext *context, co } grpc::Status RuntimeRuntimeServiceImpl::CreateContainer(grpc::ServerContext *context, - const runtime::CreateContainerRequest *request, - runtime::CreateContainerResponse *reply) + const runtime::v1alpha2::CreateContainerRequest *request, + runtime::v1alpha2::CreateContainerResponse *reply) { Errors error; std::string responseID = rService.CreateContainer(request->pod_sandbox_id(), request->config(), @@ -77,8 +78,8 @@ grpc::Status RuntimeRuntimeServiceImpl::CreateContainer(grpc::ServerContext *con } grpc::Status RuntimeRuntimeServiceImpl::StartContainer(grpc::ServerContext *context, - const runtime::StartContainerRequest *request, - runtime::StartContainerResponse *reply) + const runtime::v1alpha2::StartContainerRequest *request, + runtime::v1alpha2::StartContainerResponse *reply) { Errors error; rService.StartContainer(request->container_id(), error); @@ -90,8 +91,8 @@ grpc::Status RuntimeRuntimeServiceImpl::StartContainer(grpc::ServerContext *cont } grpc::Status RuntimeRuntimeServiceImpl::StopContainer(grpc::ServerContext *context, - const runtime::StopContainerRequest *request, - runtime::StopContainerResponse *reply) + const runtime::v1alpha2::StopContainerRequest *request, + runtime::v1alpha2::StopContainerResponse *reply) { Errors error; rService.StopContainer(request->container_id(), (int64_t)request->timeout(), error); @@ -103,8 +104,8 @@ grpc::Status RuntimeRuntimeServiceImpl::StopContainer(grpc::ServerContext *conte } grpc::Status RuntimeRuntimeServiceImpl::RemoveContainer(grpc::ServerContext *context, - const runtime::RemoveContainerRequest *request, - runtime::RemoveContainerResponse *reply) + const runtime::v1alpha2::RemoveContainerRequest *request, + runtime::v1alpha2::RemoveContainerResponse *reply) { Errors error; rService.RemoveContainer(request->container_id(), error); @@ -116,18 +117,18 @@ grpc::Status RuntimeRuntimeServiceImpl::RemoveContainer(grpc::ServerContext *con } grpc::Status RuntimeRuntimeServiceImpl::ListContainers(grpc::ServerContext *context, - const runtime::ListContainersRequest *request, - runtime::ListContainersResponse *reply) + const runtime::v1alpha2::ListContainersRequest *request, + runtime::v1alpha2::ListContainersResponse *reply) { Errors error; - std::vector> containers; + std::vector> containers; rService.ListContainers(request->has_filter() ? &request->filter() : nullptr, &containers, error); if (!error.Empty()) { return grpc::Status(grpc::StatusCode::UNKNOWN, error.GetMessage()); } for (auto iter = containers.begin(); iter != containers.end(); ++iter) { - runtime::Container *container = reply->add_containers(); + runtime::v1alpha2::Container *container = reply->add_containers(); if (container == nullptr) { return grpc::Status(grpc::StatusCode::UNKNOWN, "Out of memory"); } @@ -138,19 +139,19 @@ grpc::Status RuntimeRuntimeServiceImpl::ListContainers(grpc::ServerContext *cont } grpc::Status RuntimeRuntimeServiceImpl::ListContainerStats(grpc::ServerContext *context, - const runtime::ListContainerStatsRequest *request, - runtime::ListContainerStatsResponse *reply) + const runtime::v1alpha2::ListContainerStatsRequest *request, + runtime::v1alpha2::ListContainerStatsResponse *reply) { Errors error; - std::vector> containers; + std::vector> containers; rService.ListContainerStats(request->has_filter() ? &request->filter() : nullptr, &containers, error); if (!error.Empty()) { return grpc::Status(grpc::StatusCode::UNKNOWN, error.GetMessage()); } for (auto iter = containers.begin(); iter != containers.end(); ++iter) { - runtime::ContainerStats *container = reply->add_stats(); + runtime::v1alpha2::ContainerStats *container = reply->add_stats(); if (container == nullptr) { return grpc::Status(grpc::StatusCode::UNKNOWN, "Out of memory"); } @@ -161,11 +162,12 @@ grpc::Status RuntimeRuntimeServiceImpl::ListContainerStats(grpc::ServerContext * } grpc::Status RuntimeRuntimeServiceImpl::ContainerStatus(grpc::ServerContext *context, - const runtime::ContainerStatusRequest *request, - runtime::ContainerStatusResponse *reply) + const runtime::v1alpha2::ContainerStatusRequest *request, + runtime::v1alpha2::ContainerStatusResponse *reply) { Errors error; - std::unique_ptr contStatus = rService.ContainerStatus(request->container_id(), error); + std::unique_ptr contStatus = rService.ContainerStatus(request->container_id(), + error); if (!error.Empty() || !contStatus) { return grpc::Status(grpc::StatusCode::UNKNOWN, error.GetMessage()); } @@ -174,8 +176,9 @@ grpc::Status RuntimeRuntimeServiceImpl::ContainerStatus(grpc::ServerContext *con return grpc::Status::OK; } -grpc::Status RuntimeRuntimeServiceImpl::ExecSync(grpc::ServerContext *context, const runtime::ExecSyncRequest *request, - runtime::ExecSyncResponse *reply) +grpc::Status RuntimeRuntimeServiceImpl::ExecSync(grpc::ServerContext *context, + const runtime::v1alpha2::ExecSyncRequest *request, + runtime::v1alpha2::ExecSyncResponse *reply) { Errors error; rService.ExecSync(request->container_id(), request->cmd(), request->timeout(), reply, error); @@ -187,8 +190,8 @@ grpc::Status RuntimeRuntimeServiceImpl::ExecSync(grpc::ServerContext *context, c } grpc::Status RuntimeRuntimeServiceImpl::RunPodSandbox( - grpc::ServerContext *context, const runtime::RunPodSandboxRequest *request, - runtime::RunPodSandboxResponse *reply) + grpc::ServerContext *context, const runtime::v1alpha2::RunPodSandboxRequest *request, + runtime::v1alpha2::RunPodSandboxResponse *reply) { Errors error; std::string responseID = rService.RunPodSandbox(request->config(), error); @@ -201,8 +204,8 @@ grpc::Status RuntimeRuntimeServiceImpl::RunPodSandbox( } grpc::Status RuntimeRuntimeServiceImpl::StopPodSandbox( - grpc::ServerContext *context, const runtime::StopPodSandboxRequest *request, - runtime::StopPodSandboxResponse *reply) + grpc::ServerContext *context, const runtime::v1alpha2::StopPodSandboxRequest *request, + runtime::v1alpha2::StopPodSandboxResponse *reply) { Errors error; rService.StopPodSandbox(request->pod_sandbox_id(), error); @@ -214,8 +217,8 @@ grpc::Status RuntimeRuntimeServiceImpl::StopPodSandbox( } grpc::Status RuntimeRuntimeServiceImpl::RemovePodSandbox( - grpc::ServerContext *context, const runtime::RemovePodSandboxRequest *request, - runtime::RemovePodSandboxResponse *reply) + grpc::ServerContext *context, const runtime::v1alpha2::RemovePodSandboxRequest *request, + runtime::v1alpha2::RemovePodSandboxResponse *reply) { Errors error; rService.RemovePodSandbox(request->pod_sandbox_id(), error); @@ -226,11 +229,11 @@ grpc::Status RuntimeRuntimeServiceImpl::RemovePodSandbox( } grpc::Status RuntimeRuntimeServiceImpl::PodSandboxStatus( - grpc::ServerContext *context, const runtime::PodSandboxStatusRequest *request, - runtime::PodSandboxStatusResponse *reply) + grpc::ServerContext *context, const runtime::v1alpha2::PodSandboxStatusRequest *request, + runtime::v1alpha2::PodSandboxStatusResponse *reply) { Errors error; - std::unique_ptr podStatus; + std::unique_ptr podStatus; podStatus = rService.PodSandboxStatus(request->pod_sandbox_id(), error); if (!error.Empty() || !podStatus) { return grpc::Status(grpc::StatusCode::UNKNOWN, error.GetMessage()); @@ -241,17 +244,17 @@ grpc::Status RuntimeRuntimeServiceImpl::PodSandboxStatus( } grpc::Status RuntimeRuntimeServiceImpl::ListPodSandbox( - grpc::ServerContext *context, const runtime::ListPodSandboxRequest *request, - runtime::ListPodSandboxResponse *reply) + grpc::ServerContext *context, const runtime::v1alpha2::ListPodSandboxRequest *request, + runtime::v1alpha2::ListPodSandboxResponse *reply) { Errors error; - std::vector> pods; + std::vector> pods; rService.ListPodSandbox(request->has_filter() ? &request->filter() : nullptr, &pods, error); if (!error.Empty()) { return grpc::Status(grpc::StatusCode::UNKNOWN, error.GetMessage()); } for (auto iter = pods.begin(); iter != pods.end(); ++iter) { - runtime::PodSandbox *pod = reply->add_items(); + runtime::v1alpha2::PodSandbox *pod = reply->add_items(); if (pod == nullptr) { return grpc::Status(grpc::StatusCode::UNKNOWN, "Out of memory"); } @@ -262,8 +265,8 @@ grpc::Status RuntimeRuntimeServiceImpl::ListPodSandbox( } grpc::Status RuntimeRuntimeServiceImpl::UpdateContainerResources( - grpc::ServerContext *context, const runtime::UpdateContainerResourcesRequest *request, - runtime::UpdateContainerResourcesResponse *reply) + grpc::ServerContext *context, const runtime::v1alpha2::UpdateContainerResourcesRequest *request, + runtime::v1alpha2::UpdateContainerResourcesResponse *reply) { Errors error; rService.UpdateContainerResources(request->container_id(), request->linux(), error); @@ -275,8 +278,9 @@ grpc::Status RuntimeRuntimeServiceImpl::UpdateContainerResources( } -grpc::Status RuntimeRuntimeServiceImpl::Exec(grpc::ServerContext *context, const runtime::ExecRequest *request, - runtime::ExecResponse *response) +grpc::Status RuntimeRuntimeServiceImpl::Exec(grpc::ServerContext *context, + const runtime::v1alpha2::ExecRequest *request, + runtime::v1alpha2::ExecResponse *response) { Errors error; rService.Exec(*request, response, error); @@ -287,8 +291,9 @@ grpc::Status RuntimeRuntimeServiceImpl::Exec(grpc::ServerContext *context, const return grpc::Status::OK; } -grpc::Status RuntimeRuntimeServiceImpl::Attach(grpc::ServerContext *context, const runtime::AttachRequest *request, - runtime::AttachResponse *response) +grpc::Status RuntimeRuntimeServiceImpl::Attach(grpc::ServerContext *context, + const runtime::v1alpha2::AttachRequest *request, + runtime::v1alpha2::AttachResponse *response) { Errors error; rService.Attach(*request, response, error); @@ -299,9 +304,10 @@ grpc::Status RuntimeRuntimeServiceImpl::Attach(grpc::ServerContext *context, con return grpc::Status::OK; } -grpc::Status RuntimeRuntimeServiceImpl::UpdateRuntimeConfig(grpc::ServerContext *context, - const runtime::UpdateRuntimeConfigRequest *request, - runtime::UpdateRuntimeConfigResponse *reply) +grpc::Status RuntimeRuntimeServiceImpl::UpdateRuntimeConfig( + grpc::ServerContext *context, + const runtime::v1alpha2::UpdateRuntimeConfigRequest *request, + runtime::v1alpha2::UpdateRuntimeConfigResponse *reply) { Errors error; rService.UpdateRuntimeConfig(request->runtime_config(), error); @@ -312,11 +318,12 @@ grpc::Status RuntimeRuntimeServiceImpl::UpdateRuntimeConfig(grpc::ServerContext return grpc::Status::OK; } -grpc::Status RuntimeRuntimeServiceImpl::Status(grpc::ServerContext *context, const runtime::StatusRequest *request, - runtime::StatusResponse *reply) +grpc::Status RuntimeRuntimeServiceImpl::Status(grpc::ServerContext *context, + const runtime::v1alpha2::StatusRequest *request, + runtime::v1alpha2::StatusResponse *reply) { Errors error; - std::unique_ptr status = rService.Status(error); + std::unique_ptr status = rService.Status(error); if (status == nullptr || error.NotEmpty()) { return grpc::Status(grpc::StatusCode::UNKNOWN, error.GetMessage()); } @@ -325,3 +332,4 @@ grpc::Status RuntimeRuntimeServiceImpl::Status(grpc::ServerContext *context, con return grpc::Status::OK; } + diff --git a/src/connect/service/grpc/runtime_runtime_service.h b/src/connect/service/grpc/runtime_runtime_service.h index cd8815a..1b5f983 100644 --- a/src/connect/service/grpc/runtime_runtime_service.h +++ b/src/connect/service/grpc/runtime_runtime_service.h @@ -24,71 +24,87 @@ #include "errors.h" // Implement of runtime RuntimeService -class RuntimeRuntimeServiceImpl : public runtime::RuntimeService::Service { +class RuntimeRuntimeServiceImpl : public runtime::v1alpha2::RuntimeService::Service { public: void Init(Network::NetworkPluginConf mConf, isulad_daemon_configs *config, Errors &err); void Wait(); void Shutdown(); - grpc::Status Version(grpc::ServerContext *context, const runtime::VersionRequest *request, - runtime::VersionResponse *reply) override; + grpc::Status Version(grpc::ServerContext *context, + const runtime::v1alpha2::VersionRequest *request, + runtime::v1alpha2::VersionResponse *reply) override; - grpc::Status CreateContainer(grpc::ServerContext *context, const runtime::CreateContainerRequest *request, - runtime::CreateContainerResponse *reply) override; + grpc::Status CreateContainer(grpc::ServerContext *context, + const runtime::v1alpha2::CreateContainerRequest *request, + runtime::v1alpha2::CreateContainerResponse *reply) override; - grpc::Status StartContainer(grpc::ServerContext *context, const runtime::StartContainerRequest *request, - runtime::StartContainerResponse *reply) override; + grpc::Status StartContainer(grpc::ServerContext *context, + const runtime::v1alpha2::StartContainerRequest *request, + runtime::v1alpha2::StartContainerResponse *reply) override; - grpc::Status StopContainer(grpc::ServerContext *context, const runtime::StopContainerRequest *request, - runtime::StopContainerResponse *reply) override; + grpc::Status StopContainer(grpc::ServerContext *context, + const runtime::v1alpha2::StopContainerRequest *request, + runtime::v1alpha2::StopContainerResponse *reply) override; - grpc::Status RemoveContainer(grpc::ServerContext *context, const runtime::RemoveContainerRequest *request, - runtime::RemoveContainerResponse *reply) override; + grpc::Status RemoveContainer(grpc::ServerContext *context, + const runtime::v1alpha2::RemoveContainerRequest *request, + runtime::v1alpha2::RemoveContainerResponse *reply) override; - grpc::Status ListContainers(grpc::ServerContext *context, const runtime::ListContainersRequest *request, - runtime::ListContainersResponse *reply) override; + grpc::Status ListContainers(grpc::ServerContext *context, + const runtime::v1alpha2::ListContainersRequest *request, + runtime::v1alpha2::ListContainersResponse *reply) override; - grpc::Status ListContainerStats(grpc::ServerContext *context, const runtime::ListContainerStatsRequest *request, - runtime::ListContainerStatsResponse *reply) override; + grpc::Status ListContainerStats(grpc::ServerContext *context, + const runtime::v1alpha2::ListContainerStatsRequest *request, + runtime::v1alpha2::ListContainerStatsResponse *reply) override; - grpc::Status ContainerStatus(grpc::ServerContext *context, const runtime::ContainerStatusRequest *request, - runtime::ContainerStatusResponse *reply) override; + grpc::Status ContainerStatus(grpc::ServerContext *context, + const runtime::v1alpha2::ContainerStatusRequest *request, + runtime::v1alpha2::ContainerStatusResponse *reply) override; - grpc::Status ExecSync(grpc::ServerContext *context, const runtime::ExecSyncRequest *request, - runtime::ExecSyncResponse *reply) override; + grpc::Status ExecSync(grpc::ServerContext *context, + const runtime::v1alpha2::ExecSyncRequest *request, + runtime::v1alpha2::ExecSyncResponse *reply) override; - grpc::Status RunPodSandbox(grpc::ServerContext *context, const runtime::RunPodSandboxRequest *request, - runtime::RunPodSandboxResponse *reply) override; + grpc::Status RunPodSandbox(grpc::ServerContext *context, + const runtime::v1alpha2::RunPodSandboxRequest *request, + runtime::v1alpha2::RunPodSandboxResponse *reply) override; - grpc::Status StopPodSandbox(grpc::ServerContext *context, const runtime::StopPodSandboxRequest *request, - runtime::StopPodSandboxResponse *reply) override; + grpc::Status StopPodSandbox(grpc::ServerContext *context, + const runtime::v1alpha2::StopPodSandboxRequest *request, + runtime::v1alpha2::StopPodSandboxResponse *reply) override; - grpc::Status RemovePodSandbox(grpc::ServerContext *context, const runtime::RemovePodSandboxRequest *request, - runtime::RemovePodSandboxResponse *reply) override; + grpc::Status RemovePodSandbox(grpc::ServerContext *context, + const runtime::v1alpha2::RemovePodSandboxRequest *request, + runtime::v1alpha2::RemovePodSandboxResponse *reply) override; - grpc::Status PodSandboxStatus(grpc::ServerContext *context, const runtime::PodSandboxStatusRequest *request, - runtime::PodSandboxStatusResponse *reply) override; + grpc::Status PodSandboxStatus(grpc::ServerContext *context, + const runtime::v1alpha2::PodSandboxStatusRequest *request, + runtime::v1alpha2::PodSandboxStatusResponse *reply) override; - grpc::Status ListPodSandbox(grpc::ServerContext *context, const runtime::ListPodSandboxRequest *request, - runtime::ListPodSandboxResponse *reply) override; + grpc::Status ListPodSandbox(grpc::ServerContext *context, + const runtime::v1alpha2::ListPodSandboxRequest *request, + runtime::v1alpha2::ListPodSandboxResponse *reply) override; grpc::Status UpdateContainerResources(grpc::ServerContext *context, - const runtime::UpdateContainerResourcesRequest *request, - runtime::UpdateContainerResourcesResponse *reply) override; + const runtime::v1alpha2::UpdateContainerResourcesRequest *request, + runtime::v1alpha2::UpdateContainerResourcesResponse *reply) override; - grpc::Status Exec(grpc::ServerContext *context, const runtime::ExecRequest *request, - runtime::ExecResponse *response) override; + grpc::Status Exec(grpc::ServerContext *context, const runtime::v1alpha2::ExecRequest *request, + runtime::v1alpha2::ExecResponse *response) override; - grpc::Status Attach(grpc::ServerContext *context, const runtime::AttachRequest *request, - runtime::AttachResponse *response) override; + grpc::Status Attach(grpc::ServerContext *context, const runtime::v1alpha2::AttachRequest *request, + runtime::v1alpha2::AttachResponse *response) override; - grpc::Status UpdateRuntimeConfig(grpc::ServerContext *context, const runtime::UpdateRuntimeConfigRequest *request, - runtime::UpdateRuntimeConfigResponse *reply) override; + grpc::Status UpdateRuntimeConfig(grpc::ServerContext *context, + const runtime::v1alpha2::UpdateRuntimeConfigRequest *request, + runtime::v1alpha2::UpdateRuntimeConfigResponse *reply) override; - grpc::Status Status(grpc::ServerContext *context, const runtime::StatusRequest *request, - runtime::StatusResponse *reply) override; + grpc::Status Status(grpc::ServerContext *context, const runtime::v1alpha2::StatusRequest *request, + runtime::v1alpha2::StatusResponse *reply) override; private: CRIRuntimeServiceImpl rService; }; #endif /* _RUNTIME_RUNTIME_SERVICES_IMPL_H_ */ + diff --git a/src/connect/service/rest/rest_containers_service.h b/src/connect/service/rest/rest_containers_service.h index 21eb434..1547b38 100644 --- a/src/connect/service/rest/rest_containers_service.h +++ b/src/connect/service/rest/rest_containers_service.h @@ -28,3 +28,4 @@ int rest_register_containers_handler(evhtp_t *htp); #endif #endif + diff --git a/src/connect/service/rest/rest_images_service.h b/src/connect/service/rest/rest_images_service.h index 95a4f7d..c9b2163 100644 --- a/src/connect/service/rest/rest_images_service.h +++ b/src/connect/service/rest/rest_images_service.h @@ -28,3 +28,4 @@ int rest_register_images_handler(evhtp_t *htp); #endif #endif + diff --git a/src/connect/service/rest/rest_service.c b/src/connect/service/rest/rest_service.c index 286ac7a..3bc8ba6 100644 --- a/src/connect/service/rest/rest_service.c +++ b/src/connect/service/rest/rest_service.c @@ -135,3 +135,4 @@ void rest_server_shutdown(void) } } } + diff --git a/src/connect/service/rest/rest_service.h b/src/connect/service/rest/rest_service.h index 3a995cb..700ccc4 100644 --- a/src/connect/service/rest/rest_service.h +++ b/src/connect/service/rest/rest_service.h @@ -30,3 +30,4 @@ void rest_server_shutdown(void); #endif #endif + diff --git a/src/connect/service/rest/rest_service_common.c b/src/connect/service/rest/rest_service_common.c index 63ff9d7..f8168b2 100644 --- a/src/connect/service/rest/rest_service_common.c +++ b/src/connect/service/rest/rest_service_common.c @@ -84,3 +84,4 @@ void evhtp_send_response(evhtp_request_t *req, const char *responsedata, int res evbuffer_add(req->buffer_out, responsedata, strlen(responsedata)); evhtp_send_reply(req, rescode); } + diff --git a/src/connect/service/rest/rest_service_common.h b/src/connect/service/rest/rest_service_common.h index 36e9e61..2192c3a 100644 --- a/src/connect/service/rest/rest_service_common.h +++ b/src/connect/service/rest/rest_service_common.h @@ -32,3 +32,4 @@ void evhtp_send_response(evhtp_request_t *req, const char *responsedata, int res #endif #endif + diff --git a/src/connect/service/service_common.c b/src/connect/service/service_common.c index 9374486..405e6a7 100644 --- a/src/connect/service/service_common.c +++ b/src/connect/service/service_common.c @@ -58,3 +58,4 @@ void server_common_shutdown(void) rest_server_shutdown(); #endif } + diff --git a/src/connect/service/service_common.h b/src/connect/service/service_common.h index 5a5e51d..ee472ed 100644 --- a/src/connect/service/service_common.h +++ b/src/connect/service/service_common.h @@ -35,3 +35,4 @@ void event_monitor_exit_callback(void *arg); #endif #endif + diff --git a/src/console/console.c b/src/console/console.c index f443f60..12c1f6b 100644 --- a/src/console/console.c +++ b/src/console/console.c @@ -683,3 +683,4 @@ int start_io_copy_thread(int sync_fd, bool detach, struct io_copy_arg *copy_arg, sem_destroy(&thread_arg.wait_sem); return 0; } + diff --git a/src/console/console.h b/src/console/console.h index a7b2801..870bc53 100644 --- a/src/console/console.h +++ b/src/console/console.h @@ -96,3 +96,4 @@ int setup_tios(int fd, struct termios *curr_tios); #endif #endif + diff --git a/src/constants.h b/src/constants.h index 588e292..243abdf 100644 --- a/src/constants.h +++ b/src/constants.h @@ -60,3 +60,4 @@ #define MAX_MSG_BUFFER_SIZE (32 * 1024) #endif + diff --git a/src/contrib/config/config.json b/src/contrib/config/config.json index 351d082..9a9ec87 100644 --- a/src/contrib/config/config.json +++ b/src/contrib/config/config.json @@ -273,6 +273,7 @@ "/proc/signo", "/proc/timer_list", "/proc/timer_stats", + "/proc/sysmonitor", "/sys/firmware" ], "readonlyPaths": [ diff --git a/src/contrib/config/daemon.json b/src/contrib/config/daemon.json index 0be3db6..44a416c 100644 --- a/src/contrib/config/daemon.json +++ b/src/contrib/config/daemon.json @@ -19,12 +19,12 @@ "overlay2.override_kernel_check=true" ], "registry-mirrors": [ - "docker.io" ], "insecure-registries": [ ], "pod-sandbox-image": "", "image-opt-timeout": "5m", + "image-server-sock-addr": "unix:///var/run/lcrd/isula_image.sock", "native.umask": "secure", "network-plugin": "", "cni-bin-dir": "", diff --git a/src/contrib/config/systemcontainer_config.json b/src/contrib/config/systemcontainer_config.json index 229929b..3d2bd89 100644 --- a/src/contrib/config/systemcontainer_config.json +++ b/src/contrib/config/systemcontainer_config.json @@ -306,6 +306,7 @@ "/proc/signo", "/proc/timer_list", "/proc/timer_stats", + "/proc/sysmonitor", "/sys/firmware" ], "readonlyPaths": [ diff --git a/src/contrib/docker b/src/contrib/docker index ab3b606..f759eff 100644 --- a/src/contrib/docker +++ b/src/contrib/docker @@ -1,5 +1,5 @@ ####################################################################### -##- @Copyright (C) Huawei Technologies., Ltd. 2017-2019. All rights reserved. +##- @Copyright (C) Huawei Technologies., Ltd. 2019. All rights reserved. # - iSulad licensed under the Mulan PSL v1. # - You can use this software according to the terms and conditions of the Mulan PSL v1. # - You may obtain a copy of Mulan PSL v1 at: diff --git a/src/contrib/env_checkconfig b/src/contrib/env_checkconfig index a89cfb9..2528995 100644 --- a/src/contrib/env_checkconfig +++ b/src/contrib/env_checkconfig @@ -1,3 +1,17 @@ +####################################################################### +##- @Copyright (C) Huawei Technologies., Ltd. 2019. All rights reserved. +# - iSulad licensed under the Mulan PSL v1. +# - You can use this software according to the terms and conditions of the Mulan PSL v1. +# - You may obtain a copy of Mulan PSL v1 at: +# - http://license.coscl.org.cn/MulanPSL +# - 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 v1 for more details. +##- @Description: generate cetification +##- @Author: wujing +##- @Create: 2019-04-25 +####################################################################### #!/bin/sh @@ -18,11 +32,6 @@ $SETCOLOR_SUCCESS echo "" echo "---This is iSula environment check program---" echo "" -if [ ! -f /etc/euleros-release ]; then - $SETCOLOR_FAILURE - echo "Make sure you are running this program on EulerOS System" - exit 1 -fi config_set() { diff --git a/src/contrib/generate_certificate.bash b/src/contrib/generate_certificate.bash deleted file mode 100644 index 831ade2..0000000 --- a/src/contrib/generate_certificate.bash +++ /dev/null @@ -1,88 +0,0 @@ -####################################################################### -##- @Copyright (C) Huawei Technologies., Ltd. 2017-2019. All rights reserved. -# - iSulad licensed under the Mulan PSL v1. -# - You can use this software according to the terms and conditions of the Mulan PSL v1. -# - You may obtain a copy of Mulan PSL v1 at: -# - http://license.coscl.org.cn/MulanPSL -# - 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 v1 for more details. -##- @Description: generate cetification -##- @Author: wujing -##- @Create: 2019-04-25 -####################################################################### -#!/bin/bash -set -e -echo -n "Enter pass phrase:" -read password -echo -n "Enter public network ip:" -read publicip -echo -n "Enter host:" -read HOST - -echo " => Using hostname: tcp://$publicip:2375, You MUST connect to iSulad using this host!" - -mkdir -p $HOME/.iSulad -cd $HOME/.iSulad -rm -rf $HOME/.iSulad/* - -echo " => Generating CA key" -openssl genrsa -passout pass:$password -aes256 -out ca-key.pem 4096 -echo " => Generating CA certificate" -openssl req -passin pass:$password -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem -subj "/C=CN/ST=zhejiang/L=hangzhou/O=Huawei/OU=iSulad/CN=iSulad@huawei.com" -echo " => Generating server key" -openssl genrsa -passout pass:$password -out server-key.pem 4096 -echo " => Generating server CSR" -openssl req -passin pass:$password -subj /CN=$HOST -sha256 -new -key server-key.pem -out server.csr -echo subjectAltName = DNS:$HOST,IP:$publicip,IP:127.0.0.1 >> extfile.cnf -echo extendedKeyUsage = serverAuth >> extfile.cnf -echo " => Signing server CSR with CA" -openssl x509 -req -passin pass:$password -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf -echo " => Generating client key" -openssl genrsa -passout pass:$password -out key.pem 4096 -echo " => Generating client CSR" -openssl req -passin pass:$password -subj '/CN=client' -new -key key.pem -out client.csr -echo " => Creating extended key usage" -echo extendedKeyUsage = clientAuth > extfile-client.cnf -echo " => Signing client CSR with CA" -openssl x509 -req -passin pass:$password -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile-client.cnf -rm -v client.csr server.csr extfile.cnf extfile-client.cnf -chmod -v 0400 ca-key.pem key.pem server-key.pem -chmod -v 0444 ca.pem server-cert.pem cert.pem -if [ -d "/etc/profile.d" ]; then - echo " => Creating profile.d/iSulad" - sudo bash -c "echo '#!/bin/bash - export ISULAD_HOST=tcp://$publicip:2375 - export ISULAD_CERT_PATH=$HOME/.iSulad - export ISULAD_TLS_VERIFY=1' > /etc/profile.d/iSulad.sh" - sudo chmod +x /etc/profile.d/iSulad.sh - source /etc/profile.d/iSulad.sh -else - echo " => WARNING: No /etc/profile.d directoy on your system." - echo " => You will need to set the following environment variables before running the iSulad client(lcrc):" - echo " => ISULAD_HOST=tcp://$publicip:2375" - echo " => ISULAD_CERT_PATH=$HOME/.iSulad" - echo " => ISULAD_TLS_VERIFY=1" -fi - -OPTIONS="--tlsverify --tlscacert=$HOME/.iSulad/ca.pem --tlscert=$HOME/.iSulad/server-cert.pem --tlskey=$HOME/.iSulad/server-key.pem -H=0.0.0.0:2375" -if [ -f "/lib/systemd/system/lcrd.service" ]; then - echo " => Configuring /lib/systemd/system/lcrd.service" - SERVICE_BACKUP="/lib/systemd/system/lcrd.service.$(date +"%s")" - mv /lib/systemd/system/lcrd.service $SERVICE_BACKUP - sudo sh -c "echo '# The following line was added by iSulad TLS configuration script - OPTIONS=\"$OPTIONS\" - # A backup of the old file is at $SERVICE_BACKUP.' >> /etc/sysconfig/iSulad" - echo " => Backup file location: $SERVICE_BACKUP" -else - echo " => WARNING: No /etc/sysconfig/iSulad file found on your system." - echo " => You will need to configure your iSulad daemon with the following options:" - echo " => $OPTIONS" -fi - -export ISUALD_HOST=tcp://$publicip:2375 -export ISULAD_CERT_PATH=$HOME/.iSulad -export ISULAD_TLS_VERIFY=1 -echo " => Done! You just need to restart iSulad for the changes to take effect" - diff --git a/src/contrib/init/lcrd.init b/src/contrib/init/lcrd.init index 42b4dcc..9daa028 100644 --- a/src/contrib/init/lcrd.init +++ b/src/contrib/init/lcrd.init @@ -1,17 +1,3 @@ -####################################################################### -##- @Copyright (C) Huawei Technologies., Ltd. 2017-2019. All rights reserved. -# - iSulad licensed under the Mulan PSL v1. -# - You can use this software according to the terms and conditions of the Mulan PSL v1. -# - You may obtain a copy of Mulan PSL v1 at: -# - http://license.coscl.org.cn/MulanPSL -# - 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 v1 for more details. -##- @Description: generate cetification -##- @Author: wujing -##- @Create: 2019-04-25 -#######################################################################*/ #! /bin/sh # Provides: lcrd diff --git a/src/contrib/init/lcrd.service b/src/contrib/init/lcrd.service index a0b3bf5..051c965 100644 --- a/src/contrib/init/lcrd.service +++ b/src/contrib/init/lcrd.service @@ -1,6 +1,5 @@ [Unit] Description=iSulad Application Container Engine -Documentation=http://code.huawei.com/containers/iSulad/tree/cri/documentation After=network.target [Service] diff --git a/src/contrib/sysmonitor/isulad-check.sh b/src/contrib/sysmonitor/isulad-check.sh index 2bad76b..d980fdd 100644 --- a/src/contrib/sysmonitor/isulad-check.sh +++ b/src/contrib/sysmonitor/isulad-check.sh @@ -1,5 +1,5 @@ ####################################################################### -##- @Copyright (C) Huawei Technologies., Ltd. 2017-2019. All rights reserved. +##- @Copyright (C) Huawei Technologies., Ltd. 2019. All rights reserved. # - iSulad licensed under the Mulan PSL v1. # - You can use this software according to the terms and conditions of the Mulan PSL v1. # - You may obtain a copy of Mulan PSL v1 at: @@ -14,12 +14,7 @@ #######################################################################*/ #!/bin/sh source /etc/sysconfig/iSulad -#backtrace定位日志存放目录 -log_dir="/var/lib/lcrd/isulad-monitor" -#backtrace定位日志占用总大小,单位为KB -default_size="10240" -#backtrace定位日志总个数 -default_num="4" + #健康检查文件 healthcheck_file="/var/run/lcrd/isulad_healcheck_status" createfile_time="/var/run/lcrd/isulad_healcheck_ctime" @@ -31,188 +26,117 @@ declare -i status_change_time=930 #status_check #只进行基本的daemon状态检测,包括pid是否存在,进程状态是否异常,不进行其他的检查 #正常返回0,异常返回1 -status_check(){ - pid=$1 - if [ $? -ne 0 ];then - echo "cat /var/run/lcrd.pid failed!" - return 1 - fi +function status_check() { + pid=$1 + if [ $? -ne 0 ];then + echo "cat /var/run/lcrd.pid failed!" + return 1 + fi - cat /proc/${pid}/status >> /dev/null 2>&1 - if [ $? -ne 0 ];then - echo "/var/run/lcrd.pid exitst while process not exists!" - return 1 - fi - - dstate=`cat /proc/${pid}/status | grep State | awk '{print $2}'` - if [[ ("${dstate}x" == "Zx") || ("${dstate}x" == "Tx") ]]; then - # Z状态、T状态 - echo " dstate="${dstate}", should restart!" - return 1 - fi - return 0 + cat /proc/${pid}/status >> /dev/null 2>&1 + if [ $? -ne 0 ];then + echo "/var/run/lcrd.pid exitst while process not exists!" + return 1 + fi + + dstate=`cat /proc/${pid}/status | grep State | awk '{print $2}'` + if [[ ("${dstate}x" == "Zx") || ("${dstate}x" == "Tx") ]]; then + # Z状态、T状态 + echo " dstate="${dstate}", should restart!" + return 1 + fi + return 0 } #轮询三次进行status_check #如果三次都失败,则失败,如果有一次超时6s,也失败 #如果三次有一次成功,则成功 -basic_check() +function basic_check() { - for((i=1;i<=5;i++)); - do - sleep 2 - date_start=$(date +%s) + for((i=1;i<=5;i++)); + do + sleep 2 + date_start=$(date +%s) - tmp_id=`cat /var/run/lcrd.pid` - status_check $tmp_id - check_daemon=$? + tmp_id=`cat /var/run/lcrd.pid` + status_check $tmp_id + check_daemon=$? - date_end=$(date +%s) - if [ ${check_daemon} -eq 0 ];then - return 0 - elif [ $((date_end-date_start)) -gt 6 ];then - echo "check date is more than 6s!" - return 1 - fi - done - return 1 -} - -#检查backtrace日志文件个数是否大于5个 -checkFileNum(){ - num=`ls $log_dir | wc -l` - rm_num=$(($num-$default_num)) - k=2 - - if [ $rm_num -gt 0 ]; then - for ((i=1;i<=$rm_num;i++)) - do - rm -f $log_dir/$(ls -rt -l $log_dir | head -$k | tail -1 | awk '{print $9}') - if [ $? -ne 0 ];then - k=$((k+1)) - fi - done + date_end=$(date +%s) + if [ ${check_daemon} -eq 0 ];then + return 0 + elif [ $((date_end-date_start)) -gt 6 ];then + echo "check date is more than 6s!" + return 1 fi - - return 0 -} - -#检查backtrace日志文件总大小是否大于10M -checkFileSize(){ - num=`ls $log_dir | wc -l` - k=2 - - #文件夹本身占用4KB - size=$((`du -sk $log_dir| awk '{print $1}'`-4)) - while [ $size -ge $default_size ] - do - if [ $num -eq 0 ];then - break; - fi - rm -f $log_dir/$(ls -rt -l $log_dir | head -$k | tail -1 | awk '{print $9}') - if [ $? -ne 0 ];then - k=$((k+1)) - num=$((num-1)) - fi - size=$((`du -sk $log_dir | awk '{print $1}'`-4)) - done - - return 0 -} - -#维护/var/lib/lcrd/isulad-monitor目录下的log文件 -#限制stack log的存储空间占用 -manage_monitor_log(){ - checkFileNum - if [ $? -ne 0 ];then - echo "Failed to checkfilenum" - return 1; - fi - - checkFileSize - if [ $? -ne 0 ];then - echo "Failed to checkfilesize" - return 1; - fi + done + return 1 } #获取健康检查状态文件的创建时间 #如果文件running超过status_change_time,则代表健康检查进程故障,或者检查本身故障,或者状态文件被人恶意损坏或者更改 #此时需要重新进行健康检查并删除原文件 -createtime_check(){ - if [ ! -f "${createfile_time}" ];then - return 1 - fi - date_create=$(cat ${createfile_time}) - date_now=$(date +%s) - if [ $((date_now-date_create)) -gt ${status_change_time} ]; then - return 1 - fi - return 0 +function createtime_check() { + if [ ! -f "${createfile_time}" ];then + return 1 + fi + date_create=$(cat ${createfile_time}) + date_now=$(date +%s) + if [ $((date_now-date_create)) -gt ${status_change_time} ]; then + return 1 + fi + return 0 } -clean_healthcheck(){ - rm -rf ${healthcheck_file} - rm -rf ${createfile_time} -} -#生成堆栈日志文件 -gen_stack_log(){ - pid=$(cat /var/run/lcrd.pid) - if [ $? -ne 0 ];then - echo "cat /var/run/lcrd.pid failed!" - return 1 - fi - kill -34 ${pid} +function clean_healthcheck() { + rm -rf ${healthcheck_file} + rm -rf ${createfile_time} } #执行健康检查的后台线程,需要维护健康检查运行时 -health_check(){ - create_time=$(date +%s) +function health_check() { + create_time=$(date +%s) - touch ${createfile_time} - chmod 0640 ${createfile_time} - touch ${healthcheck_file} - chmod 0640 ${healthcheck_file} + touch ${createfile_time} + chmod 0640 ${createfile_time} + touch ${healthcheck_file} + chmod 0640 ${healthcheck_file} - echo ${create_time} > ${createfile_time} - echo "running" > ${healthcheck_file} + echo ${create_time} > ${createfile_time} + echo "running" > ${healthcheck_file} - i=0 - ret=0 + i=0 + ret=0 - while [ $i -lt ${timeout_time} ] - do - timeout -s 9 1 lcrc version $SYSMONITOR_OPTIONS - ret=$? - if [ $ret -eq 0 ];then - echo "success">${healthcheck_file} - return - else - if [ $ret -ne 137];then - sleep 1 - fi - i=$(($i+1)) - fi - done - echo "failed">${healthcheck_file} - return + while [ $i -lt ${timeout_time} ] + do + timeout -s 9 1 lcrc version $SYSMONITOR_OPTIONS + ret=$? + if [ $ret -eq 0 ];then + echo "success">${healthcheck_file} + return + else + if [ $ret -ne 137];then + sleep 1 + fi + i=$(($i+1)) + fi + done + echo "failed">${healthcheck_file} + return } -if [ ! -d ${log_dir} ]; then - mkdir -m 600 ${log_dir} -fi - #1、首先进行基本检查,最多耗时6s,如果错误,则直接返回错误;如果成功,则返回成功 basic_check if [ $? -ne 0 ];then - echo "basic check failed!" - exit 1 + echo "basic check failed!" + exit 1 fi #2、基本检查通过后,才需要进行健康检查状态的判断 #如果健康状态文件不存在,则进行健康检查,直接返回 if [ ! -f ${healthcheck_file} ];then - health_check & - exit 0 + health_check & + exit 0 fi #3、如果文件存在,则代表进行过检查,根据检查结果,做相应处理 @@ -220,39 +144,26 @@ file_status=$(cat ${healthcheck_file} 2>/dev/null) createtime_check file_change_time=$? case "$file_status" in - #上次的检查还在运行且没有超时 - running) - #或者超过规定时间还是running,代表进程可能异常或者状态位被恶意篡改,都需要重新拉起进程检查脚本 - #但是此时不代表服务已经异常,所以不重启服务 - if [ ${file_change_time} -ne 0 ];then - clean_healthcheck - health_check & - fi - exit 0 - ;; - #如果上次检查已经成功了,则直接重新拉新的进程并返回成功 - success) - clean_healthcheck - health_check & - exit 0 - ;; - ##上次的检查已经超时,代表失败,返回1,需要重新由sysmonitor restart服务 - failed) - clean_healthcheck - manage_monitor_log - sleep 5 - gen_stack_log - sleep 2 - exit 1 - ;; - #其他情况,可能是失败了,需要重新由sysmonitor restart服务 - *) - clean_healthcheck - manage_monitor_log - sleep 5 - gen_stack_log - sleep 2 - exit 1 - ;; + #上次的检查还在运行且没有超时 + running) + #或者超过规定时间还是running,代表进程可能异常或者状态位被恶意篡改,都需要重新拉起进程检查脚本 + #但是此时不代表服务已经异常,所以不重启服务 + if [ ${file_change_time} -ne 0 ];then + clean_healthcheck + health_check & + fi + exit 0 + ;; + #如果上次检查已经成功了,则直接重新拉新的进程并返回成功 + success) + clean_healthcheck + health_check & + exit 0 + ;; + #其他情况,可能是失败了,需要重新由sysmonitor restart服务 + *) + clean_healthcheck + exit 1 + ;; esac exit 0 diff --git a/src/cpputils/cxxutils.cc b/src/cpputils/cxxutils.cc index d018097..f0d1267 100644 --- a/src/cpputils/cxxutils.cc +++ b/src/cpputils/cxxutils.cc @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -39,3 +39,4 @@ std::string StringsJoin(const std::vector &vec, const std::string & } } // namespace CXXUtils + diff --git a/src/cpputils/cxxutils.h b/src/cpputils/cxxutils.h index 514615a..b8ff515 100644 --- a/src/cpputils/cxxutils.h +++ b/src/cpputils/cxxutils.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -25,3 +25,4 @@ std::vector Split(const std::string &str, char delimiter); std::string StringsJoin(const std::vector &vec, const std::string &sep); }; #endif /* __CXXUTILS_H_ */ + diff --git a/src/cpputils/stoppable_thread.cc b/src/cpputils/stoppable_thread.cc index d1df6b2..3916a1d 100644 --- a/src/cpputils/stoppable_thread.cc +++ b/src/cpputils/stoppable_thread.cc @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -37,3 +37,4 @@ void StoppableThread::stop() } + diff --git a/src/cpputils/stoppable_thread.h b/src/cpputils/stoppable_thread.h index aff403c..0482763 100644 --- a/src/cpputils/stoppable_thread.h +++ b/src/cpputils/stoppable_thread.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: diff --git a/src/cpputils/url.cc b/src/cpputils/url.cc index 5e755ed..2e66592 100644 --- a/src/cpputils/url.cc +++ b/src/cpputils/url.cc @@ -863,7 +863,10 @@ std::unique_ptr URLDatum::UrlParse(const std::string &ref) std::unique_ptr URLDatum::ResolveReference(URLDatum *ref) { - std::unique_ptr url(new URLDatum(*ref)); + std::unique_ptr url(new (std::nothrow) URLDatum(*ref)); + if (url == nullptr) { + return nullptr; + } if (url->m_scheme.empty()) { url->m_scheme = m_scheme; diff --git a/src/cpputils/url.h b/src/cpputils/url.h index 75068c5..119b460 100644 --- a/src/cpputils/url.h +++ b/src/cpputils/url.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -184,3 +184,4 @@ bool ValidUserinfo(const std::string &s); #endif + diff --git a/src/cutils/util_atomic.c b/src/cutils/util_atomic.c index 4bdf763..0c2966c 100644 --- a/src/cutils/util_atomic.c +++ b/src/cutils/util_atomic.c @@ -16,3 +16,4 @@ pthread_mutex_t g_atomic_lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t g_atomic_image_lock = PTHREAD_MUTEX_INITIALIZER; + diff --git a/src/cutils/util_atomic.h b/src/cutils/util_atomic.h index 19b5565..c595ed9 100644 --- a/src/cutils/util_atomic.h +++ b/src/cutils/util_atomic.h @@ -64,7 +64,7 @@ static inline void atomic_int_set(volatile uint64_t *atomic, uint64_t value) atomic_mutex_unlock(&g_atomic_lock); } -/* atomic int set for image*/ +/* atomic int set for image */ static inline void atomic_int_set_image(volatile uint64_t *atomic, uint64_t value) { atomic_mutex_lock(&g_atomic_image_lock); @@ -109,7 +109,7 @@ static inline bool atomic_int_dec_test(volatile uint64_t *atomic) return is_zero; } -/* atomic int dec test for image*/ +/* atomic int dec test for image */ static inline bool atomic_int_dec_test_image(volatile uint64_t *atomic) { bool is_zero = false; @@ -195,3 +195,4 @@ static inline uint64_t atomic_int_xor(volatile uint64_t *atomic, uint64_t val) #endif #endif /* __UTILS_ATOMIC_H */ + diff --git a/src/cutils/utils.c b/src/cutils/utils.c index a7bb12a..b5bfc78 100644 --- a/src/cutils/utils.c +++ b/src/cutils/utils.c @@ -266,10 +266,22 @@ bool util_check_signal_valid(int sig) return false; } +void *util_smart_calloc_s(size_t unit_size, size_t count) +{ + if (unit_size == 0) { + return NULL; + } + + if (count > (MAX_MEMORY_SIZE / unit_size)) { + return NULL; + } + + return calloc(count, unit_size); +} void *util_common_calloc_s(size_t size) { - if (size == 0 || size > SIZE_MAX) { + if (size == 0 || size > MAX_MEMORY_SIZE) { return NULL; } diff --git a/src/cutils/utils.h b/src/cutils/utils.h index 98d6b19..66e737c 100644 --- a/src/cutils/utils.h +++ b/src/cutils/utils.h @@ -30,6 +30,7 @@ #include "utils_file.h" #include "utils_convert.h" #include "utils_verify.h" +#include "utils_regex.h" #ifdef __cplusplus extern "C" { @@ -39,6 +40,14 @@ extern "C" { #define MS_REC 16384 #endif +#if __WORDSIZE == 64 +// current max user memory for 64-machine is 2^47 B +#define MAX_MEMORY_SIZE ((size_t)1 << 47) +#else +// current max user memory for 32-machine is 2^31 B +#define MAX_MEMORY_SIZE ((size_t)1 << 31) +#endif + #define MAX_ID_OFFSET 65535 #define HOST_CHANNLE_ARGS 4 #define HOST_CHANNLE_MIN_SIZE (4 * SIZE_KB) @@ -62,6 +71,7 @@ extern "C" { #define MAX_BUFFER_SIZE 4096 #define LCRD_NUMSTRLEN64 21 +#define LCRD_NUMSTRLEN32 11 #define MAXLINE 4096 #define MAX_HOST_NAME_LEN 64 #define MAX_IMAGE_NAME_LEN 255 @@ -77,7 +87,7 @@ extern "C" { #define UINT_LEN 10 -/*container id max length*/ +/* container id max length */ #define CONTAINER_ID_MAX_LEN 64 #define LIST_SIZE_MAX 1000LL @@ -99,7 +109,7 @@ extern "C" { #define Time_Minute (60LL * Time_Second) #define Time_Hour (60LL * Time_Minute) -/*Max regular file size for LCRC\LCRD to open as same as docker*/ +/* Max regular file size for LCRC\LCRD to open as same as docker */ #define REGULAR_FILE_SIZE (10 * SIZE_MB) #define rFC339Local "2006-01-02T15:04:05" @@ -354,6 +364,8 @@ int util_check_inherited(bool closeall, int fd_to_ignore); int util_sig_parse(const char *sig_name); +void *util_smart_calloc_s(size_t unit_size, size_t count); + void *util_common_calloc_s(size_t size); char *util_strdup_s(const char *src); diff --git a/src/cutils/utils_array.c b/src/cutils/utils_array.c index 6c3096d..1c54336 100644 --- a/src/cutils/utils_array.c +++ b/src/cutils/utils_array.c @@ -21,6 +21,21 @@ #include "log.h" #include "utils.h" +void util_free_array_by_len(char **array, size_t len) +{ + size_t i = 0; + + if (array == NULL) { + return; + } + + for (; i < len; i++) { + UTIL_FREE_AND_SET_NULL(array[i]); + } + + free(array); +} + size_t util_array_len(const char **array) { const char **pos; diff --git a/src/cutils/utils_array.h b/src/cutils/utils_array.h index e534735..ea13988 100644 --- a/src/cutils/utils_array.h +++ b/src/cutils/utils_array.h @@ -26,6 +26,8 @@ extern "C" { size_t util_array_len(const char **array); +void util_free_array_by_len(char **array, size_t len); + void util_free_array(char **array); int util_grow_array(char ***orig_array, size_t *orig_capacity, size_t size, diff --git a/src/cutils/utils_convert.h b/src/cutils/utils_convert.h index 1183503..b6382a5 100644 --- a/src/cutils/utils_convert.h +++ b/src/cutils/utils_convert.h @@ -34,3 +34,4 @@ int util_str_to_bool(const char *boolstr, bool *converted); #endif #endif /* __UTILS_CONVERT_H */ + diff --git a/src/cutils/utils_file.h b/src/cutils/utils_file.h index 44b460b..7cfc251 100644 --- a/src/cutils/utils_file.h +++ b/src/cutils/utils_file.h @@ -76,3 +76,4 @@ char *verify_file_and_get_real_path(const char *file); #endif #endif /* __UTILS_H */ + diff --git a/src/cutils/utils_regex.c b/src/cutils/utils_regex.c new file mode 100644 index 0000000..68ac587 --- /dev/null +++ b/src/cutils/utils_regex.c @@ -0,0 +1,140 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. + * Author: wujing + * Create: 2019-10-25 + * Description: provide regex patten functions + ********************************************************************************/ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "utils.h" + +/* + * return value: + * -1 failed + * 0 match + * 1 no match + */ +int util_reg_match(const char *patten, const char *str) +{ + int nret = 0; + regex_t reg; + regmatch_t regmatch = { 0 }; + + if (patten == NULL || str == NULL) { + ERROR("invalid NULL param"); + return -1; + } + + nret = regcomp(®, patten, REG_EXTENDED | REG_NOSUB); + if (nret) { + return -1; + } + + nret = regexec(®, str, 1, ®match, 0); + if (nret == 0) { + nret = 0; + goto free_out; + } else if (nret == REG_NOMATCH) { + nret = 1; + goto free_out; + } else { + nret = -1; + ERROR("reg match failed"); + goto free_out; + } + +free_out: + regfree(®); + + return nret; +} + +static int get_regex_size_from_wildcard(const char *wildcard, const char *escapes, size_t escapes_size, size_t *len) +{ + size_t size = 0; + size_t i, tmp; + + for (i = 0; i < escapes_size; i++) { + tmp = strings_count(wildcard, escapes[i]); + if (tmp > SIZE_MAX - size) { + ERROR("Invalid wildcard"); + return -1; + } + size += tmp; + } + + tmp = strings_count(wildcard, '*'); + if (tmp > SIZE_MAX - size - strlen(wildcard) - 3) { + ERROR("Invalid wildcard"); + return -1; + } + // ^ + escape char size + wildcard + * size + $ + '\0' + *len = 1 + size + strlen(wildcard) + tmp + 1 + 1; + return 0; +} + +int util_wildcard_to_regex(const char *wildcard, char **regex) +{ + size_t i; + size_t index = 0; + size_t regex_size; + char escapes[] = { '$', '^', '[', ']', '(', ')', '{', '|', '+', '\\', '.', '<', '>', '}' }; + if (wildcard == NULL) { + return 0; + } + + if (get_regex_size_from_wildcard(wildcard, escapes, sizeof(escapes) / sizeof(char), ®ex_size) != 0) { + return -1; + } + + *regex = malloc(regex_size); + if (*regex == NULL) { + ERROR("Out of memory"); + return -1; + } + (*regex)[index++] = '^'; + for (i = 0; i < strlen(wildcard); i++) { + char ch = wildcard[i]; + bool escaped = false; + size_t j; + for (j = 0; j < sizeof(escapes) / sizeof(char); j++) { + if (ch == escapes[j]) { + (*regex)[index++] = '\\'; + (*regex)[index++] = ch; + escaped = true; + break; + } + } + if (!escaped) { + if (ch == '*') { + (*regex)[index++] = '.'; + (*regex)[index++] = '*'; + } else if (ch == '?') { + (*regex)[index++] = '.'; + } else { + (*regex)[index++] = ch; + } + } + } + (*regex)[index++] = '$'; + (*regex)[index] = '\0'; + + return 0; +} + diff --git a/src/image/oci/oci_image_load.h b/src/cutils/utils_regex.h similarity index 66% rename from src/image/oci/oci_image_load.h rename to src/cutils/utils_regex.h index 90bf632..826e370 100644 --- a/src/image/oci/oci_image_load.h +++ b/src/cutils/utils_regex.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -9,23 +9,24 @@ * PURPOSE. * See the Mulan PSL v1 for more details. * Author: wujing - * Create: 2019-04-26 - * Description: provide image load function definition - ******************************************************************************/ -#ifndef __OCI_IMAGE_LOAD_H -#define __OCI_IMAGE_LOAD_H + * Create: 2019-10-25 + * Description: provide regex patten functions + ********************************************************************************/ -#include -#include "image.h" +#ifndef __UTILS_REGEX_H +#define __UTILS_REGEX_H #ifdef __cplusplus extern "C" { #endif -int oci_load_image(im_load_request *request); +int util_reg_match(const char *patten, const char *str); + +int util_wildcard_to_regex(const char *wildcard, char **regex); #ifdef __cplusplus } #endif -#endif +#endif /* __UTILS_REGEX_H */ + diff --git a/src/cutils/utils_string.c b/src/cutils/utils_string.c index 1171a77..a33d4eb 100644 --- a/src/cutils/utils_string.c +++ b/src/cutils/utils_string.c @@ -683,3 +683,47 @@ int dup_array_of_strings(const char **src, size_t src_len, char ***dst, size_t * return 0; } +char *util_sub_string(const char *source, size_t offset, size_t length) +{ + size_t total_len; + size_t substr_len; + char *substring = NULL; + + if (source == NULL || length == 0) { + return NULL; + } + + total_len = strlen(source); + substr_len = ((total_len - offset) >= length ? length : (total_len - offset)) + 1; + substring = (char *)malloc(substr_len * sizeof(char)); + if (substring == NULL) { + ERROR("Out of memory\n"); + return NULL; + } + if (strncpy_s(substring, substr_len, source + offset, substr_len - 1) != EOK) { + ERROR("Out of memory\n"); + free(substring); + return NULL; + } + substring[substr_len - 1] = '\0'; + + return substring; +} + +bool util_is_space_string(const char *str) +{ + size_t i; + + if (str == NULL) { + return false; + } + + for (i = 0; i < strlen(str); i++) { + if (!isspace(str[i])) { + return false; + } + } + + return true; +} + diff --git a/src/cutils/utils_string.h b/src/cutils/utils_string.h index 03ab20d..317e988 100644 --- a/src/cutils/utils_string.h +++ b/src/cutils/utils_string.h @@ -61,8 +61,13 @@ char *util_string_append(const char *post, const char *pre); int dup_array_of_strings(const char **src, size_t src_len, char ***dst, size_t *dst_len); +char *util_sub_string(const char *source, size_t offset, size_t length); + +bool util_is_space_string(const char *str); + #ifdef __cplusplus } #endif #endif /* __UTILS_STRING_H */ + diff --git a/src/cutils/utils_verify.c b/src/cutils/utils_verify.c index 72778f5..4b9725f 100644 --- a/src/cutils/utils_verify.c +++ b/src/cutils/utils_verify.c @@ -15,9 +15,8 @@ #define _GNU_SOURCE #include "utils_verify.h" - -#include #include +#include #ifdef HAVE_LIBCAP_H #include #endif @@ -26,6 +25,7 @@ #include "log.h" #include "utils.h" +#include "utils_regex.h" const char *g_all_caps[] = { "CAP_CHOWN", @@ -80,47 +80,6 @@ const char *g_all_caps[] = { #endif }; -/* - * return value: - * -1 failed - * 0 match - * 1 no match - */ -int util_reg_match(const char *patten, const char *str) -{ - int nret = 0; - regex_t reg; - regmatch_t regmatch = { 0 }; - - if (patten == NULL || str == NULL) { - ERROR("invalid NULL param"); - return -1; - } - - nret = regcomp(®, patten, REG_EXTENDED | REG_NOSUB); - if (nret) { - return -1; - } - - nret = regexec(®, str, 1, ®match, 0); - if (nret == 0) { - nret = 0; - goto free_out; - } else if (nret == REG_NOMATCH) { - nret = 1; - goto free_out; - } else { - nret = -1; - ERROR("reg match failed"); - goto free_out; - } - -free_out: - regfree(®); - - return nret; -} - bool util_valid_cmd_arg(const char *arg) { return (arg != NULL) && (strchr(arg, '|') == NULL) && (strchr(arg, '`') == NULL) && (strchr(arg, '&')) == NULL && @@ -173,24 +132,25 @@ err_out: return nret; } -static int util_vaildate_tcp_socket(const char *socket) +static bool util_vaildate_tcp_socket(const char *socket) { if (socket == NULL) { - return -1; + return false; } return util_reg_match("^(tcp://(((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]).){3}" "(25[0-5]|2[0-5][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])|localhost):" "((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})" "|([1-5][0-9]{4})|([1-9][0-9]{0,3})|0))$", - socket); + socket) == 0; } -static int util_validate_unix_socket(const char *socket) + +bool util_validate_unix_socket(const char *socket) { int nret = 0; const char *name = NULL; if (socket == NULL) { - return -1; + return false; } if (strncmp("unix://", socket, strlen("unix://"))) { @@ -211,12 +171,12 @@ static int util_validate_unix_socket(const char *socket) goto err_out; } err_out: - return nret; + return nret == 0; } bool util_validate_socket(const char *socket) { - return util_validate_unix_socket(socket) == 0 || util_vaildate_tcp_socket(socket) == 0; + return util_validate_unix_socket(socket) || util_vaildate_tcp_socket(socket); } bool util_valid_device_mode(const char *mode) @@ -429,7 +389,7 @@ cleanup: bool util_valid_time_tz(const char *time) { - char *patten = "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{2,9}Z$"; + char *patten = "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{2,9})?Z$"; if (time == NULL) { ERROR("invalid NULL param"); diff --git a/src/cutils/utils_verify.h b/src/cutils/utils_verify.h index 26b8610..148f413 100644 --- a/src/cutils/utils_verify.h +++ b/src/cutils/utils_verify.h @@ -1,5 +1,4 @@ /****************************************************************************** -#include "buffer.h" * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -27,14 +26,14 @@ extern "C" { extern const char *g_all_caps[]; -int util_reg_match(const char *patten, const char *str); - bool util_valid_cmd_arg(const char *arg); bool util_valid_signal(int sig); int util_validate_absolute_path(const char *path); +bool util_validate_unix_socket(const char *socket); + bool util_validate_socket(const char *socket); bool util_valid_device_mode(const char *mode); @@ -102,3 +101,4 @@ bool util_valid_short_sha256_id(const char *id); #endif #endif /* __UTILS_H */ + diff --git a/src/engines/engine.c b/src/engines/engine.c index 429d502..59eb07e 100644 --- a/src/engines/engine.c +++ b/src/engines/engine.c @@ -334,3 +334,4 @@ struct engine_operation *engines_get_handler(const char *name) out: return engine_op; } + diff --git a/src/engines/engine.h b/src/engines/engine.h index 3020254..c57f05d 100644 --- a/src/engines/engine.h +++ b/src/engines/engine.h @@ -103,9 +103,7 @@ typedef struct _engine_start_request_t { bool daemonize; bool tty; bool open_stdin; - const char *pidfile; const char **console_fifos; - const char *console_logpath; uint32_t start_timeout; const char *container_pidfile; const char *exit_fifo; @@ -114,21 +112,35 @@ typedef struct _engine_start_request_t { gid_t gid; gid_t *additional_gids; size_t additional_gids_len; - - const char **share_ns; } engine_start_request_t; -typedef bool (*engine_create_t)(const char *, const char *, const char *, const char *, void *); +typedef struct _engine_exec_request_t { + const char *name; + const char *lcrpath; + + const char *logpath; + const char *loglevel; + + const char **console_fifos; + + const char *user; + + const char **env; + size_t env_len; + const char **args; + size_t args_len; + + int64_t timeout; +} engine_exec_request_t; + + +typedef bool (*engine_create_t)(const char *, const char *, const char *, void *); typedef bool (*engine_start_t)(const engine_start_request_t *request); typedef bool (*engine_clean_t)(const char *name, const char *lcrpath, const char *logpath, const char *loglevel, pid_t pid); -typedef bool (*engine_kill_t)(const char *name, const char *enginepath, uint32_t signal); - -typedef int (*engine_kill_monitor_t)(const char *name, const char *enginepath); - typedef bool (*engine_delete_t)(const char *name, const char *enginepath); typedef bool (*engine_pause_t)(const char *name, const char *enginepath); @@ -139,9 +151,7 @@ typedef bool (*engine_reset_t)(const char *name, const char *enginepath); typedef bool (*engine_update_t)(const char *name, const char *enginepath, const struct engine_cgroup_resources *cr); -typedef bool (*engine_exec_t)(const char *name, const char *enginepath, const char *logpath, const char *loglevel, - const char *console_fifos[], char * const argv[], char * const env[], int64_t timeout, - pid_t *pid, int *exit_code); +typedef bool (*engine_exec_t)(const engine_exec_request_t *request, int *exit_code); typedef int (*engine_get_all_containers_info_t)(const char *enginepath, struct engine_container_summary_info **cons); @@ -158,8 +168,6 @@ typedef void (*engine_free_container_status_t)(struct engine_container_info *con typedef bool (*engine_get_container_pids_t)(const char *name, const char *rootpath, pid_t **pids, size_t *pids_len); -typedef int (*engine_monitord_spawn_t)(const char *enginepath); - typedef bool (*engine_console_t)(const char *name, const char *enginepath, char *in_fifo, char *out_fifo, char *err_fifo); @@ -181,8 +189,6 @@ struct engine_operation { char *engine_type; engine_create_t engine_create_op; engine_start_t engine_start_op; - engine_kill_t engine_kill_op; - engine_kill_monitor_t engine_kill_monitor_op; engine_delete_t engine_delete_op; engine_pause_t engine_pause_op; engine_resume_t engine_resume_op; diff --git a/src/engines/lcr/lcr_engine.c b/src/engines/lcr/lcr_engine.c index 4da846d..6ec25a3 100644 --- a/src/engines/lcr/lcr_engine.c +++ b/src/engines/lcr/lcr_engine.c @@ -28,19 +28,15 @@ #include "log.h" #include "lcrd_config.h" -typedef int(*lcr_monitor_open_t)(const char *lcrpath); -typedef int(*lcr_monitor_read_t)(int fd, struct lcr_msg *msg); -typedef struct lcr_container_info *(*lcr_container_info_get_op_t)(const char *name, const char *lcrpath); typedef int(*lcr_list_all_containers_t)(const char *lcrpath, struct lcr_container_info **info_arr); typedef void(*lcr_containers_info_free_t)(struct lcr_container_info **info_arr, size_t size); -typedef int(*lcr_stats_all_containers_t)(const char *lcrpath, struct lcr_container_state **state_arr); typedef bool(*lcr_state_op_t)(const char *name, const char *lcrpath, struct lcr_container_state *lcs); typedef void(*lcr_container_state_free_t)(struct lcr_container_state *lcs); typedef bool(*lcr_update_op_t)(const char *name, const char *lcrpath, struct lcr_cgroup_resources *cr); typedef bool(*lcr_get_console_config_op_t)(const char *name, const char *lcrpath, struct lcr_console_config *config); typedef void(*lcr_free_console_config_op_t)(struct lcr_console_config *config); -typedef int(*lcr_monitord_spawn_t)(const char *lcrpath); typedef bool(*lcr_start_op_t)(struct lcr_start_request *request); +typedef bool(*lcr_exec_op_t)(const struct lcr_exec_request *request, int *exit_code); static lcr_list_all_containers_t g_lcr_list_all_containers_op = NULL; static lcr_containers_info_free_t g_lcr_containers_info_free_op = NULL; @@ -50,7 +46,7 @@ static lcr_update_op_t g_lcr_update_op = NULL; static lcr_get_console_config_op_t g_lcr_get_console_config_op = NULL; static lcr_free_console_config_op_t g_lcr_free_console_config_op = NULL; static lcr_start_op_t g_lcr_start_op = NULL; - +static lcr_exec_op_t g_lcr_exec_op = NULL; /* * Trans the lcr_state_t to Status */ @@ -123,6 +119,13 @@ static bool lcr_start_container(const engine_start_request_t *request) return g_lcr_start_op(lcr_request); } +static bool lcr_exec_container(const engine_exec_request_t *request, int *exit_code) +{ + struct lcr_exec_request *lcr_request = (struct lcr_exec_request *)request; + + return g_lcr_exec_op(lcr_request, exit_code); +} + /* free console config */ void free_console_config(struct engine_console_config *config) { @@ -368,10 +371,6 @@ static bool load_lcr_exec_ops(void *lcr_handler, struct engine_operation *eop) if (dlerror() != NULL) { return false; } - eop->engine_kill_op = dlsym(lcr_handler, "lcr_kill"); - if (dlerror() != NULL) { - return false; - } g_lcr_update_op = dlsym(lcr_handler, "lcr_update"); if (dlerror() != NULL) { return false; @@ -392,7 +391,7 @@ static bool load_lcr_exec_ops(void *lcr_handler, struct engine_operation *eop) if (dlerror() != NULL) { return false; } - eop->engine_exec_op = dlsym(lcr_handler, "lcr_attach"); + g_lcr_exec_op = dlsym(lcr_handler, "lcr_exec"); if (dlerror() != NULL) { return false; } @@ -485,6 +484,7 @@ struct engine_operation *lcr_engine_init() eop->engine_free_container_status_op = free_container_status; eop->engine_update_op = lcr_update_container; eop->engine_start_op = lcr_start_container; + eop->engine_exec_op = lcr_exec_container; eop->engine_get_console_config_op = get_console_config; eop->engine_free_console_config_op = free_console_config; diff --git a/src/engines/lcr/lcr_engine.h b/src/engines/lcr/lcr_engine.h index e1af9da..ba8b54c 100644 --- a/src/engines/lcr/lcr_engine.h +++ b/src/engines/lcr/lcr_engine.h @@ -28,3 +28,4 @@ struct engine_operation *lcr_engine_init(); #endif #endif + diff --git a/src/error.c b/src/error.c index 317d522..387dfc0 100644 --- a/src/error.c +++ b/src/error.c @@ -33,3 +33,4 @@ const char *errno_to_error_message(lcrd_errno_t err) } return g_lcrd_strerror_tab[err].errmsg; } + diff --git a/src/error.h b/src/error.h index ec139b2..8605d9c 100644 --- a/src/error.h +++ b/src/error.h @@ -74,3 +74,4 @@ static inline void format_errorf(char **err, const char *format, ...) } #endif #endif + diff --git a/src/filters.c b/src/filters.c index 1bd702c..1003dc0 100644 --- a/src/filters.c +++ b/src/filters.c @@ -295,10 +295,8 @@ bool filters_args_match(const struct filters_args *filters, const char *field, c } for (; map_itor_valid(itor); map_itor_next(itor)) { - int mret; const char *name2match = map_itor_key(itor); - mret = util_reg_match(name2match, source); - if (mret != 0) { + if (util_reg_match(name2match, source) != 0) { continue; } map_itor_free(itor); @@ -308,7 +306,7 @@ bool filters_args_match(const struct filters_args *filters, const char *field, c return false; } -/* check whether field is one of accepted name or not*/ +/* check whether field is one of accepted name or not */ bool filters_args_valid_key(const char **accepted, size_t len, const char *field) { size_t i; diff --git a/src/filters.h b/src/filters.h index df52317..76095c7 100644 --- a/src/filters.h +++ b/src/filters.h @@ -46,3 +46,4 @@ bool filters_args_exact_match(const struct filters_args *filters, const char *fi bool filters_args_match(const struct filters_args *filters, const char *field, const char *source); #endif + diff --git a/src/http/buffer.c b/src/http/buffer.c index f876bd5..be54053 100644 --- a/src/http/buffer.c +++ b/src/http/buffer.c @@ -173,3 +173,4 @@ int buffer_append(Buffer *buf, const char *append, size_t len) return 0; } + diff --git a/src/http/buffer.h b/src/http/buffer.h index ad36709..4bd8a92 100644 --- a/src/http/buffer.h +++ b/src/http/buffer.h @@ -33,3 +33,4 @@ void buffer_free(Buffer *buf); int buffer_append(Buffer *buf, const char *append, size_t len); void buffer_empty(Buffer *buf); #endif + diff --git a/src/http/certificate.c b/src/http/certificate.c index c756913..bb18207 100644 --- a/src/http/certificate.c +++ b/src/http/certificate.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -60,3 +60,4 @@ out: fclose(fp); return ret; } + diff --git a/src/http/certificate.h b/src/http/certificate.h index e244d2a..c854c76 100644 --- a/src/http/certificate.h +++ b/src/http/certificate.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -27,3 +27,4 @@ int get_common_name_from_tls_cert(const char *cert_path, char *value, size_t len #endif #endif + diff --git a/src/http/http.c b/src/http/http.c index d707dfc..81b17bd 100644 --- a/src/http/http.c +++ b/src/http/http.c @@ -411,3 +411,4 @@ out: } return ret; } + diff --git a/src/http/http.h b/src/http/http.h index 5e2fe81..a5ac51a 100644 --- a/src/http/http.h +++ b/src/http/http.h @@ -24,24 +24,20 @@ typedef int(*progress_info_func)(void *p, double ultotal, double ulnow); struct http_get_options { - unsigned with_head : 1, /*if set, means write output with response HEADER*/ - with_body : 1, /*if set, means write output with response BODY*/ - /*if set, means set request with "Authorization:(char *)authorization"*/ + unsigned with_head : 1, /* if set, means write output with response HEADER */ + with_body : 1, /* if set, means write output with response BODY */ + /* if set, means set request with "Authorization:(char *)authorization" */ with_header_auth : 1, - /*if set, means set requst with "Content-Type: application/json"*/ + /* if set, means set requst with "Content-Type: application/json" */ with_header_json : 1, - /*if set, means set request with "Accept:(char *)accepts"*/ + /* if set, means set request with "Accept:(char *)accepts" */ with_header_accept : 1, - /*if set, means show the process progress"*/ + /* if set, means show the process progress" */ show_progress : 1; - /* - *#define HTTP_REQUEST_STRBUF 0 - *#define HTTP_REQUEST_FILE 1 - */ char outputtype; - /* if set, means connnect to unix socket*/ + /* if set, means connnect to unix socket */ char *unix_socket_path; /* @@ -50,9 +46,9 @@ struct http_get_options { */ void *output; - /*http method PUT GET POST*/ + /* http method PUT GET POST */ void *method; - /*body to be sent to server*/ + /* body to be sent to server */ void *input; size_t input_len; @@ -71,21 +67,21 @@ struct http_get_options { #define HTTP_RES_REAUTH 4 #define HTTP_RES_NOAUTH 5 -/*HTTP Get buffer size*/ +/* HTTP Get buffer size */ #define HTTP_GET_BUFFER_SIZE 1024 -/*authz error msg size*/ +/* authz error msg size */ #define AUTHZ_ERROR_MSG_SIZE 256 /* http_request() targets */ #define HTTP_REQUEST_STRBUF 0 #define HTTP_REQUEST_FILE 1 -/* authz unix sock and request url*/ +/* authz unix sock and request url */ #define AUTHZ_UNIX_SOCK "/run/docker/plugins/authz-broker.sock" #define AUTHZ_REQUEST_URL "http://localhost/isulad.auth" -/* http response code*/ +/* http response code */ enum http_response_code { StatusContinue = 100, // RFC 7231, 6.2.1 StatusSwitchingProtocols = 101, // RFC 7231, 6.2.2 @@ -169,3 +165,4 @@ void http_global_cleanup(void); #endif #endif + diff --git a/src/http/mediatype.h b/src/http/mediatype.h index 550dbee..195484e 100644 --- a/src/http/mediatype.h +++ b/src/http/mediatype.h @@ -75,3 +75,4 @@ #define BLOBS "/blobs" #endif + diff --git a/src/http/parser.h b/src/http/parser.h index b9d78a2..c750608 100644 --- a/src/http/parser.h +++ b/src/http/parser.h @@ -61,3 +61,4 @@ int parse_http(const char *buf, size_t len, struct parsed_http_message *m, enum http_parser_type type); #endif + diff --git a/src/http/rest_common.c b/src/http/rest_common.c index 666d853..8d53255 100644 --- a/src/http/rest_common.c +++ b/src/http/rest_common.c @@ -293,3 +293,4 @@ void put_body(char *body) { free(body); } + diff --git a/src/http/rest_common.h b/src/http/rest_common.h index 1d30da4..7a369c0 100644 --- a/src/http/rest_common.h +++ b/src/http/rest_common.h @@ -40,3 +40,4 @@ void put_body(char *body); #endif #endif /* __REST_COMMON_H */ + diff --git a/src/image/CMakeLists.txt b/src/image/CMakeLists.txt index 54b498b..6e014b7 100644 --- a/src/image/CMakeLists.txt +++ b/src/image/CMakeLists.txt @@ -13,7 +13,7 @@ set(local_image_incs ${CMAKE_CURRENT_SOURCE_DIR}/external ) -if (NOT DISABLE_OCI) +if (ENABLE_OCI_IMAGE) add_subdirectory(oci) list(APPEND local_image_srcs ${OCI_SRCS} @@ -23,7 +23,7 @@ if (NOT DISABLE_OCI) ) endif() -if (ENABLE_EMBEDDED) +if (ENABLE_EMBEDDED_IMAGE) add_subdirectory(embedded) list(APPEND local_image_srcs ${EMBEDDED_SRCS} diff --git a/src/image/embedded/db/db_all.h b/src/image/embedded/db/db_all.h index 00c42fe..01bed46 100644 --- a/src/image/embedded/db/db_all.h +++ b/src/image/embedded/db/db_all.h @@ -71,3 +71,4 @@ int db_read_all_images_info(struct db_all_images **image_info); void db_all_imginfo_free(struct db_all_images *images_info); #endif + diff --git a/src/image/embedded/db/db_common.h b/src/image/embedded/db/db_common.h index 4b5365f..6afd039 100644 --- a/src/image/embedded/db/db_common.h +++ b/src/image/embedded/db/db_common.h @@ -29,4 +29,5 @@ int db_common_init(const char *rootpath); void db_common_finish(void); -#endif /*__DB_COMMON_H_*/ +#endif /* __DB_COMMON_H_ */ + diff --git a/src/image/embedded/db/db_images_common.h b/src/image/embedded/db/db_images_common.h index 0c43dbc..e8480dd 100644 --- a/src/image/embedded/db/db_images_common.h +++ b/src/image/embedded/db/db_images_common.h @@ -33,3 +33,4 @@ struct db_all_images_info { }; #endif + diff --git a/src/image/embedded/db/sqlite_common.c b/src/image/embedded/db/sqlite_common.c index 2217fa8..f37dca9 100644 --- a/src/image/embedded/db/sqlite_common.c +++ b/src/image/embedded/db/sqlite_common.c @@ -212,3 +212,4 @@ void db_common_finish(void) { db_sqlite_finish(); } + diff --git a/src/image/embedded/db/sqlite_common.h b/src/image/embedded/db/sqlite_common.h index aa139ca..147fe84 100644 --- a/src/image/embedded/db/sqlite_common.h +++ b/src/image/embedded/db/sqlite_common.h @@ -33,3 +33,4 @@ int db_sqlite_request_callback(const char *stmt, sqlite_callback_t callback, void *data); #endif + diff --git a/src/image/embedded/embedded_config_merge.h b/src/image/embedded/embedded_config_merge.h index 323e964..7ed6c68 100644 --- a/src/image/embedded/embedded_config_merge.h +++ b/src/image/embedded/embedded_config_merge.h @@ -30,3 +30,4 @@ int embedded_image_merge_config(oci_runtime_spec *oci_spec, #endif #endif + diff --git a/src/image/embedded/embedded_image.c b/src/image/embedded/embedded_image.c index 6a27725..092820a 100644 --- a/src/image/embedded/embedded_image.c +++ b/src/image/embedded/embedded_image.c @@ -65,27 +65,32 @@ char *embedded_resolve_image_name(const char *image_name) { return util_strdup_s(image_name); } -int embedded_filesystem_usage(struct bim *bim, imagetool_fs_info **fs_usage) +int embedded_filesystem_usage(const im_container_fs_usage_request *request, imagetool_fs_info **fs_usage) { return 0; } -int embedded_prepare_rf(struct bim *bim, const json_map_string_string *storage_opt, char **real_rootfs) +int embedded_prepare_rf(const im_prepare_request *request, char **real_rootfs) { - return lim_create_rw_layer(bim->image_name, bim->container_id, NULL, real_rootfs); + if (request == NULL) { + ERROR("Invalid arguments"); + return -1; + } + + return lim_create_rw_layer(request->image_name, request->container_id, NULL, real_rootfs); } -int embedded_mount_rf(struct bim *bim) +int embedded_mount_rf(const im_mount_request *request) { return 0; } -int embedded_umount_rf(struct bim *bim) +int embedded_umount_rf(const im_umount_request *request) { return 0; } -int embedded_delete_rf(struct bim *bim) +int embedded_delete_rf(const im_delete_request *request) { return 0; } @@ -129,12 +134,18 @@ out: int embedded_merge_conf(oci_runtime_spec *oci_spec, const host_config *host_spec, container_custom_config *custom_spec, - struct bim *bim, char **real_rootfs) + const im_prepare_request *request, char **real_rootfs) { int ret = 0; int nret = 0; + im_umount_request iu_request = { 0 }; - nret = embedded_prepare_rf(bim, host_spec->storage_opt, real_rootfs); + if (request == NULL) { + ERROR("Invalid arguments"); + return -1; + } + + nret = embedded_prepare_rf(request, real_rootfs); if (nret != 0) { return nret; } @@ -145,14 +156,16 @@ int embedded_merge_conf(oci_runtime_spec *oci_spec, const host_config *host_spec goto umount; } - nret = do_merge_embedded_image_conf(oci_spec, custom_spec, bim->image_name); + nret = do_merge_embedded_image_conf(oci_spec, custom_spec, request->image_name); if (nret != 0) { ret = nret; goto umount; } umount: - nret = embedded_umount_rf(bim); + iu_request.name_id = request->container_id; + iu_request.force = false; + nret = embedded_umount_rf(&iu_request); if (nret != 0) { ret = nret; } @@ -241,7 +254,7 @@ out: return ret; } -int embedded_list_images(im_list_request *request, imagetool_images_list **list) +int embedded_list_images(const im_list_request *request, imagetool_images_list **list) { int ret = 0; struct db_all_images *all_images = NULL; @@ -253,7 +266,7 @@ int embedded_list_images(im_list_request *request, imagetool_images_list **list) goto out; } - if (request->filter.image.image != NULL) { + if (request->filter.image.image != NULL || request->image_filters != NULL) { INFO("Embedded images do not support filter"); ret = 0; goto out; @@ -292,7 +305,7 @@ out: return ret; } -int embedded_remove_image(im_remove_request *request) +int embedded_remove_image(const im_remove_request *request) { bool force = false; char *image_ref = NULL; @@ -344,22 +357,28 @@ out: return ret; } -int embedded_inspect_image(struct bim *bim, char **inspected_json) +int embedded_inspect_image(const im_inspect_request *request, char **inspected_json) { char *image_ref = NULL; - if (bim == NULL || inspected_json == NULL) { + if (request == NULL || inspected_json == NULL) { ERROR("Invalid input arguments"); return -1; } - image_ref = bim->image_name; + image_ref = request->image.image; return lim_query_image_data(image_ref, IMAGE_DATA_TYPE_CONFIG, inspected_json, NULL); } -int embedded_init(const char *rootpath) +int embedded_init(const struct im_configs *conf) { - return lim_init(rootpath); + if (conf == NULL) { + ERROR("Invalid image configs"); + return -1; + } + + return lim_init(conf->rootpath); } + diff --git a/src/image/embedded/embedded_image.h b/src/image/embedded/embedded_image.h index 4bab2ab..eee116c 100644 --- a/src/image/embedded/embedded_image.h +++ b/src/image/embedded/embedded_image.h @@ -20,33 +20,33 @@ bool embedded_detect(const char *image_name); -int embedded_prepare_rf(struct bim *bim, const json_map_string_string *storage_opt, char **real_rootfs); +int embedded_prepare_rf(const im_prepare_request *request, char **real_rootfs); -int embedded_filesystem_usage(struct bim *bim, imagetool_fs_info **fs_usage); +int embedded_filesystem_usage(const im_container_fs_usage_request *request, imagetool_fs_info **fs_usage); -int embedded_mount_rf(struct bim *bim); +int embedded_mount_rf(const im_mount_request *request); -int embedded_umount_rf(struct bim *bim); +int embedded_umount_rf(const im_umount_request *request); -int embedded_delete_rf(struct bim *bim); +int embedded_delete_rf(const im_delete_request *request); char *embedded_resolve_image_name(const char *image_name); int embedded_merge_conf(oci_runtime_spec *oci_spec, const host_config *host_spec, container_custom_config *custom_spec, - struct bim *bim, char **real_rootfs); + const im_prepare_request *request, char **real_rootfs); int embedded_get_user_conf(const char *basefs, host_config *hc, const char *userstr, oci_runtime_spec_process_user *puser); -int embedded_list_images(im_list_request *request, - imagetool_images_list **list); +int embedded_list_images(const im_list_request *request, imagetool_images_list **list); -int embedded_remove_image(im_remove_request *request); +int embedded_remove_image(const im_remove_request *request); -int embedded_inspect_image(struct bim *bim, char **inspected_json); +int embedded_inspect_image(const im_inspect_request *request, char **inspected_json); -int embedded_load_image(im_load_request *request); +int embedded_load_image(const im_load_request *request); -int embedded_init(const char *rootpath); +int embedded_init(const struct im_configs *conf); #endif + diff --git a/src/image/embedded/lim.c b/src/image/embedded/lim.c index 3d49987..2edb05a 100644 --- a/src/image/embedded/lim.c +++ b/src/image/embedded/lim.c @@ -494,6 +494,10 @@ static bool valid_manifest_and_get_size(embedded_manifest *manifest, const char for (i = 1; i < (int)manifest->layers_len; i++) { abs_path = util_add_path(path, manifest->layers[i]->path_in_host); + if (abs_path == NULL) { + ERROR("Failed to add path: %s, %s", path, manifest->layers[i]->path_in_host); + goto out; + } if (strlen(abs_path) > PATH_MAX || !realpath(abs_path, real_path)) { ERROR("invalid file path %s", abs_path); lcrd_try_set_error_message("Invalid content in manifest: layer not exists"); @@ -831,3 +835,4 @@ out: return ret; } + diff --git a/src/image/embedded/lim.h b/src/image/embedded/lim.h index 6575993..4d2a4b5 100644 --- a/src/image/embedded/lim.h +++ b/src/image/embedded/lim.h @@ -57,3 +57,4 @@ int lim_create_rw_layer(char *name, const char *id, char **options, char **mount_string); #endif + diff --git a/src/image/embedded/load.c b/src/image/embedded/load.c index f4914a2..33e4071 100644 --- a/src/image/embedded/load.c +++ b/src/image/embedded/load.c @@ -195,7 +195,7 @@ out: return ret; } -int embedded_load_image(im_load_request *request) +int embedded_load_image(const im_load_request *request) { if (request == NULL) { ERROR("invalid NULL param"); @@ -205,3 +205,4 @@ int embedded_load_image(im_load_request *request) return load_image(request->file); } + diff --git a/src/image/embedded/snapshot/embedded.c b/src/image/embedded/snapshot/embedded.c index e64daff..e1bca33 100644 --- a/src/image/embedded/snapshot/embedded.c +++ b/src/image/embedded/snapshot/embedded.c @@ -69,3 +69,4 @@ int ebd_generate_mount_string(struct db_image *imginfo, return 0; } + diff --git a/src/image/embedded/snapshot/embedded.h b/src/image/embedded/snapshot/embedded.h index f1e4bd3..4fc51ff 100644 --- a/src/image/embedded/snapshot/embedded.h +++ b/src/image/embedded/snapshot/embedded.h @@ -32,3 +32,4 @@ int ebd_generate_mount_string(struct db_image *imginfo, struct db_sninfo **sninfos, char **mount_string); #endif + diff --git a/src/image/embedded/snapshot/snapshot.c b/src/image/embedded/snapshot/snapshot.c index b1dc6af..c7ab4e6 100644 --- a/src/image/embedded/snapshot/snapshot.c +++ b/src/image/embedded/snapshot/snapshot.c @@ -73,3 +73,4 @@ int snapshot_generate_mount_string(uint32_t driver_type, return g_sd->plugins[driver_type].gms(imginfo, sninfos, mount_string); } + diff --git a/src/image/embedded/snapshot/snapshot.h b/src/image/embedded/snapshot/snapshot.h index 4437d08..e27cac5 100644 --- a/src/image/embedded/snapshot/snapshot.h +++ b/src/image/embedded/snapshot/snapshot.h @@ -29,3 +29,4 @@ int snapshot_generate_mount_string(uint32_t driver_type, struct db_sninfo **sninfos, char **mount_string); #endif + diff --git a/src/image/embedded/snapshot/snapshot_def.h b/src/image/embedded/snapshot/snapshot_def.h index 28fe887..711d3d0 100644 --- a/src/image/embedded/snapshot/snapshot_def.h +++ b/src/image/embedded/snapshot/snapshot_def.h @@ -46,3 +46,4 @@ struct snapshot_plugin { #endif + diff --git a/src/image/external/ext_image.c b/src/image/external/ext_image.c index 06ed52d..049f74a 100644 --- a/src/image/external/ext_image.c +++ b/src/image/external/ext_image.c @@ -28,7 +28,7 @@ #include "ext_image.h" #ifdef ENABLE_OCI_IMAGE -#include "oci_image.h" +#include "oci_common_operators.h" #include "oci_images_store.h" #include "oci_config_merge.h" #endif @@ -46,26 +46,31 @@ bool ext_detect(const char *image_name) return util_file_exists(image_name); } -int ext_filesystem_usage(struct bim *bim, imagetool_fs_info **fs_usage) +int ext_filesystem_usage(const im_container_fs_usage_request *request, imagetool_fs_info **fs_usage) { return 0; } -int ext_prepare_rf(struct bim *bim, const json_map_string_string *storage_opt, char **real_rootfs) +int ext_prepare_rf(const im_prepare_request *request, char **real_rootfs) { int ret = 0; + if (request == NULL) { + ERROR("Invalid arguments"); + return -1; + } + if (real_rootfs != NULL) { - if (bim->image_name != NULL) { + if (request->image_name != NULL) { char real_path[PATH_MAX] = { 0 }; - if (bim->image_name[0] != '/') { + if (request->image_name[0] != '/') { ERROR("Rootfs should be absolutely path"); lcrd_set_error_message("Rootfs should be absolutely path"); return -1; } - if (realpath(bim->image_name, real_path) == NULL) { - ERROR("Failed to clean rootfs path '%s': %s", bim->image_name, strerror(errno)); - lcrd_set_error_message("Failed to clean rootfs path '%s': %s", bim->image_name, strerror(errno)); + if (realpath(request->image_name, real_path) == NULL) { + ERROR("Failed to clean rootfs path '%s': %s", request->image_name, strerror(errno)); + lcrd_set_error_message("Failed to clean rootfs path '%s': %s", request->image_name, strerror(errno)); return -1; } *real_rootfs = util_strdup_s(real_path); @@ -77,17 +82,17 @@ int ext_prepare_rf(struct bim *bim, const json_map_string_string *storage_opt, c return ret; } -int ext_mount_rf(struct bim *bim) +int ext_mount_rf(const im_mount_request *request) { return 0; } -int ext_umount_rf(struct bim *bim) +int ext_umount_rf(const im_umount_request *request) { return 0; } -int ext_delete_rf(struct bim *bim) +int ext_delete_rf(const im_delete_request *request) { return 0; } @@ -97,35 +102,42 @@ char *ext_resolve_image_name(const char *image_name) return util_strdup_s(image_name); } -#ifdef ENABLE_OCI_IMAGE int ext_merge_conf(oci_runtime_spec *oci_spec, const host_config *host_spec, container_custom_config *custom_spec, - struct bim *bim, char **real_rootfs) + const im_prepare_request *request, char **real_rootfs) +#ifdef ENABLE_OCI_IMAGE { int ret = 0; char *resolved_name = NULL; oci_image_t *image_info = NULL; + im_umount_request umount_request = { 0 }; + if (request == NULL) { + ERROR("Invalid arguments"); + return -1; + } // Ensure rootfs is valid. - ret = ext_prepare_rf(bim, host_spec->storage_opt, real_rootfs); + ret = ext_prepare_rf(request, real_rootfs); if (ret != 0) { return ret; } - ret = ext_umount_rf(bim); + umount_request.name_id = request->container_id; + umount_request.force = false; + ret = ext_umount_rf(&umount_request); if (ret != 0) { return ret; } // No config neeed merge if NULL. - if (bim->ext_config_image == NULL) { + if (request->ext_config_image == NULL) { ret = 0; goto out; } // Get image's config and merge configs. - resolved_name = oci_resolve_image_name(bim->ext_config_image); + resolved_name = oci_resolve_image_name(request->ext_config_image); if (resolved_name == NULL) { - ERROR("Resolve external config image name failed, image name is %s", bim->ext_config_image); + ERROR("Resolve external config image name failed, image name is %s", request->ext_config_image); ret = -1; goto out; } @@ -149,18 +161,19 @@ out: return ret; } #else -int ext_merge_conf(oci_runtime_spec *oci_spec, const host_config *host_spec, container_custom_config *custom_spec, - struct bim *bim, char **real_rootfs) { int ret = 0; + im_umount_request umount_request = { 0 }; // Ensure rootfs is valid. - ret = ext_prepare_rf(bim, host_spec->storage_opt, real_rootfs); + ret = ext_prepare_rf(request, real_rootfs); if (ret != 0) { return ret; } - ret = ext_umount_rf(bim); + umount_request.name_id = request->container_id; + umount_request.force = false; + ret = ext_umount_rf(&umount_request); if (ret != 0) { return ret; } @@ -178,7 +191,7 @@ int ext_get_user_conf(const char *basefs, host_config *hc, const char *userstr, return get_user(basefs, hc, userstr, puser); } -int ext_list_images(im_list_request *request, imagetool_images_list **list) +int ext_list_images(const im_list_request *request, imagetool_images_list **list) { int ret = 0; @@ -192,32 +205,33 @@ out: return ret; } -int ext_remove_image(im_remove_request *request) +int ext_remove_image(const im_remove_request *request) { return 0; } -int ext_inspect_image(struct bim *bim, char **inspected_json) +int ext_inspect_image(const im_inspect_request *request, char **inspected_json) { return 0; } -int ext_load_image(im_load_request *request) +int ext_load_image(const im_load_request *request) { return 0; } -int ext_login(im_login_request *request) +int ext_login(const im_login_request *request) { return 0; } -int ext_logout(im_logout_request *request) +int ext_logout(const im_logout_request *request) { return 0; } -int ext_init(const char *rootpath) +int ext_init(const struct im_configs *conf) { return 0; } + diff --git a/src/image/external/ext_image.h b/src/image/external/ext_image.h index cc05a92..2346953 100644 --- a/src/image/external/ext_image.h +++ b/src/image/external/ext_image.h @@ -19,24 +19,25 @@ #include "image.h" bool ext_detect(const char *image_name); -int ext_filesystem_usage(struct bim *bim, imagetool_fs_info **fs_usage); +int ext_filesystem_usage(const im_container_fs_usage_request *request, imagetool_fs_info **fs_usage); -int ext_prepare_rf(struct bim *bim, const json_map_string_string *storage_opt, char **real_rootfs); -int ext_mount_rf(struct bim *bim); -int ext_umount_rf(struct bim *bim); -int ext_delete_rf(struct bim *bim); +int ext_prepare_rf(const im_prepare_request *request, char **real_rootfs); +int ext_mount_rf(const im_mount_request *request); +int ext_umount_rf(const im_umount_request *request); +int ext_delete_rf(const im_delete_request *request); char *ext_resolve_image_name(const char *image_name); int ext_merge_conf(oci_runtime_spec *oci_spec, const host_config *host_spec, container_custom_config *custom_spec, - struct bim *bim, char **real_rootfs); + const im_prepare_request *request, char **real_rootfs); int ext_get_user_conf(const char *basefs, host_config *hc, const char *userstr, oci_runtime_spec_process_user *puser); -int ext_list_images(im_list_request *request, imagetool_images_list **list); -int ext_remove_image(im_remove_request *request); -int ext_inspect_image(struct bim *bim, char **inspected_json); -int ext_load_image(im_load_request *request); -int ext_login(im_login_request *request); -int ext_logout(im_logout_request *request); +int ext_list_images(const im_list_request *request, imagetool_images_list **list); +int ext_remove_image(const im_remove_request *request); +int ext_inspect_image(const im_inspect_request *request, char **inspected_json); +int ext_load_image(const im_load_request *request); +int ext_login(const im_login_request *request); +int ext_logout(const im_logout_request *request); -int ext_init(const char *rootpath); +int ext_init(const struct im_configs *conf); #endif + diff --git a/src/image/image.c b/src/image/image.c index dd4ceec..e7e270f 100644 --- a/src/image/image.c +++ b/src/image/image.c @@ -28,13 +28,11 @@ #include "utils.h" #include "ext_image.h" +#include "filters.h" #ifdef ENABLE_OCI_IMAGE -#include "oci_image.h" -#include "oci_image_status.h" -#include "oci_image_load.h" -#include "oci_login.h" -#include "oci_logout.h" +#include "isula_image.h" +#include "oci_images_store.h" #endif #ifdef ENABLE_EMBEDDED_IMAGE @@ -44,81 +42,108 @@ /* embedded */ static const struct bim_ops g_embedded_ops = { .init = embedded_init, + .clean_resource = NULL, .detect = embedded_detect, .prepare_rf = embedded_prepare_rf, .mount_rf = embedded_mount_rf, .umount_rf = embedded_umount_rf, .delete_rf = embedded_delete_rf, + .export_rf = NULL, .merge_conf = embedded_merge_conf, .get_user_conf = embedded_get_user_conf, .list_ims = embedded_list_images, + .get_image_count = NULL, .rm_image = embedded_remove_image, .inspect_image = embedded_inspect_image, .resolve_image_name = embedded_resolve_image_name, - .filesystem_usage = embedded_filesystem_usage, + .container_fs_usage = embedded_filesystem_usage, + .get_filesystem_info = NULL, + .get_storage_status = NULL, + .image_status = NULL, .load_image = embedded_load_image, .pull_image = NULL, + + .login = NULL, + .logout = NULL, + + .health_check = NULL, }; #endif +/* isula image server */ #ifdef ENABLE_OCI_IMAGE -/* oci */ -static const struct bim_ops g_oci_ops = { - .init = oci_init, +static const struct bim_ops g_isula_ops = { + .init = isula_init, + .clean_resource = isula_exit, .detect = oci_detect, - .prepare_rf = oci_prepare_rf, - .mount_rf = oci_mount_rf, - .umount_rf = oci_umount_rf, - .delete_rf = oci_delete_rf, + .prepare_rf = isula_prepare_rf, + .mount_rf = isula_mount_rf, + .umount_rf = isula_umount_rf, + .delete_rf = isula_delete_rf, + .export_rf = isula_export_rf, - .merge_conf = oci_merge_conf, + .merge_conf = isula_merge_conf_rf, .get_user_conf = oci_get_user_conf, .list_ims = oci_list_images, - .rm_image = oci_remove_image, + .get_image_count = oci_images_store_size, + .rm_image = isula_rmi, .inspect_image = oci_inspect_image, .resolve_image_name = oci_resolve_image_name, - .filesystem_usage = oci_filesystem_usage, - .load_image = oci_load_image, - .pull_image = oci_pull_image, - .login = oci_login, - .logout = oci_logout, + .container_fs_usage = isula_container_filesystem_usage, + .get_filesystem_info = isula_get_filesystem_info, + .get_storage_status = isula_get_storage_status, + .image_status = oci_status_image, + .load_image = isual_load_image, + .pull_image = isula_pull_rf, + .login = isula_login, + .logout = isula_logout, + + .health_check = isula_health_check, }; #endif /* external */ static const struct bim_ops g_ext_ops = { .init = ext_init, + .clean_resource = NULL, .detect = ext_detect, .prepare_rf = ext_prepare_rf, .mount_rf = ext_mount_rf, .umount_rf = ext_umount_rf, .delete_rf = ext_delete_rf, + .export_rf = NULL, .merge_conf = ext_merge_conf, .get_user_conf = ext_get_user_conf, .list_ims = ext_list_images, + .get_image_count = NULL, .rm_image = ext_remove_image, .inspect_image = ext_inspect_image, .resolve_image_name = ext_resolve_image_name, - .filesystem_usage = ext_filesystem_usage, + .container_fs_usage = ext_filesystem_usage, + .image_status = NULL, + .get_filesystem_info = NULL, + .get_storage_status = NULL, .load_image = ext_load_image, .pull_image = NULL, .login = ext_login, .logout = ext_logout, + + .health_check = NULL, }; static const struct bim_type g_bims[] = { #ifdef ENABLE_OCI_IMAGE { .image_type = IMAGE_TYPE_OCI, - .ops = &g_oci_ops, + .ops = &g_isula_ops, }, #endif { .image_type = IMAGE_TYPE_EXTERNAL, .ops = &g_ext_ops }, @@ -135,6 +160,10 @@ static const struct bim_type *bim_query(const char *image_name) char *temp = NULL; for (i = 0; i < g_numbims; i++) { + if (g_bims[i].ops->resolve_image_name == NULL) { + WARN("Unimplements resolve image name in %s", g_bims[i].image_type); + continue; + } temp = g_bims[i].ops->resolve_image_name(image_name); if (temp == NULL) { lcrd_append_error_message("Failed to resovle image name%s", image_name); @@ -219,7 +248,7 @@ static struct bim *bim_get(const char *image_type, const char *image_name, const if (ext_config_image != NULL) { bim->ext_config_image = util_strdup_s(ext_config_image); if (bim->ext_config_image == NULL) { - lcrd_append_error_message("Failed to strdup external config image %s", bim->ext_config_image); + lcrd_append_error_message("Failed to dup external config image %s", bim->ext_config_image); bim_put(bim); return NULL; } @@ -230,12 +259,132 @@ static struct bim *bim_get(const char *image_type, const char *image_name, const return bim; } +int im_resolv_image_name(const char *image_type, const char *image_name, char **resolved_name) +{ + int ret = -1; + const struct bim_type *q = NULL; + + if (image_type == NULL) { + ERROR("Image type is required"); + goto out; + } + q = get_bim_by_type(image_type); + if (q == NULL) { + goto out; + } + if (q->ops->resolve_image_name == NULL) { + ERROR("Get resolve image name umimplements"); + goto out; + } + + *resolved_name = q->ops->resolve_image_name(image_name); + if (*resolved_name == NULL) { + goto out; + } + + ret = 0; +out: + return ret; +} + +int im_get_storage_status(const char *image_type, im_storage_status_response **response) +{ + int ret = -1; + const struct bim_type *q = NULL; + + if (image_type == NULL) { + ERROR("Image type is required"); + goto out; + } + q = get_bim_by_type(image_type); + if (q == NULL) { + goto out; + } + if (q->ops->get_storage_status == NULL) { + ERROR("Get storage status umimplements"); + goto out; + } + + ret = q->ops->get_storage_status(response); + if (ret != 0) { + ERROR("Get storage status failed"); + free_im_storage_status_response(*response); + *response = NULL; + goto out; + } + +out: + return ret; +} + +int im_get_filesystem_info(const char *image_type, im_fs_info_response **response) +{ + int ret = -1; + const struct bim_type *q = NULL; + + if (image_type == NULL) { + ERROR("Image type is required"); + goto out; + } + + q = get_bim_by_type(image_type); + if (q == NULL) { + goto out; + } + if (q->ops->get_filesystem_info == NULL) { + ERROR("Get filesystem info umimplements"); + goto out; + } + + EVENT("Event: {Object: get image filesystem info, Type: inspecting}"); + ret = q->ops->get_filesystem_info(response); + if (ret != 0) { + if (response != NULL && *response != NULL) { + ERROR("Get filesystem info failed: %s", (*response)->errmsg); + } else { + ERROR("Get filesystem info failed"); + } + goto out; + } + EVENT("Event: {Object: get image filesystem info, Type: inspected}"); + +out: + return ret; +} + +int im_health_check(const char *image_type) +{ + int ret = -1; + const struct bim_type *q = NULL; + + if (image_type == NULL) { + ERROR("Image type is required"); + goto out; + } + + q = get_bim_by_type(image_type); + if (q == NULL) { + ERROR("Get bim failed"); + goto out; + } + + if (q->ops->health_check == NULL) { + ERROR("Health check umimplement"); + goto out; + } + + ret = q->ops->health_check(); + +out: + return ret; +} + int im_get_container_filesystem_usage(const char *image_type, const char *id, imagetool_fs_info **fs_usage) { int ret = 0; imagetool_fs_info *filesystemusage = NULL; const struct bim_type *q = NULL; - struct bim *bim = NULL; + im_container_fs_usage_request *request = NULL; if (image_type == NULL || id == NULL) { ERROR("Invalid input arguments"); @@ -248,21 +397,24 @@ int im_get_container_filesystem_usage(const char *image_type, const char *id, im ret = -1; goto out; } + if (q->ops->container_fs_usage == NULL) { + ERROR("Unimplements filesystem usage in %s", image_type); + goto out; + } - bim = util_common_calloc_s(sizeof(struct bim)); - if (bim == NULL) { + request = util_common_calloc_s(sizeof(im_container_fs_usage_request)); + if (request == NULL) { + ERROR("Out of memory"); ret = -1; goto out; } - bim->ops = q->ops; - bim->type = q->image_type; - if (id != NULL) { - bim->container_id = util_strdup_s(id); + request->name_id = util_strdup_s(id); } - ret = bim->ops->filesystem_usage(bim, &filesystemusage); + EVENT("Event: {Object: container \'%s\' filesystem info, Type: inspecting}", id != NULL ? id : ""); + ret = q->ops->container_fs_usage(request, &filesystemusage); if (ret != 0) { ERROR("Failed to get filesystem usage for container %s", id); ret = -1; @@ -270,15 +422,17 @@ int im_get_container_filesystem_usage(const char *image_type, const char *id, im } *fs_usage = filesystemusage; + EVENT("Event: {Object: container \'%s\' filesystem info, Type: inspected}", id != NULL ? id : ""); out: - bim_put(bim); + free_im_container_fs_usage_request(request); return ret; } int im_remove_container_rootfs(const char *image_type, const char *container_id) { int ret = 0; + im_delete_request *request = NULL; struct bim *bim = NULL; if (container_id == NULL || image_type == NULL) { @@ -293,23 +447,102 @@ int im_remove_container_rootfs(const char *image_type, const char *container_id) ret = -1; goto out; } + if (bim->ops->delete_rf == NULL) { + ERROR("Unimplements delete in %s", bim->type); + goto out; + } - ret = bim->ops->delete_rf(bim); + request = util_common_calloc_s(sizeof(im_delete_request)); + if (request == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + request->name_id = util_strdup_s(container_id); + + EVENT("Event: {Object: %s, Type: removeing rootfs}", container_id); + ret = bim->ops->delete_rf(request); if (ret != 0) { ERROR("Failed to delete rootfs for container %s", container_id); ret = -1; goto out; } + EVENT("Event: {Object: %s, Type: removed rootfs}", container_id); out: bim_put(bim); + free_im_delete_request(request); return ret; } +void free_im_container_fs_usage_request(im_container_fs_usage_request *request) +{ + if (request == NULL) { + return; + } + + free(request->name_id); + request->name_id = NULL; + free(request); +} + +void free_im_prepare_request(im_prepare_request *request) +{ + if (request == NULL) { + return; + } + + free(request->image_name); + request->image_name = NULL; + free(request->container_id); + request->container_id = NULL; + free(request->ext_config_image); + request->ext_config_image = NULL; + + free_json_map_string_string(request->storage_opt); + request->storage_opt = NULL; + + free(request); +} + +void free_im_mount_request(im_mount_request *request) +{ + if (request == NULL) { + return; + } + + free(request->name_id); + request->name_id = NULL; + free(request); +} + +void free_im_delete_request(im_delete_request *request) +{ + if (request == NULL) { + return; + } + + free(request->name_id); + request->name_id = NULL; + free(request); +} + +void free_im_umount_request(im_umount_request *request) +{ + if (request == NULL) { + return; + } + + free(request->name_id); + request->name_id = NULL; + free(request); +} + int im_umount_container_rootfs(const char *image_type, const char *image_name, const char *container_id) { int ret = 0; struct bim *bim = NULL; + im_umount_request *request = NULL; if (container_id == NULL || image_type == NULL || image_name == NULL) { ERROR("Invalid input arguments"); @@ -323,16 +556,33 @@ int im_umount_container_rootfs(const char *image_type, const char *image_name, c ret = -1; goto out; } + if (bim->ops->umount_rf == NULL) { + ERROR("Unimplements umount in %s", bim->type); + goto out; + } - ret = bim->ops->umount_rf(bim); + request = (im_umount_request *)util_common_calloc_s(sizeof(im_umount_request)); + if (request == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + request->force = false; + request->name_id = bim->container_id; + bim->container_id = NULL; + + EVENT("Event: {Object: %s, Type: umounting rootfs}", container_id); + ret = bim->ops->umount_rf(request); if (ret != 0) { ERROR("Failed to umount rootfs for container %s", container_id); ret = -1; goto out; } + EVENT("Event: {Object: %s, Type: umounted rootfs}", container_id); out: bim_put(bim); + free_im_umount_request(request); return ret; } @@ -340,6 +590,7 @@ int im_mount_container_rootfs(const char *image_type, const char *image_name, co { int ret = 0; struct bim *bim = NULL; + im_mount_request *request = NULL; if (image_name == NULL || container_id == NULL || image_type == NULL) { ERROR("Invalid input arguments"); @@ -353,16 +604,31 @@ int im_mount_container_rootfs(const char *image_type, const char *image_name, co ret = -1; goto out; } + if (bim->ops->mount_rf == NULL) { + ERROR("Unimplements mount in %s", bim->type); + goto out; + } - ret = bim->ops->mount_rf(bim); + request = util_common_calloc_s(sizeof(im_mount_request)); + if (request == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + request->name_id = util_strdup_s(container_id); + + EVENT("Event: {Object: %s, Type: mounting rootfs}", container_id); + ret = bim->ops->mount_rf(request); if (ret != 0) { ERROR("Failed to mount rootfs for container %s", container_id); ret = -1; goto out; } + EVENT("Event: {Object: %s, Type: mounted rootfs}", container_id); out: bim_put(bim); + free_im_mount_request(request); return ret; } @@ -408,6 +674,7 @@ int im_merge_image_config(const char *id, const char *image_type, const char *im { int ret = 0; struct bim *bim = NULL; + im_prepare_request *request = NULL; if (real_rootfs == NULL || oci_spec == NULL || image_type == NULL) { ERROR("Invalid input arguments"); @@ -421,17 +688,40 @@ int im_merge_image_config(const char *id, const char *image_type, const char *im ret = -1; goto out; } + if (bim->ops->merge_conf == NULL) { + ERROR("Unimplements merge config in %s", bim->type); + goto out; + } - ret = bim->ops->merge_conf(oci_spec, host_spec, custom_spec, bim, real_rootfs); + request = util_common_calloc_s(sizeof(im_prepare_request)); + if (request == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + request->container_id = util_strdup_s(id); + request->image_name = util_strdup_s(image_name); + request->ext_config_image = util_strdup_s(ext_config_image); + if (host_spec != NULL) { + request->storage_opt = host_spec->storage_opt; + } + + EVENT("Event: {Object: %s, Type: preparing rootfs with image %s}", id, image_name); + + ret = bim->ops->merge_conf(oci_spec, host_spec, custom_spec, request, real_rootfs); + request->storage_opt = NULL; if (ret != 0) { ERROR("Failed to merge image %s config, config image is %s", image_name, ext_config_image); ret = -1; goto out; } + EVENT("Event: {Object: %s, Type: prepared rootfs with image %s}", id, image_name); + INFO("Use real rootfs: %s with type: %s", *real_rootfs, image_type); out: bim_put(bim); + free_im_prepare_request(request); return ret; } @@ -453,6 +743,10 @@ int im_get_user_conf(const char *image_type, const char *basefs, host_config *hc ret = -1; goto out; } + if (bim->ops->get_user_conf == NULL) { + ERROR("Unimplements get user config in %s", bim->type); + goto out; + } ret = bim->ops->get_user_conf(basefs, hc, userstr, puser); if (ret != 0) { @@ -492,7 +786,6 @@ static int append_images_to_response(im_list_response *response, imagetool_image } images_num = images_in->images_len; - // no images need to append if (images_num == 0) { goto out; @@ -524,25 +817,25 @@ static int append_images_to_response(im_list_response *response, imagetool_image out: return ret; } - -int im_list_images(im_list_request *request, im_list_response **response) +int im_list_images(const im_list_request *ctx, im_list_response **response) { - char *filter = NULL; size_t i; imagetool_images_list *images_tmp = NULL; - filter = request->filter.image.image; - *response = util_common_calloc_s(sizeof(im_list_response)); if (*response == NULL) { ERROR("Out of memory"); return -1; } - EVENT("Event: {Object: list images, Type: listing, Filter: %s}", filter ? filter : ""); + EVENT("Event: {Object: list images, Type: listing}"); for (i = 0; i < g_numbims; i++) { - int ret = g_bims[i].ops->list_ims(request, &images_tmp); + if (g_bims[i].ops->list_ims == NULL) { + DEBUG("bim %s umimplements list images operator", g_bims[i].image_type); + continue; + } + int ret = g_bims[i].ops->list_ims(ctx, &images_tmp); if (ret != 0) { ERROR("Failed to list all images with type:%s", g_bims[i].image_type); continue; @@ -555,7 +848,7 @@ int im_list_images(im_list_request *request, im_list_response **response) images_tmp = NULL; } - EVENT("Event: {Object: list images, Type: listed, Filter: %s}", filter ? filter : ""); + EVENT("Event: {Object: list images, Type: listed}"); if (g_lcrd_errmsg != NULL) { (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); @@ -572,6 +865,8 @@ void free_im_list_request(im_list_request *ptr) free(ptr->filter.image.image); ptr->filter.image.image = NULL; + filters_args_free(ptr->image_filters); + ptr->image_filters = NULL; free(ptr); } @@ -618,17 +913,18 @@ int im_pull_image(const im_pull_request *request, im_pull_response **response) } if (bim->ops->pull_image == NULL) { - WARN("Unimplements pull image in %s", bim->type); - ret = 0; + ERROR("Unimplements pull image in %s", bim->type); goto out; } + EVENT("Event: {Object: %s, Type: Pulling}", request->image); ret = bim->ops->pull_image(request, response); if (ret != 0) { ERROR("Pull image %s failed", request->image); ret = -1; goto out; } + EVENT("Event: {Object: %s, Type: Pulled}", request->image); out: bim_put(bim); @@ -671,7 +967,7 @@ void free_im_pull_response(im_pull_response *resp) free(resp); } -int im_load_image(im_load_request *request, im_load_response **response) +int im_load_image(const im_load_request *request, im_load_response **response) { int ret = -1; struct bim *bim = NULL; @@ -704,6 +1000,10 @@ int im_load_image(im_load_request *request, im_load_response **response) ERROR("Failed to init bim, image type:%s", request->type); goto pack_response; } + if (bim->ops->load_image == NULL) { + ERROR("Unimplements load image in %s", bim->type); + goto pack_response; + } EVENT("Event: {Object: %s, Type: loading}", request->file); @@ -755,7 +1055,7 @@ void free_im_load_response(im_load_response *ptr) free(ptr); } -int im_login(im_login_request *request, im_login_response **response) +int im_login(const im_login_request *request, im_login_response **response) { int ret = -1; struct bim *bim = NULL; @@ -848,7 +1148,7 @@ void free_im_login_response(im_login_response *ptr) free(ptr); } -int im_logout(im_logout_request *request, im_logout_response **response) +int im_logout(const im_logout_request *request, im_logout_response **response) { int ret = -1; struct bim *bim = NULL; @@ -929,7 +1229,66 @@ void free_im_logout_response(im_logout_response *ptr) free(ptr); } -int im_rm_image(im_remove_request *request, im_remove_response **response) +int im_image_status(im_status_request *request, im_status_response **response) +{ + int ret = -1; + char *image_ref = NULL; + const struct bim_type *bim_type = NULL; + struct bim *bim = NULL; + + if (request == NULL || response == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + *response = (im_status_response *)util_common_calloc_s(sizeof(im_status_response)); + if (*response == NULL) { + ERROR("Out of memory"); + return -1; + } + + if (request->image.image == NULL) { + ERROR("get image status requires image ref"); + lcrd_set_error_message("get image status requires image ref"); + goto pack_response; + } + + image_ref = util_strdup_s(request->image.image); + + bim_type = bim_query(image_ref); + if (bim_type == NULL) { + ERROR("No such image:%s", image_ref); + lcrd_set_error_message("No such image:%s", image_ref); + goto pack_response; + } + + bim = bim_get(bim_type->image_type, image_ref, NULL, NULL); + if (bim == NULL) { + ERROR("Failed to init bim for image %s", image_ref); + goto pack_response; + } + if (bim->ops->image_status == NULL) { + ERROR("Unimplements image status in %s", bim->type); + goto pack_response; + } + + ret = bim->ops->image_status(request, response); + if (ret != 0) { + ERROR("Failed to get status of image %s", image_ref); + ret = -1; + } + +pack_response: + if (g_lcrd_errmsg != NULL) { + free((*response)->errmsg); + (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); + } + free(image_ref); + bim_put(bim); + return ret; +} + +int im_rm_image(const im_remove_request *request, im_remove_response **response) { int ret = -1; char *image_ref = NULL; @@ -955,7 +1314,7 @@ int im_rm_image(im_remove_request *request, im_remove_response **response) image_ref = util_strdup_s(request->image.image); - EVENT("Event: {Object: %s, Type: removing}", image_ref); + EVENT("Event: {Object: %s, Type: image removing}", image_ref); bim_type = bim_query(image_ref); if (bim_type == NULL) { @@ -969,6 +1328,10 @@ int im_rm_image(im_remove_request *request, im_remove_response **response) ERROR("Failed to init bim for image %s", image_ref); goto pack_response; } + if (bim->ops->rm_image == NULL) { + ERROR("Unimplements rm image in %s", bim->type); + goto pack_response; + } ret = bim->ops->rm_image(request); if (ret != 0) { @@ -977,7 +1340,7 @@ int im_rm_image(im_remove_request *request, im_remove_response **response) goto pack_response; } - EVENT("Event: {Object: %s, Type: removed}", image_ref); + EVENT("Event: {Object: %s, Type: image removed}", image_ref); pack_response: if (g_lcrd_errmsg != NULL) { @@ -1011,6 +1374,36 @@ void free_im_remove_response(im_remove_response *ptr) free(ptr); } +static int do_im_inspect_image(struct bim *bim, char **inspected_json) +{ + int ret = 0; + im_inspect_request *update_request = NULL; + + if (bim->ops->inspect_image == NULL) { + ERROR("Unimplements inspect image in %s", bim->type); + ret = -1; + goto out; + } + update_request = util_common_calloc_s(sizeof(im_inspect_request)); + if (update_request == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + update_request->image.image = bim->image_name; + bim->image_name = NULL; + + ret = bim->ops->inspect_image(update_request, inspected_json); + if (ret != 0) { + ERROR("Failed to inspect image %s", update_request->image.image); + ret = -1; + } + +out: + free_im_inspect_request(update_request); + return ret; +} + int im_inspect_image(const im_inspect_request *request, im_inspect_response **response) { int ret = 0; @@ -1039,7 +1432,7 @@ int im_inspect_image(const im_inspect_request *request, im_inspect_response **re image_ref = util_strdup_s(request->image.image); - EVENT("Event: {Object: %s, Type: inspecting}", image_ref); + EVENT("Event: {Object: %s, Type: image inspecting}", image_ref); bim_type = bim_query(image_ref); if (bim_type == NULL) { @@ -1056,14 +1449,12 @@ int im_inspect_image(const im_inspect_request *request, im_inspect_response **re goto pack_response; } - ret = bim->ops->inspect_image(bim, &inspected_json); + ret = do_im_inspect_image(bim, &inspected_json); if (ret != 0) { - ERROR("Failed to inspect image %s", image_ref); - ret = -1; goto pack_response; } - EVENT("Event: {Object: %s, Type: inspected}", image_ref); + EVENT("Event: {Object: %s, Type: image inspected}", image_ref); pack_response: if (g_lcrd_errmsg != NULL) { @@ -1104,13 +1495,134 @@ void free_im_inspect_response(im_inspect_response *ptr) free(ptr); } -static int bims_init(const char *rootpath) +/* + * parameters: image type + * return: error return 0, success return image count + * */ +size_t im_get_image_count(const im_image_count_request *request) +{ + size_t ret = 0; + const struct bim_type *q = NULL; + + if (request == NULL || request->type == NULL) { + ERROR("Image type is required"); + goto out; + } + q = get_bim_by_type(request->type); + if (q == NULL) { + goto out; + } + if (q->ops->get_image_count == NULL) { + ERROR("Get image count umimplements"); + goto out; + } + + ret = q->ops->get_image_count(); + +out: + return ret; +} + +void free_im_image_count_request(im_image_count_request *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->type); + ptr->type = NULL; + free(ptr); +} + +int im_container_export(const im_export_request *request) +{ + int ret = 0; + int nret = 0; + struct bim *bim = NULL; + + if (request == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + if (request->file == NULL) { + ERROR("Container export requires output file path"); + ret = -1; + goto out; + } + if (request->name_id == NULL) { + ERROR("Container export requires container id"); + ret = -1; + goto out; + } + + if (request->type == NULL) { + ERROR("Missing image type"); + ret = -1; + goto out; + } + + bim = bim_get(request->type, NULL, NULL, NULL); + if (bim == NULL) { + ERROR("Failed to init bim, image type:%s", request->type); + ret = -1; + goto out; + } + if (bim->ops->export_rf == NULL) { + ERROR("Unimplements container export in %s", bim->type); + ret = -1; + goto out; + } + + EVENT("Event: {Object: %s, Type: exporting}", request->file); + + nret = bim->ops->export_rf(request); + if (nret != 0) { + ERROR("Failed to export container from %s into file %s and type %s", + request->name_id, request->file, request->type); + ret = -1; + goto out; + } + + EVENT("Event: {Object: %s, Type: exported}", request->name_id); + +out: + bim_put(bim); + return ret; +} + +void free_im_export_request(im_export_request *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->type); + ptr->type = NULL; + free(ptr->file); + ptr->file = NULL; + free(ptr->name_id); + ptr->name_id = NULL; + free(ptr); +} + +void free_im_configs(struct im_configs *conf) +{ + if (conf == NULL) { + return; + } + free(conf->rootpath); + conf->rootpath = NULL; + free(conf->server_sock); + conf->server_sock = NULL; + free(conf); +} + +static int bims_init(const struct im_configs *conf) { int ret = 0; size_t i; for (i = 0; i < g_numbims; i++) { - ret = g_bims[i].ops->init(rootpath); + ret = g_bims[i].ops->init(conf); if (ret != 0) { ERROR("Failed to init bim %s", g_bims[i].image_type); break; @@ -1122,7 +1634,31 @@ static int bims_init(const char *rootpath) int image_module_init(const char *rootpath) { - return bims_init(rootpath); + struct im_configs *conf; + int ret = -1; + + conf = (struct im_configs *)util_common_calloc_s(sizeof(struct im_configs)); + if (conf == NULL) { + ERROR("Out of memory"); + return ret; + } + conf->rootpath = util_strdup_s(rootpath); + ret = bims_init(conf); + + free_im_configs(conf); + return ret; +} + +void image_module_exit() +{ + size_t i; + + for (i = 0; i < g_numbims; i++) { + if (g_bims[i].ops->clean_resource == NULL) { + continue; + } + g_bims[i].ops->clean_resource(); + } } int map_to_key_value_string(const json_map_string_string *map, char ***array, size_t *array_len) @@ -1171,3 +1707,60 @@ cleanup: return -1; } +void free_im_status_request(im_status_request *req) +{ + if (req == NULL) { + return; + } + free(req->image.image); + req->image.image = NULL; + + free(req); +} + +void free_im_status_response(im_status_response *req) +{ + if (req == NULL) { + return; + } + free_imagetool_image_status(req->image_info); + req->image_info = NULL; + free(req->errmsg); + req->errmsg = NULL; + + free(req); +} + +void free_im_fs_info_response(im_fs_info_response *ptr) +{ + if (ptr == NULL) { + return; + } + free_imagetool_fs_info(ptr->fs_info); + ptr->fs_info = NULL; + free(ptr->errmsg); + ptr->errmsg = NULL; + + free(ptr); +} + +void free_im_storage_status_response(im_storage_status_response *ptr) +{ + if (ptr == NULL) { + return; + } + free(ptr->backing_fs); + ptr->backing_fs = NULL; + free(ptr); +} + +void im_sync_containers_isuladkit(void) +{ + DEBUG("Sync containers..."); +#ifdef ENABLE_OCI_IMAGE + if (isula_sync_containers() != 0) { + WARN("Sync containers with remote failed!!"); + } +#endif +} + diff --git a/src/image/image.h b/src/image/image.h index 79d11c6..05d0ed9 100644 --- a/src/image/image.h +++ b/src/image/image.h @@ -31,6 +31,7 @@ #include "imagetool_images_list.h" #include "imagetool_fs_info.h" +#include "imagetool_image_status.h" #ifdef __cplusplus extern "C" { @@ -52,9 +53,33 @@ typedef struct { } image_filter; #endif +typedef struct { + char *backing_fs; + bool supports_d_type; + bool native_overlay_diff; +} im_storage_status_response; + +typedef struct { + imagetool_fs_info *fs_info; + char *errmsg; +} im_fs_info_response; + +typedef struct { + // Spec of the image. + image_spec image; + // Verbose indicates whether to return extra information about the image. + bool verbose; +} im_status_request; + +typedef struct { + imagetool_image_status *image_info; + char *errmsg; +} im_status_response; + typedef struct { image_filter filter; bool check; + struct filters_args *image_filters; } im_list_request; typedef struct { @@ -131,51 +156,103 @@ typedef struct { char *errmsg; } im_logout_response; -struct bim; +typedef struct { + char *type; +} im_image_count_request; +typedef struct { + char *type; + char *file; + char *name_id; +} im_export_request; + +typedef struct { + char *name_id; + bool force; +} im_umount_request; + +typedef struct { + char *name_id; +} im_mount_request; + +typedef struct { + char *name_id; +} im_delete_request; + +typedef struct { + char *image_name; + char *container_id; + char *ext_config_image; + json_map_string_string *storage_opt; +} im_prepare_request; + +typedef struct { + char *name_id; +} im_container_fs_usage_request; + +/* configs of image driver */ +struct im_configs { + char *rootpath; + char *server_sock; +}; struct bim_ops { - int (*init)(const char *rootpath); + int (*init)(const struct im_configs *conf); + void (*clean_resource)(void); + /* detect whether image is of this bim type */ bool (*detect)(const char *image_name); - /* rootfs ops*/ - int (*prepare_rf)(struct bim *bim, const json_map_string_string *storage_opt, char **real_rootfs); - int (*mount_rf)(struct bim *bim); - int (*umount_rf)(struct bim *bim); - int (*delete_rf)(struct bim *bim); + /* rootfs ops */ + int (*prepare_rf)(const im_prepare_request *request, char **real_rootfs); + int (*mount_rf)(const im_mount_request *request); + int (*umount_rf)(const im_umount_request *request); + int (*delete_rf)(const im_delete_request *request); + int (*export_rf)(const im_export_request *request); char *(*resolve_image_name)(const char *image_name); - /* merge image config ops*/ + /* merge image config ops */ int (*merge_conf)(oci_runtime_spec *oci_spec, const host_config *host_spec, container_custom_config *custom_spec, - struct bim *bim, char **real_rootfs); + const im_prepare_request *request, char **real_rootfs); /* get user config ops */ int (*get_user_conf)(const char *basefs, host_config *hc, const char *userstr, oci_runtime_spec_process_user *puser); /* list images */ - int (*list_ims)(im_list_request *request, imagetool_images_list **images); + int (*list_ims)(const im_list_request *request, imagetool_images_list **images); + + /* get count of images */ + size_t (*get_image_count)(void); /* remove image */ - int (*rm_image)(im_remove_request *request); + int (*rm_image)(const im_remove_request *request); /* inspect image */ - int (*inspect_image)(struct bim *bim, char **inpected_json); + int (*inspect_image)(const im_inspect_request *request, char **inpected_json); - int (*filesystem_usage)(struct bim *bim, imagetool_fs_info **fs_usage); + int (*container_fs_usage)(const im_container_fs_usage_request *request, imagetool_fs_info **fs_usage); + + int (*image_status)(im_status_request *request, im_status_response **response); + + int (*get_filesystem_info)(im_fs_info_response **response); + + int (*get_storage_status)(im_storage_status_response **response); /* load image */ - int (*load_image)(im_load_request *request); + int (*load_image)(const im_load_request *request); /* pull image */ int (*pull_image)(const im_pull_request *request, im_pull_response **response); /* login */ - int (*login)(im_login_request *request); + int (*login)(const im_login_request *request); /* logout */ - int (*logout)(im_logout_request *request); + int (*logout)(const im_logout_request *request); + + /* health check */ + int (*health_check)(void); }; struct bim { @@ -195,12 +272,23 @@ struct bim_type { int image_module_init(const char *rootpath); +void image_module_exit(); + int im_get_container_filesystem_usage(const char *image_type, const char *id, imagetool_fs_info **fs_usage); +void free_im_container_fs_usage_request(im_container_fs_usage_request *request); + +void free_im_prepare_request(im_prepare_request *request); + +void free_im_mount_request(im_mount_request *request); + +void free_im_umount_request(im_umount_request *request); + +void free_im_delete_request(im_delete_request *request); + int im_mount_container_rootfs(const char *image_type, const char *image_name, const char *container_id); -int im_umount_container_rootfs(const char *image_type, const char *image_name, - const char *container_id); +int im_umount_container_rootfs(const char *image_type, const char *image_name, const char *container_id); int im_remove_container_rootfs(const char *image_type, const char *container_id); @@ -211,13 +299,13 @@ int im_merge_image_config(const char *id, const char *image_type, const char *im int im_get_user_conf(const char *image_type, const char *basefs, host_config *hc, const char *userstr, oci_runtime_spec_process_user *puser); -int im_list_images(im_list_request *request, im_list_response **response); +int im_list_images(const im_list_request *request, im_list_response **response); void free_im_list_request(im_list_request *ptr); void free_im_list_response(im_list_response *ptr); -int im_rm_image(im_remove_request *request, im_remove_response **response); +int im_rm_image(const im_remove_request *request, im_remove_response **response); void free_im_remove_request(im_remove_request *ptr); @@ -231,7 +319,7 @@ void free_im_inspect_response(im_inspect_response *ptr); int map_to_key_value_string(const json_map_string_string *map, char ***array, size_t *array_len); -int im_load_image(im_load_request *request, im_load_response **response); +int im_load_image(const im_load_request *request, im_load_response **response); void free_im_load_request(im_load_request *ptr); @@ -247,21 +335,51 @@ char *im_get_image_type(const char *image, const char *external_rootfs); bool im_config_image_exist(const char *image_name); -int im_login(im_login_request *request, im_login_response **response); +int im_login(const im_login_request *request, im_login_response **response); void free_im_login_request(im_login_request *ptr); void free_im_login_response(im_login_response *ptr); -int im_logout(im_logout_request *request, im_logout_response **response); +int im_logout(const im_logout_request *request, im_logout_response **response); void free_im_logout_request(im_logout_request *ptr); void free_im_logout_response(im_logout_response *ptr); +void free_im_configs(struct im_configs *conf); + +int im_image_status(im_status_request *request, im_status_response **response); + +void free_im_status_request(im_status_request *req); + +void free_im_status_response(im_status_response *resp); + +int im_get_filesystem_info(const char *image_type, im_fs_info_response **response); + +void free_im_fs_info_response(im_fs_info_response *ptr); + +int im_get_storage_status(const char *image_type, im_storage_status_response **response); + +void free_im_storage_status_response(im_storage_status_response *ptr); + +size_t im_get_image_count(const im_image_count_request *request); + +void free_im_image_count_request(im_image_count_request *ptr); + +int im_container_export(const im_export_request *request); + +void free_im_export_request(im_export_request *ptr); + +int im_resolv_image_name(const char *image_type, const char *image_name, char **resolved_name); + +int im_health_check(const char *image_type); + +void im_sync_containers_isuladkit(void); #ifdef __cplusplus } #endif #endif + diff --git a/src/image/oci/CMakeLists.txt b/src/image/oci/CMakeLists.txt index 8006f3b..5dc1a36 100644 --- a/src/image/oci/CMakeLists.txt +++ b/src/image/oci/CMakeLists.txt @@ -8,5 +8,6 @@ set(OCI_SRCS set(OCI_INCS ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/remote PARENT_SCOPE ) diff --git a/src/image/oci/global_config.c b/src/image/oci/global_config.c new file mode 100644 index 0000000..ad18bff --- /dev/null +++ b/src/image/oci/global_config.c @@ -0,0 +1,264 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-16 +* Description: provide isula image operator definition +*******************************************************************************/ +#include "global_config.h" + +#include + +#include "lcrd_config.h" +#include "securec.h" +#include "log.h" +#ifdef ENABLE_OCI_IMAGE +#include "driver.h" + +static int pack_global_graph_driver(const char * const *options, bool ignore_storage_opt_size, char *params[], + size_t *count) +{ + int ret = -1; + char *graph_driver = NULL; + struct graphdriver *driver = NULL; + char **graph_opts = NULL; + char **p = NULL; + size_t i = 0; + + i = *count; + + graph_driver = conf_get_lcrd_storage_driver(); + if (graph_driver == NULL) { + COMMAND_ERROR("Failed to get graph driver"); + goto out; + } + driver = graphdriver_get(graph_driver); + if (strcmp(graph_driver, "overlay2") == 0) { + // Treating overlay2 as overlay cause image was downloaded always + // in '/var/lib/lcrd/storage/overlay' directory. + // See iSulad-kit/vendor/github.com/containers/storage/drivers/overlay/overlay.go, + // Driver is inited by name "overlay". + graph_driver[strlen(graph_driver) - 1] = '\0'; + } + add_array_kv(params, PARAM_NUM, &i, options[GB_OPTION_DRIVER_NAME], graph_driver); + + graph_opts = conf_get_storage_opts(); + // since iSulad-kit will set quota when pull image, which is differ from docker, + // and we may get some error if setted, ignore it if neccessary. + for (p = graph_opts; (p != NULL) && (*p != NULL); p++) { + if (ignore_storage_opt_size && driver != NULL && driver->ops->is_quota_options(driver, *p)) { + continue; + } + add_array_kv(params, PARAM_NUM, &i, options[GB_OPTION_DRIVER_OPTIONS], *p); + } + + ret = 0; + *count = i; +out: + free(graph_driver); + util_free_array(graph_opts); + return ret; +} +#endif + +static int pack_global_graph_root(const char * const *options, char *params[], size_t *count) +{ + int ret = -1; + char *graph_root = NULL; + size_t i = 0; + + i = *count; + + graph_root = conf_get_graph_rootpath(); + if (graph_root == NULL) { + COMMAND_ERROR("Failed to get graph root directory"); + goto out; + } + add_array_kv(params, PARAM_NUM, &i, options[GB_OPTION_GRAPH_ROOT], graph_root); + + ret = 0; + *count = i; +out: + free(graph_root); + return ret; +} + +static int pack_global_graph_run(const char * const *options, char *params[], size_t *count) +{ + int ret = -1; + char *graph_run = NULL; + size_t i = 0; + + i = *count; + + graph_run = conf_get_graph_run_path(); + if (graph_run == NULL) { + COMMAND_ERROR("Failed to get graph run directory"); + goto out; + } + add_array_kv(params, PARAM_NUM, &i, options[GB_OPTION_RUN_ROOT], graph_run); + + ret = 0; + *count = i; +out: + free(graph_run); + return ret; +} + +static char *adapt_log_level() +{ +#define LOG_LEVEL_MAX 5 + const char * const log_level_name[] = { + "FATAL", "ERROR", "WARN", "INFO", "DEBUG" + }; + int i; + char *isulad_level = NULL; + char *adapted_level = NULL; + + isulad_level = conf_get_lcrd_loglevel(); + if (isulad_level == NULL) { + goto out; + } + + for (i = 0; i < LOG_LEVEL_MAX; i++) { + if (strcasecmp(log_level_name[i], isulad_level) == 0) { + adapted_level = isulad_level; + isulad_level = NULL; + break; + } + } + +out: + if (adapted_level == NULL) { + adapted_level = util_strdup_s("INFO"); + } + free(isulad_level); + return adapted_level; +} + +static void pack_global_log_level(const char * const *options, char *params[], size_t *count) +{ + char *level = NULL; + size_t i = 0; + + i = *count; + + level = adapt_log_level(); + add_array_kv(params, PARAM_NUM, &i, options[GB_OPTION_LOG_LEVEL], level); + + *count = i; + + free(level); +} + +static int pack_global_graph_registry(const char * const *options, char *params[], size_t *count) +{ + int ret = -1; + size_t i = 0; + char **registry = NULL; + char **insecure_registry = NULL; + char **p = NULL; + + i = *count; + + registry = conf_get_registry_list(); + for (p = registry; (p != NULL) && (*p != NULL); p++) { + add_array_kv(params, PARAM_NUM, &i, options[GB_OPTION_REGISTRY], *p); + } + + insecure_registry = conf_get_insecure_registry_list(); + for (p = insecure_registry; (p != NULL) && (*p != NULL); p++) { + add_array_kv(params, PARAM_NUM, &i, options[GB_OPTION_INSEC_REGISTRY], *p); + } + + ret = 0; + *count = i; + + util_free_array(registry); + util_free_array(insecure_registry); + return ret; +} + +static int pack_global_opt_time(const char * const *options, char *params[], size_t *count) +{ + int ret = -1; + size_t i = 0; + unsigned int opt_timeout = 0; + char timeout_str[UINT_LEN + 2] = { 0 }; /* format: XXXs */ + + i = *count; + + opt_timeout = conf_get_im_opt_timeout(); + if (opt_timeout != 0) { + add_array_elem(params, PARAM_NUM, &i, options[GB_OPTION_OPT_TIMEOUT]); + if (sprintf_s(timeout_str, UINT_LEN, "%us", opt_timeout) < 0) { + COMMAND_ERROR("Failed to print string"); + goto out; + } + add_array_elem(params, PARAM_NUM, &i, timeout_str); + } + + ret = 0; + *count = i; +out: + return ret; +} + +static inline bool invalid_pack_global_options_args(const char * const *options, char * const *params, + const size_t *count) +{ + if (options == NULL || params == NULL || count == NULL) { + return true; + } + return false; +} + +int pack_global_options(const char * const *options, char *params[], size_t *count, bool ignore_storage_opt_size) +{ + int ret = -1; + size_t i = 0; + + if (invalid_pack_global_options_args(options, params, count)) { + ERROR("Invalid global options arguments"); + return -1; + } + + i = *count; + + if (pack_global_graph_root(options, params, &i) != 0) { + goto out; + } + + if (pack_global_graph_run(options, params, &i) != 0) { + goto out; + } + +#ifdef ENABLE_OCI_IMAGE + if (pack_global_graph_driver(options, ignore_storage_opt_size, params, &i) != 0) { + goto out; + } +#endif + + if (pack_global_graph_registry(options, params, &i) != 0) { + goto out; + } + + if (pack_global_opt_time(options, params, &i) != 0) { + goto out; + } + + pack_global_log_level(options, params, &i); + + ret = 0; + *count = i; + +out: + return ret; +} diff --git a/src/image/oci/global_config.h b/src/image/oci/global_config.h new file mode 100644 index 0000000..50b64a1 --- /dev/null +++ b/src/image/oci/global_config.h @@ -0,0 +1,65 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-16 +* Description: provide isula image operator definition +*******************************************************************************/ +#ifndef __IMAGE_GLOBAL_CONFIG_H +#define __IMAGE_GLOBAL_CONFIG_H + +#include "utils.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PARAM_NUM 100 + +enum { + GB_OPTION_GRAPH_ROOT = 0, + GB_OPTION_RUN_ROOT, + GB_OPTION_DRIVER_NAME, + GB_OPTION_DRIVER_OPTIONS, + GB_OPTION_STORAGE_OPTIONS, + GB_OPTION_REGISTRY, + GB_OPTION_INSEC_REGISTRY, + GB_OPTION_OPT_TIMEOUT, + GB_OPTION_LOG_LEVEL, + GB_OPTION_GRPC_SERVER_ADDR, // image server socket addr + GB_OPTION_MAX, // should not be used +}; + + +static inline void add_array_elem(char **array, size_t total, size_t *pos, const char *elem) +{ + if (*pos + 1 >= total - 1) { + return; + } + array[*pos] = util_strdup_s(elem); + *pos += 1; +} + +static inline void add_array_kv(char **array, size_t total, size_t *pos, const char *k, const char *v) +{ + if (k == NULL || v == NULL) { + return; + } + add_array_elem(array, total, pos, k); + add_array_elem(array, total, pos, v); +} + +int pack_global_options(const char * const *options, char *params[], size_t *count, bool ignore_storage_opt_size); + +#ifdef __cplusplus +} +#endif + +#endif /* __IMAGE_GLOBAL_CONFIG_H */ diff --git a/src/image/oci/isula_container_export.c b/src/image/oci/isula_container_export.c new file mode 100644 index 0000000..c81b346 --- /dev/null +++ b/src/image/oci/isula_container_export.c @@ -0,0 +1,108 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula container export operator implement +*******************************************************************************/ +#include "isula_container_export.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "liblcrd.h" +#include "log.h" + +static struct isula_export_request *generate_isula_export_request(const char *name_id, const char *out_file, + uint32_t uid, uint32_t gid, + uint32_t offset) +{ + struct isula_export_request *ret = NULL; + + ret = (struct isula_export_request *)util_common_calloc_s(sizeof(struct isula_export_request)); + if (ret == NULL) { + ERROR("Out of memory"); + return ret; + } + ret->name_id = util_strdup_s(name_id); + ret->output = util_strdup_s(out_file); + ret->uid = uid; + ret->gid = gid; + ret->offset = offset; + + return ret; +} + +static int is_valid_arguments(const char *name_id, const char *out_file) +{ + if (name_id == NULL) { + lcrd_set_error_message("Export rootfs requires container name"); + return -1; + } + if (out_file == NULL) { + lcrd_set_error_message("Export rootfs requires output file path"); + return -1; + } + return 0; +} + +int isula_container_export(const char *name_id, const char *out_file, uint32_t uid, uint32_t gid, uint32_t offset) +{ + int ret = -1; + struct isula_export_request *ireq = NULL; + struct isula_export_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops = NULL; + + if (is_valid_arguments(name_id, out_file) != 0) { + ERROR("Invalid arguments"); + return -1; + } + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + + if (im_ops->container_export == NULL) { + ERROR("Umimplement container_export operator"); + return -1; + } + + ireq = generate_isula_export_request(name_id, out_file, uid, gid, offset); + if (ireq == NULL) { + goto out; + } + + iresp = (struct isula_export_response *)util_common_calloc_s(sizeof(struct isula_export_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto out; + } + + ret = im_ops->container_export(ireq, iresp, &conf); + if (ret != 0) { + ERROR("Failed to export rootfs : %s", iresp->errmsg); + lcrd_set_error_message("Failed to export rootfs with error: %s", iresp->errmsg); + } + +out: + free_isula_export_request(ireq); + free_isula_export_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/isula_container_export.h b/src/image/oci/isula_container_export.h new file mode 100644 index 0000000..f4f9eed --- /dev/null +++ b/src/image/oci/isula_container_export.h @@ -0,0 +1,30 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula container export operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_CONTAINER_EXPORT_H +#define __IMAGE_ISULA_CONTAINER_EXPORT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_container_export(const char *name_id, const char *out_file, uint32_t uid, uint32_t gid, uint32_t offset); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_container_fs_usage.c b/src/image/oci/isula_container_fs_usage.c new file mode 100644 index 0000000..2b3da73 --- /dev/null +++ b/src/image/oci/isula_container_fs_usage.c @@ -0,0 +1,108 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula container fs usage operator implement +*******************************************************************************/ +#include "isula_container_fs_usage.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "liblcrd.h" +#include "log.h" + +static int generate_isula_container_fs_usage_request(const char *name_id, + struct isula_container_fs_usage_request **ireq) +{ + struct isula_container_fs_usage_request *tmp_req = NULL; + + tmp_req = (struct isula_container_fs_usage_request *)util_common_calloc_s( + sizeof(struct isula_container_fs_usage_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + tmp_req->name_id = util_strdup_s(name_id); + + *ireq = tmp_req; + return 0; +} + +static int is_valid_arguments(const char *name_id, char **usages) +{ + if (usages == NULL) { + ERROR("Invalid arguments"); + return -1; + } + if (name_id == NULL) { + ERROR("Invalid container id or name"); + return -1; + } + return 0; +} + +int isula_container_fs_usage(const char *name_id, char **usages) +{ + int ret = -1; + struct isula_container_fs_usage_request *ireq = NULL; + struct isula_container_fs_usage_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops = NULL; + + if (is_valid_arguments(name_id, usages) != 0) { + return -1; + } + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + + if (im_ops->container_fs_usage == NULL) { + ERROR("Umimplement container fs usage operator"); + return -1; + } + + ret = generate_isula_container_fs_usage_request(name_id, &ireq); + if (ret != 0) { + goto out; + } + + iresp = (struct isula_container_fs_usage_response *)util_common_calloc_s(sizeof(struct + isula_container_fs_usage_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto out; + } + + ret = im_ops->container_fs_usage(ireq, iresp, &conf); + if (ret != 0) { + ERROR("Get container %s fs usage failed: %s", name_id, iresp->errmsg); + lcrd_set_error_message("Failed to container fs info with error: %s", iresp->errmsg); + goto out; + } + *usages = iresp->usage; + iresp->usage = NULL; + +out: + free_isula_container_fs_usage_request(ireq); + free_isula_container_fs_usage_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/isula_container_fs_usage.h b/src/image/oci/isula_container_fs_usage.h new file mode 100644 index 0000000..dcf2294 --- /dev/null +++ b/src/image/oci/isula_container_fs_usage.h @@ -0,0 +1,28 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula container fs usage operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_CONTAINER_FS_USAGE_H +#define __IMAGE_ISULA_CONTAINER_FS_USAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_container_fs_usage(const char *name_id, char **usages); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_containers_list.c b/src/image/oci/isula_containers_list.c new file mode 100644 index 0000000..d056537 --- /dev/null +++ b/src/image/oci/isula_containers_list.c @@ -0,0 +1,70 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-09-05 +* Description: isula containers list operator implement +*******************************************************************************/ +#include "isula_containers_list.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "log.h" + +int isula_list_containers(json_map_string_bool **containers) +{ + struct isula_containers_list_request ireq = { 0 }; + struct isula_containers_list_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops = NULL; + int ret = -1; + + if (containers == NULL) { + return ret; + } + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return ret; + } + if (im_ops->containers_list == NULL) { + ERROR("Umimplement containers list operator"); + return ret; + } + + iresp = (struct isula_containers_list_response *)util_common_calloc_s( + sizeof(struct isula_containers_list_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + ret = -1; + goto out; + } + + ret = im_ops->containers_list(&ireq, iresp, &conf); + if (ret != 0) { + ERROR("List containers failed: %s", iresp != NULL ? iresp->errmsg : "null"); + goto out; + } + + *containers = iresp->containers; + iresp->containers = NULL; +out: + free_isula_containers_list_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/oci_container_fs_usage.h b/src/image/oci/isula_containers_list.h similarity index 61% rename from src/image/oci/oci_container_fs_usage.h rename to src/image/oci/isula_containers_list.h index f2f2168..56fd65a 100644 --- a/src/image/oci/oci_container_fs_usage.h +++ b/src/image/oci/isula_containers_list.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -8,27 +8,23 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci image fs functions - ******************************************************************************/ +* Author: liuhao +* Create: 2019-09-5 +* Description: isula containers list operator implement +*******************************************************************************/ +#ifndef __OCI_REMOTE_CONTAINERS_LIST_H +#define __OCI_REMOTE_CONTAINERS_LIST_H -#ifndef __OCI_FS_INFO_H_ -#define __OCI_FS_INFO_H_ - -#include "oci_image_type.h" -#include "imagetool_fs_info.h" +#include "json_common.h" #ifdef __cplusplus extern "C" { #endif -bool do_oci_container_fs_info(char *id, imagetool_fs_info **fs_info); - +int isula_list_containers(json_map_string_bool **containers); #ifdef __cplusplus } #endif #endif - diff --git a/src/image/oci/isula_health_check.c b/src/image/oci/isula_health_check.c new file mode 100644 index 0000000..ffc6de2 --- /dev/null +++ b/src/image/oci/isula_health_check.c @@ -0,0 +1,64 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula health check operator implement +*******************************************************************************/ +#include "isula_health_check.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "log.h" + +int isula_do_health_check() +{ +#define HEALTH_CHECK_TIMEOUT 3 + int ret = -1; + struct isula_health_check_request ireq = {0}; + struct isula_health_check_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops = NULL; + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->health_check == NULL) { + ERROR("Umimplement health check operator"); + return -1; + } + + iresp = (struct isula_health_check_response *)util_common_calloc_s(sizeof(struct isula_health_check_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto out; + } + // update deadline for health check to 3s + conf.deadline = HEALTH_CHECK_TIMEOUT; + + ret = im_ops->health_check(&ireq, iresp, &conf); + if (ret != 0) { + WARN("Health check failed: %s", iresp->errmsg); + } + +out: + free_isula_health_check_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/isula_health_check.h b/src/image/oci/isula_health_check.h new file mode 100644 index 0000000..1892f48 --- /dev/null +++ b/src/image/oci/isula_health_check.h @@ -0,0 +1,29 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula health check operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_HEALTH_CHECK_H +#define __IMAGE_ISULA_HEALTH_CHECK_H + + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_do_health_check(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_helper.c b/src/image/oci/isula_helper.c new file mode 100644 index 0000000..581385a --- /dev/null +++ b/src/image/oci/isula_helper.c @@ -0,0 +1,55 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: helper functions for isula image +*******************************************************************************/ +#include "isula_helper.h" + +#include "utils.h" +#include "log.h" +#include "lcrd_config.h" + +int get_isula_image_connect_config(client_connect_config_t *conf) +{ + char *sock_addr = NULL; + + if (conf == NULL) { + return -1; + } + + sock_addr = conf_get_im_server_sock_addr(); + if (sock_addr == NULL) { + ERROR("Get image server sockot address failed"); + return -1; + } + + conf->socket = sock_addr; + + conf->deadline = conf_get_im_opt_timeout(); + + return 0; +} + +void free_client_connect_config_value(client_connect_config_t *conf) +{ + if (conf == NULL) { + return; + } + free(conf->socket); + conf->socket = NULL; + free_sensitive_string(conf->ca_file); + conf->ca_file = NULL; + free_sensitive_string(conf->cert_file); + conf->cert_file = NULL; + free_sensitive_string(conf->key_file); + conf->key_file = NULL; +} diff --git a/src/image/oci/isula_helper.h b/src/image/oci/isula_helper.h new file mode 100644 index 0000000..7edde9a --- /dev/null +++ b/src/image/oci/isula_helper.h @@ -0,0 +1,32 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: helper functions for isula image +*******************************************************************************/ +#ifndef __IMAGE_ISULA_HELPER_H +#define __IMAGE_ISULA_HELPER_H + +#include "connect.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int get_isula_image_connect_config(client_connect_config_t *conf); + +void free_client_connect_config_value(client_connect_config_t *conf); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_image.c b/src/image/oci/isula_image.c new file mode 100644 index 0000000..fa902af --- /dev/null +++ b/src/image/oci/isula_image.c @@ -0,0 +1,534 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: provide isula image operator definition +*******************************************************************************/ +#include "isula_image.h" + +#include +#include + +#include "log.h" +#include "run_image_server.h" +#include "isula_image_connect.h" +#include "isula_image_pull.h" +#include "isula_rootfs_prepare.h" +#include "isula_rootfs_remove.h" +#include "isula_rootfs_mount.h" +#include "isula_rootfs_umount.h" +#include "isula_image_rmi.h" +#include "isula_container_fs_usage.h" +#include "isula_image_fs_info.h" +#include "isula_storage_status.h" +#include "isula_image_load.h" +#include "isula_container_export.h" +#include "isula_login.h" +#include "isula_logout.h" +#include "isula_health_check.h" +#include "isula_images_list.h" +#include "isula_containers_list.h" + +#include "containers_store.h" +#include "oci_images_store.h" + +#include "lcrd_config.h" +#include "utils.h" + +#define IMAGE_NOT_KNOWN_ERR "image not known" +#define ISULA_IMAGE_SERVER_DEFAULT_SOCK "/var/run/isula_image.sock" + +pthread_t g_monitor_thread; + +void isula_exit(void) +{ + int nret; + + isula_kit_exit(); + nret = pthread_cancel(g_monitor_thread); + if (nret != 0) { + SYSERROR("Cancel isula monitor thread failed"); + } +} + +static int start_isula_image_server(void) +{ + struct server_monitor_conf sm_conf = {0}; + struct timespec ts = { 0 }; + sem_t wait_monitor_sem; + int ret = 0; + + // check whether isula_kit is running by systemd + if (util_file_exists(ISULA_IMAGE_SERVER_DEFAULT_SOCK)) { + if (!conf_update_im_server_sock_addr(ISULA_IMAGE_SERVER_DEFAULT_SOCK)) { + ERROR("Update image socket address failed"); + return -1; + } + return 0; + } + + if (sem_init(&wait_monitor_sem, 0, 0) != 0) { + ERROR("Semaphore init failed"); + ret = -1; + goto out; + } + sm_conf.wait_ok = &wait_monitor_sem; + + ret = pthread_create(&g_monitor_thread, NULL, isula_image_server_monitor, (void *)(&sm_conf)); + if (ret != 0) { + ERROR("Create isula image monitor thread failed: %s", strerror(ret)); + goto out; + } + + if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { + SYSERROR("Get real time failed"); + ret = -1; + goto out; + } + ts.tv_sec += 15; // set deadline 15s + + ret = sem_timedwait(&wait_monitor_sem, &ts); + if (ret != 0) { + SYSERROR("Image Server Start failed"); + goto out; + } + INFO("Image Server is Running..."); + +out: + sem_destroy(&wait_monitor_sem); + return ret; +} + +/* + * start isula image grpc server + * */ +int isula_init(const struct im_configs *conf) +{ + int ret = -1; + + if (conf == NULL) { + ERROR("Invalid image config"); + return ret; + } + + /* init grpc client */ + ret = isula_image_ops_init(); + if (ret != 0) { + ERROR("Init grpc client for isula image server failed"); + goto out; + } + + ret = start_isula_image_server(); + if (ret != 0) { + goto out; + } + + ret = oci_image_store_init(); +out: + return ret; +} + +int isula_pull_rf(const im_pull_request *request, im_pull_response **response) +{ + return isula_pull_image(request, response); +} + +int isula_prepare_rf(const im_prepare_request *request, char **real_rootfs) +{ + if (request == NULL) { + ERROR("Bim is NULL"); + return -1; + } + + return isula_rootfs_prepare_and_get_image_conf(request->container_id, request->image_name, request->storage_opt, + real_rootfs, NULL); +} + +int isula_merge_conf_rf(oci_runtime_spec *oci_spec, const host_config *host_spec, container_custom_config *custom_spec, + const im_prepare_request *request, char **real_rootfs) +{ + oci_image_spec *image = NULL; + int ret = -1; + + if (request == NULL) { + ERROR("Bim is NULL"); + return -1; + } + + ret = isula_rootfs_prepare_and_get_image_conf(request->container_id, request->image_name, host_spec->storage_opt, + real_rootfs, &image); + if (ret != 0) { + ERROR("Get prepare rootfs failed of image: %s", request->image_name); + goto out; + } + ret = oci_image_conf_merge_into_spec(request->image_name, oci_spec, custom_spec); + if (ret != 0) { + ERROR("Failed to merge oci config for image: %s", request->image_name); + goto out; + } + +out: + free_oci_image_spec(image); + return ret; +} + +int isula_delete_rf(const im_delete_request *request) +{ + if (request == NULL) { + ERROR("Request is NULL"); + return -1; + } + return isula_rootfs_remove(request->name_id); +} + +int isula_mount_rf(const im_mount_request *request) +{ + if (request == NULL) { + ERROR("Invalid arguments"); + return -1; + } + return isula_rootfs_mount(request->name_id); +} + +int isula_umount_rf(const im_umount_request *request) +{ + if (request == NULL) { + ERROR("Invalid arguments"); + return -1; + } + + return isula_rootfs_umount(request->name_id, request->force); +} + +int isula_rmi(const im_remove_request *request) +{ + int ret = -1; + char *real_image_name = NULL; + oci_image_t *image_info = NULL; + char *errmsg = NULL; + + if (request == NULL || request->image.image == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + real_image_name = oci_resolve_image_name(request->image.image); + if (real_image_name == NULL) { + ERROR("Failed to resolve image name"); + goto out; + } + image_info = oci_images_store_get(real_image_name); + if (image_info == NULL) { + INFO("No such image exist %s", real_image_name); + ret = 0; + goto out; + } + oci_image_lock(image_info); + + ret = isula_image_rmi(real_image_name, request->force, &errmsg); + if (ret != 0) { + if (strstr(errmsg, IMAGE_NOT_KNOWN_ERR) != NULL) { + DEBUG("Image %s may already removed", real_image_name); + ret = 0; + goto clean_memory; + } + lcrd_set_error_message("Failed to remove image with error: %s", errmsg); + ERROR("Failed to remove image '%s' with error: %s", real_image_name, errmsg); + goto unlock; + } + +clean_memory: + ret = remove_oci_image_from_memory(real_image_name); + if (ret != 0) { + ERROR("Failed to remove image %s from memory", real_image_name); + } +unlock: + oci_image_unlock(image_info); +out: + oci_image_unref(image_info); + free(real_image_name); + free(errmsg); + return ret; +} + +int isula_container_filesystem_usage(const im_container_fs_usage_request *request, imagetool_fs_info **fs_usage) +{ + int ret = 0; + char *output = NULL; + parser_error err = NULL; + + if (request == NULL || fs_usage == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + ret = isula_container_fs_usage(request->name_id, &output); + if (ret != 0) { + ERROR("Failed to inspect container filesystem info"); + goto out; + } + + *fs_usage = imagetool_fs_info_parse_data(output, NULL, &err); + if (*fs_usage == NULL) { + ERROR("Failed to parse output json: %s", err); + lcrd_set_error_message("Failed to parse output json:%s", err); + ret = -1; + } + +out: + free(output); + return ret; +} + +int isula_get_filesystem_info(im_fs_info_response **response) +{ + int ret = -1; + + if (response == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + *response = (im_fs_info_response *)util_common_calloc_s(sizeof(im_fs_info_response)); + if (*response == NULL) { + ERROR("Out of memory"); + return -1; + } + ret = isula_image_fs_info(*response); + if (ret != 0) { + ERROR("Failed to inspect image filesystem info"); + goto err_out; + } + + return 0; +err_out: + free_im_fs_info_response(*response); + *response = NULL; + return -1; +} + +int isula_get_storage_status(im_storage_status_response **response) +{ + int ret = -1; + + if (response == NULL) { + ERROR("Invalid input arguments"); + return ret; + } + + *response = (im_storage_status_response *)util_common_calloc_s(sizeof(im_storage_status_response)); + if (*response == NULL) { + ERROR("Out of memory"); + return ret; + } + + ret = isula_do_storage_status(*response); + if (ret != 0) { + ERROR("Get get storage status failed"); + ret = -1; + goto err_out; + } + + return 0; +err_out: + free_im_storage_status_response(*response); + *response = NULL; + return ret; +} + +int isual_load_image(const im_load_request *request) +{ + char **refs = NULL; + int ret = 0; + int ret2 = 0; + size_t i = 0; + + if (request == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + ret = isula_image_load(request->file, request->tag, &refs); + if (ret != 0) { + ERROR("Failed to load image"); + goto out; + } + +out: + // If some of images are loaded, registery it. + for (i = 0; i < util_array_len((const char **)refs); i++) { + ret2 = register_new_oci_image_into_memory(refs[i]); + if (ret2 != 0) { + ERROR("Failed to register new image %s to images store", refs[i]); + ret = -1; + break; + } + } + + util_free_array(refs); + refs = NULL; + return ret; +} + +int isula_export_rf(const im_export_request *request) +{ + int ret = 0; + + if (request == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + ret = isula_container_export(request->name_id, request->file, 0, 0, 0); + if (ret != 0) { + ERROR("Failed to export container: %s", request->name_id); + } + + return ret; +} + +int isula_login(const im_login_request *request) +{ + int ret = 0; + + if (request == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + ret = isula_do_login(request->server, request->username, request->password); + if (ret != 0) { + ERROR("Login failed"); + } + + return ret; +} + +int isula_logout(const im_logout_request *request) +{ + int ret = 0; + + if (request == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + ret = isula_do_logout(request->server); + if (ret != 0) { + ERROR("Logout failed"); + } + + return ret; +} + +int isula_health_check(void) +{ + return isula_do_health_check(); +} + +int isula_sync_images(void) +{ + int ret = 0; + size_t i = 0; + im_list_request *im_request = NULL; + imagetool_images_list *image_list = NULL; + oci_image_t *oci_image = NULL; + char *errmsg = NULL; + + im_request = (im_list_request *)util_common_calloc_s(sizeof(im_list_request)); + if (im_request == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + ret = isula_list_images(im_request, &image_list); + if (ret != 0) { + ERROR("Get remote images list failed"); + goto out; + } + + for (i = 0; i < image_list->images_len; i++) { + oci_image = oci_images_store_get((image_list->images[i])->id); + if (oci_image != NULL) { + continue; + } + WARN("Cleanup surplus image: %s in remote", (image_list->images[i])->id); + ret = isula_image_rmi((image_list->images[i])->id, true, &errmsg); + if (ret != 0) { + WARN("Remove image: %s failed: %s", (image_list->images[i])->id, errmsg); + } + free(errmsg); + errmsg = NULL; + oci_image_unref(oci_image); + } + + ret = 0; +out: + free_im_list_request(im_request); + free_imagetool_images_list(image_list); + return ret; +} + +static inline void cleanup_container_rootfs(const char *name_id, bool mounted) +{ + if (mounted && isula_rootfs_umount(name_id, true) != 0) { + WARN("Remove rootfs: %s failed", name_id); + } + + if (isula_rootfs_remove(name_id) != 0) { + WARN("Remove rootfs: %s failed", name_id); + } +} + +int isula_sync_containers(void) +{ + int ret = 0; + size_t i = 0; + json_map_string_bool *remote_containers_list = NULL; + container_t *cont = NULL; + + ret = isula_list_containers(&remote_containers_list); + if (ret != 0) { + ERROR("Get remote containers list failed"); + goto out; + } + + if (remote_containers_list == NULL) { + goto out; + } + + for (i = 0; i < remote_containers_list->len; i++) { + cont = containers_store_get(remote_containers_list->keys[i]); + // cannot found container in local map, then unmount and remove remote rootfs + if (cont == NULL) { + WARN("Cleanup surplus container: %s in remote", remote_containers_list->keys[i]); + cleanup_container_rootfs(remote_containers_list->keys[i], remote_containers_list->values[i]); + continue; + } + + // local container is stopped, but remote container is mounted. So unmount it. + if (!is_running(cont->state) && remote_containers_list->values[i]) { + WARN("Unmount unstarted container: %s", remote_containers_list->keys[i]); + ret = isula_rootfs_umount(remote_containers_list->keys[i], true); + if (ret != 0) { + WARN("Unmount rootfs: %s failed", remote_containers_list->keys[i]); + } + } + container_unref(cont); + } + + ret = 0; +out: + free_json_map_string_bool(remote_containers_list); + return ret; +} + diff --git a/src/image/oci/isula_image.h b/src/image/oci/isula_image.h new file mode 100644 index 0000000..c30b622 --- /dev/null +++ b/src/image/oci/isula_image.h @@ -0,0 +1,57 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: provide isula image operator definition +*******************************************************************************/ +#ifndef __IMAGE_ISULA_IMAGE_H +#define __IMAGE_ISULA_IMAGE_H + +#include "image.h" +#include "oci_image_spec.h" +#include "oci_common_operators.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_init(const struct im_configs *conf); +void isula_exit(void); + +int isula_pull_rf(const im_pull_request *request, im_pull_response **response); +int isula_rmi(const im_remove_request *request); +int isula_get_filesystem_info(im_fs_info_response **response); +int isual_load_image(const im_load_request *request); + +int isula_prepare_rf(const im_prepare_request *request, char **real_rootfs); +int isula_merge_conf_rf(oci_runtime_spec *oci_spec, const host_config *host_spec, container_custom_config *custom_spec, + const im_prepare_request *request, char **real_rootfs); +int isula_mount_rf(const im_mount_request *request); +int isula_umount_rf(const im_umount_request *request); +int isula_delete_rf(const im_delete_request *request); +int isula_export_rf(const im_export_request *request); +int isula_container_filesystem_usage(const im_container_fs_usage_request *request, imagetool_fs_info **fs_usage); + +int isula_get_storage_status(im_storage_status_response **response); + +int isula_login(const im_login_request *request); +int isula_logout(const im_logout_request *request); + +int isula_health_check(void); + +int isula_sync_images(void); + +int isula_sync_containers(void); +#ifdef __cplusplus +} +#endif + +#endif /* __IMAGE_ISULA_IMAGE_H */ diff --git a/src/image/oci/isula_image_fs_info.c b/src/image/oci/isula_image_fs_info.c new file mode 100644 index 0000000..f11182d --- /dev/null +++ b/src/image/oci/isula_image_fs_info.c @@ -0,0 +1,150 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image fs info operator implement +*******************************************************************************/ +#include "isula_image_fs_info.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "log.h" + +static int fs_usage_to_json_elem(const struct filesystem_usage *fusage, + imagetool_fs_info_image_filesystems_element **jelem) +{ + imagetool_fs_info_image_filesystems_element *tmp_elem = NULL; + + tmp_elem = (imagetool_fs_info_image_filesystems_element *)util_common_calloc_s( + sizeof(imagetool_fs_info_image_filesystems_element)); + if (tmp_elem == NULL) { + ERROR("Out of memory"); + return -1; + } + tmp_elem->timestamp = fusage->timestamp; + tmp_elem->fs_id = (imagetool_fs_info_image_filesystems_fs_id *)util_common_calloc_s( + sizeof(imagetool_fs_info_image_filesystems_fs_id)); + if (tmp_elem->fs_id == NULL) { + ERROR("Out of memory"); + goto err_out; + } + tmp_elem->fs_id->mountpoint = util_strdup_s(fusage->uuid); + + tmp_elem->used_bytes = (imagetool_fs_info_image_filesystems_used_bytes *)util_common_calloc_s( + sizeof(imagetool_fs_info_image_filesystems_used_bytes)); + if (tmp_elem->used_bytes == NULL) { + ERROR("Out of memory"); + goto err_out; + } + tmp_elem->used_bytes->value = *(fusage->used_bytes); + + tmp_elem->inodes_used = (imagetool_fs_info_image_filesystems_inodes_used *)util_common_calloc_s( + sizeof(imagetool_fs_info_image_filesystems_inodes_used)); + if (tmp_elem->inodes_used == NULL) { + ERROR("Out of memory"); + goto err_out; + } + tmp_elem->inodes_used->value = *(fusage->inodes_used); + + *jelem = tmp_elem; + return 0; +err_out: + free_imagetool_fs_info_image_filesystems_element(tmp_elem); + return -1; +} + +static int pack_im_response(const struct isula_image_fs_info_response *iresp, im_fs_info_response *resp) +{ + size_t i = 0; + imagetool_fs_info *info = NULL; + + if (iresp->image_filesystems_len == 0) { + return 0; + } + + info = (imagetool_fs_info *)util_common_calloc_s(sizeof(imagetool_fs_info)); + if (info == NULL) { + ERROR("Out of memory"); + return -1; + } + + info->image_filesystems = (imagetool_fs_info_image_filesystems_element **)util_smart_calloc_s( + sizeof(imagetool_fs_info_image_filesystems_element *), iresp->image_filesystems_len); + if (info->image_filesystems == NULL) { + ERROR("Out of memory"); + goto err_out; + } + + for (i = 0; i < iresp->image_filesystems_len; i++) { + if (fs_usage_to_json_elem(iresp->image_filesystems[i], &(info->image_filesystems[i])) != 0) { + goto err_out; + } + (info->image_filesystems_len)++; + } + + resp->fs_info = info; + resp->errmsg = util_strdup_s(iresp->errmsg); + return 0; + +err_out: + free_imagetool_fs_info(info); + return -1; +} + +int isula_image_fs_info(im_fs_info_response *resp) +{ + int ret = -1; + struct isula_image_fs_info_request ireq = {0}; + struct isula_image_fs_info_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops; + + if (resp == NULL) { + ERROR("Invalid arguments"); + return -1; + } + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->image_fs_info == NULL) { + ERROR("Umimplement image fs info operator"); + return -1; + } + + iresp = (struct isula_image_fs_info_response *)util_common_calloc_s(sizeof(struct isula_image_fs_info_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto out; + } + + ret = im_ops->image_fs_info(&ireq, iresp, &conf); + if (ret != 0) { + ERROR("Failed to get image fs info with error: %s", iresp->errmsg); + lcrd_set_error_message("Failed to get image fs info with error: %s", iresp->errmsg); + goto out; + } + ret = pack_im_response(iresp, resp); + +out: + free_isula_image_fs_info_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/oci_logout.h b/src/image/oci/isula_image_fs_info.h similarity index 65% rename from src/image/oci/oci_logout.h rename to src/image/oci/isula_image_fs_info.h index 1776909..32d7488 100644 --- a/src/image/oci/oci_logout.h +++ b/src/image/oci/isula_image_fs_info.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -8,21 +8,20 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v1 for more details. - * Author: wangfengtu - * Create: 2019-06-18 - * Description: provide logout function definition - ******************************************************************************/ -#ifndef __OCI_LOGOUT_H -#define __OCI_LOGOUT_H +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image fs info operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_IMAGE_FS_INFO_H +#define __IMAGE_ISULA_IMAGE_FS_INFO_H -#include #include "image.h" #ifdef __cplusplus extern "C" { #endif -int oci_logout(im_logout_request *request); +int isula_image_fs_info(im_fs_info_response *resp); #ifdef __cplusplus } diff --git a/src/image/oci/isula_image_load.c b/src/image/oci/isula_image_load.c new file mode 100644 index 0000000..c481df2 --- /dev/null +++ b/src/image/oci/isula_image_load.c @@ -0,0 +1,201 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image load operator implement +*******************************************************************************/ +#include "isula_image_load.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "liblcrd.h" +#include "utils_verify.h" +#include "log.h" + +const int g_output_max_size = 10 * SIZE_MB; /* 10M */ + +static char **get_refs(const char *output) +{ + char **refs = NULL; + char *ref = NULL; + char **lines = NULL; + size_t len = 0; + size_t size = 0; + char *key_word = "Loaded image: "; + int ret = -1; + size_t i = 0; + + lines = util_string_split(output, '\n'); + if (lines == NULL) { + return NULL; + } + + len = util_array_len((const char **)lines); + for (i = 0; i < len; i++) { + ref = strstr(lines[i], key_word); + if (ref == NULL || ref != lines[i]) { + continue; + } + + ref += strlen(key_word); + + /* +1 for terminator */ + size = strnlen(ref, (size_t)MAX_IMAGE_REF_LEN); + if (size == 0 || size > MAX_IMAGE_REF_LEN) { + ERROR("Invalid ref %s", ref); + ret = -1; + goto out; + } + ret = util_array_append(&refs, (const char *)ref); + if (ret != 0) { + ERROR("Append ref %s to array failed", ref); + goto out; + } + } + +out: + if (ret != 0) { + util_free_array(refs); + refs = NULL; + } + util_free_array(lines); + lines = NULL; + + return refs; +} + +static char **get_refs_from_output(const char *output) +{ + char *tmp_output = NULL; + char **refs = NULL; + + if (output == NULL) { + ERROR("Failed to load image because can not get output"); + lcrd_set_error_message("Failed to load image because can not get output"); + return NULL; + } + + if (strnlen(output, (size_t)(g_output_max_size + 1)) > (size_t)g_output_max_size) { + ERROR("Failed to load image because stdoutput exceeded max size"); + lcrd_set_error_message("Failed to load image because stdoutput exceeded max size"); + return NULL; + } + + /* get_refs_from_output will modify outmsg, get a copy to do this because + we want to print original output if get reference failed. */ + tmp_output = util_strdup_s(output); + refs = get_refs(tmp_output); + if (refs == NULL) { + ERROR("Failed to load image because cann't get image reference from output." + "stdout buffer is [%s]", output); + lcrd_set_error_message("Failed to load image because cann't get image reference from output"); + goto out; + } + +out: + free(tmp_output); + + return refs; +} + +static int generate_isula_load_request(const char *file, const char *tag, struct isula_load_request **ireq) +{ + struct isula_load_request *tmp_req = NULL; + + tmp_req = (struct isula_load_request *)util_common_calloc_s(sizeof(struct isula_load_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + tmp_req->file = util_strdup_s(file); + tmp_req->tag = util_strdup_s(tag); + + *ireq = tmp_req; + return 0; +} + +static int is_valid_arguments(const char *file, const char *tag, char ***refs) +{ + if (file == NULL) { + lcrd_set_error_message("Load image requires input file path"); + return -1; + } + if (tag != NULL && !util_valid_image_name(tag)) { + lcrd_try_set_error_message("Invalid tag:%s", tag); + return -1; + } + + if (refs == NULL) { + ERROR("Refs is null"); + return -1; + } + + return 0; +} + +int isula_image_load(const char *file, const char *tag, char ***refs) +{ + int ret = -1; + struct isula_load_request *ireq = NULL; + struct isula_load_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops = NULL; + + if (is_valid_arguments(file, tag, refs) != 0) { + return -1; + } + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->load == NULL) { + ERROR("Umimplement load operator"); + return -1; + } + + ret = generate_isula_load_request(file, tag, &ireq); + if (ret != 0) { + goto out; + } + + iresp = (struct isula_load_response *)util_common_calloc_s(sizeof(struct isula_load_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto out; + } + + ret = im_ops->load(ireq, iresp, &conf); + if (ret != 0) { + ERROR("Load image %s failed: %s", file, iresp->errmsg); + lcrd_set_error_message("Load image %s failed: %s", file, iresp->errmsg); + goto out; + } + *refs = get_refs_from_output(iresp->outmsg); + if (*refs == NULL) { + ret = -1; + goto out; + } + +out: + free_isula_load_request(ireq); + free_isula_load_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/isula_image_load.h b/src/image/oci/isula_image_load.h new file mode 100644 index 0000000..873511c --- /dev/null +++ b/src/image/oci/isula_image_load.h @@ -0,0 +1,28 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image load operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_IMAGE_LOAD_H +#define __IMAGE_ISULA_IMAGE_LOAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_image_load(const char *file, const char *tag, char ***ref); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_image_pull.c b/src/image/oci/isula_image_pull.c new file mode 100644 index 0000000..bc6e0ef --- /dev/null +++ b/src/image/oci/isula_image_pull.c @@ -0,0 +1,168 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image pull operator implement +*******************************************************************************/ +#include "isula_image_pull.h" + +#include "log.h" +#include "utils.h" +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "oci_images_store.h" + +static bool need_new_isula_auth(const im_pull_request *request) +{ + return ((request->username != NULL) || (request->password != NULL) || (request->auth != NULL) || + (request->server_address != NULL) || (request->identity_token != NULL) || + (request->registry_token != NULL)); +} + +static int generate_isula_auth_from_im_pull_request(const im_pull_request *request, struct isula_pull_request *ireq) +{ + if (!need_new_isula_auth(request)) { + return 0; + } + + ireq->auth = (struct isula_auth_config *)util_common_calloc_s(sizeof(struct isula_auth_config)); + if (ireq->auth == NULL) { + ERROR("Out of memory"); + return -1; + } + + ireq->auth->username = util_strdup_s(request->username); + ireq->auth->password = util_strdup_s(request->password); + ireq->auth->auth = util_strdup_s(request->auth); + ireq->auth->server_address = util_strdup_s(request->server_address); + ireq->auth->identity_token = util_strdup_s(request->identity_token); + ireq->auth->registry_token = util_strdup_s(request->registry_token); + + return 0; +} + +static int im_pull_request_to_isula_request(const im_pull_request *request, struct isula_pull_request **ireq) +{ + struct isula_pull_request *tmpreq = NULL; + int ret = -1; + + if (request == NULL || ireq == NULL) { + return -1; + } + tmpreq = (struct isula_pull_request *)util_common_calloc_s(sizeof(struct isula_pull_request)); + if (tmpreq == NULL) { + ERROR("Out of memory"); + return -1; + } + if (request->image != NULL) { + tmpreq->image = (struct image_spec *)util_common_calloc_s(sizeof(struct image_spec)); + if (tmpreq->image == NULL) { + ERROR("Out of memory"); + goto err_out; + } + tmpreq->image->image = util_strdup_s(request->image); + } + + ret = generate_isula_auth_from_im_pull_request(request, tmpreq); + if (ret != 0) { + goto err_out; + } + + *ireq = tmpreq; + return 0; +err_out: + free_isula_pull_request(tmpreq); + return -1; +} + +static int isula_pull_response_to_im(const struct isula_pull_response *iresp, im_pull_response **response) +{ + if (iresp == NULL) { + INFO("Get empty isula response"); + return 0; + } + *response = (im_pull_response *)util_common_calloc_s(sizeof(im_pull_response)); + if (*response == NULL) { + ERROR("Out of memory"); + return -1; + } + (*response)->errmsg = util_strdup_s(iresp->errmsg); + (*response)->image_ref = util_strdup_s(iresp->image_ref); + return 0; +} + +int isula_pull_image(const im_pull_request *request, im_pull_response **response) +{ + isula_image_ops *im_ops; + struct isula_pull_request *ireq = NULL; + struct isula_pull_response *iresp = NULL; + int ret = -1; + client_connect_config_t conf = { 0 }; + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->pull == NULL) { + ERROR("Umimplement pull operator"); + return -1; + } + + ret = im_pull_request_to_isula_request(request, &ireq); + if (ret != 0) { + ERROR("Parse im pull request failed"); + return -1; + } + + iresp = (struct isula_pull_response *)util_common_calloc_s(sizeof(struct isula_pull_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + ret = -1; + goto err_out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto err_out; + } + + INFO("Send pull image GRPC request"); + ret = im_ops->pull(ireq, iresp, &conf); + if (ret != 0) { + ERROR("Pull image failed: %s", iresp != NULL ? iresp->errmsg : "null"); + goto err_out; + } + + ret = isula_pull_response_to_im(iresp, response); + if (ret != 0) { + ERROR("Parse response failed"); + goto err_out; + } + + ret = register_new_oci_image_into_memory(request->image); + if (ret != 0) { + ERROR("Register image %s into store failed", request->image); + goto err_out; + } + + goto out; +err_out: + free_im_pull_response(*response); + *response = NULL; + ret = -1; +out: + free_client_connect_config_value(&conf); + free_isula_pull_request(ireq); + free_isula_pull_response(iresp); + return ret; +} diff --git a/src/image/oci/oci_login.h b/src/image/oci/isula_image_pull.h similarity index 64% rename from src/image/oci/oci_login.h rename to src/image/oci/isula_image_pull.h index 6fe6ed0..5f46ef7 100644 --- a/src/image/oci/oci_login.h +++ b/src/image/oci/isula_image_pull.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -8,24 +8,22 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v1 for more details. - * Author: wangfengtu - * Create: 2019-06-18 - * Description: provide login function definition - ******************************************************************************/ -#ifndef __OCI_LOGIN_H -#define __OCI_LOGIN_H +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image pull operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_PULL_H +#define __IMAGE_ISULA_PULL_H -#include #include "image.h" #ifdef __cplusplus extern "C" { #endif -int oci_login(im_login_request *request); +int isula_pull_image(const im_pull_request *request, im_pull_response **response); #ifdef __cplusplus } #endif - #endif diff --git a/src/image/oci/isula_image_rmi.c b/src/image/oci/isula_image_rmi.c new file mode 100644 index 0000000..c981a85 --- /dev/null +++ b/src/image/oci/isula_image_rmi.c @@ -0,0 +1,100 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image rootfs remove operator implement +*******************************************************************************/ +#include "isula_image_rmi.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "log.h" + +static int generate_isula_rmi_request(const char *image, bool force, struct isula_rmi_request **ireq) +{ + struct isula_rmi_request *tmp_req = NULL; + int ret = 0; + + if (image == NULL) { + ERROR("Required image name"); + return -1; + } + tmp_req = (struct isula_rmi_request *)util_common_calloc_s(sizeof(struct isula_rmi_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + + tmp_req->image = (struct image_spec *)util_common_calloc_s(sizeof(struct image_spec)); + if (tmp_req->image == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + tmp_req->image->image = util_strdup_s(image); + tmp_req->force = force; + +out: + *ireq = tmp_req; + return ret; +} + +int isula_image_rmi(const char *image, bool force, char **errmsg) +{ + int ret = -1; + struct isula_rmi_request *ireq = NULL; + struct isula_rmi_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops; + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->rmi == NULL) { + ERROR("Umimplement rmi operator"); + return -1; + } + + ret = generate_isula_rmi_request(image, force, &ireq); + if (ret != 0) { + goto out; + } + + iresp = (struct isula_rmi_response *)util_common_calloc_s(sizeof(struct isula_rmi_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto out; + } + + INFO("Send remove image GRPC request"); + ret = im_ops->rmi(ireq, iresp, &conf); + if (ret != 0) { + ERROR("Rmi image %s failed: %s", image, iresp->errmsg); + } + *errmsg = iresp->errmsg; + iresp->errmsg = NULL; + +out: + free_isula_rmi_request(ireq); + free_isula_rmi_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/isula_image_rmi.h b/src/image/oci/isula_image_rmi.h new file mode 100644 index 0000000..587e1c6 --- /dev/null +++ b/src/image/oci/isula_image_rmi.h @@ -0,0 +1,30 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image rootfs remove operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_IMAGE_RMI_H +#define __IMAGE_ISULA_IMAGE_RMI_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_image_rmi(const char *image, bool force, char **errmsg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_image_status.c b/src/image/oci/isula_image_status.c new file mode 100644 index 0000000..7e43189 --- /dev/null +++ b/src/image/oci/isula_image_status.c @@ -0,0 +1,156 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image status operator implement +*******************************************************************************/ +#include "isula_image_status.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "log.h" + +static int generate_isula_status_request(const char *image_name, struct isula_status_request **ireq) +{ + struct isula_status_request *tmp_req = NULL; + + if (image_name == NULL) { + ERROR("Image name is required"); + return -1; + } + tmp_req = (struct isula_status_request *)util_common_calloc_s(sizeof(struct isula_status_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + + tmp_req->image = (struct image_spec *)util_common_calloc_s(sizeof(struct image_spec)); + if (tmp_req->image == NULL) { + ERROR("Out of memory"); + goto err_out; + } + tmp_req->image->image = util_strdup_s(image_name); + + *ireq = tmp_req; + return 0; + +err_out: + free_isula_status_request(tmp_req); + return -1; +} + +static void pack_imagetool_image(struct image_metadata *data, imagetool_image **image) +{ + parser_error err = NULL; + imagetool_image *tmp_img = NULL; + + if (data == NULL) { + return; + } + tmp_img = (imagetool_image *)util_common_calloc_s(sizeof(imagetool_image)); + if (tmp_img == NULL) { + ERROR("Out of memory"); + return; + } + + tmp_img->uid = (imagetool_image_uid *)util_common_calloc_s(sizeof(imagetool_image_uid)); + if (tmp_img->uid == NULL) { + ERROR("Out of memory"); + goto err_out; + } + tmp_img->uid->value = data->uid; + data->uid = 0; + tmp_img->id = data->id; + data->id = NULL; + tmp_img->repo_tags = data->repo_tags; + data->repo_tags = NULL; + tmp_img->repo_tags_len = data->repo_tags_len; + data->repo_tags_len = 0; + tmp_img->repo_digests = data->repo_digests; + data->repo_digests = NULL; + tmp_img->repo_digests_len = data->repo_digests_len; + data->repo_digests_len = 0; + tmp_img->size = data->size; + data->size = 0; + tmp_img->username = data->username; + data->username = NULL; + + tmp_img->created = data->created; + data->created = NULL; + tmp_img->loaded = data->loaded; + data->loaded = NULL; + + // parse oci image spec + tmp_img->spec = oci_image_spec_parse_data(data->oci_spec, NULL, &err); + if (tmp_img->spec == NULL) { + ERROR("Parse oci image spec failed: %s", err); + goto err_out; + } + + free(err); + *image = tmp_img; + return; + +err_out: + free(err); + free_imagetool_image(tmp_img); +} + +imagetool_image *isula_image_get_image_info_by_name(const char *image_name) +{ + struct isula_status_request *ireq = NULL; + struct isula_status_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops; + imagetool_image *result = NULL; + int ret = -1; + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return NULL; + } + if (im_ops->status == NULL) { + ERROR("Umimplement status operator"); + return NULL; + } + + ret = generate_isula_status_request(image_name, &ireq); + if (ret != 0) { + goto out; + } + + iresp = (struct isula_status_response *)util_common_calloc_s(sizeof(struct isula_status_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto out; + } + + ret = im_ops->status(ireq, iresp, &conf); + if (ret != 0) { + ERROR("Get status of image %s failed: %s", image_name, iresp != NULL ? iresp->errmsg : "null"); + goto out; + } + + pack_imagetool_image(iresp->image, &result); +out: + free_isula_status_request(ireq); + free_isula_status_response(iresp); + free_client_connect_config_value(&conf); + return result; +} diff --git a/src/image/oci/isula_image_status.h b/src/image/oci/isula_image_status.h new file mode 100644 index 0000000..4c24f79 --- /dev/null +++ b/src/image/oci/isula_image_status.h @@ -0,0 +1,30 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image status operator implement +*******************************************************************************/ +#ifndef __OCI_REMOTE_ISULA_IMAGE_STATUS_H +#define __OCI_REMOTE_ISULA_IMAGE_STATUS_H + +#include "imagetool_image.h" + +#ifdef __cplusplus +extern "C" { +#endif + +imagetool_image *isula_image_get_image_info_by_name(const char *image_name); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_images_list.c b/src/image/oci/isula_images_list.c new file mode 100644 index 0000000..0a3d86b --- /dev/null +++ b/src/image/oci/isula_images_list.c @@ -0,0 +1,184 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula images list operator implement +*******************************************************************************/ +#include "isula_images_list.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "log.h" + +static int generate_isula_list_request(const im_list_request *req, struct isula_list_request **ireq) +{ + struct isula_list_request *tmp_req = NULL; + + if (req == NULL) { + return 0; + } + tmp_req = (struct isula_list_request *)util_common_calloc_s(sizeof(struct isula_list_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + + tmp_req->filter = util_strdup_s(req->filter.image.image); + tmp_req->check = req->check; + + *ireq = tmp_req; + return 0; +} + +/* user move to decrease memory allocate */ +static int pack_imagetool_image(struct image_metadata *data, imagetool_image **image) +{ + parser_error err = NULL; + imagetool_image *tmp_img = NULL; + + if (data == NULL) { + return -1; + } + tmp_img = (imagetool_image *)util_common_calloc_s(sizeof(imagetool_image)); + if (tmp_img == NULL) { + ERROR("Out of memory"); + return -1; + } + + tmp_img->uid = (imagetool_image_uid *)util_common_calloc_s(sizeof(imagetool_image_uid)); + if (tmp_img->uid == NULL) { + ERROR("Out of memory"); + goto err_out; + } + tmp_img->uid->value = data->uid; + data->uid = 0; + tmp_img->id = data->id; + data->id = NULL; + tmp_img->repo_tags = data->repo_tags; + data->repo_tags = NULL; + tmp_img->repo_tags_len = data->repo_tags_len; + data->repo_tags_len = 0; + tmp_img->repo_digests = data->repo_digests; + data->repo_digests = NULL; + tmp_img->repo_digests_len = data->repo_digests_len; + data->repo_digests_len = 0; + tmp_img->size = data->size; + data->size = 0; + tmp_img->username = data->username; + data->username = NULL; + + tmp_img->created = data->created; + data->created = NULL; + tmp_img->loaded = data->loaded; + data->loaded = NULL; + + // parse oci image spec + tmp_img->spec = oci_image_spec_parse_data(data->oci_spec, NULL, &err); + if (tmp_img->spec == NULL) { + ERROR("Parse oci image spec failed: %s", err); + goto err_out; + } + + free(err); + *image = tmp_img; + return 0; + +err_out: + free(err); + free_imagetool_image(tmp_img); + return -1; +} + +static void pack_imagetool_images_list(const struct isula_list_response *resp, imagetool_images_list **images) +{ + size_t i = 0; + imagetool_images_list *tmp_list = NULL; + + if (resp == NULL) { + return; + } + tmp_list = (imagetool_images_list *)util_common_calloc_s(sizeof(imagetool_images_list)); + if (tmp_list == NULL) { + ERROR("Out of memory"); + return; + } + if (resp->images_len == 0) { + DEBUG("Get number of images is 0"); + goto out; + } + tmp_list->images = (imagetool_image **)util_common_calloc_s(sizeof(imagetool_image *) * resp->images_len); + if (tmp_list->images == NULL) { + ERROR("Out of memory"); + goto out; + } + for (; i < resp->images_len; i++) { + if (pack_imagetool_image(resp->images[i], &(tmp_list->images[i])) != 0) { + break; + } + tmp_list->images_len++; + } + +out: + *images = tmp_list; +} + +int isula_list_images(const im_list_request *request, imagetool_images_list **images) +{ + struct isula_list_request *ireq = NULL; + struct isula_list_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops; + int ret = -1; + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return ret; + } + if (im_ops->list == NULL) { + ERROR("Umimplement list operator"); + return ret; + } + + ret = generate_isula_list_request(request, &ireq); + if (ret != 0) { + ret = -1; + goto out; + } + + iresp = (struct isula_list_response *)util_common_calloc_s(sizeof(struct isula_list_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + ret = -1; + goto out; + } + + ret = im_ops->list(ireq, iresp, &conf); + if (ret != 0) { + ERROR("List images failed: %s", iresp != NULL ? iresp->errmsg : "null"); + goto out; + } + + pack_imagetool_images_list(iresp, images); +out: + free_isula_list_request(ireq); + free_isula_list_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/oci_images_list.h b/src/image/oci/isula_images_list.h similarity index 62% rename from src/image/oci/oci_images_list.h rename to src/image/oci/isula_images_list.h index 7780c1d..d941404 100644 --- a/src/image/oci/oci_images_list.h +++ b/src/image/oci/isula_images_list.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -8,15 +8,13 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci images list functions - ******************************************************************************/ +* Author: liuhao +* Create: 2019-07-15 +* Description: isula images list operator implement +*******************************************************************************/ +#ifndef __OCI_REMOTE_IMAGES_LIST_H +#define __OCI_REMOTE_IMAGES_LIST_H -#ifndef __OCI_LIST_ALL_IMAGES_INFO_H_ -#define __OCI_LIST_ALL_IMAGES_INFO_H_ - -#include "oci_image_type.h" #include "imagetool_images_list.h" #include "image.h" @@ -24,11 +22,10 @@ extern "C" { #endif -int do_list_oci_images(im_list_request *request, imagetool_images_list **images); +int isula_list_images(const im_list_request *request, imagetool_images_list **images); #ifdef __cplusplus } #endif #endif - diff --git a/src/image/oci/isula_imtool_interface.c b/src/image/oci/isula_imtool_interface.c deleted file mode 100644 index c11eda7..0000000 --- a/src/image/oci/isula_imtool_interface.c +++ /dev/null @@ -1,818 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide imtool interface - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include "isula_imtool_interface.h" -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "lcrd_config.h" -#include "image.h" -#include "oci_image_pull.h" -#include "oci_image_status.h" -#include "oci_fs_info.h" -#include "oci_rootfs_prepare.h" -#include "oci_rootfs_mount.h" -#include "oci_rootfs_umount.h" -#include "oci_rootfs_remove.h" -#include "oci_rootfs_export.h" -#include "driver.h" - -#define PARAM_NUM 100 - -/* image tool name */ -#define ISULA_IMTOOL "isulad_kit" - -/* global options */ -#define IMTOOL_GB_OPTION_GRAPH_ROOT "--graph-root" -#define IMTOOL_GB_OPTION_RUN_ROOT "--run-root" -#define IMTOOL_GB_OPTION_DRIVER_NAME "--driver-name" -#define IMTOOL_GB_OPTION_DRIVER_OPTIONS "--driver-options" -#define IMTOOL_GB_OPTION_STORAGE_OPTIONS "--storage-opt" -#define IMTOOL_GB_OPTION_REGISTRY "--registry" -#define IMTOOL_GB_OPTION_INSEC_REGISTRY "--insecure-registry" -#define IMTOOL_GB_OPTION_OPT_TIMEOUT "--command-timeout" -#define IMTOOL_GB_OPTION_LOG_LEVEL "--log-level" - -/* sub command */ -#define IMTOOL_SUB_CMD_PULL "pull" -#define IMTOOL_CMD_PULL_OPTION_CREDS "--creds" -#define IMTOOL_CMD_PULL_OPTION_AUTH "--auth" -#define IMTOOL_CMD_PULL_DISABLE_TLS_VERIFY "--tls-verify=false" -#define IMTOOL_CMD_PULL_DISABLE_USE_DECRYPTED "--use-decrypted-key=false" - -#define IMTOOL_SUB_CMD_STATUS "status" - -#define IMTOOL_SUB_CMD_REMOVE_IMAGE "rmi" - -#define IMTOOL_SUB_CMD_FS_INFO "fsinfo" - -#define IMTOOL_SUB_CMD_LIST_IMAGES "images" -#define IMTOOL_CMD_IMAGES_OPTION_FILTER "--filter" -#define IMTOOL_CMD_IMAGES_OPTION_CHECK "--check" - -#define IMTOOL_SUB_CMD_PREPARE_ROOTFS "prepare" -#define IMTOOL_CMD_PREPARE_OPTION_IMAGE "--image" -#define IMTOOL_CMD_PREPARE_OPTION_NAME "--name" -#define IMTOOL_CMD_PREPARE_OPTION_ID "--id" - -#define IMTOOL_SUB_CMD_MOUNT_ROOTFS "mount" - -#define IMTOOL_SUB_CMD_UMOUNT_ROOTFS "umount" - -#define IMTOOL_SUB_CMD_REMOVE_ROOTFS "rm" - -#define IMTOOL_SUB_CMD_INFO_IMAGE "info" - -#define IMTOOL_SUB_CMD_STORAGE_STATUS "storage_status" - -#define IMTOOL_SUB_CMD_UMOUNT_STORAGE "storage_umount" - -#define IMTOOL_SUB_CMD_CONTAINER_FS_INFO "filesystemusage" - -#define IMTOOL_SUB_CMD_EXPORT_ROOTFS "export" -#define IMTOOL_CMD_OUTPUT_OPTION_ROOTFS "--output" - -#define IMTOOL_SUB_CMD_LOAD_IMAGE "load" -#define IMTOOL_CMD_INPUT_OPTION_IMAGE "--input" -#define IMTOOL_CMD_TAG_OPTION_IMAGE "--tag" - -#define IMTOOL_SUB_CMD_LOGIN "login" -#define IMTOOL_SUB_CMD_LOGOUT "logout" - -static inline void add_array_elem(char **array, size_t total, size_t *pos, const char *elem) -{ - if (*pos + 1 >= total - 1) { - return; - } - array[*pos] = util_strdup_s(elem); - *pos += 1; -} - -static inline void add_array_kv(char **array, size_t total, size_t *pos, const char *k, const char *v) -{ - if (k == NULL || v == NULL) { - return; - } - add_array_elem(array, total, pos, k); - add_array_elem(array, total, pos, v); -} - -static int pack_global_graph_driver(char *params[], size_t *count, bool ignore_storage_opt_size) -{ - int ret = -1; - char *graph_driver = NULL; - struct graphdriver *driver = NULL; - char **graph_opts = NULL; - char **p = NULL; - size_t i = 0; - - i = *count; - - graph_driver = conf_get_lcrd_storage_driver(); - if (graph_driver == NULL) { - COMMAND_ERROR("Failed to get graph driver"); - goto out; - } - driver = graphdriver_get(graph_driver); - if (strcmp(graph_driver, "overlay2") == 0) { - // Treating overlay2 as overlay cause image was downloaded always - // in '/var/lib/lcrd/storage/overlay' directory. - // See iSulad-kit/vendor/github.com/containers/storage/drivers/overlay/overlay.go, - // Driver is inited by name "overlay". - graph_driver[strlen(graph_driver) - 1] = '\0'; - } - add_array_kv(params, PARAM_NUM, &i, IMTOOL_GB_OPTION_DRIVER_NAME, graph_driver); - - graph_opts = conf_get_storage_opts(); - // since iSulad-kit will set quota when pull image, which is differ from docker, - // and we may get some error if setted, ignore it if neccessary. - for (p = graph_opts; (p != NULL) && (*p != NULL); p++) { - if (ignore_storage_opt_size && driver != NULL && driver->ops->is_quota_options(driver, *p)) { - continue; - } - add_array_kv(params, PARAM_NUM, &i, IMTOOL_GB_OPTION_DRIVER_OPTIONS, *p); - } - - ret = 0; - *count = i; -out: - free(graph_driver); - util_free_array(graph_opts); - return ret; -} - -static int pack_global_graph_root(char *params[], size_t *count) -{ - int ret = -1; - char *graph_root = NULL; - size_t i = 0; - - i = *count; - - graph_root = conf_get_graph_rootpath(); - if (graph_root == NULL) { - COMMAND_ERROR("Failed to get graph root directory"); - goto out; - } - add_array_kv(params, PARAM_NUM, &i, IMTOOL_GB_OPTION_GRAPH_ROOT, graph_root); - - ret = 0; - *count = i; -out: - free(graph_root); - return ret; -} - -static int pack_global_graph_run(char *params[], size_t *count) -{ - int ret = -1; - char *graph_run = NULL; - size_t i = 0; - - i = *count; - - graph_run = conf_get_graph_run_path(); - if (graph_run == NULL) { - COMMAND_ERROR("Failed to get graph run directory"); - goto out; - } - add_array_kv(params, PARAM_NUM, &i, IMTOOL_GB_OPTION_RUN_ROOT, graph_run); - - ret = 0; - *count = i; -out: - free(graph_run); - return ret; -} - -static int pack_global_graph_registry(char *params[], size_t *count) -{ - int ret = -1; - size_t i = 0; - char **registry = NULL; - char **insecure_registry = NULL; - char **p = NULL; - - i = *count; - - registry = conf_get_registry_list(); - for (p = registry; (p != NULL) && (*p != NULL); p++) { - add_array_kv(params, PARAM_NUM, &i, IMTOOL_GB_OPTION_REGISTRY, *p); - } - - insecure_registry = conf_get_insecure_registry_list(); - for (p = insecure_registry; (p != NULL) && (*p != NULL); p++) { - add_array_kv(params, PARAM_NUM, &i, IMTOOL_GB_OPTION_INSEC_REGISTRY, *p); - } - - ret = 0; - *count = i; - - util_free_array(registry); - util_free_array(insecure_registry); - return ret; -} - -static int pack_global_opt_time(char *params[], size_t *count) -{ - int ret = -1; - size_t i = 0; - unsigned int opt_timeout = 0; - char timeout_str[UINT_LEN + 2] = { 0 }; /*format: XXXs*/ - - i = *count; - - opt_timeout = conf_get_im_opt_timeout(); - if (opt_timeout != 0) { - add_array_elem(params, PARAM_NUM, &i, IMTOOL_GB_OPTION_OPT_TIMEOUT); - if (sprintf_s(timeout_str, UINT_LEN, "%us", opt_timeout) < 0) { - COMMAND_ERROR("Failed to print string"); - goto out; - } - add_array_elem(params, PARAM_NUM, &i, timeout_str); - } - - ret = 0; - *count = i; -out: - return ret; -} - -static int pack_global_option(char *params[], size_t *count, bool ignore_storage_opt_size) -{ - int ret = -1; - size_t i = 0; - - i = *count; - - add_array_elem(params, PARAM_NUM, &i, ISULA_IMTOOL); - - if (pack_global_graph_root(params, &i) != 0) { - goto out; - } - - if (pack_global_graph_run(params, &i) != 0) { - goto out; - } - - if (pack_global_graph_driver(params, &i, ignore_storage_opt_size) != 0) { - goto out; - } - - if (pack_global_graph_registry(params, &i) != 0) { - goto out; - } - - if (pack_global_opt_time(params, &i) != 0) { - goto out; - } - - ret = 0; - *count = i; - -out: - return ret; -} - -void execute_pull_image(void *args) -{ - image_pull_request *request = (image_pull_request *)args; - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - if (request->auth.server_address != NULL) { - add_array_kv(params, PARAM_NUM, &i, IMTOOL_GB_OPTION_REGISTRY, request->auth.server_address); - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_PULL); - - if (conf_get_use_decrypted_key_flag() == false) { - add_array_elem(params, PARAM_NUM, &i, IMTOOL_CMD_PULL_DISABLE_USE_DECRYPTED); - } - - if (conf_get_skip_insecure_verify_flag() == true) { - add_array_elem(params, PARAM_NUM, &i, IMTOOL_CMD_PULL_DISABLE_TLS_VERIFY); - } - - add_array_elem(params, PARAM_NUM, &i, request->image.image); - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot pull image with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_status_image(void *args) -{ - oci_image_status_request *request = (oci_image_status_request *)args; - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_STATUS); - - add_array_elem(params, PARAM_NUM, &i, request->image.image); - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot status image with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_remove_image(void *args) -{ - im_remove_request *request = (im_remove_request *)args; - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_REMOVE_IMAGE); - - add_array_elem(params, PARAM_NUM, &i, request->image.image); - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot remove image with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_list_images(void *args) -{ - im_list_request *request = (im_list_request *)args; - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - const char *log_level = "error"; - - if (request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - add_array_kv(params, PARAM_NUM, &i, IMTOOL_GB_OPTION_LOG_LEVEL, log_level); - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_LIST_IMAGES); - - if (request->filter.image.image != NULL) { - add_array_kv(params, PARAM_NUM, &i, IMTOOL_CMD_IMAGES_OPTION_FILTER, request->filter.image.image); - } - - if (request->check) { - add_array_elem(params, PARAM_NUM, &i, IMTOOL_CMD_IMAGES_OPTION_CHECK); - } - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot list images with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_fs_info(void *args) -{ - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_FS_INFO); - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot get image filesystem info with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_prepare_rootfs(void *args) -{ - rootfs_prepare_request *request = (rootfs_prepare_request *)args; - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, false) != 0) { - goto out; - } - - if (request->storage_opts != NULL && request->storage_opts_len > 0) { - int j; - for (j = 0; j < (int)request->storage_opts_len; j++) { - add_array_kv(params, PARAM_NUM, &i, IMTOOL_GB_OPTION_STORAGE_OPTIONS, request->storage_opts[j]); - } - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_PREPARE_ROOTFS); - - add_array_kv(params, PARAM_NUM, &i, IMTOOL_CMD_PREPARE_OPTION_IMAGE, request->image); - - add_array_kv(params, PARAM_NUM, &i, IMTOOL_CMD_PREPARE_OPTION_NAME, request->name); - - add_array_kv(params, PARAM_NUM, &i, IMTOOL_CMD_PREPARE_OPTION_ID, request->id); - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot prepare rootfs with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_mount_rootfs(void *args) -{ - rootfs_mount_request *mount_request = (rootfs_mount_request *)args; - char *mount_params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (mount_request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(mount_params, &i, false) != 0) { - goto out; - } - - add_array_elem(mount_params, PARAM_NUM, &i, IMTOOL_SUB_CMD_MOUNT_ROOTFS); - - if (mount_request->name_id != NULL) { - add_array_elem(mount_params, PARAM_NUM, &i, mount_request->name_id); - } - - execvp(ISULA_IMTOOL, mount_params); - - COMMAND_ERROR("Cannot mount rootfs with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_umount_rootfs(void *args) -{ - rootfs_umount_request *umount_request = (rootfs_umount_request *)args; - char *umount_params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (umount_request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(umount_params, &i, false) != 0) { - goto out; - } - - add_array_elem(umount_params, PARAM_NUM, &i, IMTOOL_SUB_CMD_UMOUNT_ROOTFS); - - if (umount_request->name_id != NULL) { - add_array_elem(umount_params, PARAM_NUM, &i, umount_request->name_id); - } - - execvp(ISULA_IMTOOL, umount_params); - - COMMAND_ERROR("Cannot umount rootfs with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_remove_rootfs(void *args) -{ - rootfs_remove_request *remove_request = (rootfs_remove_request *)args; - char *remove_params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (remove_request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(remove_params, &i, true) != 0) { - goto out; - } - - add_array_elem(remove_params, PARAM_NUM, &i, IMTOOL_SUB_CMD_REMOVE_ROOTFS); - - if (remove_request->name_id != NULL) { - add_array_elem(remove_params, PARAM_NUM, &i, remove_request->name_id); - } - - execvp(ISULA_IMTOOL, remove_params); - - COMMAND_ERROR("Cannot remove rootfs with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_storage_status(void *args) -{ - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_STORAGE_STATUS); - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot get storage status with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_container_fs_info(void *args) -{ - const char *id = (const char *)args; - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (id == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_CONTAINER_FS_INFO); - - add_array_elem(params, PARAM_NUM, &i, id); - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot get filesystem usage with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_export_rootfs(void *args) -{ - rootfs_export_request *request = (rootfs_export_request *)args; - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_EXPORT_ROOTFS); - - add_array_kv(params, PARAM_NUM, &i, IMTOOL_CMD_OUTPUT_OPTION_ROOTFS, request->file); - - add_array_elem(params, PARAM_NUM, &i, request->id); - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot export rootfs with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_load_image(void *args) -{ - im_load_request *request = (im_load_request *)args; - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_LOAD_IMAGE); - - add_array_kv(params, PARAM_NUM, &i, IMTOOL_CMD_INPUT_OPTION_IMAGE, request->file); - - if (request->tag != NULL) { - add_array_kv(params, PARAM_NUM, &i, IMTOOL_CMD_TAG_OPTION_IMAGE, request->tag); - } - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot load image with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_login(void *args) -{ - im_login_request *request = (im_login_request *)args; - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_LOGIN); - - if (conf_get_use_decrypted_key_flag() == false) { - add_array_elem(params, PARAM_NUM, &i, IMTOOL_CMD_PULL_DISABLE_USE_DECRYPTED); - } - - if (conf_get_skip_insecure_verify_flag() == true) { - add_array_elem(params, PARAM_NUM, &i, IMTOOL_CMD_PULL_DISABLE_TLS_VERIFY); - } - - add_array_elem(params, PARAM_NUM, &i, request->server); - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot login with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} - -void execute_logout(void *args) -{ - im_logout_request *request = (im_logout_request *)args; - char *params[PARAM_NUM] = { NULL }; - size_t i = 0; - - if (request == NULL) { - COMMAND_ERROR("Invalid input arguments"); - return; - } - - if (util_check_inherited(true, -1) != 0) { - COMMAND_ERROR("Close inherited fds failed"); - goto out; - } - - if (pack_global_option(params, &i, true) != 0) { - goto out; - } - - add_array_elem(params, PARAM_NUM, &i, IMTOOL_SUB_CMD_LOGOUT); - - if (conf_get_use_decrypted_key_flag() == false) { - add_array_elem(params, PARAM_NUM, &i, IMTOOL_CMD_PULL_DISABLE_USE_DECRYPTED); - } - - if (conf_get_skip_insecure_verify_flag() == true) { - add_array_elem(params, PARAM_NUM, &i, IMTOOL_CMD_PULL_DISABLE_TLS_VERIFY); - } - - add_array_elem(params, PARAM_NUM, &i, request->server); - - execvp(ISULA_IMTOOL, params); - - COMMAND_ERROR("Cannot logout with '%s':%s", ISULA_IMTOOL, strerror(errno)); - -out: - exit(EXIT_FAILURE); -} diff --git a/src/image/oci/isula_imtool_interface.h b/src/image/oci/isula_imtool_interface.h deleted file mode 100644 index 19ed1a3..0000000 --- a/src/image/oci/isula_imtool_interface.h +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide imtool interface - ******************************************************************************/ - -#ifndef __ISULA_IMTOOL_INTERFACE_H_ -#define __ISULA_IMTOOL_INTERFACE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void execute_pull_image(void *args); - -void execute_status_image(void *args); - -void execute_remove_image(void *args); - -void execute_list_images(void *args); - -void execute_fs_info(void *args); - -void execute_prepare_rootfs(void *args); - -void execute_mount_rootfs(void *args); - -void execute_umount_rootfs(void *args); - -void execute_remove_rootfs(void *args); - -void execute_storage_status(void *args); - -void execute_container_fs_info(void *args); - -void execute_export_rootfs(void *args); - -void execute_load_image(void *args); - -void execute_login(void *args); - -void execute_logout(void *args); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/image/oci/isula_login.c b/src/image/oci/isula_login.c new file mode 100644 index 0000000..f022d28 --- /dev/null +++ b/src/image/oci/isula_login.c @@ -0,0 +1,108 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula login operator implement +*******************************************************************************/ +#include "isula_login.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "liblcrd.h" +#include "log.h" + +static int is_valid_arguments(const char *server, const char *username, const char *password) +{ + if (server == NULL) { + lcrd_set_error_message("Login requires server address"); + return -1; + } + + if (username == NULL || password == NULL) { + lcrd_set_error_message("Missing username or password"); + return -1; + } + + return 0; +} + +static int generate_isula_login_request(const char *server, const char *username, const char *password, + struct isula_login_request **ireq) +{ + struct isula_login_request *tmp_req = NULL; + + tmp_req = (struct isula_login_request *)util_common_calloc_s(sizeof(struct isula_login_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + + tmp_req->server = util_strdup_s(server); + tmp_req->username = util_strdup_s(username); + tmp_req->password = util_strdup_s(password); + + *ireq = tmp_req; + return 0; +} + +int isula_do_login(const char *server, const char *username, const char *password) +{ + int ret = -1; + struct isula_login_request *ireq = NULL; + struct isula_login_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops; + + if (is_valid_arguments(server, username, password) != 0) { + ERROR("Invalid arguments"); + return -1; + } + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->login == NULL) { + ERROR("Umimplement login operator"); + return -1; + } + + ret = generate_isula_login_request(server, username, password, &ireq); + if (ret != 0) { + goto out; + } + + iresp = (struct isula_login_response *)util_common_calloc_s(sizeof(struct isula_login_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto out; + } + + ret = im_ops->login(ireq, iresp, &conf); + if (ret != 0) { + ERROR("Failed to login with error: %s", iresp->errmsg); + lcrd_set_error_message("Failed to login with error: %s", iresp->errmsg); + } + +out: + free_isula_login_request(ireq); + free_isula_login_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/isula_login.h b/src/image/oci/isula_login.h new file mode 100644 index 0000000..4345bdc --- /dev/null +++ b/src/image/oci/isula_login.h @@ -0,0 +1,30 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula logint operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_LOGIN_H +#define __IMAGE_ISULA_LOGIN_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_do_login(const char *server, const char *username, const char *password); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_logout.c b/src/image/oci/isula_logout.c new file mode 100644 index 0000000..16fbc84 --- /dev/null +++ b/src/image/oci/isula_logout.c @@ -0,0 +1,100 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image rootfs remove operator implement +*******************************************************************************/ +#include "isula_logout.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "liblcrd.h" +#include "log.h" + +static int generate_isula_logout_request(const char *server, struct isula_logout_request **ireq) +{ + struct isula_logout_request *tmp_req = NULL; + + tmp_req = (struct isula_logout_request *)util_common_calloc_s(sizeof(struct isula_logout_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + + tmp_req->server = util_strdup_s(server); + + *ireq = tmp_req; + return 0; +} + +static inline int is_valid_arguments(const char *server) +{ + if (server == NULL) { + lcrd_set_error_message("Logout requires server address"); + return -1; + } + return 0; +} + +int isula_do_logout(const char *server) +{ + int ret = -1; + struct isula_logout_request *ireq = NULL; + struct isula_logout_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops = NULL; + + if (is_valid_arguments(server) != 0) { + ERROR("Invlaid arguments"); + return -1; + } + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + + if (im_ops->logout == NULL) { + ERROR("Umimplement logout operator"); + return -1; + } + + ret = generate_isula_logout_request(server, &ireq); + if (ret != 0) { + goto out; + } + + iresp = (struct isula_logout_response *)util_common_calloc_s(sizeof(struct isula_logout_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto out; + } + + ret = im_ops->logout(ireq, iresp, &conf); + if (ret != 0) { + ERROR("Failed to logout with error: %s", iresp->errmsg); + lcrd_set_error_message("Failed to logout with error: %s", iresp->errmsg); + } + +out: + free_isula_logout_request(ireq); + free_isula_logout_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/isula_logout.h b/src/image/oci/isula_logout.h new file mode 100644 index 0000000..691a994 --- /dev/null +++ b/src/image/oci/isula_logout.h @@ -0,0 +1,30 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula logout operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_LOGOUT_H +#define __IMAGE_ISULA_LOGOUT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_do_logout(const char *server); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_rootfs_mount.c b/src/image/oci/isula_rootfs_mount.c new file mode 100644 index 0000000..a12707e --- /dev/null +++ b/src/image/oci/isula_rootfs_mount.c @@ -0,0 +1,88 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image rootfs mount operator implement +*******************************************************************************/ +#include "isula_rootfs_mount.h" + +#include "isula_image_connect.h" +#include "connect.h" +#include "isula_helper.h" +#include "utils.h" +#include "log.h" + +static int generate_isula_mount_request(const char *name_id, struct isula_mount_request **ireq) +{ + struct isula_mount_request *tmp_req = NULL; + + if (name_id == NULL) { + ERROR("Invalid container id or name"); + return -1; + } + tmp_req = (struct isula_mount_request *)util_common_calloc_s(sizeof(struct isula_mount_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + tmp_req->name_id = util_strdup_s(name_id); + + *ireq = tmp_req; + return 0; +} + +int isula_rootfs_mount(const char *name_id) +{ + int ret = -1; + struct isula_mount_request *ireq = NULL; + struct isula_mount_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops; + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->mount == NULL) { + ERROR("Umimplement mount operator"); + return -1; + } + + ret = generate_isula_mount_request(name_id, &ireq); + if (ret != 0) { + goto out; + } + + iresp = (struct isula_mount_response *)util_common_calloc_s(sizeof(struct isula_mount_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto out; + } + + INFO("Send mount rootfs GRPC request"); + ret = im_ops->mount(ireq, iresp, &conf); + if (ret != 0) { + ERROR("Remove rootfs %s failed: %s", name_id, iresp != NULL ? iresp->errmsg : "null"); + } + +out: + free_isula_mount_request(ireq); + free_isula_mount_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} + diff --git a/src/image/oci/isula_rootfs_mount.h b/src/image/oci/isula_rootfs_mount.h new file mode 100644 index 0000000..d9ee12d --- /dev/null +++ b/src/image/oci/isula_rootfs_mount.h @@ -0,0 +1,28 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image rootfs mount operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_MOUNT_H +#define __IMAGE_ISULA_MOUNT_H + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_rootfs_mount(const char *name_id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_rootfs_prepare.c b/src/image/oci/isula_rootfs_prepare.c new file mode 100644 index 0000000..65ff670 --- /dev/null +++ b/src/image/oci/isula_rootfs_prepare.c @@ -0,0 +1,146 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image prepare operator implement +*******************************************************************************/ +#include "isula_rootfs_prepare.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "lcrd_config.h" +#include "utils.h" +#include "log.h" + +static int generate_isula_prepare_request(const char *container_id, const char *image_name, + const json_map_string_string *storage_opt, + struct isula_prepare_request **ireq) +{ + struct isula_prepare_request *tmp_req = NULL; + + if (ireq == NULL) { + return -1; + } + + tmp_req = (struct isula_prepare_request *)util_common_calloc_s(sizeof(struct isula_prepare_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + + if (map_to_key_value_string(storage_opt, &(tmp_req->storage_opts), &(tmp_req->storage_opts_len)) != 0) { + ERROR("Map to string array failed"); + goto err_out; + } + tmp_req->id = util_strdup_s(container_id); + tmp_req->name = util_strdup_s(container_id); + tmp_req->image = util_strdup_s(image_name); + + *ireq = tmp_req; + return 0; +err_out: + free_isula_prepare_request(tmp_req); + return -1; +} + +static int parse_image_conf_from_json_str(const char *image_conf_str, oci_image_spec **spec) +{ + parser_error err = NULL; + int ret = 0; + + if (spec == NULL) { + return 0; + } + *spec = oci_image_spec_parse_data(image_conf_str, NULL, &err); + if (*spec == NULL) { + ERROR("Failed to parse image conf: %s", err); + lcrd_set_error_message("Failed to parse image conf"); + ret = -1; + } + + free(err); + return ret; +} + +static int dealwith_result(int result, struct isula_prepare_response *iresp, char **real_rootfs, oci_image_spec **spec) +{ + int ret = result; + + if (result != 0) { + if (iresp->errmsg != NULL) { + ERROR("Failed to prepare rootfs with error: %s", iresp->errmsg); + lcrd_set_error_message("Failed to prepare rootfs with error: %s", iresp->errmsg); + } else { + ERROR("Failed to prepare rootfs"); + lcrd_set_error_message("Failed to prepare rootfs"); + } + } else { + *real_rootfs = iresp->mount_point; + iresp->mount_point = NULL; + ret = parse_image_conf_from_json_str(iresp->image_conf, spec); + } + + return ret; +} + +int isula_rootfs_prepare_and_get_image_conf(const char *container_id, const char *image_name, + const json_map_string_string *storage_opt, + char **real_rootfs, oci_image_spec **spec) +{ + int ret = -1; + struct isula_prepare_request *ireq = NULL; + struct isula_prepare_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops = NULL; + + if (container_id == NULL || image_name == NULL || real_rootfs == NULL) { + ERROR("Invalid arguments"); + return -1; + } + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->prepare == NULL) { + ERROR("Umimplement prepare operator"); + return -1; + } + + iresp = (struct isula_prepare_response *)util_common_calloc_s(sizeof(struct isula_prepare_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + ret = -1; + goto err_out; + } + + ret = generate_isula_prepare_request(container_id, image_name, storage_opt, &ireq); + if (ret != 0) { + goto err_out; + } + + ret = get_isula_image_connect_config(&conf); + if (ret != 0) { + goto err_out; + } + + INFO("Send prepare rootfs GRPC request"); + ret = im_ops->prepare(ireq, iresp, &conf); + + ret = dealwith_result(ret, iresp, real_rootfs, spec); + +err_out: + free_client_connect_config_value(&conf); + free_isula_prepare_request(ireq); + free_isula_prepare_response(iresp); + return ret; +} diff --git a/src/image/oci/isula_rootfs_prepare.h b/src/image/oci/isula_rootfs_prepare.h new file mode 100644 index 0000000..c2de434 --- /dev/null +++ b/src/image/oci/isula_rootfs_prepare.h @@ -0,0 +1,33 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image prepare operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_PREPARE_H +#define __IMAGE_ISULA_PREPARE_H + +#include "image.h" +#include "oci_image_spec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_rootfs_prepare_and_get_image_conf(const char *container_id, const char *image_name, + const json_map_string_string *storage_opt, + char **real_rootfs, oci_image_spec **spec); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_rootfs_remove.c b/src/image/oci/isula_rootfs_remove.c new file mode 100644 index 0000000..9b35962 --- /dev/null +++ b/src/image/oci/isula_rootfs_remove.c @@ -0,0 +1,101 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image rootfs remove operator implement +*******************************************************************************/ +#include "isula_rootfs_remove.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "log.h" + +static int generate_isula_remove_request(const char *name_id, struct isula_remove_request **ireq) +{ + struct isula_remove_request *tmp_req = NULL; + + if (name_id == NULL) { + ERROR("Invalid container id or name"); + return -1; + } + tmp_req = (struct isula_remove_request *)util_common_calloc_s(sizeof(struct isula_remove_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + tmp_req->name_id = util_strdup_s(name_id); + + *ireq = tmp_req; + return 0; +} + +int isula_rootfs_remove(const char *name_id) +{ +#define CONTAINER_NOT_KNOWN_ERR "container not known" + int ret = 0; + int nret = -1; + struct isula_remove_request *ireq = NULL; + struct isula_remove_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops; + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->remove == NULL) { + ERROR("Umimplement remove operator"); + return -1; + } + + nret = generate_isula_remove_request(name_id, &ireq); + if (nret != 0) { + ret = -1; + goto out; + } + + iresp = (struct isula_remove_response *)util_common_calloc_s(sizeof(struct isula_remove_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + nret = get_isula_image_connect_config(&conf); + if (nret != 0) { + ret = -1; + goto out; + } + + INFO("Send remove rootfs GRPC request"); + nret = im_ops->remove(ireq, iresp, &conf); + if (nret != 0) { + if (iresp->errmsg != NULL) { + if (strstr(iresp->errmsg, CONTAINER_NOT_KNOWN_ERR) != NULL) { + DEBUG("Container %s may already removed", name_id); + goto out; + } + ERROR("Remove rootfs %s failed: %s", name_id, iresp->errmsg); + } else { + ERROR("Failed to remove rootfs of %s", name_id); + } + ret = -1; + } + +out: + free_isula_remove_request(ireq); + free_isula_remove_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/isula_rootfs_remove.h b/src/image/oci/isula_rootfs_remove.h new file mode 100644 index 0000000..6b01e4d --- /dev/null +++ b/src/image/oci/isula_rootfs_remove.h @@ -0,0 +1,28 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image rootfs remove operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_REMOVE_H +#define __IMAGE_ISULA_REMOVE_H + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_rootfs_remove(const char *name_id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_rootfs_umount.c b/src/image/oci/isula_rootfs_umount.c new file mode 100644 index 0000000..cca8e63 --- /dev/null +++ b/src/image/oci/isula_rootfs_umount.c @@ -0,0 +1,94 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image rootfs umount operator implement +*******************************************************************************/ +#include "isula_rootfs_umount.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "log.h" + +static int generate_isula_umount_request(const char *name_id, bool force, struct isula_umount_request **ireq) +{ + struct isula_umount_request *tmp_req = NULL; + + if (name_id == NULL) { + ERROR("Invalid container id or name"); + return -1; + } + tmp_req = (struct isula_umount_request *)util_common_calloc_s(sizeof(struct isula_umount_request)); + if (tmp_req == NULL) { + ERROR("Out of memory"); + return -1; + } + tmp_req->name_id = util_strdup_s(name_id); + + tmp_req->force = force; + + *ireq = tmp_req; + return 0; +} + +int isula_rootfs_umount(const char *name_id, bool force) +{ + int ret = 0; + int nret = -1; + struct isula_umount_request *ireq = NULL; + struct isula_umount_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops; + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->umount == NULL) { + ERROR("Umimplement umount operator"); + return -1; + } + + nret = generate_isula_umount_request(name_id, force, &ireq); + if (nret != 0) { + ret = -1; + goto out; + } + + iresp = (struct isula_umount_response *)util_common_calloc_s(sizeof(struct isula_umount_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + nret = get_isula_image_connect_config(&conf); + if (nret != 0) { + ret = -1; + goto out; + } + + INFO("Send umount rootfs GRPC request"); + nret = im_ops->umount(ireq, iresp, &conf); + if (nret != 0) { + ERROR("Remove rootfs %s failed: %s", name_id, iresp != NULL ? iresp->errmsg : "null"); + ret = -1; + } + +out: + free_isula_umount_request(ireq); + free_isula_umount_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} diff --git a/src/image/oci/isula_rootfs_umount.h b/src/image/oci/isula_rootfs_umount.h new file mode 100644 index 0000000..fcbb082 --- /dev/null +++ b/src/image/oci/isula_rootfs_umount.h @@ -0,0 +1,30 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula image rootfs umount operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_UMOUNT_H +#define __IMAGE_ISULA_UMOUNT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_rootfs_umount(const char *name_id, bool force); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/isula_storage_status.c b/src/image/oci/isula_storage_status.c new file mode 100644 index 0000000..28be9af --- /dev/null +++ b/src/image/oci/isula_storage_status.c @@ -0,0 +1,81 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula storage status operator implement +*******************************************************************************/ +#include "isula_storage_status.h" + +#include "isula_image_connect.h" +#include "isula_helper.h" +#include "connect.h" +#include "utils.h" +#include "log.h" + +static void pack_im_response(const struct isula_storage_status_response *iresp, im_storage_status_response *resp) +{ + resp->backing_fs = util_strdup_s(iresp->backing_fs); + resp->supports_d_type = iresp->supports_d_type; + resp->native_overlay_diff = iresp->native_overlay_diff; +} + +int isula_do_storage_status(im_storage_status_response *resp) +{ + int ret = 0; + int nret = -1; + struct isula_storage_status_request ireq = {0}; + struct isula_storage_status_response *iresp = NULL; + client_connect_config_t conf = { 0 }; + isula_image_ops *im_ops = NULL; + + if (resp == NULL) { + ERROR("Invalid arguments"); + return -1; + } + + im_ops = get_isula_image_ops(); + if (im_ops == NULL) { + ERROR("Don't init isula server grpc client"); + return -1; + } + if (im_ops->storage_status == NULL) { + ERROR("Umimplement get storage status operator"); + return -1; + } + + iresp = (struct isula_storage_status_response *)util_common_calloc_s(sizeof(struct isula_storage_status_response)); + if (iresp == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + nret = get_isula_image_connect_config(&conf); + if (nret != 0) { + ret = -1; + goto out; + } + + nret = im_ops->storage_status(&ireq, iresp, &conf); + if (nret != 0) { + ERROR("Failed to get storage status with error: %s", iresp->errmsg); + lcrd_set_error_message("Failed to get storage status with error: %s", iresp->errmsg); + ret = -1; + goto out; + } + pack_im_response(iresp, resp); + +out: + free_isula_storage_status_response(iresp); + free_client_connect_config_value(&conf); + return ret; +} + diff --git a/src/image/oci/isula_storage_status.h b/src/image/oci/isula_storage_status.h new file mode 100644 index 0000000..2c4ee38 --- /dev/null +++ b/src/image/oci/isula_storage_status.h @@ -0,0 +1,30 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: isula storage status operator implement +*******************************************************************************/ +#ifndef __IMAGE_ISULA_STORAGE_STATUS_H +#define __IMAGE_ISULA_STORAGE_STATUS_H + +#include "image.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int isula_do_storage_status(im_storage_status_response *resp); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/oci_auth.c b/src/image/oci/oci_auth.c index 3fd035d..a9c9bfb 100644 --- a/src/image/oci/oci_auth.c +++ b/src/image/oci/oci_auth.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: diff --git a/src/image/oci/oci_auth.h b/src/image/oci/oci_auth.h index 1b77f88..3234688 100644 --- a/src/image/oci/oci_auth.h +++ b/src/image/oci/oci_auth.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -28,3 +28,4 @@ char *pack_input_auth_string(auth_config *auth); #endif #endif + diff --git a/src/image/oci/oci_common_operators.c b/src/image/oci/oci_common_operators.c new file mode 100644 index 0000000..73f0bee --- /dev/null +++ b/src/image/oci/oci_common_operators.c @@ -0,0 +1,839 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. + * Author: liuhao + * Create: 2019-07-23 + * Description: provide image common function definition + ******************************************************************************/ +#include "oci_common_operators.h" +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "utils.h" +#include "securec.h" +#include "oci_images_store.h" +#include "specs_extend.h" +#include "oci_config_merge.h" + +#include "isula_image_status.h" +#include "isula_images_list.h" +#include "filters.h" + +#define DEFAULT_TAG ":latest" +#define DEFAULT_HOSTNAME "docker.io/" +#define DEFAULT_REPO_PREFIX "library/" + +static bool oci_image_exist(const char *image_name) +{ + bool ret = false; + oci_image_t *image_info = NULL; + + image_info = oci_images_store_get(image_name); + if (image_info != NULL) { + ret = true; + oci_image_unref(image_info); + } + + return ret; +} + +bool oci_detect(const char *image_name) +{ + if (image_name == NULL) { + return false; + } + + return oci_image_exist(image_name); +} + +// format: [status xx: val] +static int get_graphdriver_status_line_value(const char *line, char **start, char **end) +{ + char *pstart = NULL; + char *pend = NULL; + + pstart = strchr(line, ':'); + if (pstart == NULL) { + ERROR("Invalid output: %s", line); + return -1; + } + pstart++; + if (*pstart != ' ') { + ERROR("Invalid output: %s", line); + return -1; + } + pstart++; + + pend = strchr(pstart, '\n'); + if (pend == NULL) { + ERROR("Invalid output: %s", pstart); + return -1; + } + *pend++ = '\0'; + + *start = pstart; + *end = pend; + return 0; +} + +int pack_storage_status_response(const char *stdout_buffer, im_storage_status_response *resp) +{ + char *pstart = NULL; + char *pend = NULL; + int nret = -1; + + // Backing Filesystem: extfs + if (get_graphdriver_status_line_value(stdout_buffer, &pstart, &pend) != 0) { + goto free_out; + } + resp->backing_fs = util_strdup_s(pstart); + + // Supports d_type: true + if (get_graphdriver_status_line_value(pend, &pstart, &pend) != 0) { + goto free_out; + } + nret = util_str_to_bool(pstart, &resp->supports_d_type); + if (nret < 0) { + ERROR("Invalid output: %s", pstart); + goto free_out; + } + + // Native Overlay Diff: true + if (get_graphdriver_status_line_value(pend, &pstart, &pend) != 0) { + goto free_out; + } + nret = util_str_to_bool(pstart, &resp->native_overlay_diff); + if (nret < 0) { + ERROR("Invalid output: %s", pstart); + goto free_out; + } + nret = 0; +free_out: + + return nret; +} + +char *get_last_part(char **parts) +{ + char *last_part = NULL; + char **p; + + for (p = parts; p != NULL && *p != NULL; p++) { + last_part = *p; + } + + return last_part; +} + +// normalize the unqualified image to be domain/repo/image... +char *oci_normalize_image_name(const char *name) +{ + char temp[PATH_MAX] = { 0 }; + char **parts = NULL; + char *last_part = NULL; + char *add_dockerio = ""; + char *add_library = ""; + char *add_default_tag = ""; + + // Add prefix docker.io if necessary + parts = util_string_split(name, '/'); + if ((parts != NULL && *parts != NULL && !strings_contains_any(*parts, ".:") && + strcmp(*parts, "localhost")) || (strstr(name, "/") == NULL)) { + add_dockerio = DEFAULT_HOSTNAME; + } + + // Add library if necessary + if (strlen(add_dockerio) != 0 && strstr(name, "/") == NULL) { + add_library = DEFAULT_REPO_PREFIX; + } + + // Add default tag if necessary + last_part = get_last_part(parts); + if (last_part != NULL && strrchr(last_part, ':') == NULL) { + add_default_tag = DEFAULT_TAG; + } + + util_free_array(parts); + + // Normalize image name + if (sprintf_s(temp, sizeof(temp), "%s%s%s%s", add_dockerio, add_library, name, add_default_tag) < 0) { + ERROR("sprint temp image name failed"); + return NULL; + } + + return util_strdup_s(temp); +} + +char *oci_resolve_image_name(const char *name) +{ + if (util_valid_short_sha256_id(name) && oci_image_exist(name)) { + return util_strdup_s(name); + } + + return oci_normalize_image_name(name); +} + +static char *oci_strip_dockerio_prefix(const char *name) +{ + char prefix[PATH_MAX] = { 0 }; + size_t size = 0; + + if (name == NULL) { + ERROR("NULL image name"); + return NULL; + } + + if (sprintf_s(prefix, sizeof(prefix), "%s%s", DEFAULT_HOSTNAME, DEFAULT_REPO_PREFIX) < 0) { + ERROR("sprint prefix prefix failed"); + return NULL; + } + + // Strip docker.io/library + size = strlen(prefix); + if (strncmp(name, prefix, size) == 0 && strlen(name) > size) { + return util_strdup_s(name + size); + } + + // Strip docker.io + size = strlen(DEFAULT_HOSTNAME); + if (strncmp(name, DEFAULT_HOSTNAME, size) == 0 && strlen(name) > size) { + return util_strdup_s(name + size); + } + + return util_strdup_s(name); +} + +static void oci_strip_dockerio(const imagetool_image *image) +{ + char *repo_tag = NULL; + char *repo_digest = NULL; + size_t i = 0; + + if (image == NULL) { + return; + } + + for (i = 0; i < image->repo_tags_len; i++) { + repo_tag = image->repo_tags[i]; + image->repo_tags[i] = oci_strip_dockerio_prefix(repo_tag); + free(repo_tag); + repo_tag = NULL; + } + + for (i = 0; i < image->repo_digests_len; i++) { + repo_digest = image->repo_digests[i]; + image->repo_digests[i] = oci_strip_dockerio_prefix(repo_digest); + free(repo_digest); + repo_digest = NULL; + } + + return; +} + +int oci_get_user_conf(const char *basefs, host_config *hc, const char *userstr, oci_runtime_spec_process_user *puser) +{ + if (basefs == NULL || puser == NULL) { + ERROR("Empty basefs or puser"); + return -1; + } + return get_user(basefs, hc, userstr, puser); +} + +static int dup_oci_image_info(const imagetool_image *src, imagetool_image **dest) +{ + int ret = -1; + char *json = NULL; + parser_error err = NULL; + + if (src == NULL) { + *dest = NULL; + return 0; + } + + json = imagetool_image_generate_json(src, NULL, &err); + if (json == NULL) { + ERROR("Failed to generate json: %s", err); + goto out; + } + *dest = imagetool_image_parse_data(json, NULL, &err); + if (*dest == NULL) { + ERROR("Failed to parse json: %s", err); + goto out; + } + ret = 0; + +out: + free(err); + free(json); + return ret; +} + +static int oci_list_all_images(imagetool_images_list *images_list) +{ + int ret = 0; + size_t i = 0; + oci_image_t **images_info = NULL; + size_t images_num = 0; + + ret = oci_images_store_list(&images_info, &images_num); + if (ret != 0) { + ERROR("query all oci images info failed"); + return -1; + } + + if (images_num == 0) { + ret = 0; + goto out; + } + + images_list->images = util_smart_calloc_s(sizeof(imagetool_image *), images_num); + if (images_list->images == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + for (i = 0; i < images_num; i++) { + ret = dup_oci_image_info(images_info[i]->info, &images_list->images[i]); + if (ret != 0) { + ERROR("Failed to dup oci image %s info", images_info[i]->info->id); + ret = -1; + goto out; + } + oci_image_unref(images_info[i]); + images_list->images_len++; + } +out: + if (ret != 0) { + for (; i < images_num; i++) { + oci_image_unref(images_info[i]); + } + } + + free(images_info); + return ret; +} + +static bool image_meet_dangling_filter(const imagetool_image *src, const struct filters_args *filters) +{ + bool ret = false; + map_t *field_values_map = NULL; + const char *field = "dangling"; + map_itor *itor = NULL; + bool dangling_value = false; + + field_values_map = map_search(filters->fields, (void *)field); + if (field_values_map == NULL) { + return true; + } + + itor = map_itor_new(field_values_map); + if (itor == NULL) { + ERROR("Out of memory"); + return false; + } + + for (; map_itor_valid(itor); map_itor_next(itor)) { + if (strcmp(map_itor_key(itor), "true") == 0) { + dangling_value = true; + break; + } + } + + if (dangling_value) { + ret = src->repo_tags_len == 0; + } else { + ret = src->repo_tags_len != 0; + } + + map_itor_free(itor); + return ret; +} + +static int do_image_time_filter(map_itor *itor, bool is_before_filter, int64_t *cmp_nanos) +{ + int ret = 0; + oci_image_t *image_info = NULL; + int64_t tmp_nanos = 0; + char *tmp = oci_resolve_image_name(map_itor_key(itor)); + if (tmp == NULL) { + ERROR("Failed to resolve image name"); + goto out; + } + + image_info = oci_images_store_get(tmp); + if (image_info == NULL) { + ret = -1; + goto out; + } + free(tmp); + tmp = NULL; + + if (to_unix_nanos_from_str(image_info->info->created, &tmp_nanos) != 0) { + ERROR("Failed to get unix nano from string"); + ret = -1; + goto out; + } + oci_image_unref(image_info); + image_info = NULL; + + if (is_before_filter) { + if (*cmp_nanos > tmp_nanos) { + *cmp_nanos = tmp_nanos; + } + } else { + if (*cmp_nanos < tmp_nanos) { + *cmp_nanos = tmp_nanos; + } + } + +out: + oci_image_unref(image_info); + free(tmp); + return ret; +} + +static bool image_time_filter(const imagetool_image *src, const struct filters_args *filters, + const char *field) +{ + bool ret = false; + map_t *field_values_map = NULL; + map_itor *itor = NULL; + bool is_before_filter = true; + int64_t cmp_nanos; + int64_t tmp_nanos = 0; + + is_before_filter = (strcmp(field, "before") == 0); + cmp_nanos = is_before_filter ? INT64_MAX : 0; + + field_values_map = map_search(filters->fields, (void *)field); + if (field_values_map == NULL) { + return true; + } + + itor = map_itor_new(field_values_map); + if (itor == NULL) { + ERROR("Out of memory"); + return false; + } + + for (; map_itor_valid(itor); map_itor_next(itor)) { + if (do_image_time_filter(itor, is_before_filter, &cmp_nanos) != 0) { + goto out; + } + } + + if (to_unix_nanos_from_str(src->created, &tmp_nanos) != 0) { + ERROR("Failed to get unix nano from string"); + goto out; + } + + if (is_before_filter) { + if (tmp_nanos < cmp_nanos) { + ret = true; + } + } else { + if (tmp_nanos > cmp_nanos) { + ret = true; + } + } + +out: + map_itor_free(itor); + return ret; +} + +static bool image_meet_before_filter(const imagetool_image *src, const struct filters_args *filters) +{ + return image_time_filter(src, filters, "before"); +} + +static bool image_meet_since_filter(const imagetool_image *src, const struct filters_args *filters) +{ + return image_time_filter(src, filters, "since"); +} + +static bool image_meet_label_filter(const imagetool_image *src, const struct filters_args *filters) +{ + bool ret = false; + map_t *field_values_map = NULL; + const char *field = "label"; + map_itor *itor = NULL; + size_t i; + + field_values_map = map_search(filters->fields, (void *)field); + if (field_values_map == NULL) { + return true; + } + + if (src->spec->config == NULL || src->spec->config->labels == NULL) { + return false; + } + + itor = map_itor_new(field_values_map); + if (itor == NULL) { + ERROR("Out of memory"); + return false; + } + + for (; map_itor_valid(itor); map_itor_next(itor)) { + char *tmp_key = map_itor_key(itor); + if (tmp_key == NULL) { + ERROR("Invalid labels"); + ret = false; + goto out; + } + for (i = 0; i < src->spec->config->labels->len; i++) { + if (strcmp(tmp_key, src->spec->config->labels->keys[i]) == 0) { + ret = true; + goto out; + } + } + } + +out: + map_itor_free(itor); + return ret; +} + +static bool image_meet_reference_filter(const imagetool_image *src, const struct filters_args *filters) +{ + size_t i; + size_t len = src->repo_tags_len; + + map_t *field_values_map = map_search(filters->fields, (void *)"reference"); + if (field_values_map == NULL) { + return true; + } + + for (i = 0; i < len; i++) { + if (filters_args_match(filters, "reference", src->repo_tags[i])) { + return true; + } + } + + return false; +} + +static bool image_meet_filters(const imagetool_image *src, const struct filters_args *filters) +{ + return image_meet_dangling_filter(src, filters) && + image_meet_before_filter(src, filters) && + image_meet_since_filter(src, filters) && + image_meet_label_filter(src, filters) && + image_meet_reference_filter(src, filters); +} + +static int dup_oci_image_info_by_filters(oci_image_t *src, const struct filters_args *filters, + imagetool_images_list *images_list) +{ + int ret = 0; + char *json = NULL; + parser_error err = NULL; + imagetool_image **tmp_images = NULL; + imagetool_image *tmp_image = NULL; + size_t new_size, old_size; + + if (src == NULL || src->info == NULL) { + goto out; + } + + if (!image_meet_filters(src->info, filters)) { + goto out; + } + + json = imagetool_image_generate_json(src->info, NULL, &err); + if (json == NULL) { + ERROR("Failed to generate json: %s", err); + ret = -1; + goto out; + } + + tmp_image = imagetool_image_parse_data(json, NULL, &err); + if (tmp_image == NULL) { + ERROR("Failed to parse json: %s", err); + ret = -1; + goto out; + } + + if (images_list->images_len > SIZE_MAX / sizeof(imagetool_image *) - 1) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + new_size = (images_list->images_len + 1) * sizeof(imagetool_image *); + old_size = images_list->images_len * sizeof(imagetool_image *); + + ret = mem_realloc((void **)(&tmp_images), new_size, images_list->images, old_size); + if (ret != 0) { + ERROR("Failed to realloc memory for append images"); + ret = -1; + goto out; + } + images_list->images = tmp_images; + images_list->images[images_list->images_len] = tmp_image; + tmp_image = NULL; + images_list->images_len++; + + ret = 0; + +out: + free(err); + free(json); + free_imagetool_image(tmp_image); + return ret; +} + +static int oci_list_images_by_filters(struct filters_args *filters, imagetool_images_list *images_list) +{ + int ret = 0; + int nret; + size_t i = 0; + oci_image_t **images_info = NULL; + size_t images_num = 0; + + ret = oci_images_store_list(&images_info, &images_num); + if (ret != 0) { + ERROR("query all oci images info failed"); + return -1; + } + + if (images_num == 0) { + ret = 0; + goto out; + } + + for (i = 0; i < images_num; i++) { + nret = dup_oci_image_info_by_filters(images_info[i], filters, images_list); + if (nret != 0) { + WARN("Failed to dup oci image info"); + } + oci_image_unref(images_info[i]); + } + +out: + free(images_info); + return ret; +} + +static void oci_strip_all_dockerios(const imagetool_images_list *images) +{ + size_t i = 0; + + if (images == NULL) { + return; + } + + for (i = 0; i < images->images_len; i++) { + oci_strip_dockerio(images->images[i]); + } + + return; +} + +int oci_list_images(const im_list_request *request, imagetool_images_list **images) +{ + int ret = 0; + struct filters_args *image_filters = NULL; + + if (request != NULL && request->image_filters != NULL) { + image_filters = request->image_filters; + } + + *images = util_common_calloc_s(sizeof(imagetool_images_list)); + if (*images == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + if (image_filters != NULL) { + ret = oci_list_images_by_filters(image_filters, *images); + } else { + ret = oci_list_all_images(*images); + } + + oci_strip_all_dockerios(*images); + +out: + if (ret != 0) { + free_imagetool_images_list(*images); + *images = NULL; + } + return ret; +} + +int oci_status_image(im_status_request *request, im_status_response **response) +{ + int ret = 0; + imagetool_image_status *image = NULL; + char *image_ref = NULL; + oci_image_t *image_info = NULL; + char *resolved_name = NULL; + + if (*response == NULL) { + ERROR("Invalid arguments"); + return -1; + } + + image = util_common_calloc_s(sizeof(imagetool_image_status)); + if (image == NULL) { + ERROR("Out of memory"); + ret = -1; + goto pack_response; + } + (*response)->image_info = image; + + image_ref = request->image.image; + if (image_ref == NULL) { + ERROR("Inspect image requires image ref"); + lcrd_set_error_message("Inspect image requires image ref"); + ret = -1; + goto pack_response; + } + + resolved_name = oci_resolve_image_name(image_ref); + if (resolved_name == NULL) { + ERROR("Failed to reslove image name %s", image_ref); + lcrd_set_error_message("Failed to reslove image name %s", image_ref); + ret = -1; + goto pack_response; + } + + EVENT("Event: {Object: %s, Type: statusing image}", resolved_name); + + image_info = oci_images_store_get(resolved_name); + if (image_info == NULL) { + ERROR("No such image:%s", resolved_name); + lcrd_set_error_message("No such image:%s", resolved_name); + ret = -1; + goto pack_response; + } + + ret = dup_oci_image_info(image_info->info, &((*response)->image_info->image)); + oci_image_unref(image_info); + if (ret != 0) { + ERROR("Failed to dup image info:%s", resolved_name); + lcrd_set_error_message("Failed to dup image info:%s", resolved_name); + ret = -1; + goto pack_response; + } + + oci_strip_dockerio((*response)->image_info->image); + + EVENT("Event: {Object: %s, Type: statused image}", resolved_name); + +pack_response: + + free(resolved_name); + return ret; +} + +int oci_inspect_image(const im_inspect_request *im_request, char **inspected_json) +{ + int ret = 0; + im_status_request request; + im_status_response *response = NULL; + struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 }; + parser_error err = NULL; + + if (im_request == NULL || inspected_json == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + ret = memset_s(&request, sizeof(im_status_request), 0x00, sizeof(im_status_request)); + if (ret != EOK) { + ERROR("Failed to set memory"); + return -1; + } + request.image.image = im_request->image.image; + + response = (im_status_response *)util_common_calloc_s(sizeof(im_status_response)); + if (response == NULL) { + ERROR("Out of memory"); + goto out; + } + + ret = oci_status_image(&request, &response); + if (ret != 0) { + goto out; + } + + *inspected_json = imagetool_image_status_generate_json(response->image_info, &ctx, &err); + if (*inspected_json == NULL) { + ERROR("Failed to generate image status request json:%s", err); + ret = -1; + goto out; + } + +out: + free(err); + free_im_status_response(response); + return ret; +} + +imagetool_image *oci_get_image_info_by_name(const char *id) +{ + return isula_image_get_image_info_by_name(id); +} + +/* call low driver to get images list */ +int oci_get_all_images(const im_list_request *request, imagetool_images_list **images) +{ + return isula_list_images(request, images); +} + +int oci_image_conf_merge_into_spec(const char *image_name, oci_runtime_spec *oci_spec, + container_custom_config *custom_spec) +{ + int ret = 0; + oci_image_t *image_info = NULL; + char *resolved_name = NULL; + + if (oci_spec == NULL || image_name == NULL) { + ERROR("invalid NULL param"); + return -1; + } + + resolved_name = oci_resolve_image_name(image_name); + if (resolved_name == NULL) { + ERROR("Resolve external config image name failed, image name is %s", image_name); + ret = -1; + goto out; + } + + image_info = oci_images_store_get(resolved_name); + if (image_info == NULL) { + ERROR("Get image from image store failed, image name is %s", resolved_name); + ret = -1; + goto out; + } + + ret = oci_image_merge_config(image_info->info, oci_spec, custom_spec); + if (ret != 0) { + ERROR("Failed to merge oci config for image %s", resolved_name); + ret = -1; + goto out; + } + +out: + oci_image_unref(image_info); + free(resolved_name); + return ret; +} + diff --git a/src/image/oci/oci_common_operators.h b/src/image/oci/oci_common_operators.h new file mode 100644 index 0000000..0b42d73 --- /dev/null +++ b/src/image/oci/oci_common_operators.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. + * Author: liuhao + * Create: 2019-07-23 + * Description: provide image common function definition + ******************************************************************************/ +#ifndef __OCI_COMMON_OPERATORS_H +#define __OCI_COMMON_OPERATORS_H + +#include +#include "image.h" +#include "imagetool_image.h" +#include "oci_image_spec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int pack_storage_status_response(const char *stdout_buffer, im_storage_status_response *resp); +char *oci_normalize_image_name(const char *name); + +bool oci_detect(const char *image_name); +char *oci_resolve_image_name(const char *name); +int oci_get_user_conf(const char *basefs, host_config *hc, const char *userstr, oci_runtime_spec_process_user *puser); +int oci_list_images(const im_list_request *request, imagetool_images_list **images); +int oci_status_image(im_status_request *request, im_status_response **response); +int oci_inspect_image(const im_inspect_request *request, char **inspected_json); + +imagetool_image *oci_get_image_info_by_name(const char *id); +int oci_get_all_images(const im_list_request *request, imagetool_images_list **images); + +int oci_image_conf_merge_into_spec(const char *image_name, oci_runtime_spec *oci_spec, + container_custom_config *custom_spec); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/image/oci/oci_config_merge.c b/src/image/oci/oci_config_merge.c index fb1b2e5..957a2da 100644 --- a/src/image/oci/oci_config_merge.c +++ b/src/image/oci/oci_config_merge.c @@ -57,12 +57,7 @@ static int do_duplicate_commands(const oci_image_spec_config *config, container_ return 0; } - if (config->cmd_len > SIZE_MAX / sizeof(char *)) { - ERROR("too many commands!"); - return -1; - } - - custom_spec->cmd = (char **)util_common_calloc_s(sizeof(char *) * config->cmd_len); + custom_spec->cmd = (char **)util_smart_calloc_s(sizeof(char *), config->cmd_len); if (custom_spec->cmd == NULL) { ERROR("Out of memory"); return -1; @@ -84,12 +79,7 @@ static int do_duplicate_entrypoints(const oci_image_spec_config *config, contain return 0; } - if (config->entrypoint_len > SIZE_MAX / sizeof(char *)) { - ERROR("too many entrypoints!"); - return -1; - } - - custom_spec->entrypoint = (char **)util_common_calloc_s(sizeof(char *) * config->entrypoint_len); + custom_spec->entrypoint = (char **)util_smart_calloc_s(sizeof(char *), config->entrypoint_len); if (custom_spec->entrypoint == NULL) { ERROR("Out of memory"); return -1; @@ -156,13 +146,7 @@ static int dup_health_check_from_image(const defs_health_check *image_health_che return -1; } - if (image_health_check->test_len > SIZE_MAX / sizeof(char *)) { - ERROR("invalid health check commands!"); - ret = -1; - goto out; - } - - health_check->test = util_common_calloc_s(sizeof(char *) * image_health_check->test_len); + health_check->test = util_smart_calloc_s(sizeof(char *), image_health_check->test_len); if (health_check->test == NULL) { ERROR("Out of memory"); ret = -1; @@ -194,11 +178,7 @@ static int update_health_check_from_image(const defs_health_check *image_health_ if (custom_spec->health_check->test_len == 0) { size_t i; - if (image_health_check->test_len > SIZE_MAX / sizeof(char *)) { - ERROR("invalid health check commands!"); - return -1; - } - custom_spec->health_check->test = util_common_calloc_s(sizeof(char *) * image_health_check->test_len); + custom_spec->health_check->test = util_smart_calloc_s(sizeof(char *), image_health_check->test_len); if (custom_spec->health_check->test == NULL) { ERROR("Out of memory"); return -1; diff --git a/src/image/oci/oci_config_merge.h b/src/image/oci/oci_config_merge.h index 7fb8a2a..414ff4b 100644 --- a/src/image/oci/oci_config_merge.h +++ b/src/image/oci/oci_config_merge.h @@ -32,3 +32,4 @@ int oci_image_merge_config(imagetool_image *image_conf, oci_runtime_spec *oci_sp #endif #endif + diff --git a/src/image/oci/oci_container_fs_usage.c b/src/image/oci/oci_container_fs_usage.c deleted file mode 100644 index e04b9b8..0000000 --- a/src/image/oci/oci_container_fs_usage.c +++ /dev/null @@ -1,76 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci image fs functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include "oci_container_fs_usage.h" -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "oci_fs_info.h" -#include "log.h" -#include "utils.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" -#include "oci_rootfs_prepare.h" - -bool do_oci_container_fs_info(char *id, imagetool_fs_info **fs_info) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - parser_error err = NULL; - - if (id == NULL || fs_info == NULL) { - ERROR("Invalid input arguments"); - return false; - } - - command_ret = util_exec_cmd(execute_container_fs_info, id, NULL, &stdout_buffer, &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to get container fs info with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to container fs info with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec inspect fs info command"); - lcrd_set_error_message("Failed to exec inspect fs info command"); - } - goto free_out; - } - - if (stdout_buffer == NULL) { - ERROR("Failed to get container filesystem info becase can not get stdoutput"); - lcrd_set_error_message("Failed to get container filesystem info becase can not get stdoutput"); - goto free_out; - } - - *fs_info = imagetool_fs_info_parse_data(stdout_buffer, NULL, &err); - if (*fs_info == NULL) { - ERROR("Failed to parse output json:%s", err); - lcrd_set_error_message("Failed to parse output json:%s", err); - goto free_out; - } - - ret = true; - -free_out: - free(err); - free(stdout_buffer); - free(stderr_buffer); - return ret; -} diff --git a/src/image/oci/oci_fs_info.c b/src/image/oci/oci_fs_info.c deleted file mode 100644 index 7884b84..0000000 --- a/src/image/oci/oci_fs_info.c +++ /dev/null @@ -1,119 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci image fs functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "oci_fs_info.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" - -static bool do_fs_info(imagetool_fs_info **fs_info) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - parser_error err = NULL; - - command_ret = util_exec_cmd(execute_fs_info, NULL, NULL, &stdout_buffer, &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to get image fs info with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to image fs info with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec inspect fs info command"); - lcrd_set_error_message("Failed to exec inspect fs info command"); - } - goto free_out; - } - - if (stdout_buffer == NULL) { - ERROR("Failed to get image filesystem info becase can not get stdoutput"); - lcrd_set_error_message("Failed to get image filesystem info becase can not get stdoutput"); - goto free_out; - } - - *fs_info = imagetool_fs_info_parse_data(stdout_buffer, NULL, &err); - if (*fs_info == NULL) { - ERROR("Failed to parse output json:%s", err); - lcrd_set_error_message("Failed to parse output json:%s", err); - goto free_out; - } - - ret = true; - -free_out: - free(err); - free(stderr_buffer); - free(stdout_buffer); - return ret; -} - - -int get_fs_info(image_fs_info_response **response) -{ - int ret = 0; - imagetool_fs_info *fs_info = NULL; - - if (response == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - *response = util_common_calloc_s(sizeof(image_fs_info_response)); - if (*response == NULL) { - ERROR("Out of memory"); - return -1; - } - - EVENT("Event: {Object: sysinfo, Type: inspecting}"); - - if (!do_fs_info(&fs_info)) { - ERROR("Failed to inspect image filesystem info"); - ret = -1; - goto pack_response; - } - EVENT("Event: {Object: sysinfo, Type: inspected}"); - -pack_response: - if (g_lcrd_errmsg != NULL) { - (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); - } - - (*response)->fs_info = fs_info; - - return ret; -} - -void free_image_fs_info_response(image_fs_info_response *ptr) -{ - if (ptr == NULL) { - return; - } - free_imagetool_fs_info(ptr->fs_info); - ptr->fs_info = NULL; - free(ptr->errmsg); - ptr->errmsg = NULL; - - free(ptr); -} - diff --git a/src/image/oci/oci_fs_info.h b/src/image/oci/oci_fs_info.h deleted file mode 100644 index 0494e82..0000000 --- a/src/image/oci/oci_fs_info.h +++ /dev/null @@ -1,39 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci image fs functions - ******************************************************************************/ - -#ifndef __OCI_FS_INFO_H_ -#define __OCI_FS_INFO_H_ - -#include "oci_image_type.h" -#include "imagetool_fs_info.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - imagetool_fs_info *fs_info; - char *errmsg; -} image_fs_info_response; - -int get_fs_info(image_fs_info_response **response); - -void free_image_fs_info_response(image_fs_info_response *ptr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/image/oci/oci_image.c b/src/image/oci/oci_image.c deleted file mode 100644 index f6ad1fa..0000000 --- a/src/image/oci/oci_image.c +++ /dev/null @@ -1,732 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide image function definition - ******************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "utils.h" -#include "securec.h" -#include "oci_images_store.h" -#include "oci_image.h" -#include "oci_rootfs_prepare.h" -#include "oci_rootfs_mount.h" -#include "oci_rootfs_umount.h" -#include "oci_rootfs_remove.h" -#include "oci_config_merge.h" -#include "oci_container_fs_usage.h" -#include "oci_image_pull.h" -#include "specs_extend.h" - -static int oci_image_prepare_rootfs(const char *image, const char *name, const json_map_string_string *storage_opt, - rootfs_prepare_and_get_image_conf_response **response) -{ - int ret = 0; - rootfs_prepare_request *request = NULL; - - if (image == NULL || name == NULL) { - ERROR("Invalid input arguments"); - ret = -1; - goto out; - } - - request = util_common_calloc_s(sizeof(rootfs_prepare_request)); - if (request == NULL) { - ERROR("Memory out"); - ret = -1; - goto out; - } - - request->image = util_strdup_s(image); - request->name = util_strdup_s(name); - request->id = util_strdup_s(name); - if (map_to_key_value_string(storage_opt, &request->storage_opts, &request->storage_opts_len) != 0) { - ret = -1; - goto out; - } - - ret = prepare_rootfs_and_get_image_conf(request, response); - if (ret != 0) { - ERROR("Failed to prepare rootfs for %s with image %s", name, image); - ret = -1; - goto out; - } - -out: - free_rootfs_prepare_request(request); - return ret; -} - -static int oci_image_mount_rootfs(const char *name) -{ - int ret = 0; - rootfs_mount_request *request = NULL; - rootfs_mount_response *response = NULL; - - if (name == NULL) { - ERROR("Invalid input arguments"); - ret = -1; - goto out; - } - - request = util_common_calloc_s(sizeof(rootfs_mount_request)); - if (request == NULL) { - ERROR("Memory out"); - ret = -1; - goto out; - } - - request->name_id = util_strdup_s(name); - - ret = mount_rootfs(request, &response); - if (ret != 0 || response == NULL) { - ERROR("Failed to mount rootfs for %s", name); - ret = -1; - goto out; - } - -out: - free_rootfs_mount_request(request); - free_rootfs_mount_response(response); - return ret; -} - -static int oci_image_umount_rootfs(const char *name) -{ - int ret = 0; - rootfs_umount_request *request = NULL; - rootfs_umount_response *response = NULL; - - if (name == NULL) { - ERROR("Invalid input arguments"); - ret = -1; - goto out; - } - - request = util_common_calloc_s(sizeof(rootfs_umount_request)); - if (request == NULL) { - ERROR("Memory out"); - ret = -1; - goto out; - } - - request->name_id = util_strdup_s(name); - - ret = umount_rootfs(request, &response); - if (ret != 0) { - ERROR("Failed to umount rootfs for %s", name); - ret = -1; - goto out; - } - -out: - free_rootfs_umount_request(request); - free_rootfs_umount_response(response); - return ret; -} - -static int oci_image_remove_rootfs(const char *name) -{ - int ret = 0; - rootfs_remove_request *request = NULL; - rootfs_remove_response *response = NULL; - - if (name == NULL) { - ERROR("Invalid input arguments"); - ret = -1; - goto out; - } - - request = util_common_calloc_s(sizeof(rootfs_remove_request)); - if (request == NULL) { - ERROR("Memory out"); - ret = -1; - goto out; - } - - request->name_id = util_strdup_s(name); - - ret = remove_rootfs(request, &response); - if (ret != 0) { - ERROR("Failed to remove rootfs for %s", name); - ret = -1; - goto out; - } - -out: - free_rootfs_remove_request(request); - free_rootfs_remove_response(response); - return ret; -} - -static bool oci_image_exist(const char *image_name) -{ - bool ret = false; - oci_image_t *image_info = NULL; - - image_info = oci_images_store_get(image_name); - if (image_info != NULL) { - ret = true; - oci_image_unref(image_info); - } - - return ret; -} - -bool oci_detect(const char *image_name) -{ - if (image_name == NULL) { - return false; - } - - return oci_image_exist(image_name); -} - -int oci_filesystem_usage(struct bim *bim, imagetool_fs_info **fs_usage) -{ - int ret = 0; - imagetool_fs_info *container_fs_usage = NULL; - - if (bim == NULL || fs_usage == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - EVENT("Event: {Object: sysinfo, Type: inspecting}"); - - if (!do_oci_container_fs_info(bim->container_id, &container_fs_usage)) { - ERROR("Failed to inspect cotainer filesystem info"); - ret = -1; - goto pack_response; - } - - EVENT("Event: {Object: sysinfo, Type: inspected}"); - -pack_response: - *fs_usage = container_fs_usage; - - return ret; -} - -int oci_prepare_and_get_conf_rf(struct bim *bim, const json_map_string_string *storage_opt, - rootfs_prepare_and_get_image_conf_response **response) -{ - return oci_image_prepare_rootfs(bim->image_name, bim->container_id, storage_opt, response); -} - -int oci_prepare_rf(struct bim *bim, const json_map_string_string *storage_opt, char **real_rootfs) -{ - int ret = 0; - rootfs_prepare_and_get_image_conf_response *response = NULL; - - if (bim == NULL || real_rootfs == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - ret = oci_image_prepare_rootfs(bim->image_name, bim->container_id, storage_opt, &response); - if (ret == 0) { - *real_rootfs = response->raw_response->mount_point; - response->raw_response->mount_point = NULL; - } - free_rootfs_prepare_and_get_image_conf_response(response); - return ret; -} - -int oci_mount_rf(struct bim *bim) -{ - return oci_image_mount_rootfs(bim->container_id); -} - -int oci_umount_rf(struct bim *bim) -{ - return oci_image_umount_rootfs(bim->container_id); -} - -int oci_delete_rf(struct bim *bim) -{ - return oci_image_remove_rootfs(bim->container_id); -} - -// normalize the unqualified image to be domain/repo/image... -char *oci_normalize_image_name(const char *name) -{ -#define DEFAULT_TAG ":latest" -#define DEFAULT_HOSTNAME "docker.io/" -#define DEFAULT_REPO_PREFIX "library/" - - char temp[PATH_MAX] = { 0 }; - - - if (strstr(name, "/") == NULL) { - if (sprintf_s(temp, sizeof(temp), "%s%s", DEFAULT_HOSTNAME, DEFAULT_REPO_PREFIX) < 0) { - ERROR("sprint temp image name failed"); - return NULL; - } - } - - if (sprintf_s(temp + strlen(temp), sizeof(temp) - strlen(temp), "%s", name) < 0) { - ERROR("sprint temp image name failed"); - return NULL; - } - - if (util_tag_pos(name) == NULL) { - if (sprintf_s(temp + strlen(temp), sizeof(temp) - strlen(temp), "%s", DEFAULT_TAG) < 0) { - ERROR("sprint temp image name failed"); - return NULL; - } - } - - return util_strdup_s(temp); -} - -char *oci_resolve_image_name(const char *name) -{ - if (util_valid_short_sha256_id(name) && oci_image_exist(name)) { - return util_strdup_s(name); - } - - return oci_normalize_image_name(name); -} - -static int merge_oci_image_conf(const char *image_name, oci_runtime_spec *oci_spec, - container_custom_config *custom_spec) -{ - int ret = 0; - oci_image_t *image_info = NULL; - char *resolved_name = NULL; - - if (oci_spec == NULL || image_name == NULL) { - ERROR("invalid NULL param"); - return -1; - } - - resolved_name = oci_resolve_image_name(image_name); - if (resolved_name == NULL) { - ERROR("Resolve external config image name failed, image name is %s", image_name); - ret = -1; - goto out; - } - - image_info = oci_images_store_get(resolved_name); - if (image_info == NULL) { - ERROR("Get image from image store failed, image name is %s", resolved_name); - ret = -1; - goto out; - } - - ret = oci_image_merge_config(image_info->info, oci_spec, custom_spec); - if (ret != 0) { - ERROR("Failed to merge oci config for image %s", resolved_name); - ret = -1; - goto out; - } - -out: - oci_image_unref(image_info); - free(resolved_name); - resolved_name = NULL; - return ret; -} - - -int oci_merge_conf(oci_runtime_spec *oci_spec, const host_config *host_spec, container_custom_config *custom_spec, - struct bim *bim, char **real_rootfs) -{ - int ret = 0; - int nret = 0; - rootfs_prepare_and_get_image_conf_response *response = NULL; - - nret = oci_prepare_and_get_conf_rf(bim, host_spec->storage_opt, &response); - if (nret != 0) { - ret = nret; - goto free_out; - } - - nret = merge_oci_image_conf(bim->image_name, oci_spec, custom_spec); - if (nret != 0) { - ret = nret; - goto free_out; - } - - - *real_rootfs = response->raw_response->mount_point; - response->raw_response->mount_point = NULL; - -free_out: - free_rootfs_prepare_and_get_image_conf_response(response); - return ret; -} - -int oci_get_user_conf(const char *basefs, host_config *hc, const char *userstr, oci_runtime_spec_process_user *puser) -{ - if (basefs == NULL || puser == NULL) { - ERROR("Empty basefs or puser"); - return -1; - } - return get_user(basefs, hc, userstr, puser); -} - -static int dup_oci_image_info(const imagetool_image *src, imagetool_image **dest) -{ - int ret = -1; - char *json = NULL; - parser_error err = NULL; - - if (src == NULL) { - *dest = NULL; - return 0; - } - - json = imagetool_image_generate_json(src, NULL, &err); - if (json == NULL) { - ERROR("Failed to generate json: %s", err); - goto out; - } - *dest = imagetool_image_parse_data(json, NULL, &err); - if (*dest == NULL) { - ERROR("Failed to parse json: %s", err); - goto out; - } - ret = 0; - -out: - free(err); - free(json); - return ret; -} - -static int oci_list_all_images(imagetool_images_list *images_list) -{ - int ret = 0; - size_t i = 0; - oci_image_t **images_info = NULL; - size_t images_num = 0; - - ret = oci_images_store_list(&images_info, &images_num); - if (ret != 0) { - ERROR("query all oci images info failed"); - return -1; - } - - if (images_num == 0) { - ret = 0; - goto out; - } - - if (images_num > (SIZE_MAX / sizeof(imagetool_image *))) { - ERROR("Get too many images:%d", images_num); - ret = -1; - goto out; - } - - images_list->images = util_common_calloc_s(images_num * sizeof(imagetool_image *)); - if (images_list->images == NULL) { - ERROR("Out of memory"); - ret = -1; - goto out; - } - - for (i = 0; i < images_num; i++) { - ret = dup_oci_image_info(images_info[i]->info, &images_list->images[i]); - if (ret != 0) { - ERROR("Failed to dup oci image %s info", images_info[i]->info->id); - ret = -1; - goto out; - } - oci_image_unref(images_info[i]); - images_list->images_len++; - } -out: - if (ret != 0) { - for (; i < images_num; i++) { - oci_image_unref(images_info[i]); - } - } - - free(images_info); - return ret; -} - -static int oci_list_images_by_filter(const char *filter, imagetool_images_list *images_list) -{ - int ret = 0; - char *tmp = NULL; - oci_image_t *image_info = NULL; - - tmp = oci_resolve_image_name(filter); - if (tmp == NULL) { - ERROR("Failed to resolve image name"); - ret = -1; - goto out; - } - - image_info = oci_images_store_get(tmp); - if (image_info == NULL) { - ret = 0; - goto out; - } - - images_list->images = util_common_calloc_s(1 * sizeof(imagetool_image *)); - if (images_list->images == NULL) { - oci_image_unref(image_info); - ERROR("Out of memory"); - ret = -1; - goto out; - } - - ret = dup_oci_image_info(image_info->info, &images_list->images[0]); - oci_image_unref(image_info); - if (ret != 0) { - ERROR("Failed to dup oci image %s info", tmp); - ret = -1; - goto out; - } - images_list->images_len++; - -out: - free(tmp); - return ret; -} - -int oci_list_images(im_list_request *request, imagetool_images_list **images) -{ - int ret = 0; - char *filter = NULL; - - if (request != NULL && request->filter.image.image != NULL) { - filter = request->filter.image.image; - } - - *images = util_common_calloc_s(sizeof(imagetool_images_list)); - if (*images == NULL) { - ERROR("Out of memory"); - ret = -1; - goto out; - } - - if (filter != NULL) { - ret = oci_list_images_by_filter(filter, *images); - } else { - ret = oci_list_all_images(*images); - } - - if (ret != 0) { - goto out; - } - -out: - if (ret != 0) { - free_imagetool_images_list(*images); - *images = NULL; - } - return ret; -} - -int oci_status_image(oci_image_status_request *request, oci_image_status_response **response) -{ - int ret = 0; - imagetool_image_status *image = NULL; - char *image_ref = NULL; - oci_image_t *image_info = NULL; - char *resolved_name = NULL; - - *response = util_common_calloc_s(sizeof(oci_image_status_response)); - if (*response == NULL) { - ERROR("Out of memory"); - return -1; - } - - image = util_common_calloc_s(sizeof(imagetool_image_status)); - if (image == NULL) { - ERROR("Out of memory"); - ret = -1; - goto pack_response; - } - (*response)->image_info = image; - - image_ref = request->image.image; - if (image_ref == NULL) { - ERROR("Inspect image requires image ref"); - lcrd_set_error_message("Inspect image requires image ref"); - ret = -1; - goto pack_response; - } - - resolved_name = oci_resolve_image_name(image_ref); - if (resolved_name == NULL) { - ERROR("Failed to reslove image name %s", image_ref); - lcrd_set_error_message("Failed to reslove image name %s", image_ref); - ret = -1; - goto pack_response; - } - - EVENT("Event: {Object: %s, Type: statusing image}", resolved_name); - - image_info = oci_images_store_get(resolved_name); - if (image_info == NULL) { - ERROR("No such image:%s", resolved_name); - lcrd_set_error_message("No such image:%s", resolved_name); - ret = -1; - goto pack_response; - } - - ret = dup_oci_image_info(image_info->info, &((*response)->image_info->image)); - oci_image_unref(image_info); - if (ret != 0) { - ERROR("Failed to dup image info:%s", resolved_name); - lcrd_set_error_message("Failed to dup image info:%s", resolved_name); - ret = -1; - goto pack_response; - } - - EVENT("Event: {Object: %s, Type: statused image}", resolved_name); - -pack_response: - if (g_lcrd_errmsg != NULL) { - (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); - } - free(resolved_name); - - return ret; -} - -int oci_inspect_image(struct bim *bim, char **inspected_json) -{ - int ret = 0; - oci_image_status_request request; - oci_image_status_response *response = NULL; - struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 }; - parser_error err = NULL; - - if (bim == NULL || inspected_json == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - ret = memset_s(&request, sizeof(oci_image_status_request), 0x00, sizeof(oci_image_status_request)); - if (ret != EOK) { - ERROR("Failed to set memory"); - return -1; - } - request.image.image = bim->image_name; - - ret = oci_status_image(&request, &response); - if (ret != 0) { - goto out; - } - - *inspected_json = imagetool_image_status_generate_json(response->image_info, &ctx, &err); - if (*inspected_json == NULL) { - ERROR("Failed to generate image status request json:%s", err); - ret = -1; - goto out; - } - -out: - free(err); - free_oci_image_status_response(response); - return ret; -} - -static int im_request_to_oci_request(const im_pull_request *req, image_pull_request **oci_req) -{ - *oci_req = util_common_calloc_s(sizeof(image_pull_request)); - if (*oci_req == NULL) { - ERROR("Out of memory"); - return -1; - } - (*oci_req)->image.image = util_strdup_s(req->image); - - if (req->username != NULL) { - (*oci_req)->auth.username = util_strdup_s(req->username); - } - if (req->password != NULL) { - (*oci_req)->auth.password = util_strdup_s(req->password); - } - if (req->auth != NULL) { - (*oci_req)->auth.auth = util_strdup_s(req->auth); - } - if (req->server_address != NULL) { - (*oci_req)->auth.server_address = util_strdup_s(req->server_address); - } - if (req->identity_token != NULL) { - (*oci_req)->auth.identity_token = util_strdup_s(req->identity_token); - } - if (req->registry_token != NULL) { - (*oci_req)->auth.registry_token = util_strdup_s(req->registry_token); - } - - return 0; -} - -int oci_pull_image(const im_pull_request *request, im_pull_response **response) -{ - int ret = -1; - image_pull_response *oci_resp = NULL; - image_pull_request *oci_req = NULL; - - ret = im_request_to_oci_request(request, &oci_req); - if (ret != 0) { - goto free_out; - } - - ret = pull_image(oci_req, &oci_resp); - if (ret != 0) { - ERROR("Pull image failed: %s", oci_resp->errmsg); - goto free_out; - } - *response = util_common_calloc_s(sizeof(im_pull_response)); - if (*response == NULL) { - ret = -1; - ERROR("Out of memory"); - goto free_out; - } - (*response)->image_ref = util_strdup_s(oci_resp->image_ref); - (*response)->errmsg = util_strdup_s(oci_resp->errmsg); - -free_out: - free_image_pull_request(oci_req); - free_image_pull_response(oci_resp); - return ret; -} - -int oci_init(const char *rootpath) -{ - int ret = 0; - - ret = oci_images_store_init(); - if (ret != 0) { - ERROR("Failed to init oci images store"); - goto out; - } - - ret = image_name_id_init(); - if (ret != 0) { - ERROR("Failed to init oci name id store"); - goto out; - } - - ret = load_all_oci_images(); - -out: - return ret; -} - diff --git a/src/image/oci/oci_image.h b/src/image/oci/oci_image.h deleted file mode 100644 index 5dc0cf3..0000000 --- a/src/image/oci/oci_image.h +++ /dev/null @@ -1,53 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide image function definition - ******************************************************************************/ -#ifndef __OCI_IMAGE_H -#define __OCI_IMAGE_H - -#include -#include "image.h" -#include "oci_image_spec.h" -#include "oci_image_status.h" - -#ifdef __cplusplus -extern "C" { -#endif - -bool oci_detect(const char *image_name); -int oci_filesystem_usage(struct bim *bim, imagetool_fs_info **fs_usage); - -int oci_prepare_rf(struct bim *bim, const json_map_string_string *storage_opt, char **real_rootfs); -int oci_mount_rf(struct bim *bim); -int oci_umount_rf(struct bim *bim); -int oci_delete_rf(struct bim *bim); -char *oci_resolve_image_name(const char *name); -char *oci_normalize_image_name(const char *name); - -int oci_merge_conf(oci_runtime_spec *oci_spec, const host_config *host_spec, container_custom_config *custom_spec, - struct bim *bim, char **real_rootfs); -int oci_get_user_conf(const char *basefs, host_config *hc, const char *userstr, oci_runtime_spec_process_user *puser); -int oci_list_images(im_list_request *request, imagetool_images_list **images); -int oci_remove_image(im_remove_request *request); -int oci_status_image(oci_image_status_request *request, oci_image_status_response **response); -int oci_inspect_image(struct bim *bim, char **inspected_json); -int oci_pull_image(const im_pull_request *request, im_pull_response **response); - -int oci_init(const char *rootpath); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/image/oci/oci_image_load.c b/src/image/oci/oci_image_load.c deleted file mode 100644 index 51d7f45..0000000 --- a/src/image/oci/oci_image_load.c +++ /dev/null @@ -1,170 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: wangfengtu - * Create: 2019-04-09 - * Description: provide oci load image functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include "oci_image_load.h" -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" -#include "oci_images_store.h" -#include "image.h" - -const int stdout_buffer_max_size = 10 * SIZE_MB; /* 10M */ - -static char *get_ref_from_stdout_buffer(const char *stdout_buffer) -{ - char *ref = NULL; - size_t len = 0; - char *key_word = "Loaded image: "; - - ref = strstr(stdout_buffer, key_word); - if (ref == NULL) { - return NULL; - } - - /* skip key word */ - ref += strlen(key_word); - - /* +1 for '\n' and +1 for terminator */ - len = strnlen(ref, (size_t)(MAX_IMAGE_REF_LEN + 2)); - if (len == 0 || len > MAX_IMAGE_REF_LEN) { - return NULL; - } - - /* strip '\n' */ - ref[len - 1] = 0; - - return util_strdup_s(ref); -} - -static bool do_load(im_load_request *request, char **ref) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - char *tmp_stdout_buffer = NULL; - - command_ret = util_exec_cmd(execute_load_image, request, NULL, &stdout_buffer, &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to load image with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to load image with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec load image command"); - lcrd_set_error_message("Failed to exec load image command"); - } - goto free_out; - } - - if (stdout_buffer == NULL) { - ERROR("Failed to load image because can not get stdoutput"); - lcrd_set_error_message("Failed to load image because can not get stdoutput"); - goto free_out; - } - - if (strnlen(stdout_buffer, (size_t)(stdout_buffer_max_size + 1)) > (size_t)stdout_buffer_max_size) { - ERROR("Failed to load image because stdoutput exceeded max size"); - lcrd_set_error_message("Failed to load image because stdoutput exceeded max size"); - goto free_out; - } - - /* get_ref_from_stdout_buffer will modify stdout_buffer, get a copy to do this because - we want to print original buffer if get reference failed. */ - tmp_stdout_buffer = util_strdup_s(stdout_buffer); - *ref = get_ref_from_stdout_buffer(tmp_stdout_buffer); - if (*ref == NULL) { - ERROR("Failed to load image because cann't get image reference from stdout buffer." - "stdout buffer is [%s]", - stdout_buffer); - lcrd_set_error_message("Failed to load image because cann't get image reference from stdout buffer"); - goto free_out; - } - - ret = true; - -free_out: - free(stderr_buffer); - free(stdout_buffer); - free(tmp_stdout_buffer); - return ret; -} - -static int check_load_request_valid(const im_load_request *request) -{ - int ret = -1; - - if (request == NULL) { - ERROR("invalid load request"); - lcrd_set_error_message("invalid load request"); - goto out; - } - - if (request->file == NULL) { - ERROR("Load image requires input file path"); - lcrd_set_error_message("Load image requires input file path"); - goto out; - } - - if (request->tag != NULL) { - if (util_valid_image_name(request->tag) != true) { - ERROR("Invalid tag %s", request->tag); - lcrd_try_set_error_message("Invalid tag:%s", request->tag); - goto out; - } - } - - ret = 0; - -out: - return ret; -} - -int oci_load_image(im_load_request *request) -{ - int ret = 0; - char *ref = NULL; - - if (check_load_request_valid(request) != 0) { - ret = -1; - goto pack_response; - } - - if (!do_load(request, &ref)) { - ERROR("Failed to load image"); - ret = -1; - goto pack_response; - } - - ret = register_new_oci_image_into_memory(ref); - if (ret != 0) { - ERROR("Failed to register new image to images store"); - ret = -1; - goto pack_response; - } - -pack_response: - free(ref); - ref = NULL; - - return ret; -} diff --git a/src/image/oci/oci_image_pull.c b/src/image/oci/oci_image_pull.c deleted file mode 100644 index c646ae8..0000000 --- a/src/image/oci/oci_image_pull.c +++ /dev/null @@ -1,190 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci image pull functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "oci_images_store.h" -#include "oci_image_pull.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" -#include "oci_image.h" -#include "imagetool_auth_input.h" -#include "oci_auth.h" - -static bool do_pull(image_pull_request *request, char **image_ref) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - char *stdin_buffer = NULL; - - stdin_buffer = pack_input_auth_string(&request->auth); - if (stdin_buffer == NULL) { - ERROR("Failed to generate image auth info"); - lcrd_set_error_message("Failed to generate image auth info"); - goto free_out; - } - - command_ret = util_exec_cmd(execute_pull_image, request, stdin_buffer, &stdout_buffer, - &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to pull image with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to pull image with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec pull image command"); - lcrd_set_error_message("Failed to exec pull image command"); - } - goto free_out; - } - - if (stdout_buffer != NULL) { - INFO("Pulled image with ref: %s", stdout_buffer); - *image_ref = util_strdup_s(stdout_buffer); - } else { - ERROR("Failed to pull image ref becase can't get image ref"); - lcrd_set_error_message("Failed to pull image ref becase can't get image ref"); - goto free_out; - } - - ret = true; - -free_out: - free_sensitive_string(stdin_buffer); - free(stderr_buffer); - free(stdout_buffer); - return ret; -} - -int pull_image(image_pull_request *request, image_pull_response **response) -{ - int ret = 0; - char *tmp = NULL; - char *image_ref = NULL; - char *normalized_ref = NULL; - - if (request == NULL || response == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - if (request->image.image == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - *response = util_common_calloc_s(sizeof(image_pull_response)); - if (*response == NULL) { - ERROR("Out of memory"); - return -1; - } - - /* Max length should include the ":latest" which may not provided when - * pulling image, so we need to normalize image name before checking it. */ - normalized_ref = oci_normalize_image_name(request->image.image); - if (!util_valid_image_name(normalized_ref)) { - ERROR("Invalid image name %s", normalized_ref); - ret = -1; - lcrd_try_set_error_message("Invalid image name:%s", normalized_ref); - goto pack_response; - } - - tmp = oci_resolve_image_name(request->image.image); - if (tmp == NULL) { - ERROR("Failed to resolve image name"); - ret = -1; - goto pack_response; - } - free(request->image.image); - request->image.image = tmp; - - set_log_prefix(request->image.image); - - EVENT("Event: {Object: %s, Type: Pulling}", request->image.image); - - if (!do_pull(request, &image_ref)) { - ERROR("Failed to pull image"); - ret = -1; - goto pack_response; - } - - ret = register_new_oci_image_into_memory(request->image.image); - if (ret != 0) { - ERROR("Failed to register new image to images store"); - ret = -1; - goto pack_response; - } - - EVENT("Event: {Object: %s, Type: Pulled}", request->image.image); - -pack_response: - if (g_lcrd_errmsg != NULL) { - (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); - } - if (image_ref != NULL) { - (*response)->image_ref = util_strdup_s(image_ref); - free(image_ref); - } - - free(normalized_ref); - - free_log_prefix(); - return ret; -} - -void free_image_pull_request(image_pull_request *ptr) -{ - if (ptr == NULL) { - return; - } - free(ptr->image.image); - ptr->image.image = NULL; - free_sensitive_string(ptr->auth.username); - ptr->auth.username = NULL; - free_sensitive_string(ptr->auth.password); - ptr->auth.password = NULL; - free_sensitive_string(ptr->auth.auth); - ptr->auth.auth = NULL; - free_sensitive_string(ptr->auth.server_address); - ptr->auth.server_address = NULL; - free_sensitive_string(ptr->auth.identity_token); - ptr->auth.identity_token = NULL; - free_sensitive_string(ptr->auth.registry_token); - ptr->auth.registry_token = NULL; - - free(ptr); -} - -void free_image_pull_response(image_pull_response *ptr) -{ - if (ptr == NULL) { - return; - } - free(ptr->image_ref); - ptr->image_ref = NULL; - free(ptr->errmsg); - ptr->errmsg = NULL; - - free(ptr); -} - diff --git a/src/image/oci/oci_image_pull.h b/src/image/oci/oci_image_pull.h deleted file mode 100644 index 3b8fe87..0000000 --- a/src/image/oci/oci_image_pull.h +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci image pull functions - ******************************************************************************/ - -#ifndef __OCI_IMAGE_PULL_H_ -#define __OCI_IMAGE_PULL_H_ - -#include "oci_image_type.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - image_spec image; - auth_config auth; -} image_pull_request; - -typedef struct { - // Reference to the image in use. For most runtimes, this should be an - // image ID or digest. - char *image_ref; - char *errmsg; -} image_pull_response; - -int pull_image(image_pull_request *request, image_pull_response **response); - -void free_image_pull_request(image_pull_request *ptr); - -void free_image_pull_response(image_pull_response *ptr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/image/oci/oci_image_remove.c b/src/image/oci/oci_image_remove.c deleted file mode 100644 index 905cf4b..0000000 --- a/src/image/oci/oci_image_remove.c +++ /dev/null @@ -1,105 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci image remove functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "utils.h" -#include "log.h" -#include "image.h" -#include "oci_images_store.h" -#include "isula_imtool_interface.h" -#include "oci_image.h" - -#define IMAGE_NOT_KNOWN_ERR "image not known" - -int oci_remove_image(im_remove_request *request) -{ - int ret = 0; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - char *tmp = NULL; - oci_image_t *image_info = NULL; - bool locked = false; - - if (request->image.image == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - tmp = oci_resolve_image_name(request->image.image); - if (tmp == NULL) { - ERROR("Failed to resolve image name"); - ret = -1; - goto free_out; - } - - image_info = oci_images_store_get(tmp); - if (image_info == NULL) { - INFO("No such image exist %s", tmp); - ret = 0; - goto free_out; - } - - /* isulad_kit does not support concurrent delete tags of the same image, - * so we should make sure we delete tags one by one. */ - oci_image_lock(image_info); - locked = true; - - free(request->image.image); - request->image.image = util_strdup_s(tmp); - - command_ret = util_exec_cmd(execute_remove_image, request, NULL, &stdout_buffer, &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - if (strstr(stderr_buffer, IMAGE_NOT_KNOWN_ERR) != NULL) { - DEBUG("Image %s may already removed", request->image.image); - ret = 0; - goto clean_memory; - } - ERROR("Failed to remove image with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to remove image with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec remove image command"); - lcrd_set_error_message("Failed to exec remove image command"); - } - ret = -1; - goto free_out; - } - -clean_memory: - ret = remove_oci_image_from_memory(tmp); - if (ret != 0) { - ERROR("Failed to remove image %s from memory", tmp); - ret = -1; - goto free_out; - } - -free_out: - if (locked) { - oci_image_unlock(image_info); - } - free(tmp); - free(stderr_buffer); - free(stdout_buffer); - oci_image_unref(image_info); - return ret; -} - diff --git a/src/image/oci/oci_image_status.c b/src/image/oci/oci_image_status.c deleted file mode 100644 index 48c8505..0000000 --- a/src/image/oci/oci_image_status.c +++ /dev/null @@ -1,171 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci image status functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "oci_image_status.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" - -static bool do_status(oci_image_status_request *request, - imagetool_image_status **image) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - parser_error err = NULL; - - command_ret = util_exec_cmd(execute_status_image, request, NULL, &stdout_buffer, - &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to status image with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to status image with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec status image command"); - lcrd_set_error_message("Failed to exec status image command"); - } - goto free_out; - } - - if (stdout_buffer == NULL) { - ERROR("Failed to status image becase can not get stdoutput"); - lcrd_set_error_message("Failed to status image becase can not get stdoutput"); - goto free_out; - } - - *image = imagetool_image_status_parse_data(stdout_buffer, NULL, &err); - if (*image == NULL) { - ERROR("Failed to parse output json:%s", err); - lcrd_set_error_message("Failed to parse output json:%s", err); - goto free_out; - } - - ret = true; - -free_out: - free(err); - free(stderr_buffer); - free(stdout_buffer); - return ret; -} - - -static int do_status_oci_image(oci_image_status_request *request, - oci_image_status_response **response) -{ - int ret = 0; - imagetool_image_status *image = NULL; - char *image_ref = NULL; - - image_ref = request->image.image; - - *response = util_common_calloc_s(sizeof(oci_image_status_response)); - if (*response == NULL) { - ERROR("Out of memory"); - return -1; - } - - if (image_ref == NULL) { - ERROR("Inspect image requires image ref"); - lcrd_set_error_message("Inspect image requires image ref"); - ret = -1; - goto pack_response; - } - - EVENT("Event: {Object: %s, Type: inspecting image}", image_ref); - - if (!do_status(request, &image)) { - ERROR("Failed to status image: %s", image_ref); - ret = -1; - goto pack_response; - } - - EVENT("Event: {Object: %s, Type: inspected image}", image_ref); - -pack_response: - if (g_lcrd_errmsg != NULL) { - (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); - } - - (*response)->image_info = image; - - return ret; -} - -void free_oci_image_status_request(oci_image_status_request *ptr) -{ - if (ptr == NULL) { - return; - } - free(ptr->image.image); - ptr->image.image = NULL; - - free(ptr); -} - -void free_oci_image_status_response(oci_image_status_response *ptr) -{ - if (ptr == NULL) { - return; - } - free_imagetool_image_status(ptr->image_info); - ptr->image_info = NULL; - free(ptr->errmsg); - ptr->errmsg = NULL; - - free(ptr); -} - -imagetool_image *oci_image_get_image_info_by_name(const char *image_name) -{ - oci_image_status_request *request = NULL; - oci_image_status_response *response = NULL; - imagetool_image *image = NULL; - - if (image_name == NULL) { - ERROR("Empty image name"); - return NULL; - } - - request = (oci_image_status_request *)util_common_calloc_s(sizeof(*request)); - if (request == NULL) { - ERROR("Out of memory"); - return NULL; - } - request->image.image = util_strdup_s(image_name); - - if (do_status_oci_image(request, &response)) { - goto cleanup; - } - - if (response->image_info != NULL) { - image = response->image_info->image; - response->image_info->image = NULL; - } - -cleanup: - free_oci_image_status_request(request); - free_oci_image_status_response(response); - return image; -} diff --git a/src/image/oci/oci_image_status.h b/src/image/oci/oci_image_status.h deleted file mode 100644 index b0e8473..0000000 --- a/src/image/oci/oci_image_status.h +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci image status functions - ******************************************************************************/ - -#ifndef __OCI_IMAGE_STATUS_H_ -#define __OCI_IMAGE_STATUS_H_ - -#include "image.h" -#include "oci_image_type.h" -#include "imagetool_image_status.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - // Spec of the image. - image_spec image; - // Verbose indicates whether to return extra information about the image. - bool verbose; -} oci_image_status_request; - -typedef struct { - imagetool_image_status *image_info; - char *errmsg; -} oci_image_status_response; - -void free_oci_image_status_request(oci_image_status_request *ptr); - -void free_oci_image_status_response(oci_image_status_response *ptr); - -imagetool_image *oci_image_get_image_info_by_name(const char *image_name); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/image/oci/oci_image_type.h b/src/image/oci/oci_image_type.h index 0aa1fb6..f1c46d4 100644 --- a/src/image/oci/oci_image_type.h +++ b/src/image/oci/oci_image_type.h @@ -58,3 +58,4 @@ typedef struct { #endif #endif + diff --git a/src/image/oci/oci_image_unix.c b/src/image/oci/oci_image_unix.c index ec4fd05..a3928c0 100644 --- a/src/image/oci/oci_image_unix.c +++ b/src/image/oci/oci_image_unix.c @@ -105,3 +105,4 @@ void oci_image_unlock(oci_image_t *image) ERROR("Failed to unlock image '%s'", image->info->id); } } + diff --git a/src/image/oci/oci_image_unix.h b/src/image/oci/oci_image_unix.h index 273c178..b5591c3 100644 --- a/src/image/oci/oci_image_unix.h +++ b/src/image/oci/oci_image_unix.h @@ -50,3 +50,4 @@ void oci_image_unlock(oci_image_t *image); #endif #endif /* __ISULAD_IMAGE_UNIX_H__ */ + diff --git a/src/image/oci/oci_images_list.c b/src/image/oci/oci_images_list.c deleted file mode 100644 index 1c6e927..0000000 --- a/src/image/oci/oci_images_list.c +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: lifeng - * Create: 2018-11-08 - * Description: provide oci images list functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include "oci_images_list.h" -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "log.h" -#include "utils.h" -#include "liblcrd.h" -#include "image.h" -#include "isula_imtool_interface.h" - -static void set_char_to_terminator(char *p) -{ - *p = '\0'; -} - -static void util_log_output(char *output) -{ - size_t len = 0; - char *tmp_start = NULL; - char *tmp_end = NULL; - - if (output == NULL) { - return; - } - - len = strlen(output); - - for (tmp_start = output; tmp_start < (output + len) && tmp_start != NULL;) { - tmp_end = strchr(tmp_start, '\n'); - if (tmp_end == NULL) { - ERROR("%s", tmp_start); - break; - } - set_char_to_terminator(tmp_end); - ERROR("%s", tmp_start); - *tmp_end = '\n'; - tmp_start = tmp_end + 1; - } - - return; -} - -int do_list_oci_images(im_list_request *request, imagetool_images_list **images) -{ - int ret = -1; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - parser_error err = NULL; - - if (request == NULL || images == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - command_ret = util_exec_cmd(execute_list_images, request, NULL, &stdout_buffer, - &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to list images with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to list images with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec list images command"); - lcrd_set_error_message("Failed to exec list images command"); - } - goto free_out; - } - - if (request->check && stderr_buffer != NULL) { - util_log_output(stderr_buffer); - } - - if (stdout_buffer == NULL) { - ERROR("Failed to list images becase can not get stdoutput"); - lcrd_set_error_message("Failed to list images becase can not get stdoutput"); - goto free_out; - } - - *images = imagetool_images_list_parse_data(stdout_buffer, NULL, &err); - if (*images == NULL) { - ERROR("Failed to parse output json:%s", err); - lcrd_set_error_message("Failed to parse output json:%s", err); - goto free_out; - } - - ret = 0; - -free_out: - free(err); - free(stderr_buffer); - free(stdout_buffer); - return ret; -} diff --git a/src/image/oci/oci_images_store.c b/src/image/oci/oci_images_store.c index c93d993..7ddae66 100644 --- a/src/image/oci/oci_images_store.c +++ b/src/image/oci/oci_images_store.c @@ -16,13 +16,12 @@ #include #include "oci_images_store.h" -#include "oci_image_status.h" -#include "oci_images_list.h" #include "log.h" #include "utils.h" #include "lcrd_config.h" #include "constants.h" +#include "oci_common_operators.h" pthread_rwlock_t g_image_memory_rwlock; @@ -306,9 +305,9 @@ out: static int update_old_image_by_id(const char *id) { int ret = 0; - imagetool_image *image_info = NULL; + imagetool_image *image_info; - image_info = oci_image_get_image_info_by_name(id); + image_info = oci_get_image_info_by_name(id); if (image_info == NULL) { WARN("Failed to status old oci image %s, may be remeved", id); ret = 0; @@ -316,7 +315,6 @@ static int update_old_image_by_id(const char *id) } ret = register_new_oci_image(image_info); - out: return ret; } @@ -366,7 +364,7 @@ static int try_list_oci_images(const char *check_file, imagetool_images_list **a im_request->check = need_check; do { - ret = do_list_oci_images(im_request, all_images); + ret = oci_get_all_images(im_request, all_images); if (ret != 0 || *all_images == NULL) { list_images_ok = false; if (retry_count < max_retry) { @@ -469,11 +467,8 @@ int oci_images_store_list(oci_image_t ***out, size_t *size) ret = 0; goto unlock; } - if (*size > SIZE_MAX / sizeof(oci_image_t *)) { - ERROR("Containers store list is too long!"); - goto unlock; - } - images = util_common_calloc_s(sizeof(oci_image_t *) * (*size)); + + images = util_smart_calloc_s(sizeof(oci_image_t *), (*size)); if (images == NULL) { ERROR("Out of memory"); goto unlock; @@ -556,7 +551,7 @@ oci_image_t *oci_images_store_get_by_id(const char *id) return image; } -/* oci images store get image by image name*/ +/* oci images store get image by image name */ oci_image_t *oci_images_store_get_by_name(const char *name) { char *id = NULL; @@ -575,7 +570,7 @@ oci_image_t *oci_images_store_get_by_name(const char *name) return oci_images_store_get_by_id(id); } -/* oci images store get image by prefix*/ +/* oci images store get image by prefix */ oci_image_t *oci_images_store_get_by_prefix(const char *prefix) { oci_image_t *image = NULL; @@ -707,7 +702,7 @@ int register_new_oci_image_into_memory(const char *name) return -1; } - image_info = oci_image_get_image_info_by_name(name); + image_info = oci_get_image_info_by_name(name); if (image_info == NULL) { ERROR("Failed to get oci image %s informations", name); ret = -1; @@ -784,7 +779,7 @@ int remove_oci_image_from_memory(const char *name_or_id) goto free_out; } - image_info = oci_image_get_image_info_by_name(image->info->id); + image_info = oci_get_image_info_by_name(image->info->id); if (image_info == NULL) { WARN("Failed to status old oci image %s, may be remeved", image->info->id); @@ -811,3 +806,24 @@ free_out: return ret; } +int oci_image_store_init() +{ + int ret = 0; + + ret = oci_images_store_init(); + if (ret != 0) { + ERROR("Failed to init oci images store"); + goto out; + } + + ret = image_name_id_init(); + if (ret != 0) { + ERROR("Failed to init oci name id store"); + goto out; + } + + ret = load_all_oci_images(); + +out: + return ret; +} diff --git a/src/image/oci/oci_images_store.h b/src/image/oci/oci_images_store.h index 7d7c785..954f9e9 100644 --- a/src/image/oci/oci_images_store.h +++ b/src/image/oci/oci_images_store.h @@ -38,9 +38,11 @@ int register_new_oci_image_into_memory(const char *name); int remove_oci_image_from_memory(const char *name_or_id); +int oci_image_store_init(); #if defined(__cplusplus) || defined(c_plusplus) } #endif #endif /* __LCRD_MEMORY_STORE_H__ */ + diff --git a/src/image/oci/oci_login.c b/src/image/oci/oci_login.c deleted file mode 100644 index 6ac033b..0000000 --- a/src/image/oci/oci_login.c +++ /dev/null @@ -1,118 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: wangfengtu - * Create: 2019-06-18 - * Description: provide oci login image functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" -#include "image.h" -#include "oci_auth.h" -#include "oci_login.h" - -static bool do_login(im_login_request *request) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - char *stdin_buffer = NULL; - auth_config auth = {0}; - - auth.username = request->username; - auth.password = request->password; - stdin_buffer = pack_input_auth_string(&auth); - if (stdin_buffer == NULL) { - ERROR("Failed to generate image auth info"); - lcrd_set_error_message("Failed to generate image auth info"); - goto free_out; - } - - command_ret = util_exec_cmd(execute_login, request, stdin_buffer, - &stdout_buffer, &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to login with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to login with error: %s", - stderr_buffer); - } else { - ERROR("Failed to exec login command"); - lcrd_set_error_message("Failed to exec login command"); - } - goto free_out; - } - - ret = true; - -free_out: - free_sensitive_string(stdin_buffer); - free(stderr_buffer); - free(stdout_buffer); - return ret; -} - -static int check_login_request_valid(const im_login_request *request) -{ - int ret = -1; - - if (request == NULL) { - ERROR("invalid login request"); - lcrd_set_error_message("invalid login request"); - goto out; - } - - if (request->server == NULL) { - ERROR("Login requires server address"); - lcrd_set_error_message("Login requires server address"); - goto out; - } - - if (request->username == NULL || request->password == NULL) { - ERROR("Missing username or password"); - lcrd_set_error_message("Missing username or password"); - goto out; - } - - ret = 0; - -out: - return ret; -} - - -int oci_login(im_login_request *request) -{ - int ret = 0; - - if (check_login_request_valid(request) != 0) { - ret = -1; - goto pack_response; - } - - if (!do_login(request)) { - ret = -1; - goto pack_response; - } - -pack_response: - - return ret; -} diff --git a/src/image/oci/oci_logout.c b/src/image/oci/oci_logout.c deleted file mode 100644 index fa0e506..0000000 --- a/src/image/oci/oci_logout.c +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: wangfengtu - * Create: 2019-06-18 - * Description: provide oci logout image functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" -#include "image.h" -#include "oci_logout.h" - -static bool do_logout(im_logout_request *request) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - - command_ret = util_exec_cmd(execute_logout, request, NULL, &stdout_buffer, - &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to logout with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to logout with error: %s", - stderr_buffer); - } else { - ERROR("Failed to exec logout command"); - lcrd_set_error_message("Failed to exec logout command"); - } - goto free_out; - } - - ret = true; - -free_out: - free(stderr_buffer); - free(stdout_buffer); - return ret; -} - -static int check_logout_request_valid(const im_logout_request *request) -{ - int ret = -1; - - if (request == NULL) { - ERROR("invalid logout request"); - lcrd_set_error_message("invalid logout request"); - goto out; - } - - if (request->server == NULL) { - ERROR("Logout requires server address"); - lcrd_set_error_message("Logout requires server address"); - goto out; - } - - ret = 0; - -out: - return ret; -} - - -int oci_logout(im_logout_request *request) -{ - int ret = 0; - - if (check_logout_request_valid(request) != 0) { - ret = -1; - goto pack_response; - } - - if (!do_logout(request)) { - ret = -1; - goto pack_response; - } - -pack_response: - - return ret; -} diff --git a/src/image/oci/oci_rootfs_export.c b/src/image/oci/oci_rootfs_export.c deleted file mode 100644 index 46c8ed8..0000000 --- a/src/image/oci/oci_rootfs_export.c +++ /dev/null @@ -1,146 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: wangfengtu - * Create: 2019-04-06 - * Description: provide oci export rootfs functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "oci_rootfs_export.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" - -static bool do_export(rootfs_export_request *request) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - - command_ret = util_exec_cmd(execute_export_rootfs, request, NULL, &stdout_buffer, - &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to export rootfs with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to export rootfs with error: %s", - stderr_buffer); - } else { - ERROR("Failed to exec export rootfs command"); - lcrd_set_error_message("Failed to exec export rootfs command"); - } - goto free_out; - } - - ret = true; - -free_out: - free(stderr_buffer); - free(stdout_buffer); - return ret; -} - -static int check_export_request_valid(rootfs_export_request *request) -{ - int ret = -1; - - if (request == NULL) { - ERROR("unvalid export request"); - lcrd_set_error_message("unvalid export request"); - goto out; - } - - if (request->id == NULL) { - ERROR("Export rootfs requires container name"); - lcrd_set_error_message("Export rootfs requires container name"); - goto out; - } - - if (request->file == NULL) { - ERROR("Export rootfs requires output file path"); - lcrd_set_error_message("Export rootfs requires output file path"); - goto out; - } - - ret = 0; - -out: - return ret; -} - - -int export_rootfs(rootfs_export_request *request, - rootfs_export_response **response) -{ - int ret = 0; - - if (response == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - *response = util_common_calloc_s(sizeof(rootfs_export_response)); - if (*response == NULL) { - ERROR("Out of memory"); - return -1; - } - - if (check_export_request_valid(request) != 0) { - ret = -1; - goto pack_response; - } - - if (!do_export(request)) { - ERROR("Failed to export rootfs"); - ret = -1; - goto pack_response; - } - -pack_response: - if (g_lcrd_errmsg != NULL) { - (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); - } - - return ret; -} - -void free_rootfs_export_request(rootfs_export_request *ptr) -{ - if (ptr == NULL) { - return; - } - free(ptr->id); - ptr->id = NULL; - free(ptr->file); - ptr->file = NULL; - - free(ptr); -} - -void free_rootfs_export_response(rootfs_export_response *ptr) -{ - if (ptr == NULL) { - return; - } - - free(ptr->errmsg); - ptr->errmsg = NULL; - - free(ptr); -} - diff --git a/src/image/oci/oci_rootfs_export.h b/src/image/oci/oci_rootfs_export.h deleted file mode 100644 index 27b67e5..0000000 --- a/src/image/oci/oci_rootfs_export.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: wangfengtu - * Create: 2019-04-06 - * Description: provide oci export rootfs functions - ******************************************************************************/ - -#ifndef __OCI_EXPORT_ROOTFS_H_ -#define __OCI_EXPORT_ROOTFS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - char *file; - char *id; -} rootfs_export_request; - -typedef struct { - char *errmsg; -} rootfs_export_response; - -int export_rootfs(rootfs_export_request *request, - rootfs_export_response **response); - -void free_rootfs_export_request(rootfs_export_request *ptr); - -void free_rootfs_export_response(rootfs_export_response *ptr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/image/oci/oci_rootfs_mount.c b/src/image/oci/oci_rootfs_mount.c deleted file mode 100644 index ffaf62c..0000000 --- a/src/image/oci/oci_rootfs_mount.c +++ /dev/null @@ -1,154 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: 李峰 - * Create: 2018-11-08 - * Description: provide oci mount rootfs functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "oci_rootfs_mount.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" - -static bool do_mount(rootfs_mount_request *request, char **mounted_rootfs) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - - command_ret = util_exec_cmd(execute_mount_rootfs, request, NULL, &stdout_buffer, - &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to mount rootfs with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to mount rootfs with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec mount rootfs command"); - lcrd_set_error_message("Failed to exec mount rootfs command"); - } - goto free_out; - } - - if (stdout_buffer == NULL) { - ERROR("Failed to mount rootfs becase can not get stdoutput"); - lcrd_set_error_message("Failed to mount rootfs becase can not get stdoutput"); - goto free_out; - } - - *mounted_rootfs = util_strdup_s(stdout_buffer); - - ret = true; - -free_out: - free(stderr_buffer); - free(stdout_buffer); - return ret; -} - -static int check_mount_request_valid(rootfs_mount_request *request) -{ - int ret = -1; - - if (request == NULL) { - ERROR("unvalid mount request"); - lcrd_set_error_message("unvalid mount request"); - goto out; - } - - if (request->name_id == NULL) { - ERROR("Mount rootfs requires container name or id"); - lcrd_set_error_message("Mount rootfs requires container name or id"); - goto out; - } - - ret = 0; - -out: - return ret; -} - - -int mount_rootfs(rootfs_mount_request *request, - rootfs_mount_response **response) -{ - int ret = 0; - char *name_id = NULL; - char *mounted_rootfs = NULL; - - if (response == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - *response = util_common_calloc_s(sizeof(rootfs_mount_response)); - if (*response == NULL) { - ERROR("Out of memory"); - return -1; - } - - if (check_mount_request_valid(request) != 0) { - ret = -1; - goto pack_response; - } - - name_id = request->name_id; - - EVENT("Event: {Object: %s, Type: mounting rootfs}", name_id); - - if (!do_mount(request, &mounted_rootfs)) { - ERROR("Failed to mount rootfs"); - ret = -1; - goto pack_response; - } - - EVENT("Event: {Object: %s, Type: mounted rootfs}", name_id); - -pack_response: - free(mounted_rootfs); - if (g_lcrd_errmsg != NULL) { - (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); - } - - return ret; -} - -void free_rootfs_mount_request(rootfs_mount_request *ptr) -{ - if (ptr == NULL) { - return; - } - free(ptr->name_id); - ptr->name_id = NULL; - - free(ptr); -} - -void free_rootfs_mount_response(rootfs_mount_response *ptr) -{ - if (ptr == NULL) { - return; - } - - free(ptr->errmsg); - ptr->errmsg = NULL; - - free(ptr); -} - diff --git a/src/image/oci/oci_rootfs_mount.h b/src/image/oci/oci_rootfs_mount.h deleted file mode 100644 index fcad187..0000000 --- a/src/image/oci/oci_rootfs_mount.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: 李峰 - * Create: 2018-11-08 - * Description: provide oci mount rootfs functions - ******************************************************************************/ - -#ifndef __OCI_MOUNT_ROOTFS_H_ -#define __OCI_MOUNT_ROOTFS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - char *name_id; -} rootfs_mount_request; - -typedef struct { - char *errmsg; -} rootfs_mount_response; - -int mount_rootfs(rootfs_mount_request *request, - rootfs_mount_response **response); - -void free_rootfs_mount_request(rootfs_mount_request *ptr); - -void free_rootfs_mount_response(rootfs_mount_response *ptr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/image/oci/oci_rootfs_prepare.c b/src/image/oci/oci_rootfs_prepare.c deleted file mode 100644 index 4589a2b..0000000 --- a/src/image/oci/oci_rootfs_prepare.c +++ /dev/null @@ -1,180 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: 李峰 - * Create: 2018-11-08 - * Description: provide oci prepare rootfs functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "oci_rootfs_prepare.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" - -static bool do_prepare(rootfs_prepare_request *request, imagetool_prepare_response **response) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - parser_error err = NULL; - - command_ret = util_exec_cmd(execute_prepare_rootfs, request, NULL, &stdout_buffer, - &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to prepare rootfs with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to prepare rootfs with error: %s", - stderr_buffer); - } else { - ERROR("Failed to exec prepare rootfs command"); - lcrd_set_error_message("Failed to exec prepare rootfs command"); - } - goto free_out; - } - - if (stdout_buffer == NULL) { - ERROR("Failed to prepare rootfs becase can not get stdoutput"); - lcrd_set_error_message("Failed to prepare rootfs becase can not get stdoutput"); - goto free_out; - } - - *response = imagetool_prepare_response_parse_data(stdout_buffer, NULL, &err); - if (*response == NULL) { - ERROR("Failed to parse isulad-kit output: %s", stdout_buffer); - lcrd_set_error_message("Failed to parse isulad-kit output"); - goto free_out; - } - - ret = true; - -free_out: - free(err); - free(stderr_buffer); - free(stdout_buffer); - return ret; -} - -static int check_prepare_request_valid(rootfs_prepare_request *request) -{ - int ret = -1; - - if (request == NULL) { - ERROR("unvalid prepare request"); - lcrd_set_error_message("unvalid prepare request"); - goto out; - } - - if (request->image == NULL) { - ERROR("Prepare rootfs requires an image"); - lcrd_set_error_message("Prepare rootfs requires an image"); - goto out; - } - - if (request->name == NULL) { - ERROR("Prepare rootfs requires container name"); - lcrd_set_error_message("Prepare rootfs requires container name"); - goto out; - } - - ret = 0; - -out: - return ret; -} - -int prepare_rootfs_and_get_image_conf(rootfs_prepare_request *request, - rootfs_prepare_and_get_image_conf_response **response) -{ - int ret = 0; - char *name = NULL; - char *image = NULL; - imagetool_prepare_response *tool_response = NULL; - - if (response == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - *response = util_common_calloc_s(sizeof(rootfs_prepare_and_get_image_conf_response)); - if (*response == NULL) { - ERROR("Out of memory"); - return -1; - } - - if (check_prepare_request_valid(request) != 0) { - ret = -1; - goto pack_response; - } - - image = request->image; - name = request->name; - - EVENT("Event: {Object: %s, Type: preparing rootfs with image %s}", name, image); - - if (!do_prepare(request, &tool_response)) { - ERROR("Failed to prepare rootfs"); - ret = -1; - goto pack_response; - } - - EVENT("Event: {Object: %s, Type: prepared rootfs with image %s}", name, image); - -pack_response: - if (g_lcrd_errmsg != NULL) { - (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); - } - - (*response)->raw_response = tool_response; - - return ret; -} - -void free_rootfs_prepare_request(rootfs_prepare_request *ptr) -{ - if (ptr == NULL) { - return; - } - free(ptr->image); - ptr->image = NULL; - free(ptr->name); - ptr->name = NULL; - free(ptr->id); - ptr->id = NULL; - util_free_array(ptr->storage_opts); - ptr->storage_opts = NULL; - ptr->storage_opts_len = 0; - - free(ptr); -} - -void free_rootfs_prepare_and_get_image_conf_response(rootfs_prepare_and_get_image_conf_response *ptr) -{ - if (ptr == NULL) { - return; - } - - free_imagetool_prepare_response(ptr->raw_response); - ptr->raw_response = NULL; - - free(ptr->errmsg); - ptr->errmsg = NULL; - - free(ptr); -} - diff --git a/src/image/oci/oci_rootfs_prepare.h b/src/image/oci/oci_rootfs_prepare.h deleted file mode 100644 index 79ff074..0000000 --- a/src/image/oci/oci_rootfs_prepare.h +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: 李峰 - * Create: 2018-11-08 - * Description: provide oci prepare rootfs functions - ******************************************************************************/ - -#ifndef __OCI_PREPARE_ROOTFS_H_ -#define __OCI_PREPARE_ROOTFS_H_ - -#include "imagetool_prepare_response.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - char *image; - char *name; - char *id; - char **storage_opts; - size_t storage_opts_len; -} rootfs_prepare_request; - -typedef struct { - char *errmsg; - char *rootfs; -} rootfs_prepare_response; - -typedef struct { - char *errmsg; - imagetool_prepare_response *raw_response; -} rootfs_prepare_and_get_image_conf_response; - -void free_rootfs_prepare_request(rootfs_prepare_request *ptr); - -int prepare_rootfs_and_get_image_conf(rootfs_prepare_request *request, - rootfs_prepare_and_get_image_conf_response **response); -void free_rootfs_prepare_and_get_image_conf_response(rootfs_prepare_and_get_image_conf_response *ptr); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/image/oci/oci_rootfs_remove.c b/src/image/oci/oci_rootfs_remove.c deleted file mode 100644 index 8a0b3a3..0000000 --- a/src/image/oci/oci_rootfs_remove.c +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: 李峰 - * Create: 2018-11-08 - * Description: provide oci remove rootfs functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "oci_rootfs_remove.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" - -#define CONTAINER_NOT_KNOWN_ERR "container not known" - -static bool do_remove(rootfs_remove_request *request) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - - command_ret = util_exec_cmd(execute_remove_rootfs, request, NULL, &stdout_buffer, - &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - if (strstr(stderr_buffer, CONTAINER_NOT_KNOWN_ERR) != NULL) { - DEBUG("Container %s may already removed", request->name_id); - ret = true; - goto free_out; - } - ERROR("Failed to remove rootfs with error: %s", stderr_buffer); - lcrd_try_set_error_message("Failed to remove rootfs with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec remove rootfs command"); - lcrd_try_set_error_message("Failed to exec remove rootfs command"); - } - goto free_out; - } - - ret = true; - -free_out: - free(stderr_buffer); - free(stdout_buffer); - return ret; -} - -static int check_remove_request_valid(rootfs_remove_request *request) -{ - int ret = -1; - - if (request == NULL) { - ERROR("unvalid remove request"); - lcrd_set_error_message("unvalid remove request"); - goto out; - } - - if (request->name_id == NULL) { - ERROR("remove rootfs requires container name or id"); - lcrd_set_error_message("remove rootfs requires container name or id"); - goto out; - } - - ret = 0; - -out: - return ret; -} - - -int remove_rootfs(rootfs_remove_request *request, - rootfs_remove_response **response) -{ - int ret = 0; - char *name_id = NULL; - - if (response == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - *response = util_common_calloc_s(sizeof(rootfs_remove_response)); - if (*response == NULL) { - ERROR("Out of memory"); - return -1; - } - - if (check_remove_request_valid(request) != 0) { - ret = -1; - goto pack_response; - } - - name_id = request->name_id; - - EVENT("Event: {Object: %s, Type: removeing rootfs}", name_id); - - if (!do_remove(request)) { - ERROR("Failed to remove rootfs"); - ret = -1; - goto pack_response; - } - - EVENT("Event: {Object: %s, Type: removed rootfs}", name_id); - -pack_response: - if (g_lcrd_errmsg != NULL) { - (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); - } - - return ret; -} - -void free_rootfs_remove_request(rootfs_remove_request *ptr) -{ - if (ptr == NULL) { - return; - } - free(ptr->name_id); - ptr->name_id = NULL; - - free(ptr); -} - -void free_rootfs_remove_response(rootfs_remove_response *ptr) -{ - if (ptr == NULL) { - return; - } - - free(ptr->errmsg); - ptr->errmsg = NULL; - - free(ptr); -} - diff --git a/src/image/oci/oci_rootfs_remove.h b/src/image/oci/oci_rootfs_remove.h deleted file mode 100644 index 7e3fb0d..0000000 --- a/src/image/oci/oci_rootfs_remove.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: 李峰 - * Create: 2018-11-08 - * Description: provide oci remove rootfs functions - ******************************************************************************/ - -#ifndef __OCI_REMOVE_ROOTFS_H_ -#define __OCI_REMOVE_ROOTFS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - char *name_id; -} rootfs_remove_request; - -typedef struct { - char *errmsg; -} rootfs_remove_response; - -int remove_rootfs(rootfs_remove_request *request, - rootfs_remove_response **response); - -void free_rootfs_remove_request(rootfs_remove_request *ptr); - -void free_rootfs_remove_response(rootfs_remove_response *ptr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/image/oci/oci_rootfs_umount.c b/src/image/oci/oci_rootfs_umount.c deleted file mode 100644 index 5c6d9a4..0000000 --- a/src/image/oci/oci_rootfs_umount.c +++ /dev/null @@ -1,143 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: 李峰 - * Create: 2018-11-08 - * Description: provide oci umount rootfs functions - ******************************************************************************/ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include /* Obtain O_* constant definitions */ -#include -#include -#include - -#include "securec.h" -#include "oci_rootfs_umount.h" -#include "utils.h" -#include "log.h" -#include "liblcrd.h" -#include "isula_imtool_interface.h" - -static bool do_umount(rootfs_umount_request *request) -{ - bool ret = false; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - - command_ret = util_exec_cmd(execute_umount_rootfs, request, NULL, &stdout_buffer, &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to umount rootfs with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to umount rootfs with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec umount rootfs command"); - lcrd_set_error_message("Failed to exec umount rootfs command"); - } - goto free_out; - } - - ret = true; - -free_out: - free(stderr_buffer); - free(stdout_buffer); - return ret; -} - -static int check_umount_request_valid(rootfs_umount_request *request) -{ - int ret = -1; - - if (request == NULL) { - ERROR("unvalid umount request"); - lcrd_set_error_message("unvalid umount request"); - goto out; - } - - if (request->name_id == NULL) { - ERROR("Umount rootfs requires container name or id"); - lcrd_set_error_message("Umount rootfs requires container name or id"); - goto out; - } - - ret = 0; - -out: - return ret; -} - - -int umount_rootfs(rootfs_umount_request *request, - rootfs_umount_response **response) -{ - int ret = 0; - char *name_id = NULL; - - if (response == NULL) { - ERROR("Invalid input arguments"); - return -1; - } - - *response = util_common_calloc_s(sizeof(rootfs_umount_response)); - if (*response == NULL) { - ERROR("Out of memory"); - return -1; - } - - if (check_umount_request_valid(request) != 0) { - ret = -1; - goto pack_response; - } - - name_id = request->name_id; - - EVENT("Event: {Object: %s, Type: umounting rootfs}", name_id); - - if (!do_umount(request)) { - ERROR("Failed to umount rootfs"); - ret = -1; - goto pack_response; - } - - EVENT("Event: {Object: %s, Type: umounted rootfs}", name_id); - -pack_response: - if (g_lcrd_errmsg != NULL) { - (*response)->errmsg = util_strdup_s(g_lcrd_errmsg); - } - - return ret; -} - -void free_rootfs_umount_request(rootfs_umount_request *ptr) -{ - if (ptr == NULL) { - return; - } - free(ptr->name_id); - ptr->name_id = NULL; - - free(ptr); -} - -void free_rootfs_umount_response(rootfs_umount_response *ptr) -{ - if (ptr == NULL) { - return; - } - - free(ptr->errmsg); - ptr->errmsg = NULL; - - free(ptr); -} - diff --git a/src/image/oci/oci_rootfs_umount.h b/src/image/oci/oci_rootfs_umount.h deleted file mode 100644 index 1761861..0000000 --- a/src/image/oci/oci_rootfs_umount.h +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: 李峰 - * Create: 2018-11-08 - * Description: provide oci umount rootfs functions - ******************************************************************************/ - -#ifndef __OCI_UMOUNT_ROOTFS_H_ -#define __OCI_UMOUNT_ROOTFS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - char *name_id; -} rootfs_umount_request; - -typedef struct { - char *errmsg; -} rootfs_umount_response; - -int umount_rootfs(rootfs_umount_request *request, - rootfs_umount_response **response); - -void free_rootfs_umount_request(rootfs_umount_request *ptr); - -void free_rootfs_umount_response(rootfs_umount_response *ptr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/image/oci/run_image_server.c b/src/image/oci/run_image_server.c new file mode 100644 index 0000000..744fb17 --- /dev/null +++ b/src/image/oci/run_image_server.c @@ -0,0 +1,462 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: run isula image server +*******************************************************************************/ +#define _GNU_SOURCE +#include "run_image_server.h" + +#include /* Obtain O_* constant definitions */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "isula_image.h" +#include "isula_health_check.h" +#include "global_config.h" +#include "lcrd_config.h" +#include "log.h" +#include "utils_file.h" +#include "utils.h" + +/* global options */ +const char *g_imtool_gb_options[] = { + "--graph-root", + "--run-root", + "--driver-name", + "--driver-options", + "--storage-opt", + "--registry", + "--insecure-registry", + "--command-timeout", + "--log-level", + "--host", + NULL, +}; + +#define ISULA_IMAGE_SERVER_CMD "isulad_kit" +#define ISULA_IMAGE_DAEMON "daemon" +#define ISULA_IMAGE_DAEMON_HOST "--host" +#define ISULA_IMAGE_DAEMON_OPTION_TLS_VERIFY "--tls-verify=false" +#define ISULA_IMAGE_DAEMON_OPTION_USE_DECRYPTED "--use-decrypted-key=false" + +#define RETRY_COUNT_MAX 15 +#define HALF_A_SECOND 500000 +#define ONE_TENTH_SECOND 100000 + +static pthread_mutex_t g_mutex; +static pid_t g_isulad_kit_pid = -1; +static unsigned long long g_isulad_kit_start_time = 0; +static bool g_isula_kit_exit = false; + +static int pack_isula_image_global_options(char *params[], size_t *count, bool ignore_storage_opt_size) +{ + int ret = -1; + size_t i = 0; + char *buffer = NULL; + char *sock_addr = NULL; + + i = *count; + + add_array_elem(params, PARAM_NUM, &i, ISULA_IMAGE_SERVER_CMD); + + if (pack_global_options(g_imtool_gb_options, params, &i, ignore_storage_opt_size) != 0) { + goto out; + } + + add_array_elem(params, PARAM_NUM, &i, ISULA_IMAGE_DAEMON); + + if (!conf_get_use_decrypted_key_flag()) { + add_array_elem(params, PARAM_NUM, &i, ISULA_IMAGE_DAEMON_OPTION_USE_DECRYPTED); + } + + if (conf_get_skip_insecure_verify_flag()) { + add_array_elem(params, PARAM_NUM, &i, ISULA_IMAGE_DAEMON_OPTION_TLS_VERIFY); + } + + sock_addr = conf_get_im_server_sock_addr(); + if (sock_addr == NULL) { + COMMAND_ERROR("Get image server socket address failed"); + goto out; + } + ret = asprintf(&buffer, "%s=%s", ISULA_IMAGE_DAEMON_HOST, sock_addr); + if (ret < 0) { + COMMAND_ERROR("Out of memory"); + goto out; + } + + add_array_elem(params, PARAM_NUM, &i, buffer); + + ret = 0; + *count = i; + +out: + free(sock_addr); + free(buffer); + return ret; +} + +static void execute_run_isula_image_server(void *args) +{ + char *params[PARAM_NUM] = { NULL }; + size_t i = 0; + int ret = 0; + + if (util_check_inherited(true, -1) != 0) { + COMMAND_ERROR("Close inherited fds failed"); + goto out; + } + + ret = pack_isula_image_global_options(params, &i, false); + if (ret != 0) { + COMMAND_ERROR("Pack global options failed"); + goto out; + } + + execvp(ISULA_IMAGE_SERVER_CMD, params); + + COMMAND_ERROR("Cannot run isula-image server with '%s':%s", ISULA_IMAGE_SERVER_CMD, strerror(errno)); +out: + exit(EXIT_FAILURE); +} + +static void do_check_mainloop() +{ +#define HEALTH_CHECK_INTERVAL 1000000 + int retry_count = 0; + + while (true) { + if (isula_do_health_check() == 0) { + retry_count = 0; + } + if ((retry_count++) > RETRY_COUNT_MAX) { + ERROR("Cannot connect image server, Retry too many times. Will to restart image server"); + break; + } + + usleep_nointerupt(HEALTH_CHECK_INTERVAL); + } +} + +static unsigned long long get_image_server_start_time(pid_t server_pid) +{ + int sret = 0; + proc_t *pid_info = NULL; + char filename[PATH_MAX] = { 0 }; + char sbuf[1024] = { 0 }; /* bufs for stat */ + unsigned long long result = 0; + + if (server_pid == 0) { + return 0; + } + + sret = kill(server_pid, 0); + if (sret < 0 && errno == ESRCH) { + return 0; + } + + sret = sprintf_s(filename, sizeof(filename), "/proc/%d/stat", server_pid); + if (sret < 0 || (unsigned int)sret >= sizeof(filename)) { + ERROR("Failed to sprintf filename"); + goto out; + } + + if ((util_file2str(filename, sbuf, sizeof(sbuf))) == -1) { + ERROR("Failed to read pidfile %s", filename); + goto out; + } + + pid_info = util_stat2proc(sbuf, sizeof(sbuf)); + if (pid_info == NULL) { + ERROR("Failed to get proc stat info"); + goto out; + } + + result = pid_info->start_time; +out: + free(pid_info); + return result; +} + +static void kill_old_image_server(pid_t server_pid, unsigned long long start_time, unsigned long wait_usec) +{ + if (!util_process_alive(server_pid, start_time)) { + return; + } + if (kill(server_pid, SIGTERM) != 0) { + SYSERROR("Send term signal to server process failed"); + } + usleep_nointerupt(wait_usec); + if (kill(server_pid, SIGKILL) != 0) { + SYSERROR("Send kill signal to server process failed"); + } +} + +static void *heartbeat_for_isulad_kit(void *arg) +{ + pid_t tmp_isulad_kit_pid = -1; + unsigned long long tmp_isulad_kit_start_time = 0; + + if (pthread_detach(pthread_self()) != 0) { + ERROR("Detach heartbeat thread failed"); + return NULL; + } + + prctl(PR_SET_NAME, "HeartBeatForImageServer"); + + for (;;) { + if (pthread_mutex_lock(&g_mutex) != 0) { + usleep_nointerupt(ONE_TENTH_SECOND); + continue; + } + + tmp_isulad_kit_pid = g_isulad_kit_pid; + tmp_isulad_kit_start_time = g_isulad_kit_start_time; + + if (pthread_mutex_unlock(&g_mutex) != 0) { + ERROR("Lock isulad kit pid failed"); + break; + } + + if (tmp_isulad_kit_pid == -1) { + usleep_nointerupt(ONE_TENTH_SECOND); + continue; + } + + do_check_mainloop(); + + kill_old_image_server(tmp_isulad_kit_pid, tmp_isulad_kit_start_time, HALF_A_SECOND); + } + + return NULL; +} + +static int isula_image_server_load_first_check(const struct server_monitor_conf *conf, bool retry) +{ + int ret = 0; + unsigned long retry_cnt = 1; + + /* parent: check server is running */ + while (true) { + usleep_nointerupt(ONE_TENTH_SECOND * retry_cnt); + ret = isula_do_health_check(); + if (ret == 0) { + break; + } + retry_cnt++; + if (retry_cnt > RETRY_COUNT_MAX) { + // don't post sem to main thread + ERROR("First load image server failed"); + ret = -1; + goto out; + } + } + + /* 1. If health check success, send a mutex to main thread and make it run again; + * 2. Sync data between iSulad and iSulad-kit. + */ + if (retry) { + ret = isula_sync_images(); + if (ret != 0) { + DEBUG("Sync images list with remote failed"); + } + ret = isula_sync_containers(); + if (ret != 0) { + DEBUG("Sync containers list with remote failed"); + } + } else { + /* first run, need post sem */ + sem_post(conf->wait_ok); + } + +out: + if (retry) { + // ignore errors, throught restart image server to retry. + return 0; + } + return ret; +} + +void isula_kit_exit() +{ + if (pthread_mutex_lock(&g_mutex) != 0) { + ERROR("Lock isulad kit pid failed"); + return; + } + + g_isula_kit_exit = true; + kill_old_image_server(g_isulad_kit_pid, g_isulad_kit_start_time, ONE_TENTH_SECOND); + + if (pthread_mutex_unlock(&g_mutex) != 0) { + ERROR("Unlock isulad kit pid failed"); + } +} + +static void update_isulad_kit_pid_info(pid_t pid, unsigned long long start_time) +{ + if (pthread_mutex_lock(&g_mutex) != 0) { + ERROR("Lock isulad kit pid failed"); + return; + } + + g_isulad_kit_start_time = start_time; + g_isulad_kit_pid = pid; + + if (pthread_mutex_unlock(&g_mutex) != 0) { + ERROR("Unlock isulad kit pid failed"); + } +} + +static int load_isula_image_server(const struct server_monitor_conf *conf, bool retry, pid_t *kit_pid) +{ + pid_t pid = 0; + int ret = 0; + int nret = 0; + unsigned long long start_time = 0; + + pid = fork(); + if (pid == (pid_t) - 1) { + ERROR("Failed to fork"); + ret = -1; + goto out; + } + + if (pid == (pid_t)0) { + // child to load isula-kit binary + nret = prctl(PR_SET_PDEATHSIG, SIGKILL, (unsigned long)0, (unsigned long)0, (unsigned long)0); + if (nret < 0) { + COMMAND_ERROR("Failed to set parent death signal"); + exit(127); + } + + nret = setsid(); + if (nret < 0) { + COMMAND_ERROR("Failed to set process %d as group leader", getpid()); + } + execute_run_isula_image_server(NULL); + } + *kit_pid = pid; + + /* parent */ + start_time = get_image_server_start_time(pid); + + /* check first load isulad kit is success. */ + if (isula_image_server_load_first_check(conf, retry) != 0) { + ret = -1; + } + + /* update isulad_kit information */ + update_isulad_kit_pid_info(pid, start_time); + +out: + return ret; +} + +static void remove_old_socket_file() +{ + char *sock_addr; + + sock_addr = conf_get_im_server_sock_addr(); + if (sock_addr != NULL) { + if (unlink(sock_addr) != 0 && errno != ENOENT) { + ERROR("Remove old socket file failed: %s", strerror(errno)); + } + free(sock_addr); + } +} + +void *isula_image_server_monitor(void *arg) +{ + int nret = 0; + struct server_monitor_conf *conf = (struct server_monitor_conf *)arg; + bool retry_flag = false; + pthread_t wp_thread; + pid_t isulad_kit_pid; + + if (conf == NULL) { + ERROR("Invalid arguments"); + return NULL; + } + + nret = pthread_mutex_init(&g_mutex, NULL); + if (nret != 0) { + ERROR("Init mutex failed: %s", strerror(nret)); + goto pexit; + } + + nret = pthread_create(&wp_thread, NULL, heartbeat_for_isulad_kit, NULL); + if (nret != 0) { + ERROR("Create heartbeat thread failed: %s", strerror(nret)); + goto pexit; + } + + nret = pthread_detach(pthread_self()); + if (nret != 0) { + ERROR("Set isula image server monitor thread failed: %s", strerror(nret)); + goto pexit; + } + prctl(PR_SET_NAME, "iSulaImageMonitor"); + INFO("Begin isula image server monitor"); + +retry: + remove_old_socket_file(); + isulad_kit_pid = (pid_t) - 1; + // First, fork new process to run image server binary. + nret = load_isula_image_server(conf, retry_flag, &isulad_kit_pid); + if (nret != 0) { + if (!retry_flag) { + ERROR("First start isulad kit failed"); + goto pexit; + } + WARN("Load isula image server failed"); + } + + retry_flag = true; + if (isulad_kit_pid == (pid_t) - 1) { + usleep_nointerupt(HALF_A_SECOND); + goto retry; + } + /* waitpid for isulad_kit process */ + nret = wait_for_pid(isulad_kit_pid); + if (nret != 0) { + SYSERROR("Wait isulad kit failed"); + } + + /* clean old isulad_kit information */ + if (pthread_mutex_lock(&g_mutex) != 0) { + ERROR("Lock isulad kit pid failed"); + } + + g_isulad_kit_start_time = 0; + g_isulad_kit_pid = -1; + if (g_isula_kit_exit) { + (void)pthread_mutex_unlock(&g_mutex); + goto pexit; + } + + if (pthread_mutex_unlock(&g_mutex) != 0) { + ERROR("Unlock isulad kit pid failed"); + } + + usleep_nointerupt(HALF_A_SECOND); + // Second, wait new process; if it is failed, restart it. + goto retry; + +pexit: + return NULL; +} + diff --git a/src/image/oci/run_image_server.h b/src/image/oci/run_image_server.h new file mode 100644 index 0000000..9e08a1e --- /dev/null +++ b/src/image/oci/run_image_server.h @@ -0,0 +1,38 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. +* Author: liuhao +* Create: 2019-07-15 +* Description: run isula image server +*******************************************************************************/ +#ifndef __IMAGE_RUN_IMAGE_SERVER_H +#define __IMAGE_RUN_IMAGE_SERVER_H + +#include +#include +#include "linked_list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct server_monitor_conf { + sem_t *wait_ok; +}; + +void *isula_image_server_monitor(void *arg); + +void isula_kit_exit(); + +#ifdef __cplusplus +} +#endif + +#endif /* __IMAGE_RUN_IMAGE_SERVER_H */ diff --git a/src/json/oci_runtime_hooks.c b/src/json/oci_runtime_hooks.c index b3ac856..81c38c6 100644 --- a/src/json/oci_runtime_hooks.c +++ b/src/json/oci_runtime_hooks.c @@ -61,3 +61,4 @@ oci_runtime_spec_hooks *oci_runtime_spec_hooks_parse_file(const char *filename, yajl_tree_free(tree); return ptr; } + diff --git a/src/json/oci_runtime_hooks.h b/src/json/oci_runtime_hooks.h index 3c86126..dac9925 100644 --- a/src/json/oci_runtime_hooks.h +++ b/src/json/oci_runtime_hooks.h @@ -22,3 +22,4 @@ oci_runtime_spec_hooks *oci_runtime_spec_hooks_parse_file(const char *filename, const struct parser_context *ctx, parser_error *err); #endif + diff --git a/src/json/parse_common.c b/src/json/parse_common.c index b44ef08..f6cf78f 100644 --- a/src/json/parse_common.c +++ b/src/json/parse_common.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -31,3 +31,4 @@ out: free(err); return seccomp_spec; } + diff --git a/src/json/parse_common.h b/src/json/parse_common.h index 00ca45a..1f0bec1 100644 --- a/src/json/parse_common.h +++ b/src/json/parse_common.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -28,3 +28,4 @@ docker_seccomp *get_seccomp_security_opt_spec(const char *file); #endif #endif + diff --git a/src/json/schema/schema/container/exec-request.json b/src/json/schema/schema/container/exec-request.json index 173365a..233c6f0 100644 --- a/src/json/schema/schema/container/exec-request.json +++ b/src/json/schema/schema/container/exec-request.json @@ -34,6 +34,9 @@ }, "timeout": { "type": "int64" + }, + "user": { + "type": "string" } } -} +} \ No newline at end of file diff --git a/src/json/schema/schema/container/exec-response.json b/src/json/schema/schema/container/exec-response.json index 4f06af4..c860f6f 100644 --- a/src/json/schema/schema/container/exec-response.json +++ b/src/json/schema/schema/container/exec-response.json @@ -2,9 +2,6 @@ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { - "pid": { - "type": "int32" - }, "exit_code": { "type": "uint32" }, diff --git a/src/json/schema/schema/container/inspect.json b/src/json/schema/schema/container/inspect.json index 48ab66f..7d1573f 100644 --- a/src/json/schema/schema/container/inspect.json +++ b/src/json/schema/schema/container/inspect.json @@ -116,6 +116,9 @@ }, "HealthCheck": { "$ref": "../defs.json#/definitions/HealthCheck" + }, + "Image": { + "type":"string" } } }, diff --git a/src/json/schema/schema/cri/pod_network.json b/src/json/schema/schema/cri/pod_network.json index 7f57888..f6d83c9 100644 --- a/src/json/schema/schema/cri/pod_network.json +++ b/src/json/schema/schema/cri/pod_network.json @@ -4,10 +4,10 @@ "items": { "type": "object", "properties": { - "Name": { + "name": { "type": "string" }, - "Interface": { + "interface": { "type": "string" } } diff --git a/src/json/schema/schema/image/list-images-request.json b/src/json/schema/schema/image/list-images-request.json index 09283e3..6a58a74 100644 --- a/src/json/schema/schema/image/list-images-request.json +++ b/src/json/schema/schema/image/list-images-request.json @@ -3,7 +3,7 @@ "type": "object", "properties": { "filters": { - "$ref": "../defs.json#/definitions/ArrayOfStrings" + "$ref": "../defs.json#/definitions/filters" } } -} +} \ No newline at end of file diff --git a/src/json/schema/schema/imagetool/image.json b/src/json/schema/schema/imagetool/image.json index 2832be2..5b64a78 100644 --- a/src/json/schema/schema/imagetool/image.json +++ b/src/json/schema/schema/imagetool/image.json @@ -44,4 +44,4 @@ "$ref": "../defs.json#/definitions/HealthCheck" } } -} +} \ No newline at end of file diff --git a/src/json/schema/schema/imagetool/prepare-response.json b/src/json/schema/schema/imagetool/prepare-response.json index c87ef99..d209cda 100644 --- a/src/json/schema/schema/imagetool/prepare-response.json +++ b/src/json/schema/schema/imagetool/prepare-response.json @@ -6,4 +6,4 @@ "type": "string" } } -} +} \ No newline at end of file diff --git a/src/json/schema/schema/isulad-daemon-configs.json b/src/json/schema/schema/isulad-daemon-configs.json index c67a191..ca04ffa 100644 --- a/src/json/schema/schema/isulad-daemon-configs.json +++ b/src/json/schema/schema/isulad-daemon-configs.json @@ -59,7 +59,10 @@ "native.umask": { "type": "string" }, - "im_opt_timeout": { + "image-opt-timeout": { + "type": "string" + }, + "image-server-sock-addr": { "type": "string" }, "pod-sandbox-image": { diff --git a/src/json/schema/src/common_h.py b/src/json/schema/src/common_h.py index ce0b665..5f4ed68 100644 --- a/src/json/schema/src/common_h.py +++ b/src/json/schema/src/common_h.py @@ -44,13 +44,13 @@ extern "C" { # undef linux -//options to report error if there is unknown key found in json +// options to report error if there is unknown key found in json # define OPT_PARSE_STRICT 0x01 -//options to generate all key and value +// options to generate all key and value # define OPT_GEN_KAY_VALUE 0x02 -//options to generate simplify(no indent) json string +// options to generate simplify(no indent) json string # define OPT_GEN_SIMPLIFY 0x04 -//options not to validate utf8 data +// options not to validate utf8 data # define OPT_GEN_NO_VALIDATE_UTF8 0x08 # define GEN_SET_ERROR_AND_RETURN(stat, err) { \\ diff --git a/src/json/schema/src/generate.py b/src/json/schema/src/generate.py index 72e6d62..221570c 100644 --- a/src/json/schema/src/generate.py +++ b/src/json/schema/src/generate.py @@ -74,7 +74,7 @@ class MyRoot(object): return self.root_path -def trimJsonSuffix(name): +def trim_json_suffix(name): """ Description: generate c language for parse json map string object Interface: None @@ -82,10 +82,10 @@ def trimJsonSuffix(name): """ if name.endswith(JSON_SUFFIX) or name.endswith(REF_SUFFIX): name = name[:-len(JSON_SUFFIX)] - return helpers.convertToCStyle(name.replace('.', '_').replace('-', '_')) + return helpers.conv_to_c_style(name.replace('.', '_').replace('-', '_')) -def getPrefixPackage(filepath, rootpath): +def get_prefix_package(filepath, rootpath): """ Description: generate c language for parse json map string object Interface: None @@ -94,49 +94,52 @@ def getPrefixPackage(filepath, rootpath): realpath = os.path.realpath(filepath) if realpath.startswith(rootpath) and len(realpath) > len(rootpath): - return helpers.convertToCStyle(os.path.dirname(realpath)[(len(rootpath) + 1):]) + return helpers.conv_to_c_style(os.path.dirname(realpath)[(len(rootpath) + 1):]) else: raise RuntimeError('schema path \"%s\" is not in scope of root path \"%s\"' \ % (realpath, rootpath)) -def getPrefixFromFile(filepath): +def get_prefix_from_file(filepath): """ Description: generate c language for parse json map string object Interface: None History: 2019-06-17 """ - prefix_file = trimJsonSuffix(os.path.basename(filepath)) + prefix_file = trim_json_suffix(os.path.basename(filepath)) root_path = MyRoot.root_path - prefix_package = getPrefixPackage(filepath, root_path) + prefix_package = get_prefix_package(filepath, root_path) prefix = prefix_file if prefix_package == "" else prefix_package + "_" + prefix_file return prefix -def schemaFromFile(filepath, srcpath): + +def schema_from_file(filepath, srcpath): """ Description: generate c language for parse json map string object Interface: None History: 2019-06-17 """ schemapath = helpers.FilePath(filepath) - prefix = getPrefixFromFile(schemapath.name) + prefix = get_prefix_from_file(schemapath.name) header = helpers.FilePath(os.path.join(srcpath, prefix + ".h")) source = helpers.FilePath(os.path.join(srcpath, prefix + ".c")) schema_info = helpers.SchemaInfo(schemapath, header, source, prefix, srcpath) return schema_info -def makeRefName(refname, reffile): + +def make_ref_name(refname, reffile): """ Description: generate c language for parse json map string object Interface: None History: 2019-06-17 """ - prefix = getPrefixFromFile(reffile) + prefix = get_prefix_from_file(reffile) if refname == "" or prefix.endswith(refname): return prefix - return prefix + "_" + helpers.convertToCStyle(refname) + return prefix + "_" + helpers.conv_to_c_style(refname) -def splitRefName(ref): + +def splite_ref_name(ref): """ Description: generate c language for parse json map string object Interface: None @@ -145,6 +148,7 @@ def splitRefName(ref): tmp_f, tmp_r = ref.split("#/") if '#/' in ref else (ref, "") return tmp_f, tmp_r + def merge(children): """ Description: generate c language for parse json map string object @@ -166,7 +170,8 @@ BASIC_TYPES = ( "booleanPointer" ) -def judgeSupportedType(typ): + +def judge_support_type(typ): """ Description: generate c language for parse json map string object Interface: None @@ -174,7 +179,8 @@ def judgeSupportedType(typ): """ return typ in ("integer", "boolean", "string", "double") or typ in BASIC_TYPES -def getRefSubref(src, subref): + +def get_ref_subref(src, subref): """ Description: generate c language for parse json map string object Interface: None @@ -190,14 +196,15 @@ def getRefSubref(src, subref): return src, cur, subrefname -def getRefRoot(schema_info, src, ref, curfile): + +def get_ref_root(schema_info, src, ref, curfile): """ Description: generate c language for parse json map string object Interface: None History: 2019-06-17 """ refname = "" - tmp_f, tmp_r = splitRefName(ref) + tmp_f, tmp_r = splite_ref_name(ref) if tmp_f == "": cur = src @@ -205,7 +212,7 @@ def getRefRoot(schema_info, src, ref, curfile): realpath = os.path.realpath(os.path.join(os.path.dirname(curfile), tmp_f)) curfile = realpath - subschema = schemaFromFile(realpath, schema_info.filesdir) + subschema = schema_from_file(realpath, schema_info.filesdir) if schema_info.refs is None: schema_info.refs = {} schema_info.refs[subschema.header.basename] = subschema @@ -213,19 +220,20 @@ def getRefRoot(schema_info, src, ref, curfile): cur = src = json.loads(i.read()) subcur = cur if tmp_r != "": - src, subcur, refname = getRefSubref(src, tmp_r) + src, subcur, refname = get_ref_subref(src, tmp_r) if 'type' not in subcur and '$ref' in subcur: - subf, subr = splitRefName(subcur['$ref']) + subf, subr = splite_ref_name(subcur['$ref']) if subf == "": - src, subcur, refname = getRefSubref(src, subr) + src, subcur, refname = get_ref_subref(src, subr) if 'type' not in subcur: raise RuntimeError("Not support reference of nesting more than 2 level: ", ref) else: - return getRefRoot(schema_info, src, subcur['$ref'], curfile) - return src, subcur, curfile, makeRefName(refname, curfile) + return get_ref_root(schema_info, src, subcur['$ref'], curfile) + return src, subcur, curfile, make_ref_name(refname, curfile) -def getTypePatternInCur(cur, schema_info, src, curfile): + +def get_type_pattern_incur(cur, schema_info, src, curfile): """ Description: generate c language for parse json map string object Interface: None @@ -244,22 +252,23 @@ def getTypePatternInCur(cur, schema_info, src, curfile): if 'type' in value: val = value["type"] else: - dummy_subsrc, subcur, dummy_subcurfile, dummy_subrefname = getRefRoot( + dummy_subsrc, subcur, dummy_subcurfile, dummy_subrefname = get_ref_root( schema_info, src, value['$ref'], curfile) val = subcur['type'] break - mapKey = { + m_key = { 'object': 'Object', 'string': 'String', 'integer': 'Int', 'boolean': 'Bool' }[val] - map_val = mapKey + map_val = m_key typ = 'map' + map_key + map_val return typ + class GenerateNodeInfo(object): ''' Description: Store schema information @@ -289,7 +298,8 @@ class GenerateNodeInfo(object): ''' return self.name -def generateAllofArrayTypNode(node_info, src, typ, refname): + +def gen_all_arr_typnode(node_info, src, typ, refname): """ Description: generate c language for parse json map string object Interface: None @@ -302,7 +312,7 @@ def generateAllofArrayTypNode(node_info, src, typ, refname): subtyp = None subtypobj = None required = None - children = merge(parseList(schema_info, name, src, cur["items"]['allOf'], curfile)) + children = merge(resolve_list(schema_info, name, src, cur["items"]['allOf'], curfile)) subtyp = children[0].typ subtypobj = children return helpers.Unite(name, @@ -313,7 +323,8 @@ def generateAllofArrayTypNode(node_info, src, typ, refname): subtypname=refname, required=required), src -def generateAnyofArrayTypNode(node_info, src, typ, refname): + +def gen_any_arr_typnode(node_info, src, typ, refname): """ Description: generate c language for parse json map string object Interface: None @@ -326,7 +337,7 @@ def generateAnyofArrayTypNode(node_info, src, typ, refname): subtyp = None subtypobj = None required = None - anychildren = parseList(schema_info, name, src, cur["items"]['anyOf'], curfile) + anychildren = resolve_list(schema_info, name, src, cur["items"]['anyOf'], curfile) subtyp = anychildren[0].typ children = anychildren[0].children subtypobj = children @@ -339,7 +350,8 @@ def generateAnyofArrayTypNode(node_info, src, typ, refname): subtypname=refname, required=required), src -def generateRefArrayTypNode(node_info, src, typ, refname): + +def gen_ref_arr_typnode(node_info, src, typ, refname): """ Description: generate c language for parse json map string object Interface: None @@ -350,11 +362,11 @@ def generateRefArrayTypNode(node_info, src, typ, refname): cur = node_info.cur curfile = node_info.curfile - item_type, src = resolveType(schema_info, name, src, cur["items"], curfile) - ref_file, subref = splitRefName(cur['items']['$ref']) + item_type, src = resolve_type(schema_info, name, src, cur["items"], curfile) + ref_file, subref = splite_ref_name(cur['items']['$ref']) if ref_file == "": - src, dummy_subcur, subrefname = getRefSubref(src, subref) - refname = makeRefName(subrefname, curfile) + src, dummy_subcur, subrefname = get_ref_subref(src, subref) + refname = make_ref_name(subrefname, curfile) else: refname = item_type.subtypname return helpers.Unite(name, @@ -365,7 +377,8 @@ def generateRefArrayTypNode(node_info, src, typ, refname): subtypname=refname, required=item_type.required), src -def generateTypeArrayTypNode(node_info, src, typ, refname): + +def gen_type_arr_typnode(node_info, src, typ, refname): """ Description: generate c language for parse json map string object Interface: None @@ -376,7 +389,7 @@ def generateTypeArrayTypNode(node_info, src, typ, refname): cur = node_info.cur curfile = node_info.curfile - item_type, src = resolveType(schema_info, name, src, cur["items"], curfile) + item_type, src = resolve_type(schema_info, name, src, cur["items"], curfile) return helpers.Unite(name, typ, None, @@ -386,7 +399,7 @@ def generateTypeArrayTypNode(node_info, src, typ, refname): required=item_type.required), src -def generateArrayTypNode(node_info, src, typ, refname): +def gen_arr_typnode(node_info, src, typ, refname): """ Description: generate c language for parse json map string object Interface: None @@ -395,16 +408,17 @@ def generateArrayTypNode(node_info, src, typ, refname): cur = node_info.cur if 'allOf' in cur["items"]: - return generateAllofArrayTypNode(node_info, src, typ, refname) + return gen_all_arr_typnode(node_info, src, typ, refname) elif 'anyOf' in cur["items"]: - return generateAnyofArrayTypNode(node_info, src, typ, refname) + return gen_any_arr_typnode(node_info, src, typ, refname) elif '$ref' in cur["items"]: - return generateRefArrayTypNode(node_info, src, typ, refname) + return gen_ref_arr_typnode(node_info, src, typ, refname) elif 'type' in cur["items"]: - return generateTypeArrayTypNode(node_info, src, typ, refname) + return gen_type_arr_typnode(node_info, src, typ, refname) return None -def generateObjTypNode(node_info, src, typ, refname): + +def gen_obj_typnode(node_info, src, typ, refname): """ Description: generate c language for parse json map string object Interface: None @@ -420,18 +434,18 @@ def generateObjTypNode(node_info, src, typ, refname): required = None if 'allOf' in cur: - children = merge(parseList(schema_info, name, src, cur['allOf'], curfile)) + children = merge(resolve_list(schema_info, name, src, cur['allOf'], curfile)) elif 'anyOf' in cur: - children = parseList(schema_info, name, src, cur['anyOf'], curfile) + children = resolve_list(schema_info, name, src, cur['anyOf'], curfile) elif 'patternProperties' in cur: - children = parseProperties(schema_info, name, src, cur, curfile) + children = parse_properties(schema_info, name, src, cur, curfile) children[0].name = children[0].name.replace('_{1,}', 'element').replace('_{2,}', \ 'element') children[0].fixname = "values" - if helpers.validBasicMapName(children[0].typ): - children[0].name = helpers.makeBasicMapName(children[0].typ) + if helpers.valid_basic_map_name(children[0].typ): + children[0].name = helpers.make_basic_map_name(children[0].typ) else: - children = parseProperties(schema_info, name, src, cur, curfile) \ + children = parse_properties(schema_info, name, src, cur, curfile) \ if 'properties' in cur else None if 'required' in cur: required = cur['required'] @@ -443,14 +457,15 @@ def generateObjTypNode(node_info, src, typ, refname): subtypname=refname,\ required=required), src -def getTypNotOneof(schema_info, src, cur, curfile): + +def get_typ_notoneof(schema_info, src, cur, curfile): """ Description: generate c language for parse json map string object Interface: None History: 2019-06-17 """ if 'patternProperties' in cur: - typ = getTypePatternInCur(cur, schema_info, src, curfile) + typ = get_type_pattern_incur(cur, schema_info, src, curfile) elif "type" in cur: typ = cur["type"] else: @@ -459,7 +474,7 @@ def getTypNotOneof(schema_info, src, cur, curfile): return typ -def resolveType(schema_info, name, src, cur, curfile): +def resolve_type(schema_info, name, src, cur, curfile): """ Description: generate c language for parse json map string object Interface: None @@ -472,31 +487,31 @@ def resolveType(schema_info, name, src, cur, curfile): refname = None if '$ref' in cur: - src, cur, curfile, refname = getRefRoot(schema_info, src, cur['$ref'], curfile) + src, cur, curfile, refname = get_ref_root(schema_info, src, cur['$ref'], curfile) if "oneOf" in cur: cur = cur['oneOf'][0] if '$ref' in cur: - return resolveType(schema_info, name, src, cur, curfile) + return resolve_type(schema_info, name, src, cur, curfile) else: typ = cur['type'] else: - typ = getTypNotOneof(schema_info, src, cur, curfile) + typ = get_typ_notoneof(schema_info, src, cur, curfile) node_info = GenerateNodeInfo(schema_info, name, cur, curfile) - if helpers.validBasicMapName(typ): + if helpers.valid_basic_map_name(typ): pass elif typ == 'array': - return generateArrayTypNode(node_info, src, typ, refname) + return gen_arr_typnode(node_info, src, typ, refname) elif typ == 'object' or typ == 'mapStringObject': - return generateObjTypNode(node_info, src, typ, refname) + return gen_obj_typnode(node_info, src, typ, refname) elif typ == 'ArrayOfStrings': typ = 'array' subtyp = 'string' children = subtypobj = None else: - if not judgeSupportedType(typ): + if not judge_support_type(typ): raise RuntimeError("Invalid schema type: %s" % typ) children = None @@ -509,7 +524,7 @@ def resolveType(schema_info, name, src, cur, curfile): required=required), src -def parseList(schema_info, name, schema, objs, curfile): +def resolve_list(schema_info, name, schema, objs, curfile): """ Description: generate c language for parse json map string object Interface: None @@ -518,9 +533,10 @@ def parseList(schema_info, name, schema, objs, curfile): obj = [] index = 0 for i in objs: - generated_name = helpers.CombinationName( \ - i['$ref'].split("/")[-1]) if '$ref' in i else helpers.CombinationName(name.name + str(index)) - node, _ = resolveType(schema_info, generated_name, schema, i, curfile) + generated_name = helpers.CombinateName( \ + i['$ref'].split("/")[-1]) if '$ref' in i \ + else helpers.CombinateName(name.name + str(index)) + node, _ = resolve_type(schema_info, generated_name, schema, i, curfile) if node: obj.append(node) index += 1 @@ -529,7 +545,7 @@ def parseList(schema_info, name, schema, objs, curfile): return obj -def parseDictionary(schema_info, name, schema, objs, curfile): +def parse_dict(schema_info, name, schema, objs, curfile): """ Description: generate c language for parse json map string object Interface: None @@ -537,7 +553,7 @@ def parseDictionary(schema_info, name, schema, objs, curfile): """ obj = [] for i in objs: - node, _ = resolveType(schema_info, name.append(i), schema, objs[i], curfile) + node, _ = resolve_type(schema_info, name.append(i), schema, objs[i], curfile) if node: obj.append(node) if not obj: @@ -545,19 +561,20 @@ def parseDictionary(schema_info, name, schema, objs, curfile): return obj -def parseProperties(schema_info, name, schema, props, curfile): +def parse_properties(schema_info, name, schema, props, curfile): """ Description: generate c language for parse json map string object Interface: None History: 2019-06-17 """ if 'definitions' in props: - return parseDictionary(schema_info, name, schema, props['definitions'], curfile) + return parse_dict(schema_info, name, schema, props['definitions'], curfile) if 'patternProperties' in props: - return parseDictionary(schema_info, name, schema, props['patternProperties'], curfile) - return parseDictionary(schema_info, name, schema, props['properties'], curfile) + return parse_dict(schema_info, name, schema, props['patternProperties'], curfile) + return parse_dict(schema_info, name, schema, props['properties'], curfile) -def handleTypeNotInSchema(schema_info, schema, prefix): + +def handle_type_not_in_schema(schema_info, schema, prefix): """ Description: generate c language for parse json map string object Interface: None @@ -566,8 +583,8 @@ def handleTypeNotInSchema(schema_info, schema, prefix): required = None if 'definitions' in schema: return helpers.Unite( \ - helpers.CombinationName("definitions"), 'definitions', \ - parseProperties(schema_info, helpers.CombinationName(""), schema, schema, \ + helpers.CombinateName("definitions"), 'definitions', \ + parse_properties(schema_info, helpers.CombinateName(""), schema, schema, \ schema_info.name.name), None, None, None, None) else: if len(schema) > 1: @@ -577,15 +594,19 @@ def handleTypeNotInSchema(schema_info, schema, prefix): for value in schema: if 'required' in schema[value]: required = schema[value]['required'] - childrens = parseProperties(schema_info, helpers.CombinationName(""), schema[value], \ - schema[value], schema_info.name.name) - value_node = helpers.Unite(helpers.CombinationName(prefix), 'object', childrens, None, None, \ - None, required) + childrens = parse_properties(schema_info, helpers.CombinateName(""), \ + schema[value], schema[value], \ + schema_info.name.name) + value_node = helpers.Unite(helpers.CombinateName(prefix), \ + 'object', childrens, None, None, \ + None, required) value_nodes.append(value_node) - return helpers.Unite(helpers.CombinationName("definitions"), 'definitions', value_nodes, None, None, \ + return helpers.Unite(helpers.CombinateName("definitions"), \ + 'definitions', value_nodes, None, None, \ None, None) -def parseSchema(schema_info, schema, prefix): + +def parse_schema(schema_info, schema, prefix): """ Description: generate c language for parse json map string object Interface: None @@ -593,23 +614,21 @@ def parseSchema(schema_info, schema, prefix): """ required = None if 'type' not in schema: - return handleTypeNotInSchema(schema_info, schema, prefix) - - if 'type' not in schema: - print("No 'type' defined in schema") - return prefix, None + return handle_type_not_in_schema(schema_info, schema, prefix) if 'object' in schema['type']: if 'required' in schema: required = schema['required'] return helpers.Unite( - helpers.CombinationName(prefix), 'object', - parseProperties(schema_info, helpers.CombinationName(""), schema, schema, schema_info.name.name), \ + helpers.CombinateName(prefix), 'object', + parse_properties(schema_info, \ + helpers.CombinateName(""), \ + schema, schema, schema_info.name.name), \ None, None, None, required) elif 'array' in schema['type']: - item_type, _ = resolveType(schema_info, helpers.CombinationName(""), schema['items'], \ - schema['items'], schema_info.name.name) - return helpers.Unite(helpers.CombinationName(prefix), 'array', None, item_type.typ, \ + item_type, _ = resolve_type(schema_info, helpers.CombinateName(""), \ + schema['items'], schema['items'], schema_info.name.name) + return helpers.Unite(helpers.CombinateName(prefix), 'array', None, item_type.typ, \ item_type.children, None, item_type.required) else: print("Not supported type '%s'") % schema['type'] @@ -631,8 +650,8 @@ def expand(tree, structs, visited): for i in tree.subtypobj: expand(i, structs, visited=visited) - if tree.typ == 'array' and helpers.validBasicMapName(tree.subtyp): - name = helpers.CombinationName(tree.name + "_element") + if tree.typ == 'array' and helpers.valid_basic_map_name(tree.subtyp): + name = helpers.CombinateName(tree.name + "_element") node = helpers.Unite(name, tree.subtyp, None) expand(node, structs, visited) @@ -658,13 +677,13 @@ def reflection(schema_info, gen_ref): with open(schema_info.name.name) as schema_file: schema_json = json.loads(schema_file.read(), object_pairs_hook=OrderedDict) try: - tree = parseSchema(schema_info, schema_json, schema_info.prefix) + tree = parse_schema(schema_info, schema_json, schema_info.prefix) if tree is None: print("Failed parse schema") sys.exit(1) structs = expand(tree, [], {}) - headers.headerReflection(structs, schema_info, header_file) - sources.sourceReflection(structs, schema_info, source_file, tree.typ) + headers.header_reflect(structs, schema_info, header_file) + sources.src_reflect(structs, schema_info, source_file, tree.typ) except RuntimeError: traceback.print_exc() print("Failed to parse schema file: %s") % schema_info.name.name @@ -681,7 +700,7 @@ def reflection(schema_info, gen_ref): reflection(reffile, True) -def generateCommonFiles(out): +def gen_common_files(out): """ Description: generate c language for parse json map string object Interface: None @@ -699,7 +718,8 @@ def generateCommonFiles(out): fcntl.flock(source_file, fcntl.LOCK_UN) fcntl.flock(header_file, fcntl.LOCK_UN) -def handlerSingleFile(args, srcpath, gen_ref, schemapath): + +def handle_single_file(args, srcpath, gen_ref, schemapath): """ Description: generate c language for parse json map string object Interface: None @@ -715,7 +735,7 @@ def handlerSingleFile(args, srcpath, gen_ref, schemapath): for dirpath, dummy_dirnames, files in os.walk(schemapath.name): for target_file in files: if target_file.endswith(JSON_SUFFIX): - schema_info = schemaFromFile(os.path.join(dirpath, target_file), \ + schema_info = schema_from_file(os.path.join(dirpath, target_file), \ srcpath.name) reflection(schema_info, gen_ref) else: @@ -723,17 +743,17 @@ def handlerSingleFile(args, srcpath, gen_ref, schemapath): for target_file in os.listdir(schemapath.name): fullpath = os.path.join(schemapath.name, target_file) if fullpath.endswith(JSON_SUFFIX) and os.path.isfile(fullpath): - schema_info = schemaFromFile(fullpath, srcpath.name) + schema_info = schema_from_file(fullpath, srcpath.name) reflection(schema_info, gen_ref) else: if schemapath.name.endswith(JSON_SUFFIX): - schema_info = schemaFromFile(schemapath.name, srcpath.name) + schema_info = schema_from_file(schemapath.name, srcpath.name) reflection(schema_info, gen_ref) else: print('File %s is not ends with .json') % schemapath.name -def handlerFiles(args, srcpath): +def handle_files(args, srcpath): """ Description: generate c language for parse json map string object Interface: None @@ -742,7 +762,8 @@ def handlerFiles(args, srcpath): for path in args.path: gen_ref = args.gen_ref schemapath = helpers.FilePath(path) - handlerSingleFile(args, srcpath, gen_ref, schemapath) + handle_single_file(args, srcpath, gen_ref, schemapath) + def main(): """ @@ -795,8 +816,11 @@ def main(): os.makedirs(srcpath.name) if args.gen_common: - generateCommonFiles(srcpath.name) - handlerFiles(args, srcpath) + gen_common_files(srcpath.name) + handle_files(args, srcpath) + if __name__ == "__main__": main() + + diff --git a/src/json/schema/src/headers.py b/src/json/schema/src/headers.py index 972e36c..a2cff89 100644 --- a/src/json/schema/src/headers.py +++ b/src/json/schema/src/headers.py @@ -19,7 +19,7 @@ History: 2019-06-17 #!/usr/bin/python -Es import helpers -def appendHeaderArray(obj, header, prefix): +def append_header_arr(obj, header, prefix): ''' Description: Write c header file of array Interface: None @@ -30,28 +30,29 @@ def appendHeaderArray(obj, header, prefix): header.write("typedef struct {\n") for i in obj.subtypobj: if i.typ == 'array': - c_typ = helpers.getPrefixPointer(i.name, i.subtyp, prefix) or \ - helpers.getMapCTypes(i.subtyp) + c_typ = helpers.get_prefixe_pointer(i.name, i.subtyp, prefix) or \ + helpers.get_map_c_types(i.subtyp) if i.subtypobj is not None: - c_typ = helpers.getNameSubstr(i.name, prefix) + c_typ = helpers.get_name_substr(i.name, prefix) - if not helpers.judgeComplex(i.subtyp): + if not helpers.judge_complex(i.subtyp): header.write(" %s%s*%s;\n" % (c_typ, " " if '*' not in c_typ else "", \ i.fixname)) else: header.write(" %s **%s;\n" % (c_typ, i.fixname)) header.write(" size_t %s;\n\n" % (i.fixname + "_len")) else: - c_typ = helpers.getPrefixPointer(i.name, i.typ, prefix) or \ - helpers.getMapCTypes(i.typ) + c_typ = helpers.get_prefixe_pointer(i.name, i.typ, prefix) or \ + helpers.get_map_c_types(i.typ) header.write(" %s%s%s;\n" % (c_typ, " " if '*' not in c_typ else "", i.fixname)) - typename = helpers.getNameSubstr(obj.name, prefix) + typename = helpers.get_name_substr(obj.name, prefix) header.write("}\n%s;\n\n" % typename) header.write("void free_%s(%s *ptr);\n\n" % (typename, typename)) header.write("%s *make_%s(yajl_val tree, const struct parser_context *ctx, parser_error *err);"\ "\n\n" % (typename, typename)) -def appendHeaderMapStrObj(obj, header, prefix): + +def append_header_map_str_obj(obj, header, prefix): ''' Description: Write c header file of mapStringObject Interface: None @@ -60,86 +61,89 @@ def appendHeaderMapStrObj(obj, header, prefix): child = obj.children[0] header.write("typedef struct {\n") header.write(" char **keys;\n") - if helpers.validBasicMapName(child.typ): - c_typ = helpers.getPrefixPointer("", child.typ, "") + if helpers.valid_basic_map_name(child.typ): + c_typ = helpers.get_prefixe_pointer("", child.typ, "") elif child.subtypname: c_typ = child.subtypname else: - c_typ = helpers.getPrefixPointer(child.name, child.typ, prefix) + c_typ = helpers.get_prefixe_pointer(child.name, child.typ, prefix) header.write(" %s%s*%s;\n" % (c_typ, " " if '*' not in c_typ else "", child.fixname)) header.write(" size_t len;\n") -def appendHeaderChildArray(child, header, prefix): + +def append_header_child_arr(child, header, prefix): ''' Description: Write c header file of array of child Interface: None History: 2019-06-17 ''' - if helpers.getMapCTypes(child.subtyp) != "": - c_typ = helpers.getMapCTypes(child.subtyp) - elif helpers.validBasicMapName(child.subtyp): - c_typ = '%s *' % helpers.makeBasicMapName(child.subtyp) + if helpers.get_map_c_types(child.subtyp) != "": + c_typ = helpers.get_map_c_types(child.subtyp) + elif helpers.valid_basic_map_name(child.subtyp): + c_typ = '%s *' % helpers.make_basic_map_name(child.subtyp) elif child.subtypname is not None: c_typ = child.subtypname elif child.subtypobj is not None: - c_typ = helpers.getNameSubstr(child.name, prefix) + c_typ = helpers.get_name_substr(child.name, prefix) else: - c_typ = helpers.getPrefixPointer(child.name, child.subtyp, prefix) + c_typ = helpers.get_prefixe_pointer(child.name, child.subtyp, prefix) - if helpers.validBasicMapName(child.subtyp): - header.write(" %s **%s;\n" % (helpers.makeBasicMapName(child.subtyp), child.fixname)) - elif not helpers.judgeComplex(child.subtyp): + if helpers.valid_basic_map_name(child.subtyp): + header.write(" %s **%s;\n" % (helpers.make_basic_map_name(child.subtyp), child.fixname)) + elif not helpers.judge_complex(child.subtyp): header.write(" %s%s*%s;\n" % (c_typ, " " if '*' not in c_typ else "", child.fixname)) else: header.write(" %s%s**%s;\n" % (c_typ, " " if '*' not in c_typ else "", child.fixname)) header.write(" size_t %s;\n\n" % (child.fixname + "_len")) -def appendHeaderChildOthers(child, header, prefix): + +def append_header_child_others(child, header, prefix): ''' Description: Write c header file of others of child Interface: None History: 2019-06-17 ''' - if helpers.getMapCTypes(child.typ) != "": - c_typ = helpers.getMapCTypes(child.typ) - elif helpers.validBasicMapName(child.typ): - c_typ = '%s *' % helpers.makeBasicMapName(child.typ) + if helpers.get_map_c_types(child.typ) != "": + c_typ = helpers.get_map_c_types(child.typ) + elif helpers.valid_basic_map_name(child.typ): + c_typ = '%s *' % helpers.make_basic_map_name(child.typ) elif child.subtypname: - c_typ = helpers.getPrefixPointer(child.subtypname, child.typ, "") + c_typ = helpers.get_prefixe_pointer(child.subtypname, child.typ, "") else: - c_typ = helpers.getPrefixPointer(child.name, child.typ, prefix) + c_typ = helpers.get_prefixe_pointer(child.name, child.typ, prefix) header.write(" %s%s%s;\n\n" % (c_typ, " " if '*' not in c_typ else "", child.fixname)) -def appendTypeCHeader(obj, header, prefix): + +def append_type_c_header(obj, header, prefix): ''' Description: Write c header file Interface: None History: 2019-06-17 ''' - if not helpers.judgeComplex(obj.typ): + if not helpers.judge_complex(obj.typ): return if obj.typ == 'array': - appendHeaderArray(obj, header, prefix) + append_header_arr(obj, header, prefix) return if obj.typ == 'mapStringObject': if obj.subtypname is not None: return - appendHeaderMapStrObj(obj, header, prefix) + append_header_map_str_obj(obj, header, prefix) elif obj.typ == 'object': if obj.subtypname is not None: return header.write("typedef struct {\n") if obj.children is None: - header.write(" char unuseful;//unuseful definition to avoid empty struct\n") - for i in obj.children or [ ]: + header.write(" char unuseful; // unuseful definition to avoid empty struct\n") + for i in obj.children or []: if i.typ == 'array': - appendHeaderChildArray(i, header, prefix) + append_header_child_arr(i, header, prefix) else: - appendHeaderChildOthers(i, header, prefix) + append_header_child_others(i, header, prefix) - typename = helpers.getPrefixName(obj.name, prefix) + typename = helpers.get_prefixe_name(obj.name, prefix) header.write("}\n%s;\n\n" % typename) header.write("void free_%s(%s *ptr);\n\n" % (typename, typename)) header.write("%s *make_%s(yajl_val tree, const struct parser_context *ctx, parser_error *err)"\ @@ -147,7 +151,8 @@ def appendTypeCHeader(obj, header, prefix): header.write("yajl_gen_status gen_%s(yajl_gen g, const %s *ptr, const struct parser_context "\ "*ctx, parser_error *err);\n\n" % (typename, typename)) -def headerReflection(structs, schema_info, header): + +def header_reflect(structs, schema_info, header): ''' Description: Reflection header files Interface: None @@ -168,7 +173,7 @@ def headerReflection(structs, schema_info, header): header.write("#endif\n\n") for i in structs: - appendTypeCHeader(i, header, prefix) + append_type_c_header(i, header, prefix) length = len(structs) toptype = structs[length - 1].typ if length != 0 else "" if toptype == 'object': @@ -195,3 +200,4 @@ def headerReflection(structs, schema_info, header): header.write("}\n") header.write("#endif\n\n") header.write("#endif\n\n") + diff --git a/src/json/schema/src/helpers.py b/src/json/schema/src/helpers.py index b88ed69..ca4e5aa 100644 --- a/src/json/schema/src/helpers.py +++ b/src/json/schema/src/helpers.py @@ -20,16 +20,16 @@ History: 2019-06-17 import os import sys -def appendSeparator(subStr): +def append_separator(substr): ''' Description: append only '_' at last position of subStr Interface: None History: 2019-09-20 ''' - if subStr and subStr[-1] != '_': - subStr.append('_') + if substr and substr[-1] != '_': + substr.append('_') -def convertToCStyle(name): +def conv_to_c_style(name): ''' Description: convert name to linux c format Interface: None @@ -38,33 +38,33 @@ def convertToCStyle(name): if name is None or name == "": return "" name = name.replace('.', '_').replace('-', '_').replace('/', '_') - subStr = [] + substr = [] preindex = 0 index = 0 for index, char in enumerate(name): if char == '_': - appendSeparator(subStr) - subStr.append(name[preindex:index].lower()) + append_separator(substr) + substr.append(name[preindex:index].lower()) preindex = index + 1 if not char.isupper() and name[preindex].isupper() and \ name[preindex + 1].isupper(): - appendSeparator(subStr) - subStr.append(name[preindex:index - 1].lower()) + append_separator(substr) + substr.append(name[preindex:index - 1].lower()) preindex = index - 1 continue if char.isupper() and index > 0 and name[index - 1].islower(): - appendSeparator(subStr) - subStr.append(name[preindex:index].lower()) + append_separator(substr) + substr.append(name[preindex:index].lower()) preindex = index if preindex <= index and index >= 0 and name[index] != '_' and \ preindex != 0: - appendSeparator(subStr) - subStr.append(name[preindex:index + 1].lower()) - result = ''.join(subStr) + append_separator(substr) + substr.append(name[preindex:index + 1].lower()) + result = ''.join(substr) return result -def getMapCTypes(typ): +def get_map_c_types(typ): ''' Description: Get map c types Interface: None @@ -103,7 +103,7 @@ def getMapCTypes(typ): return map_c_types[typ] return "" -def validBasicMapName(typ): +def valid_basic_map_name(typ): ''' Description: Valid basic map name Interface: None @@ -112,14 +112,14 @@ def validBasicMapName(typ): return typ != 'mapStringObject' and hasattr(typ, 'startswith') and \ typ.startswith('map') -def makeBasicMapName(mapname): +def make_basic_map_name(mapname): ''' Description: Make basic map name Interface: None History: 2019-06-17 ''' basic_map_types = ('string', 'int', 'bool') - parts = convertToCStyle(mapname).split('_') + parts = conv_to_c_style(mapname).split('_') if len(parts) != 3 or parts[0] != 'map' or \ (parts[1] not in basic_map_types) or \ (parts[2] not in basic_map_types): @@ -128,7 +128,7 @@ def makeBasicMapName(mapname): return "json_map_%s_%s" % (parts[1], parts[2]) -def getNameSubstr(name, prefix): +def get_name_substr(name, prefix): ''' Description: Make array name Interface: None @@ -137,7 +137,7 @@ def getNameSubstr(name, prefix): return "%s_element" % prefix if name is None or name == "" or prefix == name \ else "%s_%s_element" % (prefix, name) -def getPrefixName(name, prefix): +def get_prefixe_name(name, prefix): ''' Description: Make name Interface: None @@ -149,19 +149,19 @@ def getPrefixName(name, prefix): return "%s" % name return "%s_%s" % (prefix, name) -def getPrefixPointer(name, typ, prefix): +def get_prefixe_pointer(name, typ, prefix): ''' Description: Make pointer name Interface: None History: 2019-06-17 ''' if typ != 'object' and typ != 'mapStringObject' and \ - not validBasicMapName(typ): + not valid_basic_map_name(typ): return "" - return '%s *' % makeBasicMapName(typ) if validBasicMapName(typ) \ - else "%s *" % getPrefixName(name, prefix) + return '%s *' % make_basic_map_name(typ) if valid_basic_map_name(typ) \ + else "%s *" % get_prefixe_name(name, prefix) -def judgeComplex(typ): +def judge_complex(typ): ''' Description: Check compound object Interface: None @@ -169,7 +169,7 @@ def judgeComplex(typ): ''' return typ in ('object', 'array', 'mapStringObject') -def judgeDataType(typ): +def judge_data_type(typ): ''' Description: Check numeric type Interface: None @@ -180,7 +180,7 @@ def judgeDataType(typ): return True return typ in ("integer", "UID", "GID", "double") -def judgeDataPointerType(typ): +def judge_data_pointer_type(typ): ''' Description: Check numeric pointer type Interface: None @@ -190,7 +190,7 @@ def judgeDataPointerType(typ): return True return False -def obtainDataPointerType(typ): +def obtain_data_pointer_type(typ): ''' Description: Get numeric pointer type Interface: None @@ -199,22 +199,22 @@ def obtainDataPointerType(typ): index = typ.find("Pointer") return typ[0:index] if index != -1 else "" -def obtainPointer(name, typ, prefix): +def obtain_pointer(name, typ, prefix): ''' Description: Obtain pointer string Interface: None History: 2019-06-17 ''' - ptr = getPrefixPointer(name, typ, prefix) + ptr = get_prefixe_pointer(name, typ, prefix) if ptr != "": return ptr return "char *" if typ == "string" else \ ("%s *" % typ if typ == "ArrayOfStrings" else "") -class CombinationName(object): +class CombinateName(object): ''' - Description: Store CombinationName information + Description: Store CombinateName information Interface: None History: 2019-06-17 ''' @@ -236,7 +236,7 @@ class CombinationName(object): History: 2019-06-17 ''' prefix_name = self.name + '_' if self.name != "" else "" - return CombinationName(prefix_name + leaf, leaf) + return CombinateName(prefix_name + leaf, leaf) class Unite(object): @@ -253,9 +253,9 @@ class Unite(object): self.subtypobj = subtypobj self.subtypname = subtypname self.required = required - self.name = convertToCStyle(name.name.replace('.', '_')) + self.name = conv_to_c_style(name.name.replace('.', '_')) self.origname = name.leaf or name.name - self.fixname = convertToCStyle(self.origname.replace('.', '_')) + self.fixname = conv_to_c_style(self.origname.replace('.', '_')) @@ -297,7 +297,7 @@ class SchemaInfo(object): def __init__(self, name, header, source, prefix, filesdir, refs=None): self.name = name - self.fileprefix = convertToCStyle( \ + self.fileprefix = conv_to_c_style( \ name.basename.replace('.', '_').replace('-', '_')) self.header = header self.source = source @@ -311,3 +311,7 @@ class SchemaInfo(object): def __str__(self): return self.__repr__(self) + + + + diff --git a/src/json/schema/src/read_file.c b/src/json/schema/src/read_file.c index 530e52e..beecd91 100644 --- a/src/json/schema/src/read_file.c +++ b/src/json/schema/src/read_file.c @@ -149,3 +149,4 @@ char *read_file(const char *path, size_t *length) (void)fclose(fp); return buf; } + diff --git a/src/json/schema/src/read_file.h b/src/json/schema/src/read_file.h index cc14940..af57f5b 100644 --- a/src/json/schema/src/read_file.h +++ b/src/json/schema/src/read_file.h @@ -23,3 +23,4 @@ char *fread_file(FILE *stream, size_t *length); char *read_file(const char *path, size_t *length); #endif + diff --git a/src/json/schema/src/sources.py b/src/json/schema/src/sources.py index 6835a9e..2cb5982 100644 --- a/src/json/schema/src/sources.py +++ b/src/json/schema/src/sources.py @@ -19,30 +19,31 @@ History: 2018-04-25 created import helpers -def appendCCode(obj, c_file, prefix): +def append_c_code(obj, c_file, prefix): """ Description: append c language code to file Interface: None History: 2019-06-17 """ - parseJsonToC(obj, c_file, prefix) - makeCFree(obj, c_file, prefix) - obtainCJson(obj, c_file, prefix) + parse_json_to_c(obj, c_file, prefix) + make_c_free(obj, c_file, prefix) + get_c_json(obj, c_file, prefix) -def parseMapStringObject(obj, c_file, prefix, obj_typename): + +def parse_map_string_obj(obj, c_file, prefix, obj_typename): """ Description: generate c language for parse json map string object Interface: None History: 2019-06-17 """ child = obj.children[0] - if helpers.validBasicMapName(child.typ): - childname = helpers.makeBasicMapName(child.typ) + if helpers.valid_basic_map_name(child.typ): + childname = helpers.make_basic_map_name(child.typ) else: if child.subtypname: childname = child.subtypname else: - childname = helpers.getPrefixName(child.name, prefix) + childname = helpers.get_prefixe_name(child.name, prefix) c_file.write(' if (YAJL_GET_OBJECT(tree) != NULL && YAJL_GET_OBJECT(tree)->len > 0) {\n') c_file.write(' size_t i;\n') c_file.write(' ret->len = YAJL_GET_OBJECT(tree)->len;\n') @@ -63,7 +64,8 @@ def parseMapStringObject(obj, c_file, prefix, obj_typename): c_file.write(' }\n') c_file.write(' }\n') -def parseObjectType(obj, c_file, prefix, obj_typename): + +def parse_obj_type(obj, c_file, prefix, obj_typename): """ Description: generate c language for parse object type Interface: None @@ -71,34 +73,34 @@ def parseObjectType(obj, c_file, prefix, obj_typename): """ if obj.typ == 'string': c_file.write(' {\n') - readValueGenerator(c_file, 2, 'get_val(tree, "%s", yajl_t_string)' % obj.origname, \ + read_val_generator(c_file, 2, 'get_val(tree, "%s", yajl_t_string)' % obj.origname, \ "ret->%s" % obj.fixname, obj.typ, obj.origname, obj_typename) c_file.write(' }\n') - elif helpers.judgeDataType(obj.typ): + elif helpers.judge_data_type(obj.typ): c_file.write(' {\n') - readValueGenerator(c_file, 2, 'get_val(tree, "%s", yajl_t_number)' % obj.origname, \ + read_val_generator(c_file, 2, 'get_val(tree, "%s", yajl_t_number)' % obj.origname, \ "ret->%s" % obj.fixname, obj.typ, obj.origname, obj_typename) c_file.write(' }\n') - elif helpers.judgeDataPointerType(obj.typ): + elif helpers.judge_data_pointer_type(obj.typ): c_file.write(' {\n') - readValueGenerator(c_file, 2, 'get_val(tree, "%s", yajl_t_number)' % obj.origname, \ + read_val_generator(c_file, 2, 'get_val(tree, "%s", yajl_t_number)' % obj.origname, \ "ret->%s" % obj.fixname, obj.typ, obj.origname, obj_typename) c_file.write(' }\n') if obj.typ == 'boolean': c_file.write(' {\n') - readValueGenerator(c_file, 2, 'get_val(tree, "%s", yajl_t_true)' % obj.origname, \ + read_val_generator(c_file, 2, 'get_val(tree, "%s", yajl_t_true)' % obj.origname, \ "ret->%s" % obj.fixname, obj.typ, obj.origname, obj_typename) c_file.write(' }\n') if obj.typ == 'booleanPointer': c_file.write(' {\n') - readValueGenerator(c_file, 2, 'get_val(tree, "%s", yajl_t_true)' % obj.origname, \ + read_val_generator(c_file, 2, 'get_val(tree, "%s", yajl_t_true)' % obj.origname, \ "ret->%s" % obj.fixname, obj.typ, obj.origname, obj_typename) c_file.write(' }\n') elif obj.typ == 'object' or obj.typ == 'mapStringObject': if obj.subtypname is not None: typename = obj.subtypname else: - typename = helpers.getPrefixName(obj.name, prefix) + typename = helpers.get_prefixe_name(obj.name, prefix) c_file.write( ' ret->%s = make_%s(get_val(tree, "%s", yajl_t_object), ctx, err);\n' \ % (obj.fixname, typename, obj.origname)) @@ -110,7 +112,7 @@ def parseObjectType(obj, c_file, prefix, obj_typename): if obj.subtypname: typename = obj.subtypname else: - typename = helpers.getNameSubstr(obj.name, prefix) + typename = helpers.get_name_substr(obj.name, prefix) c_file.write(' {\n') c_file.write(' yajl_val tmp = get_val(tree, "%s", yajl_t_array);\n' \ % (obj.origname)) @@ -155,18 +157,18 @@ def parseObjectType(obj, c_file, prefix, obj_typename): ' ret->%s = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) *' \ ' sizeof(*ret->%s));\n' % (obj.fixname, obj.fixname)) c_file.write(' for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) {\n') - readValueGenerator(c_file, 4, 'YAJL_GET_ARRAY(tmp)->values[i]', \ + read_val_generator(c_file, 4, 'YAJL_GET_ARRAY(tmp)->values[i]', \ "ret->%s[i]" % obj.fixname, obj.subtyp, obj.origname, obj_typename) c_file.write(' }\n') c_file.write(' }\n') c_file.write(' }\n') - elif helpers.validBasicMapName(obj.typ): + elif helpers.valid_basic_map_name(obj.typ): c_file.write(' {\n') c_file.write(' yajl_val tmp = get_val(tree, "%s", yajl_t_object);\n' \ % (obj.origname)) c_file.write(' if (tmp != NULL) {\n') c_file.write(' ret->%s = make_%s(tmp, ctx, err);\n' \ - % (obj.fixname, helpers.makeBasicMapName(obj.typ))) + % (obj.fixname, helpers.make_basic_map_name(obj.typ))) c_file.write(' if (ret->%s == NULL) {\n' % (obj.fixname)) c_file.write(' char *new_error = NULL;\n') c_file.write(" if (asprintf(&new_error, \"Value error for key" \ @@ -182,20 +184,19 @@ def parseObjectType(obj, c_file, prefix, obj_typename): c_file.write(' }\n') c_file.write(' }\n') -def parseObjectOrArrayObject(obj, c_file, prefix, obj_typename): +def parse_obj_arr_obj(obj, c_file, prefix, obj_typename): """ Description: generate c language for parse object or array object Interface: None History: 2019-06-17 """ nodes = obj.children if obj.typ == 'object' else obj.subtypobj - required_to_check = [] for i in nodes or []: if obj.required and i.origname in obj.required and \ - not helpers.judgeDataType(i.typ) and i.typ != 'boolean': + not helpers.judge_data_type(i.typ) and i.typ != 'boolean': required_to_check.append(i) - parseObjectType(i, c_file, prefix, obj_typename) + parse_obj_type(i, c_file, prefix, obj_typename) for i in required_to_check: c_file.write(' if (ret->%s == NULL) {\n' % i.fixname) @@ -222,26 +223,24 @@ def parseObjectOrArrayObject(obj, c_file, prefix, obj_typename): } """ % condition) -def parseJsonToC(obj, c_file, prefix): + +def parse_json_to_c(obj, c_file, prefix): """ Description: generate c language for parse json file Interface: None History: 2019-06-17 """ - if not helpers.judgeComplex(obj.typ): + if not helpers.judge_complex(obj.typ): return - if obj.typ == 'object' or obj.typ == 'mapStringObject': if obj.subtypname: return - obj_typename = typename = helpers.getPrefixName(obj.name, prefix) - + obj_typename = typename = helpers.get_prefixe_name(obj.name, prefix) if obj.typ == 'array': - obj_typename = typename = helpers.getNameSubstr(obj.name, prefix) + obj_typename = typename = helpers.get_name_substr(obj.name, prefix) objs = obj.subtypobj if objs is None or obj.subtypname: return - c_file.write("%s *make_%s(yajl_val tree, const struct parser_context *ctx, "\ "parser_error *err) {\n" % (typename, typename)) c_file.write(" %s *ret = NULL;\n" % (typename)) @@ -249,31 +248,29 @@ def parseJsonToC(obj, c_file, prefix): c_file.write(" if (tree == NULL)\n") c_file.write(" return ret;\n") c_file.write(" ret = safe_malloc(sizeof(*ret));\n") - if obj.typ == 'mapStringObject': - parseMapStringObject(obj, c_file, prefix, obj_typename) + parse_map_string_obj(obj, c_file, prefix, obj_typename) if obj.typ == 'object' or (obj.typ == 'array' and obj.subtypobj): - parseObjectOrArrayObject(obj, c_file, prefix, obj_typename) - + parse_obj_arr_obj(obj, c_file, prefix, obj_typename) c_file.write(' return ret;\n') c_file.write("}\n\n") -def obtainMapStringObject(obj, c_file, prefix): +def get_map_string_obj(obj, c_file, prefix): """ Description: c language generate map string object Interface: None History: 2019-06-17 """ child = obj.children[0] - if helpers.validBasicMapName(child.typ): - childname = helpers.makeBasicMapName(child.typ) + if helpers.valid_basic_map_name(child.typ): + childname = helpers.make_basic_map_name(child.typ) else: if child.subtypname: childname = child.subtypname else: - childname = helpers.getPrefixName(child.name, prefix) + childname = helpers.get_prefixe_name(child.name, prefix) c_file.write(' size_t len = 0, i;\n') c_file.write(" if (ptr != NULL)\n") c_file.write(" len = ptr->len;\n") @@ -286,7 +283,8 @@ def obtainMapStringObject(obj, c_file, prefix): % child.fixname) c_file.write(' for (i = 0; i < len; i++) {\n') c_file.write(' char *str = ptr->keys[i] ? ptr->keys[i] : "";\n') - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)str, strlen(str));\n') + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)str, strlen(str));\n') c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(' stat = gen_%s(g, ptr->%s[i], ctx, err);\n' \ @@ -301,7 +299,8 @@ def obtainMapStringObject(obj, c_file, prefix): c_file.write(" if (!len && !(ctx->options & OPT_GEN_SIMPLIFY))\n") c_file.write(' yajl_gen_config(g, yajl_gen_beautify, 1);\n') -def obtainObjectOrArrayObject(obj, c_file, prefix): + +def get_obj_arr_obj(obj, c_file, prefix): """ Description: c language generate object or array object Interface: None @@ -311,17 +310,16 @@ def obtainObjectOrArrayObject(obj, c_file, prefix): c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) ||' \ ' (ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) c_file.write(' char *str = "";\n') - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)("%s"), strlen("%s"));\n' \ - % (obj.origname, obj.origname)) + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s != NULL) {\n" % obj.fixname) c_file.write(" str = ptr->%s;\n" % obj.fixname) c_file.write(" }\n") - jsonValueGenerator(c_file, 2, "str", 'g', 'ctx', obj.typ) + json_value_generator(c_file, 2, "str", 'g', 'ctx', obj.typ) c_file.write(" }\n") - - elif helpers.judgeDataType(obj.typ): + elif helpers.judge_data_type(obj.typ): c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) ||' \ ' (ptr != NULL && ptr->%s)) {\n' % obj.fixname) if obj.typ == 'double': @@ -331,55 +329,53 @@ def obtainObjectOrArrayObject(obj, c_file, prefix): else: numtyp = 'long long int' c_file.write(' %s num = 0;\n' % numtyp) - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)("%s"), strlen("%s"));\n' \ - % (obj.origname, obj.origname)) + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s) {\n" % obj.fixname) c_file.write(" num = (%s)ptr->%s;\n" % (numtyp, obj.fixname)) c_file.write(" }\n") - jsonValueGenerator(c_file, 2, "num", 'g', 'ctx', obj.typ) + json_value_generator(c_file, 2, "num", 'g', 'ctx', obj.typ) c_file.write(" }\n") - - elif helpers.judgeDataPointerType(obj.typ): + elif helpers.judge_data_pointer_type(obj.typ): c_file.write(' if ((ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) - numtyp = helpers.obtainDataPointerType(obj.typ) + numtyp = helpers.obtain_data_pointer_type(obj.typ) if numtyp == "": return - c_file.write(' %s num = 0;\n' % helpers.getMapCTypes(numtyp)) - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)("%s"), strlen("%s"));\n' \ - % (obj.origname, obj.origname)) + c_file.write(' %s num = 0;\n' % helpers.get_map_c_types(numtyp)) + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s != NULL) {\n" % obj.fixname) c_file.write(" num = (%s)*(ptr->%s);\n" \ - % (helpers.getMapCTypes(numtyp), obj.fixname)) + % (helpers.get_map_c_types(numtyp), obj.fixname)) c_file.write(" }\n") - jsonValueGenerator(c_file, 2, "num", 'g', 'ctx', numtyp) + json_value_generator(c_file, 2, "num", 'g', 'ctx', numtyp) c_file.write(" }\n") - elif obj.typ == 'boolean': c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) ||' \ ' (ptr != NULL && ptr->%s)) {\n' % obj.fixname) c_file.write(' bool b = false;\n') - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)("%s"), strlen("%s"));\n' \ - % (obj.origname, obj.origname)) + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s) {\n" % obj.fixname) c_file.write(" b = ptr->%s;\n" % obj.fixname) c_file.write(" }\n") - jsonValueGenerator(c_file, 2, "b", 'g', 'ctx', obj.typ) + json_value_generator(c_file, 2, "b", 'g', 'ctx', obj.typ) c_file.write(" }\n") elif obj.typ == 'object' or obj.typ == 'mapStringObject': if obj.subtypname: typename = obj.subtypname else: - typename = helpers.getPrefixName(obj.name, prefix) + typename = helpers.get_prefixe_name(obj.name, prefix) c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) ||' \ ' (ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)("%s"), strlen("%s"));\n' \ - % (obj.origname, obj.origname)) + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(' stat = gen_%s(g, ptr != NULL ? ptr->%s : NULL, ctx, err);\n' \ @@ -387,17 +383,16 @@ def obtainObjectOrArrayObject(obj, c_file, prefix): c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" }\n") - elif obj.typ == 'array' and (obj.subtypobj or obj.subtyp == 'object'): if obj.subtypname: typename = obj.subtypname else: - typename = helpers.getNameSubstr(obj.name, prefix) + typename = helpers.get_name_substr(obj.name, prefix) c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) || ' \ '(ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) c_file.write(' size_t len = 0, i;\n') - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)("%s"), strlen("%s"));\n' \ - % (obj.origname, obj.origname)) + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s != NULL) {\n" % obj.fixname) @@ -426,15 +421,16 @@ def obtainObjectOrArrayObject(obj, c_file, prefix): % (obj.fixname, obj.fixname)) c_file.write(' const char *str = "";\n') c_file.write(' size_t len = 0;\n') - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)("%s"), strlen("%s"));\n' \ - % (obj.origname, obj.origname)) + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s != NULL) {\n" % obj.fixname) c_file.write(" str = (const char *)ptr->%s;\n" % obj.fixname) c_file.write(" len = ptr->%s_len;\n" % obj.fixname) c_file.write(" }\n") - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)str, len);\n') + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)str, len);\n') c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" }\n") @@ -442,8 +438,8 @@ def obtainObjectOrArrayObject(obj, c_file, prefix): c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) || ' \ '(ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) c_file.write(' size_t len = 0, i;\n') - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)("%s"), strlen("%s"));\n' \ - % (obj.origname, obj.origname)) + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s != NULL) {\n" % obj.fixname) @@ -455,7 +451,7 @@ def obtainObjectOrArrayObject(obj, c_file, prefix): c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(' for (i = 0; i < len; i++) {\n') - jsonValueGenerator(c_file, 3, "ptr->%s[i]" % obj.fixname, 'g', 'ctx', obj.subtyp) + json_value_generator(c_file, 3, "ptr->%s[i]" % obj.fixname, 'g', 'ctx', obj.subtyp) c_file.write(' }\n') c_file.write(' stat = yajl_gen_array_close((yajl_gen)g);\n') c_file.write(" if (yajl_gen_status_ok != stat)\n") @@ -463,44 +459,42 @@ def obtainObjectOrArrayObject(obj, c_file, prefix): c_file.write(" if (!len && !(ctx->options & OPT_GEN_SIMPLIFY))\n") c_file.write(' yajl_gen_config(g, yajl_gen_beautify, 1);\n') c_file.write(' }\n') - - elif helpers.validBasicMapName(obj.typ): + elif helpers.valid_basic_map_name(obj.typ): c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) || ' \ '(ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) - c_file.write(' stat = yajl_gen_string((yajl_gen)g, (const unsigned char *)("%s"), strlen("%s"));\n' \ - % (obj.origname, obj.origname)) + c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ + (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(' stat = gen_%s(g, ptr ? ptr->%s : NULL, ctx, err);\n' \ - % (helpers.makeBasicMapName(obj.typ), obj.fixname)) + % (helpers.make_basic_map_name(obj.typ), obj.fixname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" }\n") -def obtainCJson(obj, c_file, prefix): + +def get_c_json(obj, c_file, prefix): """ Description: c language generate json file Interface: None History: 2019-06-17 """ - if not helpers.judgeComplex(obj.typ) or obj.subtypname: + if not helpers.judge_complex(obj.typ) or obj.subtypname: return if obj.typ == 'object' or obj.typ == 'mapStringObject': - obj_typename = typename = helpers.getPrefixName(obj.name, prefix) + typename = helpers.get_prefixe_name(obj.name, prefix) elif obj.typ == 'array': - obj_typename = typename = helpers.getNameSubstr(obj.name, prefix) + typename = helpers.get_name_substr(obj.name, prefix) objs = obj.subtypobj if objs is None: return - c_file.write( "yajl_gen_status gen_%s(yajl_gen g, const %s *ptr, const struct parser_context " \ "*ctx, parser_error *err) {\n" % (typename, typename)) c_file.write(" yajl_gen_status stat = yajl_gen_status_ok;\n") c_file.write(" *err = 0;\n") - if obj.typ == 'mapStringObject': - obtainMapStringObject(obj, c_file, prefix) + get_map_string_obj(obj, c_file, prefix) elif obj.typ == 'object' or (obj.typ == 'array' and obj.subtypobj): nodes = obj.children if obj.typ == 'object' else obj.subtypobj if nodes is None: @@ -510,10 +504,8 @@ def obtainCJson(obj, c_file, prefix): c_file.write(" stat = yajl_gen_map_open((yajl_gen)g);\n") c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") - for i in nodes or []: - obtainObjectOrArrayObject(i, c_file, prefix) - + get_obj_arr_obj(i, c_file, prefix) c_file.write(" stat = yajl_gen_map_close((yajl_gen)g);\n") c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") @@ -524,17 +516,17 @@ def obtainCJson(obj, c_file, prefix): c_file.write("}\n\n") -def readValueGenerator(c_file, level, src, dest, typ, keyname, obj_typename): +def read_val_generator(c_file, level, src, dest, typ, keyname, obj_typename): """ Description: read value generateor Interface: None History: 2019-06-17 """ - if helpers.validBasicMapName(typ): + if helpers.valid_basic_map_name(typ): c_file.write('%syajl_val val = %s;\n' % (' ' * level, src)) c_file.write('%sif (val != NULL) {\n' % (' ' * level)) c_file.write('%s%s = make_%s(val, ctx, err);\n' \ - % (' ' * (level + 1), dest, helpers.makeBasicMapName(typ))) + % (' ' * (level + 1), dest, helpers.make_basic_map_name(typ))) c_file.write('%sif (%s == NULL) {\n' % (' ' * (level + 1), dest)) c_file.write('%s char *new_error = NULL;\n' % (' ' * (level + 1))) c_file.write("%s if (asprintf(&new_error, \"Value error for key" \ @@ -555,7 +547,7 @@ def readValueGenerator(c_file, level, src, dest, typ, keyname, obj_typename): c_file.write('%schar *str = YAJL_GET_STRING(val);\n' % (' ' * (level + 1))) c_file.write('%s%s = safe_strdup(str ? str : "");\n' % (' ' * (level + 1), dest)) c_file.write('%s}\n' % (' ' * level)) - elif helpers.judgeDataType(typ): + elif helpers.judge_data_type(typ): c_file.write('%syajl_val val = %s;\n' % (' ' * (level), src)) c_file.write('%sif (val != NULL) {\n' % (' ' * (level))) if typ.startswith("uint") or \ @@ -578,14 +570,14 @@ def readValueGenerator(c_file, level, src, dest, typ, keyname, obj_typename): c_file.write('%s return NULL;\n' % (' ' * (level + 1))) c_file.write('%s}\n' % (' ' * (level + 1))) c_file.write('%s}\n' % (' ' * (level))) - elif helpers.judgeDataPointerType(typ): - num_type = helpers.obtainDataPointerType(typ) + elif helpers.judge_data_pointer_type(typ): + num_type = helpers.obtain_data_pointer_type(typ) if num_type == "": return c_file.write('%syajl_val val = %s;\n' % (' ' * (level), src)) c_file.write('%sif (val != NULL) {\n' % (' ' * (level))) c_file.write('%s%s = safe_malloc(sizeof(%s));\n' % - (' ' * (level + 1), dest, helpers.getMapCTypes(num_type))) + (' ' * (level + 1), dest, helpers.get_map_c_types(num_type))) c_file.write('%sint invalid = common_safe_%s(YAJL_GET_NUMBER(val), %s);\n' \ % (' ' * (level + 1), num_type, dest)) c_file.write('%sif (invalid) {\n' % (' ' * (level + 1))) @@ -617,105 +609,86 @@ def readValueGenerator(c_file, level, src, dest, typ, keyname, obj_typename): c_file.write('%s}\n' % (' ' * (level))) -def jsonValueGenerator(c_file, level, src, dst, ptx, typ): +def json_value_generator(c_file, level, src, dst, ptx, typ): """ Description: json value generateor Interface: None History: 2019-06-17 """ - if helpers.validBasicMapName(typ): + if helpers.valid_basic_map_name(typ): c_file.write('%sstat = gen_%s(%s, %s, %s, err);\n' \ - % (' ' * (level), helpers.makeBasicMapName(typ), dst, src, ptx)) + % (' ' * (level), helpers.make_basic_map_name(typ), dst, src, ptx)) c_file.write("%sif (yajl_gen_status_ok != stat)\n" % (' ' * (level))) c_file.write("%sGEN_SET_ERROR_AND_RETURN(stat, err);\n" % (' ' * (level + 1))) elif typ == 'string': - c_file.write('%sstat = yajl_gen_string((yajl_gen)%s, (const unsigned char *)(%s), strlen(%s));\n' \ - % (' ' * (level), dst, src, src)) + c_file.write('%sstat = yajl_gen_string((yajl_gen)%s, \ + (const unsigned char *)(%s), strlen(%s));\n' % (' ' * (level), dst, src, src)) c_file.write("%sif (yajl_gen_status_ok != stat)\n" % (' ' * (level))) c_file.write("%sGEN_SET_ERROR_AND_RETURN(stat, err);\n" % (' ' * (level + 1))) - - elif helpers.judgeDataType(typ): + elif helpers.judge_data_type(typ): if typ == 'double': - c_file.write('%sstat = yajl_gen_double((yajl_gen)%s, %s);\n' % (' ' * (level), dst, src)) + c_file.write('%sstat = yajl_gen_double((yajl_gen)%s, %s);\n' \ + % (' ' * (level), dst, src)) elif typ.startswith("uint") or typ == 'GID' or typ == 'UID': c_file.write('%sstat = map_uint(%s, %s);\n' % (' ' * (level), dst, src)) else: c_file.write('%sstat = map_int(%s, %s);\n' % (' ' * (level), dst, src)) c_file.write("%sif (yajl_gen_status_ok != stat)\n" % (' ' * (level))) - c_file.write("%sGEN_SET_ERROR_AND_RETURN(stat, err);\n" % (' ' * (level + 1))) - + c_file.write("%sGEN_SET_ERROR_AND_RETURN(stat, err);\n" \ + % (' ' * (level + 1))) elif typ == 'boolean': - c_file.write('%sstat = yajl_gen_bool((yajl_gen)%s, (int)(%s));\n' % (' ' * (level), dst, src)) + c_file.write('%sstat = yajl_gen_bool((yajl_gen)%s, (int)(%s));\n' \ + % (' ' * (level), dst, src)) c_file.write("%sif (yajl_gen_status_ok != stat)\n" % (' ' * (level))) c_file.write("%sGEN_SET_ERROR_AND_RETURN(stat, err);\n" % (' ' * (level + 1))) -def makeCFree(obj, c_file, prefix): +def make_c_free(obj, c_file, prefix): """ Description: generate c free function Interface: None History: 2019-06-17 """ - if not helpers.judgeComplex(obj.typ) or obj.subtypname: + if not helpers.judge_complex(obj.typ) or obj.subtypname: return - - typename = helpers.getPrefixName(obj.name, prefix) - + typename = helpers.get_prefixe_name(obj.name, prefix) case = obj.typ - result = { - 'mapStringObject': lambda x: [], - 'object': lambda x: x.children, - 'array': lambda x: x.subtypobj - }[case](obj) - + result = {'mapStringObject': lambda x: [], 'object': lambda x: x.children, + 'array': lambda x: x.subtypobj}[case](obj) objs = result if obj.typ == 'array': if objs is None: return else: - typename = helpers.getNameSubstr(obj.name, prefix) - + typename = helpers.get_name_substr(obj.name, prefix) c_file.write("void free_%s(%s *ptr) {\n" % (typename, typename)) c_file.write(" if (ptr == NULL)\n") c_file.write(" return;\n") if obj.typ == 'mapStringObject': child = obj.children[0] - if helpers.validBasicMapName(child.typ): - childname = helpers.makeBasicMapName(child.typ) + if helpers.valid_basic_map_name(child.typ): + childname = helpers.make_basic_map_name(child.typ) else: if child.subtypname: childname = child.subtypname else: - childname = helpers.getPrefixName(child.name, prefix) - c_file.write(" if (ptr->keys != NULL && ptr->%s != NULL) {\n" % child.fixname) - c_file.write(" size_t i;\n") - c_file.write(" for (i = 0; i < ptr->len; i++) {\n") - c_file.write(" free(ptr->keys[i]);\n") - c_file.write(" ptr->keys[i] = NULL;\n") - c_file.write(" free_%s(ptr->%s[i]);\n" % (childname, child.fixname)) - c_file.write(" ptr->%s[i] = NULL;\n" % (child.fixname)) - c_file.write(" }\n") - c_file.write(" free(ptr->keys);\n") - c_file.write(" ptr->keys = NULL;\n") - c_file.write(" free(ptr->%s);\n" % (child.fixname)) - c_file.write(" ptr->%s = NULL;\n" % (child.fixname)) - c_file.write(" }\n") - + childname = helpers.get_prefixe_name(child.name, prefix) + c_file_map_str(c_file, child, childname) for i in objs or []: - if helpers.validBasicMapName(i.typ): - free_func = helpers.makeBasicMapName(i.typ) + if helpers.valid_basic_map_name(i.typ): + free_func = helpers.make_basic_map_name(i.typ) c_file.write(" free_%s(ptr->%s);\n" % (free_func, i.fixname)) c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) if i.typ == 'mapStringObject': if i.subtypname: free_func = i.subtypname else: - free_func = helpers.getPrefixName(i.name, prefix) + free_func = helpers.get_prefixe_name(i.name, prefix) c_file.write(" free_%s(ptr->%s);\n" % (free_func, i.fixname)) c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) elif i.typ == 'array': - if helpers.validBasicMapName(i.subtyp): - free_func = helpers.makeBasicMapName(i.subtyp) + if helpers.valid_basic_map_name(i.subtyp): + free_func = helpers.make_basic_map_name(i.subtyp) c_file.write(" if (ptr->%s != NULL) {\n" % i.fixname) c_file.write(" size_t i;\n") c_file.write(" for (i = 0; i < ptr->%s_len; i++) {\n" % i.fixname) @@ -728,25 +701,15 @@ def makeCFree(obj, c_file, prefix): c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) c_file.write(" }\n") elif i.subtyp == 'string': - c_file.write(" if (ptr->%s != NULL) {\n" % i.fixname) - c_file.write(" size_t i;\n") - c_file.write(" for (i = 0; i < ptr->%s_len; i++) {\n" % i.fixname) - c_file.write(" if (ptr->%s[i] != NULL) {\n" % (i.fixname)) - c_file.write(" free(ptr->%s[i]);\n" % (i.fixname)) - c_file.write(" ptr->%s[i] = NULL;\n" % (i.fixname)) - c_file.write(" }\n") - c_file.write(" }\n") - c_file.write(" free(ptr->%s);\n" % (i.fixname)) - c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) - c_file.write(" }\n") - elif not helpers.judgeComplex(i.subtyp): + c_file_str(c_file, i) + elif not helpers.judge_complex(i.subtyp): c_file.write(" free(ptr->%s);\n" % (i.fixname)) c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) elif i.subtyp == 'object' or i.subtypobj is not None: if i.subtypname is not None: free_func = i.subtypname else: - free_func = helpers.getNameSubstr(i.name, prefix) + free_func = helpers.get_name_substr(i.name, prefix) c_file.write(" if (ptr->%s != NULL) {\n" % i.fixname) c_file.write(" size_t i;\n") c_file.write(" for (i = 0; i < ptr->%s_len; i++)\n" % i.fixname) @@ -757,23 +720,17 @@ def makeCFree(obj, c_file, prefix): c_file.write(" free(ptr->%s);\n" % i.fixname) c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) c_file.write(" }\n") - - c_typ = helpers.obtainPointer(i.name, i.subtypobj, prefix) + c_typ = helpers.obtain_pointer(i.name, i.subtypobj, prefix) if c_typ == "": continue if i.subobj is not None: c_typ = c_typ + "_element" c_file.write(" free_%s(ptr->%s);\n" % (c_typ, i.fixname)) c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) - else: # not array - typename = helpers.getPrefixName(i.name, prefix) - if i.typ == 'string': - c_file.write(" free(ptr->%s);\n" % (i.fixname)) - c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) - elif i.typ == 'booleanPointer': - c_file.write(" free(ptr->%s);\n" % (i.fixname)) - c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) - elif helpers.judgeDataPointerType(i.typ): + else: + typename = helpers.get_prefixe_name(i.name, prefix) + if i.typ == 'string' or i.typ == 'booleanPointer' or \ + helpers.judge_data_pointer_type(i.typ): c_file.write(" free(ptr->%s);\n" % (i.fixname)) c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) elif i.typ == 'object': @@ -787,13 +744,54 @@ def makeCFree(obj, c_file, prefix): c_file.write("}\n\n") -def sourceReflection(structs, schema_info, c_file, root_typ): +def c_file_map_str(c_file, child, childname): + """ + Description: generate c code for map string + Interface: None + History: 2019-10-31 + """ + c_file.write(" if (ptr->keys != NULL && ptr->%s != NULL) {\n" % child.fixname) + c_file.write(" size_t i;\n") + c_file.write(" for (i = 0; i < ptr->len; i++) {\n") + c_file.write(" free(ptr->keys[i]);\n") + c_file.write(" ptr->keys[i] = NULL;\n") + c_file.write(" free_%s(ptr->%s[i]);\n" % (childname, child.fixname)) + c_file.write(" ptr->%s[i] = NULL;\n" % (child.fixname)) + c_file.write(" }\n") + c_file.write(" free(ptr->keys);\n") + c_file.write(" ptr->keys = NULL;\n") + c_file.write(" free(ptr->%s);\n" % (child.fixname)) + c_file.write(" ptr->%s = NULL;\n" % (child.fixname)) + c_file.write(" }\n") + + +def c_file_str(c_file, i): + """ + Description: generate c code template + Interface: None + History: 2019-10-31 + """ + c_file.write(" if (ptr->%s != NULL) {\n" % i.fixname) + c_file.write(" size_t i;\n") + c_file.write(" for (i = 0; i < ptr->%s_len; i++) {\n" % i.fixname) + c_file.write(" if (ptr->%s[i] != NULL) {\n" % (i.fixname)) + c_file.write(" free(ptr->%s[i]);\n" % (i.fixname)) + c_file.write(" ptr->%s[i] = NULL;\n" % (i.fixname)) + c_file.write(" }\n") + c_file.write(" }\n") + c_file.write(" free(ptr->%s);\n" % (i.fixname)) + c_file.write(" ptr->%s = NULL;\n" % (i.fixname)) + c_file.write(" }\n") + + +def src_reflect(structs, schema_info, c_file, root_typ): """ Description: reflect code Interface: None History: 2019-06-17 """ - c_file.write("// Generated from %s. Do not edit!\n" % (schema_info.name.basename)) + c_file.write("// Generated from %s. Do not edit!\n" \ + % (schema_info.name.basename)) c_file.write("#ifndef _GNU_SOURCE\n") c_file.write("#define _GNU_SOURCE\n") c_file.write("#endif\n") @@ -801,14 +799,12 @@ def sourceReflection(structs, schema_info, c_file, root_typ): c_file.write('#include \n') c_file.write('#include "securec.h"\n') c_file.write('#include "%s"\n\n' % schema_info.header.basename) - for i in structs: - appendCCode(i, c_file, schema_info.prefix) - - obtainCEpilogue(c_file, schema_info.prefix, root_typ) + append_c_code(i, c_file, schema_info.prefix) + get_c_epilog(c_file, schema_info.prefix, root_typ) -def obtainCEpilogue(c_file, prefix, typ): +def get_c_epilog(c_file, prefix, typ): """ Description: generate c language epilogue Interface: None @@ -816,7 +812,6 @@ def obtainCEpilogue(c_file, prefix, typ): """ if typ != 'array' and typ != 'object': return - if typ == 'array': c_file.write("""\n %s_element **make_%s(yajl_val tree, const struct parser_context *ctx, parser_error *err, size_t *len) { @@ -877,13 +872,11 @@ yajl_gen_status gen_%s(yajl_gen g, const %s_element **ptr, size_t len, const str return yajl_gen_status_ok; } """ % (prefix, prefix, prefix)) - c_file.write(""" %s%s*%s_parse_file(const char *filename, const struct parser_context *ctx, parser_error *err%s) { %s%s*ptr = NULL;""" % (prefix, ' ' if typ == 'object' else '_element *', \ prefix, '' if typ == 'object' else ', size_t *len', \ prefix, ' ' if typ == 'object' else '_element *')) - c_file.write(""" size_t filesize; char *content = NULL; @@ -903,13 +896,11 @@ yajl_gen_status gen_%s(yajl_gen g, const %s_element **ptr, size_t len, const str return ptr; } """ % (prefix, '' if typ == 'object' else ', len')) - c_file.write(""" %s%s*%s_parse_file_stream(FILE *stream, const struct parser_context *ctx, parser_error *err%s) { %s%s*ptr = NULL;""" % (prefix, ' ' if typ == 'object' else '_element *', \ prefix, '' if typ == 'object' else ', size_t *len', \ prefix, ' ' if typ == 'object' else '_element *')) - c_file.write(""" size_t filesize; char *content = NULL ; @@ -928,13 +919,11 @@ yajl_gen_status gen_%s(yajl_gen g, const %s_element **ptr, size_t len, const str return ptr; } """ % (prefix, '' if typ == 'object' else ', len')) - c_file.write(""" %s%s*%s_parse_data(const char *jsondata, const struct parser_context *ctx, parser_error *err%s) { %s%s*ptr = NULL;""" % (prefix, ' ' if typ == 'object' else '_element *', \ prefix, '' if typ == 'object' else ', size_t *len', \ prefix, ' ' if typ == 'object' else '_element *')) - c_file.write(""" yajl_val tree; char errbuf[1024]; @@ -958,12 +947,10 @@ yajl_gen_status gen_%s(yajl_gen g, const %s_element **ptr, size_t len, const str return ptr; } """ % (prefix, '' if typ == 'object' else ', len')) - c_file.write("char *%s_generate_json(const %s%s*ptr%s, const struct parser_context *ctx," \ " parser_error *err) {" % (prefix, prefix, \ ' ' if typ == 'object' else '_element *', \ '' if typ == 'object' else ', size_t len')) - c_file.write(""" yajl_gen g = NULL; struct parser_context tmp_ctx = { 0 }; @@ -1011,3 +998,5 @@ out: } """ % (prefix, '' if typ == 'object' else ', len')) + + diff --git a/src/liblcrc.h b/src/liblcrc.h index 17912d1..2b4dbf6 100644 --- a/src/liblcrc.h +++ b/src/liblcrc.h @@ -335,18 +335,19 @@ struct lcrc_list_request { struct lcrc_container_summary_info { char *id; - char *name; - uint32_t has_pid; - uint32_t pid; - Container_Status status; char *image; char *command; + char *name; + Container_Status status; uint32_t exit_code; + uint32_t has_pid; + uint32_t pid; uint32_t restart_count; char *startat; char *finishat; char *runtime; char *health_state; + int64_t created; }; struct lcrc_list_response { @@ -461,12 +462,12 @@ struct lcrc_exec_request { size_t env_len; char **env; int64_t timeout; + char *user; }; struct lcrc_exec_response { uint32_t cc; uint32_t server_errono; - uint32_t pid; uint32_t exit_code; char *errmsg; }; @@ -576,7 +577,7 @@ struct lcrc_image_info { char *digest; int64_t created; /* seconds */ int32_t created_nanos; - int64_t size; /*Bytes*/ + int64_t size; /* Bytes */ }; struct lcrc_create_image_request { @@ -591,6 +592,7 @@ struct lcrc_create_image_response { }; struct lcrc_list_images_request { + struct lcrc_filters *filters; // unuseful definition to avoid generate empty struct which will get 0 if we call sizeof char unuseful; }; diff --git a/src/liblcrd.c b/src/liblcrd.c index 0cb38a6..4b9f018 100644 --- a/src/liblcrd.c +++ b/src/liblcrd.c @@ -231,3 +231,4 @@ void container_log_config_free(struct container_log_config *conf) conf->size = 0; free(conf); } + diff --git a/src/liblcrd.h b/src/liblcrd.h index c328f1a..7b47532 100644 --- a/src/liblcrd.h +++ b/src/liblcrd.h @@ -24,7 +24,7 @@ extern "C" { #endif -/*record the lcrd errmsg*/ +/* record the lcrd errmsg */ extern __thread char *g_lcrd_errmsg; #define CONTAINER_LOG_CONFIG_KEY_FILE "log.console.file" @@ -47,7 +47,7 @@ extern __thread char *g_lcrd_errmsg; #define MAX_HOSTS 10 -/*clear the g_lcrd_errmsg*/ +/* clear the g_lcrd_errmsg */ #define DAEMON_CLEAR_ERRMSG() do { \ if (g_lcrd_errmsg != NULL) { \ free(g_lcrd_errmsg); \ @@ -81,14 +81,14 @@ struct lcrd_client_cgroup_resources { }; struct create_custom_config { - /*environment variables*/ + /* environment variables */ int env_len; char **env; /* cgroup resources */ struct lcrd_client_cgroup_resources cr; - /* hugepage limits*/ + /* hugepage limits */ int hugepage_limits_len; char **hugepage_limits; @@ -104,7 +104,7 @@ struct create_custom_config { /* user and group */ char *user; - /*hostname*/ + /* hostname */ char *hostname; /* privileged */ @@ -116,7 +116,7 @@ struct create_custom_config { /* alldevices */ bool all_devices; - /* system container*/ + /* system container */ bool system_container; /* cap add */ @@ -274,7 +274,7 @@ struct lcrd_image_info { char *digest; int64_t created; /* seconds */ int32_t created_nanos; - int64_t size; /*Bytes*/ + int64_t size; /* Bytes */ }; struct lcrd_create_image_request { diff --git a/src/linked_list.h b/src/linked_list.h index 4f96026..0a4a0a1 100644 --- a/src/linked_list.h +++ b/src/linked_list.h @@ -15,6 +15,8 @@ #ifndef __LINKED_LIST_H #define __LINKED_LIST_H +#include + struct linked_list { void *elem; struct linked_list *next; @@ -120,3 +122,4 @@ static inline size_t linked_list_len(struct linked_list *list) } #endif + diff --git a/src/log.c b/src/log.c index f3e5a95..a71bd63 100644 --- a/src/log.c +++ b/src/log.c @@ -33,13 +33,27 @@ const char * const g_log_prio_name[] = { "FATAL", "ALERT", "CRIT", "ERROR", "WARN", "NOTICE", "INFO", "DEBUG", "TRACE" }; +/* predefined priorities. */ +enum log_priority { + LOG_PRIORITY_FATAL = LOG_EMERG, + LOG_PRIORITY_ALERT = LOG_ALERT, + LOG_PRIORITY_CRIT = LOG_CRIT, + LOG_PRIORITY_ERROR = LOG_ERR, + LOG_PRIORITY_WARN = LOG_WARNING, + LOG_PRIORITY_NOTICE = LOG_NOTICE, + LOG_PRIORITY_INFO = LOG_INFO, + LOG_PRIORITY_DEBUG = LOG_DEBUG, + LOG_PRIORITY_TRACE, + LOG_PRIORITY_MAX +}; + #define MAX_MSG_LENGTH 4096 static __thread char *g_log_prefix = NULL; static char *g_log_vmname = NULL; static bool g_log_quiet = false; -static int g_log_level = ISULA_LOG_DEBUG; +static int g_log_level = LOG_PRIORITY_DEBUG; static int g_log_driver = LOG_DRIVER_STDOUT; int g_lcrd_log_fd = -1; @@ -89,8 +103,10 @@ static ssize_t write_nointr(int fd, const void *buf, size_t count) return nret; } -void log_append_logfile(const struct log_object_metadata *metadata, const char *timestamp, const char *msg); -void log_append_stderr(const struct log_object_metadata *metadata, const char *timestamp, const char *msg); +void log_append_logfile(const struct log_event *event, const char *timestamp, const char *msg); +void log_append_stderr(const struct log_event *event, const char *timestamp, const char *msg); + +int lcrd_unix_trans_to_utc(char *buf, size_t bufsize, const struct timespec *time); /* change str logdriver to enum */ int change_str_logdriver_to_enum(const char *driver) @@ -149,14 +165,14 @@ static int log_init_checker(const struct log_config *log) return -1; } - for (i = ISULA_LOG_FATAL; i < ISULA_LOG_MAX; i++) { + for (i = LOG_PRIORITY_FATAL; i < LOG_PRIORITY_MAX; i++) { if (strcasecmp(g_log_prio_name[i], log->priority) == 0) { g_log_level = i; break; } } - if (i == ISULA_LOG_MAX) { + if (i == LOG_PRIORITY_MAX) { fprintf(stderr, "Unable to parse logging level:%s\n", log->priority); return -1; } @@ -218,57 +234,31 @@ out: return nret; } -static char *parse_timespec_to_human() -{ - struct timespec timestamp; - struct tm ptm = { 0 }; - char date_time[ISULAD_LOG_BUFFER_SIZE] = { 0 }; - int nret; - - if (clock_gettime(CLOCK_REALTIME, ×tamp) == -1) { - fprintf(stderr, "Failed to get real time\n"); - return 0; - } - - if (localtime_r(&(timestamp.tv_sec), &ptm) == NULL) { - SYSERROR("Transfer timespec failed"); - return NULL; - } - - nret = sprintf_s(date_time, ISULAD_LOG_BUFFER_SIZE, "%04d%02d%02d%02d%02d%02d.%03ld", - ptm.tm_year + 1900, ptm.tm_mon + 1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, ptm.tm_sec, - timestamp.tv_nsec / 1000000); - - if (nret < 0) { - COMMAND_ERROR("Sprintf failed"); - return NULL; - } - - return util_strdup_s(date_time); -} - /* log append */ -int log_append(const struct log_object_metadata *metadata, const char *format, ...) +int log_append(const struct log_event *event, const char *format, ...) { int rc = 0; va_list args; char msg[MAX_MSG_LENGTH] = { 0 }; - char *date_time = NULL; - int ret = 0; + char date_time[LCRD_LOG_TIME_SIZE] = { 0 }; + struct timespec timestamp; va_start(args, format); - rc = vsprintf_s(msg, MAX_MSG_LENGTH, format, args); + rc = vsnprintf_truncated_s(msg, MAX_MSG_LENGTH, format, args); va_end(args); if (rc < 0 || rc >= MAX_MSG_LENGTH) { - rc = sprintf_s(msg, MAX_MSG_LENGTH, "%s", "!!LONG LONG A LOG!!"); + rc = sprintf_s(msg, MAX_MSG_LENGTH, "%s", "Failed to truncate print error log"); if (rc < 0) { return 0; } } - date_time = parse_timespec_to_human(); - if (date_time == NULL) { - goto out; + if (clock_gettime(CLOCK_REALTIME, ×tamp) == -1) { + fprintf(stderr, "Failed to get real time"); + return -1; + } + if (lcrd_unix_trans_to_utc(date_time, LCRD_LOG_TIME_SIZE, ×tamp) < 0) { + return 0; } switch (g_log_driver) { @@ -276,39 +266,35 @@ int log_append(const struct log_object_metadata *metadata, const char *format, . if (g_log_quiet) { break; } - log_append_stderr(metadata, date_time, msg); + log_append_stderr(event, date_time, msg); break; case LOG_DRIVER_FIFO: if (g_lcrd_log_fd == -1) { - COMMAND_ERROR("Do not set log file"); - ret = -1; - goto out; + fprintf(stderr, "Do not set log file\n"); + return -1; } - log_append_logfile(metadata, date_time, msg); + log_append_logfile(event, date_time, msg); break; case LOG_DRIVER_NOSET: break; default: - COMMAND_ERROR("Invalid log driver"); - ret = -1; - goto out; + fprintf(stderr, "Invalid log driver\n"); + return -1; } -out: - free(date_time); - return ret; + return 0; } /* log append logfile */ -void log_append_logfile(const struct log_object_metadata *metadata, const char *timestamp, const char *msg) +void log_append_logfile(const struct log_event *event, const char *timestamp, const char *msg) { int log_fd = -1; int nret = 0; size_t size = 0; char *tmp_prefix = NULL; - char log_buffer[ISULAD_LOG_BUFFER_SIZE] = { 0 }; + char log_buffer[LCRD_LOG_BUFFER_SIZE] = { 0 }; - if (metadata == NULL || metadata->level > g_log_level) { + if (event == NULL || event->priority > g_log_level) { return; } log_fd = g_lcrd_log_fd; @@ -320,13 +306,13 @@ void log_append_logfile(const struct log_object_metadata *metadata, const char * if (tmp_prefix != NULL && strlen(tmp_prefix) > 15) { tmp_prefix = tmp_prefix + (strlen(tmp_prefix) - 15); } - if (metadata->func != NULL && metadata->file != NULL) { - nret = sprintf_s(log_buffer, sizeof(log_buffer), "%15s %s %-8s %s - %s:%s:%d - %s", - tmp_prefix ? tmp_prefix : "", timestamp, g_log_prio_name[metadata->level], - g_log_vmname ? g_log_vmname : "lcrd", metadata->file, metadata->func, - metadata->line, msg); + if (event->locinfo != NULL) { + nret = snprintf_truncated_s(log_buffer, sizeof(log_buffer), "%15s %s %-8s %s - %s:%s:%d - %s", + tmp_prefix ? tmp_prefix : "", timestamp, g_log_prio_name[event->priority], + g_log_vmname ? g_log_vmname : "lcrd", event->locinfo->file, event->locinfo->func, + event->locinfo->line, msg); } else { - nret = sprintf_s(log_buffer, sizeof(log_buffer), "%s %s", timestamp, msg); + nret = snprintf_truncated_s(log_buffer, sizeof(log_buffer), "%s %s", timestamp, msg); } if (nret < 0) { @@ -346,11 +332,11 @@ void log_append_logfile(const struct log_object_metadata *metadata, const char * } /* log append stderr */ -void log_append_stderr(const struct log_object_metadata *metadata, const char *timestamp, const char *msg) +void log_append_stderr(const struct log_event *event, const char *timestamp, const char *msg) { char *tmp_prefix = NULL; - if (metadata == NULL || metadata->level > g_log_level) { + if (event == NULL || event->priority > g_log_level) { return; } @@ -359,14 +345,14 @@ void log_append_stderr(const struct log_object_metadata *metadata, const char *t tmp_prefix = tmp_prefix + (strlen(tmp_prefix) - 15); } - if (metadata->func != NULL && metadata->file != NULL) { + if (event->locinfo != NULL) { fprintf(stderr, "%15s ", tmp_prefix ? tmp_prefix : ""); } fprintf(stderr, "%s ", timestamp); - if (metadata->func != NULL && metadata->file != NULL) { - fprintf(stderr, "%-8s ", g_log_prio_name[metadata->level]); + if (event->locinfo != NULL) { + fprintf(stderr, "%-8s ", g_log_prio_name[event->priority]); fprintf(stderr, "%s - ", g_log_vmname ? g_log_vmname : "lcrd"); - fprintf(stderr, "%s:%s:%d - ", metadata->file, metadata->func, metadata->line); + fprintf(stderr, "%s:%s:%d - ", event->locinfo->file, event->locinfo->func, event->locinfo->line); } fprintf(stderr, "%s", msg); fprintf(stderr, "\n"); @@ -396,7 +382,7 @@ int lcrd_unix_trans_to_utc(char *buf, size_t bufsize, const struct timespec *tim /* Transtate seconds to number of days. */ trans_to_days = time->tv_sec / 86400; - /* Calculate days from 0000-03-01 to 1970-01-01.Days base it*/ + /* Calculate days from 0000-03-01 to 1970-01-01.Days base it */ all_days = trans_to_days + 719468; /* compute the age.One age means 400 years(146097 days) */ @@ -457,3 +443,4 @@ int lcrd_unix_trans_to_utc(char *buf, size_t bufsize, const struct timespec *tim return 0; } + diff --git a/src/log.h b/src/log.h index 7173c51..afbd7ec 100644 --- a/src/log.h +++ b/src/log.h @@ -15,7 +15,9 @@ #ifndef __LCRD_LOG_H #define __LCRD_LOG_H +#include #include +#include #include #ifdef __cplusplus @@ -30,7 +32,7 @@ extern "C" { #define F_DUPFD_CLOEXEC 1030 #endif -#define ISULAD_LOG_BUFFER_SIZE 4096 +#define LCRD_LOG_BUFFER_SIZE 4096 /* We're logging in seconds and nanoseconds. Assuming that the underlying * datatype is currently at maximum a 64bit integer, we have a date string that @@ -38,20 +40,7 @@ extern "C" { * */ #define LCRD_LOG_TIME_SIZE 42 -enum g_log_driver { LOG_DRIVER_STDOUT, LOG_DRIVER_FIFO, LOG_DRIVER_NOSET }; - -enum isula_log_level { - ISULA_LOG_FATAL = 0, - ISULA_LOG_ALERT, - ISULA_LOG_CRIT, - ISULA_LOG_ERROR, - ISULA_LOG_WARN, - ISULA_LOG_NOTICE, - ISULA_LOG_INFO, - ISULA_LOG_DEBUG, - ISULA_LOG_TRACE, - ISULA_LOG_MAX -}; +enum g_log_driver { LOG_DRIVER_STDOUT, LOG_DRIVER_FIFO, LOG_DRIVER_SYSLOG, LOG_DRIVER_NOSET }; struct log_config { const char *name; @@ -62,22 +51,23 @@ struct log_config { bool quiet; }; -/* brief logging event object */ -struct log_object_metadata { - /* location information of the logging item */ +/* location information of the logging event */ +struct log_locinfo { const char *file; const char *func; int line; - - int level; }; -#define LOG_METADATA_INIT \ +#define LOG_LOCINFO_INIT \ { \ .file = __FILE__, .func = __func__, .line = __LINE__, \ } - +/* brief logging event object */ +struct log_event { + int priority; + struct log_locinfo *locinfo; +}; int log_init(struct log_config *log); void set_default_command_log_config(const char *name, struct log_config *log); @@ -88,47 +78,87 @@ void free_log_prefix(); int change_str_logdriver_to_enum(const char *driver); -int log_append(const struct log_object_metadata *metadata, const char *format, ...); +int log_append(const struct log_event *event, const char *format, ...); -#define ISULA_COMMON_LOG(loglevel, format, ...) \ - do { \ - struct log_object_metadata meta = LOG_METADATA_INIT; \ - meta.level = loglevel; \ - (void)log_append(&meta, format, ##__VA_ARGS__); \ +#define DEBUG(format, ...) \ + do { \ + struct log_locinfo locinfo = LOG_LOCINFO_INIT; \ + struct log_event append_log_event; \ + append_log_event.locinfo = &locinfo; \ + append_log_event.priority = LOG_DEBUG; \ + (void)log_append(&append_log_event, format, ##__VA_ARGS__); \ } while (0) -#define DEBUG(format, ...) \ - ISULA_COMMON_LOG(ISULA_LOG_DEBUG, format, ##__VA_ARGS__) - #define INFO(format, ...) \ - ISULA_COMMON_LOG(ISULA_LOG_INFO, format, ##__VA_ARGS__) + do { \ + struct log_locinfo locinfo = LOG_LOCINFO_INIT; \ + struct log_event append_log_event; \ + append_log_event.locinfo = &locinfo; \ + append_log_event.priority = LOG_INFO; \ + (void)log_append(&append_log_event, format, ##__VA_ARGS__); \ + } while (0) #define NOTICE(format, ...) \ - ISULA_COMMON_LOG(ISULA_LOG_NOTICE, format, ##__VA_ARGS__) + do { \ + struct log_locinfo locinfo = LOG_LOCINFO_INIT; \ + struct log_event append_log_event; \ + append_log_event.locinfo = &locinfo; \ + append_log_event.priority = LOG_NOTICE; \ + (void)log_append(&append_log_event, format, ##__VA_ARGS__); \ + } while (0) #define WARN(format, ...) \ - ISULA_COMMON_LOG(ISULA_LOG_WARN, format, ##__VA_ARGS__) + do { \ + struct log_locinfo locinfo = LOG_LOCINFO_INIT; \ + struct log_event append_log_event; \ + append_log_event.locinfo = &locinfo; \ + append_log_event.priority = LOG_WARNING; \ + (void)log_append(&append_log_event, format, ##__VA_ARGS__); \ + } while (0) #define ERROR(format, ...) \ - ISULA_COMMON_LOG(ISULA_LOG_ERROR, format, ##__VA_ARGS__) + do { \ + struct log_locinfo locinfo = LOG_LOCINFO_INIT; \ + struct log_event append_log_event; \ + append_log_event.locinfo = &locinfo; \ + append_log_event.priority = LOG_ERR; \ + (void)log_append(&append_log_event, format, ##__VA_ARGS__); \ + } while (0) -#define EVENT(format, ...) \ - do { \ - struct log_object_metadata metadata; \ - metadata.level = ISULA_LOG_ERROR; \ - metadata.func = NULL; \ - metadata.file = NULL; \ - log_append(&metadata, format, ##__VA_ARGS__); \ +#define EVENT(format, ...) \ + do { \ + struct log_event append_log_event; \ + append_log_event.locinfo = NULL; \ + append_log_event.priority = LOG_ERR; \ + log_append(&append_log_event, format, ##__VA_ARGS__); \ } while (0) #define CRIT(format, ...) \ - ISULA_COMMON_LOG(ISULA_LOG_CRIT, format, ##__VA_ARGS__) + do { \ + struct log_locinfo locinfo = LOG_LOCINFO_INIT; \ + struct log_event append_log_event; \ + append_log_event.locinfo = &locinfo; \ + append_log_event.priority = LOG_CRIT; \ + (void)log_append(&append_log_event, format, ##__VA_ARGS__); \ + } while (0) #define ALERT(format, ...) \ - ISULA_COMMON_LOG(ISULA_LOG_ALERT, format, ##__VA_ARGS__) + do { \ + struct log_locinfo locinfo = LOG_LOCINFO_INIT; \ + struct log_event append_log_event; \ + append_log_event.locinfo = &locinfo; \ + append_log_event.priority = LOG_ALERT; \ + (void)log_append(&append_log_event, format, ##__VA_ARGS__); \ + } while (0) #define FATAL(format, ...) \ - ISULA_COMMON_LOG(ISULA_LOG_FATAL, format, ##__VA_ARGS__) + do { \ + struct log_locinfo locinfo = LOG_LOCINFO_INIT; \ + struct log_event append_log_event; \ + append_log_event.locinfo = &locinfo; \ + append_log_event.priority = LOG_EMERG; \ + (void)log_append(&append_log_event, format, ##__VA_ARGS__); \ + } while (0) #define SYSERROR(format, ...) \ do { \ @@ -145,3 +175,4 @@ int log_append(const struct log_object_metadata *metadata, const char *format, . #endif #endif /* __LCRD_LOG_H */ + diff --git a/src/mainloop.c b/src/mainloop.c index e4e14c7..65464af 100644 --- a/src/mainloop.c +++ b/src/mainloop.c @@ -156,3 +156,4 @@ int epoll_loop_close(struct epoll_descr *descr) return close(descr->fd); } + diff --git a/src/mainloop.h b/src/mainloop.h index 2fe4886..fdc4071 100644 --- a/src/mainloop.h +++ b/src/mainloop.h @@ -40,3 +40,4 @@ extern int epoll_loop_open(struct epoll_descr *descr); extern int epoll_loop_close(struct epoll_descr *descr); #endif + diff --git a/src/map/map.h b/src/map/map.h index 71e9bd8..d6f7ebe 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -104,3 +104,4 @@ void map_clear(map_t *map); #endif #endif /* __LCRD_MAP_H__ */ + diff --git a/src/map/rb_tree.c b/src/map/rb_tree.c index 7f71578..2b728f4 100644 --- a/src/map/rb_tree.c +++ b/src/map/rb_tree.c @@ -141,14 +141,14 @@ void rbtree_free(rb_tree_t *tree) } /* - *----------------------------------------------------------- + * ----------------------------------------------------------- * | | * y left rot x * / \ <=========== / \ * x γ α y * / \ ===========> / \ * α β right rot β γ - *------------------------------------------------------------ + * ------------------------------------------------------------ */ static void left_rot(rb_tree_t *tree, rb_node_t *node) { @@ -614,3 +614,4 @@ void *rbtree_iterator_value(rb_iterator_t *itor) } return itor->node ? itor->node->value : NULL; } + diff --git a/src/map/rb_tree.h b/src/map/rb_tree.h index 14d8648..4cb41a7 100644 --- a/src/map/rb_tree.h +++ b/src/map/rb_tree.h @@ -80,3 +80,4 @@ void *rbtree_iterator_value(rb_iterator_t *itor); #endif #endif /* __RB_TREE_H_ */ + diff --git a/src/namespace.c b/src/namespace.c index 45c1212..9f13b63 100644 --- a/src/namespace.c +++ b/src/namespace.c @@ -96,3 +96,4 @@ char *get_share_namespace_path(const char *type, const char *src_path) return tmp_mode; } + diff --git a/src/namespace.h b/src/namespace.h index 0c1f906..5843020 100644 --- a/src/namespace.h +++ b/src/namespace.h @@ -70,3 +70,4 @@ static inline bool is_container(const char *mode) char *get_share_namespace_path(const char *type, const char *src_path); #endif + diff --git a/src/pack_config.c b/src/pack_config.c index 15d580a..57434de 100644 --- a/src/pack_config.c +++ b/src/pack_config.c @@ -659,7 +659,7 @@ static void pack_cgroup_resources(host_config *dstconfig, const lcrc_host_config dstconfig->pids_limit = srcconfig->cr->pids_limit; dstconfig->files_limit = srcconfig->cr->files_limit; - /* oom score adj*/ + /* oom score adj */ dstconfig->oom_score_adj = (int)srcconfig->cr->oom_score_adj; } diff --git a/src/pack_config.h b/src/pack_config.h index 16f9518..b6386f2 100644 --- a/src/pack_config.h +++ b/src/pack_config.h @@ -31,3 +31,4 @@ int generate_container_config(const lcrc_container_config_t *custom_conf, #endif #endif + diff --git a/src/path.c b/src/path.c index 6e235d6..b22d6a5 100644 --- a/src/path.c +++ b/src/path.c @@ -679,3 +679,107 @@ cleanup: return ret; } +int split_path_dir_entry(const char *path, char **dir, char **base) +{ +#define EXTRA_LEN 3 + char cleaned[PATH_MAX + EXTRA_LEN] = { 0 }; + char *dup = NULL; + + if (cleanpath(path, cleaned, PATH_MAX) == NULL) { + ERROR("Failed to clean path"); + return -1; + } + if (specify_current_dir(path)) { + set_char_to_separator(&cleaned[strlen(cleaned)]); + cleaned[strlen(cleaned)] = '.'; + } + dup = util_strdup_s(cleaned); + if (dir != NULL) { + *dir = util_strdup_s(dirname(dup)); + } + if (base != NULL) { + *base = util_strdup_s(basename(cleaned)); + } + free(dup); + return 0; +} + +static char *find_realpath(const char *path) +{ + int ret; + int i; + int max_symlink_iter = 10; + char *iter_path = NULL; + struct stat st; + + iter_path = util_strdup_s(path); + ret = lstat(iter_path, &st); + for (i = 0; i <= max_symlink_iter && ret == 0 && S_ISLNK(st.st_mode); i++) { + char target[PATH_MAX] = { 0 }; + char *parent = NULL; + + ret = (int)readlink(iter_path, target, PATH_MAX - 1); + if (ret < 0) { + ERROR("Failed to read link of %s: %s", iter_path, strerror(errno)); + goto out; + } + // is not absolutely path + if (target[0] != '\0' && target[0] != '/') { + if (split_path_dir_entry(iter_path, &parent, NULL) < 0) { + goto out; + } + free(iter_path); + iter_path = util_path_join(parent, target); + if (iter_path == NULL) { + ERROR("Failed to join path"); + free(parent); + goto out; + } + } else { + free(iter_path); + iter_path = util_strdup_s(target); + } + ret = lstat(iter_path, &st); + free(parent); + } + if (i > max_symlink_iter) { + ERROR("Too many symlinks in: %s", path); + goto out; + } + return iter_path; +out: + free(iter_path); + return NULL; +} + +int realpath_in_scope(const char *rootfs, const char *path, char **real_path) +{ + int ret = 0; + char full_path[PATH_MAX] = { 0 }; + char cleaned[PATH_MAX] = { 0 }; + char *tmp = NULL; + + if (sprintf_s(full_path, sizeof(full_path), "%s%s", rootfs, path) < 0) { + ERROR("sprintf error: %s", strerror(errno)); + ret = -1; + goto out; + } + if (cleanpath(full_path, cleaned, PATH_MAX) == NULL) { + ERROR("Failed to clean path: %s", full_path); + ret = -1; + goto out; + } + tmp = find_realpath(cleaned); + if (tmp == NULL) { + ret = -1; + goto out; + } + if (strncmp(tmp, rootfs, strlen(rootfs)) != 0) { + free(tmp); + ret = -1; + goto out; + } + *real_path = tmp; +out: + return ret; +} diff --git a/src/path.h b/src/path.h index 6852912..988d31e 100644 --- a/src/path.h +++ b/src/path.h @@ -41,8 +41,13 @@ bool has_trailing_path_separator(const char *path); char *preserve_trailing_dot_or_separator(const char *cleanedpath, const char *originalpath); +int split_path_dir_entry(const char *path, char **dir, char **base); + +int realpath_in_scope(const char *rootfs, const char *path, char **real_path); + #ifdef __cplusplus } #endif #endif + diff --git a/src/plugin/plugin.c b/src/plugin/plugin.c index cc3f715..66e7049 100644 --- a/src/plugin/plugin.c +++ b/src/plugin/plugin.c @@ -225,7 +225,7 @@ static int set_env_enable_plugins(oci_runtime_spec *oci) if (util_env_insert(&oci->process->env, &oci->process->env_len, LCRD_ENABLE_PLUGINS, strlen(LCRD_ENABLE_PLUGINS), uniq)) { - ERROR("set env %s failed", uniq); + WARN("set env %s failed", uniq); } free(uniq); @@ -250,6 +250,7 @@ static char **get_enable_plugins(const char *plugins) arr = util_string_split(plugins, LCRD_ENABLE_PLUGINS_SEPERATOR_CHAR); if (arr == NULL) { ERROR("Out of memory"); + goto out; } arr_len = util_array_len((const char **)arr); diff --git a/src/plugin/plugin.h b/src/plugin/plugin.h index fe6e25d..aae99f5 100644 --- a/src/plugin/plugin.h +++ b/src/plugin/plugin.h @@ -114,3 +114,4 @@ int plugin_event_container_post_remove(const container_t *cont); int plugin_event_container_post_remove2(const char *cid, const oci_runtime_spec *oci); #endif /* _PLUGIN_H_ */ + diff --git a/src/plugin/pspec.h b/src/plugin/pspec.h index 2a34465..7537654 100644 --- a/src/plugin/pspec.h +++ b/src/plugin/pspec.h @@ -40,3 +40,4 @@ int set_pspec(oci_runtime_spec *oci, const char *data); char *merge_pspec(const char *base, const char *data); #endif /* PSPEC_H */ + diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt new file mode 100644 index 0000000..1a46eec --- /dev/null +++ b/src/runtime/CMakeLists.txt @@ -0,0 +1,23 @@ +# get current directory sources files + +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} runtime_top_srcs) +add_subdirectory(lcr) + +set(local_runtime_srcs + ${runtime_top_srcs} + ${LCR_SRCS} + ) + +set(local_runtime_incs + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/lcr + ) + +set(RUNTIME_SRCS + ${local_runtime_srcs} + PARENT_SCOPE + ) +set(RUNTIME_INCS + ${local_runtime_incs} + PARENT_SCOPE + ) diff --git a/src/runtime/lcr/CMakeLists.txt b/src/runtime/lcr/CMakeLists.txt new file mode 100644 index 0000000..f3b1c4d --- /dev/null +++ b/src/runtime/lcr/CMakeLists.txt @@ -0,0 +1,7 @@ +# get current directory sources files +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_lcr_srcs) + +set(LCR_SRCS + ${local_lcr_srcs} + PARENT_SCOPE + ) diff --git a/src/runtime/lcr/lcr_rt_ops.c b/src/runtime/lcr/lcr_rt_ops.c new file mode 100644 index 0000000..eb8a873 --- /dev/null +++ b/src/runtime/lcr/lcr_rt_ops.c @@ -0,0 +1,396 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. + * Author: lifeng + * Create: 2019-11-22 + * Description: provide container list callback function definition + ********************************************************************************/ + +#include +#include +#include + +#include "lcr_rt_ops.h" +#include "log.h" +#include "engine.h" +#include "callback.h" +#include "error.h" +#include "lcrd_config.h" +#include "runtime.h" + +bool rt_lcr_detect(const char *runtime) +{ + /* now we just support lcr engine */ + if (runtime != NULL && strcasecmp(runtime, "lcr") == 0) { + return true; + } + + return false; +} + +int rt_lcr_create(const char *name, const char *runtime, const rt_create_params_t *params) +{ + int ret = 0; + char *runtime_root = NULL; + struct engine_operation *engine_ops = NULL; + + runtime_root = conf_get_routine_rootdir(runtime); + if (runtime_root == NULL) { + ERROR("Root path is NULL"); + ret = -1; + goto out; + } + + engine_ops = engines_get_handler(runtime); + if (engine_ops == NULL || engine_ops->engine_create_op == NULL) { + ERROR("Failed to get engine create operations"); + ret = -1; + goto out; + } + + if (!engine_ops->engine_create_op(name, runtime_root, params->real_rootfs, params->oci_config_data)) { + ERROR("Failed to create container"); + const char *tmpmsg = NULL; + tmpmsg = engine_ops->engine_get_errmsg_op(); + lcrd_set_error_message("Create container error: %s", + (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg + : DEF_ERR_RUNTIME_STR); + engine_ops->engine_clear_errmsg_op(); + ret = -1; + goto out; + } + +out: + free(runtime_root); + return ret; +} + +static int parse_container_pid(const char *S, const container_pid_t *pid_info) +{ + int num; + + num = sscanf_s(S, "%d %Lu %d %Lu", &pid_info->pid, &pid_info->start_time, &pid_info->ppid, &pid_info->pstart_time); + if (num != 4) { // args num to read is 4 + ERROR("Call sscanf error: %s", errno ? strerror(errno) : ""); + return -1; + } + + return 0; +} + +static int lcr_rt_read_pidfile(const char *pidfile, const container_pid_t *pid_info) +{ + if (pidfile == NULL || pid_info == NULL) { + ERROR("Invalid input arguments"); + return -1; + } + + char sbuf[1024] = { 0 }; /* bufs for stat */ + + if ((util_file2str(pidfile, sbuf, sizeof(sbuf))) == -1) { + return -1; + } + + return parse_container_pid(sbuf, pid_info); +} + +int rt_lcr_start(const char *name, const char *runtime, const rt_start_params_t *params, container_pid_t *pid_info) +{ + int ret = 0; + struct engine_operation *engine_ops = NULL; + engine_start_request_t request = { 0 }; + + engine_ops = engines_get_handler(runtime); + if (engine_ops == NULL || engine_ops->engine_start_op == NULL) { + ERROR("Failed to get engine start operations"); + ret = -1; + goto out; + } + + request.name = name; + request.lcrpath = params->rootpath; + request.logpath = params->logpath; + request.loglevel = params->loglevel; + request.daemonize = true; + request.tty = params->tty; + request.open_stdin = params->open_stdin; + request.console_fifos = params->console_fifos; + request.start_timeout = params->start_timeout; + request.container_pidfile = params->container_pidfile; + request.exit_fifo = params->exit_fifo; + request.uid = params->puser->uid; + request.gid = params->puser->gid; + request.additional_gids = params->puser->additional_gids; + request.additional_gids_len = params->puser->additional_gids_len; + + if (!engine_ops->engine_start_op(&request)) { + const char *tmpmsg = NULL; + tmpmsg = engine_ops->engine_get_errmsg_op(); + lcrd_set_error_message("Start container error: %s", + (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg + : DEF_ERR_RUNTIME_STR); + ERROR("Start container error: %s", (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg + : DEF_ERR_RUNTIME_STR); + engine_ops->engine_clear_errmsg_op(); + ret = -1; + goto out; + } + ret = lcr_rt_read_pidfile(params->container_pidfile, pid_info); + if (ret != 0) { + ERROR("Failed to get started container's pid info, start container fail"); + ret = -1; + goto out; + } +out: + return ret; +} + +int rt_lcr_restart(const char *name, const char *runtime, const rt_restart_params_t *params) +{ + return RUNTIME_NOT_IMPLEMENT_RESET; +} + +int rt_lcr_clean_resource(const char *name, const char *runtime, const rt_clean_params_t *params) +{ + int ret = 0; + struct engine_operation *engine_ops = NULL; + + engine_ops = engines_get_handler(runtime); + if (engine_ops == NULL || engine_ops->engine_clean_op == NULL) { + ERROR("Failed to get engine clean operations"); + ret = -1; + goto out; + } + + if (!engine_ops->engine_clean_op(name, params->rootpath, params->logpath, params->loglevel, params->pid)) { + const char *tmpmsg = NULL; + tmpmsg = engine_ops->engine_get_errmsg_op(); + lcrd_try_set_error_message("Clean resource container error;%s", + (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg + : DEF_ERR_RUNTIME_STR); + ret = -1; + goto out; + } + +out: + if (engine_ops != NULL) { + engine_ops->engine_clear_errmsg_op(); + } + return ret; +} + +static int remove_container_rootpath(const char *id, const char *root_path) +{ + int ret = 0; + char cont_root_path[PATH_MAX] = { 0 }; + + ret = sprintf_s(cont_root_path, sizeof(cont_root_path), "%s/%s", root_path, id); + if (ret < 0) { + ERROR("Failed to sprintf container_state"); + ret = -1; + goto out; + } + ret = util_recursive_rmdir(cont_root_path, 0); + if (ret != 0) { + const char *tmp_err = (errno != 0) ? strerror(errno) : "error"; + ERROR("Failed to delete container's root directory %s: %s", cont_root_path, tmp_err); + lcrd_set_error_message("Failed to delete container's root directory %s: %s", cont_root_path, tmp_err); + ret = -1; + goto out; + } + +out: + return ret; +} + +int rt_lcr_rm(const char *name, const char *runtime, const rt_rm_params_t *params) +{ + int ret = 0; + struct engine_operation *engine_ops = NULL; + + engine_ops = engines_get_handler(runtime); + if (engine_ops == NULL || engine_ops->engine_delete_op == NULL) { + ERROR("Failed to get engine delete operations"); + ret = -1; + goto out; + } + + if (!engine_ops->engine_delete_op(name, params->rootpath)) { + const char *tmpmsg = engine_ops->engine_get_errmsg_op(); + if (tmpmsg != NULL && strstr(tmpmsg, "No such container") != NULL) { + // container root path may been corrupted, try to remove by daemon + WARN("container %s root path may been corrupted, try to remove by daemon", name); + if (remove_container_rootpath(name, params->rootpath) == 0) { + goto out; + } + } + lcrd_set_error_message("Runtime delete container error: %s", + (tmpmsg != NULL && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg : DEF_ERR_RUNTIME_STR); + ERROR("Runtime delete container error: %s", + (tmpmsg != NULL && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg : DEF_ERR_RUNTIME_STR); + ret = -1; + goto out; + } + +out: + if (engine_ops != NULL) { + engine_ops->engine_clear_errmsg_op(); + } + return ret; +} + +int rt_lcr_get_console_config(const char *name, const char *runtime, const rt_get_console_conf_params_t *params) +{ + int ret = 0; + struct engine_operation *engine_ops = NULL; + + engine_ops = engines_get_handler(runtime); + if (engine_ops == NULL || (engine_ops->engine_get_console_config_op) == NULL) { + ERROR("Failed to get engine get_console_config operation"); + ret = -1; + goto out; + } + + if (!engine_ops->engine_get_console_config_op(name, params->rootpath, params->config)) { + ERROR("Failed to get console config"); + const char *tmpmsg = NULL; + tmpmsg = engine_ops->engine_get_errmsg_op(); + lcrd_set_error_message("Get console config error;%s", (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? + tmpmsg : DEF_ERR_RUNTIME_STR); + ret = -1; + goto out; + } + + +out: + if (engine_ops != NULL) { + engine_ops->engine_clear_errmsg_op(); + } + return ret; +} + +int rt_lcr_status(const char *name, const char *runtime, const rt_status_params_t *params, + struct engine_container_info *status) +{ + int ret = 0; + int nret = 0; + struct engine_operation *engine_ops = NULL; + + engine_ops = engines_get_handler(runtime); + if (engine_ops == NULL || engine_ops->engine_get_container_status_op == NULL) { + ERROR("Failed to get engine status operations"); + ret = -1; + goto out; + } + + nret = engine_ops->engine_get_container_status_op(name, params->rootpath, status); + if (nret != 0) { + engine_ops->engine_clear_errmsg_op(); + ret = -1; + goto out; + } + +out: + return ret; +} + +int rt_lcr_exec(const char *id, const char *runtime, const rt_exec_params_t *params, int *exit_code) +{ + int ret = 0; + struct engine_operation *engine_ops = NULL; + engine_exec_request_t request = { 0 }; + + engine_ops = engines_get_handler(runtime); + if (engine_ops == NULL || engine_ops->engine_exec_op == NULL) { + DEBUG("Failed to get engine exec operations"); + ret = -1; + goto out; + } + + request.name = id; + request.lcrpath = params->rootpath; + request.logpath = params->logpath; + request.loglevel = params->loglevel; + request.args = (const char **)params->args; + request.args_len = params->args_len; + request.env = (const char **)params->envs; + request.env_len = params->envs_len; + request.console_fifos = params->console_fifos; + request.timeout = params->timeout; + request.user = params->user; + + if (!engine_ops->engine_exec_op(&request, exit_code)) { + const char *tmpmsg = NULL; + tmpmsg = engine_ops->engine_get_errmsg_op(); + lcrd_set_error_message("Exec container error;%s", (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? + tmpmsg : DEF_ERR_RUNTIME_STR); + util_contain_errmsg(g_lcrd_errmsg, exit_code); + engine_ops->engine_clear_errmsg_op(); + ret = -1; + goto out; + } + +out: + return ret; +} + +int rt_lcr_pause(const char *name, const char *runtime, const rt_pause_params_t *params) +{ + int ret = 0; + struct engine_operation *engine_ops = NULL; + + engine_ops = engines_get_handler(runtime); + if (engine_ops == NULL || engine_ops->engine_pause_op == NULL) { + DEBUG("Failed to get engine pause operations"); + ret = -1; + goto out; + } + + if (!engine_ops->engine_pause_op(name, params->rootpath)) { + DEBUG("Pause container %s failed", name); + const char *tmpmsg = NULL; + tmpmsg = engine_ops->engine_get_errmsg_op(); + lcrd_set_error_message("Pause container error;%s", (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? + tmpmsg : DEF_ERR_RUNTIME_STR); + engine_ops->engine_clear_errmsg_op(); + ret = -1; + goto out; + } +out: + return ret; +} + +int rt_lcr_resume(const char *name, const char *runtime, const rt_resume_params_t *params) +{ + int ret = 0; + struct engine_operation *engine_ops = NULL; + + engine_ops = engines_get_handler(runtime); + if (engine_ops == NULL || engine_ops->engine_resume_op == NULL) { + DEBUG("Failed to get engine resume operations"); + ret = -1; + goto out; + } + + if (!engine_ops->engine_resume_op(name, params->rootpath)) { + DEBUG("Resume container %s failed", name); + const char *tmpmsg = NULL; + tmpmsg = engine_ops->engine_get_errmsg_op(); + lcrd_set_error_message("Resume container error;%s", + (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg + : DEF_ERR_RUNTIME_STR); + + engine_ops->engine_clear_errmsg_op(); + ret = -1; + goto out; + } +out: + return ret; +} diff --git a/src/runtime/lcr/lcr_rt_ops.h b/src/runtime/lcr/lcr_rt_ops.h new file mode 100644 index 0000000..a75f8d5 --- /dev/null +++ b/src/runtime/lcr/lcr_rt_ops.h @@ -0,0 +1,43 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. + * Author: lifeng + * Create: 2019-11-22 + * Description: provide container list callback function definition + *******************************************************************************/ + +#ifndef __RUNTIME_LCR_OPS_INTERFACE_H_ +#define __RUNTIME_LCR_OPS_INTERFACE_H_ + +#include "runtime.h" + +#ifdef __cplusplus +extern "C" { +#endif + +bool rt_lcr_detect(const char *runtime); +int rt_lcr_create(const char *name, const char *runtime, const rt_create_params_t *params); +int rt_lcr_start(const char *name, const char *runtime, const rt_start_params_t *params, container_pid_t *pid_info); +int rt_lcr_restart(const char *name, const char *runtime, const rt_restart_params_t *params); +int rt_lcr_clean_resource(const char *name, const char *runtime, const rt_clean_params_t *params); +int rt_lcr_rm(const char *name, const char *runtime, const rt_rm_params_t *params); +int rt_lcr_get_console_config(const char *name, const char *runtime, const rt_get_console_conf_params_t *params); +int rt_lcr_status(const char *name, const char *runtime, const rt_status_params_t *params, + struct engine_container_info *status); +int rt_lcr_exec(const char *id, const char *runtime, const rt_exec_params_t *params, int *exit_code); +int rt_lcr_pause(const char *name, const char *runtime, const rt_pause_params_t *params); +int rt_lcr_resume(const char *name, const char *runtime, const rt_resume_params_t *params); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c new file mode 100644 index 0000000..579e3f8 --- /dev/null +++ b/src/runtime/runtime.c @@ -0,0 +1,308 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. + * Author: lifeng + * Create: 2019-11-14 + * Description: provide runtime functions + ******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "runtime.h" +#include "log.h" +#include "utils.h" +#include "lcr_rt_ops.h" + +static const struct rt_ops g_lcr_rt_ops = { + .detect = rt_lcr_detect, + .rt_create = rt_lcr_create, + .rt_start = rt_lcr_start, + .rt_restart = rt_lcr_restart, + .rt_clean_resource = rt_lcr_clean_resource, + .rt_rm = rt_lcr_rm, + .rt_get_console_config = rt_lcr_get_console_config, + .rt_status = rt_lcr_status, + .rt_exec = rt_lcr_exec, + .rt_pause = rt_lcr_pause, + .rt_resume = rt_lcr_resume, +}; + +static const struct rt_ops *g_rt_ops[] = { + &g_lcr_rt_ops +}; + +static const size_t g_rt_nums = sizeof(g_rt_ops) / sizeof(struct rt_ops *); + +static const struct rt_ops *rt_ops_query(const char *runtime) +{ + size_t i; + + for (i = 0; i < g_rt_nums; i++) { + bool r = g_rt_ops[i]->detect(runtime); + if (r) { + break; + } + } + + if (i == g_rt_nums) { + return NULL; + } + return g_rt_ops[i]; +} + +int runtime_create(const char *name, const char *runtime, const rt_create_params_t *params) +{ + int ret = 0; + const struct rt_ops *ops = NULL; + + if (name == NULL || runtime == NULL) { + ERROR("Invalide arguments for runtime create"); + ret = -1; + goto out; + } + + ops = rt_ops_query(runtime); + if (ops == NULL) { + ERROR("Failed to get runtime ops for %s", runtime); + ret = -1; + goto out; + } + + ret = ops->rt_create(name, runtime, params); + +out: + return ret; +} + +int runtime_start(const char *name, const char *runtime, const rt_start_params_t *params, container_pid_t *pid_info) +{ + int ret = 0; + const struct rt_ops *ops = NULL; + + if (name == NULL || runtime == NULL || pid_info == NULL) { + ERROR("Invalide arguments for runtime start"); + ret = -1; + goto out; + } + + ops = rt_ops_query(runtime); + if (ops == NULL) { + ERROR("Failed to get runtime ops"); + ret = -1; + goto out; + } + + ret = ops->rt_start(name, runtime, params, pid_info); + +out: + return ret; +} + +int runtime_restart(const char *name, const char *runtime, const rt_restart_params_t *params) +{ + int ret = 0; + const struct rt_ops *ops = NULL; + + if (name == NULL || runtime == NULL) { + ERROR("Invalide arguments for runtime restart"); + ret = -1; + goto out; + } + + ops = rt_ops_query(runtime); + if (ops == NULL) { + ERROR("Failed to get runtime ops"); + ret = -1; + goto out; + } + + ret = ops->rt_restart(name, runtime, params); + +out: + return ret; +} + + +int runtime_clean_resource(const char *name, const char *runtime, const rt_clean_params_t *params) +{ + int ret = 0; + const struct rt_ops *ops = NULL; + + if (name == NULL || runtime == NULL) { + ERROR("Invalide arguments for runtime clean"); + ret = -1; + goto out; + } + + ops = rt_ops_query(runtime); + if (ops == NULL) { + ERROR("Failed to get runtime ops"); + ret = -1; + goto out; + } + + ret = ops->rt_clean_resource(name, runtime, params); + +out: + return ret; +} + +int runtime_rm(const char *name, const char *runtime, const rt_rm_params_t *params) +{ + int ret = 0; + const struct rt_ops *ops = NULL; + + if (name == NULL || runtime == NULL) { + ERROR("Invalide arguments for runtime rm"); + ret = -1; + goto out; + } + + ops = rt_ops_query(runtime); + if (ops == NULL) { + ERROR("Failed to get runtime ops"); + ret = -1; + goto out; + } + + ret = ops->rt_rm(name, runtime, params); + +out: + return ret; +} + +int runtime_get_console_config(const char *name, const char *runtime, const rt_get_console_conf_params_t *params) +{ + int ret = 0; + const struct rt_ops *ops = NULL; + + if (name == NULL || runtime == NULL) { + ERROR("Invalide arguments for runtime get console config"); + ret = -1; + goto out; + } + + ops = rt_ops_query(runtime); + if (ops == NULL) { + ERROR("Failed to get runtime ops"); + ret = -1; + goto out; + } + + ret = ops->rt_get_console_config(name, runtime, params); + +out: + return ret; +} + +int runtime_status(const char *name, const char *runtime, const rt_status_params_t *params, + struct engine_container_info *status) +{ + int ret = 0; + const struct rt_ops *ops = NULL; + + if (name == NULL || runtime == NULL || status == NULL) { + ERROR("Invalide arguments for runtime start"); + ret = -1; + goto out; + } + + ops = rt_ops_query(runtime); + if (ops == NULL) { + ERROR("Failed to get runtime ops"); + ret = -1; + goto out; + } + + ret = ops->rt_status(name, runtime, params, status); + +out: + return ret; +} + +int runtime_exec(const char *name, const char *runtime, const rt_exec_params_t *params, + int *exit_code) +{ + int ret = 0; + const struct rt_ops *ops = NULL; + + if (name == NULL || runtime == NULL || exit_code == NULL) { + ERROR("Invalide arguments for runtime exec"); + ret = -1; + goto out; + } + + ops = rt_ops_query(runtime); + if (ops == NULL) { + ERROR("Failed to get runtime ops"); + ret = -1; + goto out; + } + + ret = ops->rt_exec(name, runtime, params, exit_code); + +out: + return ret; +} + +int runtime_pause(const char *name, const char *runtime, const rt_pause_params_t *params) +{ + int ret = 0; + const struct rt_ops *ops = NULL; + + if (name == NULL || runtime == NULL || params == NULL) { + ERROR("Invalide arguments for runtime pause"); + ret = -1; + goto out; + } + + ops = rt_ops_query(runtime); + if (ops == NULL) { + ERROR("Failed to get runtime ops"); + ret = -1; + goto out; + } + + ret = ops->rt_pause(name, runtime, params); + +out: + return ret; +} + +int runtime_resume(const char *name, const char *runtime, const rt_resume_params_t *params) +{ + int ret = 0; + const struct rt_ops *ops = NULL; + + if (name == NULL || runtime == NULL || params == NULL) { + ERROR("Invalide arguments for runtime resume"); + ret = -1; + goto out; + } + + ops = rt_ops_query(runtime); + if (ops == NULL) { + ERROR("Failed to get runtime ops"); + ret = -1; + goto out; + } + + ret = ops->rt_resume(name, runtime, params); + +out: + return ret; +} diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h new file mode 100644 index 0000000..a63e1aa --- /dev/null +++ b/src/runtime/runtime.h @@ -0,0 +1,151 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * 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 v1 for more details. + * Author: lifeng + * Create: 2019-11-22 + * Description: provide runtime function definition + ******************************************************************************/ +#ifndef __RUNTIME_H +#define __RUNTIME_H + +#include +#include + +#include "container_unix.h" +#include "engine.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define RUNTIME_NOT_IMPLEMENT_RESET -2 + +typedef struct _rt_create_params_t { + const char *rootfs; + const char *bundle; + const char *state; + const char *real_rootfs; + void *oci_config_data; + bool terminal; + const char *stdin; + const char *stdout; + const char *stderr; +} rt_create_params_t; + + +typedef struct _rt_start_params_t { + const char *rootpath; + bool tty; + bool open_stdin; + + const char *logpath; + const char *loglevel; + + const char **console_fifos; + + uint32_t start_timeout; + + const char *container_pidfile; + const char *exit_fifo; + const oci_runtime_spec_process_user *puser; +} rt_start_params_t; + +typedef struct _rt_restart_params_t { + const char *rootpath; +} rt_restart_params_t; + +typedef struct _rt_clean_params_t { + const char *rootpath; + const char *statepath; + const char *logpath; + const char *loglevel; + pid_t pid; +} rt_clean_params_t; + +typedef struct _rt_rm_params_t { + const char *rootpath; +} rt_rm_params_t; + +typedef struct _rt_get_console_conf_params_t { + const char *rootpath; + struct engine_console_config *config; +} rt_get_console_conf_params_t; + +typedef struct _rt_status_params_t { + const char *rootpath; +} rt_status_params_t; + +typedef struct _rt_exec_params_t { + const char *rootpath; + const char *logpath; + const char *loglevel; + const char **console_fifos; + int64_t timeout; + const char *user; + const char * const *args; + size_t args_len; + const char * const *envs; + size_t envs_len; +} rt_exec_params_t; + +typedef struct _rt_pause_params_t { + const char *rootpath; +} rt_pause_params_t; + +typedef struct _rt_resume_params_t { + const char *rootpath; +} rt_resume_params_t; + +struct rt_ops { + /* detect whether runtime is of this runtime type */ + bool (*detect)(const char *runtime); + + /* runtime ops */ + int (*rt_create)(const char *name, const char *runtime, const rt_create_params_t *params); + + int (*rt_start)(const char *name, const char *runtime, const rt_start_params_t *params, container_pid_t *pid_info); + + int (*rt_restart)(const char *name, const char *runtime, const rt_restart_params_t *params); + + int (*rt_clean_resource)(const char *name, const char *runtime, const rt_clean_params_t *params); + + int (*rt_rm)(const char *name, const char *runtime, const rt_rm_params_t *params); + + int (*rt_get_console_config)(const char *name, const char *runtime, const rt_get_console_conf_params_t *params); + + int (*rt_status)(const char *name, const char *runtime, const rt_status_params_t *params, + struct engine_container_info *status); + + int (*rt_exec)(const char *name, const char *runtime, const rt_exec_params_t *params, + int *exit_code); + + int (*rt_pause)(const char *name, const char *runtime, const rt_pause_params_t *params); + int (*rt_resume)(const char *name, const char *runtime, const rt_resume_params_t *params); +}; + +int runtime_create(const char *name, const char *runtime, const rt_create_params_t *params); +int runtime_clean_resource(const char *name, const char *runtime, const rt_clean_params_t *params); +int runtime_start(const char *name, const char *runtime, const rt_start_params_t *params, container_pid_t *pid_info); +int runtime_restart(const char *name, const char *runtime, const rt_restart_params_t *params); +int runtime_rm(const char *name, const char *runtime, const rt_rm_params_t *params); +int runtime_get_console_config(const char *name, const char *runtime, const rt_get_console_conf_params_t *params); +int runtime_status(const char *name, const char *runtime, const rt_status_params_t *params, + struct engine_container_info *status); +int runtime_exec(const char *name, const char *runtime, const rt_exec_params_t *params, + int *exit_code); +int runtime_pause(const char *name, const char *runtime, const rt_pause_params_t *params); +int runtime_resume(const char *name, const char *runtime, const rt_resume_params_t *params); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/services/CMakeLists.txt b/src/services/CMakeLists.txt index da75cfd..b5ccdea 100644 --- a/src/services/CMakeLists.txt +++ b/src/services/CMakeLists.txt @@ -11,7 +11,7 @@ add_subdirectory(execution) list(APPEND local_services_srcs ${EXECUTION_SRCS}) list(APPEND local_services_incs ${EXECUTION_INCS}) -if (NOT DISABLE_OCI) +if (ENABLE_OCI_IMAGE) add_subdirectory(graphdriver) list(APPEND local_services_srcs ${GRAPHDRIVER_SRCS}) list(APPEND local_services_incs ${GRAPHDRIVER_INCS}) diff --git a/src/services/callback.c b/src/services/callback.c index fe03f78..ae178dc 100644 --- a/src/services/callback.c +++ b/src/services/callback.c @@ -33,3 +33,4 @@ service_callback_t *get_service_callback(void) { return &g_isulad_servicecallback; } + diff --git a/src/services/callback.h b/src/services/callback.h index 0bf5997..350a2d1 100644 --- a/src/services/callback.h +++ b/src/services/callback.h @@ -175,3 +175,4 @@ service_callback_t *get_service_callback(void); #endif #endif + diff --git a/src/services/cri/checkpoint_handler.cc b/src/services/cri/checkpoint_handler.cc index 6d72146..e0ba26f 100644 --- a/src/services/cri/checkpoint_handler.cc +++ b/src/services/cri/checkpoint_handler.cc @@ -154,6 +154,7 @@ out: void PortMapping::CStructToPortMapping(const cri_port_mapping *pmapping, Errors &error) { + (void)error; if (pmapping == nullptr) { return; } @@ -362,5 +363,4 @@ void PodSandboxCheckpoint::CStructToCheckpoint(const cri_checkpoint *checkpoint, } } -} // namespace cri - +} // namespace cri diff --git a/src/services/cri/checkpoint_handler.h b/src/services/cri/checkpoint_handler.h index 1547fc1..990fde4 100644 --- a/src/services/cri/checkpoint_handler.h +++ b/src/services/cri/checkpoint_handler.h @@ -87,5 +87,5 @@ private: std::string m_checkSum; }; -} // namespace cri +} // namespace cri #endif diff --git a/src/services/cri/cni_network_plugin.cc b/src/services/cri/cni_network_plugin.cc index d52ed59..dc2d3f9 100644 --- a/src/services/cri/cni_network_plugin.cc +++ b/src/services/cri/cni_network_plugin.cc @@ -57,7 +57,12 @@ static std::unique_ptr GetLoNetwork(const std::string &binDir, const exit(1); } - auto result = std::unique_ptr(new CNINetwork("lo", loConf)); + auto result = std::unique_ptr(new (std::nothrow) CNINetwork("lo", loConf)); + if (result == nullptr) { + ERROR("Out of memory"); + return nullptr; + } + result->InsertPath(VendorCNIDir(vendorDirPrefix, "loopback")); result->InsertPath(binDir); @@ -245,11 +250,15 @@ int CniNetworkPlugin::InsertNewNetwork(struct cni_network_list_conf *n_list, std::string tpath = VendorCNIDir(vendorCNIDirPrefix, confType); if (tpath.empty()) { free_cni_network_list_conf(n_list); - n_list = nullptr; err.SetError("Out of memory"); return -1; } - std::unique_ptr network(new CNINetwork(n_list->name, n_list)); + std::unique_ptr network(new (std::nothrow) CNINetwork(n_list->name, n_list)); + if (network == nullptr) { + free_cni_network_list_conf(n_list); + err.SetError("Out of memory"); + return -1; + } network->InsertPath(tpath); network->InsertPath(binDir); @@ -646,8 +655,7 @@ void CniNetworkPlugin::BuildCNIRuntimeConf(const std::string &podName, const std err.Errorf("could not retrieve port mappings: %s", err.GetCMessage()); goto free_out; } - std::copy(checkpoint.GetData()->GetPortMappings().begin(), - checkpoint.GetData()->GetPortMappings().end(), + std::copy(checkpoint.GetData()->GetPortMappings().begin(), checkpoint.GetData()->GetPortMappings().end(), std::back_inserter(portMappings)); } @@ -716,5 +724,4 @@ void CniNetworkPlugin::UnlockNetworkMap(Errors &error) } } -} // namespace Network - +} // namespace Network diff --git a/src/services/cri/cni_network_plugin.h b/src/services/cri/cni_network_plugin.h index 30ee81d..abaa441 100644 --- a/src/services/cri/cni_network_plugin.h +++ b/src/services/cri/cni_network_plugin.h @@ -152,6 +152,6 @@ private: std::map> m_networks; }; -} // namespace Network +} // namespace Network #endif diff --git a/src/services/cri/cri_container.cc b/src/services/cri/cri_container.cc index 06f034e..a098c88 100644 --- a/src/services/cri/cri_container.cc +++ b/src/services/cri/cri_container.cc @@ -31,6 +31,7 @@ #include "path.h" #include "naming.h" #include "parse_common.h" +#include "image.h" #include "cri_runtime_service.h" #include "request_cache.h" @@ -45,7 +46,6 @@ std::string CRIRuntimeServiceImpl::GetRealContainerOrSandboxID(const std::string error.SetError("Unimplemented callback"); return realID; } - container_get_id_request *request { nullptr }; container_get_id_response *response { nullptr }; request = (container_get_id_request *)util_common_calloc_s(sizeof(container_get_id_request)); @@ -73,7 +73,6 @@ std::string CRIRuntimeServiceImpl::GetRealContainerOrSandboxID(const std::string goto cleanup; } } - if (strncmp(response->id, id.c_str(), id.length()) != 0) { error.Errorf("No such container with id: %s", id.c_str()); goto cleanup; @@ -117,8 +116,8 @@ void CRIRuntimeServiceImpl::GetContainerTimeStamps(container_inspect *inspect, i } container_custom_config *CRIRuntimeServiceImpl::GenerateCreateContainerCustomConfig( - const std::string &realPodSandboxID, const runtime::ContainerConfig &containerConfig, - const runtime::PodSandboxConfig &podSandboxConfig, Errors &error) + const std::string &realPodSandboxID, const runtime::v1alpha2::ContainerConfig &containerConfig, + const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, Errors &error) { container_custom_config *custom_config = (container_custom_config *)util_common_calloc_s(sizeof(container_custom_config)); @@ -151,8 +150,7 @@ container_custom_config *CRIRuntimeServiceImpl::GenerateCreateContainerCustomCon } if (append_json_map_string_string(custom_config->labels, - CRIHelpers::Constants::CONTAINER_LOGPATH_LABEL_KEY.c_str(), - real_logpath)) { + CRIHelpers::Constants::CONTAINER_LOGPATH_LABEL_KEY.c_str(), real_logpath)) { error.SetError("Append map string string failed"); goto cleanup; } @@ -174,8 +172,8 @@ cleanup: return nullptr; } -int CRIRuntimeServiceImpl::PackCreateContainerHostConfigDevices(const runtime::ContainerConfig &containerConfig, - host_config *hostconfig, Errors &error) +int CRIRuntimeServiceImpl::PackCreateContainerHostConfigDevices( + const runtime::v1alpha2::ContainerConfig &containerConfig, host_config *hostconfig, Errors &error) { int ret { 0 }; @@ -209,8 +207,8 @@ out: return ret; } -int CRIRuntimeServiceImpl::PackCreateContainerHostConfigSecurityContext(const runtime::ContainerConfig &containerConfig, - host_config *hostconfig, Errors &error) +int CRIRuntimeServiceImpl::PackCreateContainerHostConfigSecurityContext( + const runtime::v1alpha2::ContainerConfig &containerConfig, host_config *hostconfig, Errors &error) { if (!containerConfig.linux().has_security_context()) { return 0; @@ -247,8 +245,8 @@ int CRIRuntimeServiceImpl::PackCreateContainerHostConfigSecurityContext(const ru return 0; } -host_config *CRIRuntimeServiceImpl::GenerateCreateContainerHostConfig(const runtime::ContainerConfig &containerConfig, - Errors &error) +host_config *CRIRuntimeServiceImpl::GenerateCreateContainerHostConfig( + const runtime::v1alpha2::ContainerConfig &containerConfig, Errors &error) { host_config *hostconfig = (host_config *)util_common_calloc_s(sizeof(host_config)); if (hostconfig == nullptr) { @@ -287,10 +285,8 @@ cleanup: } container_create_request *CRIRuntimeServiceImpl::GenerateCreateContainerRequest( - const std::string &realPodSandboxID, - const runtime::ContainerConfig &containerConfig, - const runtime::PodSandboxConfig &podSandboxConfig, - Errors &error) + const std::string &realPodSandboxID, const runtime::v1alpha2::ContainerConfig &containerConfig, + const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, Errors &error) { struct parser_context ctx { OPT_GEN_SIMPLIFY, 0 @@ -357,8 +353,8 @@ cleanup: } std::string CRIRuntimeServiceImpl::CreateContainer(const std::string &podSandboxID, - const runtime::ContainerConfig &containerConfig, - const runtime::PodSandboxConfig &podSandboxConfig, + const runtime::v1alpha2::ContainerConfig &containerConfig, + const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, Errors &error) { std::string response_id { "" }; @@ -399,7 +395,7 @@ cleanup: return response_id; } -void CRIRuntimeServiceImpl::MakeContainerConfig(const runtime::ContainerConfig &config, +void CRIRuntimeServiceImpl::MakeContainerConfig(const runtime::v1alpha2::ContainerConfig &config, container_custom_config *cConfig, Errors &error) { if (config.command_size() > 0) { @@ -533,8 +529,7 @@ void CRIRuntimeServiceImpl::StartContainer(const std::string &containerID, Error container_start_response *response { nullptr }; int ret {}; - container_start_request *request = - (container_start_request *)util_common_calloc_s(sizeof(container_start_request)); + container_start_request *request = (container_start_request *)util_common_calloc_s(sizeof(container_start_request)); if (request == nullptr) { error.SetError("Out of memory"); goto cleanup; @@ -581,8 +576,7 @@ void CRIRuntimeServiceImpl::StopContainer(const std::string &containerID, int64_ } container_stop_response *response { nullptr }; - container_stop_request *request = - (container_stop_request *)util_common_calloc_s(sizeof(container_stop_request)); + container_stop_request *request = (container_stop_request *)util_common_calloc_s(sizeof(container_stop_request)); if (request == nullptr) { error.SetError("Out of memory"); goto cleanup; @@ -675,10 +669,15 @@ cleanup: } void CRIRuntimeServiceImpl::ListContainersToGRPC(container_list_response *response, - std::vector> *pods, Errors &error) + std::vector> *pods, + Errors &error) { - for (size_t i = 0; i < response->containers_len; i++) { - std::unique_ptr container(new runtime::Container); + for (size_t i {}; i < response->containers_len; i++) { + std::unique_ptr container(new (std::nothrow) runtime::v1alpha2::Container); + if (container == nullptr) { + error.SetError("Out of memory"); + return; + } if (response->containers[i]->id != nullptr) { container->set_id(response->containers[i]->id); @@ -696,15 +695,15 @@ void CRIRuntimeServiceImpl::ListContainersToGRPC(container_list_response *respon CRIHelpers::ExtractAnnotations(response->containers[i]->annotations, *container->mutable_annotations()); for (size_t j = 0; j < response->containers[i]->labels->len; j++) { - if (strcmp(response->containers[i]->labels->keys[j], - CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY.c_str()) == 0) { + if (strcmp(response->containers[i]->labels->keys[j], CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY.c_str()) == + 0) { container->set_pod_sandbox_id(response->containers[i]->labels->values[j]); break; } } if (response->containers[i]->image != nullptr) { - runtime::ImageSpec *image = container->mutable_image(); + runtime::v1alpha2::ImageSpec *image = container->mutable_image(); image->set_image(response->containers[i]->image); imagetool_image *ir = CRIHelpers::InspectImageByID(response->containers[i]->image, error); if (error.NotEmpty() || ir == nullptr) { @@ -719,7 +718,7 @@ void CRIRuntimeServiceImpl::ListContainersToGRPC(container_list_response *respon free_imagetool_image(ir); } - runtime::ContainerState state = + runtime::v1alpha2::ContainerState state = CRIHelpers::ContainerStatusToRuntime(Container_Status(response->containers[i]->status)); container->set_state(state); @@ -727,7 +726,7 @@ void CRIRuntimeServiceImpl::ListContainersToGRPC(container_list_response *respon } } -void CRIRuntimeServiceImpl::ListContainersFromGRPC(const runtime::ContainerFilter *filter, +void CRIRuntimeServiceImpl::ListContainersFromGRPC(const runtime::v1alpha2::ContainerFilter *filter, container_list_request **request, Errors &error) { *request = (container_list_request *)util_common_calloc_s(sizeof(container_list_request)); @@ -780,8 +779,9 @@ void CRIRuntimeServiceImpl::ListContainersFromGRPC(const runtime::ContainerFilte } } -void CRIRuntimeServiceImpl::ListContainers(const runtime::ContainerFilter *filter, - std::vector> *containers, Errors &error) +void CRIRuntimeServiceImpl::ListContainers(const runtime::v1alpha2::ContainerFilter *filter, + std::vector> *containers, + Errors &error) { if (m_cb == nullptr || m_cb->container.list == nullptr) { error.SetError("Unimplemented callback"); @@ -811,15 +811,20 @@ cleanup: free_container_list_response(response); } -void CRIRuntimeServiceImpl::ContainerStatsToGRPC(container_stats_response *response, - std::vector> *containerstats, - Errors &error) +void CRIRuntimeServiceImpl::ContainerStatsToGRPC( + container_stats_response *response, + std::vector> *containerstats, Errors &error) { int ret {}; for (size_t i {}; i < response->container_stats_len; i++) { - std::unique_ptr container(new runtime::ContainerStats); imagetool_fs_info *fs_usage { nullptr }; + using ContainerStatsPtr = std::unique_ptr; + ContainerStatsPtr container(new (std::nothrow) runtime::v1alpha2::ContainerStats); + if (container == nullptr) { + ERROR("Out of memory"); + return; + } if (response->container_stats[i]->id != nullptr && response->container_stats[i]->image_type != nullptr) { container->mutable_attributes()->set_id(response->container_stats[i]->id); @@ -860,9 +865,46 @@ void CRIRuntimeServiceImpl::ContainerStatsToGRPC(container_stats_response *respo } } -void CRIRuntimeServiceImpl::ListContainerStats(const runtime::ContainerStatsFilter *filter, - std::vector> *containerstats, - Errors &error) +int CRIRuntimeServiceImpl::PackContainerStatsFilter(const runtime::v1alpha2::ContainerStatsFilter *filter, + container_stats_request *request, Errors &error) +{ + if (filter == nullptr) { + return 0; + } + + if (!filter->id().empty()) { + if (CRIHelpers::FiltersAdd(request->filters, "id", filter->id()) != 0) { + error.SetError("Failed to add filter"); + return -1; + } + } + if (!filter->pod_sandbox_id().empty()) { + if (CRIHelpers::FiltersAddLabel(request->filters, CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY, + filter->pod_sandbox_id()) != 0) { + error.SetError("Failed to add filter"); + return -1; + } + } + + // Add some label + if (CRIHelpers::FiltersAddLabel(request->filters, CRIHelpers::Constants::CONTAINER_TYPE_LABEL_KEY, + CRIHelpers::Constants::CONTAINER_TYPE_LABEL_CONTAINER) != 0) { + error.SetError("Failed to add filter"); + return -1; + } + for (auto &iter : filter->label_selector()) { + if (CRIHelpers::FiltersAddLabel(request->filters, iter.first, iter.second) != 0) { + error.SetError("Failed to add filter"); + return -1; + } + } + + return 0; +} + +void CRIRuntimeServiceImpl::ListContainerStats( + const runtime::v1alpha2::ContainerStatsFilter *filter, + std::vector> *containerstats, Errors &error) { if (m_cb == nullptr || m_cb->container.stats == nullptr) { error.SetError("Unimplemented callback"); @@ -888,33 +930,8 @@ void CRIRuntimeServiceImpl::ListContainerStats(const runtime::ContainerStatsFilt goto cleanup; } - if (filter != nullptr) { - if (!filter->id().empty()) { - if (CRIHelpers::FiltersAdd(request->filters, "id", filter->id()) != 0) { - error.SetError("Failed to add filter"); - goto cleanup; - } - } - if (!filter->pod_sandbox_id().empty()) { - if (CRIHelpers::FiltersAddLabel(request->filters, CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY, - filter->pod_sandbox_id()) != 0) { - error.SetError("Failed to add filter"); - goto cleanup; - } - } - - // Add some label - if (CRIHelpers::FiltersAddLabel(request->filters, CRIHelpers::Constants::CONTAINER_TYPE_LABEL_KEY, - CRIHelpers::Constants::CONTAINER_TYPE_LABEL_CONTAINER) != 0) { - error.SetError("Failed to add filter"); - goto cleanup; - } - for (auto &iter : filter->label_selector()) { - if (CRIHelpers::FiltersAddLabel(request->filters, iter.first, iter.second) != 0) { - error.SetError("Failed to add filter"); - goto cleanup; - } - } + if (PackContainerStatsFilter(filter, request, error) != 0) { + goto cleanup; } if (m_cb->container.stats(request, &response)) { @@ -933,30 +950,30 @@ cleanup: } int CRIRuntimeServiceImpl::PackContainerImageToStatus(container_inspect *inspect, - std::unique_ptr &contStatus, + std::unique_ptr &contStatus, Errors &error) { if (inspect->image == nullptr) { return 0; } - contStatus->mutable_image()->set_image(inspect->image); - imagetool_image *ir = CRIHelpers::InspectImageByID(inspect->image, error); + contStatus->mutable_image()->set_image(inspect->config->image); + imagetool_image *ir = CRIHelpers::InspectImageByID(inspect->config->image, error); if (error.NotEmpty() || ir == nullptr) { - error.Errorf("unable to inspect image %s while inspecting container %s: %s", inspect->image, inspect->name, - error.Empty() ? "Unknown" : error.GetMessage().c_str()); + error.Errorf("unable to inspect image %s while inspecting container %s: %s", inspect->config->image, + inspect->name, error.Empty() ? "Unknown" : error.GetMessage().c_str()); free_imagetool_image(ir); return -1; } - contStatus->set_image_ref(CRIHelpers::ToPullableImageID(inspect->image, ir)); + contStatus->set_image_ref(CRIHelpers::ToPullableImageID(inspect->config->image, ir)); free_imagetool_image(ir); return 0; } void CRIRuntimeServiceImpl::UpdateBaseStatusFromInspect(container_inspect *inspect, int64_t &createdAt, int64_t &startedAt, int64_t &finishedAt, - std::unique_ptr &contStatus) + std::unique_ptr &contStatus) { - runtime::ContainerState state { runtime::CONTAINER_UNKNOWN }; + runtime::v1alpha2::ContainerState state { runtime::v1alpha2::CONTAINER_UNKNOWN }; std::string reason, message; int32_t exitCode { 0 }; @@ -966,23 +983,23 @@ void CRIRuntimeServiceImpl::UpdateBaseStatusFromInspect(container_inspect *inspe if (inspect->state->running) { // Container is running - state = runtime::CONTAINER_RUNNING; + state = runtime::v1alpha2::CONTAINER_RUNNING; } else { // Container is not running. - if (finishedAt) { // Case 1 - state = runtime::CONTAINER_EXITED; + if (finishedAt) { // Case 1 + state = runtime::v1alpha2::CONTAINER_EXITED; if (inspect->state->exit_code == 0) { reason = "Completed"; } else { reason = "Error"; } - } else if (inspect->state->exit_code) { // Case 2 - state = runtime::CONTAINER_EXITED; + } else if (inspect->state->exit_code) { // Case 2 + state = runtime::v1alpha2::CONTAINER_EXITED; finishedAt = createdAt; startedAt = createdAt; reason = "ContainerCannotRun"; - } else { // Case 3 - state = runtime::CONTAINER_CREATED; + } else { // Case 3 + state = runtime::v1alpha2::CONTAINER_CREATED; } if (inspect->state->error != nullptr) { message = inspect->state->error; @@ -1001,7 +1018,7 @@ pack_status: } void CRIRuntimeServiceImpl::PackLabelsToStatus(container_inspect *inspect, - std::unique_ptr &contStatus) + std::unique_ptr &contStatus) { if (inspect->config == nullptr || inspect->config->labels == nullptr) { return; @@ -1017,25 +1034,26 @@ void CRIRuntimeServiceImpl::PackLabelsToStatus(container_inspect *inspect, } void CRIRuntimeServiceImpl::ConvertMountsToStatus(container_inspect *inspect, - std::unique_ptr &contStatus) + std::unique_ptr &contStatus) { for (size_t i = 0; i < inspect->mounts_len; i++) { - runtime::Mount *mount = contStatus->add_mounts(); + runtime::v1alpha2::Mount *mount = contStatus->add_mounts(); mount->set_host_path(inspect->mounts[i]->source); mount->set_container_path(inspect->mounts[i]->destination); mount->set_readonly(!inspect->mounts[i]->rw); if (inspect->mounts[i]->propagation == nullptr || strcmp(inspect->mounts[i]->propagation, "rprivate") == 0) { - mount->set_propagation(runtime::PROPAGATION_PRIVATE); + mount->set_propagation(runtime::v1alpha2::PROPAGATION_PRIVATE); } else if (strcmp(inspect->mounts[i]->propagation, "rslave") == 0) { - mount->set_propagation(runtime::PROPAGATION_HOST_TO_CONTAINER); + mount->set_propagation(runtime::v1alpha2::PROPAGATION_HOST_TO_CONTAINER); } else if (strcmp(inspect->mounts[i]->propagation, "rshared") == 0) { - mount->set_propagation(runtime::PROPAGATION_BIDIRECTIONAL); + mount->set_propagation(runtime::v1alpha2::PROPAGATION_BIDIRECTIONAL); } // Note: Can't set SeLinuxRelabel } } void CRIRuntimeServiceImpl::ContainerStatusToGRPC(container_inspect *inspect, - std::unique_ptr &contStatus, Errors &error) + std::unique_ptr &contStatus, + Errors &error) { if (inspect->id != nullptr) { contStatus->set_id(inspect->id); @@ -1066,8 +1084,8 @@ void CRIRuntimeServiceImpl::ContainerStatusToGRPC(container_inspect *inspect, ConvertMountsToStatus(inspect, contStatus); } -std::unique_ptr CRIRuntimeServiceImpl::ContainerStatus(const std::string &containerID, - Errors &error) +std::unique_ptr CRIRuntimeServiceImpl::ContainerStatus( + const std::string &containerID, Errors &error) { if (containerID.empty()) { error.SetError("Empty pod sandbox id"); @@ -1089,8 +1107,13 @@ std::unique_ptr CRIRuntimeServiceImpl::ContainerStatus error.SetError("Get null inspect"); return nullptr; } + using ContainerStatusPtr = std::unique_ptr; + ContainerStatusPtr contStatus(new (std::nothrow) runtime::v1alpha2::ContainerStatus); + if (contStatus == nullptr) { + error.SetError("Out of memory"); + return nullptr; + } - std::unique_ptr contStatus(new runtime::ContainerStatus); ContainerStatusToGRPC(inspect, contStatus, error); free_container_inspect(inspect); @@ -1098,7 +1121,8 @@ std::unique_ptr CRIRuntimeServiceImpl::ContainerStatus } void CRIRuntimeServiceImpl::UpdateContainerResources(const std::string &containerID, - const runtime::LinuxContainerResources &resources, Errors &error) + const runtime::v1alpha2::LinuxContainerResources &resources, + Errors &error) { if (containerID.empty()) { error.SetError("Invalid empty container id."); @@ -1219,7 +1243,7 @@ void CRIRuntimeServiceImpl::ExecSyncFromGRPC(const std::string &containerID, void CRIRuntimeServiceImpl::ExecSync(const std::string &containerID, const google::protobuf::RepeatedPtrField &cmd, int64_t timeout, - runtime::ExecSyncResponse *reply, Errors &error) + runtime::v1alpha2::ExecSyncResponse *reply, Errors &error) { struct io_write_wrapper stringWriter = { 0 }; @@ -1264,7 +1288,7 @@ cleanup: free_container_exec_response(response); } -int CRIRuntimeServiceImpl::ValidateExecRequest(const runtime::ExecRequest &req, Errors &error) +int CRIRuntimeServiceImpl::ValidateExecRequest(const runtime::v1alpha2::ExecRequest &req, Errors &error) { if (req.container_id().empty()) { error.SetError("missing required container id!"); @@ -1284,6 +1308,7 @@ int CRIRuntimeServiceImpl::ValidateExecRequest(const runtime::ExecRequest &req, return -1; } bool running = status->state != nullptr && status->state->running; + bool paused = status->state != nullptr && status->state->paused; free_container_inspect(status); if (!running) { ERROR("Container is not running: %s", req.container_id().c_str()); @@ -1291,6 +1316,12 @@ int CRIRuntimeServiceImpl::ValidateExecRequest(const runtime::ExecRequest &req, return -1; } + if (paused) { + ERROR("Container %s is paused, unpause the container before exec", req.container_id().c_str()); + error.Errorf("Container %s is paused, unpause the container before exec", req.container_id().c_str()); + return -1; + } + if (req.tty() && req.stderr()) { error.SetError("tty and stderr cannot both be true!"); return -1; @@ -1311,14 +1342,19 @@ std::string CRIRuntimeServiceImpl::BuildURL(const std::string &method, const std return wsurl.ResolveReference(&url)->String(); } -void CRIRuntimeServiceImpl::Exec(const runtime::ExecRequest &req, runtime::ExecResponse *resp, Errors &error) +void CRIRuntimeServiceImpl::Exec(const runtime::v1alpha2::ExecRequest &req, runtime::v1alpha2::ExecResponse *resp, + Errors &error) { if (ValidateExecRequest(req, error)) { return; } RequestCache *cache = RequestCache::GetInstance(); - runtime::ExecRequest *execReq = new runtime::ExecRequest(req); - std::string token = cache->Insert(const_cast(execReq)); + runtime::v1alpha2::ExecRequest *execReq = new (std::nothrow) runtime::v1alpha2::ExecRequest(req); + if (execReq == nullptr) { + error.SetError("Out of memory"); + return; + } + std::string token = cache->Insert(const_cast(execReq)); if (token.empty()) { error.SetError("failed to get a unique token!"); return; @@ -1327,7 +1363,7 @@ void CRIRuntimeServiceImpl::Exec(const runtime::ExecRequest &req, runtime::ExecR resp->set_url(url); } -int CRIRuntimeServiceImpl::ValidateAttachRequest(const runtime::AttachRequest &req, Errors &error) +int CRIRuntimeServiceImpl::ValidateAttachRequest(const runtime::v1alpha2::AttachRequest &req, Errors &error) { if (req.container_id().empty()) { error.SetError("missing required container id!"); @@ -1351,7 +1387,8 @@ int CRIRuntimeServiceImpl::ValidateAttachRequest(const runtime::AttachRequest &r return 0; } -void CRIRuntimeServiceImpl::Attach(const runtime::AttachRequest &req, runtime::AttachResponse *resp, Errors &error) +void CRIRuntimeServiceImpl::Attach(const runtime::v1alpha2::AttachRequest &req, runtime::v1alpha2::AttachResponse *resp, + Errors &error) { if (ValidateAttachRequest(req, error)) { return; @@ -1361,8 +1398,12 @@ void CRIRuntimeServiceImpl::Attach(const runtime::AttachRequest &req, runtime::A return; } RequestCache *cache = RequestCache::GetInstance(); - runtime::AttachRequest *attachReq = new runtime::AttachRequest(req); - std::string token = cache->Insert(const_cast(attachReq)); + runtime::v1alpha2::AttachRequest *attachReq = new (std::nothrow) runtime::v1alpha2::AttachRequest(req); + if (attachReq == nullptr) { + error.SetError("Out of memory"); + return; + } + std::string token = cache->Insert(const_cast(attachReq)); if (token.empty()) { error.SetError("failed to get a unique token!"); return; @@ -1411,4 +1452,3 @@ cleanup: free(perr); return inspect_data; } - diff --git a/src/services/cri/cri_helpers.cc b/src/services/cri/cri_helpers.cc index e8e2cc3..a760a96 100644 --- a/src/services/cri/cri_helpers.cc +++ b/src/services/cri/cri_helpers.cc @@ -49,13 +49,12 @@ const std::string Constants::POD_CHECKPOINT_KEY { "cri.sandbox.isulad.checkpoint const char *InternalLabelKeys[] = { CRIHelpers::Constants::CONTAINER_TYPE_LABEL_KEY.c_str(), CRIHelpers::Constants::CONTAINER_LOGPATH_LABEL_KEY.c_str(), - CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY.c_str(), - nullptr + CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY.c_str(), nullptr }; std::string GetDefaultSandboxImage(Errors &err) { - const std::string defaultPodSandboxImageName { "rnd-dockerhub.huawei.com/library/pause" }; + const std::string defaultPodSandboxImageName { "pause" }; const std::string defaultPodSandboxImageVersion { "3.0" }; std::string machine; struct utsname uts; @@ -266,20 +265,20 @@ int FiltersAddLabel(defs_filters *filters, const std::string &key, const std::st return FiltersAdd(filters, "label", key + "=" + value); } -runtime::ContainerState ContainerStatusToRuntime(Container_Status status) +runtime::v1alpha2::ContainerState ContainerStatusToRuntime(Container_Status status) { switch (status) { case CONTAINER_STATUS_CREATED: case CONTAINER_STATUS_STARTING: - return runtime::CONTAINER_CREATED; + return runtime::v1alpha2::CONTAINER_CREATED; case CONTAINER_STATUS_PAUSED: case CONTAINER_STATUS_RESTARTING: case CONTAINER_STATUS_RUNNING: - return runtime::CONTAINER_RUNNING; + return runtime::v1alpha2::CONTAINER_RUNNING; case CONTAINER_STATUS_STOPPED: - return runtime::CONTAINER_EXITED; + return runtime::v1alpha2::CONTAINER_EXITED; default: - return runtime::CONTAINER_UNKNOWN; + return runtime::v1alpha2::CONTAINER_UNKNOWN; } } @@ -303,8 +302,8 @@ char **StringVectorToCharArray(std::vector &path) imagetool_image *InspectImageByID(const std::string &imageID, Errors &err) { - oci_image_status_request *request { nullptr }; - oci_image_status_response *response { nullptr }; + im_status_request *request { nullptr }; + im_status_response *response { nullptr }; imagetool_image *image { nullptr }; if (imageID.empty()) { @@ -312,7 +311,7 @@ imagetool_image *InspectImageByID(const std::string &imageID, Errors &err) return nullptr; } - request = (oci_image_status_request *)util_common_calloc_s(sizeof(oci_image_status_request)); + request = (im_status_request *)util_common_calloc_s(sizeof(im_status_request)); if (request == nullptr) { ERROR("Out of memory"); err.SetError("Out of memory"); @@ -320,7 +319,7 @@ imagetool_image *InspectImageByID(const std::string &imageID, Errors &err) } request->image.image = util_strdup_s(imageID.c_str()); - if (oci_status_image(request, &response)) { + if (im_image_status(request, &response) != 0) { if (response != nullptr && response->errmsg != nullptr) { err.SetError(response->errmsg); } else { @@ -335,8 +334,8 @@ imagetool_image *InspectImageByID(const std::string &imageID, Errors &err) } cleanup: - free_oci_image_status_request(request); - free_oci_image_status_response(response); + free_im_status_request(request); + free_im_status_response(response); return image; } @@ -405,11 +404,14 @@ cri_pod_network_element **GetNetworkPlaneFromPodAnno(const google::protobuf::Map return result; } -std::unique_ptr CheckpointToSandbox(const std::string &id, - const cri::PodSandboxCheckpoint &checkpoint) +std::unique_ptr CheckpointToSandbox(const std::string &id, + const cri::PodSandboxCheckpoint &checkpoint) { - std::unique_ptr result(new runtime::PodSandbox); - runtime::PodSandboxMetadata *metadata = new (std::nothrow) runtime::PodSandboxMetadata; + std::unique_ptr result(new (std::nothrow) runtime::v1alpha2::PodSandbox); + if (result == nullptr) { + return nullptr; + } + runtime::v1alpha2::PodSandboxMetadata *metadata = new (std::nothrow) runtime::v1alpha2::PodSandboxMetadata; if (metadata == nullptr) { return nullptr; } @@ -418,13 +420,14 @@ std::unique_ptr CheckpointToSandbox(const std::string &id, metadata->set_namespace_(checkpoint.GetNamespace()); result->set_allocated_metadata(metadata); result->set_id(id); - result->set_state(runtime::SANDBOX_NOTREADY); + result->set_state(runtime::v1alpha2::SANDBOX_NOTREADY); return result; } -void UpdateCreateConfig(container_custom_config *createConfig, host_config *hc, const runtime::ContainerConfig &config, - const std::string &podSandboxID, Errors &error) +void UpdateCreateConfig(container_custom_config *createConfig, host_config *hc, + const runtime::v1alpha2::ContainerConfig &config, const std::string &podSandboxID, + Errors &error) { if (createConfig == nullptr || hc == nullptr) { return; @@ -437,7 +440,7 @@ void UpdateCreateConfig(container_custom_config *createConfig, host_config *hc, return; } if (config.linux().has_resources()) { - runtime::LinuxContainerResources rOpts = config.linux().resources(); + runtime::v1alpha2::LinuxContainerResources rOpts = config.linux().resources(); hc->memory = rOpts.memory_limit_in_bytes(); hc->memory_swap = CRIRuntimeService::Constants::DefaultMemorySwap; hc->cpu_shares = rOpts.cpu_shares(); @@ -456,8 +459,8 @@ void UpdateCreateConfig(container_custom_config *createConfig, host_config *hc, createConfig->tty = config.tty(); } -void GenerateMountBindings(const google::protobuf::RepeatedPtrField &mounts, host_config *hostconfig, - Errors &err) +void GenerateMountBindings(const google::protobuf::RepeatedPtrField &mounts, + host_config *hostconfig, Errors &err) { if (mounts.size() <= 0 || hostconfig == nullptr) { return; @@ -485,11 +488,11 @@ void GenerateMountBindings(const google::protobuf::RepeatedPtrField GenerateEnvList(const ::google::protobuf::RepeatedPtrField<::runtime::KeyValue> &envs) +std::vector GenerateEnvList( + const ::google::protobuf::RepeatedPtrField<::runtime::v1alpha2::KeyValue> &envs) { std::vector vect; - std::for_each(envs.begin(), envs.end(), [&vect](const ::runtime::KeyValue & elem) { + std::for_each(envs.begin(), envs.end(), [&vect](const ::runtime::v1alpha2::KeyValue & elem) { vect.push_back(elem.key() + "=" + elem.value()); }); return vect; @@ -531,13 +535,13 @@ err_out: return false; } -std::string ToIsuladContainerStatus(const runtime::ContainerStateValue &state) +std::string ToIsuladContainerStatus(const runtime::v1alpha2::ContainerStateValue &state) { - if (state.state() == runtime::CONTAINER_CREATED) { + if (state.state() == runtime::v1alpha2::CONTAINER_CREATED) { return "created"; - } else if (state.state() == runtime::CONTAINER_RUNNING) { + } else if (state.state() == runtime::v1alpha2::CONTAINER_RUNNING) { return "running"; - } else if (state.state() == runtime::CONTAINER_EXITED) { + } else if (state.state() == runtime::v1alpha2::CONTAINER_EXITED) { return "exited"; } else { return "unknown"; @@ -708,5 +712,8 @@ out: free_cri_checkpoint(criCheckpoint); } -} // namespace CRIHelpers - +std::string DeterminePodIPBySandboxID(const std::string &podSandboxID) +{ + return ""; +} +} // namespace CRIHelpers diff --git a/src/services/cri/cri_helpers.h b/src/services/cri/cri_helpers.h index 8ec0349..43281d2 100644 --- a/src/services/cri/cri_helpers.h +++ b/src/services/cri/cri_helpers.h @@ -24,12 +24,12 @@ #include "container_def.h" #include "host_config.h" #include "callback.h" -#include "oci_image_status.h" +#include "docker_seccomp.h" #include "cri_pod_network.h" #include "checkpoint_handler.h" +#include "image.h" namespace CRIHelpers { - class Constants { public: static const std::string DEFAULT_RUNTIME_NAME; @@ -68,7 +68,7 @@ int FiltersAddLabel(defs_filters *filters, const std::string &key, const std::st void ProtobufAnnoMapToStd(const google::protobuf::Map &annotations, std::map &newAnnos); -runtime::ContainerState ContainerStatusToRuntime(Container_Status status); +runtime::v1alpha2::ContainerState ContainerStatusToRuntime(Container_Status status); char **StringVectorToCharArray(std::vector &path); @@ -85,28 +85,32 @@ std::string sha256(const char *val); cri_pod_network_element **GetNetworkPlaneFromPodAnno(const google::protobuf::Map &annotations, size_t *len, Errors &error); -std::unique_ptr CheckpointToSandbox(const std::string &id, - const cri::PodSandboxCheckpoint &checkpoint); +std::unique_ptr CheckpointToSandbox(const std::string &id, + const cri::PodSandboxCheckpoint &checkpoint); std::string StringsJoin(const std::vector &vec, const std::string &sep); -void UpdateCreateConfig(container_custom_config *createConfig, host_config *hc, const runtime::ContainerConfig &config, - const std::string &podSandboxID, Errors &error); +void UpdateCreateConfig(container_custom_config *createConfig, host_config *hc, + const runtime::v1alpha2::ContainerConfig &config, const std::string &podSandboxID, + Errors &error); -void GenerateMountBindings(const google::protobuf::RepeatedPtrField &mounts, host_config *hostconfig, - Errors &err); +void GenerateMountBindings(const google::protobuf::RepeatedPtrField &mounts, + host_config *hostconfig, Errors &err); -std::vector GenerateEnvList(const ::google::protobuf::RepeatedPtrField<::runtime::KeyValue> &envs); +std::vector +GenerateEnvList(const ::google::protobuf::RepeatedPtrField<::runtime::v1alpha2::KeyValue> &envs); bool ValidateCheckpointKey(const std::string &key, Errors &error); -std::string ToIsuladContainerStatus(const runtime::ContainerStateValue &state); +std::string ToIsuladContainerStatus(const runtime::v1alpha2::ContainerStateValue &state); std::vector GetSecurityOpts(const std::string &seccompProfile, const char &separator, Errors &error); std::string CreateCheckpoint(cri::PodSandboxCheckpoint &checkpoint, Errors &error); void GetCheckpoint(const std::string &jsonCheckPoint, cri::PodSandboxCheckpoint &checkpoint, Errors &error); -}; // namespace CRIHelpers + +std::string DeterminePodIPBySandboxID(const std::string &podSandboxID); +}; // namespace CRIHelpers #endif /* _CRI_HELPERS_H_ */ diff --git a/src/services/cri/cri_image_service.cc b/src/services/cri/cri_image_service.cc index a06f2b7..992dce1 100644 --- a/src/services/cri/cri_image_service.cc +++ b/src/services/cri/cri_image_service.cc @@ -27,7 +27,7 @@ #include "utils.h" #include "cri_helpers.h" -static void conv_image_to_grpc(const imagetool_image *element, std::unique_ptr &image) +static void conv_image_to_grpc(const imagetool_image *element, std::unique_ptr &image) { if (element == nullptr) { return; @@ -52,7 +52,7 @@ static void conv_image_to_grpc(const imagetool_image *element, std::unique_ptrset_size(element->size); if (element->uid != nullptr) { - runtime::Int64Value *uid_value = new (std::nothrow) runtime::Int64Value; + runtime::v1alpha2::Int64Value *uid_value = new (std::nothrow) runtime::v1alpha2::Int64Value; if (uid_value == nullptr) { return; } @@ -67,8 +67,9 @@ static void conv_image_to_grpc(const imagetool_image *element, std::unique_ptr> *images, Errors &error) + std::vector> *images, + Errors &error) { imagetool_images_list *list_images = response->images; if (list_images == nullptr) { @@ -138,7 +140,11 @@ void CRIImageServiceImpl::list_images_to_grpc(im_list_response *response, } for (size_t i = 0; i < list_images->images_len; i++) { - std::unique_ptr image(new runtime::Image); + std::unique_ptr image(new (std::nothrow) runtime::v1alpha2::Image); + if (image == nullptr) { + error.SetError("Out of memory"); + return; + } imagetool_image *element = list_images->images[i]; conv_image_to_grpc(element, image); @@ -146,8 +152,8 @@ void CRIImageServiceImpl::list_images_to_grpc(im_list_response *response, } } -void CRIImageServiceImpl::ListImages(const runtime::ImageFilter &filter, - std::vector> *images, Errors &error) +void CRIImageServiceImpl::ListImages(const runtime::v1alpha2::ImageFilter &filter, + std::vector> *images, Errors &error) { im_list_request *request { nullptr }; im_list_response *response { nullptr }; @@ -176,11 +182,11 @@ cleanup: return; } -int CRIImageServiceImpl::status_request_from_grpc(const runtime::ImageSpec *image, oci_image_status_request **request, - Errors &error) +int CRIImageServiceImpl::status_request_from_grpc(const runtime::v1alpha2::ImageSpec *image, + im_status_request **request, Errors &error) { - oci_image_status_request *tmpreq = - (oci_image_status_request *)util_common_calloc_s(sizeof(oci_image_status_request)); + im_status_request *tmpreq = + (im_status_request *)util_common_calloc_s(sizeof(im_status_request)); if (tmpreq == nullptr) { ERROR("Out of memory"); error.SetError("Out of memory"); @@ -196,8 +202,8 @@ int CRIImageServiceImpl::status_request_from_grpc(const runtime::ImageSpec *imag return 0; } -std::unique_ptr CRIImageServiceImpl::status_image_to_grpc(oci_image_status_response *response, - Errors &error) +std::unique_ptr CRIImageServiceImpl::status_image_to_grpc(im_status_response *response, + Errors &error) { imagetool_image_status *image_info = response->image_info; if (image_info == nullptr) { @@ -209,24 +215,29 @@ std::unique_ptr CRIImageServiceImpl::status_image_to_grpc(oci_im return nullptr; } - std::unique_ptr image(new runtime::Image); + std::unique_ptr image(new (std::nothrow) runtime::v1alpha2::Image); + if (image == nullptr) { + ERROR("Out of memory"); + return nullptr; + } conv_image_to_grpc(element, image); return image; } -std::unique_ptr CRIImageServiceImpl::ImageStatus(const runtime::ImageSpec &image, Errors &error) +std::unique_ptr CRIImageServiceImpl::ImageStatus(const runtime::v1alpha2::ImageSpec &image, + Errors &error) { - oci_image_status_request *request { nullptr }; - oci_image_status_response *response { nullptr }; - std::unique_ptr out { nullptr }; + im_status_request *request { nullptr }; + im_status_response *response { nullptr }; + std::unique_ptr out { nullptr }; int ret = status_request_from_grpc(&image, &request, error); if (ret != 0) { goto cleanup; } - ret = oci_status_image(request, &response); + ret = im_image_status(request, &response); if (ret != 0) { if (response != nullptr && response->errmsg != nullptr) { error.SetError(response->errmsg); @@ -240,13 +251,13 @@ std::unique_ptr CRIImageServiceImpl::ImageStatus(const runtime:: cleanup: DAEMON_CLEAR_ERRMSG(); - free_oci_image_status_request(request); - free_oci_image_status_response(response); + free_im_status_request(request); + free_im_status_response(response); return out; } -std::string CRIImageServiceImpl::PullImage(const runtime::ImageSpec &image, const runtime::AuthConfig &auth, - Errors &error) +std::string CRIImageServiceImpl::PullImage(const runtime::v1alpha2::ImageSpec &image, + const runtime::v1alpha2::AuthConfig &auth, Errors &error) { std::string out_str { "" }; im_pull_request *request { nullptr }; @@ -256,9 +267,7 @@ std::string CRIImageServiceImpl::PullImage(const runtime::ImageSpec &image, cons if (ret != 0) { goto cleanup; } -#ifdef ENABLE_OCI_IMAGE request->type = util_strdup_s(IMAGE_TYPE_OCI); -#endif ret = im_pull_image(request, &response); if (ret != 0) { @@ -280,8 +289,8 @@ cleanup: return out_str; } -int CRIImageServiceImpl::remove_request_from_grpc(const runtime::ImageSpec *image, im_remove_request **request, - Errors &error) +int CRIImageServiceImpl::remove_request_from_grpc(const runtime::v1alpha2::ImageSpec *image, + im_remove_request **request, Errors &error) { im_remove_request *tmpreq = (im_remove_request *)util_common_calloc_s(sizeof(im_remove_request)); if (tmpreq == nullptr) { @@ -299,7 +308,7 @@ int CRIImageServiceImpl::remove_request_from_grpc(const runtime::ImageSpec *imag return 0; } -void CRIImageServiceImpl::RemoveImage(const runtime::ImageSpec &image, Errors &error) +void CRIImageServiceImpl::RemoveImage(const runtime::v1alpha2::ImageSpec &image, Errors &error) { std::string out_str { "" }; im_remove_request *request { nullptr }; @@ -324,8 +333,8 @@ cleanup: return; } -void CRIImageServiceImpl::fs_info_to_grpc(image_fs_info_response *response, - std::vector> *fs_infos, +void CRIImageServiceImpl::fs_info_to_grpc(im_fs_info_response *response, + std::vector> *fs_infos, Errors &error) { imagetool_fs_info *got_fs_info = response->fs_info; @@ -334,21 +343,32 @@ void CRIImageServiceImpl::fs_info_to_grpc(image_fs_info_response *response, } for (size_t i {}; i < got_fs_info->image_filesystems_len; i++) { - std::unique_ptr fs_info(new runtime::FilesystemUsage); + using FilesystemUsagePtr = std::unique_ptr; + FilesystemUsagePtr fs_info(new (std::nothrow) runtime::v1alpha2::FilesystemUsage); + if (fs_info == nullptr) { + ERROR("Out of memory"); + return; + } imagetool_fs_info_image_filesystems_element *element = got_fs_info->image_filesystems[i]; fs_info->set_timestamp(element->timestamp); if (element->fs_id != nullptr && element->fs_id->mountpoint != nullptr) { - runtime::StorageIdentifier *fs_id = new runtime::StorageIdentifier; - fs_id->set_uuid(element->fs_id->mountpoint); - fs_info->set_allocated_storage_id(fs_id); + runtime::v1alpha2::FilesystemIdentifier *fs_id = + new (std::nothrow)runtime::v1alpha2::FilesystemIdentifier; + if (fs_id == nullptr) { + ERROR("Out of memory"); + return; + } + fs_id->set_mountpoint(element->fs_id->mountpoint); + fs_info->set_allocated_fs_id(fs_id); } if (element->used_bytes != nullptr) { - runtime::UInt64Value *used_bytes = new (std::nothrow) runtime::UInt64Value; + runtime::v1alpha2::UInt64Value *used_bytes = new (std::nothrow) runtime::v1alpha2::UInt64Value; if (used_bytes == nullptr) { + ERROR("Out of memory"); return; } used_bytes->set_value(element->used_bytes->value); @@ -356,8 +376,9 @@ void CRIImageServiceImpl::fs_info_to_grpc(image_fs_info_response *response, } if (element->inodes_used != nullptr) { - runtime::UInt64Value *inodes_used = new (std::nothrow) runtime::UInt64Value; + runtime::v1alpha2::UInt64Value *inodes_used = new (std::nothrow) runtime::v1alpha2::UInt64Value; if (inodes_used == nullptr) { + ERROR("Out of memory"); return; } inodes_used->set_value(element->inodes_used->value); @@ -368,11 +389,12 @@ void CRIImageServiceImpl::fs_info_to_grpc(image_fs_info_response *response, } } -void CRIImageServiceImpl::ImageFsInfo(std::vector> *usages, Errors &error) +void CRIImageServiceImpl::ImageFsInfo(std::vector> *usages, + Errors &error) { - image_fs_info_response *response { nullptr }; + im_fs_info_response *response { nullptr }; - if (get_fs_info(&response)) { + if (im_get_filesystem_info(IMAGE_TYPE_OCI, &response)) { if (response != nullptr && response->errmsg != nullptr) { error.SetError(response->errmsg); } else { @@ -385,7 +407,6 @@ void CRIImageServiceImpl::ImageFsInfo(std::vector #include #include "cri_services.h" -#include "oci_image_pull.h" -#include "oci_image.h" -#include "oci_fs_info.h" #include "image.h" class CRIImageServiceImpl : public cri::ImageManagerService { @@ -32,35 +29,37 @@ public: CRIImageServiceImpl &operator=(const CRIImageServiceImpl &) = delete; virtual ~CRIImageServiceImpl() = default; - void ListImages(const runtime::ImageFilter &filter, std::vector> *images, - Errors &error) override; + void ListImages(const runtime::v1alpha2::ImageFilter &filter, + std::vector> *images, Errors &error) override; - std::unique_ptr ImageStatus(const runtime::ImageSpec &image, Errors &error) override; + std::unique_ptr ImageStatus(const runtime::v1alpha2::ImageSpec &image, + Errors &error) override; - std::string PullImage(const runtime::ImageSpec &image, const runtime::AuthConfig &auth, + std::string PullImage(const runtime::v1alpha2::ImageSpec &image, const runtime::v1alpha2::AuthConfig &auth, Errors &error) override; - void RemoveImage(const runtime::ImageSpec &image, Errors &error) override; + void RemoveImage(const runtime::v1alpha2::ImageSpec &image, Errors &error) override; - void ImageFsInfo(std::vector> *usages, Errors &error) override; + void ImageFsInfo(std::vector> *usages, Errors &error) override; private: - int pull_request_from_grpc(const runtime::ImageSpec *image, const runtime::AuthConfig *auth, + int pull_request_from_grpc(const runtime::v1alpha2::ImageSpec *image, const runtime::v1alpha2::AuthConfig *auth, im_pull_request **request, Errors &error); - int list_request_from_grpc(const runtime::ImageFilter *filter, im_list_request **request, Errors &error); + int list_request_from_grpc(const runtime::v1alpha2::ImageFilter *filter, im_list_request **request, Errors &error); - void list_images_to_grpc(im_list_response *response, std::vector> *images, + void list_images_to_grpc(im_list_response *response, std::vector> *images, Errors &error); - int status_request_from_grpc(const runtime::ImageSpec *image, oci_image_status_request **request, Errors &error); + int status_request_from_grpc(const runtime::v1alpha2::ImageSpec *image, im_status_request **request, + Errors &error); - std::unique_ptr status_image_to_grpc(oci_image_status_response *response, Errors &error); + std::unique_ptr status_image_to_grpc(im_status_response *response, Errors &error); - void fs_info_to_grpc(image_fs_info_response *response, - std::vector> *fs_infos, Errors &error); + void fs_info_to_grpc(im_fs_info_response *response, + std::vector> *fs_infos, Errors &error); - int remove_request_from_grpc(const runtime::ImageSpec *image, im_remove_request **request, Errors &error); + int remove_request_from_grpc(const runtime::v1alpha2::ImageSpec *image, im_remove_request **request, Errors &error); }; #endif /* _CRI_IMAGE_SERVICES_IMPL_H_ */ diff --git a/src/services/cri/cri_runtime_service.cc b/src/services/cri/cri_runtime_service.cc index 2babaa8..bcaa96c 100644 --- a/src/services/cri/cri_runtime_service.cc +++ b/src/services/cri/cri_runtime_service.cc @@ -40,7 +40,7 @@ std::string Constants::sandboxContainerName { "POD" }; std::string Constants::kubeAPIVersion { "0.1.0" }; std::string Constants::iSulaRuntimeName { "iSulad" }; std::string Constants::RESOLV_CONF_PATH { "/etc/resolv.conf" }; -} +} // namespace CRIRuntimeService CRIRuntimeServiceImpl::CRIRuntimeServiceImpl() { m_cb = get_service_callback(); @@ -50,7 +50,7 @@ CRIRuntimeServiceImpl::CRIRuntimeServiceImpl() } void CRIRuntimeServiceImpl::VersionResponseToGRPC(container_version_response *response, - runtime::VersionResponse *gResponse, Errors &error) + runtime::v1alpha2::VersionResponse *gResponse, Errors &error) { gResponse->set_version(CRIRuntimeService::Constants::kubeAPIVersion); gResponse->set_runtime_name(CRIRuntimeService::Constants::iSulaRuntimeName); @@ -83,7 +83,7 @@ void CRIRuntimeServiceImpl::Init(Network::NetworkPluginConf mConf, const std::st m_pluginManager = std::make_shared(chosen); } -void CRIRuntimeServiceImpl::Version(const std::string &apiVersion, runtime::VersionResponse *versionResponse, +void CRIRuntimeServiceImpl::Version(const std::string &apiVersion, runtime::v1alpha2::VersionResponse *versionResponse, Errors &error) { (void)apiVersion; @@ -108,7 +108,7 @@ cleanup: free_container_version_response(response); } -void CRIRuntimeServiceImpl::UpdateRuntimeConfig(const runtime::RuntimeConfig &config, Errors &error) +void CRIRuntimeServiceImpl::UpdateRuntimeConfig(const runtime::v1alpha2::RuntimeConfig &config, Errors &error) { const std::string NET_PLUGIN_EVENT_POD_CIDR_CHANGE { "pod-cidr-change" }; const std::string NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR { "pod-cidr" }; @@ -122,14 +122,18 @@ void CRIRuntimeServiceImpl::UpdateRuntimeConfig(const runtime::RuntimeConfig &co return; } -std::unique_ptr CRIRuntimeServiceImpl::Status(Errors &error) +std::unique_ptr CRIRuntimeServiceImpl::Status(Errors &error) { - std::unique_ptr status(new runtime::RuntimeStatus); + std::unique_ptr status(new (std::nothrow) runtime::v1alpha2::RuntimeStatus); + if (status == nullptr) { + error.SetError("Out of memory"); + return nullptr; + } - runtime::RuntimeCondition *runtimeReady = status->add_conditions(); + runtime::v1alpha2::RuntimeCondition *runtimeReady = status->add_conditions(); runtimeReady->set_type(CRIHelpers::Constants::RUNTIME_READY); runtimeReady->set_status(true); - runtime::RuntimeCondition *networkReady = status->add_conditions(); + runtime::v1alpha2::RuntimeCondition *networkReady = status->add_conditions(); networkReady->set_type(CRIHelpers::Constants::NETWORK_READY); networkReady->set_status(true); @@ -182,3 +186,4 @@ cleanup: free_container_inspect(inspect_data); return result; } + diff --git a/src/services/cri/cri_runtime_service.h b/src/services/cri/cri_runtime_service.h index ba7268d..ab00a0d 100644 --- a/src/services/cri/cri_runtime_service.h +++ b/src/services/cri/cri_runtime_service.h @@ -52,7 +52,7 @@ public: static std::string RESOLV_CONF_PATH; static constexpr int MAX_DNS_SEARCHES { 6 }; }; -} // namespace CRIRuntimeService +} // namespace CRIRuntimeService class CRIRuntimeServiceImpl : public cri::RuntimeManager, public cri::RuntimeVersioner, @@ -73,31 +73,31 @@ public: std::string GetNetNS(const std::string &podSandboxID, Errors &err); - void Version(const std::string &apiVersion, runtime::VersionResponse *versionResponse, + void Version(const std::string &apiVersion, runtime::v1alpha2::VersionResponse *versionResponse, Errors &error) override; - void UpdateRuntimeConfig(const runtime::RuntimeConfig &config, Errors &error) override; + void UpdateRuntimeConfig(const runtime::v1alpha2::RuntimeConfig &config, Errors &error) override; - std::unique_ptr Status(Errors &error) override; + std::unique_ptr Status(Errors &error) override; - std::string RunPodSandbox(const runtime::PodSandboxConfig &config, Errors &error) override; + std::string RunPodSandbox(const runtime::v1alpha2::PodSandboxConfig &config, Errors &error) override; void StopPodSandbox(const std::string &podSandboxID, Errors &error) override; void RemovePodSandbox(const std::string &podSandboxID, Errors &error) override; - std::unique_ptr PodSandboxStatus(const std::string &podSandboxID, - Errors &error) override; + std::unique_ptr PodSandboxStatus(const std::string &podSandboxID, + Errors &error) override; - void ListPodSandbox(const runtime::PodSandboxFilter *filter, - std::vector> *pods, Errors &error) override; + void ListPodSandbox(const runtime::v1alpha2::PodSandboxFilter *filter, + std::vector> *pods, Errors &error) override; - void PortForward(const runtime::PortForwardRequest &req, runtime::PortForwardResponse *resp, + void PortForward(const runtime::v1alpha2::PortForwardRequest &req, runtime::v1alpha2::PortForwardResponse *resp, Errors &error) override; std::string CreateContainer(const std::string &podSandboxID, - const runtime::ContainerConfig &containerConfig, - const runtime::PodSandboxConfig &podSandboxConfig, Errors &error) override; + const runtime::v1alpha2::ContainerConfig &containerConfig, + const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, Errors &error) override; void StartContainer(const std::string &containerID, Errors &error) override; @@ -105,67 +105,69 @@ public: void RemoveContainer(const std::string &containerID, Errors &error) override; - void ListContainers(const runtime::ContainerFilter *filter, - std::vector> *containers, Errors &error) override; + void ListContainers(const runtime::v1alpha2::ContainerFilter *filter, + std::vector> *containers, Errors &error) override; - void ListContainerStats(const runtime::ContainerStatsFilter *filter, - std::vector> *containerstats, + void ListContainerStats(const runtime::v1alpha2::ContainerStatsFilter *filter, + std::vector> *containerstats, Errors &error) override; - std::unique_ptr ContainerStatus(const std::string &containerID, - Errors &error) override; + std::unique_ptr ContainerStatus(const std::string &containerID, + Errors &error) override; void UpdateContainerResources(const std::string &containerID, - const runtime::LinuxContainerResources &resources, Errors &error) override; + const runtime::v1alpha2::LinuxContainerResources &resources, Errors &error) override; void ExecSync(const std::string &containerID, const google::protobuf::RepeatedPtrField &cmd, - int64_t timeout, runtime::ExecSyncResponse *reply, Errors &error) override; + int64_t timeout, runtime::v1alpha2::ExecSyncResponse *reply, Errors &error) override; - void Exec(const runtime::ExecRequest &req, runtime::ExecResponse *resp, Errors &error) override; + void Exec(const runtime::v1alpha2::ExecRequest &req, runtime::v1alpha2::ExecResponse *resp, Errors &error) override; - void Attach(const runtime::AttachRequest &req, runtime::AttachResponse *resp, Errors &error) override; + void Attach(const runtime::v1alpha2::AttachRequest &req, runtime::v1alpha2::AttachResponse *resp, + Errors &error) override; private: - void VersionResponseToGRPC(container_version_response *response, runtime::VersionResponse *gResponse, + void VersionResponseToGRPC(container_version_response *response, runtime::v1alpha2::VersionResponse *gResponse, Errors &error); bool IsDefaultNetworkPlane(cri_pod_network_element *network); void SetSandboxStatusNetwork(container_inspect *inspect, const std::string &podSandboxID, - std::unique_ptr &podStatus, Errors &error); + std::unique_ptr &podStatus, Errors &error); void PodSandboxStatusToGRPC(container_inspect *inspect, const std::string &podSandboxID, - std::unique_ptr &podStatus, Errors &error); + std::unique_ptr &podStatus, Errors &error); void ListPodSandboxToGRPC(container_list_response *response, - std::vector> *pods, bool filterOutReadySandboxes, - Errors &error); + std::vector> *pods, + bool filterOutReadySandboxes, Errors &error); - void ListContainersToGRPC(container_list_response *response, std::vector> *pods, - Errors &error); + void ListContainersToGRPC(container_list_response *response, + std::vector> *pods, Errors &error); void ContainerStatsToGRPC(container_stats_response *response, - std::vector> *pods, Errors &error); + std::vector> *pods, Errors &error); - void ContainerStatusToGRPC(container_inspect *inspect, std::unique_ptr &contStatus, - Errors &error); + void ContainerStatusToGRPC(container_inspect *inspect, + std::unique_ptr &contStatus, Errors &error); void ExecSyncFromGRPC(const std::string &containerID, const google::protobuf::RepeatedPtrField &cmd, int64_t timeout, container_exec_request **request, Errors &error); - void ListContainersFromGRPC(const runtime::ContainerFilter *filter, container_list_request **request, + void ListContainersFromGRPC(const runtime::v1alpha2::ContainerFilter *filter, container_list_request **request, Errors &error); - void ListPodSandboxFromGRPC(const runtime::PodSandboxFilter *filter, container_list_request **request, + void ListPodSandboxFromGRPC(const runtime::v1alpha2::PodSandboxFilter *filter, container_list_request **request, bool *filterOutReadySandboxes, Errors &error); - void ApplySandboxResources(const runtime::LinuxPodSandboxConfig *lc, host_config *hc, Errors &error); + void ApplySandboxResources(const runtime::v1alpha2::LinuxPodSandboxConfig *lc, host_config *hc, Errors &error); - void ApplySandboxLinuxOptions(const runtime::LinuxPodSandboxConfig &lc, host_config *hc, + void ApplySandboxLinuxOptions(const runtime::v1alpha2::LinuxPodSandboxConfig &lc, host_config *hc, container_custom_config *custom_config, Errors &error); - void MakeSandboxIsuladConfig(const runtime::PodSandboxConfig &c, host_config *hc, + void MakeSandboxIsuladConfig(const runtime::v1alpha2::PodSandboxConfig &c, host_config *hc, container_custom_config *custom_config, Errors &error); - void MakeContainerConfig(const runtime::ContainerConfig &config, container_custom_config *cConfig, Errors &error); + void MakeContainerConfig(const runtime::v1alpha2::ContainerConfig &config, container_custom_config *cConfig, + Errors &error); void GetContainerLogPath(const std::string &containerID, char **path, char **realPath, Errors &error); @@ -173,28 +175,30 @@ private: void RemoveContainerLogSymlink(const std::string &containerID, Errors &error); - std::string MakeSandboxName(const runtime::PodSandboxMetadata &metadata); + std::string MakeSandboxName(const runtime::v1alpha2::PodSandboxMetadata &metadata); - std::string MakeContainerName(const runtime::PodSandboxConfig &s, const runtime::ContainerConfig &c); + std::string MakeContainerName(const runtime::v1alpha2::PodSandboxConfig &s, + const runtime::v1alpha2::ContainerConfig &c); - void modifyContainerNamespaceOptions(bool hasOpts, const runtime::NamespaceOption &nsOpts, const char *ID, + void modifyContainerNamespaceOptions(bool hasOpts, const runtime::v1alpha2::NamespaceOption &nsOpts, const char *ID, host_config *hconf, Errors &err); - bool SharesHostNetwork(container_inspect *inspect); - bool SharesHostPid(container_inspect *inspect); - bool SharesHostIpc(container_inspect *inspect); + runtime::v1alpha2::NamespaceMode SharesHostNetwork(container_inspect *inspect); + runtime::v1alpha2::NamespaceMode SharesHostPid(container_inspect *inspect); + runtime::v1alpha2::NamespaceMode SharesHostIpc(container_inspect *inspect); void GetContainerTimeStamps(container_inspect *inspect, int64_t *createdAt, int64_t *startedAt, int64_t *finishedAt, Errors &err); - int ValidateExecRequest(const runtime::ExecRequest &req, Errors &error); + int ValidateExecRequest(const runtime::v1alpha2::ExecRequest &req, Errors &error); std::string BuildURL(const std::string &method, const std::string &token); - int ValidateAttachRequest(const runtime::AttachRequest &req, Errors &error); + int ValidateAttachRequest(const runtime::v1alpha2::AttachRequest &req, Errors &error); - std::string ParseCheckpointProtocol(runtime::Protocol protocol); + std::string ParseCheckpointProtocol(runtime::v1alpha2::Protocol protocol); - void ConstructPodSandboxCheckpoint(const runtime::PodSandboxConfig &config, cri::PodSandboxCheckpoint &checkpoint); + void ConstructPodSandboxCheckpoint(const runtime::v1alpha2::PodSandboxConfig &config, + cri::PodSandboxCheckpoint &checkpoint); std::string GetIP(const std::string &podSandboxID, container_inspect *inspect, const std::string &networkInterface, Errors &error); @@ -204,39 +208,43 @@ private: void ClearNetworkReady(const std::string &podSandboxID); bool EnsureSandboxImageExists(const std::string &image, Errors &error); void StopContainerHelper(const std::string &containerID, Errors &error); - void SetupSandboxFiles(const std::string &podID, const runtime::PodSandboxConfig &config, Errors &error); - container_create_request *GenerateCreateContainerRequest(const std::string &realPodSandboxID, - const runtime::ContainerConfig &containerConfig, - const runtime::PodSandboxConfig &podSandboxConfig, - Errors &error); - host_config *GenerateCreateContainerHostConfig(const runtime::ContainerConfig &containerConfig, Errors &error); - int PackCreateContainerHostConfigSecurityContext(const runtime::ContainerConfig &containerConfig, + void SetupSandboxFiles(const std::string &podID, const runtime::v1alpha2::PodSandboxConfig &config, Errors &error); + container_create_request * + GenerateCreateContainerRequest(const std::string &realPodSandboxID, + const runtime::v1alpha2::ContainerConfig &containerConfig, + const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, Errors &error); + host_config *GenerateCreateContainerHostConfig(const runtime::v1alpha2::ContainerConfig &containerConfig, + Errors &error); + int PackCreateContainerHostConfigSecurityContext(const runtime::v1alpha2::ContainerConfig &containerConfig, host_config *hostconfig, Errors &error); - int PackCreateContainerHostConfigDevices(const runtime::ContainerConfig &containerConfig, host_config *hostconfig, - Errors &error); - container_custom_config *GenerateCreateContainerCustomConfig(const std::string &realPodSandboxID, - const runtime::ContainerConfig &containerConfig, - const runtime::PodSandboxConfig &podSandboxConfig, - Errors &error); - int PackContainerImageToStatus(container_inspect *inspect, std::unique_ptr &contStatus, - Errors &error); + int PackCreateContainerHostConfigDevices(const runtime::v1alpha2::ContainerConfig &containerConfig, + host_config *hostconfig, Errors &error); + container_custom_config * + GenerateCreateContainerCustomConfig(const std::string &realPodSandboxID, + const runtime::v1alpha2::ContainerConfig &containerConfig, + const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, Errors &error); + int PackContainerImageToStatus(container_inspect *inspect, + std::unique_ptr &contStatus, Errors &error); void UpdateBaseStatusFromInspect(container_inspect *inspect, int64_t &createdAt, int64_t &startedAt, - int64_t &finishedAt, std::unique_ptr &contStatus); - void PackLabelsToStatus(container_inspect *inspect, std::unique_ptr &contStatus); - void ConvertMountsToStatus(container_inspect *inspect, std::unique_ptr &contStatus); + int64_t &finishedAt, + std::unique_ptr &contStatus); + void PackLabelsToStatus(container_inspect *inspect, + std::unique_ptr &contStatus); + void ConvertMountsToStatus(container_inspect *inspect, + std::unique_ptr &contStatus); - void SetupSandboxNetwork(const runtime::PodSandboxConfig &config, const std::string &response_id, + void SetupSandboxNetwork(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &response_id, const std::string &jsonCheckpoint, Errors &error); - void SetupUserDefinedNetworkPlane(const runtime::PodSandboxConfig &config, const std::string &response_id, + void SetupUserDefinedNetworkPlane(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &response_id, container_inspect *inspect_data, std::map &stdAnnos, Errors &error); void StartSandboxContainer(const std::string &response_id, Errors &error); - std::string CreateSandboxContainer(const runtime::PodSandboxConfig &config, const std::string &image, + std::string CreateSandboxContainer(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &image, std::string &jsonCheckpoint, Errors &error); - container_create_request *GenerateSandboxCreateContainerRequest(const runtime::PodSandboxConfig &config, + container_create_request *GenerateSandboxCreateContainerRequest(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &image, std::string &jsonCheckpoint, Errors &error); - container_create_request *PackCreateContainerRequest(const runtime::PodSandboxConfig &config, + container_create_request *PackCreateContainerRequest(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &image, host_config *hostconfig, container_custom_config *custom_config, Errors &error); int GetRealSandboxIDToStop(const std::string &podSandboxID, bool &hostNetwork, std::string &name, std::string &ns, @@ -250,6 +258,10 @@ private: std::map &stdAnnos, Errors &error); int RemoveAllContainersInSandbox(const std::string &realSandboxID, std::vector &errors); int DoRemovePodSandbox(const std::string &realSandboxID, std::vector &errors); + void MergeSecurityContextToHostConfig(const runtime::v1alpha2::PodSandboxConfig &c, + host_config *hc, Errors &error); + int PackContainerStatsFilter(const runtime::v1alpha2::ContainerStatsFilter *filter, + container_stats_request *request, Errors &error); private: service_callback_t *m_cb { nullptr }; diff --git a/src/services/cri/cri_sandbox.cc b/src/services/cri/cri_sandbox.cc index e7c2fae..0428b06 100644 --- a/src/services/cri/cri_sandbox.cc +++ b/src/services/cri/cri_sandbox.cc @@ -35,38 +35,50 @@ #include "container_custom_config.h" #include "checkpoint_handler.h" #include "cri_security_context.h" +#include "cxxutils.h" -bool CRIRuntimeServiceImpl::SharesHostNetwork(container_inspect *inspect) +runtime::v1alpha2::NamespaceMode CRIRuntimeServiceImpl::SharesHostNetwork(container_inspect *inspect) { - if (inspect != nullptr && inspect->host_config != nullptr && inspect->host_config->network_mode) { - return strcmp(inspect->host_config->network_mode, CRIRuntimeService::Constants::namespaceModeHost.c_str()) == 0; + if (inspect != nullptr && inspect->host_config != nullptr && inspect->host_config->network_mode && + std::string(inspect->host_config->network_mode) == CRIRuntimeService::Constants::namespaceModeHost) { + return runtime::v1alpha2::NamespaceMode::NODE; } - return false; + return runtime::v1alpha2::NamespaceMode::POD; } -bool CRIRuntimeServiceImpl::SharesHostPid(container_inspect *inspect) +runtime::v1alpha2::NamespaceMode CRIRuntimeServiceImpl::SharesHostPid(container_inspect *inspect) { - if (inspect != nullptr && inspect->host_config != nullptr && inspect->host_config->pid_mode) { - return strcmp(inspect->host_config->pid_mode, CRIRuntimeService::Constants::namespaceModeHost.c_str()) == 0; + if (inspect != nullptr && inspect->host_config != nullptr && inspect->host_config->pid_mode && + std::string(inspect->host_config->pid_mode) == CRIRuntimeService::Constants::namespaceModeHost) { + return runtime::v1alpha2::NamespaceMode::NODE; } - return false; + return runtime::v1alpha2::NamespaceMode::CONTAINER; } -bool CRIRuntimeServiceImpl::SharesHostIpc(container_inspect *inspect) +runtime::v1alpha2::NamespaceMode CRIRuntimeServiceImpl::SharesHostIpc(container_inspect *inspect) { - if (inspect != nullptr && inspect->host_config != nullptr && inspect->host_config->ipc_mode) { - return strcmp(inspect->host_config->ipc_mode, CRIRuntimeService::Constants::namespaceModeHost.c_str()) == 0; + if (inspect != nullptr && inspect->host_config != nullptr && inspect->host_config->ipc_mode && + std::string(inspect->host_config->ipc_mode) == CRIRuntimeService::Constants::namespaceModeHost) { + return runtime::v1alpha2::NamespaceMode::NODE; } - return false; + return runtime::v1alpha2::NamespaceMode::POD; } bool CRIRuntimeServiceImpl::EnsureSandboxImageExists(const std::string &image, Errors &error) { - runtime::ImageSpec imageRef; - runtime::AuthConfig auth; + runtime::v1alpha2::ImageSpec imageRef; + runtime::v1alpha2::AuthConfig auth; + runtime::v1alpha2::ImageSpec imageSpec; + Errors err; + + imageSpec.set_image(image); + std::unique_ptr imageStatus = rImageService.ImageStatus(imageSpec, err); + if (err.Empty()) { + return true; + } + imageStatus.reset(); imageRef.set_image(image); - std::string outRef = rImageService.PullImage(imageRef, auth, error); if (!error.Empty() || outRef.empty()) { return false; @@ -75,18 +87,18 @@ bool CRIRuntimeServiceImpl::EnsureSandboxImageExists(const std::string &image, E return true; } -std::string CRIRuntimeServiceImpl::ParseCheckpointProtocol(runtime::Protocol protocol) +std::string CRIRuntimeServiceImpl::ParseCheckpointProtocol(runtime::v1alpha2::Protocol protocol) { switch (protocol) { - case runtime::UDP: + case runtime::v1alpha2::UDP: return "udp"; - case runtime::TCP: + case runtime::v1alpha2::TCP: default: return "tcp"; } } -void CRIRuntimeServiceImpl::ConstructPodSandboxCheckpoint(const runtime::PodSandboxConfig &config, +void CRIRuntimeServiceImpl::ConstructPodSandboxCheckpoint(const runtime::v1alpha2::PodSandboxConfig &config, cri::PodSandboxCheckpoint &checkpoint) { checkpoint.SetName(config.metadata().name()); @@ -97,25 +109,27 @@ void CRIRuntimeServiceImpl::ConstructPodSandboxCheckpoint(const runtime::PodSand for (int i = 0; i < len; i++) { cri::PortMapping item; - runtime::PortMapping iter = config.port_mappings(i); + runtime::v1alpha2::PortMapping iter = config.port_mappings(i); item.SetProtocol(ParseCheckpointProtocol(iter.protocol())); item.SetContainerPort(iter.container_port()); item.SetHostPort(iter.host_port()); (checkpoint.GetData())->InsertPortMapping(item); } - - (checkpoint.GetData())->SetHostNetwork(config.linux().security_context().namespace_options().host_network()); + if (config.linux().security_context().namespace_options().network() == runtime::v1alpha2::NamespaceMode::NODE) { + (checkpoint.GetData())->SetHostNetwork(true); + } } -void CRIRuntimeServiceImpl::ApplySandboxResources(const runtime::LinuxPodSandboxConfig *lc, host_config *hc, +void CRIRuntimeServiceImpl::ApplySandboxResources(const runtime::v1alpha2::LinuxPodSandboxConfig *lc, host_config *hc, Errors &error) { hc->memory_swap = CRIRuntimeService::Constants::DefaultMemorySwap; hc->cpu_shares = CRIRuntimeService::Constants::DefaultSandboxCPUshares; } -void CRIRuntimeServiceImpl::ApplySandboxLinuxOptions(const runtime::LinuxPodSandboxConfig &lc, host_config *hc, - container_custom_config *custom_config, Errors &error) +void CRIRuntimeServiceImpl::ApplySandboxLinuxOptions(const runtime::v1alpha2::LinuxPodSandboxConfig &lc, + host_config *hc, container_custom_config *custom_config, + Errors &error) { CRISecurity::ApplySandboxSecurityContext(lc, custom_config, hc, error); if (error.NotEmpty()) { @@ -150,7 +164,44 @@ void CRIRuntimeServiceImpl::ApplySandboxLinuxOptions(const runtime::LinuxPodSand } } -void CRIRuntimeServiceImpl::MakeSandboxIsuladConfig(const runtime::PodSandboxConfig &c, host_config *hc, +void CRIRuntimeServiceImpl::MergeSecurityContextToHostConfig(const runtime::v1alpha2::PodSandboxConfig &c, + host_config *hc, Errors &error) +{ + // Security Opts + if (!c.linux().has_security_context()) { + return; + } + + const char securityOptSep = '='; + std::vector securityOpts = + CRIHelpers::GetSecurityOpts(c.linux().security_context().seccomp_profile_path(), securityOptSep, error); + if (error.NotEmpty()) { + error.Errorf("failed to generate security options for sandbox %s", c.metadata().name().c_str()); + return; + } + if (securityOpts.size() > 0) { + char **tmp_security_opt = nullptr; + + if (securityOpts.size() > (SIZE_MAX / sizeof(char *)) - hc->security_opt_len) { + error.Errorf("Out of memory"); + return; + } + size_t newSize = (hc->security_opt_len + securityOpts.size()) * sizeof(char *); + size_t oldSize = hc->security_opt_len * sizeof(char *); + int ret = mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hc->security_opt, oldSize); + if (ret != 0) { + error.Errorf("Out of memory"); + return; + } + hc->security_opt = tmp_security_opt; + for (size_t i = 0; i < securityOpts.size(); i++) { + hc->security_opt[hc->security_opt_len] = util_strdup_s(securityOpts[i].c_str()); + hc->security_opt_len++; + } + } +} + +void CRIRuntimeServiceImpl::MakeSandboxIsuladConfig(const runtime::v1alpha2::PodSandboxConfig &c, host_config *hc, container_custom_config *custom_config, Errors &error) { custom_config->labels = CRIHelpers::MakeLabels(c.labels(), error); @@ -219,8 +270,8 @@ void CRIRuntimeServiceImpl::MakeSandboxIsuladConfig(const runtime::PodSandboxCon } } -void CRIRuntimeServiceImpl::SetupSandboxFiles(const std::string &resolvPath, const runtime::PodSandboxConfig &config, - Errors &error) +void CRIRuntimeServiceImpl::SetupSandboxFiles(const std::string &resolvPath, + const runtime::v1alpha2::PodSandboxConfig &config, Errors &error) { if (resolvPath.empty()) { return; @@ -259,11 +310,10 @@ void CRIRuntimeServiceImpl::SetupSandboxFiles(const std::string &resolvPath, con } } -container_create_request *CRIRuntimeServiceImpl::PackCreateContainerRequest(const runtime::PodSandboxConfig &config, - const std::string &image, - host_config *hostconfig, - container_custom_config *custom_config, - Errors &error) +container_create_request *CRIRuntimeServiceImpl::PackCreateContainerRequest( + const runtime::v1alpha2::PodSandboxConfig &config, + const std::string &image, host_config *hostconfig, + container_custom_config *custom_config, Errors &error) { struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 }; parser_error perror = nullptr; @@ -299,7 +349,9 @@ error_out: } container_create_request *CRIRuntimeServiceImpl::GenerateSandboxCreateContainerRequest( - const runtime::PodSandboxConfig &config, const std::string &image, std::string &jsonCheckpoint, Errors &error) + const runtime::v1alpha2::PodSandboxConfig &config, + const std::string &image, std::string &jsonCheckpoint, + Errors &error) { container_create_request *create_request = nullptr; host_config *hostconfig = nullptr; @@ -355,7 +407,7 @@ cleanup: return create_request; } -std::string CRIRuntimeServiceImpl::CreateSandboxContainer(const runtime::PodSandboxConfig &config, +std::string CRIRuntimeServiceImpl::CreateSandboxContainer(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &image, std::string &jsonCheckpoint, Errors &error) { @@ -404,7 +456,7 @@ void CRIRuntimeServiceImpl::StartSandboxContainer(const std::string &response_id free_container_start_response(start_response); } -void CRIRuntimeServiceImpl::SetupUserDefinedNetworkPlane(const runtime::PodSandboxConfig &config, +void CRIRuntimeServiceImpl::SetupUserDefinedNetworkPlane(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &response_id, container_inspect *inspect_data, std::map &stdAnnos, Errors &error) @@ -441,8 +493,9 @@ cleanup: free_cri_pod_network(networks, len); } -void CRIRuntimeServiceImpl::SetupSandboxNetwork(const runtime::PodSandboxConfig &config, const std::string &response_id, - const std::string &jsonCheckpoint, Errors &error) +void CRIRuntimeServiceImpl::SetupSandboxNetwork(const runtime::v1alpha2::PodSandboxConfig &config, + const std::string &response_id, const std::string &jsonCheckpoint, + Errors &error) { std::map stdAnnos; container_inspect *inspect_data = InspectContainer(response_id, error); @@ -460,7 +513,7 @@ void CRIRuntimeServiceImpl::SetupSandboxNetwork(const runtime::PodSandboxConfig } } // Do not invoke network plugins if in hostNetwork mode. - if (config.linux().security_context().namespace_options().host_network()) { + if (config.linux().security_context().namespace_options().network() == runtime::v1alpha2::NamespaceMode::NODE) { goto cleanup; } @@ -468,8 +521,8 @@ void CRIRuntimeServiceImpl::SetupSandboxNetwork(const runtime::PodSandboxConfig CRIHelpers::ProtobufAnnoMapToStd(config.annotations(), stdAnnos); stdAnnos[CRIHelpers::Constants::POD_CHECKPOINT_KEY] = jsonCheckpoint; m_pluginManager->SetUpPod(config.metadata().namespace_(), config.metadata().name(), - Network::DEFAULT_NETWORK_PLANE_NAME, Network::DEFAULT_NETWORK_INTERFACE_NAME, - response_id, stdAnnos, error); + Network::DEFAULT_NETWORK_PLANE_NAME, Network::DEFAULT_NETWORK_INTERFACE_NAME, response_id, + stdAnnos, error); if (error.NotEmpty()) { ERROR("SetupPod failed: %s", error.GetCMessage()); StopContainerHelper(response_id, error); @@ -487,7 +540,7 @@ cleanup: free_container_inspect(inspect_data); } -std::string CRIRuntimeServiceImpl::RunPodSandbox(const runtime::PodSandboxConfig &config, Errors &error) +std::string CRIRuntimeServiceImpl::RunPodSandbox(const runtime::v1alpha2::PodSandboxConfig &config, Errors &error) { std::string response_id; std::string jsonCheckpoint; @@ -546,7 +599,7 @@ int CRIRuntimeServiceImpl::GetRealSandboxIDToStop(const std::string &podSandboxI auto status = PodSandboxStatus(podSandboxID, statusErr); if (statusErr.Empty()) { if (status->linux().namespaces().has_options()) { - hostNetwork = status->linux().namespaces().options().host_network(); + hostNetwork = (status->linux().namespaces().options().network() == runtime::v1alpha2::NamespaceMode::NODE); } if (status->has_metadata()) { name = status->metadata().name(); @@ -597,8 +650,8 @@ int CRIRuntimeServiceImpl::StopAllContainersInSandbox(const std::string &realSan } // Add sandbox label - if (CRIHelpers::FiltersAddLabel(list_request->filters, - CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY, realSandboxID) != 0) { + if (CRIHelpers::FiltersAddLabel(list_request->filters, CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY, + realSandboxID) != 0) { error.SetError("Failed to add label"); ret = -1; goto cleanup; @@ -719,6 +772,7 @@ void CRIRuntimeServiceImpl::StopPodSandbox(const std::string &podSandboxID, Erro error.SetError("Invalid empty sandbox id."); return; } + if (GetRealSandboxIDToStop(podSandboxID, hostNetwork, name, ns, realSandboxID, stdAnnos, error)) { return; } @@ -910,47 +964,83 @@ bool CRIRuntimeServiceImpl::IsDefaultNetworkPlane(cri_pod_network_element *netwo } void CRIRuntimeServiceImpl::SetSandboxStatusNetwork(container_inspect *inspect, const std::string &podSandboxID, - std::unique_ptr &podStatus, + std::unique_ptr &podStatus, Errors &error) { - runtime::PodSandboxNetworkStatus *network = podStatus->add_networks(); - std::string ipAddress = GetIP(podSandboxID, inspect, "", error); + if (podStatus->annotations_size() == 0) { + return; + } + std::vector ipInfo; + std::string IP; + size_t len = 0; + auto networks = CRIHelpers::GetNetworkPlaneFromPodAnno(*podStatus->mutable_annotations(), &len, error); if (error.NotEmpty()) { - WARN("get default ip failed: %s", error.GetCMessage()); - error.Clear(); + ERROR("Couldn't get network plane from pod annotations: %s", error.GetCMessage()); + return; } - INFO("get default net ip: %s", ipAddress.c_str()); - network->set_name(Network::DEFAULT_NETWORK_INTERFACE_NAME); - network->set_network(Network::DEFAULT_NETWORK_PLANE_NAME); - network->set_ip(ipAddress); - if (podStatus->annotations_size() > 0) { - size_t len = 0; - auto networks = CRIHelpers::GetNetworkPlaneFromPodAnno(*podStatus->mutable_annotations(), &len, error); + bool isDefaultNetDisable = false; + for (size_t i = 0; i < len; i++) { + if (networks[i]->name == nullptr) { + ERROR("Invalid network config, do not have name"); + error.SetError("Invalid networks config"); + goto free_out; + } + if (std::string(networks[i]->name) == Network::POD_DISABLE_DEFAULT_NET_ANNOTATION_KEY) { + isDefaultNetDisable = true; + } + } + + IP = CRIHelpers::DeterminePodIPBySandboxID(podSandboxID); + if (IP.empty() && !isDefaultNetDisable) { + if (len > SIZE_MAX / sizeof(cri_pod_network_element *) - 1) { + ERROR("Too many cri pod network elements!"); + goto free_out; + } + size_t new_size = (len + 1) * sizeof(cri_pod_network_element *); + size_t old_size = len * sizeof(cri_pod_network_element *); + cri_pod_network_element **new_networks; + if (mem_realloc((void **)(&new_networks), new_size, (void *)networks, old_size) != 0) { + ERROR("Failed to realloc memory for append cri pod network element"); + goto free_out; + } + networks = new_networks; + cri_pod_network_element *new_element = + (cri_pod_network_element *)util_common_calloc_s(sizeof(cri_pod_network_element)); + if (new_element == NULL) { + ERROR("Out of memory"); + goto free_out; + } + new_element->interface = util_strdup_s(Network::GetInterfaceName().c_str()); + networks[len] = new_element; + len++; + } + + for (size_t i = 0; i < len; i++) { + std::string iterfaceName { networks[i]->interface != nullptr ? networks[i]->interface : "" }; + std::string interfaceIP = GetIP(podSandboxID, inspect, iterfaceName, error); if (error.NotEmpty()) { - ERROR("Couldn't get network plane from pod annotations: %s", error.GetCMessage()); - return; + WARN("get default ip failed: %s", error.GetCMessage()); + error.Clear(); } - for (size_t i = 0; i < len; i++) { - if (IsDefaultNetworkPlane(networks[i])) { - network = podStatus->add_networks(); - std::string ip = GetIP(podSandboxID, inspect, networks[i]->interface, error); - network->set_name(networks[i]->interface); - network->set_network(networks[i]->name); - network->set_ip(ip); - INFO("get %s net ip: %s", networks[i]->name, ip.c_str()); - } - free_cri_pod_network_element(networks[i]); - networks[i] = nullptr; - } - free(networks); + ipInfo.push_back(iterfaceName + ":" + interfaceIP); } + podStatus->mutable_network()->set_ip(CXXUtils::StringsJoin(ipInfo, ";")); + +free_out: + for (size_t i = 0; i < len; i++) { + free_cri_pod_network_element(networks[i]); + networks[i] = nullptr; + } + + free(networks); } void CRIRuntimeServiceImpl::PodSandboxStatusToGRPC(container_inspect *inspect, const std::string &podSandboxID, - std::unique_ptr &podStatus, Errors &error) + std::unique_ptr &podStatus, + Errors &error) { int64_t createdAt {}; - runtime::NamespaceOption *options { nullptr }; + runtime::v1alpha2::NamespaceOption *options { nullptr }; if (inspect->id) { podStatus->set_id(inspect->id); @@ -963,9 +1053,9 @@ void CRIRuntimeServiceImpl::PodSandboxStatusToGRPC(container_inspect *inspect, c podStatus->set_created_at(createdAt); if (inspect->state && inspect->state->running) { - podStatus->set_state(runtime::SANDBOX_READY); + podStatus->set_state(runtime::v1alpha2::SANDBOX_READY); } else { - podStatus->set_state(runtime::SANDBOX_NOTREADY); + podStatus->set_state(runtime::v1alpha2::SANDBOX_NOTREADY); } if (inspect->config) { @@ -974,14 +1064,15 @@ void CRIRuntimeServiceImpl::PodSandboxStatusToGRPC(container_inspect *inspect, c } options = podStatus->mutable_linux()->mutable_namespaces()->mutable_options(); - options->set_host_network(SharesHostNetwork(inspect)); - options->set_host_pid(SharesHostPid(inspect)); - options->set_host_ipc(SharesHostIpc(inspect)); + options->set_network(SharesHostNetwork(inspect)); + options->set_pid(SharesHostPid(inspect)); + options->set_ipc(SharesHostIpc(inspect)); // add networks // get default network status SetSandboxStatusNetwork(inspect, podSandboxID, podStatus, error); if (error.NotEmpty()) { + ERROR("Set network status failed: %s", error.GetCMessage()); return; } @@ -1001,7 +1092,7 @@ std::string CRIRuntimeServiceImpl::GetIPFromPlugin(container_inspect *inspect, s return ""; } - runtime::PodSandboxMetadata metadata; + runtime::v1alpha2::PodSandboxMetadata metadata; CRINaming::ParseSandboxName(inspect->name, metadata, error); if (error.NotEmpty()) { return ""; @@ -1044,6 +1135,7 @@ std::string CRIRuntimeServiceImpl::GetIP(const std::string &podSandboxID, contai if (error.Empty()) { return ip; } + if (inspect->network_settings->ip_address) { WARN("Use container inspect ip info: %s", error.GetCMessage()); error.Clear(); @@ -1054,11 +1146,11 @@ std::string CRIRuntimeServiceImpl::GetIP(const std::string &podSandboxID, contai return ""; } -std::unique_ptr CRIRuntimeServiceImpl::PodSandboxStatus(const std::string &podSandboxID, - Errors &error) +std::unique_ptr CRIRuntimeServiceImpl::PodSandboxStatus( + const std::string &podSandboxID, Errors &error) { container_inspect *inspect { nullptr }; - std::unique_ptr podStatus(new runtime::PodSandboxStatus); + std::unique_ptr podStatus(new runtime::v1alpha2::PodSandboxStatus); if (podSandboxID.empty()) { error.SetError("Empty pod sandbox id"); @@ -1070,32 +1162,30 @@ std::unique_ptr CRIRuntimeServiceImpl::PodSandboxStat error.Errorf("Failed to find sandbox id %s: %s", podSandboxID.c_str(), error.GetCMessage()); return nullptr; } - inspect = InspectContainer(realSandboxID, error); if (error.NotEmpty()) { + ERROR("Inspect pod failed: %s", error.GetCMessage()); return nullptr; } - PodSandboxStatusToGRPC(inspect, realSandboxID, podStatus, error); - free_container_inspect(inspect); return podStatus; } void CRIRuntimeServiceImpl::ListPodSandboxToGRPC(container_list_response *response, - std::vector> *pods, + std::vector> *pods, bool filterOutReadySandboxes, Errors &error) { for (size_t i = 0; i < response->containers_len; i++) { - std::unique_ptr pod(new runtime::PodSandbox); + std::unique_ptr pod(new runtime::v1alpha2::PodSandbox); if (response->containers[i]->id) { pod->set_id(response->containers[i]->id); } if (response->containers[i]->status == CONTAINER_STATUS_RUNNING) { - pod->set_state(runtime::SANDBOX_READY); + pod->set_state(runtime::v1alpha2::SANDBOX_READY); } else { - pod->set_state(runtime::SANDBOX_NOTREADY); + pod->set_state(runtime::v1alpha2::SANDBOX_NOTREADY); } pod->set_created_at(response->containers[i]->created); @@ -1105,7 +1195,7 @@ void CRIRuntimeServiceImpl::ListPodSandboxToGRPC(container_list_response *respon CRIHelpers::ExtractAnnotations(response->containers[i]->annotations, *pod->mutable_annotations()); - if (filterOutReadySandboxes && pod->state() == runtime::SANDBOX_READY) { + if (filterOutReadySandboxes && pod->state() == runtime::v1alpha2::SANDBOX_READY) { continue; } @@ -1113,7 +1203,7 @@ void CRIRuntimeServiceImpl::ListPodSandboxToGRPC(container_list_response *respon } } -void CRIRuntimeServiceImpl::ListPodSandboxFromGRPC(const runtime::PodSandboxFilter *filter, +void CRIRuntimeServiceImpl::ListPodSandboxFromGRPC(const runtime::v1alpha2::PodSandboxFilter *filter, container_list_request **request, bool *filterOutReadySandboxes, Errors &error) { @@ -1143,7 +1233,7 @@ void CRIRuntimeServiceImpl::ListPodSandboxFromGRPC(const runtime::PodSandboxFilt } } if (filter->has_state()) { - if (filter->state().state() == runtime::SANDBOX_READY) { + if (filter->state().state() == runtime::v1alpha2::SANDBOX_READY) { (*request)->all = false; } else { *filterOutReadySandboxes = true; @@ -1160,8 +1250,9 @@ void CRIRuntimeServiceImpl::ListPodSandboxFromGRPC(const runtime::PodSandboxFilt } } -void CRIRuntimeServiceImpl::ListPodSandbox(const runtime::PodSandboxFilter *filter, - std::vector> *pods, Errors &error) +void CRIRuntimeServiceImpl::ListPodSandbox(const runtime::v1alpha2::PodSandboxFilter *filter, + std::vector> *pods, + Errors &error) { int ret; container_list_request *request { nullptr }; @@ -1194,8 +1285,8 @@ cleanup: free_container_list_response(response); } -void CRIRuntimeServiceImpl::PortForward(const runtime::PortForwardRequest &req, runtime::PortForwardResponse *resp, - Errors &error) +void CRIRuntimeServiceImpl::PortForward(const runtime::v1alpha2::PortForwardRequest &req, + runtime::v1alpha2::PortForwardResponse *resp, Errors &error) { } @@ -1243,4 +1334,3 @@ void CRIRuntimeServiceImpl::ClearNetworkReady(const std::string &podSandboxID) pthread_mutex_unlock(&m_networkReadyLock); } - diff --git a/src/services/cri/cri_security_context.cc b/src/services/cri/cri_security_context.cc index d742778..d03c383 100644 --- a/src/services/cri/cri_security_context.cc +++ b/src/services/cri/cri_security_context.cc @@ -19,7 +19,8 @@ #include "log.h" namespace CRISecurity { -static void ModifyContainerConfig(const runtime::LinuxContainerSecurityContext &sc, container_custom_config *config) +static void ModifyContainerConfig(const runtime::v1alpha2::LinuxContainerSecurityContext &sc, + container_custom_config *config) { if (sc.has_run_as_user()) { free(config->user); @@ -31,99 +32,118 @@ static void ModifyContainerConfig(const runtime::LinuxContainerSecurityContext & } } -static void ModifyHostConfig(const runtime::LinuxContainerSecurityContext &sc, host_config *hostConfig, Errors &error) +static void ModifyHostConfigCapabilities(const runtime::v1alpha2::LinuxContainerSecurityContext &sc, + host_config *hostConfig, Errors &error) +{ + if (!sc.has_capabilities()) { + return; + } + + const google::protobuf::RepeatedPtrField &capAdd = sc.capabilities().add_capabilities(); + if (capAdd.size() > 0) { + if (static_cast(capAdd.size()) > SIZE_MAX / sizeof(char *)) { + error.SetError("Invalid capability add size"); + return; + } + hostConfig->cap_add = (char **)util_common_calloc_s(sizeof(char *) * capAdd.size()); + if (hostConfig->cap_add == nullptr) { + error.SetError("Out of memory"); + return; + } + for (int i {}; i < capAdd.size(); i++) { + hostConfig->cap_add[i] = util_strdup_s(capAdd[i].c_str()); + hostConfig->cap_add_len++; + } + } + const google::protobuf::RepeatedPtrField &capDrop = sc.capabilities().drop_capabilities(); + if (capDrop.size() > 0) { + if (static_cast(capDrop.size()) > SIZE_MAX / sizeof(char *)) { + error.SetError("Invalid capability drop size"); + return; + } + hostConfig->cap_drop = (char **)util_common_calloc_s(sizeof(char *) * capDrop.size()); + if (hostConfig->cap_drop == nullptr) { + error.SetError("Out of memory"); + return; + } + for (int i = 0; i < capDrop.size(); i++) { + hostConfig->cap_drop[i] = util_strdup_s(capDrop[i].c_str()); + hostConfig->cap_drop_len++; + } + } +} + +static void ModifyHostConfigNoNewPrivs(const runtime::v1alpha2::LinuxContainerSecurityContext &sc, + host_config *hostConfig, Errors &error) +{ + char **tmp_security_opt { nullptr }; + + if (!sc.no_new_privs()) { + return; + } + + if (hostConfig->security_opt_len > (SIZE_MAX / sizeof(char *)) - 1) { + error.Errorf("Out of memory"); + return; + } + + size_t oldSize = hostConfig->security_opt_len * sizeof(char *); + size_t newSize = oldSize + sizeof(char *); + int ret = mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hostConfig->security_opt, oldSize); + if (ret != 0) { + error.Errorf("Out of memory"); + return; + } + hostConfig->security_opt = tmp_security_opt; + hostConfig->security_opt[hostConfig->security_opt_len++] = util_strdup_s("no-new-privileges"); +} + +static void ModifyHostConfigscSupplementalGroups(const runtime::v1alpha2::LinuxContainerSecurityContext &sc, + host_config *hostConfig, Errors &error) +{ + if (sc.supplemental_groups().size() == 0) { + return; + } + + const google::protobuf::RepeatedField &groups = sc.supplemental_groups(); + if (groups.size() > 0) { + if (static_cast(groups.size()) > SIZE_MAX / sizeof(char *)) { + error.SetError("Invalid group size"); + return; + } + hostConfig->group_add = (char **)util_common_calloc_s(sizeof(char *) * groups.size()); + if (hostConfig->group_add == nullptr) { + error.SetError("Out of memory"); + return; + } + for (int i = 0; i < groups.size(); i++) { + hostConfig->group_add[i] = util_strdup_s(std::to_string(groups[i]).c_str()); + hostConfig->group_add_len++; + } + } +} + +static void ModifyHostConfig(const runtime::v1alpha2::LinuxContainerSecurityContext &sc, host_config *hostConfig, + Errors &error) { hostConfig->privileged = sc.privileged(); hostConfig->readonly_rootfs = sc.readonly_rootfs(); - if (sc.has_capabilities()) { - const google::protobuf::RepeatedPtrField &capAdd = sc.capabilities().add_capabilities(); - if (capAdd.size() > 0) { - if (static_cast(capAdd.size()) > SIZE_MAX / sizeof(char *)) { - error.SetError("Invalid capability add size"); - return; - } - hostConfig->cap_add = (char **)util_common_calloc_s(sizeof(char *) * capAdd.size()); - if (hostConfig->cap_add == nullptr) { - error.SetError("Out of memory"); - return; - } - for (int i {}; i < capAdd.size(); i++) { - hostConfig->cap_add[i] = util_strdup_s(capAdd[i].c_str()); - hostConfig->cap_add_len++; - } - } - const google::protobuf::RepeatedPtrField &capDrop = sc.capabilities().drop_capabilities(); - if (capDrop.size() > 0) { - if (static_cast(capDrop.size()) > SIZE_MAX / sizeof(char *)) { - error.SetError("Invalid capability drop size"); - return; - } - hostConfig->cap_drop = (char **)util_common_calloc_s(sizeof(char *) * capDrop.size()); - if (hostConfig->cap_drop == nullptr) { - error.SetError("Out of memory"); - return; - } - for (int i = 0; i < capDrop.size(); i++) { - hostConfig->cap_drop[i] = util_strdup_s(capDrop[i].c_str()); - hostConfig->cap_drop_len++; - } - } - } - // note: Apply apparmor options, selinux options, noNewPrivilege - if (sc.no_new_privs()) { - char **tmp_security_opt { nullptr }; - - if (hostConfig->security_opt_len > (SIZE_MAX / sizeof(char *)) - 1) { - error.Errorf("Out of memory"); - return; - } - - size_t oldSize = hostConfig->security_opt_len * sizeof(char *); - size_t newSize = oldSize + sizeof(char *); - int ret = mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hostConfig->security_opt, oldSize); - if (ret != 0) { - error.Errorf("Out of memory"); - return; - } - hostConfig->security_opt = tmp_security_opt; - hostConfig->security_opt[hostConfig->security_opt_len++] = util_strdup_s("no-new-privileges"); - } - - if (sc.supplemental_groups().size() > 0) { - const google::protobuf::RepeatedField &groups = sc.supplemental_groups(); - if (groups.size() > 0) { - if (static_cast(groups.size()) > SIZE_MAX / sizeof(char *)) { - error.SetError("Invalid group size"); - return; - } - hostConfig->group_add = (char **)util_common_calloc_s(sizeof(char *) * groups.size()); - if (hostConfig->group_add == nullptr) { - error.SetError("Out of memory"); - return; - } - for (int i = 0; i < groups.size(); i++) { - hostConfig->group_add[i] = util_strdup_s(std::to_string(groups[i]).c_str()); - hostConfig->group_add_len++; - } - } - } + ModifyHostConfigCapabilities(sc, hostConfig, error); + ModifyHostConfigNoNewPrivs(sc, hostConfig, error); + ModifyHostConfigscSupplementalGroups(sc, hostConfig, error); } -static void ModifyCommonNamespaceOptions(const runtime::NamespaceOption &nsOpts, host_config *hostConfig) +static void ModifyCommonNamespaceOptions(const runtime::v1alpha2::NamespaceOption &nsOpts, host_config *hostConfig) { - if (nsOpts.host_pid()) { + if (nsOpts.pid() == runtime::v1alpha2::NamespaceMode::NODE) { free(hostConfig->pid_mode); hostConfig->pid_mode = util_strdup_s(CRIRuntimeService::Constants::namespaceModeHost.c_str()); } - if (nsOpts.host_ipc()) { - free(hostConfig->ipc_mode); - hostConfig->ipc_mode = util_strdup_s(CRIRuntimeService::Constants::namespaceModeHost.c_str()); - } } -static void ModifyHostNetworkOptionForContainer(bool hostNetwork, const std::string &podSandboxID, - host_config *hostConfig) +static void ModifyHostNetworkOptionForContainer(const runtime::v1alpha2::NamespaceMode &hostNetwork, + const std::string &podSandboxID, host_config *hostConfig) { std::string sandboxNSMode = "container:" + podSandboxID; @@ -131,47 +151,60 @@ static void ModifyHostNetworkOptionForContainer(bool hostNetwork, const std::str hostConfig->network_mode = util_strdup_s(sandboxNSMode.c_str()); free(hostConfig->ipc_mode); hostConfig->ipc_mode = util_strdup_s(sandboxNSMode.c_str()); - if (hostNetwork) { + if (hostNetwork == runtime::v1alpha2::NamespaceMode::NODE) { free(hostConfig->uts_mode); hostConfig->uts_mode = util_strdup_s(CRIRuntimeService::Constants::namespaceModeHost.c_str()); } } -static void ModifyHostNetworkOptionForSandbox(bool hostNetwork, host_config *hostConfig) +static void ModifyHostNetworkOptionForSandbox(const runtime::v1alpha2::NamespaceOption &nsOpts, host_config *hostConfig) { - if (hostNetwork) { + if (nsOpts.ipc() == runtime::v1alpha2::NamespaceMode::NODE) { + free(hostConfig->ipc_mode); + hostConfig->ipc_mode = util_strdup_s(CRIRuntimeService::Constants::namespaceModeHost.c_str()); + } + + if (nsOpts.network() == runtime::v1alpha2::NamespaceMode::NODE) { + free(hostConfig->network_mode); hostConfig->network_mode = util_strdup_s(CRIRuntimeService::Constants::namespaceModeHost.c_str()); } // Note: default networkMode is not supported } -static void ModifyContainerNamespaceOptions(const runtime::NamespaceOption &nsOpts, const std::string &podSandboxID, - host_config *hostConfig, Errors &error) +static void ModifyContainerNamespaceOptions(const runtime::v1alpha2::NamespaceOption &nsOpts, + const std::string &podSandboxID, host_config *hostConfig, Errors &error) { - std::string pidMode = "container:" + podSandboxID; - hostConfig->pid_mode = util_strdup_s(pidMode.c_str()); + if (nsOpts.pid() == runtime::v1alpha2::NamespaceMode::POD) { + free(hostConfig->pid_mode); + hostConfig->pid_mode = util_strdup_s(""); + } /* set common Namespace options */ ModifyCommonNamespaceOptions(nsOpts, hostConfig); /* modify host network option for container */ - ModifyHostNetworkOptionForContainer(nsOpts.host_network(), podSandboxID, hostConfig); + ModifyHostNetworkOptionForContainer(nsOpts.network(), podSandboxID, hostConfig); } -static void ModifySandboxNamespaceOptions(const runtime::NamespaceOption &nsOpts, host_config *hostConfig, +static void ModifySandboxNamespaceOptions(const runtime::v1alpha2::NamespaceOption &nsOpts, host_config *hostConfig, Errors &error) { /* set common Namespace options */ ModifyCommonNamespaceOptions(nsOpts, hostConfig); /* modify host network option for container */ - ModifyHostNetworkOptionForSandbox(nsOpts.host_network(), hostConfig); + ModifyHostNetworkOptionForSandbox(nsOpts, hostConfig); } -void ApplySandboxSecurityContext(const runtime::LinuxPodSandboxConfig &lc, container_custom_config *config, +void ApplySandboxSecurityContext(const runtime::v1alpha2::LinuxPodSandboxConfig &lc, container_custom_config *config, host_config *hc, Errors &error) { - std::unique_ptr sc(new runtime::LinuxContainerSecurityContext); + std::unique_ptr sc( + new (std::nothrow) runtime::v1alpha2::LinuxContainerSecurityContext); + if (sc == nullptr) { + error.SetError("Out of memory"); + return; + } if (lc.has_security_context()) { - const runtime::LinuxSandboxSecurityContext &old = lc.security_context(); + const runtime::v1alpha2::LinuxSandboxSecurityContext &old = lc.security_context(); if (old.has_run_as_user()) { *sc->mutable_run_as_user() = old.run_as_user(); } @@ -192,11 +225,11 @@ void ApplySandboxSecurityContext(const runtime::LinuxPodSandboxConfig &lc, conta ModifySandboxNamespaceOptions(sc->namespace_options(), hc, error); } -void ApplyContainerSecurityContext(const runtime::LinuxContainerConfig &lc, const std::string &podSandboxID, +void ApplyContainerSecurityContext(const runtime::v1alpha2::LinuxContainerConfig &lc, const std::string &podSandboxID, container_custom_config *config, host_config *hc, Errors &error) { if (lc.has_security_context()) { - const runtime::LinuxContainerSecurityContext &sc = lc.security_context(); + const runtime::v1alpha2::LinuxContainerSecurityContext &sc = lc.security_context(); ModifyContainerConfig(sc, config); ModifyHostConfig(sc, hc, error); if (error.NotEmpty()) { @@ -210,4 +243,4 @@ void ApplyContainerSecurityContext(const runtime::LinuxContainerConfig &lc, cons } } -} // namespace CRISecurity +} // namespace CRISecurity diff --git a/src/services/cri/cri_security_context.h b/src/services/cri/cri_security_context.h index 1d44a18..d0958e0 100644 --- a/src/services/cri/cri_security_context.h +++ b/src/services/cri/cri_security_context.h @@ -22,12 +22,12 @@ #include "host_config.h" namespace CRISecurity { -void ApplySandboxSecurityContext(const runtime::LinuxPodSandboxConfig &lc, container_custom_config *config, +void ApplySandboxSecurityContext(const runtime::v1alpha2::LinuxPodSandboxConfig &lc, container_custom_config *config, host_config *hc, Errors &error); -void ApplyContainerSecurityContext(const runtime::LinuxContainerConfig &lc, const std::string &podSandboxID, +void ApplyContainerSecurityContext(const runtime::v1alpha2::LinuxContainerConfig &lc, const std::string &podSandboxID, container_custom_config *config, host_config *hc, Errors &errorr); -} // namespace CRISecurity +} // namespace CRISecurity #endif /* _CRI_SECURITY_CONTEXT_H_ */ diff --git a/src/services/cri/cri_services.h b/src/services/cri/cri_services.h index e783668..a5a143d 100644 --- a/src/services/cri/cri_services.h +++ b/src/services/cri/cri_services.h @@ -26,14 +26,15 @@ namespace cri { class RuntimeVersioner { public: - virtual void Version(const std::string &apiVersion, runtime::VersionResponse *versionResponse, Errors &error) = 0; + virtual void Version(const std::string &apiVersion, runtime::v1alpha2::VersionResponse *versionResponse, + Errors &error) = 0; }; class ContainerManager { public: virtual std::string CreateContainer(const std::string &podSandboxID, - const runtime::ContainerConfig &containerConfig, - const runtime::PodSandboxConfig &podSandboxConfig, Errors &error) = 0; + const runtime::v1alpha2::ContainerConfig &containerConfig, + const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, Errors &error) = 0; virtual void StartContainer(const std::string &containerID, Errors &error) = 0; @@ -41,65 +42,72 @@ public: virtual void RemoveContainer(const std::string &containerID, Errors &error) = 0; - virtual void ListContainers(const runtime::ContainerFilter *filter, - std::vector> *containers, Errors &error) = 0; + virtual void ListContainers(const runtime::v1alpha2::ContainerFilter *filter, + std::vector> *containers, + Errors &error) = 0; - virtual void ListContainerStats(const runtime::ContainerStatsFilter *filter, - std::vector> *containerstats, + virtual void ListContainerStats(const runtime::v1alpha2::ContainerStatsFilter *filter, + std::vector> *containerstats, Errors &error) = 0; - virtual std::unique_ptr ContainerStatus(const std::string &containerID, - Errors &error) = 0; + virtual std::unique_ptr ContainerStatus(const std::string &containerID, + Errors &error) = 0; virtual void UpdateContainerResources(const std::string &containerID, - const runtime::LinuxContainerResources &resources, Errors &error) = 0; + const runtime::v1alpha2::LinuxContainerResources &resources, + Errors &error) = 0; virtual void ExecSync(const std::string &containerID, const google::protobuf::RepeatedPtrField &cmd, - int64_t timeout, runtime::ExecSyncResponse *reply, Errors &error) = 0; + int64_t timeout, runtime::v1alpha2::ExecSyncResponse *reply, Errors &error) = 0; - virtual void Exec(const runtime::ExecRequest &req, runtime::ExecResponse *resp, Errors &error) = 0; + virtual void Exec(const runtime::v1alpha2::ExecRequest &req, runtime::v1alpha2::ExecResponse *resp, + Errors &error) = 0; - virtual void Attach(const runtime::AttachRequest &req, runtime::AttachResponse *resp, Errors &error) = 0; + virtual void Attach(const runtime::v1alpha2::AttachRequest &req, runtime::v1alpha2::AttachResponse *resp, + Errors &error) = 0; }; class PodSandboxManager { public: - virtual std::string RunPodSandbox(const runtime::PodSandboxConfig &config, Errors &error) = 0; + virtual std::string RunPodSandbox(const runtime::v1alpha2::PodSandboxConfig &config, Errors &error) = 0; virtual void StopPodSandbox(const std::string &podSandboxID, Errors &error) = 0; virtual void RemovePodSandbox(const std::string &podSandboxID, Errors &error) = 0; - virtual std::unique_ptr PodSandboxStatus(const std::string &podSandboxID, - Errors &error) = 0; + virtual std::unique_ptr PodSandboxStatus(const std::string &podSandboxID, + Errors &error) = 0; - virtual void ListPodSandbox(const runtime::PodSandboxFilter *filter, - std::vector> *pods, Errors &error) = 0; + virtual void ListPodSandbox(const runtime::v1alpha2::PodSandboxFilter *filter, + std::vector> *pods, Errors &error) = 0; - virtual void PortForward(const runtime::PortForwardRequest &req, runtime::PortForwardResponse *resp, - Errors &error) = 0; + virtual void PortForward(const runtime::v1alpha2::PortForwardRequest &req, + runtime::v1alpha2::PortForwardResponse *resp, Errors &error) = 0; }; class RuntimeManager { public: - virtual void UpdateRuntimeConfig(const runtime::RuntimeConfig &config, Errors &error) = 0; + virtual void UpdateRuntimeConfig(const runtime::v1alpha2::RuntimeConfig &config, Errors &error) = 0; - virtual std::unique_ptr Status(Errors &error) = 0; + virtual std::unique_ptr Status(Errors &error) = 0; }; class ImageManagerService { public: - virtual void ListImages(const runtime::ImageFilter &filter, std::vector> *images, - Errors &error) = 0; + virtual void ListImages(const runtime::v1alpha2::ImageFilter &filter, + std::vector> *images, Errors &error) = 0; - virtual std::unique_ptr ImageStatus(const runtime::ImageSpec &image, Errors &error) = 0; + virtual std::unique_ptr ImageStatus(const runtime::v1alpha2::ImageSpec &image, + Errors &error) = 0; - virtual std::string PullImage(const runtime::ImageSpec &image, const runtime::AuthConfig &auth, Errors &error) = 0; + virtual std::string PullImage(const runtime::v1alpha2::ImageSpec &image, const runtime::v1alpha2::AuthConfig &auth, + Errors &error) = 0; - virtual void RemoveImage(const runtime::ImageSpec &image, Errors &error) = 0; + virtual void RemoveImage(const runtime::v1alpha2::ImageSpec &image, Errors &error) = 0; - virtual void ImageFsInfo(std::vector> *usages, Errors &error) = 0; + virtual void ImageFsInfo(std::vector> *usages, + Errors &error) = 0; }; -} // namespace cri +} // namespace cri #endif /* _CRI_SERVICES_H_ */ diff --git a/src/services/cri/errors.h b/src/services/cri/errors.h index 3946586..cfdffc1 100644 --- a/src/services/cri/errors.h +++ b/src/services/cri/errors.h @@ -21,7 +21,11 @@ class Errors { public: Errors(); - Errors(const Errors ©) : m_message(copy.m_message), m_code(copy.m_code) {} + Errors(const Errors ©) + : m_message(copy.m_message) + , m_code(copy.m_code) + { + } Errors &operator=(const Errors &); virtual ~Errors(); diff --git a/src/services/cri/naming.cc b/src/services/cri/naming.cc index 8db5a63..9d210f1 100644 --- a/src/services/cri/naming.cc +++ b/src/services/cri/naming.cc @@ -51,7 +51,7 @@ static int parseName(const std::string &name, std::vector &items, u return 0; } -std::string MakeSandboxName(const runtime::PodSandboxMetadata &metadata) +std::string MakeSandboxName(const runtime::v1alpha2::PodSandboxMetadata &metadata) { std::string sname; @@ -70,7 +70,7 @@ std::string MakeSandboxName(const runtime::PodSandboxMetadata &metadata) return sname; } -void ParseSandboxName(const std::string &name, runtime::PodSandboxMetadata &metadata, Errors &err) +void ParseSandboxName(const std::string &name, runtime::v1alpha2::PodSandboxMetadata &metadata, Errors &err) { int ret {}; std::vector items; @@ -87,7 +87,7 @@ void ParseSandboxName(const std::string &name, runtime::PodSandboxMetadata &meta metadata.set_attempt(attempt); } -std::string MakeContainerName(const runtime::PodSandboxConfig &s, const runtime::ContainerConfig &c) +std::string MakeContainerName(const runtime::v1alpha2::PodSandboxConfig &s, const runtime::v1alpha2::ContainerConfig &c) { std::string sname; @@ -106,7 +106,7 @@ std::string MakeContainerName(const runtime::PodSandboxConfig &s, const runtime: return sname; } -void ParseContainerName(const std::string &name, runtime::ContainerMetadata *metadata, Errors &err) +void ParseContainerName(const std::string &name, runtime::v1alpha2::ContainerMetadata *metadata, Errors &err) { int ret {}; std::vector items; @@ -121,4 +121,4 @@ void ParseContainerName(const std::string &name, runtime::ContainerMetadata *met metadata->set_attempt(attempt); } -} // namespace CRINaming +} // namespace CRINaming diff --git a/src/services/cri/naming.h b/src/services/cri/naming.h index 5a596f0..c7ad28e 100644 --- a/src/services/cri/naming.h +++ b/src/services/cri/naming.h @@ -20,13 +20,14 @@ #include namespace CRINaming { -std::string MakeSandboxName(const runtime::PodSandboxMetadata &metadata); +std::string MakeSandboxName(const runtime::v1alpha2::PodSandboxMetadata &metadata); -std::string MakeContainerName(const runtime::PodSandboxConfig &s, const runtime::ContainerConfig &c); +std::string MakeContainerName(const runtime::v1alpha2::PodSandboxConfig &s, + const runtime::v1alpha2::ContainerConfig &c); -void ParseSandboxName(const std::string &name, runtime::PodSandboxMetadata &metadata, Errors &err); +void ParseSandboxName(const std::string &name, runtime::v1alpha2::PodSandboxMetadata &metadata, Errors &err); -void ParseContainerName(const std::string &name, runtime::ContainerMetadata *metadata, Errors &err); -} // namespace CRINaming +void ParseContainerName(const std::string &name, runtime::v1alpha2::ContainerMetadata *metadata, Errors &err); +} // namespace CRINaming #endif /* _CRI_RUNTIME_SERVICES_IMPL_H_ */ diff --git a/src/services/cri/network_plugin.cc b/src/services/cri/network_plugin.cc index fe074f1..520095e 100644 --- a/src/services/cri/network_plugin.cc +++ b/src/services/cri/network_plugin.cc @@ -139,8 +139,8 @@ free_out: return result; } -std::string GetPodIP(const std::string &nsenterPath, const std::string &netnsPath, - const std::string &interfaceName, Errors &error) +std::string GetPodIP(const std::string &nsenterPath, const std::string &netnsPath, const std::string &interfaceName, + Errors &error) { std::string ip = GetOnePodIP(nsenterPath, netnsPath, interfaceName, "-4", error); if (error.NotEmpty()) { @@ -158,7 +158,11 @@ void InitNetworkPlugin(std::vector> *plugins, std if (networkPluginName.empty()) { DEBUG("network plugin name empty"); - *result = std::shared_ptr(new NoopNetworkPlugin); + *result = std::shared_ptr(new (std::nothrow) NoopNetworkPlugin); + if (*result == nullptr) { + ERROR("Out of memory"); + return; + } (*result)->Init(criImpl, hairpinMode, nonMasqueradeCIDR, mtu, err); return; } @@ -305,7 +309,11 @@ void PluginManager::Lock(const std::string &fullPodName, Errors &error) auto iter = m_pods.find(fullPodName); PodLock *lock { nullptr }; if (iter == m_pods.end()) { - auto tmpLock = std::unique_ptr(new PodLock()); + auto tmpLock = std::unique_ptr(new (std::nothrow) PodLock()); + if (tmpLock == nullptr) { + error.SetError("Out of memory"); + return; + } lock = tmpLock.get(); m_pods[fullPodName] = std::move(tmpLock); } else { @@ -442,8 +450,7 @@ unlock: } void NoopNetworkPlugin::Init(CRIRuntimeServiceImpl *criImpl, const std::string &hairpinMode, - const std::string &nonMasqueradeCIDR, - int mtu, Errors &error) + const std::string &nonMasqueradeCIDR, int mtu, Errors &error) { char *stderr_str { nullptr }; char *stdout_str { nullptr }; @@ -518,5 +525,8 @@ void NoopNetworkPlugin::Status(Errors &error) return; } +const std::string &GetInterfaceName() +{ + return DEFAULT_NETWORK_INTERFACE_NAME; +} } // namespace Network - diff --git a/src/services/cri/network_plugin.h b/src/services/cri/network_plugin.h index ac2bf9f..7c37add 100644 --- a/src/services/cri/network_plugin.h +++ b/src/services/cri/network_plugin.h @@ -27,19 +27,25 @@ class CRIRuntimeServiceImpl; namespace Network { const std::string DEFAULT_NETWORK_PLANE_NAME = "default"; const std::string DEFAULT_NETWORK_INTERFACE_NAME = "eth0"; +const std::string POD_DISABLE_DEFAULT_NET_ANNOTATION_KEY = "network.alpha.kubernetes.io/disableDefaultNetwork"; class NetworkPluginConf { public: /* settings for net plugin */ NetworkPluginConf(const std::string &dockershimRootDirectory = "/var/lib/lcrd/shim", const std::string &pluginConfDir = "/etc/cni/net.d/", - const std::string &pluginBinDir = "/opt/cni/bin", - const std::string &pluginName = "", - const std::string &hairpinMode = "hairpin-veth", - const std::string &nonMasqueradeCIDR = "", int32_t mtu = 1460) - : m_dockershimRootDirectory(dockershimRootDirectory), m_pluginConfDir(pluginConfDir), - m_pluginBinDir(pluginBinDir), m_pluginName(pluginName), - m_hairpinMode(hairpinMode), m_nonMasqueradeCIDR(nonMasqueradeCIDR), m_mtu(mtu) {} + const std::string &pluginBinDir = "/opt/cni/bin", const std::string &pluginName = "", + const std::string &hairpinMode = "hairpin-veth", const std::string &nonMasqueradeCIDR = "", + int32_t mtu = 1460) + : m_dockershimRootDirectory(dockershimRootDirectory) + , m_pluginConfDir(pluginConfDir) + , m_pluginBinDir(pluginBinDir) + , m_pluginName(pluginName) + , m_hairpinMode(hairpinMode) + , m_nonMasqueradeCIDR(nonMasqueradeCIDR) + , m_mtu(mtu) + { + } ~NetworkPluginConf() = default; const std::string &GetDockershimRootDirectory() const; @@ -121,8 +127,8 @@ public: virtual ~NoopNetworkPlugin() = default; - void Init(CRIRuntimeServiceImpl *criImpl, const std::string &hairpinMode, - const std::string &nonMasqueradeCIDR, int mtu, Errors &error) override; + void Init(CRIRuntimeServiceImpl *criImpl, const std::string &hairpinMode, const std::string &nonMasqueradeCIDR, + int mtu, Errors &error) override; void Event(const std::string &name, std::map &details) override; @@ -185,7 +191,10 @@ private: class PluginManager { public: - explicit PluginManager(std::shared_ptr plugin) : m_plugin(plugin) {} + explicit PluginManager(std::shared_ptr plugin) + : m_plugin(plugin) + { + } ~PluginManager() = default; std::string PluginName(); void Event(const std::string &name, std::map &details); @@ -215,8 +224,10 @@ void InitNetworkPlugin(std::vector> *plugins, std void ProbeNetworkPlugins(const std::string &pluginDir, const std::string &binDir, std::vector> *plugins); -std::string GetPodIP(const std::string &nsenterPath, const std::string &netnsPath, - const std::string &interfaceName, Errors &error); -} // namespace Network +std::string GetPodIP(const std::string &nsenterPath, const std::string &netnsPath, const std::string &interfaceName, + Errors &error); + +const std::string &GetInterfaceName(); +} // namespace Network #endif diff --git a/src/services/cri/request_cache.cc b/src/services/cri/request_cache.cc index c5b85df..e817530 100644 --- a/src/services/cri/request_cache.cc +++ b/src/services/cri/request_cache.cc @@ -89,7 +89,6 @@ std::string RequestCache::UniqueToken() for (size_t j {}; j < tokenSize; ++j) { rawToken[j] = (char)uniform_dist(e1); } - lws_b64_encode_string(rawToken, (int)strlen(rawToken), buf, (int)sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (strlen(buf) < TokenLen) { @@ -150,4 +149,3 @@ bool RequestCache::IsValidToken(const std::string &token) found = true; return ele.req; } - diff --git a/src/services/cri/request_cache.h b/src/services/cri/request_cache.h index ef86f7f..eb7f279 100644 --- a/src/services/cri/request_cache.h +++ b/src/services/cri/request_cache.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -54,4 +54,5 @@ private: const size_t MaxInFlight { 1000 }; const size_t TokenLen { 8 }; }; -#endif /*__REQUEST_CACHE_H_*/ + +#endif /* __REQUEST_CACHE_H_ */ diff --git a/src/services/execution/events/collector.c b/src/services/execution/events/collector.c index 9ba4be4..5e2287f 100644 --- a/src/services/execution/events/collector.c +++ b/src/services/execution/events/collector.c @@ -322,7 +322,7 @@ out: return ret; } -/* events copy*/ +/* events copy */ static void event_copy(const struct lcrd_events_format *src, struct lcrd_events_format *dest) { if (src == NULL || dest == NULL) { @@ -650,7 +650,7 @@ static int post_event_to_events_hander(const struct lcrd_events_format *events) return -1; } - /*only post STOPPED event to events_hander */ + /* only post STOPPED event to events_hander */ if (events->type != EVENTS_TYPE_STOPPED1) { return 0; } @@ -832,3 +832,4 @@ int newcollector() out: return ret; } + diff --git a/src/services/execution/events/collector.h b/src/services/execution/events/collector.h index f7c3d97..642e514 100644 --- a/src/services/execution/events/collector.h +++ b/src/services/execution/events/collector.h @@ -43,3 +43,4 @@ void free_event(struct lcrd_events_format *event); int lcrd_monitor_send_event(const char *name, runtime_state_t state, int pid, int exit_code); #endif /* __COLLECTOR_H */ + diff --git a/src/services/execution/events/events_handler.c b/src/services/execution/events/events_handler.c index 685035b..4581d07 100644 --- a/src/services/execution/events/events_handler.c +++ b/src/services/execution/events/events_handler.c @@ -112,7 +112,7 @@ static int container_state_changed(container_t *cont, const struct lcrd_events_f bool should_restart = false; bool auto_remove = false; - /*only handle Exit event*/ + /* only handle Exit event */ if (events->type != EVENTS_TYPE_STOPPED1) { return 0; } @@ -327,3 +327,4 @@ out: events_handler_unlock(handler); return ret; } + diff --git a/src/services/execution/events/events_handler.h b/src/services/execution/events/events_handler.h index 33cacb3..48eee16 100644 --- a/src/services/execution/events/events_handler.h +++ b/src/services/execution/events/events_handler.h @@ -36,3 +36,4 @@ void events_handler_free(events_handler_t *handler); int events_handler_post_events(events_handler_t *handler, const struct lcrd_events_format *event); #endif /* __EVENTS_HANDLER_H */ + diff --git a/src/services/execution/execute/execution.c b/src/services/execution/execute/execution.c index 76e9ee9..a260aff 100644 --- a/src/services/execution/execute/execution.c +++ b/src/services/execution/execute/execution.c @@ -49,7 +49,7 @@ #include "plugin.h" #include "health_check.h" #include "execution_network.h" -#include "runtime_interface.h" +#include "runtime.h" #include "specs_extend.h" #include "utils.h" #include "error.h" @@ -210,6 +210,7 @@ static int do_clean_container(const container_t *cont, pid_t pid) char *logdriver = NULL; const char *id = cont->common_config->id; const char *runtime = cont->runtime; + rt_clean_params_t params = { 0 }; if (conf_get_daemon_log_config(&loglevel, &logdriver, &engine_log_path) != 0) { ERROR("Failed to get log config"); @@ -217,7 +218,13 @@ static int do_clean_container(const container_t *cont, pid_t pid) goto out; } - ret = runtime_clean_resource(id, runtime, cont->root_path, engine_log_path, loglevel, pid); + params.rootpath = cont->root_path; + params.statepath = cont->state_path; + params.logpath = engine_log_path; + params.loglevel = loglevel; + params.pid = pid; + + ret = runtime_clean_resource(id, runtime, ¶ms); if (ret != 0) { ERROR("Failed to clean failed started container %s", id); ret = -1; @@ -256,8 +263,6 @@ int clean_container_resource(const char *id, const char *runtime, pid_t pid) cont = containers_store_get(id); if (cont == NULL) { WARN("No such container:%s", id); - lcrd_set_error_message("No such container:%s", id); - ret = -1; goto out; } @@ -636,37 +641,32 @@ static int write_env_to_target_file(const container_t *cont) } static int do_post_start_on_success(const char *id, const char *runtime, - const char *pidfile, int exit_fifo_fd, container_pid_t **pid_info) + const char *pidfile, int exit_fifo_fd, const container_pid_t *pid_info) { int ret = 0; - *pid_info = container_read_pidfile(pidfile); - if (*pid_info == NULL) { - ERROR("Failed to get started container's pid info, start container fail"); - close(exit_fifo_fd); - ret = -1; - goto out; - } - // exit_fifo_fd was closed in supervisor_add_exit_monitor - if (supervisor_add_exit_monitor(exit_fifo_fd, *pid_info, id, runtime)) { + if (supervisor_add_exit_monitor(exit_fifo_fd, pid_info, id, runtime)) { ERROR("Failed to add exit monitor to supervisor"); ret = -1; } -out: return ret; } -static void do_post_start_on_failure(const container_t *cont, int exit_fifo_fd, - const char *engine_log_path, const char *loglevel) +static void clean_resources_on_failure(const container_t *cont, const char *engine_log_path, const char *loglevel) { int ret = 0; const char *id = cont->common_config->id; const char *runtime = cont->runtime; + rt_clean_params_t params = { 0 }; - close(exit_fifo_fd); + params.rootpath = cont->root_path; + params.statepath = cont->state_path; + params.logpath = engine_log_path; + params.loglevel = loglevel; + params.pid = 0; - ret = runtime_clean_resource(id, runtime, cont->root_path, engine_log_path, loglevel, 0); + ret = runtime_clean_resource(id, runtime, ¶ms); if (ret != 0) { ERROR("Failed to clean failed started container %s", id); } @@ -675,7 +675,7 @@ static void do_post_start_on_failure(const container_t *cont, int exit_fifo_fd, } static int do_start_container(container_t *cont, const char *console_fifos[], bool reset_rm, - container_pid_t **pid_info) + container_pid_t *pid_info) { int ret = 0; int nret = 0; @@ -691,6 +691,7 @@ static int do_start_container(container_t *cont, const char *console_fifos[], bo oci_runtime_spec_process_user *puser = NULL; const char *runtime = cont->runtime; const char *id = cont->common_config->id; + rt_start_params_t start_params = { 0 }; if (mount_dev_tmpfs_for_system_container(cont) < 0) { ret = -1; @@ -744,26 +745,45 @@ static int do_start_container(container_t *cont, const char *console_fifos[], bo goto close_exit_fd; } + if (verify_container_settings_start(cont->root_path, id) != 0) { + ret = -1; + goto close_exit_fd; + } + start_timeout = conf_get_start_timeout(); if (cont->common_config->config != NULL) { tty = cont->common_config->config->tty; open_stdin = cont->common_config->config->open_stdin; } - ret = runtime_start(id, runtime, cont->root_path, tty, open_stdin, engine_log_path, loglevel, - console_fifos, NULL, start_timeout, pidfile, exit_fifo, puser); + start_params.rootpath = cont->root_path; + start_params.tty = tty; + start_params.open_stdin = open_stdin; + start_params.logpath = engine_log_path; + start_params.loglevel = loglevel; + start_params.console_fifos = console_fifos; + start_params.start_timeout = start_timeout; + start_params.container_pidfile = pidfile; + start_params.exit_fifo = exit_fifo; + start_params.puser = puser; + + ret = runtime_start(id, runtime, &start_params, pid_info); if (ret == 0) { if (do_post_start_on_success(id, runtime, pidfile, exit_fifo_fd, pid_info) != 0) { ERROR("Failed to do post start on runtime start success"); ret = -1; + goto clean_resources; } } else { - do_post_start_on_failure(cont, exit_fifo_fd, engine_log_path, loglevel); + goto close_exit_fd; } goto out; close_exit_fd: close(exit_fifo_fd); + +clean_resources: + clean_resources_on_failure(cont, engine_log_path, loglevel); out: free_oci_runtime_spec_process_user(puser); free(loglevel); @@ -793,7 +813,7 @@ static bool save_after_auto_remove(container_t *cont) ERROR("Failed to cleanup container %s", cont->common_config->id); return true; } - return false; /*do not save container if already auto removed*/ + return false; /* do not save container if already auto removed */ } return true; @@ -802,7 +822,8 @@ static bool save_after_auto_remove(container_t *cont) int start_container(container_t *cont, const char *console_fifos[], bool reset_rm) { int ret = 0; - container_pid_t *pid_info = NULL; + container_pid_t pid_info = { 0 }; + int exit_code = 125; if (cont == NULL || console_fifos == NULL) { ERROR("Invalid input arguments"); @@ -817,6 +838,13 @@ int start_container(container_t *cont, const char *console_fifos[], bool reset_r goto out; } + if (is_paused(cont->state)) { + ERROR("Cannot start a paused container, try unpause instead"); + lcrd_set_error_message("Cannot start a paused container, try unpause instead."); + ret = -1; + goto out; + } + if (is_removal_in_progress(cont->state) || is_dead(cont->state)) { ERROR("Container is marked for removal and cannot be started."); lcrd_set_error_message("Container is marked for removal and cannot be started."); @@ -839,25 +867,25 @@ 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) { - int exit_code = 125; ERROR("Runtime start container failed"); - container_state_set_error(cont->state, (const char *)g_lcrd_errmsg); ret = -1; - util_contain_errmsg(g_lcrd_errmsg, &exit_code); - state_set_stopped(cont->state, exit_code); - container_wait_stop_cond_broadcast(cont); - if (save_after_auto_remove(cont)) { - goto save_container; - } else { - goto out; - } + goto set_stopped; } else { - state_set_running(cont->state, pid_info, true); + state_set_running(cont->state, &pid_info, true); cont->common_config->has_been_manually_stopped = false; init_health_monitor(cont->common_config->id); goto save_container; } +set_stopped: + container_state_set_error(cont->state, (const char *)g_lcrd_errmsg); + util_contain_errmsg(g_lcrd_errmsg, &exit_code); + state_set_stopped(cont->state, exit_code); + container_wait_stop_cond_broadcast(cont); + if (!save_after_auto_remove(cont)) { + goto out; + } + save_container: if (container_to_disk(cont)) { ERROR("Failed to save container \"%s\" to disk", cont->common_config->id); @@ -866,7 +894,6 @@ save_container: } out: container_unlock(cont); - free(pid_info); return ret; } @@ -927,10 +954,6 @@ static int container_start_prepare(container_t *cont, const container_start_requ return -1; } - if (verify_container_settings_start(cont->root_path, id) != 0) { - return -1; - } - if (prepare_start_io(cont, request, fifopath, fifos, stdinfd, stdout_handler, stderr_handler) != 0) { return -1; } @@ -992,7 +1015,7 @@ static int container_start_cb(const container_start_request *request, container_ goto pack_response; } - if (start_container(cont, (const char **)fifos, true)) { + if (start_container(cont, (const char **)fifos, true) != 0) { cc = LCRD_ERR_EXEC; goto pack_response; } @@ -1019,6 +1042,8 @@ static int kill_with_signal(container_t *cont, uint32_t signal) { int ret = 0; const char *id = cont->common_config->id; + bool need_unpause = is_paused(cont->state); + rt_resume_params_t params = { 0 }; if (container_exit_on_next(cont)) { ERROR("Failed to cancel restart manager"); @@ -1042,9 +1067,16 @@ static int kill_with_signal(container_t *cont, uint32_t signal) stop_health_checks(id); ret = send_signal_to_process(cont->state->state->pid, cont->state->state->start_time, signal); - if (ret != 0) { - ERROR("Failed to grace shutdown container %s", id); + ERROR("Failed to send signal to container %s with signal %d", id, signal); + } + if (signal == SIGKILL && need_unpause) { + params.rootpath = cont->root_path; + if (runtime_resume(id, cont->runtime, ¶ms) != 0) { + ERROR("Cannot unpause container: %s", id); + ret = -1; + goto out; + } } out: @@ -1134,6 +1166,7 @@ static int restart_container(container_t *cont) const char *id = cont->common_config->id; const char *runtime = cont->runtime; const char *rootpath = cont->root_path; + rt_restart_params_t params = { 0 }; container_lock(cont); @@ -1145,7 +1178,9 @@ static int restart_container(container_t *cont) (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); - ret = runtime_restart(id, runtime, rootpath); + params.rootpath = rootpath; + + ret = runtime_restart(id, runtime, ¶ms); if (ret == -2) { goto out; } @@ -1196,7 +1231,7 @@ static uint32_t stop_and_start(container_t *cont, int timeout) goto out; } - if (start_container(cont, console_fifos, true)) { + if (start_container(cont, console_fifos, true) != 0) { cc = LCRD_ERR_EXEC; goto out; } @@ -1527,32 +1562,16 @@ pack_response: static int do_runtime_rm_helper(const char *id, const char *runtime, const char *rootpath) { int ret = 0; - /* notes: we do not use force stop in lcr, we do stop above */ - if (runtime_rm(id, runtime, rootpath)) { - if (strstr(g_lcrd_errmsg, "No such container") != NULL) { - // container root path may been corrupted, try to remove by daemon - char cont_root_path[PATH_MAX] = { 0 }; - WARN("container %s root path may been corrupted, try to remove by daemon", id); - ret = sprintf_s(cont_root_path, sizeof(cont_root_path), "%s/%s", rootpath, id); - if (ret < 0) { - ERROR("Failed to sprintf container_state"); - ret = -1; - goto out; - } - ret = util_recursive_rmdir(cont_root_path, 0); - if (ret != 0) { - const char *tmp_err = (errno != 0) ? strerror(errno) : "error"; - ERROR("Failed to delete container's root directory %s: %s", cont_root_path, tmp_err); - lcrd_set_error_message("Failed to delete container's root directory %s: %s", cont_root_path, tmp_err); - ret = -1; - goto out; - } - } else { - ERROR("Runtime remove container failed"); - ret = -1; - goto out; - } + rt_rm_params_t params = { 0 }; + + params.rootpath = rootpath; + + if (runtime_rm(id, runtime, ¶ms)) { + ERROR("Runtime remove container failed"); + ret = -1; + goto out; } + out: return ret; } diff --git a/src/services/execution/execute/execution.h b/src/services/execution/execute/execution.h index b6c7792..c3f9250 100644 --- a/src/services/execution/execute/execution.h +++ b/src/services/execution/execute/execution.h @@ -41,3 +41,4 @@ int set_container_to_removal(const container_t *cont); #endif #endif + diff --git a/src/services/execution/execute/execution_create.c b/src/services/execution/execute/execution_create.c index 30b4f27..0d8d942 100644 --- a/src/services/execution/execute/execution_create.c +++ b/src/services/execution/execute/execution_create.c @@ -38,7 +38,7 @@ #include "verify.h" #include "containers_store.h" #include "execution_network.h" -#include "runtime_interface.h" +#include "runtime.h" #include "plugin.h" #include "image.h" #include "utils.h" @@ -864,6 +864,8 @@ int container_create_cb(const container_create_request *request, container_custom_config *custom_spec = NULL; container_config_v2_common_config *v2_spec = NULL; host_config_host_channel *host_channel = NULL; + rt_create_params_t create_params = { 0 }; + rt_rm_params_t delete_params = { 0 }; DAEMON_CLEAR_ERRMSG(); @@ -923,7 +925,10 @@ int container_create_cb(const container_create_request *request, goto clean_rootfs; } - if (runtime_create(id, runtime, real_rootfs, oci_config_data) != 0) { + create_params.real_rootfs = real_rootfs; + create_params.oci_config_data = oci_config_data; + + if (runtime_create(id, runtime, &create_params) != 0) { ERROR("Runtime create container failed"); cc = LCRD_ERR_EXEC; goto clean_rootfs; @@ -944,7 +949,8 @@ int container_create_cb(const container_create_request *request, goto pack_response; clean_on_error: - (void)runtime_rm(id, runtime, runtime_root); + delete_params.rootpath = runtime_root; + (void)runtime_rm(id, runtime, &delete_params); clean_rootfs: (void)im_remove_container_rootfs(image_type, id); diff --git a/src/services/execution/execute/execution_create.h b/src/services/execution/execute/execution_create.h index 1fc11c4..73d5230 100644 --- a/src/services/execution/execute/execution_create.h +++ b/src/services/execution/execute/execution_create.h @@ -33,3 +33,4 @@ void umount_host_channel(const host_config_host_channel *host_channel); #endif #endif + diff --git a/src/services/execution/execute/execution_extend.c b/src/services/execution/execute/execution_extend.c index 50f11e8..1f92236 100644 --- a/src/services/execution/execute/execution_extend.c +++ b/src/services/execution/execute/execution_extend.c @@ -42,10 +42,7 @@ #include "execution_extend.h" #include "sysinfo.h" #include "health_check.h" - -#ifdef ENABLE_OCI_IMAGE -#include "oci_rootfs_export.h" -#endif +#include "runtime.h" #include "filters.h" #include "utils.h" @@ -526,38 +523,11 @@ pack_response: return (cc == LCRD_SUCCESS) ? 0 : -1; } -static int runtime_resume(const char *id, const char *runtime, const char *rootpath) -{ - int ret = 0; - struct engine_operation *engine_ops = NULL; - - engine_ops = engines_get_handler(runtime); - if (engine_ops == NULL || engine_ops->engine_resume_op == NULL) { - DEBUG("Failed to get engine resume operations"); - ret = -1; - goto out; - } - - if (!engine_ops->engine_resume_op(id, rootpath)) { - DEBUG("Resume container %s failed", id); - const char *tmpmsg = NULL; - tmpmsg = engine_ops->engine_get_errmsg_op(); - lcrd_set_error_message("Resume container error;%s", - (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg - : DEF_ERR_RUNTIME_STR); - - engine_ops->engine_clear_errmsg_op(); - ret = -1; - goto out; - } -out: - return ret; -} - static int resume_container(container_t *cont) { int ret = 0; const char *id = cont->common_config->id; + rt_resume_params_t params = { 0 }; container_lock(cont); @@ -575,7 +545,9 @@ static int resume_container(container_t *cont) goto out; } - if (runtime_resume(id, cont->runtime, cont->root_path)) { + params.rootpath = cont->root_path; + + if (runtime_resume(id, cont->runtime, ¶ms)) { ERROR("Failed to resume container:%s", id); ret = -1; goto out; @@ -598,8 +570,7 @@ out: static int oci_image_export_rootfs(const char *id, const char *file) { int ret = 0; - rootfs_export_request *request = NULL; - rootfs_export_response *response = NULL; + im_export_request *request = NULL; if (id == NULL || file == NULL) { ERROR("Invalid input arguments"); @@ -607,26 +578,24 @@ static int oci_image_export_rootfs(const char *id, const char *file) goto out; } - request = util_common_calloc_s(sizeof(rootfs_export_request)); + request = util_common_calloc_s(sizeof(im_export_request)); if (request == NULL) { ERROR("Memory out"); ret = -1; goto out; } - request->id = util_strdup_s(id); + request->name_id = util_strdup_s(id); request->file = util_strdup_s(file); + request->type = util_strdup_s(IMAGE_TYPE_OCI); - ret = export_rootfs(request, &response); + ret = im_container_export(request); if (ret != 0) { ERROR("Failed to export rootfs to %s from container %s", file, id); - ret = -1; - goto out; } out: - free_rootfs_export_request(request); - free_rootfs_export_response(response); + free_im_export_request(request); return ret; } #endif @@ -732,36 +701,11 @@ pack_response: return (cc == LCRD_SUCCESS) ? 0 : -1; } -static int runtime_pause(const char *id, const char *runtime, const char *rootpath) -{ - int ret = 0; - struct engine_operation *engine_ops = NULL; - - engine_ops = engines_get_handler(runtime); - if (engine_ops == NULL || engine_ops->engine_pause_op == NULL) { - DEBUG("Failed to get engine pause operations"); - ret = -1; - goto out; - } - - if (!engine_ops->engine_pause_op(id, rootpath)) { - DEBUG("Pause container %s failed", id); - const char *tmpmsg = NULL; - tmpmsg = engine_ops->engine_get_errmsg_op(); - lcrd_set_error_message("Pause container error;%s", (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? - tmpmsg : DEF_ERR_RUNTIME_STR); - engine_ops->engine_clear_errmsg_op(); - ret = -1; - goto out; - } -out: - return ret; -} - static int pause_container(container_t *cont) { int ret = 0; const char *id = cont->common_config->id; + rt_pause_params_t params = { 0 }; container_lock(cont); @@ -786,7 +730,9 @@ static int pause_container(container_t *cont) goto out; } - if (runtime_pause(id, cont->runtime, cont->root_path)) { + params.rootpath = cont->root_path; + + if (runtime_pause(id, cont->runtime, ¶ms)) { ERROR("Failed to pause container:%s", id); ret = -1; goto out; diff --git a/src/services/execution/execute/execution_extend.h b/src/services/execution/execute/execution_extend.h index ff6f3aa..29e7cdb 100644 --- a/src/services/execution/execute/execution_extend.h +++ b/src/services/execution/execute/execution_extend.h @@ -30,3 +30,4 @@ void container_extend_callback_init(service_container_callback_t *cb); #endif #endif + diff --git a/src/services/execution/execute/execution_information.c b/src/services/execution/execute/execution_information.c index 46afc5e..ba79509 100644 --- a/src/services/execution/execute/execution_information.c +++ b/src/services/execution/execute/execution_information.c @@ -40,12 +40,8 @@ #include "sysinfo.h" #include "read_file.h" -#ifdef ENABLE_OCI_IMAGE -#include "oci_images_store.h" -#endif - #include "container_state.h" -#include "runtime_interface.h" +#include "runtime.h" #include "list.h" #include "utils.h" #include "error.h" @@ -201,6 +197,7 @@ static int isulad_info_cb(const host_info_request *request, host_info_response * char *operating_system = NULL; char *huge_page_size = NULL; struct utsname u; + im_image_count_request *im_request = NULL; DAEMON_CLEAR_ERRMSG(); @@ -222,9 +219,18 @@ static int isulad_info_cb(const host_info_request *request, host_info_response * cc = LCRD_ERR_EXEC; goto pack_response; } + + im_request = util_common_calloc_s(sizeof(im_image_count_request)); + if (im_request == NULL) { + ERROR("Out of memory"); + cc = LCRD_ERR_MEMOUT; + goto pack_response; + } #ifdef ENABLE_OCI_IMAGE - images_num = oci_images_store_size(); + im_request->type = util_strdup_s(IMAGE_TYPE_OCI); #endif + images_num = im_get_image_count(im_request); + operating_system = get_operating_system(); if (operating_system == NULL) { ERROR("Failed to get operating system info!"); @@ -302,6 +308,7 @@ pack_response: } free(huge_page_size); free(operating_system); + free_im_image_count_request(im_request); free_log_prefix(); DAEMON_CLEAR_ERRMSG(); return (cc == LCRD_SUCCESS) ? 0 : -1; @@ -999,7 +1006,7 @@ out: return ret; } -static int dup_container_config(const container_config *src, container_inspect_config *dest) +static int dup_container_config(const char *image, const container_config *src, container_inspect_config *dest) { int ret = 0; @@ -1010,6 +1017,7 @@ static int dup_container_config(const container_config *src, container_inspect_c dest->hostname = src->hostname ? util_strdup_s(src->hostname) : util_strdup_s(""); dest->user = src->user ? util_strdup_s(src->user) : util_strdup_s(""); dest->tty = src->tty; + dest->image = image ? util_strdup_s(image) : util_strdup_s("none"); if (dup_container_config_env(src, dest) != 0) { ret = -1; @@ -1036,6 +1044,7 @@ static int dup_container_config(const container_config *src, container_inspect_c ret = -1; goto out; } + out: return ret; } @@ -1147,6 +1156,92 @@ out: return ret; } +static int inspect_image(const char *image, imagetool_image **result) +{ + int ret = 0; + im_status_request *request = NULL; + im_status_response *response = NULL; + + if (image == NULL) { + ERROR("Empty image name or id"); + return -1; + } + + request = (im_status_request *)util_common_calloc_s(sizeof(im_status_request)); + if (request == NULL) { + ERROR("Out of memory"); + return -1; + } + request->image.image = util_strdup_s(image); + + if (im_image_status(request, &response) != 0) { + if (response != NULL && response->errmsg != NULL) { + ERROR("failed to inspect inspect image info: %s", response->errmsg); + } else { + ERROR("Failed to call status image"); + } + ret = -1; + goto cleanup; + } + + if (response->image_info != NULL) { + *result = response->image_info->image; + response->image_info->image = NULL; + } + +cleanup: + free_im_status_request(request); + free_im_status_response(response); + return ret; +} + +static int pack_inspect_general_image_data(const char *image, container_inspect *inspect) +{ + int ret = 0; + imagetool_image *ir = NULL; + size_t len = 0; + char *image_data = NULL; + + if (image == NULL || strcmp(image, "none") == 0) { + inspect->image = util_strdup_s("none"); + return 0; + } + + if (inspect_image(image, &ir) != 0) { + ERROR("Failed to inspect image status"); + ret = -1; + goto out; + } + + if (strlen(ir->id) > SIZE_MAX / sizeof(char) - strlen("sha256:")) { + ERROR("Invalid image id"); + ret = -1; + goto out; + } + + len = strlen("sha256:") + strlen(ir->id) + 1; + image_data = (char *)util_common_calloc_s(len * sizeof(char)); + if (image_data == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + if (sprintf_s(image_data, len, "sha256:%s", ir->id) < 0) { + ERROR("Failed to sprintf string"); + ret = -1; + goto out; + } + + inspect->image = image_data; + image_data = NULL; + +out: + free_imagetool_image(ir); + free(image_data); + return ret; +} + static int pack_inspect_general_data(const container_t *cont, container_inspect *inspect) { int ret = 0; @@ -1163,7 +1258,11 @@ static int pack_inspect_general_data(const container_t *cont, container_inspect goto out; } - inspect->image = cont->common_config->image ? util_strdup_s(cont->common_config->image) : util_strdup_s("none"); + if (pack_inspect_general_image_data(cont->common_config->image, inspect) != 0) { + ERROR("Failed to pack image info"); + ret = -1; + goto out; + } if (cont->common_config->log_path != NULL) { inspect->log_path = util_strdup_s(cont->common_config->log_path); @@ -1181,6 +1280,7 @@ static int pack_inspect_general_data(const container_t *cont, container_inspect ret = -1; goto out; } + out: return ret; } @@ -1196,7 +1296,7 @@ static int pack_inspect_config(const container_t *cont, container_inspect *inspe goto out; } - if (dup_container_config(cont->common_config->config, inspect->config) != 0) { + if (dup_container_config(cont->common_config->image, cont->common_config->config, inspect->config) != 0) { ERROR("Failed to dup container config"); ret = -1; goto out; @@ -1524,6 +1624,7 @@ static int container_conf_cb(const struct lcrd_container_conf_request *request, struct engine_operation *engine_ops = NULL; struct engine_console_config config = { 0 }; container_t *cont = NULL; + rt_get_console_conf_params_t params = { 0 }; DAEMON_CLEAR_ERRMSG(); if (request == NULL || response == NULL) { @@ -1561,7 +1662,10 @@ static int container_conf_cb(const struct lcrd_container_conf_request *request, id = cont->common_config->id; set_log_prefix(id); - if (runtime_get_console_config(id, cont->runtime, cont->root_path, &config) != 0) { + params.rootpath = cont->root_path; + params.config = &config; + + if (runtime_get_console_config(id, cont->runtime, ¶ms) != 0) { cc = LCRD_ERR_EXEC; goto pack_response; } diff --git a/src/services/execution/execute/execution_information.h b/src/services/execution/execute/execution_information.h index dec1fbd..3ac74dd 100644 --- a/src/services/execution/execute/execution_information.h +++ b/src/services/execution/execute/execution_information.h @@ -29,3 +29,4 @@ void container_information_callback_init(service_container_callback_t *cb); #endif #endif + diff --git a/src/services/execution/execute/execution_network.c b/src/services/execution/execute/execution_network.c index 6bf6162..43be0fb 100644 --- a/src/services/execution/execute/execution_network.c +++ b/src/services/execution/execute/execution_network.c @@ -34,25 +34,16 @@ #include "config.h" #include "containers_store.h" #include "namespace.h" +#include "path.h" static int write_hostname_to_file(const char *rootfs, const char *hostname) { int ret = 0; - size_t path_len = 0; char *file_path = NULL; - path_len = strlen(rootfs) + strlen("/etc/hostname") + 1; - if (path_len > PATH_MAX) { - ERROR("Invalid path length"); - return -1; - } - file_path = util_common_calloc_s(path_len); - if (file_path == NULL) { - ERROR("Failed to malloc hostname path memory"); - return -1; - } - if (sprintf_s(file_path, path_len, "%s%s", rootfs, "/etc/hostname") < 0) { - ERROR("Failed to print string"); + if (realpath_in_scope(rootfs, "/etc/hostname", &file_path) < 0) { + SYSERROR("Failed to get real path '/etc/hostname' under rootfs '%s'", rootfs); + lcrd_set_error_message("Failed to get real path '/etc/hostname' under rootfs '%s'", rootfs); goto error_out; } if (hostname != NULL) { @@ -71,18 +62,9 @@ error_out: static int fopen_network(FILE **fp, char **file_path, const char *rootfs, const char *filename) { - size_t path_len = strlen(rootfs) + strlen(filename) + 1; - if (path_len > PATH_MAX) { - ERROR("Invalid path length"); - return -1; - } - *file_path = util_common_calloc_s(path_len); - if (*file_path == NULL) { - ERROR("Failed to malloc network path memory"); - return -1; - } - if (sprintf_s(*file_path, path_len, "%s%s", rootfs, filename) < 0) { - ERROR("Failed to print string"); + if (realpath_in_scope(rootfs, filename, file_path) < 0) { + SYSERROR("Failed to get real path '%s' under rootfs '%s'", filename, rootfs); + lcrd_set_error_message("Failed to get real path '%s' under rootfs '%s'", filename, rootfs); return -1; } *fp = util_fopen(*file_path, "a+"); @@ -315,7 +297,7 @@ static int merge_dns_search(const host_config *host_spec, char **content, const } } } - if (strlen(*content) > content_len) { + if (*content != NULL && strlen(*content) > content_len) { (*content)[strlen(*content) - 1] = '\n'; } @@ -373,7 +355,7 @@ static int merge_dns_options(const host_config *host_spec, char **content, const } } } - if (strlen(*content) > content_len) { + if (*content != NULL && strlen(*content) > content_len) { (*content)[strlen(*content) - 1] = '\n'; } @@ -905,3 +887,4 @@ int container_initialize_networking(const container_t *cont) return ret; } + diff --git a/src/services/execution/execute/execution_network.h b/src/services/execution/execute/execution_network.h index 512d51c..d4f76ee 100644 --- a/src/services/execution/execute/execution_network.h +++ b/src/services/execution/execute/execution_network.h @@ -35,3 +35,4 @@ int init_container_network_confs(const char *id, const char *rootpath, const hos #endif #endif + diff --git a/src/services/execution/execute/execution_stream.c b/src/services/execution/execute/execution_stream.c index a7e763f..6cb4c0d 100644 --- a/src/services/execution/execute/execution_stream.c +++ b/src/services/execution/execute/execution_stream.c @@ -45,6 +45,7 @@ #include "error.h" #include "logger_json_file.h" #include "constants.h" +#include "runtime.h" static char *create_single_fifo(const char *statepath, const char *subpath, const char *stdflag) { @@ -248,81 +249,15 @@ out: return ret; } -static int runtime_exec(const char *id, const char *runtime, const char *rootpath, const char *engine_log_path, - const char *loglevel, const char *console_fifos[], char * const argv[], - char * const env[], int64_t timeout, pid_t *pid, int *exit_code) -{ - int ret = 0; - struct engine_operation *engine_ops = NULL; - - engine_ops = engines_get_handler(runtime); - if (engine_ops == NULL || engine_ops->engine_exec_op == NULL) { - DEBUG("Failed to get engine exec operations"); - ret = -1; - goto out; - } - - if (!engine_ops->engine_exec_op(id, rootpath, engine_log_path, loglevel, - console_fifos, argv, env, timeout, pid, exit_code)) { - const char *tmpmsg = NULL; - tmpmsg = engine_ops->engine_get_errmsg_op(); - lcrd_set_error_message("Exec container error;%s", (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? - tmpmsg : DEF_ERR_RUNTIME_STR); - util_contain_errmsg(g_lcrd_errmsg, exit_code); - engine_ops->engine_clear_errmsg_op(); - ret = -1; - goto out; - } - -out: - return ret; -} - -static int exec_container(container_t *cont, const char *runtime, char * const console_fifos[], +static int exec_container(container_t *cont, const char *runtime, char * const console_fifos[], const char *user, size_t argc, const char **argv, size_t env_len, const char **env, - int64_t timeout, pid_t *pid, int *exit_code) + int64_t timeout, int *exit_code) { int ret = 0; - size_t i, tmp_env_len, tmp_argc; char *engine_log_path = NULL; char *loglevel = NULL; char *logdriver = NULL; - const char **tmp_argv = NULL; - const char **tmp_env = NULL; - - // Append null pointer to end of argv - tmp_argc = argc + 1; - if (tmp_argc > SIZE_MAX / sizeof(char *)) { - ERROR("Too many parameters!"); - return -1; - } - tmp_argv = util_common_calloc_s(tmp_argc * sizeof(char *)); - if (tmp_argv == NULL) { - FATAL("out of memory"); - return -1; - } - - for (i = 0; i < tmp_argc - 1; i++) { - tmp_argv[i] = argv[i]; - } - - // Append null pointer to end of env - tmp_env_len = env_len + 1; - if (tmp_env_len > SIZE_MAX / sizeof(char *)) { - ERROR("The environment variable length is too long!"); - ret = -1; - goto out; - } - tmp_env = util_common_calloc_s(tmp_env_len * sizeof(char *)); - if (tmp_env == NULL) { - FATAL("out of memory"); - ret = -1; - goto out; - } - - for (i = 0; i < tmp_env_len - 1; i++) { - tmp_env[i] = env[i]; - } + rt_exec_params_t params = { 0 }; loglevel = conf_get_lcrd_loglevel(); if (loglevel == NULL) { @@ -343,9 +278,18 @@ static int exec_container(container_t *cont, const char *runtime, char * const c goto out; } - if (runtime_exec(cont->common_config->id, runtime, cont->root_path, engine_log_path, loglevel, - (const char **)console_fifos, (char * const *)tmp_argv, - (char * const *)tmp_env, timeout, pid, exit_code)) { + params.loglevel = loglevel; + params.logpath = engine_log_path; + params.console_fifos = (const char **)console_fifos; + params.rootpath = cont->root_path; + params.timeout = timeout; + params.user = user; + params.args = (const char * const *)argv; + params.args_len = argc; + params.envs = (const char * const *)env; + params.envs_len = env_len; + + if (runtime_exec(cont->common_config->id, runtime, ¶ms, exit_code)) { ERROR("Runtime exec container failed"); ret = -1; goto out; @@ -355,8 +299,6 @@ out: free(loglevel); free(engine_log_path); free(logdriver); - free(tmp_argv); - free(tmp_env); return ret; } @@ -433,12 +375,11 @@ out: return ret; } -static void container_exec_cb_end(container_exec_response *response, uint32_t cc, pid_t pid, int exit_code, int sync_fd, +static void container_exec_cb_end(container_exec_response *response, uint32_t cc, int exit_code, int sync_fd, pthread_t thread_id) { if (response != NULL) { response->cc = cc; - response->pid = pid; response->exit_code = (uint32_t)exit_code; if (g_lcrd_errmsg != NULL) { response->errmsg = util_strdup_s(g_lcrd_errmsg); @@ -460,18 +401,112 @@ static void container_exec_cb_end(container_exec_response *response, uint32_t cc } } +static int get_user_and_groups_conf(const container_t *cont, const char *username, + oci_runtime_spec_process_user **puser) +{ + int ret = -1; + if (username == NULL) { + return 0; + } + + if (cont == NULL || cont->common_config == NULL) { + ERROR("Can not found container config"); + return -1; + } + + *puser = util_common_calloc_s(sizeof(oci_runtime_spec_process_user)); + if (*puser == NULL) { + ERROR("Out of memory"); + return -1; + } + + ret = im_get_user_conf(cont->common_config->image_type, cont->common_config->base_fs, + cont->hostconfig, username, *puser); + if (ret != 0) { + ERROR("Get user failed with '%s'", username ? username : ""); + free_oci_runtime_spec_process_user(*puser); + *puser = NULL; + } + + return ret; +} + +// user string(UID:GID) +static int generate_user_string_by_uid_gid(const oci_runtime_spec_process_user *puser, char **user) +{ + char uid_str[LCRD_NUMSTRLEN32] = { 0 }; + char gid_str[LCRD_NUMSTRLEN32] = { 0 }; + size_t len; + + if (sprintf_s(uid_str, LCRD_NUMSTRLEN32, "%u", (unsigned int)puser->uid) < 0) { + ERROR("Invalid UID:%u", (unsigned int)puser->uid); + return -1; + } + + if (sprintf_s(gid_str, LCRD_NUMSTRLEN32, "%u", (unsigned int)puser->gid) < 0) { + ERROR("Invalid attach uid value :%u", (unsigned int)puser->gid); + return -1; + } + + len = strlen(uid_str) + 1 + strlen(gid_str) + 1; + *user = (char *)util_common_calloc_s(len * sizeof(char)); + if (*user == NULL) { + ERROR("Out of memory"); + return -1; + } + + if (sprintf_s(*user, len, "%u:%u", (unsigned int)puser->uid, (unsigned int)puser->gid) < 0) { + ERROR("Invalid UID:GID (%u:%u)", (unsigned int)puser->uid, (unsigned int)puser->gid); + free(*user); + *user = NULL; + return -1; + } + + return 0; +} + +static int get_exec_user_string(const container_t *cont, const char *username, char **user) +{ + int ret = 0; + oci_runtime_spec_process_user *puser = NULL; + + if (username == NULL) { + return 0; + } + + if (cont == NULL || user == NULL) { + ERROR("Invalid parameters"); + return -1; + } + + if (get_user_and_groups_conf(cont, username, &puser) != 0) { + ERROR("Failed to get user and groups conf"); + ret = -1; + goto out; + } + + if (generate_user_string_by_uid_gid(puser, user) != 0) { + ret = -1; + goto out; + } + +out: + free_oci_runtime_spec_process_user(puser); + return ret; +} + static int container_exec_cb(const container_exec_request *request, container_exec_response **response, int stdinfd, struct io_write_wrapper *stdout_handler) { int exit_code = 0; int sync_fd = -1; - pid_t pid = -1; uint32_t cc = LCRD_SUCCESS; char *id = NULL; char *fifos[3] = { NULL, NULL, NULL }; char *fifopath = NULL; pthread_t thread_id = 0; container_t *cont = NULL; + char *user = NULL; DAEMON_CLEAR_ERRMSG(); if (request == NULL || response == NULL) { @@ -483,8 +518,13 @@ static int container_exec_cb(const container_exec_request *request, container_ex goto pack_response; } id = cont->common_config->id; - set_log_prefix(id); + if (get_exec_user_string(cont, request->user, &user) != 0) { + cc = LCRD_ERR_EXEC; + goto pack_response; + } + + set_log_prefix(id); EVENT("Event: {Object: %s, Type: execing}", id); if (gc_is_gc_progress(id)) { @@ -494,14 +534,35 @@ static int container_exec_cb(const container_exec_request *request, container_ex goto pack_response; } + if (!is_running(cont->state)) { + ERROR("Container %s is not running", id); + lcrd_set_error_message("Container %s is not running", id); + cc = LCRD_ERR_EXEC; + goto pack_response; + } + + if (is_paused(cont->state)) { + ERROR("Container %s ispaused, unpause the container before exec", id); + lcrd_set_error_message("Container %s paused, unpause the container before exec", id); + cc = LCRD_ERR_EXEC; + goto pack_response; + } + + if (is_restarting(cont->state)) { + ERROR("Container %s is currently restarting, wait until the container is running", id); + lcrd_set_error_message("Container %s is currently restarting, wait until the container is running", id); + cc = LCRD_ERR_EXEC; + goto pack_response; + } + if (exec_prepare_console(cont, request, stdinfd, stdout_handler, fifos, &fifopath, &sync_fd, &thread_id)) { cc = LCRD_ERR_EXEC; goto pack_response; } - if (exec_container(cont, cont->runtime, (char * const *)fifos, request->argv_len, + if (exec_container(cont, cont->runtime, (char * const *)fifos, user, request->argv_len, (const char **)request->argv, request->env_len, - (const char **)request->env, request->timeout, &pid, &exit_code)) { + (const char **)request->env, request->timeout, &exit_code)) { cc = LCRD_ERR_EXEC; goto pack_response; } @@ -509,12 +570,13 @@ static int container_exec_cb(const container_exec_request *request, container_ex EVENT("Event: {Object: %s, Type: execed}", id); pack_response: - container_exec_cb_end(*response, cc, pid, exit_code, sync_fd, thread_id); + container_exec_cb_end(*response, cc, exit_code, sync_fd, thread_id); delete_daemon_fifos(fifopath, (const char **)fifos); free(fifos[0]); free(fifos[1]); free(fifos[2]); free(fifopath); + free(user); container_unref(cont); free_log_prefix(); @@ -941,6 +1003,58 @@ static container_path_stat *resolve_and_stat_path(const char *rootpath, const ch return stat; } +static int pause_container(const container_t *cont) +{ + int ret = 0; + rt_pause_params_t params = { 0 }; + const char *id = cont->common_config->id; + + params.rootpath = cont->root_path; + + if (runtime_pause(id, cont->runtime, ¶ms)) { + ERROR("Failed to pause container:%s", id); + ret = -1; + goto out; + } + + state_set_paused(cont->state); + + if (container_to_disk(cont)) { + ERROR("Failed to save container \"%s\" to disk", id); + ret = -1; + goto out; + } + +out: + return ret; +} + +static int resume_container(const container_t *cont) +{ + int ret = 0; + rt_resume_params_t params = { 0 }; + const char *id = cont->common_config->id; + + params.rootpath = cont->root_path; + + if (runtime_resume(id, cont->runtime, ¶ms)) { + ERROR("Failed to resume container:%s", id); + ret = -1; + goto out; + } + + state_reset_paused(cont->state); + + if (container_to_disk(cont)) { + ERROR("Failed to save container \"%s\" to disk", id); + ret = -1; + goto out; + } + +out: + return ret; +} + static int copy_from_container_cb(const struct lcrd_copy_from_container_request *request, const stream_func_wrapper *stream, char **err) { @@ -951,6 +1065,7 @@ static int copy_from_container_cb(const struct lcrd_copy_from_container_request container_path_stat *stat = NULL; container_t *cont = NULL; struct lcrd_copy_from_container_response *response = NULL; + bool need_pause = false; DAEMON_CLEAR_ERRMSG(); if (request == NULL || stream == NULL || err == NULL) { @@ -970,10 +1085,19 @@ static int copy_from_container_cb(const struct lcrd_copy_from_container_request goto unlock_container; } + need_pause = is_running(cont->state) && !is_paused(cont->state); + if (need_pause) { + if (pause_container(cont) != 0) { + ERROR("can't copy to a container which is cannot be paused"); + lcrd_set_error_message("can't copy to a container which is cannot be paused"); + goto unlock_container; + } + } + nret = im_mount_container_rootfs(cont->common_config->image_type, cont->common_config->image, cont->common_config->id); if (nret != 0) { - goto unlock_container; + goto unpause_container; } stat = resolve_and_stat_path(cont->common_config->base_fs, request->srcpath, &resolvedpath, &abspath); @@ -1000,6 +1124,10 @@ cleanup_rootfs: cont->common_config->id) != 0) { WARN("Can not umount rootfs of container: %s", cont->common_config->id); } +unpause_container: + if (need_pause && resume_container(cont) != 0) { + ERROR("can't resume container which has been paused before copy"); + } unlock_container: container_unlock(cont); container_unref(cont); @@ -1224,6 +1352,7 @@ static int copy_to_container_cb(const container_copy_to_request *request, char *dstdir = NULL; char *transform = NULL; container_t *cont = NULL; + bool need_pause = false; DAEMON_CLEAR_ERRMSG(); if (request == NULL || stream == NULL || err == NULL) { @@ -1243,10 +1372,19 @@ static int copy_to_container_cb(const container_copy_to_request *request, goto unlock_container; } + need_pause = is_running(cont->state) && !is_paused(cont->state); + if (need_pause) { + if (pause_container(cont) != 0) { + ERROR("can't copy to a container which is cannot be paused"); + lcrd_set_error_message("can't copy to a container which is cannot be paused"); + goto unlock_container; + } + } + nret = im_mount_container_rootfs(cont->common_config->image_type, cont->common_config->image, cont->common_config->id); if (nret != 0) { - goto unlock_container; + goto unpause_container; } dstdir = copy_to_container_get_dstdir(cont, request, &transform); @@ -1271,11 +1409,18 @@ static int copy_to_container_cb(const container_copy_to_request *request, } ret = 0; + cleanup_rootfs: if (im_umount_container_rootfs(cont->common_config->image_type, cont->common_config->image, cont->common_config->id) != 0) { WARN("Can not umount rootfs of container: %s", cont->common_config->id); } + +unpause_container: + if (need_pause && resume_container(cont) != 0) { + ERROR("can't resume container which has been paused before copy"); + } + unlock_container: container_unlock(cont); container_unref(cont); diff --git a/src/services/execution/execute/list.c b/src/services/execution/execute/list.c index e97c90c..71fdb37 100644 --- a/src/services/execution/execute/list.c +++ b/src/services/execution/execute/list.c @@ -451,12 +451,11 @@ static int fill_lcrdinfo(container_container *lcrdinfo, const container_config_v char *image = NULL; char *timestr = NULL; char *defvalue = "-"; + int64_t created_nanos = 0; - if (cont->common_config != NULL) { - ret = convert_common_config_info(map_labels, cont->common_config, lcrdinfo); - if (ret != 0) { - goto out; - } + ret = convert_common_config_info(map_labels, cont->common_config, lcrdinfo); + if (ret != 0) { + goto out; } lcrdinfo->pid = (int32_t)cont_state->pid; @@ -477,6 +476,14 @@ static int fill_lcrdinfo(container_container *lcrdinfo, const container_config_v lcrdinfo->runtime = cont->runtime ? util_strdup_s(cont->runtime) : util_strdup_s("none"); lcrdinfo->health_state = container_get_health_state(cont_state); + if (cont->common_config->created != NULL) { + ret = to_unix_nanos_from_str(cont->common_config->created, &created_nanos); + if (ret != 0) { + goto out; + } + } + + lcrdinfo->created = created_nanos; out: return ret; @@ -635,7 +642,7 @@ static int pack_list_containers(char **idsarray, const struct list_context *ctx, ret = -1; goto out; } - j = 0; + while (idsarray != NULL && idsarray[j] != NULL) { response->containers[response->containers_len] = get_container_info(idsarray[j], ctx); if (response->containers[response->containers_len] == NULL) { diff --git a/src/services/execution/execute/list.h b/src/services/execution/execute/list.h index 40ef873..944e90f 100644 --- a/src/services/execution/execute/list.h +++ b/src/services/execution/execute/list.h @@ -31,3 +31,4 @@ int container_list_cb(const container_list_request *request, container_list_resp #endif #endif + diff --git a/src/services/execution/execute/runtime_interface.c b/src/services/execution/execute/runtime_interface.c deleted file mode 100644 index e090ae8..0000000 --- a/src/services/execution/execute/runtime_interface.c +++ /dev/null @@ -1,248 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: tanyifeng - * Create: 2017-11-22 - * Description: provide container list callback function definition - ********************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "engine.h" -#include "callback.h" -#include "runtime_interface.h" -#include "error.h" -#include "lcrd_config.h" - -int runtime_create(const char *name, const char *runtime, const char *rootfs, void *oci_config_data) -{ - int ret = 0; - char *runtime_root = NULL; - struct engine_operation *engine_ops = NULL; - - runtime_root = conf_get_routine_rootdir(runtime); - if (runtime_root == NULL) { - ERROR("Root path is NULL"); - ret = -1; - goto out; - } - - engine_ops = engines_get_handler(runtime); - if (engine_ops == NULL || engine_ops->engine_create_op == NULL) { - ERROR("Failed to get engine create operations"); - ret = -1; - goto out; - } - - if (!engine_ops->engine_create_op(name, runtime_root, rootfs, NULL, - (void *)oci_config_data)) { - ERROR("Failed to create container"); - const char *tmpmsg = NULL; - tmpmsg = engine_ops->engine_get_errmsg_op(); - lcrd_set_error_message("Create container error: %s", - (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg - : DEF_ERR_RUNTIME_STR); - engine_ops->engine_clear_errmsg_op(); - ret = -1; - goto out; - } - -out: - free(runtime_root); - return ret; -} - -int runtime_start(const char *name, const char *runtime, const char *rootpath, bool tty, bool interactive, - const char *engine_log_path, const char *loglevel, const char *console_fifos[], - const char *share_ns[], unsigned int start_timeout, const char *pidfile, const char *exit_fifo, - const oci_runtime_spec_process_user *puser) -{ - int ret = 0; - struct engine_operation *engine_ops = NULL; - engine_start_request_t request = { 0 }; - - engine_ops = engines_get_handler(runtime); - if (engine_ops == NULL || engine_ops->engine_start_op == NULL) { - ERROR("Failed to get engine start operations"); - ret = -1; - goto out; - } - - request.name = name; - request.lcrpath = rootpath; - request.logpath = engine_log_path; - request.loglevel = loglevel; - request.daemonize = true; - request.tty = tty; - request.open_stdin = interactive; - request.pidfile = NULL; - request.console_fifos = console_fifos; - request.console_logpath = NULL; - request.share_ns = (const char **)share_ns; - request.start_timeout = start_timeout; - request.container_pidfile = pidfile; - request.exit_fifo = exit_fifo; - if (puser != NULL) { - request.uid = puser->uid; - request.gid = puser->gid; - request.additional_gids = puser->additional_gids; - request.additional_gids_len = puser->additional_gids_len; - } - if (!engine_ops->engine_start_op(&request)) { - const char *tmpmsg = NULL; - tmpmsg = engine_ops->engine_get_errmsg_op(); - lcrd_set_error_message("Start container error: %s", - (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg - : DEF_ERR_RUNTIME_STR); - ERROR("Start container error: %s", (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg - : DEF_ERR_RUNTIME_STR); - engine_ops->engine_clear_errmsg_op(); - ret = -1; - goto out; - } -out: - return ret; -} - -int runtime_restart(const char *name, const char *runtime, const char *rootpath) -{ - int ret = 0; - struct engine_operation *engine_ops = NULL; - - engine_ops = engines_get_handler(runtime); - if (engine_ops == NULL || engine_ops->engine_reset_op == NULL) { - ERROR("Get reset operation failed"); - ret = -2; - goto out; - } - - if (!engine_ops->engine_reset_op(name, rootpath)) { - ERROR("Reset operate failed"); - if (engine_ops->engine_get_errmsg_op != NULL) { - const char *tmpmsg = NULL; - tmpmsg = engine_ops->engine_get_errmsg_op(); - lcrd_set_error_message("Restart container error: %s", - (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg - : DEF_ERR_RUNTIME_STR); - if (engine_ops->engine_clear_errmsg_op != NULL) { - engine_ops->engine_clear_errmsg_op(); - } - } - ret = -1; - } -out: - return ret; -} - -int runtime_clean_resource(const char *name, const char *runtime, const char *rootpath, - const char *engine_log_path, const char *loglevel, pid_t pid) -{ - int ret = 0; - struct engine_operation *engine_ops = NULL; - - engine_ops = engines_get_handler(runtime); - if (engine_ops == NULL || engine_ops->engine_clean_op == NULL) { - ERROR("Failed to get engine clean operations"); - ret = -1; - goto out; - } - - if (!engine_ops->engine_clean_op(name, rootpath, engine_log_path, loglevel, pid)) { - const char *tmpmsg = NULL; - tmpmsg = engine_ops->engine_get_errmsg_op(); - lcrd_try_set_error_message("Clean resource container error;%s", - (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg - : DEF_ERR_RUNTIME_STR); - ret = -1; - goto out; - } - -out: - if (engine_ops != NULL) { - engine_ops->engine_clear_errmsg_op(); - } - return ret; -} - -int runtime_rm(const char *name, const char *runtime, const char *rootpath) -{ - int ret = 0; - struct engine_operation *engine_ops = NULL; - - engine_ops = engines_get_handler(runtime); - if (engine_ops == NULL || engine_ops->engine_delete_op == NULL) { - ERROR("Failed to get engine delete operations"); - ret = -1; - goto out; - } - - if (!engine_ops->engine_delete_op(name, rootpath)) { - ERROR("Delete container %s failed", name); - const char *tmpmsg = NULL; - tmpmsg = engine_ops->engine_get_errmsg_op(); - lcrd_set_error_message("Runtime delete container error: %s", - (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? tmpmsg : DEF_ERR_RUNTIME_STR); - - ret = -1; - goto out; - } - -out: - if (engine_ops != NULL) { - engine_ops->engine_clear_errmsg_op(); - } - return ret; -} - -int runtime_get_console_config(const char *name, const char *runtime, const char *rootpath, - struct engine_console_config *config) -{ - int ret = 0; - struct engine_operation *engine_ops = NULL; - - engine_ops = engines_get_handler(runtime); - if (engine_ops == NULL || (engine_ops->engine_get_console_config_op) == NULL) { - ERROR("Failed to get engine get_console_config operation"); - ret = -1; - goto out; - } - - if (!engine_ops->engine_get_console_config_op(name, rootpath, config)) { - ERROR("Failed to get console config"); - const char *tmpmsg = NULL; - tmpmsg = engine_ops->engine_get_errmsg_op(); - lcrd_set_error_message("Get console config error;%s", (tmpmsg && strcmp(tmpmsg, DEF_SUCCESS_STR)) ? - tmpmsg : DEF_ERR_RUNTIME_STR); - ret = -1; - goto out; - } - - -out: - if (engine_ops != NULL) { - engine_ops->engine_clear_errmsg_op(); - } - return ret; -} - diff --git a/src/services/execution/execute/runtime_interface.h b/src/services/execution/execute/runtime_interface.h deleted file mode 100644 index 093ca68..0000000 --- a/src/services/execution/execute/runtime_interface.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Author: tanyifeng - * Create: 2017-11-22 - * Description: provide container list callback function definition - *******************************************************************************/ - -#ifndef __EXECUTION_RUNTIME_INTERFACE_H_ -#define __EXECUTION_RUNTIME_INTERFACE_H_ - -#include "engine.h" -#include "oci_runtime_spec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int runtime_rm(const char *name, const char *runtime, const char *rootpath); -int runtime_clean_resource(const char *name, const char *runtime, const char *rootpath, - const char *engine_log_path, const char *loglevel, pid_t pid); -int runtime_restart(const char *name, const char *runtime, const char *rootpath); - -int runtime_start(const char *name, const char *runtime, const char *rootpath, bool tty, bool interactive, - const char *engine_log_path, const char *loglevel, const char *console_fifos[], - const char *share_ns[], unsigned int start_timeout, const char *pidfile, const char *exit_fifo, - const oci_runtime_spec_process_user *puser); -int runtime_create(const char *name, const char *runtime, const char *rootfs, void *oci_config_data); -int runtime_get_console_config(const char *name, const char *runtime, const char *rootpath, - struct engine_console_config *config); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/services/execution/log_gather.h b/src/services/execution/log_gather.h index 9ada9de..8ce7d37 100644 --- a/src/services/execution/log_gather.h +++ b/src/services/execution/log_gather.h @@ -41,3 +41,4 @@ enum log_gather_driver { void *log_gather(void *arg); #endif + diff --git a/src/services/execution/manager/container_state.c b/src/services/execution/manager/container_state.c index 777272d..0aff72b 100644 --- a/src/services/execution/manager/container_state.c +++ b/src/services/execution/manager/container_state.c @@ -125,7 +125,7 @@ void state_reset_starting(container_state_t *s) container_state_unlock(s); } -/* state set running*/ +/* state set running */ void state_set_running(container_state_t *s, const container_pid_t *pid_info, bool initial) { container_config_v2_state *state = NULL; @@ -169,7 +169,7 @@ void state_set_running(container_state_t *s, const container_pid_t *pid_info, bo container_state_unlock(s); } -/* state reset stopped*/ +/* state reset stopped */ void state_set_stopped(container_state_t *s, int exit_code) { container_config_v2_state *state = NULL; @@ -200,7 +200,7 @@ void state_set_stopped(container_state_t *s, int exit_code) container_state_unlock(s); } -/* state set paused*/ +/* state set paused */ void state_set_paused(container_state_t *s) { container_config_v2_state *state = NULL; @@ -217,7 +217,7 @@ void state_set_paused(container_state_t *s) container_state_unlock(s); } -/* state reset paused*/ +/* state reset paused */ void state_reset_paused(container_state_t *s) { container_config_v2_state *state = NULL; @@ -234,7 +234,7 @@ void state_reset_paused(container_state_t *s) container_state_unlock(s); } -/* update start and finish time*/ +/* update start and finish time */ void update_start_and_finish_time(container_state_t *s, const char *finish_at) { container_config_v2_state *state = NULL; @@ -265,7 +265,7 @@ void update_start_and_finish_time(container_state_t *s, const char *finish_at) return; } -/* state set restarting*/ +/* state set restarting */ void state_set_restarting(container_state_t *s, int exit_code) { container_config_v2_state *state = NULL; @@ -321,7 +321,7 @@ bool state_set_removal_in_progress(container_state_t *s) return ret; } -/* state reset removal in progress*/ +/* state reset removal in progress */ void state_reset_removal_in_progress(container_state_t *s) { if (s == NULL) { @@ -337,7 +337,7 @@ void state_reset_removal_in_progress(container_state_t *s) return; } -/* container state set error*/ +/* container state set error */ void container_state_set_error(container_state_t *s, const char *err) { container_state_lock(s); @@ -348,7 +348,7 @@ void container_state_set_error(container_state_t *s, const char *err) container_state_unlock(s); } -/* state judge status*/ +/* state judge status */ Container_Status state_judge_status(const container_config_v2_state *state) { if (state == NULL) { @@ -393,7 +393,7 @@ const char *state_to_string(Container_Status cs) return state_string[cs]; } -/* state get status*/ +/* state get status */ Container_Status state_get_status(container_state_t *s) { Container_Status status = CONTAINER_STATUS_UNKNOWN; @@ -459,7 +459,7 @@ error: return ret; } -/* state get info*/ +/* state get info */ container_config_v2_state *state_get_info(container_state_t *s) { container_config_v2_state *state = NULL; @@ -502,7 +502,7 @@ container_config_v2_state *state_get_info(container_state_t *s) return state; } -/* state get exitcode*/ +/* state get exitcode */ uint32_t state_get_exitcode(container_state_t *s) { uint32_t exit_code = 0; @@ -522,7 +522,7 @@ uint32_t state_get_exitcode(container_state_t *s) return exit_code; } -/* is running*/ +/* is running */ bool is_running(container_state_t *s) { bool ret = false; @@ -540,7 +540,7 @@ bool is_running(container_state_t *s) return ret; } -/* is restarting*/ +/* is restarting */ bool is_restarting(container_state_t *s) { bool ret = false; @@ -558,7 +558,7 @@ bool is_restarting(container_state_t *s) return ret; } -/* is paused*/ +/* is paused */ bool is_paused(container_state_t *s) { bool ret = false; @@ -576,7 +576,7 @@ bool is_paused(container_state_t *s) return ret; } -/* is removal in progress*/ +/* is removal in progress */ bool is_removal_in_progress(container_state_t *s) { bool ret = false; diff --git a/src/services/execution/manager/container_state.h b/src/services/execution/manager/container_state.h index 9110360..1fd3bf2 100644 --- a/src/services/execution/manager/container_state.h +++ b/src/services/execution/manager/container_state.h @@ -97,3 +97,4 @@ int dup_health_check_status(defs_health **dst, const defs_health *src); #endif #endif /* __LCRD_CONTAINER_STATE_H__ */ + diff --git a/src/services/execution/manager/container_unix.c b/src/services/execution/manager/container_unix.c index 1e5ff16..eb8cc28 100644 --- a/src/services/execution/manager/container_unix.c +++ b/src/services/execution/manager/container_unix.c @@ -1208,7 +1208,7 @@ int container_exit_on_next(container_t *cont) return ret; } -/* this function should be called in container_lock*/ +/* this function should be called in container_lock */ int container_wait_stop(container_t *cont, int timeout) { int ret = 0; diff --git a/src/services/execution/manager/container_unix.h b/src/services/execution/manager/container_unix.h index 2b5d99d..6536f6e 100644 --- a/src/services/execution/manager/container_unix.h +++ b/src/services/execution/manager/container_unix.h @@ -115,3 +115,4 @@ int save_config_v2_json(const char *id, const char *rootpath, const char *v2conf #endif #endif /* __LCRD_CONTAINER_UNIX_H__ */ + diff --git a/src/services/execution/manager/containers_gc.c b/src/services/execution/manager/containers_gc.c index 69e4b34..f2d64c6 100644 --- a/src/services/execution/manager/containers_gc.c +++ b/src/services/execution/manager/containers_gc.c @@ -377,6 +377,14 @@ static void gc_monitor_process(const char *id, pid_t pid, unsigned long long sta } } +static void add_to_list_tail_to_retry_gc(struct linked_list *it) +{ + gc_containers_lock(); + linked_list_del(it); + linked_list_add_tail(&g_gc_containers.containers_list, it); + gc_containers_unlock(); +} + static void gc_container_process(struct linked_list *it) { int ret = 0; @@ -396,6 +404,8 @@ static void gc_container_process(struct linked_list *it) ret = clean_container_resource(id, runtime, pid); if (ret != 0) { WARN("Failed to clean resources of container %s", id); + add_to_list_tail_to_retry_gc(it); + return; } /* remove container from gc list */ @@ -418,13 +428,7 @@ static void gc_container_process(struct linked_list *it) if (ret < 0 && errno != ESRCH) { ERROR("Can not kill process (pid=%d) with SIGKILL for container %s", pid, id); } - - gc_containers_lock(); - - linked_list_del(it); - linked_list_add_tail(&g_gc_containers.containers_list, it); - - gc_containers_unlock(); + add_to_list_tail_to_retry_gc(it); } } static void do_gc_container(struct linked_list *it) @@ -467,7 +471,7 @@ static void *gchandler(void *arg) do_gc_container(it); wait_continue: - usleep_nointerupt(100 * 1000); /* wait 100 millisecond to check next gc container*/ + usleep_nointerupt(100 * 1000); /* wait 100 millisecond to check next gc container */ } error: return NULL; @@ -517,3 +521,4 @@ int start_gchandler() out: return ret; } + diff --git a/src/services/execution/manager/containers_gc.h b/src/services/execution/manager/containers_gc.h index 6c7130f..74b309a 100644 --- a/src/services/execution/manager/containers_gc.h +++ b/src/services/execution/manager/containers_gc.h @@ -46,3 +46,4 @@ bool gc_is_gc_progress(const char *id); #endif #endif /* __LCRD_CONTAINER_GC_H__ */ + diff --git a/src/services/execution/manager/containers_store.c b/src/services/execution/manager/containers_store.c index 734a653..f7e0b32 100644 --- a/src/services/execution/manager/containers_store.c +++ b/src/services/execution/manager/containers_store.c @@ -119,7 +119,7 @@ static container_t *containers_store_get_by_id(const char *id) return cont; } -/* containers store get container by container name*/ +/* containers store get container by container name */ static container_t *containers_store_get_by_name(const char *name) { char *id = NULL; @@ -138,7 +138,7 @@ static container_t *containers_store_get_by_name(const char *name) return containers_store_get_by_id(id); } -/* containers store get container by prefix*/ +/* containers store get container by prefix */ container_t *containers_store_get_by_prefix(const char *prefix) { bool ret = false; diff --git a/src/services/execution/manager/containers_store.h b/src/services/execution/manager/containers_store.h index b4ef36a..530437c 100644 --- a/src/services/execution/manager/containers_store.h +++ b/src/services/execution/manager/containers_store.h @@ -54,3 +54,4 @@ bool name_index_rename(const char *new_name, const char *old_name, const char *i #endif #endif /* __LCRD_MEMORY_STORE_H__ */ + diff --git a/src/services/execution/manager/monitord.c b/src/services/execution/manager/monitord.c index 4d90493..5dc35ec 100644 --- a/src/services/execution/manager/monitord.c +++ b/src/services/execution/manager/monitord.c @@ -70,7 +70,7 @@ static int monitor_event_cb(int fd, uint32_t events, void *cbdata, struct epoll_ goto out; } - /* second, handle events*/ + /* second, handle events */ events_handler(&mmsg); if (malloc_trim(0) == 0) { DEBUG("Malloc trim failed"); @@ -227,3 +227,4 @@ out: free(statedir); return ret; } + diff --git a/src/services/execution/manager/monitord.h b/src/services/execution/manager/monitord.h index d230ff7..e09f33e 100644 --- a/src/services/execution/manager/monitord.h +++ b/src/services/execution/manager/monitord.h @@ -47,3 +47,4 @@ int read_monitord_message_timeout(int fd, struct monitord_msg *msg, int timeout) int new_monitord(struct monitord_sync_data *msync); #endif + diff --git a/src/services/execution/manager/restartmanager.c b/src/services/execution/manager/restartmanager.c index f05ea59..df7a781 100644 --- a/src/services/execution/manager/restartmanager.c +++ b/src/services/execution/manager/restartmanager.c @@ -61,8 +61,6 @@ static void *container_restart(void *args) int ret = 0; struct restart_args *arg = args; char *id = arg->id; - uint64_t timeout = arg->timeout; - int exit_code = arg->exit_code; container_t *cont = NULL; const char *console_fifos[3] = { NULL, NULL, NULL }; restart_manager_t *rm = NULL; @@ -92,21 +90,22 @@ static void *container_restart(void *args) goto set_stopped; } - ret = restart_manager_wait_cancel(rm, timeout); + ret = restart_manager_wait_cancel(rm, arg->timeout); if (ret == 0) { INFO("Canceled to restart container '%s' cased %d", id, ret); goto set_stopped; } - (void)start_container(cont, console_fifos, false); + if (start_container(cont, console_fifos, false) != 0 && is_restarting(cont->state)) { + goto set_stopped; + } goto out; set_stopped: container_lock(cont); - state_set_stopped(cont->state, exit_code); + state_set_stopped(cont->state, arg->exit_code); container_wait_stop_cond_broadcast(cont); container_unlock(cont); - out: container_unref(cont); restart_manager_unref(rm); @@ -463,3 +462,4 @@ int restart_manager_cancel(restart_manager_t *rm) restart_manager_unlock(rm); return 0; } + diff --git a/src/services/execution/manager/restartmanager.h b/src/services/execution/manager/restartmanager.h index 866c99a..5ab7ca3 100644 --- a/src/services/execution/manager/restartmanager.h +++ b/src/services/execution/manager/restartmanager.h @@ -61,3 +61,4 @@ int container_restart_in_thread(const char *id, uint64_t timeout, int exit_code) #endif /* __RESTARTMANAGER_H */ + diff --git a/src/services/execution/manager/restore.c b/src/services/execution/manager/restore.c index d309a1e..0d15370 100644 --- a/src/services/execution/manager/restore.c +++ b/src/services/execution/manager/restore.c @@ -31,7 +31,6 @@ #include "image.h" #ifdef ENABLE_OCI_IMAGE -#include "oci_image.h" #include "oci_images_store.h" #endif @@ -249,10 +248,9 @@ static int check_container_image_exist(const container_t *cont) /* only check exist for oci image */ if (strcmp(image_type, IMAGE_TYPE_OCI) == 0) { - tmp = oci_resolve_image_name(image_name); - if (tmp == NULL) { + ret = im_resolv_image_name(image_type, image_name, &tmp); + if (ret != 0) { ERROR("Failed to resolve image %s", image_name); - ret = -1; goto out; } image = oci_images_store_get(tmp); @@ -270,7 +268,7 @@ out: } #endif -static void try_to_set_container_running(Container_Status status, container_t *cont, +static void try_to_set_container_running(Container_Status status, const container_t *cont, const container_pid_t *pid_info) { int pid = 0; @@ -281,6 +279,17 @@ static void try_to_set_container_running(Container_Status status, container_t *c } } +static void try_to_set_paused_container_pid(Container_Status status, const container_t *cont, + const container_pid_t *pid_info) +{ + int pid = 0; + + pid = state_get_pid(cont->state); + if (status != CONTAINER_STATUS_RUNNING || pid != pid_info->pid) { + state_set_running(cont->state, pid_info, false); + } +} + static int restore_check_id_valid(const char *id, const struct engine_container_summary_info *info, size_t container_num) { @@ -352,6 +361,36 @@ out: return ret; } +static int restore_paused_container(Container_Status status, container_t *cont, + const struct engine_container_summary_info *info) +{ + int ret = 0; + const char *id = cont->common_config->id; + container_pid_t *pid_info = NULL; + + state_set_paused(cont->state); + + pid_info = load_running_container_pid_info(cont); + if (pid_info == NULL) { + ERROR("Failed to restore container:%s due to unable to read container pid info", id); + int nret = post_stopped_container_to_gc(id, cont->runtime, cont->state_path, info->pid); + if (nret != 0) { + ERROR("Failed to post container %s to garbage" + "collector, that may lost some resources" + "used with container!", id); + } + ret = -1; + goto out; + } else { + try_to_set_paused_container_pid(status, cont, pid_info); + } + container_reset_manually_stopped(cont); + +out: + free(pid_info); + return ret; +} + /* restore state */ static int restore_state(container_t *cont, const struct engine_container_summary_info *info, size_t container_num) { @@ -389,6 +428,11 @@ static int restore_state(container_t *cont, const struct engine_container_summar if (ret != 0) { goto out; } + } else if (info[c_index].status == ENGINE_CONTAINER_STATUS_PAUSED) { + ret = restore_paused_container(status, cont, &info[c_index]); + if (ret != 0) { + goto out; + } } else { ERROR("Container %s get invalid status %d", id, info[c_index].status); } diff --git a/src/services/execution/manager/supervisor.c b/src/services/execution/manager/supervisor.c index c71b05e..fd962c6 100644 --- a/src/services/execution/manager/supervisor.c +++ b/src/services/execution/manager/supervisor.c @@ -165,7 +165,9 @@ static void *clean_resources_thread(void *arg) retry: if (false == util_process_alive(pid, start_time)) { ret = clean_container_resource(name, runtime, pid); - if (ret != 0) { + // clean_container_resource failed, do not log error message, + // just add to gc to retry clean resource. + if (ret != 0 && gc_add_container(name, runtime, &data->pid_info) != 0) { ERROR("Failed to clean resources of container %s", name); } } else { @@ -333,3 +335,4 @@ int new_supervisor() out: return ret; } + diff --git a/src/services/execution/spec/specs.c b/src/services/execution/spec/specs.c index e5a9b96..d7f9563 100644 --- a/src/services/execution/spec/specs.c +++ b/src/services/execution/spec/specs.c @@ -1009,7 +1009,7 @@ static int merge_conf_cgroup_memory(oci_runtime_spec *oci_spec, const host_confi } } - /* memory swap*/ + /* memory swap */ if (host_spec->memory_swap != 0) { ret = merge_memory_swap(oci_spec, host_spec->memory_swap); if (ret != 0) { @@ -1468,7 +1468,7 @@ static int change_tmpfs_mount_size(const oci_runtime_spec *oci_spec, int64_t mem if (memory_limit <= 0) { goto out; } - /*set tmpfs mount size to half of container memory limit*/ + /* set tmpfs mount size to half of container memory limit */ if (sprintf_s(size_opt, sizeof(size_opt), "size=%lldk", (long long int)(memory_limit / 2048)) < 0) { ERROR("Out of memory"); ret = -1; diff --git a/src/services/execution/spec/specs.h b/src/services/execution/spec/specs.h index 2f8ada7..14dc022 100644 --- a/src/services/execution/spec/specs.h +++ b/src/services/execution/spec/specs.h @@ -31,3 +31,4 @@ int merge_global_config(oci_runtime_spec *oci_spec); oci_runtime_spec *read_oci_config(const char *rootpath, const char *name); #endif + diff --git a/src/services/execution/spec/specs_extend.c b/src/services/execution/spec/specs_extend.c index 5525c87..2281de5 100644 --- a/src/services/execution/spec/specs_extend.c +++ b/src/services/execution/spec/specs_extend.c @@ -367,32 +367,28 @@ out: static char *get_env_abs_file_path(const oci_runtime_spec *oci_spec, const char *env_target_file) { - char *abs_path = NULL; + char *env_path = NULL; int64_t file_size = 0; if (oci_spec->root == NULL || oci_spec->root->path == NULL) { return NULL; } - abs_path = util_path_join(oci_spec->root->path, env_target_file); - if (abs_path == NULL) { - ERROR("Failed to get env abs file path"); - return NULL; + if (realpath_in_scope(oci_spec->root->path, env_target_file, &env_path) < 0) { + ERROR("env target file '%s' real path must be under rootfs '%s'", env_target_file, oci_spec->root->path); + goto out; } - if (strncmp(abs_path, oci_spec->root->path, strlen(oci_spec->root->path)) != 0) { - ERROR("env target file path must be under rootfs '%s'", oci_spec->root->path); - free(abs_path); - return NULL; + if (!util_file_exists(env_path)) { + return env_path; } - if (!util_file_exists(abs_path)) { - return abs_path; - } - file_size = util_file_size(abs_path); + file_size = util_file_size(env_path); if (file_size > REGULAR_FILE_SIZE) { ERROR("env target file %s, size exceed limit: %lld", env_target_file, REGULAR_FILE_SIZE); - free(abs_path); - return NULL; + goto out; } - return abs_path; + return env_path; +out: + free(env_path); + return NULL; } int merge_env_target_file(oci_runtime_spec *oci_spec, const char *env_target_file) @@ -1287,3 +1283,4 @@ out: return ret; } + diff --git a/src/services/execution/spec/specs_extend.h b/src/services/execution/spec/specs_extend.h index 1838376..066a330 100644 --- a/src/services/execution/spec/specs_extend.h +++ b/src/services/execution/spec/specs_extend.h @@ -63,3 +63,4 @@ int get_user(const char *basefs, const host_config *hc, const char *userstr, oci #endif #endif + diff --git a/src/services/execution/spec/specs_mount.c b/src/services/execution/spec/specs_mount.c index 6e9b470..3cc643f 100644 --- a/src/services/execution/spec/specs_mount.c +++ b/src/services/execution/spec/specs_mount.c @@ -1498,7 +1498,7 @@ static int merge_custom_one_device(oci_runtime_spec *oci_spec, const host_config goto out; } - /* malloc for linux->device*/ + /* malloc for linux->device */ oci_runtime_defs_linux_device **spec_dev = NULL; if (oci_spec->linux->devices_len > SIZE_MAX / sizeof(oci_runtime_defs_linux_device *) - 1) { ERROR("Too many linux devices to merge!"); @@ -1827,7 +1827,7 @@ static bool mount_file(oci_runtime_spec *container, const char *src_path, const bool ret = false; defs_mount *tmp_mounts = NULL; - /*mount options*/ + /* mount options */ if (options_len > SIZE_MAX / sizeof(char *)) { ERROR("Options len is too long!"); goto out_free; @@ -1839,7 +1839,7 @@ static bool mount_file(oci_runtime_spec *container, const char *src_path, const } options[0] = util_strdup_s("rbind"); options[1] = util_strdup_s("rprivate"); - /*generate mount node*/ + /* generate mount node */ tmp_mounts = util_common_calloc_s(sizeof(defs_mount)); if (tmp_mounts == NULL) { ERROR("Malloc tmp_mounts memory failed"); @@ -1853,11 +1853,11 @@ static bool mount_file(oci_runtime_spec *container, const char *src_path, const tmp_mounts->options_len = options_len; options = NULL; - /*expand mount array*/ + /* expand mount array */ if (!mounts_expand(container, 1)) { goto out_free; } - /*add a new mount node*/ + /* add a new mount node */ container->mounts[container->mounts_len - 1] = tmp_mounts; ret = true; @@ -1889,7 +1889,7 @@ static bool add_host_channel_mount(oci_runtime_spec *container, const host_confi options[0] = util_strdup_s("rbind"); options[1] = util_strdup_s("rprivate"); options[2] = util_strdup_s(host_channel->permissions); - /*generate mount node*/ + /* generate mount node */ tmp_mounts = util_common_calloc_s(sizeof(defs_mount)); if (tmp_mounts == NULL) { ERROR("Malloc tmp_mounts memory failed"); @@ -1903,11 +1903,11 @@ static bool add_host_channel_mount(oci_runtime_spec *container, const host_confi tmp_mounts->options_len = options_len; options = NULL; - /*expand mount array*/ + /* expand mount array */ if (!mounts_expand(container, 1)) { goto out_free; } - /*add a new mount node*/ + /* add a new mount node */ container->mounts[container->mounts_len - 1] = tmp_mounts; ret = true; @@ -1956,12 +1956,11 @@ static int change_dev_shm_size(oci_runtime_spec *oci_spec, int64_t shm_size) return -1; } -int merge_conf_mounts(oci_runtime_spec *oci_spec, container_custom_config *custom_spec, host_config *host_spec, - container_config_v2_common_config *common_config) +static int merge_volumes_to_mount(oci_runtime_spec *oci_spec, host_config *host_spec, + container_config_v2_common_config *common_config) { int ret = 0; - /* volumes to mount */ if (host_spec->binds != NULL && host_spec->binds_len) { ret = merge_volumes(oci_spec, host_spec->binds, host_spec->binds_len, common_config, @@ -1972,15 +1971,33 @@ int merge_conf_mounts(oci_runtime_spec *oci_spec, container_custom_config *custo } } - /* host channel to mount */ - if (host_spec->host_channel != NULL) { - if (!add_host_channel_mount(oci_spec, host_spec->host_channel)) { - ERROR("Failed to merge host channel mount"); - goto out; - } +out: + return ret; +} + +static int merge_host_channel_to_mount(oci_runtime_spec *oci_spec, host_config *host_spec) +{ + int ret = 0; + + if (host_spec->host_channel == NULL) { + return 0; } - /* mounts to mount filesystem */ + if (!add_host_channel_mount(oci_spec, host_spec->host_channel)) { + ERROR("Failed to merge host channel mount"); + ret = -1; + goto out; + } + +out: + return ret; +} + +static int merge_mounts_to_mount_filesystem(oci_runtime_spec *oci_spec, container_custom_config *custom_spec, + host_config *host_spec, container_config_v2_common_config *common_config) +{ + int ret = 0; + if (custom_spec->mounts && custom_spec->mounts_len) { ret = merge_volumes(oci_spec, custom_spec->mounts, custom_spec->mounts_len, common_config, @@ -1991,6 +2008,14 @@ int merge_conf_mounts(oci_runtime_spec *oci_spec, container_custom_config *custo } } +out: + return ret; +} + +static int merge_shm_size(oci_runtime_spec *oci_spec, host_config *host_spec) +{ + int ret = 0; + if (host_spec->shm_size >= 0) { if (host_spec->shm_size == 0) { host_spec->shm_size = DEFAULT_SHM_SIZE; @@ -2003,6 +2028,15 @@ int merge_conf_mounts(oci_runtime_spec *oci_spec, container_custom_config *custo } } +out: + return ret; +} + +static int merge_network_config_files(oci_runtime_spec *oci_spec, host_config *host_spec, + container_config_v2_common_config *common_config) +{ + int ret = 0; + if (is_container(host_spec->network_mode)) { /* add network config files */ if (common_config->hosts_path != NULL && !mount_file(oci_spec, common_config->hosts_path, ETC_HOSTS)) { @@ -2017,6 +2051,44 @@ int merge_conf_mounts(oci_runtime_spec *oci_spec, container_custom_config *custo goto out; } } + +out: + return ret; +} + +int merge_conf_mounts(oci_runtime_spec *oci_spec, container_custom_config *custom_spec, host_config *host_spec, + container_config_v2_common_config *common_config) +{ + int ret = 0; + + /* volumes to mount */ + ret = merge_volumes_to_mount(oci_spec, host_spec, common_config); + if (ret != 0) { + goto out; + } + + /* host channel to mount */ + if (merge_host_channel_to_mount(oci_spec, host_spec) != 0) { + ret = -1; + goto out; + } + + /* mounts to mount filesystem */ + if (merge_mounts_to_mount_filesystem(oci_spec, custom_spec, host_spec, common_config) != 0) { + ret = -1; + goto out; + } + + if (merge_shm_size(oci_spec, host_spec) != 0) { + ret = -1; + goto out; + } + + if (merge_network_config_files(oci_spec, host_spec, common_config) != 0) { + ret = -1; + goto out; + } + out: return ret; } diff --git a/src/services/execution/spec/specs_security.h b/src/services/execution/spec/specs_security.h index 536781b..07d1e07 100644 --- a/src/services/execution/spec/specs_security.h +++ b/src/services/execution/spec/specs_security.h @@ -33,3 +33,4 @@ int adapt_settings_for_system_container(oci_runtime_spec *oci_spec, const host_c int merge_seccomp(oci_runtime_spec *oci_spec, const host_config *host_spec); #endif + diff --git a/src/services/execution/spec/sysinfo.h b/src/services/execution/spec/sysinfo.h index f53a8df..2831a53 100644 --- a/src/services/execution/spec/sysinfo.h +++ b/src/services/execution/spec/sysinfo.h @@ -135,3 +135,4 @@ mountinfo_t *find_mount_info(mountinfo_t **minfos, const char *dir); void free_mounts_info(mountinfo_t **minfos); #endif /* __SYSINFO_H */ + diff --git a/src/services/execution/spec/verify.c b/src/services/execution/spec/verify.c index b2b186a..fee7af9 100644 --- a/src/services/execution/spec/verify.c +++ b/src/services/execution/spec/verify.c @@ -1971,3 +1971,4 @@ out: return ret; } + diff --git a/src/services/execution/spec/verify.h b/src/services/execution/spec/verify.h index 040f5d3..2f2c255 100644 --- a/src/services/execution/spec/verify.h +++ b/src/services/execution/spec/verify.h @@ -30,3 +30,4 @@ int verify_health_check_parameter(const container_custom_config *custom_spec); #endif /* __VERIFY_H */ + diff --git a/src/services/graphdriver/driver.c b/src/services/graphdriver/driver.c index 99525eb..251a277 100644 --- a/src/services/graphdriver/driver.c +++ b/src/services/graphdriver/driver.c @@ -23,8 +23,8 @@ #include "utils.h" #include "liblcrd.h" #include "log.h" -#include "isula_imtool_interface.h" #include "lcrd_config.h" +#include "image.h" /* overlay2 */ @@ -83,63 +83,15 @@ struct graphdriver *graphdriver_get(const char *name) return NULL; } -// format: [status xx: val] -static int get_graphdriver_status_line_value(const char *line, char **start, char **end) -{ - char *pstart = NULL; - char *pend = NULL; - - pstart = strchr(line, ':'); - if (pstart == NULL) { - ERROR("Invalid output: %s", line); - return -1; - } - pstart++; - if (*pstart != ' ') { - ERROR("Invalid output: %s", line); - return -1; - } - pstart++; - - pend = strchr(pstart, '\n'); - if (pend == NULL) { - ERROR("Invalid output: %s", pstart); - return -1; - } - *pend++ = '\0'; - - *start = pstart; - *end = pend; - return 0; -} - struct graphdriver_status *graphdriver_get_status(void) { struct graphdriver_status *status = NULL; - bool command_ret = false; - char *stdout_buffer = NULL; - char *stderr_buffer = NULL; - char *pstart = NULL; - char *pend = NULL; int ret = -1; - int nret = -1; + im_storage_status_response *resp = NULL; - command_ret = util_exec_cmd(execute_storage_status, NULL, NULL, &stdout_buffer, &stderr_buffer); - if (!command_ret) { - if (stderr_buffer != NULL) { - ERROR("Failed to get storage status with error: %s", stderr_buffer); - lcrd_set_error_message("Failed to get storage status with error: %s", stderr_buffer); - } else { - ERROR("Failed to exec storage status command"); - lcrd_set_error_message("Failed to storage status command"); - } - goto free_out; - } - - if (stdout_buffer == NULL) { - ERROR("Failed to get storage status because can not get stdoutput"); - lcrd_set_error_message("Failed to get storage status because can not get stdoutput"); - goto free_out; + ret = im_get_storage_status(IMAGE_TYPE_OCI, &resp); + if (ret != 0) { + return NULL; } status = util_common_calloc_s(sizeof(struct graphdriver_status)); @@ -148,36 +100,13 @@ struct graphdriver_status *graphdriver_get_status(void) goto free_out; } - // Backing Filesystem: extfs - if (get_graphdriver_status_line_value(stdout_buffer, &pstart, &pend) != 0) { - goto free_out; - } - status->backing_fs = util_strdup_s(pstart); - - // Supports d_type: true - if (get_graphdriver_status_line_value(pend, &pstart, &pend) != 0) { - goto free_out; - } - nret = util_str_to_bool(pstart, &status->supports_d_type); - if (nret < 0) { - ERROR("Invalid output: %s", pstart); - goto free_out; - } - - // Native Overlay Diff: true - if (get_graphdriver_status_line_value(pend, &pstart, &pend) != 0) { - goto free_out; - } - nret = util_str_to_bool(pstart, &status->native_overlay_diff); - if (nret < 0) { - ERROR("Invalid output: %s", pstart); - goto free_out; - } + status->backing_fs = util_strdup_s(resp->backing_fs); + status->supports_d_type = resp->supports_d_type; + status->native_overlay_diff = resp->native_overlay_diff; ret = 0; free_out: - free(stderr_buffer); - free(stdout_buffer); + free_im_storage_status_response(resp); if (ret != 0) { free_graphdriver_status(status); return NULL; diff --git a/src/services/graphdriver/driver.h b/src/services/graphdriver/driver.h index 94a355a..888ecf4 100644 --- a/src/services/graphdriver/driver.h +++ b/src/services/graphdriver/driver.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -62,3 +62,4 @@ void free_graphdriver_status(struct graphdriver_status *status); #endif #endif + diff --git a/src/services/graphdriver/overlay2/driver_overlay2.c b/src/services/graphdriver/overlay2/driver_overlay2.c index 4ea9753..b6755c3 100644 --- a/src/services/graphdriver/overlay2/driver_overlay2.c +++ b/src/services/graphdriver/overlay2/driver_overlay2.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: diff --git a/src/services/graphdriver/overlay2/driver_overlay2.h b/src/services/graphdriver/overlay2/driver_overlay2.h index 2986eb4..267dba1 100644 --- a/src/services/graphdriver/overlay2/driver_overlay2.h +++ b/src/services/graphdriver/overlay2/driver_overlay2.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -32,3 +32,4 @@ bool overlay2_is_quota_options(struct graphdriver *driver, const char *option); #endif #endif + diff --git a/src/services/image/image_cb.c b/src/services/image/image_cb.c index 0ea4919..b32a933 100644 --- a/src/services/image/image_cb.c +++ b/src/services/image/image_cb.c @@ -34,7 +34,12 @@ #include "engine.h" #include "lcrd_config.h" #include "mediatype.h" - +#include "filters.h" +#ifdef ENABLE_OCI_IMAGE +#include "oci_image_unix.h" +#include "oci_images_store.h" +#include "oci_common_operators.h" +#endif static int docker_load_image(const char *file, const char *tag, const char *type) { int ret = 0; @@ -71,7 +76,7 @@ out: return ret; } -/* image load cb*/ +/* image load cb */ static int image_load_cb(const image_load_image_request *request, image_load_image_response **response) { @@ -280,7 +285,7 @@ out: return (ret < 0) ? ECOMMON : ret; } -/* delete image info*/ +/* delete image info */ static int delete_image_info(const char *image_ref, bool force) { int ret = 0; @@ -474,8 +479,8 @@ static int trans_im_list_images(const im_list_response *im_list, image_list_imag return 0; } - /* If one image have several repo tags, display them all. Image with no - * repo will also be displayed */ + // If one image have several repo tags, display them all. Image with no + // repo will also be displayed images_display_num = calc_images_display_num(im_list->images); if (images_display_num >= (SIZE_MAX / sizeof(image_image *))) { INFO("Too many images, out of memory"); @@ -506,6 +511,155 @@ out: return ret; } +static im_list_request *image_list_context_new(const image_list_images_request *request) +{ + im_list_request *ctx = NULL; + + ctx = util_common_calloc_s(sizeof(im_list_request)); + if (ctx == NULL) { + ERROR("Out of memory"); + return NULL; + } + + return ctx; +} + +#ifdef ENABLE_OCI_IMAGE +struct image_list_context { + struct filters_args *image_filters; +}; + +static const char *g_accepted_image_filter_tags[] = { + "dangling", + "label", + "before", + "since", + "reference", + NULL +}; + +static bool is_valid_dangling_string(const char *val) +{ + return strcmp(val, "true") == 0 || strcmp(val, "false") == 0; +} + +static bool is_valid_image(const char *val) +{ + bool ret = true; + oci_image_t *image_info = NULL; + char *resolved_name = NULL; + int nret = im_resolv_image_name(IMAGE_TYPE_OCI, val, &resolved_name); + if (nret != 0) { + ERROR("Failed to resolve image name"); + ret = false; + goto out; + } + image_info = oci_images_store_get(resolved_name); + if (image_info == NULL) { + ERROR("No such image: %s", val); + ret = false; + goto out; + } + +out: + free(resolved_name); + oci_image_unref(image_info); + return ret; +} + +static int do_add_filters(const char *filter_key, const json_map_string_bool *filter_value, im_list_request *ctx) +{ + int ret = 0; + size_t j; + bool bret = false; + char *value = NULL; + + for (j = 0; j < filter_value->len; j++) { + if (strcmp(filter_key, "reference") == 0) { + if (util_wildcard_to_regex(filter_value->keys[j], &value) != 0) { + ERROR("Failed to convert wildcard to regex: %s", filter_value->keys[j]); + lcrd_set_error_message("Failed to convert wildcard to regex: %s", filter_value->keys[j]); + ret = -1; + goto out; + } + } else if (strcmp(filter_key, "dangling") == 0) { + if (!is_valid_dangling_string(filter_value->keys[j])) { + ERROR("Unrecognised filter value for status: %s", filter_value->keys[j]); + lcrd_set_error_message("Unrecognised filter value for status: %s", filter_value->keys[j]); + ret = -1; + goto out; + } + value = util_strdup_s(filter_value->keys[j]); + } else if (strcmp(filter_key, "before") == 0 || strcmp(filter_key, "since") == 0) { + if (!is_valid_image(filter_value->keys[j])) { + ERROR("No such image: %s", filter_value->keys[j]); + lcrd_set_error_message("No such image: %s", filter_value->keys[j]); + ret = -1; + goto out; + } + value = util_strdup_s(filter_value->keys[j]); + } else { + value = util_strdup_s(filter_value->keys[j]); + } + + bret = filters_args_add(ctx->image_filters, filter_key, value); + if (!bret) { + ERROR("Add filter args failed"); + ret = -1; + goto out; + } + free(value); + value = NULL; + } + +out: + free(value); + return ret; +} +#endif + +static im_list_request *fold_filter(const image_list_images_request *request) +{ + im_list_request *ctx = NULL; + + ctx = image_list_context_new(request); + if (ctx == NULL) { + ERROR("Out of memory"); + goto error_out; + } +#ifdef ENABLE_OCI_IMAGE + size_t i; + if (request->filters == NULL) { + return ctx; + } + + ctx->image_filters = filters_args_new(); + if (ctx->image_filters == NULL) { + ERROR("Out of memory"); + goto error_out; + } + + for (i = 0; i < request->filters->len; i++) { + if (!filters_args_valid_key(g_accepted_image_filter_tags, + sizeof(g_accepted_image_filter_tags) / sizeof(char *), + request->filters->keys[i])) { + ERROR("Invalid filter '%s'", request->filters->keys[i]); + lcrd_set_error_message("Invalid filter '%s'", request->filters->keys[i]); + goto error_out; + } + + if (do_add_filters(request->filters->keys[i], request->filters->values[i], ctx) != 0) { + goto error_out; + } + } +#endif + return ctx; + +error_out: + free_im_list_request(ctx); + return NULL; +} + /* image list cb */ int image_list_cb(const image_list_images_request *request, image_list_images_response **response) @@ -515,24 +669,24 @@ int image_list_cb(const image_list_images_request *request, im_list_request *im_request = NULL; im_list_response *im_response = NULL; - if (response == NULL) { + if (request == NULL || response == NULL) { ERROR("Invalid input arguments"); return EINVALIDARGS; } DAEMON_CLEAR_ERRMSG(); - im_request = util_common_calloc_s(sizeof(im_list_request)); - if (im_request == NULL) { + *response = util_common_calloc_s(sizeof(image_list_images_response)); + if (*response == NULL) { ERROR("Out of memory"); cc = LCRD_ERR_MEMOUT; goto out; } - *response = util_common_calloc_s(sizeof(image_list_images_response)); - if (*response == NULL) { - ERROR("Out of memory"); - cc = LCRD_ERR_MEMOUT; + im_request = fold_filter(request); + if (im_request == NULL) { + ERROR("Failed to fold filters"); + cc = LCRD_ERR_EXEC; goto out; } diff --git a/src/services/image/image_cb.h b/src/services/image/image_cb.h index 544886c..aed8f67 100644 --- a/src/services/image/image_cb.h +++ b/src/services/image/image_cb.h @@ -31,3 +31,4 @@ void image_callback_init(service_image_callback_t *cb); #endif #endif + diff --git a/src/sha256/sha256.c b/src/sha256/sha256.c index e303e57..534ba79 100644 --- a/src/sha256/sha256.c +++ b/src/sha256/sha256.c @@ -264,3 +264,4 @@ char *sha256_digest(void *stream, bool isgzip) } return digest; } + diff --git a/src/sha256/sha256.h b/src/sha256/sha256.h index fc60fe0..429e645 100644 --- a/src/sha256/sha256.h +++ b/src/sha256/sha256.h @@ -48,3 +48,4 @@ char *sha256_digest(void *stream, bool isgzip); # endif #endif + diff --git a/src/sysctl_tools.c b/src/sysctl_tools.c index d090e31..ad631b2 100644 --- a/src/sysctl_tools.c +++ b/src/sysctl_tools.c @@ -117,3 +117,4 @@ free_out: } return val; } + diff --git a/src/sysctl_tools.h b/src/sysctl_tools.h index e448f2e..62f8133 100644 --- a/src/sysctl_tools.h +++ b/src/sysctl_tools.h @@ -29,3 +29,4 @@ int set_sysctl(const char *sysctl, int new_value, char **err); } #endif #endif + diff --git a/src/tar/lcrdtar.c b/src/tar/lcrdtar.c index aaead68..6a6d07b 100644 --- a/src/tar/lcrdtar.c +++ b/src/tar/lcrdtar.c @@ -231,31 +231,6 @@ static int archive_context_close(void *context, char **err) return ret; } -static int split_path_dir_entry(const char *path, char **dir, char **base) -{ - char cleaned[PATH_MAX + 3] = { 0 }; - char *dup = NULL; - - if (cleanpath(path, cleaned, PATH_MAX) == NULL) { - ERROR("Failed to clean path"); - return -1; - } - - if (specify_current_dir(path)) { - set_char_to_separator(&cleaned[strlen(cleaned)]); - cleaned[strlen(cleaned)] = '.'; - } - dup = util_strdup_s(cleaned); - if (dir != NULL) { - *dir = util_strdup_s(dirname(dup)); - } - if (base != NULL) { - *base = util_strdup_s(basename(cleaned)); - } - free(dup); - return 0; -} - static int get_rebase_name(const char *path, const char *real_path, char **resolved_path, char **rebase_name) { diff --git a/src/types_def.c b/src/types_def.c index 6688de8..a099253 100644 --- a/src/types_def.c +++ b/src/types_def.c @@ -19,6 +19,19 @@ #include "log.h" #include "utils.h" +bool unix_nanos_to_timestamp(int64_t nanos, types_timestamp_t *timestamp) +{ + if (timestamp == NULL) { + return false; + } + timestamp->has_seconds = true; + timestamp->seconds = nanos / Time_Second; + timestamp->has_nanos = true; + timestamp->nanos = nanos % Time_Second; + + return true; +} + int types_timestamp_cmp_check(const types_timestamp_t *t1, const types_timestamp_t *t2) { if (t1 == NULL && t2 == NULL) { @@ -772,18 +785,6 @@ static int time_format_duration_bad(char *out, size_t len) return 1; /* format ok with bad data, return 1 */ } -static int time_format_duration_ago(char *out, size_t len) -{ - if (strcmp(out, "-") != 0 && strlen(out) + 5 < len) { - if (strcat_s(out, len, " ago") != EOK) { - ERROR("Strcat string error"); - return -1; - } - } - - return 0; -} - int time_format_duration(const char *in, char *out, size_t len) { int32_t nanos = 0; @@ -819,7 +820,24 @@ int time_format_duration(const char *in, char *out, size_t len) return time_format_duration_bad(out, len); } - return time_format_duration_ago(out, len); + return 0; +} + +int time_format_duration_ago(const char *in, char *out, size_t len) +{ + if (time_format_duration(in, out, len) != 0) { + ERROR("Get format duration"); + return -1; + } + + if (strcmp(out, "-") != 0 && strlen(out) + 5 < len) { + if (strcat_s(out, len, " ago") != EOK) { + ERROR("Strcat string error"); + return -1; + } + } + + return 0; } int time_tz_to_seconds_nanos(const char *time_tz, int64_t *seconds, int32_t *nanos) diff --git a/src/types_def.h b/src/types_def.h index a0ab9fa..7383876 100644 --- a/src/types_def.h +++ b/src/types_def.h @@ -25,9 +25,9 @@ extern "C" { #endif typedef struct types_timestamp { - uint32_t has_seconds; + bool has_seconds; int64_t seconds; - uint32_t has_nanos; + bool has_nanos; int32_t nanos; } types_timestamp_t; @@ -36,6 +36,8 @@ struct types_timezone { int min; }; +bool unix_nanos_to_timestamp(int64_t nanos, types_timestamp_t *timestamp); + int64_t time_seconds_since(const char *in); int types_timestamp_cmp(const types_timestamp_t *t1, const types_timestamp_t *t2); @@ -62,8 +64,10 @@ bool get_tm_from_str(const char *str, struct tm *tm, int32_t *nanos); int time_format_duration(const char *in, char *out, size_t len); +int time_format_duration_ago(const char *in, char *out, size_t len); #ifdef __cplusplus } #endif #endif + diff --git a/src/websocket/service/attach_serve.cc b/src/websocket/service/attach_serve.cc index ee68f0f..1eba860 100644 --- a/src/websocket/service/attach_serve.cc +++ b/src/websocket/service/attach_serve.cc @@ -27,7 +27,7 @@ int AttachServe::Execute(struct lws *wsi, const std::string &token, ERROR("invalid token :%s", token.c_str()); return -1; } - runtime::AttachRequest *request = dynamic_cast(cachedRequest); + runtime::v1alpha2::AttachRequest *request = dynamic_cast(cachedRequest); if (request == nullptr) { ERROR("failed to get exec request!"); return -1; @@ -66,7 +66,7 @@ int AttachServe::Execute(struct lws *wsi, const std::string &token, return ret; } -int AttachServe::RequestFromCri(const runtime::AttachRequest *grequest, +int AttachServe::RequestFromCri(const runtime::v1alpha2::AttachRequest *grequest, container_attach_request **request) { container_attach_request *tmpreq = nullptr; @@ -89,3 +89,4 @@ int AttachServe::RequestFromCri(const runtime::AttachRequest *grequest, return 0; } + diff --git a/src/websocket/service/attach_serve.h b/src/websocket/service/attach_serve.h index ada2a55..c38b110 100644 --- a/src/websocket/service/attach_serve.h +++ b/src/websocket/service/attach_serve.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -35,7 +35,8 @@ public: virtual ~AttachServe() = default; int Execute(struct lws *wsi, const std::string &token, int read_pipe_fd) override; private: - int RequestFromCri(const runtime::AttachRequest *grequest, + int RequestFromCri(const runtime::v1alpha2::AttachRequest *grequest, container_attach_request **request); }; -#endif /*__ATTACH_SERVE_H_*/ +#endif /* __ATTACH_SERVE_H_ */ + diff --git a/src/websocket/service/exec_serve.cc b/src/websocket/service/exec_serve.cc index 751d6e5..13e0f91 100644 --- a/src/websocket/service/exec_serve.cc +++ b/src/websocket/service/exec_serve.cc @@ -27,7 +27,7 @@ int ExecServe::Execute(struct lws *wsi, const std::string &token, ERROR("invalid token :%s", token.c_str()); return -1; } - runtime::ExecRequest *request = dynamic_cast(cachedRequest); + runtime::v1alpha2::ExecRequest *request = dynamic_cast(cachedRequest); if (request == nullptr) { ERROR("failed to get exec request!"); return -1; @@ -74,7 +74,7 @@ int ExecServe::Execute(struct lws *wsi, const std::string &token, return ret; } -int ExecServe::RequestFromCri(const runtime::ExecRequest *grequest, +int ExecServe::RequestFromCri(const runtime::v1alpha2::ExecRequest *grequest, container_exec_request **request) { container_exec_request *tmpreq = nullptr; diff --git a/src/websocket/service/exec_serve.h b/src/websocket/service/exec_serve.h index 5eea0b0..c716fd6 100644 --- a/src/websocket/service/exec_serve.h +++ b/src/websocket/service/exec_serve.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -39,7 +39,8 @@ public: virtual ~ExecServe() = default; int Execute(struct lws *wsi, const std::string &token, int read_pipe_fd) override; private: - int RequestFromCri(const runtime::ExecRequest *grequest, + int RequestFromCri(const runtime::v1alpha2::ExecRequest *grequest, container_exec_request **request); }; -#endif /*__EXEC_SERVE_H_*/ +#endif /* __EXEC_SERVE_H_ */ + diff --git a/src/websocket/service/route_callback_register.h b/src/websocket/service/route_callback_register.h index a131dfe..394324a 100644 --- a/src/websocket/service/route_callback_register.h +++ b/src/websocket/service/route_callback_register.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -89,5 +89,6 @@ private: int m_read_pipe_fd; }; -#endif /*__ROUTE_CALLBACK_REGISTER_H_*/ +#endif /* __ROUTE_CALLBACK_REGISTER_H_ */ + diff --git a/src/websocket/service/stream_server.cc b/src/websocket/service/stream_server.cc index 994a82f..c2fd4be 100644 --- a/src/websocket/service/stream_server.cc +++ b/src/websocket/service/stream_server.cc @@ -39,3 +39,4 @@ void websocket_server_shutdown(void) WebsocketServer *server = WebsocketServer::GetInstance(); server->Shutdown(); } + diff --git a/src/websocket/service/stream_server.h b/src/websocket/service/stream_server.h index 99dbedb..cfd563e 100644 --- a/src/websocket/service/stream_server.h +++ b/src/websocket/service/stream_server.h @@ -30,5 +30,6 @@ void websocket_server_shutdown(void); } #endif -#endif /*__WEBSOCKET_STREAM_SERVICE_H*/ +#endif /* __WEBSOCKET_STREAM_SERVICE_H */ + diff --git a/src/websocket/service/ws_server.cc b/src/websocket/service/ws_server.cc index 6120da6..2d8b1a8 100644 --- a/src/websocket/service/ws_server.cc +++ b/src/websocket/service/ws_server.cc @@ -411,6 +411,7 @@ void WebsocketServer::Wait() CloseAllWsSession(); lws_context_destroy(m_context); + closelog(); } diff --git a/src/websocket/service/ws_server.h b/src/websocket/service/ws_server.h index 169c4ed..3b164cd 100644 --- a/src/websocket/service/ws_server.h +++ b/src/websocket/service/ws_server.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -122,5 +122,5 @@ private: ssize_t WsWriteToClient(void *context, const void *data, size_t len); int closeWsConnect(void *context, char **err); -#endif /*__WEBSOCKET_SERVER_H_*/ +#endif /* __WEBSOCKET_SERVER_H_ */ diff --git a/test/GTest-Run.xsl b/test/GTest-Run.xsl new file mode 100644 index 0000000..4c17996 --- /dev/null +++ b/test/GTest-Run.xsl @@ -0,0 +1,92 @@ + + + + + + GTest - GTest Run Summary Report + + + + +
+

+ GTest - Google's C++ test framework.
+ https://github.com/google/googletest +

+
+ +

+

+

GTest Run Results

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ Running Suite +
+ Running test ... + Failed
+ + + +
Message
+
Passed
+ +

+ + + + + + + + + + + + + + + + + + + + + + +
Cumulative Summary for Run
Testsuite Total Run Succeeded Failed Inactive
+ +

+


+
File Generated By GTest -
+
+ + + + + diff --git a/test/cutils/utils_array/CMakeLists.txt b/test/cutils/utils_array/CMakeLists.txt index 677cd85..6f7c8dd 100644 --- a/test/cutils/utils_array/CMakeLists.txt +++ b/test/cutils/utils_array/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_file.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_convert.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_verify.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_regex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/sha256/sha256.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/path.c ${CMAKE_BINARY_DIR}/json/json_common.c diff --git a/test/cutils/utils_array/utils_array_llt.cc b/test/cutils/utils_array/utils_array_llt.cc index 80072f1..830e3c9 100644 --- a/test/cutils/utils_array/utils_array_llt.cc +++ b/test/cutils/utils_array/utils_array_llt.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: diff --git a/test/cutils/utils_convert/CMakeLists.txt b/test/cutils/utils_convert/CMakeLists.txt index 4fa5609..53886ad 100644 --- a/test/cutils/utils_convert/CMakeLists.txt +++ b/test/cutils/utils_convert/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_file.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_convert.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_verify.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_regex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/sha256/sha256.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/path.c ${CMAKE_BINARY_DIR}/json/json_common.c diff --git a/test/cutils/utils_convert/utils_convert_llt.cc b/test/cutils/utils_convert/utils_convert_llt.cc index 4c76365..9808c93 100644 --- a/test/cutils/utils_convert/utils_convert_llt.cc +++ b/test/cutils/utils_convert/utils_convert_llt.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: diff --git a/test/cutils/utils_string/CMakeLists.txt b/test/cutils/utils_string/CMakeLists.txt index 37d4428..1b9d0bd 100644 --- a/test/cutils/utils_string/CMakeLists.txt +++ b/test/cutils/utils_string/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_file.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_convert.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_verify.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cutils/utils_regex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/sha256/sha256.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/path.c ${CMAKE_BINARY_DIR}/json/json_common.c diff --git a/test/cutils/utils_string/utils_string_llt.cc b/test/cutils/utils_string/utils_string_llt.cc index eb14a1c..bf2486a 100644 --- a/test/cutils/utils_string/utils_string_llt.cc +++ b/test/cutils/utils_string/utils_string_llt.cc @@ -1,13 +1,5 @@ /* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -812,3 +804,4 @@ TEST(utils_string_llt, test_dup_array_of_strings) ASSERT_NE(ret, 0); MOCK_CLEAR(calloc); } + diff --git a/test/image/oci/CMakeLists.txt b/test/image/oci/CMakeLists.txt index 0de2f67..78cd9c4 100644 --- a/test/image/oci/CMakeLists.txt +++ b/test/image/oci/CMakeLists.txt @@ -1,8 +1,3 @@ project(iSulad_LLT) add_subdirectory(oci_config_merge) -add_subdirectory(oci_rootfs_remove) -add_subdirectory(oci_rootfs_mount) -add_subdirectory(oci_rootfs_umount) -add_subdirectory(oci_rootfs_export) -add_subdirectory(oci_rootfs_prepare) diff --git a/test/image/oci/oci_config_merge/CMakeLists.txt b/test/image/oci/oci_config_merge/CMakeLists.txt index d8a07cb..23c3f18 100644 --- a/test/image/oci/oci_config_merge/CMakeLists.txt +++ b/test/image/oci/oci_config_merge/CMakeLists.txt @@ -5,6 +5,7 @@ SET(EXE oci_config_merge_llt) add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/oci_config_merge.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_regex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_verify.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_array.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_string.c @@ -22,6 +23,7 @@ add_executable(${EXE} ${CMAKE_BINARY_DIR}/json/defs.c ${CMAKE_BINARY_DIR}/json/container_config_v2.c ${CMAKE_BINARY_DIR}/json/container_config.c + ${CMAKE_BINARY_DIR}/json/container_custom_config.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config/lcrd_config.c ${CMAKE_BINARY_DIR}/json/oci_runtime_spec.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/sysinfo.c @@ -54,5 +56,5 @@ target_include_directories(${EXE} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci ) -set_target_properties(${EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,util_common_calloc_s -Wl,--wrap,merge_env") +set_target_properties(${EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,util_common_calloc_s -Wl,--wrap,util_smart_calloc_s -Wl,--wrap,merge_env") target_link_libraries(${EXE} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lyajl -lsecurec -lz) diff --git a/test/image/oci/oci_config_merge/imagetool_image.json b/test/image/oci/oci_config_merge/imagetool_image.json index 1a521fb..ad92a79 100644 --- a/test/image/oci/oci_config_merge/imagetool_image.json +++ b/test/image/oci/oci_config_merge/imagetool_image.json @@ -1,10 +1,10 @@ { "id": "e4db68de4ff27c2adfea0c54bbb73a61a42f5b667c326de4d7d5b19ab71c6a3b", "repo_tags": [ - "rnd-dockerhub.huawei.com/official/busybox:latest" + "busybox:latest" ], "repo_digests": [ - "rnd-dockerhub.huawei.com/official/busybox@sha256:64da743694ece2ca88df34bf4c5378fdfc44a1a5b50478722e2ff98b82e4a5c9" + "busybox@sha256:64da743694ece2ca88df34bf4c5378fdfc44a1a5b50478722e2ff98b82e4a5c9" ], "size": 1443304, "created": "2019-06-15T00:19:54.402459069Z", diff --git a/test/image/oci/oci_config_merge/oci_config_merge_llt.cc b/test/image/oci/oci_config_merge/oci_config_merge_llt.cc index 86d4c00..9437b14 100644 --- a/test/image/oci/oci_config_merge/oci_config_merge_llt.cc +++ b/test/image/oci/oci_config_merge/oci_config_merge_llt.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -34,6 +34,9 @@ extern "C" { DECLARE_WRAPPER_V(util_common_calloc_s, void *, (size_t size)); DEFINE_WRAPPER_V(util_common_calloc_s, void *, (size_t size), (size)); + DECLARE_WRAPPER_V(util_smart_calloc_s, void *, (size_t size, size_t len)); + DEFINE_WRAPPER_V(util_smart_calloc_s, void *, (size_t size, size_t len), (size, len)); + DECLARE_WRAPPER(merge_env, int, (oci_runtime_spec *oci_spec, const char **env, size_t env_len)); DEFINE_WRAPPER(merge_env, int, (oci_runtime_spec *oci_spec, const char **env, size_t env_len), \ (oci_spec, env, env_len)); @@ -52,6 +55,19 @@ void *util_common_calloc_s_fail(size_t size) } } +void *util_smart_calloc_s_fail(size_t size, size_t len) +{ + g_malloc_count++; + + if (g_malloc_count == g_malloc_match) { + g_malloc_match++; + g_malloc_count = 0; + return NULL; + } else { + return __real_util_smart_calloc_s(size, len); + } +} + TEST(oci_config_merge_llt, test_oci_image_merge_config) { char *imagetool_image_file = NULL; @@ -72,6 +88,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(oci_spec != NULL); free(err); err = NULL; + free(oci_runtime_spec_file); + oci_runtime_spec_file = NULL; custom_config = (container_custom_config *) util_common_calloc_s(sizeof(container_custom_config)); ASSERT_TRUE(custom_config != NULL); @@ -80,7 +98,7 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) free_oci_runtime_spec(oci_spec); oci_spec = NULL; - free(custom_config); + free_container_custom_config(custom_config); custom_config = NULL; // Parameter oci_spec is NULL @@ -91,6 +109,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(tool_image->spec != NULL); free(err); err = NULL; + free(imagetool_image_file); + imagetool_image_file = NULL; custom_config = (container_custom_config *) util_common_calloc_s(sizeof(container_custom_config)); ASSERT_TRUE(custom_config != NULL); @@ -99,7 +119,7 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) free_imagetool_image(tool_image); tool_image = NULL; - free(custom_config); + free_container_custom_config(custom_config); custom_config = NULL; // Parameter custom_spec is NULL @@ -110,6 +130,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(tool_image->spec != NULL); free(err); err = NULL; + free(imagetool_image_file); + imagetool_image_file = NULL; oci_runtime_spec_file = json_path(OCI_RUNTIME_SPEC_FILE); ASSERT_TRUE(oci_runtime_spec_file != NULL); @@ -117,6 +139,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(oci_spec != NULL); free(err); err = NULL; + free(oci_runtime_spec_file); + oci_runtime_spec_file = NULL; ASSERT_NE(oci_image_merge_config(tool_image, oci_spec, NULL), 0); @@ -133,6 +157,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(tool_image->spec != NULL); free(err); err = NULL; + free(imagetool_image_file); + imagetool_image_file = NULL; oci_runtime_spec_file = json_path(OCI_RUNTIME_SPEC_FILE); ASSERT_TRUE(oci_runtime_spec_file != NULL); @@ -140,6 +166,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(oci_spec != NULL); free(err); err = NULL; + free(oci_runtime_spec_file); + oci_runtime_spec_file = NULL; custom_config = (container_custom_config *) util_common_calloc_s(sizeof(container_custom_config)); ASSERT_TRUE(custom_config != NULL); @@ -150,7 +178,7 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) oci_spec = NULL; free_imagetool_image(tool_image); tool_image = NULL; - free(custom_config); + free_container_custom_config(custom_config); custom_config = NULL; // image_config's volumes not NULL @@ -163,10 +191,15 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(tool_image->spec->config->volumes == NULL); free(err); err = NULL; - tool_image->spec->config->volumes = (defs_map_string_object *) util_common_calloc_s(sizeof(defs_map_string_object)); + free(imagetool_image_file); + imagetool_image_file = NULL; + tool_image->spec->config->volumes = (defs_map_string_object *)util_common_calloc_s(sizeof(defs_map_string_object)); ASSERT_TRUE(tool_image->spec->config->volumes != NULL); tool_image->spec->config->volumes->keys = single_array_from_string("/data"); ASSERT_TRUE(tool_image->spec->config->volumes->keys != NULL); + tool_image->spec->config->volumes->values = (defs_map_string_object_element **) + util_common_calloc_s(sizeof(defs_map_string_object_element *)); + ASSERT_TRUE(tool_image->spec->config->volumes->values != NULL); tool_image->spec->config->volumes->len = 1; oci_runtime_spec_file = json_path(OCI_RUNTIME_SPEC_FILE); @@ -175,6 +208,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(oci_spec != NULL); free(err); err = NULL; + free(oci_runtime_spec_file); + oci_runtime_spec_file = NULL; custom_config = (container_custom_config *) util_common_calloc_s(sizeof(container_custom_config)); ASSERT_TRUE(custom_config != NULL); @@ -185,7 +220,7 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) oci_spec = NULL; free_imagetool_image(tool_image); tool_image = NULL; - free(custom_config); + free_container_custom_config(custom_config); custom_config = NULL; // Config merge condition 1 @@ -196,6 +231,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(tool_image->spec != NULL); free(err); err = NULL; + free(imagetool_image_file); + imagetool_image_file = NULL; ASSERT_TRUE(tool_image->spec->config != NULL); free(tool_image->spec->config->working_dir); @@ -227,6 +264,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(oci_spec != NULL); free(err); err = NULL; + free(oci_runtime_spec_file); + oci_runtime_spec_file = NULL; free(oci_spec->process->cwd); oci_spec->process->cwd = util_strdup_s("/bin/pwd"); @@ -280,7 +319,7 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) oci_spec = NULL; free_imagetool_image(tool_image); tool_image = NULL; - free(custom_config); + free_container_custom_config(custom_config); custom_config = NULL; // Config merge condition 2 @@ -291,6 +330,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(tool_image->spec != NULL); free(err); err = NULL; + free(imagetool_image_file); + imagetool_image_file = NULL; ASSERT_TRUE(tool_image->spec->config != NULL); free(tool_image->spec->config->working_dir); @@ -320,6 +361,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(oci_spec != NULL); free(err); err = NULL; + free(oci_runtime_spec_file); + oci_runtime_spec_file = NULL; free(oci_spec->process->cwd); oci_spec->process->cwd = util_strdup_s("/bin/pwd"); @@ -366,7 +409,7 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) oci_spec = NULL; free_imagetool_image(tool_image); tool_image = NULL; - free(custom_config); + free_container_custom_config(custom_config); custom_config = NULL; // Test malloc failed @@ -378,6 +421,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(tool_image->spec != NULL); free(err); err = NULL; + free(imagetool_image_file); + imagetool_image_file = NULL; oci_runtime_spec_file = json_path(OCI_RUNTIME_SPEC_FILE); ASSERT_TRUE(oci_runtime_spec_file != NULL); @@ -385,10 +430,13 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(oci_spec != NULL); free(err); err = NULL; + free(oci_runtime_spec_file); + oci_runtime_spec_file = NULL; custom_config = (container_custom_config *) util_common_calloc_s(sizeof(container_custom_config)); ASSERT_TRUE(custom_config != NULL); + g_malloc_match = 1; // Test update_health_check_from_image executed failed caused by malloc failed. if (i == 3) { g_malloc_match = 2; @@ -404,15 +452,15 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) tool_image->spec->config->entrypoint_len = 1; } - MOCK_SET_V(util_common_calloc_s, util_common_calloc_s_fail); + MOCK_SET_V(util_smart_calloc_s, util_smart_calloc_s_fail); ASSERT_NE(oci_image_merge_config(tool_image, oci_spec, custom_config), 0); - MOCK_CLEAR(util_common_calloc_s); + MOCK_CLEAR(util_smart_calloc_s); free_oci_runtime_spec(oci_spec); oci_spec = NULL; free_imagetool_image(tool_image); tool_image = NULL; - free(custom_config); + free_container_custom_config(custom_config); custom_config = NULL; } @@ -424,6 +472,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(tool_image->spec != NULL); free(err); err = NULL; + free(imagetool_image_file); + imagetool_image_file = NULL; oci_runtime_spec_file = json_path(OCI_RUNTIME_SPEC_FILE); ASSERT_TRUE(oci_runtime_spec_file != NULL); @@ -431,6 +481,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(oci_spec != NULL); free(err); err = NULL; + free(oci_runtime_spec_file); + oci_runtime_spec_file = NULL; custom_config = (container_custom_config *) util_common_calloc_s(sizeof(container_custom_config)); ASSERT_TRUE(custom_config != NULL); @@ -443,7 +495,7 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) oci_spec = NULL; free_imagetool_image(tool_image); tool_image = NULL; - free(custom_config); + free_container_custom_config(custom_config); custom_config = NULL; // Test test_len == NULL @@ -454,6 +506,8 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(tool_image->spec != NULL); free(err); err = NULL; + free(imagetool_image_file); + imagetool_image_file = NULL; oci_runtime_spec_file = json_path(OCI_RUNTIME_SPEC_FILE); ASSERT_TRUE(oci_runtime_spec_file != NULL); @@ -461,8 +515,11 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) ASSERT_TRUE(oci_spec != NULL); free(err); err = NULL; + free(oci_runtime_spec_file); + oci_runtime_spec_file = NULL; util_free_array(tool_image->healthcheck->test); + tool_image->healthcheck->test = NULL; tool_image->healthcheck->test_len = 0; custom_config = (container_custom_config *) util_common_calloc_s(sizeof(container_custom_config)); @@ -474,6 +531,6 @@ TEST(oci_config_merge_llt, test_oci_image_merge_config) oci_spec = NULL; free_imagetool_image(tool_image); tool_image = NULL; - free(custom_config); + free_container_custom_config(custom_config); custom_config = NULL; } diff --git a/test/image/oci/oci_llt_common.cc b/test/image/oci/oci_llt_common.cc index 179349a..e3f0142 100644 --- a/test/image/oci/oci_llt_common.cc +++ b/test/image/oci/oci_llt_common.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -40,6 +40,21 @@ char **single_array_from_string(const char *value) return arr; } +char *conf_get_graph_rootpath_success() +{ + return util_strdup_s("/var/lib/lcrd/storage"); +} + +char *conf_get_graph_run_path_success() +{ + return util_strdup_s("/var/run/lcrd/storage"); +} + +char *conf_get_lcrd_storage_driver_success() +{ + return util_strdup_s("overlay"); +} + char **conf_get_storage_opts_success() { return single_array_from_string("overlay.override_kernel_check=true"); @@ -52,7 +67,7 @@ char **conf_get_registry_list_success() char **conf_get_insecure_registry_list_success() { - return single_array_from_string("rnd-dockerhub.huawei.com"); + return single_array_from_string("isulad"); } char *json_path(const char *file) diff --git a/test/image/oci/oci_llt_common.h b/test/image/oci/oci_llt_common.h index daafcb8..6bf58c4 100644 --- a/test/image/oci/oci_llt_common.h +++ b/test/image/oci/oci_llt_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -27,14 +27,14 @@ extern "C" { #define DECLARE_OCI_LLT_COMMON_WRAPPER \ extern "C" {\ - DECLARE_WRAPPER(conf_get_graph_rootpath, char *, ());\ - DEFINE_WRAPPER(conf_get_graph_rootpath, char *, (), ());\ + DECLARE_WRAPPER_V(conf_get_graph_rootpath, char *, ());\ + DEFINE_WRAPPER_V(conf_get_graph_rootpath, char *, (), ());\ \ - DECLARE_WRAPPER(conf_get_graph_run_path, char *, ());\ - DEFINE_WRAPPER(conf_get_graph_run_path, char *, (), ());\ + DECLARE_WRAPPER_V(conf_get_graph_run_path, char *, ());\ + DEFINE_WRAPPER_V(conf_get_graph_run_path, char *, (), ());\ \ - DECLARE_WRAPPER(conf_get_lcrd_storage_driver, char *, ());\ - DEFINE_WRAPPER(conf_get_lcrd_storage_driver, char *, (), ());\ + DECLARE_WRAPPER_V(conf_get_lcrd_storage_driver, char *, ());\ + DEFINE_WRAPPER_V(conf_get_lcrd_storage_driver, char *, (), ());\ \ DECLARE_WRAPPER_V(conf_get_storage_opts, char **, ());\ DEFINE_WRAPPER_V(conf_get_storage_opts, char **, (), ());\ @@ -54,9 +54,9 @@ extern "C" { #define MOCK_SET_DEFAULT_ISULAD_KIT_OPTS \ {\ - MOCK_SET(conf_get_graph_rootpath, util_strdup_s("/var/lib/lcrd/storage"));\ - MOCK_SET(conf_get_graph_run_path, util_strdup_s("/var/run/lcrd/storage"));\ - MOCK_SET(conf_get_lcrd_storage_driver, util_strdup_s("overlay"));\ + MOCK_SET_V(conf_get_graph_rootpath, conf_get_graph_rootpath_success);\ + MOCK_SET_V(conf_get_graph_run_path, conf_get_graph_run_path_success);\ + MOCK_SET_V(conf_get_lcrd_storage_driver, conf_get_lcrd_storage_driver_success);\ MOCK_SET_V(conf_get_storage_opts, conf_get_storage_opts_success);\ MOCK_SET_V(conf_get_registry_list, conf_get_registry_list_success);\ MOCK_SET_V(conf_get_insecure_registry_list, conf_get_insecure_registry_list_success);\ @@ -76,6 +76,9 @@ extern "C" { char *json_path(const char *file); int execvp_success(const char *file, char * const argv[]); +char *conf_get_graph_rootpath_success(); +char *conf_get_graph_run_path_success(); +char *conf_get_lcrd_storage_driver_success(); char **conf_get_storage_opts_success(); char **conf_get_registry_list_success(); char **conf_get_insecure_registry_list_success(); diff --git a/test/image/oci/oci_rootfs_export/CMakeLists.txt b/test/image/oci/oci_rootfs_export/CMakeLists.txt deleted file mode 100644 index 624de79..0000000 --- a/test/image/oci/oci_rootfs_export/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -project(iSulad_LLT) - -SET(EXE oci_rootfs_export_llt) - -add_executable(${EXE} - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/oci_rootfs_export.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_verify.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_array.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_string.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_convert.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/log.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/sha256/sha256.c - ${CMAKE_BINARY_DIR}/json/json_common.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/path.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/specs_mount.c - ${CMAKE_BINARY_DIR}/json/host_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/specs_extend.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/liblcrd.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_defs_linux.c - ${CMAKE_BINARY_DIR}/json/defs.c - ${CMAKE_BINARY_DIR}/json/container_config_v2.c - ${CMAKE_BINARY_DIR}/json/container_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config/lcrd_config.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_spec.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/sysinfo.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_config_linux.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/commander.c - ${CMAKE_BINARY_DIR}/json/isulad_daemon_configs.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json/schema/src/read_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/lcrd/arguments.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/isula_imtool_interface.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/driver.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/overlay2/driver_overlay2.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci/oci_llt_common.cc - oci_rootfs_export_llt.cc) - -target_include_directories(${EXE} PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/../../../include - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec - ${CMAKE_BINARY_DIR}/json - ${CMAKE_BINARY_DIR}/conf - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/sha256 - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json/schema/src - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/console - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/overlay2 - ) - -set_target_properties(${EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,conf_get_graph_rootpath -Wl,--wrap,conf_get_graph_run_path -Wl,--wrap,conf_get_lcrd_storage_driver -Wl,--wrap,conf_get_storage_opts -Wl,--wrap,conf_get_registry_list -Wl,--wrap,conf_get_insecure_registry_list -Wl,--wrap,conf_get_im_opt_timeout -Wl,--wrap,execvp -Wl,--wrap,util_exec_cmd") -target_link_libraries(${EXE} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lyajl -lsecurec -lz) diff --git a/test/image/oci/oci_rootfs_export/oci_rootfs_export_llt.cc b/test/image/oci/oci_rootfs_export/oci_rootfs_export_llt.cc deleted file mode 100644 index 88b7713..0000000 --- a/test/image/oci/oci_rootfs_export/oci_rootfs_export_llt.cc +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Description: oci_rootfs_export llt - * Author: wangfengtu - * Create: 2019-08-26 - */ - -#include -#include -#include -#include -#include "mock.h" -#include "utils.h" -#include "oci_rootfs_export.h" -#include "oci_llt_common.h" - -static int g_exec_cmd_count = 0; - -DECLARE_OCI_LLT_COMMON_WRAPPER - -extern "C" { - DECLARE_WRAPPER_V(util_exec_cmd, bool, \ - (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg)); - DEFINE_WRAPPER_V(util_exec_cmd, bool, \ - (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg), \ - (cb_func, args, stdin_msg, stdout_msg, stderr_msg)); -} - -static bool util_exec_cmd_fail(exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, - char **stderr_msg) -{ - g_exec_cmd_count++; - if (g_exec_cmd_count == 1) { - *stderr_msg = util_strdup_s("Device or Resource Busy"); - return false; - } - - if (g_exec_cmd_count == 2) { - *stderr_msg = NULL; - return false; - } - - return 0; -} - -TEST(oci_rootfs_export_llt, test_export_rootfs) -{ - rootfs_export_request *req = NULL; - rootfs_export_response *resp = NULL; - int i = 0; - - // Test parameter NULL part1 - ASSERT_NE(export_rootfs(NULL, NULL), 0); - - // Test parameter NULL part2 - ASSERT_NE(export_rootfs(NULL, &resp), 0); - free_rootfs_export_response(resp); - resp = NULL; - - // Test parameter NULL part3 - req = (rootfs_export_request*)util_common_calloc_s(sizeof(rootfs_export_request)); - ASSERT_TRUE(req != NULL); - req->id = util_strdup_s("3aa25673f3683f225cb4a8209347acd5a8ea9c2d4c9e02d394cbaab6933d9c4d"); - ASSERT_TRUE(req->id != NULL); - ASSERT_NE(export_rootfs(req, &resp), 0); - free_rootfs_export_request(req); - req = NULL; - free_rootfs_export_response(resp); - resp = NULL; - - // Test content of parameter NULL - req = (rootfs_export_request*)util_common_calloc_s(sizeof(rootfs_export_request)); - ASSERT_TRUE(req != NULL); - ASSERT_NE(export_rootfs(req, &resp), 0); - free_rootfs_export_request(req); - req = NULL; - free_rootfs_export_response(resp); - resp = NULL; - - // Test parameter collect - req = (rootfs_export_request*)util_common_calloc_s(sizeof(rootfs_export_request)); - ASSERT_TRUE(req != NULL); - req->file = util_strdup_s("/root/root-fs"); - ASSERT_TRUE(req->file != NULL); - req->id = util_strdup_s("3aa25673f3683f225cb4a8209347acd5a8ea9c2d4c9e02d394cbaab6933d9c4d"); - ASSERT_TRUE(req->id != NULL); - - MOCK_SET_DEFAULT_ISULAD_KIT_OPTS - MOCK_SET_V(execvp, execvp_success); - ASSERT_EQ(export_rootfs(req, &resp), 0); - ASSERT_TRUE(resp != NULL); - MOCK_CLEAR_DEFAULT_ISULAD_KIT_OPTS - MOCK_CLEAR(execvp); - - free_rootfs_export_request(req); - req = NULL; - free_rootfs_export_response(resp); - resp = NULL; - - // Put MOCK_SET_V here to avoid warning "(style) Local variable MOCK_SET_V shadows outer variable" - MOCK_SET_V(util_exec_cmd, util_exec_cmd_fail); - // 1. Test util_exec_cmd failed with stderr_buffer != NULL - // 2. Test util_exec_cmd failed with stderr_buffer == NULL - for (i = 0; i < 3; i++) { - req = (rootfs_export_request*)util_common_calloc_s(sizeof(rootfs_export_request)); - ASSERT_TRUE(req != NULL); - req->file = util_strdup_s("/root/root-fs"); - ASSERT_TRUE(req->file != NULL); - req->id = util_strdup_s("3aa25673f3683f225cb4a8209347acd5a8ea9c2d4c9e02d394cbaab6933d9c4d"); - ASSERT_TRUE(req->id != NULL); - - MOCK_SET_DEFAULT_ISULAD_KIT_OPTS - ASSERT_NE(export_rootfs(req, &resp), 0); - MOCK_CLEAR_DEFAULT_ISULAD_KIT_OPTS - - free_rootfs_export_request(req); - req = NULL; - free_rootfs_export_response(resp); - resp = NULL; - } - MOCK_CLEAR(util_exec_cmd); -} - -TEST(oci_rootfs_export_llt, test_free_rootfs_export_request) -{ - rootfs_export_request *req = NULL; - - // Test free NULL - free_rootfs_export_request(NULL); - - // Test free file and id NULL - req = (rootfs_export_request*)util_common_calloc_s(sizeof(rootfs_export_request)); - ASSERT_TRUE(req != NULL); - - free_rootfs_export_request(req); - req = NULL; - - // Test free all Not NULL - req = (rootfs_export_request*)util_common_calloc_s(sizeof(rootfs_export_request)); - ASSERT_TRUE(req != NULL); - req->file = util_strdup_s("/root/root-fs"); - ASSERT_TRUE(req->file != NULL); - req->id = util_strdup_s("3aa25673f3683f225cb4a8209347acd5a8ea9c2d4c9e02d394cbaab6933d9c4d"); - ASSERT_TRUE(req->id != NULL); - - free_rootfs_export_request(req); - req = NULL; -} - -TEST(oci_rootfs_export_llt, test_free_rootfs_export_response) -{ - rootfs_export_response *resp = NULL; - - // Test free NULL - free_rootfs_export_response(NULL); - - // Test free errmsg NULL - resp = (rootfs_export_response*)util_common_calloc_s(sizeof(rootfs_export_response)); - ASSERT_TRUE(resp != NULL); - - free_rootfs_export_response(resp); - resp = NULL; - - // Test free all Not NULL - resp = (rootfs_export_response*)util_common_calloc_s(sizeof(rootfs_export_response)); - ASSERT_TRUE(resp != NULL); - resp->errmsg = util_strdup_s("This is error message"); - ASSERT_TRUE(resp->errmsg != NULL); - - free_rootfs_export_response(resp); - resp = NULL; -} diff --git a/test/image/oci/oci_rootfs_mount/CMakeLists.txt b/test/image/oci/oci_rootfs_mount/CMakeLists.txt deleted file mode 100644 index 0f42be3..0000000 --- a/test/image/oci/oci_rootfs_mount/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -project(iSulad_LLT) - -SET(EXE oci_rootfs_mount_llt) - -add_executable(${EXE} - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/oci_rootfs_mount.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_verify.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_array.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_string.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_convert.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/log.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/sha256/sha256.c - ${CMAKE_BINARY_DIR}/json/json_common.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/path.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/specs_mount.c - ${CMAKE_BINARY_DIR}/json/host_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/specs_extend.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/liblcrd.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_defs_linux.c - ${CMAKE_BINARY_DIR}/json/defs.c - ${CMAKE_BINARY_DIR}/json/container_config_v2.c - ${CMAKE_BINARY_DIR}/json/container_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config/lcrd_config.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_spec.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/sysinfo.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_config_linux.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/commander.c - ${CMAKE_BINARY_DIR}/json/isulad_daemon_configs.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json/schema/src/read_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/lcrd/arguments.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/isula_imtool_interface.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/driver.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/overlay2/driver_overlay2.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci/oci_llt_common.cc - oci_rootfs_mount_llt.cc) - -target_include_directories(${EXE} PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/../../../include - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec - ${CMAKE_BINARY_DIR}/json - ${CMAKE_BINARY_DIR}/conf - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/sha256 - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json/schema/src - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/console - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/overlay2 - ) - -set_target_properties(${EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,conf_get_graph_rootpath -Wl,--wrap,conf_get_graph_run_path -Wl,--wrap,conf_get_lcrd_storage_driver -Wl,--wrap,conf_get_storage_opts -Wl,--wrap,conf_get_registry_list -Wl,--wrap,conf_get_insecure_registry_list -Wl,--wrap,conf_get_im_opt_timeout -Wl,--wrap,execvp -Wl,--wrap,util_exec_cmd") -target_link_libraries(${EXE} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lyajl -lsecurec -lz) diff --git a/test/image/oci/oci_rootfs_mount/oci_rootfs_mount_llt.cc b/test/image/oci/oci_rootfs_mount/oci_rootfs_mount_llt.cc deleted file mode 100644 index 5c7df8c..0000000 --- a/test/image/oci/oci_rootfs_mount/oci_rootfs_mount_llt.cc +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Description: oci_rootfs_mount llt - * Author: wangfengtu - * Create: 2019-08-26 - */ - -#include -#include -#include -#include -#include "mock.h" -#include "utils.h" -#include "oci_rootfs_mount.h" -#include "oci_llt_common.h" - -static int g_exec_cmd_count = 0; - -DECLARE_OCI_LLT_COMMON_WRAPPER - -extern "C" { - DECLARE_WRAPPER_V(util_exec_cmd, bool, \ - (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg)); - DEFINE_WRAPPER_V(util_exec_cmd, bool, \ - (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg), \ - (cb_func, args, stdin_msg, stdout_msg, stderr_msg)); -} - -static bool util_exec_cmd_fail(exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, - char **stderr_msg) -{ - g_exec_cmd_count++; - if (g_exec_cmd_count == 1) { - *stderr_msg = util_strdup_s("Device or Resource Busy"); - return false; - } - - if (g_exec_cmd_count == 2) { - *stderr_msg = NULL; - return false; - } - - if (g_exec_cmd_count == 3) { - *stdout_msg = NULL; - return true; - } - - return 0; -} - -TEST(oci_rootfs_mount_llt, test_mount_rootfs) -{ - rootfs_mount_request *req = NULL; - rootfs_mount_response *resp = NULL; - int i = 0; - - // Test parameter NULL - ASSERT_NE(mount_rootfs(NULL, NULL), 0); - ASSERT_NE(mount_rootfs(NULL, &resp), 0); - free_rootfs_mount_response(resp); - resp = NULL; - - // Test content of parameter NULL - req = (rootfs_mount_request*)util_common_calloc_s(sizeof(rootfs_mount_request)); - ASSERT_TRUE(req != NULL); - ASSERT_NE(mount_rootfs(req, &resp), 0); - free_rootfs_mount_request(req); - req = NULL; - free_rootfs_mount_response(resp); - resp = NULL; - - // Test parameter collect - req = (rootfs_mount_request*)util_common_calloc_s(sizeof(rootfs_mount_request)); - ASSERT_TRUE(req != NULL); - req->name_id = util_strdup_s("image_name"); - ASSERT_TRUE(req->name_id != NULL); - - MOCK_SET_DEFAULT_ISULAD_KIT_OPTS - MOCK_SET_V(execvp, execvp_success); - ASSERT_EQ(mount_rootfs(req, &resp), 0); - ASSERT_TRUE(resp != NULL); - MOCK_CLEAR_DEFAULT_ISULAD_KIT_OPTS - MOCK_CLEAR(execvp); - - free_rootfs_mount_request(req); - req = NULL; - free_rootfs_mount_response(resp); - resp = NULL; - - // Put MOCK_SET_V here to avoid warning "(style) Local variable MOCK_SET_V shadows outer variable" - MOCK_SET_V(util_exec_cmd, util_exec_cmd_fail); - // 1. Test util_exec_cmd failed with stderr_buffer != NULL - // 2. Test util_exec_cmd failed with stderr_buffer == NULL - // 3. Test util_exec_cmd success with stdout_buffer == NULL - for (i = 0; i < 3; i++) { - req = (rootfs_mount_request*)util_common_calloc_s(sizeof(rootfs_mount_request)); - ASSERT_TRUE(req != NULL); - req->name_id = util_strdup_s("image_name"); - ASSERT_TRUE(req->name_id != NULL); - - MOCK_SET_DEFAULT_ISULAD_KIT_OPTS - ASSERT_NE(mount_rootfs(req, &resp), 0); - MOCK_CLEAR_DEFAULT_ISULAD_KIT_OPTS - - free_rootfs_mount_request(req); - req = NULL; - free_rootfs_mount_response(resp); - resp = NULL; - } - MOCK_CLEAR(util_exec_cmd); -} - -TEST(oci_rootfs_mount_llt, test_free_rootfs_mount_request) -{ - rootfs_mount_request *req = NULL; - - // Test free NULL - free_rootfs_mount_request(NULL); - - // Test free name_id NULL - req = (rootfs_mount_request*)util_common_calloc_s(sizeof(rootfs_mount_request)); - ASSERT_TRUE(req != NULL); - - free_rootfs_mount_request(req); - req = NULL; - - // Test free all Not NULL - req = (rootfs_mount_request*)util_common_calloc_s(sizeof(rootfs_mount_request)); - ASSERT_TRUE(req != NULL); - req->name_id = util_strdup_s("image_name"); - ASSERT_TRUE(req->name_id != NULL); - - free_rootfs_mount_request(req); - req = NULL; -} - -TEST(oci_rootfs_mount_llt, test_free_rootfs_mount_response) -{ - rootfs_mount_response *resp = NULL; - - // Test free NULL - free_rootfs_mount_response(NULL); - - // Test free errmsg NULL - resp = (rootfs_mount_response*)util_common_calloc_s(sizeof(rootfs_mount_response)); - ASSERT_TRUE(resp != NULL); - - free_rootfs_mount_response(resp); - resp = NULL; - - // Test free all Not NULL - resp = (rootfs_mount_response*)util_common_calloc_s(sizeof(rootfs_mount_response)); - ASSERT_TRUE(resp != NULL); - resp->errmsg = util_strdup_s("This is error message"); - ASSERT_TRUE(resp->errmsg != NULL); - - free_rootfs_mount_response(resp); - resp = NULL; -} diff --git a/test/image/oci/oci_rootfs_prepare/CMakeLists.txt b/test/image/oci/oci_rootfs_prepare/CMakeLists.txt deleted file mode 100644 index dc1d053..0000000 --- a/test/image/oci/oci_rootfs_prepare/CMakeLists.txt +++ /dev/null @@ -1,62 +0,0 @@ -project(iSulad_LLT) - -SET(EXE oci_rootfs_prepare_llt) - -add_executable(${EXE} - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/oci_rootfs_prepare.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_verify.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_array.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_string.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_convert.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/log.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/sha256/sha256.c - ${CMAKE_BINARY_DIR}/json/json_common.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/path.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/specs_mount.c - ${CMAKE_BINARY_DIR}/json/host_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/specs_extend.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/liblcrd.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_defs_linux.c - ${CMAKE_BINARY_DIR}/json/defs.c - ${CMAKE_BINARY_DIR}/json/container_config_v2.c - ${CMAKE_BINARY_DIR}/json/container_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config/lcrd_config.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_spec.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/sysinfo.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_config_linux.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/commander.c - ${CMAKE_BINARY_DIR}/json/isulad_daemon_configs.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json/schema/src/read_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/lcrd/arguments.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/isula_imtool_interface.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/driver.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/overlay2/driver_overlay2.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci/oci_llt_common.cc - ${CMAKE_BINARY_DIR}/json/imagetool_prepare_response.c - ${CMAKE_BINARY_DIR}/json/oci_image_spec.c - oci_rootfs_prepare_llt.cc) - -target_include_directories(${EXE} PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/../../../include - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec - ${CMAKE_BINARY_DIR}/json - ${CMAKE_BINARY_DIR}/conf - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/sha256 - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json/schema/src - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/console - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/overlay2 - ) - -set_target_properties(${EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,conf_get_graph_rootpath -Wl,--wrap,conf_get_graph_run_path -Wl,--wrap,conf_get_lcrd_storage_driver -Wl,--wrap,conf_get_storage_opts -Wl,--wrap,conf_get_registry_list -Wl,--wrap,conf_get_insecure_registry_list -Wl,--wrap,conf_get_im_opt_timeout -Wl,--wrap,execvp -Wl,--wrap,util_exec_cmd") -target_link_libraries(${EXE} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lyajl -lsecurec -lz) diff --git a/test/image/oci/oci_rootfs_prepare/oci_rootfs_prepare_llt.cc b/test/image/oci/oci_rootfs_prepare/oci_rootfs_prepare_llt.cc deleted file mode 100644 index 7eb2e89..0000000 --- a/test/image/oci/oci_rootfs_prepare/oci_rootfs_prepare_llt.cc +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Description: oci_rootfs_prepare llt - * Author: wangfengtu - * Create: 2019-08-26 - */ - -#include -#include -#include -#include -#include -#include "mock.h" -#include "utils.h" -#include "oci_rootfs_prepare.h" -#include "oci_llt_common.h" - -static int g_exec_cmd_count = 0; - -DECLARE_OCI_LLT_COMMON_WRAPPER - -extern "C" { - DECLARE_WRAPPER_V(util_exec_cmd, bool, \ - (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg)); - DEFINE_WRAPPER_V(util_exec_cmd, bool, \ - (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg), \ - (cb_func, args, stdin_msg, stdout_msg, stderr_msg)); -} - -static bool util_exec_cmd_fail(exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, - char **stderr_msg) -{ - g_exec_cmd_count++; - if (g_exec_cmd_count == 1) { - *stderr_msg = util_strdup_s("Device or Resource Busy"); - return false; - } - - if (g_exec_cmd_count == 2) { - *stderr_msg = NULL; - return false; - } - - if (g_exec_cmd_count == 3) { - *stdout_msg = NULL; - return true; - } - - if (g_exec_cmd_count == 4) { - *stdout_msg = util_strdup_s("invalid"); - return true; - } - - return 0; -} - -#define OCI_IMAGE_SPEC_FILE "image/oci/oci_rootfs_prepare/prepare_response.json" - -static imagetool_prepare_response *prepare_response_from_json() -{ - imagetool_prepare_response *response = NULL; - parser_error err = NULL; - char *json_file = NULL; - - json_file = json_path(OCI_IMAGE_SPEC_FILE); - if (json_file == NULL) { - return NULL; - } - - response = imagetool_prepare_response_parse_file(json_file, NULL, &err); - if (response == NULL) { - goto out; - } - -out: - free(json_file); - json_file = NULL; - - free(err); - err = NULL; - - return response; -} - -static int execvp_prepare_success(const char *file, char * const argv[]) -{ - char *json_file = NULL; - - json_file = json_path(OCI_IMAGE_SPEC_FILE); - if (json_file == NULL) { - return -1; - } - - execlp("cat", "cat", json_file, NULL); - - free(json_file); - json_file = NULL; - - return -1; -} - -TEST(oci_rootfs_prepare_llt, test_prepare_rootfs_and_get_image_conf) -{ - // In order to skip codingstyle check. Error info "Lines should very rarely be longer than 120 characters" -#define RESP_MP "/var/lib/lcrd/storage/overlay/f50fdf298b3881051cbc383e3b293619dfb53c98805937784096353302d2b213/merged" - rootfs_prepare_request *req = NULL; - rootfs_prepare_and_get_image_conf_response *resp = NULL; - int i = 0; - - // Test parameter NULL part1 - ASSERT_NE(prepare_rootfs_and_get_image_conf(NULL, NULL), 0); - ASSERT_NE(prepare_rootfs_and_get_image_conf(NULL, &resp), 0); - free_rootfs_prepare_and_get_image_conf_response(resp); - resp = NULL; - // Test parameter NULL part2 - req = (rootfs_prepare_request*)util_common_calloc_s(sizeof(rootfs_prepare_request)); - ASSERT_TRUE(req != NULL); - ASSERT_NE(prepare_rootfs_and_get_image_conf(req, &resp), 0); - free_rootfs_prepare_and_get_image_conf_response(resp); - resp = NULL; - // Test parameter NULL part3 - req = (rootfs_prepare_request*)util_common_calloc_s(sizeof(rootfs_prepare_request)); - ASSERT_TRUE(req != NULL); - req->image = util_strdup_s("image_name"); - ASSERT_TRUE(req->image != NULL); - ASSERT_NE(prepare_rootfs_and_get_image_conf(req, &resp), 0); - free_rootfs_prepare_request(req); - req = NULL; - free_rootfs_prepare_and_get_image_conf_response(resp); - resp = NULL; - // Test parameter NULL part4 - req = (rootfs_prepare_request*)util_common_calloc_s(sizeof(rootfs_prepare_request)); - ASSERT_TRUE(req != NULL); - req->name = util_strdup_s("name"); - ASSERT_TRUE(req->name != NULL); - ASSERT_NE(prepare_rootfs_and_get_image_conf(req, &resp), 0); - free_rootfs_prepare_request(req); - req = NULL; - free_rootfs_prepare_and_get_image_conf_response(resp); - resp = NULL; - - // Test parameter collect - req = (rootfs_prepare_request*)util_common_calloc_s(sizeof(rootfs_prepare_request)); - ASSERT_TRUE(req != NULL); - req->image = util_strdup_s("image_name"); - ASSERT_TRUE(req->image != NULL); - req->name = util_strdup_s("name"); - ASSERT_TRUE(req->name != NULL); - req->id = util_strdup_s("0ac632258473464fa06a317e0347834ba652a00080506f5ea10e9ef8e7db5459"); - ASSERT_TRUE(req->id != NULL); - req->storage_opts = conf_get_storage_opts_success(); - ASSERT_TRUE(req->storage_opts != NULL); - req->storage_opts_len = 1; - - MOCK_SET_DEFAULT_ISULAD_KIT_OPTS - MOCK_SET_V(execvp, execvp_prepare_success); - ASSERT_EQ(prepare_rootfs_and_get_image_conf(req, &resp), 0); - ASSERT_TRUE(resp != NULL); - ASSERT_TRUE(resp->raw_response != NULL); - ASSERT_STREQ(resp->raw_response->mount_point, RESP_MP); - MOCK_CLEAR_DEFAULT_ISULAD_KIT_OPTS - MOCK_CLEAR(execvp); - - free_rootfs_prepare_request(req); - req = NULL; - free_rootfs_prepare_and_get_image_conf_response(resp); - resp = NULL; - - // Put MOCK_SET_V here to avoid warning "(style) Local variable MOCK_SET_V shadows outer variable" - MOCK_SET_V(util_exec_cmd, util_exec_cmd_fail); - // 1. Test util_exec_cmd failed with stderr_buffer != NULL - // 2. Test util_exec_cmd failed with stderr_buffer == NULL - // 3. Test util_exec_cmd success with stdout_buffer == NULL - // 4. Test util_exec_cmd success with stdout_buffer invalid - for (i = 0; i < 4; i++) { - req = (rootfs_prepare_request*)util_common_calloc_s(sizeof(rootfs_prepare_request)); - ASSERT_TRUE(req != NULL); - req->image = util_strdup_s("image_name"); - ASSERT_TRUE(req->image != NULL); - req->name = util_strdup_s("name"); - ASSERT_TRUE(req->name != NULL); - req->id = util_strdup_s("0ac632258473464fa06a317e0347834ba652a00080506f5ea10e9ef8e7db5459"); - ASSERT_TRUE(req->id != NULL); - req->storage_opts = conf_get_storage_opts_success(); - ASSERT_TRUE(req->storage_opts != NULL); - req->storage_opts_len = 1; - - MOCK_SET_DEFAULT_ISULAD_KIT_OPTS - ASSERT_NE(prepare_rootfs_and_get_image_conf(req, &resp), 0); - MOCK_CLEAR_DEFAULT_ISULAD_KIT_OPTS - - free_rootfs_prepare_request(req); - req = NULL; - free_rootfs_prepare_and_get_image_conf_response(resp); - resp = NULL; - } - MOCK_CLEAR(util_exec_cmd); -} - -TEST(oci_rootfs_prepare_llt, test_free_rootfs_prepare_request) -{ - rootfs_prepare_request *req = NULL; - - // Test free NULL - free_rootfs_prepare_request(NULL); - - // Test free content NULL - req = (rootfs_prepare_request*)util_common_calloc_s(sizeof(rootfs_prepare_request)); - ASSERT_TRUE(req != NULL); - - free_rootfs_prepare_request(req); - req = NULL; - - // Test free all Not NULL - req = (rootfs_prepare_request*)util_common_calloc_s(sizeof(rootfs_prepare_request)); - ASSERT_TRUE(req != NULL); - req->image = util_strdup_s("image_name"); - ASSERT_TRUE(req->image != NULL); - req->name = util_strdup_s("name"); - ASSERT_TRUE(req->name != NULL); - req->id = util_strdup_s("0ac632258473464fa06a317e0347834ba652a00080506f5ea10e9ef8e7db5459"); - ASSERT_TRUE(req->id != NULL); - req->storage_opts = conf_get_storage_opts_success(); - ASSERT_TRUE(req->storage_opts != NULL); - req->storage_opts_len = 1; - - free_rootfs_prepare_request(req); - req = NULL; -} - -TEST(oci_rootfs_prepare_llt, test_free_rootfs_prepare_and_get_image_conf_response) -{ - size_t size = 0; - rootfs_prepare_and_get_image_conf_response *resp = NULL; - - // Test free NULL - free_rootfs_prepare_and_get_image_conf_response(NULL); - - // Test free errmsg NULL - size = sizeof(rootfs_prepare_and_get_image_conf_response); - resp = (rootfs_prepare_and_get_image_conf_response*)util_common_calloc_s(size); - ASSERT_TRUE(resp != NULL); - - free_rootfs_prepare_and_get_image_conf_response(resp); - resp = NULL; - - // Test free all Not NULL - size = sizeof(rootfs_prepare_and_get_image_conf_response); - resp = (rootfs_prepare_and_get_image_conf_response*)util_common_calloc_s(size); - ASSERT_TRUE(resp != NULL); - - resp->errmsg = util_strdup_s("This is error message"); - ASSERT_TRUE(resp->errmsg != NULL); - - resp->raw_response = prepare_response_from_json(); - ASSERT_TRUE(resp->raw_response != NULL); - - free_rootfs_prepare_and_get_image_conf_response(resp); - resp = NULL; -} diff --git a/test/image/oci/oci_rootfs_prepare/prepare_response.json b/test/image/oci/oci_rootfs_prepare/prepare_response.json deleted file mode 100644 index fbaa8eb..0000000 --- a/test/image/oci/oci_rootfs_prepare/prepare_response.json +++ /dev/null @@ -1 +0,0 @@ -{"mount_point":"/var/lib/lcrd/storage/overlay/f50fdf298b3881051cbc383e3b293619dfb53c98805937784096353302d2b213/merged"} diff --git a/test/image/oci/oci_rootfs_remove/CMakeLists.txt b/test/image/oci/oci_rootfs_remove/CMakeLists.txt deleted file mode 100644 index 823e03d..0000000 --- a/test/image/oci/oci_rootfs_remove/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -project(iSulad_LLT) - -SET(EXE oci_rootfs_remove_llt) - -add_executable(${EXE} - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/oci_rootfs_remove.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_verify.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_array.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_string.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_convert.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/log.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/sha256/sha256.c - ${CMAKE_BINARY_DIR}/json/json_common.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/path.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/specs_mount.c - ${CMAKE_BINARY_DIR}/json/host_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/specs_extend.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/liblcrd.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_defs_linux.c - ${CMAKE_BINARY_DIR}/json/defs.c - ${CMAKE_BINARY_DIR}/json/container_config_v2.c - ${CMAKE_BINARY_DIR}/json/container_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config/lcrd_config.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_spec.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/sysinfo.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_config_linux.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/commander.c - ${CMAKE_BINARY_DIR}/json/isulad_daemon_configs.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json/schema/src/read_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/lcrd/arguments.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/isula_imtool_interface.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/driver.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/overlay2/driver_overlay2.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci/oci_llt_common.cc - oci_rootfs_remove_llt.cc) - -target_include_directories(${EXE} PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/../../../include - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec - ${CMAKE_BINARY_DIR}/json - ${CMAKE_BINARY_DIR}/conf - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/sha256 - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json/schema/src - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/console - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/overlay2 - ) - -set_target_properties(${EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,conf_get_graph_rootpath -Wl,--wrap,conf_get_graph_run_path -Wl,--wrap,conf_get_lcrd_storage_driver -Wl,--wrap,conf_get_storage_opts -Wl,--wrap,conf_get_registry_list -Wl,--wrap,conf_get_insecure_registry_list -Wl,--wrap,conf_get_im_opt_timeout -Wl,--wrap,execvp -Wl,--wrap,util_exec_cmd") -target_link_libraries(${EXE} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lyajl -lsecurec -lz) diff --git a/test/image/oci/oci_rootfs_remove/oci_rootfs_remove_llt.cc b/test/image/oci/oci_rootfs_remove/oci_rootfs_remove_llt.cc deleted file mode 100644 index 3f32494..0000000 --- a/test/image/oci/oci_rootfs_remove/oci_rootfs_remove_llt.cc +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Description: oci_rootfs_remove llt - * Author: wangfengtu - * Create: 2019-08-26 - */ - -#include -#include -#include -#include -#include "mock.h" -#include "utils.h" -#include "oci_rootfs_remove.h" -#include "oci_llt_common.h" - -static int g_exec_cmd_count = 0; - -DECLARE_OCI_LLT_COMMON_WRAPPER - -extern "C" { - DECLARE_WRAPPER_V(util_exec_cmd, bool, \ - (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg)); - DEFINE_WRAPPER_V(util_exec_cmd, bool, \ - (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg), \ - (cb_func, args, stdin_msg, stdout_msg, stderr_msg)); -} - -static bool util_exec_cmd_fail(exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, - char **stderr_msg) -{ - g_exec_cmd_count++; - if (g_exec_cmd_count == 1) { - *stderr_msg = util_strdup_s("Device or Resource Busy"); - return false; - } - - if (g_exec_cmd_count == 2) { - *stderr_msg = NULL; - return false; - } - - if (g_exec_cmd_count == 3) { - *stderr_msg = util_strdup_s("container not known"); - return false; - } - - return 0; -} - -TEST(oci_rootfs_remove_llt, test_remove_rootfs) -{ - rootfs_remove_request *req = NULL; - rootfs_remove_response *resp = NULL; - int i = 0; - - // Test parameter NULL - ASSERT_NE(remove_rootfs(NULL, NULL), 0); - ASSERT_NE(remove_rootfs(NULL, &resp), 0); - free_rootfs_remove_response(resp); - resp = NULL; - - // Test content of parameter NULL - req = (rootfs_remove_request*)util_common_calloc_s(sizeof(rootfs_remove_request)); - ASSERT_TRUE(req != NULL); - ASSERT_NE(remove_rootfs(req, &resp), 0); - free_rootfs_remove_request(req); - req = NULL; - free_rootfs_remove_response(resp); - resp = NULL; - - // Test parameter collect - req = (rootfs_remove_request*)util_common_calloc_s(sizeof(rootfs_remove_request)); - ASSERT_TRUE(req != NULL); - req->name_id = util_strdup_s("image_name"); - ASSERT_TRUE(req->name_id != NULL); - - MOCK_SET_DEFAULT_ISULAD_KIT_OPTS - MOCK_SET_V(execvp, execvp_success); - ASSERT_EQ(remove_rootfs(req, &resp), 0); - ASSERT_TRUE(resp != NULL); - MOCK_CLEAR_DEFAULT_ISULAD_KIT_OPTS - MOCK_CLEAR(execvp); - - free_rootfs_remove_request(req); - req = NULL; - free_rootfs_remove_response(resp); - resp = NULL; - - // Put MOCK_SET_V here to avoid warning "(style) Local variable MOCK_SET_V shadows outer variable" - MOCK_SET_V(util_exec_cmd, util_exec_cmd_fail); - // 1. Test util_exec_cmd failed with stderr_buffer != NULL - // 1. Test util_exec_cmd failed with stderr_buffer == NULL - // 3. Test util_exec_cmd failed with stderr_buffer contains "container not known" - for (i = 0; i < 3; i++) { - req = (rootfs_remove_request*)util_common_calloc_s(sizeof(rootfs_remove_request)); - ASSERT_TRUE(req != NULL); - req->name_id = util_strdup_s("image_name"); - ASSERT_TRUE(req->name_id != NULL); - - MOCK_SET_DEFAULT_ISULAD_KIT_OPTS - if (i == 2) { - // If stderr_buffer contains "container not known", - // remove_rootfs must return success. - ASSERT_EQ(remove_rootfs(req, &resp), 0); - } else { - ASSERT_NE(remove_rootfs(req, &resp), 0); - } - MOCK_CLEAR_DEFAULT_ISULAD_KIT_OPTS - - free_rootfs_remove_request(req); - req = NULL; - free_rootfs_remove_response(resp); - resp = NULL; - } - MOCK_CLEAR(util_exec_cmd); -} - -TEST(oci_rootfs_remove_llt, test_free_rootfs_remove_request) -{ - rootfs_remove_request *req = NULL; - - // Test free NULL - free_rootfs_remove_request(NULL); - - // Test free name_id NULL - req = (rootfs_remove_request*)util_common_calloc_s(sizeof(rootfs_remove_request)); - ASSERT_TRUE(req != NULL); - - free_rootfs_remove_request(req); - req = NULL; - - // Test free all Not NULL - req = (rootfs_remove_request*)util_common_calloc_s(sizeof(rootfs_remove_request)); - ASSERT_TRUE(req != NULL); - req->name_id = util_strdup_s("image_name"); - ASSERT_TRUE(req->name_id != NULL); - - free_rootfs_remove_request(req); - req = NULL; -} - -TEST(oci_rootfs_remove_llt, test_free_rootfs_remove_response) -{ - rootfs_remove_response *resp = NULL; - - // Test free NULL - free_rootfs_remove_response(NULL); - - // Test free errmsg NULL - resp = (rootfs_remove_response*)util_common_calloc_s(sizeof(rootfs_remove_response)); - ASSERT_TRUE(resp != NULL); - - free_rootfs_remove_response(resp); - resp = NULL; - - // Test free all Not NULL - resp = (rootfs_remove_response*)util_common_calloc_s(sizeof(rootfs_remove_response)); - ASSERT_TRUE(resp != NULL); - resp->errmsg = util_strdup_s("This is error message"); - ASSERT_TRUE(resp->errmsg != NULL); - - free_rootfs_remove_response(resp); - resp = NULL; -} diff --git a/test/image/oci/oci_rootfs_umount/CMakeLists.txt b/test/image/oci/oci_rootfs_umount/CMakeLists.txt deleted file mode 100644 index 563b528..0000000 --- a/test/image/oci/oci_rootfs_umount/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -project(iSulad_LLT) - -SET(EXE oci_rootfs_umount_llt) - -add_executable(${EXE} - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/oci_rootfs_umount.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_verify.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_array.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_string.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_convert.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils/utils_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/log.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/sha256/sha256.c - ${CMAKE_BINARY_DIR}/json/json_common.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/path.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/specs_mount.c - ${CMAKE_BINARY_DIR}/json/host_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/specs_extend.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/liblcrd.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_defs_linux.c - ${CMAKE_BINARY_DIR}/json/defs.c - ${CMAKE_BINARY_DIR}/json/container_config_v2.c - ${CMAKE_BINARY_DIR}/json/container_config.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config/lcrd_config.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_spec.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec/sysinfo.c - ${CMAKE_BINARY_DIR}/json/oci_runtime_config_linux.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/commander.c - ${CMAKE_BINARY_DIR}/json/isulad_daemon_configs.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json/schema/src/read_file.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/lcrd/arguments.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci/isula_imtool_interface.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/driver.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/overlay2/driver_overlay2.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci/oci_llt_common.cc - oci_rootfs_umount_llt.cc) - -target_include_directories(${EXE} PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/../../../include - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image/oci - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/image - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cutils - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/execution/spec - ${CMAKE_BINARY_DIR}/json - ${CMAKE_BINARY_DIR}/conf - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/sha256 - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/json/schema/src - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/console - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/services/graphdriver/overlay2 - ) - -set_target_properties(${EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,conf_get_graph_rootpath -Wl,--wrap,conf_get_graph_run_path -Wl,--wrap,conf_get_lcrd_storage_driver -Wl,--wrap,conf_get_storage_opts -Wl,--wrap,conf_get_registry_list -Wl,--wrap,conf_get_insecure_registry_list -Wl,--wrap,conf_get_im_opt_timeout -Wl,--wrap,execvp -Wl,--wrap,util_exec_cmd") -target_link_libraries(${EXE} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lyajl -lsecurec -lz) diff --git a/test/image/oci/oci_rootfs_umount/oci_rootfs_umount_llt.cc b/test/image/oci/oci_rootfs_umount/oci_rootfs_umount_llt.cc deleted file mode 100644 index bd629dc..0000000 --- a/test/image/oci/oci_rootfs_umount/oci_rootfs_umount_llt.cc +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. - * Description: oci_rootfs_umount llt - * Author: wangfengtu - * Create: 2019-08-26 - */ - -#include -#include -#include -#include -#include "mock.h" -#include "utils.h" -#include "oci_rootfs_umount.h" -#include "oci_llt_common.h" - -static int g_exec_cmd_count = 0; - -DECLARE_OCI_LLT_COMMON_WRAPPER - -extern "C" { - DECLARE_WRAPPER_V(util_exec_cmd, bool, \ - (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg)); - DEFINE_WRAPPER_V(util_exec_cmd, bool, \ - (exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg), \ - (cb_func, args, stdin_msg, stdout_msg, stderr_msg)); -} - -static bool util_exec_cmd_fail(exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, - char **stderr_msg) -{ - g_exec_cmd_count++; - if (g_exec_cmd_count == 1) { - *stderr_msg = util_strdup_s("Device or Resource Busy"); - return false; - } - - if (g_exec_cmd_count == 2) { - *stderr_msg = NULL; - return false; - } - - return 0; -} - - -TEST(oci_rootfs_umount_llt, test_umount_rootfs) -{ - rootfs_umount_request *req = NULL; - rootfs_umount_response *resp = NULL; - int i = 0; - - // Test parameter NULL - ASSERT_NE(umount_rootfs(NULL, NULL), 0); - ASSERT_NE(umount_rootfs(NULL, &resp), 0); - free_rootfs_umount_response(resp); - resp = NULL; - - // Test content of parameter NULL - req = (rootfs_umount_request*)util_common_calloc_s(sizeof(rootfs_umount_request)); - ASSERT_TRUE(req != NULL); - ASSERT_NE(umount_rootfs(req, &resp), 0); - free_rootfs_umount_request(req); - req = NULL; - free_rootfs_umount_response(resp); - resp = NULL; - - // Test parameter collect - req = (rootfs_umount_request*)util_common_calloc_s(sizeof(rootfs_umount_request)); - ASSERT_TRUE(req != NULL); - req->name_id = util_strdup_s("image_name"); - ASSERT_TRUE(req->name_id != NULL); - - MOCK_SET_DEFAULT_ISULAD_KIT_OPTS - MOCK_SET_V(execvp, execvp_success); - ASSERT_EQ(umount_rootfs(req, &resp), 0); - ASSERT_TRUE(resp != NULL); - MOCK_CLEAR_DEFAULT_ISULAD_KIT_OPTS - MOCK_CLEAR(execvp); - - free_rootfs_umount_request(req); - req = NULL; - free_rootfs_umount_response(resp); - resp = NULL; - - // Put MOCK_SET_V here to avoid warning "(style) Local variable MOCK_SET_V shadows outer variable" - MOCK_SET_V(util_exec_cmd, util_exec_cmd_fail); - // 1. Test util_exec_cmd failed with stderr_buffer != NULL - // 2. Test util_exec_cmd failed with stderr_buffer == NULL - for (i = 0; i < 2; i++) { - req = (rootfs_umount_request*)util_common_calloc_s(sizeof(rootfs_umount_request)); - ASSERT_TRUE(req != NULL); - req->name_id = util_strdup_s("image_name"); - ASSERT_TRUE(req->name_id != NULL); - - MOCK_SET_DEFAULT_ISULAD_KIT_OPTS - ASSERT_NE(umount_rootfs(req, &resp), 0); - MOCK_CLEAR_DEFAULT_ISULAD_KIT_OPTS - - free_rootfs_umount_request(req); - req = NULL; - free_rootfs_umount_response(resp); - resp = NULL; - } - MOCK_CLEAR(util_exec_cmd); -} - -TEST(oci_rootfs_umount_llt, test_free_rootfs_umount_request) -{ - rootfs_umount_request *req = NULL; - - // Test free NULL - free_rootfs_umount_request(NULL); - - // Test free name_id NULL - req = (rootfs_umount_request*)util_common_calloc_s(sizeof(rootfs_umount_request)); - ASSERT_TRUE(req != NULL); - - free_rootfs_umount_request(req); - req = NULL; - - // Test free all Not NULL - req = (rootfs_umount_request*)util_common_calloc_s(sizeof(rootfs_umount_request)); - ASSERT_TRUE(req != NULL); - req->name_id = util_strdup_s("image_name"); - ASSERT_TRUE(req->name_id != NULL); - - free_rootfs_umount_request(req); - req = NULL; -} - -TEST(oci_rootfs_umount_llt, test_free_rootfs_umount_response) -{ - rootfs_umount_response *resp = NULL; - - // Test free NULL - free_rootfs_umount_response(NULL); - - // Test free errmsg NULL - resp = (rootfs_umount_response*)util_common_calloc_s(sizeof(rootfs_umount_response)); - ASSERT_TRUE(resp != NULL); - - free_rootfs_umount_response(resp); - resp = NULL; - - // Test free all Not NULL - resp = (rootfs_umount_response*)util_common_calloc_s(sizeof(rootfs_umount_response)); - ASSERT_TRUE(resp != NULL); - resp->errmsg = util_strdup_s("This is error message"); - ASSERT_TRUE(resp->errmsg != NULL); - - free_rootfs_umount_response(resp); - resp = NULL; -} diff --git a/test/include/mock.h b/test/include/mock.h index caf8902..8ac7d2a 100644 --- a/test/include/mock.h +++ b/test/include/mock.h @@ -1,13 +1,5 @@ /* - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. - * iSulad licensed under the Mulan PSL v1. - * You can use this software according to the terms and conditions of the Mulan PSL v1. - * You may obtain a copy of Mulan PSL v1 at: - * http://license.coscl.org.cn/MulanPSL - * 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 v1 for more details. + * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. * iSulad licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: @@ -131,3 +123,4 @@ extern "C" { #endif /* MOCK_H */ + diff --git a/test/llt.sh b/test/llt.sh index 848f848..2821754 100644 --- a/test/llt.sh +++ b/test/llt.sh @@ -1,95 +1,109 @@ +####################################################################### +##- @Copyright (C) Huawei Technologies., Ltd. 2019. All rights reserved. +# - iSulad licensed under the Mulan PSL v1. +# - You can use this software according to the terms and conditions of the Mulan PSL v1. +# - You may obtain a copy of Mulan PSL v1 at: +# - http://license.coscl.org.cn/MulanPSL +# - 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 v1 for more details. +##- @Description: generate cetification +##- @Author: wujing +##- @Create: 2019-04-25 +####################################################################### #! /bin/bash #set -xe usage() { - echo "Usage: sh llt.sh [OPTIONS]" - echo "Use llt.sh to control llt operation" - echo "" - echo "Misc:" - echo " -h, --help Print this help, then exit" - echo - echo "Compile Options:" - echo " -m, --cmake