├── AUTHORS ├── README.md ├── TODO ├── makefile ├── ChangeLog-CN ├── iconv_README.sh ├── src ├── makefile ├── util │ ├── LOGC.c │ ├── LOGC.h │ ├── makefile │ ├── makefile.Linux │ ├── version.c │ ├── socket.c │ ├── filerpl.h │ ├── pts.c │ ├── string.c │ ├── file.c │ ├── cocker_util.h │ ├── list.c │ ├── filerpl.c │ └── list.h ├── makefile.Linux ├── cocker │ ├── makefile │ ├── cocker_in.h │ ├── makefile.Linux │ ├── show_container_root.c │ ├── action_vip.c │ ├── action_port_mapping.c │ ├── action_getfile.c │ ├── action_putfile.c │ ├── action_volume.c │ ├── action_export.c │ ├── action_install_test.c │ ├── action_rplfile.c │ ├── action_version.c │ ├── action_del_image.c │ ├── action_copy_image.c │ ├── action_shutdown.c │ ├── action_import.c │ ├── action_spush.c │ ├── show_ssearch.c │ ├── action_to_container.c │ ├── util.c │ ├── action_spull.c │ ├── action_destroy.c │ ├── env.c │ ├── action_to_image.c │ ├── action_run.c │ ├── action_attach.c │ ├── show_images.c │ ├── show_containers.c │ ├── action_create.c │ └── main.c └── cockerinit │ ├── makefile │ ├── makefile.Linux │ ├── cockerinit_in.h │ ├── main.c │ ├── pts_and_tcp_bridge.c │ ├── pty.c │ └── server.c ├── README.zh-CN.md ├── makefile.Linux ├── shbin ├── makefile ├── makefile.Linux ├── cocker_etc_profile_template.sh ├── cocker_container_root.sh ├── cocker_ldd_and_cp_lib64.sh ├── cocker_profile_template.sh ├── cocker_create_image_rhel-7.4-gcc-x86_64.sh ├── cocker_create_image_rhel-7.4-sshd-x86_64.sh ├── cocker_create_image_rhel-7.4-x86_64.sh └── cocker_install_test.sh ├── images ├── cocker.vsd ├── cocker_pty.png ├── cocker_cgroup.png ├── cocker_network.png ├── cocker_overlayfs.png ├── cocker_architecture.png └── cocker_state_transition_diagram.png ├── doc └── container_coretech_and_cocker.ppt ├── makeinstall └── .gitignore /AUTHORS: -------------------------------------------------------------------------------- 1 | calvin calvinwilliams@163.com 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | see README.zh-CN.md in Chinese -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/TODO -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/makefile -------------------------------------------------------------------------------- /ChangeLog-CN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/ChangeLog-CN -------------------------------------------------------------------------------- /iconv_README.sh: -------------------------------------------------------------------------------- 1 | iconv -f GB18030 -t UTF-8 README.zh-CN.md >README.zh-CN.UTF8.md 2 | -------------------------------------------------------------------------------- /src/makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/makefile -------------------------------------------------------------------------------- /README.zh-CN.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/README.zh-CN.md -------------------------------------------------------------------------------- /makefile.Linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/makefile.Linux -------------------------------------------------------------------------------- /shbin/makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/shbin/makefile -------------------------------------------------------------------------------- /src/util/LOGC.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/util/LOGC.c -------------------------------------------------------------------------------- /src/util/LOGC.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/util/LOGC.h -------------------------------------------------------------------------------- /images/cocker.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/images/cocker.vsd -------------------------------------------------------------------------------- /src/makefile.Linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/makefile.Linux -------------------------------------------------------------------------------- /src/util/makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/util/makefile -------------------------------------------------------------------------------- /shbin/makefile.Linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/shbin/makefile.Linux -------------------------------------------------------------------------------- /src/cocker/makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/cocker/makefile -------------------------------------------------------------------------------- /images/cocker_pty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/images/cocker_pty.png -------------------------------------------------------------------------------- /src/cocker/cocker_in.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/cocker/cocker_in.h -------------------------------------------------------------------------------- /src/cockerinit/makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/cockerinit/makefile -------------------------------------------------------------------------------- /src/util/makefile.Linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/util/makefile.Linux -------------------------------------------------------------------------------- /images/cocker_cgroup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/images/cocker_cgroup.png -------------------------------------------------------------------------------- /images/cocker_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/images/cocker_network.png -------------------------------------------------------------------------------- /src/cocker/makefile.Linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/cocker/makefile.Linux -------------------------------------------------------------------------------- /images/cocker_overlayfs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/images/cocker_overlayfs.png -------------------------------------------------------------------------------- /images/cocker_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/images/cocker_architecture.png -------------------------------------------------------------------------------- /src/cockerinit/makefile.Linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/src/cockerinit/makefile.Linux -------------------------------------------------------------------------------- /doc/container_coretech_and_cocker.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/doc/container_coretech_and_cocker.ppt -------------------------------------------------------------------------------- /images/cocker_state_transition_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinwilliams/cocker/HEAD/images/cocker_state_transition_diagram.png -------------------------------------------------------------------------------- /makeinstall: -------------------------------------------------------------------------------- 1 | _HDERBASE = /usr/include 2 | _LIBBASE = /lib64 3 | _BINBASE = /bin 4 | 5 | _CFLAGS = -I. -I$(_HDERBASE) -I/usr/include 6 | _LFLAGS = -L. -L$(_LIBBASE) -L/usr/lib64 -L/usr/lib 7 | 8 | _HDERINST = $(_HDERBASE) 9 | _LIBINST = $(_LIBBASE) 10 | _BININST = $(_BINBASE) 11 | 12 | -------------------------------------------------------------------------------- /src/util/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_util.h" 10 | 11 | char _COCKER_VERSION_0_28_0[] = "0.28.0" ; 12 | char *_COCKER_VERSION = _COCKER_VERSION_0_28_0 ; 13 | 14 | -------------------------------------------------------------------------------- /shbin/cocker_etc_profile_template.sh: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # cocker - Container Machine Engine 3 | # author : calvin 4 | # email : calvinwilliams@163.com 5 | # 6 | # Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | ###################################################################### 8 | 9 | set -o vi 10 | 11 | export PATH=.:/bin:/usr/bin:/usr/local/bin 12 | export TERM=xterm 13 | 14 | echo "--- Welcome to cocker contrainer ---" 15 | echo "" 16 | 17 | -------------------------------------------------------------------------------- /shbin/cocker_container_root.sh: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # cocker - Container Machine Engine 3 | # author : calvin 4 | # email : calvinwilliams@163.com 5 | # 6 | # Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | ###################################################################### 8 | 9 | #!/bin/bash 10 | 11 | if [ $# -ne 1 ] ; then 12 | echo "USAGE : . cocker_container_root.sh (container)" 13 | exit 1 14 | fi 15 | 16 | CONTAINER=$1 17 | 18 | export COCKER_CONTAINER_ROOT=`cocker -s container_root -c $CONTAINER` 19 | 20 | -------------------------------------------------------------------------------- /shbin/cocker_ldd_and_cp_lib64.sh: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # cocker - Container Machine Engine 3 | # author : calvin 4 | # email : calvinwilliams@163.com 5 | # 6 | # Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | ###################################################################### 8 | 9 | #!/bin/bash 10 | 11 | mkdir -p ../lib ../lib64 12 | 13 | ls -1 | while read EXEFILE ; do 14 | ldd $EXEFILE | awk '{if(NF==4&&$2=="=>")print $3;else if(NF==2)print $1}' | while read LIBFILE ; do 15 | if [ ! -f ..$LIBFILE ] ; then 16 | cp $LIBFILE ../lib64/ 17 | fi 18 | done 19 | done 20 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /shbin/cocker_profile_template.sh: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # cocker - Container Machine Engine 3 | # author : calvin 4 | # email : calvinwilliams@163.com 5 | # 6 | # Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | ###################################################################### 8 | 9 | export PATH=.:/bin:/usr/bin:/usr/local/bin 10 | export PATH=.:/sbin:/usr/sbin:/usr/local/sbin:$PATH 11 | 12 | alias l='ls -l' 13 | alias ll='ls -lF' 14 | alias lf='ls -F' 15 | alias lrt='ls -lrt' 16 | 17 | alias rm='rm -i' 18 | alias mv='mv -i' 19 | alias cp='cp -i' 20 | 21 | alias view='vi -R' 22 | 23 | set -o vi 24 | 25 | OSNAME=`uname -a|awk '{print $1}'` 26 | HOSTNAME=`hostname` 27 | USERNAME=$LOGNAME 28 | export PS1='[$USERNAME@$HOSTNAME $PWD] ' 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/cockerinit/cockerinit_in.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #ifndef _H_COCKERINIT_IN_ 10 | #define _H_COCKERINIT_IN_ 11 | 12 | #include "cocker_util.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | struct CommandParameter 19 | { 20 | char *__container_id ; 21 | char *__single ; 22 | } ; 23 | 24 | struct CockerInitEnvironment 25 | { 26 | struct CommandParameter cmd_para ; 27 | 28 | int alive_pipe_0 ; 29 | 30 | int listen_sock ; 31 | struct sockaddr_un listen_addr ; 32 | int accepted_sock ; 33 | struct sockaddr_un accepted_addr ; 34 | 35 | int ptm_fd ; 36 | pid_t bash_pid ; 37 | } ; 38 | 39 | int server( struct CockerInitEnvironment *env ); 40 | int create_pty( struct CockerInitEnvironment *env ); 41 | int pts_and_tcp_bridge( struct CockerInitEnvironment *env ); 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /src/cocker/show_container_root.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoShow_container_root( struct CockerEnvironment *env ) 12 | { 13 | char container_root_path[ PATH_MAX + 1 ] ; 14 | 15 | int nret = 0 ; 16 | 17 | SetLogcFile( "/var/cocker/cocker.log" ); 18 | SetLogcLevel( LOGCLEVEL_INFO ); 19 | 20 | /* preprocess input parameters */ 21 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 22 | nret = access( env->container_path_base , F_OK ) ; 23 | INTER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__container ) 24 | 25 | Snprintf( container_root_path , sizeof(container_root_path) , "%s/merged" , env->container_path_base ); 26 | 27 | /* get container root */ 28 | printf( "%s\n" , container_root_path ); 29 | 30 | return 0; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/cocker/action_vip.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_vip( struct CockerEnvironment *env ) 12 | { 13 | char container_vip_file[ PATH_MAX + 1 ] ; 14 | 15 | int nret = 0 ; 16 | 17 | /* preprocess input parameters */ 18 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 19 | nret = access( env->container_path_base , F_OK ) ; 20 | I1TER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__container ) 21 | 22 | /* modify vip */ 23 | nret = WriteFileLine( env->cmd_para.__vip , container_vip_file , sizeof(container_vip_file) , "%s/vip" , env->container_path_base ) ; 24 | INTER1( "*** ERROR : WriteFileLine vip failed[%d] , errno[%d]\n" , nret , errno ) 25 | EIDTE( "write file [%s] ok\n" , container_vip_file ) 26 | 27 | printf( "OK\n" ); 28 | 29 | return 0; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/cocker/action_port_mapping.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_port_mapping( struct CockerEnvironment *env ) 12 | { 13 | char container_port_mapping_file[ PATH_MAX + 1 ] ; 14 | 15 | int nret = 0 ; 16 | 17 | /* preprocess input parameters */ 18 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 19 | nret = access( env->container_path_base , F_OK ) ; 20 | I1TER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__container ) 21 | 22 | /* modify port mapping */ 23 | nret = WriteFileLine( env->cmd_para.__port_mapping , container_port_mapping_file , sizeof(container_port_mapping_file) , "%s/port_mapping" , env->container_path_base ) ; 24 | INTER1( "*** ERROR : WriteFileLine port_mapping failed[%d] , errno[%d]\n" , nret , errno ) 25 | EIDTE( "write file [%s] ok\n" , container_port_mapping_file ) 26 | 27 | printf( "OK\n" ); 28 | 29 | return 0; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/cocker/action_getfile.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_getfile( struct CockerEnvironment *env ) 12 | { 13 | char src_file[ PATH_MAX + 1 ] ; 14 | char cmd[ 4096 ] ; 15 | 16 | int nret = 0 ; 17 | 18 | SetLogcFile( "/var/cocker/cocker.log" ); 19 | SetLogcLevel( LOGCLEVEL_INFO ); 20 | 21 | /* preprocess input parameters */ 22 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 23 | nret = access( env->container_path_base , F_OK ) ; 24 | INTER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__container ) 25 | 26 | Snprintf( src_file , sizeof(src_file)-1 , "%s/merged%s" , env->container_path_base , env->cmd_para.__src_file ); 27 | nret = access( src_file , F_OK ) ; 28 | INTER1( "*** ERROR : src file '%s' not found\n" , src_file ) 29 | 30 | /* get file */ 31 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "cp -rf %s %s" , src_file , env->cmd_para.__dst_file ); 32 | INTER1( "*** ERROR : system [%s] failed[%d]\\n" , cmd , nret ) 33 | 34 | printf( "OK\n" ); 35 | 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/cocker/action_putfile.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_putfile( struct CockerEnvironment *env ) 12 | { 13 | char dst_file[ PATH_MAX + 1 ] ; 14 | char cmd[ 4096 ] ; 15 | 16 | int nret = 0 ; 17 | 18 | SetLogcFile( "/var/cocker/cocker.log" ); 19 | SetLogcLevel( LOGCLEVEL_INFO ); 20 | 21 | /* preprocess input parameters */ 22 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 23 | nret = access( env->container_path_base , F_OK ) ; 24 | INTER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__container ) 25 | 26 | nret = access( env->cmd_para.__src_file , F_OK ) ; 27 | INTER1( "*** ERROR : src file '%s' not found\n" , env->cmd_para.__src_file ) 28 | 29 | Snprintf( dst_file , sizeof(dst_file)-1 , "%s/merged%s" , env->container_path_base , env->cmd_para.__dst_file ); 30 | 31 | /* put file */ 32 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "cp -rf %s %s" , env->cmd_para.__src_file , dst_file ); 33 | INTER1( "*** ERROR : system [%s] failed[%d]\\n" , cmd , nret ) 34 | 35 | printf( "OK\n" ); 36 | 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /shbin/cocker_create_image_rhel-7.4-gcc-x86_64.sh: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # cocker - Container Machine Engine 3 | # author : calvin 4 | # email : calvinwilliams@163.com 5 | # 6 | # Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | ###################################################################### 8 | 9 | #!/bin/bash 10 | 11 | which supermin5 >/dev/null 12 | if [ $? -ne 0 ] ; then 13 | echo "*** ERROR : Install supermin5 first" 14 | fi 15 | 16 | printf "Your name or enter null : " 17 | read MY_NAME 18 | if [ x"${MY_NAME}" != x"" ] ; then 19 | MY_NAME="${MY_NAME}=" 20 | fi 21 | 22 | printf "Version or enter null : " 23 | read VERSION 24 | if [ x"${VERSION}" != x"" ] ; then 25 | VERSION=":${VERSION}" 26 | fi 27 | 28 | IMAGE_FILENAME="${MY_NAME}rhel-7.4-gcc-x86_64${VERSION}.cockerimage" 29 | 30 | rm -rf appliance.d supermin.d 31 | 32 | rm -f ${IMAGE_FILENAME} 33 | 34 | supermin5 -v --prepare coreutils -o supermin.d 35 | supermin5 -v --prepare gcc make -o supermin.d 36 | supermin5 -v --build --format chroot supermin.d -o appliance.d 37 | 38 | IMAGE_RLAYER_PATH_BASE="appliance.d" 39 | 40 | rm -f ${IMAGE_RLAYER_PATH_BASE}/usr/bin/ld 41 | cp -f /usr/bin/ld ${IMAGE_RLAYER_PATH_BASE}/usr/bin/ 42 | 43 | cd appliance.d && tar --numeric-owner -cvzf ../${IMAGE_FILENAME} * && cd .. 44 | 45 | rm -rf appliance.d supermin.d 46 | 47 | -------------------------------------------------------------------------------- /src/util/socket.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_util.h" 10 | 11 | int writen( int sock , char *send_buffer , int send_len , int *p_sent_len ) 12 | { 13 | int len , remain_len , sent_len ; 14 | 15 | remain_len = send_len ; 16 | sent_len = 0 ; 17 | 18 | while( remain_len > 0 ) 19 | { 20 | len = write( sock , send_buffer+sent_len , remain_len ) ; 21 | if( len == -1 ) 22 | { 23 | if( p_sent_len ) 24 | (*p_sent_len) = sent_len ; 25 | return -1; 26 | } 27 | 28 | sent_len += len ; 29 | remain_len -= len ; 30 | } 31 | 32 | if( p_sent_len ) 33 | (*p_sent_len) = sent_len ; 34 | 35 | return 0; 36 | } 37 | 38 | int readn( int sock , char *recv_buffer , int recv_len , int *p_received_len ) 39 | { 40 | int len , remain_len ; 41 | 42 | remain_len = recv_len ; 43 | recv_len = 0 ; 44 | if( p_received_len ) 45 | (*p_received_len) = 0 ; 46 | 47 | while( remain_len > 0 ) 48 | { 49 | len = read( sock , recv_buffer+recv_len , remain_len ) ; 50 | if( len == 0 ) 51 | { 52 | if( p_received_len ) 53 | (*p_received_len) = recv_len ; 54 | return 1; 55 | } 56 | else if( len == -1 ) 57 | { 58 | if( p_received_len ) 59 | (*p_received_len) = recv_len ; 60 | return -1; 61 | } 62 | 63 | recv_len += len ; 64 | remain_len -= len ; 65 | } 66 | 67 | if( p_received_len ) 68 | (*p_received_len) = recv_len ; 69 | 70 | return 0; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /src/cocker/action_volume.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_volume( struct CockerEnvironment *env ) 12 | { 13 | char container_volume_file[ PATH_MAX + 1 ] ; 14 | FILE *container_volume_fp = NULL ; 15 | struct CockerVolume *volume = NULL ; 16 | 17 | int nret = 0 ; 18 | 19 | /* preprocess input parameters */ 20 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 21 | nret = access( env->container_path_base , F_OK ) ; 22 | I1TER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__container ) 23 | 24 | /* modify volume */ 25 | if( ! list_empty( & (env->cmd_para.volume_list) ) ) 26 | { 27 | Snprintf( container_volume_file , sizeof(container_volume_file) , "%s/volume" , env->container_path_base ) ; 28 | container_volume_fp = fopen( container_volume_file , "w" ) ; 29 | IxTER1( (container_volume_fp==NULL) , "*** ERROR : WriteFileLine volume failed[%d] , errno[%d]\n" , nret , errno ) 30 | 31 | list_for_each_entry( volume , & (env->cmd_para.volume_list) , struct CockerVolume , volume_node ) 32 | { 33 | fprintf( container_volume_fp , "%.*s:%s\n" , volume->host_path_len , volume->host_path , volume->container_path ); 34 | IDTI( "write file %s [%.*s:%s]\n" , container_volume_file , volume->host_path_len , volume->host_path , volume->container_path ) 35 | } 36 | 37 | fclose( container_volume_fp ); 38 | } 39 | 40 | printf( "OK\n" ); 41 | 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/util/filerpl.h: -------------------------------------------------------------------------------- 1 | #ifndef _H_FILERPL_ 2 | #define _H_FILERPL_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | #define FILERPL_ERROR_PARAMETER -11 19 | #define FILERPL_ERROR_MALLOC -21 20 | #define FILERPL_ERROR_REALLOC -22 21 | #define FILERPL_ERROR_OPEN -31 22 | #define FILERPL_ERROR_FSTAT -32 23 | #define FILERPL_ERROR_READ -33 24 | #define FILERPL_ERROR_MMAP -34 25 | #define FILERPL_ERROR_WRITE -35 26 | #define FILERPL_ERROR_MAP_INVALID_1 -101 27 | #define FILERPL_ERROR_MAP_INVALID_2 -102 28 | #define FILERPL_ERROR_MAP_INVALID_3 -103 29 | #define FILERPL_ERROR_MAP_INVALID_4 -104 30 | #define FILERPL_ERROR_MAP_INVALID_5 -105 31 | #define FILERPL_ERROR_MAP_INVALID_6 -106 32 | 33 | 34 | int filerpl( char *tpl_pathfilename , char *map_pathfilename , char *ins_pathfilename ); 35 | 36 | int strrpl( char **pp_buf , int *p_buf_len , int *p_buf_size , char *key , int key_len , char *value , int value_len ); 37 | 38 | int LoadRplTemplateFile( char *tpl_pathfilename , char **pp_tpl_buf , int *p_tpl_buf_len , int *p_tpl_buf_size ); 39 | int LoadRplMappingFile( char *map_pathfilename , char **pp_map_buf , int *p_map_buf_len , int *p_map_buf_size ); 40 | int ConvertRplBuffer( char **pp_ins_buf , int *p_ins_buf_len , int *p_ins_buf_size , char *p_map_buf , int map_buf_len ); 41 | int DumpRplInstanceFile( char *p_ins_buf , int ins_buf_len , char *ins_pathfilename ); 42 | 43 | int FreeRplBuffer( char **pp_buf , int *p_buf_len , int *p_buf_size ); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif 50 | 51 | -------------------------------------------------------------------------------- /src/cocker/action_export.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_export( struct CockerEnvironment *env ) 12 | { 13 | char image[ IMAGES_ID_LEN_MAX + 1 ] ; 14 | char version[ PATH_MAX + 1 ] ; 15 | char image_file[ PATH_MAX + 1 ] ; 16 | char current_path[ PATH_MAX + 1 ] ; 17 | char cmd[ 4096 ] ; 18 | 19 | int nret = 0 ; 20 | 21 | /* preprocess input parameters */ 22 | Snprintf( image , sizeof(image) , "%s" , env->cmd_para.__image ); 23 | SplitImageVersion( image , version , sizeof(version) ); 24 | 25 | Snprintf( image_file , sizeof(image_file) , "%s%s%s.cockerimage" , image , (version[0]?":":"") , version ); 26 | 27 | Snprintf( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s/%s" , env->images_path_base , image , (version[0]?version:"_") ); 28 | nret = access( env->image_path_base , F_OK ) ; 29 | I1TER1( "*** ERROR : image '%s' not found\n" , env->cmd_para.__image ) 30 | 31 | /* pack image folders and files */ 32 | memset( current_path , 0x00 , sizeof(current_path) ); 33 | getcwd( current_path , sizeof(current_path) ); 34 | 35 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "cd %s/rlayer/ && tar --force-local -czf %s * && mv %s %s/" , env->image_path_base , image_file , image_file , current_path ) ; 36 | INTER1( "*** ERROR : SnprintfAndSystem [cd %s/rlayer/ && tar --force-local -czf %s * && mv %s %s/] failed[%d] , errno[%d]\n" , env->image_path_base , image_file , image_file , current_path , nret , errno ) 37 | EIDTI( "system [%s] ok\n" , cmd ) 38 | 39 | printf( "OK\n" ); 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /shbin/cocker_create_image_rhel-7.4-sshd-x86_64.sh: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # cocker - Container Machine Engine 3 | # author : calvin 4 | # email : calvinwilliams@163.com 5 | # 6 | # Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | ###################################################################### 8 | 9 | #!/bin/bash 10 | 11 | which supermin5 >/dev/null 12 | if [ $? -ne 0 ] ; then 13 | echo "*** ERROR : Install supermin5 first" 14 | fi 15 | 16 | printf "Your name or enter null : " 17 | read MY_NAME 18 | if [ x"${MY_NAME}" != x"" ] ; then 19 | MY_NAME="${MY_NAME}=" 20 | fi 21 | 22 | printf "Version or enter null : " 23 | read VERSION 24 | if [ x"${VERSION}" != x"" ] ; then 25 | VERSION=":${VERSION}" 26 | fi 27 | 28 | IMAGE_FILENAME="${MY_NAME}rhel-7.4-sshd-x86_64${VERSION}.cockerimage" 29 | 30 | rm -rf appliance.d supermin.d 31 | 32 | rm -f ${IMAGE_FILENAME} 33 | 34 | supermin5 -v --prepare openssh-server -o supermin.d 35 | supermin5 -v --build --format chroot supermin.d -o appliance.d 36 | 37 | IMAGE_RLAYER_PATH_BASE="appliance.d" 38 | 39 | echo "sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin" >>${IMAGE_RLAYER_PATH_BASE}/etc/passwd 40 | # echo "root:root" | chpasswd -R ${IMAGE_RLAYER_PATH_BASE} 41 | # echo "calvin:calvin" | chpasswd -R ${IMAGE_RLAYER_PATH_BASE} 42 | ssh-keygen -t rsa -f ${IMAGE_RLAYER_PATH_BASE}/etc/ssh/ssh_host_rsa_key 43 | ssh-keygen -t rsa -f ${IMAGE_RLAYER_PATH_BASE}/etc/ssh/ssh_host_ecdsa_key 44 | 45 | cd appliance.d && tar --numeric-owner -cvzf ../${IMAGE_FILENAME} * && cd .. 46 | 47 | rm -rf appliance.d supermin.d 48 | 49 | echo "NOTICE : run 'passwd root' later in container" 50 | echo "NOTICE : run 'nohup /usr/sbin/sshd -D' later in container" 51 | 52 | -------------------------------------------------------------------------------- /src/cocker/action_install_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_install_test( struct CockerEnvironment *env ) 12 | { 13 | char version_path_base[ PATH_MAX + 1 ] ; 14 | char image_rlayer_path[ PATH_MAX + 1 ] ; 15 | char cmd[ 4096 ] ; 16 | 17 | int nret = 0 ; 18 | 19 | /* preprocess input parameters */ 20 | nret = SnprintfAndMakeDir( version_path_base , sizeof(version_path_base)-1 , "%s/test" , env->images_path_base ) ; 21 | if( env->cmd_para.__version ) 22 | { 23 | nret = SnprintfAndMakeDir( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s" , version_path_base , env->cmd_para.__version ) ; 24 | } 25 | else 26 | { 27 | nret = SnprintfAndMakeDir( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/_" , version_path_base ) ; 28 | } 29 | INTER1( "*** ERROR : SnprintfAndMakeDir image_path_base failed[%d] , errno[%d]\n" , nret , errno ) 30 | EIDTI( "mkdir %s ok\n" , env->image_path_base ) 31 | 32 | /* create image */ 33 | nret = SnprintfAndMakeDir( image_rlayer_path , sizeof(image_rlayer_path)-1 , "%s/rlayer" , env->image_path_base ) ; 34 | INTER1( "*** ERROR : SnprintfAndMakeDir rlayer failed[%d] , errno[%d]\n" , nret , errno ) 35 | EIDTI( "mkdir %s ok\n" , image_rlayer_path ) 36 | 37 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "cocker_install_test.sh %s" , image_rlayer_path ) ; 38 | INTER1( "*** ERROR : SnprintfAndSystem [cocker_install_test.sh %s] failed[%d] , errno[%d]\n" , env->image_path_base , nret , errno ) 39 | EIDTI( "system [%s] ok\n" , cmd ) 40 | 41 | printf( "OK\n" ); 42 | 43 | return 0; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/cocker/action_rplfile.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_rplfile( struct CockerEnvironment *env ) 12 | { 13 | char template_file[ PATH_MAX + 1 ] ; 14 | char instance_file[ PATH_MAX + 1 ] ; 15 | 16 | int nret = 0 ; 17 | 18 | SetLogcFile( "/var/cocker/cocker.log" ); 19 | SetLogcLevel( LOGCLEVEL_INFO ); 20 | 21 | /* preprocess input parameters */ 22 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 23 | nret = access( env->container_path_base , F_OK ) ; 24 | INTER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__container ) 25 | 26 | Snprintf( template_file , sizeof(template_file)-1 , "%s/merged%s" , env->container_path_base , env->cmd_para.__template_file ); 27 | nret = access( template_file , F_OK ) ; 28 | INTER1( "*** ERROR : template file '%s' not found\n" , template_file ) 29 | 30 | if( env->cmd_para.__instance_file ) 31 | { 32 | Snprintf( instance_file , sizeof(instance_file)-1 , "%s/merged%s" , env->container_path_base , env->cmd_para.__instance_file ); 33 | } 34 | else 35 | { 36 | strncpy( instance_file , template_file , sizeof(instance_file)-1 ); 37 | } 38 | 39 | /* replace file */ 40 | if( env->cmd_para.__debug ) 41 | { 42 | I( "filerpl [%s] [%s] [%s]\n" , template_file , env->cmd_para.__mapping_file , instance_file ) 43 | } 44 | nret = filerpl( template_file , env->cmd_para.__mapping_file , instance_file ) ; 45 | INTER1( "*** ERROR : filerpl failed[%d]\\n" , nret ) 46 | 47 | printf( "OK\n" ); 48 | 49 | return 0; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/cocker/action_version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_version( struct CockerEnvironment *env ) 12 | { 13 | char image[ IMAGES_ID_LEN_MAX + 1 ] ; 14 | char old_version[ PATH_MAX + 1 ] ; 15 | char new_version[ PATH_MAX + 1 ] ; 16 | char cmd[ 4096 ] ; 17 | 18 | int nret = 0 ; 19 | 20 | /* preprocess input parameters */ 21 | memset( image , 0x00 , sizeof(image) ); 22 | strncpy( image , env->cmd_para.__image , sizeof(image)-1 ); 23 | SplitImageVersion( image , old_version , sizeof(old_version) ); 24 | if( old_version[0] == '\0' ) 25 | strcpy( old_version , "_" ); 26 | 27 | Snprintf( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s/%s" , env->images_path_base , image , old_version ); 28 | nret = access( env->image_path_base , F_OK ) ; 29 | I1TER1( "*** ERROR : image '%s' not found\n" , env->cmd_para.__image ) 30 | 31 | memset( new_version , 0x00 , sizeof(new_version) ); 32 | if( env->cmd_para.__version ) 33 | { 34 | strncpy( new_version , env->cmd_para.__version , sizeof(new_version)-1 ); 35 | } 36 | if( new_version[0] == '\0' ) 37 | { 38 | strcpy( new_version , "_" ); 39 | } 40 | 41 | /* modify version */ 42 | IxTER1( (STRCMP( old_version,==,new_version)) , "version equal\n" ) 43 | 44 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "mv %s/%s/%s %s/%s/%s" , env->images_path_base , image , old_version , env->images_path_base , image , new_version ) ; 45 | INTER1( "*** ERROR : SnprintfAndSystem [mv %s/%s/%s %s/%s/%s] failed[%d] , errno[%d]\n" , env->images_path_base , image , old_version , env->images_path_base , image , new_version , nret , errno ) 46 | EIDTI( "modify version ok\n" ) 47 | 48 | printf( "OK\n" ); 49 | 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/cockerinit/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cockerinit_in.h" 10 | 11 | int main( int argc , char *argv[] ) 12 | { 13 | struct CockerInitEnvironment *env = NULL ; 14 | int i ; 15 | char *p = NULL ; 16 | 17 | int nret = 0 ; 18 | 19 | SetLogcFile( "/cockerinit.log" ); 20 | SetLogcLevel( LOGCLEVEL_INFO ); 21 | 22 | INFOLOGC( "--- cockerinit begin ---" ) 23 | 24 | env = (struct CockerInitEnvironment *)malloc( sizeof(struct CockerInitEnvironment) ) ; 25 | if( env == NULL ) 26 | { 27 | E( "*** ERROR : malloc failed , errno[%d]\n" , errno ) 28 | return 1; 29 | } 30 | memset( env , 0x00 , sizeof(struct CockerInitEnvironment) ); 31 | 32 | for( i = 1 ; i < argc ; i++ ) 33 | { 34 | if( STRCMP( argv[i] , == , "-v" ) ) 35 | { 36 | E( "cockerinit v%s build %s %s\n" , _COCKER_VERSION , __DATE__ , __TIME__ ) 37 | free( env ); 38 | exit(0); 39 | } 40 | else if( STRCMP( argv[i] , == , "--container" ) && i + 1 < argc ) 41 | { 42 | env->cmd_para.__container_id = argv[i+1] ; 43 | i++; 44 | } 45 | else if( STRCMP( argv[i] , == , "--single" ) ) 46 | { 47 | env->cmd_para.__single = argv[i] ; 48 | } 49 | else 50 | { 51 | E( "*** ERROR : invalid parameter '%s'\n" , argv[i] ) 52 | return -7; 53 | } 54 | } 55 | if( env->cmd_para.__container_id == NULL ) 56 | { 57 | E( "*** ERROR : '--container' need for running\n" ) 58 | return -7; 59 | } 60 | 61 | p = getenv( "COCKER_ALIVE_PIPE" ) ; 62 | if( p == NULL ) 63 | { 64 | E( "*** ERROR : please run me by cocker\n" ) 65 | return 1; 66 | } 67 | else 68 | { 69 | I( "getenv(\"COCKER_ALIVE_PIPE\")[%s]\n" , p ) 70 | } 71 | env->alive_pipe_0 = atoi(p) ; 72 | 73 | nret = server( env ) ; 74 | 75 | free( env ); 76 | 77 | INFOLOGC( "--- cockerinit end ---" ) 78 | 79 | return -nret; 80 | } 81 | -------------------------------------------------------------------------------- /src/cocker/action_del_image.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_del_image( struct CockerEnvironment *env ) 12 | { 13 | char image[ IMAGES_ID_LEN_MAX + 1 ] ; 14 | char version[ PATH_MAX + 1 ] ; 15 | char version_path_base[ PATH_MAX + 1 ] ; 16 | char image_path_base[ PATH_MAX + 1 ] ; 17 | char image_rlayer_path_base[ PATH_MAX + 1 ] ; 18 | char cmd[ 4096 ] ; 19 | 20 | int nret = 0 ; 21 | 22 | /* preprocess input parameters */ 23 | memset( image , 0x00 , sizeof(image) ); 24 | strncpy( image , env->cmd_para.__image , sizeof(image)-1 ); 25 | SplitImageVersion( image , version , sizeof(version) ); 26 | 27 | Snprintf( version_path_base , sizeof(version_path_base)-1 , "%s/%s" , env->images_path_base , image ); 28 | 29 | Snprintf( image_path_base , sizeof(image_path_base)-1 , "%s/%s/%s" , env->images_path_base , image , (version[0]?version:"_") ); 30 | nret = access( image_path_base , F_OK ) ; 31 | I1TER1( "*** ERROR : image '%s' not found\n" , env->cmd_para.__image ) 32 | 33 | /* del image folders and files */ 34 | Snprintf( image_rlayer_path_base , sizeof(image_rlayer_path_base)-1 , "%s/rlayer" , image_path_base ); 35 | nret = access( image_rlayer_path_base , F_OK ) ; 36 | I1TER1( "*** ERROR : image '%s' invalid\n" , env->cmd_para.__image ) 37 | 38 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "rm -rf %s" , image_path_base ) ; 39 | INTER1( "*** ERROR : SnprintfAndSystem [rm -rf %s] failed[%d] , errno[%d]\n" , image_path_base , nret , errno ) 40 | EIDTI( "system [%s] ok\n" , cmd ) 41 | 42 | if( IsDirectoryEmpty( version_path_base ) == 0 ) 43 | { 44 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "rmdir %s" , version_path_base ) ; 45 | INTER1( "*** ERROR : SnprintfAndSystem [rmdir %s] failed[%d] , errno[%d]\n" , version_path_base , nret , errno ) 46 | EIDTI( "system [%s] ok\n" , cmd ) 47 | } 48 | 49 | printf( "OK\n" ); 50 | 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/cocker/action_copy_image.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_copy_image( struct CockerEnvironment *env ) 12 | { 13 | char from_image[ IMAGES_ID_LEN_MAX + 1 ] ; 14 | char from_version[ PATH_MAX + 1 ] ; 15 | char to_image[ IMAGES_ID_LEN_MAX + 1 ] ; 16 | char to_version[ PATH_MAX + 1 ] ; 17 | char from_image_path_base[ PATH_MAX + 1 ] ; 18 | char to_image_path_base[ PATH_MAX + 1 ] ; 19 | char cmd[ 4096 ] ; 20 | 21 | int nret = 0 ; 22 | 23 | /* preprocess input parameters */ 24 | memset( from_image , 0x00 , sizeof(from_image) ); 25 | strncpy( from_image , env->cmd_para.__from_image , sizeof(from_image)-1 ); 26 | SplitImageVersion( from_image , from_version , sizeof(from_version) ); 27 | 28 | Snprintf( from_image_path_base , sizeof(from_image_path_base)-1 , "%s/%s/%s" , env->images_path_base , from_image , (from_version[0]?from_version:"_") ); 29 | nret = access( from_image_path_base , F_OK ) ; 30 | I1TER1( "*** ERROR : image '%s' not found\n" , env->cmd_para.__from_image ) 31 | 32 | memset( to_image , 0x00 , sizeof(to_image) ); 33 | strncpy( to_image , env->cmd_para.__to_image , sizeof(to_image)-1 ); 34 | SplitImageVersion( to_image , to_version , sizeof(to_version) ); 35 | 36 | Snprintf( to_image_path_base , sizeof(to_image_path_base)-1 , "%s/%s/%s" , env->images_path_base , to_image , (to_version[0]?to_version:"_") ); 37 | nret = access( to_image_path_base , F_OK ) ; 38 | I0TER1( "*** ERROR : image '%s' exist\n" , env->cmd_para.__to_image ) 39 | 40 | /* copy image folders and files */ 41 | SnprintfAndMakeDir( NULL , -1 , "%s/%s" , env->images_path_base , to_image ); 42 | 43 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "cp -rf %s %s" , from_image_path_base , to_image_path_base ) ; 44 | INTER1( "*** ERROR : SnprintfAndSystem [cp -rf %s %s] failed[%d] , errno[%d]\n" , from_image_path_base , to_image_path_base , nret , errno ) 45 | EIDTI( "system [%s] ok\n" , cmd ) 46 | 47 | printf( "OK\n" ); 48 | 49 | return 0; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/cockerinit/pts_and_tcp_bridge.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cockerinit_in.h" 10 | 11 | int pts_and_tcp_bridge( struct CockerInitEnvironment *env ) 12 | { 13 | struct pollfd poll_fds[ 2 ] ; 14 | char buf[ 4096 ] ; 15 | int len ; 16 | 17 | int nret = 0 ; 18 | 19 | while(1) 20 | { 21 | poll_fds[0].fd = env->accepted_sock ; 22 | poll_fds[0].events = POLLIN|POLLHUP ; 23 | poll_fds[0].revents = 0 ; 24 | poll_fds[1].fd = env->ptm_fd ; 25 | poll_fds[1].events = POLLIN|POLLHUP ; 26 | poll_fds[1].revents = 0 ; 27 | nret = poll( poll_fds , 2 , -1 ) ; 28 | if( nret == -1 ) 29 | { 30 | FATALLOGC( "poll failed , errno[%d]\n" , errno ) 31 | return -1; 32 | } 33 | 34 | if( (poll_fds[0].revents&POLLIN) || (poll_fds[0].revents&POLLHUP) ) 35 | { 36 | len = read( env->accepted_sock , buf , sizeof(buf)-1 ) ; 37 | if( len == 0 ) 38 | { 39 | INFOLOGC( "read 0 from accepted sock\n" ) 40 | return 0; 41 | } 42 | else if( len == -1 ) 43 | { 44 | ERRORLOGC( "read from accepted sock failed , errno[%d]\n" , errno ) 45 | return -11; 46 | } 47 | 48 | nret = writen( env->ptm_fd , buf , len , NULL ) ; 49 | if( nret == -1 ) 50 | { 51 | ERRORLOGC( "write to ptm fd failed , errno[%d]\n" , errno ) 52 | return -12; 53 | } 54 | } 55 | 56 | if( (poll_fds[1].revents&POLLIN) || (poll_fds[1].revents&POLLHUP) ) 57 | { 58 | len = read( env->ptm_fd , buf , sizeof(buf)-1 ) ; 59 | if( len == 0 ) 60 | { 61 | INFOLOGC( "read 0 from ptm fd\n" ) 62 | return 0; 63 | } 64 | else if( len == -1 ) 65 | { 66 | if( errno == EIO ) 67 | { 68 | INFOLOGC( "read from ptm fd IOERR , errno[%d]\n" , errno ) 69 | return 0; 70 | } 71 | else 72 | { 73 | ERRORLOGC( "read from ptm fd failed , errno[%d]\n" , errno ) 74 | return -21; 75 | } 76 | } 77 | 78 | nret = writen( env->accepted_sock , buf , len , NULL ) ; 79 | if( nret == -1 ) 80 | { 81 | ERRORLOGC( "write to accepted sock failed , errno[%d]\n" , errno ) 82 | return -22; 83 | } 84 | } 85 | } 86 | 87 | return 0; 88 | } 89 | 90 | -------------------------------------------------------------------------------- /shbin/cocker_create_image_rhel-7.4-x86_64.sh: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # cocker - Container Machine Engine 3 | # author : calvin 4 | # email : calvinwilliams@163.com 5 | # 6 | # Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | ###################################################################### 8 | 9 | #!/bin/bash 10 | 11 | which supermin5 >/dev/null 12 | if [ $? -ne 0 ] ; then 13 | echo "*** ERROR : Install supermin5 first" 14 | fi 15 | 16 | printf "Your name or enter null : " 17 | read MY_NAME 18 | if [ x"${MY_NAME}" != x"" ] ; then 19 | MY_NAME="${MY_NAME}=" 20 | fi 21 | 22 | printf "Version or enter null : " 23 | read VERSION 24 | if [ x"${VERSION}" != x"" ] ; then 25 | VERSION=":${VERSION}" 26 | fi 27 | 28 | IMAGE_FILENAME="${MY_NAME}rhel-7.4-x86_64${VERSION}.cockerimage" 29 | 30 | rm -rf appliance.d supermin.d 31 | 32 | rm -f ${IMAGE_FILENAME} 33 | 34 | supermin5 -v --prepare bash coreutils -o supermin.d 35 | supermin5 -v --prepare bash coreutils which man-db procps-ng hostname vim-minimal file iputils openssh-clients nmap-ncat util-linux tar wget curl net-tools iproute iptables iptables-services sysvinit-tools time bc m4 expect less findutils sysstat iotop ksh tcsh ftp zip gzip at shadow-utils dos2unix psmisc cronie telnet initscripts sudo cups-client lsof tcpdump sysctl glibc-common binutils valgrind strace yum -o supermin.d 36 | supermin5 -v --build --format chroot supermin.d -o appliance.d 37 | 38 | IMAGE_RLAYER_PATH_BASE="appliance.d" 39 | 40 | mknod -m 600 ${IMAGE_RLAYER_PATH_BASE}/dev/console c 5 1 41 | mknod -m 600 ${IMAGE_RLAYER_PATH_BASE}/dev/initctl p 42 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/full c 1 7 43 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/null c 1 3 44 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/zero c 1 5 45 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/random c 1 8 46 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/urandom c 1 9 47 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/ptmx c 5 2 48 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/tty c 5 0 49 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/tty0 c 4 0 50 | mkdir -p ${IMAGE_RLAYER_PATH_BASE}/dev/pts 51 | 52 | cp /bin/cockerinit ${IMAGE_RLAYER_PATH_BASE}/bin/ 53 | cp /lib64/libcocker_util.so ${IMAGE_RLAYER_PATH_BASE}/lib64/ 54 | 55 | cp /etc/resolv.conf ${IMAGE_RLAYER_PATH_BASE}/etc/ 56 | 57 | mkdir -p /mnt/cdrom 58 | 59 | cd appliance.d && tar --numeric-owner -cvzf ../${IMAGE_FILENAME} * && cd .. 60 | 61 | rm -rf appliance.d supermin.d 62 | 63 | -------------------------------------------------------------------------------- /src/cocker/action_shutdown.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int _DoAction_kill( struct CockerEnvironment *env , int signal_no ) 12 | { 13 | char container_pid_file[ PATH_MAX + 1 ] ; 14 | char pid_str[ PID_LEN_MAX + 1 ] ; 15 | pid_t pid ; 16 | 17 | int nret = 0 ; 18 | 19 | /* preprocess input parameters */ 20 | nret = SnprintfAndMakeDir( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ) ; 21 | INTER1( "*** ERROR : SnprintfAndMakeDir[%s] failed[%d]\n" , env->container_path_base , nret ) 22 | 23 | GetEthernetNames( env , env->cmd_para.__container ); 24 | 25 | /* read pid file */ 26 | memset( pid_str , 0x00 , sizeof(pid_str) ); 27 | memset( container_pid_file , 0x00 , sizeof(container_pid_file) ); 28 | nret = ReadFileLine( pid_str , sizeof(pid_str)-1 , container_pid_file , sizeof(container_pid_file) , "%s/pid" , env->container_path_base ) ; 29 | INTER1( "*** ERROR : SnprintfAndUnlink %s failed\n" , container_pid_file ) 30 | 31 | TrimEnter( pid_str ); 32 | 33 | /* stop container */ 34 | pid = atoi(pid_str) ; 35 | if( pid > 0 ) 36 | { 37 | nret = kill( pid , 0 ) ; 38 | if( nret == 0 ) 39 | { 40 | /* kill clone create_pty */ 41 | kill( pid , signal_no ); 42 | 43 | while(1) 44 | { 45 | nret = kill( pid , 0 ) ; 46 | if( nret == -1 ) 47 | { 48 | /* destroy container */ 49 | CleanContainerResource( env ); 50 | break; 51 | } 52 | 53 | sleep(1); 54 | } 55 | } 56 | else 57 | { 58 | printf( "*** ERROR : container[%s] expection\n" , pid_str ); 59 | 60 | if( env->cmd_para.__forcely ) 61 | { 62 | /* destroy container */ 63 | CleanContainerResource( env ); 64 | } 65 | } 66 | } 67 | else 68 | { 69 | printf( "*** ERROR : container is not running\n" ); 70 | } 71 | 72 | return 0; 73 | } 74 | 75 | int DoAction_shutdown( struct CockerEnvironment *env ) 76 | { 77 | int nret = 0 ; 78 | 79 | nret = _DoAction_kill( env , SIGTERM ) ; 80 | if( nret == 0 ) 81 | I( "OK\n" ) 82 | 83 | return nret; 84 | } 85 | 86 | int DoAction_kill( struct CockerEnvironment *env ) 87 | { 88 | int nret = 0 ; 89 | 90 | nret = _DoAction_kill( env , SIGKILL ) ; 91 | if( nret == 0 ) 92 | I( "OK\n" ) 93 | 94 | return nret; 95 | } 96 | 97 | -------------------------------------------------------------------------------- /src/util/pts.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_util.h" 10 | 11 | pid_t pty_fork( struct termios *p_origin_termios , struct winsize *p_origin_winsize , int *p_ptm_fd ) 12 | { 13 | int ptm_fd ; 14 | int pts_fd ; 15 | char pts_pathfilename[ PATH_MAX + 1 ] ; 16 | int lock ; 17 | 18 | pid_t pid ; 19 | 20 | int nret = 0 ; 21 | 22 | ptm_fd = open( "/dev/pts/ptmx" , O_RDWR ) ; 23 | if( ptm_fd == -1 ) 24 | return -1; 25 | 26 | nret = ptsname_r( ptm_fd , pts_pathfilename , sizeof(pts_pathfilename) ) ; 27 | if( nret == -1 ) 28 | { 29 | close( ptm_fd ); 30 | return -2; 31 | } 32 | 33 | nret = chmod( pts_pathfilename , S_IRUSR|S_IWUSR|S_IWGRP ) ; 34 | if( nret == -1 ) 35 | { 36 | close( ptm_fd ); 37 | return -3; 38 | } 39 | 40 | lock = 0 ; 41 | nret = ioctl( ptm_fd , TIOCSPTLCK , & lock ) ; 42 | if( nret == -1 ) 43 | { 44 | close( ptm_fd ); 45 | return -4; 46 | } 47 | 48 | pid = fork() ; 49 | if( pid == -1 ) 50 | { 51 | return -11; 52 | } 53 | else if( pid == 0 ) 54 | { 55 | close( ptm_fd ); 56 | 57 | nret = setsid() ; 58 | if( nret == -1 ) 59 | return -21; 60 | 61 | pts_fd = open( pts_pathfilename , O_RDWR ) ; 62 | if( pts_fd == -1 ) 63 | return -22; 64 | 65 | #if defined(TIOCSCTTY) 66 | nret = ioctl( pts_fd , TIOCSCTTY , NULL ) ; 67 | if( nret == -1 ) 68 | return -23; 69 | #endif 70 | 71 | if( p_origin_termios ) 72 | { 73 | nret = tcsetattr( pts_fd , TCSANOW , p_origin_termios ) ; 74 | if( nret == -1 ) 75 | return -24; 76 | } 77 | 78 | if( p_origin_winsize ) 79 | { 80 | nret = ioctl( pts_fd , TIOCSWINSZ , p_origin_winsize ) ; 81 | if( nret == -1 ) 82 | return -25; 83 | } 84 | 85 | nret = dup2( pts_fd , STDIN_FILENO ) ; 86 | if( nret == -1 ) 87 | return -26; 88 | 89 | nret = dup2( pts_fd , STDOUT_FILENO ) ; 90 | if( nret == -1 ) 91 | return -27; 92 | 93 | nret = dup2( pts_fd , STDERR_FILENO ) ; 94 | if( nret == -1 ) 95 | return -28; 96 | 97 | if( pts_fd != STDIN_FILENO && pts_fd != STDOUT_FILENO && pts_fd != STDERR_FILENO ) 98 | close( pts_fd ); 99 | 100 | return 0; 101 | } 102 | else 103 | { 104 | if( p_ptm_fd ) 105 | (*p_ptm_fd) = ptm_fd ; 106 | 107 | return pid; 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /shbin/cocker_install_test.sh: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # cocker - Container Machine Engine 3 | # author : calvin 4 | # email : calvinwilliams@163.com 5 | # 6 | # Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | ###################################################################### 8 | 9 | #!/bin/bash 10 | 11 | if [ $# -ne 1 ] ; then 12 | echo "USAGE : cocker_install_test.sh (image_path_base)" 13 | exit 1 14 | fi 15 | 16 | IMAGE_RLAYER_PATH_BASE=$1 17 | 18 | cd ${IMAGE_RLAYER_PATH_BASE} 19 | mkdir -p -m 755 bin sbin lib lib64 usr etc root dev proc mnt var tmp 20 | mkdir -p -m 755 mnt/cdrom 21 | 22 | # install /bin and /lib64 23 | cd /bin 24 | cp bash tty which locale env ls cat echo cp mv rm pwd cd mkdir rmdir clear ps grep more id uname hostname vi vim awk sed tr file ldd top netstat ping telnet ssh nc mount umount ${IMAGE_RLAYER_PATH_BASE}/bin/ 25 | cp cockerinit ${IMAGE_RLAYER_PATH_BASE}/bin/ 26 | cd ${IMAGE_RLAYER_PATH_BASE}/bin/ 27 | cocker_ldd_and_cp_lib64.sh 28 | 29 | # install /sbin and /lib64 30 | cd /sbin 31 | cp ifconfig route ip iptables ${IMAGE_RLAYER_PATH_BASE}/sbin/ 32 | cd ${IMAGE_RLAYER_PATH_BASE}/sbin/ 33 | cocker_ldd_and_cp_lib64.sh 34 | 35 | # install /etc/profile and $HOME/.profile 36 | cp /bin/cocker_etc_profile_template.sh ${IMAGE_RLAYER_PATH_BASE}/etc/profile 37 | cp /bin/cocker_profile_template.sh ${IMAGE_RLAYER_PATH_BASE}/root/.profile 38 | 39 | # install /etc/passwd and /etc/group 40 | echo "root:x:0:0:root:/root:/bin/bash" >${IMAGE_RLAYER_PATH_BASE}/etc/passwd 41 | echo "root:x:0:" >${IMAGE_RLAYER_PATH_BASE}/etc/group 42 | 43 | # install /dev/pts 44 | mknod -m 600 ${IMAGE_RLAYER_PATH_BASE}/dev/console c 5 1 45 | mknod -m 600 ${IMAGE_RLAYER_PATH_BASE}/dev/initctl p 46 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/full c 1 7 47 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/null c 1 3 48 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/zero c 1 5 49 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/random c 1 8 50 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/urandom c 1 9 51 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/ptmx c 5 2 52 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/tty c 5 0 53 | mknod -m 666 ${IMAGE_RLAYER_PATH_BASE}/dev/tty0 c 4 0 54 | mkdir -p ${IMAGE_RLAYER_PATH_BASE}/dev/pts 55 | 56 | # install /usr/share/terminfo 57 | mkdir -p ${IMAGE_RLAYER_PATH_BASE}/usr/share 58 | cp -rf /usr/share/terminfo ${IMAGE_RLAYER_PATH_BASE}/usr/share/ 59 | 60 | # install other test files 61 | printf "{ \"leaf\":\"\${LEAF}\" }\n" >${IMAGE_RLAYER_PATH_BASE}/root/tpl.txt 62 | 63 | -------------------------------------------------------------------------------- /src/cocker/action_import.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_import( struct CockerEnvironment *env ) 12 | { 13 | int image_file_len ; 14 | char image_id[ IMAGES_ID_LEN_MAX + 1 ] ; 15 | char version[ PATH_MAX + 1 ] ; 16 | char image_rlayer_path_base[ PATH_MAX + 1 ] ; 17 | char current_path[ PATH_MAX + 1 ] ; 18 | char cmd[ 4096 ] ; 19 | 20 | int nret = 0 ; 21 | 22 | /* preprocess input parameters */ 23 | image_file_len = strlen(env->cmd_para.__image_file) ; 24 | IxTER1( (image_file_len < sizeof(COCKERIMAGE_FILE_EXTNAME)-1) , "image file[%s] too small\n" , env->cmd_para.__image_file ) 25 | IxTER1( (STRCMP(env->cmd_para.__image_file+image_file_len-(sizeof(COCKERIMAGE_FILE_EXTNAME)-1),!=,COCKERIMAGE_FILE_EXTNAME)) , "image file name[%s] invalid\n" , env->cmd_para.__image_file ) 26 | 27 | memset( image_id , 0x00 , sizeof(image_id) ); 28 | strncpy( image_id , env->cmd_para.__image_file , image_file_len-(sizeof(COCKERIMAGE_FILE_EXTNAME)-1)-1 ); 29 | SplitImageVersion( image_id , version , sizeof(version) ); 30 | 31 | Snprintf( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s/%s" , env->images_path_base , image_id , (version[0]?version:"_") ); 32 | nret = access( env->image_path_base , F_OK ) ; 33 | I0TER1( "*** ERROR : image '%s' exist\n" , image_id ) 34 | 35 | /* pack image folders and files */ 36 | nret = SnprintfAndMakeDir( NULL , -1 , "%s/%s" , env->images_path_base , image_id ) ; 37 | 38 | nret = SnprintfAndMakeDir( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s/%s" , env->images_path_base , image_id , (version[0]?version:"_") ) ; 39 | INTER1( "*** ERROR : SnprintfAndMakeDir / failed[%d] , errno[%d]\n" , nret , errno ) 40 | EIDTI( "mkdir %s ok\n" , env->image_path_base ) 41 | 42 | nret = SnprintfAndMakeDir( image_rlayer_path_base , sizeof(image_rlayer_path_base)-1 , "%s/rlayer" , env->image_path_base ) ; 43 | INTER1( "*** ERROR : SnprintfAndMakeDir /rlayer failed[%d] , errno[%d]\n" , nret , errno ) 44 | EIDTI( "mkdir %s ok\n" , image_rlayer_path_base ) 45 | 46 | memset( current_path , 0x00 , sizeof(current_path) ); 47 | getcwd( current_path , sizeof(current_path) ); 48 | 49 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "cd %s/rlayer/ && tar --force-local -xzf %s/%s" , env->image_path_base , current_path , env->cmd_para.__image_file ) ; 50 | INTER1( "*** ERROR : SnprintfAndSystem [cd %s/rlayer/ && tar --force-local -xzf %s/%s] failed[%d] , errno[%d]\n" , env->image_path_base , current_path , env->cmd_para.__image_file , nret , errno ) 51 | EIDTI( "system [%s] ok\n" , cmd ) 52 | 53 | printf( "OK\n" ); 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/cocker/action_spush.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_spush( struct CockerEnvironment *env ) 12 | { 13 | char image[ IMAGES_ID_LEN_MAX + 1 ] ; 14 | char version[ PATH_MAX + 1 ] ; 15 | char image_file[ PATH_MAX + 1 ] ; 16 | char current_path[ PATH_MAX + 1 ] ; 17 | char cmd[ 4096 ] ; 18 | char srepo[ SREPO_LEN_MAX + 1 ] ; 19 | char srepo_file[ PATH_MAX + 1 ] ; 20 | 21 | int nret = 0 ; 22 | int nret2 = 0 ; 23 | 24 | /* preprocess input parameters */ 25 | Snprintf( image , sizeof(image) , "%s" , env->cmd_para.__image ); 26 | SplitImageVersion( image , version , sizeof(version) ); 27 | 28 | Snprintf( image_file , sizeof(image_file) , "%s%s%s.cockerimage" , image , (version[0]=='\0'?"":":") , version ); 29 | 30 | Snprintf( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s/%s" , env->images_path_base , image , (version[0]?version:"_") ); 31 | nret = access( env->image_path_base , F_OK ) ; 32 | I1TER1( "*** ERROR : image '%s' not found\n" , env->cmd_para.__image ) 33 | 34 | memset( srepo , 0x00 , sizeof(srepo) ); 35 | memset( srepo_file , 0x00 , sizeof(srepo_file) ); 36 | nret = ReadFileLine( srepo , sizeof(srepo) , srepo_file , sizeof(srepo_file) , "%s/srepo" , env->cocker_home ) ; 37 | I1TER1( "read %s failed\n" , srepo_file ) 38 | EIDTI( "read %s ok\n" , srepo_file ) 39 | 40 | /* pack and upload image */ 41 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "ssh %s \"ls ./%s\" >/dev/null 2>/dev/null" , srepo , image_file ) ; 42 | if( nret == 0 ) 43 | { 44 | E( "*** ERROR : image '%s' exist in srepo\n" , image_file ); 45 | if( ! env->cmd_para.__forcely ) 46 | return nret; 47 | } 48 | 49 | memset( current_path , 0x00 , sizeof(current_path) ); 50 | getcwd( current_path , sizeof(current_path) ); 51 | 52 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "cd %s/rlayer/ && tar --force-local -czf %s * && mv %s %s/" , env->image_path_base , image_file , image_file , current_path ) ; 53 | INTER1( "*** ERROR : SnprintfAndSystem [cd %s/rlayer/ && tar --force-local -czf %s * && mv %s %s/] failed[%d] , errno[%d]\n" , env->image_path_base , image_file , image_file , current_path , nret , errno ) 54 | EIDTI( "system [%s] ok\n" , cmd ) 55 | 56 | if( env->cmd_para.__debug ) 57 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "scp ./%s %s:~/" , image_file , srepo ) ; 58 | else 59 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "scp ./%s %s:~/ >/dev/null 2>/dev/null" , image_file , srepo ) ; 60 | INTEx( {if(nret2==0)nret2=nret;} , "*** ERROR : SnprintfAndSystem [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 61 | EIDTI( "system [%s] ok\n" , cmd ) 62 | 63 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "rm %s" , image_file ) ; 64 | INTER1( "*** ERROR : SnprintfAndSystem [rm %s] failed[%d] , errno[%d]\n" , image_file , nret , errno ) 65 | EIDTI( "system [%s] ok\n" , cmd ) 66 | 67 | printf( "OK\n" ); 68 | 69 | if( nret2 ) 70 | return nret2; 71 | else 72 | return 0; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /src/cocker/show_ssearch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoShow_ssearch( struct CockerEnvironment *env ) 12 | { 13 | char srepo[ SREPO_LEN_MAX + 1 ] ; 14 | char srepo_file[ PATH_MAX + 1 ] ; 15 | char cmd[ 4096 ] ; 16 | FILE *pp = NULL ; 17 | char buf[ 4096 ] ; 18 | int count ; 19 | int image_size ; 20 | char image_size_str[ 32 + 1] ; 21 | char image_modify_datetime[ 32 + 1 ] ; 22 | char image_id[ IMAGES_ID_LEN_MAX + 1 ] ; 23 | 24 | int nret = 0 ; 25 | 26 | if( env->cmd_para.__srepo ) 27 | { 28 | memset( srepo_file , 0x00 , sizeof(srepo_file) ); 29 | nret = WriteFileLine( env->cmd_para.__srepo , srepo_file , sizeof(srepo_file) , "%s/srepo" , env->cocker_home ) ; 30 | I1TER1( "write %s failed\n" , srepo_file ) 31 | EIDTI( "write %s ok\n" , srepo_file ) 32 | } 33 | 34 | memset( srepo , 0x00 , sizeof(srepo) ); 35 | memset( srepo_file , 0x00 , sizeof(srepo_file) ); 36 | nret = ReadFileLine( srepo , sizeof(srepo) , srepo_file , sizeof(srepo_file) , "%s/srepo" , env->cocker_home ) ; 37 | I1TER1( "read %s failed\n" , srepo_file ) 38 | EIDTI( "read %s ok\n" , srepo_file ) 39 | 40 | if( env->cmd_para.__match == NULL ) 41 | { 42 | Snprintf( cmd , sizeof(cmd) , "ssh %s ls -l --full-time \"*.cockerimage\" 2>/dev/null" , srepo ) ; 43 | } 44 | else 45 | { 46 | Snprintf( cmd , sizeof(cmd) , "ssh %s ls -l --full-time \"*%s*.cockerimage\" 2>/dev/null" , srepo , env->cmd_para.__match ) ; 47 | } 48 | pp = popen( cmd , "r" ) ; 49 | IxTER1( (pp==NULL) , "popen [%s] failed , errno[%d]\n" , cmd , errno ) 50 | EIDTI( "popen [%s] ok\n" , cmd ) 51 | 52 | count = 0 ; 53 | while(1) 54 | { 55 | memset( buf , 0x00 , sizeof(buf) ); 56 | if( fgets( buf , sizeof(buf) , pp ) == NULL ) 57 | break; 58 | TrimEnter( buf ); 59 | 60 | memset( image_modify_datetime , 0x00 , sizeof(image_modify_datetime) ); 61 | memset( image_id , 0x00 , sizeof(image_id) ); 62 | sscanf( buf , "%*s%*s%*s%*s%d%s %[^.].%*s%*s%s" , & image_size , image_modify_datetime , image_modify_datetime+10 , image_id ); 63 | image_modify_datetime[10] = 'T' ; 64 | image_id[strlen(image_id)-sizeof(COCKERIMAGE_FILE_EXTNAME)] = '\0' ; 65 | 66 | if( image_size > 1024*1024*1024 ) 67 | Snprintf( image_size_str , sizeof(image_size_str) , "%d GB" , image_size / (1024*1024*1024) ); 68 | else if( image_size > 1024*1024 ) 69 | Snprintf( image_size_str , sizeof(image_size_str) , "%d MB" , image_size / (1024*1024) ); 70 | else if( image_size > 1024 ) 71 | Snprintf( image_size_str , sizeof(image_size_str) , "%d KB" , image_size / 1024 ); 72 | else if( image_size >= 0 ) 73 | Snprintf( image_size_str , sizeof(image_size_str) , "%d B" , image_size ); 74 | else 75 | Snprintf( image_size_str , sizeof(image_size_str) , "(unknow)" ); 76 | 77 | /* output */ 78 | if( count == 0 ) 79 | { 80 | printf( "%-45s %-19s %-10s\n" , "image_id" , "modify_datetime" , "size" ); 81 | printf( "----------------------------------------------------------------------\n" ); 82 | } 83 | 84 | printf( "%-45s %-19s %s\n" , image_id , image_modify_datetime , image_size_str ); 85 | 86 | count++; 87 | } 88 | 89 | return 0; 90 | } 91 | 92 | -------------------------------------------------------------------------------- /src/cocker/action_to_container.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_to_container( struct CockerEnvironment *env ) 12 | { 13 | char image[ IMAGES_ID_LEN_MAX + 1 ] ; 14 | char version[ PATH_MAX + 1 ] ; 15 | char *p = NULL ; 16 | char *p2 = NULL ; 17 | char cmd[ 4096 ] ; 18 | char version_path_base[ PATH_MAX + 1 ] ; 19 | 20 | int nret = 0 ; 21 | 22 | /* preprocess input parameters */ 23 | memset( image , 0x00 , sizeof(image) ); 24 | strncpy( image , env->cmd_para.__from_image , sizeof(image)-1 ); 25 | 26 | p = image ; 27 | p2 = strchr( p , ':' ) ; 28 | if( p2 == NULL ) 29 | { 30 | Snprintf( version_path_base , sizeof(version_path_base) , "%s/%s" , env->images_path_base , p ) ; 31 | nret = GetMaxVersionPath( version_path_base , version , sizeof(version) ) ; 32 | INTER1( "*** ERROR : GetMaxVersionPath[%s] failed[%d]\n" , version_path_base , nret ) 33 | 34 | nret = SnprintfAndCheckDir( NULL , -1 , "%s/%s/%s/rlayer" , env->images_path_base , p , version ) ; 35 | } 36 | else 37 | { 38 | strcpy( version , "_" ); 39 | (*p2) = '0' ; 40 | nret = SnprintfAndCheckDir( NULL , -1 , "%s/%.*s/%s/rlayer" , env->images_path_base , (int)(p2-p) , p , p2+1 ) ; 41 | } 42 | INTER1( "*** ERROR : image[%s] not found\n" , image ) 43 | 44 | Snprintf( version_path_base , sizeof(version_path_base) , "%s/%s" , env->images_path_base , image ); 45 | 46 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__to_container ); 47 | nret = access( env->container_path_base , F_OK ) ; 48 | I0TER1( "*** ERROR : container '%s' exist\n" , env->cmd_para.__to_container ) 49 | 50 | GetEthernetNames( env , env->cmd_para.__to_container ); 51 | 52 | /* create container folders and files */ 53 | nret = CreateContainer( env , env->cmd_para.__image , env->cmd_para.__to_container ) ; 54 | INTER1( "*** ERROR : CreateContainer failed[%d] , errno[%d]\n" , nret , errno ) 55 | EIDTI( "CreateContainer %s from %s ok\n" , env->cmd_para.__to_container , env->cmd_para.__from_image ) 56 | 57 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "mv -f %s/%s/rlayer/* %s/rwlayer/" , version_path_base , version , env->container_path_base ) ; 58 | INTER1( "*** ERROR : SnprintfAndSystem [mv -f %s/%s/rlayer/* %s/rwlayer/] failed[%d] , errno[%d]\n" , version_path_base , version , env->container_path_base , nret , errno ) 59 | EIDTI( "system [%s] ok\n" , cmd ) 60 | 61 | nret = WriteFileLine( version , NULL , -1 , "%s/version" , env->container_path_base ) ; 62 | INTER1( "*** ERROR : WriteFileLine version failed[%d] , errno[%d]\n" , nret , errno ) 63 | EIDTI( "write file %s ok\n" , "version" ) 64 | 65 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "rm -rf %s/%s" , version_path_base , version ) ; 66 | INTER1( "*** ERROR : SnprintfAndSystem [rm -rf %s/%s] failed[%d] , errno[%d]\n" , version_path_base , version , nret , errno ) 67 | EIDTI( "system [%s] ok\n" , cmd ) 68 | 69 | nret = IsDirectoryEmpty( version_path_base ) ; 70 | if( nret == 0 ) 71 | { 72 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "rmdir %s" , version_path_base ) ; 73 | INTER1( "*** ERROR : SnprintfAndSystem [rmdir %s] failed[%d] , errno[%d]\n" , version_path_base , nret , errno ) 74 | EIDTI( "system [%s] ok\n" , cmd ) 75 | } 76 | 77 | printf( "OK\n" ); 78 | 79 | return 0; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/cocker/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | void GetEthernetNames( struct CockerEnvironment *env , char *container_id ) 12 | { 13 | char ethername_postfix[ 10 + 1 ] ; 14 | 15 | memset( ethername_postfix , 0x00 , sizeof(ethername_postfix) ); 16 | GenerateEthernamePostfix( container_id , ethername_postfix ); 17 | 18 | memset( env->netns_name , 0x00 , sizeof(env->netns_name) ); 19 | snprintf( env->netns_name , sizeof(env->netns_name) , "nns%.10s" , ethername_postfix ); 20 | 21 | memset( env->netbr_name , 0x00 , sizeof(env->netbr_name) ); 22 | snprintf( env->netbr_name , sizeof(env->netbr_name) , "cocker0" ); 23 | 24 | memset( env->veth1_name , 0x00 , sizeof(env->veth1_name) ); 25 | snprintf( env->veth1_name , sizeof(env->veth1_name) , "eth%.10s" , ethername_postfix ); 26 | 27 | memset( env->veth0_name , 0x00 , sizeof(env->veth0_name) ); 28 | snprintf( env->veth0_name , sizeof(env->veth0_name) , "vth%.10s" , ethername_postfix ); 29 | 30 | memset( env->veth0_sname , 0x00 , sizeof(env->veth0_sname) ); 31 | snprintf( env->veth0_sname , sizeof(env->veth0_sname) , "eth0" ); 32 | 33 | return; 34 | } 35 | 36 | int SplitImageVersion( char *image_id , char *version , int version_bufsize ) 37 | { 38 | char *p = NULL ; 39 | 40 | memset( version , 0x00 , version_bufsize ); 41 | 42 | p = strchr( image_id , ':' ) ; 43 | if( p ) 44 | { 45 | strncpy( version , p+1 , version_bufsize-1 ); 46 | (*p) = '\0' ; 47 | 48 | return 1; 49 | } 50 | 51 | return 0; 52 | } 53 | 54 | int GetMaxVersionPath( char *version_path_base , char *max_version , int max_version_bufsize ) 55 | { 56 | DIR *dir = NULL ; 57 | struct dirent *dirent = NULL ; 58 | char sub_path[ PATH_MAX + 1 ] ; 59 | struct stat dir_stat ; 60 | int max_v1 , max_v2 , max_v3 , max_v4 ; 61 | int v1 , v2 , v3 , v4 ; 62 | char version[ PATH_MAX + 1 ] = "" ; 63 | 64 | int nret = 0 ; 65 | 66 | dir = opendir( version_path_base ) ; 67 | if( dir == NULL ) 68 | return -1; 69 | 70 | max_v1 = -1 ; 71 | max_v2 = -1 ; 72 | max_v3 = -1 ; 73 | max_v4 = -1 ; 74 | while(1) 75 | { 76 | dirent = readdir( dir ) ; 77 | if( dirent == NULL ) 78 | break; 79 | if( STRCMP( dirent->d_name , == , "." ) || STRCMP( dirent->d_name , == , ".." ) ) 80 | continue; 81 | 82 | if( Snprintf( sub_path , sizeof(sub_path) , "%s/%s" , version_path_base , dirent->d_name ) == NULL ) 83 | { 84 | closedir( dir ); 85 | return -2; 86 | } 87 | 88 | memset( & dir_stat , 0x00 , sizeof(struct stat) ); 89 | nret = stat( sub_path , & dir_stat ) ; 90 | if( nret == -1 ) 91 | { 92 | closedir( dir ); 93 | return -3; 94 | } 95 | if( ! S_ISDIR(dir_stat.st_mode) ) 96 | continue; 97 | 98 | sscanf( dirent->d_name , "%d.%d.%d.%d" , & v1 , & v2 , & v3 , & v4 ); 99 | if( v1 < max_v1 ) 100 | continue; 101 | if( v2 < max_v2 ) 102 | continue; 103 | if( v3 < max_v3 ) 104 | continue; 105 | if( v4 < max_v4 ) 106 | continue; 107 | 108 | strncpy( version , dirent->d_name , sizeof(version)-1 ); 109 | max_v1 = v1 ; 110 | max_v2 = v2 ; 111 | max_v3 = v3 ; 112 | max_v4 = v4 ; 113 | } 114 | 115 | closedir( dir ); 116 | 117 | if( version[0] == '0' ) 118 | { 119 | return 1; 120 | } 121 | else 122 | { 123 | strncpy( max_version , version , max_version_bufsize-1 ); 124 | return 0; 125 | } 126 | } 127 | 128 | -------------------------------------------------------------------------------- /src/util/string.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_util.h" 10 | 11 | char *SnprintfV( char *path_buf , int path_bufsize , char *path_format , va_list valist ) 12 | { 13 | static char path[ 4096 ] = "" ; 14 | 15 | static char *p_path = NULL ; 16 | static int path_size = 0 ; 17 | 18 | int nret = 0 ; 19 | 20 | if( path_buf == NULL ) 21 | { 22 | p_path = path ; 23 | path_size = sizeof(path)-1 ; 24 | } 25 | else 26 | { 27 | p_path = path_buf ; 28 | path_size = path_bufsize ; 29 | } 30 | 31 | memset( p_path , 0x00 , path_size ); 32 | nret = vsnprintf( p_path , path_size-1 , path_format , valist ) ; 33 | if( SNPRINTF_OVERFLOW( nret , path_size ) ) 34 | return NULL; 35 | 36 | return p_path; 37 | } 38 | 39 | char *Snprintf( char *path_buf , int path_bufsize , char *path_format , ... ) 40 | { 41 | char *p_path = NULL ; 42 | va_list valist ; 43 | 44 | va_start( valist , path_format ); 45 | p_path = SnprintfV( path_buf , path_bufsize , path_format , valist ) ; 46 | va_end( valist ); 47 | if( p_path == NULL ) 48 | return NULL; 49 | 50 | return p_path; 51 | } 52 | 53 | char *TrimEnter( char *str ) 54 | { 55 | char *ptr = NULL ; 56 | 57 | if( str == NULL ) 58 | return NULL; 59 | 60 | for( ptr = str + strlen(str) - 1 ; ptr >= str ; ptr-- ) 61 | { 62 | if( (*ptr) == '\r' || (*ptr) == '\n' ) 63 | (*ptr) = '\0' ; 64 | else 65 | break; 66 | } 67 | 68 | return str; 69 | } 70 | 71 | char *GenerateContainerId( char *images_id , char *container_id ) 72 | { 73 | MD5_CTX md5_ctx ; 74 | struct timeval now ; 75 | char time_buf[ 10+1+6 + 1 ] ; 76 | unsigned char md5[ MD5_DIGEST_LENGTH + 1 ] ; 77 | int i ; 78 | unsigned char *p_md5 = NULL ; 79 | unsigned char *p_md5_exp = NULL ; 80 | const unsigned char hex_charset[] = "0123456789ABCDEF" ; 81 | 82 | MD5_Init( & md5_ctx ); 83 | 84 | MD5_Update( & md5_ctx , images_id , strlen(images_id) ); 85 | 86 | gettimeofday( & now , NULL ); 87 | memset( time_buf , 0x00 , sizeof(time_buf) ); 88 | snprintf( time_buf , sizeof(time_buf)-1 , "%6ld.%06ld" , now.tv_sec , now.tv_usec ); 89 | MD5_Update( & md5_ctx , time_buf , strlen(time_buf) ); 90 | 91 | memset( md5 , 0x00 , sizeof(md5) ); 92 | MD5_Final( md5 , & md5_ctx ); 93 | 94 | for( p_md5 = md5 , p_md5_exp = (unsigned char *)container_id , i = 0 ; i < CONTAINER_ID_LEN_MAX/2 ; p_md5++ , p_md5_exp+=2 , i++ ) 95 | { 96 | p_md5_exp[0] = hex_charset[(p_md5[0]&0xF0)>>4] ; 97 | p_md5_exp[1] = hex_charset[p_md5[0]&0x0F] ; 98 | } 99 | 100 | return container_id; 101 | } 102 | 103 | char *GenerateEthernamePostfix( char *container_id , char *ethername_postfix ) 104 | { 105 | MD5_CTX md5_ctx ; 106 | unsigned char md5[ MD5_DIGEST_LENGTH + 1 ] ; 107 | int i ; 108 | unsigned char *p_md5 = NULL ; 109 | unsigned char *p_md5_exp = NULL ; 110 | const unsigned char hex_charset[] = "0123456789ABCDEF" ; 111 | 112 | MD5_Init( & md5_ctx ); 113 | 114 | MD5_Update( & md5_ctx , container_id , strlen(container_id) ); 115 | 116 | memset( md5 , 0x00 , sizeof(md5) ); 117 | MD5_Final( md5 , & md5_ctx ); 118 | 119 | for( p_md5 = md5 , p_md5_exp = (unsigned char *)ethername_postfix , i = 0 ; i < 5 ; p_md5++ , p_md5_exp+=2 , i++ ) 120 | { 121 | p_md5_exp[0] = hex_charset[(p_md5[0]&0xF0)>>4] ; 122 | p_md5_exp[1] = hex_charset[p_md5[0]&0x0F] ; 123 | } 124 | 125 | return ethername_postfix; 126 | } 127 | 128 | -------------------------------------------------------------------------------- /src/cocker/action_spull.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_spull( struct CockerEnvironment *env ) 12 | { 13 | char srepo[ SREPO_LEN_MAX + 1 ] ; 14 | char srepo_file[ PATH_MAX + 1 ] ; 15 | char image_file[ PATH_MAX + 1 ] ; 16 | char image_id[ IMAGES_ID_LEN_MAX + 1 ] ; 17 | char version[ PATH_MAX + 1 ] ; 18 | char image_rlayer_path_base[ PATH_MAX + 1 ] ; 19 | char current_path[ PATH_MAX + 1 ] ; 20 | char cmd[ 4096 ] ; 21 | 22 | int nret = 0 ; 23 | 24 | /* preprocess input parameters */ 25 | Snprintf( image_file , sizeof(image_file) , "%s.%s" , env->cmd_para.__image , COCKERIMAGE_FILE_EXTNAME ); 26 | 27 | memset( image_id , 0x00 , sizeof(image_id) ); 28 | strncpy( image_id , env->cmd_para.__image , sizeof(image_id)-1 ); 29 | SplitImageVersion( image_id , version , sizeof(version) ); 30 | 31 | Snprintf( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s/%s" , env->images_path_base , image_id , (version[0]?version:"_") ); 32 | nret = access( env->image_path_base , F_OK ) ; 33 | I0TER1( "*** ERROR : image '%s' exist\n" , image_id ) 34 | 35 | memset( srepo , 0x00 , sizeof(srepo) ); 36 | memset( srepo_file , 0x00 , sizeof(srepo_file) ); 37 | nret = ReadFileLine( srepo , sizeof(srepo) , srepo_file , sizeof(srepo_file) , "%s/srepo" , env->cocker_home ) ; 38 | I1TER1( "read %s failed\n" , srepo_file ) 39 | EIDTI( "read %s ok\n" , srepo_file ) 40 | 41 | /* download and import image file */ 42 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "ssh %s \"ls ./%s.cockerimage\" >/dev/null 2>/dev/null" , srepo , env->cmd_para.__image ) ; 43 | if( nret ) 44 | { 45 | E( "*** ERROR : image '%s' not found in srepo\n" , env->cmd_para.__image_file ); 46 | if( ! env->cmd_para.__forcely ) 47 | return nret; 48 | } 49 | 50 | if( env->cmd_para.__debug ) 51 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "scp %s:~/%s ." , srepo , image_file ) ; 52 | else 53 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "scp %s:~/%s . >/dev/null 2>/dev/null" , srepo , image_file ) ; 54 | INTER1( "*** ERROR : SnprintfAndSystem [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 55 | EIDTI( "system [%s] ok\n" , cmd ) 56 | 57 | nret = SnprintfAndMakeDir( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s" , env->images_path_base , image_id ) ; 58 | nret = SnprintfAndMakeDir( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s/%s" , env->images_path_base , image_id , (version[0]?version:"_") ) ; 59 | INTER1( "*** ERROR : SnprintfAndMakeDir %s failed[%d] , errno[%d]\n" , env->image_path_base , nret , errno ) 60 | EIDTI( "mkdir %s ok\n" , env->image_path_base ) 61 | 62 | nret = SnprintfAndMakeDir( image_rlayer_path_base , sizeof(image_rlayer_path_base)-1 , "%s/rlayer" , env->image_path_base ) ; 63 | INTER1( "*** ERROR : SnprintfAndMakeDir %s failed[%d] , errno[%d]\n" , image_rlayer_path_base , nret , errno ) 64 | EIDTI( "mkdir %s ok\n" , image_rlayer_path_base ) 65 | 66 | memset( current_path , 0x00 , sizeof(current_path) ); 67 | getcwd( current_path , sizeof(current_path) ); 68 | 69 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "cd %s/rlayer/ && tar --force-local -xzf %s/%s" , env->image_path_base , current_path , image_file ) ; 70 | INTER1( "*** ERROR : SnprintfAndSystem [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 71 | EIDTI( "system [%s] ok\n" , cmd ) 72 | 73 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "rm %s" , image_file ) ; 74 | INTER1( "*** ERROR : SnprintfAndSystem [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 75 | EIDTI( "system [%s] ok\n" , cmd ) 76 | 77 | printf( "OK\n" ); 78 | 79 | return 0; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/cockerinit/pty.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cockerinit_in.h" 10 | 11 | int create_pty( struct CockerInitEnvironment *env ) 12 | { 13 | struct winsize origin_winsize ; 14 | char cmd[ 4096 ] ; 15 | struct termios ptm_termios ; 16 | #if 0 17 | int argc ; 18 | char *argv[64] = { NULL } ; 19 | char *p = NULL ; 20 | char *p2 = NULL ; 21 | int i ; 22 | #endif 23 | 24 | int nret = 0 ; 25 | 26 | SetLogcFile( "/cockerinit.log" ); 27 | SetLogcLevel( LOGCLEVEL_INFO ); 28 | 29 | memset( & origin_winsize , 0x00 , sizeof(struct winsize) ); 30 | nret = recv( env->accepted_sock , & origin_winsize , sizeof(struct winsize) , 0 ) ; 31 | if( nret <= 0 ) 32 | { 33 | FATALLOGC( "*** ERROR : recv winsize failed[%d] , errno[%d]\n" , nret , errno ) 34 | exit(9); 35 | } 36 | else 37 | { 38 | INFOLOGC( "recv winsize ok , [%d]bytes\n" , nret ) 39 | } 40 | 41 | memset( cmd , 0x00 , sizeof(cmd) ); 42 | nret = recv( env->accepted_sock , cmd , sizeof(cmd) , 0 ) ; 43 | if( nret <= 0 ) 44 | { 45 | FATALLOGC( "*** ERROR : recv cmd failed[%d] , errno[%d]\n" , nret , errno ) 46 | exit(9); 47 | } 48 | else 49 | { 50 | INFOLOGC( "recv cmd ok , [%d]bytes , cmd[%s]\n" , nret , cmd ); 51 | } 52 | 53 | /* 54 | signal( SIGCLD , SIG_IGN ); 55 | signal( SIGCHLD , SIG_IGN ); 56 | */ 57 | 58 | /* printf( "pty_fork ...\n" ); */ 59 | env->bash_pid = pty_fork( NULL , & origin_winsize , & (env->ptm_fd) ) ; 60 | if( env->bash_pid < 0 ) 61 | { 62 | FATALLOGC( "*** ERROR : pty_fork failed[%d] , errno[%d]\n" , env->bash_pid , errno ) 63 | exit(9); 64 | } 65 | else if( env->bash_pid == 0 ) 66 | { 67 | nret = tcgetattr( STDIN_FILENO , & ptm_termios ) ; 68 | if( nret == -1 ) 69 | { 70 | FATALLOGC( "*** ERROR : tcgetattr failed[%d] , errno[%d]\n" , nret , errno ) 71 | exit(1); 72 | } 73 | 74 | ptm_termios.c_lflag |= ECHO ; 75 | ptm_termios.c_oflag |= ONLCR | XTABS ; 76 | ptm_termios.c_iflag |= ICRNL ; 77 | ptm_termios.c_iflag &= ~IXOFF ; 78 | 79 | nret = tcsetattr( STDIN_FILENO , TCSANOW , & ptm_termios ) ; 80 | if( nret == -1 ) 81 | { 82 | FATALLOGC( "*** ERROR : tcsetattr failed[%d] , errno[%d]\n" , nret , errno ) 83 | exit(1); 84 | } 85 | 86 | #if 0 87 | argc = 0 ; 88 | p = strtok( cmd , " \t" ) ; 89 | while( p ) 90 | { 91 | if( argc >= sizeof(argv)/sizeof(argv[0])-1 ) 92 | break; 93 | 94 | if( argc == 0 ) 95 | { 96 | argv[argc++] = p ; 97 | argv[argc++] = p ; 98 | p2 = strrchr( argv[1] , '/' ) ; 99 | if( p2 ) 100 | { 101 | argv[1] = p2+1 ; 102 | } 103 | } 104 | else 105 | { 106 | argv[argc++] = p ; 107 | } 108 | 109 | p = strtok( NULL , " \t" ) ; 110 | } 111 | argv[argc++] = NULL ; 112 | 113 | for( i = 0 ; i < argc ; i++ ) 114 | INFOLOGC( "argv[%d]=[%s]\n" , i , argv[i] ) 115 | 116 | if( strchr( argv[0] , '/' ) ) 117 | nret = execv( argv[0] , argv+1 ) ; 118 | else 119 | nret = execvp( argv[0] , argv+1 ) ; 120 | #endif 121 | if( STRCMP( cmd , == , "/bin/bash -l" ) ) 122 | nret = execl( "/bin/bash" , "bash" , "-l" , NULL ) ; 123 | else 124 | nret = execl( "/bin/bash" , "bash" , "-c" , cmd , NULL ) ; 125 | if( nret == -1 ) 126 | { 127 | FATALLOGC( "*** ERROR : execl failed[%d] , errno[%d]\n" , nret , errno ) 128 | exit(1); 129 | } 130 | 131 | exit(1); 132 | } 133 | else 134 | { 135 | INFOLOGC( "pty_fork parent\n" ) 136 | 137 | nret = pts_and_tcp_bridge( env ); 138 | INFOLOGC( "pts_and_tcp_bridge return[%d]\n" , nret ) 139 | 140 | INFOLOGC( "close accepted sock and ptm_fd\n" ) 141 | close( env->accepted_sock ); 142 | close( env->ptm_fd ); 143 | } 144 | 145 | return 0; 146 | } 147 | 148 | -------------------------------------------------------------------------------- /src/cockerinit/server.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cockerinit_in.h" 10 | 11 | int server( struct CockerInitEnvironment *env ) 12 | { 13 | struct pollfd poll_fds[ 2 ] ; 14 | socklen_t accepted_addr_len ; 15 | pid_t pid ; 16 | int status ; 17 | 18 | int nret = 0 ; 19 | 20 | signal( SIGPIPE , SIG_IGN ); 21 | 22 | env->listen_sock = socket( AF_UNIX , SOCK_STREAM , 0 ) ; 23 | if( env->listen_sock == -1 ) 24 | { 25 | E( "*** ERROR : socket failed , errno[%d]\n" , errno ) 26 | return -1; 27 | } 28 | 29 | memset( & (env->listen_addr) , 0x00 , sizeof(struct sockaddr_un) ); 30 | env->listen_addr.sun_family = AF_UNIX ; 31 | snprintf( env->listen_addr.sun_path , sizeof(env->listen_addr.sun_path)-1 , "/dev/cocker.sock" ); 32 | if( access( env->listen_addr.sun_path , F_OK ) == 0 ) 33 | { 34 | unlink( env->listen_addr.sun_path ); 35 | } 36 | nret = bind( env->listen_sock , (struct sockaddr *) & (env->listen_addr) , sizeof(struct sockaddr_un) ) ; 37 | if( nret == -1 ) 38 | { 39 | E( "*** ERROR : bind failed , errno[%d]\n" , errno ) 40 | return -1; 41 | } 42 | 43 | nret = listen( env->listen_sock , 1024 ) ; 44 | if( nret == -1 ) 45 | { 46 | E( "*** ERROR : listen failed , errno[%d]\n" , errno ) 47 | return -1; 48 | } 49 | 50 | while(1) 51 | { 52 | _POLL : 53 | poll_fds[0].fd = env->alive_pipe_0 ; 54 | poll_fds[0].events = POLLIN|POLLHUP ; 55 | poll_fds[0].revents = 0 ; 56 | poll_fds[1].fd = env->listen_sock ; 57 | poll_fds[1].events = POLLIN|POLLHUP ; 58 | poll_fds[1].revents = 0 ; 59 | nret = poll( poll_fds , 2 , 1000 ) ; 60 | if( nret == -1 ) 61 | { 62 | return -1; 63 | } 64 | else if( nret == 0 ) 65 | { 66 | _WAITPID : 67 | pid = waitpid( -1 , & status , WNOHANG ); 68 | if( pid == -1 ) 69 | { 70 | if( errno == ECHILD ) 71 | { 72 | INFOLOGC( "waitpid ECHILD\n" ) 73 | } 74 | else 75 | { 76 | FATALLOGC( "*** ERROR : waitpid failed , errno[%d]\n" , errno ) 77 | return -1; 78 | } 79 | } 80 | else if( pid > 0 ) 81 | { 82 | INFOLOGC( "waitpid[%d] ok\n" , pid ) 83 | goto _WAITPID; 84 | } 85 | 86 | goto _POLL; 87 | } 88 | 89 | if( (poll_fds[0].revents&POLLIN) || (poll_fds[0].revents&POLLHUP) ) 90 | { 91 | INFOLOGC( "alive pipe broken\n" ) 92 | return 0; 93 | } 94 | 95 | if( (poll_fds[1].revents&POLLIN) || (poll_fds[1].revents&POLLHUP) ) 96 | { 97 | char ch ; 98 | 99 | accepted_addr_len = sizeof(struct sockaddr_un) ; 100 | env->accepted_sock = accept( env->listen_sock , (struct sockaddr *) & (env->accepted_addr) , & accepted_addr_len ); 101 | if( env->accepted_sock == - 1 ) 102 | { 103 | ERRORLOGC( "*** ERROR : accept failed , errno[%d]\n" , errno ) 104 | return -1; 105 | } 106 | 107 | INFOLOGC( "new session accepted" ) 108 | 109 | /* 110 | signal( SIGCLD , SIG_IGN ); 111 | signal( SIGCHLD , SIG_IGN ); 112 | */ 113 | 114 | nret = recv( env->accepted_sock , & ch , 1 , 0 ) ; 115 | if( nret <= 0 ) 116 | { 117 | ERRORLOGC( "*** ERROR : recv 'C' failed , errno[%d]\n" , errno ) 118 | return -1; 119 | } 120 | else 121 | { 122 | INFOLOGC( "recv ok , [%c]\n" , ch ) 123 | } 124 | 125 | if( ch == 'C' ) 126 | { 127 | pid = fork() ; 128 | if( pid == -1 ) 129 | { 130 | ERRORLOGC( "*** ERROR : fork failed , errno[%d]\n" , errno ) 131 | return -1; 132 | } 133 | else if( pid == 0 ) 134 | { 135 | close( env->listen_sock ); 136 | 137 | exit(-create_pty( env )); 138 | } 139 | } 140 | 141 | close( env->accepted_sock ); 142 | } 143 | } 144 | 145 | close( env->listen_sock ); 146 | 147 | return 0; 148 | } 149 | 150 | -------------------------------------------------------------------------------- /src/cocker/action_destroy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | #define WAIT_FOR_SHUTDOWN_COUNT 5 12 | 13 | int DoAction_destroy( struct CockerEnvironment *env ) 14 | { 15 | int i ; 16 | char pid_str[ PID_LEN_MAX + 1 ] ; 17 | pid_t pid ; 18 | char net[ NET_LEN_MAX + 1 ] ; 19 | char container_net_file[ PATH_MAX + 1 ] ; 20 | char container_pid_file[ PATH_MAX + 1 ] ; 21 | char container_rwlayer_path_base[ PATH_MAX + 1 ] ; 22 | char cmd[ 4096 ] ; 23 | 24 | int nret = 0 ; 25 | 26 | /* preprocess input parameters */ 27 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 28 | nret = access( env->container_path_base , F_OK ) ; 29 | I1TER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__container ) 30 | 31 | GetEthernetNames( env , env->cmd_para.__container ); 32 | 33 | /* if --shutdown optional */ 34 | if( env->cmd_para.__shutdown ) 35 | { 36 | nret = _DoAction_kill( env , SIGTERM ) ; 37 | if( nret ) 38 | { 39 | if( env->cmd_para.__forcely == NULL ) 40 | return -1; 41 | } 42 | 43 | Snprintf( container_pid_file , sizeof(container_pid_file) , "%s/%s/pid" , env->containers_path_base , env->cmd_para.__container ) ; 44 | for( i = 0 ; i < WAIT_FOR_SHUTDOWN_COUNT ; i++ ) 45 | { 46 | nret = access( container_pid_file , F_OK ) ; 47 | if( nret == -1 ) 48 | break; 49 | 50 | sleep(1); 51 | } 52 | if( i >= WAIT_FOR_SHUTDOWN_COUNT ) 53 | ER1( "*** ERROR : wait for shutdown failed\n" ) 54 | } 55 | 56 | /* read pid file */ 57 | memset( pid_str , 0x00 , sizeof(pid_str) ); 58 | memset( container_pid_file , 0x00 , sizeof(container_pid_file) ); 59 | nret = ReadFileLine( pid_str , sizeof(pid_str)-1 , container_pid_file , sizeof(container_pid_file) , "%s/%s/pid" , env->containers_path_base , env->cmd_para.__container ) ; 60 | if( nret == 0 ) 61 | { 62 | TrimEnter( pid_str ); 63 | 64 | pid = atoi(pid_str) ; 65 | if( pid > 0 ) 66 | { 67 | nret = kill( pid , 0 ) ; 68 | I0TER1( "*** ERROR : container is already running\n" ) 69 | } 70 | } 71 | 72 | Snprintf( container_rwlayer_path_base , sizeof(container_rwlayer_path_base)-1 , "%s/rwlayer" , env->container_path_base ); 73 | nret = access( container_rwlayer_path_base , F_OK ) ; 74 | I1TER1( "*** ERROR : container '%s' invalid\n" , env->cmd_para.__container ) 75 | 76 | /* clean container resouce */ 77 | if( env->cmd_para.__forcely ) 78 | { 79 | CleanContainerResource( env ); 80 | } 81 | 82 | /* read net file */ 83 | memset( net , 0x00 , sizeof(net) ); 84 | memset( container_net_file , 0x00 , sizeof(container_net_file) ); 85 | nret = ReadFileLine( net , sizeof(net) , container_net_file , sizeof(container_net_file) , "%s/net" , env->container_path_base ) ; 86 | ILTER1( "*** ERROR : ReadFileLine net failed\n" ) 87 | EIDTI( "read file net ok\n" ) 88 | 89 | TrimEnter( net ); 90 | 91 | /* destroy network-namespace */ 92 | if( STRCMP( net , == , "BRIDGE" ) || env->cmd_para.__forcely ) 93 | { 94 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "ip netns del %s" , env->netns_name ) ; 95 | INTEFR1( "*** ERROR : system [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 96 | EIDTI( "system [%s] ok\n" , cmd ) 97 | } 98 | else if( STRCMP( net , == , "CUSTOM" ) ) 99 | { 100 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "ip netns del %s" , env->netns_name ) ; 101 | INTEFR1( "*** ERROR : system [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 102 | EIDTI( "system [%s] ok\n" , cmd ) 103 | } 104 | 105 | /* destroy container folders and files */ 106 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "rm -rf %s" , env->container_path_base ) ; 107 | INTEFR1( "*** ERROR : system [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 108 | EIDTI( "system [%s] ok\n" , cmd ) 109 | 110 | printf( "OK\n" ); 111 | 112 | return 0; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /src/cocker/env.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int CreateCockerEnvironment( struct CockerEnvironment **pp_env ) 12 | { 13 | struct CockerEnvironment *env = NULL ; 14 | 15 | char netbr_name[ ETHERNET_NAME_LEN_MAX + 1 ] ; 16 | char cmd[ 4096 ] ; 17 | int len ; 18 | 19 | int nret = 0 ; 20 | 21 | env = (struct CockerEnvironment *)malloc( sizeof(struct CockerEnvironment) ) ; 22 | if( env == NULL ) 23 | { 24 | printf( "*** ERROR : malloc failed , errno[%d]\n" , errno ); 25 | return 1; 26 | } 27 | memset( env , 0x00 , sizeof(struct CockerEnvironment) ); 28 | 29 | if( getenv("COCKER_HOME" ) ) 30 | { 31 | nret = SnprintfAndMakeDir( env->cocker_home , sizeof(env->cocker_home)-1 , "%s" , getenv("COCKER_HOME" ) ) ; 32 | if( nret ) 33 | { 34 | printf( "*** ERROR : SnprintfAndMakeDir[%s] failed[%d]\n" , env->cocker_home , nret ); 35 | free( env ); 36 | return -1; 37 | } 38 | } 39 | else 40 | { 41 | nret = SnprintfAndMakeDir( env->cocker_home , sizeof(env->cocker_home)-1 , "/var/cocker" ) ; 42 | if( nret ) 43 | { 44 | printf( "*** ERROR : SnprintfAndMakeDir[%s] failed[%d]\n" , env->cocker_home , nret ); 45 | free( env ); 46 | return -1; 47 | } 48 | } 49 | 50 | nret = SnprintfAndMakeDir( env->images_path_base , sizeof(env->images_path_base)-1 , "%s/images" , env->cocker_home ) ; 51 | if( nret ) 52 | { 53 | printf( "*** ERROR : SnprintfAndMakeDir[%s] failed[%d]\n" , env->images_path_base , nret ); 54 | return -1; 55 | } 56 | 57 | nret = SnprintfAndMakeDir( env->containers_path_base , sizeof(env->containers_path_base)-1 , "%s/containers" , env->cocker_home ) ; 58 | if( nret ) 59 | { 60 | printf( "*** ERROR : SnprintfAndMakeDir[%s] failed[%d]\n" , env->containers_path_base , nret ); 61 | return -1; 62 | } 63 | 64 | memset( netbr_name , 0x00 , sizeof(netbr_name) ); 65 | len = snprintf( netbr_name , sizeof(netbr_name)-1 , "cocker0" ) ; 66 | if( SNPRINTF_OVERFLOW(len,sizeof(netbr_name)-1) ) 67 | { 68 | printf( "*** ERROR : netbr name overflow\n" ); 69 | free( env ); 70 | return -1; 71 | } 72 | 73 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "brctl show | grep -E \"^%s\" >/dev/null 2>&1" , netbr_name ) ; 74 | if( nret ) 75 | { 76 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "brctl addbr %s" , netbr_name ) ; 77 | if( nret ) 78 | { 79 | printf( "*** ERROR : system [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ); 80 | free( env ); 81 | return -1; 82 | } 83 | else if( env->cmd_para.__debug ) 84 | { 85 | printf( "system [%s] ok\n" , cmd ); 86 | } 87 | 88 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "ifconfig %s 166.88.0.1" , netbr_name ) ; 89 | if( nret ) 90 | { 91 | printf( "*** ERROR : system [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ); 92 | return -1; 93 | } 94 | else if( env->cmd_para.__debug ) 95 | { 96 | printf( "system [%s] ok\n" , cmd ); 97 | } 98 | 99 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "ifconfig %s up" , netbr_name ) ; 100 | if( nret ) 101 | { 102 | printf( "*** ERROR : system [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ); 103 | return -1; 104 | } 105 | else if( env->cmd_para.__debug ) 106 | { 107 | printf( "system [%s] ok\n" , cmd ); 108 | } 109 | } 110 | 111 | memset( cmd , 0x00 , sizeof(cmd) ); 112 | SnprintfAndPopen( env->netbr_ip , sizeof(env->netbr_ip) , cmd , sizeof(cmd) , "ifconfig cocker0 | grep -w inet | awk '{print $2}'" ); 113 | TrimEnter( env->netbr_ip ); 114 | 115 | INIT_LIST_HEAD( & (env->cmd_para.volume_list) ); 116 | 117 | (*pp_env) = env ; 118 | 119 | return 0; 120 | } 121 | 122 | void DestroyCockerEnvironment( struct CockerEnvironment **pp_env ) 123 | { 124 | struct CockerVolume *volume = NULL ; 125 | struct CockerVolume *next_volume = NULL ; 126 | 127 | list_for_each_entry_safe( volume , next_volume , & ((*pp_env)->cmd_para.volume_list) , struct CockerVolume , volume_node ) 128 | { 129 | list_del( & (volume->volume_node) ); 130 | free( volume ); 131 | } 132 | 133 | free( (*pp_env) ); 134 | (*pp_env) = NULL ; 135 | 136 | return; 137 | } 138 | 139 | -------------------------------------------------------------------------------- /src/cocker/action_to_image.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoAction_to_image( struct CockerEnvironment *env ) 12 | { 13 | char version[ PATH_MAX + 1 ] ; 14 | char pid_str[ PID_LEN_MAX + 1 ] ; 15 | pid_t pid ; 16 | char net[ NET_LEN_MAX + 1 ] ; 17 | char image_rlayer_path_base[ PATH_MAX + 1 ] ; 18 | char container_pid_file[ PATH_MAX + 1 ] ; 19 | char container_net_file[ PATH_MAX + 1 ] ; 20 | char cmd[ 4096 ] ; 21 | 22 | int nret = 0 ; 23 | 24 | /* preprocess input parameters */ 25 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__from_container ); 26 | nret = access( env->container_path_base , F_OK ) ; 27 | I1TER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__from_container ) 28 | 29 | memset( version , 0x00 , sizeof(version) ); 30 | nret = ReadFileLine( version , sizeof(version)-1 , NULL , -1 , "%s/%s/version" , env->containers_path_base , env->cmd_para.__from_container ) ; 31 | I1TER1( "*** ERROR : container '%s' is not converted from image\n" , env->cmd_para.__from_container ) 32 | 33 | if( env->cmd_para.__version ) 34 | { 35 | strncpy( version , env->cmd_para.__version , sizeof(version)-1 ); 36 | } 37 | if( version[0] == '\0' ) 38 | { 39 | strcpy( version , "_" ); 40 | } 41 | 42 | Snprintf( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s/%s" , env->images_path_base , env->cmd_para.__to_image , version ); 43 | nret = access( env->image_path_base , F_OK ) ; 44 | I0TER1( "*** ERROR : image '%s%s%s' exist\n" , env->cmd_para.__to_image , (version[0]?version:"") , version ) 45 | 46 | GetEthernetNames( env , env->cmd_para.__from_container ); 47 | 48 | /* read pid file */ 49 | memset( pid_str , 0x00 , sizeof(pid_str) ); 50 | memset( container_pid_file , 0x00 , sizeof(container_pid_file) ); 51 | nret = ReadFileLine( pid_str , sizeof(pid_str)-1 , container_pid_file , sizeof(container_pid_file) , "%s/%s/pid" , env->containers_path_base , env->cmd_para.__from_container ) ; 52 | if( nret == 0 ) 53 | { 54 | pid = atoi(pid_str) ; 55 | if( pid > 0 ) 56 | { 57 | nret = kill( pid , 0 ) ; 58 | I0TER1( "*** ERROR : container is already running\n" ) 59 | } 60 | } 61 | 62 | /* read net file */ 63 | memset( net , 0x00 , sizeof(net) ); 64 | memset( container_net_file , 0x00 , sizeof(container_net_file) ); 65 | nret = ReadFileLine( net , sizeof(net) , container_net_file , sizeof(container_net_file) , "%s/net" , env->container_path_base ) ; 66 | ILTER1( "*** ERROR : ReadFileLine net failed\n" ) 67 | EIDTI( "read file net ok\n" ) 68 | 69 | TrimEnter( net ); 70 | 71 | /* destroy network-namespace */ 72 | if( STRCMP( net , == , "BRIDGE" ) || env->cmd_para.__forcely ) 73 | { 74 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "ip netns del %s" , env->netns_name ) ; 75 | INTEFR1( "*** ERROR : system [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 76 | EIDTI( "system [%s] ok\n" , cmd ) 77 | } 78 | else if( STRCMP( net , == , "CUSTOM" ) ) 79 | { 80 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "ip netns del %s" , env->netns_name ) ; 81 | INTEFR1( "*** ERROR : system [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 82 | EIDTI( "system [%s] ok\n" , cmd ) 83 | } 84 | 85 | /* create image */ 86 | nret = SnprintfAndMakeDir( NULL , -1 , "%s/%s" , env->images_path_base , env->cmd_para.__to_image ) ; 87 | 88 | nret = SnprintfAndMakeDir( env->image_path_base , sizeof(env->image_path_base)-1 , "%s/%s/%s" , env->images_path_base , env->cmd_para.__to_image , version ) ; 89 | INTER1( "*** ERROR : SnprintfAndMakeDir image_path_base failed[%d] , errno[%d]\n" , nret , errno ) 90 | EIDTI( "mkdir %s ok\n" , env->image_path_base ) 91 | 92 | nret = SnprintfAndMakeDir( image_rlayer_path_base , sizeof(image_rlayer_path_base)-1 , "%s/rlayer" , env->image_path_base ) ; 93 | INTER1( "*** ERROR : SnprintfAndMakeDir image_rlayer_path_base failed[%d] , errno[%d]\n" , nret , errno ) 94 | EIDTI( "mkdir %s ok\n" , image_rlayer_path_base ) 95 | 96 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "mv -f %s/rwlayer/* %s/rlayer/" , env->container_path_base , env->image_path_base ) ; 97 | INTER1( "*** ERROR : SnprintfAndSystem [mv -f %s/rwlayer/* %s/rlayer/] failed[%d] , errno[%d]\n" , env->container_path_base , env->image_path_base , nret , errno ) 98 | EIDTI( "system [%s] ok\n" , cmd ) 99 | 100 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "rm -rf %s" , env->container_path_base ) ; 101 | INTER1( "*** ERROR : SnprintfAndSystem [rm -rf %s] failed[%d] , errno[%d]\n" , env->container_path_base , nret , errno ) 102 | EIDTI( "system [%s] ok\n" , cmd ) 103 | 104 | printf( "OK\n" ); 105 | 106 | return 0; 107 | } 108 | 109 | -------------------------------------------------------------------------------- /src/cocker/action_run.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | #define TRY_CONNECT_COUNT 5 12 | 13 | struct termios g_termios_init ; 14 | struct termios g_termios_raw ; 15 | 16 | static void RestoreTerminalAttr() 17 | { 18 | tcsetattr( 0 , TCSANOW , & g_termios_init ); 19 | return; 20 | } 21 | 22 | static int tcp_and_pts_bridge( int connected_sock ) 23 | { 24 | struct pollfd poll_fds[ 1 ] ; 25 | char buf[ 4096 ] ; 26 | int len ; 27 | 28 | int nret = 0 ; 29 | 30 | tcgetattr( STDIN_FILENO , & g_termios_init ); 31 | atexit( & RestoreTerminalAttr ); 32 | memcpy( & g_termios_raw , & g_termios_init , sizeof(struct termios) ); 33 | cfmakeraw( & g_termios_raw ); 34 | tcsetattr( STDIN_FILENO , TCSANOW , & g_termios_raw ) ; 35 | 36 | while(1) 37 | { 38 | poll_fds[0].fd = connected_sock ; 39 | poll_fds[0].events = POLLIN|POLLHUP ; 40 | poll_fds[0].revents = 0 ; 41 | nret = poll( poll_fds , 2 , 1000 ) ; 42 | if( nret == 0 ) 43 | { 44 | break; 45 | } 46 | else if( nret == -1 ) 47 | { 48 | E( "*** ERROR : select failed , errno[%d]\n" , errno ) 49 | return -1; 50 | } 51 | 52 | if( (poll_fds[0].revents&POLLIN) || (poll_fds[0].revents&POLLHUP) ) 53 | { 54 | len = read( connected_sock , buf , sizeof(buf)-1 ) ; 55 | if( len == 0 ) 56 | { 57 | return 0; 58 | } 59 | else if( len == -1 ) 60 | { 61 | E( "*** ERROR : read connected_sock failed , errno[%d]\n" , errno ) 62 | return -1; 63 | } 64 | 65 | nret = writen( STDOUT_FILENO , buf , len , NULL ) ; 66 | if( nret == -1 ) 67 | { 68 | E( "*** ERROR : writen STDOUT_FILENO failed , errno[%d]\n" , errno ) 69 | return -1; 70 | } 71 | 72 | break; 73 | } 74 | } 75 | 76 | return 0; 77 | } 78 | 79 | int DoAction_run( struct CockerEnvironment *env ) 80 | { 81 | char container_merge_path[ PATH_MAX + 1 ] ; 82 | 83 | int connected_sock ; 84 | struct sockaddr_un connected_addr ; 85 | int i ; 86 | struct winsize origin_winsize ; 87 | char *bash_cmd = NULL ; 88 | 89 | int nret = 0 ; 90 | 91 | /* preprocess input parameters */ 92 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 93 | nret = access( env->container_path_base , F_OK ) ; 94 | I1TER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__container ) 95 | 96 | Snprintf( container_merge_path , sizeof(container_merge_path)-1 , "%s/merged" , env->container_path_base ); 97 | nret = access( container_merge_path , F_OK ) ; 98 | I1TER1( "*** ERROR : merged not exist in container '%s'\n" , env->cmd_para.__container ) 99 | 100 | GetEthernetNames( env , env->cmd_para.__container ); 101 | 102 | /* client connect to cockerinit */ 103 | connected_sock = socket( AF_UNIX , SOCK_STREAM , 0 ) ; 104 | if( connected_sock == -1 ) 105 | { 106 | E( "*** ERROR : socket failed , errno[%d]\n" , errno ) 107 | return -1; 108 | } 109 | 110 | for( i = 0 ; i < TRY_CONNECT_COUNT ; i++ ) 111 | { 112 | memset( & connected_addr , 0x00 , sizeof(struct sockaddr_un) ); 113 | connected_addr.sun_family = AF_UNIX ; 114 | snprintf( connected_addr.sun_path , sizeof(connected_addr.sun_path)-1 , "%s/dev/cocker.sock" , container_merge_path ); 115 | nret = connect( connected_sock , (struct sockaddr *) & connected_addr , sizeof(struct sockaddr_un) ) ; 116 | if( nret == 0 ) 117 | break; 118 | 119 | sleep(1); 120 | } 121 | if( i >= TRY_CONNECT_COUNT ) 122 | { 123 | E( "*** ERROR : connect[%s] failed , errno[%d]\n" , connected_addr.sun_path , errno ) 124 | return -1; 125 | } 126 | 127 | nret = ioctl( STDIN_FILENO , TIOCGWINSZ , & origin_winsize ) ; 128 | if( nret == -1 ) 129 | { 130 | E( "*** ERROR : ioctl STDIN_FILENO for origin failed , errno[%d]\n" , errno ) 131 | return -1; 132 | } 133 | 134 | nret = send( connected_sock , "C" , 1 , 0 ) ; 135 | if( nret == -1 ) 136 | { 137 | E( "*** ERROR : send 'C' failed , errno[%d]\n" , errno ) 138 | return -1; 139 | } 140 | 141 | nret = send( connected_sock , (void*) & origin_winsize , sizeof(struct winsize) , 0 ) ; 142 | if( nret == -1 ) 143 | { 144 | E( "*** ERROR : send winsize failed , errno[%d]\n" , errno ) 145 | return -1; 146 | } 147 | 148 | bash_cmd = env->cmd_para.__cmd ; 149 | nret = send( connected_sock , bash_cmd , strlen(bash_cmd) , 0 ) ; 150 | if( nret == -1 ) 151 | { 152 | E( "*** ERROR : send cmd failed , errno[%d]\n" , errno ) 153 | return -1; 154 | } 155 | 156 | tcp_and_pts_bridge( connected_sock ); 157 | 158 | RestoreTerminalAttr(); 159 | 160 | close( connected_sock ); 161 | 162 | return 0; 163 | 164 | } 165 | 166 | -------------------------------------------------------------------------------- /src/cocker/action_attach.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | #define TRY_CONNECT_COUNT 5 12 | 13 | struct termios g_termios_init ; 14 | struct termios g_termios_raw ; 15 | 16 | static void RestoreTerminalAttr() 17 | { 18 | tcsetattr( 0 , TCSANOW , & g_termios_init ); 19 | return; 20 | } 21 | 22 | static int tcp_and_pts_bridge( int connected_sock ) 23 | { 24 | struct pollfd poll_fds[ 2 ] ; 25 | char buf[ 4096 ] ; 26 | int len ; 27 | 28 | int nret = 0 ; 29 | 30 | tcgetattr( STDIN_FILENO , & g_termios_init ); 31 | atexit( & RestoreTerminalAttr ); 32 | memcpy( & g_termios_raw , & g_termios_init , sizeof(struct termios) ); 33 | cfmakeraw( & g_termios_raw ); 34 | tcsetattr( STDIN_FILENO , TCSANOW , & g_termios_raw ) ; 35 | 36 | while(1) 37 | { 38 | poll_fds[0].fd = connected_sock ; 39 | poll_fds[0].events = POLLIN|POLLHUP ; 40 | poll_fds[0].revents = 0 ; 41 | poll_fds[1].fd = STDIN_FILENO ; 42 | poll_fds[1].events = POLLIN|POLLHUP ; 43 | poll_fds[1].revents = 0 ; 44 | nret = poll( poll_fds , 2 , -1 ) ; 45 | if( nret == -1 ) 46 | { 47 | E( "*** ERROR : select failed , errno[%d]\n" , errno ) 48 | return -1; 49 | } 50 | 51 | if( (poll_fds[0].revents&POLLIN) || (poll_fds[0].revents&POLLHUP) ) 52 | { 53 | len = read( connected_sock , buf , sizeof(buf)-1 ) ; 54 | if( len == 0 ) 55 | { 56 | return 0; 57 | } 58 | else if( len == -1 ) 59 | { 60 | E( "*** ERROR : read connected_sock failed , errno[%d]\n" , errno ) 61 | return -1; 62 | } 63 | 64 | nret = writen( STDOUT_FILENO , buf , len , NULL ) ; 65 | if( nret == -1 ) 66 | { 67 | E( "*** ERROR : writen STDOUT_FILENO failed , errno[%d]\n" , errno ) 68 | return -1; 69 | } 70 | } 71 | 72 | if( (poll_fds[1].revents&POLLIN) || (poll_fds[1].revents&POLLHUP) ) 73 | { 74 | len = read( STDIN_FILENO , buf , sizeof(buf)-1 ) ; 75 | if( len == 0 ) 76 | { 77 | return 0; 78 | } 79 | else if( len == -1 ) 80 | { 81 | E( "*** ERROR : read STDIN_FILENO failed , errno[%d]\n" , errno ) 82 | return -1; 83 | } 84 | 85 | nret = writen( connected_sock , buf , len , NULL ) ; 86 | if( nret == -1 ) 87 | { 88 | E( "*** ERROR : writen connected_sock failed , errno[%d]\n" , errno ) 89 | return -1; 90 | } 91 | } 92 | } 93 | 94 | return 0; 95 | } 96 | 97 | int DoAction_attach( struct CockerEnvironment *env ) 98 | { 99 | char container_merge_path[ PATH_MAX + 1 ] ; 100 | 101 | int connected_sock ; 102 | struct sockaddr_un connected_addr ; 103 | int i ; 104 | struct winsize origin_winsize ; 105 | char *bash_cmd = NULL ; 106 | 107 | int nret = 0 ; 108 | 109 | /* preprocess input parameters */ 110 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 111 | nret = access( env->container_path_base , F_OK ) ; 112 | I1TER1( "*** ERROR : container '%s' not found\n" , env->cmd_para.__container ) 113 | 114 | Snprintf( container_merge_path , sizeof(container_merge_path)-1 , "%s/merged" , env->container_path_base ); 115 | nret = access( container_merge_path , F_OK ) ; 116 | I1TER1( "*** ERROR : merged not exist in container '%s'\n" , env->cmd_para.__container ) 117 | 118 | GetEthernetNames( env , env->cmd_para.__container ); 119 | 120 | /* client connect to cockerinit */ 121 | connected_sock = socket( AF_UNIX , SOCK_STREAM , 0 ) ; 122 | if( connected_sock == -1 ) 123 | { 124 | E( "*** ERROR : socket failed , errno[%d]\n" , errno ) 125 | return -1; 126 | } 127 | 128 | for( i = 0 ; i < TRY_CONNECT_COUNT ; i++ ) 129 | { 130 | memset( & connected_addr , 0x00 , sizeof(struct sockaddr_un) ); 131 | connected_addr.sun_family = AF_UNIX ; 132 | snprintf( connected_addr.sun_path , sizeof(connected_addr.sun_path)-1 , "%s/dev/cocker.sock" , container_merge_path ); 133 | nret = connect( connected_sock , (struct sockaddr *) & connected_addr , sizeof(struct sockaddr_un) ) ; 134 | if( nret == 0 ) 135 | break; 136 | 137 | sleep(1); 138 | } 139 | if( i >= TRY_CONNECT_COUNT ) 140 | { 141 | E( "*** ERROR : connect[%s] failed , errno[%d]\n" , connected_addr.sun_path , errno ) 142 | return -1; 143 | } 144 | 145 | nret = ioctl( STDIN_FILENO , TIOCGWINSZ , & origin_winsize ) ; 146 | if( nret == -1 ) 147 | { 148 | E( "*** ERROR : ioctl STDIN_FILENO for origin failed , errno[%d]\n" , errno ) 149 | return -1; 150 | } 151 | 152 | nret = send( connected_sock , "C" , 1 , 0 ) ; 153 | if( nret == -1 ) 154 | { 155 | E( "*** ERROR : send 'C' failed , errno[%d]\n" , errno ) 156 | return -1; 157 | } 158 | 159 | nret = send( connected_sock , (void*) & origin_winsize , sizeof(struct winsize) , 0 ) ; 160 | if( nret == -1 ) 161 | { 162 | E( "*** ERROR : send winsize failed , errno[%d]\n" , errno ) 163 | return -1; 164 | } 165 | 166 | bash_cmd = "/bin/bash -l" ; 167 | nret = send( connected_sock , bash_cmd , strlen(bash_cmd) , 0 ) ; 168 | if( nret == -1 ) 169 | { 170 | E( "*** ERROR : send bash_cmd failed , errno[%d]\n" , errno ) 171 | return -1; 172 | } 173 | 174 | tcp_and_pts_bridge( connected_sock ); 175 | 176 | RestoreTerminalAttr(); 177 | 178 | close( connected_sock ); 179 | 180 | return 0; 181 | 182 | } 183 | 184 | -------------------------------------------------------------------------------- /src/cocker/show_images.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoShow_images( struct CockerEnvironment *cocker_env ) 12 | { 13 | DIR *dir = NULL ; 14 | struct dirent *dirent = NULL ; 15 | DIR *dir2 = NULL ; 16 | struct dirent *dirent2 = NULL ; 17 | char version_path_base[ PATH_MAX + 1 ] ; 18 | char image_path_base[ PATH_MAX + 1 ] ; 19 | struct stat dir_stat ; 20 | int count ; 21 | char version[ VERSION_LEN_MAX + 1 ] ; 22 | char image_id[ IMAGES_ID_LEN_MAX + 1 ] ; 23 | struct stat image_path_stat ; 24 | struct tm image_path_modifytm ; 25 | char image_path_modifytime_buf[ 32 + 1 ] ; 26 | char image_rlayer_path[ PATH_MAX + 1 ] ; 27 | char image_size_file[ PATH_MAX + 1 ] ; 28 | struct stat image_size_file_stat ; 29 | int image_size ; 30 | char image_size_str[ 32 + 1 ] ; 31 | char file_buffer[ 4096 ] ; 32 | 33 | int nret = 0 ; 34 | 35 | count = 0 ; 36 | dir = opendir( cocker_env->images_path_base ) ; 37 | while( dir ) 38 | { 39 | dirent = readdir( dir ) ; 40 | if( dirent == NULL ) 41 | break; 42 | 43 | if( STRCMP( dirent->d_name , == , "." ) || STRCMP( dirent->d_name , == , ".." ) ) 44 | continue; 45 | 46 | if( Snprintf( version_path_base , sizeof(version_path_base) , "%s/%s" , cocker_env->images_path_base , dirent->d_name ) == NULL ) 47 | continue; 48 | memset( & dir_stat , 0x00 , sizeof(struct stat) ); 49 | nret = stat( version_path_base , & dir_stat ) ; 50 | if( nret == -1 ) 51 | continue; 52 | 53 | if( ! S_ISDIR(dir_stat.st_mode) ) 54 | continue; 55 | 56 | Snprintf( image_id , sizeof(image_id) , "%s" , dirent->d_name ); 57 | 58 | dir2 = opendir( version_path_base ) ; 59 | while( dir2 ) 60 | { 61 | dirent2 = readdir( dir2 ) ; 62 | if( dirent2 == NULL ) 63 | break; 64 | 65 | if( STRCMP( dirent2->d_name , == , "." ) || STRCMP( dirent2->d_name , == , ".." ) ) 66 | continue; 67 | 68 | if( Snprintf( image_path_base , sizeof(image_path_base) , "%s/%s" , version_path_base , dirent2->d_name ) == NULL ) 69 | continue; 70 | memset( & dir_stat , 0x00 , sizeof(struct stat) ); 71 | nret = stat( image_path_base , & dir_stat ) ; 72 | if( nret == -1 ) 73 | continue; 74 | if( ! S_ISDIR(dir_stat.st_mode) ) 75 | continue; 76 | 77 | Snprintf( version , sizeof(version) , "%s" , dirent2->d_name ); 78 | 79 | memset( image_path_base , 0x00 , sizeof(image_path_base) ); 80 | Snprintf( image_path_base , sizeof(image_path_base) , "%s/%s" , version_path_base , version ); 81 | stat( image_path_base , & image_path_stat ); 82 | memset( image_path_modifytime_buf , 0x00 , sizeof(image_path_modifytime_buf) ); 83 | localtime_r( & (image_path_stat.st_mtime) , & image_path_modifytm ); 84 | strftime( image_path_modifytime_buf , sizeof(image_path_modifytime_buf) , "%Y-%m-%dT%H:%M:%S" , & image_path_modifytm ); 85 | 86 | /* size */ 87 | Snprintf( image_rlayer_path , sizeof(image_rlayer_path) , "%s/rlayer" , image_path_base ); 88 | 89 | memset( file_buffer , 0x00 , sizeof(file_buffer) ); 90 | memset( image_size_file , 0x00 , sizeof(image_size_file) ); 91 | nret = ReadFileLine( file_buffer , sizeof(file_buffer) , image_size_file , sizeof(image_size_file) , "%s/size" , image_path_base ) ; 92 | if( nret ) 93 | { 94 | nret = GetDirectorySize( image_rlayer_path , & image_size ) ; 95 | if( nret ) 96 | { 97 | image_size = -1 ; 98 | } 99 | else 100 | { 101 | Snprintf( file_buffer , sizeof(file_buffer) , "%d" , image_size ); 102 | WriteFileLine( file_buffer , image_size_file , sizeof(image_size_file) , "%s/size" , image_path_base ); 103 | } 104 | } 105 | else 106 | { 107 | stat( image_size_file , & image_size_file_stat ); 108 | nret = IsDirectoryNewThan( image_rlayer_path , image_size_file_stat.st_mtime ) ; 109 | if( nret < 0 ) 110 | { 111 | image_size = -1 ; 112 | } 113 | else if( nret > 0 ) 114 | { 115 | nret = GetDirectorySize( image_rlayer_path , & image_size ) ; 116 | if( nret ) 117 | { 118 | image_size = -1 ; 119 | } 120 | else 121 | { 122 | Snprintf( file_buffer , sizeof(file_buffer) , "%d" , image_size ); 123 | WriteFileLine( file_buffer , image_size_file , sizeof(image_size_file) , "%s/size" , image_path_base ); 124 | } 125 | } 126 | else 127 | { 128 | image_size = atoi(file_buffer) ; 129 | } 130 | } 131 | 132 | if( image_size > 1024*1024*1024 ) 133 | Snprintf( image_size_str , sizeof(image_size_str) , "%d GB" , image_size / (1024*1024*1024) ); 134 | else if( image_size > 1024*1024 ) 135 | Snprintf( image_size_str , sizeof(image_size_str) , "%d MB" , image_size / (1024*1024) ); 136 | else if( image_size > 1024 ) 137 | Snprintf( image_size_str , sizeof(image_size_str) , "%d KB" , image_size / 1024 ); 138 | else if( image_size >= 0 ) 139 | Snprintf( image_size_str , sizeof(image_size_str) , "%d B" , image_size ); 140 | else 141 | Snprintf( image_size_str , sizeof(image_size_str) , "(unknow)" ); 142 | 143 | /* output */ 144 | if( count == 0 ) 145 | { 146 | printf( "%-30s %-10s %-19s %-10s\n" , "image_id" , "version" , "modify_datetime" , "size" ); 147 | printf( "--------------------------------------------------------------------\n" ); 148 | } 149 | 150 | printf( "%-30s %-10s %-19s %s\n" , dirent->d_name , version , image_path_modifytime_buf , image_size_str ); 151 | 152 | count++; 153 | } 154 | } 155 | 156 | return 0; 157 | } 158 | 159 | -------------------------------------------------------------------------------- /src/cocker/show_containers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int DoShow_containers( struct CockerEnvironment *cocker_env ) 12 | { 13 | DIR *dir = NULL ; 14 | struct dirent *dirent = NULL ; 15 | char container_path_base[ PATH_MAX + 1 ] ; 16 | struct stat dir_stat ; 17 | int count ; 18 | 19 | char container_image_file[ PATH_MAX + 1 ] ; 20 | char image[ 4096 ] ; 21 | char container_hostname_file[ PATH_MAX + 1 ] ; 22 | char hostname[ HOST_NAME_MAX ] ; 23 | char container_net_file[ PATH_MAX + 1 ] ; 24 | char net[ NET_LEN_MAX ] ; 25 | char container_netns_file[ PATH_MAX + 1 ] ; 26 | char netns[ NETNS_NAME_LEN_MAX ] ; 27 | char container_pid_file[ PATH_MAX + 1 ] ; 28 | char pid_str[ PID_LEN_MAX ] ; 29 | pid_t pid ; 30 | char status[ 40 ] ; 31 | char container_rwlayer_path[ PATH_MAX + 1 ] ; 32 | char container_size_file[ PATH_MAX + 1 ] ; 33 | struct stat container_size_file_stat ; 34 | int container_size ; 35 | char container_size_str[ 20 + 1 ] ; 36 | char file_buffer[ 4096 ] ; 37 | 38 | int nret = 0 ; 39 | 40 | dir = opendir( cocker_env->containers_path_base ) ; 41 | count = 0 ; 42 | while(1) 43 | { 44 | dirent = readdir( dir ) ; 45 | if( dirent == NULL ) 46 | break; 47 | 48 | if( STRCMP( dirent->d_name , == , "." ) || STRCMP( dirent->d_name , == , ".." ) ) 49 | continue; 50 | 51 | if( Snprintf( container_path_base , sizeof(container_path_base) , "%s/%s" , cocker_env->containers_path_base , dirent->d_name ) == NULL ) 52 | continue; 53 | memset( & dir_stat , 0x00 , sizeof(struct stat) ); 54 | nret = stat( container_path_base , & dir_stat ) ; 55 | if( nret == -1 ) 56 | continue; 57 | if( ! S_ISDIR(dir_stat.st_mode) ) 58 | continue; 59 | 60 | /* image */ 61 | memset( image , 0x00 , sizeof(image) ); 62 | memset( container_image_file , 0x00 , sizeof(container_image_file) ); 63 | nret = ReadFileLine( image , sizeof(image) , container_image_file , sizeof(container_image_file) , "%s/%s/image" , cocker_env->containers_path_base , dirent->d_name ) ; 64 | if( nret ) 65 | { 66 | memset( container_image_file , 0x00 , sizeof(container_image_file) ); 67 | memset( image , 0x00 , sizeof(image) ); 68 | } 69 | TrimEnter( image ); 70 | 71 | /* hostname */ 72 | memset( hostname , 0x00 , sizeof(hostname) ); 73 | memset( container_hostname_file , 0x00 , sizeof(container_hostname_file) ); 74 | nret = ReadFileLine( hostname , sizeof(hostname) , container_hostname_file , sizeof(container_hostname_file) , "%s/%s/hostname" , cocker_env->containers_path_base , dirent->d_name ) ; 75 | if( nret ) 76 | { 77 | memset( container_hostname_file , 0x00 , sizeof(container_hostname_file) ); 78 | memset( hostname , 0x00 , sizeof(hostname) ); 79 | } 80 | TrimEnter( hostname ); 81 | 82 | /* net */ 83 | memset( net , 0x00 , sizeof(net) ); 84 | memset( container_net_file , 0x00 , sizeof(container_net_file) ); 85 | nret = ReadFileLine( net , sizeof(net) , container_net_file , sizeof(container_net_file) , "%s/%s/net" , cocker_env->containers_path_base , dirent->d_name ) ; 86 | if( nret ) 87 | { 88 | memset( container_net_file , 0x00 , sizeof(container_net_file) ); 89 | memset( net , 0x00 , sizeof(net) ); 90 | } 91 | TrimEnter( net ); 92 | 93 | /* netns */ 94 | memset( netns , 0x00 , sizeof(netns) ); 95 | memset( container_netns_file , 0x00 , sizeof(container_netns_file) ); 96 | nret = ReadFileLine( netns , sizeof(netns) , container_netns_file , sizeof(container_netns_file) , "%s/%s/netns" , cocker_env->containers_path_base , dirent->d_name ) ; 97 | if( nret ) 98 | { 99 | memset( container_netns_file , 0x00 , sizeof(container_netns_file) ); 100 | memset( netns , 0x00 , sizeof(netns) ); 101 | } 102 | TrimEnter( netns ); 103 | 104 | /* size */ 105 | Snprintf( container_rwlayer_path , sizeof(container_rwlayer_path) , "%s/%s/rwlayer" , cocker_env->containers_path_base , dirent->d_name ); 106 | 107 | memset( file_buffer , 0x00 , sizeof(file_buffer) ); 108 | memset( container_size_file , 0x00 , sizeof(container_size_file) ); 109 | nret = ReadFileLine( file_buffer , sizeof(file_buffer) , container_size_file , sizeof(container_size_file) , "%s/%s/size" , cocker_env->containers_path_base , dirent->d_name ) ; 110 | if( nret ) 111 | { 112 | nret = GetDirectorySize( container_rwlayer_path , & container_size ) ; 113 | if( nret ) 114 | { 115 | container_size = -1 ; 116 | } 117 | else 118 | { 119 | Snprintf( file_buffer , sizeof(file_buffer) , "%d" , container_size ); 120 | WriteFileLine( file_buffer , container_size_file , sizeof(container_size_file) , "%s/%s/size" , cocker_env->containers_path_base , dirent->d_name ); 121 | } 122 | } 123 | else 124 | { 125 | stat( container_size_file , & container_size_file_stat ); 126 | nret = IsDirectoryNewThan( container_rwlayer_path , container_size_file_stat.st_mtime ) ; 127 | if( nret < 0 ) 128 | { 129 | container_size = -1 ; 130 | } 131 | else if( nret > 0 ) 132 | { 133 | nret = GetDirectorySize( container_rwlayer_path , & container_size ) ; 134 | if( nret ) 135 | { 136 | container_size = -1 ; 137 | } 138 | else 139 | { 140 | Snprintf( file_buffer , sizeof(file_buffer) , "%d" , container_size ); 141 | WriteFileLine( file_buffer , container_size_file , sizeof(container_size_file) , "%s/%s/size" , cocker_env->containers_path_base , dirent->d_name ); 142 | } 143 | } 144 | else 145 | { 146 | container_size = atoi(file_buffer) ; 147 | } 148 | } 149 | 150 | if( container_size > 1024*1024*1024 ) 151 | Snprintf( container_size_str , sizeof(container_size_str) , "%d GB" , container_size / (1024*1024*1024) ); 152 | else if( container_size > 1024*1024 ) 153 | Snprintf( container_size_str , sizeof(container_size_str) , "%d MB" , container_size / (1024*1024) ); 154 | else if( container_size > 1024 ) 155 | Snprintf( container_size_str , sizeof(container_size_str) , "%d KB" , container_size / 1024 ); 156 | else if( container_size >= 0 ) 157 | Snprintf( container_size_str , sizeof(container_size_str) , "%d B" , container_size ); 158 | else 159 | Snprintf( container_size_str , sizeof(container_size_str) , "(unknow)" ); 160 | 161 | /* pid */ 162 | memset( container_pid_file , 0x00 , sizeof(container_pid_file) ); 163 | memset( pid_str , 0x00 , sizeof(pid_str) ); 164 | nret = ReadFileLine( pid_str , sizeof(pid_str) , container_pid_file , sizeof(container_pid_file) , "%s/%s/pid" , cocker_env->containers_path_base , dirent->d_name ) ; 165 | if( nret ) 166 | { 167 | memset( pid_str , 0x00 , sizeof(pid_str) ); 168 | memset( container_pid_file , 0x00 , sizeof(container_pid_file) ); 169 | if( nret > 0 ) 170 | { 171 | Snprintf( status , sizeof(status) , "STOPED" ); 172 | } 173 | else 174 | { 175 | Snprintf( status , sizeof(status) , "EXPECTION" ); 176 | } 177 | } 178 | else 179 | { 180 | TrimEnter( pid_str ); 181 | pid = atoi(pid_str) ; 182 | nret = kill( pid , 0 ) ; 183 | if( nret == -1 ) 184 | { 185 | Snprintf( status , sizeof(status) , "EXPECTION(%s)" , pid_str ); 186 | } 187 | else 188 | { 189 | Snprintf( status , sizeof(status) , "RUNNING(%s)" , pid_str ); 190 | } 191 | } 192 | 193 | /* output */ 194 | if( count == 0 ) 195 | { 196 | printf( "%-20s %-20s %-10s %-10s %-16s %-10s %s\n" , "container_id" , "image" , "hostname" , "net" , "netns" , "size" , "status" ); 197 | printf( "-----------------------------------------------------------------------------------------------------------\n" ); 198 | } 199 | 200 | printf( "%-20s %-20s %-10s %-10s %-16s %-10s %s\n" , dirent->d_name , image , hostname , net , netns , container_size_str , status ); 201 | 202 | count++; 203 | } 204 | 205 | return 0; 206 | } 207 | 208 | -------------------------------------------------------------------------------- /src/util/file.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_util.h" 10 | 11 | int SnprintfAndCheckDir( char *path_buf , int path_bufsize , char *path_format , ... ) 12 | { 13 | char *p_path = NULL ; 14 | va_list valist ; 15 | struct stat dir_stat ; 16 | 17 | int nret = 0 ; 18 | 19 | va_start( valist , path_format ); 20 | p_path = SnprintfV( path_buf , path_bufsize , path_format , valist ) ; 21 | va_end( valist ); 22 | if( p_path == NULL ) 23 | return -1; 24 | 25 | memset( & dir_stat , 0x00 , sizeof(struct stat) ); 26 | nret = stat( p_path , & dir_stat ) ; 27 | if( nret == -1 ) 28 | return -1; 29 | if( ! S_ISDIR(dir_stat.st_mode) ) 30 | return -2; 31 | 32 | return 0; 33 | } 34 | 35 | int SnprintfAndChangeDir( char *path_buf , int path_bufsize , char *path_format , ... ) 36 | { 37 | char *p_path = NULL ; 38 | va_list valist ; 39 | 40 | va_start( valist , path_format ); 41 | p_path = SnprintfV( path_buf , path_bufsize , path_format , valist ) ; 42 | va_end( valist ); 43 | if( p_path == NULL ) 44 | return -1; 45 | 46 | chdir( p_path ); 47 | 48 | return 0; 49 | } 50 | 51 | int CheckAndMakeDir( char *path ) 52 | { 53 | int nret = 0 ; 54 | 55 | nret = access( path , F_OK ) ; 56 | if( nret == -1 ) 57 | { 58 | nret = mkdir( path , 00777 ) ; 59 | if( nret == -1 ) 60 | return -1; 61 | } 62 | 63 | return 0; 64 | } 65 | 66 | int SnprintfAndMakeDir( char *path_buf , int path_bufsize , char *path_format , ... ) 67 | { 68 | char *p_path = NULL ; 69 | va_list valist ; 70 | 71 | int nret = 0 ; 72 | 73 | va_start( valist , path_format ); 74 | p_path = SnprintfV( path_buf , path_bufsize , path_format , valist ) ; 75 | va_end( valist ); 76 | if( p_path == NULL ) 77 | return -1; 78 | 79 | nret = CheckAndMakeDir( p_path ) ; 80 | if( nret ) 81 | return OVERLAY_RET(100,nret); 82 | 83 | return 0; 84 | } 85 | 86 | int SnprintfAndUnlink( char *path_buf , int path_bufsize , char *path_format , ... ) 87 | { 88 | char *p_file = NULL ; 89 | va_list valist ; 90 | 91 | int nret = 0 ; 92 | 93 | va_start( valist , path_format ); 94 | p_file = SnprintfV( path_buf , path_bufsize , path_format , valist ) ; 95 | va_end( valist ); 96 | if( p_file == NULL ) 97 | return -1; 98 | 99 | nret = unlink( p_file ) ; 100 | if( nret == -1 ) 101 | return OVERLAY_RET(100,nret); 102 | 103 | return 0; 104 | } 105 | 106 | int SnprintfAndSystem( char *cmd_buf , int cmd_bufsize , char *cmd_format , ... ) 107 | { 108 | char *p_cmd = NULL ; 109 | va_list valist ; 110 | 111 | int nret = 0 ; 112 | 113 | va_start( valist , cmd_format ); 114 | p_cmd = SnprintfV( cmd_buf , cmd_bufsize , cmd_format , valist ) ; 115 | va_end( valist ); 116 | if( p_cmd == NULL ) 117 | return -1; 118 | 119 | nret = system( p_cmd ) ; 120 | if( nret ) 121 | return OVERLAY_RET(100,nret); 122 | 123 | return 0; 124 | } 125 | 126 | int SnprintfAndPopen( char *output_buf , int output_bufsize , char *cmd_buf , int cmd_bufsize , char *cmd_format , ... ) 127 | { 128 | char *p_cmd = NULL ; 129 | FILE *popen_fp = NULL ; 130 | va_list valist ; 131 | 132 | int nret = 0 ; 133 | 134 | va_start( valist , cmd_format ); 135 | p_cmd = SnprintfV( cmd_buf , cmd_bufsize , cmd_format , valist ) ; 136 | va_end( valist ); 137 | if( p_cmd == NULL ) 138 | return -1; 139 | 140 | popen_fp = popen( p_cmd , "r" ) ; 141 | if( popen_fp == NULL ) 142 | return -2; 143 | 144 | if( output_buf ) 145 | { 146 | memset( output_buf , 0x00 , output_bufsize ); 147 | nret = fread( output_buf , output_bufsize , 1 , popen_fp ) ; 148 | if( nret == -1 ) 149 | return -3; 150 | } 151 | 152 | pclose( popen_fp ); 153 | 154 | return 0; 155 | } 156 | 157 | int WriteFileLine( char *fileline , char *pathfile_buf , int pathfile_bufsize , char *pathfile_format , ... ) 158 | { 159 | char *p_pathfile = NULL ; 160 | va_list valist ; 161 | int fd ; 162 | 163 | va_start( valist , pathfile_format ); 164 | p_pathfile = SnprintfV( pathfile_buf , pathfile_bufsize , pathfile_format , valist ) ; 165 | va_end( valist ); 166 | if( p_pathfile == NULL ) 167 | return -1; 168 | 169 | fd = open( p_pathfile , O_CREAT|O_TRUNC|O_WRONLY , 00777 ) ; 170 | if( fd == -1 ) 171 | return -1; 172 | 173 | write( fd , fileline , strlen(fileline) ); 174 | 175 | close( fd ); 176 | 177 | return 0; 178 | } 179 | 180 | int ReadFileLine( char *fileline_buf , int fileline_bufsize , char *pathfile_buf , int pathfile_bufsize , char *pathfile_format , ... ) 181 | { 182 | char *p_pathfile = NULL ; 183 | va_list valist ; 184 | int fd ; 185 | int len ; 186 | 187 | va_start( valist , pathfile_format ); 188 | p_pathfile = SnprintfV( pathfile_buf , pathfile_bufsize , pathfile_format , valist ) ; 189 | va_end( valist ); 190 | if( p_pathfile == NULL ) 191 | return -1; 192 | 193 | fd = open( p_pathfile , O_RDONLY , 00777 ) ; 194 | if( fd == -1 ) 195 | return 1; 196 | 197 | len = read( fd , fileline_buf , fileline_bufsize ) ; 198 | 199 | close( fd ); 200 | 201 | if( fileline_buf[len-1] == '\n' ) 202 | fileline_buf[len-1] = '\0' ; 203 | 204 | return 0; 205 | } 206 | 207 | int IsDirectoryNewThan( char *path , time_t mtime ) 208 | { 209 | DIR *dir = NULL ; 210 | struct dirent *dirent = NULL ; 211 | char sub_path[ PATH_MAX + 1 ] ; 212 | struct stat dir_stat ; 213 | 214 | int nret = 0 ; 215 | 216 | dir = opendir( path ) ; 217 | if( dir == NULL ) 218 | return -1; 219 | while(1) 220 | { 221 | dirent = readdir( dir ) ; 222 | if( dirent == NULL ) 223 | break; 224 | if( STRCMP( dirent->d_name , == , "." ) || STRCMP( dirent->d_name , == , ".." ) ) 225 | continue; 226 | 227 | if( Snprintf( sub_path , sizeof(sub_path) , "%s/%s" , path , dirent->d_name ) == NULL ) 228 | return -2; 229 | 230 | memset( & dir_stat , 0x00 , sizeof(struct stat) ); 231 | nret = stat( sub_path , & dir_stat ) ; 232 | if( nret == -1 ) 233 | return -3; 234 | if( S_ISDIR(dir_stat.st_mode) ) 235 | { 236 | if( dir_stat.st_mtime > mtime ) 237 | return 1; 238 | 239 | return IsDirectoryNewThan( sub_path , mtime ); 240 | } 241 | } 242 | 243 | return 0; 244 | } 245 | 246 | static int _GetDirectorySize( char *path , int *p_directory_size ) 247 | { 248 | DIR *dir = NULL ; 249 | struct dirent *dirent = NULL ; 250 | char sub_path[ PATH_MAX + 1 ] ; 251 | struct stat file_stat ; 252 | 253 | int nret = 0 ; 254 | 255 | dir = opendir( path ) ; 256 | if( dir == NULL ) 257 | return -1; 258 | 259 | while(1) 260 | { 261 | dirent = readdir( dir ) ; 262 | if( dirent == NULL ) 263 | break; 264 | if( STRCMP( dirent->d_name , == , "." ) || STRCMP( dirent->d_name , == , ".." ) ) 265 | continue; 266 | 267 | if( Snprintf( sub_path , sizeof(sub_path) , "%s/%s" , path , dirent->d_name ) == NULL ) 268 | { 269 | closedir( dir ); 270 | return -2; 271 | } 272 | 273 | memset( & file_stat , 0x00 , sizeof(struct stat) ); 274 | nret = stat( sub_path , & file_stat ) ; 275 | if( nret == -1 ) 276 | { 277 | closedir( dir ); 278 | return -3; 279 | } 280 | 281 | if( S_ISDIR(file_stat.st_mode) ) 282 | { 283 | nret = _GetDirectorySize( sub_path , p_directory_size ) ; 284 | if( nret ) 285 | return nret; 286 | } 287 | else if( S_ISREG(file_stat.st_mode) ) 288 | { 289 | (*p_directory_size) += file_stat.st_size ; 290 | } 291 | } 292 | 293 | closedir( dir ); 294 | 295 | return 0; 296 | } 297 | 298 | int GetDirectorySize( char *path , int *p_directory_size ) 299 | { 300 | (*p_directory_size) = 0 ; 301 | return _GetDirectorySize( path , p_directory_size ); 302 | } 303 | 304 | int IsDirectoryEmpty( char *version_path_base ) 305 | { 306 | DIR *dir = NULL ; 307 | struct dirent *dirent = NULL ; 308 | 309 | dir = opendir( version_path_base ) ; 310 | if( dir == NULL ) 311 | return -1; 312 | 313 | while(1) 314 | { 315 | dirent = readdir( dir ) ; 316 | if( dirent == NULL ) 317 | break; 318 | if( STRCMP( dirent->d_name , == , "." ) || STRCMP( dirent->d_name , == , ".." ) ) 319 | continue; 320 | 321 | closedir( dir ); 322 | return 1; 323 | } 324 | 325 | closedir( dir ); 326 | return 0; 327 | } 328 | 329 | -------------------------------------------------------------------------------- /src/cocker/action_create.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | int CreateContainer( struct CockerEnvironment *env , char *__image , char *__container ) 12 | { 13 | char container[ CONTAINER_ID_LEN_MAX + 1 ] ; 14 | 15 | char cmd[ 4096 ] ; 16 | 17 | char pid_str[ PID_LEN_MAX + 1 ] ; 18 | pid_t pid ; 19 | struct CockerVolume *volume = NULL ; 20 | FILE *container_volume_fp = NULL ; 21 | 22 | char container_rwlayer_path[ PATH_MAX + 1 ] ; 23 | char container_rwlayer_etc_path[ PATH_MAX + 1 ] ; 24 | char container_merged_path[ PATH_MAX + 1 ] ; 25 | char container_workdir_path[ PATH_MAX + 1 ] ; 26 | char container_image_file[ PATH_MAX + 1 ] ; 27 | char container_hostname_file[ PATH_MAX + 1 ] ; 28 | char container_volume_file[ PATH_MAX + 1 ] ; 29 | char container_rwlayer_net_file[ PATH_MAX + 1 ] ; 30 | char container_rwlayer_netns_file[ PATH_MAX + 1 ] ; 31 | char container_vip_file[ PATH_MAX + 1 ] ; 32 | char container_port_mapping_file[ PATH_MAX + 1 ] ; 33 | 34 | int nret = 0 ; 35 | 36 | /* preprocess input parameters */ 37 | Snprintf( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , env->cmd_para.__container ); 38 | nret = access( env->container_path_base , F_OK ) ; 39 | I0TER1( "*** ERROR : container '%s' exist\n" , env->cmd_para.__container ) 40 | 41 | if( __image && __image[0] ) 42 | { 43 | char image[ IMAGES_ID_LEN_MAX + 1 ] ; 44 | char version[ PATH_MAX + 1 ] ; 45 | char *p = NULL ; 46 | char *p2 = NULL ; 47 | 48 | memset( image , 0x00 , sizeof(image) ); 49 | strncpy( image , __image , sizeof(image)-1 ); 50 | p = strtok( image , "," ) ; 51 | while( p ) 52 | { 53 | p2 = strchr( p , ':' ) ; 54 | if( p2 == NULL ) 55 | { 56 | Snprintf( env->version_path_base , sizeof(env->version_path_base) , "%s/%s" , env->images_path_base , p ) ; 57 | nret = GetMaxVersionPath( env->version_path_base , version , sizeof(version) ) ; 58 | INTER1( "*** ERROR : GetMaxVersionPath[%s] failed[%d]\n" , env->version_path_base , nret ) 59 | 60 | nret = SnprintfAndCheckDir( NULL , -1 , "%s/%s/%s/rlayer" , env->images_path_base , p , version ) ; 61 | } 62 | else 63 | { 64 | nret = SnprintfAndCheckDir( NULL , -1 , "%s/%.*s/%s/rlayer" , env->images_path_base , (int)(p2-p) , p , p2+1 ) ; 65 | } 66 | INTER1( "*** ERROR : image[%s] not found\n" , p ) 67 | 68 | p = strtok( NULL , "," ) ; 69 | } 70 | } 71 | 72 | if( __container == NULL ) 73 | { 74 | memset( container , 0x00 , sizeof(container) ); 75 | GenerateContainerId( __image , container ); 76 | __container = container ; 77 | } 78 | 79 | GetEthernetNames( env , __container ); 80 | 81 | /* read pid file */ 82 | memset( pid_str , 0x00 , sizeof(pid_str) ); 83 | nret = ReadFileLine( pid_str , sizeof(pid_str)-1 , NULL , -1 , "%s/%s/pid" , env->containers_path_base , __container ) ; 84 | if( nret == 0 ) 85 | { 86 | pid = atoi(pid_str) ; 87 | if( pid > 0 ) 88 | { 89 | nret = kill( pid , 0 ) ; 90 | I0TER1( "*** ERROR : container is already running\n" ) 91 | } 92 | } 93 | 94 | /* create container folders and files */ 95 | nret = SnprintfAndMakeDir( env->container_path_base , sizeof(env->container_path_base)-1 , "%s/%s" , env->containers_path_base , __container ) ; 96 | INTER1( "*** ERROR : SnprintfAndMakeDir / failed[%d] , errno[%d]\n" , nret , errno ) 97 | EIDTI( "mkdir %s ok\n" , env->container_path_base ) 98 | 99 | nret = SnprintfAndMakeDir( container_rwlayer_path , sizeof(container_rwlayer_path) , "%s/rwlayer" , env->container_path_base ) ; 100 | INTER1( "*** ERROR : SnprintfAndMakeDir rwlayer failed[%d] , errno[%d]\n" , nret , errno ) 101 | EIDTI( "mkdir %s ok\n" , container_rwlayer_path ) 102 | 103 | nret = SnprintfAndMakeDir( container_rwlayer_etc_path , sizeof(container_rwlayer_etc_path) , "%s/rwlayer/etc" , env->container_path_base ) ; 104 | INTER1( "*** ERROR : SnprintfAndMakeDir /etc failed[%d] , errno[%d]\n" , nret , errno ) 105 | EIDTI( "mkdir %s ok\n" , container_rwlayer_etc_path ) 106 | 107 | nret = SnprintfAndMakeDir( container_merged_path , sizeof(container_merged_path) , "%s/merged" , env->container_path_base ) ; 108 | INTER1( "*** ERROR : SnprintfAndMakeDir merged failed[%d] , errno[%d]\n" , nret , errno ) 109 | EIDTI( "mkdir %s ok\n" , container_merged_path ) 110 | 111 | nret = SnprintfAndMakeDir( container_workdir_path , sizeof(container_workdir_path) , "%s/workdir" , env->container_path_base ) ; 112 | INTER1( "*** ERROR : SnprintfAndMakeDir workdir failed[%d] , errno[%d]\n" , nret , errno ) 113 | EIDTI( "mkdir %s ok\n" , container_workdir_path ) 114 | 115 | if( __image && __image[0] ) 116 | { 117 | nret = WriteFileLine( __image , container_image_file , sizeof(container_image_file) , "%s/image" , env->container_path_base ) ; 118 | INTER1( "*** ERROR : WriteFileLine image failed[%d] , errno[%d]\n" , nret , errno ) 119 | EIDTI( "write file %s ok\n" , container_image_file ) 120 | } 121 | /* 122 | else 123 | { 124 | nret = WriteFileLine( "" , container_image_file , sizeof(container_image_file) , "%s/images" , env->container_path_base ) ; 125 | INTER1( "*** ERROR : WriteFileLine image failed[%d] , errno[%d]\n" , nret , errno ) 126 | EIDTI( "write file %s ok\n" , container_image_file ) 127 | } 128 | */ 129 | 130 | if( ! list_empty( & (env->cmd_para.volume_list) ) ) 131 | { 132 | Snprintf( container_volume_file , sizeof(container_volume_file) , "%s/volume" , env->container_path_base ) ; 133 | container_volume_fp = fopen( container_volume_file , "w" ) ; 134 | IxTER1( (container_volume_fp==NULL) , "*** ERROR : WriteFileLine volume failed[%d] , errno[%d]\n" , nret , errno ) 135 | 136 | list_for_each_entry( volume , & (env->cmd_para.volume_list) , struct CockerVolume , volume_node ) 137 | { 138 | fprintf( container_volume_fp , "%.*s:%s\n" , volume->host_path_len , volume->host_path , volume->container_path ); 139 | IDTI( "write file %s [%.*s:%s]\n" , container_volume_file , volume->host_path_len , volume->host_path , volume->container_path ) 140 | } 141 | 142 | fclose( container_volume_fp ); 143 | } 144 | 145 | if( env->cmd_para.__host_name == NULL ) 146 | env->cmd_para.__host_name = __container ; 147 | 148 | nret = WriteFileLine( env->cmd_para.__host_name , container_hostname_file , sizeof(container_hostname_file) , "%s/hostname" , env->container_path_base ) ; 149 | INTER1( "*** ERROR : WriteFileLine hostname failed[%d] , errno[%d]\n" , nret , errno ) 150 | EIDTI( "write file %s ok\n" , container_hostname_file ) 151 | 152 | /* create network-namespace */ 153 | nret = WriteFileLine( env->cmd_para.__net , container_rwlayer_net_file , sizeof(container_rwlayer_net_file) , "%s/net" , env->container_path_base ) ; 154 | INTER1( "*** ERROR : WriteFileLine vip failed[%d] , errno[%d]\n" , nret , errno ) 155 | EIDTI( "write file [%s] ok\n" , container_rwlayer_net_file ) 156 | 157 | if( STRCMP( env->cmd_para.__net , == , "BRIDGE" ) ) 158 | { 159 | nret = WriteFileLine( env->netns_name , container_rwlayer_netns_file , sizeof(container_rwlayer_netns_file) , "%s/netns" , env->container_path_base ) ; 160 | INTER1( "*** ERROR : WriteFileLine netns failed[%d] , errno[%d]\n" , nret , errno ) 161 | EIDTI( "write file [%s] ok\n" , container_rwlayer_netns_file ) 162 | 163 | nret = WriteFileLine( env->cmd_para.__vip , container_vip_file , sizeof(container_vip_file) , "%s/vip" , env->container_path_base ) ; 164 | INTER1( "*** ERROR : WriteFileLine vip failed[%d] , errno[%d]\n" , nret , errno ) 165 | EIDTI( "write file [%s] ok\n" , container_vip_file ) 166 | 167 | if( env->cmd_para.__port_mapping ) 168 | { 169 | nret = WriteFileLine( env->cmd_para.__port_mapping , container_port_mapping_file , sizeof(container_port_mapping_file) , "%s/port_mapping" , env->container_path_base ) ; 170 | INTER1( "*** ERROR : WriteFileLine port_mapping failed[%d] , errno[%d]\n" , nret , errno ) 171 | EIDTI( "write file [%s] ok\n" , container_port_mapping_file ) 172 | } 173 | 174 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "ip netns add %s" , env->netns_name ) ; 175 | INTER1( "*** ERROR : system [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 176 | EIDTI( "system [%s] ok\n" , cmd ) 177 | } 178 | else if( STRCMP( env->cmd_para.__net , == , "CUSTOM" ) ) 179 | { 180 | nret = WriteFileLine( env->netns_name , container_rwlayer_netns_file , sizeof(container_rwlayer_netns_file) , "%s/netns" , env->container_path_base ) ; 181 | INTER1( "*** ERROR : WriteFileLine netns failed[%d] , errno[%d]\n" , nret , errno ) 182 | EIDTI( "write file [%s] ok\n" , container_rwlayer_netns_file ) 183 | 184 | nret = SnprintfAndSystem( cmd , sizeof(cmd) , "ip netns add %s" , env->netns_name ) ; 185 | INTER1( "*** ERROR : system [%s] failed[%d] , errno[%d]\n" , cmd , nret , errno ) 186 | EIDTI( "system [%s] ok\n" , cmd ) 187 | } 188 | 189 | return 0; 190 | } 191 | 192 | int DoAction_create( struct CockerEnvironment *env ) 193 | { 194 | int nret = 0 ; 195 | 196 | nret = CreateContainer( env , env->cmd_para.__image , env->cmd_para.__container ) ; 197 | if( nret == 0 ) 198 | { 199 | if( env->cmd_para.__boot ) 200 | { 201 | nret = DoAction_boot( env ) ; 202 | } 203 | else 204 | { 205 | printf( "OK\n" ); 206 | } 207 | } 208 | 209 | return nret; 210 | } 211 | -------------------------------------------------------------------------------- /src/util/cocker_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #ifndef _H_VH_UTIL_IN_ 10 | #define _H_VH_UTIL_IN_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "openssl/md5.h" 34 | #define __USE_GNU 35 | #include 36 | 37 | #include "list.h" 38 | 39 | #include "LOGC.h" 40 | #include "filerpl.h" 41 | 42 | int ptmname_r(int fd, char * buf, size_t buflen); 43 | int ptsname_r(int fd, char * buf, size_t buflen); 44 | 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | 49 | #ifndef MAX 50 | #define MAX(_a_,_b_) ( (_a_)>(_b_)?(_a_):(_b_) ) 51 | #endif 52 | 53 | #ifndef MIN 54 | #define MIN(_a_,_b_) ( (_a_)<(_b_)?(_a_):(_b_) ) 55 | #endif 56 | 57 | #ifndef STRCMP 58 | #define STRCMP(_a_,_C_,_b_) ( strcmp(_a_,_b_) _C_ 0 ) 59 | #define STRNCMP(_a_,_C_,_b_,_n_) ( strncmp(_a_,_b_,_n_) _C_ 0 ) 60 | #endif 61 | 62 | #ifndef STRICMP 63 | #if ( defined _WIN32 ) 64 | #define STRICMP(_a_,_C_,_b_) ( stricmp(_a_,_b_) _C_ 0 ) 65 | #define STRNICMP(_a_,_C_,_b_,_n_) ( strnicmp(_a_,_b_,_n_) _C_ 0 ) 66 | #elif ( defined __unix ) || ( defined _AIX ) || ( defined __linux__ ) || ( defined __hpux ) 67 | #define STRICMP(_a_,_C_,_b_) ( strcasecmp(_a_,_b_) _C_ 0 ) 68 | #define STRNICMP(_a_,_C_,_b_,_n_) ( strncasecmp(_a_,_b_,_n_) _C_ 0 ) 69 | #endif 70 | #endif 71 | 72 | #ifndef SNPRINTF_OVERFLOW 73 | #define SNPRINTF_OVERFLOW(_ret_,_sizeof_) ( (_ret_) == -1 || (_ret_) >= (_sizeof_) ) 74 | #endif 75 | 76 | #ifndef OVERLAY_RET 77 | #define OVERLAY_RET(_ret_,_inframe_ret_) ((_inframe_ret_)<0?-(_ret_)+(_inframe_ret_):(_ret_)+(_inframe_ret_)) 78 | #endif 79 | 80 | #ifndef IMAGES_ID_LEN_MAX 81 | #define IMAGES_ID_LEN_MAX 1024 82 | #endif 83 | 84 | #ifndef CREATE_DATATIME_LEN_MAX 85 | #define CREATE_DATATIME_LEN_MAX 20 86 | #endif 87 | 88 | #ifndef VERSION_LEN_MAX 89 | #define VERSION_LEN_MAX 16 90 | #endif 91 | 92 | #ifndef TAG_LEN_MAX 93 | #define TAG_LEN_MAX 64 94 | #endif 95 | 96 | #ifndef CONTAINER_ID_LEN_MAX 97 | #define CONTAINER_ID_LEN_MAX 64 98 | #endif 99 | 100 | #ifndef ETHERNET_NAME_LEN_MAX 101 | #define ETHERNET_NAME_LEN_MAX 13 102 | #endif 103 | 104 | #ifndef NET_LEN_MAX 105 | #define NET_LEN_MAX 10 106 | #endif 107 | 108 | #ifndef NETNS_NAME_LEN_MAX 109 | #define NETNS_NAME_LEN_MAX 256 110 | #endif 111 | 112 | #ifndef IP_LEN_MAX 113 | #define IP_LEN_MAX 20 114 | #endif 115 | 116 | #ifndef PORT_MAP_LEN_MAX 117 | #define PORT_MAP_LEN_MAX 64 118 | #endif 119 | 120 | #ifndef PID_LEN_MAX 121 | #define PID_LEN_MAX 20 122 | #endif 123 | 124 | #ifndef CGROUP_PATH 125 | #define CGROUP_PATH "/sys/fs/cgroup" 126 | #endif 127 | 128 | #ifndef COCKERIMAGE_FILE_EXTNAME 129 | #define COCKERIMAGE_FILE_EXTNAME "cockerimage" 130 | #endif 131 | 132 | #ifndef SREPO_LEN_MAX 133 | #define SREPO_LEN_MAX 1024 134 | #endif 135 | 136 | /* 137 | * expression macro 138 | */ 139 | 140 | #define IS_NULL_OR_EMPTY(_p_) ( (_p_) == NULL || (_p_)[0] == '\0' ) 141 | 142 | /* 143 | * statement macro 144 | */ 145 | 146 | #define I( ... ) \ 147 | { \ 148 | printf( __VA_ARGS__ ); fflush(stdout); \ 149 | INFOLOGC( __VA_ARGS__ ) \ 150 | } \ 151 | 152 | #define E(...) \ 153 | { \ 154 | printf( __VA_ARGS__ ); fflush(stdout); \ 155 | ERRORLOGC( __VA_ARGS__ ) \ 156 | } \ 157 | 158 | #define ER1(...) \ 159 | { \ 160 | printf( __VA_ARGS__ ); fflush(stdout); \ 161 | ERRORLOGC( __VA_ARGS__ ) \ 162 | return -1; \ 163 | } \ 164 | 165 | #define INTx(_return_statement_,...) \ 166 | if( nret ) \ 167 | { \ 168 | _return_statement_; \ 169 | } \ 170 | 171 | #define INTE(...) \ 172 | if( nret ) \ 173 | { \ 174 | printf( __VA_ARGS__ ); fflush(stdout); \ 175 | ERRORLOGC( __VA_ARGS__ ) \ 176 | } \ 177 | 178 | #define INTER1(...) \ 179 | if( nret ) \ 180 | { \ 181 | printf( __VA_ARGS__ ); fflush(stdout); \ 182 | ERRORLOGC( __VA_ARGS__ ) \ 183 | return -1; \ 184 | } \ 185 | 186 | #define INTERX(_return_val_,...) \ 187 | if( nret ) \ 188 | { \ 189 | printf( __VA_ARGS__ ); fflush(stdout); \ 190 | ERRORLOGC( __VA_ARGS__ ) \ 191 | return (_return_val_); \ 192 | } \ 193 | 194 | #define INTEx(_return_statement_,...) \ 195 | if( nret ) \ 196 | { \ 197 | printf( __VA_ARGS__ ); fflush(stdout); \ 198 | ERRORLOGC( __VA_ARGS__ ) \ 199 | _return_statement_; \ 200 | } \ 201 | 202 | #define INTEFR1(...) \ 203 | if( nret ) \ 204 | { \ 205 | printf( __VA_ARGS__ ); fflush(stdout); \ 206 | ERRORLOGC( __VA_ARGS__ ) \ 207 | if( ! env->cmd_para.__forcely ) \ 208 | return -1; \ 209 | } \ 210 | 211 | #define ILTER1(...) \ 212 | if( nret < 0 ) \ 213 | { \ 214 | printf( __VA_ARGS__ ); fflush(stdout); \ 215 | ERRORLOGC( __VA_ARGS__ ) \ 216 | return -1; \ 217 | } \ 218 | 219 | #define ILTx(_return_statement_) \ 220 | if( nret < 0 ) \ 221 | { \ 222 | _return_statement_; \ 223 | } \ 224 | 225 | #define I0TI(...) \ 226 | if( nret == 0 ) \ 227 | { \ 228 | printf( __VA_ARGS__ ); fflush(stdout); \ 229 | INFOLOGC( __VA_ARGS__ ) \ 230 | } \ 231 | 232 | #define I0TER1(...) \ 233 | if( nret == 0 ) \ 234 | { \ 235 | printf( __VA_ARGS__ ); fflush(stdout); \ 236 | ERRORLOGC( __VA_ARGS__ ) \ 237 | return -1; \ 238 | } \ 239 | 240 | #define I1TE(...) \ 241 | if( nret == -1 ) \ 242 | { \ 243 | printf( __VA_ARGS__ ); fflush(stdout); \ 244 | ERRORLOGC( __VA_ARGS__ ) \ 245 | } \ 246 | 247 | #define I1TER1(...) \ 248 | if( nret == -1 ) \ 249 | { \ 250 | printf( __VA_ARGS__ ); fflush(stdout); \ 251 | ERRORLOGC( __VA_ARGS__ ) \ 252 | return -1; \ 253 | } \ 254 | 255 | #define I1TERX(_return_val_,...) \ 256 | if( nret == -1 ) \ 257 | { \ 258 | printf( __VA_ARGS__ ); fflush(stdout); \ 259 | ERRORLOGC( __VA_ARGS__ ) \ 260 | return (_return_val_); \ 261 | } \ 262 | 263 | #define I1TERx(_return_statement_,...) \ 264 | if( nret == -1 ) \ 265 | { \ 266 | printf( __VA_ARGS__ ); fflush(stdout); \ 267 | ERRORLOGC( __VA_ARGS__ ) \ 268 | _return_statement_; \ 269 | } \ 270 | 271 | #define IxTER1(_condition_exp_,...) \ 272 | if( (_condition_exp_) ) \ 273 | { \ 274 | printf( __VA_ARGS__ ); fflush(stdout); \ 275 | ERRORLOGC( __VA_ARGS__ ) \ 276 | return -1; \ 277 | } \ 278 | 279 | #define IxTEFR1(_condition_exp_,...) \ 280 | if( (_condition_exp_) ) \ 281 | { \ 282 | printf( __VA_ARGS__ ); fflush(stdout); \ 283 | ERRORLOGC( __VA_ARGS__ ) \ 284 | if( ! env->cmd_para.__forcely ) \ 285 | return -1; \ 286 | } \ 287 | 288 | #define IxTERX(_condition_exp_,_return_val_,...) \ 289 | if( (_condition_exp_) ) \ 290 | { \ 291 | printf( __VA_ARGS__ ); fflush(stdout); \ 292 | ERRORLOGC( __VA_ARGS__ ) \ 293 | return (_return_val_); \ 294 | } \ 295 | 296 | #define IxTEx(_condition_exp_,_return_statement_,...) \ 297 | if( (_condition_exp_) ) \ 298 | { \ 299 | printf( __VA_ARGS__ ); fflush(stdout); \ 300 | ERRORLOGC( __VA_ARGS__ ) \ 301 | _return_statement_; \ 302 | } \ 303 | 304 | #define IDTI(...) \ 305 | if( env->cmd_para.__debug ) \ 306 | { \ 307 | printf( __VA_ARGS__ ); fflush(stdout); \ 308 | INFOLOGC( __VA_ARGS__ ) \ 309 | } \ 310 | 311 | #define IDTE(...) \ 312 | if( env->cmd_para.__debug ) \ 313 | { \ 314 | printf( __VA_ARGS__ ); fflush(stdout); \ 315 | ERRORLOGC( __VA_ARGS__ ) \ 316 | } \ 317 | 318 | #define EIDTI(...) \ 319 | else if( env->cmd_para.__debug ) \ 320 | { \ 321 | printf( __VA_ARGS__ ); fflush(stdout); \ 322 | INFOLOGC( __VA_ARGS__ ) \ 323 | } \ 324 | 325 | #define EIDTE(...) \ 326 | else if( env->cmd_para.__debug ) \ 327 | { \ 328 | printf( __VA_ARGS__ ); fflush(stdout); \ 329 | ERRORLOGC( __VA_ARGS__ ) \ 330 | } \ 331 | 332 | extern char *_COCKER_VERSION ; 333 | 334 | /* 335 | * string 336 | */ 337 | 338 | char *SnprintfV( char *path_buf , int path_bufsize , char *path_format , va_list valist ); 339 | char *Snprintf( char *path_buf , int path_bufsize , char *path_format , ... ); 340 | 341 | char *TrimEnter( char *str ); 342 | 343 | char *GenerateContainerId( char *images_id , char *container_id ); 344 | char *GenerateEthernamePostfix( char *container_id , char *ethername_postfix ); 345 | 346 | /* 347 | * file 348 | */ 349 | 350 | int CheckAndMakeDir( char *path ); 351 | 352 | int SnprintfAndCheckDir( char *path_buf , int path_bufsize , char *path_format , ... ); 353 | int SnprintfAndChangeDir( char *path_buf , int path_bufsize , char *path_format , ... ); 354 | int SnprintfAndMakeDir( char *path_buf , int path_bufsize , char *path_format , ... ); 355 | 356 | int SnprintfAndUnlink( char *path_buf , int path_bufsize , char *path_format , ... ); 357 | 358 | int SnprintfAndSystem( char *cmd_buf , int cmd_bufsize , char *cmd_format , ... ); 359 | int SnprintfAndPopen( char *output_buf , int output_bufsize , char *cmd_buf , int cmd_bufsize , char *cmd_format , ... ); 360 | 361 | int WriteFileLine( char *fileline , char *pathfile_buf , int pathfile_bufsize , char *pathfile_format , ... ); 362 | int ReadFileLine( char *fileline_buf , int fileline_bufsize , char *pathfile_buf , int pathfile_bufsize , char *pathfile_format , ... ); 363 | 364 | int IsDirectoryNewThan( char *path , time_t mtime ); 365 | int GetDirectorySize( char *path , int *p_directory_size ); 366 | int IsDirectoryEmpty( char *version_path_base ); 367 | 368 | /* 369 | * socket 370 | */ 371 | 372 | int writen( int sock , char *send_buffer , int send_len , int *p_sent_len ); 373 | int readn( int sock , char *recv_buffer , int recv_len , int *p_received_len ); 374 | 375 | /* 376 | * pts 377 | */ 378 | 379 | pid_t pty_fork( struct termios *p_origin_termios , struct winsize *p_origin_winsize , int *p_ptm_fd ); 380 | 381 | #ifdef __cplusplus 382 | } 383 | #endif 384 | 385 | #endif 386 | 387 | -------------------------------------------------------------------------------- /src/util/list.c: -------------------------------------------------------------------------------- 1 | #include "list.h" 2 | 3 | void INIT_LIST_HEAD(struct list_head *list) 4 | { 5 | WRITE_ONCE(list->next, list); 6 | list->prev = list; 7 | } 8 | 9 | /* 10 | * Insert a new entry between two known consecutive entries. 11 | * 12 | * This is only for internal list manipulation where we know 13 | * the prev/next entries already! 14 | */ 15 | static void __list_add(struct list_head *new, 16 | struct list_head *prev, 17 | struct list_head *next) 18 | { 19 | next->prev = new; 20 | new->next = next; 21 | new->prev = prev; 22 | WRITE_ONCE(prev->next, new); 23 | } 24 | 25 | /** 26 | * list_add - add a new entry 27 | * @new: new entry to be added 28 | * @head: list head to add it after 29 | * 30 | * Insert a new entry after the specified head. 31 | * This is good for implementing stacks. 32 | */ 33 | void list_add(struct list_head *new, struct list_head *head) 34 | { 35 | __list_add(new, head, head->next); 36 | } 37 | 38 | 39 | /** 40 | * list_add_tail - add a new entry 41 | * @new: new entry to be added 42 | * @head: list head to add it before 43 | * 44 | * Insert a new entry before the specified head. 45 | * This is useful for implementing queues. 46 | */ 47 | void list_add_tail(struct list_head *new, struct list_head *head) 48 | { 49 | __list_add(new, head->prev, head); 50 | } 51 | 52 | /* 53 | * Delete a list entry by making the prev/next entries 54 | * point to each other. 55 | * 56 | * This is only for internal list manipulation where we know 57 | * the prev/next entries already! 58 | */ 59 | static void __list_del(struct list_head * prev, struct list_head * next) 60 | { 61 | next->prev = prev; 62 | WRITE_ONCE(prev->next, next); 63 | } 64 | 65 | /** 66 | * list_del - deletes entry from list. 67 | * @entry: the element to delete from the list. 68 | * Note: list_empty() on entry does not return true after this, the entry is 69 | * in an undefined state. 70 | */ 71 | static void __list_del_entry(struct list_head *entry) 72 | { 73 | __list_del(entry->prev, entry->next); 74 | } 75 | 76 | void list_del(struct list_head *entry) 77 | { 78 | __list_del(entry->prev, entry->next); 79 | entry->next = LIST_POISON1; 80 | entry->prev = LIST_POISON2; 81 | } 82 | 83 | /** 84 | * list_replace - replace old entry by new one 85 | * @old : the element to be replaced 86 | * @new : the new element to insert 87 | * 88 | * If @old was empty, it will be overwritten. 89 | */ 90 | void list_replace(struct list_head *old, struct list_head *new) 91 | { 92 | new->next = old->next; 93 | new->next->prev = new; 94 | new->prev = old->prev; 95 | new->prev->next = new; 96 | } 97 | 98 | void list_replace_init(struct list_head *old, struct list_head *new) 99 | { 100 | list_replace(old, new); 101 | INIT_LIST_HEAD(old); 102 | } 103 | 104 | /** 105 | * list_del_init - deletes entry from list and reinitialize it. 106 | * @entry: the element to delete from the list. 107 | */ 108 | void list_del_init(struct list_head *entry) 109 | { 110 | __list_del_entry(entry); 111 | INIT_LIST_HEAD(entry); 112 | } 113 | 114 | /** 115 | * list_move - delete from one list and add as another's head 116 | * @list: the entry to move 117 | * @head: the head that will precede our entry 118 | */ 119 | void list_move(struct list_head *list, struct list_head *head) 120 | { 121 | __list_del_entry(list); 122 | list_add(list, head); 123 | } 124 | 125 | /** 126 | * list_move_tail - delete from one list and add as another's tail 127 | * @list: the entry to move 128 | * @head: the head that will follow our entry 129 | */ 130 | void list_move_tail(struct list_head *list, struct list_head *head) 131 | { 132 | __list_del_entry(list); 133 | list_add_tail(list, head); 134 | } 135 | 136 | /** 137 | * list_is_last - tests whether @list is the last entry in list @head 138 | * @list: the entry to test 139 | * @head: the head of the list 140 | */ 141 | int list_is_last(const struct list_head *list, const struct list_head *head) 142 | { 143 | return list->next == head; 144 | } 145 | 146 | /** 147 | * list_empty - tests whether a list is empty 148 | * @head: the list to test. 149 | */ 150 | int list_empty(const struct list_head *head) 151 | { 152 | return READ_ONCE(head->next) == head; 153 | } 154 | 155 | /** 156 | * list_empty_careful - tests whether a list is empty and not being modified 157 | * @head: the list to test 158 | * 159 | * Description: 160 | * tests whether a list is empty _and_ checks that no other CPU might be 161 | * in the process of modifying either member (next or prev) 162 | * 163 | * NOTE: using list_empty_careful() without synchronization 164 | * can only be safe if the only activity that can happen 165 | * to the list entry is list_del_init(). Eg. it cannot be used 166 | * if another CPU could re-list_add() it. 167 | */ 168 | int list_empty_careful(const struct list_head *head) 169 | { 170 | struct list_head *next = head->next; 171 | return (next == head) && (next == head->prev); 172 | } 173 | 174 | /** 175 | * list_rotate_left - rotate the list to the left 176 | * @head: the head of the list 177 | */ 178 | void list_rotate_left(struct list_head *head) 179 | { 180 | struct list_head *first; 181 | 182 | if (!list_empty(head)) { 183 | first = head->next; 184 | list_move_tail(first, head); 185 | } 186 | } 187 | 188 | /** 189 | * list_is_singular - tests whether a list has just one entry. 190 | * @head: the list to test. 191 | */ 192 | int list_is_singular(const struct list_head *head) 193 | { 194 | return !list_empty(head) && (head->next == head->prev); 195 | } 196 | 197 | static void __list_cut_position(struct list_head *list, 198 | struct list_head *head, struct list_head *entry) 199 | { 200 | struct list_head *new_first = entry->next; 201 | list->next = head->next; 202 | list->next->prev = list; 203 | list->prev = entry; 204 | entry->next = list; 205 | head->next = new_first; 206 | new_first->prev = head; 207 | } 208 | 209 | /** 210 | * list_cut_position - cut a list into two 211 | * @list: a new list to add all removed entries 212 | * @head: a list with entries 213 | * @entry: an entry within head, could be the head itself 214 | * and if so we won't cut the list 215 | * 216 | * This helper moves the initial part of @head, up to and 217 | * including @entry, from @head to @list. You should 218 | * pass on @entry an element you know is on @head. @list 219 | * should be an empty list or a list you do not care about 220 | * losing its data. 221 | * 222 | */ 223 | void list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry) 224 | { 225 | if (list_empty(head)) 226 | return; 227 | if (list_is_singular(head) && 228 | (head->next != entry && head != entry)) 229 | return; 230 | if (entry == head) 231 | INIT_LIST_HEAD(list); 232 | else 233 | __list_cut_position(list, head, entry); 234 | } 235 | 236 | static void __list_splice(const struct list_head *list, 237 | struct list_head *prev, 238 | struct list_head *next) 239 | { 240 | struct list_head *first = list->next; 241 | struct list_head *last = list->prev; 242 | 243 | first->prev = prev; 244 | prev->next = first; 245 | 246 | last->next = next; 247 | next->prev = last; 248 | } 249 | 250 | /** 251 | * list_splice - join two lists, this is designed for stacks 252 | * @list: the new list to add. 253 | * @head: the place to add it in the first list. 254 | */ 255 | void list_splice(const struct list_head *list, struct list_head *head) 256 | { 257 | if (!list_empty(list)) 258 | __list_splice(list, head, head->next); 259 | } 260 | 261 | /** 262 | * list_splice_tail - join two lists, each list being a queue 263 | * @list: the new list to add. 264 | * @head: the place to add it in the first list. 265 | */ 266 | void list_splice_tail(struct list_head *list, struct list_head *head) 267 | { 268 | if (!list_empty(list)) 269 | __list_splice(list, head->prev, head); 270 | } 271 | 272 | /** 273 | * list_splice_init - join two lists and reinitialise the emptied list. 274 | * @list: the new list to add. 275 | * @head: the place to add it in the first list. 276 | * 277 | * The list at @list is reinitialised 278 | */ 279 | void list_splice_init(struct list_head *list, struct list_head *head) 280 | { 281 | if (!list_empty(list)) { 282 | __list_splice(list, head, head->next); 283 | INIT_LIST_HEAD(list); 284 | } 285 | } 286 | 287 | /** 288 | * list_splice_tail_init - join two lists and reinitialise the emptied list 289 | * @list: the new list to add. 290 | * @head: the place to add it in the first list. 291 | * 292 | * Each of the lists is a queue. 293 | * The list at @list is reinitialised 294 | */ 295 | void list_splice_tail_init(struct list_head *list, struct list_head *head) 296 | { 297 | if (!list_empty(list)) { 298 | __list_splice(list, head->prev, head); 299 | INIT_LIST_HEAD(list); 300 | } 301 | } 302 | 303 | void INIT_HLIST_NODE(struct hlist_node *h) 304 | { 305 | h->next = NULL; 306 | h->pprev = NULL; 307 | } 308 | 309 | int hlist_unhashed(const struct hlist_node *h) 310 | { 311 | return !h->pprev; 312 | } 313 | 314 | int hlist_empty(const struct hlist_head *h) 315 | { 316 | return !READ_ONCE(h->first); 317 | } 318 | 319 | static void __hlist_del(struct hlist_node *n) 320 | { 321 | struct hlist_node *next = n->next; 322 | struct hlist_node **pprev = n->pprev; 323 | 324 | WRITE_ONCE(*pprev, next); 325 | if (next) 326 | next->pprev = pprev; 327 | } 328 | 329 | void hlist_del(struct hlist_node *n) 330 | { 331 | __hlist_del(n); 332 | n->next = HLIST_POISON1; 333 | n->pprev = HLIST_POISON2; 334 | } 335 | 336 | void hlist_del_init(struct hlist_node *n) 337 | { 338 | if (!hlist_unhashed(n)) { 339 | __hlist_del(n); 340 | INIT_HLIST_NODE(n); 341 | } 342 | } 343 | 344 | void hlist_add_head(struct hlist_node *n, struct hlist_head *h) 345 | { 346 | struct hlist_node *first = h->first; 347 | n->next = first; 348 | if (first) 349 | first->pprev = &n->next; 350 | WRITE_ONCE(h->first, n); 351 | n->pprev = &h->first; 352 | } 353 | 354 | /* next must be != NULL */ 355 | void hlist_add_before(struct hlist_node *n, struct hlist_node *next) 356 | { 357 | n->pprev = next->pprev; 358 | n->next = next; 359 | next->pprev = &n->next; 360 | WRITE_ONCE(*(n->pprev), n); 361 | } 362 | 363 | void hlist_add_behind(struct hlist_node *n, struct hlist_node *prev) 364 | { 365 | n->next = prev->next; 366 | WRITE_ONCE(prev->next, n); 367 | n->pprev = &prev->next; 368 | 369 | if (n->next) 370 | n->next->pprev = &n->next; 371 | } 372 | 373 | /* after that we'll appear to be on some hlist and hlist_del will work */ 374 | void hlist_add_fake(struct hlist_node *n) 375 | { 376 | n->pprev = &n->next; 377 | } 378 | 379 | int hlist_fake(struct hlist_node *h) 380 | { 381 | return h->pprev == &h->next; 382 | } 383 | 384 | /* 385 | * Check whether the node is the only node of the head without 386 | * accessing head: 387 | */ 388 | int hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h) 389 | { 390 | return !n->next && n->pprev == &h->first; 391 | } 392 | 393 | /* 394 | * Move a list from one list head to another. Fixup the pprev 395 | * reference of the first entry if it exists. 396 | */ 397 | void hlist_move_list(struct hlist_head *old, struct hlist_head *new) 398 | { 399 | new->first = old->first; 400 | if (new->first) 401 | new->first->pprev = &new->first; 402 | old->first = NULL; 403 | } 404 | 405 | -------------------------------------------------------------------------------- /src/util/filerpl.c: -------------------------------------------------------------------------------- 1 | #include "filerpl.h" 2 | 3 | #define _DEBUG 0 4 | 5 | int strrpl( char **pp_buf , int *p_buf_len , int *p_buf_size , char *key , int key_len , char *value , int value_len ) 6 | { 7 | int diff_len ; 8 | char *p = NULL ; 9 | int p_offset ; 10 | 11 | if( pp_buf == NULL || (*pp_buf) == NULL || p_buf_len == NULL || p_buf_size == NULL ) 12 | return FILERPL_ERROR_PARAMETER; 13 | if( key == NULL || value == NULL ) 14 | return FILERPL_ERROR_PARAMETER; 15 | 16 | if( key_len < 0 ) 17 | key_len = strlen(key) ; 18 | if( value_len < 0 ) 19 | value_len = strlen(value) ; 20 | diff_len = value_len - key_len ; 21 | 22 | p = (*pp_buf) - 1 ; 23 | while(1) 24 | { 25 | #if _DEBUG 26 | printf( "strrpl - while - buf[%d/%d][%s]\n" , (*p_buf_len) , (*p_buf_size) , (*pp_buf) ); 27 | #endif 28 | 29 | p = strstr( p+1 , key ) ; 30 | if( p == NULL ) 31 | break; 32 | 33 | #if _DEBUG 34 | printf( "strrpl - while - p[%.10s...]\n" , p ); 35 | #endif 36 | 37 | if( (*p_buf_len) + diff_len > (*p_buf_size)-1 ) 38 | { 39 | char *new_buf ; 40 | int new_buf_size ; 41 | 42 | p_offset = p - (*pp_buf) ; 43 | 44 | new_buf_size = (*p_buf_size) ; 45 | if( new_buf_size <= 1024*1024*1024 ) 46 | new_buf_size *= 2 ; 47 | if( (*p_buf_len) + diff_len > new_buf_size-1 ) 48 | new_buf_size = (*p_buf_len) + diff_len + 1 ; 49 | new_buf = realloc( (*pp_buf) , new_buf_size ) ; 50 | if( new_buf == NULL ) 51 | return FILERPL_ERROR_REALLOC; 52 | 53 | #if _DEBUG 54 | printf( "strrpl - while - ins_buf_size [%d]->[%d]\n" , (*p_buf_size) , new_buf_size ); 55 | #endif 56 | 57 | (*pp_buf) = new_buf ; 58 | (*p_buf_size) = new_buf_size ; 59 | 60 | p = (*pp_buf) + p_offset ; 61 | } 62 | 63 | /* 64 | 123KEY456 65 | KEY 66 | VALUE 67 | */ 68 | memmove( p+value_len , p+key_len , (*p_buf_len) - ( p-(*pp_buf) + key_len ) ); 69 | memcpy( p , value , value_len ); 70 | (*p_buf_len) += diff_len ; 71 | (*pp_buf)[(*p_buf_len)] = '\0' ; 72 | } 73 | 74 | return 0; 75 | } 76 | 77 | static int _PrepareBuffer( struct stat *file_stat , char **pp_buf , int *p_buf_len , int *p_buf_size ) 78 | { 79 | if( (*pp_buf) == NULL ) 80 | { 81 | (*p_buf_size) = file_stat->st_size + 1 ; 82 | (*pp_buf) = malloc( (*p_buf_size) + 1 ) ; 83 | if( (*pp_buf) == NULL ) 84 | return FILERPL_ERROR_MALLOC; 85 | memset( (*pp_buf) , 0x00 , (*p_buf_size) ); 86 | (*p_buf_len) = 0 ; 87 | } 88 | else if( (*p_buf_size)-1 < file_stat->st_size ) 89 | { 90 | int new_buf_size ; 91 | char *new_buf = NULL ; 92 | 93 | new_buf_size = file_stat->st_size + 1 + 1 ; 94 | new_buf = realloc( (*pp_buf) , new_buf_size ) ; 95 | if( new_buf == NULL ) 96 | return FILERPL_ERROR_REALLOC; 97 | memset( new_buf , 0x00 , new_buf_size ); 98 | 99 | (*pp_buf) = new_buf ; 100 | (*p_buf_size) = new_buf_size ; 101 | (*p_buf_len) = 0 ; 102 | } 103 | else 104 | { 105 | memset( (*pp_buf) , 0x00 , (*p_buf_size) ); 106 | } 107 | 108 | return 0; 109 | } 110 | 111 | int FreeRplBuffer( char **pp_buf , int *p_buf_len , int *p_buf_size ) 112 | { 113 | if( pp_buf == NULL || p_buf_len == NULL || p_buf_size == NULL ) 114 | return FILERPL_ERROR_PARAMETER; 115 | 116 | if( (*pp_buf) == NULL ) 117 | return 0; 118 | 119 | free( (*pp_buf) ); 120 | (*p_buf_len) = 0 ; 121 | (*p_buf_size) = 0 ; 122 | 123 | return 0; 124 | } 125 | 126 | int LoadRplTemplateFile( char *tpl_pathfilename , char **pp_tpl_buf , int *p_tpl_buf_len , int *p_tpl_buf_size ) 127 | { 128 | int fd ; 129 | struct stat file_stat ; 130 | 131 | int nret = 0 ; 132 | 133 | if( pp_tpl_buf == NULL ) 134 | return FILERPL_ERROR_PARAMETER; 135 | 136 | fd = open( tpl_pathfilename , O_RDONLY ) ; 137 | if( fd == -1 ) 138 | return FILERPL_ERROR_OPEN; 139 | 140 | nret = fstat( fd , & file_stat ) ; 141 | if( nret == -1 ) 142 | { 143 | close( fd ); 144 | return FILERPL_ERROR_FSTAT; 145 | } 146 | 147 | nret = _PrepareBuffer( & file_stat , pp_tpl_buf , p_tpl_buf_len , p_tpl_buf_size ) ; 148 | if( nret ) 149 | { 150 | close( fd ); 151 | return nret; 152 | } 153 | 154 | (*p_tpl_buf_len) = read( fd , (*pp_tpl_buf) , file_stat.st_size ) ; 155 | if( (*p_tpl_buf_len) < file_stat.st_size ) 156 | { 157 | close( fd ); 158 | return FILERPL_ERROR_READ; 159 | } 160 | 161 | close( fd ); 162 | 163 | return 0; 164 | } 165 | 166 | int LoadRplMappingFile( char *map_pathfilename , char **pp_map_buf , int *p_map_buf_len , int *p_map_buf_size ) 167 | { 168 | int fd ; 169 | struct stat file_stat ; 170 | char *base = NULL ; 171 | char *p1 = NULL ; 172 | char *p_key_begin = NULL ; 173 | int key_len ; 174 | char *p_value_begin = NULL ; 175 | int value_len ; 176 | char *p2 = NULL ; 177 | 178 | int nret = 0 ; 179 | 180 | if( pp_map_buf == NULL ) 181 | return FILERPL_ERROR_PARAMETER; 182 | 183 | fd = open( map_pathfilename , O_RDONLY ) ; 184 | if( fd == -1 ) 185 | return FILERPL_ERROR_OPEN; 186 | 187 | nret = fstat( fd , & file_stat ) ; 188 | if( nret == -1 ) 189 | { 190 | close( fd ); 191 | return FILERPL_ERROR_FSTAT; 192 | } 193 | 194 | nret = _PrepareBuffer( & file_stat , pp_map_buf , p_map_buf_len , p_map_buf_size ) ; 195 | if( nret ) 196 | { 197 | close( fd ); 198 | return nret; 199 | } 200 | 201 | base = mmap( NULL , file_stat.st_size , PROT_READ , MAP_SHARED , fd , 0 ) ; 202 | if( base == NULL ) 203 | { 204 | close( fd ); 205 | return FILERPL_ERROR_MMAP; 206 | } 207 | 208 | close( fd ); 209 | 210 | p1 = base ; 211 | p2 = (*pp_map_buf) ; 212 | while(1) 213 | { 214 | /* 215 | key value\n 216 | key value\n 217 | key val ue\n 218 | */ 219 | 220 | /* before key */ 221 | do 222 | { 223 | if( (*p1) != ' ' && (*p1) != '\t' ) 224 | { 225 | break; 226 | } 227 | else if( (*p1) == '\0' ) 228 | { 229 | break; 230 | } 231 | else if( (*p1) == '\r' || (*p1) == '\n' ) 232 | { 233 | break; 234 | } 235 | } 236 | while( p1++ ); 237 | if( (*p1) == '\0' ) 238 | break; 239 | if( (*p1) == '\r' || (*p1) == '\n' ) 240 | { 241 | p1++; 242 | continue; 243 | } 244 | 245 | p_key_begin = p1 ; 246 | 247 | /* key */ 248 | do 249 | { 250 | if( (*p1) == ' ' || (*p1) == '\t' ) 251 | { 252 | break; 253 | } 254 | else if( (*p1) == '\0' ) 255 | { 256 | munmap( base , 0 ); 257 | return FILERPL_ERROR_MAP_INVALID_1; 258 | } 259 | else if( (*p1) == '\r' || (*p1) == '\n' ) 260 | { 261 | munmap( base , 0 ); 262 | return FILERPL_ERROR_MAP_INVALID_2; 263 | } 264 | } 265 | while( p1++ ); 266 | 267 | key_len = p1 - p_key_begin ; 268 | if( key_len <= 0 ) 269 | { 270 | munmap( base , 0 ); 271 | return FILERPL_ERROR_MAP_INVALID_3; 272 | } 273 | memcpy( p2 , p_key_begin , key_len ); 274 | p2 += key_len + 1 ; 275 | (*p_map_buf_len) += key_len + 1 ; 276 | 277 | /* before value */ 278 | do 279 | { 280 | if( (*p1) != ' ' && (*p1) != '\t' ) 281 | { 282 | break; 283 | } 284 | else if( (*p1) == '\0' ) 285 | { 286 | munmap( base , 0 ); 287 | return FILERPL_ERROR_MAP_INVALID_4; 288 | } 289 | else if( (*p1) == '\r' || (*p1) == '\n' ) 290 | { 291 | munmap( base , 0 ); 292 | return FILERPL_ERROR_MAP_INVALID_5; 293 | } 294 | } 295 | while( p1++ ); 296 | 297 | p_value_begin = p1 ; 298 | 299 | /* value */ 300 | do 301 | { 302 | if( (*p1) == ' ' || (*p1) == '\t' ) 303 | { 304 | break; 305 | } 306 | else if( (*p1) == '\0' ) 307 | { 308 | break; 309 | } 310 | else if( (*p1) == '\r' || (*p1) == '\n' ) 311 | { 312 | break; 313 | } 314 | } 315 | while( p1++ ); 316 | 317 | value_len = p1 - p_value_begin ; 318 | if( value_len > 0 ) 319 | memcpy( p2 , p_value_begin , value_len ); 320 | p2 += value_len + 1 ; 321 | (*p_map_buf_len) += value_len + 1 ; 322 | 323 | if( (*p1) == '\0' ) 324 | break; 325 | } 326 | 327 | munmap( base , 0 ); 328 | 329 | return 0; 330 | } 331 | 332 | int ConvertRplBuffer( char **pp_ins_buf , int *p_ins_buf_len , int *p_ins_buf_size , char *p_map_buf , int map_buf_len ) 333 | { 334 | char *key = NULL ; 335 | char *value = NULL ; 336 | 337 | int nret = 0 ; 338 | 339 | key = p_map_buf ; 340 | while( (*key) ) 341 | { 342 | value = key + strlen(key) + 1 ; 343 | 344 | #if _DEBUG 345 | printf( "ConvertRplBuffer - key[%s] value[%s] buf[%.*s]\n" , key , value , (*p_ins_buf_len) , (*pp_ins_buf) ); 346 | #endif 347 | 348 | nret = strrpl( pp_ins_buf , p_ins_buf_len , p_ins_buf_size , key , -1 , value , -1 ) ; 349 | if( nret ) 350 | return nret; 351 | 352 | key = value + strlen(value) + 1 ; 353 | } 354 | 355 | return 0; 356 | } 357 | 358 | int DumpRplInstanceFile( char *p_ins_buf , int ins_buf_len , char *ins_pathfilename ) 359 | { 360 | int fd ; 361 | 362 | int nret = 0 ; 363 | 364 | if( p_ins_buf == NULL || ins_buf_len < 0 || ins_pathfilename == NULL ) 365 | return FILERPL_ERROR_PARAMETER; 366 | 367 | fd = open( ins_pathfilename , O_CREAT|O_WRONLY , 00777 ) ; 368 | if( fd == -1 ) 369 | return FILERPL_ERROR_OPEN; 370 | 371 | nret = write( fd , p_ins_buf , ins_buf_len ) ; 372 | if( nret < ins_buf_len ) 373 | { 374 | close( fd ); 375 | return FILERPL_ERROR_WRITE; 376 | } 377 | 378 | close( fd ); 379 | 380 | return 0; 381 | } 382 | 383 | int filerpl( char *tpl_pathfilename , char *map_pathfilename , char *ins_pathfilename ) 384 | { 385 | char *ins_buf = NULL ; 386 | int ins_buf_len = 0 ; 387 | int ins_buf_size = 0 ; 388 | char *map_buf = NULL ; 389 | int map_buf_len = 0 ; 390 | int map_buf_size = 0 ; 391 | 392 | int nret = 0 ; 393 | 394 | #if _DEBUG 395 | printf( "ConvertRplFile - LoadRplTemplateFile\n" ); 396 | #endif 397 | 398 | nret = LoadRplTemplateFile( tpl_pathfilename , & ins_buf , & ins_buf_len , & ins_buf_size ) ; 399 | if( nret ) 400 | return nret; 401 | 402 | #if _DEBUG 403 | printf( "ConvertRplFile tpl_buf[%d/%d][%s]\n" , ins_buf_len , ins_buf_size , ins_buf ); 404 | #endif 405 | 406 | #if _DEBUG 407 | printf( "ConvertRplFile - LoadRplMappingFile\n" ); 408 | #endif 409 | 410 | nret = LoadRplMappingFile( map_pathfilename , & map_buf , & map_buf_len , & map_buf_size ) ; 411 | if( nret ) 412 | return nret; 413 | 414 | #if _DEBUG 415 | printf( "ConvertRplFile - map_buf[%d/%d][%s]\n" , map_buf_len , map_buf_size , map_buf ); 416 | 417 | { 418 | char *key = NULL ; 419 | char *value = NULL ; 420 | 421 | key = map_buf ; 422 | while( (*key) ) 423 | { 424 | value = key + strlen(key) + 1 ; 425 | 426 | printf( "ConvertRplFile - key[%s] value[%s]\n" , key , value ); 427 | 428 | key = value + strlen(value) + 1 ; 429 | } 430 | } 431 | #endif 432 | 433 | #if _DEBUG 434 | printf( "ConvertRplFile - ConvertRplBuffer\n" ); 435 | #endif 436 | 437 | nret = ConvertRplBuffer( & ins_buf , & ins_buf_len , & ins_buf_size , map_buf , map_buf_len ) ; 438 | if( nret ) 439 | return nret; 440 | 441 | #if _DEBUG 442 | printf( "ConvertRplFile - ins_buf[%d/%d][%s]\n" , ins_buf_len , ins_buf_size , ins_buf ); 443 | #endif 444 | 445 | #if _DEBUG 446 | printf( "ConvertRplFile - DumpRplInstanceFile\n" ); 447 | #endif 448 | 449 | nret = DumpRplInstanceFile( ins_buf , ins_buf_len , ins_pathfilename ) ; 450 | if( nret ) 451 | return nret; 452 | 453 | FreeRplBuffer( & ins_buf , & ins_buf_len , & ins_buf_size ); 454 | FreeRplBuffer( & map_buf , & map_buf_len , & map_buf_size ); 455 | 456 | return 0; 457 | } 458 | 459 | #if 0 460 | int main() 461 | { 462 | int nret = 0 ; 463 | 464 | nret = ConvertRplFile( "tpl.txt" , "map.txt" , "ins.txt" ) ; 465 | if( nret ) 466 | { 467 | printf( "ConvertRplFile failed[%d]\n" , nret ); 468 | return 1; 469 | } 470 | else 471 | { 472 | printf( "ConvertRplFile ok\n" ); 473 | return 0; 474 | } 475 | } 476 | #endif 477 | 478 | -------------------------------------------------------------------------------- /src/util/list.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_LIST_H 2 | #define _LINUX_LIST_H 3 | 4 | /* 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | */ 11 | #include 12 | 13 | #ifndef container_of 14 | #define container_of(ptr, type, member) ((type *)( (char *)(ptr) - offsetof(type,member) )) 15 | #endif 16 | 17 | #ifndef offsetof 18 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 19 | #endif 20 | 21 | /* 22 | * Simple doubly linked list implementation. 23 | * 24 | * Some of the internal functions ("__xxx") are useful when 25 | * manipulating whole lists rather than single entries, as 26 | * sometimes we already know the next/prev entries and we can 27 | * generate better code by using them directly rather than 28 | * using the generic single-entry routines. 29 | */ 30 | 31 | struct list_head { 32 | struct list_head *next, *prev; 33 | }; 34 | 35 | #define WRITE_ONCE(_var_,_val_) (_var_) = (_val_) 36 | #define READ_ONCE(_var_) (_var_) 37 | 38 | #define POISON_POINTER_DELTA 0 39 | #define LIST_POISON1 ((struct list_head *) 0x100 + POISON_POINTER_DELTA) 40 | #define LIST_POISON2 ((struct list_head *) 0x200 + POISON_POINTER_DELTA) 41 | 42 | #define LIST_HEAD_INIT(name) { &(name), &(name) } 43 | 44 | #define LIST_HEAD(name) \ 45 | struct list_head name = LIST_HEAD_INIT(name) 46 | 47 | void INIT_LIST_HEAD(struct list_head *list); 48 | void list_add(struct list_head *_new, struct list_head *head); 49 | void list_add_tail(struct list_head *_new, struct list_head *head); 50 | void list_del(struct list_head *entry); 51 | void list_replace(struct list_head *old, struct list_head *_new); 52 | void list_replace_init(struct list_head *old, struct list_head *_new); 53 | void list_del_init(struct list_head *entry); 54 | void list_move(struct list_head *list, struct list_head *head); 55 | void list_move_tail(struct list_head *list, struct list_head *head); 56 | int list_is_last(const struct list_head *list, const struct list_head *head); 57 | int list_empty(const struct list_head *head); 58 | int list_empty_careful(const struct list_head *head); 59 | void list_rotate_left(struct list_head *head); 60 | int list_is_singular(const struct list_head *head); 61 | void list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry); 62 | void list_splice(const struct list_head *list, struct list_head *head); 63 | void list_splice_tail(struct list_head *list, struct list_head *head); 64 | void list_splice_init(struct list_head *list, struct list_head *head); 65 | void list_splice_tail_init(struct list_head *list, struct list_head *head); 66 | 67 | /** 68 | * list_entry - get the struct for this entry 69 | * @ptr: the &struct list_head pointer. 70 | * @type: the type of the struct this is embedded in. 71 | * @member: the name of the list_head within the struct. 72 | */ 73 | #define list_entry(ptr, type, member) \ 74 | container_of(ptr, type, member) 75 | 76 | /** 77 | * list_first_entry - get the first element from a list 78 | * @ptr: the list head to take the element from. 79 | * @type: the type of the struct this is embedded in. 80 | * @member: the name of the list_head within the struct. 81 | * 82 | * Note, that list is expected to be not empty. 83 | */ 84 | #define list_first_entry(ptr, type, member) \ 85 | list_entry((ptr)->next, type, member) 86 | 87 | /** 88 | * list_last_entry - get the last element from a list 89 | * @ptr: the list head to take the element from. 90 | * @type: the type of the struct this is embedded in. 91 | * @member: the name of the list_head within the struct. 92 | * 93 | * Note, that list is expected to be not empty. 94 | */ 95 | #define list_last_entry(ptr, type, member) \ 96 | list_entry((ptr)->prev, type, member) 97 | 98 | /** 99 | * list_first_entry_or_null - get the first element from a list 100 | * @ptr: the list head to take the element from. 101 | * @type: the type of the struct this is embedded in. 102 | * @member: the name of the list_head within the struct. 103 | * 104 | * Note that if the list is empty, it returns NULL. 105 | */ 106 | #define list_first_entry_or_null(ptr, type, member) \ 107 | (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL) 108 | 109 | /** 110 | * list_next_entry - get the next element in list 111 | * @p_node: the type * to cursor 112 | * @member: the name of the list_head within the struct. 113 | */ 114 | #define list_next_entry(p_node, type, member) \ 115 | list_entry((p_node)->member.next, type, member) 116 | 117 | /** 118 | * list_prev_entry - get the prev element in list 119 | * @p_node: the type * to cursor 120 | * @member: the name of the list_head within the struct. 121 | */ 122 | #define list_prev_entry(p_node, type, member) \ 123 | list_entry((p_node)->member.prev, type, member) 124 | 125 | /** 126 | * list_for_each - iterate over a list 127 | * @p_node: the &struct list_head to use as a loop cursor. 128 | * @head: the head for your list. 129 | */ 130 | #define list_for_each(p_node, head) \ 131 | for (p_node = (head)->next; p_node != (head); p_node = p_node->next) 132 | 133 | /** 134 | * list_for_each_prev - iterate over a list backwards 135 | * @p_node: the &struct list_head to use as a loop cursor. 136 | * @head: the head for your list. 137 | */ 138 | #define list_for_each_prev(p_node, head) \ 139 | for (p_node = (head)->prev; p_node != (head); p_node = p_node->prev) 140 | 141 | /** 142 | * list_for_each_safe - iterate over a list safe against removal of list entry 143 | * @p_node: the &struct list_head to use as a loop cursor. 144 | * @n: another &struct list_head to use as temporary storage 145 | * @head: the head for your list. 146 | */ 147 | #define list_for_each_safe(p_node, n, head) \ 148 | for (p_node = (head)->next, n = p_node->next; p_node != (head); \ 149 | p_node = n, n = p_node->next) 150 | 151 | /** 152 | * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry 153 | * @p_node: the &struct list_head to use as a loop cursor. 154 | * @n: another &struct list_head to use as temporary storage 155 | * @head: the head for your list. 156 | */ 157 | #define list_for_each_prev_safe(p_node, n, head) \ 158 | for (p_node = (head)->prev, n = p_node->prev; \ 159 | p_node != (head); \ 160 | p_node = n, n = p_node->prev) 161 | 162 | /** 163 | * list_for_each_entry - iterate over list of given type 164 | * @p_node: the type * to use as a loop cursor. 165 | * @head: the head for your list. 166 | * @member: the name of the list_head within the struct. 167 | */ 168 | #define list_for_each_entry(p_node, head, type, member) \ 169 | for (p_node = list_first_entry(head, type, member); \ 170 | &p_node->member != (head); \ 171 | p_node = list_next_entry(p_node, type, member)) 172 | 173 | /** 174 | * list_for_each_entry_reverse - iterate backwards over list of given type. 175 | * @p_node: the type * to use as a loop cursor. 176 | * @head: the head for your list. 177 | * @member: the name of the list_head within the struct. 178 | */ 179 | #define list_for_each_entry_reverse(p_node, head, member) \ 180 | for (p_node = list_last_entry(head, typeof(*p_node), member); \ 181 | &p_node->member != (head); \ 182 | p_node = list_prev_entry(p_node, member)) 183 | 184 | /** 185 | * list_prepare_entry - prepare a p_node entry for use in list_for_each_entry_continue() 186 | * @p_node: the type * to use as a start point 187 | * @head: the head of the list 188 | * @member: the name of the list_head within the struct. 189 | * 190 | * Prepares a p_node entry for use as a start point in list_for_each_entry_continue(). 191 | */ 192 | #define list_prepare_entry(p_node, head, member) \ 193 | ((p_node) ? : list_entry(head, typeof(*p_node), member)) 194 | 195 | /** 196 | * list_for_each_entry_continue - continue iteration over list of given type 197 | * @p_node: the type * to use as a loop cursor. 198 | * @head: the head for your list. 199 | * @member: the name of the list_head within the struct. 200 | * 201 | * Continue to iterate over list of given type, continuing after 202 | * the current position. 203 | */ 204 | #define list_for_each_entry_continue(p_node, head, member) \ 205 | for (p_node = list_next_entry(p_node, member); \ 206 | &p_node->member != (head); \ 207 | p_node = list_next_entry(p_node, member)) 208 | 209 | /** 210 | * list_for_each_entry_continue_reverse - iterate backwards from the given point 211 | * @p_node: the type * to use as a loop cursor. 212 | * @head: the head for your list. 213 | * @member: the name of the list_head within the struct. 214 | * 215 | * Start to iterate over list of given type backwards, continuing after 216 | * the current position. 217 | */ 218 | #define list_for_each_entry_continue_reverse(p_node, head, member) \ 219 | for (p_node = list_prev_entry(p_node, member); \ 220 | &p_node->member != (head); \ 221 | p_node = list_prev_entry(p_node, member)) 222 | 223 | /** 224 | * list_for_each_entry_from - iterate over list of given type from the current point 225 | * @p_node: the type * to use as a loop cursor. 226 | * @head: the head for your list. 227 | * @member: the name of the list_head within the struct. 228 | * 229 | * Iterate over list of given type, continuing from current position. 230 | */ 231 | #define list_for_each_entry_from(p_node, head, member) \ 232 | for (; &p_node->member != (head); \ 233 | p_node = list_next_entry(p_node, member)) 234 | 235 | /** 236 | * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry 237 | * @p_node: the type * to use as a loop cursor. 238 | * @n: another type * to use as temporary storage 239 | * @head: the head for your list. 240 | * @member: the name of the list_head within the struct. 241 | */ 242 | #define list_for_each_entry_safe(p_node, n, head, type, member) \ 243 | for (p_node = list_first_entry(head, type, member), \ 244 | n = list_next_entry(p_node, type, member); \ 245 | &p_node->member != (head); \ 246 | p_node = n, n = list_next_entry(n, type, member)) 247 | 248 | /** 249 | * list_for_each_entry_safe_continue - continue list iteration safe against removal 250 | * @p_node: the type * to use as a loop cursor. 251 | * @n: another type * to use as temporary storage 252 | * @head: the head for your list. 253 | * @member: the name of the list_head within the struct. 254 | * 255 | * Iterate over list of given type, continuing after current point, 256 | * safe against removal of list entry. 257 | */ 258 | #define list_for_each_entry_safe_continue(p_node, n, head, member) \ 259 | for (p_node = list_next_entry(p_node, member), \ 260 | n = list_next_entry(p_node, member); \ 261 | &p_node->member != (head); \ 262 | p_node = n, n = list_next_entry(n, member)) 263 | 264 | /** 265 | * list_for_each_entry_safe_from - iterate over list from current point safe against removal 266 | * @p_node: the type * to use as a loop cursor. 267 | * @n: another type * to use as temporary storage 268 | * @head: the head for your list. 269 | * @member: the name of the list_head within the struct. 270 | * 271 | * Iterate over list of given type from current point, safe against 272 | * removal of list entry. 273 | */ 274 | #define list_for_each_entry_safe_from(p_node, n, head, member) \ 275 | for (n = list_next_entry(p_node, member); \ 276 | &p_node->member != (head); \ 277 | p_node = n, n = list_next_entry(n, member)) 278 | 279 | /** 280 | * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal 281 | * @p_node: the type * to use as a loop cursor. 282 | * @n: another type * to use as temporary storage 283 | * @head: the head for your list. 284 | * @member: the name of the list_head within the struct. 285 | * 286 | * Iterate backwards over list of given type, safe against removal 287 | * of list entry. 288 | */ 289 | #define list_for_each_entry_safe_reverse(p_node, n, head, member) \ 290 | for (p_node = list_last_entry(head, typeof(*p_node), member), \ 291 | n = list_prev_entry(p_node, member); \ 292 | &p_node->member != (head); \ 293 | p_node = n, n = list_prev_entry(n, member)) 294 | 295 | /** 296 | * list_safe_reset_next - reset a stale list_for_each_entry_safe loop 297 | * @p_node: the loop cursor used in the list_for_each_entry_safe loop 298 | * @n: temporary storage used in list_for_each_entry_safe 299 | * @member: the name of the list_head within the struct. 300 | * 301 | * list_safe_reset_next is not safe to use in general if the list may be 302 | * modified concurrently (eg. the lock is dropped in the loop body). An 303 | * exception to this is if the cursor element (p_node) is pinned in the list, 304 | * and list_safe_reset_next is called after re-taking the lock and before 305 | * completing the current iteration of the loop body. 306 | */ 307 | #define list_safe_reset_next(p_node, n, member) \ 308 | n = list_next_entry(p_node, member) 309 | 310 | /* 311 | * Double linked lists with a single pointer list head. 312 | * Mostly useful for hash tables where the two pointer list head is 313 | * too wasteful. 314 | * You lose the ability to access the tail in O(1). 315 | */ 316 | 317 | struct hlist_head { 318 | struct hlist_node *first; 319 | }; 320 | 321 | struct hlist_node { 322 | struct hlist_node *next, **pprev; 323 | }; 324 | 325 | #define HLIST_POISON1 ((struct hlist_node *) 0x100 + POISON_POINTER_DELTA) 326 | #define HLIST_POISON2 ((struct hlist_node **) 0x200 + POISON_POINTER_DELTA) 327 | 328 | #define HLIST_HEAD_INIT { .first = NULL } 329 | #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } 330 | #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) 331 | 332 | void INIT_HLIST_NODE(struct hlist_node *h); 333 | int hlist_unhashed(const struct hlist_node *h); 334 | int hlist_empty(const struct hlist_head *h); 335 | void hlist_del(struct hlist_node *n); 336 | void hlist_del_init(struct hlist_node *n); 337 | void hlist_add_head(struct hlist_node *n, struct hlist_head *h); 338 | void hlist_add_before(struct hlist_node *n, struct hlist_node *next); 339 | void hlist_add_behind(struct hlist_node *n, struct hlist_node *prev); 340 | void hlist_add_fake(struct hlist_node *n); 341 | int hlist_fake(struct hlist_node *h); 342 | int hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h); 343 | void hlist_move_list(struct hlist_head *old, struct hlist_head *_new); 344 | 345 | #define hlist_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 346 | 347 | #define hlist_for_each(pos, head) \ 348 | for (pos = (head)->first; pos ; pos = pos->next) 349 | 350 | #define hlist_for_each_safe(pos, n, head) \ 351 | for (pos=(head)->first, n=((pos)?((pos)->next):NULL) ; pos ; pos = n, n=((pos)?((pos)->next):NULL) ) 352 | 353 | #define hlist_entry_safe(ptr, type, member) (ptr==NULL?NULL:hlist_entry(ptr, type, member)) 354 | 355 | /** 356 | * hlist_for_each_entry - iterate over list of given type 357 | * @pos: the type * to use as a loop cursor. 358 | * @head: the head for your list. 359 | * @member: the name of the hlist_node within the struct. 360 | */ 361 | #define hlist_for_each_entry(pos, head, type, member) \ 362 | for (pos = hlist_entry_safe((head)->first, type, member); \ 363 | pos; \ 364 | pos = hlist_entry_safe((pos)->member.next, type, member)) 365 | 366 | /** 367 | * hlist_for_each_entry_continue - iterate over a hlist continuing after current point 368 | * @pos: the type * to use as a loop cursor. 369 | * @member: the name of the hlist_node within the struct. 370 | */ 371 | #define hlist_for_each_entry_continue(pos, member) \ 372 | for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ 373 | pos; \ 374 | pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) 375 | 376 | /** 377 | * hlist_for_each_entry_from - iterate over a hlist continuing from current point 378 | * @pos: the type * to use as a loop cursor. 379 | * @member: the name of the hlist_node within the struct. 380 | */ 381 | #define hlist_for_each_entry_from(pos, member) \ 382 | for (; pos; \ 383 | pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) 384 | 385 | /** 386 | * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry 387 | * @pos: the type * to use as a loop cursor. 388 | * @n: another &struct hlist_node to use as temporary storage 389 | * @head: the head for your list. 390 | * @member: the name of the hlist_node within the struct. 391 | */ 392 | #define hlist_for_each_entry_safe(pos, n, head, member) \ 393 | for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ 394 | pos && ({ n = pos->member.next; 1; }); \ 395 | pos = hlist_entry_safe(n, typeof(*pos), member)) 396 | 397 | #endif 398 | -------------------------------------------------------------------------------- /src/cocker/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cocker - Container Machine Engine 3 | * author : calvin 4 | * email : calvinwilliams@163.com 5 | * 6 | * Licensed under the LGPL v2.1, see the file LICENSE in base directory. 7 | */ 8 | 9 | #include "cocker_in.h" 10 | 11 | static void usage() 12 | { 13 | printf( "USAGE : cocker -v\n" ); 14 | printf( " -s images\n" ); 15 | printf( " -s containers\n" ); 16 | printf( " -a create (-m|--image) (image[:version])[,(image[:version])]... [ create options ] [ (-c|--container) (container) ] [ (-b|--boot) [ cgroup options ] [ (-t|--attach) | (-e|--exec) (cmd|\"program para1 ...\") ] ]\n" ); 17 | printf( " -a rplfile (-c|--container) (container) (--template-file) (template_file) (--mapping-file) (mapping_file) [ (--instance-file) (instance_file) ]\n" ); 18 | printf( " -a boot (-c|--container) (container) [ cgroup options ] [ (-t|--attach) | (-e|--exec) (cmd|\"program para1 ...\") ]\n" ); 19 | printf( " -a attach (-c|--container) (container)\n" ); 20 | printf( " -a run (-c|--container) (container) (--cmd) (cmd)\n" ); 21 | printf( " -a shutdown (-c|--container) (container) [ (-f|--forcely) ]\n" ); 22 | printf( " -a kill (-c|--container) (container) [ (-f|--forcely) ]\n" ); 23 | printf( " -a destroy (-c|--container) (container) [ (-f|--forcely) ] [ (-h|--shutdown) ]\n" ); 24 | printf( " -a version (-m|--image) (image[:version]) [ --version (version) ]\n" ); 25 | printf( " -a vip (-c|--container) (container) --vip (ip)\n" ); 26 | printf( " -a port_mapping (-c|--container) (container) --port-mapping (src_port:dst_port)\n" ); 27 | printf( " -a volume (-c|--container) (container) --volume (host_path[:container_path])[ ...]\n" ); 28 | printf( " -a to_image --from-container (container) [ --verion (verion) ] --to-image (image)\n" ); 29 | printf( " -a to_container --from-image (image[:version]) (-m|--image) (image[:version])[,(image[:version])]... [ create options ] --to-container (container)\n" ); 30 | printf( " -a copy_image --from-image (image[:version]) --to-image (image[:version])\n" ); 31 | printf( " -a del_image (-m|--image) (image[:version])\n" ); 32 | printf( " -a import --image-file (file)\n" ); 33 | printf( " -a export (-m|--image) (image[:version])\n" ); 34 | printf( " -s ssearch --srepo (user@host)\n" ); 35 | printf( " -a install_test\n" ); 36 | printf( "create options : [ --volume (host_path:container_path) ][ --volume ... ] [ --host (hostname) ] [ --net (BRIDGE|HOST|CUSTOM) ] [ --host-eth (eth) ] [ --vip (ip) ] [ --port-mapping (src_port:dst_port) ]\n" ); 37 | printf( "cgroup options : [ --cpus [(cpu_num,...)|(cpu_num-cpu_num2)] ] [ --cpu-quota (percent%%) ] [ --mem-limit (num|numM) ]\n" ); 38 | printf( " enable debug : [ (-d|--debug) ]\n" ); 39 | return; 40 | } 41 | 42 | static int ParseCommandParameters( struct CockerEnvironment *env , int argc , char *argv[] ) 43 | { 44 | int i ; 45 | char cmd[ 4096 ] ; 46 | 47 | int nret = 0 ; 48 | 49 | for( i = 1 ; i < argc ; i++ ) 50 | { 51 | if( STRCMP( argv[i] , == , "-v" ) ) 52 | { 53 | printf( "cocker v%s build %s %s\n" , _COCKER_VERSION , __DATE__ , __TIME__ ); 54 | DestroyCockerEnvironment( & env ); 55 | exit(0); 56 | } 57 | else if( STRCMP( argv[i] , == , "-s" ) && i + 1 < argc ) 58 | { 59 | env->cmd_para._show = argv[i+1] ; 60 | i++; 61 | } 62 | else if( STRCMP( argv[i] , == , "-a" ) && i + 1 < argc ) 63 | { 64 | env->cmd_para._action = argv[i+1] ; 65 | i++; 66 | } 67 | else if( STRCMP( argv[i] , == , "--version" ) && i + 1 < argc ) 68 | { 69 | env->cmd_para.__version = argv[i+1] ; 70 | i++; 71 | } 72 | else if( ( STRCMP( argv[i] , == , "-m" ) || STRCMP( argv[i] , == , "--image" ) ) && i + 1 < argc ) 73 | { 74 | env->cmd_para.__image = argv[i+1] ; 75 | i++; 76 | } 77 | else if( ( STRCMP( argv[i] , == , "-c" ) || STRCMP( argv[i] , == , "--container" ) ) && i + 1 < argc ) 78 | { 79 | env->cmd_para.__container = argv[i+1] ; 80 | i++; 81 | } 82 | else if( STRCMP( argv[i] , == , "--host" ) && i + 1 < argc ) 83 | { 84 | env->cmd_para.__host_name = argv[i+1] ; 85 | i++; 86 | } 87 | else if( STRCMP( argv[i] , == , "--net" ) && i + 1 < argc ) 88 | { 89 | env->cmd_para.__net = argv[i+1] ; 90 | i++; 91 | } 92 | else if( STRCMP( argv[i] , == , "--host-eth" ) && i + 1 < argc ) 93 | { 94 | env->cmd_para.__host_eth = argv[i+1] ; 95 | i++; 96 | } 97 | else if( STRCMP( argv[i] , == , "--vip" ) && i + 1 < argc ) 98 | { 99 | env->cmd_para.__vip = argv[i+1] ; 100 | i++; 101 | } 102 | else if( STRCMP( argv[i] , == , "--port-mapping" ) && i + 1 < argc ) 103 | { 104 | env->cmd_para.__port_mapping = argv[i+1] ; 105 | i++; 106 | } 107 | else if( STRCMP( argv[i] , == , "--volume" ) && i + 1 < argc ) 108 | { 109 | struct CockerVolume *volume = NULL ; 110 | char *p = NULL ; 111 | 112 | volume = (struct CockerVolume *)malloc( sizeof(struct CockerVolume) ) ; 113 | if( volume == NULL ) 114 | { 115 | printf( "*** ERROR : malloc failed , errno[%d]\n" , errno ); 116 | exit(1); 117 | } 118 | memset( volume , 0x00 , sizeof(struct CockerVolume) ); 119 | 120 | volume->host_path = argv[i+1] ; 121 | p = strchr( volume->host_path , ':' ) ; 122 | if( p ) 123 | { 124 | volume->host_path_len = p - volume->host_path ; 125 | volume->container_path = p + 1 ; 126 | } 127 | else 128 | { 129 | volume->host_path_len = strlen(volume->host_path) ; 130 | volume->container_path = volume->host_path ; 131 | } 132 | 133 | list_add_tail( & (volume->volume_node) , & (env->cmd_para.volume_list) ); 134 | 135 | env->cmd_para.__volume = argv[i+1] ; 136 | i++; 137 | } 138 | else if( STRCMP( argv[i] , == , "--cpus" ) && i + 1 < argc ) 139 | { 140 | env->cmd_para.__cpus = argv[i+1] ; 141 | i++; 142 | } 143 | else if( STRCMP( argv[i] , == , "--cpu-quota" ) && i + 1 < argc ) 144 | { 145 | env->cmd_para.__cpu_quota = argv[i+1] ; 146 | i++; 147 | } 148 | else if( STRCMP( argv[i] , == , "--mem-limit" ) && i + 1 < argc ) 149 | { 150 | env->cmd_para.__mem_limit = argv[i+1] ; 151 | i++; 152 | } 153 | else if( ( STRCMP( argv[i] , == , "-b" ) || STRCMP( argv[i] , == , "--boot" ) ) ) 154 | { 155 | env->cmd_para.__boot = argv[i] ; 156 | } 157 | else if( ( STRCMP( argv[i] , == , "-t" ) || STRCMP( argv[i] , == , "--attach" ) ) ) 158 | { 159 | env->cmd_para.__attach = argv[i] ; 160 | } 161 | else if( ( STRCMP( argv[i] , == , "-e" ) || STRCMP( argv[i] , == , "--exec" ) ) && i + 1 < argc ) 162 | { 163 | env->cmd_para.__exec = argv[i+1] ; 164 | i++; 165 | } 166 | else if( ( STRCMP( argv[i] , == , "-h" ) || STRCMP( argv[i] , == , "--shutdown" ) ) ) 167 | { 168 | env->cmd_para.__shutdown = argv[i] ; 169 | } 170 | else if( STRCMP( argv[i] , == , "--from-container" ) && i + 1 < argc ) 171 | { 172 | env->cmd_para.__from_container = argv[i+1] ; 173 | i++; 174 | } 175 | else if( STRCMP( argv[i] , == , "--to-image" ) && i + 1 < argc ) 176 | { 177 | env->cmd_para.__to_image = argv[i+1] ; 178 | i++; 179 | } 180 | else if( STRCMP( argv[i] , == , "--from-image" ) && i + 1 < argc ) 181 | { 182 | env->cmd_para.__from_image = argv[i+1] ; 183 | i++; 184 | } 185 | else if( STRCMP( argv[i] , == , "--to-container" ) && i + 1 < argc ) 186 | { 187 | env->cmd_para.__to_container = argv[i+1] ; 188 | i++; 189 | } 190 | else if( STRCMP( argv[i] , == , "--image-file" ) && i + 1 < argc ) 191 | { 192 | env->cmd_para.__image_file = argv[i+1] ; 193 | i++; 194 | } 195 | else if( STRCMP( argv[i] , == , "--srepo" ) && i + 1 < argc ) 196 | { 197 | env->cmd_para.__srepo = argv[i+1] ; 198 | i++; 199 | } 200 | else if( STRCMP( argv[i] , == , "--match" ) && i + 1 < argc ) 201 | { 202 | env->cmd_para.__match = argv[i+1] ; 203 | i++; 204 | } 205 | else if( STRCMP( argv[i] , == , "--cmd" ) && i + 1 < argc ) 206 | { 207 | env->cmd_para.__cmd = argv[i+1] ; 208 | i++; 209 | } 210 | else if( STRCMP( argv[i] , == , "--template-file" ) && i + 1 < argc ) 211 | { 212 | env->cmd_para.__template_file = argv[i+1] ; 213 | i++; 214 | } 215 | else if( STRCMP( argv[i] , == , "--mapping-file" ) && i + 1 < argc ) 216 | { 217 | env->cmd_para.__mapping_file = argv[i+1] ; 218 | i++; 219 | } 220 | else if( STRCMP( argv[i] , == , "--instance-file" ) && i + 1 < argc ) 221 | { 222 | env->cmd_para.__instance_file = argv[i+1] ; 223 | i++; 224 | } 225 | else if( STRCMP( argv[i] , == , "--src-file" ) && i + 1 < argc ) 226 | { 227 | env->cmd_para.__src_file = argv[i+1] ; 228 | i++; 229 | } 230 | else if( STRCMP( argv[i] , == , "--dst-file" ) && i + 1 < argc ) 231 | { 232 | env->cmd_para.__dst_file = argv[i+1] ; 233 | i++; 234 | } 235 | else if( ( STRCMP( argv[i] , == , "-d" ) || STRCMP( argv[i] , == , "--debug" ) ) ) 236 | { 237 | env->cmd_para.__debug = argv[i] ; 238 | } 239 | else if( ( STRCMP( argv[i] , == , "-f" ) || STRCMP( argv[i] , == , "--forcely" ) ) ) 240 | { 241 | env->cmd_para.__forcely = argv[i] ; 242 | } 243 | else 244 | { 245 | printf( "*** ERROR : invalid parameter '%s'\n" , argv[i] ); 246 | usage(); 247 | return -7; 248 | } 249 | } 250 | 251 | if( env->cmd_para.__net == NULL ) 252 | env->cmd_para.__net = "HOST" ; 253 | 254 | if( ! ( STRCMP( env->cmd_para.__net , == , "BRIDGE" ) || STRCMP( env->cmd_para.__net , == , "HOST" ) || STRCMP( env->cmd_para.__net , == , "CUSTOM" ) ) ) 255 | { 256 | printf( "*** ERROR : '--net' value[%s] invalid\n" , env->cmd_para.__net ); 257 | return -7; 258 | } 259 | 260 | if( env->cmd_para.__host_eth ) 261 | { 262 | memset( env->host_eth_name , 0x00 , sizeof(env->host_eth_name) ); 263 | strncpy( env->host_eth_name , env->cmd_para.__host_eth , sizeof(env->host_eth_name)-1 ); 264 | } 265 | else 266 | { 267 | struct ifaddrs *ifa_base = NULL ; 268 | struct ifaddrs *ifa = NULL ; 269 | 270 | nret = getifaddrs( & ifa_base ) ; 271 | if( nret == -1 ) 272 | { 273 | printf( "*** ERROR : getifaddrs failed[%d] , errno[%d]\n" , nret , errno ); 274 | return -1; 275 | } 276 | 277 | memset( env->host_eth_name , 0x00 , sizeof(env->host_eth_name) ); 278 | ifa = ifa_base ; 279 | while( ifa ) 280 | { 281 | if( ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET ) 282 | { 283 | if( STRCMP( ifa->ifa_name , != , "lo" ) && STRCMP( ifa->ifa_name , != , "cocker0" ) && STRNCMP( ifa->ifa_name , != , "veth" , 4 ) ) 284 | { 285 | strncpy( env->host_eth_name , ifa->ifa_name , sizeof(env->host_eth_name)-1 ); 286 | break; 287 | } 288 | } 289 | 290 | ifa = ifa->ifa_next ; 291 | } 292 | 293 | freeifaddrs( ifa_base ); 294 | 295 | if( env->host_eth_name[0] == '\0' ) 296 | { 297 | printf( "*** ERROR : host if name not found\n" ); 298 | return -1; 299 | } 300 | } 301 | 302 | memset( cmd , 0x00 , sizeof(cmd) ); 303 | SnprintfAndPopen( env->host_eth_ip , sizeof(env->host_eth_ip) , cmd , sizeof(cmd) , "ifconfig %s | grep -w inet | awk '{print $2}'" , env->host_eth_name ); 304 | TrimEnter( env->host_eth_ip ); 305 | 306 | if( env->cmd_para.__cpus || env->cmd_para.__cpu_quota || env->cmd_para.__mem_limit ) 307 | env->cgroup_enable = 1 ; 308 | 309 | return 0; 310 | } 311 | 312 | static int ExecuteCommandParameters( struct CockerEnvironment *env ) 313 | { 314 | int nret = 0 ; 315 | 316 | SetLogcFile( "/var/cocker/cocker.log" ); 317 | SetLogcLevel( LOGCLEVEL_INFO ); 318 | 319 | if( env->cmd_para._show ) 320 | { 321 | if( STRCMP( env->cmd_para._show , == , "images" ) ) 322 | { 323 | INFOLOGC( "--- call DoShow_images ---" ) 324 | nret = DoShow_images( env ) ; 325 | INFOLOGC( "--- DoShow_images return[%d] ---" , nret ) 326 | } 327 | else if( STRCMP( env->cmd_para._show , == , "containers" ) ) 328 | { 329 | INFOLOGC( "--- call DoShow_containers ---" ) 330 | nret = DoShow_containers( env ) ; 331 | INFOLOGC( "--- DoShow_containers return[%d] ---" , nret ) 332 | } 333 | else if( STRCMP( env->cmd_para._show , == , "container_root" ) ) 334 | { 335 | INFOLOGC( "--- call DoShow_container_root ---" ) 336 | nret = DoShow_container_root( env ) ; 337 | INFOLOGC( "--- DoShow_container_root return[%d] ---" , nret ) 338 | } 339 | else if( STRCMP( env->cmd_para._show , == , "ssearch" ) ) 340 | { 341 | INFOLOGC( "--- call DoShow_ssearch ---" ) 342 | nret = DoShow_ssearch( env ) ; 343 | INFOLOGC( "--- DoShow_ssearch return[%d] ---" , nret ) 344 | } 345 | else 346 | { 347 | printf( "*** ERROR : show[%s] invalid\n" , env->cmd_para._show ); 348 | return -7; 349 | } 350 | } 351 | else if( env->cmd_para._action ) 352 | { 353 | if( STRCMP( env->cmd_para._action , == , "install_test" ) ) 354 | { 355 | return -DoAction_install_test( env ); 356 | } 357 | else if( STRCMP( env->cmd_para._action , == , "create" ) ) 358 | { 359 | if( IS_NULL_OR_EMPTY(env->cmd_para.__image) ) 360 | { 361 | printf( "*** ERROR : expect '--image' with action '-a create'\n" ); 362 | return -7; 363 | } 364 | 365 | if( env->cmd_para.__net && STRCMP( env->cmd_para.__net , == , "BRIDGE" ) ) 366 | { 367 | if( ( env->cmd_para.__vip == NULL || env->cmd_para.__vip[0] == '\0' ) ) 368 | { 369 | printf( "*** ERROR : expect '--vip' with action '-a create'\n" ); 370 | return -7; 371 | } 372 | } 373 | 374 | INFOLOGC( "--- call DoAction_create ---" ) 375 | nret = DoAction_create( env ) ; 376 | INFOLOGC( "--- DoAction_create return[%d] ---" , nret ) 377 | } 378 | else if( STRCMP( env->cmd_para._action , == , "boot" ) ) 379 | { 380 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 381 | { 382 | printf( "*** ERROR : expect '--container' with action '-a boot'\n" ); 383 | return -7; 384 | } 385 | 386 | INFOLOGC( "--- call DoAction_boot ---" ) 387 | nret = DoAction_boot( env ) ; 388 | INFOLOGC( "--- DoAction_boot return[%d] ---" , nret ) 389 | } 390 | else if( STRCMP( env->cmd_para._action , == , "attach" ) ) 391 | { 392 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 393 | { 394 | printf( "*** ERROR : expect '--container' with action '-a attach'\n" ); 395 | return -7; 396 | } 397 | 398 | INFOLOGC( "--- call DoAction_attach ---" ) 399 | nret = DoAction_attach( env ) ; 400 | INFOLOGC( "--- DoAction_attach return[%d] ---" , nret ) 401 | } 402 | else if( STRCMP( env->cmd_para._action , == , "run" ) ) 403 | { 404 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 405 | { 406 | printf( "*** ERROR : expect '--container' with action '-a run'\n" ); 407 | return -7; 408 | } 409 | 410 | if( IS_NULL_OR_EMPTY(env->cmd_para.__cmd) ) 411 | { 412 | printf( "*** ERROR : expect '--cmd' with action '-a run'\n" ); 413 | return -7; 414 | } 415 | 416 | INFOLOGC( "--- call DoAction_run ---" ) 417 | nret = DoAction_run( env ) ; 418 | INFOLOGC( "--- DoAction_run return[%d] ---" , nret ) 419 | } 420 | else if( STRCMP( env->cmd_para._action , == , "rplfile" ) ) 421 | { 422 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 423 | { 424 | printf( "*** ERROR : expect '--container' with action '-a rplfile'\n" ); 425 | return -7; 426 | } 427 | 428 | if( IS_NULL_OR_EMPTY(env->cmd_para.__template_file) ) 429 | { 430 | printf( "*** ERROR : expect '--template-file' with action '-a rplfile'\n" ); 431 | return -7; 432 | } 433 | 434 | if( IS_NULL_OR_EMPTY(env->cmd_para.__mapping_file) ) 435 | { 436 | printf( "*** ERROR : expect '--mapping-file' with action '-a rplfile'\n" ); 437 | return -7; 438 | } 439 | 440 | INFOLOGC( "--- call DoAction_rplfile ---" ) 441 | nret = DoAction_rplfile( env ) ; 442 | INFOLOGC( "--- DoAction_rplfile return[%d] ---" , nret ) 443 | } 444 | else if( STRCMP( env->cmd_para._action , == , "putfile" ) ) 445 | { 446 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 447 | { 448 | printf( "*** ERROR : expect '--container' with action '-a putfile'\n" ); 449 | return -7; 450 | } 451 | 452 | if( IS_NULL_OR_EMPTY(env->cmd_para.__src_file) ) 453 | { 454 | printf( "*** ERROR : expect '--src-file' with action '-a putfile'\n" ); 455 | return -7; 456 | } 457 | 458 | if( IS_NULL_OR_EMPTY(env->cmd_para.__dst_file) ) 459 | { 460 | printf( "*** ERROR : expect '--dst-file' with action '-a putfile'\n" ); 461 | return -7; 462 | } 463 | 464 | INFOLOGC( "--- call DoAction_putfile ---" ) 465 | nret = DoAction_putfile( env ) ; 466 | INFOLOGC( "--- DoAction_putfile return[%d] ---" , nret ) 467 | } 468 | else if( STRCMP( env->cmd_para._action , == , "getfile" ) ) 469 | { 470 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 471 | { 472 | printf( "*** ERROR : expect '--container' with action '-a getfile'\n" ); 473 | return -7; 474 | } 475 | 476 | if( IS_NULL_OR_EMPTY(env->cmd_para.__src_file) ) 477 | { 478 | printf( "*** ERROR : expect '--src-file' with action '-a getfile'\n" ); 479 | return -7; 480 | } 481 | 482 | if( IS_NULL_OR_EMPTY(env->cmd_para.__dst_file) ) 483 | { 484 | printf( "*** ERROR : expect '--dst-file' with action '-a getfile'\n" ); 485 | return -7; 486 | } 487 | 488 | INFOLOGC( "--- call DoAction_getfile ---" ) 489 | nret = DoAction_getfile( env ) ; 490 | INFOLOGC( "--- DoAction_getfile return[%d] ---" , nret ) 491 | } 492 | else if( STRCMP( env->cmd_para._action , == , "shutdown" ) ) 493 | { 494 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 495 | { 496 | printf( "*** ERROR : expect '--container' with action '-a shutdown'\n" ); 497 | return -7; 498 | } 499 | 500 | INFOLOGC( "--- call DoAction_shutdown ---" ) 501 | nret = DoAction_shutdown( env ) ; 502 | INFOLOGC( "--- DoAction_shutdown return[%d] ---" , nret ) 503 | } 504 | else if( STRCMP( env->cmd_para._action , == , "kill" ) ) 505 | { 506 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 507 | { 508 | printf( "*** ERROR : expect '--container' with action '-a kill'\n" ); 509 | return -7; 510 | } 511 | 512 | INFOLOGC( "--- call DoAction_kill ---" ) 513 | nret = DoAction_kill( env ) ; 514 | INFOLOGC( "--- DoAction_kill return[%d] ---" , nret ) 515 | } 516 | else if( STRCMP( env->cmd_para._action , == , "destroy" ) ) 517 | { 518 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 519 | { 520 | printf( "*** ERROR : expect '--container' with action '-a destroy'\n" ); 521 | return -7; 522 | } 523 | 524 | INFOLOGC( "--- call DoAction_destroy ---" ) 525 | nret = DoAction_destroy( env ) ; 526 | INFOLOGC( "--- DoAction_destroy return[%d] ---" , nret ) 527 | } 528 | else if( STRCMP( env->cmd_para._action , == , "version" ) ) 529 | { 530 | if( IS_NULL_OR_EMPTY(env->cmd_para.__image) ) 531 | { 532 | printf( "*** ERROR : expect '--image' with action '-a version'\n" ); 533 | return -7; 534 | } 535 | 536 | INFOLOGC( "--- call DoAction_version ---" ) 537 | nret = DoAction_version( env ) ; 538 | INFOLOGC( "--- DoAction_version return[%d] ---" , nret ) 539 | } 540 | else if( STRCMP( env->cmd_para._action , == , "vip" ) ) 541 | { 542 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 543 | { 544 | printf( "*** ERROR : expect '--container' with action '-a vip'\n" ); 545 | return -7; 546 | } 547 | 548 | if( IS_NULL_OR_EMPTY(env->cmd_para.__vip) ) 549 | { 550 | printf( "*** ERROR : expect '--vip' with action '-a vip'\n" ); 551 | return -7; 552 | } 553 | 554 | INFOLOGC( "--- call DoAction_vip ---" ) 555 | nret = DoAction_vip( env ) ; 556 | INFOLOGC( "--- DoAction_vip return[%d] ---" , nret ) 557 | } 558 | else if( STRCMP( env->cmd_para._action , == , "port_mapping" ) ) 559 | { 560 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 561 | { 562 | printf( "*** ERROR : expect '--container' with action '-a port_mapping'\n" ); 563 | return -7; 564 | } 565 | 566 | if( IS_NULL_OR_EMPTY(env->cmd_para.__port_mapping) ) 567 | { 568 | printf( "*** ERROR : expect '--port-mapping' with action '-a port_mapping'\n" ); 569 | return -7; 570 | } 571 | 572 | INFOLOGC( "--- call DoAction_port_mapping ---" ) 573 | nret = DoAction_port_mapping( env ) ; 574 | INFOLOGC( "--- DoAction_port_mapping return[%d] ---" , nret ) 575 | } 576 | else if( STRCMP( env->cmd_para._action , == , "volume" ) ) 577 | { 578 | if( IS_NULL_OR_EMPTY(env->cmd_para.__container) ) 579 | { 580 | printf( "*** ERROR : expect '--volume' with action '-a volume'\n" ); 581 | return -7; 582 | } 583 | 584 | if( IS_NULL_OR_EMPTY(env->cmd_para.__volume) ) 585 | { 586 | printf( "*** ERROR : expect '--volume' with action '-a volume'\n" ); 587 | return -7; 588 | } 589 | 590 | INFOLOGC( "--- call DoAction_volume ---" ) 591 | nret = DoAction_volume( env ) ; 592 | INFOLOGC( "--- DoAction_volume return[%d] ---" , nret ) 593 | } 594 | else if( STRCMP( env->cmd_para._action , == , "to_image" ) ) 595 | { 596 | if( IS_NULL_OR_EMPTY(env->cmd_para.__from_container) ) 597 | { 598 | printf( "*** ERROR : expect '--from-container' with action '-a to_image'\n" ); 599 | return -7; 600 | } 601 | 602 | if( IS_NULL_OR_EMPTY(env->cmd_para.__to_image) ) 603 | { 604 | printf( "*** ERROR : expect '--to-image' with action '-a to_image'\n" ); 605 | return -7; 606 | } 607 | 608 | INFOLOGC( "--- call DoAction_to_image ---" ) 609 | nret = DoAction_to_image( env ) ; 610 | INFOLOGC( "--- DoAction_to_image return[%d] ---" , nret ) 611 | } 612 | else if( STRCMP( env->cmd_para._action , == , "to_container" ) ) 613 | { 614 | if( IS_NULL_OR_EMPTY(env->cmd_para.__from_image) ) 615 | { 616 | printf( "*** ERROR : expect '--from-image' with action '-a to_image'\n" ); 617 | return -7; 618 | } 619 | 620 | if( IS_NULL_OR_EMPTY(env->cmd_para.__to_container) ) 621 | { 622 | printf( "*** ERROR : expect '--to-container' with action '-a to_container'\n" ); 623 | return -7; 624 | } 625 | 626 | if( STRCMP( env->cmd_para.__net , == , "BRIDGE" ) && env->cmd_para.__vip[0] == '\0' ) 627 | { 628 | printf( "*** ERROR : expect '--vip' with action '-a create'\n" ); 629 | return -7; 630 | } 631 | 632 | INFOLOGC( "--- call DoAction_to_container ---" ) 633 | nret = DoAction_to_container( env ) ; 634 | INFOLOGC( "--- DoAction_to_container return[%d] ---" , nret ) 635 | } 636 | else if( STRCMP( env->cmd_para._action , == , "copy_image" ) ) 637 | { 638 | if( IS_NULL_OR_EMPTY(env->cmd_para.__from_image) ) 639 | { 640 | printf( "*** ERROR : expect '--from-image' with action '-a copy_image'\n" ); 641 | return -7; 642 | } 643 | 644 | if( IS_NULL_OR_EMPTY(env->cmd_para.__to_image) ) 645 | { 646 | printf( "*** ERROR : expect '--to-image' with action '-a copy_image'\n" ); 647 | return -7; 648 | } 649 | 650 | INFOLOGC( "--- call DoAction_copy_image ---" ) 651 | nret = DoAction_copy_image( env ) ; 652 | INFOLOGC( "--- DoAction_copy_image return[%d] ---" , nret ) 653 | } 654 | else if( STRCMP( env->cmd_para._action , == , "del_image" ) ) 655 | { 656 | if( IS_NULL_OR_EMPTY(env->cmd_para.__image) ) 657 | { 658 | printf( "*** ERROR : expect '--image' with action '-a del_image'\n" ); 659 | return -7; 660 | } 661 | 662 | INFOLOGC( "--- call DoAction_del_image ---" ) 663 | nret = DoAction_del_image( env ) ; 664 | INFOLOGC( "--- DoAction_del_image return[%d] ---" , nret ) 665 | } 666 | else if( STRCMP( env->cmd_para._action , == , "export" ) ) 667 | { 668 | if( IS_NULL_OR_EMPTY(env->cmd_para.__image) ) 669 | { 670 | printf( "*** ERROR : expect '--image' with action '-a export'\n" ); 671 | return -7; 672 | } 673 | 674 | INFOLOGC( "--- call DoAction_export ---" ) 675 | nret = DoAction_export( env ) ; 676 | INFOLOGC( "--- DoAction_export return[%d] ---" , nret ) 677 | } 678 | else if( STRCMP( env->cmd_para._action , == , "import" ) ) 679 | { 680 | if( IS_NULL_OR_EMPTY(env->cmd_para.__image_file) ) 681 | { 682 | printf( "*** ERROR : expect '--image-file' with action '-a import'\n" ); 683 | return -7; 684 | } 685 | 686 | INFOLOGC( "--- call DoAction_import ---" ) 687 | nret = DoAction_import( env ) ; 688 | INFOLOGC( "--- DoAction_import return[%d] ---" , nret ) 689 | } 690 | else if( STRCMP( env->cmd_para._action , == , "spush" ) ) 691 | { 692 | if( IS_NULL_OR_EMPTY(env->cmd_para.__image) ) 693 | { 694 | printf( "*** ERROR : expect '--image' with action '-a spush'\n" ); 695 | return -7; 696 | } 697 | 698 | INFOLOGC( "--- call DoAction_spush ---" ) 699 | nret = DoAction_spush( env ) ; 700 | INFOLOGC( "--- DoAction_spush return[%d] ---" , nret ) 701 | } 702 | else if( STRCMP( env->cmd_para._action , == , "spull" ) ) 703 | { 704 | if( IS_NULL_OR_EMPTY(env->cmd_para.__image) ) 705 | { 706 | printf( "*** ERROR : expect '--image' with action '-a spull'\n" ); 707 | return -7; 708 | } 709 | 710 | INFOLOGC( "--- call DoAction_spull ---" ) 711 | nret = DoAction_spull( env ) ; 712 | INFOLOGC( "--- DoAction_spull return[%d] ---" , nret ) 713 | } 714 | else 715 | { 716 | printf( "*** ERROR : action[%s] invalid\n" , env->cmd_para._action ); 717 | return -7; 718 | } 719 | } 720 | else 721 | { 722 | printf( "*** ERROR : cmd para action[%s] invalid\n" , env->cmd_para._action ); 723 | return -7; 724 | } 725 | 726 | return -nret; 727 | } 728 | 729 | int main( int argc , char *argv[] ) 730 | { 731 | struct CockerEnvironment *env = NULL ; 732 | 733 | int nret = 0 ; 734 | 735 | nret = CreateCockerEnvironment( & env ) ; 736 | if( nret ) 737 | { 738 | return -nret; 739 | } 740 | 741 | if( argc == 1 ) 742 | { 743 | usage(); 744 | return 0; 745 | } 746 | 747 | nret = ParseCommandParameters( env , argc , argv ) ; 748 | if( nret ) 749 | { 750 | return -nret; 751 | } 752 | 753 | nret = ExecuteCommandParameters( env ) ; 754 | DestroyCockerEnvironment( & env ); 755 | if( nret ) 756 | { 757 | return -nret; 758 | } 759 | 760 | return 0; 761 | } 762 | 763 | --------------------------------------------------------------------------------