occlum/tools/occlum
2024-03-06 15:59:26 +08:00

830 lines
26 KiB
Bash
Executable File

#!/bin/bash
set -e
this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
occlum_dir="$( cd "$( dirname "$this_dir/../../../" )" >/dev/null 2>&1 && pwd )"
build_makefile=$occlum_dir/build/bin/occlum_build.mk
if [[ "$occlum_dir" == "/opt/occlum" ]]; then
version_header=$occlum_dir/include/occlum_version.h
occlum_sgx_env=$occlum_dir/sgxsdk-tools/environment
else
version_header=$occlum_dir/src/pal/include/occlum_version.h
occlum_sgx_env=$occlum_dir/etc/environment
fi
# For deployment environment, version header file may not exist
if [ -f "$version_header" ]; then
major_ver=`grep '\#define OCCLUM_MAJOR_VERSION' $version_header | awk '{print $3}'`
minor_ver=`grep '\#define OCCLUM_MINOR_VERSION' $version_header | awk '{print $3}'`
patch_ver=`grep '\#define OCCLUM_PATCH_VERSION' $version_header | awk '{print $3}'`
occlum_version="$major_ver.$minor_ver.$patch_ver"
fi
instance_dir=`pwd`
status_file=$instance_dir/.__occlum_status
# For deployment environment, env for sgx-sdk may not exist
if [ -f "$occlum_sgx_env" ]; then
source $occlum_sgx_env
SGX_GDB="$SGX_SDK/bin/sgx-gdb"
if [[ -n $SGX_MODE && "$SGX_MODE" == "HYPER" ]]; then
ENCLAVE_SIGN_TOOL="$SGX_SDK/bin/x64/sgx_sign_hyper"
else
ENCLAVE_SIGN_TOOL="$SGX_SDK/bin/x64/sgx_sign"
fi
ENCLAVE_SIGN_KEY="$occlum_dir/etc/template/Enclave.pem"
fi
get_enclave_debuggable_flag() {
jq '.metadata.debuggable' $instance_dir/Occlum.json
}
get_enclave_enable_kss_flag() {
jq '.metadata.enable_kss' $instance_dir/Occlum.json
}
exit_error() {
echo "Error: $@" >&2
exit 1
}
report_arg_error() {
echo $1 >&2
echo ""
cat <<EOF
Usage:
occlum new <path> [--init-ra <grpc_ratls/aecs>]
Create a new directory at <path> and initialize as the Occlum instance.
If flag --init-ra specifies, generate initfs with RA KMS client function.
occlum init [--init-ra <grpc_ratls/aecs>]
Initialize a directory as the Occlum instance.
If flag --init-ra specifies, generate initfs with RA KMS client function.
occlum build [--sign-key <key_path>] [--sign-tool <tool_path>] [--image-key <key_path>] [--buildin-image-key] [-f/--force] [--enable-edmm <Y/N>]
Build and sign an Occlum SGX enclave (.so) and generate its associated secure
FS image according to the user-provided image directory and Occlum.json config file.
The whole building process is incremental: the building artifacts are built only
when needed.
To force rebuilding all artifacts, give the [-f/--force] flag.
occlum run <program_name> <program_args>
Run the user program inside an SGX enclave.
occlum package [<package_name>.tar.gz]
Generate a minimal, self-contained package (.tar.gz) for the Occlum instance.
The resulting package can then be copied to a deployment environment and unpacked
as a runnable Occlum instance.
All runtime dependencies required by the Occlum instance---except Intel SGX driver,
enable_rdfsbase kernel module, and Intel SGX PSW---are included in the package.
If package_name is not specified, the directory name of Occlum instance will be used.
In default only HW release mode package is supported. Debug or simulation mode package
could be supported by adding "--debug" flag.
occlum gdb <program_name> <program_args>
Debug the program running inside an SGX enclave with GDB.
occlum mount [--sign-key <key_path>] [--sign-tool <tool_path>] [--image-key <key_path>] <path>
Mount the secure FS image of the Occlum instance as a Linux FS at an existing <path>.
This makes it easy to access and manipulate Occlum's secure FS for debug purpose.
occlum gen-image-key <key_path>
Generate a file consists of a randomly generated 128-bit key for encryption of the FS image.
occlum print mrsigner|mrenclave
Print Occlum instance's mrsigner, mrenclave.
EOF
}
check_has_init() {
if [ ! -f "$status_file" ]; then
echo "Error: the current working directory is not initialized as an Occlum instance. Need to run \"occlum init\" first."
exit 1
fi
}
check_has_built() {
check_has_init
if [ ! -d "$instance_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
}
check_has_run() {
if pgrep --full "$instance_dir/build/bin/occlum-run" > /dev/null ; then
echo "Error: the process of current Occlum instance is running. Need to wait for the process to finish or kill it first."
exit 1
fi
}
check_has_start() {
if pgrep --full "build/bin/occlum_exec_server -d $instance_dir" > /dev/null ; then
echo "Error: the server of current Occlum instance has been started."
exit 1
fi
}
check_has_not_start() {
if ! pgrep --full "build/bin/occlum_exec_server -d $instance_dir" > /dev/null ; then
echo "Error: the server of current Occlum instance has not been started."
exit 1
fi
}
check_aesm_service() {
# Ignore AESM service status for simulation mode
if [ "$(cat $instance_dir/.sgx_mode 2>/dev/null)" != "HW" ]; then
return
fi
# AESM is not necessary for SGX2
lscpu | grep sgx_lc > /dev/null 2>&1 || ret=$?
if [[ $ret -eq 0 ]]; then
return
fi
AESM_SOCKET_FILE=/var/run/aesmd/aesm.socket
for i in $(seq 1 3); do
if [ -S "$AESM_SOCKET_FILE" ]; then
return
else
sleep 5
fi
done
echo "Error: AESM service is not started yet. Need to start it first"
exit 1
}
gen_initfs_aecs()
{
echo "Generate initfs with AECS client"
mkdir -p initfs
mkdir -p initfs/bin
mkdir -p initfs/lib
mkdir -p initfs/dev
mkdir -p initfs/proc
mkdir -p initfs/etc/kubetee
mkdir -p initfs/lib64
mkdir -p initfs/opt/occlum/
# add default timezone file
cp /etc/localtime initfs/etc/
local os_lib_path=${1:-"/usr/lib/x86_64-linux-gnu"}
# add glibc base libraries
# just copy from the image
cp -rf image/opt/occlum/glibc initfs/opt/occlum/
cp -f image/lib64/ld-linux-x86-64.so.2 initfs/lib64/
local occlum_glibc_lib=/opt/occlum/glibc/lib
# add aecs required libs
cp -t initfs/$occlum_glibc_lib \
"$occlum_dir"/toolchains/aecs_client/* \
$os_lib_path/libssl.so.1.1 \
$os_lib_path/libz.so.1 \
$os_lib_path/libcrypto.so.1.1 \
$os_lib_path/libdl.so.2 \
$occlum_glibc_lib/libnss_files.so.2 \
$occlum_glibc_lib/libnss_dns.so.2 \
$occlum_glibc_lib/libresolv.so.2
# add libprotobuf.so.32 if existed
if [ -f $os_lib_path/libprotobuf.so.32 ]; then
cp -t initfs/$occlum_glibc_lib $os_lib_path/libprotobuf.so.32
fi
# add template init_ra_conf
cp "$occlum_dir"/etc/template/init_aecs.json "$instance_dir"/init_ra_conf.json
cp "$occlum_dir"/build/bin/init_aecs initfs/bin/init
cp "$occlum_dir"/etc/template/Occlum.json "$instance_dir"/
}
gen_initfs_grpc_ratls()
{
echo "Generate initfs with GRPC RATLS KMS client"
mkdir -p initfs
mkdir -p initfs/bin
mkdir -p initfs/lib
mkdir -p initfs/dev
mkdir -p initfs/proc
mkdir -p initfs/etc
# add default timezone file
cp /etc/localtime initfs/etc/
# add ssl ca-certificates
mkdir -p initfs/etc/ssl/certs
cp /etc/ssl/certs/ca-certificates.crt initfs/etc/ssl/certs
# add musl
local occlum_musl_lib=/usr/local/occlum/x86_64-linux-musl/lib
cp -t initfs/lib \
/lib/ld-musl-x86_64.so.1 \
"$occlum_musl_lib/libc.so" \
"$occlum_musl_lib/libstdc++.so.6" \
"$occlum_musl_lib/libgcc_s.so.1" \
"$occlum_musl_lib/libgomp.so.1"
# add grpc_ratls required libs
cp -t initfs/lib \
"$occlum_dir"/toolchains/grpc_ratls/musl/libgrpc_ratls_client.so \
"$occlum_dir"/toolchains/grpc_ratls/musl/libhw_grpc_proto.so \
"$occlum_dir"/toolchains/dcap_lib/musl/libocclum_dcap.so.0.1.0 \
"$occlum_dir"/toolchains/gcc/x86_64-linux-musl/lib/libcjson.so.1
# add template init_ra_conf
cp "$occlum_dir"/etc/template/init_grpc_ratls.json "$instance_dir"/init_ra_conf.json
cp "$occlum_dir"/build/bin/init_grpc_ratls initfs/bin/init
cp "$occlum_dir"/etc/template/Occlum.json "$instance_dir"/
}
gen_initfs()
{
mkdir -p initfs
mkdir -p initfs/bin
mkdir -p initfs/lib
mkdir -p initfs/dev
mkdir -p initfs/proc
mkdir -p initfs/etc
# add default /etc/hosts
echo "127.0.0.1 localhost" > initfs/etc/hosts
# add default timezone file
cp /etc/localtime initfs/etc/
# add musl
local occlum_musl_lib=/usr/local/occlum/x86_64-linux-musl/lib
cp -t initfs/lib \
/lib/ld-musl-x86_64.so.1 \
"$occlum_musl_lib/libc.so" \
"$occlum_musl_lib/libstdc++.so.6" \
"$occlum_musl_lib/libgcc_s.so.1" \
"$occlum_musl_lib/libgomp.so.1"
cp "$occlum_dir"/build/bin/init initfs/bin/
cp "$occlum_dir"/etc/template/Occlum.json "$instance_dir"/
}
cmd_new() {
if [ -z $1 ]; then
echo "Error: target directory is not set"
exit 1
fi
dir_path="$1"
if [[ "$dir_path" != "/"* ]]; then
dir_path="$instance_dir/$1"
fi
if [[ -e "$dir_path" ]]; then
echo "Error: destination \"$dir_path\" already exists"
exit 1
fi
mkdir -p $dir_path
instance_dir=$dir_path
status_file=$instance_dir/.__occlum_status
cd $dir_path && cmd_init ${@:2:2}
}
cmd_init() {
if [ -f "$status_file" ]; then
echo "Error: the current working directory has been initialized as an Occlum instance"
exit 1
fi
local init_ra=""
while [ -n "$1" ]; do
case "$1" in
--init-ra) [ -n "$2" ] && init_ra=$2 ; shift 2 || exit_error "Empty init-ra option provided" ;;
*) ;;
esac
done
echo "initialized" > $status_file
cd "$instance_dir"
mkdir -p image
mkdir -p image/bin
mkdir -p image/lib
mkdir -p image/lib64
mkdir -p image/root
mkdir -p image/host
mkdir -p image/tmp
mkdir -p image/dev
mkdir -p image/proc
mkdir -p image/etc
local occlum_glibc_lib=/opt/occlum/glibc/lib
local occlum_glibc_etc=/opt/occlum/glibc/etc
if [ -d "$occlum_glibc_lib" ]; then
mkdir -p "image/$occlum_glibc_lib"
mkdir -p "image/$occlum_glibc_etc"
fi
# add default /etc/hosts
echo "127.0.0.1 localhost" > image/etc/hosts
# add default timezone file
cp /etc/localtime image/etc/
# add musl
local occlum_musl_lib=/usr/local/occlum/x86_64-linux-musl/lib
cp -t image/lib \
/lib/ld-musl-x86_64.so.1 \
"$occlum_musl_lib/libc.so" \
"$occlum_musl_lib/libstdc++.so.6" \
"$occlum_musl_lib/libgcc_s.so.1" \
"$occlum_musl_lib/libgomp.so.1"
# add glibc
local os_lib_path="/usr/lib/x86_64-linux-gnu" # for ubuntu
if [ -d "$occlum_glibc_lib" ]; then
cp -t image/lib64 \
"$occlum_glibc_lib/ld-linux-x86-64.so.2"
ln -sf /lib64/ld-linux-x86-64.so.2 "image/$occlum_glibc_lib/ld-linux-x86-64.so.2"
cp -t "image/$occlum_glibc_lib" \
"$occlum_glibc_lib/libc.so.6" \
"$occlum_glibc_lib/libpthread.so.0" \
"$occlum_glibc_lib/libm.so.6"
local os_release=`awk -F= '/^NAME/{print $2}' /etc/os-release`
if [ "$os_release" != "\"Ubuntu\"" ]; then
os_lib_path="/usr/lib64/" # for openanolis, alios
fi
cp -t "image/$occlum_glibc_lib" \
"${os_lib_path}/libstdc++.so.6" \
"${os_lib_path}/libgcc_s.so.1"
cp -t "image/$occlum_glibc_etc" \
/etc/localtime
fi
if [[ "$init_ra" == "grpc_ratls" ]]; then
gen_initfs_grpc_ratls
elif [[ "$init_ra" == "aecs" ]]; then
gen_initfs_aecs ${os_lib_path}
else
gen_initfs
fi
chmod 644 "$instance_dir"/Occlum.json
echo "$instance_dir initialized as an Occlum instance"
}
cmd_build() {
check_has_init
pal_lib=libocclum-pal.so
libos_lib=libocclum-libos.so
BUILDIN_IMAGE_KEY=false
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=$2 ; shift 2 || exit_error "empty sgx mode";;
--enable-edmm) [[ -n "$2" && "$2" != "N" ]] && export ENABLE_EDMM=Y ; shift 2 || exit_error "empty edmm mode";;
--image-key) [ -n "$2" ] && SECURE_IMAGE_KEY=$2 ; shift 2 || exit_error "empty secure image key path" ;;
--buildin-image-key) BUILDIN_IMAGE_KEY=true ; shift ;;
--force | -f) MAKE_OPTION="clean" ; shift ;;
*) 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"
if [ -n "$SECURE_IMAGE_KEY" ]; then
[ -e "$SECURE_IMAGE_KEY" ] || exit_error "invalid secure image key path: $SECURE_IMAGE_KEY"
fi
echo "Enclave sign-tool: $ENCLAVE_SIGN_TOOL"
echo "Enclave sign-key: $ENCLAVE_SIGN_KEY"
[ -n "$SECURE_IMAGE_KEY" ] && echo "Image encryption key: $SECURE_IMAGE_KEY"
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SGX_SDK/sdk_libs
if [[ "$SGX_MODE" != "HYPER" ]]; then
pal_lib=libocclum-pal_sim.so
libos_lib=libocclum-libos_sim.so
else
pal_lib=libocclum-pal_hyper.so
libos_lib=libocclum-libos_hyper.so
fi
echo "SGX mode: $SGX_MODE"
INSTANCE_IS_FOR_EDMM_PLATFORM="NO"
else
echo "SGX mode: HW"
# ENABLE_EDMM is only valid for HW mode and is not enabled by default
case "$ENABLE_EDMM" in
"Y" | "YES" | "Yes" | "yes" | "True" | "true" | "1")
INSTANCE_IS_FOR_EDMM_PLATFORM="YES"
;;
*)
INSTANCE_IS_FOR_EDMM_PLATFORM="NO"
;;
esac
fi
if [[ -f "$instance_dir/init_ra_conf.json" ]]; then
cp "$instance_dir/init_ra_conf.json" "$instance_dir/initfs/etc/"
fi
# If sgx mode is changed, build thoroughly again
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
if [ "$(cat $instance_dir/.sgx_mode 2>/dev/null)" != "$SGX_MODE" ]; then
MAKE_OPTION="clean"
fi
else
#HW mode
if [ "$(cat $instance_dir/.sgx_mode 2>/dev/null)" != "HW" ]; then
MAKE_OPTION="clean"
fi
fi
rm -rf "$instance_dir/run"
if [[ -n $MAKE_OPTION ]]; then
occlum_dir=$occlum_dir instance_dir=$instance_dir \
make -f $build_makefile $MAKE_OPTION
fi
occlum_dir=$occlum_dir instance_dir=$instance_dir pal_lib=$pal_lib major_ver=$major_ver \
occlum_version=$occlum_version libos_lib=$libos_lib INSTANCE_IS_FOR_EDMM_PLATFORM=$INSTANCE_IS_FOR_EDMM_PLATFORM \
ENCLAVE_SIGN_KEY=$ENCLAVE_SIGN_KEY ENCLAVE_SIGN_TOOL=$ENCLAVE_SIGN_TOOL \
SECURE_IMAGE_KEY=$SECURE_IMAGE_KEY BUILDIN_IMAGE_KEY=$BUILDIN_IMAGE_KEY \
make -f $build_makefile --no-builtin-rules
cd "$instance_dir"
echo "built" > $status_file
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
echo "$SGX_MODE" > .sgx_mode
else
echo "HW" > .sgx_mode
fi
mkdir -p "$instance_dir/run/mount/__ROOT"
mkdir -p "$instance_dir/run/initfs/__ROOT"
echo "Built the Occlum image and enclave successfully"
}
cmd_run() {
check_has_built
check_has_run
check_aesm_service
loop=true
while [ -n "$1" ] && [ "$loop" = "true" ]; do
case "$1" in
--config-id) [ -n "$2" ] && export OCCLUM_CONF_ID_BASE64=$2 ; shift 2 || exit_error "Empty Base64 Encoded Occlum Config ID provided" ;;
--config-svn) [ -n "$2" ] && export OCCLUM_CONF_SVN=$2 ; shift 2 || exit_error "Empty Occlum Config SVN provided" ;;
*) loop=false ;;
esac
done
SGX_MODE=$(cat $instance_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH="$instance_dir/build/lib:$SGX_SDK/sdk_libs/"
else
export LD_LIBRARY_PATH="$instance_dir/build/lib"
fi
echo "running" > $status_file
if [ "`get_enclave_debuggable_flag`" == "false" ]; then
export OCCLUM_RELEASE_ENCLAVE=1
fi
if [ "`get_enclave_enable_kss_flag`" == "true" ]; then
export OCCLUM_ENABLE_KSS=1
fi
RUST_BACKTRACE=1 "$instance_dir/build/bin/occlum-run" "$@"
echo "built" > $status_file
}
cmd_start() {
check_has_built
check_has_start
check_aesm_service
loop=true
while [ -n "$1" ] && [ "$loop" = "true" ]; do
case "$1" in
--config-id) [ -n "$2" ] && export OCCLUM_CONF_ID_BASE64=$2 ; shift 2 || exit_error "Empty Base64 Encoded Occlum Config ID provided" ;;
--config-svn) [ -n "$2" ] && export OCCLUM_CONF_SVN=$2 ; shift 2 || exit_error "Empty Occlum Config SVN provided" ;;
*) loop=false ;;
esac
done
SGX_MODE=$(cat $instance_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH="$instance_dir/build/lib:$SGX_SDK/sdk_libs/"
else
export LD_LIBRARY_PATH="$instance_dir/build/lib"
fi
echo "running" > $status_file
if [ "`get_enclave_debuggable_flag`" == "false" ]; then
export OCCLUM_RELEASE_ENCLAVE=1
fi
if [ "`get_enclave_enable_kss_flag`" == "true" ]; then
export OCCLUM_ENABLE_KSS=1
fi
RUST_BACKTRACE=1 "$instance_dir/build/bin/occlum_exec_client" start
echo "built" > $status_file
}
cmd_exec() {
check_has_built
check_has_not_start
SGX_MODE=$(cat $instance_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH="$instance_dir/build/lib:$SGX_SDK/sdk_libs/"
else
export LD_LIBRARY_PATH="$instance_dir/build/lib"
fi
echo "running" > "$status_file"
RUST_BACKTRACE=1 "$instance_dir/build/bin/occlum_exec_client" exec -- "$@"
echo "built" > "$status_file"
}
cmd_stop() {
check_has_built
check_has_not_start
SGX_MODE=$(cat $instance_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH="$instance_dir/build/lib:$SGX_SDK/sdk_libs/"
else
export LD_LIBRARY_PATH="$instance_dir/build/lib"
fi
echo "running" > "$status_file"
RUST_BACKTRACE=1 "$instance_dir/build/bin/occlum_exec_client" stop -t 0
## Ensure the server is stopped, default timeout is 30s
for i in $(seq 0 30); do
if pgrep --full "build/bin/occlum_exec_server -d $instance_dir" > /dev/null ; then
sleep 1
else
echo "server stopped."
echo "built" > "$status_file"
exit 0
fi
done
echo "Error: timeout to stop the server, let's kill it."
pkill -SIGKILL --full "build/bin/occlum_exec_server -d $instance_dir"
echo "built" > "$status_file"
}
cmd_package() {
check_has_built
debug="false"
instance_base_name=$(basename $instance_dir)
package_name="$instance_base_name.tar.gz"
while [ -n "$1" ]; do
case "$1" in
--debug) debug="true" ; shift ;;
*) package_name=$1 ; shift ;;
esac
done
if [[ "$package_name" != *.tar.gz ]]; then
package_name="$package_name.tar.gz"
fi
if [[ "`get_enclave_debuggable_flag`" == "true" && "$debug" != "true" ]]; then
echo 'Warning: current Occlum instance is configured as "debuggable".'
echo '(If it is not expected, you can modify the Occlum.json "metadata" - "debuggable" field to "false" and build again. And then use "occlum package")'
echo 'Or, use "occlum package --debug" to support debug mode package'
exit 1
fi
SGX_MODE=$(cat $instance_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" == "SIM" && "$debug" != "true" ]]; then
echo '"occlum package" command should only be used for an Occlum instance of SGX hardware mode or hyper mode, not the simulation mode.'
echo 'Please run "occlum build --sgx-mode HW/HYPER" and then use "occlum package"'
echo 'Or, use "occlum package --debug" to support similation mode package'
exit 1
fi
rm -f $package_name
pkg_files="\
$instance_base_name/Occlum.json \
$instance_base_name/build/bin \
$instance_base_name/build/lib/libocclum-libos.signed.so \
$instance_base_name/build/lib/libocclum-pal.so* \
$instance_base_name/build/initfs $instance_base_name/build/mount \
$instance_base_name/build/.Occlum_sys.json.protected \
$instance_base_name/initfs $instance_base_name/run \
$instance_base_name/.__occlum_status $instance_base_name/.sgx_mode \
"
if [[ "$SGX_MODE" == "SIM" ]]; then
extra_files="\
$instance_base_name/build/lib/libocclum-pal_sim.so* \
"
elif [[ "$SGX_MODE" == "HYPER" ]]; then
extra_files="\
$instance_base_name/build/lib/libocclum-pal_hyper.so* \
"
fi
cd .. && tar -cvzf $instance_dir/$package_name \
--transform s/$instance_base_name/$(basename $package_name .tar.gz)/ \
$pkg_files $extra_files
echo "The package $package_name is generated successfully"
}
cmd_gdb() {
check_has_built
SGX_MODE=$(cat $instance_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH="$instance_dir/build/lib:$SGX_SDK/sdk_libs/"
else
export LD_LIBRARY_PATH="$instance_dir/build/lib"
fi
echo "debugging" > "$status_file"
OCCLUM_GDB=1 $SGX_GDB --args "$instance_dir/build/bin/occlum-run" "$@"
echo "built" > "$status_file"
}
cmd_mount() {
check_has_built
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" ;;
--image-key) [ -n "$2" ] && SECURE_IMAGE_KEY=$2 ; shift 2 || exit_error "empty secure image key path" ;;
*) MNT_POINT=$1 ; shift ;;
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"
if [ -n "$SECURE_IMAGE_KEY" ]; then
[ -e "$SECURE_IMAGE_KEY" ] || exit_error "invalid secure image key path: $SECURE_IMAGE_KEY"
fi
[ -d "$MNT_POINT" ] || exit_error "invalid mount point: $MNT_POINT"
echo "Mount tool sign-tool: $ENCLAVE_SIGN_TOOL"
echo "Mount tool sign-key: $ENCLAVE_SIGN_KEY"
[ -n "$SECURE_IMAGE_KEY" ] && echo "Image decryption key: $SECURE_IMAGE_KEY"
echo "Mount point: $MNT_POINT"
SGX_MODE=$(cat $instance_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
if [[ "$SGX_MODE" != "HYPER" ]]; then
sefs_cli="$occlum_dir/build/bin/sefs-cli_sim"
sefs_cli_lib="$occlum_dir/build/lib/libsefs-cli_sim.so"
else
sefs_cli="$occlum_dir/build/bin/sefs-cli_hyper"
sefs_cli_lib="$occlum_dir/build/lib/libsefs-cli_hyper.so"
fi
echo "SGX mode: $SGX_MODE"
else
sefs_cli="$occlum_dir/build/bin/sefs-cli"
sefs_cli_lib="$occlum_dir/build/lib/libsefs-cli.so"
echo "SGX mode: HW"
fi
signed_sefs_cli_lib="$instance_dir/build/lib/libsefs-cli.signed.so"
echo "Signing the mount tool..."
"$ENCLAVE_SIGN_TOOL" sign \
-key "$ENCLAVE_SIGN_KEY" \
-config "$occlum_dir/build/sefs-cli.Enclave.xml" \
-enclave "$sefs_cli_lib" \
-out "$signed_sefs_cli_lib"
image_fs="$instance_dir/build/mount/__ROOT"
if [ -e "$instance_dir/run/mount/__ROOT/metadata" ]; then
container_fs="$instance_dir/run/mount/__ROOT"
else
container_fs=""
fi
[ -n "$SECURE_IMAGE_KEY" ] && SECURE_IMAGE_KEY_OPTION="--key $SECURE_IMAGE_KEY"
echo "Start to mount the FS..."
LD_LIBRARY_PATH="$SGX_SDK/sdk_libs" "$sefs_cli" \
--enclave "$signed_sefs_cli_lib" \
mount \
$SECURE_IMAGE_KEY_OPTION \
"$image_fs" \
"$container_fs" \
"$MNT_POINT"
# After mounting the FS, remove the signed mount tool
rm -f "$signed_sefs_cli_lib"
}
cmd_status() {
cat "$status_file"
}
cmd_gen_image_key() {
if [ -z $@ ]; then
echo "Error: target file is not set"
exit 1
fi
key_path="$@"
if [[ "$key_path" != "/"* ]]; then
key_path="$instance_dir/$@"
fi
cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 32 | head -n 1 | sed -r 's/.{2}/&-/g; s/.$//' > $key_path
}
cmd_print_info() {
if [ -z $1 ]; then
echo "Error: print info name not provided"
exit 1
fi
libos_so="build/lib/libocclum-libos.signed.so"
info="$1"
[ -e "$libos_so" ] || \
exit_error "No $libos_so existed"
if [[ "$info" == "mrenclave" ]]; then
sgx_sign dump -enclave $libos_so -dumpfile dumpfile >/dev/null 2>&1
sed -n -e '/enclave_hash.m/,/metadata->enclave_css.body.isv_prod_id/p' dumpfile \
|head -3|tail -2|xargs|sed 's/0x//g'|sed 's/ //g'
rm dumpfile
elif [[ "$info" == "mrsigner" ]]; then
sgx_sign dump -enclave $libos_so -dumpfile dumpfile >/dev/null 2>&1
tail -2 dumpfile |xargs|sed 's/0x//g'|sed 's/ //g'
rm dumpfile
else
exit_error "No valid info name provided"
fi
}
if [[ ( "$#" < 1 ) ]] ; then
report_arg_error "Error: no sub-command is given"
exit 1
fi
cmd=$1
case "$cmd" in
new)
cmd_new "${@:2}"
;;
init)
cmd_init "${@:2}"
;;
build)
cmd_build "${@:2}"
;;
run)
cmd_run "${@:2}"
;;
start)
cmd_start "${@:2}"
;;
exec)
cmd_exec "${@:2}"
;;
stop)
cmd_stop
;;
package)
cmd_package "${@:2}"
;;
gdb)
cmd_gdb "${@:2}"
;;
mount)
cmd_mount "${@:2}"
;;
status)
cmd_status
;;
gen-image-key)
cmd_gen_image_key "${@:2:1}"
;;
print)
cmd_print_info "${@:2:1}"
;;
*)
report_arg_error "Error: unknown sub-command $cmd"
exit 1
esac