Package init

This commit is contained in:
dogsheng 2019-12-25 15:50:34 +08:00
parent ffd6ebe70c
commit 2556c6e04c
441 changed files with 14359 additions and 8892 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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)

View File

@ -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"
```

View File

@ -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'
```

View File

View File

@ -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

View File

@ -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

View File

@ -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)

View 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;
}

View File

@ -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;

View File

@ -82,3 +82,4 @@
"/ContainerService/Attach",
*/
#endif

View File

@ -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{
}

View File

@ -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;

View File

@ -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 {

View File

@ -34,3 +34,4 @@
#define ImagesServiceInspect "/ImagesService/Inspect"
#endif

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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;

View File

@ -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 */

View File

@ -137,3 +137,4 @@ int cmd_kill_main(int argc, const char **argv)
exit(EXIT_SUCCESS);
}

View File

@ -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

View File

@ -96,3 +96,4 @@ int cmd_rename_main(int argc, const char **argv)
exit(EXIT_SUCCESS);
}

View File

@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_rename_args;
int cmd_rename_main(int argc, const char **argv);
#endif

View File

@ -117,3 +117,4 @@ int cmd_restart_main(int argc, const char **argv)
exit(EXIT_SUCCESS);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -121,3 +121,4 @@ int cmd_stop_main(int argc, const char **argv)
exit(EXIT_SUCCESS);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -170,3 +170,4 @@ int cmd_events_main(int argc, const char **argv)
exit(EXIT_SUCCESS);
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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

View File

@ -116,3 +116,4 @@ int cmd_pause_main(int argc, const char **argv)
exit(EXIT_SUCCESS);
}

View File

@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_pause_args;
int cmd_pause_main(int argc, const char **argv);
#endif

View File

@ -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);
}

View File

@ -23,3 +23,4 @@ extern struct client_arguments g_cmd_resume_args;
int cmd_resume_main(int argc, const char **argv);
#endif

View File

@ -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 */

View File

@ -164,3 +164,4 @@ int update_checker(const struct client_arguments *args)
return ret;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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:

View File

@ -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 */

View File

@ -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:

View File

@ -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 */

View File

@ -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:

View File

@ -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 */

View File

@ -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 */

View File

@ -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);
}

View File

@ -26,3 +26,4 @@ extern struct client_arguments g_cmd_health_check_args;
int cmd_health_check_main(int argc, const char **argv);
#endif

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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, &timestamp)) {
ERROR("Failed to get timestamp");
return -1;
}
if (!get_time_buffer(&timestamp, 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(&reg, patten, REG_EXTENDED);
status = regexec(&reg, source, MATCH_NUM, pmatch, 0);
regfree(&reg);
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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -131,3 +131,4 @@ int cmd_wait_main(int argc, const char **argv)
exit(EXIT_SUCCESS);
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -387,3 +387,4 @@ int cmd_attach_main(int argc, const char **argv)
out:
exit((exit_code != 0) ? (int)exit_code : ret);
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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 */

View File

@ -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()

View File

@ -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()

View File

@ -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

View File

@ -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()

View File

@ -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 */

View File

@ -32,3 +32,4 @@ int grpc_ops_init(lcrc_connect_ops *ops)
return 0;
}

View File

@ -28,3 +28,4 @@ int grpc_ops_init(lcrc_connect_ops *ops);
#endif
#endif /* __GRPC_CLIENT_H */

View File

@ -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;
}

View File

@ -28,3 +28,4 @@ int grpc_containers_client_ops_init(lcrc_connect_ops *ops);
#endif
#endif

View File

@ -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;
}

View File

@ -28,3 +28,4 @@ int grpc_images_client_ops_init(lcrc_connect_ops *ops);
#endif
#endif

File diff suppressed because it is too large Load Diff

View 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 */

View 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);
}

View 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 */

View File

@ -49,3 +49,4 @@ lcrc_connect_ops *get_connect_client_ops(void)
{
return &g_connect_ops;
}

View File

@ -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