#!/bin/bash this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" occlum_dir="$( cd "$( dirname "$this_dir/../../../" )" >/dev/null 2>&1 && pwd )" if [ -z $OCCLUM_INSTANCE_DIR ];then OCCLUM_INSTANCE_DIR=".occlum" fi working_dir=`pwd` context_dir="$working_dir/$OCCLUM_INSTANCE_DIR" SGX_SDK="${SGX_SDK:-/opt/intel/sgxsdk}" SGX_GDB="$SGX_SDK/bin/sgx-gdb" ENCLAVE_SIGN_TOOL="$SGX_SDK/bin/x64/sgx_sign" ENCLAVE_SIGN_KEY="$occlum_dir/etc/template/Enclave.pem" exit_error() { echo "Error: $@" >&2 exit 1 } report_arg_error() { echo $1 >&2 echo "" cat <] [--sign-tool ] Generate a secure Occlum FS image and Occlum SGX enclave. occlum run Run the user program inside an SGX enclave. To run the enclave in SGX hardware release mode, use: OCCLUM_RELEASE_ENCLAVE=1 occlum run occlum gdb Debug the program running inside an SGX enclave with GDB. EOF } get_conf_root_fs_mac() { LD_LIBRARY_PATH="$SGX_SDK/sdk_libs" \ "$occlum_dir/$build_dir/bin/occlum-protect-integrity" show-mac "$context_dir/build/mount/__ROOT/metadata" } get_conf_default_stack_size() { cat "$working_dir/Occlum.json" | \ python -c "import sys, json; print json.load(sys.stdin)['process']['default_stack_size']" } get_conf_default_heap_size() { cat "$working_dir/Occlum.json" | \ python -c "import sys, json; print json.load(sys.stdin)['process']['default_heap_size']" } get_conf_default_mmap_size() { cat "$working_dir/Occlum.json" | \ python -c "import sys, json; print json.load(sys.stdin)['process']['default_mmap_size']" } get_conf_user_space_size() { cat "$working_dir/Occlum.json" | \ python -c "import sys, json; print json.load(sys.stdin)['vm']['user_space_size']" } get_conf_env() { cat "$working_dir/Occlum.json" | \ python -c "import sys, json; print json.dumps(json.load(sys.stdin)['env'])" } get_conf_entry_points() { cat "$working_dir/Occlum.json" | \ python -c "import sys, json; print json.dumps(json.load(sys.stdin)['entry_points'])" } get_occlum_conf_file_mac() { LD_LIBRARY_PATH="$SGX_SDK/sdk_libs" \ "$occlum_dir/$build_dir/bin/occlum-protect-integrity" show-mac "$context_dir/build/Occlum.json.protected" } parse_occlum_user_space_size() { local size_with_unit=`get_conf_user_space_size` numfmt --from=iec ${size_with_unit::-1} } check_has_init() { if [ ! -d "$context_dir" ]; then echo "Error: the current working directory is not initialized as an Occlum context. Need to run \"occlum init\" first." exit 1 fi } check_has_built() { check_has_init if [ ! -d "$context_dir/run/mount/root" ]; then echo "Error: the Occlum image and enclave are not built yet. Need to run \"occlum build\" first." exit 1 fi } cmd_init() { if [ -d "$context_dir" ]; then echo "Error: the current working directory has been initialized as an Occlum context" exit 1 fi mkdir "$context_dir" cd "$context_dir" echo "initialized" > status cd "$working_dir" mkdir -p image mkdir -p image/bin mkdir -p image/lib mkdir -p image/root mkdir -p image/host mkdir -p image/tmp local occlum_gcc_lib=/usr/local/occlum/x86_64-linux-musl/lib cp -t image/lib/ \ /lib/ld-musl-x86_64.so.1 \ "$occlum_gcc_lib/libc.so" \ "$occlum_gcc_lib/libstdc++.so.6" \ "$occlum_gcc_lib/libgcc_s.so.1" \ "$occlum_gcc_lib/libgomp.so.1" cp "$occlum_dir"/etc/template/Enclave.xml "$working_dir"/ cp "$occlum_dir"/etc/template/Occlum.json "$working_dir"/ chmod 644 "$working_dir"/Enclave.xml chmod 644 "$working_dir"/Occlum.json echo "Initialized an Occlum context in $working_dir" } cmd_build() { check_has_init build_dir=build while [ -n "$1" ]; do case "$1" in --sign-key) [ -n "$2" ] && ENCLAVE_SIGN_KEY=$2 ; shift 2 || exit_error "empty signing key path" ;; --sign-tool) [ -n "$2" ] && ENCLAVE_SIGN_TOOL=$2 ; shift 2 || exit_error "empty signing tool path" ;; --sgx-mode) [[ -n "$2" && "$2" != "HW" ]] && export SGX_MODE=SW && build_dir=build_sim ; shift 2 || exit_error "empty sgx mode";; *) exit_error "Unknown option: $1" ;; esac done [ -e "$ENCLAVE_SIGN_KEY" ] || exit_error "invalid signing key path: $ENCLAVE_SIGN_KEY" [ -e "$ENCLAVE_SIGN_TOOL" ] || exit_error "invalid signing tool path: $ENCLAVE_SIGN_TOOL" echo "Enclave sign-tool: $ENCLAVE_SIGN_TOOL" echo "Enclave sign-key: $ENCLAVE_SIGN_KEY" if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SGX_SDK/sdk_libs build_dir=build_sim echo "SGX mode: $SGX_MODE" else echo "SGX mode: HW" fi cd "$context_dir" echo "building" > status rm -rf build rm -rf run mkdir -p build/bin cp "$occlum_dir/$build_dir/bin/occlum-run" build/bin/ mkdir -p build/lib cp "$occlum_dir/$build_dir/lib/libocclum-libos-core.a" build/lib/ cp "$occlum_dir/$build_dir/lib/libocclum-pal.so" build/lib/ mkdir -p build/src/libos/src/builtin chmod 531 -R $working_dir/image/bin chmod 531 -R $working_dir/image/lib mkdir -p build/mount/ cd "$occlum_dir/$build_dir/bin/" && \ LD_LIBRARY_PATH="$SGX_SDK/sdk_libs" ./sefs-fuse \ --integrity-only \ "$context_dir/build/mount/__ROOT" \ "$working_dir/image" \ zip export OCCLUM_CONF_ROOT_FS_MAC=`get_conf_root_fs_mac` export OCCLUM_CONF_USER_SPACE_SIZE=`get_conf_user_space_size` export OCCLUM_CONF_DEFAULT_STACK_SIZE=`get_conf_default_stack_size` export OCCLUM_CONF_DEFAULT_HEAP_SIZE=`get_conf_default_heap_size` export OCCLUM_CONF_DEFAULT_MMAP_SIZE=`get_conf_default_mmap_size` export OCCLUM_CONF_ENV=`get_conf_env` export OCCLUM_CONF_ENTRY_POINTS=`get_conf_entry_points` cd "$context_dir/build" "$occlum_dir/$build_dir/bin/occlum-gen-default-occlum-json"\ > "Occlum.json" LD_LIBRARY_PATH="$SGX_SDK/sdk_libs" "$occlum_dir/$build_dir/bin/occlum-protect-integrity" protect Occlum.json export OCCLUM_BUILTIN_CONF_FILE_MAC=`get_occlum_conf_file_mac` echo "EXPORT => OCCLUM_BUILTIN_CONF_FILE_MAC = $OCCLUM_BUILTIN_CONF_FILE_MAC" export OCCLUM_BUILTIN_VM_USER_SPACE_SIZE=`parse_occlum_user_space_size` echo "EXPORT => OCCLUM_BUILTIN_VM_USER_SPACE_SIZE = $OCCLUM_BUILTIN_VM_USER_SPACE_SIZE" cd "$context_dir" mkdir -p src/libos/src/ cp "$occlum_dir/src/sgxenv.mk" src/ cp "$occlum_dir/src/libos/Makefile" src/libos/ cp "$occlum_dir/src/libos/Enclave.lds" src/libos/ cp -r "$occlum_dir/src/libos/src/builtin" src/libos/src/builtin cd src/libos && \ make clean-builtin && \ make "$context_dir/build/lib/libocclum-libos.so" ONLY_REBUILD_BUILTIN=1 CONTEXT=1 $ENCLAVE_SIGN_TOOL sign \ -key $ENCLAVE_SIGN_KEY \ -config "$working_dir/Enclave.xml" \ -enclave "$context_dir/build/lib/libocclum-libos.so" \ -out "$context_dir/build/lib/libocclum-libos.signed.so" cd "$context_dir" echo "built" > status if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then echo "SIM" > .sgx_mode else echo "HW" > .sgx_mode fi mkdir -p "$context_dir/run/mount/root" ln -s $occlum_dir/$build_dir/bin/occlum_exec_client $context_dir/build/bin/occlum_exec_client ln -s $occlum_dir/$build_dir/bin/occlum_exec_server $context_dir/build/bin/occlum_exec_server echo "Built the Occlum image and enclave successfully" } cmd_run() { check_has_built SGX_MODE=$(cat $context_dir/.sgx_mode) if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then export LD_LIBRARY_PATH="$context_dir/build/lib:$SGX_SDK/sdk_libs/" else export LD_LIBRARY_PATH="$context_dir/build/lib" fi cd "$working_dir" echo "running" > "$context_dir/status" RUST_BACKTRACE=1 "$context_dir/build/bin/occlum-run" "$@" echo "built" > "$context_dir/status" } cmd_start() { check_has_built SGX_MODE=$(cat $context_dir/.sgx_mode) if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then export LD_LIBRARY_PATH="$context_dir/build/lib:$SGX_SDK/sdk_libs/" else export LD_LIBRARY_PATH="$context_dir/build/lib" fi cd "$working_dir" echo "running" > "$context_dir/status" RUST_BACKTRACE=1 "$context_dir/build/bin/occlum_exec_client" start echo "built" > "$context_dir/status" } cmd_exec() { check_has_built SGX_MODE=$(cat $context_dir/.sgx_mode) if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then export LD_LIBRARY_PATH="$context_dir/build/lib:$SGX_SDK/sdk_libs/" else export LD_LIBRARY_PATH="$context_dir/build/lib" fi cd "$working_dir" echo "running" > "$context_dir/status" RUST_BACKTRACE=1 "$context_dir/build/bin/occlum_exec_client" exec -- "$@" echo "built" > "$context_dir/status" } cmd_stop() { check_has_built SGX_MODE=$(cat $context_dir/.sgx_mode) if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then export LD_LIBRARY_PATH="$context_dir/build/lib:$SGX_SDK/sdk_libs/" else export LD_LIBRARY_PATH="$context_dir/build/lib" fi cd "$working_dir" echo "running" > "$context_dir/status" RUST_BACKTRACE=1 "$context_dir/build/bin/occlum_exec_client" stop -t 0 echo "built" > "$context_dir/status" } cmd_gdb() { check_has_built SGX_MODE=$(cat $context_dir/.sgx_mode) if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then export LD_LIBRARY_PATH="$context_dir/build/lib:$SGX_SDK/sdk_libs/" else export LD_LIBRARY_PATH="$context_dir/build/lib" fi cd "$working_dir" echo "debugging" > "$context_dir/status" OCCLUM_GDB=1 $SGX_GDB --args "$context_dir/build/bin/occlum-run" "$@" echo "built" > "$context_dir/status" } cmd_status() { cat "$context_dir/status" } set -e if [[ ( "$#" < 1 ) ]] ; then report_arg_error "Error: no sub-command is given" exit 1 fi cmd=$1 case "$cmd" in init) cmd_init ;; build) cmd_build "${@:2}" ;; run) cmd_run "${@:2}" ;; start) cmd_start ;; exec) cmd_exec "${@:2}" ;; stop) cmd_stop ;; gdb) cmd_gdb "${@:2}" ;; status) cmd_status ;; *) report_arg_error "Error: unknown sub-command $cmd" exit 1 esac