occlum/tools/occlum
Hui, Chunyang 6a17e6292c Add support for user specified instance dir name
The default instance dir of Occlum is ".occlum". User now can specify the name
by declaring environment variable "OCCLUM_INSTANCE_DIR"
2020-05-15 02:59:16 +00:00

296 lines
8.8 KiB
Bash
Executable File

#!/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 <<EOF
Usage:
occlum init
Initialize a directory as the Occlum context
occlum build [--sign-key <key_path>] [--sign-tool <tool_path>]
Generate a secure Occlum FS image and Occlum SGX enclave.
occlum run <program_name> <program_args>
Run the user program inside an SGX enclave.
To run the enclave in SGX hardware release mode, use:
OCCLUM_RELEASE_ENCLAVE=1 occlum run <program_name> <program_args>
occlum gdb <program_name> <program_args>
Debug the program running inside an SGX enclave with GDB.
EOF
}
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() {
"$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/libcompiler-rt-patch.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/" && \
./sefs-fuse \
--integrity-only \
"$context_dir/build/mount/__ROOT" \
"$working_dir/image" \
zip
export OCCLUM_CONF_ROOT_FS_MAC=`"$occlum_dir/$build_dir/bin/occlum-protect-integrity" show-mac "$context_dir/build/mount/__ROOT/metadata"`
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"
"$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"
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_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}"
;;
gdb)
cmd_gdb "${@:2}"
;;
status)
cmd_status
;;
*)
report_arg_error "Error: unknown sub-command $cmd"
exit 1
esac