You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@teaclave.apache.org by "GeminiCarrie (via GitHub)" <gi...@apache.org> on 2023/04/04 10:41:05 UTC

[GitHub] [incubator-teaclave] GeminiCarrie opened a new pull request, #685: Integration with Occlum

GeminiCarrie opened a new pull request, #685:
URL: https://github.com/apache/incubator-teaclave/pull/685

   ## Description
   
   This PR provides a way to integrate Teaclave with Occlum.
    
   
   ## Type of change (select or add applied and delete the others)
   
   - [ ] Bug fix (non-breaking change which fixes an issue)
   - [x] New feature (non-breaking change which adds functionality)
   - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
   - [ ] API change with a documentation update
   - [ ] Additional test coverage
   - [ ] Code cleanup or just sync with upstream third-party crates
   
   ## How has this been tested?
   
   ## Checklist
   
   - [x] Fork the repo and create your branch from `master`.
   - [ ] If you've added code that should be tested, add tests.
   - [ ] If you've changed APIs, update the documentation.
   - [x] Ensure the tests pass (see CI results).
   - [x] Make sure your code lints/format.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@teaclave.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@teaclave.apache.org
For additional commands, e-mail: notifications-help@teaclave.apache.org


[GitHub] [incubator-teaclave] henrysun007 commented on a diff in pull request #685: Integration with Occlum

Posted by "henrysun007 (via GitHub)" <gi...@apache.org>.
henrysun007 commented on code in PR #685:
URL: https://github.com/apache/incubator-teaclave/pull/685#discussion_r1159216606


