Package init
This commit is contained in:
parent
ffd6ebe70c
commit
2556c6e04c
@ -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)
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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"
|
||||
```
|
||||
@ -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'
|
||||
```
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
541
src/api/image_client/isula_image.proto
Normal file
541
src/api/image_client/isula_image.proto
Normal file
@ -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<string, bool> 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/<full-path-to-profile>: the profile installed on the node.
|
||||
// <full-path-to-profile> 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<string, string> 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/<podUID>/`
|
||||
// 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<string, string> 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<string, string> 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<string, string> 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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -82,3 +82,4 @@
|
||||
"/ContainerService/Attach",
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
||||
@ -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/<full-path-to-profile>: the profile installed on the node.
|
||||
// <full-path-to-profile> 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/<podUID>/`
|
||||
// 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<string, string> 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<string, string> 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/<full-path-to-profile>: the profile installed on the node.
|
||||
// <full-path-to-profile> 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/<podUID>/`
|
||||
// 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{
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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<string, string> filters = 1;
|
||||
}
|
||||
|
||||
message ListImagesResponse {
|
||||
|
||||
@ -34,3 +34,4 @@
|
||||
#define ImagesServiceInspect "/ImagesService/Inspect"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -137,3 +137,4 @@ int cmd_kill_main(int argc, const char **argv)
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -96,3 +96,4 @@ int cmd_rename_main(int argc, const char **argv)
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_rename_args;
|
||||
int cmd_rename_main(int argc, const char **argv);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -117,3 +117,4 @@ int cmd_restart_main(int argc, const char **argv)
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -121,3 +121,4 @@ int cmd_stop_main(int argc, const char **argv)
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -170,3 +170,4 @@ int cmd_events_main(int argc, const char **argv)
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -116,3 +116,4 @@ int cmd_pause_main(int argc, const char **argv)
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_pause_args;
|
||||
int cmd_pause_main(int argc, const char **argv);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_resume_args;
|
||||
int cmd_resume_main(int argc, const char **argv);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -164,3 +164,4 @@ int update_checker(const struct client_arguments *args)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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, "<none>");
|
||||
printf("%-*s ", (int)length->tag_length, "<none>");
|
||||
} 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, "<none>");
|
||||
} 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("<none>");
|
||||
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 : "<none>");
|
||||
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);
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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,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 */
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -26,3 +26,4 @@ extern struct client_arguments g_cmd_health_check_args;
|
||||
int cmd_health_check_main(int argc, const char **argv);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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 <json>: 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);
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -12,7 +12,12 @@
|
||||
* Create: 2018-11-08
|
||||
* Description: provide container ps functions
|
||||
******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <regex.h>
|
||||
#include <errno.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -131,3 +131,4 @@ int cmd_wait_main(int argc, const char **argv)
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -387,3 +387,4 @@ int cmd_attach_main(int argc, const char **argv)
|
||||
out:
|
||||
exit((exit_code != 0) ? (int)exit_code : ret);
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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: <name|uid>[:<group|gid>])", 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 */
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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 <stdbool.h>
|
||||
|
||||
#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
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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<sTB> stub_;
|
||||
std::string m_tlsMode { ClientBaseConstants::TLS_OFF };
|
||||
std::string m_certFile { "" };
|
||||
|
||||
unsigned int deadline;
|
||||
};
|
||||
|
||||
template <class REQUEST, class RESPONSE, class FUNC>
|
||||
@ -200,8 +210,14 @@ int container_func(const REQUEST *request, RESPONSE *response, void *arg) noexce
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::unique_ptr<FUNC> client(new FUNC(arg));
|
||||
std::unique_ptr<FUNC> client(new (std::nothrow) FUNC(arg));
|
||||
if (client == nullptr) {
|
||||
ERROR("Out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return client->run(request, response);
|
||||
}
|
||||
|
||||
#endif /* __CLIENT_BASH_H */
|
||||
|
||||
|
||||
@ -32,3 +32,4 @@ int grpc_ops_init(lcrc_connect_ops *ops)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -28,3 +28,4 @@ int grpc_ops_init(lcrc_connect_ops *ops);
|
||||
#endif
|
||||
|
||||
#endif /* __GRPC_CLIENT_H */
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -28,3 +28,4 @@ int grpc_containers_client_ops_init(lcrc_connect_ops *ops);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
* Description: provide grpc container service functions
|
||||
******************************************************************************/
|
||||
#include "grpc_images_client.h"
|
||||
#include <string>
|
||||
#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<std::string, std::string> *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<runtime::ImageService, runtime::ImageService::Stub, lcrc_pull_request,
|
||||
runtime::PullImageRequest, lcrc_pull_response, runtime::PullImageResponse> {
|
||||
class ImagesPull : public
|
||||
ClientBase<runtime::v1alpha2::ImageService, runtime::v1alpha2::ImageService::Stub, lcrc_pull_request,
|
||||
runtime::v1alpha2::PullImageRequest, lcrc_pull_response, runtime::v1alpha2::PullImageResponse> {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -28,3 +28,4 @@ int grpc_images_client_ops_init(lcrc_connect_ops *ops);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
1041
src/connect/client/grpc/grpc_isula_image_client.cc
Normal file
1041
src/connect/client/grpc/grpc_isula_image_client.cc
Normal file
File diff suppressed because it is too large
Load Diff
30
src/connect/client/grpc/grpc_isula_image_client.h
Normal file
30
src/connect/client/grpc/grpc_isula_image_client.h
Normal file
@ -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 */
|
||||
495
src/connect/client/isula_image_connect.c
Normal file
495
src/connect/client/isula_image_connect.c
Normal file
@ -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);
|
||||
}
|
||||
367
src/connect/client/isula_image_connect.h
Normal file
367
src/connect/client/isula_image_connect.h
Normal file
@ -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 <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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 */
|
||||
@ -49,3 +49,4 @@ lcrc_connect_ops *get_connect_client_ops(void)
|
||||
{
|
||||
return &g_connect_ops;
|
||||
}
|
||||
|
||||
|
||||
@ -143,3 +143,4 @@ lcrc_connect_ops *get_connect_client_ops(void);
|
||||
#endif
|
||||
|
||||
#endif /* __LCRC_CONNECT_H */
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user