Package init
This commit is contained in:
commit
b405092176
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.pyc
|
||||||
|
build
|
||||||
74
CMakeLists.txt
Normal file
74
CMakeLists.txt
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
cmake_minimum_required (VERSION 3.12.1)
|
||||||
|
project (lcr)
|
||||||
|
|
||||||
|
option(VERSION "set lcr version" ON)
|
||||||
|
if (VERSION STREQUAL "ON")
|
||||||
|
set(LCR_VERSION "1.0.15")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(DEBUG "set lcr gcc option" ON)
|
||||||
|
if (DEBUG STREQUAL "ON")
|
||||||
|
add_definitions("-g -o2")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(GCOV "set lcr gcov option" OFF)
|
||||||
|
if (GCOV STREQUAL "ON")
|
||||||
|
set(LCR_GCOV "ON")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (LIB_INSTALL_DIR)
|
||||||
|
set(LIB_INSTALL_DIR_DEFAULT ${LIB_INSTALL_DIR})
|
||||||
|
else()
|
||||||
|
set(LIB_INSTALL_DIR_DEFAULT "lib")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# check depends libs and headers
|
||||||
|
include(cmake/checker.cmake)
|
||||||
|
if (CHECKER_RESULT)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Get the latest abbreviated commit hash of the working branch
|
||||||
|
execute_process(
|
||||||
|
COMMAND git rev-parse HEAD
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
message("-- commit id: " ${GIT_COMMIT_HASH})
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "-fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2 -O2 -Wall -Werror")
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-E -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wtrampolines -fPIE -pie -shared -pthread")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-E -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wtrampolines -fPIE -pie")
|
||||||
|
|
||||||
|
add_definitions(-DLCRPATH="${CMAKE_INSTALL_PREFIX}/var/lib/lcr")
|
||||||
|
add_definitions(-DLOGPATH="${CMAKE_INSTALL_PREFIX}/var/log/lcr")
|
||||||
|
add_definitions(-DLCR_GIT_COMMIT="${GIT_COMMIT_HASH}")
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
|
||||||
|
"${CMAKE_BINARY_DIR}/conf/config.h"
|
||||||
|
)
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/lcr.pc.in"
|
||||||
|
"${CMAKE_BINARY_DIR}/conf/lcr.pc"
|
||||||
|
)
|
||||||
|
|
||||||
|
# build which type of lcr library
|
||||||
|
option(USESHARED "set type of liblcr, default is shared" ON)
|
||||||
|
if (USESHARED STREQUAL "ON")
|
||||||
|
set(LIBTYPE "SHARED")
|
||||||
|
message("-- Build shared library")
|
||||||
|
else ()
|
||||||
|
set(LIBTYPE "STATIC")
|
||||||
|
message("-- Build static library")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
|
|
||||||
|
# install all files
|
||||||
|
install(FILES ${CMAKE_BINARY_DIR}/conf/lcr.pc
|
||||||
|
DESTINATION ${LIB_INSTALL_DIR_DEFAULT}/pkgconfig PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE)
|
||||||
|
install(FILES src/lcrcontainer.h
|
||||||
|
DESTINATION include/lcr)
|
||||||
121
License/LICENSE
Normal file
121
License/LICENSE
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
木兰宽松许可证, 第1版
|
||||||
|
|
||||||
|
木兰宽松许可证, 第1版
|
||||||
|
2019年8月 http://license.coscl.org.cn/MulanPSL
|
||||||
|
|
||||||
|
您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第1版(“本许可证”)的如下条款的约束:
|
||||||
|
|
||||||
|
0. 定义
|
||||||
|
|
||||||
|
“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
|
||||||
|
|
||||||
|
“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
|
||||||
|
|
||||||
|
“法人实体”是指提交贡献的机构及其“关联实体”。
|
||||||
|
|
||||||
|
“关联实体”是指,对“本许可证”下的一方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
|
||||||
|
|
||||||
|
“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
|
||||||
|
|
||||||
|
1. 授予版权许可
|
||||||
|
|
||||||
|
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
|
||||||
|
|
||||||
|
2. 授予专利许可
|
||||||
|
|
||||||
|
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括仅因您或他人修改“贡献”或其他结合而将必然会侵犯到的专利权利要求。如您或您的“关联实体”直接或间接地(包括通过代理、专利被许可人或受让人),就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
|
||||||
|
|
||||||
|
3. 无商标许可
|
||||||
|
|
||||||
|
“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
|
||||||
|
|
||||||
|
4. 分发限制
|
||||||
|
|
||||||
|
您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
|
||||||
|
|
||||||
|
5. 免责声明与责任限制
|
||||||
|
|
||||||
|
“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
|
||||||
|
|
||||||
|
条款结束。
|
||||||
|
|
||||||
|
如何将木兰宽松许可证,第1版,应用到您的软件
|
||||||
|
|
||||||
|
如果您希望将木兰宽松许可证,第1版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
|
||||||
|
|
||||||
|
1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
|
||||||
|
|
||||||
|
2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
|
||||||
|
|
||||||
|
3, 请将如下声明文本放入每个源文件的头部注释中。
|
||||||
|
|
||||||
|
Copyright (c) [2019] [name of copyright holder]
|
||||||
|
[Software Name] is 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.
|
||||||
|
|
||||||
|
|
||||||
|
Mulan Permissive Software License,Version 1
|
||||||
|
|
||||||
|
Mulan Permissive Software License,Version 1 (Mulan PSL v1)
|
||||||
|
August 2019 http://license.coscl.org.cn/MulanPSL
|
||||||
|
|
||||||
|
Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v1 (this License) with following terms and conditions:
|
||||||
|
|
||||||
|
0. Definition
|
||||||
|
|
||||||
|
Software means the program and related documents which are comprised of those Contribution and licensed under this License.
|
||||||
|
|
||||||
|
Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
|
||||||
|
|
||||||
|
Legal Entity means the entity making a Contribution and all its Affiliates.
|
||||||
|
|
||||||
|
Affiliates means entities that control, or are controlled by, or are under common control with a party to this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
|
||||||
|
|
||||||
|
Contribution means the copyrightable work licensed by a particular Contributor under this License.
|
||||||
|
|
||||||
|
1. Grant of Copyright License
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
|
||||||
|
|
||||||
|
2. Grant of Patent License
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed, excluding of any patent claims solely be infringed by your or others’ modification or other combinations. If you or your Affiliates directly or indirectly (including through an agent, patent licensee or assignee), institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
|
||||||
|
|
||||||
|
3. No Trademark License
|
||||||
|
|
||||||
|
No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4.
|
||||||
|
|
||||||
|
4. Distribution Restriction
|
||||||
|
|
||||||
|
You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
|
||||||
|
|
||||||
|
5. Disclaimer of Warranty and Limitation of Liability
|
||||||
|
|
||||||
|
The Software and Contribution in it are provided without warranties of any kind, either express or implied. In no event shall any Contributor or copyright holder be liable to you for any damages, including, but not limited to any direct, or indirect, special or consequential damages arising from your use or inability to use the Software or the Contribution in it, no matter how it’s caused or based on which legal theory, even if advised of the possibility of such damages.
|
||||||
|
|
||||||
|
End of the Terms and Conditions
|
||||||
|
|
||||||
|
How to apply the Mulan Permissive Software License,Version 1 (Mulan PSL v1) to your software
|
||||||
|
|
||||||
|
To apply the Mulan PSL v1 to your work, for easy identification by recipients, you are suggested to complete following three steps:
|
||||||
|
|
||||||
|
i. Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
|
||||||
|
ii. Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package;
|
||||||
|
iii. Attach the statement to the appropriate annotated syntax at the beginning of each source file.
|
||||||
|
|
||||||
|
Copyright (c) [2019] [name of copyright holder]
|
||||||
|
[Software Name] is 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.
|
||||||
23
README.md
Normal file
23
README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# lcr
|
||||||
|
|
||||||
|
`lcr`(Lightweight Container Runtime) is CLI tool for spawning and running containers according to OCI specification.
|
||||||
|
It is based on `liblxc` and written by `C`.
|
||||||
|
|
||||||
|
## How to Contribute
|
||||||
|
|
||||||
|
We always welcome new contributors. And we are happy to provide guidance for the new contributors.
|
||||||
|
iSulad follows the kernel coding conventions. You can find a detailed introduction at:
|
||||||
|
|
||||||
|
- https://www.kernel.org/doc/html/v4.10/process/coding-style.html
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
Without considering distribution specific details a simple
|
||||||
|
|
||||||
|
mkdir -p build && cd ./build && cmake .. && make && sudo make install
|
||||||
|
|
||||||
|
is usually sufficient.
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
lcr is licensed under the Mulan PSL v1.
|
||||||
42
cmake/checker.cmake
Normal file
42
cmake/checker.cmake
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# check depends library and headers
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
||||||
|
macro(_CHECK)
|
||||||
|
if (${ARGV0} STREQUAL "${ARGV1}")
|
||||||
|
message("error: can not find " ${ARGV2} " program")
|
||||||
|
set(CHECKER_RESULT 1)
|
||||||
|
else()
|
||||||
|
message("-- found " ${ARGV2} " --- works")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
#check python
|
||||||
|
find_program(CMD_PYTHON python)
|
||||||
|
_CHECK(CMD_PYTHON "CMD_PYTHON-NOTFOUND" "python")
|
||||||
|
|
||||||
|
# check securec
|
||||||
|
find_path(LIBSECUREC_INCLUDE_DIR securec.h)
|
||||||
|
_CHECK(LIBSECUREC_INCLUDE_DIR "LIBSECUREC_INCLUDE_DIR-NOTFOUND" "securec.h")
|
||||||
|
|
||||||
|
find_library(LIBSECUREC_LIBRARY securec)
|
||||||
|
_CHECK(LIBSECUREC_LIBRARY "LIBSECUREC_LIBRARY-NOTFOUND" "libsecurec.so")
|
||||||
|
|
||||||
|
# check liblxc
|
||||||
|
pkg_check_modules(PC_LIBLXC REQUIRED "lxc>=3")
|
||||||
|
find_path(LIBLXC_INCLUDE_DIR lxc/lxccontainer.h
|
||||||
|
HINTS ${PC_LIBLXC_INCLUDEDIR} ${PC_LIBLXC_INCLUDE_DIRS})
|
||||||
|
_CHECK(LIBLXC_INCLUDE_DIR "LIBLXC_INCLUDE_DIR-NOTFOUND" "lxc/lxccontainer.h")
|
||||||
|
|
||||||
|
find_library(LIBLXC_LIBRARY lxc
|
||||||
|
HINTS ${PC_LIBLXC_LIBDIR} ${PC_LIBLXC_LIBRARY_DIRS})
|
||||||
|
_CHECK(LIBLXC_LIBRARY "LIBLXC_LIBRARY-NOTFOUND" "liblxc.so")
|
||||||
|
|
||||||
|
# check libyajl
|
||||||
|
pkg_check_modules(PC_LIBYAJL REQUIRED "yajl>=2")
|
||||||
|
find_path(LIBYAJL_INCLUDE_DIR yajl/yajl_tree.h
|
||||||
|
HINTS ${PC_LIBYAJL_INCLUDEDIR} ${PC_LIBYAJL_INCLUDE_DIRS})
|
||||||
|
_CHECK(LIBYAJL_INCLUDE_DIR "LIBYAJL_INCLUDE_DIR-NOTFOUND" "yajl/yajl_tree.h")
|
||||||
|
|
||||||
|
find_library(LIBYAJL_LIBRARY yajl
|
||||||
|
HINTS ${PC_LIBYAJL_LIBDIR} ${PC_LIBYAJL_LIBRARY_DIRS})
|
||||||
|
_CHECK(LIBYAJL_LIBRARY "LIBYAJL_LIBRARY-NOTFOUND" "libyajl.so")
|
||||||
1
config.h.in
Normal file
1
config.h.in
Normal file
@ -0,0 +1 @@
|
|||||||
|
#cmakedefine VERSION "@LCR_VERSION@"
|
||||||
1672
contrib/oci.config.json
Normal file
1672
contrib/oci.config.json
Normal file
File diff suppressed because it is too large
Load Diff
12
lcr.pc.in
Normal file
12
lcr.pc.in
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
libdir=@CMAKE_INSTALL_PREFIX@/lib
|
||||||
|
localstatedir=@CMAKE_INSTALL_PREFIX@/var
|
||||||
|
includedir=@CMAKE_INSTALL_PREFIX@/include
|
||||||
|
|
||||||
|
Name: liblcr
|
||||||
|
Description: light-weighted container runtime library
|
||||||
|
Version: @LCR_VERSION@
|
||||||
|
URL: http://code.huawei.com/containers/liblcr
|
||||||
|
Libs: -L@CMAKE_INSTALL_PREFIX@/lib -llcr
|
||||||
|
Cflags: -I@CMAKE_INSTALL_PREFIX@/include
|
||||||
|
|
||||||
78
lcr.spec
Normal file
78
lcr.spec
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
%global _version 1.0.15
|
||||||
|
%global _release 20190612.105034.gitefd3b7ac
|
||||||
|
Name: lcr
|
||||||
|
Version: %{_version}
|
||||||
|
Release: %{_release}%{?dist}
|
||||||
|
URL: http://code.huawei.com/containers/lcr
|
||||||
|
Source: %{name}-1.0.tar.gz
|
||||||
|
Summary: Lightweight Container Runtime
|
||||||
|
Group: Applications/System
|
||||||
|
License: Mulan PSL v1
|
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}
|
||||||
|
|
||||||
|
BuildRequires: cmake
|
||||||
|
BuildRequires: lxc
|
||||||
|
BuildRequires: lxc-devel
|
||||||
|
BuildRequires: yajl yajl-devel
|
||||||
|
BuildRequires: libsecurec libsecurec-devel
|
||||||
|
Requires: rsync bridge-utils lxc
|
||||||
|
ExclusiveArch: x86_64 aarch64
|
||||||
|
|
||||||
|
%ifarch x86_64
|
||||||
|
Provides: liblcr.so()(64bit)
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%ifarch aarch64
|
||||||
|
Provides: liblcr.so()(64bit)
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%description
|
||||||
|
Containers are insulated areas inside a system, which have their own namespace
|
||||||
|
for filesystem, network, PID, IPC, CPU and memory allocation and which can be
|
||||||
|
created using the Control Group and Namespace features included in the Linux
|
||||||
|
kernel.
|
||||||
|
|
||||||
|
This package provides the lightweight container tools and library to control
|
||||||
|
lxc-based containers.
|
||||||
|
|
||||||
|
%global debug_package %{nil}
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -c -n %{name}-%{version}
|
||||||
|
|
||||||
|
%build
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
%cmake -DDEBUG=OFF -DLIB_INSTALL_DIR=%{_libdir} ../
|
||||||
|
%make_build
|
||||||
|
|
||||||
|
%install
|
||||||
|
rm -rf %{buildroot}
|
||||||
|
cd build
|
||||||
|
mkdir -p %{buildroot}/{%{_libdir},%{_libdir}/pkgconfig,%{_includedir}/%{name},%{_bindir}}
|
||||||
|
install -m 0644 ./src/liblcr.so %{buildroot}/%{_libdir}/liblcr.so
|
||||||
|
install -m 0644 ./conf/lcr.pc %{buildroot}/%{_libdir}/pkgconfig/lcr.pc
|
||||||
|
install -m 0644 ../src/lcrcontainer.h %{buildroot}/%{_includedir}/%{name}/lcrcontainer.h
|
||||||
|
|
||||||
|
find %{buildroot} -type f -name '*.la' -exec rm -f {} ';'
|
||||||
|
find %{buildroot} -name '*.a' -exec rm -f {} ';'
|
||||||
|
find %{buildroot} -name '*.cmake' -exec rm -f {} ';'
|
||||||
|
|
||||||
|
%clean
|
||||||
|
rm -rf %{buildroot}
|
||||||
|
|
||||||
|
%pre
|
||||||
|
|
||||||
|
%post -p /sbin/ldconfig
|
||||||
|
|
||||||
|
%postun -p /sbin/ldconfig
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
%{_libdir}/*
|
||||||
|
%{_libdir}/pkgconfig/%{name}.pc
|
||||||
|
%{_includedir}/%{name}/lcrcontainer.h
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
* Fri Apr 14 2017 Hui Wang <hw.huiwang@huawei.com> - 0.0.1
|
||||||
|
- Initial RPM release
|
||||||
64
src/CMakeLists.txt
Normal file
64
src/CMakeLists.txt
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# generate .c and .h files for json
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/json)
|
||||||
|
|
||||||
|
# get liblcr source files
|
||||||
|
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} topsrcs)
|
||||||
|
message("-- Get top srcs: " ${topsrcs})
|
||||||
|
aux_source_directory(${CMAKE_BINARY_DIR}/json generatesrcs)
|
||||||
|
message("-- Get generate srcs: " ${generatesrcs})
|
||||||
|
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/json/schema/src commonjsonsrcs)
|
||||||
|
message("-- Get common json srcs: " ${commonjsonsrcs})
|
||||||
|
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/json topjsonsrcs)
|
||||||
|
message("-- Get top json srcs: " ${topjsonsrcs})
|
||||||
|
|
||||||
|
# set liblcr library
|
||||||
|
add_library(liblcr ${LIBTYPE} ${topsrcs} ${topjsonsrcs} ${commonjsonsrcs} ${generatesrcs})
|
||||||
|
|
||||||
|
set(check_incs
|
||||||
|
${LIBSECUREC_INCLUDE_DIR}
|
||||||
|
${LIBLXC_INCLUDE_DIR}
|
||||||
|
${LIBYAJL_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
set(check_libs
|
||||||
|
${LIBSECUREC_LIBRARY}
|
||||||
|
${LIBLXC_LIBRARY}
|
||||||
|
${LIBYAJL_LIBRARY}
|
||||||
|
)
|
||||||
|
list(REMOVE_DUPLICATES check_incs)
|
||||||
|
list(REMOVE_DUPLICATES check_libs)
|
||||||
|
|
||||||
|
# set liblcr include dirs
|
||||||
|
target_include_directories(liblcr
|
||||||
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/json
|
||||||
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/json/schema/src
|
||||||
|
PUBLIC ${CMAKE_BINARY_DIR}/json
|
||||||
|
PUBLIC ${CMAKE_BINARY_DIR}/conf
|
||||||
|
PUBLIC ${check_incs}
|
||||||
|
)
|
||||||
|
|
||||||
|
# set liblcr compile flags
|
||||||
|
set_target_properties(liblcr PROPERTIES PREFIX "")
|
||||||
|
|
||||||
|
if (LCR_GCOV)
|
||||||
|
set(CMAKE_C_FLAGS_DEBUG "-Wall -fprofile-arcs -ftest-coverage")
|
||||||
|
message("------compile with gcov-------------")
|
||||||
|
message("-----CFLAGS: " ${CMAKE_C_FLAGS_DEBUG})
|
||||||
|
message("------------------------------------")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(liblcr ${check_libs})
|
||||||
|
|
||||||
|
if (CMAKE_TOOLCHAIN_FILE)
|
||||||
|
target_link_directories(liblcr PUBLIC ${CMAKE_LIBRARY_PATH})
|
||||||
|
target_link_libraries(liblcr ${EXTRAL_LINK_LIBS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(cmd)
|
||||||
|
if (LCR_GCOV)
|
||||||
|
target_link_libraries(liblcr -lgcov)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# install all files
|
||||||
|
install(TARGETS liblcr
|
||||||
|
LIBRARY DESTINATION ${LIB_INSTALL_DIR_DEFAULT} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE)
|
||||||
239
src/buffer.c
Normal file
239
src/buffer.c
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container buffer definition
|
||||||
|
******************************************************************************/
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <securec.h>
|
||||||
|
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
/* buffer allocate */
|
||||||
|
Buffer *buffer_alloc(size_t initial_size)
|
||||||
|
{
|
||||||
|
Buffer *buf = NULL;
|
||||||
|
char *tmp = NULL;
|
||||||
|
|
||||||
|
if (initial_size == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = util_common_calloc_s(sizeof(Buffer));
|
||||||
|
if (buf == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = calloc(1, initial_size);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->contents = tmp;
|
||||||
|
buf->bytes_used = 0;
|
||||||
|
buf->total_size = initial_size;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buffer strlen */
|
||||||
|
static size_t buffer_strlen(const Buffer *buf)
|
||||||
|
{
|
||||||
|
return buf == NULL ? 0 : buf->bytes_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buffer free */
|
||||||
|
void buffer_free(Buffer *buf)
|
||||||
|
{
|
||||||
|
if (buf == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free(buf->contents);
|
||||||
|
buf->contents = NULL;
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buffer has space */
|
||||||
|
static bool buffer_has_space(const Buffer *buf, size_t desired_length)
|
||||||
|
{
|
||||||
|
size_t bytes_remaining = 0;
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bytes_remaining = buf->total_size - buf->bytes_used;
|
||||||
|
|
||||||
|
return desired_length <= bytes_remaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buffer grow */
|
||||||
|
static int buffer_grow(Buffer *buf, size_t minimum_size)
|
||||||
|
{
|
||||||
|
size_t factor = 0;
|
||||||
|
errno_t ret = 0;
|
||||||
|
size_t new_size = 0;
|
||||||
|
char *tmp = NULL;
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
factor = buf->total_size;
|
||||||
|
if (factor < minimum_size) {
|
||||||
|
factor = minimum_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (factor > SIZE_MAX / 2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_size = factor * 2;
|
||||||
|
if (new_size == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = util_common_calloc_s(new_size);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
ERROR("Out of memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = memcpy_s(tmp, new_size, buf->contents, buf->total_size);
|
||||||
|
if (ret != EOK) {
|
||||||
|
ERROR("Failed to copy memory");
|
||||||
|
free(tmp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf->contents);
|
||||||
|
buf->contents = tmp;
|
||||||
|
buf->total_size = new_size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buffer cat */
|
||||||
|
static void buffer_cat(Buffer *buf, const char *append, size_t length)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
if (append[i] == '\0') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(buf->contents + buf->bytes_used + i) = append[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->bytes_used += i;
|
||||||
|
*(buf->contents + buf->bytes_used) = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buffer append */
|
||||||
|
static int buffer_append(Buffer *buf, const char *append, size_t length)
|
||||||
|
{
|
||||||
|
size_t desired_length = 0;
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
desired_length = length + 1;
|
||||||
|
if (!buffer_has_space(buf, desired_length)) {
|
||||||
|
if (buffer_grow(buf, desired_length) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_cat(buf, append, length);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buffer nappendf */
|
||||||
|
int buffer_nappendf(Buffer *buf, size_t length, const char *format, ...)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
size_t printf_length = 0;
|
||||||
|
char *tmp = NULL;
|
||||||
|
va_list argp;
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > SIZE_MAX / sizeof(char) - 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf_length = length + 1;
|
||||||
|
tmp = calloc(1, printf_length * sizeof(char));
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(argp, format);
|
||||||
|
status = vsprintf_s(tmp, printf_length, format, argp);
|
||||||
|
va_end(argp);
|
||||||
|
if (status < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = buffer_append(buf, tmp, length);
|
||||||
|
if (status != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tmp);
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
free(tmp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buffer to string */
|
||||||
|
char *buffer_to_s(const Buffer *buf)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
char *result = NULL;
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = buffer_strlen(buf);
|
||||||
|
if (len == SIZE_MAX) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = calloc(1, len + 1);
|
||||||
|
if (result == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (strncpy_s(result, len + 1, buf->contents, len) != EOK) {
|
||||||
|
ERROR("Failed to copy string!");
|
||||||
|
free(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
32
src/buffer.h
Normal file
32
src/buffer.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container buffer definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef LCRD_BUFFER_H
|
||||||
|
#define LCRD_BUFFER_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
typedef struct Buffer {
|
||||||
|
char *contents;
|
||||||
|
size_t bytes_used;
|
||||||
|
size_t total_size;
|
||||||
|
} Buffer;
|
||||||
|
|
||||||
|
Buffer *buffer_alloc(size_t initial_size);
|
||||||
|
void buffer_free(Buffer *buf);
|
||||||
|
int buffer_nappendf(Buffer *buf, size_t length, const char *format, ...);
|
||||||
|
char *buffer_to_s(const Buffer *buf);
|
||||||
|
#endif
|
||||||
22
src/cmd/CMakeLists.txt
Normal file
22
src/cmd/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# get lcr source files
|
||||||
|
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} cmdsrcs)
|
||||||
|
|
||||||
|
# set lcr binary
|
||||||
|
add_executable(lcr ${cmdsrcs})
|
||||||
|
target_link_libraries(lcr liblcr)
|
||||||
|
|
||||||
|
# set lcr include headers
|
||||||
|
target_include_directories(lcr
|
||||||
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
PUBLIC ${CMAKE_SOURCE_DIR}/src/json
|
||||||
|
PUBLIC ${CMAKE_SOURCE_DIR}/src/json/schema/src
|
||||||
|
PUBLIC ${CMAKE_BINARY_DIR}/json
|
||||||
|
PUBLIC ${CMAKE_BINARY_DIR}/conf
|
||||||
|
)
|
||||||
|
if (LCR_GCOV)
|
||||||
|
target_link_libraries(lcr -lgcov)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# install all files
|
||||||
|
install(TARGETS lcr
|
||||||
|
RUNTIME DESTINATION bin PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE)
|
||||||
67
src/cmd/arguments.c
Normal file
67
src/cmd/arguments.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container arguments functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commands.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
/* lcr arguments init */
|
||||||
|
void lcr_arguments_init(struct lcr_arguments *args)
|
||||||
|
{
|
||||||
|
args->name = NULL;
|
||||||
|
args->log_file = NULL;
|
||||||
|
args->log_priority = NULL;
|
||||||
|
args->quiet = 0;
|
||||||
|
args->lcrpath = NULL;
|
||||||
|
args->create_rootfs = NULL;
|
||||||
|
args->create_dist = NULL;
|
||||||
|
args->spec_bundle = NULL;
|
||||||
|
args->spec_translate = NULL;
|
||||||
|
args->spec_dist = NULL;
|
||||||
|
args->list_quiet = false;
|
||||||
|
args->list_running = false;
|
||||||
|
args->list_stopped = false;
|
||||||
|
args->list_active = false;
|
||||||
|
args->start_daemonize = true;
|
||||||
|
args->start_pidfile = NULL;
|
||||||
|
args->console_logpath = NULL;
|
||||||
|
args->console_fifos[0] = NULL;
|
||||||
|
args->console_fifos[1] = NULL;
|
||||||
|
args->delete_force = false;
|
||||||
|
args->argc = 0;
|
||||||
|
args->argv = NULL;
|
||||||
|
args->ociconfig = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* print common help */
|
||||||
|
void print_common_help()
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
struct lcr_arguments cmd_common_args = {};
|
||||||
|
struct command_option options[] = {
|
||||||
|
COMMON_OPTIONS(cmd_common_args)
|
||||||
|
};
|
||||||
|
len = sizeof(options) / sizeof(options[0]);
|
||||||
|
qsort(options, len, sizeof(options[0]), compare_options);
|
||||||
|
fprintf(stdout, "COMMON OPTIONS :\n");
|
||||||
|
print_options((int)len, options);
|
||||||
|
}
|
||||||
99
src/cmd/arguments.h
Normal file
99
src/cmd/arguments.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container arguments definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __LCR_ARGUMENTS_H
|
||||||
|
#define __LCR_ARGUMENTS_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct lcr_arguments;
|
||||||
|
|
||||||
|
struct args_cgroup_resources {
|
||||||
|
char *blkio_weight;
|
||||||
|
char *cpu_shares;
|
||||||
|
char *cpu_period;
|
||||||
|
char *cpu_quota;
|
||||||
|
char *cpuset_cpus;
|
||||||
|
char *cpuset_mems;
|
||||||
|
char *memory_limit;
|
||||||
|
char *memory_swap;
|
||||||
|
char *memory_reservation;
|
||||||
|
char *kernel_memory_limit;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lcr_arguments {
|
||||||
|
const char *progname; /* sub command name */
|
||||||
|
|
||||||
|
// For common options
|
||||||
|
char *name; /*container name */
|
||||||
|
char *log_file;
|
||||||
|
char *log_priority;
|
||||||
|
int quiet;
|
||||||
|
|
||||||
|
char *lcrpath;
|
||||||
|
|
||||||
|
// lcr create
|
||||||
|
char *create_rootfs;
|
||||||
|
char *create_dist;
|
||||||
|
char *ociconfig;
|
||||||
|
|
||||||
|
// lcr run
|
||||||
|
// lcr spec
|
||||||
|
char *spec_bundle;
|
||||||
|
char *spec_translate;
|
||||||
|
char *spec_dist;
|
||||||
|
// lcr list
|
||||||
|
bool list_quiet;
|
||||||
|
bool list_active;
|
||||||
|
bool list_running;
|
||||||
|
bool list_stopped;
|
||||||
|
// lcr start
|
||||||
|
bool start_daemonize;
|
||||||
|
char *start_pidfile;
|
||||||
|
char *console_logpath;
|
||||||
|
const char *console_fifos[2];
|
||||||
|
|
||||||
|
// lcr kill
|
||||||
|
char *signal;
|
||||||
|
|
||||||
|
// lcr delete
|
||||||
|
bool delete_force;
|
||||||
|
// lcr update
|
||||||
|
struct args_cgroup_resources cr;
|
||||||
|
|
||||||
|
// remaining arguments
|
||||||
|
char * const * argv;
|
||||||
|
int argc;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define COMMON_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "logfile", 'o', &(cmdargs).log_file, \
|
||||||
|
"Set the log file path wherer debug information is written", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "logpriority", 'l', &(cmdargs).log_priority, "Set log priority to LEVEL", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_BOOL, false, "silence", 's', &(cmdargs).quiet, "Don't produce any output to stderr", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "lcrpath", 'P', &(cmdargs).lcrpath, "Use specified container path", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "help", 0, NULL, "Show help", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "version", 0, NULL, "Print the version", NULL }
|
||||||
|
|
||||||
|
|
||||||
|
extern void print_common_help();
|
||||||
|
|
||||||
|
extern void lcr_arguments_init(struct lcr_arguments *args);
|
||||||
|
|
||||||
|
#define lcr_print_error(arg, fmt, args...) \
|
||||||
|
fprintf(stderr, "%s: " fmt "\n", (arg)->progname, ## args)
|
||||||
|
|
||||||
|
#endif /*__LCR_ARGUMENTS_H*/
|
||||||
71
src/cmd/clean.c
Normal file
71
src/cmd/clean.c
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container clean functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "clean.h"
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
const char g_lcr_cmd_clean_desc[] =
|
||||||
|
"Delete any resources held by the container often used with detached container NAME";
|
||||||
|
static const char g_lcr_cmd_clean_usage[] = "clean [command options] --name=NAME";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_clean_args;
|
||||||
|
|
||||||
|
int cmd_clean_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = {
|
||||||
|
CLEAN_OPTIONS(g_lcr_cmd_clean_args),
|
||||||
|
COMMON_OPTIONS(g_lcr_cmd_clean_args)
|
||||||
|
};
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_clean_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]),
|
||||||
|
argc, (const char **)argv,
|
||||||
|
g_lcr_cmd_clean_desc, g_lcr_cmd_clean_usage);
|
||||||
|
if (command_parse_args(&cmd, &(g_lcr_cmd_clean_args.argc), &(g_lcr_cmd_clean_args.argv))) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(g_lcr_cmd_clean_args.name, g_lcr_cmd_clean_args.log_file,
|
||||||
|
g_lcr_cmd_clean_args.log_priority,
|
||||||
|
g_lcr_cmd_clean_args.progname,
|
||||||
|
g_lcr_cmd_clean_args.quiet,
|
||||||
|
LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_lcr_cmd_clean_args.name == NULL) {
|
||||||
|
fprintf(stderr, "missing container name, use -n,--name option\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lcr_clean(g_lcr_cmd_clean_args.name,
|
||||||
|
g_lcr_cmd_clean_args.lcrpath,
|
||||||
|
g_lcr_cmd_clean_args.log_file,
|
||||||
|
g_lcr_cmd_clean_args.log_priority,
|
||||||
|
0)) {
|
||||||
|
fprintf(stderr, "Failed to clean container %s\n", g_lcr_cmd_clean_args.name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "Container \"%s\" Cleaned\n", g_lcr_cmd_clean_args.name);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
28
src/cmd/clean.h
Normal file
28
src/cmd/clean.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container clean definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_CLEAN_H
|
||||||
|
#define __CMD_CLEAN_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define CLEAN_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL }
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_clean_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_clean_args;
|
||||||
|
int cmd_clean_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_CLEAN_H */
|
||||||
433
src/cmd/commander.c
Normal file
433
src/cmd/commander.c
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container commander functions
|
||||||
|
******************************************************************************/
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "utils.h"
|
||||||
|
#include "commander.h"
|
||||||
|
#include "securec.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
int compare_options(const void *s1, const void *s2)
|
||||||
|
{
|
||||||
|
return strcmp((*(const command_option_t *)s1).large, (*(const command_option_t *)s2).large);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_max_option_length(int options_len, const command_option_t *options)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int max_option_len = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < options_len; i++) {
|
||||||
|
command_option_t option = options[i];
|
||||||
|
// -s
|
||||||
|
int len = 2;
|
||||||
|
// -s, --large
|
||||||
|
if (option.large != NULL) {
|
||||||
|
len = (int)(strlen(option.large) + 6);
|
||||||
|
}
|
||||||
|
if (len > max_option_len) {
|
||||||
|
max_option_len = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_option_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_print_options(int options_len, const command_option_t *options, int max_option_len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < options_len; i++) {
|
||||||
|
command_option_t option = options[i];
|
||||||
|
int curindex;
|
||||||
|
int space_left = 0;
|
||||||
|
|
||||||
|
curindex = fprintf(stdout, " ");
|
||||||
|
if (option.small) {
|
||||||
|
curindex += fprintf(stdout, "-%c", (char)(option.small));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.large != NULL) {
|
||||||
|
if (option.small) {
|
||||||
|
curindex += fprintf(stdout, ", --%s", option.large);
|
||||||
|
} else {
|
||||||
|
curindex += fprintf(stdout, " --%s", option.large);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curindex <= max_option_len) {
|
||||||
|
space_left = max_option_len - curindex;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "%*s%s\n", space_left, "", option.description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_options(int options_len, const command_option_t *options)
|
||||||
|
{
|
||||||
|
int max_option_len = 0;
|
||||||
|
|
||||||
|
max_option_len = get_max_option_length(options_len, options);
|
||||||
|
|
||||||
|
// format: " -s, --large description"
|
||||||
|
max_option_len += 6;
|
||||||
|
|
||||||
|
do_print_options(options_len, options, max_option_len);
|
||||||
|
|
||||||
|
fputc('\n', stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void command_help(const command_t *self)
|
||||||
|
{
|
||||||
|
const char *progname = strrchr(self->name, '/');
|
||||||
|
if (progname == NULL) {
|
||||||
|
progname = self->name;
|
||||||
|
} else {
|
||||||
|
progname++;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "\nUsage: %s [options] %s\n\n", progname, self->usage);
|
||||||
|
fprintf(stderr, "%s\n\n", self->description);
|
||||||
|
qsort(self->options, (size_t)(self->option_count), sizeof(self->options[0]), compare_options);
|
||||||
|
print_options(self->option_count, self->options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void command_init(command_t *self, command_option_t *options, int options_len, int argc, const char **argv,
|
||||||
|
const char *description, const char *usage)
|
||||||
|
{
|
||||||
|
if (memset_s(self, sizeof(command_t), 0, sizeof(command_t)) != EOK) {
|
||||||
|
COMMAND_ERROR("Failed to set memory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self->name = argv[0];
|
||||||
|
self->argc = argc - 2;
|
||||||
|
self->argv = argv + 2;
|
||||||
|
self->usage = usage;
|
||||||
|
self->description = description;
|
||||||
|
self->options = options;
|
||||||
|
self->option_count = options_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void command_option(command_t *self, command_option_type_t type, void *data, int small, const char *large,
|
||||||
|
const char *desc, command_callback_t cb)
|
||||||
|
{
|
||||||
|
if (self->option_count == COMMANDER_MAX_OPTIONS) {
|
||||||
|
COMMAND_ERROR("Maximum option definitions exceeded\n");
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
int n = self->option_count++;
|
||||||
|
command_option_t *option = &(self->options[n]);
|
||||||
|
option->type = type;
|
||||||
|
option->data = data;
|
||||||
|
option->cb = cb;
|
||||||
|
option->small = small;
|
||||||
|
option->description = desc;
|
||||||
|
option->large = large;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_option_arg(command_t *self, command_option_t *option, const char **opt_arg, const char **readed)
|
||||||
|
{
|
||||||
|
if ((self == NULL) || (option == NULL) || (opt_arg == NULL)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (option->hasdata) {
|
||||||
|
*readed = *opt_arg;
|
||||||
|
*opt_arg = NULL;
|
||||||
|
}
|
||||||
|
if (!option->hasdata && self->argc > 1) {
|
||||||
|
option->hasdata = true;
|
||||||
|
*readed = *++(self->argv);
|
||||||
|
self->argc--;
|
||||||
|
}
|
||||||
|
if (!option->hasdata) {
|
||||||
|
COMMAND_ERROR("Flag needs an argument: --%s", option->large);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_option_type_bool(const command_option_t *option, const char **opt_arg)
|
||||||
|
{
|
||||||
|
if (option->hasdata && strcmp(*opt_arg, "true") && strcmp(*opt_arg, "false")) {
|
||||||
|
COMMAND_ERROR("Invalid boolean value \"%s\" for flag --%s", *opt_arg, option->large);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (option->hasdata) {
|
||||||
|
if (!strcmp(*opt_arg, "true")) {
|
||||||
|
*(bool *)(option->data) = true;
|
||||||
|
} else {
|
||||||
|
*(bool *)(option->data) = false;
|
||||||
|
}
|
||||||
|
*opt_arg = NULL;
|
||||||
|
} else {
|
||||||
|
*(bool *)option->data = true;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_option_type_string(command_t *self, command_option_t *option, const char **opt_arg)
|
||||||
|
{
|
||||||
|
if (read_option_arg(self, option, opt_arg, (const char **)(option->data))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (option->cb != NULL) {
|
||||||
|
return option->cb(option, *(char **)(option->data));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_option_type_string_dup(command_t *self, command_option_t *option, const char **opt_arg)
|
||||||
|
{
|
||||||
|
const char *readed = NULL;
|
||||||
|
if (read_option_arg(self, option, opt_arg, &readed)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(*(char **)(option->data));
|
||||||
|
|
||||||
|
*(char **)option->data = util_strdup_s(readed);
|
||||||
|
|
||||||
|
if (option->cb != NULL) {
|
||||||
|
return option->cb(option, readed);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_option_type_callback(command_t *self, command_option_t *option, const char **opt_arg)
|
||||||
|
{
|
||||||
|
const char *readed = NULL;
|
||||||
|
if (read_option_arg(self, option, opt_arg, &readed)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (option->cb == NULL) {
|
||||||
|
COMMAND_ERROR("Must specify callback for type array");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return option->cb(option, readed);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int command_get_option_data(command_t *self, command_option_t *option, const char **opt_arg)
|
||||||
|
{
|
||||||
|
if (option == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch (option->type) {
|
||||||
|
case CMD_OPT_TYPE_BOOL:
|
||||||
|
return handle_option_type_bool(option, opt_arg);
|
||||||
|
case CMD_OPT_TYPE_STRING:
|
||||||
|
return handle_option_type_string(self, option, opt_arg);
|
||||||
|
case CMD_OPT_TYPE_STRING_DUP:
|
||||||
|
return handle_option_type_string_dup(self, option, opt_arg);
|
||||||
|
case CMD_OPT_TYPE_CALLBACK:
|
||||||
|
return handle_option_type_callback(self, option, opt_arg);
|
||||||
|
default:
|
||||||
|
COMMAND_ERROR("Unkown command option type:%d", option->type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static int have_short_options(const command_t *self, char arg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < self->option_count; i++) {
|
||||||
|
if (self->options[i].small == arg) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_option_argument_when_match_flag(const char **opt_arg, command_option_t *option, bool *found)
|
||||||
|
{
|
||||||
|
*found = true;
|
||||||
|
if ((*opt_arg)[1] != '\0') {
|
||||||
|
if ((*opt_arg)[1] == '=') {
|
||||||
|
*opt_arg = *opt_arg + 2;
|
||||||
|
option->hasdata = true;
|
||||||
|
} else {
|
||||||
|
*opt_arg = *opt_arg + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*opt_arg = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int command_parse_short_arg(command_t *self, const char *arg)
|
||||||
|
{
|
||||||
|
const char *opt_arg = arg;
|
||||||
|
bool found = true;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
do {
|
||||||
|
found = false;
|
||||||
|
if (opt_arg[0] == 'h' && have_short_options(self, 'h') < 0) {
|
||||||
|
command_help(self);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
for (j = 0; j < self->option_count; ++j) {
|
||||||
|
command_option_t *option = &(self->options[j]);
|
||||||
|
option->hasdata = false;
|
||||||
|
|
||||||
|
if (option->small != opt_arg[0]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// match flag
|
||||||
|
set_option_argument_when_match_flag(&opt_arg, option, &found);
|
||||||
|
|
||||||
|
if (command_get_option_data(self, option, &opt_arg)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (found && (opt_arg != NULL));
|
||||||
|
|
||||||
|
if (opt_arg != NULL) {
|
||||||
|
COMMAND_ERROR("Unkown flag found:'%c'", opt_arg[0]);
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int command_parse_long_arg(command_t *self, const char *arg)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (!strcmp(arg, "help")) {
|
||||||
|
command_help(self);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < self->option_count; ++j) {
|
||||||
|
command_option_t *option = &(self->options[j]);
|
||||||
|
const char *opt_arg = NULL;
|
||||||
|
option->hasdata = false;
|
||||||
|
|
||||||
|
if (option->large == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt_arg = str_skip_str(arg, option->large);
|
||||||
|
if (opt_arg == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_arg[0]) {
|
||||||
|
if (opt_arg[0] != '=') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
opt_arg = opt_arg + 1;
|
||||||
|
option->hasdata = true;
|
||||||
|
} else {
|
||||||
|
opt_arg = NULL;
|
||||||
|
}
|
||||||
|
if (command_get_option_data(self, option, &opt_arg)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
COMMAND_ERROR("Unkown flag found:'--%s'\n", arg);
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int command_parse_args(command_t *self, int *argc, char * const **argv)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
for (; self->argc; self->argc--, self->argv++) {
|
||||||
|
const char *arg = self->argv[0];
|
||||||
|
|
||||||
|
if (arg[0] != '-' || !arg[1]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// short option
|
||||||
|
if (arg[1] != '-') {
|
||||||
|
arg = arg + 1;
|
||||||
|
ret = command_parse_short_arg(self, arg);
|
||||||
|
if (!ret) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --
|
||||||
|
if (!arg[2]) {
|
||||||
|
self->argc--;
|
||||||
|
self->argv++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// long option
|
||||||
|
arg = arg + 2;
|
||||||
|
ret = command_parse_long_arg(self, arg);
|
||||||
|
if (!ret) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (self->argc > 0) {
|
||||||
|
*argc = self->argc;
|
||||||
|
*argv = (char * const *)(self->argv);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int command_append_array_with_space(command_option_t *option, const char *arg)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char *narg = util_string_replace(SPACE_MAGIC_STR, " ", arg);
|
||||||
|
if (narg == NULL) {
|
||||||
|
COMMAND_ERROR("Memory allocation error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = util_array_append(option->data, narg);
|
||||||
|
free(narg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int command_append_array(command_option_t *option, const char *arg)
|
||||||
|
{
|
||||||
|
if (option == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
char ***array = option->data;
|
||||||
|
return util_array_append(array, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int command_convert_llong(command_option_t *option, const char *arg)
|
||||||
|
{
|
||||||
|
if (option == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (util_safe_llong(arg, option->data)) {
|
||||||
|
COMMAND_ERROR("Invalid value \"%s\" for flag --%s", arg, option->large);
|
||||||
|
return EINVALIDARGS;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int command_convert_uint(command_option_t *option, const char *arg)
|
||||||
|
{
|
||||||
|
if (option == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (util_safe_uint(arg, option->data)) {
|
||||||
|
COMMAND_ERROR("Invalid value \"%s\" for flag --%s", arg, option->large);
|
||||||
|
return EINVALIDARGS;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
84
src/cmd/commander.h
Normal file
84
src/cmd/commander.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container commander definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __COMMANDER_H_
|
||||||
|
#define __COMMANDER_H_
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifndef COMMANDER_MAX_OPTIONS
|
||||||
|
#define COMMANDER_MAX_OPTIONS 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* no arguments */
|
||||||
|
CMD_OPT_TYPE_BOOL,
|
||||||
|
/* required arguments */
|
||||||
|
CMD_OPT_TYPE_STRING,
|
||||||
|
CMD_OPT_TYPE_STRING_DUP,
|
||||||
|
CMD_OPT_TYPE_CALLBACK
|
||||||
|
} command_option_type_t;
|
||||||
|
|
||||||
|
struct _command;
|
||||||
|
|
||||||
|
struct command_option;
|
||||||
|
|
||||||
|
typedef int (*command_callback_t)(struct command_option *options, const char *arg);
|
||||||
|
|
||||||
|
typedef struct command_option {
|
||||||
|
command_option_type_t type;
|
||||||
|
bool hasdata;
|
||||||
|
const char *large;
|
||||||
|
int small;
|
||||||
|
void *data;
|
||||||
|
const char *description;
|
||||||
|
command_callback_t cb;
|
||||||
|
} command_option_t;
|
||||||
|
|
||||||
|
typedef struct _command {
|
||||||
|
const char *type;
|
||||||
|
const char *usage;
|
||||||
|
const char *description;
|
||||||
|
const char *name;
|
||||||
|
const char *version;
|
||||||
|
int option_count;
|
||||||
|
command_option_t *options;
|
||||||
|
int argc;
|
||||||
|
const char **argv;
|
||||||
|
} command_t;
|
||||||
|
|
||||||
|
void command_init(command_t *self, command_option_t *options, int options_len, int argc, const char **argv,
|
||||||
|
const char *description, const char *usage);
|
||||||
|
|
||||||
|
int compare_options(const void *s1, const void *s2);
|
||||||
|
|
||||||
|
void print_options(int options_len, const command_option_t *options);
|
||||||
|
|
||||||
|
void command_help(const command_t *self);
|
||||||
|
|
||||||
|
void command_option(command_t *self, command_option_type_t type, void *data, int small, const char *large,
|
||||||
|
const char *desc, command_callback_t cb);
|
||||||
|
|
||||||
|
int command_parse_args(command_t *self, int *argc, char * const **argv);
|
||||||
|
|
||||||
|
int command_append_array(command_option_t *option, const char *arg);
|
||||||
|
|
||||||
|
int command_append_array_with_space(command_option_t *option, const char *arg);
|
||||||
|
|
||||||
|
int command_convert_llong(command_option_t *option, const char *arg);
|
||||||
|
|
||||||
|
int command_convert_uint(command_option_t *option, const char *arg);
|
||||||
|
|
||||||
|
#endif /* COMMANDER_H */
|
||||||
157
src/cmd/commands.c
Normal file
157
src/cmd/commands.c
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container commands functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "securec.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "commands.h"
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "config.h" // For VERSION
|
||||||
|
|
||||||
|
const char cmd_option_desc[] = "Options";
|
||||||
|
const char cmd_option_usage[] = "[OPTIONS] COMMAND [arg...]";
|
||||||
|
struct lcr_arguments g_lcr_cmd_args = {};
|
||||||
|
|
||||||
|
/* print version */
|
||||||
|
static void print_version()
|
||||||
|
{
|
||||||
|
printf("Version %s, commit %s\n", VERSION, LCR_GIT_COMMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*command by name*/
|
||||||
|
const struct command *command_by_name(const struct command *commands, const char * const name)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
if (commands == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (!commands[i].name) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(commands[i].name, name) == 0) {
|
||||||
|
return commands + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compare commands */
|
||||||
|
int compare_commands(const void *s1, const void *s2)
|
||||||
|
{
|
||||||
|
return strcmp((*(const struct command *)s1).name, (*(const struct command *)s2).name);
|
||||||
|
}
|
||||||
|
// Default help command if implementation doesn't provide one
|
||||||
|
int command_default_help(const char * const program_name, struct command *commands, int argc, const char **argv)
|
||||||
|
{
|
||||||
|
const struct command *command = NULL;
|
||||||
|
|
||||||
|
if (commands == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 0) {
|
||||||
|
size_t i = 0;
|
||||||
|
size_t max_size = 0;
|
||||||
|
|
||||||
|
printf("USAGE:\n");
|
||||||
|
printf("\t%s [OPTIONS] COMMAND [args...]\n", program_name);
|
||||||
|
printf("\n");
|
||||||
|
printf("COMMANDS:\n");
|
||||||
|
|
||||||
|
for (i = 0; commands[i].name != NULL; i++) {
|
||||||
|
size_t cmd_size = strlen(commands[i].name);
|
||||||
|
if (cmd_size > max_size) {
|
||||||
|
max_size = cmd_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qsort(commands, i, sizeof(commands[0]), compare_commands);
|
||||||
|
for (i = 0; commands[i].name != NULL; i++) {
|
||||||
|
printf("\t%*s\t%s\n", -(int)max_size, commands[i].name, commands[i].description);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
print_common_help();
|
||||||
|
return 0;
|
||||||
|
} else if (argc > 1) {
|
||||||
|
printf("%s: unrecognized argument: \"%s\"\n", program_name, argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
command = command_by_name(commands, argv[0]);
|
||||||
|
|
||||||
|
if (command == NULL) {
|
||||||
|
printf("%s: sub-command \"%s\" not found\n", program_name, argv[0]);
|
||||||
|
printf("run `lcr --help` for a list of sub-commonds\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command->longdesc != NULL) {
|
||||||
|
printf("%s\n", command->longdesc);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* option command init */
|
||||||
|
void option_command_init(command_t *self, command_option_t *options, int options_len, int argc, const char **argv,
|
||||||
|
const char *description, const char *usage)
|
||||||
|
{
|
||||||
|
if (memset_s(self, sizeof(command_t), 0, sizeof(command_t)) != EOK) {
|
||||||
|
COMMAND_ERROR("Failed to set memory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self->name = argv[0];
|
||||||
|
self->argc = argc - 1;
|
||||||
|
self->argv = argv + 1;
|
||||||
|
self->usage = usage;
|
||||||
|
self->description = description;
|
||||||
|
self->options = options;
|
||||||
|
self->option_count = options_len;
|
||||||
|
}
|
||||||
|
// Tries to execute a command in the command list. The command name
|
||||||
|
// must be in argv[1]. Example usage:
|
||||||
|
//
|
||||||
|
int run_command(struct command *commands, int argc, const char **argv)
|
||||||
|
{
|
||||||
|
const struct command *command = NULL;
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
return command_default_help(argv[0], commands, argc - 1, argv + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "help") == 0 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
|
||||||
|
return command_default_help(argv[0], commands, argc - 2, argv + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "--version") == 0) {
|
||||||
|
print_version();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
command = command_by_name(commands, argv[1]);
|
||||||
|
if (command != NULL) {
|
||||||
|
return command->executor(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s: command \"%s\" not found\n", argv[0], argv[1]);
|
||||||
|
printf("run `%s --help` or `run -h` for a list of sub-commonds\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
49
src/cmd/commands.h
Normal file
49
src/cmd/commands.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container commands definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __COMMAND_H
|
||||||
|
#define __COMMAND_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
// A command is described by:
|
||||||
|
// @name: The name which should be passed as a second parameter
|
||||||
|
// @executor: The function that will be executed if the command
|
||||||
|
// matches. Receives the argc of the program minus two, and
|
||||||
|
// the rest os argv
|
||||||
|
// @description: Brief description, will show in help messages
|
||||||
|
// @longdesc: Long descripton to show when you run `help <command>`
|
||||||
|
struct command {
|
||||||
|
const char * const name;
|
||||||
|
int (*executor)(int, const char **);
|
||||||
|
const char * const description;
|
||||||
|
const char * const longdesc;
|
||||||
|
struct lcr_arguments *args;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Gets a pointer to a command, to allow implementing custom behavior
|
||||||
|
// returns null if not found.
|
||||||
|
//
|
||||||
|
// NOTE: Command arrays must end in a command with all member is NULL
|
||||||
|
const struct command *command_by_name(const struct command *commands, const char * const name);
|
||||||
|
|
||||||
|
// Default help command if implementation doesn't prvide one
|
||||||
|
int commmand_default_help(const char * const program_name, struct command *commands, int argc, char **argv);
|
||||||
|
|
||||||
|
// Tries to execute a command in the command list, The command name
|
||||||
|
// must be in argv[1]. Example usage
|
||||||
|
int run_command(struct command *commands, int argc, const char **argv);
|
||||||
|
#endif /* __COMMAND_H */
|
||||||
122
src/cmd/create.c
Normal file
122
src/cmd/create.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container create functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
#include "create.h"
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "read_file.h"
|
||||||
|
|
||||||
|
const char g_lcr_cmd_create_desc[] = "create a container";
|
||||||
|
static const char g_lcr_cmd_create_usage[] = "create --name=NAME --rootfs=<dir|blkdev>";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_create_args = { 0 };
|
||||||
|
|
||||||
|
static int check_create_args(struct lcr_arguments *lcr_cmd_create_args)
|
||||||
|
{
|
||||||
|
if (lcr_cmd_create_args->name == NULL) {
|
||||||
|
ERROR("Missing --name,-n option\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_cmd_create_args->create_rootfs == NULL) {
|
||||||
|
ERROR("Missing --rootfs option\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_cmd_create_args->create_dist == NULL) {
|
||||||
|
lcr_cmd_create_args->create_dist = "ubuntu";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists(lcr_cmd_create_args->create_rootfs)) {
|
||||||
|
ERROR("Rootfs dir \"%s\" does not exist\n", lcr_cmd_create_args->create_rootfs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_oci_json_data(char **oci_json_data, size_t *filesize)
|
||||||
|
{
|
||||||
|
if (g_lcr_cmd_create_args.ociconfig == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*oci_json_data = read_file(g_lcr_cmd_create_args.ociconfig, filesize);
|
||||||
|
if (*oci_json_data == NULL) {
|
||||||
|
ERROR("Can not read the file \"%s\"\n", g_lcr_cmd_create_args.ociconfig);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_create_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
char *oci_json_data = NULL;
|
||||||
|
size_t filesize;
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = {
|
||||||
|
CREATE_OPTIONS(g_lcr_cmd_create_args),
|
||||||
|
COMMON_OPTIONS(g_lcr_cmd_create_args)
|
||||||
|
};
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_create_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv,
|
||||||
|
g_lcr_cmd_create_desc, g_lcr_cmd_create_usage);
|
||||||
|
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_create_args.argc, &g_lcr_cmd_create_args.argv)) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_create_args(&g_lcr_cmd_create_args)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read_oci_json_data(&oci_json_data, &filesize) != 0) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(g_lcr_cmd_create_args.name,
|
||||||
|
g_lcr_cmd_create_args.log_file,
|
||||||
|
g_lcr_cmd_create_args.log_priority,
|
||||||
|
g_lcr_cmd_create_args.progname,
|
||||||
|
g_lcr_cmd_create_args.quiet,
|
||||||
|
LOGPATH)) {
|
||||||
|
free(oci_json_data);
|
||||||
|
oci_json_data = NULL;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lcr_create(g_lcr_cmd_create_args.name,
|
||||||
|
g_lcr_cmd_create_args.lcrpath,
|
||||||
|
g_lcr_cmd_create_args.create_rootfs,
|
||||||
|
g_lcr_cmd_create_args.create_dist,
|
||||||
|
oci_json_data)) {
|
||||||
|
ERROR("Error creating container %s", g_lcr_cmd_create_args.name);
|
||||||
|
free(oci_json_data);
|
||||||
|
oci_json_data = NULL;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO("Container \"%s\" created\n", g_lcr_cmd_create_args.name);
|
||||||
|
free(oci_json_data);
|
||||||
|
oci_json_data = NULL;
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
36
src/cmd/create.h
Normal file
36
src/cmd/create.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container create definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_CREATE_H
|
||||||
|
#define __CMD_CREATE_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define CREATE_OPTIONS(cmdargs) \
|
||||||
|
{CMD_OPT_TYPE_STRING, false, "dist", 0, &(cmdargs).create_dist, \
|
||||||
|
"Generate distribution specification, now support: `ubuntu`, `app`," \
|
||||||
|
" `none`\n\t\t\tthe default dist is `ubuntu`\n\t\t\tNOTE: if the dist is `none`," \
|
||||||
|
" it will not create default spec.", NULL}, \
|
||||||
|
{CMD_OPT_TYPE_STRING, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL}, \
|
||||||
|
{CMD_OPT_TYPE_STRING, false, "ociconfig", 'c', &(cmdargs).ociconfig, \
|
||||||
|
"File containing oci configuration (in json format)", NULL}, \
|
||||||
|
{CMD_OPT_TYPE_STRING, false, "rootfs", 0, &(cmdargs).create_rootfs, \
|
||||||
|
"Specify the rootfs for the container, dir or block device", NULL}
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_create_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_create_args;
|
||||||
|
int cmd_create_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_CREATE_H */
|
||||||
72
src/cmd/delete.c
Normal file
72
src/cmd/delete.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container delete functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
#include "lcrcontainer_extend.h"
|
||||||
|
#include "delete.h"
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
const char g_lcr_cmd_delete_desc[] = "Delete a container";
|
||||||
|
static const char g_lcr_cmd_delete_usage[] = "delete --name=NAME";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_delete_args;
|
||||||
|
|
||||||
|
static int delete_cmd_init(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = { DELETE_OPTIONS(g_lcr_cmd_delete_args), COMMON_OPTIONS(g_lcr_cmd_delete_args) };
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_delete_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv, g_lcr_cmd_delete_desc,
|
||||||
|
g_lcr_cmd_delete_usage);
|
||||||
|
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_delete_args.argc, &g_lcr_cmd_delete_args.argv)) {
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_delete_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
if (delete_cmd_init(argc, argv) != 0) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(g_lcr_cmd_delete_args.name, g_lcr_cmd_delete_args.log_file, g_lcr_cmd_delete_args.log_priority,
|
||||||
|
g_lcr_cmd_delete_args.progname, g_lcr_cmd_delete_args.quiet, LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_lcr_cmd_delete_args.name == NULL) {
|
||||||
|
fprintf(stderr, "missing --name,-n option\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lcr_delete_with_force(g_lcr_cmd_delete_args.name, g_lcr_cmd_delete_args.lcrpath,
|
||||||
|
g_lcr_cmd_delete_args.delete_force)) {
|
||||||
|
fprintf(stderr, "Error deleteing container %s\n", g_lcr_cmd_delete_args.name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "Container \"%s\" deleted\n", g_lcr_cmd_delete_args.name);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
30
src/cmd/delete.h
Normal file
30
src/cmd/delete.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container delete definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_DELETE_H
|
||||||
|
#define __CMD_DELETE_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define DELETE_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_BOOL, false, "force", 'f', &cmdargs.delete_force, \
|
||||||
|
"Forcibly deletes the container if it is still running", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "name", 'n', &cmdargs.name, "Name of the container", NULL }
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_delete_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_delete_args;
|
||||||
|
int cmd_delete_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_DELETE_H */
|
||||||
87
src/cmd/exec.c
Normal file
87
src/cmd/exec.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container exec functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
#include "exec.h"
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
const char g_lcr_cmd_exec_desc[] = "execute new process inside the container";
|
||||||
|
static const char g_lcr_cmd_exec_usage[] = "exec --name=NAME [-- COMMAND]";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_exec_args;
|
||||||
|
|
||||||
|
static inline int check_container_name()
|
||||||
|
{
|
||||||
|
if (g_lcr_cmd_exec_args.name == NULL) {
|
||||||
|
fprintf(stderr, "missing --name,-n option\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_exec_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
pid_t pid = 0;
|
||||||
|
int ret;
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = {
|
||||||
|
EXEC_OPTIONS(g_lcr_cmd_exec_args),
|
||||||
|
COMMON_OPTIONS(g_lcr_cmd_exec_args)
|
||||||
|
};
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_exec_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv,
|
||||||
|
g_lcr_cmd_exec_desc, g_lcr_cmd_exec_usage);
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_exec_args.argc, &g_lcr_cmd_exec_args.argv)) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(g_lcr_cmd_exec_args.name,
|
||||||
|
g_lcr_cmd_exec_args.log_file,
|
||||||
|
g_lcr_cmd_exec_args.log_priority,
|
||||||
|
g_lcr_cmd_exec_args.progname,
|
||||||
|
g_lcr_cmd_exec_args.quiet,
|
||||||
|
LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_container_name() != 0) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lcr_exec(g_lcr_cmd_exec_args.name,
|
||||||
|
g_lcr_cmd_exec_args.lcrpath,
|
||||||
|
g_lcr_cmd_exec_args.argc,
|
||||||
|
g_lcr_cmd_exec_args.argv,
|
||||||
|
&pid)) {
|
||||||
|
fprintf(stderr, "Error execute new process inside container \"%s\"\n",
|
||||||
|
g_lcr_cmd_exec_args.name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = wait_for_pid(pid) < 0;
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "exec success bug got bad return %d\n", ret);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
28
src/cmd/exec.h
Normal file
28
src/cmd/exec.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container exec definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_EXEC_H
|
||||||
|
#define __CMD_EXEC_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define EXEC_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL }
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_exec_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_exec_args;
|
||||||
|
int cmd_exec_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_EXEC_H */
|
||||||
33
src/cmd/help.c
Normal file
33
src/cmd/help.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container help functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "help.h"
|
||||||
|
|
||||||
|
const char g_lcr_cmd_help_desc[] =
|
||||||
|
"show a list of commands or help for one command";
|
||||||
|
const char g_lcr_cmd_help_long_desc[] =
|
||||||
|
"NAME:\n"
|
||||||
|
"\tlcr help - show a list of commands or help for one command\n"
|
||||||
|
"\n"
|
||||||
|
"USAGE:\n"
|
||||||
|
"\tlcr help [command]\n";
|
||||||
|
|
||||||
|
/* cmd help main */
|
||||||
|
int cmd_help_main(int argc, char **argv, struct lcr_arguments *lcr_cmd_args)
|
||||||
|
{
|
||||||
|
printf("cmd_list\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
25
src/cmd/help.h
Normal file
25
src/cmd/help.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container help definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_HELP_H
|
||||||
|
#define __CMD_HELP_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_help_desc[];
|
||||||
|
extern const char g_lcr_cmd_help_long_desc[];
|
||||||
|
|
||||||
|
int cmd_help_main(int argc, char **argv, struct lcr_arguments *lcr_cmd_args);
|
||||||
|
|
||||||
|
#endif /* __CMD_HELP_H */
|
||||||
95
src/cmd/kill.c
Normal file
95
src/cmd/kill.c
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container kill functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
|
||||||
|
#include "securec.h"
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "kill.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
const char g_lcr_cmd_kill_desc[] = "Kill a container with the identifier NAME";
|
||||||
|
static const char g_lcr_cmd_kill_usage[] = "kill [command options] --name=NAME";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_kill_args;
|
||||||
|
|
||||||
|
static int parse_verify_signal(int *signo)
|
||||||
|
{
|
||||||
|
*signo = util_sig_parse(g_lcr_cmd_kill_args.signal);
|
||||||
|
if (*signo == -1) {
|
||||||
|
fprintf(stderr, "Invalid signal: %s", g_lcr_cmd_kill_args.signal);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!util_valid_signal(*signo)) {
|
||||||
|
fprintf(stderr, "The Linux daemon does not support signal %d", *signo);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int check_container_name()
|
||||||
|
{
|
||||||
|
if (g_lcr_cmd_kill_args.name == NULL) {
|
||||||
|
fprintf(stderr, "Missing container name, use -n,--name option");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int cmd_kill_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
int signo;
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = {
|
||||||
|
KILL_OPTIONS(g_lcr_cmd_kill_args),
|
||||||
|
COMMON_OPTIONS(g_lcr_cmd_kill_args)
|
||||||
|
};
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_kill_args);
|
||||||
|
g_lcr_cmd_kill_args.signal = "SIGKILL";
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv,
|
||||||
|
g_lcr_cmd_kill_desc, g_lcr_cmd_kill_usage);
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_kill_args.argc, &g_lcr_cmd_kill_args.argv)) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(g_lcr_cmd_kill_args.name, g_lcr_cmd_kill_args.log_file,
|
||||||
|
g_lcr_cmd_kill_args.log_priority,
|
||||||
|
g_lcr_cmd_kill_args.progname,
|
||||||
|
g_lcr_cmd_kill_args.quiet,
|
||||||
|
LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_container_name() != 0) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse_verify_signal(&signo) != 0) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lcr_kill(g_lcr_cmd_kill_args.name, g_lcr_cmd_kill_args.lcrpath, (uint32_t)signo)) {
|
||||||
|
fprintf(stderr, "Container \"%s\" kill failed", g_lcr_cmd_kill_args.name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", g_lcr_cmd_kill_args.name);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
30
src/cmd/kill.h
Normal file
30
src/cmd/kill.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container kill definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_KILL_H
|
||||||
|
#define __CMD_KILL_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define KILL_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "signal", 's', &(cmdargs).signal, \
|
||||||
|
"Signal to send to the container (default \"SIGKILL\")", NULL }
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_kill_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_kill_args;
|
||||||
|
int cmd_kill_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_KILL_H */
|
||||||
148
src/cmd/lcr.c
Normal file
148
src/cmd/lcr.c
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide lcr container functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "commands.h"
|
||||||
|
#include "create.h"
|
||||||
|
#include "delete.h"
|
||||||
|
#include "spec.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "start.h"
|
||||||
|
#include "clean.h"
|
||||||
|
#include "exec.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include "pause.h"
|
||||||
|
#include "resume.h"
|
||||||
|
#include "update.h"
|
||||||
|
#include "help.h"
|
||||||
|
#include "kill.h"
|
||||||
|
|
||||||
|
|
||||||
|
// The list of our supported commands
|
||||||
|
struct command g_commands[] = {
|
||||||
|
{
|
||||||
|
// `create` sub-command
|
||||||
|
"create",
|
||||||
|
cmd_create_main,
|
||||||
|
g_lcr_cmd_create_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_create_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `delete` sub-command
|
||||||
|
"delete",
|
||||||
|
cmd_delete_main,
|
||||||
|
g_lcr_cmd_delete_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_delete_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `spec` sub-command
|
||||||
|
"spec",
|
||||||
|
cmd_spec_main,
|
||||||
|
g_lcr_cmd_spec_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_spec_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `list` sub-command
|
||||||
|
"list",
|
||||||
|
cmd_list_main,
|
||||||
|
g_lcr_cmd_list_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_list_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `start` sub-command
|
||||||
|
"start",
|
||||||
|
cmd_start_main,
|
||||||
|
g_lcr_cmd_start_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_start_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `kill` sub-command
|
||||||
|
"kill",
|
||||||
|
cmd_kill_main,
|
||||||
|
g_lcr_cmd_kill_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_kill_args
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
// `clean` sub-command
|
||||||
|
"clean",
|
||||||
|
cmd_clean_main,
|
||||||
|
g_lcr_cmd_clean_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_clean_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `exec` sub-command
|
||||||
|
"exec",
|
||||||
|
cmd_exec_main,
|
||||||
|
g_lcr_cmd_exec_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_exec_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `state` sub-command
|
||||||
|
"state",
|
||||||
|
cmd_state_main,
|
||||||
|
g_lcr_cmd_state_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_state_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `pause` sub-command
|
||||||
|
"pause",
|
||||||
|
cmd_pause_main,
|
||||||
|
g_lcr_cmd_pause_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_pause_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `resume` sub-command
|
||||||
|
"resume",
|
||||||
|
cmd_resume_main,
|
||||||
|
g_lcr_cmd_resume_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_resume_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `update` sub-command
|
||||||
|
"update",
|
||||||
|
cmd_update_main,
|
||||||
|
g_lcr_cmd_update_desc,
|
||||||
|
NULL,
|
||||||
|
&g_lcr_cmd_update_args
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// `help` sub-command
|
||||||
|
"help",
|
||||||
|
NULL,
|
||||||
|
g_lcr_cmd_help_desc,
|
||||||
|
g_lcr_cmd_help_long_desc,
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
{ NULL, NULL, NULL, NULL, NULL } // End of the list
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
return run_command(g_commands, argc, argv);
|
||||||
|
}
|
||||||
222
src/cmd/list.c
Normal file
222
src/cmd/list.c
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container list functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
#include "lcrcontainer_extend.h"
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
/* keep track of field widths for printing. */
|
||||||
|
struct lcr_lens {
|
||||||
|
unsigned int lcr_name_len;
|
||||||
|
unsigned int lcr_state_len;
|
||||||
|
unsigned int lcr_interface_len;
|
||||||
|
unsigned int lcr_ipv4_len;
|
||||||
|
unsigned int lcr_ipv6_len;
|
||||||
|
unsigned int lcr_init_len;
|
||||||
|
unsigned int lcr_ram_len;
|
||||||
|
unsigned int lcr_swap_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char g_lcr_cmd_list_desc[] = "lists containers";
|
||||||
|
static const char g_lcr_cmd_list_usage[] = "list [command options]";
|
||||||
|
|
||||||
|
static void info_field_width(const struct lcr_container_info *info, const size_t size, struct lcr_lens *l);
|
||||||
|
static void info_print_table(const struct lcr_container_info *info, size_t size, const struct lcr_lens *length,
|
||||||
|
const struct lcr_arguments *args);
|
||||||
|
static void info_print_quiet(const struct lcr_container_info *info, size_t size, const struct lcr_arguments *args);
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_list_args = { 0 };
|
||||||
|
|
||||||
|
int cmd_list_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = { LIST_OPTIONS(g_lcr_cmd_list_args), COMMON_OPTIONS(g_lcr_cmd_list_args) };
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_list_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv, g_lcr_cmd_list_desc,
|
||||||
|
g_lcr_cmd_list_usage);
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_list_args.argc, &g_lcr_cmd_list_args.argv)) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(NULL, g_lcr_cmd_list_args.log_file, g_lcr_cmd_list_args.log_priority, g_lcr_cmd_list_args.progname,
|
||||||
|
g_lcr_cmd_list_args.quiet, LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lcr_lens max_len = {
|
||||||
|
.lcr_name_len = 4, /* NAME */
|
||||||
|
.lcr_state_len = 5, /* STATE */
|
||||||
|
.lcr_interface_len = 9, /* INTERFACE */
|
||||||
|
.lcr_ipv4_len = 4, /* IPV4 */
|
||||||
|
.lcr_ipv6_len = 4, /* IPV6 */
|
||||||
|
.lcr_init_len = 3, /* PID */
|
||||||
|
.lcr_ram_len = 3, /* RAM */
|
||||||
|
.lcr_swap_len = 4, /* SWAP */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lcr_container_info *info_arr = NULL;
|
||||||
|
int num;
|
||||||
|
|
||||||
|
DEBUG("Get the container information");
|
||||||
|
if (g_lcr_cmd_list_args.list_active) {
|
||||||
|
num = lcr_list_active_containers(g_lcr_cmd_list_args.lcrpath, &info_arr);
|
||||||
|
} else {
|
||||||
|
num = lcr_list_all_containers(g_lcr_cmd_list_args.lcrpath, &info_arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num == -1) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_lcr_cmd_list_args.list_quiet == true) {
|
||||||
|
info_print_quiet(info_arr, (size_t)num, &g_lcr_cmd_list_args);
|
||||||
|
} else {
|
||||||
|
info_field_width(info_arr, (size_t)num, &max_len);
|
||||||
|
info_print_table(info_arr, (size_t)num, &max_len, &g_lcr_cmd_list_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcr_containers_info_free(&info_arr, (size_t)num);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool should_skip_print_info(const struct lcr_arguments *args, const struct lcr_container_info *in)
|
||||||
|
{
|
||||||
|
return (args->list_running == true && strncmp(in->state, "RUNNING", 7)) ||
|
||||||
|
(args->list_stopped == true && strncmp(in->state, "STOPPED", 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void info_print_quiet(const struct lcr_container_info *info, size_t size, const struct lcr_arguments *args)
|
||||||
|
{
|
||||||
|
if (size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const struct lcr_container_info *in = NULL;
|
||||||
|
size_t i = 0;
|
||||||
|
for (i = 0, in = info; i < size; i++, in++) {
|
||||||
|
if (should_skip_print_info(args, in)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("%s\n", in->name ? in->name : "-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void info_print_table(const struct lcr_container_info *info, size_t size, const struct lcr_lens *length,
|
||||||
|
const struct lcr_arguments *args)
|
||||||
|
{
|
||||||
|
if (size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("%-*s ", (int)length->lcr_name_len, "NAME");
|
||||||
|
printf("%-*s ", (int)length->lcr_state_len, "STATE");
|
||||||
|
printf("%-*s ", (int)length->lcr_ipv4_len, "IPV4");
|
||||||
|
printf("%-*s ", (int)length->lcr_ipv6_len, "IPV6");
|
||||||
|
printf("\n");
|
||||||
|
const struct lcr_container_info *in = NULL;
|
||||||
|
size_t i = 0;
|
||||||
|
for (i = 0, in = info; i < size; i++, in++) {
|
||||||
|
if (should_skip_print_info(args, in)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("%-*s ", (int)length->lcr_name_len, in->name ? in->name : "-");
|
||||||
|
printf("%-*s ", (int)length->lcr_state_len, in->state ? in->state : "-");
|
||||||
|
printf("%-*s ", (int)length->lcr_ipv4_len, in->ipv4 ? in->ipv4 : "-");
|
||||||
|
printf("%-*s ", (int)length->lcr_ipv6_len, in->ipv6 ? in->ipv6 : "-");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void width_ip_and_memory(const struct lcr_container_info *in, struct lcr_lens *l)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
if (in->ipv4) {
|
||||||
|
len = strlen(in->ipv4);
|
||||||
|
if (len > l->lcr_ipv4_len) {
|
||||||
|
l->lcr_ipv4_len = (unsigned int)len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (in->ipv6) {
|
||||||
|
len = strlen(in->ipv6);
|
||||||
|
if (len > l->lcr_ipv6_len) {
|
||||||
|
l->lcr_ipv6_len = (unsigned int)len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (size_t)sprintf_s(buf, sizeof(buf), "%.2f", in->ram);
|
||||||
|
if (len > l->lcr_ram_len) {
|
||||||
|
l->lcr_ram_len = (unsigned int)len;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (size_t)sprintf_s(buf, sizeof(buf), "%.2f", in->swap);
|
||||||
|
if (len > l->lcr_swap_len) {
|
||||||
|
l->lcr_swap_len = (unsigned int)len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_info_field_max_width(const struct lcr_container_info *in, struct lcr_lens *l)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (in->name) {
|
||||||
|
len = strlen(in->name);
|
||||||
|
if (len > l->lcr_name_len) {
|
||||||
|
l->lcr_name_len = (unsigned int)len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (in->state) {
|
||||||
|
len = strlen(in->state);
|
||||||
|
if (len > l->lcr_state_len) {
|
||||||
|
l->lcr_state_len = (unsigned int)len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (in->interface) {
|
||||||
|
len = strlen(in->interface);
|
||||||
|
if (len > l->lcr_interface_len) {
|
||||||
|
l->lcr_interface_len = (unsigned int)len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in->init != -1) {
|
||||||
|
char buf[64];
|
||||||
|
int nret = sprintf_s(buf, sizeof(buf), "%d", in->init);
|
||||||
|
if (nret > 0 && (size_t)nret > l->lcr_init_len) {
|
||||||
|
l->lcr_init_len = (size_t)nret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width_ip_and_memory(in, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void info_field_width(const struct lcr_container_info *info, const size_t size, struct lcr_lens *l)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
const struct lcr_container_info *in = NULL;
|
||||||
|
|
||||||
|
for (i = 0, in = info; i < size; i++, in++) {
|
||||||
|
set_info_field_max_width(in, l);
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/cmd/list.h
Normal file
31
src/cmd/list.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container list definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_LIST_H
|
||||||
|
#define __CMD_LIST_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define LIST_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_BOOL, false, "quiet", 'q', &(cmdargs).list_quiet, "Display only container names", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_BOOL, false, "active", 0, &(cmdargs).list_active, "List only active containers", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_BOOL, false, "running", 0, &(cmdargs).list_running, "List only running containers", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_BOOL, false, "stopped", 0, &(cmdargs).list_stopped, "List only stopped containers", NULL }
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_list_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_list_args;
|
||||||
|
int cmd_list_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_LIST_H */
|
||||||
68
src/cmd/pause.c
Normal file
68
src/cmd/pause.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container pause functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "pause.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
const char g_lcr_cmd_pause_desc[] = "Pause container in specified container NAME";
|
||||||
|
static const char g_lcr_cmd_pause_usage[] = "pause [command options] --name=NAME";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_pause_args;
|
||||||
|
|
||||||
|
int cmd_pause_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = {
|
||||||
|
PAUSE_OPTIONS(g_lcr_cmd_pause_args),
|
||||||
|
COMMON_OPTIONS(g_lcr_cmd_pause_args)
|
||||||
|
};
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_pause_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]),
|
||||||
|
argc,
|
||||||
|
(const char **)argv,
|
||||||
|
g_lcr_cmd_pause_desc, g_lcr_cmd_pause_usage);
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_pause_args.argc, &g_lcr_cmd_pause_args.argv)) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(g_lcr_cmd_pause_args.name, g_lcr_cmd_pause_args.log_file,
|
||||||
|
g_lcr_cmd_pause_args.log_priority,
|
||||||
|
g_lcr_cmd_pause_args.progname,
|
||||||
|
g_lcr_cmd_pause_args.quiet,
|
||||||
|
LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_lcr_cmd_pause_args.name == NULL) {
|
||||||
|
fprintf(stderr, "missing container name, use -n,--name option\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lcr_pause(g_lcr_cmd_pause_args.name, g_lcr_cmd_pause_args.lcrpath)) {
|
||||||
|
fprintf(stderr, "Failed to pause container %s\n", g_lcr_cmd_pause_args.name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "Container \"%s\" paused\n", g_lcr_cmd_pause_args.name);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
28
src/cmd/pause.h
Normal file
28
src/cmd/pause.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container pause definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_PAUSE_H
|
||||||
|
#define __CMD_PAUSE_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define PAUSE_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL }
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_pause_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_pause_args;
|
||||||
|
int cmd_pause_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_PAUSE_H */
|
||||||
60
src/cmd/resume.c
Normal file
60
src/cmd/resume.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container resume functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "resume.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
const char g_lcr_cmd_resume_desc[] = "Resume container in specified container NAME";
|
||||||
|
static const char g_lcr_cmd_resume_usage[] = "resume [command options] --name=NAME";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_resume_args;
|
||||||
|
|
||||||
|
int cmd_resume_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = { RESUME_OPTIONS(g_lcr_cmd_resume_args), COMMON_OPTIONS(g_lcr_cmd_resume_args) };
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_resume_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv, g_lcr_cmd_resume_desc,
|
||||||
|
g_lcr_cmd_resume_usage);
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_resume_args.argc, &g_lcr_cmd_resume_args.argv)) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(g_lcr_cmd_resume_args.name, g_lcr_cmd_resume_args.log_file, g_lcr_cmd_resume_args.log_priority,
|
||||||
|
g_lcr_cmd_resume_args.progname, g_lcr_cmd_resume_args.quiet, LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_lcr_cmd_resume_args.name == NULL) {
|
||||||
|
fprintf(stderr, "missing container name, use -n,--name option\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lcr_resume(g_lcr_cmd_resume_args.name, g_lcr_cmd_resume_args.lcrpath)) {
|
||||||
|
fprintf(stderr, "Failed to resume container %s\n", g_lcr_cmd_resume_args.name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "Container \"%s\" resumed\n", g_lcr_cmd_resume_args.name);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
28
src/cmd/resume.h
Normal file
28
src/cmd/resume.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container resume definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_RESUME_H
|
||||||
|
#define __CMD_RESUME_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define RESUME_OPTIONS(cmdargs) \
|
||||||
|
{CMD_OPT_TYPE_STRING, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL}
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_resume_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_resume_args;
|
||||||
|
int cmd_resume_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_RESUME_H */
|
||||||
209
src/cmd/spec.c
Normal file
209
src/cmd/spec.c
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container spec functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
#include "lcrcontainer_extend.h"
|
||||||
|
#include "oci_runtime_spec.h"
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "spec.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
const char g_lcr_cmd_spec_desc[] =
|
||||||
|
"Create a new specification file.";
|
||||||
|
static const char g_lcr_cmd_spec_usage[] = "spec [command options]";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_spec_args;
|
||||||
|
|
||||||
|
static void determine_distribution(const struct lcr_arguments *spec_args,
|
||||||
|
struct lcr_list **lcr_conf, char **seccomp_conf)
|
||||||
|
{
|
||||||
|
char *distribution = NULL;
|
||||||
|
|
||||||
|
if (spec_args->spec_dist != NULL) {
|
||||||
|
distribution = util_strdup_s(spec_args->spec_dist);
|
||||||
|
} else {
|
||||||
|
distribution = util_strdup_s("app");
|
||||||
|
}
|
||||||
|
*lcr_conf = lcr_dist2spec(distribution, seccomp_conf);
|
||||||
|
|
||||||
|
free(distribution);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_lcr_config(const struct lcr_arguments *spec_args, const struct lcr_list *lcr_conf)
|
||||||
|
{
|
||||||
|
if (lcr_conf == NULL) {
|
||||||
|
if (spec_args->spec_dist != NULL) {
|
||||||
|
ERROR("Create distribution specific configuration failed");
|
||||||
|
} else {
|
||||||
|
ERROR("Translate oci specification to lcr configuration failed");
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_lcr_conf(const struct lcr_arguments *spec_args,
|
||||||
|
struct lcr_list **lcr_conf, char **seccomp_conf)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
oci_runtime_spec *container = NULL;
|
||||||
|
|
||||||
|
if (spec_args->spec_translate == NULL) {
|
||||||
|
determine_distribution(spec_args, lcr_conf, seccomp_conf);
|
||||||
|
} else {
|
||||||
|
if (!container_parse(spec_args->spec_translate, NULL, &container)) {
|
||||||
|
ERROR("Failed to parse container!");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
*lcr_conf = lcr_oci2lcr(NULL, NULL, container, seccomp_conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_lcr_config(spec_args, *lcr_conf) != 0) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
free_oci_runtime_spec(container);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_lcr_fake_path_name(const char *bundle, char **fake_path,
|
||||||
|
char **fake_name)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
size_t len = 0;
|
||||||
|
size_t slash_index = 0;
|
||||||
|
|
||||||
|
len = strlen(bundle);
|
||||||
|
for (slash_index = len - 1; slash_index > 0;
|
||||||
|
slash_index--) {
|
||||||
|
if (bundle[slash_index] == '/') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*fake_path = util_common_calloc_s(slash_index + 1);
|
||||||
|
if (*fake_path == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncpy_s(*fake_path, slash_index + 1, bundle, slash_index) != EOK) {
|
||||||
|
ERROR("Failed to copy string!");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
(*fake_path)[slash_index] = '\0';
|
||||||
|
|
||||||
|
*fake_name = util_common_calloc_s((len - slash_index) + 1);
|
||||||
|
if (*fake_name == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncpy_s(*fake_name, (len - slash_index) + 1, &(bundle[slash_index + 1]),
|
||||||
|
len - slash_index) != EOK) {
|
||||||
|
ERROR("Failed to copy string!");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
(*fake_name)[(len - slash_index) - 1] = '\0';
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_spec_dist_and_translate()
|
||||||
|
{
|
||||||
|
if ((g_lcr_cmd_spec_args.spec_dist != NULL) && (g_lcr_cmd_spec_args.spec_translate != NULL)) {
|
||||||
|
ERROR("-t can't be used with --dist");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_spec_bundle(char *bundle, size_t len)
|
||||||
|
{
|
||||||
|
if (g_lcr_cmd_spec_args.spec_bundle == NULL) {
|
||||||
|
if (getcwd(bundle, len) == NULL) {
|
||||||
|
ERROR("getcwd failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (strlen(g_lcr_cmd_spec_args.spec_bundle) >= PATH_MAX ||
|
||||||
|
realpath(g_lcr_cmd_spec_args.spec_bundle, bundle) == NULL) {
|
||||||
|
ERROR("failed to get absolute path '%s'\n", g_lcr_cmd_spec_args.spec_bundle);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_spec_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
char *fakepath = NULL;
|
||||||
|
char *fakename = NULL;
|
||||||
|
char *seccomp = NULL;
|
||||||
|
char bundle[PATH_MAX] = { 0 };
|
||||||
|
struct lcr_list *lcr_conf = NULL;
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = {
|
||||||
|
SPEC_OPTIONS(g_lcr_cmd_spec_args),
|
||||||
|
COMMON_OPTIONS(g_lcr_cmd_spec_args)
|
||||||
|
};
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_spec_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc,
|
||||||
|
(const char **)argv, g_lcr_cmd_spec_desc, g_lcr_cmd_spec_usage);
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_spec_args.argc, &g_lcr_cmd_spec_args.argv)) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(NULL, g_lcr_cmd_spec_args.log_file, g_lcr_cmd_spec_args.log_priority,
|
||||||
|
g_lcr_cmd_spec_args.progname, g_lcr_cmd_spec_args.quiet, LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_spec_dist_and_translate() != 0) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_spec_bundle(bundle, PATH_MAX) != 0) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_lcr_fake_path_name(bundle, &fakepath, &fakename) ||
|
||||||
|
get_lcr_conf(&g_lcr_cmd_spec_args, &lcr_conf, &seccomp)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lcr_save_spec(fakename, fakepath, lcr_conf, seccomp)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
|
lcr_free_config(lcr_conf);
|
||||||
|
free(lcr_conf);
|
||||||
|
free(seccomp);
|
||||||
|
free(fakepath);
|
||||||
|
free(fakename);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
33
src/cmd/spec.h
Normal file
33
src/cmd/spec.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container spec definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_SPEC_H
|
||||||
|
#define __CMD_SPEC_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define SPEC_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "bundle", 'b', &(cmdargs).spec_bundle, \
|
||||||
|
"Path to the root of the bundle directory, default is current directory", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "translate", 't', &(cmdargs).spec_translate, \
|
||||||
|
"Translate oci specification (in json format) to lcr configuration", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "dist", 0, &(cmdargs).spec_dist, \
|
||||||
|
"Generate distribution specification, now support: ubuntu", NULL }
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_spec_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_spec_args;
|
||||||
|
int cmd_spec_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_SPEC_H */
|
||||||
111
src/cmd/start.c
Normal file
111
src/cmd/start.c
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container start functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
#include "start.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
const char g_lcr_cmd_start_desc[] = "start container";
|
||||||
|
static const char g_lcr_cmd_start_usage[] = "start [command options] --name=NAME";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_start_args;
|
||||||
|
int callback_foreground(command_option_t *option, const char *arg)
|
||||||
|
{
|
||||||
|
struct lcr_arguments *args = (struct lcr_arguments *)option->data;
|
||||||
|
if (arg == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(arg, "true")) {
|
||||||
|
args->start_daemonize = false;
|
||||||
|
} else if (!strcmp(arg, "false")) {
|
||||||
|
args->start_daemonize = true;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int cmd_start_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = {
|
||||||
|
START_OPTIONS(g_lcr_cmd_start_args),
|
||||||
|
COMMON_OPTIONS(g_lcr_cmd_start_args)
|
||||||
|
};
|
||||||
|
struct lcr_start_request request = {0};
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_start_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv,
|
||||||
|
g_lcr_cmd_start_desc, g_lcr_cmd_start_usage);
|
||||||
|
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_start_args.argc, &g_lcr_cmd_start_args.argv) ||
|
||||||
|
start_checker(&g_lcr_cmd_start_args)) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(g_lcr_cmd_start_args.name, g_lcr_cmd_start_args.log_file,
|
||||||
|
g_lcr_cmd_start_args.log_priority,
|
||||||
|
g_lcr_cmd_start_args.name,
|
||||||
|
g_lcr_cmd_start_args.quiet,
|
||||||
|
LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_lcr_cmd_start_args.name == NULL) {
|
||||||
|
fprintf(stderr, "missing container name, use -n,--name option\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
request.name = g_lcr_cmd_start_args.name;
|
||||||
|
request.lcrpath = g_lcr_cmd_start_args.lcrpath;
|
||||||
|
request.logpath = g_lcr_cmd_start_args.log_file;
|
||||||
|
request.loglevel = g_lcr_cmd_start_args.log_priority;
|
||||||
|
request.daemonize = g_lcr_cmd_start_args.start_daemonize;
|
||||||
|
request.tty = true;
|
||||||
|
request.open_stdin = true;
|
||||||
|
request.pidfile = g_lcr_cmd_start_args.start_pidfile;
|
||||||
|
request.console_fifos = g_lcr_cmd_start_args.console_fifos;
|
||||||
|
request.console_logpath = g_lcr_cmd_start_args.console_logpath;
|
||||||
|
|
||||||
|
if (!lcr_start(&request)) {
|
||||||
|
ERROR("Failed to start container %s", g_lcr_cmd_start_args.name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_lcr_cmd_start_args.start_daemonize) {
|
||||||
|
fprintf(stdout, "Container \"%s\" started\n", g_lcr_cmd_start_args.name);
|
||||||
|
}
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_start_arguments(const struct lcr_arguments *args)
|
||||||
|
{
|
||||||
|
return (args->console_fifos[0] && !args->console_fifos[1]) ||
|
||||||
|
(!args->console_fifos[0] && args->console_fifos[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int start_checker(const struct lcr_arguments *args)
|
||||||
|
{
|
||||||
|
if (check_start_arguments(args)) {
|
||||||
|
fprintf(stderr, "Should specify the input and output FIFOs at the same time\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
39
src/cmd/start.h
Normal file
39
src/cmd/start.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container start definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_START_H
|
||||||
|
#define __CMD_START_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define START_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_BOOL, false, "daemon", 'd', &(cmdargs).start_daemonize, \
|
||||||
|
"Daemonize the container (default)", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_CALLBACK, false, "foreground", 'F', &(cmdargs).start_daemonize, \
|
||||||
|
"Start with the current tty attached to /dev/console", callback_foreground }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "pidfile", 0, &(cmdargs).start_pidfile, "Create a file with the process id", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "console_file", 'L', &(cmdargs).console_logpath, \
|
||||||
|
"Save the console output to the file", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "in-fifo", 0, &(cmdargs).console_fifos[0], "console fifo", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "out-fifo", 0, &(cmdargs).console_fifos[1], "console fifo", NULL }
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_start_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_start_args;
|
||||||
|
int callback_foreground(command_option_t *option, const char *arg);
|
||||||
|
int start_checker(const struct lcr_arguments *args);
|
||||||
|
int cmd_start_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_START_H */
|
||||||
194
src/cmd/state.c
Normal file
194
src/cmd/state.c
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container state functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <securec.h>
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
const char g_lcr_cmd_state_desc[] = "Output the state of a container";
|
||||||
|
static const char g_lcr_cmd_state_usage[] = "state --name=NAME";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_state_args;
|
||||||
|
|
||||||
|
static uint64_t read_memory_info(void)
|
||||||
|
{
|
||||||
|
uint64_t sysmem_limit = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
char *line = NULL;
|
||||||
|
char *p = NULL;
|
||||||
|
|
||||||
|
FILE *fp = util_fopen("/proc/meminfo", "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
ERROR("Failed to open /proc/meminfo");
|
||||||
|
return sysmem_limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (getline(&line, &len, fp) != -1) {
|
||||||
|
p = strchr(line, ' ');
|
||||||
|
if (p == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
p++;
|
||||||
|
if (strcmp(line, "MemTotal:") == 0) {
|
||||||
|
while (*p != '\0' && (*p == ' ' || *p == '\t')) {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if (*p == '\0') {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
sysmem_limit = strtoull(p, NULL, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
fclose(fp);
|
||||||
|
free(line);
|
||||||
|
return sysmem_limit * SIZE_KB;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void size_humanize(unsigned long long val, char *buf, size_t bufsz)
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
|
||||||
|
if (val > 1 << 30) {
|
||||||
|
ret = sprintf_s(buf, bufsz, "%u.%2.2u GiB",
|
||||||
|
(unsigned int)(val >> 30),
|
||||||
|
(unsigned int)((val & ((1 << 30) - 1)) * 100) >> 30);
|
||||||
|
} else if (val > 1 << 20) {
|
||||||
|
unsigned long long x = val + 5243; /* for rounding */
|
||||||
|
ret = sprintf_s(buf, bufsz, "%u.%2.2u MiB",
|
||||||
|
(unsigned int)(x >> 20), (unsigned int)(((x & ((1 << 20) - 1)) * 100) >> 20));
|
||||||
|
} else if (val > 1 << 10) {
|
||||||
|
unsigned long long x = val + 5; /* for rounding */
|
||||||
|
ret = sprintf_s(buf, bufsz, "%u.%2.2u KiB",
|
||||||
|
(unsigned int)(x >> 10), (unsigned int)(((x & ((1 << 10) - 1)) * 100) >> 10));
|
||||||
|
} else {
|
||||||
|
ret = sprintf_s(buf, bufsz, "%u bytes", (unsigned int)val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
ERROR("Failed to sprintf string");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_state(const struct lcr_container_state *lcs)
|
||||||
|
{
|
||||||
|
char buf[BUFSIZE];
|
||||||
|
|
||||||
|
fprintf(stdout, "%-15s %s\n", "Name:", lcs->name);
|
||||||
|
fprintf(stdout, "%-15s %s\n", "State:", lcs->state);
|
||||||
|
if (strcmp(lcs->state, "RUNNING") != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "%-15s %d\n", "PID:", lcs->init);
|
||||||
|
fprintf(stdout, "%-15s %.2f seconds\n", "CPU use:",
|
||||||
|
(double)lcs->cpu_use_nanos / 1000000000.0);
|
||||||
|
|
||||||
|
fprintf(stdout, "%-15s %llu\n", "Pids current:",
|
||||||
|
(unsigned long long)lcs->pids_current);
|
||||||
|
|
||||||
|
size_humanize(lcs->mem_used, buf, sizeof(buf));
|
||||||
|
fprintf(stdout, "%-15s %s\n", "Memory use:", buf);
|
||||||
|
|
||||||
|
size_humanize(lcs->mem_limit, buf, sizeof(buf));
|
||||||
|
fprintf(stdout, "%-15s %s\n", "Memory limit:", buf);
|
||||||
|
|
||||||
|
size_humanize(lcs->kmem_used, buf, sizeof(buf));
|
||||||
|
fprintf(stdout, "%-15s %s\n", "KMem use:", buf);
|
||||||
|
|
||||||
|
size_humanize(lcs->kmem_limit, buf, sizeof(buf));
|
||||||
|
fprintf(stdout, "%-15s %s\n", "KMem limit:", buf);
|
||||||
|
|
||||||
|
size_humanize(lcs->io_service_bytes.read, buf, sizeof(buf));
|
||||||
|
fprintf(stdout, "%-15s %s\n", "Blkio read:", buf);
|
||||||
|
|
||||||
|
size_humanize(lcs->io_service_bytes.write, buf, sizeof(buf));
|
||||||
|
fprintf(stdout, "%-15s %s\n", "Blkio write:", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int check_container_name()
|
||||||
|
{
|
||||||
|
if (g_lcr_cmd_state_args.name == NULL) {
|
||||||
|
fprintf(stderr, "missing --name,-n option\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_sysmem_limit(struct lcr_container_state *state)
|
||||||
|
{
|
||||||
|
uint64_t sysmem_limit = 0;
|
||||||
|
|
||||||
|
sysmem_limit = read_memory_info();
|
||||||
|
if (sysmem_limit > 0 && state->mem_limit > sysmem_limit) {
|
||||||
|
state->mem_limit = sysmem_limit;
|
||||||
|
}
|
||||||
|
if (sysmem_limit > 0 && state->kmem_limit > sysmem_limit) {
|
||||||
|
state->kmem_limit = sysmem_limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_state_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
struct lcr_container_state state = { 0 };
|
||||||
|
command_t cmd;
|
||||||
|
struct command_option options[] = {
|
||||||
|
STATE_OPTIONS(g_lcr_cmd_state_args),
|
||||||
|
COMMON_OPTIONS(g_lcr_cmd_state_args)
|
||||||
|
};
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_state_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv,
|
||||||
|
g_lcr_cmd_state_desc, g_lcr_cmd_state_usage);
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_state_args.argc, &g_lcr_cmd_state_args.argv)) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(g_lcr_cmd_state_args.name,
|
||||||
|
g_lcr_cmd_state_args.log_file,
|
||||||
|
g_lcr_cmd_state_args.log_priority,
|
||||||
|
g_lcr_cmd_state_args.progname,
|
||||||
|
g_lcr_cmd_state_args.quiet,
|
||||||
|
LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_container_name() != 0) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lcr_state(g_lcr_cmd_state_args.name, g_lcr_cmd_state_args.lcrpath, &state)) {
|
||||||
|
fprintf(stderr, "Error get the container \"%s\"'s state\n", g_lcr_cmd_state_args.name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_sysmem_limit(&state);
|
||||||
|
|
||||||
|
print_state(&state);
|
||||||
|
lcr_container_state_free(&state);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
28
src/cmd/state.h
Normal file
28
src/cmd/state.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container state definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_STATE_H
|
||||||
|
#define __CMD_STATE_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define STATE_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL }
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_state_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_state_args;
|
||||||
|
int cmd_state_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_STATE_H */
|
||||||
122
src/cmd/update.c
Normal file
122
src/cmd/update.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container update functions
|
||||||
|
******************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <securec.h>
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
#include "update.h"
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define BLKIOWEIGHT 1
|
||||||
|
#define CPUSHARES 2
|
||||||
|
#define CPUPERIOD 3
|
||||||
|
#define CPUQUOTA 4
|
||||||
|
#define CPUSETCPUS 5
|
||||||
|
#define CPUSETMEMS 6
|
||||||
|
#define KERNELMEMORY 7
|
||||||
|
#define MEMORYRESERV 8
|
||||||
|
#define MEMORYSWAP 9
|
||||||
|
|
||||||
|
const char g_lcr_cmd_update_desc[] = "Update configuration of a container";
|
||||||
|
static const char g_lcr_cmd_update_usage[] = "update --name=NAME";
|
||||||
|
|
||||||
|
struct lcr_arguments g_lcr_cmd_update_args;
|
||||||
|
|
||||||
|
static void to_cgroup_cpu_resources(const struct lcr_arguments *args, struct lcr_cgroup_resources *cr)
|
||||||
|
{
|
||||||
|
if (args->cr.blkio_weight) {
|
||||||
|
cr->blkio_weight = strtoull(args->cr.blkio_weight, NULL, 10);
|
||||||
|
}
|
||||||
|
if (args->cr.cpu_shares) {
|
||||||
|
cr->cpu_shares = strtoull(args->cr.cpu_shares, NULL, 10);
|
||||||
|
}
|
||||||
|
if (args->cr.cpu_period) {
|
||||||
|
cr->cpu_period = strtoull(args->cr.cpu_period, NULL, 10);
|
||||||
|
}
|
||||||
|
if (args->cr.cpu_quota) {
|
||||||
|
cr->cpu_quota = strtoull(args->cr.cpu_quota, NULL, 10);
|
||||||
|
}
|
||||||
|
if (args->cr.cpuset_cpus) {
|
||||||
|
cr->cpuset_cpus = args->cr.cpuset_cpus;
|
||||||
|
}
|
||||||
|
if (args->cr.cpuset_mems) {
|
||||||
|
cr->cpuset_mems = args->cr.cpuset_mems;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void to_cgroup_mem_resources(const struct lcr_arguments *args, struct lcr_cgroup_resources *cr)
|
||||||
|
{
|
||||||
|
if (args->cr.kernel_memory_limit) {
|
||||||
|
cr->kernel_memory_limit = strtoull(args->cr.kernel_memory_limit, NULL, 10);
|
||||||
|
}
|
||||||
|
if (args->cr.memory_reservation) {
|
||||||
|
cr->memory_reservation = strtoull(args->cr.memory_reservation, NULL, 10);
|
||||||
|
}
|
||||||
|
if (args->cr.memory_limit) {
|
||||||
|
cr->memory_limit = strtoull(args->cr.memory_limit, NULL, 10);
|
||||||
|
}
|
||||||
|
if (args->cr.memory_swap) {
|
||||||
|
cr->memory_swap = strtoull(args->cr.memory_swap, NULL, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void to_cgroup_resources(const struct lcr_arguments *args, struct lcr_cgroup_resources *cr)
|
||||||
|
{
|
||||||
|
if (args == NULL || cr == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
to_cgroup_cpu_resources(args, cr);
|
||||||
|
|
||||||
|
to_cgroup_mem_resources(args, cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_update_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
command_t cmd;
|
||||||
|
struct lcr_cgroup_resources cr = { 0 };
|
||||||
|
struct command_option options[] = { UPDATE_OPTIONS(g_lcr_cmd_update_args), COMMON_OPTIONS(g_lcr_cmd_update_args) };
|
||||||
|
|
||||||
|
lcr_arguments_init(&g_lcr_cmd_update_args);
|
||||||
|
|
||||||
|
command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv, g_lcr_cmd_update_desc,
|
||||||
|
g_lcr_cmd_update_usage);
|
||||||
|
|
||||||
|
if (command_parse_args(&cmd, &g_lcr_cmd_update_args.argc, &g_lcr_cmd_update_args.argv)) {
|
||||||
|
exit(EINVALIDARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lcr_log_init(g_lcr_cmd_update_args.name, g_lcr_cmd_update_args.log_file, g_lcr_cmd_update_args.log_priority,
|
||||||
|
g_lcr_cmd_update_args.progname, g_lcr_cmd_update_args.quiet, LOGPATH)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_lcr_cmd_update_args.name == NULL) {
|
||||||
|
fprintf(stderr, "missing --name,-n option\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
to_cgroup_resources(&g_lcr_cmd_update_args, &cr);
|
||||||
|
if (!lcr_update(g_lcr_cmd_update_args.name, g_lcr_cmd_update_args.lcrpath, &cr)) {
|
||||||
|
fprintf(stderr, "Error update container %s\n", g_lcr_cmd_update_args.name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
46
src/cmd/update.h
Normal file
46
src/cmd/update.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container update definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __CMD_UPDATE_H
|
||||||
|
#define __CMD_UPDATE_H
|
||||||
|
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "commander.h"
|
||||||
|
|
||||||
|
#define UPDATE_OPTIONS(cmdargs) \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "blkio-weight", 0, &(cmdargs).cr.blkio_weight, \
|
||||||
|
"Block IO (relative weight), between 10 and 1000", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "cpu-shares", 0, &(cmdargs).cr.cpu_shares, "CPU shares (relative weight)", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "cpu-period", 0, &(cmdargs).cr.cpu_period, \
|
||||||
|
"Limit CPU CFS (Completely Fair Scheduler) period", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "cpu-quota", 0, &(cmdargs).cr.cpu_quota, \
|
||||||
|
"Limit CPU CFS (Completely Fair Scheduler) quota", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "cpuset-cpus", 0, &(cmdargs).cr.cpuset_cpus, \
|
||||||
|
"CPUs in which to allow execution (0-3, 0,1)", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "cpuset-mems", 0, &(cmdargs).cr.cpuset_mems, \
|
||||||
|
"MEMs in which to allow execution (0-3, 0,1)", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "kernel-memory", 0, &(cmdargs).cr.kernel_memory_limit, \
|
||||||
|
"Kernel memory limit", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "memory", 'm', &(cmdargs).cr.memory_limit, "Memory limit", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "memory-reservation", 0, &(cmdargs).cr.memory_reservation, \
|
||||||
|
"Memory soft limit", NULL }, \
|
||||||
|
{ CMD_OPT_TYPE_STRING, false, "memory-swap", 0, &(cmdargs).cr.memory_swap, \
|
||||||
|
"Swap limit equal to memory plus swap: '-1' to enable unlimited swap", NULL }
|
||||||
|
|
||||||
|
extern const char g_lcr_cmd_update_desc[];
|
||||||
|
extern struct lcr_arguments g_lcr_cmd_update_args;
|
||||||
|
int cmd_update_main(int argc, const char **argv);
|
||||||
|
|
||||||
|
#endif /* __CMD_UPDATE_H */
|
||||||
2611
src/conf.c
Normal file
2611
src/conf.c
Normal file
File diff suppressed because it is too large
Load Diff
110
src/conf.h
Normal file
110
src/conf.h
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container conf function
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __LCR_CONF_H
|
||||||
|
#define __LCR_CONF_H
|
||||||
|
|
||||||
|
#include "oci_runtime_spec.h"
|
||||||
|
#include "lcr_list.h"
|
||||||
|
|
||||||
|
#define INVALID_INT 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Store lcr configuration
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
char *value;
|
||||||
|
} lcr_config_item_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return value:
|
||||||
|
* 0 is valid item
|
||||||
|
* 1 will skip this
|
||||||
|
* -1 is invalid item
|
||||||
|
* */
|
||||||
|
typedef int(*lcr_check_item_t)(const char *);
|
||||||
|
/*
|
||||||
|
* Store annotations configuration
|
||||||
|
* */
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
char *lxc_item_name;
|
||||||
|
lcr_check_item_t checker;
|
||||||
|
} lcr_annotation_item_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* seccomp trans arch
|
||||||
|
* */
|
||||||
|
typedef struct {
|
||||||
|
char *arch;
|
||||||
|
char *value;
|
||||||
|
} lcr_arch_value;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get host arch
|
||||||
|
* */
|
||||||
|
typedef struct {
|
||||||
|
char *arch;
|
||||||
|
char *value;
|
||||||
|
int num;
|
||||||
|
} lcr_host_arch;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a lcr_list node, and initialize the elem to a lcr_config_item_t with
|
||||||
|
* key and value
|
||||||
|
*/
|
||||||
|
struct lcr_list *create_lcr_list_node(const char *key, const char *value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free a lcr_list node
|
||||||
|
*/
|
||||||
|
void free_lcr_list_node(struct lcr_list *node);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate oci hostname to lcr config
|
||||||
|
*/
|
||||||
|
struct lcr_list *trans_oci_hostname(const char *hostname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate oci process struct to lcr config
|
||||||
|
*/
|
||||||
|
struct lcr_list *trans_oci_process(const oci_runtime_spec_process *proc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate oci root struct to lcr config
|
||||||
|
*/
|
||||||
|
struct lcr_list *trans_oci_root(const oci_runtime_spec_root *root, const oci_runtime_config_linux *linux);
|
||||||
|
/*
|
||||||
|
* Translate oci mounts struct to lcr config
|
||||||
|
*/
|
||||||
|
struct lcr_list *trans_oci_mounts(const oci_runtime_spec *c);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate oci linux struct to lcr config
|
||||||
|
*/
|
||||||
|
struct lcr_list *trans_oci_linux(const oci_runtime_config_linux *l, char **seccomp_conf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate oci annotations to lcr config
|
||||||
|
* This is not supported in standard oci runtime-spec
|
||||||
|
*/
|
||||||
|
struct lcr_list *trans_annotations(const json_map_string_string *anno);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get other lxc needed configurations
|
||||||
|
*/
|
||||||
|
struct lcr_list *get_needed_lxc_conf();
|
||||||
|
|
||||||
|
#endif /*__LCR_CONF_H*/
|
||||||
50
src/constants.h
Normal file
50
src/constants.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide constant definition
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _LCRD_CONSTANTS_H
|
||||||
|
#define _LCRD_CONSTANTS_H
|
||||||
|
|
||||||
|
/* mode of file and directory */
|
||||||
|
|
||||||
|
#define DEFAULT_SECURE_FILE_MODE 0640
|
||||||
|
|
||||||
|
#define DEFAULT_SECURE_DIRECTORY_MODE 0750
|
||||||
|
|
||||||
|
#define ROOTFS_MNT_DIRECTORY_MODE 0640
|
||||||
|
|
||||||
|
#define CONFIG_DIRECTORY_MODE 0750
|
||||||
|
|
||||||
|
#define CONFIG_FILE_MODE 0640
|
||||||
|
|
||||||
|
#define ARCH_LOG_FILE_MODE 0440
|
||||||
|
|
||||||
|
#define WORKING_LOG_FILE_MODE 0640
|
||||||
|
|
||||||
|
#define LOG_DIRECTORY_MODE 0750
|
||||||
|
|
||||||
|
#define TEMP_DIRECTORY_MODE 0750
|
||||||
|
|
||||||
|
#define DEBUG_FILE_MODE 0640
|
||||||
|
|
||||||
|
#define DEBUG_DIRECTORY_MODE 0750
|
||||||
|
|
||||||
|
// Config file path
|
||||||
|
#define OCIHOOKSFILE "ocihooks.json"
|
||||||
|
#define OCICONFIGFILE "ociconfig.json"
|
||||||
|
#define LXCCONFIGFILE "config"
|
||||||
|
|
||||||
|
#define PARAM_NUM 50
|
||||||
|
|
||||||
|
#endif
|
||||||
116
src/error.c
Normal file
116
src/error.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container error definition
|
||||||
|
******************************************************************************/
|
||||||
|
#include "utils.h"
|
||||||
|
#include "securec.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
|
// record the lcr error
|
||||||
|
__thread engine_error_t g_lcr_error = {
|
||||||
|
.errcode = LCR_SUCCESS,
|
||||||
|
.errmsg = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LCR_ERRMSG_GEN(n, s) { LCR_##n, s },
|
||||||
|
struct lcr_strerror_tab_t {
|
||||||
|
lcr_errno_t lcr_errno;
|
||||||
|
const char *errmsg;
|
||||||
|
};
|
||||||
|
static const struct lcr_strerror_tab_t g_lcr_strerror_tab[] = {
|
||||||
|
LCR_ERRNO_MAP(LCR_ERRMSG_GEN)
|
||||||
|
};
|
||||||
|
#undef LCR_ERRMSG_GEN
|
||||||
|
|
||||||
|
const char *errno_to_error_message(lcr_errno_t err)
|
||||||
|
{
|
||||||
|
if ((size_t)err >= sizeof(g_lcr_strerror_tab) / sizeof(g_lcr_strerror_tab[0])) {
|
||||||
|
return g_lcr_strerror_tab[LCR_ERR_UNKNOWN].errmsg;
|
||||||
|
}
|
||||||
|
return g_lcr_strerror_tab[err].errmsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_error_message(engine_error_t *error)
|
||||||
|
{
|
||||||
|
if (error == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error->errcode = LCR_SUCCESS;
|
||||||
|
free(error->errmsg);
|
||||||
|
error->errmsg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcr_set_error_message(lcr_errno_t errcode, const char *format, ...)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char errbuf[BUFSIZ + 1] = { 0 };
|
||||||
|
|
||||||
|
va_list argp;
|
||||||
|
va_start(argp, format);
|
||||||
|
|
||||||
|
ret = vsprintf_s(errbuf, BUFSIZ, format, argp);
|
||||||
|
va_end(argp);
|
||||||
|
clear_error_message(&g_lcr_error);
|
||||||
|
if (ret < 0) {
|
||||||
|
g_lcr_error.errcode = LCR_ERR_FORMAT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_lcr_error.errcode = errcode;
|
||||||
|
g_lcr_error.errmsg = util_strdup_s(errbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcr_try_set_error_message(lcr_errno_t errcode, const char *format, ...)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char errbuf[BUFSIZ + 1] = { 0 };
|
||||||
|
va_list argp;
|
||||||
|
|
||||||
|
if (g_lcr_error.errmsg != NULL || g_lcr_error.errcode != LCR_SUCCESS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
va_start(argp, format);
|
||||||
|
ret = vsprintf_s(errbuf, BUFSIZ, format, argp);
|
||||||
|
va_end(argp);
|
||||||
|
clear_error_message(&g_lcr_error);
|
||||||
|
if (ret < 0) {
|
||||||
|
g_lcr_error.errcode = LCR_ERR_FORMAT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_lcr_error.errcode = errcode;
|
||||||
|
g_lcr_error.errmsg = util_strdup_s(errbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcr_append_error_message(lcr_errno_t errcode, const char *format, ...)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char errbuf[BUFSIZ + 1] = { 0 };
|
||||||
|
char *result = NULL;
|
||||||
|
|
||||||
|
va_list argp;
|
||||||
|
va_start(argp, format);
|
||||||
|
|
||||||
|
ret = vsprintf_s(errbuf, BUFSIZ, format, argp);
|
||||||
|
va_end(argp);
|
||||||
|
if (ret < 0) {
|
||||||
|
g_lcr_error.errcode = LCR_ERR_FORMAT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_lcr_error.errcode = errcode;
|
||||||
|
result = util_string_append(g_lcr_error.errmsg, errbuf);
|
||||||
|
if (result == NULL) {
|
||||||
|
g_lcr_error.errcode = LCR_ERR_MEMOUT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free(g_lcr_error.errmsg);
|
||||||
|
g_lcr_error.errmsg = result;
|
||||||
|
}
|
||||||
68
src/error.h
Normal file
68
src/error.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container error definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __LCR_ERROR_H
|
||||||
|
#define __LCR_ERROR_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct engine_error {
|
||||||
|
uint32_t errcode;
|
||||||
|
char *errmsg;
|
||||||
|
} engine_error_t;
|
||||||
|
|
||||||
|
/*record the lcr error*/
|
||||||
|
extern __thread engine_error_t g_lcr_error;
|
||||||
|
|
||||||
|
#define DEF_SUCCESS_STR "Success"
|
||||||
|
#define DEF_ERR_RUNTIME_STR "Runtime error"
|
||||||
|
|
||||||
|
#define LCR_ERRNO_MAP(XX) \
|
||||||
|
XX(SUCCESS, DEF_SUCCESS_STR) \
|
||||||
|
\
|
||||||
|
/* err in posix api call */ \
|
||||||
|
XX(ERR_MEMOUT, "Out of memory") \
|
||||||
|
XX(ERR_MEMSET, "Memory set error") \
|
||||||
|
\
|
||||||
|
/* err in other case or call function int thirdparty library */ \
|
||||||
|
XX(ERR_FORMAT, "Error message is too long") \
|
||||||
|
XX(ERR_INPUT, "Invalid input parameter") \
|
||||||
|
XX(ERR_INTERNAL, "Server internal error") \
|
||||||
|
\
|
||||||
|
/* err in runtime module */ \
|
||||||
|
XX(ERR_RUNTIME, DEF_ERR_RUNTIME_STR) \
|
||||||
|
\
|
||||||
|
/* err max */ \
|
||||||
|
XX(ERR_UNKNOWN, "Unknown error")
|
||||||
|
|
||||||
|
#define LCR_ERRNO_GEN(n, s) LCR_##n,
|
||||||
|
typedef enum { LCR_ERRNO_MAP(LCR_ERRNO_GEN) } lcr_errno_t;
|
||||||
|
#undef LCR_ERRNO_GEN
|
||||||
|
|
||||||
|
const char *errno_to_error_message(lcr_errno_t err);
|
||||||
|
|
||||||
|
void clear_error_message(engine_error_t *error);
|
||||||
|
|
||||||
|
void lcr_set_error_message(lcr_errno_t errcode, const char *format, ...);
|
||||||
|
|
||||||
|
void lcr_try_set_error_message(lcr_errno_t errcode, const char *format, ...);
|
||||||
|
|
||||||
|
void lcr_append_error_message(lcr_errno_t errcode, const char *format, ...);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
2
src/json/CMakeLists.txt
Normal file
2
src/json/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# generate .c and .h files for json
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/schema)
|
||||||
82
src/json/oci_runtime_hooks.c
Normal file
82
src/json/oci_runtime_hooks.c
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr 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: maoweiyong
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide oci runtime hooks functions
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
#include <securec.h>
|
||||||
|
#include "read_file.h"
|
||||||
|
#include "oci_runtime_hooks.h"
|
||||||
|
|
||||||
|
#define PARSE_ERR_BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
char *oci_runtime_spec_hooks_generate_json(const oci_runtime_spec_hooks *ptr, const struct parser_context *ctx,
|
||||||
|
parser_error *err)
|
||||||
|
{
|
||||||
|
yajl_gen g = NULL;
|
||||||
|
struct parser_context tmp_ctx = { 0 };
|
||||||
|
const unsigned char *gen_buf = NULL;
|
||||||
|
char *json_buf = NULL;
|
||||||
|
size_t gen_len = 0;
|
||||||
|
errno_t eret;
|
||||||
|
|
||||||
|
if (ptr == NULL || err == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*err = NULL;
|
||||||
|
if (ctx == NULL) {
|
||||||
|
ctx = &tmp_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!json_gen_init(&g, ctx)) {
|
||||||
|
*err = strdup("Json_gen init failed");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (yajl_gen_status_ok != gen_oci_runtime_spec_hooks(g, ptr, ctx, err)) {
|
||||||
|
if (*err == NULL) {
|
||||||
|
*err = strdup("Failed to generate json");
|
||||||
|
}
|
||||||
|
goto free_out;
|
||||||
|
}
|
||||||
|
yajl_gen_get_buf(g, &gen_buf, &gen_len);
|
||||||
|
if (gen_buf == NULL) {
|
||||||
|
*err = strdup("Error to get generated json");
|
||||||
|
goto free_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gen_len > SIZE_MAX - 1) {
|
||||||
|
*err = strdup("Generated json too long");
|
||||||
|
goto free_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_buf = malloc(gen_len + 1);
|
||||||
|
if (json_buf == NULL) {
|
||||||
|
*err = strdup("Out of memory");
|
||||||
|
goto free_out;
|
||||||
|
}
|
||||||
|
eret = memcpy_s((void *)json_buf, gen_len + 1, (void *)gen_buf, gen_len);
|
||||||
|
if (eret != EOK) {
|
||||||
|
*err = strdup("Memcpy failed");
|
||||||
|
goto free_out;
|
||||||
|
}
|
||||||
|
json_buf[gen_len] = '\0';
|
||||||
|
|
||||||
|
free_out:
|
||||||
|
yajl_gen_clear(g);
|
||||||
|
yajl_gen_free(g);
|
||||||
|
out:
|
||||||
|
return json_buf;
|
||||||
|
}
|
||||||
24
src/json/oci_runtime_hooks.h
Normal file
24
src/json/oci_runtime_hooks.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr 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: maoweiyong
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide oci runtime hooks functions
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _CONTAINER_HOOKS_H
|
||||||
|
#define _CONTAINER_HOOKS_H
|
||||||
|
|
||||||
|
#include "oci_runtime_spec.h"
|
||||||
|
|
||||||
|
char *oci_runtime_spec_hooks_generate_json(const oci_runtime_spec_hooks *ptr, const struct parser_context *ctx,
|
||||||
|
parser_error *err);
|
||||||
|
|
||||||
|
#endif
|
||||||
16
src/json/schema/CMakeLists.txt
Normal file
16
src/json/schema/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
project (JSONGenerator)
|
||||||
|
|
||||||
|
set(cmdpath python)
|
||||||
|
set(pysrcpath ${CMAKE_CURRENT_SOURCE_DIR}/src/generate.py)
|
||||||
|
set(schemapath ${CMAKE_CURRENT_SOURCE_DIR}/schema)
|
||||||
|
set(outputpath ${CMAKE_BINARY_DIR}/json)
|
||||||
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
message("-- Generate .c and .h file into: " ${outputpath})
|
||||||
|
|
||||||
|
execute_process(COMMAND ${cmdpath} ${pysrcpath} --gen-common --gen-ref -r --root=${schemapath} --out=${outputpath} ${schemapath}
|
||||||
|
ERROR_VARIABLE err
|
||||||
|
)
|
||||||
|
if (err)
|
||||||
|
message("error: " ${err})
|
||||||
|
endif()
|
||||||
233
src/json/schema/schema/defs.json
Normal file
233
src/json/schema/schema/defs.json
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
{
|
||||||
|
" description": "Definitions used throughout the OpenContainer Specification",
|
||||||
|
"definitions": {
|
||||||
|
"int8": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": -128,
|
||||||
|
"maximum": 127
|
||||||
|
},
|
||||||
|
"int16": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": -32768,
|
||||||
|
"maximum": 32767
|
||||||
|
},
|
||||||
|
"int32": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": -2147483648,
|
||||||
|
"maximum": 2147483647
|
||||||
|
},
|
||||||
|
"int64": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": -9223372036854776000,
|
||||||
|
"maximum": 9223372036854776000
|
||||||
|
},
|
||||||
|
"uint8": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 255
|
||||||
|
},
|
||||||
|
"uint16": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 65535
|
||||||
|
},
|
||||||
|
"uint32": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 4294967295
|
||||||
|
},
|
||||||
|
"uint64": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 18446744073709552000
|
||||||
|
},
|
||||||
|
"uint16Pointer": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/uint16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"uint64Pointer": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/uint64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stringPointer": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"percent": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 100
|
||||||
|
},
|
||||||
|
"UID": {
|
||||||
|
"$ref": "#/definitions/uint32"
|
||||||
|
},
|
||||||
|
"GID": {
|
||||||
|
"$ref": "#/definitions/uint32"
|
||||||
|
},
|
||||||
|
"ArrayOfGIDs": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/GID"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"FilePath": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Env": {
|
||||||
|
"$ref": "#/definitions/ArrayOfStrings"
|
||||||
|
},
|
||||||
|
"Hook": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"path": {
|
||||||
|
"$ref": "#/definitions/FilePath"
|
||||||
|
},
|
||||||
|
"args": {
|
||||||
|
"$ref": "#/definitions/ArrayOfStrings"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"$ref": "#/definitions/Env"
|
||||||
|
},
|
||||||
|
"timeout": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"path"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ArrayOfHooks": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Hook"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IDMapping": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"hostID": {
|
||||||
|
"$ref": "#/definitions/uint32"
|
||||||
|
},
|
||||||
|
"containerID": {
|
||||||
|
"$ref": "#/definitions/uint32"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"$ref": "#/definitions/uint32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"hostID",
|
||||||
|
"containerID",
|
||||||
|
"size"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Mount": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"source": {
|
||||||
|
"$ref": "#/definitions/FilePath"
|
||||||
|
},
|
||||||
|
"destination": {
|
||||||
|
"$ref": "#/definitions/FilePath"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"$ref": "#/definitions/ArrayOfStrings"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"destination"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ArrayOfStrings": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapStringString": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{1,}": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapStringInt": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{1,}": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapStringBool": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{1,}": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapIntString": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{2,}": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapIntInt": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{2,}": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapIntBool": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{2,}": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapStringObject": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{1,}": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ociVersion": {
|
||||||
|
"description": "The version of Open Container Runtime Specification that the document complies with",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"annotations": {
|
||||||
|
"$ref": "#/definitions/mapStringString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
271
src/json/schema/schema/oci/runtime/config-linux.json
Normal file
271
src/json/schema/schema/oci/runtime/config-linux.json
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
{
|
||||||
|
"linux": {
|
||||||
|
"description": "Linux platform-specific configurations",
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"devices": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/devices",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs-linux.json#/definitions/Device"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uidMappings": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/uidMappings",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs.json#/definitions/IDMapping"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gidMappings": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/gidMappings",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs.json#/definitions/IDMapping"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"namespaces": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/namespaces",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "defs-linux.json#/definitions/NamespaceReference"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"devices": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/devices",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs-linux.json#/definitions/DeviceCgroup"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pids": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/pids",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"limit": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/pids/limit",
|
||||||
|
"$ref": "defs.json#/definitions/int64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"limit"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockIO": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/blockIO",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"weight": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/blockIO/weight",
|
||||||
|
"$ref": "defs-linux.json#/definitions/weight"
|
||||||
|
},
|
||||||
|
"leafWeight": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/blockIO/leafWeight",
|
||||||
|
"$ref": "defs-linux.json#/definitions/weight"
|
||||||
|
},
|
||||||
|
"throttleReadBpsDevice": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/blockIO/throttleReadBpsDevice",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs-linux.json#/definitions/blockIODeviceThrottle"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"throttleWriteBpsDevice": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/blockIO/throttleWriteBpsDevice",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs-linux.json#/definitions/blockIODeviceThrottle"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"throttleReadIOPSDevice": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/blockIO/throttleReadIOPSDevice",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs-linux.json#/definitions/blockIODeviceThrottle"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"throttleWriteIOPSDevice": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/blockIO/throttleWriteIOPSDevice",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs-linux.json#/definitions/blockIODeviceThrottle"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"weightDevice": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/blockIO/weightDevice",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs-linux.json#/definitions/blockIODeviceWeight"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cpu": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/cpu",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"cpus": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/cpu/cpus",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"mems": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/cpu/mems",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"period": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/cpu/period",
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
},
|
||||||
|
"quota": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/cpu/quota",
|
||||||
|
"$ref": "defs.json#/definitions/int64"
|
||||||
|
},
|
||||||
|
"realtimePeriod": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/cpu/realtimePeriod",
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
},
|
||||||
|
"realtimeRuntime": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/cpu/realtimeRuntime",
|
||||||
|
"$ref": "defs.json#/definitions/int64"
|
||||||
|
},
|
||||||
|
"shares": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/cpu/shares",
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hugepageLimits": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/hugepageLimits",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"pageSize": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"pageSize",
|
||||||
|
"limit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"memory": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/memory",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"kernel": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/memory/kernel",
|
||||||
|
"$ref": "defs.json#/definitions/int64"
|
||||||
|
},
|
||||||
|
"kernelTCP": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/memory/kernelTCP",
|
||||||
|
"$ref": "defs.json#/definitions/int64"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/memory/limit",
|
||||||
|
"$ref": "defs.json#/definitions/int64"
|
||||||
|
},
|
||||||
|
"reservation": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/memory/reservation",
|
||||||
|
"$ref": "defs.json#/definitions/int64"
|
||||||
|
},
|
||||||
|
"swap": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/memory/swap",
|
||||||
|
"$ref": "defs.json#/definitions/int64"
|
||||||
|
},
|
||||||
|
"swappiness": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/memory/swappiness",
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
},
|
||||||
|
"disableOOMKiller": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/memory/disableOOMKiller",
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/network",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"classID": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/network/classId",
|
||||||
|
"$ref": "defs.json#/definitions/uint32"
|
||||||
|
},
|
||||||
|
"priorities": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/resources/network/priorities",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs-linux.json#/definitions/NetworkInterfacePriority"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cgroupsPath": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/cgroupsPath",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"rootfsPropagation": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/rootfsPropagation",
|
||||||
|
"$ref": "defs-linux.json#/definitions/RootfsPropagation"
|
||||||
|
},
|
||||||
|
"seccomp": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/seccomp",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"defaultAction": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/seccomp/defaultAction",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"architectures": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/seccomp/architectures",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs-linux.json#/definitions/SeccompArch"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"syscalls": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/seccomp/syscalls",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs-linux.json#/definitions/Syscall"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"defaultAction"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sysctl": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/sysctl",
|
||||||
|
"$ref": "defs.json#/definitions/mapStringString"
|
||||||
|
},
|
||||||
|
"maskedPaths": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/maskedPaths",
|
||||||
|
"$ref": "defs.json#/definitions/ArrayOfStrings"
|
||||||
|
},
|
||||||
|
"readonlyPaths": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/readonlyPaths",
|
||||||
|
"$ref": "defs.json#/definitions/ArrayOfStrings"
|
||||||
|
},
|
||||||
|
"mountLabel": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/mountLabel",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
270
src/json/schema/schema/oci/runtime/defs-linux.json
Normal file
270
src/json/schema/schema/oci/runtime/defs-linux.json
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
{
|
||||||
|
"definitions": {
|
||||||
|
"RootfsPropagation": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"private",
|
||||||
|
"shared",
|
||||||
|
"slave",
|
||||||
|
"unbindable"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SeccompArch": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"SCMP_ARCH_X86",
|
||||||
|
"SCMP_ARCH_X86_64",
|
||||||
|
"SCMP_ARCH_X32",
|
||||||
|
"SCMP_ARCH_ARM",
|
||||||
|
"SCMP_ARCH_AARCH64",
|
||||||
|
"SCMP_ARCH_MIPS",
|
||||||
|
"SCMP_ARCH_MIPS64",
|
||||||
|
"SCMP_ARCH_MIPS64N32",
|
||||||
|
"SCMP_ARCH_MIPSEL",
|
||||||
|
"SCMP_ARCH_MIPSEL64",
|
||||||
|
"SCMP_ARCH_MIPSEL64N32",
|
||||||
|
"SCMP_ARCH_PPC",
|
||||||
|
"SCMP_ARCH_PPC64",
|
||||||
|
"SCMP_ARCH_PPC64LE",
|
||||||
|
"SCMP_ARCH_S390",
|
||||||
|
"SCMP_ARCH_S390X",
|
||||||
|
"SCMP_ARCH_PARISC",
|
||||||
|
"SCMP_ARCH_PARISC64"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SeccompAction": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"SCMP_ACT_KILL",
|
||||||
|
"SCMP_ACT_TRAP",
|
||||||
|
"SCMP_ACT_ERRNO",
|
||||||
|
"SCMP_ACT_TRACE",
|
||||||
|
"SCMP_ACT_ALLOW"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SeccompOperators": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"SCMP_CMP_NE",
|
||||||
|
"SCMP_CMP_LT",
|
||||||
|
"SCMP_CMP_LE",
|
||||||
|
"SCMP_CMP_EQ",
|
||||||
|
"SCMP_CMP_GE",
|
||||||
|
"SCMP_CMP_GT",
|
||||||
|
"SCMP_CMP_MASKED_EQ"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SyscallArg": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"index": {
|
||||||
|
"$ref": "defs.json#/definitions/uint32"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
},
|
||||||
|
"valueTwo": {
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
},
|
||||||
|
"op": {
|
||||||
|
"$ref": "#/definitions/SeccompOperators"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"index",
|
||||||
|
"value",
|
||||||
|
"op"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Syscall": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"names": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"$ref": "#/definitions/SeccompAction"
|
||||||
|
},
|
||||||
|
"args": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/SyscallArg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"names",
|
||||||
|
"action"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Major": {
|
||||||
|
"description": "major device number",
|
||||||
|
"$ref": "defs.json#/definitions/int64"
|
||||||
|
},
|
||||||
|
"Minor": {
|
||||||
|
"description": "minor device number",
|
||||||
|
"$ref": "defs.json#/definitions/int64"
|
||||||
|
},
|
||||||
|
"FileMode": {
|
||||||
|
"description": "File permissions mode (typically an octal value)",
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 512
|
||||||
|
},
|
||||||
|
"FileType": {
|
||||||
|
"description": "Type of a block or special character device",
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[cbup]$"
|
||||||
|
},
|
||||||
|
"Device": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/definitions/FileType"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"$ref": "defs.json#/definitions/FilePath"
|
||||||
|
},
|
||||||
|
"fileMode": {
|
||||||
|
"$ref": "#/definitions/FileMode"
|
||||||
|
},
|
||||||
|
"major": {
|
||||||
|
"$ref": "#/definitions/Major"
|
||||||
|
},
|
||||||
|
"minor": {
|
||||||
|
"$ref": "#/definitions/Minor"
|
||||||
|
},
|
||||||
|
"uid": {
|
||||||
|
"$ref": "defs.json#/definitions/UID"
|
||||||
|
},
|
||||||
|
"gid": {
|
||||||
|
"$ref": "defs.json#/definitions/GID"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"weight": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"blockIODevice": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"major": {
|
||||||
|
"$ref": "#/definitions/Major"
|
||||||
|
},
|
||||||
|
"minor": {
|
||||||
|
"$ref": "#/definitions/Minor"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"major",
|
||||||
|
"minor"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockIODeviceWeight": {
|
||||||
|
"type": "object",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/blockIODevice"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"weight": {
|
||||||
|
"$ref": "#/definitions/weight"
|
||||||
|
},
|
||||||
|
"leafWeight": {
|
||||||
|
"$ref": "#/definitions/weight"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockIODeviceThrottle": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/blockIODevice"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"rate": {
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"DeviceCgroup": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"allow": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"major": {
|
||||||
|
"$ref": "#/definitions/Major"
|
||||||
|
},
|
||||||
|
"minor": {
|
||||||
|
"$ref": "#/definitions/Minor"
|
||||||
|
},
|
||||||
|
"access": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"allow"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"NetworkInterfacePriority": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"priority": {
|
||||||
|
"$ref": "defs.json#/definitions/uint32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"priority"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"NamespaceType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"mount",
|
||||||
|
"pid",
|
||||||
|
"network",
|
||||||
|
"uts",
|
||||||
|
"ipc",
|
||||||
|
"user",
|
||||||
|
"cgroup"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"NamespaceReference": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/definitions/NamespaceType"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"$ref": "defs.json#/definitions/FilePath"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
233
src/json/schema/schema/oci/runtime/defs.json
Normal file
233
src/json/schema/schema/oci/runtime/defs.json
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
{
|
||||||
|
" description": "Definitions used throughout the OpenContainer Specification",
|
||||||
|
"definitions": {
|
||||||
|
"int8": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": -128,
|
||||||
|
"maximum": 127
|
||||||
|
},
|
||||||
|
"int16": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": -32768,
|
||||||
|
"maximum": 32767
|
||||||
|
},
|
||||||
|
"int32": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": -2147483648,
|
||||||
|
"maximum": 2147483647
|
||||||
|
},
|
||||||
|
"int64": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": -9223372036854776000,
|
||||||
|
"maximum": 9223372036854776000
|
||||||
|
},
|
||||||
|
"uint8": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 255
|
||||||
|
},
|
||||||
|
"uint16": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 65535
|
||||||
|
},
|
||||||
|
"uint32": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 4294967295
|
||||||
|
},
|
||||||
|
"uint64": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 18446744073709552000
|
||||||
|
},
|
||||||
|
"uint16Pointer": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/uint16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"uint64Pointer": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/uint64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stringPointer": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"percent": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 100
|
||||||
|
},
|
||||||
|
"UID": {
|
||||||
|
"$ref": "#/definitions/uint32"
|
||||||
|
},
|
||||||
|
"GID": {
|
||||||
|
"$ref": "#/definitions/uint32"
|
||||||
|
},
|
||||||
|
"ArrayOfGIDs": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/GID"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"FilePath": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Env": {
|
||||||
|
"$ref": "#/definitions/ArrayOfStrings"
|
||||||
|
},
|
||||||
|
"Hook": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"path": {
|
||||||
|
"$ref": "#/definitions/FilePath"
|
||||||
|
},
|
||||||
|
"args": {
|
||||||
|
"$ref": "#/definitions/ArrayOfStrings"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"$ref": "#/definitions/Env"
|
||||||
|
},
|
||||||
|
"timeout": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"path"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ArrayOfHooks": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Hook"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IDMapping": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"hostID": {
|
||||||
|
"$ref": "#/definitions/uint32"
|
||||||
|
},
|
||||||
|
"containerID": {
|
||||||
|
"$ref": "#/definitions/uint32"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"$ref": "#/definitions/uint32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"hostID",
|
||||||
|
"containerID",
|
||||||
|
"size"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Mount": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"source": {
|
||||||
|
"$ref": "#/definitions/FilePath"
|
||||||
|
},
|
||||||
|
"destination": {
|
||||||
|
"$ref": "#/definitions/FilePath"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"$ref": "#/definitions/ArrayOfStrings"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"destination"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ArrayOfStrings": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapStringString": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{1,}": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapStringInt": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{1,}": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapStringBool": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{1,}": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapIntString": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{2,}": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapIntInt": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{2,}": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapIntBool": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{2,}": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapStringObject": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".{1,}": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ociVersion": {
|
||||||
|
"description": "The version of Open Container Runtime Specification that the document complies with",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"annotations": {
|
||||||
|
"$ref": "#/definitions/mapStringString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
216
src/json/schema/schema/oci/runtime/spec.json
Normal file
216
src/json/schema/schema/oci/runtime/spec.json
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
{
|
||||||
|
"description": "Open Container Runtime Specification Container Configuration Schema",
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
|
"id": "https://opencontainers.org/schema/bundle",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"ociVersion": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/ociVersion",
|
||||||
|
"$ref": "defs.json#/definitions/ociVersion"
|
||||||
|
},
|
||||||
|
"hooks": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/hooks",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"prestart": {
|
||||||
|
"$ref": "defs.json#/definitions/ArrayOfHooks"
|
||||||
|
},
|
||||||
|
"poststart": {
|
||||||
|
"$ref": "defs.json#/definitions/ArrayOfHooks"
|
||||||
|
},
|
||||||
|
"poststop": {
|
||||||
|
"$ref": "defs.json#/definitions/ArrayOfHooks"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"annotations": {
|
||||||
|
"$ref": "defs.json#/definitions/annotations"
|
||||||
|
},
|
||||||
|
"hostname": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/hostname",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"mounts": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/mounts",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "defs.json#/definitions/Mount"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"description": "Configures the container's root filesystem.",
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/root",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"path": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/root/path",
|
||||||
|
"$ref": "defs.json#/definitions/FilePath"
|
||||||
|
},
|
||||||
|
"readonly": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/root/readonly",
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"process": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"cwd",
|
||||||
|
"args"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"args": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/args",
|
||||||
|
"$ref": "defs.json#/definitions/ArrayOfStrings"
|
||||||
|
},
|
||||||
|
"consoleSize": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/consoleSize",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"height",
|
||||||
|
"width"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"height": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/consoleSize/height",
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/consoleSize/width",
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cwd": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/cwd",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/env",
|
||||||
|
"$ref": "defs.json#/definitions/Env"
|
||||||
|
},
|
||||||
|
"terminal": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/terminal",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/user",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"uid": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/user/uid",
|
||||||
|
"$ref": "defs.json#/definitions/UID"
|
||||||
|
},
|
||||||
|
"gid": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/user/gid",
|
||||||
|
"$ref": "defs.json#/definitions/GID"
|
||||||
|
},
|
||||||
|
"additionalGids": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/user/additionalGids",
|
||||||
|
"$ref": "defs.json#/definitions/ArrayOfGIDs"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/user/username",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"capabilities": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/linux/capabilities",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"bounding": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/linux/capabilities/bounding",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permitted": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/linux/capabilities/permitted",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"effective": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/linux/capabilities/effective",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inheritable": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/linux/capabilities/inheritable",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ambient": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/linux/capabilities/ambient",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"apparmorProfile": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/linux/apparmorProfile",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"oomScoreAdj": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/linux/oomScoreAdj",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"selinuxLabel": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/linux/selinuxLabel",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"noNewPrivileges": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/linux/noNewPrivileges",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"rlimits": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/rlimits",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/rlimits/0",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"soft",
|
||||||
|
"hard"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"hard": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/rlimits/0/hard",
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
},
|
||||||
|
"soft": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/rlimits/0/soft",
|
||||||
|
"$ref": "defs.json#/definitions/uint64"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/linux/rlimits/0/type",
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^RLIMIT_[A-Z]+$"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"$ref": "config-linux.json#/linux"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"ociVersion"
|
||||||
|
]
|
||||||
|
}
|
||||||
45
src/json/schema/schema/oci/runtime/state.json
Normal file
45
src/json/schema/schema/oci/runtime/state.json
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"description": "Open Container Runtime State Schema",
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
|
"id": "https://opencontainers.org/schema/state",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"ociVersion": {
|
||||||
|
"id": "https://opencontainers.org/schema/runtime/state/ociVersion",
|
||||||
|
"$ref": "defs.json#/definitions/ociVersion"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"id": "https://opencontainers.org/schema/runtime/state/id",
|
||||||
|
"description": "the container's ID",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"id": "https://opencontainers.org/schema/runtime/state/status",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"creating",
|
||||||
|
"created",
|
||||||
|
"running",
|
||||||
|
"stopped"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pid": {
|
||||||
|
"id": "https://opencontainers.org/schema/runtime/state/pid",
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0
|
||||||
|
},
|
||||||
|
"bundle": {
|
||||||
|
"id": "https://opencontainers.org/schema/runtime/state/bundle",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"annotations": {
|
||||||
|
"$ref": "defs.json#/definitions/annotations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"ociVersion",
|
||||||
|
"id",
|
||||||
|
"status",
|
||||||
|
"bundle"
|
||||||
|
]
|
||||||
|
}
|
||||||
18
src/json/schema/schema/start-generate-config.json
Normal file
18
src/json/schema/schema/start-generate-config.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"uid": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/user/uid",
|
||||||
|
"$ref": "defs.json#/definitions/UID"
|
||||||
|
},
|
||||||
|
"gid": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/user/gid",
|
||||||
|
"$ref": "defs.json#/definitions/GID"
|
||||||
|
},
|
||||||
|
"additionalGids": {
|
||||||
|
"id": "https://opencontainers.org/schema/bundle/process/user/additionalGids",
|
||||||
|
"$ref": "defs.json#/definitions/ArrayOfGIDs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/json/schema/src/CMakeLists.txt
Normal file
3
src/json/schema/src/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# get current directory sources files
|
||||||
|
|
||||||
|
message("-- do nothing ")
|
||||||
1223
src/json/schema/src/common_c.py
Normal file
1223
src/json/schema/src/common_c.py
Normal file
File diff suppressed because it is too large
Load Diff
198
src/json/schema/src/common_h.py
Normal file
198
src/json/schema/src/common_h.py
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Description: commom header file
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
# - Copyright (C) Huawei Technologies., Ltd. 2018-2019. All rights reserved.
|
||||||
|
# - lcr 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 json
|
||||||
|
# - Author: tanyifeng
|
||||||
|
# - Create: 2018-04-25
|
||||||
|
#!/usr/bin/python -Es
|
||||||
|
|
||||||
|
"""
|
||||||
|
Description: json common c code
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-18
|
||||||
|
Purpose: defined the common tool function for parse json
|
||||||
|
Defined the CODE global variable to hold the c code
|
||||||
|
"""
|
||||||
|
# - Defined the CODE global variable to hold the c code
|
||||||
|
CODE = '''// Auto generated file. Do not edit!
|
||||||
|
# ifndef _JSON_COMMON_H
|
||||||
|
# define _JSON_COMMON_H
|
||||||
|
|
||||||
|
# include <stdbool.h>
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <string.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <stdint.h>
|
||||||
|
# include <yajl/yajl_tree.h>
|
||||||
|
# include <yajl/yajl_gen.h>
|
||||||
|
# include "securec.h"
|
||||||
|
|
||||||
|
# ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# undef linux
|
||||||
|
|
||||||
|
//options to report error if there is unknown key found in json
|
||||||
|
# define OPT_PARSE_STRICT 0x01
|
||||||
|
//options to generate all key and value
|
||||||
|
# define OPT_GEN_KAY_VALUE 0x02
|
||||||
|
//options to generate simplify(no indent) json string
|
||||||
|
# define OPT_GEN_SIMPLIFY 0x04
|
||||||
|
//options not to validate utf8 data
|
||||||
|
# define OPT_GEN_NO_VALIDATE_UTF8 0x08
|
||||||
|
|
||||||
|
# define GEN_SET_ERROR_AND_RETURN(stat, err) { \\
|
||||||
|
if (*(err) == NULL) {\\
|
||||||
|
if (asprintf(err, "%s: %s: %d: error generating json, errcode: %u", __FILE__, __func__, __LINE__, stat) < 0) { \\
|
||||||
|
*(err) = safe_strdup("error allocating memory"); \\
|
||||||
|
} \\
|
||||||
|
}\\
|
||||||
|
return stat; \\
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef char *parser_error;
|
||||||
|
|
||||||
|
struct parser_context {
|
||||||
|
unsigned int options;
|
||||||
|
FILE *stderr;
|
||||||
|
};
|
||||||
|
|
||||||
|
yajl_gen_status map_uint(void *ctx, long long unsigned int num);
|
||||||
|
|
||||||
|
yajl_gen_status map_int(void *ctx, long long int num);
|
||||||
|
|
||||||
|
bool json_gen_init(yajl_gen *g, const struct parser_context *ctx);
|
||||||
|
|
||||||
|
yajl_val get_val(yajl_val tree, const char *name, yajl_type type);
|
||||||
|
|
||||||
|
void *safe_malloc(size_t size);
|
||||||
|
|
||||||
|
int common_safe_double(const char *numstr, double *converted);
|
||||||
|
|
||||||
|
int common_safe_uint8(const char *numstr, uint8_t *converted);
|
||||||
|
|
||||||
|
int common_safe_uint16(const char *numstr, uint16_t *converted);
|
||||||
|
|
||||||
|
int common_safe_uint32(const char *numstr, uint32_t *converted);
|
||||||
|
|
||||||
|
int common_safe_uint64(const char *numstr, uint64_t *converted);
|
||||||
|
|
||||||
|
int common_safe_uint(const char *numstr, unsigned int *converted);
|
||||||
|
|
||||||
|
int common_safe_int8(const char *numstr, int8_t *converted);
|
||||||
|
|
||||||
|
int common_safe_int16(const char *numstr, int16_t *converted);
|
||||||
|
|
||||||
|
int common_safe_int32(const char *numstr, int32_t *converted);
|
||||||
|
|
||||||
|
int common_safe_int64(const char *numstr, int64_t *converted);
|
||||||
|
|
||||||
|
int common_safe_int(const char *numstr, int *converted);
|
||||||
|
|
||||||
|
char *safe_strdup(const char *src);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int *keys;
|
||||||
|
int *values;
|
||||||
|
size_t len;
|
||||||
|
} json_map_int_int;
|
||||||
|
|
||||||
|
void free_json_map_int_int(json_map_int_int *map);
|
||||||
|
|
||||||
|
json_map_int_int *make_json_map_int_int(yajl_val src, const struct parser_context *ctx, parser_error *err);
|
||||||
|
|
||||||
|
yajl_gen_status gen_json_map_int_int(void *ctx, const json_map_int_int *map, const struct parser_context *ptx, parser_error *err);
|
||||||
|
|
||||||
|
int append_json_map_int_int(json_map_int_int *map, int key, int val);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int *keys;
|
||||||
|
bool *values;
|
||||||
|
size_t len;
|
||||||
|
} json_map_int_bool;
|
||||||
|
|
||||||
|
void free_json_map_int_bool(json_map_int_bool *map);
|
||||||
|
|
||||||
|
json_map_int_bool *make_json_map_int_bool(yajl_val src, const struct parser_context *ctx, parser_error *err);
|
||||||
|
|
||||||
|
yajl_gen_status gen_json_map_int_bool(void *ctx, const json_map_int_bool *map, const struct parser_context *ptx, parser_error *err);
|
||||||
|
|
||||||
|
int append_json_map_int_bool(json_map_int_bool *map, int key, bool val);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int *keys;
|
||||||
|
char **values;
|
||||||
|
size_t len;
|
||||||
|
} json_map_int_string;
|
||||||
|
|
||||||
|
void free_json_map_int_string(json_map_int_string *map);
|
||||||
|
|
||||||
|
json_map_int_string *make_json_map_int_string(yajl_val src, const struct parser_context *ctx, parser_error *err);
|
||||||
|
|
||||||
|
yajl_gen_status gen_json_map_int_string(void *ctx, const json_map_int_string *map, const struct parser_context *ptx, parser_error *err);
|
||||||
|
|
||||||
|
int append_json_map_int_string(json_map_int_string *map, int key, const char *val);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char **keys;
|
||||||
|
int *values;
|
||||||
|
size_t len;
|
||||||
|
} json_map_string_int;
|
||||||
|
|
||||||
|
void free_json_map_string_int(json_map_string_int *map);
|
||||||
|
|
||||||
|
json_map_string_int *make_json_map_string_int(yajl_val src, const struct parser_context *ctx, parser_error *err);
|
||||||
|
|
||||||
|
yajl_gen_status gen_json_map_string_int(void *ctx, const json_map_string_int *map, const struct parser_context *ptx, parser_error *err);
|
||||||
|
|
||||||
|
int append_json_map_string_int(json_map_string_int *map, const char *key, int val);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char **keys;
|
||||||
|
bool *values;
|
||||||
|
size_t len;
|
||||||
|
} json_map_string_bool;
|
||||||
|
|
||||||
|
void free_json_map_string_bool(json_map_string_bool *map);
|
||||||
|
|
||||||
|
json_map_string_bool *make_json_map_string_bool(yajl_val src, const struct parser_context *ctx, parser_error *err);
|
||||||
|
|
||||||
|
yajl_gen_status gen_json_map_string_bool(void *ctx, const json_map_string_bool *map, const struct parser_context *ptx, parser_error *err);
|
||||||
|
|
||||||
|
int append_json_map_string_bool(json_map_string_bool *map, const char *key, bool val);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char **keys;
|
||||||
|
char **values;
|
||||||
|
size_t len;
|
||||||
|
} json_map_string_string;
|
||||||
|
|
||||||
|
void free_json_map_string_string(json_map_string_string *map);
|
||||||
|
|
||||||
|
json_map_string_string *make_json_map_string_string(yajl_val src, const struct parser_context *ctx, parser_error *err);
|
||||||
|
|
||||||
|
yajl_gen_status gen_json_map_string_string(void *ctx, const json_map_string_string *map, const struct parser_context *ptx, parser_error *err);
|
||||||
|
|
||||||
|
int append_json_map_string_string(json_map_string_string *map, const char *key, const char *val);
|
||||||
|
|
||||||
|
char *json_marshal_string(const char *str, size_t strlen, const struct parser_context *ctx, parser_error *err);
|
||||||
|
|
||||||
|
# ifdef __cplusplus
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# endif
|
||||||
|
'''
|
||||||
802
src/json/schema/src/generate.py
Normal file
802
src/json/schema/src/generate.py
Normal file
@ -0,0 +1,802 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Description: header class and functions
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
# - Copyright (C) Huawei Technologies., Ltd. 2018-2019. All rights reserved.
|
||||||
|
# - lcr 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 json
|
||||||
|
# - Author: tanyifeng
|
||||||
|
# - Create: 2018-04-25
|
||||||
|
#!/usr/bin/python -Es
|
||||||
|
|
||||||
|
import traceback
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import fcntl
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
|
import helpers
|
||||||
|
import headers
|
||||||
|
import sources
|
||||||
|
import common_h
|
||||||
|
import common_c
|
||||||
|
|
||||||
|
# - json suffix
|
||||||
|
JSON_SUFFIX = ".json"
|
||||||
|
|
||||||
|
'''
|
||||||
|
Description: ref suffix
|
||||||
|
Interface: ref_suffix
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
# - Description: ref suffix
|
||||||
|
REF_SUFFIX = "_json"
|
||||||
|
|
||||||
|
'''
|
||||||
|
Description: root paths
|
||||||
|
Interface: rootpaths
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
class MyRoot(object):
|
||||||
|
'''
|
||||||
|
Description: Store schema information
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
def __init__(self, root_path):
|
||||||
|
self.root_path = root_path
|
||||||
|
|
||||||
|
def get_repr(self):
|
||||||
|
'''
|
||||||
|
Description: Store schema information
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
return "{root_path:(%s)}" % (self.root_path)
|
||||||
|
|
||||||
|
def get_path(self):
|
||||||
|
'''
|
||||||
|
Description: Store schema information
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
return self.root_path
|
||||||
|
|
||||||
|
|
||||||
|
def trimJsonSuffix(name):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
if name.endswith(JSON_SUFFIX) or name.endswith(REF_SUFFIX):
|
||||||
|
name = name[:-len(JSON_SUFFIX)]
|
||||||
|
return helpers.convertToCStyle(name.replace('.', '_').replace('-', '_'))
|
||||||
|
|
||||||
|
|
||||||
|
def getPrefixPackage(filepath, rootpath):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
realpath = os.path.realpath(filepath)
|
||||||
|
|
||||||
|
if realpath.startswith(rootpath) and len(realpath) > len(rootpath):
|
||||||
|
return helpers.convertToCStyle(os.path.dirname(realpath)[(len(rootpath) + 1):])
|
||||||
|
else:
|
||||||
|
raise RuntimeError('schema path \"%s\" is not in scope of root path \"%s\"' \
|
||||||
|
% (realpath, rootpath))
|
||||||
|
|
||||||
|
|
||||||
|
def getPrefixFromFile(filepath):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
prefix_file = trimJsonSuffix(os.path.basename(filepath))
|
||||||
|
root_path = MyRoot.root_path
|
||||||
|
prefix_package = getPrefixPackage(filepath, root_path)
|
||||||
|
prefix = prefix_file if prefix_package == "" else prefix_package + "_" + prefix_file
|
||||||
|
return prefix
|
||||||
|
|
||||||
|
def schemaFromFile(filepath, srcpath):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
schemapath = helpers.FilePath(filepath)
|
||||||
|
prefix = getPrefixFromFile(schemapath.name)
|
||||||
|
header = helpers.FilePath(os.path.join(srcpath, prefix + ".h"))
|
||||||
|
source = helpers.FilePath(os.path.join(srcpath, prefix + ".c"))
|
||||||
|
schema_info = helpers.SchemaInfo(schemapath, header, source, prefix, srcpath)
|
||||||
|
return schema_info
|
||||||
|
|
||||||
|
def makeRefName(refname, reffile):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
prefix = getPrefixFromFile(reffile)
|
||||||
|
if refname == "" or prefix.endswith(refname):
|
||||||
|
return prefix
|
||||||
|
return prefix + "_" + helpers.convertToCStyle(refname)
|
||||||
|
|
||||||
|
def splitRefName(ref):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
tmp_f, tmp_r = ref.split("#/") if '#/' in ref else (ref, "")
|
||||||
|
return tmp_f, tmp_r
|
||||||
|
|
||||||
|
def merge(children):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
subchildren = []
|
||||||
|
for i in children:
|
||||||
|
for j in i.children:
|
||||||
|
subchildren.append(j)
|
||||||
|
|
||||||
|
return subchildren
|
||||||
|
|
||||||
|
# BASIC_TYPES include all basic types
|
||||||
|
BASIC_TYPES = (
|
||||||
|
"byte", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", "UID", "GID",
|
||||||
|
"bytePointer", "doublePointer", "int8Pointer", "int16Pointer", "int32Pointer", "int64Pointer",
|
||||||
|
"uint8Pointer", "uint16Pointer", "uint32Pointer", "uint64Pointer", "ArrayOfStrings",
|
||||||
|
"booleanPointer"
|
||||||
|
)
|
||||||
|
|
||||||
|
def judgeSupportedType(typ):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
return typ in ("integer", "boolean", "string", "double") or typ in BASIC_TYPES
|
||||||
|
|
||||||
|
def getRefSubref(src, subref):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
cur = src
|
||||||
|
subrefname = ""
|
||||||
|
for j in subref.split('/'):
|
||||||
|
subrefname = j
|
||||||
|
if j in BASIC_TYPES:
|
||||||
|
return src, {"type": j}, subrefname
|
||||||
|
cur = cur[j]
|
||||||
|
|
||||||
|
return src, cur, subrefname
|
||||||
|
|
||||||
|
def getRefRoot(schema_info, src, ref, curfile):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
refname = ""
|
||||||
|
tmp_f, tmp_r = splitRefName(ref)
|
||||||
|
|
||||||
|
if tmp_f == "":
|
||||||
|
cur = src
|
||||||
|
else:
|
||||||
|
realpath = os.path.realpath(os.path.join(os.path.dirname(curfile), tmp_f))
|
||||||
|
curfile = realpath
|
||||||
|
|
||||||
|
subschema = schemaFromFile(realpath, schema_info.filesdir)
|
||||||
|
if schema_info.refs is None:
|
||||||
|
schema_info.refs = {}
|
||||||
|
schema_info.refs[subschema.header.basename] = subschema
|
||||||
|
with open(realpath) as i:
|
||||||
|
cur = src = json.loads(i.read())
|
||||||
|
subcur = cur
|
||||||
|
if tmp_r != "":
|
||||||
|
src, subcur, refname = getRefSubref(src, tmp_r)
|
||||||
|
|
||||||
|
if 'type' not in subcur and '$ref' in subcur:
|
||||||
|
subf, subr = splitRefName(subcur['$ref'])
|
||||||
|
if subf == "":
|
||||||
|
src, subcur, refname = getRefSubref(src, subr)
|
||||||
|
if 'type' not in subcur:
|
||||||
|
raise RuntimeError("Not support reference of nesting more than 2 level: ", ref)
|
||||||
|
else:
|
||||||
|
return getRefRoot(schema_info, src, subcur['$ref'], curfile)
|
||||||
|
return src, subcur, curfile, makeRefName(refname, curfile)
|
||||||
|
|
||||||
|
def getTypePatternInCur(cur, schema_info, src, curfile):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
# pattern of key:
|
||||||
|
# '.{1,}' represents type 'string',
|
||||||
|
# '.{2,}' represents type 'integer'
|
||||||
|
if '.{2,}' in cur['patternProperties']:
|
||||||
|
map_key = 'Int'
|
||||||
|
else:
|
||||||
|
map_key = 'String'
|
||||||
|
for i, value in enumerate(cur['patternProperties'].values()):
|
||||||
|
# only use the first value
|
||||||
|
if i == 0:
|
||||||
|
if 'type' in value:
|
||||||
|
val = value["type"]
|
||||||
|
else:
|
||||||
|
dummy_subsrc, subcur, dummy_subcurfile, dummy_subrefname = getRefRoot(
|
||||||
|
schema_info, src, value['$ref'], curfile)
|
||||||
|
val = subcur['type']
|
||||||
|
break
|
||||||
|
|
||||||
|
mapKey = {
|
||||||
|
'object': 'Object',
|
||||||
|
'string': 'String',
|
||||||
|
'integer': 'Int',
|
||||||
|
'boolean': 'Bool'
|
||||||
|
}[val]
|
||||||
|
map_val = mapKey
|
||||||
|
|
||||||
|
typ = 'map' + map_key + map_val
|
||||||
|
return typ
|
||||||
|
|
||||||
|
class GenerateNodeInfo(object):
|
||||||
|
'''
|
||||||
|
Description: Store schema information
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
def __init__(self, schema_info, name, cur, curfile):
|
||||||
|
self.schema_info = schema_info
|
||||||
|
self.name = name
|
||||||
|
self.cur = cur
|
||||||
|
self.curfile = curfile
|
||||||
|
|
||||||
|
def get_repr(self):
|
||||||
|
'''
|
||||||
|
Description: Store schema information
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
return "{schema_info:(%s) name:(%s) cur:(%s) curfile:(%s)}" \
|
||||||
|
% (self.schema_info, self.name, self.cur, self.curfile)
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
'''
|
||||||
|
Description: Store schema information
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def generateAllofArrayTypNode(node_info, src, typ, refname):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
schema_info = node_info.schema_info
|
||||||
|
name = node_info.name
|
||||||
|
cur = node_info.cur
|
||||||
|
curfile = node_info.curfile
|
||||||
|
subtyp = None
|
||||||
|
subtypobj = None
|
||||||
|
required = None
|
||||||
|
children = merge(parseList(schema_info, name, src, cur["items"]['allOf'], curfile))
|
||||||
|
subtyp = children[0].typ
|
||||||
|
subtypobj = children
|
||||||
|
return helpers.Unite(name,
|
||||||
|
typ,
|
||||||
|
children,
|
||||||
|
subtyp=subtyp,
|
||||||
|
subtypobj=subtypobj,
|
||||||
|
subtypname=refname,
|
||||||
|
required=required), src
|
||||||
|
|
||||||
|
def generateAnyofArrayTypNode(node_info, src, typ, refname):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
schema_info = node_info.schema_info
|
||||||
|
name = node_info.name
|
||||||
|
cur = node_info.cur
|
||||||
|
curfile = node_info.curfile
|
||||||
|
subtyp = None
|
||||||
|
subtypobj = None
|
||||||
|
required = None
|
||||||
|
anychildren = parseList(schema_info, name, src, cur["items"]['anyOf'], curfile)
|
||||||
|
subtyp = anychildren[0].typ
|
||||||
|
children = anychildren[0].children
|
||||||
|
subtypobj = children
|
||||||
|
refname = anychildren[0].subtypname
|
||||||
|
return helpers.Unite(name,
|
||||||
|
typ,
|
||||||
|
children,
|
||||||
|
subtyp=subtyp,
|
||||||
|
subtypobj=subtypobj,
|
||||||
|
subtypname=refname,
|
||||||
|
required=required), src
|
||||||
|
|
||||||
|
def generateRefArrayTypNode(node_info, src, typ, refname):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
schema_info = node_info.schema_info
|
||||||
|
name = node_info.name
|
||||||
|
cur = node_info.cur
|
||||||
|
curfile = node_info.curfile
|
||||||
|
|
||||||
|
item_type, src = resolveType(schema_info, name, src, cur["items"], curfile)
|
||||||
|
ref_file, subref = splitRefName(cur['items']['$ref'])
|
||||||
|
if ref_file == "":
|
||||||
|
src, dummy_subcur, subrefname = getRefSubref(src, subref)
|
||||||
|
refname = makeRefName(subrefname, curfile)
|
||||||
|
else:
|
||||||
|
refname = item_type.subtypname
|
||||||
|
return helpers.Unite(name,
|
||||||
|
typ,
|
||||||
|
None,
|
||||||
|
subtyp=item_type.typ,
|
||||||
|
subtypobj=item_type.children,
|
||||||
|
subtypname=refname,
|
||||||
|
required=item_type.required), src
|
||||||
|
|
||||||
|
def generateTypeArrayTypNode(node_info, src, typ, refname):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
schema_info = node_info.schema_info
|
||||||
|
name = node_info.name
|
||||||
|
cur = node_info.cur
|
||||||
|
curfile = node_info.curfile
|
||||||
|
|
||||||
|
item_type, src = resolveType(schema_info, name, src, cur["items"], curfile)
|
||||||
|
return helpers.Unite(name,
|
||||||
|
typ,
|
||||||
|
None,
|
||||||
|
subtyp=item_type.typ,
|
||||||
|
subtypobj=item_type.children,
|
||||||
|
subtypname=refname,
|
||||||
|
required=item_type.required), src
|
||||||
|
|
||||||
|
|
||||||
|
def generateArrayTypNode(node_info, src, typ, refname):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
cur = node_info.cur
|
||||||
|
|
||||||
|
if 'allOf' in cur["items"]:
|
||||||
|
return generateAllofArrayTypNode(node_info, src, typ, refname)
|
||||||
|
elif 'anyOf' in cur["items"]:
|
||||||
|
return generateAnyofArrayTypNode(node_info, src, typ, refname)
|
||||||
|
elif '$ref' in cur["items"]:
|
||||||
|
return generateRefArrayTypNode(node_info, src, typ, refname)
|
||||||
|
elif 'type' in cur["items"]:
|
||||||
|
return generateTypeArrayTypNode(node_info, src, typ, refname)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def generateObjTypNode(node_info, src, typ, refname):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
schema_info = node_info.schema_info
|
||||||
|
name = node_info.name
|
||||||
|
cur = node_info.cur
|
||||||
|
curfile = node_info.curfile
|
||||||
|
children = None
|
||||||
|
subtyp = None
|
||||||
|
subtypobj = None
|
||||||
|
required = None
|
||||||
|
|
||||||
|
if 'allOf' in cur:
|
||||||
|
children = merge(parseList(schema_info, name, src, cur['allOf'], curfile))
|
||||||
|
elif 'anyOf' in cur:
|
||||||
|
children = parseList(schema_info, name, src, cur['anyOf'], curfile)
|
||||||
|
elif 'patternProperties' in cur:
|
||||||
|
children = parseProperties(schema_info, name, src, cur, curfile)
|
||||||
|
children[0].name = children[0].name.replace('_{1,}', 'element').replace('_{2,}', \
|
||||||
|
'element')
|
||||||
|
children[0].fixname = "values"
|
||||||
|
if helpers.validBasicMapName(children[0].typ):
|
||||||
|
children[0].name = helpers.makeBasicMapName(children[0].typ)
|
||||||
|
else:
|
||||||
|
children = parseProperties(schema_info, name, src, cur, curfile) \
|
||||||
|
if 'properties' in cur else None
|
||||||
|
if 'required' in cur:
|
||||||
|
required = cur['required']
|
||||||
|
return helpers.Unite(name,\
|
||||||
|
typ,\
|
||||||
|
children,\
|
||||||
|
subtyp=subtyp,\
|
||||||
|
subtypobj=subtypobj,\
|
||||||
|
subtypname=refname,\
|
||||||
|
required=required), src
|
||||||
|
|
||||||
|
def getTypNotOneof(schema_info, src, cur, curfile):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
if 'patternProperties' in cur:
|
||||||
|
typ = getTypePatternInCur(cur, schema_info, src, curfile)
|
||||||
|
elif "type" in cur:
|
||||||
|
typ = cur["type"]
|
||||||
|
else:
|
||||||
|
typ = "object"
|
||||||
|
|
||||||
|
return typ
|
||||||
|
|
||||||
|
|
||||||
|
def resolveType(schema_info, name, src, cur, curfile):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
children = None
|
||||||
|
subtyp = None
|
||||||
|
subtypobj = None
|
||||||
|
required = None
|
||||||
|
refname = None
|
||||||
|
|
||||||
|
if '$ref' in cur:
|
||||||
|
src, cur, curfile, refname = getRefRoot(schema_info, src, cur['$ref'], curfile)
|
||||||
|
|
||||||
|
if "oneOf" in cur:
|
||||||
|
cur = cur['oneOf'][0]
|
||||||
|
if '$ref' in cur:
|
||||||
|
return resolveType(schema_info, name, src, cur, curfile)
|
||||||
|
else:
|
||||||
|
typ = cur['type']
|
||||||
|
else:
|
||||||
|
typ = getTypNotOneof(schema_info, src, cur, curfile)
|
||||||
|
|
||||||
|
node_info = GenerateNodeInfo(schema_info, name, cur, curfile)
|
||||||
|
|
||||||
|
if helpers.validBasicMapName(typ):
|
||||||
|
pass
|
||||||
|
elif typ == 'array':
|
||||||
|
return generateArrayTypNode(node_info, src, typ, refname)
|
||||||
|
elif typ == 'object' or typ == 'mapStringObject':
|
||||||
|
return generateObjTypNode(node_info, src, typ, refname)
|
||||||
|
elif typ == 'ArrayOfStrings':
|
||||||
|
typ = 'array'
|
||||||
|
subtyp = 'string'
|
||||||
|
children = subtypobj = None
|
||||||
|
else:
|
||||||
|
if not judgeSupportedType(typ):
|
||||||
|
raise RuntimeError("Invalid schema type: %s" % typ)
|
||||||
|
children = None
|
||||||
|
|
||||||
|
return helpers.Unite(name,
|
||||||
|
typ,
|
||||||
|
children,
|
||||||
|
subtyp=subtyp,
|
||||||
|
subtypobj=subtypobj,
|
||||||
|
subtypname=refname,
|
||||||
|
required=required), src
|
||||||
|
|
||||||
|
|
||||||
|
def parseList(schema_info, name, schema, objs, curfile):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
obj = []
|
||||||
|
index = 0
|
||||||
|
for i in objs:
|
||||||
|
generated_name = helpers.CombinationName( \
|
||||||
|
i['$ref'].split("/")[-1]) if '$ref' in i else helpers.CombinationName(name.name + str(index))
|
||||||
|
node, _ = resolveType(schema_info, generated_name, schema, i, curfile)
|
||||||
|
if node:
|
||||||
|
obj.append(node)
|
||||||
|
index += 1
|
||||||
|
if not obj:
|
||||||
|
obj = None
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
def parseDictionary(schema_info, name, schema, objs, curfile):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
obj = []
|
||||||
|
for i in objs:
|
||||||
|
node, _ = resolveType(schema_info, name.append(i), schema, objs[i], curfile)
|
||||||
|
if node:
|
||||||
|
obj.append(node)
|
||||||
|
if not obj:
|
||||||
|
obj = None
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
def parseProperties(schema_info, name, schema, props, curfile):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
if 'definitions' in props:
|
||||||
|
return parseDictionary(schema_info, name, schema, props['definitions'], curfile)
|
||||||
|
if 'patternProperties' in props:
|
||||||
|
return parseDictionary(schema_info, name, schema, props['patternProperties'], curfile)
|
||||||
|
return parseDictionary(schema_info, name, schema, props['properties'], curfile)
|
||||||
|
|
||||||
|
def handleTypeNotInSchema(schema_info, schema, prefix):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
required = None
|
||||||
|
if 'definitions' in schema:
|
||||||
|
return helpers.Unite( \
|
||||||
|
helpers.CombinationName("definitions"), 'definitions', \
|
||||||
|
parseProperties(schema_info, helpers.CombinationName(""), schema, schema, \
|
||||||
|
schema_info.name.name), None, None, None, None)
|
||||||
|
else:
|
||||||
|
if len(schema) > 1:
|
||||||
|
print('More than one element found in schema')
|
||||||
|
return None
|
||||||
|
value_nodes = []
|
||||||
|
for value in schema:
|
||||||
|
if 'required' in schema[value]:
|
||||||
|
required = schema[value]['required']
|
||||||
|
childrens = parseProperties(schema_info, helpers.CombinationName(""), schema[value], \
|
||||||
|
schema[value], schema_info.name.name)
|
||||||
|
value_node = helpers.Unite(helpers.CombinationName(prefix), 'object', childrens, None, None, \
|
||||||
|
None, required)
|
||||||
|
value_nodes.append(value_node)
|
||||||
|
return helpers.Unite(helpers.CombinationName("definitions"), 'definitions', value_nodes, None, None, \
|
||||||
|
None, None)
|
||||||
|
|
||||||
|
def parseSchema(schema_info, schema, prefix):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
required = None
|
||||||
|
if 'type' not in schema:
|
||||||
|
return handleTypeNotInSchema(schema_info, schema, prefix)
|
||||||
|
|
||||||
|
if 'type' not in schema:
|
||||||
|
print("No 'type' defined in schema")
|
||||||
|
return prefix, None
|
||||||
|
|
||||||
|
if 'object' in schema['type']:
|
||||||
|
if 'required' in schema:
|
||||||
|
required = schema['required']
|
||||||
|
return helpers.Unite(
|
||||||
|
helpers.CombinationName(prefix), 'object',
|
||||||
|
parseProperties(schema_info, helpers.CombinationName(""), schema, schema, schema_info.name.name), \
|
||||||
|
None, None, None, required)
|
||||||
|
elif 'array' in schema['type']:
|
||||||
|
item_type, _ = resolveType(schema_info, helpers.CombinationName(""), schema['items'], \
|
||||||
|
schema['items'], schema_info.name.name)
|
||||||
|
return helpers.Unite(helpers.CombinationName(prefix), 'array', None, item_type.typ, \
|
||||||
|
item_type.children, None, item_type.required)
|
||||||
|
else:
|
||||||
|
print("Not supported type '%s'") % schema['type']
|
||||||
|
return prefix, None
|
||||||
|
|
||||||
|
|
||||||
|
def expand(tree, structs, visited):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
if tree.children is not None:
|
||||||
|
for i in tree.children:
|
||||||
|
if tree.subtypname:
|
||||||
|
i.subtypname = "from_ref"
|
||||||
|
expand(i, structs, visited=visited)
|
||||||
|
if tree.subtypobj is not None:
|
||||||
|
for i in tree.subtypobj:
|
||||||
|
expand(i, structs, visited=visited)
|
||||||
|
|
||||||
|
if tree.typ == 'array' and helpers.validBasicMapName(tree.subtyp):
|
||||||
|
name = helpers.CombinationName(tree.name + "_element")
|
||||||
|
node = helpers.Unite(name, tree.subtyp, None)
|
||||||
|
expand(node, structs, visited)
|
||||||
|
|
||||||
|
id_ = "%s:%s" % (tree.name, tree.typ)
|
||||||
|
if id_ not in visited.keys():
|
||||||
|
structs.append(tree)
|
||||||
|
visited[id_] = tree
|
||||||
|
|
||||||
|
return structs
|
||||||
|
|
||||||
|
|
||||||
|
def reflection(schema_info, gen_ref):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
with open(schema_info.header.name, "w") as \
|
||||||
|
header_file, open(schema_info.source.name, "w") as source_file:
|
||||||
|
fcntl.flock(header_file, fcntl.LOCK_EX)
|
||||||
|
fcntl.flock(source_file, fcntl.LOCK_EX)
|
||||||
|
|
||||||
|
with open(schema_info.name.name) as schema_file:
|
||||||
|
schema_json = json.loads(schema_file.read(), object_pairs_hook=OrderedDict)
|
||||||
|
try:
|
||||||
|
tree = parseSchema(schema_info, schema_json, schema_info.prefix)
|
||||||
|
if tree is None:
|
||||||
|
print("Failed parse schema")
|
||||||
|
sys.exit(1)
|
||||||
|
structs = expand(tree, [], {})
|
||||||
|
headers.headerReflection(structs, schema_info, header_file)
|
||||||
|
sources.sourceReflection(structs, schema_info, source_file, tree.typ)
|
||||||
|
except RuntimeError:
|
||||||
|
traceback.print_exc()
|
||||||
|
print("Failed to parse schema file: %s") % schema_info.name.name
|
||||||
|
sys.exit(1)
|
||||||
|
finally:
|
||||||
|
pass
|
||||||
|
|
||||||
|
fcntl.flock(source_file, fcntl.LOCK_UN)
|
||||||
|
fcntl.flock(header_file, fcntl.LOCK_UN)
|
||||||
|
|
||||||
|
if gen_ref is True:
|
||||||
|
if schema_info.refs:
|
||||||
|
for reffile in schema_info.refs.values():
|
||||||
|
reflection(reffile, True)
|
||||||
|
|
||||||
|
|
||||||
|
def generateCommonFiles(out):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
print(out, " gao\n")
|
||||||
|
with open(os.path.join(out, 'json_common.h'), "w") as \
|
||||||
|
header_file, open(os.path.join(out, 'json_common.c'), "w") as source_file:
|
||||||
|
fcntl.flock(header_file, fcntl.LOCK_EX)
|
||||||
|
fcntl.flock(source_file, fcntl.LOCK_EX)
|
||||||
|
|
||||||
|
header_file.write(common_h.CODE)
|
||||||
|
source_file.write(common_c.CODE)
|
||||||
|
|
||||||
|
fcntl.flock(source_file, fcntl.LOCK_UN)
|
||||||
|
fcntl.flock(header_file, fcntl.LOCK_UN)
|
||||||
|
|
||||||
|
def handlerSingleFile(args, srcpath, gen_ref, schemapath):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
if not os.path.exists(schemapath.name) or not os.path.exists(srcpath.name):
|
||||||
|
print('Path %s is not exist') % schemapath.name
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if os.path.isdir(schemapath.name):
|
||||||
|
if args.recursive is True:
|
||||||
|
# recursively parse schema
|
||||||
|
for dirpath, dummy_dirnames, files in os.walk(schemapath.name):
|
||||||
|
for target_file in files:
|
||||||
|
if target_file.endswith(JSON_SUFFIX):
|
||||||
|
schema_info = schemaFromFile(os.path.join(dirpath, target_file), \
|
||||||
|
srcpath.name)
|
||||||
|
reflection(schema_info, gen_ref)
|
||||||
|
else:
|
||||||
|
# only parse files in current direcotory
|
||||||
|
for target_file in os.listdir(schemapath.name):
|
||||||
|
fullpath = os.path.join(schemapath.name, target_file)
|
||||||
|
if fullpath.endswith(JSON_SUFFIX) and os.path.isfile(fullpath):
|
||||||
|
schema_info = schemaFromFile(fullpath, srcpath.name)
|
||||||
|
reflection(schema_info, gen_ref)
|
||||||
|
else:
|
||||||
|
if schemapath.name.endswith(JSON_SUFFIX):
|
||||||
|
schema_info = schemaFromFile(schemapath.name, srcpath.name)
|
||||||
|
reflection(schema_info, gen_ref)
|
||||||
|
else:
|
||||||
|
print('File %s is not ends with .json') % schemapath.name
|
||||||
|
|
||||||
|
|
||||||
|
def handlerFiles(args, srcpath):
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
for path in args.path:
|
||||||
|
gen_ref = args.gen_ref
|
||||||
|
schemapath = helpers.FilePath(path)
|
||||||
|
handlerSingleFile(args, srcpath, gen_ref, schemapath)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""
|
||||||
|
Description: generate c language for parse json map string object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
"""
|
||||||
|
parser = argparse.ArgumentParser(prog='generate.py',
|
||||||
|
usage='%(prog)s [options] path [path ...]',
|
||||||
|
description='Generate C header and source from json-schema')
|
||||||
|
parser.add_argument('path', nargs='+', help='File or directory to parse')
|
||||||
|
parser.add_argument(
|
||||||
|
'--root',
|
||||||
|
required=True,
|
||||||
|
help=
|
||||||
|
'All schema files must be placed in root directory or sub-directory of root," \
|
||||||
|
" and naming of C variables is started from this path'
|
||||||
|
)
|
||||||
|
parser.add_argument('--gen-common',
|
||||||
|
action='store_true',
|
||||||
|
help='Generate json_common.c and json_common.h')
|
||||||
|
parser.add_argument('--gen-ref',
|
||||||
|
action='store_true',
|
||||||
|
help='Generate reference file defined in schema with key \"$ref\"')
|
||||||
|
parser.add_argument('-r',
|
||||||
|
'--recursive',
|
||||||
|
action='store_true',
|
||||||
|
help='Recursively generate all schema files in directory')
|
||||||
|
parser.add_argument(
|
||||||
|
'--out',
|
||||||
|
help='Specify a directory to save C header and source(default is current directory)')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if not args.root:
|
||||||
|
print('Missing root path, see help')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
root_path = os.path.realpath(args.root)
|
||||||
|
if not os.path.exists(root_path):
|
||||||
|
print('Root %s is not exist') % args.root
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
MyRoot.root_path = root_path
|
||||||
|
|
||||||
|
if args.out:
|
||||||
|
srcpath = helpers.FilePath(args.out)
|
||||||
|
else:
|
||||||
|
srcpath = helpers.FilePath(os.getcwd())
|
||||||
|
if not os.path.exists(srcpath.name):
|
||||||
|
os.makedirs(srcpath.name)
|
||||||
|
|
||||||
|
if args.gen_common:
|
||||||
|
generateCommonFiles(srcpath.name)
|
||||||
|
handlerFiles(args, srcpath)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
197
src/json/schema/src/headers.py
Normal file
197
src/json/schema/src/headers.py
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Description: header class and functions
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
# - Copyright (C) Huawei Technologies., Ltd. 2018-2019. All rights reserved.
|
||||||
|
# - lcr 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 json
|
||||||
|
# - Author: tanyifeng
|
||||||
|
# - Create: 2018-04-25
|
||||||
|
#!/usr/bin/python -Es
|
||||||
|
import helpers
|
||||||
|
|
||||||
|
def appendHeaderArray(obj, header, prefix):
|
||||||
|
'''
|
||||||
|
Description: Write c header file of array
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
if not obj.subtypobj or obj.subtypname:
|
||||||
|
return
|
||||||
|
header.write("typedef struct {\n")
|
||||||
|
for i in obj.subtypobj:
|
||||||
|
if i.typ == 'array':
|
||||||
|
c_typ = helpers.getPrefixPointer(i.name, i.subtyp, prefix) or \
|
||||||
|
helpers.getMapCTypes(i.subtyp)
|
||||||
|
if i.subtypobj is not None:
|
||||||
|
c_typ = helpers.getNameSubstr(i.name, prefix)
|
||||||
|
|
||||||
|
if not helpers.judgeComplex(i.subtyp):
|
||||||
|
header.write(" %s%s*%s;\n" % (c_typ, " " if '*' not in c_typ else "", \
|
||||||
|
i.fixname))
|
||||||
|
else:
|
||||||
|
header.write(" %s **%s;\n" % (c_typ, i.fixname))
|
||||||
|
header.write(" size_t %s;\n\n" % (i.fixname + "_len"))
|
||||||
|
else:
|
||||||
|
c_typ = helpers.getPrefixPointer(i.name, i.typ, prefix) or \
|
||||||
|
helpers.getMapCTypes(i.typ)
|
||||||
|
header.write(" %s%s%s;\n" % (c_typ, " " if '*' not in c_typ else "", i.fixname))
|
||||||
|
typename = helpers.getNameSubstr(obj.name, prefix)
|
||||||
|
header.write("}\n%s;\n\n" % typename)
|
||||||
|
header.write("void free_%s(%s *ptr);\n\n" % (typename, typename))
|
||||||
|
header.write("%s *make_%s(yajl_val tree, const struct parser_context *ctx, parser_error *err);"\
|
||||||
|
"\n\n" % (typename, typename))
|
||||||
|
|
||||||
|
def appendHeaderMapStrObj(obj, header, prefix):
|
||||||
|
'''
|
||||||
|
Description: Write c header file of mapStringObject
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
child = obj.children[0]
|
||||||
|
header.write("typedef struct {\n")
|
||||||
|
header.write(" char **keys;\n")
|
||||||
|
if helpers.validBasicMapName(child.typ):
|
||||||
|
c_typ = helpers.getPrefixPointer("", child.typ, "")
|
||||||
|
elif child.subtypname:
|
||||||
|
c_typ = child.subtypname
|
||||||
|
else:
|
||||||
|
c_typ = helpers.getPrefixPointer(child.name, child.typ, prefix)
|
||||||
|
header.write(" %s%s*%s;\n" % (c_typ, " " if '*' not in c_typ else "", child.fixname))
|
||||||
|
header.write(" size_t len;\n")
|
||||||
|
|
||||||
|
def appendHeaderChildArray(child, header, prefix):
|
||||||
|
'''
|
||||||
|
Description: Write c header file of array of child
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
if helpers.getMapCTypes(child.subtyp) != "":
|
||||||
|
c_typ = helpers.getMapCTypes(child.subtyp)
|
||||||
|
elif helpers.validBasicMapName(child.subtyp):
|
||||||
|
c_typ = '%s *' % helpers.makeBasicMapName(child.subtyp)
|
||||||
|
elif child.subtypname is not None:
|
||||||
|
c_typ = child.subtypname
|
||||||
|
elif child.subtypobj is not None:
|
||||||
|
c_typ = helpers.getNameSubstr(child.name, prefix)
|
||||||
|
else:
|
||||||
|
c_typ = helpers.getPrefixPointer(child.name, child.subtyp, prefix)
|
||||||
|
|
||||||
|
if helpers.validBasicMapName(child.subtyp):
|
||||||
|
header.write(" %s **%s;\n" % (helpers.makeBasicMapName(child.subtyp), child.fixname))
|
||||||
|
elif not helpers.judgeComplex(child.subtyp):
|
||||||
|
header.write(" %s%s*%s;\n" % (c_typ, " " if '*' not in c_typ else "", child.fixname))
|
||||||
|
else:
|
||||||
|
header.write(" %s%s**%s;\n" % (c_typ, " " if '*' not in c_typ else "", child.fixname))
|
||||||
|
header.write(" size_t %s;\n\n" % (child.fixname + "_len"))
|
||||||
|
|
||||||
|
def appendHeaderChildOthers(child, header, prefix):
|
||||||
|
'''
|
||||||
|
Description: Write c header file of others of child
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
if helpers.getMapCTypes(child.typ) != "":
|
||||||
|
c_typ = helpers.getMapCTypes(child.typ)
|
||||||
|
elif helpers.validBasicMapName(child.typ):
|
||||||
|
c_typ = '%s *' % helpers.makeBasicMapName(child.typ)
|
||||||
|
elif child.subtypname:
|
||||||
|
c_typ = helpers.getPrefixPointer(child.subtypname, child.typ, "")
|
||||||
|
else:
|
||||||
|
c_typ = helpers.getPrefixPointer(child.name, child.typ, prefix)
|
||||||
|
header.write(" %s%s%s;\n\n" % (c_typ, " " if '*' not in c_typ else "", child.fixname))
|
||||||
|
|
||||||
|
def appendTypeCHeader(obj, header, prefix):
|
||||||
|
'''
|
||||||
|
Description: Write c header file
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
if not helpers.judgeComplex(obj.typ):
|
||||||
|
return
|
||||||
|
|
||||||
|
if obj.typ == 'array':
|
||||||
|
appendHeaderArray(obj, header, prefix)
|
||||||
|
return
|
||||||
|
|
||||||
|
if obj.typ == 'mapStringObject':
|
||||||
|
if obj.subtypname is not None:
|
||||||
|
return
|
||||||
|
appendHeaderMapStrObj(obj, header, prefix)
|
||||||
|
elif obj.typ == 'object':
|
||||||
|
if obj.subtypname is not None:
|
||||||
|
return
|
||||||
|
header.write("typedef struct {\n")
|
||||||
|
if obj.children is None:
|
||||||
|
header.write(" char unuseful;//unuseful definition to avoid empty struct\n")
|
||||||
|
for i in obj.children or [ ]:
|
||||||
|
if i.typ == 'array':
|
||||||
|
appendHeaderChildArray(i, header, prefix)
|
||||||
|
else:
|
||||||
|
appendHeaderChildOthers(i, header, prefix)
|
||||||
|
|
||||||
|
typename = helpers.getPrefixName(obj.name, prefix)
|
||||||
|
header.write("}\n%s;\n\n" % typename)
|
||||||
|
header.write("void free_%s(%s *ptr);\n\n" % (typename, typename))
|
||||||
|
header.write("%s *make_%s(yajl_val tree, const struct parser_context *ctx, parser_error *err)"\
|
||||||
|
";\n\n" % (typename, typename))
|
||||||
|
header.write("yajl_gen_status gen_%s(yajl_gen g, const %s *ptr, const struct parser_context "\
|
||||||
|
"*ctx, parser_error *err);\n\n" % (typename, typename))
|
||||||
|
|
||||||
|
def headerReflection(structs, schema_info, header):
|
||||||
|
'''
|
||||||
|
Description: Reflection header files
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
prefix = schema_info.prefix
|
||||||
|
header.write("// Generated from %s. Do not edit!\n" % (schema_info.name.basename))
|
||||||
|
header.write("#ifndef %s_SCHEMA_H\n" % prefix.upper())
|
||||||
|
header.write("#define %s_SCHEMA_H\n\n" % prefix.upper())
|
||||||
|
header.write("#include <sys/types.h>\n")
|
||||||
|
header.write("#include <stdint.h>\n")
|
||||||
|
header.write("#include \"json_common.h\"\n")
|
||||||
|
if schema_info.refs:
|
||||||
|
for ref in schema_info.refs.keys():
|
||||||
|
header.write("#include \"%s\"\n" % (ref))
|
||||||
|
header.write("\n#ifdef __cplusplus\n")
|
||||||
|
header.write("extern \"C\" {\n")
|
||||||
|
header.write("#endif\n\n")
|
||||||
|
|
||||||
|
for i in structs:
|
||||||
|
appendTypeCHeader(i, header, prefix)
|
||||||
|
length = len(structs)
|
||||||
|
toptype = structs[length - 1].typ if length != 0 else ""
|
||||||
|
if toptype == 'object':
|
||||||
|
header.write("%s *%s_parse_file(const char *filename, const struct parser_context *ctx, "\
|
||||||
|
"parser_error *err);\n\n" % (prefix, prefix))
|
||||||
|
header.write("%s *%s_parse_file_stream(FILE *stream, const struct parser_context *ctx, "\
|
||||||
|
"parser_error *err);\n\n" % (prefix, prefix))
|
||||||
|
header.write("%s *%s_parse_data(const char *jsondata, const struct parser_context *ctx, "\
|
||||||
|
"parser_error *err);\n\n" % (prefix, prefix))
|
||||||
|
header.write("char *%s_generate_json(const %s *ptr, const struct parser_context *ctx, "\
|
||||||
|
"parser_error *err);\n\n" % (prefix, prefix))
|
||||||
|
elif toptype == 'array':
|
||||||
|
header.write("void free_%s(%s_element **ptr, size_t len);\n\n" % (prefix, prefix))
|
||||||
|
header.write("%s_element **%s_parse_file(const char *filename, const struct "\
|
||||||
|
"parser_context *ctx, parser_error *err, size_t *len);\n\n" % (prefix, prefix))
|
||||||
|
header.write("%s_element **%s_parse_file_stream(FILE *stream, const struct "\
|
||||||
|
"parser_context *ctx, parser_error *err, size_t *len);\n\n" % (prefix, prefix))
|
||||||
|
header.write("%s_element **%s_parse_data(const char *jsondata, const struct "\
|
||||||
|
"parser_context *ctx, parser_error *err, size_t *len);\n\n" % (prefix, prefix))
|
||||||
|
header.write("char *%s_generate_json(const %s_element **ptr, size_t len, "\
|
||||||
|
"const struct parser_context *ctx, parser_error *err);\n\n" % (prefix, prefix))
|
||||||
|
|
||||||
|
header.write("#ifdef __cplusplus\n")
|
||||||
|
header.write("}\n")
|
||||||
|
header.write("#endif\n\n")
|
||||||
|
header.write("#endif\n\n")
|
||||||
313
src/json/schema/src/helpers.py
Normal file
313
src/json/schema/src/helpers.py
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Description: helper class and functions
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
# - Copyright (C) Huawei Technologies., Ltd. 2018-2019. All rights reserved.
|
||||||
|
# - lcr 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 json
|
||||||
|
# - Author: tanyifeng
|
||||||
|
# - Create: 2018-04-25
|
||||||
|
#!/usr/bin/python -Es
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def appendSeparator(subStr):
|
||||||
|
'''
|
||||||
|
Description: append only '_' at last position of subStr
|
||||||
|
Interface: None
|
||||||
|
History: 2019-09-20
|
||||||
|
'''
|
||||||
|
if subStr and subStr[-1] != '_':
|
||||||
|
subStr.append('_')
|
||||||
|
|
||||||
|
def convertToCStyle(name):
|
||||||
|
'''
|
||||||
|
Description: convert name to linux c format
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
if name is None or name == "":
|
||||||
|
return ""
|
||||||
|
name = name.replace('.', '_').replace('-', '_').replace('/', '_')
|
||||||
|
subStr = []
|
||||||
|
preindex = 0
|
||||||
|
index = 0
|
||||||
|
for index, char in enumerate(name):
|
||||||
|
if char == '_':
|
||||||
|
appendSeparator(subStr)
|
||||||
|
subStr.append(name[preindex:index].lower())
|
||||||
|
preindex = index + 1
|
||||||
|
if not char.isupper() and name[preindex].isupper() and \
|
||||||
|
name[preindex + 1].isupper():
|
||||||
|
appendSeparator(subStr)
|
||||||
|
subStr.append(name[preindex:index - 1].lower())
|
||||||
|
preindex = index - 1
|
||||||
|
continue
|
||||||
|
if char.isupper() and index > 0 and name[index - 1].islower():
|
||||||
|
appendSeparator(subStr)
|
||||||
|
subStr.append(name[preindex:index].lower())
|
||||||
|
preindex = index
|
||||||
|
|
||||||
|
if preindex <= index and index >= 0 and name[index] != '_' and \
|
||||||
|
preindex != 0:
|
||||||
|
appendSeparator(subStr)
|
||||||
|
subStr.append(name[preindex:index + 1].lower())
|
||||||
|
result = ''.join(subStr)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def getMapCTypes(typ):
|
||||||
|
'''
|
||||||
|
Description: Get map c types
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
map_c_types = {
|
||||||
|
'byte': 'uint8_t',
|
||||||
|
'string': 'char *',
|
||||||
|
'integer': 'int',
|
||||||
|
'boolean': 'bool',
|
||||||
|
'double': 'double',
|
||||||
|
'int8': 'int8_t',
|
||||||
|
"int16": 'int16_t',
|
||||||
|
"int32": "int32_t",
|
||||||
|
"int64": "int64_t",
|
||||||
|
'uint8': 'uint8_t',
|
||||||
|
"uint16": 'uint16_t',
|
||||||
|
"uint32": "uint32_t",
|
||||||
|
"uint64": "uint64_t",
|
||||||
|
"UID": "uid_t",
|
||||||
|
"GID": "gid_t",
|
||||||
|
"booleanPointer": "bool *",
|
||||||
|
'bytePointer': 'uint8_t *',
|
||||||
|
'integerPointer': 'int *',
|
||||||
|
'doublePointer': 'double *',
|
||||||
|
'int8Pointer': 'int8_t *',
|
||||||
|
"int16Pointer": 'int16_t *',
|
||||||
|
"int32Pointer": "int32_t *",
|
||||||
|
"int64Pointer": "int64_t *",
|
||||||
|
'uint8Pointer': 'uint8_t *',
|
||||||
|
"uint16Pointer": 'uint16_t *',
|
||||||
|
"uint32Pointer": "uint32_t *",
|
||||||
|
"uint64Pointer": "uint64_t *",
|
||||||
|
}
|
||||||
|
if typ in map_c_types:
|
||||||
|
return map_c_types[typ]
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def validBasicMapName(typ):
|
||||||
|
'''
|
||||||
|
Description: Valid basic map name
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
return typ != 'mapStringObject' and hasattr(typ, 'startswith') and \
|
||||||
|
typ.startswith('map')
|
||||||
|
|
||||||
|
def makeBasicMapName(mapname):
|
||||||
|
'''
|
||||||
|
Description: Make basic map name
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
basic_map_types = ('string', 'int', 'bool')
|
||||||
|
parts = convertToCStyle(mapname).split('_')
|
||||||
|
if len(parts) != 3 or parts[0] != 'map' or \
|
||||||
|
(parts[1] not in basic_map_types) or \
|
||||||
|
(parts[2] not in basic_map_types):
|
||||||
|
print('Invalid map name: %s') % mapname
|
||||||
|
sys.exit(1)
|
||||||
|
return "json_map_%s_%s" % (parts[1], parts[2])
|
||||||
|
|
||||||
|
|
||||||
|
def getNameSubstr(name, prefix):
|
||||||
|
'''
|
||||||
|
Description: Make array name
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
return "%s_element" % prefix if name is None or name == "" or prefix == name \
|
||||||
|
else "%s_%s_element" % (prefix, name)
|
||||||
|
|
||||||
|
def getPrefixName(name, prefix):
|
||||||
|
'''
|
||||||
|
Description: Make name
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
if name is None or name == "" or prefix.endswith(name):
|
||||||
|
return "%s" % prefix
|
||||||
|
if prefix is None or prefix == "" or prefix == name or name.endswith(prefix):
|
||||||
|
return "%s" % name
|
||||||
|
return "%s_%s" % (prefix, name)
|
||||||
|
|
||||||
|
def getPrefixPointer(name, typ, prefix):
|
||||||
|
'''
|
||||||
|
Description: Make pointer name
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
if typ != 'object' and typ != 'mapStringObject' and \
|
||||||
|
not validBasicMapName(typ):
|
||||||
|
return ""
|
||||||
|
return '%s *' % makeBasicMapName(typ) if validBasicMapName(typ) \
|
||||||
|
else "%s *" % getPrefixName(name, prefix)
|
||||||
|
|
||||||
|
def judgeComplex(typ):
|
||||||
|
'''
|
||||||
|
Description: Check compound object
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
return typ in ('object', 'array', 'mapStringObject')
|
||||||
|
|
||||||
|
def judgeDataType(typ):
|
||||||
|
'''
|
||||||
|
Description: Check numeric type
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
if (typ.startswith("int") or typ.startswith("uint")) and \
|
||||||
|
"Pointer" not in typ:
|
||||||
|
return True
|
||||||
|
return typ in ("integer", "UID", "GID", "double")
|
||||||
|
|
||||||
|
def judgeDataPointerType(typ):
|
||||||
|
'''
|
||||||
|
Description: Check numeric pointer type
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
if (typ.startswith("int") or typ.startswith("uint")) and "Pointer" in typ:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def obtainDataPointerType(typ):
|
||||||
|
'''
|
||||||
|
Description: Get numeric pointer type
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
index = typ.find("Pointer")
|
||||||
|
return typ[0:index] if index != -1 else ""
|
||||||
|
|
||||||
|
def obtainPointer(name, typ, prefix):
|
||||||
|
'''
|
||||||
|
Description: Obtain pointer string
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
ptr = getPrefixPointer(name, typ, prefix)
|
||||||
|
if ptr != "":
|
||||||
|
return ptr
|
||||||
|
|
||||||
|
return "char *" if typ == "string" else \
|
||||||
|
("%s *" % typ if typ == "ArrayOfStrings" else "")
|
||||||
|
|
||||||
|
class CombinationName(object):
|
||||||
|
'''
|
||||||
|
Description: Store CombinationName information
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self, name, leaf=None):
|
||||||
|
self.name = name
|
||||||
|
self.leaf = leaf
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def append(self, leaf):
|
||||||
|
'''
|
||||||
|
Description: append name
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
prefix_name = self.name + '_' if self.name != "" else ""
|
||||||
|
return CombinationName(prefix_name + leaf, leaf)
|
||||||
|
|
||||||
|
|
||||||
|
class Unite(object):
|
||||||
|
'''
|
||||||
|
Description: Store Unite information
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
def __init__(self, name, typ, children, subtyp=None, subtypobj=None, subtypname=None, \
|
||||||
|
required=None):
|
||||||
|
self.typ = typ
|
||||||
|
self.children = children
|
||||||
|
self.subtyp = subtyp
|
||||||
|
self.subtypobj = subtypobj
|
||||||
|
self.subtypname = subtypname
|
||||||
|
self.required = required
|
||||||
|
self.name = convertToCStyle(name.name.replace('.', '_'))
|
||||||
|
self.origname = name.leaf or name.name
|
||||||
|
self.fixname = convertToCStyle(self.origname.replace('.', '_'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
if self.subtyp is not None:
|
||||||
|
return "name:(%s) type:(%s -> %s)" \
|
||||||
|
% (self.name, self.typ, self.subtyp)
|
||||||
|
return "name:(%s) type:(%s)" % (self.name, self.typ)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.__repr__(self)
|
||||||
|
|
||||||
|
|
||||||
|
class FilePath(object):
|
||||||
|
'''
|
||||||
|
Description: Store filepath information
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = os.path.realpath(name)
|
||||||
|
self.dirname = os.path.dirname(self.name)
|
||||||
|
self.basename = os.path.basename(self.name)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "{name:(%s) dirname:(%s) basename:(%s)}" \
|
||||||
|
% (self.name, self.dirname, self.basename)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.__repr__(self)
|
||||||
|
|
||||||
|
|
||||||
|
class SchemaInfo(object):
|
||||||
|
'''
|
||||||
|
Description: Store schema information
|
||||||
|
Interface: None
|
||||||
|
History: 2019-06-17
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self, name, header, source, prefix, filesdir, refs=None):
|
||||||
|
self.name = name
|
||||||
|
self.fileprefix = convertToCStyle( \
|
||||||
|
name.basename.replace('.', '_').replace('-', '_'))
|
||||||
|
self.header = header
|
||||||
|
self.source = source
|
||||||
|
self.prefix = prefix
|
||||||
|
self.refs = refs
|
||||||
|
self.filesdir = os.path.realpath(filesdir)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "{name:(%s) header:(%s) source:(%s) prefix:(%s)}" \
|
||||||
|
% (self.name, self.header, self.source, self.prefix)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.__repr__(self)
|
||||||
151
src/json/schema/src/read_file.c
Normal file
151
src/json/schema/src/read_file.c
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: tanyifeng
|
||||||
|
* Create: 2018-11-1
|
||||||
|
* Description: provide file read functions
|
||||||
|
********************************************************************************/
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include "securec.h"
|
||||||
|
#include "read_file.h"
|
||||||
|
|
||||||
|
#ifndef O_CLOEXEC
|
||||||
|
#define O_CLOEXEC 02000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define JSON_MAX_SIZE (10LL * 1024LL * 1024LL)
|
||||||
|
#define FILE_MODE 0640
|
||||||
|
|
||||||
|
static int do_check_fread_args(const FILE *stream, const size_t *length)
|
||||||
|
{
|
||||||
|
if (stream == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (length == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *fread_file(FILE *stream, size_t *length)
|
||||||
|
{
|
||||||
|
char *buf = NULL;
|
||||||
|
char *tmpbuf = NULL;
|
||||||
|
size_t off = 0;
|
||||||
|
|
||||||
|
if (do_check_fread_args(stream, length) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
size_t ret, newsize, sizejudge;
|
||||||
|
int pret;
|
||||||
|
errno_t rc = EOK;
|
||||||
|
sizejudge = (JSON_MAX_SIZE - BUFSIZ) - 1;
|
||||||
|
if (sizejudge < off) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
newsize = off + BUFSIZ + 1;
|
||||||
|
|
||||||
|
tmpbuf = (char *)calloc(1, newsize);
|
||||||
|
if (tmpbuf == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf != NULL) {
|
||||||
|
pret = memcpy_s(tmpbuf, newsize, buf, off);
|
||||||
|
if (pret) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = memset_s(buf, off, 0, off);
|
||||||
|
if (rc != EOK) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = tmpbuf;
|
||||||
|
tmpbuf = NULL;
|
||||||
|
|
||||||
|
ret = fread(buf + off, 1, BUFSIZ, stream);
|
||||||
|
if (ret == 0 && ferror(stream)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (ret < BUFSIZ || feof(stream)) {
|
||||||
|
*length = off + ret + 1;
|
||||||
|
buf[*length - 1] = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
off += BUFSIZ;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
free(buf);
|
||||||
|
free(tmpbuf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_check_args(const char *path, const size_t *length)
|
||||||
|
{
|
||||||
|
if (path == NULL || length == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (strlen(path) > PATH_MAX) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *read_file(const char *path, size_t *length)
|
||||||
|
{
|
||||||
|
char *buf = NULL;
|
||||||
|
char rpath[PATH_MAX + 1] = { 0 };
|
||||||
|
int fd = -1;
|
||||||
|
int tmperrno = -1;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
|
||||||
|
if (do_check_args(path, length) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (realpath(path, rpath) == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(rpath, O_RDONLY | O_CLOEXEC, FILE_MODE);
|
||||||
|
if (fd < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp = fdopen(fd, "r");
|
||||||
|
tmperrno = errno;
|
||||||
|
if (fp == NULL) {
|
||||||
|
(void)close(fd);
|
||||||
|
errno = tmperrno;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = fread_file(fp, length);
|
||||||
|
(void)fclose(fp);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
25
src/json/schema/src/read_file.h
Normal file
25
src/json/schema/src/read_file.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: tanyifeng
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container read file definition
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef __JSON_READ_FILE_H_
|
||||||
|
#define __JSON_READ_FILE_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
char *fread_file(FILE *stream, size_t *length);
|
||||||
|
|
||||||
|
char *read_file(const char *path, size_t *length);
|
||||||
|
|
||||||
|
#endif
|
||||||
1013
src/json/schema/src/sources.py
Normal file
1013
src/json/schema/src/sources.py
Normal file
File diff suppressed because it is too large
Load Diff
138
src/lcr_list.h
Normal file
138
src/lcr_list.h
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container lcr list definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __LCR_LIST_H
|
||||||
|
#define __LCR_LIST_H
|
||||||
|
|
||||||
|
|
||||||
|
struct lcr_list {
|
||||||
|
void *elem;
|
||||||
|
struct lcr_list *next;
|
||||||
|
struct lcr_list *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Iterate through an lcr list.*/
|
||||||
|
#define lcr_list_for_each(__iterator, __list) \
|
||||||
|
for ((__iterator) = (__list)->next; \
|
||||||
|
(__iterator) != (__list); \
|
||||||
|
(__iterator) = (__iterator)->next)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate safely through an lcr list
|
||||||
|
*/
|
||||||
|
#define lcr_list_for_each_safe(__iterator, __list, __next) \
|
||||||
|
for ((__iterator) = (__list)->next, (__next) = (__iterator)->next; \
|
||||||
|
(__iterator) != (__list); \
|
||||||
|
(__iterator) = (__next), (__next) = (__next)->next)
|
||||||
|
|
||||||
|
/* Initialize list. */
|
||||||
|
static inline void lcr_list_init(struct lcr_list *list)
|
||||||
|
{
|
||||||
|
list->elem = NULL;
|
||||||
|
list->next = list->prev = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add an element to a list. See lcr_list_add() and lcr_list_add_tail() for an
|
||||||
|
* idiom. */
|
||||||
|
static inline void lcr_list_add_elem(struct lcr_list *list, void *elem)
|
||||||
|
{
|
||||||
|
list->elem = elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve first element of list. */
|
||||||
|
static inline void *lcr_list_first_elem(struct lcr_list *list)
|
||||||
|
{
|
||||||
|
return list->next->elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve last element of list. */
|
||||||
|
static inline void *lcr_list_last_elem(struct lcr_list *list)
|
||||||
|
{
|
||||||
|
return list->prev->elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine if list is empty. */
|
||||||
|
static inline int lcr_list_empty(const struct lcr_list *list)
|
||||||
|
{
|
||||||
|
return list == list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Workhorse to be called from lcr_list_add() and lcr_list_add_tail(). */
|
||||||
|
static inline void __lcr_list_add(struct lcr_list *new, struct lcr_list *prev, struct lcr_list *next)
|
||||||
|
{
|
||||||
|
next->prev = new;
|
||||||
|
new->next = next;
|
||||||
|
new->prev = prev;
|
||||||
|
prev->next = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Idiom to add an element to the beginning of an lcr list
|
||||||
|
*/
|
||||||
|
static inline void lcr_list_add(struct lcr_list *head, struct lcr_list *list)
|
||||||
|
{
|
||||||
|
__lcr_list_add(list, head, head->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Idiom to add an element to the end of an lcr list
|
||||||
|
*/
|
||||||
|
static inline void lcr_list_add_tail(
|
||||||
|
struct lcr_list *head, struct lcr_list *list)
|
||||||
|
{
|
||||||
|
__lcr_list_add(list, head->prev, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Idiom to merge two lcr list */
|
||||||
|
static inline void lcr_list_merge(
|
||||||
|
struct lcr_list *list1, struct lcr_list *list2)
|
||||||
|
{
|
||||||
|
struct lcr_list *list1_tail, *list2_tail;
|
||||||
|
list1_tail = list1->prev;
|
||||||
|
list2_tail = list2->prev;
|
||||||
|
// to merge two list, we need:
|
||||||
|
// 1. update list1's prev (next is not needed) to list2's tail
|
||||||
|
list1->prev = list2_tail;
|
||||||
|
// 2. update list1's tail's next to list2
|
||||||
|
list1_tail->next = list2;
|
||||||
|
// 3. update list2's prev to list1's tail
|
||||||
|
list2->prev = list1_tail;
|
||||||
|
// 4. update list2's tail's next to list1
|
||||||
|
list2_tail->next = list1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Idiom to free an lcr list */
|
||||||
|
static inline void lcr_list_del(struct lcr_list *list)
|
||||||
|
{
|
||||||
|
struct lcr_list *next, *prev;
|
||||||
|
|
||||||
|
next = list->next;
|
||||||
|
prev = list->prev;
|
||||||
|
next->prev = prev;
|
||||||
|
prev->next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return length of the list. */
|
||||||
|
static inline size_t lcr_list_len(struct lcr_list *list)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
struct lcr_list *iter;
|
||||||
|
lcr_list_for_each(iter, list) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
2077
src/lcrcontainer.c
Normal file
2077
src/lcrcontainer.c
Normal file
File diff suppressed because it is too large
Load Diff
313
src/lcrcontainer.h
Normal file
313
src/lcrcontainer.h
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container definition
|
||||||
|
******************************************************************************/
|
||||||
|
/*
|
||||||
|
* liblcrapi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LCR_CONTAINER_H
|
||||||
|
#define __LCR_CONTAINER_H
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <lxc/lxccontainer.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* define console log config */
|
||||||
|
|
||||||
|
struct lcr_console_config {
|
||||||
|
char *log_path;
|
||||||
|
unsigned int log_rotate;
|
||||||
|
char *log_file_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Store lcr container info
|
||||||
|
*/
|
||||||
|
struct lcr_container_info {
|
||||||
|
/* Name of container.*/
|
||||||
|
char *name;
|
||||||
|
/* State of container.*/
|
||||||
|
char *state;
|
||||||
|
/* Interface of container.*/
|
||||||
|
char *interface;
|
||||||
|
char *ipv4;
|
||||||
|
char *ipv6;
|
||||||
|
pid_t init;
|
||||||
|
double ram;
|
||||||
|
double swap;
|
||||||
|
bool running;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct blkio_stats {
|
||||||
|
uint64_t read;
|
||||||
|
uint64_t write;
|
||||||
|
uint64_t total;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Store lcr container state
|
||||||
|
*/
|
||||||
|
struct lcr_container_state {
|
||||||
|
/* Name of container */
|
||||||
|
char *name;
|
||||||
|
/* State of container */
|
||||||
|
char *state;
|
||||||
|
/* The process ID of the init container*/
|
||||||
|
pid_t init;
|
||||||
|
/* Current pids */
|
||||||
|
uint64_t pids_current;
|
||||||
|
/* CPU usage*/
|
||||||
|
uint64_t cpu_use_nanos;
|
||||||
|
uint64_t cpu_use_user;
|
||||||
|
uint64_t cpu_use_sys;
|
||||||
|
/* BlkIO usage*/
|
||||||
|
struct blkio_stats io_service_bytes;
|
||||||
|
struct blkio_stats io_serviced;
|
||||||
|
/* Memory usage */
|
||||||
|
uint64_t mem_used;
|
||||||
|
uint64_t mem_limit;
|
||||||
|
/* Kernel Memory usage */
|
||||||
|
uint64_t kmem_used;
|
||||||
|
uint64_t kmem_limit;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
lcr_msg_state,
|
||||||
|
lcr_msg_priority,
|
||||||
|
lcr_msg_exit_code,
|
||||||
|
} lcr_msg_type_t;
|
||||||
|
|
||||||
|
struct lcr_msg {
|
||||||
|
lcr_msg_type_t type;
|
||||||
|
char name[NAME_MAX + 1];
|
||||||
|
int value;
|
||||||
|
int pid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lcr_cgroup_resources {
|
||||||
|
uint64_t blkio_weight;
|
||||||
|
uint64_t cpu_shares;
|
||||||
|
uint64_t cpu_period;
|
||||||
|
uint64_t cpu_quota;
|
||||||
|
char *cpuset_cpus;
|
||||||
|
char *cpuset_mems;
|
||||||
|
uint64_t memory_limit;
|
||||||
|
uint64_t memory_swap;
|
||||||
|
uint64_t memory_reservation;
|
||||||
|
uint64_t kernel_memory_limit;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get one container info for a given lcrpath.
|
||||||
|
* return struct of container info, or NULL on error.
|
||||||
|
*/
|
||||||
|
struct lcr_container_info *lcr_container_info_get(const char *name, const char *lcrpath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free lcr_container_info returned lcr_container_info_get
|
||||||
|
*/
|
||||||
|
void lcr_container_info_free(struct lcr_container_info *info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a complete list of all containers for a given lcrpath.
|
||||||
|
* return Number of containers, or -1 on error.
|
||||||
|
*/
|
||||||
|
int lcr_list_all_containers(const char *lcrpath, struct lcr_container_info **info_arr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free lcr_container_info array returned by lcr_list_{active,all}_containers
|
||||||
|
*/
|
||||||
|
void lcr_containers_info_free(struct lcr_container_info **info_arr, size_t size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a container
|
||||||
|
* param name : container name
|
||||||
|
* param lcrpath: container path
|
||||||
|
* param rootfs : the path of rootfs used for the container
|
||||||
|
* param dist : the distribution for generate specification
|
||||||
|
* NOTE: if the dist is `none`, it will not create default spec
|
||||||
|
* param oci_config_data : json string of oci config data
|
||||||
|
*/
|
||||||
|
bool lcr_create(const char *name, const char *lcrpath, const char *rootfs,
|
||||||
|
const char *dist, const void *oci_config_data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start a container
|
||||||
|
* param name : container name, required.
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
* param logpath : log file path.
|
||||||
|
* param loglevel : log level.
|
||||||
|
* param pidfile : container pidfile path, set to NULL if you don't need.
|
||||||
|
* param daemonize : daemonize the container.
|
||||||
|
* console_fifos[] : path of the console fifos,[0]:input, [1]:output.used internal by lcrd
|
||||||
|
* console_logpath :path of console log file,
|
||||||
|
* set to NULL if want to use the default configure(base on the config file)
|
||||||
|
set to PATH(for example "/home/XX/XX.log"), LXC will save the console to this file
|
||||||
|
* share_ns : array of container's name or pid which want to share namespace with them
|
||||||
|
* start_timeout : seconds for waiting on a container to start before it is killed
|
||||||
|
* container_pidfile : container's pidfile
|
||||||
|
* param argv : array of arguments to pass to init.
|
||||||
|
* uid : user to run container
|
||||||
|
* gid : user in which group
|
||||||
|
* additional_gids : Add additional groups to join
|
||||||
|
*/
|
||||||
|
struct lcr_start_request {
|
||||||
|
const char *name;
|
||||||
|
const char *lcrpath;
|
||||||
|
|
||||||
|
const char *logpath;
|
||||||
|
const char *loglevel;
|
||||||
|
|
||||||
|
bool daemonize;
|
||||||
|
bool tty;
|
||||||
|
bool open_stdin;
|
||||||
|
const char *pidfile;
|
||||||
|
const char **console_fifos;
|
||||||
|
const char *console_logpath;
|
||||||
|
uint32_t start_timeout;
|
||||||
|
const char *container_pidfile;
|
||||||
|
const char *exit_fifo;
|
||||||
|
|
||||||
|
uid_t uid;
|
||||||
|
gid_t gid;
|
||||||
|
gid_t *additional_gids;
|
||||||
|
size_t additional_gids_len;
|
||||||
|
|
||||||
|
const char **share_ns;
|
||||||
|
};
|
||||||
|
bool lcr_start(const struct lcr_start_request *request);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stop a container
|
||||||
|
* param name : container name, required.
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
* param signal : signal to send to the container.
|
||||||
|
*/
|
||||||
|
bool lcr_kill(const char *name, const char *lcrpath, uint32_t signal);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete a container
|
||||||
|
* param name : container name, required.
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
* param force : force to delete container
|
||||||
|
*/
|
||||||
|
bool lcr_delete(const char *name, const char *lcrpath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute process inside a container
|
||||||
|
* param name : container name, required.
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
* param argc : the size of the argv array
|
||||||
|
* param argv : array of arguments to be execute inside container
|
||||||
|
* param pid : ID of process running inside container
|
||||||
|
*/
|
||||||
|
bool lcr_exec(const char *name, const char *lcrpath, int argc, char * const * argv, pid_t *pid);
|
||||||
|
|
||||||
|
|
||||||
|
bool lcr_clean(const char *name, const char *lcrpath, const char *logpath, const char *loglevel, pid_t pid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get state of the container
|
||||||
|
* param name : container name, required.
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
* param lcs : returned contaiener state
|
||||||
|
*/
|
||||||
|
bool lcr_state(const char *name, const char *lcrpath, struct lcr_container_state *lcs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pause a container
|
||||||
|
* param name : container name, required.
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
*/
|
||||||
|
bool lcr_pause(const char *name, const char *lcrpath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resume a container
|
||||||
|
* param name : container name, required.
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
*/
|
||||||
|
bool lcr_resume(const char *name, const char *lcrpath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free lcr_container_state returned by lcr_state
|
||||||
|
*/
|
||||||
|
void lcr_container_state_free(struct lcr_container_state *lcs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* console function
|
||||||
|
* param name : name of container
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
* param in_fifo : fifo names of input FIFO
|
||||||
|
* param out_fifo : fifo names of output FIFO
|
||||||
|
* Returns false if the console FIFOs add failed, true if success
|
||||||
|
*/
|
||||||
|
bool lcr_console(const char *name, const char *lcrpath, const char *in_fifo, const char *out_fifo,
|
||||||
|
const char *err_fifo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get container console configs
|
||||||
|
* param name : name of container
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
* param config : use to store container console configs, cannot be NULL
|
||||||
|
*/
|
||||||
|
bool lcr_get_console_config(const char *name, const char *lcrpath, struct lcr_console_config *config);
|
||||||
|
|
||||||
|
void lcr_free_console_config(struct lcr_console_config *config);
|
||||||
|
|
||||||
|
int lcr_log_init(const char *name, const char *file, const char *priority,
|
||||||
|
const char *prefix, int quiet, const char *lcrpath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute process inside a container
|
||||||
|
* param name : container name, required.
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
* param stdinfd : stdinfd
|
||||||
|
* param stdoutfd : stdoutfd
|
||||||
|
* param stderrfd : stderrfd
|
||||||
|
* param escape : prefix for escape command, for example if escape equals 1 means the escape
|
||||||
|
* prefix is <CTRL+a>, you can type <CTRL+a q> to exit the console.
|
||||||
|
* -1 means never exit console by hand.
|
||||||
|
* param argc : the size of the argv array
|
||||||
|
* param argv : array of arguments to be execute inside container(terminated with "NULL")
|
||||||
|
* param env : array of environment variables to be set inside container(terminated with "NULL")
|
||||||
|
* param timeout : Timeout in seconds for attach container
|
||||||
|
* param pid : ID of process running inside container
|
||||||
|
* param exit_code : exit_code of process running inside container
|
||||||
|
*/
|
||||||
|
bool lcr_attach(const char *name, const char *lcrpath, const char *logpath, const char *loglevel,
|
||||||
|
const char *console_fifos[], char * const argv[], char * const env[],
|
||||||
|
int64_t timeout, pid_t *pid, int *exit_code);
|
||||||
|
|
||||||
|
bool lcr_update(const char *name, const char *lcrpath, const struct lcr_cgroup_resources *cr);
|
||||||
|
|
||||||
|
const char *lcr_get_errmsg();
|
||||||
|
|
||||||
|
void lcr_free_errmsg();
|
||||||
|
|
||||||
|
bool lcr_get_container_pids(const char *name, const char *lcrpath, pid_t **pids, size_t *pids_len);
|
||||||
|
|
||||||
|
bool translate_spec(const struct lxc_container *c, const char *oci_json_data, const char *container_rootfs);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LCR_CONTAINER_H */
|
||||||
1092
src/lcrcontainer_execute.c
Normal file
1092
src/lcrcontainer_execute.c
Normal file
File diff suppressed because it is too large
Load Diff
41
src/lcrcontainer_execute.h
Normal file
41
src/lcrcontainer_execute.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __LCR_CONTAINER_EXECUTE_H
|
||||||
|
#define __LCR_CONTAINER_EXECUTE_H
|
||||||
|
|
||||||
|
#include "lcrcontainer.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool do_update(struct lxc_container *c, const char *name, const char *lcrpath, const struct lcr_cgroup_resources *cr);
|
||||||
|
|
||||||
|
void do_lcr_state(struct lxc_container *c, struct lcr_container_state *lcs);
|
||||||
|
|
||||||
|
bool do_attach(const char *name, const char *path, const char *logpath, const char *loglevel,
|
||||||
|
const char *console_fifos[], const char * const argv[], const char * const env[], int64_t timeout,
|
||||||
|
pid_t *exec_pid, int *exit_code);
|
||||||
|
|
||||||
|
void execute_lxc_start(const char *name, const char *path, const char *logpath, const char *loglevel,
|
||||||
|
bool daemonize, bool tty, bool open_stdin, const char *pidfile,
|
||||||
|
const char *console_fifos[], const char *console_logpath, const char *share_ns[],
|
||||||
|
uint32_t start_timeout, const char *container_pidfile, const char *exit_fifo);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LCR_CONTAINER_EXECUTE_H */
|
||||||
1097
src/lcrcontainer_extend.c
Normal file
1097
src/lcrcontainer_extend.c
Normal file
File diff suppressed because it is too large
Load Diff
99
src/lcrcontainer_extend.h
Normal file
99
src/lcrcontainer_extend.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container definition
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __LCR_CONTAINER_EXTEND_H
|
||||||
|
#define __LCR_CONTAINER_EXTEND_H
|
||||||
|
|
||||||
|
#include <lxc/lxccontainer.h>
|
||||||
|
|
||||||
|
#include "oci_runtime_spec.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* defined in `lcr_list.h` */
|
||||||
|
struct lcr_list;
|
||||||
|
|
||||||
|
#define SAFE_MALLOC(P, size, ret) \
|
||||||
|
do { \
|
||||||
|
(P) = util_common_calloc_s((size)); \
|
||||||
|
if ((P) == NULL) { \
|
||||||
|
ERROR("Out of memory"); \
|
||||||
|
(ret) = false; \
|
||||||
|
} \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a complete list of active containers for a given lcrpath.
|
||||||
|
* return Number of containers, or -1 on error.
|
||||||
|
*/
|
||||||
|
int lcr_list_active_containers(const char *lcrpath, struct lcr_container_info **info_arr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete a container
|
||||||
|
* param name : container name, required.
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
* param force : force to delete container
|
||||||
|
*/
|
||||||
|
bool lcr_delete_with_force(const char *name, const char *lcrpath, bool force);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free lcr_conf
|
||||||
|
*/
|
||||||
|
void lcr_free_config(struct lcr_list *lcr_conf);
|
||||||
|
|
||||||
|
bool container_parse(const char *oci_filename, const char *oci_json_data, oci_runtime_spec **container);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate oci specification to lcr configuration.
|
||||||
|
* You should pass oci_filename or oci_spec to this function.
|
||||||
|
* param oci_filename : oci spec filename, in json format
|
||||||
|
* param oci_json_data : json string of oci config data
|
||||||
|
* param new_container : return newest oci_runtime_spec struct
|
||||||
|
* param seccomp : return seccomp parsed from oci spec
|
||||||
|
* return: a linked list
|
||||||
|
*/
|
||||||
|
struct lcr_list *lcr_oci2lcr(const struct lxc_container *c, const char *container_rootfs,
|
||||||
|
oci_runtime_spec *new_container,
|
||||||
|
char **seccomp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate lcr_config_info according to distribution.
|
||||||
|
* param distribution : system distribution, now support: ubuntu
|
||||||
|
* param seccomp_conf [out] : return seccomp configuration if needed.
|
||||||
|
* return: a linked list
|
||||||
|
*/
|
||||||
|
struct lcr_list *lcr_dist2spec(const char *distribution, char **seccomp_conf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a new specification file
|
||||||
|
* param name : container name, required.
|
||||||
|
* param lcrpath : container path, set to NULL if you want use default lcrpath.
|
||||||
|
* param lcr_conf : generate specification according to lcr_conf list
|
||||||
|
* param seccomp_conf : seccomp_conf will be wrote into seccomp file, set it to NULL if you don't need
|
||||||
|
*/
|
||||||
|
bool lcr_save_spec(const char *name, const char *lcrpath, const struct lcr_list *lcr_conf, const char *seccomp_conf);
|
||||||
|
|
||||||
|
int lcr_containers_info_get(const char *lcrpath, struct lcr_container_info **info, size_t *size, char **containers,
|
||||||
|
int num);
|
||||||
|
|
||||||
|
char *lcr_get_bundle(const char *lcrpath, const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LCR_CONTAINER_EXTEND_H */
|
||||||
373
src/log.c
Normal file
373
src/log.c
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container log functions
|
||||||
|
******************************************************************************/
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "securec.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
const char * const g_engine_log_prio_name[] = {
|
||||||
|
"FATAL", "ALERT", "CRIT", "ERROR", "WARN",
|
||||||
|
"NOTICE", "INFO", "DEBUG", "TRACE"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_MSG_LENGTH 4096
|
||||||
|
#define MAX_LOG_PREFIX_LENGTH 15
|
||||||
|
|
||||||
|
static __thread char *g_engine_log_prefix = NULL;
|
||||||
|
|
||||||
|
static char *g_engine_log_vmname = NULL;
|
||||||
|
static bool g_engine_log_quiet = false;
|
||||||
|
static int g_engine_log_level = ENGINE_LOG_DEBUG;
|
||||||
|
static int g_engine_log_driver = LOG_DRIVER_STDOUT;
|
||||||
|
int g_engine_log_fd = -1;
|
||||||
|
|
||||||
|
/* engine set log prefix */
|
||||||
|
void engine_set_log_prefix(const char *prefix)
|
||||||
|
{
|
||||||
|
if (prefix == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(g_engine_log_prefix);
|
||||||
|
|
||||||
|
g_engine_log_prefix = util_strdup_s(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* engine free log prefix */
|
||||||
|
void engine_free_log_prefix()
|
||||||
|
{
|
||||||
|
free(g_engine_log_prefix);
|
||||||
|
|
||||||
|
g_engine_log_prefix = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t write_nointr(int fd, const void *buf, size_t count);
|
||||||
|
|
||||||
|
void log_append_logfile(const struct engine_log_object_metadata *meta, const char *timestamp, const char *msg);
|
||||||
|
void log_append_stderr(const struct engine_log_object_metadata *meta, const char *timestamp, const char *msg);
|
||||||
|
|
||||||
|
/* engine change str logdriver to enum */
|
||||||
|
int engine_change_str_logdriver_to_enum(const char *driver)
|
||||||
|
{
|
||||||
|
if (driver == NULL) {
|
||||||
|
return LOG_DRIVER_NOSET;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(driver, "stdout")) {
|
||||||
|
return LOG_DRIVER_STDOUT;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(driver, "fifo")) {
|
||||||
|
return LOG_DRIVER_FIFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOG_FIFO_SIZE (1024 * 1024)
|
||||||
|
|
||||||
|
/* open fifo */
|
||||||
|
int open_fifo(const char *fifo_path)
|
||||||
|
{
|
||||||
|
int nret;
|
||||||
|
int fifo_fd = -1;
|
||||||
|
|
||||||
|
nret = mknod(fifo_path, S_IFIFO | S_IRUSR | S_IWUSR, (dev_t)0);
|
||||||
|
if (nret && errno != EEXIST) {
|
||||||
|
printf("Mknod failed: %s\n", strerror(errno));
|
||||||
|
return nret;
|
||||||
|
}
|
||||||
|
|
||||||
|
fifo_fd = util_open(fifo_path, O_RDWR | O_NONBLOCK, 0);
|
||||||
|
if (fifo_fd == -1) {
|
||||||
|
fprintf(stderr, "Open fifo %s failed: %s\n", fifo_path, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcntl(fifo_fd, F_SETPIPE_SZ, LOG_FIFO_SIZE) == -1) {
|
||||||
|
fprintf(stderr, "Set fifo buffer size failed: %s", strerror(errno));
|
||||||
|
close(fifo_fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fifo_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* engine close log file */
|
||||||
|
void engine_close_log_file()
|
||||||
|
{
|
||||||
|
if (g_engine_log_fd != -1) {
|
||||||
|
close(g_engine_log_fd);
|
||||||
|
g_engine_log_fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init log driver */
|
||||||
|
static int init_log_driver(const struct engine_log_config *log)
|
||||||
|
{
|
||||||
|
int i, driver;
|
||||||
|
|
||||||
|
for (i = ENGINE_LOG_FATAL; i < ENGINE_LOG_MAX; i++) {
|
||||||
|
if (!strcasecmp(g_engine_log_prio_name[i], log->priority)) {
|
||||||
|
g_engine_log_level = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == ENGINE_LOG_MAX) {
|
||||||
|
fprintf(stderr, "Unable to parse logging level:%s\n", log->priority);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
driver = engine_change_str_logdriver_to_enum(log->driver);
|
||||||
|
if (driver < 0) {
|
||||||
|
fprintf(stderr, "Invalid log driver: %s\n", log->driver);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
g_engine_log_driver = driver;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* log enable */
|
||||||
|
int log_enable(const struct engine_log_config *log)
|
||||||
|
{
|
||||||
|
int nret = 0;
|
||||||
|
char *full_path = NULL;
|
||||||
|
|
||||||
|
if ((log->name == NULL) || (log->priority == NULL)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_engine_log_fd != -1) {
|
||||||
|
fprintf(stderr, "engine log already initialized\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (init_log_driver(log)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(g_engine_log_vmname);
|
||||||
|
|
||||||
|
g_engine_log_vmname = util_strdup_s(log->name);
|
||||||
|
|
||||||
|
g_engine_log_quiet = log->quiet;
|
||||||
|
|
||||||
|
if ((log->file == NULL) || strcmp(log->file, "none") == 0) {
|
||||||
|
if (g_engine_log_driver == LOG_DRIVER_FIFO) {
|
||||||
|
fprintf(stderr, "Must set log file for driver %s\n", log->driver);
|
||||||
|
nret = -1;
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
full_path = util_strdup_s(log->file);
|
||||||
|
if (full_path == NULL) {
|
||||||
|
fprintf(stderr, "Out of memory\n");
|
||||||
|
nret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (util_build_dir(full_path)) {
|
||||||
|
fprintf(stderr, "failed to create dir for log file\n");
|
||||||
|
nret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
g_engine_log_fd = open_fifo(full_path);
|
||||||
|
|
||||||
|
if (g_engine_log_fd == -1) {
|
||||||
|
nret = -1;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
if (nret) {
|
||||||
|
if (g_engine_log_driver == LOG_DRIVER_FIFO) {
|
||||||
|
g_engine_log_driver = LOG_DRIVER_NOSET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(full_path);
|
||||||
|
|
||||||
|
return nret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *parse_timespec_to_human()
|
||||||
|
{
|
||||||
|
struct timespec timestamp;
|
||||||
|
struct tm ptm = { 0 };
|
||||||
|
char date_time[ENGINE_LOG_TIME_SIZE] = { 0 };
|
||||||
|
int nret;
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_REALTIME, ×tamp) == -1) {
|
||||||
|
fprintf(stderr, "Failed to get real time\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localtime_r(&(timestamp.tv_sec), &ptm) == NULL) {
|
||||||
|
SYSERROR("Transfer timespec failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nret = sprintf_s(date_time, ENGINE_LOG_TIME_SIZE, "%04d%02d%02d%02d%02d%02d.%03ld",
|
||||||
|
ptm.tm_year + 1900, ptm.tm_mon + 1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, ptm.tm_sec,
|
||||||
|
timestamp.tv_nsec / 1000000);
|
||||||
|
|
||||||
|
if (nret < 0) {
|
||||||
|
COMMAND_ERROR("Sprintf failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return util_strdup_s(date_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* engine log append */
|
||||||
|
int engine_log_append(const struct engine_log_object_metadata *meta, const char *format, ...)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
va_list args;
|
||||||
|
char msg[MAX_MSG_LENGTH] = { 0 };
|
||||||
|
char *date_time = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
rc = vsprintf_s(msg, MAX_MSG_LENGTH, format, args);
|
||||||
|
va_end(args);
|
||||||
|
if (rc < 0 || rc >= MAX_MSG_LENGTH) {
|
||||||
|
rc = sprintf_s(msg, MAX_MSG_LENGTH, "%s", "!!LONG LONG A LOG!!");
|
||||||
|
if (rc < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
date_time = parse_timespec_to_human();
|
||||||
|
if (date_time == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (g_engine_log_driver) {
|
||||||
|
case LOG_DRIVER_STDOUT:
|
||||||
|
if (g_engine_log_quiet) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
log_append_stderr(meta, date_time, msg);
|
||||||
|
break;
|
||||||
|
case LOG_DRIVER_FIFO:
|
||||||
|
if (g_engine_log_fd == -1) {
|
||||||
|
fprintf(stderr, "Do not set log file\n");
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
log_append_logfile(meta, date_time, msg);
|
||||||
|
break;
|
||||||
|
case LOG_DRIVER_NOSET:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Invalid log driver\n");
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(date_time);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* log append logfile */
|
||||||
|
void log_append_logfile(const struct engine_log_object_metadata *meta, const char *timestamp, const char *msg)
|
||||||
|
{
|
||||||
|
char log_buffer[ENGINE_LOG_BUFFER_SIZE] = { 0 };
|
||||||
|
int log_fd = -1;
|
||||||
|
int nret;
|
||||||
|
size_t size;
|
||||||
|
char *tmp_prefix = NULL;
|
||||||
|
|
||||||
|
if (meta->level > g_engine_log_level) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log_fd = g_engine_log_fd;
|
||||||
|
if (log_fd == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_prefix = g_engine_log_prefix ? g_engine_log_prefix : g_engine_log_vmname;
|
||||||
|
if (tmp_prefix != NULL && strlen(tmp_prefix) > MAX_LOG_PREFIX_LENGTH) {
|
||||||
|
tmp_prefix = tmp_prefix + (strlen(tmp_prefix) - MAX_LOG_PREFIX_LENGTH);
|
||||||
|
}
|
||||||
|
nret = sprintf_s(log_buffer, sizeof(log_buffer), "%15s %s %-8s %s - %s:%s:%d - %s", tmp_prefix ? tmp_prefix : "",
|
||||||
|
timestamp, g_engine_log_prio_name[meta->level],
|
||||||
|
g_engine_log_vmname ? g_engine_log_vmname : "engine", meta->file, meta->func,
|
||||||
|
meta->line, msg);
|
||||||
|
|
||||||
|
if (nret < 0) {
|
||||||
|
nret = sprintf_s(log_buffer, sizeof(log_buffer), "%15s %s %-8s %s - %s:%s:%d - %s",
|
||||||
|
tmp_prefix ? tmp_prefix : "", timestamp, g_engine_log_prio_name[meta->level],
|
||||||
|
g_engine_log_vmname ? g_engine_log_vmname : "engine", meta->file,
|
||||||
|
meta->func, meta->line, "Large log message");
|
||||||
|
if (nret < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = (size_t)nret;
|
||||||
|
|
||||||
|
if (size > (sizeof(log_buffer) - 1)) {
|
||||||
|
size = sizeof(log_buffer) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_buffer[size] = '\n';
|
||||||
|
|
||||||
|
if (write_nointr(log_fd, log_buffer, (size + 1)) == -1) {
|
||||||
|
fprintf(stderr, "write log into logfile failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* log append stderr */
|
||||||
|
void log_append_stderr(const struct engine_log_object_metadata *meta, const char *timestamp, const char *msg)
|
||||||
|
{
|
||||||
|
char *tmp_prefix = NULL;
|
||||||
|
if (meta->level > g_engine_log_level) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_prefix = g_engine_log_prefix ? g_engine_log_prefix : g_engine_log_vmname;
|
||||||
|
if (tmp_prefix != NULL && strlen(tmp_prefix) > MAX_LOG_PREFIX_LENGTH) {
|
||||||
|
tmp_prefix = tmp_prefix + (strlen(tmp_prefix) - MAX_LOG_PREFIX_LENGTH);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%15s %s %-8s ", tmp_prefix ? tmp_prefix : "", timestamp, g_engine_log_prio_name[meta->level]);
|
||||||
|
fprintf(stderr, "%s - ", g_engine_log_vmname ? g_engine_log_vmname : "engine");
|
||||||
|
fprintf(stderr, "%s:%s:%d - ", meta->file, meta->func, meta->line);
|
||||||
|
fprintf(stderr, "%s", msg);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write nointr */
|
||||||
|
ssize_t write_nointr(int fd, const void *buf, size_t count)
|
||||||
|
{
|
||||||
|
ssize_t nret;
|
||||||
|
for (;;) {
|
||||||
|
nret = write(fd, buf, count);
|
||||||
|
if (nret < 0 && errno == EINTR) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nret;
|
||||||
|
}
|
||||||
146
src/log.h
Normal file
146
src/log.h
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container log functions
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __LCR_LOG_H
|
||||||
|
#define __LCR_LOG_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_CLOEXEC
|
||||||
|
#define O_CLOEXEC 02000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef F_DUPFD_CLOEXEC
|
||||||
|
#define F_DUPFD_CLOEXEC 1030
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ENGINE_LOG_BUFFER_SIZE 4096
|
||||||
|
|
||||||
|
/* We're logging in seconds and nanoseconds. Assuming that the underlying
|
||||||
|
* datatype is currently at maximum a 64bit integer, we have a date string that
|
||||||
|
* is of maximum length (2^64 - 1) * 2 = (21 + 21) = 42.
|
||||||
|
* */
|
||||||
|
#define ENGINE_LOG_TIME_SIZE 42
|
||||||
|
|
||||||
|
/*errmsg that defined in lcrc & lcrd*/
|
||||||
|
#define DAEMON_ERROR_GRPC_INIT_STR "Init failed"
|
||||||
|
#define DAEMON_ERROR_GRPC_CONNENCT_STR "Can not connect with server.Is the docker dameon running on the host?"
|
||||||
|
#define DAEMON_ERROR_GRPC_SERVER_STR "Server internal error"
|
||||||
|
|
||||||
|
enum engine_log_level {
|
||||||
|
ENGINE_LOG_FATAL = 0,
|
||||||
|
ENGINE_LOG_ALERT,
|
||||||
|
ENGINE_LOG_CRIT,
|
||||||
|
ENGINE_LOG_ERROR,
|
||||||
|
ENGINE_LOG_WARN,
|
||||||
|
ENGINE_LOG_NOTICE,
|
||||||
|
ENGINE_LOG_INFO,
|
||||||
|
ENGINE_LOG_DEBUG,
|
||||||
|
ENGINE_LOG_TRACE,
|
||||||
|
ENGINE_LOG_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum g_engine_log_driver {
|
||||||
|
LOG_DRIVER_STDOUT,
|
||||||
|
LOG_DRIVER_FIFO,
|
||||||
|
LOG_DRIVER_NOSET,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct engine_log_config {
|
||||||
|
const char *name;
|
||||||
|
const char *file;
|
||||||
|
const char *priority;
|
||||||
|
const char *prefix;
|
||||||
|
const char *driver;
|
||||||
|
bool quiet;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ENGINE_LOG_LOCINFO_INIT \
|
||||||
|
{ \
|
||||||
|
.file = __FILE__, .func = __func__, .line = __LINE__, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* brief logging object metadata */
|
||||||
|
struct engine_log_object_metadata {
|
||||||
|
int level;
|
||||||
|
|
||||||
|
/* location information of the logging item */
|
||||||
|
const char *file;
|
||||||
|
const char *func;
|
||||||
|
int line;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void engine_close_log_file();
|
||||||
|
int log_enable(const struct engine_log_config *log);
|
||||||
|
|
||||||
|
void engine_set_log_prefix(const char *prefix);
|
||||||
|
|
||||||
|
void engine_free_log_prefix();
|
||||||
|
|
||||||
|
int engine_change_str_logdriver_to_enum(const char *driver);
|
||||||
|
|
||||||
|
int engine_log_append(const struct engine_log_object_metadata *event, const char *format, ...);
|
||||||
|
|
||||||
|
#define COMMON_LOG(loglevel, format, ...) \
|
||||||
|
do { \
|
||||||
|
struct engine_log_object_metadata meta = ENGINE_LOG_LOCINFO_INIT; \
|
||||||
|
meta.level = loglevel; \
|
||||||
|
(void)engine_log_append(&meta, format, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define DEBUG(format, ...) \
|
||||||
|
COMMON_LOG(ENGINE_LOG_FATAL, format, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
#define INFO(format, ...) \
|
||||||
|
COMMON_LOG(ENGINE_LOG_INFO, format, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
#define NOTICE(format, ...) \
|
||||||
|
COMMON_LOG(ENGINE_LOG_NOTICE, format, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
#define WARN(format, ...) \
|
||||||
|
COMMON_LOG(ENGINE_LOG_WARN, format, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
#define ERROR(format, ...) \
|
||||||
|
COMMON_LOG(ENGINE_LOG_ERROR, format, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
#define CRIT(format, ...) \
|
||||||
|
COMMON_LOG(ENGINE_LOG_CRIT, format, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
#define ALERT(format, ...) \
|
||||||
|
COMMON_LOG(ENGINE_LOG_ALERT, format, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
#define FATAL(format, ...) \
|
||||||
|
COMMON_LOG(ENGINE_LOG_FATAL, format, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
#define SYSERROR(format, ...) \
|
||||||
|
do { \
|
||||||
|
ERROR("%s - " format, strerror(errno), ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define COMMAND_ERROR(fmt, args...) \
|
||||||
|
do { \
|
||||||
|
(void)fprintf(stderr, fmt "\n", ##args); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LCR_LOG_H */
|
||||||
1657
src/utils.c
Normal file
1657
src/utils.c
Normal file
File diff suppressed because it is too large
Load Diff
202
src/utils.h
Normal file
202
src/utils.h
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
|
||||||
|
* lcr licensed under the Mulan PSL v1.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
* You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
* See the Mulan PSL v1 for more details.
|
||||||
|
* Author: wujing
|
||||||
|
* Create: 2018-11-08
|
||||||
|
* Description: provide container utils functions
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __LCR_UTILS_H
|
||||||
|
#define __LCR_UTILS_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef O_CLOEXEC
|
||||||
|
#define O_CLOEXEC 02000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ECOMMON 1
|
||||||
|
#define EINVALIDARGS 125
|
||||||
|
#define ECMDNOTFOUND 127
|
||||||
|
|
||||||
|
#define LCR_NUMSTRLEN64 21
|
||||||
|
|
||||||
|
#define SPACE_MAGIC_STR "[#)"
|
||||||
|
|
||||||
|
#define MAX_PATH_DEPTH 1024
|
||||||
|
|
||||||
|
#define SIZE_KB 1024LL
|
||||||
|
#define SIZE_MB (1024LL * SIZE_KB)
|
||||||
|
#define SIZE_GB (1024LL * SIZE_MB)
|
||||||
|
#define SIZE_TB (1024LL * SIZE_GB)
|
||||||
|
#define SIZE_PB (1024LL * SIZE_TB)
|
||||||
|
|
||||||
|
#define BUFSIZE 4096
|
||||||
|
|
||||||
|
#ifndef SIGTRAP
|
||||||
|
#define SIGTRAP 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGIOT
|
||||||
|
#define SIGIOT 6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGEMT
|
||||||
|
#define SIGEMT 7
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGBUS
|
||||||
|
#define SIGBUS 7
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGSTKFLT
|
||||||
|
#define SIGSTKFLT 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGCLD
|
||||||
|
#define SIGCLD 17
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGURG
|
||||||
|
#define SIGURG 23
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGXCPU
|
||||||
|
#define SIGXCPU 24
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGXFSZ
|
||||||
|
#define SIGXFSZ 25
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGVTALRM
|
||||||
|
#define SIGVTALRM 26
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGPROF
|
||||||
|
#define SIGPROF 27
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGWINCH
|
||||||
|
#define SIGWINCH 28
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGIO
|
||||||
|
#define SIGIO 29
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGPOLL
|
||||||
|
#define SIGPOLL 29
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGINFO
|
||||||
|
#define SIGINFO 29
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGLOST
|
||||||
|
#define SIGLOST 37
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGPWR
|
||||||
|
#define SIGPWR 30
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGUNUSED
|
||||||
|
#define SIGUNUSED 31
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGSYS
|
||||||
|
#define SIGSYS 31
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGRTMIN1
|
||||||
|
#define SIGRTMIN1 34
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIGRTMAX
|
||||||
|
#define SIGRTMAX 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SIGNAL_MAP_DEFAULT \
|
||||||
|
{ \
|
||||||
|
{ SIGHUP, "HUP" }, { SIGINT, "INT" }, { SIGQUIT, "QUIT" }, { SIGILL, "ILL" }, { SIGABRT, "ABRT" }, \
|
||||||
|
{ SIGFPE, "FPE" }, { SIGKILL, "KILL" }, { SIGSEGV, "SEGV" }, { SIGPIPE, "PIPE" }, { SIGALRM, "ALRM" }, \
|
||||||
|
{ SIGTERM, "TERM" }, { SIGUSR1, "USR1" }, { SIGUSR2, "USR2" }, { SIGCHLD, "CHLD" }, \
|
||||||
|
{ SIGCONT, "CONT" }, { SIGSTOP, "STOP" }, { SIGTSTP, "TSTP" }, { SIGTTIN, "TTIN" }, \
|
||||||
|
{ SIGTTOU, "TTOU" }, { SIGTRAP, "TRAP" }, { SIGIOT, "IOT" }, { SIGEMT, "EMT" }, { SIGBUS, "BUS" }, \
|
||||||
|
{ SIGSTKFLT, "STKFLT" }, { SIGCLD, "CLD" }, { SIGURG, "URG" }, { SIGXCPU, "XCPU" }, \
|
||||||
|
{ SIGXFSZ, "XFSZ" }, { SIGVTALRM, "VTALRM" }, { SIGPROF, "PROF" }, { SIGWINCH, "WINCH" }, \
|
||||||
|
{ SIGIO, "IO" }, { SIGPOLL, "POLL" }, { SIGINFO, "INFO" }, { SIGLOST, "LOST" }, { SIGPWR, "PWR" }, \
|
||||||
|
{ SIGUNUSED, "UNUSED" }, { SIGSYS, "SYS" }, { SIGRTMIN, "RTMIN" }, { SIGRTMIN + 1, "RTMIN+1" }, \
|
||||||
|
{ SIGRTMIN + 2, "RTMIN+2" }, { SIGRTMIN + 3, "RTMIN+3" }, { SIGRTMIN + 4, "RTMIN+4" }, \
|
||||||
|
{ SIGRTMIN + 5, "RTMIN+5" }, { SIGRTMIN + 6, "RTMIN+6" }, { SIGRTMIN + 7, "RTMIN+7" }, \
|
||||||
|
{ SIGRTMIN + 8, "RTMIN+8" }, { SIGRTMIN + 9, "RTMIN+9" }, { SIGRTMIN + 10, "RTMIN+10" }, \
|
||||||
|
{ SIGRTMIN + 11, "RTMIN+11" }, { SIGRTMIN + 12, "RTMIN+12" }, { SIGRTMIN + 13, "RTMIN+13" }, \
|
||||||
|
{ SIGRTMIN + 14, "RTMIN+14" }, { SIGRTMIN + 15, "RTMIN+15" }, { SIGRTMAX - 14, "RTMAX-14" }, \
|
||||||
|
{ SIGRTMAX - 13, "RTMAX-13" }, { SIGRTMAX - 12, "RTMAX-12" }, { SIGRTMAX - 11, "RTMAX-11" }, \
|
||||||
|
{ SIGRTMAX - 10, "RTMAX-10" }, { SIGRTMAX - 9, "RTMAX-9" }, { SIGRTMAX - 8, "RTMAX-8" }, \
|
||||||
|
{ SIGRTMAX - 7, "RTMAX-7" }, { SIGRTMAX - 6, "RTMAX-6" }, { SIGRTMAX - 5, "RTMAX-5" }, \
|
||||||
|
{ SIGRTMAX - 4, "RTMAX-4" }, { SIGRTMAX - 3, "RTMAX-3" }, { SIGRTMAX - 2, "RTMAX-2" }, \
|
||||||
|
{ SIGRTMAX - 1, "RTMAX-1" }, { SIGRTMAX, "RTMAX" }, \
|
||||||
|
}
|
||||||
|
|
||||||
|
bool file_exists(const char *path);
|
||||||
|
bool dir_exists(const char *path);
|
||||||
|
int wait_for_pid(pid_t pid);
|
||||||
|
int wait_for_pid_status(pid_t pid);
|
||||||
|
char *util_string_join(const char *sep, const char **parts, size_t len);
|
||||||
|
int util_mkdir_p(const char *dir, mode_t mode);
|
||||||
|
char **lcr_string_split_and_trim(const char *str, char _sep);
|
||||||
|
void lcr_free_array(void **array);
|
||||||
|
int lcr_grow_array(void ***array, size_t *capacity, size_t new_size, size_t capacity_increment);
|
||||||
|
size_t lcr_array_len(void **array);
|
||||||
|
int mem_realloc(void **new, size_t newsize, void *old, size_t oldsize);
|
||||||
|
bool util_valid_cmd_arg(const char *arg);
|
||||||
|
int util_safe_ullong(const char *numstr, unsigned long long *converted);
|
||||||
|
int util_safe_strtod(const char *numstr, double *converted);
|
||||||
|
int util_safe_uint(const char *numstr, unsigned int *converted);
|
||||||
|
int parse_byte_size_string(const char *s, int64_t *converted);
|
||||||
|
bool util_dir_exists(const char *path);
|
||||||
|
int util_ensure_path(char **confpath, const char *path);
|
||||||
|
int util_recursive_rmdir(const char *dirpath, int recursive_depth);
|
||||||
|
char *util_string_replace(const char *needle, const char *replacement, const char *haystack);
|
||||||
|
int util_open(const char *filename, int flags, mode_t mode);
|
||||||
|
|
||||||
|
FILE *util_fopen(const char *filename, const char *mode);
|
||||||
|
|
||||||
|
void *util_common_calloc_s(size_t size);
|
||||||
|
int util_safe_int(const char *numstr, int *converted);
|
||||||
|
int util_check_inherited(bool closeall, int fd_to_ignore);
|
||||||
|
char *util_string_append(const char *dst, const char *src);
|
||||||
|
char *util_string_split_prefix(size_t prefix_len, const char *file);
|
||||||
|
|
||||||
|
int util_build_dir(const char *name);
|
||||||
|
ssize_t util_write_nointr(int fd, const void *buf, size_t count);
|
||||||
|
ssize_t util_read_nointr(int fd, void *buf, size_t count);
|
||||||
|
void util_free_array(char **array);
|
||||||
|
|
||||||
|
int util_sig_parse(const char *signame);
|
||||||
|
bool util_valid_signal(int sig);
|
||||||
|
size_t util_array_len(char **array);
|
||||||
|
const char *str_skip_str(const char *str, const char *skip);
|
||||||
|
int util_array_append(char ***array, const char *element);
|
||||||
|
int util_safe_llong(const char *numstr, long long *converted);
|
||||||
|
char *util_strdup_s(const char *src);
|
||||||
|
int util_null_stdfds(void);
|
||||||
|
|
||||||
|
bool util_copy_file(const char *src_file, const char *dst_file);
|
||||||
|
|
||||||
|
bool util_write_file(const char *filepath, const char *content, size_t len, bool add_newline);
|
||||||
|
|
||||||
|
int util_atomic_write_file(const char *filepath, const char *content);
|
||||||
|
|
||||||
|
#endif /*__LCR_UTILS_H */
|
||||||
554
tools/static_check
Executable file
554
tools/static_check
Executable file
@ -0,0 +1,554 @@
|
|||||||
|
#######################################################################
|
||||||
|
##- @Copyright (C) Huawei Technologies., Ltd. 2017-2019. All rights reserved.
|
||||||
|
# - lcr licensed under the Mulan PSL v1.
|
||||||
|
# - You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
# - You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
# - http://license.coscl.org.cn/MulanPSL
|
||||||
|
# - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
# - IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
# - PURPOSE.
|
||||||
|
# - See the Mulan PSL v1 for more details.
|
||||||
|
##- @Description: generate cetification
|
||||||
|
##- @Author: wujing
|
||||||
|
##- @Create: 2019-04-25
|
||||||
|
#######################################################################
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# This script is the implementation portal for the iSulad project Personal level build static check.
|
||||||
|
# set -euxo pipefail
|
||||||
|
|
||||||
|
CURRENT_PATH=$(pwd)
|
||||||
|
CI_TOOLS_PROJECT="/root/workspace/ci_tools"
|
||||||
|
export LOCAL_INCLUDE="/root/workspace/ci_tools/rule/include"
|
||||||
|
export EULER_CODE_PATH="$(realpath ${CURRENT_PATH}/..)"
|
||||||
|
LINT_RULE_FILE="/root/workspace/ci_tools/rule/pclint"
|
||||||
|
PCLINT_TOOL="/usr/local/bin/flint"
|
||||||
|
CODESTYLE_TOOL="/usr/local/bin/cpplint.py"
|
||||||
|
CMETRICS_TOOL="/root/cmetrics/cmetrics.py"
|
||||||
|
|
||||||
|
function usage() {
|
||||||
|
echo -e "\
|
||||||
|
=================================================================================================\033[1;37m
|
||||||
|
_____ ______ ___ ______ ____ ______ ______ __ __ ______ ______ __ __
|
||||||
|
/ ___//_ __// | /_ __// _// ____/ / ____// / / // ____// ____// //_/
|
||||||
|
\__ \ / / / /| | / / / / / / / / / /_/ // __/ / / / ,<
|
||||||
|
___/ / / / / ___ | / / _/ / / /___ / /___ / __ // /___ / /___ / /| |
|
||||||
|
/____/ /_/ /_/ |_|/_/ /___/ \____/ \____//_/ /_//_____/ \____//_/ |_| \033[0m
|
||||||
|
================================================================================================="
|
||||||
|
echo "Usage: $0 [options]"
|
||||||
|
echo "Personal level build static check script for iSulad project"
|
||||||
|
echo "Options:"
|
||||||
|
echo " -u, --update-ci-tools Update ci tools project and replace header files with latest ones"
|
||||||
|
echo " -p, --pclint Perform pclint code static check"
|
||||||
|
echo " -s, --codestyle Perform codestyle(codedex) code static check"
|
||||||
|
echo " -c, --detail-cmetrics Detail code statistics analysis"
|
||||||
|
echo " -m, --simple-cmetrics Simple code statistics analysis"
|
||||||
|
echo " -a, --all Perform all checks and statistics"
|
||||||
|
echo " -i, --incremental-check Perform incremental check"
|
||||||
|
echo " -f, --quick-format Incremental format code by astyle/clang-format"
|
||||||
|
echo " -k, --style-check Check code style by astyle"
|
||||||
|
echo " --cpp-check Check code style by Cppcheck"
|
||||||
|
echo " -h, --help Script help information"
|
||||||
|
}
|
||||||
|
|
||||||
|
function err() {
|
||||||
|
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_ci_tools() {
|
||||||
|
cd ${CI_TOOLS_PROJECT}
|
||||||
|
git fetch origin
|
||||||
|
git diff > static_check_backup.patch
|
||||||
|
git checkout .
|
||||||
|
git rebase origin/next_docker
|
||||||
|
cd ${CURRENT_PATH}
|
||||||
|
for file in $(find . -regextype posix-extended -regex ".*\.(h)")
|
||||||
|
do
|
||||||
|
cp $file $LOCAL_INCLUDE/docker/iSulad
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
PCLINT_MASKED_RULE="679|826|726|322|571"
|
||||||
|
|
||||||
|
function pclint_check() {
|
||||||
|
echo -e "\
|
||||||
|
=================================================================================================\033[1;35m
|
||||||
|
____ ______ __ ____ _ __ ______ ______ __ __ ______ ______ __ __
|
||||||
|
/ __ \ / ____// / / _// | / //_ __/ / ____// / / // ____// ____// //_/
|
||||||
|
/ /_/ // / / / / / / |/ / / / / / / /_/ // __/ / / / ,<
|
||||||
|
/ ____// /___ / /___ _/ / / /| / / / / /___ / __ // /___ / /___ / /| |
|
||||||
|
/_/ \____//_____//___//_/ |_/ /_/ \____//_/ /_//_____/ \____//_/ |_| \033[0m
|
||||||
|
================================================================================================="
|
||||||
|
local start_time=$(date +%s)
|
||||||
|
local files
|
||||||
|
if [[ ${1} == "all" ]]; then
|
||||||
|
files=$(find ./src -regextype posix-extended -regex ".*\.(c)")
|
||||||
|
else
|
||||||
|
files=$(git diff --name-only HEAD | grep -E "*.c$")
|
||||||
|
fi
|
||||||
|
files=(${files// / })
|
||||||
|
local total=${#files[@]}
|
||||||
|
local failure_num=0
|
||||||
|
local index=1
|
||||||
|
for file in ${files[@]}
|
||||||
|
do
|
||||||
|
${PCLINT_TOOL} -i ${LINT_RULE_FILE} std_lcr.lnt $file 2>&1 | grep -E "Err|Warn|Info" | grep -vE ${PCLINT_MASKED_RULE}
|
||||||
|
if [[ $? -eq 0 ]];then
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;31m\033[5m%s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[FAILED]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
failure_num=$((failure_num+1))
|
||||||
|
else
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;32m%-5s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[PASS]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
fi
|
||||||
|
index=$((index+1))
|
||||||
|
done
|
||||||
|
printf "%0.s=" {1..96}
|
||||||
|
printf "\n"
|
||||||
|
local end_time=$(date +%s)
|
||||||
|
local duration=$((${end_time} - ${start_time}))
|
||||||
|
echo -e "\033[1;36mTotal files: ${total}\033[0m, \033[1;32msuccess: $((total-failure_num))\033[0m, \033[1;31mfailure: ${failure_num}\033[0m. \033[1;33mSpend time: ${duration} seconds\033[0m"
|
||||||
|
if [[ ${failure_num} -ne 0 ]]; then
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
CODESTYLE_MASKED_RULE=(
|
||||||
|
"Start-processing"
|
||||||
|
"Done-processing"
|
||||||
|
"Total-errors-found"
|
||||||
|
"\[build/header_guard\]-\[5\]"
|
||||||
|
"\[build/c++11\]-\[5\]"
|
||||||
|
"\[whitespace/indent\]-\[3\]"
|
||||||
|
"\[whitespace/braces\]-\[4\]"
|
||||||
|
"\[readability/condition\]-\[2\]"
|
||||||
|
"\[whitespace/braces\]-\[5\]"
|
||||||
|
"\[build/c\+\+11\]-\[5\]"
|
||||||
|
"\[build/include_order\]-\[4\]"
|
||||||
|
"\[readability/multiline_string\]-\[5\]"
|
||||||
|
"\[runtime/string\]-\[4\]"
|
||||||
|
"\[whitespace/semicolon\]-\[5\]"
|
||||||
|
"\[whitespace/comments\]-\[2\]"
|
||||||
|
"\[build/c\+\+11\]-\[3\]"
|
||||||
|
"\[whitespace/operators\]-\[4\]"
|
||||||
|
"\[runtime/threadsafe_fn\]-\[2\]"
|
||||||
|
"\[runtime/printf\]-\[4\]"
|
||||||
|
"\[readability/alt_tokens\]-\[2\]"
|
||||||
|
)
|
||||||
|
function codestyle_check() {
|
||||||
|
echo -e "\
|
||||||
|
=================================================================================================\033[1;33m
|
||||||
|
______ ____ ____ ____ _ __ ______ _____ ________ __ __ ______
|
||||||
|
/ ____// __ \ / __ \ / _// | / // ____// ___//_ __/\ \/ // / / ____/
|
||||||
|
/ / / / / // / / / / / / |/ // / __ \__ \ / / \ // / / __/
|
||||||
|
/ /___ / /_/ // /_/ /_/ / / /| // /_/ / ___/ / / / / // /___ / /___
|
||||||
|
\____/ \____//_____//___//_/ |_/ \____/ /____/ /_/ /_//_____//_____/\033[0m
|
||||||
|
================================================================================================="
|
||||||
|
local masked_rule=$(echo ${CODESTYLE_MASKED_RULE[@]} | sed -e "s/ /|/g" -e "s/-/ /g")
|
||||||
|
local start_time=$(date +%s)
|
||||||
|
local files
|
||||||
|
if [[ ${1} == "all" ]]; then
|
||||||
|
files=$(find ./src -regextype posix-extended -regex ".*\.(h|c|cc)")
|
||||||
|
else
|
||||||
|
files=$(git diff --name-only HEAD | grep -E "*.h$|*.c$|*.cc$")
|
||||||
|
fi
|
||||||
|
files=(${files// / })
|
||||||
|
local total=${#files[@]}
|
||||||
|
local failure_num=0
|
||||||
|
local index=1
|
||||||
|
for file in ${files[@]}
|
||||||
|
do
|
||||||
|
python3 ${CODESTYLE_TOOL} $file 2>&1 | grep -vE "${masked_rule}"
|
||||||
|
if [[ $? -eq 0 ]];then
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;31m\033[5m%s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[FAILED]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
failure_num=$((failure_num+1))
|
||||||
|
else
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;32m%-5s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[PASS]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
fi
|
||||||
|
index=$((index+1))
|
||||||
|
done
|
||||||
|
printf "%0.s=" {1..96}
|
||||||
|
printf "\n"
|
||||||
|
local end_time=$(date +%s)
|
||||||
|
local duration=$((${end_time} - ${start_time}))
|
||||||
|
echo -e "\033[1;36mTotal files: ${total}\033[0m, \033[1;32msuccess: $((total-failure_num))\033[0m, \033[1;31mfailure: ${failure_num}\033[0m. \033[1;33mSpend time: ${duration} seconds\033[0m"
|
||||||
|
if [[ ${failure_num} -ne 0 ]]; then
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
CPPCHRECK_RULE=(
|
||||||
|
"information"
|
||||||
|
"warning"
|
||||||
|
"performance"
|
||||||
|
"style"
|
||||||
|
# "unusedFunction"
|
||||||
|
# "all"
|
||||||
|
)
|
||||||
|
CPPCHRCK_LOG="${CURRENT_PATH}/cppcheck.log"
|
||||||
|
|
||||||
|
function cpp_check() {
|
||||||
|
echo -e "\
|
||||||
|
=================================================================================================\033[1;33m
|
||||||
|
______ ____ ____ ______ __ __ ______ ______ __ __
|
||||||
|
/ ____// __ \ / __ \ / ____// / / // ____// ____// //_/
|
||||||
|
/ / / /_/ // /_/ / / / / /_/ // __/ / / / ,<
|
||||||
|
/ /___ / ____// ____/ / /___ / __ // /___ / /___ / /| |
|
||||||
|
\____//_/ /_/ \____//_/ /_//_____/ \____//_/ |_|\033[0m
|
||||||
|
================================================================================================="
|
||||||
|
echo "cpp check is in progress, please wait a few seconds..."
|
||||||
|
printf "%0.s*" {1..97}
|
||||||
|
printf "\n"
|
||||||
|
local check_rule=$(echo ${CPPCHRECK_RULE[@]} | sed -e "s/ /,/g")
|
||||||
|
local start_time=$(date +%s)
|
||||||
|
result=$(cppcheck --enable=${check_rule} -I ./src -I ./build -i ./build -i ./isula_testcases -i ./CI ./ 2>&1 \
|
||||||
|
| grep -vE "^Checking|done$|Cppcheck cannot find all the include files")
|
||||||
|
nums=$(echo "${result}" | wc -l)
|
||||||
|
echo "${result}"
|
||||||
|
local end_time=$(date +%s)
|
||||||
|
local duration=$((${end_time} - ${start_time}))
|
||||||
|
if [[ ${nums} -eq 0 ]] || [[ -z ${result} ]]; then
|
||||||
|
echo -e "\033[1;32mSuccess: clean code!\033[0m \033[1;33mSpend time: ${duration} seconds\033[0m"
|
||||||
|
else
|
||||||
|
printf "%0.s*" {1..97}
|
||||||
|
printf "\n"
|
||||||
|
echo -e "\033[1;31mFailure: There are ${nums} warnings that you need to handle\033[0m. \033[1;33mSpend time: ${duration} seconds\033[0m"
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function clang_format() {
|
||||||
|
echo -e "\
|
||||||
|
=================================================================================================\033[1;36m
|
||||||
|
______ __ ___ _ __ ______ ______ ____ ____ __ ___ ___ ______
|
||||||
|
/ ____// / / | / | / // ____/ / ____// __ \ / __ \ / |/ // | /_ __/
|
||||||
|
/ / / / / /| | / |/ // / __ ______ / /_ / / / // /_/ // /|_/ // /| | / /
|
||||||
|
/ /___ / /___ / ___ | / /| // /_/ //_____// __/ / /_/ // _, _// / / // ___ | / /
|
||||||
|
\____//_____//_/ |_|/_/ |_/ \____/ /_/ \____//_/ |_|/_/ /_//_/ |_|/_/ \033[0m]
|
||||||
|
================================================================================================="
|
||||||
|
local start_time=$(date +%s)
|
||||||
|
local files=$(git diff --name-only HEAD | grep -E "*.h$|*.c$|*.cc$")
|
||||||
|
files=(${files// / })
|
||||||
|
local total=${#files[@]}
|
||||||
|
local failure_num=0
|
||||||
|
local index=1
|
||||||
|
for file in ${files[@]}
|
||||||
|
do
|
||||||
|
clang-format -i ${file}
|
||||||
|
if [[ $? -ne 0 ]];then
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;31m\033[5m%s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[FAILED]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
failure_num=$((failure_num+1))
|
||||||
|
else
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;32m%-5s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[PASS]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
fi
|
||||||
|
index=$((index+1))
|
||||||
|
done
|
||||||
|
printf "%0.s=" {1..96}
|
||||||
|
printf "\n"
|
||||||
|
local end_time=$(date +%s)
|
||||||
|
local duration=$((${end_time} - ${start_time}))
|
||||||
|
echo -e "\033[1;36mTotal files: ${total}\033[0m, \033[1;32msuccess: $((total-failure_num))\033[0m, \033[1;31mfailure: ${failure_num}\033[0m. \033[1;33mSpend time: ${duration} seconds\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_astyle_fix() {
|
||||||
|
astyle --options=none --lineend=linux --mode=c \
|
||||||
|
--style=kr \
|
||||||
|
--add-braces \
|
||||||
|
--indent=spaces=4 \
|
||||||
|
--indent-preprocessor \
|
||||||
|
--indent-col1-comments \
|
||||||
|
--indent-switches \
|
||||||
|
--indent-cases \
|
||||||
|
--min-conditional-indent=0 \
|
||||||
|
--max-instatement-indent=120 \
|
||||||
|
--max-code-length=120 \
|
||||||
|
--break-after-logical \
|
||||||
|
--pad-oper \
|
||||||
|
--pad-header \
|
||||||
|
--unpad-paren \
|
||||||
|
--pad-comma \
|
||||||
|
--lineend=linux \
|
||||||
|
--align-reference=name \
|
||||||
|
--close-templates \
|
||||||
|
--indent-preproc-define \
|
||||||
|
--indent-cases \
|
||||||
|
--indent-switches \
|
||||||
|
--attach-namespaces \
|
||||||
|
--attach-classes \
|
||||||
|
--attach-extern-c \
|
||||||
|
--attach-closing-while \
|
||||||
|
--indent-col1-comments \
|
||||||
|
--break-one-line-headers \
|
||||||
|
--close-templates < "${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function astyle_fix() {
|
||||||
|
[[ -z "${1}" || ! -r "${1}" ]] && exit -1
|
||||||
|
tmp="$(mktemp --tmpdir=$(dirname "${1}"))"
|
||||||
|
do_astyle_fix "${1}" > "${tmp}"
|
||||||
|
sed -i 's/\*const/\* const/g' "${tmp}"
|
||||||
|
mv "${tmp}" "${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function astyle_format() {
|
||||||
|
echo -e "\
|
||||||
|
=================================================================================================\033[1;36m
|
||||||
|
___ _____ ________ __ __ ______ ______ ____ ____ __ ___ ___ ______
|
||||||
|
/ | / ___//_ __/\ \/ // / / ____/ / ____// __ \ / __ \ / |/ // | /_ __/
|
||||||
|
/ /| | \__ \ / / \ // / / __/ ______ / /_ / / / // /_/ // /|_/ // /| | / /
|
||||||
|
/ ___ | ___/ / / / / // /___ / /___/_____// __/ / /_/ // _, _// / / // ___ | / /
|
||||||
|
/_/ |_|/____/ /_/ /_//_____//_____/ /_/ \____//_/ |_|/_/ /_//_/ |_|/_/ \033[0m]
|
||||||
|
================================================================================================="
|
||||||
|
local start_time=$(date +%s)
|
||||||
|
local files=$(find ./src -regextype posix-extended -regex ".*\.(h|c|cc)")
|
||||||
|
files=(${files// / })
|
||||||
|
local total=${#files[@]}
|
||||||
|
local failure_num=0
|
||||||
|
local index=1
|
||||||
|
for file in ${files[@]}
|
||||||
|
do
|
||||||
|
astyle_fix ${file}
|
||||||
|
if [[ $? -ne 0 ]];then
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;31m\033[5m%s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[FAILED]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
failure_num=$((failure_num+1))
|
||||||
|
else
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;32m%-5s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[PASS]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
fi
|
||||||
|
index=$((index+1))
|
||||||
|
done
|
||||||
|
printf "%0.s=" {1..96}
|
||||||
|
printf "\n"
|
||||||
|
local end_time=$(date +%s)
|
||||||
|
local duration=$((${end_time} - ${start_time}))
|
||||||
|
echo -e "\033[1;36mTotal files: ${total}\033[0m, \033[1;32msuccess: $((total-failure_num))\033[0m, \033[1;31mfailure: ${failure_num}\033[0m. \033[1;33mSpend time: ${duration} seconds\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
function quick_format() {
|
||||||
|
if [[ $1 == "clang-format" ]]; then
|
||||||
|
clang_format
|
||||||
|
else
|
||||||
|
astyle_format
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_astyle_check() {
|
||||||
|
[[ -z "$1" || ! -r "$1" ]] && return -1
|
||||||
|
|
||||||
|
do_astyle_fix "$1" | diff -pu --label="$1.orig" "$1" --label="$1" -
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function style_check() {
|
||||||
|
echo -e "\
|
||||||
|
=================================================================================================
|
||||||
|
███████╗████████╗██╗ ██╗██╗ ███████╗ ██████╗██╗ ██╗███████╗ ██████╗██╗ ██╗
|
||||||
|
██╔════╝╚══██╔══╝╚██╗ ██╔╝██║ ██╔════╝ ██╔════╝██║ ██║██╔════╝██╔════╝██║ ██╔╝
|
||||||
|
███████╗ ██║ ╚████╔╝ ██║ █████╗ ██║ ███████║█████╗ ██║ █████╔╝
|
||||||
|
╚════██║ ██║ ╚██╔╝ ██║ ██╔══╝ ██║ ██╔══██║██╔══╝ ██║ ██╔═██╗
|
||||||
|
███████║ ██║ ██║ ███████╗███████╗ ╚██████╗██║ ██║███████╗╚██████╗██║ ██╗
|
||||||
|
╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚═╝
|
||||||
|
================================================================================================="
|
||||||
|
local start_time=$(date +%s)
|
||||||
|
local files
|
||||||
|
if [[ ${1} == "all" ]]; then
|
||||||
|
files=$(find ./src -regextype posix-extended -regex ".*\.(h|c|cc)")
|
||||||
|
else
|
||||||
|
files=$(git diff --name-only HEAD | grep -E "*.h$|*.c$|*.cc$")
|
||||||
|
fi
|
||||||
|
files=(${files// / })
|
||||||
|
local total=${#files[@]}
|
||||||
|
local failure_num=0
|
||||||
|
local index=1
|
||||||
|
for file in ${files[@]}
|
||||||
|
do
|
||||||
|
do_astyle_check ${file}
|
||||||
|
if [[ $? -ne 0 ]];then
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;31m\033[5m%s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[FAILED]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
failure_num=$((failure_num+1))
|
||||||
|
else
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;32m%-5s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[PASS]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
fi
|
||||||
|
index=$((index+1))
|
||||||
|
done
|
||||||
|
printf "%0.s=" {1..96}
|
||||||
|
printf "\n"
|
||||||
|
local end_time=$(date +%s)
|
||||||
|
local duration=$((${end_time} - ${start_time}))
|
||||||
|
echo -e "\033[1;36mTotal files: ${total}\033[0m, \033[1;32msuccess: $((total-failure_num))\033[0m, \033[1;31mfailure: ${failure_num}\033[0m. \033[1;33mSpend time: ${duration} seconds\033[0m"
|
||||||
|
if [[ ${failure_num} -ne 0 ]]; then
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function cmetrics_check() {
|
||||||
|
echo -e "\
|
||||||
|
=================================================================================================\033[1;36m
|
||||||
|
______ __ ___ ______ ______ ____ ____ ______ _____ ______ __ __ ______ ______ __ __
|
||||||
|
/ ____// |/ // ____//_ __// __ \ / _// ____// ___/ / ____// / / // ____// ____// //_/
|
||||||
|
/ / / /|_/ // __/ / / / /_/ / / / / / \__ \ / / / /_/ // __/ / / / ,<
|
||||||
|
/ /___ / / / // /___ / / / _, _/_/ / / /___ ___/ / / /___ / __ // /___ / /___ / /| |
|
||||||
|
\____//_/ /_//_____/ /_/ /_/ |_|/___/ \____/ /____/ \____//_/ /_//_____/ \____//_/ |_|\033[0m
|
||||||
|
================================================================================================="
|
||||||
|
if [[ ${1} == "simple" ]]; then
|
||||||
|
printf "%0.s*" {1..97}
|
||||||
|
printf "\n"
|
||||||
|
result=$(python3 ${CMETRICS_TOOL} -fp ./src)
|
||||||
|
echo "${result}"
|
||||||
|
printf "%0.s*" {1..97}
|
||||||
|
printf "\n"
|
||||||
|
CyclomaticComplexityPerMethod=$(echo "${result}" | grep '\[\*\] Cyclomatic Complexity per Method' | awk '{print $NF}')
|
||||||
|
if [[ $(echo "${CyclomaticComplexityPerMethod} > 5" | bc) -eq 1 ]]; then
|
||||||
|
echo -e "\033[1;31mFailure: cyclomatic complexity per method(${CyclomaticComplexityPerMethod}) greater then 5\033[0m."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo -e "\033[1;32mSuccess: cyclomatic complexity per method(${CyclomaticComplexityPerMethod}) less then 5\033[0m."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local start_time=$(date +%s)
|
||||||
|
local files
|
||||||
|
if [[ ${1} == "all" ]]; then
|
||||||
|
files=$(find ./src -regextype posix-extended -regex ".*\.(h|c|cc)")
|
||||||
|
else
|
||||||
|
files=$(git diff --name-only HEAD | grep -E "*.h$|*.c$|*.cc$")
|
||||||
|
fi
|
||||||
|
files=(${files// / })
|
||||||
|
local total=${#files[@]}
|
||||||
|
local failure_num=0
|
||||||
|
local index=1
|
||||||
|
if [[ ${total} -eq 0 ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
for file in ${files[@]}
|
||||||
|
do
|
||||||
|
result=$(python3 ${CMETRICS_TOOL} -fp ${file})
|
||||||
|
CyclomaticComplexityperMethod=$(echo "${result}" | grep "\[\*\] Cyclomatic Complexity per Method:" | awk '{print $NF}')
|
||||||
|
CyclomaticComplexityperMethod=${CyclomaticComplexityperMethod:-0}
|
||||||
|
MaximumCyclomaticComplexity=$(echo "${result}" | grep "\[\*\] Maximum Cyclomatic Complexity:" | awk '{print $NF}')
|
||||||
|
MaximumCyclomaticComplexity=${MaximumCyclomaticComplexity:-0}
|
||||||
|
MaximumDepth=$(echo "${result}" | grep "\[\*\] Maximum Depth:" | awk '{print $NF}')
|
||||||
|
MaximumDepth=${MaximumDepth:-0}
|
||||||
|
RawLines=$(echo "${result}" | grep "\[\*\] Raw Lines:" | awk '{print $NF}')
|
||||||
|
RawLines=${RawLines:-0}
|
||||||
|
if [[ ${MaximumCyclomaticComplexity} -gt 10 ]] || [[ $(echo "${CyclomaticComplexityperMethod} > 5" | bc) -eq 1 ]] || \
|
||||||
|
[[ ${MaximumDepth} -gt 5 ]] || [[ ${RawLines} -gt 2000 ]]; then
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;31m\033[5m%s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[FAILED]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
failure_num=$((failure_num+1))
|
||||||
|
else
|
||||||
|
printf "[\033[1;36m%03d\033[0m\033[1;33m/\033[0m\033[1;34m%03d\033[0m]@%-80s \033[1;32m%-5s\033[0m\n" \
|
||||||
|
${index} ${total} ${file} "[PASS]" | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
|
||||||
|
fi
|
||||||
|
printf "%s\n%s\n%s\n %-1.3f | %3d | %2d | %4d\n%s\n" \
|
||||||
|
"-------------------------------------------------------------------------------------------------" \
|
||||||
|
" Cyclomatic Complexity per Method | Maximum Cyclomatic Complexity | Maximum Depth | Raw Lines " \
|
||||||
|
"-------------------------------------------------------------------------------------------------" \
|
||||||
|
${CyclomaticComplexityperMethod} ${MaximumCyclomaticComplexity} ${MaximumDepth} ${RawLines} \
|
||||||
|
"-------------------------------------------------------------------------------------------------"
|
||||||
|
index=$((index+1))
|
||||||
|
done
|
||||||
|
printf "%0.s=" {1..97}
|
||||||
|
printf "\n"
|
||||||
|
local end_time=$(date +%s)
|
||||||
|
local duration=$((${end_time} - ${start_time}))
|
||||||
|
echo -e "\033[1;36mTotal files: ${total}\033[0m, \033[1;32msuccess: $((total-failure_num))\033[0m, \033[1;31mfailure: ${failure_num}\033[0m. \033[1;33mSpend time: ${duration} seconds\033[0m"
|
||||||
|
printf "%0.s*" {1..97}
|
||||||
|
printf "\n"
|
||||||
|
if [[ ${1} == "all" ]]; then
|
||||||
|
result=$(python3 ${CMETRICS_TOOL} -fp ./src)
|
||||||
|
else
|
||||||
|
result=$(python3 ${CMETRICS_TOOL} -fp ${files[@]})
|
||||||
|
fi
|
||||||
|
echo "${result}"
|
||||||
|
printf "%0.s*" {1..96}
|
||||||
|
printf "\n"
|
||||||
|
CyclomaticComplexityPerMethod=$(echo "${result}" | grep '\[\*\] Cyclomatic Complexity per Method' | awk '{print $NF}')
|
||||||
|
if [[ $(echo "${CyclomaticComplexityPerMethod} > 5" | bc) -eq 1 ]]; then
|
||||||
|
echo -e "\033[1;31mFailure: cyclomatic complexity per method(${CyclomaticComplexityPerMethod}) greater then 5\033[0m."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo -e "\033[1;32mSuccess: cyclomatic complexity per method(${CyclomaticComplexityPerMethod}) less then 5\033[0m."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function incremental_check() {
|
||||||
|
style_check "incremental"
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
pclint_check "incremental"
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
codestyle_check "incremental"
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
cpp_check
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cmetrics_check "incremental"
|
||||||
|
}
|
||||||
|
|
||||||
|
function static_check_all() {
|
||||||
|
style_check "all"
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
pclint_check "all"
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
codestyle_check "all"
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
cpp_check
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cmetrics_check "simple"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# -eq 0 ]];then
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
args=`getopt -o upscmiaf:kh --long update-ci-tools,pclint,codestyle,detail-cmetrics,simple-cmetrics,incremental-check,all,quick-format:,style-check,cpp-check,help -- "$@"`
|
||||||
|
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
|
||||||
|
eval set -- "$args"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-u|--update-ci-tools) update_ci_tools || (err "failed to update ci tools project" && exit -1); shift ;;
|
||||||
|
-p|--pclint) pclint_check "all" || (err "failed to perfrom pclint code static check" && exit -1); shift ;;
|
||||||
|
-s|--codestyle) codestyle_check "all" || (err "failed to perfrom codestyle(codedex) code static check" && exit -1); shift ;;
|
||||||
|
-c|--detail-cmetrics) cmetrics_check "all" || (err "failed to perform detail checks and statistics" && exit -1); shift ;;
|
||||||
|
-m|--simple-cmetrics) cmetrics_check "simple" || (err "failed to perform simple checks and statistics" && exit -1); shift ;;
|
||||||
|
-i|--incremental-check) incremental_check || (err "failed to perform incremental check" && exit -1); shift ;;
|
||||||
|
-a|--all) static_check_all || (err "failed to perform all checks and statistics" && exit -1); shift ;;
|
||||||
|
-f|--quick-format) quick_format $2 || (err "failed to format code" && exit -1); shift 2 ;;
|
||||||
|
-k|--style-check) style_check "all" || (err "failed to check code style" && exit -1); shift ;;
|
||||||
|
--cpp-check) cpp_check || (err "failed to check code style" && exit -1); shift ;;
|
||||||
|
-h|--help) usage ; exit 0 ;;
|
||||||
|
--) shift ; break ;;
|
||||||
|
*) err "invalid parameter" ; exit -1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
56
update-version.bash
Executable file
56
update-version.bash
Executable file
@ -0,0 +1,56 @@
|
|||||||
|
#######################################################################
|
||||||
|
##- @Copyright (C) Huawei Technologies., Ltd. 2017-2019. All rights reserved.
|
||||||
|
# - lcr licensed under the Mulan PSL v1.
|
||||||
|
# - You can use this software according to the terms and conditions of the Mulan PSL v1.
|
||||||
|
# - You may obtain a copy of Mulan PSL v1 at:
|
||||||
|
# - http://license.coscl.org.cn/MulanPSL
|
||||||
|
# - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||||
|
# - IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
||||||
|
# - PURPOSE.
|
||||||
|
# - See the Mulan PSL v1 for more details.
|
||||||
|
##- @Description: generate cetification
|
||||||
|
##- @Author: wujing
|
||||||
|
##- @Create: 2019-04-25
|
||||||
|
#######################################################################
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# usage
|
||||||
|
# ./update-version.bash
|
||||||
|
topDir=$(git rev-parse --show-toplevel)
|
||||||
|
specfile="${topDir}/lcr.spec"
|
||||||
|
CMakefile="${topDir}/CMakeLists.txt"
|
||||||
|
old_version=$(cat ${specfile} | grep "%global" | grep "_version" | awk {'print $3'})
|
||||||
|
first_old_version=$(cat ${specfile} | grep "%global" | grep "_version" | awk {'print $3'} | awk -F "." {'print $1'})
|
||||||
|
second_old_version=$(cat ${specfile} | grep "%global" | grep "_version" | awk {'print $3'} | awk -F "." {'print $2'})
|
||||||
|
third_old_version=$(cat ${specfile} | grep "%global" | grep "_version" | awk {'print $3'} | awk -F "." {'print $3'})
|
||||||
|
read -p "Which level version do you want to upgrade?[1/2/3/d/N](default:N) select:" choice
|
||||||
|
if [[ ! -n "${choice}" || ${choice} == "N" ]]; then
|
||||||
|
echo "The version number has not been modified, it is still ${old_version}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${choice} -eq "1" ]]; then
|
||||||
|
first_old_version=$(($first_old_version+1))
|
||||||
|
second_old_version="0"
|
||||||
|
third_old_version="0"
|
||||||
|
elif [[ ${choice} -eq "2" ]]; then
|
||||||
|
second_old_version=$(($second_old_version+1))
|
||||||
|
third_old_version="0"
|
||||||
|
elif [[ ${choice} -eq "3" ]]; then
|
||||||
|
third_old_version=$(($third_old_version+1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
new_version=${first_old_version}.${second_old_version}.${third_old_version}
|
||||||
|
|
||||||
|
echo "The version number has been modified: ${old_version} => ${new_version}"
|
||||||
|
|
||||||
|
old_release=$(cat ${specfile} | grep "%global" | grep "_release" | awk {'print $3'})
|
||||||
|
commit_id_long=`git log --pretty=oneline -1 | awk {'print $1'}`
|
||||||
|
commit_id=${commit_id_long:0:8}
|
||||||
|
new_release=`date "+%Y%m%d"`.`date "+%H%M%S"`.git$commit_id
|
||||||
|
echo "The relase version has been modified, it is ${new_release}"
|
||||||
|
sed -i "s/set(LCR_VERSION \"${old_version}\")/set(LCR_VERSION \"${new_version}\")/g" ${CMakefile}
|
||||||
|
sed -i "s/^\%global _version ${old_version}$/\%global _version ${new_version}/g" ${specfile}
|
||||||
|
sed -i "s/^\%global _release ${old_release}$/\%global _release ${new_release}/g" ${specfile}
|
||||||
|
|
||||||
|
echo "The release number has been modified: ${old_release} => ${new_release}"
|
||||||
Loading…
x
Reference in New Issue
Block a user