830 lines
26 KiB
Bash
Executable File
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
|