##########
CMakeLists.txt:
##########
@@ -347,3 +347,23 @@ add_cargo_build_dylib_staticlib_target(teaclave_client_sdk
 # ${TEACLAVE_EXAMPLE_INSTALL_DIR}/quickstart_c )
 
 add_enclave_sig_target_n_hooks()
+
+set(LIBOS_EXTRA_CARGO_FLAGS --features "libos")
+set(LIBOS_DEPENDS prep)
+if(EXECUTOR_WAMR)
+    list(APPEND LIBOS_DEPENDS wamr)
+  endif()

Review Comment:
   The spaces before `endif` should be removed to align with `if`.



##########
attestation/src/platform/libos/occlum.rs:
##########
@@ -0,0 +1,152 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use super::super::{PlatformError, Result};
+use libc::*;
+use log::debug;
+use sgx_crypto::ecc::EcPublicKey;
+use sgx_rand::{RdRand, Rng};
+use sgx_types::error::SgxStatus;
+use sgx_types::types::*;
+use std::ffi::CString;
+
+const SGX_CMD_NUM_GEN_EPID_QUOTE: u64 = (2u32

Review Comment:
   Please add comments to mark which code is from occlum source.



##########
services/execution/app/src/main.rs:
##########
@@ -15,14 +15,27 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use anyhow::Result;
-use teaclave_service_app_utils::launch_teaclave_service;
+cfg_if::cfg_if! {
+    if #[cfg(feature = "libos")]  {
 
-// Use to import ocall
-pub use teaclave_file_agent::ocall_handle_file_request;
+        fn main(){
+            env_logger::init();
+            // The Absolute path of runtime.config.toml in occlum instance
+            let config_path = "runtime.config.toml";
+            let config = teaclave_config::RuntimeConfig::from_toml(config_path).expect("Failed to load config file.");
+            if let Err(e) =teaclave_execution_service_enclave::start_service(&config){
+                println!("app will exit, error {:?}",e);

Review Comment:
   Please use log trait.



##########
services/execution/enclave/src/task_file_manager.rs:
##########
@@ -117,7 +120,8 @@ impl InterInput {
         let dst = &self.staged_path;
         let staged_file_info = match self.file.crypto_info {
             FileCrypto::TeaclaveFile128(crypto) => {
-                std::untrusted::fs::soft_link(src, dst)?;
+                #[allow(deprecated)]

Review Comment:
   Better to use feature gating.



##########
services/execution/enclave/Cargo.toml:
##########
@@ -41,12 +41,25 @@ mesalock_sgx = [
   "teaclave_config/build_config",
   "teaclave_worker/mesalock_sgx",
 ]
+libos = [  

Review Comment:
   please sort the features in alphabetical order. 



##########
cmake/scripts/test.sh:
##########
@@ -272,6 +272,53 @@ run_examples() {
   cleanup
 }
 
+run_libos_examples() {
+  trap cleanup INT TERM ERR
+
+  echo_title "libos examples"
+  if [ "${SGX_MODE}" = "HW" ]; then
+      echo "Running LibOS's examples in SGX HW mode is not currently supported."
+      exit
+  fi
+  mkdir -p /tmp/fusion_data
+
+  pushd ${TEACLAVE_SERVICE_INSTALL_DIR}
+  ./teaclave_authentication_service &
+  ./teaclave_storage_service &
+  wait_port 7776 17776 17778 # wait for authentication and storage service
+  ./teaclave_management_service &
+  ./teaclave_scheduler_service &
+  wait_port 17777 17780 # wait for management service and scheduler_service
+  ./teaclave_access_control_service &
+  ./teaclave_frontend_service &
+  wait_port 17779 7777 # wait for other services
+
+  start_storage_server
+
+  pushd ${TEACLAVE_BIN_INSTALL_DIR}
+  cp -rf ${TEACLAVE_SERVICE_INSTALL_DIR}/auditors .
+  cp -f ${TEACLAVE_SERVICE_INSTALL_DIR}/runtime.config.toml .
+  cp -f ${TEACLAVE_SERVICE_INSTALL_DIR}/enclave_info.toml .
+  # Run tests of libos service separately
+  ./teaclave_execution_service_libos &
+
+  pushd ${TEACLAVE_PROJECT_ROOT}/examples/python
+  export PYTHONPATH=${TEACLAVE_PROJECT_ROOT}/sdk/python
+  python3 builtin_echo.py
+  python3 builtin_gbdt_train.py
+  python3 builtin_online_decrypt.py
+  python3 builtin_private_join_and_compute.py
+  python3 builtin_ordered_set_intersect.py
+  python3 builtin_rsa_sign.py
+  python3 builtin_face_detection.py
+  python3 builtin_password_check.py

Review Comment:
   Pleae check wheather the the wasmr can be run in libos.



##########
attestation/src/platform/libos/occlum.rs:
##########
@@ -0,0 +1,152 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use super::super::{PlatformError, Result};
+use libc::*;
+use log::debug;
+use sgx_crypto::ecc::EcPublicKey;
+use sgx_rand::{RdRand, Rng};
+use sgx_types::error::SgxStatus;
+use sgx_types::types::*;
+use std::ffi::CString;
+
+const SGX_CMD_NUM_GEN_EPID_QUOTE: u64 = (2u32
+    | ('s' as u32) << 8
+    | (std::mem::size_of::<IoctlGenEPIDQuoteArg>() as u32) << 16
+    | 3u32 << 30) as u64;
+// for dcap
+const IOCTL_MAX_RETRIES: u32 = 20;
+const SGXIOC_GET_DCAP_QUOTE_SIZE: u64 = 0x80047307;
+const SGXIOC_GEN_DCAP_QUOTE: u64 = 0xc0187308;
+
+#[repr(C)]
+pub struct IoctlGenDCAPQuoteArg {
+    pub report_data: *const ReportData, // Input
+    pub quote_size: *mut u32,           // Input/output
+    pub quote_buf: *mut u8,             // Output
+}
+
+#[repr(C)]
+struct IoctlGenEPIDQuoteArg {
+    report_data: ReportData,   // Input
+    quote_type: QuoteSignType, // Input
+    spid: Spid,                // Input
+    nonce: QuoteNonce,         // Input
+    sigrl_ptr: *const u8,      // Input (optional)
+    sigrl_len: u32,            // Input (optional)
+    quote_buf_len: u32,        // Input
+    quote_buf: *mut u8,        // Output
+}
+
+fn get_dev_fd() -> libc::c_int {
+    let path = CString::new("/dev/sgx").unwrap();
+    let fd = unsafe { libc::open(path.as_ptr(), O_RDONLY) };
+    if fd > 0 {
+        fd
+    } else {
+        panic!("Open /dev/sgx failed")
+    }
+}
+
+/// Create report data.
+pub(crate) fn create_sgx_report_data(pub_k: EcPublicKey) -> ReportData {
+    debug!("create_sgx_report_data");
+    let mut report_data: ReportData = ReportData::default();
+    let mut pub_k_gx = pub_k.public_key().gx;
+    pub_k_gx.reverse();
+    let mut pub_k_gy = pub_k.public_key().gy;
+    pub_k_gy.reverse();
+    report_data.d[..32].clone_from_slice(&pub_k_gx);
+    report_data.d[32..].clone_from_slice(&pub_k_gy);
+    report_data
+}
+
+macro_rules! do_ioctl {
+    ($cmd:expr,$arg:expr) => {
+        let mut retries = 0;
+        let mut ret = -1;
+        let fd = get_dev_fd();
+        log::debug!("begin do_ioctl {}", stringify!($cmd));
+        while retries < IOCTL_MAX_RETRIES {
+            ret = unsafe { libc::ioctl(fd, $cmd, $arg) };
+            if ret == 0 {
+                break;
+                // EBUSY 16
+            }
+            std::thread::sleep(std::time::Duration::from_secs(2));
+            retries += 1;
+        }
+        if retries == IOCTL_MAX_RETRIES {
+            return Err(PlatformError::OCallError(
+                format!("{} error code: {}", stringify!($cmd), ret),
+                SgxStatus::Unexpected,
+            ));
+        }
+    };
+}
+
+/// Get quote with attestation key ID and enclave's local report.
+pub(crate) fn get_sgx_epid_quote(spid: &Spid, report_data: ReportData) -> Result<Vec<u8>> {
+    let sigrl_ptr: *const u8 = std::ptr::null();
+    let quote_len: u32 = 4096;
+    let mut quote = vec![0u8; quote_len as usize];
+    let mut qe_report_info = QeReportInfo::default();
+    let mut quote_nonce = QuoteNonce::default();
+
+    let mut rng = RdRand::new().map_err(PlatformError::SgxRngError)?;
+    rng.fill_bytes(&mut quote_nonce.rand);
+    qe_report_info.nonce = quote_nonce;
+
+    debug!("SGX_CMD_NUM_GEN_EPID_QUOTE");
+    let mut quote_arg = IoctlGenEPIDQuoteArg {
+        report_data,                         // Input
+        quote_type: QuoteSignType::Linkable, // Input
+        spid: spid.to_owned(),               // Input
+        nonce: quote_nonce,                  // Input
+        sigrl_ptr,                           // Input (optional)
+        sigrl_len: 0,                        // Input (optional)
+        quote_buf_len: quote_len,            // Input
+        quote_buf: quote.as_mut_ptr(),       // Output
+    };
+
+    // gen quote and check qe_quote and quote nonce
+    do_ioctl!(SGX_CMD_NUM_GEN_EPID_QUOTE, &mut quote_arg);
+    let sgx_quote = unsafe { &*(quote.as_ptr() as *const Quote) };
+    let quote_size = std::mem::size_of::<Quote>() + sgx_quote.signature_len as usize;
+    if quote_size > quote.len() {
+        return Err(PlatformError::OCallError(

Review Comment:
   It seems appropriate to use `GetQuoteError` for `GEN_EPID_QUOTE`.



##########
cmake/scripts/test.sh:
##########
@@ -272,6 +272,53 @@ run_examples() {
   cleanup
 }
 
+run_libos_examples() {
+  trap cleanup INT TERM ERR
+
+  echo_title "libos examples"
+  if [ "${SGX_MODE}" = "HW" ]; then
+      echo "Running LibOS's examples in SGX HW mode is not currently supported."
+      exit
+  fi
+  mkdir -p /tmp/fusion_data
+
+  pushd ${TEACLAVE_SERVICE_INSTALL_DIR}
+  ./teaclave_authentication_service &
+  ./teaclave_storage_service &
+  wait_port 7776 17776 17778 # wait for authentication and storage service
+  ./teaclave_management_service &
+  ./teaclave_scheduler_service &
+  wait_port 17777 17780 # wait for management service and scheduler_service
+  ./teaclave_access_control_service &
+  ./teaclave_frontend_service &
+  wait_port 17779 7777 # wait for other services
+
+  start_storage_server
+
+  pushd ${TEACLAVE_BIN_INSTALL_DIR}
+  cp -rf ${TEACLAVE_SERVICE_INSTALL_DIR}/auditors .
+  cp -f ${TEACLAVE_SERVICE_INSTALL_DIR}/runtime.config.toml .
+  cp -f ${TEACLAVE_SERVICE_INSTALL_DIR}/enclave_info.toml .
+  # Run tests of libos service separately
+  ./teaclave_execution_service_libos &

Review Comment:
   add wait or sleep to wait for the service to start



##########
attestation/src/platform/mod.rs:
##########
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#[cfg(feature = "libos")]
+pub(crate) mod libos;
+pub(crate) mod sgx;
+#[cfg(all(feature = "libos", feature = "mesalock_sgx"))]
+compile_error!("feature \"mesalock_sgx\" and feature \"libos\" cannot be enabled at the same time");
+
+#[cfg(feature = "libos")]
+pub(crate) use libos::occlum::{create_sgx_report_data, get_sgx_dcap_quote, get_sgx_epid_quote};
+#[cfg(feature = "mesalock_sgx")]
+pub(crate) use sgx::{create_sgx_isv_enclave_report, get_sgx_quote, init_sgx_quote};
+
+use sgx_types::error::SgxStatus;
+
+type Result<T> = std::result::Result<T, PlatformError>;
+
+#[allow(dead_code)]

Review Comment:
   When will the enum not be used? Better to use feature gating than allow dead code.



##########
services/execution/enclave/src/file_handler.rs:
##########
@@ -15,26 +15,41 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use anyhow::ensure;
-use anyhow::Result;
-use sgx_types::error::SgxStatus;
+use anyhow::{ensure, Result};
 use teaclave_types::FileAgentRequest;
 
-extern "C" {
-    fn ocall_handle_file_request(p_retval: *mut u32, in_buf: *const u8, in_len: u32) -> SgxStatus;
-}
+cfg_if::cfg_if! {
+    if #[cfg(feature = "mesalock_sgx")]  {
+        use sgx_types::error::SgxStatus;
+
+        extern "C" {
+            fn ocall_handle_file_request(p_retval: *mut u32, in_buf: *const u8, in_len: u32) -> SgxStatus;
+        }
+
+        pub(crate) fn handle_file_request(request: FileAgentRequest) -> Result<()> {
+            let mut rt: u32 = 2;
+            let bytes = serde_json::to_vec(&request)?;
+            let buf_len = bytes.len();
+            let res =
+                unsafe { ocall_handle_file_request(&mut rt as _, bytes.as_ptr() as _, buf_len as u32) };
+            ensure!(res == SgxStatus::Success, "ocall sgx_error = {:?}", res);
+            ensure!(rt == 0, "ocall error = {:?}", rt);
+            Ok(())
+        }
 
-#[allow(dead_code)]
-pub(crate) fn handle_file_request(request: FileAgentRequest) -> Result<()> {
-    let mut rt: u32 = 2;
-    let bytes = serde_json::to_vec(&request)?;
-    let buf_len = bytes.len();
-    let res =
-        unsafe { ocall_handle_file_request(&mut rt as _, bytes.as_ptr() as _, buf_len as u32) };
+    }else{
 
-    ensure!(res == SgxStatus::Success, "ocall sgx_error = {:?}", res);
-    ensure!(rt == 0, "ocall error = {:?}", rt);
-    Ok(())
+        use teaclave_file_agent::ocall_handle_file_request;

Review Comment:
   `ocall_handle_file_request` is not suitable for an application running in libos.



##########
docs/executing-in-occlum.md:
##########
@@ -0,0 +1,81 @@
+---
+permalink: /docs/executing-in-occlum
+---
+
+# Executing builtin-functions in Occlum
+
+The example shows how to run teaclave builtin-functions in Occlum.
+
+## Requirements
+Firstly, get the official occlum Docker image to build teaclave.

Review Comment:
   Can we build teaclave in teaclave docker image and use the output in occlum image?



##########
services/execution/enclave/src/file_handler.rs:
##########
@@ -15,26 +15,41 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use anyhow::ensure;
-use anyhow::Result;
-use sgx_types::error::SgxStatus;
+use anyhow::{ensure, Result};
 use teaclave_types::FileAgentRequest;
 
-extern "C" {
-    fn ocall_handle_file_request(p_retval: *mut u32, in_buf: *const u8, in_len: u32) -> SgxStatus;
-}
+cfg_if::cfg_if! {
+    if #[cfg(feature = "mesalock_sgx")]  {
+        use sgx_types::error::SgxStatus;
+
+        extern "C" {
+            fn ocall_handle_file_request(p_retval: *mut u32, in_buf: *const u8, in_len: u32) -> SgxStatus;
+        }
+
+        pub(crate) fn handle_file_request(request: FileAgentRequest) -> Result<()> {
+            let mut rt: u32 = 2;
+            let bytes = serde_json::to_vec(&request)?;
+            let buf_len = bytes.len();
+            let res =
+                unsafe { ocall_handle_file_request(&mut rt as _, bytes.as_ptr() as _, buf_len as u32) };
+            ensure!(res == SgxStatus::Success, "ocall sgx_error = {:?}", res);
+            ensure!(rt == 0, "ocall error = {:?}", rt);
+            Ok(())
+        }
 
-#[allow(dead_code)]
-pub(crate) fn handle_file_request(request: FileAgentRequest) -> Result<()> {
-    let mut rt: u32 = 2;
-    let bytes = serde_json::to_vec(&request)?;
-    let buf_len = bytes.len();
-    let res =
-        unsafe { ocall_handle_file_request(&mut rt as _, bytes.as_ptr() as _, buf_len as u32) };
+    }else{

Review Comment:
   `else` should be formated. Something might be missing with the format check.



##########
services/execution/app/src/main.rs:
##########
@@ -15,14 +15,27 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use anyhow::Result;
-use teaclave_service_app_utils::launch_teaclave_service;
+cfg_if::cfg_if! {
+    if #[cfg(feature = "libos")]  {
 
-// Use to import ocall
-pub use teaclave_file_agent::ocall_handle_file_request;
+        fn main(){
+            env_logger::init();
+            // The Absolute path of runtime.config.toml in occlum instance
+            let config_path = "runtime.config.toml";
+            let config = teaclave_config::RuntimeConfig::from_toml(config_path).expect("Failed to load config file.");
+            if let Err(e) =teaclave_execution_service_enclave::start_service(&config){
+                println!("app will exit, error {:?}",e);
+            }
+        }
 
-const PACKAGE_NAME: &str = env!("CARGO_PKG_NAME");
+    } else  {
+        // Use to import ocall
+        pub use teaclave_file_agent::ocall_handle_file_request;
+        const PACKAGE_NAME: &str = env!("CARGO_PKG_NAME");
 
-fn main() -> Result<()> {
-    launch_teaclave_service(PACKAGE_NAME)
+        fn main() ->  anyhow::Result<()> {
+            teaclave_service_app_utils::launch_teaclave_service(PACKAGE_NAME)
+        }
+

Review Comment:
   The blank line can be removed.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@teaclave.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@teaclave.apache.org
For additional commands, e-mail: notifications-help@teaclave.apache.org


[GitHub] [incubator-teaclave] henrysun007 commented on a diff in pull request #685: Integration with Occlum

Posted by "henrysun007 (via GitHub)" <gi...@apache.org>.
henrysun007 commented on code in PR #685:
URL: https://github.com/apache/incubator-teaclave/pull/685#discussion_r1160428276


##########
services/execution/enclave/src/lib.rs:
##########
@@ -84,36 +81,49 @@ fn start_service(config: &RuntimeConfig) -> Result<()> {
     service.start()
 }
 
-#[handle_ecall]
-fn handle_start_service(input: &StartServiceInput) -> TeeServiceResult<StartServiceOutput> {
-    match start_service(&input.config) {
-        Ok(_) => Ok(StartServiceOutput),
-        // terminate the enclave for executor
-        Err(e) => {
-            log::error!("Service shutdown, reason: {}", e);
-            Err(TeeServiceError::EnclaveForceTermination)
+#[cfg(feature = "mesalock_sgx")]
+pub mod handle_ecall {

Review Comment:
   `ecall` or `ecall_handle` seems better here.



##########
docs/executing-in-occlum.md:
##########
@@ -0,0 +1,66 @@
+---
+permalink: /docs/executing-in-occlum
+---
+
+# Executing builtin-functions in Occlum
+
+The example shows how to run teaclave builtin-functions in Occlum.
+
+## Build 
+
+1. Clone the teaclave project.
+
+```
+git clone https://github.com/apache/incubator-teaclave.git ./teaclave && cd ./teaclave
+```
+
+2. Edit the config/build.config.toml and add the executable binary as accepted inbound service of scheduler. The following is an example that uses teaclave_execution_service_libos as the name of binary. 
+
+```
+scheduler      = ["teaclave_execution_service", "teaclave_execution_service_libos"]
+```
+
+Note that the same name should be used in the build.config.toml and enclave_info.toml.
+
+3. Build teaclave project. After building the project, you can find the binary teaclave_execution_service_libos in ${TEACLAVE_BIN_INSTALL_DIR}. Work at teaclave project source directory.
+
+```
+mkdir build && cd build
+cmake ..
+make
+```
+
+4. Build occlum instance. Cmake/scripts/build_occlum_instance.sh is a demo script to build an instance.

Review Comment:
   Better highlight file path like `Cmake/scripts/build_occlum_instance.sh`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@teaclave.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@teaclave.apache.org
For additional commands, e-mail: notifications-help@teaclave.apache.org


[GitHub] [incubator-teaclave] henrysun007 merged pull request #685: Integration with Occlum

Posted by "henrysun007 (via GitHub)" <gi...@apache.org>.
henrysun007 merged PR #685:
URL: https://github.com/apache/incubator-teaclave/pull/685


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@teaclave.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@teaclave.apache.org
For additional commands, e-mail: notifications-help@teaclave.apache.org