| diff --git a/.drone.yml b/.drone.yml |
| index fa2e4c7..19b7350 100644 |
| --- a/.drone.yml |
| +++ b/.drone.yml |
| @@ -12,41 +12,59 @@ |
| # 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. |
| - |
| -x-isgx-1804-image: &isgx-1804-image |
| - image: teaclave/teaclave-build-ubuntu-1804-sgx-2.14:0.1.5 |
| - |
| kind: pipeline |
| -name: sgx-debug-ubuntu-1804 |
| +name: sgx-debug-ubuntu-2004 |
| |
| steps: |
| - name: prepare |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| + environment: |
| + SSH_USERNAME: |
| + from_secret: SSH_USERNAME |
| + SSH_PRIVATE_KEY: |
| + from_secret: SSH_PRIVATE_KEY |
| + SSH_SERVER_IP: |
| + from_secret: SSH_SERVER_IP |
| commands: |
| + - mkdir -p algorithm2_hash_sgx |
| + - echo $SSH_PRIVATE_KEY | base64 -d > id_rsa |
| + - chmod 400 id_rsa |
| + - scp -i id_rsa -oStrictHostKeyChecking=no $SSH_USERNAME@$SSH_SERVER_IP:/xlabfs/ci/cleanroom-workload-devkit-ci-bot/libalgorithm2.a algorithm2_hash_sgx |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| + - echo "127.0.0.1 teaclave-file-service" >> /etc/hosts |
| - mkdir -p build |
| - cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DTEST_MODE=ON .. |
| - name: check |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make check |
| - name: compile |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make VERBOSE=1 -j2 |
| -- name: tvm example |
| - <<: *isgx-1804-image |
| +- name: package-cli |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - - . ~/.cargo/env |
| - - cd examples/python/wasm_tvm_mnist_payload |
| + - . /root/.cargo/env |
| + - . /opt/sgxsdk/environment |
| + - apt update |
| + - apt install -y clang |
| + - pip3 install pyoxidizer |
| + - cd cleanroom-cli |
| - make |
| +# - name: tvm example |
| +# image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| +# commands: |
| +# - . ~/.cargo/env |
| +# - cd examples/python/wasm_tvm_mnist_payload |
| +# - make |
| - name: test |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| environment: |
| AS_ALGO: sgx_epid |
| AS_URL: https://api.trustedservices.intel.com:443 |
| @@ -65,6 +83,8 @@ steps: |
| - . /opt/sgxsdk/environment |
| - (cd release/tool && ./teaclave_sgx_tool status) |
| - (cd release/tool && ./teaclave_sgx_tool attestation --key $AS_KEY --spid $AS_SPID) |
| + - export TEACLAVE_LOG=warn |
| + - echo "127.0.0.1 teaclave-file-service" >> /etc/hosts |
| - cd build && make run-tests |
| |
| volumes: |
| @@ -75,46 +95,65 @@ volumes: |
| host: |
| path: /var/run/aesmd/aesm.socket |
| |
| +trigger: |
| + ref: |
| + exclude: |
| + - refs/tags/cli-** |
| + |
| node: |
| instance: mesatee-sgx |
| |
| ---- |
| |
| -x-dcap-1804-image: &dcap-1804-image |
| - image: teaclave/teaclave-build-ubuntu-1804-sgx-dcap-1.11:0.1.5 |
| +--- |
| |
| kind: pipeline |
| -name: sgx-dcap-debug-ubuntu-1804 |
| +name: sgx-dcap-release-ubuntu-2004 |
| |
| steps: |
| - name: prepare |
| - <<: *dcap-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.1 |
| + environment: |
| + SSH_USERNAME: |
| + from_secret: SSH_USERNAME |
| + SSH_PRIVATE_KEY: |
| + from_secret: SSH_PRIVATE_KEY |
| + SSH_SERVER_IP: |
| + from_secret: SSH_SERVER_IP |
| commands: |
| + - mkdir -p algorithm2_hash_sgx |
| + - echo $SSH_PRIVATE_KEY | base64 -d > id_rsa |
| + - chmod 400 id_rsa |
| + - scp -i id_rsa -oStrictHostKeyChecking=no $SSH_USERNAME@$SSH_SERVER_IP:/xlabfs/ci/cleanroom-workload-devkit-ci-bot/libalgorithm2.a algorithm2_hash_sgx |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| + - echo "127.0.0.1 teaclave-file-service" >> /etc/hosts |
| - mkdir -p build |
| - - cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DTEST_MODE=ON -DDCAP=ON .. |
| + - cd build && cmake -DCMAKE_BUILD_TYPE=Release -DTEST_MODE=ON -DDCAP=ON .. |
| - name: check |
| - <<: *dcap-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make check |
| - name: compile |
| - <<: *dcap-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - sed -i 's/ias_root_ca_cert/dcap_root_ca_cert/' config/build.config.toml |
| - cd build && make VERBOSE=1 -j2 |
| -- name: tvm example |
| - <<: *dcap-1804-image |
| +- name: package-cli |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - - . ~/.cargo/env |
| - - cd examples/python/wasm_tvm_mnist_payload |
| + - . /root/.cargo/env |
| + - . /opt/sgxsdk/environment |
| + - pip3 install pyoxidizer |
| + - apt update |
| + - apt install -y clang |
| + - cd cleanroom-cli |
| - make |
| - name: test |
| - <<: *dcap-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.1 |
| environment: |
| AS_ALGO: sgx_ecdsa |
| AS_URL: https://localhost:8080 |
| @@ -141,6 +180,7 @@ steps: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - (cd release/dcap && ./teaclave_dcap_ref_as &) |
| + - echo "127.0.0.1 teaclave-file-service" >> /etc/hosts |
| - cd build && make run-tests |
| |
| volumes: |
| @@ -163,440 +203,393 @@ volumes: |
| host: |
| path: /etc/sgx_default_qcnl.conf |
| |
| +trigger: |
| + ref: |
| + exclude: |
| + - refs/tags/cli-** |
| + |
| node: |
| instance: mesatee-sgx-dcap |
| |
| ---- |
| |
| -x-isgx-2004-image: &isgx-2004-image |
| - image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.3 |
| +--- |
| |
| kind: pipeline |
| -name: sgx-debug-ubuntu-2004 |
| +name: sgx-dcap-release-tag-publish-ubuntu-2004 |
| |
| steps: |
| - name: prepare |
| - <<: *isgx-2004-image |
| - commands: |
| - - . /root/.cargo/env |
| - - . /opt/sgxsdk/environment |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.1 |
| + environment: |
| + SSH_USERNAME: |
| + from_secret: SSH_USERNAME |
| + SSH_PRIVATE_KEY: |
| + from_secret: SSH_PRIVATE_KEY |
| + SSH_SERVER_IP: |
| + from_secret: SSH_SERVER_IP |
| + DCAP_ROOT_CA_CERT: |
| + from_secret: DCAP_ROOT_CA_CERT |
| + DCAP_SERVER_CERT: |
| + from_secret: DCAP_SERVER_CERT |
| + DCAP_SERVER_KEY: |
| + from_secret: DCAP_SERVER_KEY |
| + commands: |
| + - mkdir -p algorithm2_hash_sgx |
| + - echo $SSH_PRIVATE_KEY | base64 -d > id_rsa |
| + - echo $DCAP_ROOT_CA_CERT | base64 -d > keys/dcap_root_ca_cert.pem |
| + - echo $DCAP_SERVER_CERT | base64 -d > keys/dcap_server_cert.pem |
| + - echo $DCAP_SERVER_KEY | base64 -d > keys/dcap_server_key.pem |
| + - chmod 400 id_rsa |
| + - scp -i id_rsa -oStrictHostKeyChecking=no $SSH_USERNAME@$SSH_SERVER_IP:/xlabfs/ci/cleanroom-workload-devkit-ci-bot/libalgorithm2.a algorithm2_hash_sgx |
| + - . /root/.cargo/env |
| + - . /opt/sgxsdk/environment |
| + - echo "127.0.0.1 teaclave-file-service" >> /etc/hosts |
| - mkdir -p build |
| - - cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DTEST_MODE=ON .. |
| + - cd build && cmake -DCMAKE_BUILD_TYPE=Release -DTEST_MODE=OFF -DDCAP=ON .. |
| - name: check |
| - <<: *isgx-2004-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make check |
| - name: compile |
| - <<: *isgx-2004-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| + - sed -i 's/ias_root_ca_cert/dcap_root_ca_cert/' config/build.config.toml |
| - cd build && make VERBOSE=1 -j2 |
| -- name: tvm example |
| - <<: *isgx-2004-image |
| - commands: |
| - - . ~/.cargo/env |
| - - cd examples/python/wasm_tvm_mnist_payload |
| - - make |
| -- name: test |
| - <<: *isgx-2004-image |
| +- name: publish |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.1 |
| environment: |
| - AS_ALGO: sgx_epid |
| - AS_URL: https://api.trustedservices.intel.com:443 |
| - AS_KEY: |
| - from_secret: V5_KEY |
| - AS_SPID: |
| - from_secret: V5_SPID |
| - privileged: true |
| - volumes: |
| - - name: isgx |
| - path: /dev/isgx |
| - - name: aesmd |
| - path: /var/run/aesmd/aesm.socket |
| - commands: |
| - - . /root/.cargo/env |
| - - . /opt/sgxsdk/environment |
| - - (cd release/tool && ./teaclave_sgx_tool status) |
| - - (cd release/tool && ./teaclave_sgx_tool attestation --key $AS_KEY --spid $AS_SPID) |
| - - cd build && make run-tests |
| + SSH_USERNAME: |
| + from_secret: SSH_USERNAME |
| + SSH_PRIVATE_KEY: |
| + from_secret: SSH_PRIVATE_KEY |
| + SSH_SERVER_IP: |
| + from_secret: SSH_SERVER_IP |
| + PUBLISH_DIR: |
| + from_secret: PUBLISH_DIR |
| + commands: |
| + - release_id=${DRONE_TAG}_$(git rev-parse --short HEAD) |
| + - out_service="dcap_service_release_$release_id" |
| + - mkdir $out_service |
| + - cp -r ./release $out_service/release |
| + - cp -r ./dcap_deployment/docker $out_service/docker |
| + - cp -r ./monitoring/prometheus.py $out_service |
| + |
| + - out_sdk="dcap_sdk_release_$release_id" |
| + - mkdir $out_sdk |
| + - cp -r ./sdk/python $out_sdk/python |
| + - cp ./release/services/enclave_info.toml $out_sdk/enclave_info.toml |
| + - cp ./release/cli/teaclave_cli $out_sdk/teaclave_cli |
| + - cp ./keys/dcap_root_ca_cert.pem $out_sdk/dcap_root_cert.pem |
| + |
| + - tar czvf $out_sdk.tgz $out_sdk |
| + - tar czvf $out_service.tgz $out_service |
| + - scp -i id_rsa -oStrictHostKeyChecking=no $out_sdk.tgz $SSH_USERNAME@$SSH_SERVER_IP:$PUBLISH_DIR |
| + - scp -i id_rsa -oStrictHostKeyChecking=no $out_service.tgz $SSH_USERNAME@$SSH_SERVER_IP:$PUBLISH_DIR |
| |
| -volumes: |
| -- name: isgx |
| - host: |
| - path: /dev/isgx |
| -- name: aesmd |
| - host: |
| - path: /var/run/aesmd/aesm.socket |
| + |
| +trigger: |
| + ref: |
| + include: |
| + - refs/tags/service-** |
| + |
| +depends_on: |
| + - sgx-dcap-release-ubuntu-2004 |
| |
| node: |
| instance: mesatee-sgx |
| |
| --- |
| |
| -x-dcap-2004-image: &dcap-2004-image |
| - image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.3 |
| - |
| kind: pipeline |
| -name: sgx-dcap-debug-ubuntu-2004 |
| +name: sgx-release-ubuntu-2004 |
| |
| steps: |
| - name: prepare |
| - <<: *dcap-2004-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| + environment: |
| + SSH_USERNAME: |
| + from_secret: SSH_USERNAME |
| + SSH_PRIVATE_KEY: |
| + from_secret: SSH_PRIVATE_KEY |
| + SSH_SERVER_IP: |
| + from_secret: SSH_SERVER_IP |
| commands: |
| + - mkdir -p algorithm2_hash_sgx |
| + - echo $SSH_PRIVATE_KEY | base64 -d > id_rsa |
| + - chmod 400 id_rsa |
| + - scp -i id_rsa -oStrictHostKeyChecking=no $SSH_USERNAME@$SSH_SERVER_IP:/xlabfs/ci/cleanroom-workload-devkit-ci-bot/libalgorithm2.a algorithm2_hash_sgx |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| + - echo "127.0.0.1 teaclave-file-service" >> /etc/hosts |
| - mkdir -p build |
| - - cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DTEST_MODE=ON -DDCAP=ON .. |
| + - cd build && cmake -DCMAKE_BUILD_TYPE=Release -DTEST_MODE=OFF .. |
| - name: check |
| - <<: *dcap-2004-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make check |
| - name: compile |
| - <<: *dcap-2004-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - - sed -i 's/ias_root_ca_cert/dcap_root_ca_cert/' config/build.config.toml |
| - cd build && make VERBOSE=1 -j2 |
| -- name: tvm example |
| - image: teaclave/teaclave-build-ubuntu-1804-sgx-2.14:0.1.5 |
| +- name: package-cli |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - - . ~/.cargo/env |
| - - cd examples/python/wasm_tvm_mnist_payload |
| - - make |
| -- name: test |
| - <<: *dcap-2004-image |
| - environment: |
| - AS_ALGO: sgx_ecdsa |
| - AS_URL: https://localhost:8080 |
| - AS_KEY: |
| - from_secret: V5_KEY |
| - AS_SPID: |
| - from_secret: V5_SPID |
| - privileged: true |
| - volumes: |
| - - name: sgx |
| - path: /dev/sgx |
| - - name: sgx_enclave |
| - path: /dev/sgx_enclave |
| - - name: sgx_provision |
| - path: /dev/sgx_provision |
| - - name: aesmd |
| - path: /var/run/aesmd/aesm.socket |
| - - name: aesmd-conf |
| - path: /etc/aesmd.conf |
| - - name: qcnl |
| - path: /etc/sgx_default_qcnl.conf |
| - commands: |
| - - echo "$(ip route | awk 'NR==1 {print $3}') pccs-server" >> /etc/hosts |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - - (cd release/dcap && ./teaclave_dcap_ref_as &) |
| - - cd build && make run-tests |
| - |
| -volumes: |
| -- name: sgx |
| - host: |
| - path: /dev/sgx |
| -- name: sgx_enclave |
| - host: |
| - path: /dev/sgx_enclave |
| -- name: sgx_provision |
| - host: |
| - path: /dev/sgx_provision |
| -- name: aesmd |
| - host: |
| - path: /var/run/aesmd/aesm.socket |
| -- name: aesmd-conf |
| - host: |
| - path: /etc/aesmd.conf |
| -- name: qcnl |
| - host: |
| - path: /etc/sgx_default_qcnl.conf |
| - |
| -node: |
| - instance: mesatee-sgx-dcap |
| - |
| ---- |
| - |
| -x-dcap-2004-image: &dcap-2004-image |
| - image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.3 |
| - |
| -kind: pipeline |
| -name: sgx-dcap-coverage-ubuntu-2004 |
| - |
| -steps: |
| -- name: prepare |
| - <<: *dcap-2004-image |
| - commands: |
| - - . /root/.cargo/env |
| - - . /opt/sgxsdk/environment |
| - - mkdir -p build |
| - - cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DTEST_MODE=ON -DDCAP=ON -DCOV=ON .. |
| -- name: check |
| - <<: *dcap-2004-image |
| - commands: |
| - - . /root/.cargo/env |
| - - . /opt/sgxsdk/environment |
| - - cd build && make check |
| -- name: compile |
| - <<: *dcap-2004-image |
| - commands: |
| - - . /root/.cargo/env |
| - - . /opt/sgxsdk/environment |
| - - sed -i 's/ias_root_ca_cert/dcap_root_ca_cert/' config/build.config.toml |
| - - cd build && make VERBOSE=1 -j2 |
| -- name: tvm example |
| - image: teaclave/teaclave-build-ubuntu-1804-sgx-2.14:0.1.5 |
| - commands: |
| - - . ~/.cargo/env |
| - - cd examples/python/wasm_tvm_mnist_payload |
| + - pip3 install pyoxidizer |
| + - apt update |
| + - apt install -y clang |
| + - cd cleanroom-cli |
| - make |
| +# - name: tvm example |
| +# image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| +# commands: |
| +# - . ~/.cargo/env |
| +# - cd examples/python/wasm_tvm_mnist_payload |
| +# - make |
| - name: test |
| - <<: *dcap-2004-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| + privileged: true |
| environment: |
| - AS_ALGO: sgx_ecdsa |
| - AS_URL: https://localhost:8080 |
| + AS_ALGO: sgx_epid |
| + AS_URL: https://api.trustedservices.intel.com:443 |
| AS_KEY: |
| from_secret: V5_KEY |
| AS_SPID: |
| from_secret: V5_SPID |
| - privileged: true |
| volumes: |
| - - name: sgx |
| - path: /dev/sgx |
| - - name: sgx_enclave |
| - path: /dev/sgx_enclave |
| - - name: sgx_provision |
| - path: /dev/sgx_provision |
| + - name: isgx |
| + path: /dev/isgx |
| - name: aesmd |
| path: /var/run/aesmd/aesm.socket |
| - - name: aesmd-conf |
| - path: /etc/aesmd.conf |
| - - name: qcnl |
| - path: /etc/sgx_default_qcnl.conf |
| commands: |
| - - echo "$(ip route | awk 'NR==1 {print $3}') pccs-server" >> /etc/hosts |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - - (cd release/dcap && ./teaclave_dcap_ref_as &) |
| - - cd build && make run-tests && make cov |
| + - cd build && make run-examples |
| |
| volumes: |
| -- name: sgx |
| - host: |
| - path: /dev/sgx |
| -- name: sgx_enclave |
| - host: |
| - path: /dev/sgx_enclave |
| -- name: sgx_provision |
| +- name: isgx |
| host: |
| - path: /dev/sgx_provision |
| + path: /dev/isgx |
| - name: aesmd |
| host: |
| path: /var/run/aesmd/aesm.socket |
| -- name: aesmd-conf |
| - host: |
| - path: /etc/aesmd.conf |
| -- name: qcnl |
| - host: |
| - path: /etc/sgx_default_qcnl.conf |
| + |
| +trigger: |
| + ref: |
| + exclude: |
| + - refs/tags/cli-** |
| |
| node: |
| - instance: mesatee-sgx-dcap |
| ---- |
| + instance: mesatee-sgx |
| |
| -x-dcap-2004-image: &dcap-2004-image |
| - image: teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.3 |
| +--- |
| |
| kind: pipeline |
| -name: sgx-dcap-release-ubuntu-2004 |
| +name: sim-debug-ubuntu-2004 |
| |
| steps: |
| - name: prepare |
| - <<: *dcap-2004-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| + environment: |
| + SSH_USERNAME: |
| + from_secret: SSH_USERNAME |
| + SSH_PRIVATE_KEY: |
| + from_secret: SSH_PRIVATE_KEY |
| + SSH_SERVER_IP: |
| + from_secret: SSH_SERVER_IP |
| commands: |
| + - mkdir -p algorithm2_hash_sgx |
| + - echo $SSH_PRIVATE_KEY | base64 -d > id_rsa |
| + - chmod 400 id_rsa |
| + - scp -i id_rsa -oStrictHostKeyChecking=no $SSH_USERNAME@$SSH_SERVER_IP:/xlabfs/ci/cleanroom-workload-devkit-ci-bot/libalgorithm2.a algorithm2_hash_sgx |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| + - echo "127.0.0.1 teaclave-file-service" >> /etc/hosts |
| - mkdir -p build |
| - - cd build && cmake -DCMAKE_BUILD_TYPE=Release -DTEST_MODE=OFF -DDCAP=ON .. |
| + - cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DSGX_SIM_MODE=ON -DTEST_MODE=ON .. |
| - name: check |
| - <<: *dcap-2004-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make check |
| - name: compile |
| - <<: *dcap-2004-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - - sed -i 's/ias_root_ca_cert/dcap_root_ca_cert/' config/build.config.toml |
| - cd build && make VERBOSE=1 -j2 |
| -- name: tvm example |
| - <<: *dcap-2004-image |
| - commands: |
| - - . ~/.cargo/env |
| - - cd examples/python/wasm_tvm_mnist_payload |
| - - make |
| +- name: package-cli |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| + commands: |
| + - . /root/.cargo/env |
| + - . /opt/sgxsdk/environment |
| + - pip3 install pyoxidizer |
| + - apt update |
| + - apt install -y clang |
| + - cd cleanroom-cli |
| + - make |
| +# - name: tvm example |
| +# image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| +# commands: |
| +# - . ~/.cargo/env |
| +# - cd examples/python/wasm_tvm_mnist_payload |
| +# - make |
| - name: test |
| - <<: *dcap-2004-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| environment: |
| - AS_ALGO: sgx_ecdsa |
| - AS_URL: https://localhost:8080 |
| + AS_ALGO: sgx_epid |
| + AS_URL: https://api.trustedservices.intel.com:443 |
| AS_KEY: |
| from_secret: V5_KEY |
| AS_SPID: |
| from_secret: V5_SPID |
| - privileged: true |
| - volumes: |
| - - name: sgx |
| - path: /dev/sgx |
| - - name: sgx_enclave |
| - path: /dev/sgx_enclave |
| - - name: sgx_provision |
| - path: /dev/sgx_provision |
| - - name: aesmd |
| - path: /var/run/aesmd/aesm.socket |
| - - name: aesmd-conf |
| - path: /etc/aesmd.conf |
| - - name: qcnl |
| - path: /etc/sgx_default_qcnl.conf |
| commands: |
| - - echo "$(ip route | awk 'NR==1 {print $3}') pccs-server" >> /etc/hosts |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - - (cd release/dcap && ./teaclave_dcap_ref_as &) |
| - - cd build && make run-examples |
| + - echo "127.0.0.1 teaclave-file-service" >> /etc/hosts |
| + - cd build && make run-tests |
| |
| -volumes: |
| -- name: sgx |
| - host: |
| - path: /dev/sgx |
| -- name: sgx_enclave |
| - host: |
| - path: /dev/sgx_enclave |
| -- name: sgx_provision |
| - host: |
| - path: /dev/sgx_provision |
| -- name: aesmd |
| - host: |
| - path: /var/run/aesmd/aesm.socket |
| -- name: aesmd-conf |
| - host: |
| - path: /etc/aesmd.conf |
| -- name: qcnl |
| - host: |
| - path: /etc/sgx_default_qcnl.conf |
| +trigger: |
| + ref: |
| + exclude: |
| + - refs/tags/cli-** |
| |
| node: |
| - instance: mesatee-sgx-dcap |
| + instance: mesatee-sgx |
| |
| --- |
| |
| -x-isgx-1804-image: &isgx-1804-image |
| - image: teaclave/teaclave-build-ubuntu-1804-sgx-2.14:0.1.5 |
| - |
| kind: pipeline |
| -name: sgx-release-ubuntu-1804 |
| +name: sim-release-ubuntu-2004 |
| |
| steps: |
| - name: prepare |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| + environment: |
| + SSH_USERNAME: |
| + from_secret: SSH_USERNAME |
| + SSH_PRIVATE_KEY: |
| + from_secret: SSH_PRIVATE_KEY |
| + SSH_SERVER_IP: |
| + from_secret: SSH_SERVER_IP |
| commands: |
| + - mkdir -p algorithm2_hash_sgx |
| + - echo $SSH_PRIVATE_KEY | base64 -d > id_rsa |
| + - chmod 400 id_rsa |
| + - scp -i id_rsa -oStrictHostKeyChecking=no $SSH_USERNAME@$SSH_SERVER_IP:/xlabfs/ci/cleanroom-workload-devkit-ci-bot/libalgorithm2.a algorithm2_hash_sgx |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| + - echo "127.0.0.1 teaclave-file-service" >> /etc/hosts |
| - mkdir -p build |
| - - cd build && cmake -DCMAKE_BUILD_TYPE=Release -DTEST_MODE=OFF .. |
| + - cd build && cmake -DCMAKE_BUILD_TYPE=Release -DSGX_SIM_MODE=ON -DTEST_MODE=OFF .. |
| - name: check |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make check |
| - name: compile |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make VERBOSE=1 -j2 |
| -- name: tvm example |
| - <<: *isgx-1804-image |
| +- name: package-cli |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - - . ~/.cargo/env |
| - - cd examples/python/wasm_tvm_mnist_payload |
| + - . /root/.cargo/env |
| + - . /opt/sgxsdk/environment |
| + - pip3 install pyoxidizer |
| + - apt update |
| + - apt install -y clang |
| + - cd cleanroom-cli |
| - make |
| +# - name: tvm example |
| +# image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| +# commands: |
| +# - . ~/.cargo/env |
| +# - cd examples/python/wasm_tvm_mnist_payload |
| +# - make |
| - name: test |
| - <<: *isgx-1804-image |
| - privileged: true |
| - environment: |
| - AS_ALGO: sgx_epid |
| - AS_URL: https://api.trustedservices.intel.com:443 |
| - AS_KEY: |
| - from_secret: V5_KEY |
| - AS_SPID: |
| - from_secret: V5_SPID |
| - volumes: |
| - - name: isgx |
| - path: /dev/isgx |
| - - name: aesmd |
| - path: /var/run/aesmd/aesm.socket |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make run-examples |
| |
| -volumes: |
| -- name: isgx |
| - host: |
| - path: /dev/isgx |
| -- name: aesmd |
| - host: |
| - path: /var/run/aesmd/aesm.socket |
| +trigger: |
| + ref: |
| + exclude: |
| + - refs/tags/cli-** |
| |
| node: |
| instance: mesatee-sgx |
| |
| --- |
| |
| -x-isgx-1804-image: &isgx-1804-image |
| - image: teaclave/teaclave-build-ubuntu-1804-sgx-2.14:0.1.5 |
| - |
| kind: pipeline |
| -name: sim-debug-ubuntu-1804 |
| +name: sim-debug-ubuntu-2004-test-log |
| |
| steps: |
| - name: prepare |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| + environment: |
| + SSH_USERNAME: |
| + from_secret: SSH_USERNAME |
| + SSH_PRIVATE_KEY: |
| + from_secret: SSH_PRIVATE_KEY |
| + SSH_SERVER_IP: |
| + from_secret: SSH_SERVER_IP |
| commands: |
| + - mkdir -p algorithm2_hash_sgx |
| + - echo $SSH_PRIVATE_KEY | base64 -d > id_rsa |
| + - chmod 400 id_rsa |
| + - scp -i id_rsa -oStrictHostKeyChecking=no $SSH_USERNAME@$SSH_SERVER_IP:/xlabfs/ci/cleanroom-workload-devkit-ci-bot/libalgorithm2.a algorithm2_hash_sgx |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| + - echo "127.0.0.1 teaclave-file-service" >> /etc/hosts |
| - mkdir -p build |
| - cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DSGX_SIM_MODE=ON -DTEST_MODE=ON .. |
| - name: check |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make check |
| - name: compile |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make VERBOSE=1 -j2 |
| -- name: tvm example |
| - <<: *isgx-1804-image |
| +- name: package-cli |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - - . ~/.cargo/env |
| - - cd examples/python/wasm_tvm_mnist_payload |
| + - . /root/.cargo/env |
| + - . /opt/sgxsdk/environment |
| + - pip3 install pyoxidizer |
| + - apt update |
| + - apt install -y clang |
| + - cd cleanroom-cli |
| - make |
| +# - name: tvm example |
| +# image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| +# commands: |
| +# - . ~/.cargo/env |
| +# - cd examples/python/wasm_tvm_mnist_payload |
| +# - make |
| - name: test |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| environment: |
| AS_ALGO: sgx_epid |
| AS_URL: https://api.trustedservices.intel.com:443 |
| @@ -607,84 +600,59 @@ steps: |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - - cd build && make run-tests |
| - |
| -node: |
| - instance: mesatee-sgx |
| - |
| ---- |
| + - cd build |
| + - export TEACLAVE_LOG=warn && make run-examples |
| |
| -x-isgx-1804-image: &isgx-1804-image |
| - image: teaclave/teaclave-build-ubuntu-1804-sgx-2.14:0.1.5 |
| - |
| -kind: pipeline |
| -name: sim-release-ubuntu-1804 |
| - |
| -steps: |
| -- name: prepare |
| - <<: *isgx-1804-image |
| - commands: |
| - - . /root/.cargo/env |
| - - . /opt/sgxsdk/environment |
| - - mkdir -p build |
| - - cd build && cmake -DCMAKE_BUILD_TYPE=Release -DSGX_SIM_MODE=ON -DTEST_MODE=OFF .. |
| -- name: check |
| - <<: *isgx-1804-image |
| - commands: |
| - - . /root/.cargo/env |
| - - . /opt/sgxsdk/environment |
| - - cd build && make check |
| -- name: compile |
| - <<: *isgx-1804-image |
| - commands: |
| - - . /root/.cargo/env |
| - - . /opt/sgxsdk/environment |
| - - cd build && make VERBOSE=1 -j2 |
| -- name: tvm example |
| - <<: *isgx-1804-image |
| - commands: |
| - - . ~/.cargo/env |
| - - cd examples/python/wasm_tvm_mnist_payload |
| - - make |
| -- name: test |
| - <<: *isgx-1804-image |
| - commands: |
| - - . /root/.cargo/env |
| - - . /opt/sgxsdk/environment |
| - - cd build && make run-examples |
| +trigger: |
| + ref: |
| + exclude: |
| + - refs/tags/cli-** |
| |
| node: |
| instance: mesatee-sgx |
| |
| --- |
| |
| -x-isgx-1804-image: &isgx-1804-image |
| - image: teaclave/teaclave-build-ubuntu-1804-sgx-2.14:0.1.5 |
| - |
| kind: pipeline |
| name: lint |
| |
| steps: |
| - name: prepare |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| + environment: |
| + SSH_USERNAME: |
| + from_secret: SSH_USERNAME |
| + SSH_PRIVATE_KEY: |
| + from_secret: SSH_PRIVATE_KEY |
| + SSH_SERVER_IP: |
| + from_secret: SSH_SERVER_IP |
| commands: |
| + - mkdir -p algorithm2_hash_sgx |
| + - echo $SSH_PRIVATE_KEY | base64 -d > id_rsa |
| + - chmod 400 id_rsa |
| + - scp -i id_rsa -oStrictHostKeyChecking=no $SSH_USERNAME@$SSH_SERVER_IP:/xlabfs/ci/cleanroom-workload-devkit-ci-bot/libalgorithm2.a algorithm2_hash_sgx |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - mkdir -p build |
| - cd build && cmake -DRUSTFLAGS="-D warnings" -DTEST_MODE=ON .. |
| - name: check |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make check |
| - name: clippy |
| - <<: *isgx-1804-image |
| + image: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.1 |
| commands: |
| - . /root/.cargo/env |
| - . /opt/sgxsdk/environment |
| - cd build && make CLP=1 |
| |
| +trigger: |
| + ref: |
| + exclude: |
| + - refs/tags/cli-** |
| + |
| node: |
| instance: mesatee-sgx |
| |
| @@ -723,15 +691,17 @@ trigger: |
| - hourly |
| |
| depends_on: |
| - - sgx-debug-ubuntu-1804 |
| - - sgx-dcap-debug-ubuntu-1804 |
| - sgx-debug-ubuntu-2004 |
| - - sgx-dcap-debug-ubuntu-2004 |
| - - sgx-dcap-coverage-ubuntu-2004 |
| - - sgx-release-ubuntu-1804 |
| - - sim-debug-ubuntu-1804 |
| - - sim-release-ubuntu-1804 |
| + - sgx-dcap-release-ubuntu-2004 |
| + - sgx-release-ubuntu-2004 |
| + - sim-debug-ubuntu-2004 |
| + - sim-release-ubuntu-2004 |
| - lint |
| |
| +trigger: |
| + ref: |
| + exclude: |
| + - refs/tags/cli-** |
| + |
| node: |
| - instance: mesatee-sgx |
| + instance: mesatee-sgx |
| \ No newline at end of file |
| diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml |
| deleted file mode 100644 |
| index 2ca637a..0000000 |
| --- a/.github/workflows/ci.yml |
| +++ /dev/null |
| @@ -1,170 +0,0 @@ |
| -# 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. |
| - |
| -name: CI |
| -on: [push, pull_request] |
| -defaults: |
| - run: |
| - shell: bash |
| - |
| -jobs: |
| - teaclave-client-sdk-macos: |
| - runs-on: macos-latest |
| - steps: |
| - - uses: actions/checkout@v2 |
| - with: |
| - submodules: 'true' |
| - - name: Install dependencies |
| - run: | |
| - brew install cmake openssl@1.1 |
| - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y |
| - export PATH=~/.cargo/bin:$PATH |
| - rustup default nightly-2020-10-25 && rustup target add aarch64-apple-ios x86_64-apple-ios |
| - - name: Building Teaclave Client SDK |
| - run: | |
| - export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig:/usr/local/opt/libssh2/lib/pkgconfig/" |
| - export PATH=~/.cargo/bin:$PATH |
| - cargo +stable install cargo-lipo |
| - cargo build --manifest-path sdk/rust/Cargo.toml |
| - cargo build --manifest-path sdk/rust/Cargo.toml --target aarch64-apple-ios |
| - cargo lipo --manifest-path sdk/rust/Cargo.toml |
| - cd sdk/swift/TeaclaveClientSDK && xcodebuild -scheme TeaclaveClientSDK |
| - sim-debug-ubuntu-1804: |
| - runs-on: ubuntu-18.04 |
| - container: teaclave/teaclave-build-ubuntu-1804-sgx-2.14:0.1.5 |
| - steps: |
| - - uses: actions/checkout@v2 |
| - - name: Setting up $HOME |
| - run: | |
| - cp /root/.bashrc $HOME/.bashrc && |
| - ln -sf /root/.rustup ~/.rustup && |
| - ln -sf /root/.cargo ~/.cargo |
| - - name: Preparing build system |
| - run: | |
| - . ~/.cargo/env && |
| - . /opt/sgxsdk/environment && |
| - mkdir -p build && |
| - cd build && |
| - cmake -DCMAKE_BUILD_TYPE=Debug -DSGX_SIM_MODE=ON -DTEST_MODE=ON .. |
| - - name: Building |
| - run: | |
| - . /opt/sgxsdk/environment && |
| - . ~/.cargo/env && |
| - cd build && |
| - make VERBOSE=1 |
| - - name: Build TVM example |
| - run: | |
| - . ~/.cargo/env && |
| - cd ${GITHUB_WORKSPACE}/examples/python/wasm_tvm_mnist_payload && |
| - make |
| - - name: Run tests and examples |
| - run: | |
| - export AS_SPID="00000000000000000000000000000000" && |
| - export AS_KEY="00000000000000000000000000000000" && |
| - export AS_ALGO="sgx_epid" && |
| - export AS_URL="https://api.trustedservices.intel.com:443" && |
| - . ~/.cargo/env && |
| - cd build && |
| - make run-tests |
| - |
| - sim-debug-ubuntu-2004: |
| - runs-on: ubuntu-20.04 |
| - container: teaclave/teaclave-build-ubuntu-2004-sgx-2.15.1:0.1.3 |
| - steps: |
| - - uses: actions/checkout@v2 |
| - - name: Setting up $HOME |
| - run: | |
| - cp /root/.bashrc $HOME/.bashrc && |
| - ln -sf /root/.rustup ~/.rustup && |
| - ln -sf /root/.cargo ~/.cargo |
| - - name: Preparing build system |
| - run: | |
| - . ~/.cargo/env && |
| - . /opt/sgxsdk/environment && |
| - mkdir -p build && |
| - cd build && |
| - cmake -DCMAKE_BUILD_TYPE=Debug -DSGX_SIM_MODE=ON -DTEST_MODE=ON .. |
| - - name: Building |
| - run: | |
| - . /opt/sgxsdk/environment && |
| - . ~/.cargo/env && |
| - cd build && |
| - make VERBOSE=1 |
| - - name: Build TVM example |
| - run: | |
| - . ~/.cargo/env && |
| - cd ${GITHUB_WORKSPACE}/examples/python/wasm_tvm_mnist_payload && |
| - make |
| - - name: Run tests and examples |
| - run: | |
| - export AS_SPID="00000000000000000000000000000000" && |
| - export AS_KEY="00000000000000000000000000000000" && |
| - export AS_ALGO="sgx_epid" && |
| - export AS_URL="https://api.trustedservices.intel.com:443" && |
| - . ~/.cargo/env && |
| - cd build && |
| - make run-tests |
| - |
| - format: |
| - runs-on: ubuntu-18.04 |
| - container: teaclave/teaclave-build-ubuntu-1804-sgx-2.14:0.1.5 |
| - steps: |
| - - uses: actions/checkout@v2 |
| - - name: Setting up $HOME |
| - run: | |
| - cp /root/.bashrc $HOME/.bashrc && |
| - ln -sf /root/.rustup ~/.rustup && |
| - ln -sf /root/.cargo ~/.cargo |
| - - name: Preparing build system |
| - run: | |
| - . ~/.cargo/env && |
| - . /opt/sgxsdk/environment && |
| - mkdir -p build && |
| - cd build && |
| - cmake -DRUSTFLAGS="-D warnings" -DTEST_MODE=ON .. |
| - - name: Checking code format |
| - run: | |
| - . /root/.cargo/env && |
| - cd build && make check |
| - lint: |
| - runs-on: ubuntu-18.04 |
| - container: teaclave/teaclave-build-ubuntu-1804-sgx-2.14:0.1.5 |
| - steps: |
| - - uses: actions/checkout@v2 |
| - - name: Setting up $HOME |
| - run: | |
| - cp /root/.bashrc $HOME/.bashrc && |
| - ln -sf /root/.rustup ~/.rustup && |
| - ln -sf /root/.cargo ~/.cargo |
| - - name: Preparing build system |
| - run: | |
| - . ~/.cargo/env && |
| - . /opt/sgxsdk/environment && |
| - mkdir -p build && |
| - cd build && |
| - cmake -DRUSTFLAGS="-D warnings" -DTEST_MODE=ON .. |
| - - name: Code linting with Clippy |
| - run: | |
| - . /opt/sgxsdk/environment && |
| - . /root/.cargo/env && |
| - cd build && make CLP=1 |
| - license: |
| - runs-on: ubuntu-18.04 |
| - steps: |
| - - uses: actions/checkout@v2 |
| - - name: Check License Header |
| - uses: apache/skywalking-eyes@main |
| diff --git a/.github/workflows/cli-packaging.yml b/.github/workflows/cli-packaging.yml |
| new file mode 100644 |
| index 0000000..9f42d95 |
| --- /dev/null |
| +++ b/.github/workflows/cli-packaging.yml |
| @@ -0,0 +1,122 @@ |
| +# 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. |
| + |
| +name: cli-packaging |
| +on: |
| + push: |
| + tags: |
| + - 'cli-**' |
| +defaults: |
| + run: |
| + shell: bash |
| + |
| + |
| +jobs: |
| + matrix-packaging: |
| + runs-on: ${{ matrix.label }} |
| + strategy: |
| + matrix: |
| + label: [ci-mac-x86_64, ci-linux-x64] |
| + steps: |
| + - uses: actions/checkout@v2 |
| + - name: Set env |
| + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV |
| + - name: Test |
| + run: | |
| + echo $RELEASE_VERSION |
| + echo $(uname) $(uname -m) |
| + - name: Building Cleanroom CLI |
| + run: | |
| + CommitID=$(git rev-parse --short HEAD) |
| + UniqID=$RELEASE_VERSION-$CommitID |
| + DestBase=/xlabfs/shared/teaclave-release/tmp |
| + DestDir=$DestBase/$UniqID |
| + echo $DestDir |
| + |
| + ssh node5 "mkdir -p $DestDir -m775" |
| + |
| + cd cleanroom-cli |
| + make azure > make_azure.log |
| + |
| + os=$(uname) |
| + arch=$(uname -m) |
| + package_name=cleanroom-cli-$os-$arch |
| + |
| + ls $package_name.tgz |
| + |
| + scp $package_name.tgz node5:"$DestDir" |
| + |
| + mac-arm64-packaging: |
| + runs-on: ci-mac-arm64 |
| + steps: |
| + - uses: actions/checkout@v2 |
| + - name: Set env |
| + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV |
| + - name: Test |
| + run: | |
| + echo $RELEASE_VERSION |
| + echo $(uname) $(uname -m) |
| + - name: Building Cleanroom CLI |
| + run: | |
| + CommitID=$(git rev-parse --short HEAD) |
| + UniqID=$RELEASE_VERSION-$CommitID |
| + DestBase=/xlabfs/shared/teaclave-release/tmp |
| + DestDir=$DestBase/$UniqID |
| + echo $DestDir |
| + |
| + ssh node5 "mkdir -p $DestDir -m775" |
| + |
| + cd cleanroom-cli |
| + |
| + arch -arm64 make azure > make_azure.log |
| + package_name=cleanroom-cli-Darwin-arm64 |
| + |
| + ls $package_name.tgz |
| + |
| + scp $package_name.tgz node5:"$DestDir" |
| + |
| + archive-packages: |
| + needs: [matrix-packaging, mac-arm64-packaging] |
| + runs-on: ci-linux-x64 |
| + steps: |
| + - uses: actions/checkout@v2 |
| + - name: Set ENV |
| + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV |
| + - name: Test ENV |
| + run: | |
| + echo $RELEASE_VERSION |
| + - name: Building Cleanroom CLI |
| + run: | |
| + CommitID=$(git rev-parse --short HEAD) |
| + UniqID=$RELEASE_VERSION-$CommitID |
| + ReleaseDir=/xlabfs/shared/teaclave-release |
| + DestBase=/xlabfs/shared/teaclave-release/tmp |
| + DestDir=$DestBase/$UniqID |
| + echo $DestDir |
| + |
| + cd cleanroom-cli/ |
| + cli_version=$(cat cleanroom-cli.py | sed -n 's/^__version__ = "\(.*\)"/\1/p') |
| + echo $cli_version |
| + |
| + echo $RELEASE_VERSION | grep -qE "$cli_version$" |
| + |
| + echo $cli_version > version |
| + cp version $DestDir |
| + cp install.sh $DestDir |
| + |
| + tar czvf cleanroom-$UniqID.tgz -C $DestBase $UniqID |
| + cp cleanroom-$UniqID.tgz $ReleaseDir |
| diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml |
| deleted file mode 100644 |
| index b9c5ff0..0000000 |
| --- a/.github/workflows/codeql-analysis.yml |
| +++ /dev/null |
| @@ -1,62 +0,0 @@ |
| -# 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. |
| - |
| -name: "Code scanning" |
| - |
| -on: |
| - push: |
| - pull_request: |
| - schedule: |
| - - cron: '36 22 * * 3' |
| - |
| -jobs: |
| - analyze-cpp: |
| - name: Analyze cpp |
| - runs-on: ubuntu-latest |
| - |
| - steps: |
| - - name: Checkout repository |
| - uses: actions/checkout@v2 |
| - with: |
| - submodules: 'true' |
| - |
| - - name: Initialize CodeQL |
| - uses: github/codeql-action/init@v1 |
| - with: |
| - languages: cpp |
| - |
| - - name: Build C projects |
| - run: cd examples/c && make |
| - |
| - - name: Perform CodeQL Analysis |
| - uses: github/codeql-action/analyze@v1 |
| - |
| - analyze-python: |
| - name: Analyze python |
| - runs-on: ubuntu-latest |
| - |
| - steps: |
| - - name: Checkout repository |
| - uses: actions/checkout@v2 |
| - |
| - - name: Initialize CodeQL |
| - uses: github/codeql-action/init@v1 |
| - with: |
| - languages: python |
| - |
| - - name: Perform CodeQL Analysis |
| - uses: github/codeql-action/analyze@v1 |
| diff --git a/.gitmodules b/.gitmodules |
| index b2955f0..d861c3f 100644 |
| --- a/.gitmodules |
| +++ b/.gitmodules |
| @@ -15,5 +15,6 @@ |
| ignore = dirty |
| [submodule "third_party/wasm-micro-runtime"] |
| path = third_party/wasm-micro-runtime |
| - url = https://github.com/bytecodealliance/wasm-micro-runtime |
| + url = https://github.com/organization/wasm-micro-runtime |
| + branch = cleanroom |
| ignore = dirty |
| diff --git a/CMakeLists.txt b/CMakeLists.txt |
| index ff7b657..3d46b38 100644 |
| --- a/CMakeLists.txt |
| +++ b/CMakeLists.txt |
| @@ -110,8 +110,12 @@ parse_cargo_packages( |
| if(NOT TEST_MODE) |
| list(FILTER SGX_APPS EXCLUDE REGEX "_tests$") |
| list(FILTER SGX_APP_CATEGORIES EXCLUDE REGEX "tests") |
| + list(FILTER SGX_APPS EXCLUDE REGEX "_profiling$") |
| + list(FILTER SGX_APP_CATEGORIES EXCLUDE REGEX "profiling") |
| list(FILTER SGX_LIBS EXCLUDE REGEX "_tests_enclave$") |
| list(FILTER SGX_LIB_CATEGORIES EXCLUDE REGEX "tests") |
| + list(FILTER SGX_LIBS EXCLUDE REGEX "_profiling_enclave$") |
| + list(FILTER SGX_LIB_CATEGORIES EXCLUDE REGEX "profiling") |
| endif() |
| |
| if(NOT DCAP) |
| @@ -189,6 +193,7 @@ set(WAMR_OUTPUTS |
| ${TEACLAVE_OUT_DIR}/libvmlib.a |
| ) |
| |
| + |
| if(USE_PREBUILT_MESAPY) |
| add_custom_command( |
| OUTPUT ${MESAPY_OUTPUTS} |
| @@ -220,22 +225,27 @@ ExternalProject_Add(wamr_teaclave |
| LOG_BUILD 1 |
| ) |
| |
| + |
| add_custom_command( |
| OUTPUT ${WAMR_OUTPUTS} |
| DEPENDS wamr_teaclave |
| COMMAND |
| - cp ${WAMR_TEACLAVE_ROOT_DIR}/build/libvmlib.a ${TEACLAVE_OUT_DIR} |
| + cp ${WAMR_TEACLAVE_ROOT_DIR}/build/libvmlib.a ${TEACLAVE_OUT_DIR} && |
| + cp ${ALGORITHM2_ROOT_DIR}/libalgorithm2.a ${TEACLAVE_OUT_DIR} |
| WORKING_DIRECTORY ${WAMR_TEACLAVE_ROOT_DIR}/build |
| ) |
| |
| + |
| add_custom_target(mesapy |
| DEPENDS ${MESAPY_OUTPUTS} |
| ) |
| |
| + |
| add_custom_target(wamr |
| DEPENDS ${WAMR_TEACLAVE_ROOT_DIR}/CMakeLists.txt ${WAMR_OUTPUTS} |
| ) |
| |
| + |
| # mesapy components |
| add_custom_command( |
| OUTPUT ${TEACLAVE_OUT_DIR}/acs_py_enclave.c |
| @@ -303,3 +313,4 @@ add_cargo_build_dylib_staticlib_target(teaclave_client_sdk |
| # ${TEACLAVE_EXAMPLE_INSTALL_DIR}/quickstart_c ) |
| |
| add_enclave_sig_target_n_hooks() |
| + |
| diff --git a/NOTICE b/NOTICE |
| index 8d84f50..22629d1 100644 |
| --- a/NOTICE |
| +++ b/NOTICE |
| @@ -1,5 +1,5 @@ |
| Apache Teaclave (incubating) |
| -Copyright 2019-2022 The Apache Software Foundation |
| +Copyright 2019-2021 The Apache Software Foundation |
| |
| This product includes software developed at |
| The Apache Software Foundation (http://www.apache.org/). |
| diff --git a/README.md b/README.md |
| index fe59a6f..4c0cbbf 100644 |
| --- a/README.md |
| +++ b/README.md |
| @@ -55,7 +55,6 @@ platform, making computation on privacy-sensitive data safe and simple. |
| |
| ### Contribute to Teaclave |
| |
| -- [Release Guide](docs/release-guide.md) |
| - [Rust Development Guideline](docs/rust-guideline.md) |
| - [Development Tips](docs/development-tips.md) |
| |
| diff --git a/attestation/Cargo.toml b/attestation/Cargo.toml |
| index 35bc104..85e6cc2 100644 |
| --- a/attestation/Cargo.toml |
| +++ b/attestation/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_attestation" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Provides TLS-based remote attestation mechanism in Teaclave." |
| license = "Apache-2.0" |
| @@ -44,7 +44,7 @@ cfg-if = { version = "0.1.9" } |
| chrono = { version = "0.4.6" } |
| hex = { version = "0.4.0" } |
| httparse = { version = "1.3.2", default-features = false } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| num-bigint = { version = "0.2.2" } |
| percent-encoding = { version = "2.1.0" } |
| rustls = { version = "0.16.0", features = ["dangerous_configuration"] } |
| diff --git a/binder/Cargo.toml b/binder/Cargo.toml |
| index a427e2f..eb5b869 100644 |
| --- a/binder/Cargo.toml |
| +++ b/binder/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_binder" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Abstract communication interfaces between TEE untrusted/trusted worlds." |
| license = "Apache-2.0" |
| @@ -39,7 +39,7 @@ app_unit_test = [] |
| cfg-if = { version = "0.1.9" } |
| anyhow = { version = "1.0.26" } |
| env_logger = { version = "0.7.1" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| serde = { version = "1.0.92", features = ["derive"] } |
| serde_json = { version = "1.0.39" } |
| thiserror = { version = "1.0.9" } |
| diff --git a/binder/attribute/Cargo.toml b/binder/attribute/Cargo.toml |
| index a4162de..538af15 100644 |
| --- a/binder/attribute/Cargo.toml |
| +++ b/binder/attribute/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_binder_attribute" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Macros for binder" |
| license = "Apache-2.0" |
| diff --git a/binder/src/proto.rs b/binder/src/proto.rs |
| index b3e7fa7..aab5c5f 100644 |
| --- a/binder/src/proto.rs |
| +++ b/binder/src/proto.rs |
| @@ -96,14 +96,22 @@ impl RunTestInput { |
| #[derive(Serialize, Deserialize, Debug)] |
| pub struct RunTestOutput; |
| |
| -#[derive(Default, Serialize, Deserialize, Debug)] |
| +#[derive(Serialize, Deserialize, Debug)] |
| +pub enum SubCmd { |
| + Attestation, |
| + BackupDb, |
| +} |
| + |
| +#[derive(Serialize, Deserialize, Debug)] |
| pub struct RawJsonInput { |
| + pub sub_cmd: SubCmd, |
| pub json: String, |
| } |
| |
| impl RawJsonInput { |
| - pub fn new(json: impl ToString) -> Self { |
| + pub fn new(sub_cmd: SubCmd, json: impl ToString) -> Self { |
| Self { |
| + sub_cmd, |
| json: json.to_string(), |
| } |
| } |
| diff --git a/cli/Cargo.toml b/cli/Cargo.toml |
| index ff36216..aa0bcf6 100644 |
| --- a/cli/Cargo.toml |
| +++ b/cli/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_cli" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave command line tool" |
| license = "Apache-2.0" |
| diff --git a/cmake/TeaclaveGenVars.cmake b/cmake/TeaclaveGenVars.cmake |
| index 347ed06..966bcba 100644 |
| --- a/cmake/TeaclaveGenVars.cmake |
| +++ b/cmake/TeaclaveGenVars.cmake |
| @@ -17,6 +17,7 @@ |
| |
| set(TEACLAVE_PROJECT_ROOT ${PROJECT_SOURCE_DIR}) |
| set(TEACLAVE_BUILD_ROOT ${PROJECT_BINARY_DIR}) |
| +set(TEACLAVE_CLEANROOMCLI_ROOT ${PROJECT_SOURCE_DIR}/cleanroom-cli) |
| set(TEACLAVE_OUT_DIR ${PROJECT_BINARY_DIR}/intermediate) |
| set(TEACLAVE_INSTALL_DIR ${PROJECT_SOURCE_DIR}/release) |
| set(TEACLAVE_EDL_DIR ${PROJECT_SOURCE_DIR}/edl) |
| @@ -45,6 +46,9 @@ set(TRUSTED_TARGET_DIR ${TEACLAVE_TARGET_DIR}/trusted) |
| set(WAMR_TEACLAVE_ROOT_DIR |
| ${PROJECT_SOURCE_DIR}/third_party/wasm-micro-runtime/product-mini/platforms/teaclave-sgx |
| ) |
| +set(ALGORITHM2_ROOT_DIR |
| + ${PROJECT_SOURCE_DIR}/algorithm2_hash_sgx |
| +) |
| # build.rs will read ENV{ENCLAVE_OUT_DIR} for linking |
| set(ENCLAVE_OUT_DIR ${TEACLAVE_OUT_DIR}) |
| set(RUST_SGX_SDK ${PROJECT_SOURCE_DIR}/third_party/rust-sgx-sdk) |
| @@ -123,6 +127,7 @@ set(TEACLAVE_COMMON_ENVS |
| TEACLAVE_EXAMPLE_INSTALL_DIR=${TEACLAVE_EXAMPLE_INSTALL_DIR} |
| TEACLAVE_BIN_INSTALL_DIR=${TEACLAVE_BIN_INSTALL_DIR} |
| TEACLAVE_CLI_INSTALL_DIR=${TEACLAVE_CLI_INSTALL_DIR} |
| + TEACLAVE_CLEANROOMCLI_ROOT=${TEACLAVE_CLEANROOMCLI_ROOT} |
| TEACLAVE_TOOL_INSTALL_DIR=${TEACLAVE_TOOL_INSTALL_DIR} |
| TEACLAVE_DCAP_INSTALL_DIR=${TEACLAVE_DCAP_INSTALL_DIR} |
| TEACLAVE_LIB_INSTALL_DIR=${TEACLAVE_LIB_INSTALL_DIR} |
| diff --git a/cmake/TeaclaveUtils.cmake b/cmake/TeaclaveUtils.cmake |
| index 144a0f7..877a525 100644 |
| --- a/cmake/TeaclaveUtils.cmake |
| +++ b/cmake/TeaclaveUtils.cmake |
| @@ -58,17 +58,8 @@ function(init_submodules) |
| ) |
| endif() |
| # Patch WAMR after pulling |
| - if(NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/wasm-micro-runtime/product-mini/platforms/teaclave-sgx/CMakeLists.txt") |
| - execute_process( |
| - COMMAND |
| - patch -N -p1 |
| - INPUT_FILE "../wamr.patch" |
| - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/wasm-micro-runtime |
| - ) |
| - endif() |
| endif() |
| endif() |
| - |
| if(NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/crates-io" |
| OR NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/crates-sgx" |
| OR NOT EXISTS "${PROJECT_SOURCE_DIR}/third_party/mesapy" |
| diff --git a/cmake/UtilTargets.cmake b/cmake/UtilTargets.cmake |
| index 5c6cf1c..d707b95 100644 |
| --- a/cmake/UtilTargets.cmake |
| +++ b/cmake/UtilTargets.cmake |
| @@ -74,8 +74,12 @@ if(TEST_MODE) |
| run-sdk-tests COMMAND ${TEACLAVE_COMMON_ENVS} |
| ${MT_SCRIPT_DIR}/test.sh sdk) |
| add_custom_target( |
| - run-cancel-test COMMAND ${TEACLAVE_COMMON_ENVS} |
| + run-cancel-tests COMMAND ${TEACLAVE_COMMON_ENVS} |
| ${MT_SCRIPT_DIR}/test.sh cancel) |
| + |
| + add_custom_target( |
| + run-cleanroomcli-tests COMMAND ${TEACLAVE_COMMON_ENVS} |
| + ${MT_SCRIPT_DIR}/test.sh cleanroomcli) |
| else() |
| add_custom_target( |
| run-tests |
| diff --git a/cmake/scripts/parse_cargo_packages.py b/cmake/scripts/parse_cargo_packages.py |
| index 457b9c7..3412191 100644 |
| --- a/cmake/scripts/parse_cargo_packages.py |
| +++ b/cmake/scripts/parse_cargo_packages.py |
| @@ -95,6 +95,7 @@ def pkg_path_2_category(pkg_path): |
| DEFAULT_EDL_LIB = "Enclave_common_t" |
| PKG_NAME_TO_EDL_LIB = { |
| "teaclave_unit_tests_enclave": "Enclave_fa_t", |
| + "teaclave_profiling_enclave": "Enclave_fa_t", |
| "teaclave_execution_service_enclave": "Enclave_fa_t", |
| } |
| |
| diff --git a/cmake/scripts/prep.sh b/cmake/scripts/prep.sh |
| index dc87812..6fa4b21 100755 |
| --- a/cmake/scripts/prep.sh |
| +++ b/cmake/scripts/prep.sh |
| @@ -26,7 +26,7 @@ REQUIRED_ENVS=("CMAKE_SOURCE_DIR" "CMAKE_BINARY_DIR" |
| "TEACLAVE_CLI_INSTALL_DIR" "TEACLAVE_TOOL_INSTALL_DIR" "TEACLAVE_DCAP_INSTALL_DIR" |
| "TEACLAVE_LIB_INSTALL_DIR" "TEACLAVE_TEST_INSTALL_DIR" |
| "TEACLAVE_AUDITORS_DIR" "TEACLAVE_EXAMPLE_AUDITORS_DIR" "DCAP" "TEACLAVE_SYMLINKS" |
| -"TEACLAVE_PROJECT_ROOT" |
| +"TEACLAVE_PROJECT_ROOT" "TEACLAVE_CLEANROOMCLI_ROOT" |
| ) |
| |
| for var in "${REQUIRED_ENVS[@]}"; do |
| diff --git a/cmake/scripts/sgx_link_sign.sh b/cmake/scripts/sgx_link_sign.sh |
| index b2e4de7..dd9a44e 100755 |
| --- a/cmake/scripts/sgx_link_sign.sh |
| +++ b/cmake/scripts/sgx_link_sign.sh |
| @@ -46,7 +46,7 @@ fi |
| |
| TEACLAVE_LINK_FLAGS="-L${TEACLAVE_OUT_DIR} -lpycomponent ffi.o -lpypy-c -lsgx_tlibc_ext -lffi" |
| if [ "$TEACLAVE_EXECUTOR_WAMR" == "ON" ]; then |
| - TEACLAVE_LINK_FLAGS+=" -lvmlib" |
| + TEACLAVE_LINK_FLAGS+=" -lvmlib -lalgorithm2" |
| fi |
| |
| # Enable the security flags |
| diff --git a/cmake/scripts/test.sh b/cmake/scripts/test.sh |
| index a8a5747..1f79e61 100755 |
| --- a/cmake/scripts/test.sh |
| +++ b/cmake/scripts/test.sh |
| @@ -18,7 +18,6 @@ |
| # under the License. |
| |
| set -eE |
| -export TEACLAVE_LOG=teaclave=info |
| |
| if [ -z "${TEACLAVE_PROJECT_ROOT}" ] \ |
| || [ -z "${SGX_SDK}" ] || [ -z "${SGX_MODE}" ]; then |
| @@ -69,7 +68,7 @@ cleanup() { |
| wait_port() { |
| for port in "$@" |
| do |
| - timeout 10 bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/$0/$1; do sleep 1; done' localhost "$port" |
| + timeout 20 bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/$0/$1; do sleep 1; done' localhost "$port" |
| done |
| } |
| |
| @@ -227,16 +226,17 @@ run_examples() { |
| |
| # Run tests of execution service separately |
| ./teaclave_execution_service & |
| - sleep 3 # wait for execution services |
| + sleep 6 # wait for execution services |
| popd |
| |
| # Generate WASM file for WAMR Rust example |
| - pushd ${TEACLAVE_PROJECT_ROOT}/examples/python/wasm_rust_psi_payload |
| - make |
| - popd |
| + # pushd ${TEACLAVE_PROJECT_ROOT}/examples/python/wasm_rust_psi_payload |
| + # make |
| + # popd |
| |
| pushd ${TEACLAVE_PROJECT_ROOT}/examples/python |
| export PYTHONPATH=${TEACLAVE_PROJECT_ROOT}/sdk/python |
| + python3 test_default_arguments.py |
| python3 builtin_echo.py |
| python3 mesapy_echo.py |
| python3 mesapy_logistic_reg.py |
| @@ -248,24 +248,29 @@ run_examples() { |
| python3 builtin_rsa_sign.py |
| python3 builtin_face_detection.py |
| python3 builtin_password_check.py |
| - python3 wasm_c_simple_add.py |
| - python3 wasm_rust_psi.py |
| - python3 wasm_tvm_mnist.py |
| + python3 cleanroom_algorithm1.py |
| + python3 cleanroom_stderr.py |
| + python3 builtin_cleanroom_algorithm2.py |
| + # python3 cleanroom_algorithm1_repeat.py |
| + # python3 cleanroom_algorithm2.py |
| + # python3 wasm_c_simple_add.py |
| + # python3 wasm_rust_psi.py |
| + # python3 wasm_tvm_mnist.py |
| python3 test_disable_function.py |
| popd |
| |
| - pushd ${TEACLAVE_PROJECT_ROOT}/examples/c |
| - make run |
| - popd |
| - |
| - pushd ${TEACLAVE_PROJECT_ROOT}/examples/rust |
| - pushd ./builtin_echo |
| - RUSTFLAGS=${RUSTFLAGS} cargo run |
| - popd |
| - pushd ./builtin_ordered_set_intersect |
| - RUSTFLAGS=${RUSTFLAGS} cargo run |
| - popd |
| - popd |
| + # pushd ${TEACLAVE_PROJECT_ROOT}/examples/c |
| + # make run |
| + # popd |
| + |
| + # pushd ${TEACLAVE_PROJECT_ROOT}/examples/rust |
| + # pushd ./builtin_echo |
| + # RUSTFLAGS=${RUSTFLAGS} cargo run |
| + # popd |
| + # pushd ./builtin_ordered_set_intersect |
| + # RUSTFLAGS=${RUSTFLAGS} cargo run |
| + # popd |
| + # popd |
| |
| # kill all background services |
| cleanup |
| @@ -301,7 +306,7 @@ run_cancel_test() { |
| # Run of execution services separately |
| ./teaclave_execution_service & exe_pid1=$! |
| ./teaclave_execution_service & exe_pid2=$! |
| - sleep 10 # wait for execution services |
| + sleep 25 # wait for execution services |
| popd |
| |
| echo "executor 1 pid: $exe_pid1" |
| @@ -312,7 +317,7 @@ run_cancel_test() { |
| python3 mesapy_deadloop_cancel.py |
| popd |
| |
| - sleep 10 # Wait for executor exit |
| + sleep 15 # Wait for executor exit |
| |
| live_pids=0 |
| if ps -p $exe_pid1 > /dev/null |
| @@ -325,6 +330,7 @@ run_cancel_test() { |
| live_pids=$((live_pids+1)) |
| fi |
| |
| + echo "Current Executor: ${live_pids}" |
| if [ $live_pids -eq 1 ] |
| then |
| echo "only one executor is killed, test passed" |
| @@ -336,6 +342,46 @@ run_cancel_test() { |
| cleanup |
| } |
| |
| +run_cleanroomcli_tests() { |
| + trap cleanup INT TERM ERR |
| + |
| + echo_title "cleanroom cli" |
| + mkdir -p /tmp/fusion_data |
| + pushd ${TEACLAVE_CLI_INSTALL_DIR} |
| + ./teaclave_cli verify \ |
| + --enclave-info ../examples/enclave_info.toml \ |
| + --public-keys $(find ../examples -name "*.public.pem") \ |
| + --signatures $(find ../examples -name "*.sign.sha256") |
| + popd |
| + |
| + echo "initiating Teaclave..." |
| + |
| + 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 |
| + |
| + # Run of execution services separately |
| + ./teaclave_execution_service & exe_pid1=$! |
| + sleep 25 # wait for execution services |
| + popd |
| + |
| + pushd ${TEACLAVE_CLEANROOMCLI_ROOT} |
| + ./run_test.sh |
| + popd |
| + |
| + # kill all background services |
| + cleanup |
| +} |
| + |
| case "$1" in |
| "unit") |
| run_unit_tests |
| @@ -355,6 +401,9 @@ case "$1" in |
| "cancel") |
| run_cancel_test |
| ;; |
| + "cleanroomcli") |
| + run_cleanroomcli_tests |
| + ;; |
| *) |
| run_unit_tests |
| run_integration_tests |
| @@ -362,5 +411,6 @@ case "$1" in |
| run_sdk_tests |
| run_examples |
| run_cancel_test |
| + run_cleanroomcli_tests |
| ;; |
| esac |
| diff --git a/cmake/tomls/Cargo.sgx_trusted_lib.toml b/cmake/tomls/Cargo.sgx_trusted_lib.toml |
| index 687b4ca..4b2681e 100644 |
| --- a/cmake/tomls/Cargo.sgx_trusted_lib.toml |
| +++ b/cmake/tomls/Cargo.sgx_trusted_lib.toml |
| @@ -26,6 +26,7 @@ members = [ |
| "services/management/enclave", |
| "services/scheduler/enclave", |
| "tests/unit/enclave", |
| + "tests/profiling/enclave", |
| "tests/functional/enclave", |
| "tests/integration/enclave", |
| "tool/enclave", |
| @@ -90,6 +91,7 @@ sct = { git = "https://github.com/mesalock-linux/sct.rs", branch = |
| serde = { git = "https://github.com/mesalock-linux/serde-sgx" } |
| serde_derive = { git = "https://github.com/mesalock-linux/serde-sgx" } |
| serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } |
| +bincode = { git = "https://github.com/mesalock-linux/bincode-sgx"} |
| threadpool = { git = "https://github.com/mesalock-linux/rust-threadpool-sgx" } |
| # tiff = { git = "https://github.com/mesalock-linux/image-tiff-sgx" } |
| toml = { git = "https://github.com/mesalock-linux/toml-rs-sgx" } |
| @@ -99,3 +101,6 @@ uuid = { git = "https://github.com/mesalock-linux/uuid-sgx" } |
| webpki = { git = "https://github.com/mesalock-linux/webpki", branch = "mesalock_sgx" } |
| webpki-roots = { git = "https://github.com/mesalock-linux/webpki-roots", branch = "mesalock_sgx" } |
| yasna = { git = "https://github.com/mesalock-linux/yasna.rs-sgx" } |
| + |
| +[profile.release] |
| +lto = true |
| diff --git a/cmake/tomls/Cargo.sgx_untrusted_app.toml b/cmake/tomls/Cargo.sgx_untrusted_app.toml |
| index 2fa8058..bb8c7e3 100644 |
| --- a/cmake/tomls/Cargo.sgx_untrusted_app.toml |
| +++ b/cmake/tomls/Cargo.sgx_untrusted_app.toml |
| @@ -26,6 +26,7 @@ members = [ |
| "services/management/app", |
| "services/scheduler/app", |
| "tests/unit/app", |
| + "tests/profiling/app", |
| "tests/functional/app", |
| "tests/integration/app", |
| "tool/app", |
| @@ -40,3 +41,6 @@ sgx_urts = { git = "https://github.com/apache/teaclave-sgx-sdk", rev = "v1.1.3" |
| sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk", rev = "v1.1.3" } |
| sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk", rev = "v1.1.3" } |
| sgx_trts = { git = "https://github.com/apache/teaclave-sgx-sdk", rev = "v1.1.3" } |
| + |
| +[profile.release] |
| +lto = true |
| diff --git a/cmake/tomls/Cargo.unix_app.toml b/cmake/tomls/Cargo.unix_app.toml |
| index 718170f..f239c32 100644 |
| --- a/cmake/tomls/Cargo.unix_app.toml |
| +++ b/cmake/tomls/Cargo.unix_app.toml |
| @@ -34,3 +34,6 @@ exclude = [ |
| # sgx_urts = { git = "https://github.com/apache/teaclave-sgx-sdk", rev = "v1.1.3" } |
| sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk", rev = "v1.1.3" } |
| sgx_ucrypto = { git = "https://github.com/apache/teaclave-sgx-sdk", rev = "v1.1.3" } |
| + |
| +[profile.release] |
| +lto = true |
| diff --git a/common/protected_fs_rs/Cargo.lock b/common/protected_fs_rs/Cargo.lock |
| index 84dab3f..b0601a3 100644 |
| --- a/common/protected_fs_rs/Cargo.lock |
| +++ b/common/protected_fs_rs/Cargo.lock |
| @@ -25,7 +25,7 @@ checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" |
| |
| [[package]] |
| name = "protected_fs_rs" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "cfg-if", |
| "libc", |
| diff --git a/common/protected_fs_rs/Cargo.toml b/common/protected_fs_rs/Cargo.toml |
| index 8370ae4..ab877b8 100644 |
| --- a/common/protected_fs_rs/Cargo.toml |
| +++ b/common/protected_fs_rs/Cargo.toml |
| @@ -1,6 +1,6 @@ |
| [package] |
| name = "protected_fs_rs" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Ported sgx_protected_fs (Intel SGX SDK) running out side sgx with Rust bindings." |
| license-file = "Apache-2.0" |
| diff --git a/common/rusty_leveldb_sgx/Cargo.toml b/common/rusty_leveldb_sgx/Cargo.toml |
| index 2c09ebf..5173df2 100644 |
| --- a/common/rusty_leveldb_sgx/Cargo.toml |
| +++ b/common/rusty_leveldb_sgx/Cargo.toml |
| @@ -24,6 +24,7 @@ integer-encoding = { version = "1.0" } |
| |
| protected_fs_rs = { path = "../protected_fs_rs", optional = true } |
| teaclave_test_utils = { path = "../../tests/utils", optional = true } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| |
| sgx_tstd = { version = "1.1.3", optional = true } |
| sgx_trts = { version = "1.1.3", optional = true } |
| diff --git a/common/rusty_leveldb_sgx/src/db_impl.rs b/common/rusty_leveldb_sgx/src/db_impl.rs |
| index 04cb757..56b6a7f 100644 |
| --- a/common/rusty_leveldb_sgx/src/db_impl.rs |
| +++ b/common/rusty_leveldb_sgx/src/db_impl.rs |
| @@ -136,7 +136,9 @@ impl DB { |
| db.vset.borrow_mut().log_and_apply(ve)?; |
| } |
| |
| + log::warn!("delete_obsolete_files at open"); |
| db.delete_obsolete_files()?; |
| + |
| db.maybe_do_compaction()?; |
| Ok(db) |
| } |
| @@ -187,8 +189,8 @@ impl DB { |
| // Recover from all log files not in the descriptor. |
| let mut max_seq = 0; |
| let filenames = self.opt.env.children(&self.path)?; |
| - let mut expected = self.vset.borrow().live_files(); |
| let mut log_files = vec![]; |
| + let mut expected = self.vset.borrow().live_files(); |
| |
| for file in &filenames { |
| if let Ok((num, typ)) = parse_file_name(&file) { |
| @@ -201,12 +203,15 @@ impl DB { |
| } |
| } |
| if !expected.is_empty() { |
| - log!(self.opt.log, "Missing at least these files: {:?}", expected); |
| + //log!(self.opt.log, "Missing at least these files: {:?}", expected); |
| + //return err(StatusCode::Corruption, "missing live files (see log)"); |
| + log::error!("Missing at least these files: {:?}", expected); |
| return err(StatusCode::Corruption, "missing live files (see log)"); |
| } |
| |
| log_files.sort(); |
| for i in 0..log_files.len() { |
| + log::info!("Recover log_file: {:?}", log_files[i]); |
| let (save_manifest_, max_seq_) = |
| self.recover_log_file(log_files[i], i == log_files.len() - 1, ve)?; |
| if save_manifest_ { |
| @@ -337,7 +342,8 @@ impl DB { |
| if typ == FileType::Table { |
| let _ = self.cache.borrow_mut().evict(num); |
| } |
| - log!(self.opt.log, "Deleting file type={:?} num={}", typ, num); |
| + //log!(self.opt.log, "Deleting file type={:?} num={}", typ, num); |
| + log::warn!("Deleting file type={:?} num={}", typ, num); |
| if let Err(e) = self.opt.env.delete(&self.path.join(&name)) { |
| log!(self.opt.log, "Deleting file num={} failed: {}", num, e); |
| } |
| diff --git a/common/rusty_leveldb_sgx/src/lib.rs b/common/rusty_leveldb_sgx/src/lib.rs |
| index a5727b6..40aa59c 100644 |
| --- a/common/rusty_leveldb_sgx/src/lib.rs |
| +++ b/common/rusty_leveldb_sgx/src/lib.rs |
| @@ -86,6 +86,79 @@ pub use crate::write_batch::WriteBatch; |
| pub use db_impl::DB; |
| pub use disk_env::PosixDiskEnv; |
| |
| +use std::collections::VecDeque; |
| +use std::path::Path; |
| +use std::vec::Vec; |
| + |
| +use table_cache::TableCache; |
| +pub struct DBReader { |
| + nums: Vec<types::FileNum>, |
| + tc: TableCache, |
| +} |
| + |
| +impl DBReader { |
| + pub fn new(db_name: impl AsRef<Path>, opt: Options) -> Result<Self> { |
| + let filenames = opt.env.children(db_name.as_ref())?; |
| + let tc = TableCache::new(db_name.as_ref(), opt, 1024); |
| + let mut nums = vec![]; |
| + for name in filenames { |
| + if let Ok((num, typ)) = types::parse_file_name(&name) { |
| + match typ { |
| + types::FileType::Table => nums.push(num), |
| + _ => {} |
| + } |
| + } |
| + } |
| + Ok(DBReader { nums, tc }) |
| + } |
| +} |
| + |
| +pub struct DBReaderIntoIterator { |
| + tables: VecDeque<table_reader::Table>, |
| + table_iter: Option<table_reader::TableIterator>, |
| +} |
| + |
| +impl IntoIterator for DBReader { |
| + type Item = (Vec<u8>, Vec<u8>); |
| + type IntoIter = DBReaderIntoIterator; |
| + |
| + fn into_iter(mut self) -> Self::IntoIter { |
| + let mut tables: VecDeque<_> = self |
| + .nums |
| + .clone() |
| + .into_iter() |
| + .map(|num| self.tc.get_table(num).unwrap()) |
| + .collect(); |
| + |
| + let opt_table = tables.pop_front(); |
| + DBReaderIntoIterator { |
| + tables, |
| + table_iter: opt_table.map(|table| table.iter()), |
| + } |
| + } |
| +} |
| + |
| +impl Iterator for DBReaderIntoIterator { |
| + type Item = (Vec<u8>, Vec<u8>); |
| + |
| + fn next(&mut self) -> Option<Self::Item> { |
| + if self.table_iter.is_none() { |
| + return None; |
| + } |
| + |
| + let iter = self.table_iter.as_mut().unwrap(); |
| + if iter.advance() { |
| + let (mut k, mut v) = (vec![], vec![]); |
| + iter.current(&mut k, &mut v); |
| + Some((k, v)) |
| + } else { |
| + let opt_table = self.tables.pop_front(); |
| + self.table_iter = opt_table.map(|table| table.iter()); |
| + self.next() |
| + } |
| + } |
| +} |
| + |
| #[cfg(feature = "enclave_unit_test")] |
| pub mod tests { |
| use super::*; |
| diff --git a/common/rusty_leveldb_sgx/src/version_set.rs b/common/rusty_leveldb_sgx/src/version_set.rs |
| index 3718976..58cd5ef 100644 |
| --- a/common/rusty_leveldb_sgx/src/version_set.rs |
| +++ b/common/rusty_leveldb_sgx/src/version_set.rs |
| @@ -647,8 +647,7 @@ impl VersionSet { |
| self.finalize(&mut v); |
| self.add_version(v); |
| self.manifest_num = self.next_file_num - 1; |
| - log!( |
| - self.opt.log, |
| + log::info!( |
| "Recovered manifest with next_file={} manifest_num={} log_num={} prev_log_num={} \ |
| last_seq={}", |
| self.next_file_num, |
| diff --git a/config/Cargo.toml b/config/Cargo.toml |
| index b4b29dc..8385d88 100644 |
| --- a/config/Cargo.toml |
| +++ b/config/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_config" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Build and runtime configurations." |
| license = "Apache-2.0" |
| @@ -30,7 +30,7 @@ build_config = [] |
| |
| [dependencies] |
| anyhow = { version = "1.0.26" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| serde = { version = "1.0.92", features = ["derive"] } |
| toml = { version = "0.5.1" } |
| url = { version = "2.1.1" } |
| diff --git a/config/config_gen/Cargo.lock b/config/config_gen/Cargo.lock |
| index 23b17a0..0e22458 100644 |
| --- a/config/config_gen/Cargo.lock |
| +++ b/config/config_gen/Cargo.lock |
| @@ -329,7 +329,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_config_gen" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "askama", |
| "pem", |
| diff --git a/config/config_gen/Cargo.toml b/config/config_gen/Cargo.toml |
| index 31e203c..5835865 100644 |
| --- a/config/config_gen/Cargo.toml |
| +++ b/config/config_gen/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_config_gen" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Generating build config." |
| license = "Apache-2.0" |
| diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml |
| index f1f1224..dd507f9 100644 |
| --- a/crypto/Cargo.toml |
| +++ b/crypto/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_crypto" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave crypto" |
| license = "Apache-2.0" |
| diff --git a/dcap/Cargo.toml b/dcap/Cargo.toml |
| index 8b3012c..4affa2e 100644 |
| --- a/dcap/Cargo.toml |
| +++ b/dcap/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_dcap_ref_as" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave DCAP Attestation Service (Reference Implementation)" |
| license = "Apache-2.0" |
| diff --git a/dcap_deployment/backup_db.sh b/dcap_deployment/backup_db.sh |
| new file mode 100755 |
| index 0000000..4b53025 |
| --- /dev/null |
| +++ b/dcap_deployment/backup_db.sh |
| @@ -0,0 +1,56 @@ |
| +#!/bin/bash |
| +set -e |
| + |
| +orig_bak=/data/backup/database_$(date +"%Y_%m_%d_%I_%M_%p").tgz |
| + |
| +# back and tar original db |
| +tar czvf $orig_bak /cleanroom-demo-data/database |
| + |
| +BASE="$HOME/backup_db/" |
| +cd $BASE/release/tool |
| + |
| +# two working directories |
| +# - tool/existing/ |
| +# - tool/converted/ |
| + |
| +# ensure clean working dir |
| +rm -rf ./existing |
| +mkdir ./existing |
| + |
| +# create existing |
| +tar xzvf $orig_bak -C ./existing |
| + |
| +# convert existing to ./converted in docker |
| + |
| +DOCKER="teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.1" |
| +LOCAL_AESM="/var/run/aesmd/aesm.socket" |
| +DOCKER_AESM="/var/run/aesmd/aesm.socket" |
| + |
| +BuildScript=$(cat << 'EOF' |
| + . /opt/sgxsdk/environment; |
| + cd /teaclave/release/tool |
| + rm -rf ./converted |
| + mkdir ./converted |
| + cd ./existing |
| + for db in ./cleanroom-demo-data/database/*_db; do |
| + existing_db=$(realpath $db) |
| + mkdir -p "../converted/$db" |
| + new_db=$(realpath ../converted/$db) |
| + echo "convert $existing_db to $new_db" |
| + |
| + key="00010203040506070f0e0d0c0b0a0908" |
| + |
| + pushd /teaclave/release/tool |
| + ./teaclave_sgx_tool backup $existing_db $new_db --key $key |
| + popd |
| + done |
| +EOF |
| +) |
| + |
| +docker run --device /dev/sgx/enclave:/dev/sgx/enclave --device /dev/sgx/provision:/dev/sgx/provision -v ${LOCAL_AESM}:${DOCKER_AESM} -v `pwd`:/teaclave/release/tool $DOCKER /bin/bash -c "$BuildScript" |
| + |
| +# tar converted db into the same dir as $orig_bak |
| +cd ./converted |
| +tar czvf $orig_bak.converted . |
| + |
| + |
| diff --git a/dcap_deployment/dcap_release_build.sh b/dcap_deployment/dcap_release_build.sh |
| new file mode 100755 |
| index 0000000..0c32b4f |
| --- /dev/null |
| +++ b/dcap_deployment/dcap_release_build.sh |
| @@ -0,0 +1,28 @@ |
| +#!/bin/bash |
| +set -e |
| + |
| +BASE=$HOME/dcap-release |
| +cd $BASE |
| + |
| +git clone git@github.com:organization/incubator-teaclave.git |
| +cd incubator-teaclave |
| + |
| +sed -i 's/https:\/\/github.com\/organization/git@github.com:organization/' .gitmodules |
| +sed -i 's/ias_root_ca_cert/dcap_root_ca_cert/' config/build.config.toml |
| + |
| +mkdir algorithm2_hash_sgx |
| +cp /xlabfs/ci/cleanroom-workload-devkit-ci-bot/libalgorithm2.a algorithm2_hash_sgx |
| + |
| +git submodule update --recursive --init |
| +mkdir build |
| + |
| +BuildScript=$(cat <<-END |
| + . /root/.cargo/env; |
| + . /opt/sgxsdk/environment; |
| + cd /teaclave/build; |
| + cmake -DCMAKE_BUILD_TYPE=Release -DTEST_MODE=OFF -DDCAP=ON .. && |
| + make -j4 |
| +END |
| +) |
| +docker run -v `pwd`:/teaclave "teaclave/teaclave-build-ubuntu-2004-sgx-dcap-1.12.1:0.1.1" /bin/bash -c "$BuildScript" |
| + |
| diff --git a/dcap_deployment/docker/README.md b/dcap_deployment/docker/README.md |
| new file mode 100644 |
| index 0000000..139a8c7 |
| --- /dev/null |
| +++ b/dcap_deployment/docker/README.md |
| @@ -0,0 +1,77 @@ |
| +# Teaclave Docker Internal DCAP Deployment |
| + |
| +## Check configuration file |
| +Make sure the PCCS\_URL is set correctly, and `USE_SECURE_CERT=FALSE`. |
| + |
| +``` |
| +❯ cat /etc/sgx_default_qcnl.conf |
| +# PCCS server address |
| +PCCS_URL=https://pccs-server:8081/sgx/certification/v3/ |
| + |
| +# To accept insecure HTTPS certificate, set this option to FALSE |
| +USE_SECURE_CERT=FALSE |
| +``` |
| + |
| +## Check aesmd |
| +``` |
| +sudo service aesmd status |
| +● aesmd.service - Intel(R) Architectural Enclave Service Manager |
| + Loaded: loaded (/lib/systemd/system/aesmd.service; enabled; vendor preset: enabled) |
| + Active: active (running) since Wed 2021-12-15 22:19:20 PST; 1h 48min ago |
| + Process: 25632 ExecStartPre=/opt/intel/sgx-aesm-service/aesm/linksgx.sh (code=exited, status=0/SUCCESS) |
| + Process: 25639 ExecStartPre=/bin/mkdir -p /var/run/aesmd/ (code=exited, status=0/SUCCESS) |
| + Process: 25640 ExecStartPre=/bin/chown -R aesmd:aesmd /var/run/aesmd/ (code=exited, status=0/SUCCESS) |
| + Process: 25641 ExecStartPre=/bin/chmod 0755 /var/run/aesmd/ (code=exited, status=0/SUCCESS) |
| + Process: 25642 ExecStartPre=/bin/chown -R aesmd:aesmd /var/opt/aesmd/ (code=exited, status=0/SUCCESS) |
| + Process: 25643 ExecStartPre=/bin/chmod 0750 /var/opt/aesmd/ (code=exited, status=0/SUCCESS) |
| + Process: 25644 ExecStart=/opt/intel/sgx-aesm-service/aesm/aesm_service (code=exited, status=0/SUCCESS) |
| + Main PID: 25645 (aesm_service) |
| + Tasks: 4 (limit: 76883) |
| + Memory: 3.6M |
| + CGroup: /system.slice/aesmd.service |
| + └─25645 /opt/intel/sgx-aesm-service/aesm/aesm_service |
| + |
| +Dec 15 22:19:20 xlab-sgx4 systemd[1]: Starting Intel(R) Architectural Enclave Service Manager... |
| +Dec 15 22:19:20 xlab-sgx4 systemd[1]: Started Intel(R) Architectural Enclave Service Manager. |
| +Dec 15 22:19:20 xlab-sgx4 aesm_service[25645]: The server sock is 0x556bdd36bad0 |
| +``` |
| + |
| +## Check pccs |
| +``` |
| +sudo service pccs status |
| +● pccs.service - Provisioning Certificate Caching Service (PCCS) |
| + Loaded: loaded (/lib/systemd/system/pccs.service; enabled; vendor preset: enabled) |
| + Active: active (running) since Wed 2021-12-15 22:19:15 PST; 1h 49min ago |
| + Docs: https://github.com/intel/SGXDataCenterAttestationPrimitives/blob/master/QuoteGeneration/pccs/README.md |
| + Main PID: 25609 (node) |
| + Tasks: 11 (limit: 76883) |
| + Memory: 64.0M |
| + CGroup: /system.slice/pccs.service |
| + └─25609 /usr/bin/node -r esm /opt/intel/sgx-dcap-pccs/pccs_server.js |
| +``` |
| + |
| +Test pccs with the following command: |
| +``` |
| +curl -v -k -G "https://127.0.0.1:8081/sgx/certification/v3/rootcacrl" |
| +``` |
| + |
| +## Launch teaclave\_dcap\_ref\_as on host |
| +``` |
| +cd release/dcap/ |
| +./teaclave_dcap_ref_as |
| +``` |
| + |
| +## Launch service dockers |
| + |
| +``` |
| +$ ./run-teaclave-services.sh |
| +Starting teaclave-file-service ... done |
| +Starting teaclave-authentication-service ... done |
| +Starting teaclave-access-control-service ... done |
| +Starting teaclave-scheduler-service ... done |
| +Starting teaclave-management-service ... done |
| +Starting teaclave-execution-service ... done |
| +Starting teaclave-frontend-service ... done |
| +Attaching to ... |
| +``` |
| + |
| diff --git a/dcap_deployment/docker/deploy_compose_build.sh b/dcap_deployment/docker/deploy_compose_build.sh |
| new file mode 100755 |
| index 0000000..acd7146 |
| --- /dev/null |
| +++ b/dcap_deployment/docker/deploy_compose_build.sh |
| @@ -0,0 +1,4 @@ |
| +#!/bin/bash |
| +set -e |
| + |
| +docker-compose -f docker-compose-ubuntu-2004.yml -f docker-compose-dcap-dev.override.yml -f docker-compose-aesm-socket.override.yml build |
| diff --git a/dcap_deployment/docker/deploy_compose_run.sh b/dcap_deployment/docker/deploy_compose_run.sh |
| new file mode 100755 |
| index 0000000..ef66479 |
| --- /dev/null |
| +++ b/dcap_deployment/docker/deploy_compose_run.sh |
| @@ -0,0 +1,5 @@ |
| +#!/bin/bash |
| +set -e |
| + |
| +source run.env |
| +docker-compose -f docker-compose-ubuntu-2004.yml -f docker-compose-dcap-dev.override.yml -f docker-compose-aesm-socket.override.yml up |
| diff --git a/dcap_deployment/docker/docker-compose-aesm-socket.override.yml b/dcap_deployment/docker/docker-compose-aesm-socket.override.yml |
| new file mode 100644 |
| index 0000000..20a7ab6 |
| --- /dev/null |
| +++ b/dcap_deployment/docker/docker-compose-aesm-socket.override.yml |
| @@ -0,0 +1,61 @@ |
| +# 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. |
| + |
| +version: '3.7' |
| + |
| +services: |
| + teaclave-authentication-service: |
| + volumes: |
| + - type: bind |
| + source: /var/run/aesmd/aesm.socket |
| + target: /var/run/aesmd/aesm.socket |
| + |
| + teaclave-frontend-service: |
| + volumes: |
| + - type: bind |
| + source: /var/run/aesmd/aesm.socket |
| + target: /var/run/aesmd/aesm.socket |
| + |
| + teaclave-management-service: |
| + volumes: |
| + - type: bind |
| + source: /var/run/aesmd/aesm.socket |
| + target: /var/run/aesmd/aesm.socket |
| + |
| + teaclave-storage-service: |
| + volumes: |
| + - type: bind |
| + source: /var/run/aesmd/aesm.socket |
| + target: /var/run/aesmd/aesm.socket |
| + |
| + teaclave-access-control-service: |
| + volumes: |
| + - type: bind |
| + source: /var/run/aesmd/aesm.socket |
| + target: /var/run/aesmd/aesm.socket |
| + |
| + teaclave-execution-service: |
| + volumes: |
| + - type: bind |
| + source: /var/run/aesmd/aesm.socket |
| + target: /var/run/aesmd/aesm.socket |
| + |
| + teaclave-scheduler-service: |
| + volumes: |
| + - type: bind |
| + source: /var/run/aesmd/aesm.socket |
| + target: /var/run/aesmd/aesm.socket |
| diff --git a/dcap_deployment/docker/docker-compose-aesm-vol.override.yml b/dcap_deployment/docker/docker-compose-aesm-vol.override.yml |
| new file mode 100644 |
| index 0000000..49459a0 |
| --- /dev/null |
| +++ b/dcap_deployment/docker/docker-compose-aesm-vol.override.yml |
| @@ -0,0 +1,51 @@ |
| +# 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. |
| + |
| +version: '3.7' |
| + |
| +volumes: |
| + aesmd-socket: |
| + external: true |
| + |
| +services: |
| + teaclave-authentication-service: |
| + volumes: |
| + - aesmd-socket:/var/run/aesmd |
| + |
| + teaclave-frontend-service: |
| + volumes: |
| + - aesmd-socket:/var/run/aesmd |
| + |
| + teaclave-management-service: |
| + volumes: |
| + - aesmd-socket:/var/run/aesmd |
| + |
| + teaclave-storage-service: |
| + volumes: |
| + - aesmd-socket:/var/run/aesmd |
| + |
| + teaclave-access-control-service: |
| + volumes: |
| + - aesmd-socket:/var/run/aesmd |
| + |
| + teaclave-execution-service: |
| + volumes: |
| + - aesmd-socket:/var/run/aesmd |
| + |
| + teaclave-scheduler-service: |
| + volumes: |
| + - aesmd-socket:/var/run/aesmd |
| diff --git a/dcap_deployment/docker/docker-compose-dcap-dev.override.yml b/dcap_deployment/docker/docker-compose-dcap-dev.override.yml |
| new file mode 100644 |
| index 0000000..efb0215 |
| --- /dev/null |
| +++ b/dcap_deployment/docker/docker-compose-dcap-dev.override.yml |
| @@ -0,0 +1,54 @@ |
| +# 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. |
| + |
| +version: '3.7' |
| + |
| +services: |
| + teaclave-authentication-service: |
| + devices: |
| + - /dev/sgx/enclave |
| + - /dev/sgx/provision |
| + |
| + teaclave-frontend-service: |
| + devices: |
| + - /dev/sgx/enclave |
| + - /dev/sgx/provision |
| + |
| + teaclave-management-service: |
| + devices: |
| + - /dev/sgx/enclave |
| + - /dev/sgx/provision |
| + |
| + teaclave-storage-service: |
| + devices: |
| + - /dev/sgx/enclave |
| + - /dev/sgx/provision |
| + |
| + teaclave-access-control-service: |
| + devices: |
| + - /dev/sgx/enclave |
| + - /dev/sgx/provision |
| + |
| + teaclave-execution-service: |
| + devices: |
| + - /dev/sgx/enclave |
| + - /dev/sgx/provision |
| + |
| + teaclave-scheduler-service: |
| + devices: |
| + - /dev/sgx/enclave |
| + - /dev/sgx/provision |
| diff --git a/dcap_deployment/docker/docker-compose-ubuntu-2004.yml b/dcap_deployment/docker/docker-compose-ubuntu-2004.yml |
| new file mode 100644 |
| index 0000000..aea234a |
| --- /dev/null |
| +++ b/dcap_deployment/docker/docker-compose-ubuntu-2004.yml |
| @@ -0,0 +1,230 @@ |
| +# 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. |
| + |
| +version: '3.7' |
| + |
| +services: |
| + teaclave-authentication-service: |
| + build: |
| + context: ../ |
| + dockerfile: docker/teaclave-rt.ubuntu-2004.Dockerfile |
| + ports: |
| + - 7776:7776 |
| + expose: |
| + - 7776 |
| + - 17776 |
| + volumes: |
| + - ./runtime.config.toml:/teaclave/runtime.config.toml |
| + - /cleanroom-demo-data:/cleanroom-demo-data |
| + - /etc/aesmd.conf:/etc/aesmd.conf |
| + - ./hosts:/etc/hosts |
| + working_dir: /teaclave |
| + environment: |
| + - AS_SPID |
| + - AS_KEY |
| + - AS_ALGO |
| + - AS_URL |
| + - TEACLAVE_LOG |
| + entrypoint: ./teaclave_authentication_service |
| + container_name: teaclave-authentication-service |
| + networks: |
| + api: |
| + internal: |
| + |
| + teaclave-frontend-service: |
| + build: |
| + context: ../ |
| + dockerfile: docker/teaclave-rt.ubuntu-2004.Dockerfile |
| + ports: |
| + - 7777:7777 |
| + expose: |
| + - 7777 |
| + volumes: |
| + - ./runtime.config.toml:/teaclave/runtime.config.toml |
| + - /etc/aesmd.conf:/etc/aesmd.conf |
| + - ./hosts:/etc/hosts |
| + working_dir: /teaclave |
| + environment: |
| + - AS_SPID |
| + - AS_KEY |
| + - AS_ALGO |
| + - AS_URL |
| + - TEACLAVE_LOG |
| + entrypoint: ./teaclave_frontend_service |
| + depends_on: |
| + - teaclave-management-service |
| + container_name: teaclave-frontend-service |
| + networks: |
| + api: |
| + internal: |
| + |
| + teaclave-management-service: |
| + build: |
| + context: ../ |
| + dockerfile: docker/teaclave-rt.ubuntu-2004.Dockerfile |
| + expose: |
| + - 17777 |
| + volumes: |
| + - ./runtime.config.toml:/teaclave/runtime.config.toml |
| + - /cleanroom-demo-data:/cleanroom-demo-data |
| + - /etc/aesmd.conf:/etc/aesmd.conf |
| + - ./hosts:/etc/hosts |
| + working_dir: /teaclave |
| + environment: |
| + - AS_SPID |
| + - AS_KEY |
| + - AS_ALGO |
| + - AS_URL |
| + - TEACLAVE_LOG |
| + entrypoint: ./teaclave_management_service |
| + depends_on: |
| + - teaclave-storage-service |
| + - teaclave-access-control-service |
| + container_name: teaclave-management-service |
| + networks: |
| + internal: |
| + |
| + teaclave-storage-service: |
| + build: |
| + context: ../ |
| + dockerfile: docker/teaclave-rt.ubuntu-2004.Dockerfile |
| + expose: |
| + - 17778 |
| + volumes: |
| + - ./runtime.config.toml:/teaclave/runtime.config.toml |
| + - /cleanroom-demo-data:/cleanroom-demo-data |
| + - /etc/aesmd.conf:/etc/aesmd.conf |
| + - ./hosts:/etc/hosts |
| + working_dir: /teaclave |
| + environment: |
| + - AS_SPID |
| + - AS_KEY |
| + - AS_ALGO |
| + - AS_URL |
| + - TEACLAVE_LOG |
| + entrypoint: ./teaclave_storage_service |
| + container_name: teaclave-storage-service |
| + networks: |
| + internal: |
| + |
| + teaclave-access-control-service: |
| + build: |
| + context: ../ |
| + dockerfile: docker/teaclave-rt.ubuntu-2004.Dockerfile |
| + expose: |
| + - 17779 |
| + volumes: |
| + - ./runtime.config.toml:/teaclave/runtime.config.toml |
| + - /etc/aesmd.conf:/etc/aesmd.conf |
| + - ./hosts:/etc/hosts |
| + working_dir: /teaclave |
| + environment: |
| + - AS_SPID |
| + - AS_KEY |
| + - AS_ALGO |
| + - AS_URL |
| + - TEACLAVE_LOG |
| + container_name: teaclave-access-control-service |
| + entrypoint: ./teaclave_access_control_service |
| + networks: |
| + internal: |
| + |
| + teaclave-execution-service: |
| + build: |
| + context: ../ |
| + dockerfile: docker/teaclave-rt.ubuntu-2004.Dockerfile |
| + expose: |
| + - 17770 |
| + volumes: |
| + - ./runtime.config.toml:/teaclave/runtime.config.toml |
| + - /cleanroom-demo-data:/cleanroom-demo-data |
| + - /etc/aesmd.conf:/etc/aesmd.conf |
| + - ./hosts:/etc/hosts |
| + working_dir: /teaclave |
| + environment: |
| + - AS_SPID |
| + - AS_KEY |
| + - AS_ALGO |
| + - AS_URL |
| + - TEACLAVE_LOG |
| + entrypoint: ./teaclave_execution_service |
| + container_name: teaclave-execution-service |
| + restart: always |
| + depends_on: |
| + - teaclave-scheduler-service |
| + networks: |
| + internal: |
| + fs: |
| + |
| + teaclave-scheduler-service: |
| + build: |
| + context: ../ |
| + dockerfile: docker/teaclave-rt.ubuntu-2004.Dockerfile |
| + expose: |
| + - 17780 |
| + volumes: |
| + - ./runtime.config.toml:/teaclave/runtime.config.toml |
| + - /etc/aesmd.conf:/etc/aesmd.conf |
| + - ./hosts:/etc/hosts |
| + working_dir: /teaclave |
| + environment: |
| + - AS_SPID |
| + - AS_KEY |
| + - AS_ALGO |
| + - AS_URL |
| + - TEACLAVE_LOG |
| + entrypoint: ./teaclave_scheduler_service |
| + container_name: teaclave-scheduler-service |
| + depends_on: |
| + - teaclave-storage-service |
| + networks: |
| + internal: |
| + |
| + teaclave-file-service: |
| + image: python:3 |
| + container_name: teaclave-file-service |
| + volumes: |
| + - ../release/tests:/teaclave-file-service |
| + - /cleanroom-demo-data/file:/cleanroom-demo-data/file |
| + working_dir: /cleanroom-demo-data/file |
| + ports: |
| + - 6789:6789 |
| + expose: |
| + - 6789 |
| + entrypoint: /teaclave-file-service/scripts/simple_http_server.py |
| + networks: |
| + fs: |
| + |
| + teaclave-file-external-service: |
| + image: python:3 |
| + container_name: teaclave-file-external-service |
| + volumes: |
| + - ../release/tests:/teaclave-file-external-service |
| + - /cleanroom-demo-data/file:/cleanroom-demo-data/file |
| + working_dir: /cleanroom-demo-data/file |
| + ports: |
| + - 7789:7789 |
| + expose: |
| + - 7789 |
| + entrypoint: ["/teaclave-file-external-service/scripts/auth_http_server.py", "7789", "001dda666e88921cfa9cecd5935d387b17b16c70022fe119ce69dee0ec84e3d9"] |
| + networks: |
| + fs: |
| + |
| +networks: |
| + internal: |
| + api: |
| + fs: |
| diff --git a/dcap_deployment/docker/hosts b/dcap_deployment/docker/hosts |
| new file mode 100644 |
| index 0000000..7e5fe60 |
| --- /dev/null |
| +++ b/dcap_deployment/docker/hosts |
| @@ -0,0 +1,2 @@ |
| +172.17.0.1 api-as-dev.cleanroom.com |
| + |
| diff --git a/dcap_deployment/docker/run-teaclave-services.sh b/dcap_deployment/docker/run-teaclave-services.sh |
| new file mode 100644 |
| index 0000000..581edcd |
| --- /dev/null |
| +++ b/dcap_deployment/docker/run-teaclave-services.sh |
| @@ -0,0 +1,224 @@ |
| +#!/bin/bash |
| + |
| +# 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. |
| + |
| +SGX_DEV_SEL="none" |
| +AESM_SEL="none" |
| + |
| +function sgx_dev_detect() { |
| + local ISGX_DEV=/dev/isgx |
| + local ISGX_DEV_EXIST=false |
| + if [ -c "$ISGX_DEV" ]; then |
| + echo "$ISGX_DEV device detected." |
| + ISGX_DEV_EXIST=true |
| + fi |
| + |
| + local ENCL_DEV=/dev/sgx/enclave |
| + local ENCL_DEV_EXIST=false |
| + if [ -L "$ENCL_DEV" ] && [ -c $(realpath $ENCL_DEV) ]; then |
| + echo "$ENCL_DEV device detected." |
| + ENCL_DEV_EXIST=true |
| + fi |
| + |
| + local PROV_DEV=/dev/sgx/provision |
| + local PROV_DEV_EXIST=false |
| + if [ -L "$PROV_DEV" ] && [ -c $(realpath $PROV_DEV) ]; then |
| + echo "$PROV_DEV device detected." |
| + PROV_DEV_EXIST=true |
| + fi |
| + |
| + if ($ISGX_DEV_EXIST && $ENCL_DEV_EXIST && $PROV_DEV_EXIST); then |
| + PS3='Please enter your choice: ' |
| + options=("ISGX device" "DCAP device" "Quit") |
| + select opt in "${options[@]}" |
| + do |
| + case $opt in |
| + "ISGX device") |
| + echo "you chose $opt" |
| + SGX_DEV_SEL="isgx" |
| + break |
| + ;; |
| + "DCAP device") |
| + echo "you chose $opt" |
| + SGX_DEV_SEL="dcap" |
| + break |
| + ;; |
| + "Quit") |
| + exit 1 |
| + ;; |
| + *) echo "invalid option $REPLY" ;; |
| + esac |
| + done |
| + else |
| + if $ISGX_DEV_EXIST; then |
| + SGX_DEV_SEL="isgx" |
| + fi |
| + if ($ENCL_DEV_EXIST && $PROV_DEV_EXIST); then |
| + SGX_DEV_SEL="dcap" |
| + fi |
| + fi |
| +} |
| + |
| +function aesm_detect() { |
| + local AESM_SOCK=/var/run/aesmd/aesm.socket |
| + local AESM_SOCK_EXIST=false |
| + if [ -S "$AESM_SOCK" ]; then |
| + echo "$AESM_SOCK socket detected." |
| + AESM_SOCK_EXIST=true |
| + fi |
| + |
| + local AESM_VOL=aesmd-socket |
| + local AESM_VOL_EXIST=false |
| + if docker volume inspect $AESM_VOL 2>&1 > /dev/null ; then |
| + echo "$AESM_VOL volume detected." |
| + AESM_VOL_EXIST=true |
| + fi |
| + |
| + if ($AESM_SOCK_EXIST && $AESM_VOL_EXIST); then |
| + PS3='Please enter your choice: ' |
| + options=("$AESM_SOCK socket" "$AESM_VOL volume" "Quit") |
| + select opt in "${options[@]}" |
| + do |
| + case $opt in |
| + "$AESM_SOCK socket") |
| + echo "you chose $opt" |
| + AESM_SEL="sock" |
| + break |
| + ;; |
| + "$AESM_VOL volume") |
| + echo "you chose $opt" |
| + AESM_SEL="vol" |
| + break |
| + ;; |
| + "Quit") |
| + exit 1 |
| + ;; |
| + *) echo "invalid option $REPLY" ;; |
| + esac |
| + done |
| + else |
| + if $AESM_SOCK_EXIST; then |
| + AESM_SEL="sock" |
| + fi |
| + if $AESM_VOL_EXIST; then |
| + AESM_SEL="vol" |
| + fi |
| + fi |
| +} |
| + |
| +function usage { |
| + echo "Usage: $(basename $0) [-hdbm:]" 2>&1 |
| + echo ' -h shows usage' |
| + echo ' -m run mode (default: sgx)' |
| + echo ' -d detached mode' |
| + echo ' -b build or rebuild services' |
| + echo 'Available run modes: sim, sgx' |
| + exit 1 |
| +} |
| + |
| +RUN_MODE="sgx" |
| +DETACH_ARG="" |
| +optstring="hdbm:" |
| +while getopts ${optstring} arg; do |
| + case ${arg} in |
| + h) |
| + echo "showing usage!" |
| + usage |
| + ;; |
| + d) |
| + DETACH_ARG="-d" |
| + ;; |
| + b) |
| + BUILD_ARG="--build" |
| + ;; |
| + m) |
| + RUN_MODE=$OPTARG |
| + ;; |
| + esac |
| +done |
| + |
| +shift $((OPTIND-1)) |
| + |
| +case $RUN_MODE in |
| + "sgx") |
| + sgx_dev_detect |
| + aesm_detect |
| + ;; |
| + "sim") |
| + ;; |
| + *) |
| + echo "The specified run mode: $RUN_MODE is not recognized." |
| + usage |
| + ;; |
| +esac |
| + |
| +OV_PREFIX="docker-compose-" |
| +OV_SUFFIX=".override.yml" |
| +SGX_DEV_OV_FILE="" |
| +AESM_OV_FILE="" |
| +case $SGX_DEV_SEL in |
| + "isgx") |
| + SGX_DEV_OV_FILE="isgx-dev" |
| + ;; |
| + "dcap") |
| + SGX_DEV_OV_FILE="dcap-dev" |
| + ;; |
| + "none") |
| + ;; |
| + *) |
| + echo "Invalid SGX device." |
| + exit 2 |
| + ;; |
| +esac |
| +SGX_DEV_OV_FILE="${OV_PREFIX}${SGX_DEV_OV_FILE}${OV_SUFFIX}" |
| + |
| +case $AESM_SEL in |
| + "sock") |
| + AESM_OV_FILE="aesm-socket" |
| + ;; |
| + "vol") |
| + AESM_OV_FILE="aesm-vol" |
| + ;; |
| + "none") |
| + ;; |
| + *) |
| + echo "Invalid AESM service." |
| + exit 2 |
| + ;; |
| +esac |
| +AESM_OV_FILE="${OV_PREFIX}${AESM_OV_FILE}${OV_SUFFIX}" |
| + |
| +DOCKER_COMPOSE_FILE="docker-compose-ubuntu-1804.yml" |
| +DC_ARGS="" |
| +if [ "$RUN_MODE" == "sgx" ]; then |
| + if [ "$SGX_DEV_SEL" == "none" ]; then |
| + echo "Cannot find a valid sgx device." |
| + exit 3 |
| + fi |
| + if [ "$AESM_SEL" == "none" ]; then |
| + echo "Cannot find a valid aesm service." |
| + exit 6 |
| + fi |
| + DC_ARGS="-f $DOCKER_COMPOSE_FILE -f $SGX_DEV_OV_FILE -f $AESM_OV_FILE" |
| +else |
| + DC_ARGS="-f $DOCKER_COMPOSE_FILE" |
| +fi |
| + |
| +echo COMMAND: docker-compose ${DC_ARGS} up ${DETACH_ARG} ${BUILD_ARG} |
| + |
| +#docker-compose ${DC_ARGS} up ${DETACH_ARG} ${BUILD_ARG} --build |
| diff --git a/dcap_deployment/docker/run.env b/dcap_deployment/docker/run.env |
| new file mode 100644 |
| index 0000000..25d16de |
| --- /dev/null |
| +++ b/dcap_deployment/docker/run.env |
| @@ -0,0 +1,4 @@ |
| +export AS_ALGO=sgx_ecdsa |
| +export AS_URL=https://api-as-dev.cleanroom.com:8080 |
| +export AS_KEY="00000000000000000000000000000000" |
| +export AS_SPID="00000000000000000000000000000000" |
| diff --git a/dcap_deployment/docker/runtime.config.toml b/dcap_deployment/docker/runtime.config.toml |
| new file mode 100644 |
| index 0000000..e5a7297 |
| --- /dev/null |
| +++ b/dcap_deployment/docker/runtime.config.toml |
| @@ -0,0 +1,51 @@ |
| +# 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. |
| + |
| +# Teaclave Runtime Config |
| +# |
| +# Note that this config is loaded at running time. We don't have to trust the |
| +# content though. Maliciously crafted config from this file will not break data |
| +# confidentiality/integrity. |
| + |
| +[api_endpoints] |
| +authentication = { listen_address = "0.0.0.0:7776" } |
| +frontend = { listen_address = "0.0.0.0:7777" } |
| + |
| +[internal_endpoints] |
| +authentication = { listen_address = "0.0.0.0:17776", advertised_address = "teaclave-authentication-service:17776" } |
| +management = { listen_address = "0.0.0.0:17777", advertised_address = "teaclave-management-service:17777" } |
| +storage = { listen_address = "0.0.0.0:17778", advertised_address = "teaclave-storage-service:17778" } |
| +access_control = { listen_address = "0.0.0.0:17779", advertised_address = "teaclave-access-control-service:17779" } |
| +execution = { listen_address = "0.0.0.0:17770", advertised_address = "teaclave-execution-service:17770" } |
| +scheduler = { listen_address = "0.0.0.0:17780", advertised_address = "teaclave-scheduler-service:17780" } |
| + |
| +[audit] |
| +enclave_info = { path = "enclave_info.toml" } |
| +auditor_signatures = [ |
| + { path = "auditors/godzilla/godzilla.sign.sha256" }, |
| + { path = "auditors/optimus_prime/optimus_prime.sign.sha256" }, |
| + { path = "auditors/albus_dumbledore/albus_dumbledore.sign.sha256" }, |
| +] |
| + |
| +[attestation] |
| +algorithm = "sgx_ecdsa" |
| +url = "https://api-as-dev.cleanroom.com:8080" |
| +key = "00000000000000000000000000000000" |
| +spid = "00000000000000000000000000000000" |
| + |
| +[mount] |
| +fusion_base_dir = "/cleanroom-demo-data" |
| diff --git a/dcap_deployment/docker/teaclave-rt.ubuntu-2004.Dockerfile b/dcap_deployment/docker/teaclave-rt.ubuntu-2004.Dockerfile |
| new file mode 100644 |
| index 0000000..5bd4261 |
| --- /dev/null |
| +++ b/dcap_deployment/docker/teaclave-rt.ubuntu-2004.Dockerfile |
| @@ -0,0 +1,81 @@ |
| +# 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. |
| + |
| +FROM ubuntu:20.04 |
| + |
| +ENV VERSION 2.15.101.1-focal1 |
| +ENV SGX_DOWNLOAD_URL_BASE "https://download.01.org/intel-sgx/sgx-linux/2.15.1/distro/ubuntu20.04-server/" |
| +ENV SGX_LINUX_X64_SDK sgx_linux_x64_sdk_2.15.101.1.bin |
| +ENV SGX_LINUX_X64_SDK_URL "$SGX_DOWNLOAD_URL_BASE/$SGX_LINUX_X64_SDK" |
| + |
| +ENV DEBIAN_FRONTEND=noninteractive |
| + |
| +RUN apt-get update && apt-get install -q -y \ |
| + libcurl4-openssl-dev \ |
| + libprotobuf-dev \ |
| + curl \ |
| + pkg-config \ |
| + wget \ |
| + build-essential \ |
| + gpg-agent |
| + |
| +RUN echo 'deb [arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu focal main' | \ |
| + tee /etc/apt/sources.list.d/intel-sgx.list |
| +RUN curl -fsSL https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | apt-key add - |
| + |
| +RUN apt-get update && apt-get install -q -y \ |
| + libsgx-launch=$VERSION \ |
| + libsgx-urts=$VERSION \ |
| + libsgx-quote-ex=$VERSION \ |
| + libsgx-uae-service=$VERSION |
| +RUN mkdir /etc/init |
| + |
| +# Install Intel SGX SDK for libsgx_urts_sim.so |
| +RUN wget $SGX_LINUX_X64_SDK_URL && \ |
| + chmod u+x $SGX_LINUX_X64_SDK && \ |
| + echo -e 'no\n/opt' | ./$SGX_LINUX_X64_SDK && \ |
| + rm $SGX_LINUX_X64_SDK && \ |
| + echo 'source /opt/sgxsdk/environment' >> /etc/environment |
| +ENV LD_LIBRARY_PATH=/opt/sgxsdk/sdk_libs |
| + |
| +# Make a directory for fusion data. Since we are in the single machine mode, |
| +# there is no need to mount a network file system. |
| +RUN mkdir -p /tmp/fusion_data |
| + |
| +ADD release/services/teaclave_frontend_service /teaclave/ |
| +ADD release/services/teaclave_frontend_service_enclave.signed.so /teaclave/ |
| + |
| +ADD release/services/teaclave_authentication_service /teaclave/ |
| +ADD release/services/teaclave_authentication_service_enclave.signed.so /teaclave/ |
| + |
| +ADD release/services/teaclave_management_service /teaclave/ |
| +ADD release/services/teaclave_management_service_enclave.signed.so /teaclave/ |
| + |
| +ADD release/services/teaclave_scheduler_service /teaclave/ |
| +ADD release/services/teaclave_scheduler_service_enclave.signed.so /teaclave/ |
| + |
| +ADD release/services/teaclave_access_control_service /teaclave/ |
| +ADD release/services/teaclave_access_control_service_enclave.signed.so /teaclave/ |
| + |
| +ADD release/services/teaclave_storage_service /teaclave/ |
| +ADD release/services/teaclave_storage_service_enclave.signed.so /teaclave/ |
| + |
| +ADD release/services/teaclave_execution_service /teaclave/ |
| +ADD release/services/teaclave_execution_service_enclave.signed.so /teaclave/ |
| + |
| +ADD release/services/enclave_info.toml /teaclave/ |
| +ADD release/services/auditors /teaclave/auditors |
| diff --git a/dcap_deployment/pack_publish.sh b/dcap_deployment/pack_publish.sh |
| new file mode 100755 |
| index 0000000..9f96467 |
| --- /dev/null |
| +++ b/dcap_deployment/pack_publish.sh |
| @@ -0,0 +1,37 @@ |
| +#!/bin/bash |
| + |
| +DEFAULT_PUBLISH_DIR=/xlabfs/shared/teaclave-release |
| +DEFAULT_VERSION_PREFIX=="0.0.6" |
| +DEFAULT_REPO=$HOME/dcap-release/incubator-teaclave |
| + |
| +read -p "Enter Repo Path [$DEFAULT_REPO]: " repo |
| +repo=${repo:-$DEFAULT_REPO} |
| + |
| +read -p "Enter publish dir [$DEFAULT_PUBLISH_DIR]: " publish_dir |
| +publish_dir=${publish_dir:-$DEFAULT_PUBLISH_DIR} |
| + |
| +read -p "Enter version prefix [$DEFAULT_VERSION_PREFIX]: " version_prefix |
| +version_prefix=${version_prefix:-$DEFAULT_VERSION_PREFIX} |
| + |
| +commit_id=$(git rev-parse --short HEAD) |
| +version="$version_prefix_$commit_id" |
| + |
| +out="dcap_service_release_$version" |
| +mkdir $out |
| +cp -r $repo/release $out/release |
| +cp -r $repo/dcap_deployment/docker $out/docker |
| +tar czvf $out.tgz $out |
| +cp $out.tgz $publish_dir/ |
| +rm $out.tgz |
| +rm -rf $out |
| + |
| +out="dcap_sdk_release_$version" |
| +mkdir $out |
| +cp -r $repo/sdk/python $out/python |
| +cp $repo/release/services/enclave_info.toml $out/enclave_info.toml |
| +cp $repo/keys/dcap_root_ca_cert.pem $out/dcap_root_cert.pem |
| +tar czvf $out.tgz $out |
| +cp $out.tgz $publish_dir/ |
| +rm $out.tgz |
| +rm -rf $out |
| + |
| diff --git a/dcap_deployment/pull_latest_deploy.sh b/dcap_deployment/pull_latest_deploy.sh |
| new file mode 100755 |
| index 0000000..3e2db77 |
| --- /dev/null |
| +++ b/dcap_deployment/pull_latest_deploy.sh |
| @@ -0,0 +1,41 @@ |
| +#!/bin/bash |
| +set -e |
| + |
| +DEFAULT_PUBLISH_BASE=/xlabfs/shared/teaclave-release |
| +DEFAULT_DEPLOY_BASE=$HOME/teaclave-dcap-deploy |
| + |
| +read -p "Confirm Publish Path [$DEFAULT_PUBLISH_BASE]: " PUBLISH_BASE |
| +PUBLISH_BASE=${PUBLISH_BASE:-$DEFAULT_PUBLISH_BASE} |
| + |
| +read -p "Confirm Deploy Path [$DEFAULT_DEPLOY_BASE]: " DEPLOY_BASE |
| +DEPLOY_BASE=${DEPLOY_BASE:-$DEFAULT_DEPLOY_BASE} |
| + |
| +mkdir -p $DEPLOY_BASE |
| +mkdir -p $DEPLOY_BASE/logs |
| + |
| +release_tar_path=`ls -t $PUBLISH_BASE/dcap_service_release*.tgz | head -1` |
| +echo "[+] Latest relase tar is : $release_tar_path ..." |
| +cp $release_tar_path $DEPLOY_BASE |
| + |
| +echo "[+] Copy $release_tar_path to $DEPLOY_BASE ..." |
| +filename=$(basename -- "$release_tar_path") |
| +tar_name="${filename%%.tgz}" |
| + |
| + |
| +echo "[+] Extract $tar_name.tgz ..." |
| +pushd $DEPLOY_BASE |
| +tar xzf $tar_name.tgz |
| + |
| +log_path=$DEPLOY_BASE/logs/$tar_name.log |
| +echo "[+] Start service and logging to $log_path .." |
| + |
| +pushd $DEPLOY_BASE/$tar_name/docker/ |
| +./deploy_compose_build.sh |
| +popd |
| + |
| +echo "Please stop the previous depyloyment and run the following command in a tmux session ... " |
| + |
| +echo "cd $DEPLOY_BASE/$tar_name/docker/" |
| +echo "TEACLAVE_LOG=info ./deploy_compose_run.sh >> $log_path 2>&1" |
| + |
| +popd |
| diff --git a/docker/docker-compose-ubuntu-1804.yml b/docker/docker-compose-ubuntu-1804.yml |
| index ad718b5..bb55584 100644 |
| --- a/docker/docker-compose-ubuntu-1804.yml |
| +++ b/docker/docker-compose-ubuntu-1804.yml |
| @@ -75,6 +75,7 @@ services: |
| - 17777 |
| volumes: |
| - ./runtime.config.toml:/teaclave/runtime.config.toml |
| + - /tmp/fusion_data:/tmp/fusion_data |
| working_dir: /teaclave |
| environment: |
| - AS_SPID |
| @@ -138,6 +139,7 @@ services: |
| - 17770 |
| volumes: |
| - ./runtime.config.toml:/teaclave/runtime.config.toml |
| + - /tmp/fusion_data:/tmp/fusion_data |
| working_dir: /teaclave |
| environment: |
| - AS_SPID |
| @@ -147,6 +149,7 @@ services: |
| - TEACLAVE_LOG |
| entrypoint: ./teaclave_execution_service |
| container_name: teaclave-execution-service |
| + restart: always |
| depends_on: |
| - teaclave-scheduler-service |
| networks: |
| @@ -181,6 +184,10 @@ services: |
| volumes: |
| - ../tests:/teaclave-file-service |
| working_dir: /teaclave-file-service |
| + ports: |
| + - 6789:6789 |
| + expose: |
| + - 6789 |
| entrypoint: ./scripts/simple_http_server.py |
| networks: |
| fs: |
| diff --git a/docker/docker-compose-ubuntu-2004.yml b/docker/docker-compose-ubuntu-2004.yml |
| index a639ec7..103dc3b 100644 |
| --- a/docker/docker-compose-ubuntu-2004.yml |
| +++ b/docker/docker-compose-ubuntu-2004.yml |
| @@ -149,6 +149,7 @@ services: |
| - TEACLAVE_LOG |
| entrypoint: ./teaclave_execution_service |
| container_name: teaclave-execution-service |
| + restart: always |
| depends_on: |
| - teaclave-scheduler-service |
| networks: |
| diff --git a/docker/run-teaclave-services.sh b/docker/run-teaclave-services.sh |
| index a711fd0..d9b4fce 100755 |
| --- a/docker/run-teaclave-services.sh |
| +++ b/docker/run-teaclave-services.sh |
| @@ -84,7 +84,7 @@ function aesm_detect() { |
| |
| local AESM_VOL=aesmd-socket |
| local AESM_VOL_EXIST=false |
| - if docker volume inspect $AESM_VOL > /dev/null 2>&1; then |
| + if docker volume inspect $AESM_VOL 2>&1 > /dev/null ; then |
| echo "$AESM_VOL volume detected." |
| AESM_VOL_EXIST=true |
| fi |
| diff --git a/docs/README.md b/docs/README.md |
| index 0366c56..875ca7c 100644 |
| --- a/docs/README.md |
| +++ b/docs/README.md |
| @@ -25,7 +25,6 @@ permalink: /docs/ |
| |
| ## Contribute |
| |
| -- [Release Guide](release-guide.md) |
| - [Development Tips](development-tips.md) |
| - [Rust Development Guideline](rust-guideline.md) |
| |
| diff --git a/docs/release-guide.md b/docs/release-guide.md |
| deleted file mode 100644 |
| index 57f69f8..0000000 |
| --- a/docs/release-guide.md |
| +++ /dev/null |
| @@ -1,282 +0,0 @@ |
| ---- |
| -permalink: /docs/release-guide |
| ---- |
| - |
| -# Release Guide |
| - |
| -This document guide you through how to prepare and publish an official release. |
| -Releasing a new version in the community contains multiple steps, here is an |
| -overview. |
| - |
| -[[toc]] |
| - |
| -## Prepare the Release Notes |
| - |
| -For a new release, you should first prepare the release note. Release note |
| -contains summaries of new features, enhancements, bug fixes, |
| -docs, known issues, and deprecation, etc. You can see the notes of |
| -[past release](https://github.com/apache/incubator-teaclave/releases) as an example. |
| - |
| -## Prepare the GPG Signing Key |
| - |
| -You can skip this section if you have already uploaded your key. That is, the |
| -GPG signing key has been added in the following places: |
| - - The KEYS file in repo (<https://github.com/apache/incubator-teaclave/blob/master/KEYS>) |
| - - Apache release dist sever (<https://dist.apache.org/repos/dist/release/incubator/teaclave/KEYS>) |
| - |
| -If you are the first to publish a release, please follow this instruction to |
| -generating and uplaoding keys. |
| - |
| -To generate GPG key, please refer to |
| -<https://www.apache.org/dev/openpgp.html#generate-key> for details. |
| - |
| -If you want to do the release on another machine, you can transfer your GPG key |
| -to that machine via the `gpg --export` and `gpg --import` commands. |
| - |
| -The last step is to update the KEYS file with your code signing key. Check in |
| -the changes to the main branch of the repository, as well as ASF SVN, |
| - |
| -Here is an instruction of editing the KEYS file in the ASF SVN. |
| - |
| -``` |
| -# the --depth=files will avoid checkout existing folders |
| -svn co --depth=files "https://dist.apache.org/repos/dist/dev/incubator/teaclave" svn-dev-teaclave |
| -cd svn-dev-teaclave |
| -# edit KEYS file |
| -svn ci --username $ASF_USERNAME --password "$ASF_PASSWORD" -m "Update KEYS" |
| -# update downloads.apache.org |
| -svn rm --username $ASF_USERNAME --password "$ASF_PASSWORD" https://dist.apache.org/repos/dist/release/incubator/teaclave/KEYS -m "Update KEYS" |
| -svn cp --username $ASF_USERNAME --password "$ASF_PASSWORD" https://dist.apache.org/repos/dist/dev/incubator/teaclave/KEYS https://dist.apache.org/repos/dist/release/incubator/teaclave/ -m "Update KEYS" |
| -``` |
| - |
| -## Cut a Release Candidate |
| - |
| -To cut a release candidate, one needs to first cut a branch from the main branch |
| -using selected version string. We follow the [semantic versioning](https://semver.org/) |
| -guidelines for new version string. In short, x.y.z means MAJOR.MINOR.PATCH. Since we |
| -already have the release note, we can decide the version string to be released |
| -based on the changes. |
| - |
| -Note that in our workflow, the main branch should be freezed during the |
| -releasing period, i.e, no new features and enhancements can be merged into it. |
| -Only changes on this release can be merged and committed into the releasing |
| -branch. |
| - |
| -For example, to release version 1.0.0, let us first create a new branch |
| -`release-v1.0.0` from the main branch. |
| - |
| -``` |
| -git clone https://github.com/apache/incubator-teaclave |
| -cd incubator-teaclave |
| -git checkout -b release-v1.0.0 |
| -``` |
| - |
| -The next step is to do a complete version bumping (e.g., changing files which |
| -contain versions and bump them from v0.9.0 to v1.0.0). Note that this affect |
| -multiple files in different languages. Then, commit the changes to this |
| -releasing branch. Other bug fixes and docs improvements can be also commited at |
| -this time. |
| - |
| -When cleanups are done, make sure all tests can be passed. Then, add a tag with |
| -the current commit in the form of "v1.0.0-rc.1" where 1 means it's the first |
| -release candidate. You can add the tag using git or add on GitHub. |
| - |
| -Using Git: |
| -``` |
| -git tag v1.0.0-rc.1 |
| -git push origin v1.0.0-rc.1 |
| -``` |
| - |
| -## Create Release Artifacts |
| - |
| -Create the source code artifacts, including a self-contained tarball without git |
| -history, a signature file signed by keys in the KEYS file, and a sha256 hash |
| -file. |
| - |
| -``` |
| -git clone git@github.com:apache/incubator-teaclave.git apache-teaclave-1.0.0-rc.1-incubating |
| -cd apache-teaclave-1.0.0-rc.1-incubating |
| -git checkout v1.0.0-rc.1 |
| -mkdir build && cd build && cmake .. && cd .. # This will init submodules and apply patches |
| -rm -rf build |
| -find . -name ".git" -print0 | xargs -0 rm -rf # Remove all .git directories |
| -cd .. |
| -tar czvf apache-teaclave-1.0.0-rc.1-incubating.tar.gz apache-teaclave-1.0.0-rc.1-incubating |
| -``` |
| - |
| -Use your GPG key to sign the created artifact. First make sure your GPG is set |
| -to use the correct private key, |
| - |
| -``` |
| -$ gpg --list-key |
| -/home/user/.gnupg/pubring.kbx |
| ------------------------------------- |
| -pub rsa4096 2020-08-17 [SC] |
| - 154xxx |
| -uid [ unknown] XXX (CODE SIGNING KEY) <xxx@apache.org> |
| -sub rsa4096 2020-08-17 [E] |
| -``` |
| - |
| -``` |
| -gpg -u 154xxx --armor --detach-sign apache-teaclave-1.0.0-rc.1-incubating.tar.gz |
| -sha512sum apache-teaclave-1.0.0-rc.1-incubating.tar.gz > apache-teaclave-1.0.0-rc.1-incubating.tar.gz.sha512 |
| -``` |
| - |
| -At this point, we got three files in the release artifacts: |
| - - `apache-teaclave-1.0.0-rc.1-incubating.tar.gz`: source code tarball |
| - - `apache-teaclave-1.0.0-rc.1-incubating.tar.gz.asc`: signature |
| - - `apache-teaclave-1.0.0-rc.1-incubating.tar.gz.sha512`: SHA512 hash |
| - |
| -## Check the Artifacts |
| - |
| -We suggest to double check the release artifacts, e.g., verify the signature, |
| -hash value and build from scratch. |
| -There is a [checklist](https://cwiki.apache.org/confluence/display/INCUBATOR/Incubator+Release+Checklist) which can help the process. |
| - |
| -## Upload the Release Candidate Artifacts |
| - |
| -The release artifacts needs to be uploaded to ASF SVN, |
| - |
| -``` |
| -# the --depth=files will avoid checkout existing folders |
| -svn co --depth=files "https://dist.apache.org/repos/dist/dev/incubator/teaclave" svn-dev-teaclave |
| -cd svn-dev-teaclave |
| -mkdir 1.0.0-rc.1 |
| -# copy files (.tar.gz, .asc, .sha512) into it |
| -svn add 1.0.0-rc.1 |
| -svn ci --username $ASF_USERNAME --password "$ASF_PASSWORD" -m "Add 1.0.0-rc.1" |
| -``` |
| - |
| -## Publish the Pre-Release on GitHub |
| - |
| -The next step is to publish a pre-release. Go to the GitHub repo's "Releases" |
| -tab and click "Draft a new release". |
| - |
| -- Choose a tag and select v1.0.0-rc.1. |
| -- Copy and paste the release note draft into the description box. |
| -- Select "This is a pre-release". |
| -- Upload the artifacts created by the previous steps. |
| -- Click "Publish release". |
| - |
| -## Call a Vote on the Release Candidate |
| - |
| -There are two votes need to be done for releasing a incubating project. |
| -The first vote takes place on the Apache Teaclave developers list |
| -(`dev@teaclave.apache.org`). Once it is closed with pass, we can call for the |
| -second in the Apache Incubator general list |
| -(`general@incubator.apache.org`). Look at past voting threads to see how this |
| -proceeds. The email should contains these information. |
| - |
| -- Provide the link to the draft of the release notes in the email |
| -- Provide the link to the release candidate artifacts |
| -- Make sure the email is in text format and the links are correct |
| - |
| -For the dev@ vote, there must be at least 3 binding +1 votes and more +1 votes |
| -than -1 votes. Once the vote is done, you should also send out a summary email |
| -with the totals, with a subject that looks something like `[VOTE][RESULT]`. |
| - |
| -In ASF, votes are open at least 72hrs (3 days). If you don't get enough number |
| -of binding votes within that time, you cannot close the voting deadline. You |
| -need to extend it. |
| - |
| -If the voting fails, the community needs to modified the release accordingly, |
| -create a new release candidate and re-run the voting process. |
| - |
| -Here are some examples: |
| - |
| -**Vote in the dev@teaclave list**: |
| - |
| -- subject: [VOTE] Release Apache Teaclave (incubating) v0.3.0-rc.1 |
| -- to: dev@teaclave.apache.org |
| -- link: <https://lists.apache.org/thread/9dzwv0y9l9qf9hol2rpwv85ns1xfgn7k> |
| - |
| -**Result in the dev@teaclave list**: |
| - |
| -- subject: [RESULT][VOTE] Release Apache Teaclave (incubating) v0.3.0-rc.1 |
| -- to: dev@teaclave.apache.org |
| -- link: <https://lists.apache.org/thread/tyqhx2m9q0z1qg7dbxczf58nnpvxfzrn> |
| - |
| -**Vote in the general@incubator list**: |
| - |
| -- subject: [VOTE] Release Apache Teaclave (incubating) v0.3.0-rc.1 |
| -- to: general@incubator.apache.org |
| -- link: <https://lists.apache.org/thread/mrwl41shgx60p432mw2lc6zcdw1lk6lk> |
| - |
| -**Result in the general@incubator list**: |
| - |
| -- subject: [RESULT][VOTE] Release Apache Teaclave (incubating) v0.3.0-rc.1 |
| -- to: dev@teaclave.apache.org |
| -- link: <https://lists.apache.org/thread/gbv3f7l9bf6t1876byqm1v4stsw7g00z> |
| - |
| -## Post the Release |
| - |
| -After the vote passes, we need to crate the final release artifacts: |
| - |
| -``` |
| -cd svn-dev-teaclave |
| -mkdir 1.0.0 |
| -# copy RC files (.tar.gz, .asc, .sha512) into it and rename them |
| -cp 1.0.0-rc.1/apache-teaclave-1.0.0-rc.1-incubating.tar.gz 1.0.0/apache-teaclave-1.0.0-incubating.tar.gz |
| -cp 1.0.0-rc.1/apache-teaclave-1.0.0-rc.1-incubating.tar.gz.asc 1.0.0/apache-teaclave-1.0.0-incubating.tar.gz.asc |
| -cp 1.0.0-rc.1/apache-teaclave-1.0.0-rc.1-incubating.tar.gz.sha512 1.0.0/apache-teaclave-1.0.0-incubating.tar.gz.sha512 |
| -# edit the file name (i.e., remove the rc version) in the sha512 file |
| -vi 1.0.0/apache-teaclave-1.0.0-incubating.tar.gz.sha512 |
| -svn add 1.0.0 |
| -svn ci --username $ASF_USERNAME --password "$ASF_PASSWORD" -m "Add 1.0.0" |
| -``` |
| - |
| -To upload the binaries to Apache mirrors, you copy the binaries from the dev |
| -directory (this should be where they are voted) to the dist directory. |
| -These artifacts will be automatically propagated to the CDN service. |
| - |
| -``` |
| -export SVN_EDITOR=vim |
| -svn cp https://dist.apache.org/repos/dist/dev/incubator/teaclave/1.0.0 https://dist.apache.org/repos/dist/release/incubator/teaclave/1.0.0 |
| - |
| -# If you've added your signing key to the KEYS file, also update the release copy. |
| -svn co --depth=files "https://dist.apache.org/repos/dist/release/incubator/teaclave" svn-dist-teaclave |
| -curl "https://dist.apache.org/repos/dist/dev/incubator/teaclave/KEYS" > svn-dist-teaclave/KEYS |
| -(cd svn-dist-teaclave && svn ci --username $ASF_USERNAME --password "$ASF_PASSWORD" -m "Update KEYS") |
| -``` |
| - |
| -Merge commits in the release branch to the main branch, create a new release tag |
| -(v1.0.0 in this case) on Github and remove the pre-release candidate tag. |
| - |
| -``` |
| -git checkout master |
| -## merge the release branch and use --ff-only to ensure the commit hash for voting is also in the master branch |
| -git merge release-v1.0.0 --ff-only |
| -git tag v1.0.0 |
| -git push origin v1.0.0 |
| -git push --delete origin v1.0.0-rc.1 |
| -git push --delete origin release-v1.0.0 |
| -``` |
| - |
| -At last update the release notes and corresponding artifacts on GitHub. |
| - |
| -## Update the Website |
| - |
| -The website repository is located at <https://github.com/apache/incubator-teaclave-website>. |
| -Modify the download page to include the release artifacts as well as the GPG |
| -signature and SHA hash. Note that only put the latest version in the download page. |
| -Older releases are archived in the archive site automatically |
| -(<https://archive.apache.org/dist/incubator/teaclave/>). |
| - |
| -Note that the links to the release artifact should start with |
| -`https://www.apache.org/dyn/closer.lua/incubator/teaclave` to better utilize the |
| -Apache CND. You can refer to the previous release link. |
| - |
| - |
| -## Post the Announcement |
| - |
| -Post new version release annoucement to the mailing list, blog and other |
| -channels (Twitter, Discord, etc.). |
| - |
| -**Mailing list example**: |
| -- subject: [ANNOUNCE] Apache Teaclave (incubating) 0.3.0 released |
| -- to: announce@apache.org, dev@teaclave.apache.org |
| -- link: <https://lists.apache.org/thread/frck6z5v135f8c7w64nkgqk86w1soqc7> |
| - |
| -**Blog example**: |
| -- title: Announcing Apache Teaclave (incubating) 0.3.0 |
| -- link: <https://teaclave.apache.org/blog/2021-10-01-announcing-teaclave-0-3-0/> |
| diff --git a/examples/c/builtin_echo.c b/examples/c/builtin_echo.c |
| index 3276be3..9a83835 100644 |
| --- a/examples/c/builtin_echo.c |
| +++ b/examples/c/builtin_echo.c |
| @@ -34,7 +34,7 @@ const char *register_function_request_serialized = QUOTE({ |
| "executor_type" : "builtin", |
| "public" : true, |
| "payload" : [], |
| - "arguments" : ["message"], |
| + "arguments" : [{"key": "message", "default_value": "", "allow_overwrite": true}], |
| "inputs" : [], |
| "outputs" : [], |
| "user_allowlist": [] |
| diff --git a/examples/c/builtin_ordered_set_intersect.c b/examples/c/builtin_ordered_set_intersect.c |
| index 1ce5e57..21d9c43 100644 |
| --- a/examples/c/builtin_ordered_set_intersect.c |
| +++ b/examples/c/builtin_ordered_set_intersect.c |
| @@ -60,7 +60,7 @@ const char *register_function_request_serialized = QUOTE( |
| "executor_type": "builtin", |
| "public": true, |
| "payload": [], |
| - "arguments": ["order"], |
| + "arguments": [{"key": "order", "default_value": "", "allow_overwrite": true}], |
| "inputs": [ |
| {"name": "input_data1", "description": "Client 0 data.", "optional": false}, |
| {"name": "input_data2", "description": "Client 1 data.", "optional": false} |
| diff --git a/examples/python/builtin_cleanroom_algorithm2.py b/examples/python/builtin_cleanroom_algorithm2.py |
| new file mode 100644 |
| index 0000000..76c8830 |
| --- /dev/null |
| +++ b/examples/python/builtin_cleanroom_algorithm2.py |
| @@ -0,0 +1,188 @@ |
| +#!/usr/bin/env python3 |
| + |
| +# 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. |
| + |
| +import sys |
| +import time |
| +import json |
| + |
| +from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap, FunctionArgument |
| +from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| + |
| +# User 0: an algorithm provider. |
| +# User 1: a RNA provider. |
| + |
| + |
| +class UserData: |
| + |
| + def __init__(self, |
| + user_id, |
| + password, |
| + input_url="", |
| + output_url="", |
| + input_cmac=[], |
| + key=[]): |
| + self.user_id = user_id |
| + self.password = password |
| + self.input_url = input_url |
| + self.output_url = output_url |
| + self.input_cmac = input_cmac |
| + self.key = key |
| + |
| + |
| +# If you're using `docker-compose` to start the Teaclave server containers, |
| +# please change `localhost` to `teaclave-file-service` |
| +INPUT_FILE_URL_PREFIX = "http://localhost:6789/fixtures/functions/cleanroom-algorithm2-hash/" |
| +OUTPUT_FILE_URL_PREFIX = "http://localhost:6789/fixtures/functions/cleanroom-algorithm2-hash/" |
| + |
| +# User0 updates the algorithm. User1 sends the RNA information and gets the results. |
| +USER_DATA_0 = UserData("Algorithm Owner", "password", None, None, None, None) |
| + |
| +USER_DATA_1 = UserData("Gene Owner", "password", |
| + INPUT_FILE_URL_PREFIX + "stdout.enc", |
| + OUTPUT_FILE_URL_PREFIX + "result.enc", [ |
| + 0xff, 0xed, 0x3a, 0xe7, 0xef, 0xc9, 0x1f, 0x2c, |
| + 0xd1, 0x24, 0xbf, 0x0b, 0xed, 0xff, 0xb5, 0x1b |
| + ], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) |
| + |
| + |
| +class DataList: |
| + |
| + def __init__(self, data_name, data_id): |
| + self.data_name = data_name |
| + self.data_id = data_id |
| + |
| + |
| +class Client: |
| + |
| + def __init__(self, user_id, user_password): |
| + self.user_id = user_id |
| + self.user_password = user_password |
| + with connect_authentication_service() as client: |
| + print(f"[+] {self.user_id} login") |
| + token = client.user_login(self.user_id, self.user_password) |
| + self.client = connect_frontend_service() |
| + metadata = {"id": self.user_id, "token": token} |
| + self.client.metadata = metadata |
| + |
| + def register_function(self): |
| + client = self.client |
| + |
| + print(f"[+] {self.user_id} registering the algorithm2 function") |
| + function_id = client.register_function( |
| + name="builtin-cleanroom-algorithm2-hash", |
| + description="algorithm2", |
| + executor_type="builtin", |
| + arguments=[FunctionArgument("args"), |
| + FunctionArgument("debug")], |
| + inputs=[FunctionInput("input_file", "protain data.")], |
| + outputs=[FunctionOutput("output_file", "Output data.")]) |
| + return function_id |
| + |
| + def create_task(self, function_id): |
| + print(f"[+] {self.user_id} creating the task") |
| + client = self.client |
| + args = ["algorithm2", "100", "200"] |
| + task_id = client.create_task( |
| + function_id=function_id, |
| + function_arguments=({ |
| + "args": json.dumps(args), |
| + "debug": "false", |
| + }), |
| + executor="builtin", |
| + inputs_ownership=[OwnerList("input_file", [USER_DATA_1.user_id])], |
| + outputs_ownership=[ |
| + OwnerList("output_file", [USER_DATA_1.user_id]) |
| + ]) |
| + return task_id |
| + |
| + def run_task(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} invoking the task") |
| + client.invoke_task(task_id) |
| + |
| + def register_data(self, task_id, input_url, input_cmac, output_url, |
| + file_key, input_label, output_label): |
| + client = self.client |
| + print(f"[+] {self.user_id} registering the input file") |
| + cmac = input_cmac |
| + schema = "teaclave-file-128" |
| + key = file_key |
| + iv = [] |
| + print(input_url) |
| + input_id = client.register_input_file(input_url, schema, key, iv, cmac) |
| + print(output_url) |
| + output_id = client.register_output_file(output_url, schema, key, iv) |
| + print(f"[+] {self.user_id} assigning data to task") |
| + client.assign_data_to_task(task_id, [DataList(input_label, input_id)], |
| + [DataList(output_label, output_id)]) |
| + |
| + def approve_task(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} approving task") |
| + client.approve_task(task_id) |
| + |
| + def get_task_result(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} getting task result") |
| + return bytes(client.get_task_result(task_id)) |
| + |
| + |
| +def main(): |
| + print( |
| + "User 0 (Algorithm owner) registers the function and uploads the algorithm." |
| + ) |
| + print( |
| + "User 1 (Gene Owner) creates the task, uploads the secret data, and retrieves the result." |
| + ) |
| + # Register user |
| + platform_admin = PlatformAdmin("admin", "teaclave") |
| + try: |
| + platform_admin.register_user(USER_DATA_0.user_id, USER_DATA_0.password) |
| + platform_admin.register_user(USER_DATA_1.user_id, USER_DATA_1.password) |
| + except Exception: |
| + pass |
| + user0 = Client(USER_DATA_0.user_id, USER_DATA_0.password) |
| + function_id = user0.register_function() |
| + |
| + start = time.time() |
| + |
| + user1 = Client(USER_DATA_1.user_id, USER_DATA_1.password) |
| + |
| + task_id = user1.create_task(function_id) |
| + user1.register_data(task_id, USER_DATA_1.input_url, USER_DATA_1.input_cmac, |
| + USER_DATA_1.output_url, USER_DATA_1.key, "input_file", |
| + "output_file") |
| + |
| + # user1.approve_task(task_id) |
| + user1.approve_task(task_id) |
| + |
| + ## USER 1 start the computation |
| + user1.run_task(task_id) |
| + |
| + ## USER 1 get the result |
| + result_user1 = user1.get_task_result(task_id) |
| + |
| + end = time.time() |
| + |
| + print("[+] Gene Owner result: " + result_user1.decode("utf-8")) |
| + print("[+] Time: " + str(end - start)) |
| + |
| + |
| +if __name__ == '__main__': |
| + main() |
| diff --git a/examples/python/builtin_echo.py b/examples/python/builtin_echo.py |
| index 8c6f154..fdfed5e 100644 |
| --- a/examples/python/builtin_echo.py |
| +++ b/examples/python/builtin_echo.py |
| @@ -20,6 +20,7 @@ |
| import sys |
| |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service |
| +from teaclave import FunctionArgument |
| |
| |
| class BuiltinEchoExample: |
| @@ -42,7 +43,7 @@ class BuiltinEchoExample: |
| name="builtin-echo", |
| description="Native Echo Function", |
| executor_type="builtin", |
| - arguments=["message"]) |
| + arguments=[FunctionArgument("message")]) |
| |
| print("[+] creating task") |
| task_id = client.create_task( |
| diff --git a/examples/python/builtin_face_detection.py b/examples/python/builtin_face_detection.py |
| index 416e99c..a074373 100644 |
| --- a/examples/python/builtin_face_detection.py |
| +++ b/examples/python/builtin_face_detection.py |
| @@ -25,6 +25,7 @@ from PIL import Image, ImageDraw |
| import requests |
| |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service |
| +from teaclave import FunctionArgument |
| |
| |
| class BuiltinFaceDetectionExample: |
| @@ -49,9 +50,12 @@ class BuiltinFaceDetectionExample: |
| executor_type="builtin", |
| inputs=[], |
| arguments=[ |
| - "image", "min_face_size", "score_thresh", |
| - "pyramid_scale_factor", "slide_window_step_x", |
| - "slide_window_step_y" |
| + FunctionArgument("image"), |
| + FunctionArgument("min_face_size"), |
| + FunctionArgument("score_thresh"), |
| + FunctionArgument("pyramid_scale_factor"), |
| + FunctionArgument("slide_window_step_x"), |
| + FunctionArgument("slide_window_step_y") |
| ]) |
| |
| print("[+] creating task") |
| diff --git a/examples/python/builtin_gbdt_train.py b/examples/python/builtin_gbdt_train.py |
| index 43f0898..b5392ab 100644 |
| --- a/examples/python/builtin_gbdt_train.py |
| +++ b/examples/python/builtin_gbdt_train.py |
| @@ -19,7 +19,7 @@ |
| |
| import sys |
| |
| -from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service |
| |
| |
| @@ -44,9 +44,15 @@ class BuiltinGbdtExample: |
| description="Native Gbdt Training Function", |
| executor_type="builtin", |
| arguments=[ |
| - "feature_size", "max_depth", "iterations", "shrinkage", |
| - "feature_sample_ratio", "data_sample_ratio", "min_leaf_size", |
| - "loss", "training_optimization_level" |
| + FunctionArgument("feature_size"), |
| + FunctionArgument("max_depth"), |
| + FunctionArgument("iterations"), |
| + FunctionArgument("shrinkage"), |
| + FunctionArgument("feature_sample_ratio"), |
| + FunctionArgument("data_sample_ratio"), |
| + FunctionArgument("min_leaf_size"), |
| + FunctionArgument("loss"), |
| + FunctionArgument("training_optimization_level") |
| ], |
| inputs=[ |
| FunctionInput("training_data", "Input traning data file.") |
| diff --git a/examples/python/builtin_online_decrypt.py b/examples/python/builtin_online_decrypt.py |
| index aee9c80..9a30b3b 100644 |
| --- a/examples/python/builtin_online_decrypt.py |
| +++ b/examples/python/builtin_online_decrypt.py |
| @@ -21,6 +21,7 @@ import sys |
| import base64 |
| |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service |
| +from teaclave import FunctionArgument |
| |
| |
| class BuiltinOnlineDecryptExample: |
| @@ -43,7 +44,12 @@ class BuiltinOnlineDecryptExample: |
| name="builtin_online_decrypt", |
| description="Native Online Decrypt", |
| executor_type="builtin", |
| - arguments=["key", "nonce", "encrypted_data", "algorithm"]) |
| + arguments=[ |
| + FunctionArgument("key"), |
| + FunctionArgument("nonce"), |
| + FunctionArgument("encrypted_data"), |
| + FunctionArgument("algorithm") |
| + ]) |
| |
| print("[+] creating task") |
| task_id = client.create_task( |
| diff --git a/examples/python/builtin_ordered_set_intersect.py b/examples/python/builtin_ordered_set_intersect.py |
| index a9eaa65..6cb8981 100644 |
| --- a/examples/python/builtin_ordered_set_intersect.py |
| +++ b/examples/python/builtin_ordered_set_intersect.py |
| @@ -19,7 +19,7 @@ |
| |
| import sys |
| |
| -from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| |
| # In the example, user 0 creates the task and user 0, 1, upload their private data. |
| @@ -91,7 +91,7 @@ class Client: |
| name="builtin-ordered-set-intersect", |
| description="Native Private Set Intersection", |
| executor_type="builtin", |
| - arguments=["order"], |
| + arguments=[FunctionArgument("order")], |
| inputs=[ |
| FunctionInput("input_data1", "Client 0 data."), |
| FunctionInput("input_data2", "Client 1 data.") |
| diff --git a/examples/python/builtin_private_join_and_compute.py b/examples/python/builtin_private_join_and_compute.py |
| index 461463e..aab8ca7 100644 |
| --- a/examples/python/builtin_private_join_and_compute.py |
| +++ b/examples/python/builtin_private_join_and_compute.py |
| @@ -19,7 +19,7 @@ |
| |
| import sys |
| |
| -from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| |
| # In the example, user 3 creates the task and user 0, 1, 2 upload their private data. |
| @@ -98,7 +98,7 @@ class ConfigClient: |
| name="builtin-private-join-and-compute", |
| description="Native Private Join And Compute", |
| executor_type="builtin", |
| - arguments=["num_user"], |
| + arguments=[FunctionArgument("num_user")], |
| inputs=[ |
| FunctionInput("input_data0", "Bank A data file."), |
| FunctionInput("input_data1", "Bank B data file."), |
| diff --git a/examples/python/builtin_rsa_sign.py b/examples/python/builtin_rsa_sign.py |
| index 0724756..b21e91c 100644 |
| --- a/examples/python/builtin_rsa_sign.py |
| +++ b/examples/python/builtin_rsa_sign.py |
| @@ -19,7 +19,7 @@ |
| |
| import sys |
| |
| -from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| |
| |
| @@ -61,7 +61,7 @@ def register_func(client): |
| name="builtin-rsa-sign", |
| description="Native Rsa Signing Function", |
| executor_type="builtin", |
| - arguments=["data"], |
| + arguments=[FunctionArgument("data")], |
| inputs=[FunctionInput("rsa_key", "Input key file.")]) |
| |
| return function_id |
| diff --git a/examples/python/cleanroom_algorithm1.py b/examples/python/cleanroom_algorithm1.py |
| new file mode 100644 |
| index 0000000..e417039 |
| --- /dev/null |
| +++ b/examples/python/cleanroom_algorithm1.py |
| @@ -0,0 +1,196 @@ |
| +#!/usr/bin/env python3 |
| + |
| +# 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. |
| + |
| +import sys |
| +import time |
| +import json |
| + |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| +from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| + |
| +# User 0: an algorithm provider. |
| +# User 1: a RNA provider. |
| + |
| + |
| +class UserData: |
| + |
| + def __init__(self, |
| + user_id, |
| + password, |
| + input_url="", |
| + output_url="", |
| + input_cmac=[], |
| + key=[]): |
| + self.user_id = user_id |
| + self.password = password |
| + self.input_url = input_url |
| + self.output_url = output_url |
| + self.input_cmac = input_cmac |
| + self.key = key |
| + |
| + |
| +# If you're using `docker-compose` to start the Teaclave server containers, |
| +# please change `localhost` to `teaclave-file-service` |
| +INPUT_FILE_URL_PREFIX = "http://localhost:6789/fixtures/functions/cleanroom-algorithm1/" |
| +OUTPUT_FILE_URL_PREFIX = "http://localhost:6789/fixtures/functions/cleanroom-algorithm1/" |
| + |
| +# User0 updates the algorithm. User1 sends the RNA information and gets the results. |
| +USER_DATA_0 = UserData("Algorithm Owner", "password", None, None, None, None) |
| + |
| +USER_DATA_1 = UserData("Gene Owner", "password", |
| + INPUT_FILE_URL_PREFIX + "testseq.enc", |
| + OUTPUT_FILE_URL_PREFIX + "stdout.enc", [ |
| + 0x99, 0x88, 0x31, 0x62, 0x30, 0xe6, 0x40, 0x67, |
| + 0xde, 0xe1, 0x20, 0xf2, 0xaf, 0x7b, 0xe6, 0xcf |
| + ], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) |
| + |
| +PAYLOAD_FILE = "../../tests/fixtures/functions/cleanroom-algorithm1/cleanroom-app.cpk" |
| + |
| + |
| +class DataList: |
| + |
| + def __init__(self, data_name, data_id): |
| + self.data_name = data_name |
| + self.data_id = data_id |
| + |
| + |
| +class Client: |
| + |
| + def __init__(self, user_id, user_password): |
| + self.user_id = user_id |
| + self.user_password = user_password |
| + with connect_authentication_service() as client: |
| + print(f"[+] {self.user_id} login") |
| + token = client.user_login(self.user_id, self.user_password) |
| + self.client = connect_frontend_service() |
| + metadata = {"id": self.user_id, "token": token} |
| + self.client.metadata = metadata |
| + |
| + def register_function(self): |
| + client = self.client |
| + |
| + print(f"[+] {self.user_id} registering the algorithm1 function") |
| + with open(PAYLOAD_FILE, "rb") as f: |
| + payload = f.read() |
| + function_id = client.register_function( |
| + name="cleanroom", |
| + description="algorithm1", |
| + payload=list(payload), |
| + executor_type="cleanroom", |
| + arguments=[FunctionArgument("args"), |
| + FunctionArgument("debug")], |
| + inputs=[FunctionInput("input_file", "RNA data.")], |
| + outputs=[FunctionOutput("output_file", "Output data.")]) |
| + return function_id |
| + |
| + def create_task(self, function_id): |
| + print(f"[+] {self.user_id} creating the task") |
| + client = self.client |
| + args = [ |
| + "algorithm1_v", "100", "0", "0", "0", "0", "0", "5.0", |
| + "example.shape" |
| + ] |
| + task_id = client.create_task( |
| + function_id=function_id, |
| + function_arguments=({ |
| + "args": json.dumps(args), |
| + "debug": "true", |
| + }), |
| + executor="cleanroom", |
| + inputs_ownership=[OwnerList("input_file", [USER_DATA_1.user_id])], |
| + outputs_ownership=[ |
| + OwnerList("output_file", [USER_DATA_1.user_id]) |
| + ]) |
| + return task_id |
| + |
| + def run_task(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} invoking the task") |
| + client.invoke_task(task_id) |
| + |
| + def register_data(self, task_id, input_url, input_cmac, output_url, |
| + file_key, input_label, output_label): |
| + client = self.client |
| + |
| + print(f"[+] {self.user_id} registering the input file") |
| + cmac = input_cmac |
| + schema = "teaclave-file-128" |
| + key = file_key |
| + iv = [] |
| + print(input_url) |
| + input_id = client.register_input_file(input_url, schema, key, iv, cmac) |
| + print(output_url) |
| + output_id = client.register_output_file(output_url, schema, key, iv) |
| + print(f"[+] {self.user_id} assigning data to task") |
| + client.assign_data_to_task(task_id, [DataList(input_label, input_id)], |
| + [DataList(output_label, output_id)]) |
| + |
| + def approve_task(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} approving task") |
| + client.approve_task(task_id) |
| + |
| + def get_task_result(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} getting task result") |
| + return bytes(client.get_task_result(task_id)) |
| + |
| + |
| +def main(): |
| + print( |
| + "User 0 (Algorithm owner) registers the function and uploads the algorithm." |
| + ) |
| + print( |
| + "User 1 (Gene Owner) creates the task, uploads the secret data, and retrieves the result." |
| + ) |
| + # Register user |
| + platform_admin = PlatformAdmin("admin", "teaclave") |
| + try: |
| + platform_admin.register_user(USER_DATA_0.user_id, USER_DATA_0.password) |
| + platform_admin.register_user(USER_DATA_1.user_id, USER_DATA_1.password) |
| + except Exception: |
| + pass |
| + user0 = Client(USER_DATA_0.user_id, USER_DATA_0.password) |
| + function_id = user0.register_function() |
| + |
| + start = time.time() |
| + |
| + user1 = Client(USER_DATA_1.user_id, USER_DATA_1.password) |
| + task_id = user1.create_task(function_id) |
| + user1.register_data(task_id, USER_DATA_1.input_url, USER_DATA_1.input_cmac, |
| + USER_DATA_1.output_url, USER_DATA_1.key, "input_file", |
| + "output_file") |
| + |
| + # user1.approve_task(task_id) |
| + user1.approve_task(task_id) |
| + |
| + ## USER 1 start the computation |
| + user1.run_task(task_id) |
| + |
| + ## USER 1 get the result |
| + result_user1 = user1.get_task_result(task_id) |
| + |
| + end = time.time() |
| + |
| + print("[+] User 1 result: " + result_user1.decode("utf-8")) |
| + print("[+] Time: " + str(end - start)) |
| + |
| + |
| +if __name__ == '__main__': |
| + main() |
| diff --git a/examples/python/cleanroom_algorithm1_repeat.py b/examples/python/cleanroom_algorithm1_repeat.py |
| new file mode 100644 |
| index 0000000..2ccaa99 |
| --- /dev/null |
| +++ b/examples/python/cleanroom_algorithm1_repeat.py |
| @@ -0,0 +1,222 @@ |
| +#!/usr/bin/env python3 |
| + |
| +# 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. |
| + |
| +import sys |
| +import time |
| +import traceback |
| + |
| +from teaclave import (AuthenticationService, FrontendService, |
| + AuthenticationClient, FrontendClient, FunctionInput, |
| + FunctionOutput, FunctionArgument, OwnerList, DataMap) |
| +from utils import (AUTHENTICATION_SERVICE_ADDRESS, FRONTEND_SERVICE_ADDRESS, |
| + AS_ROOT_CA_CERT_PATH, ENCLAVE_INFO_PATH, USER_ID, |
| + USER_PASSWORD, PlatformAdmin) |
| + |
| +# User 0: an algorithm provider. |
| +# User 1: a RNA provider. |
| + |
| + |
| +class UserData: |
| + |
| + def __init__(self, |
| + user_id, |
| + password, |
| + input_url="", |
| + output_url="", |
| + input_cmac=[], |
| + key=[]): |
| + self.user_id = user_id |
| + self.password = password |
| + self.input_url = input_url |
| + self.output_url = output_url |
| + self.input_cmac = input_cmac |
| + self.key = key |
| + |
| + |
| +# If you're using `docker-compose` to start the Teaclave server containers, |
| +# please change `localhost` to `teaclave-file-service` |
| +INPUT_FILE_URL_PREFIX = "http://localhost:6789/fixtures/functions/cleanroom-algorithm1/" |
| +OUTPUT_FILE_URL_PREFIX = "http://localhost:6789/fixtures/functions/cleanroom-algorithm1/" |
| + |
| +# User0 updates the algorithm. User1 sends the RNA information and gets the results. |
| +USER_DATA_0 = UserData("Algorithm Owner", "password", None, None, None, None) |
| + |
| +USER_DATA_1 = UserData("Gene Owner", "password", |
| + INPUT_FILE_URL_PREFIX + "testseq.enc", |
| + OUTPUT_FILE_URL_PREFIX + "stdout.enc", [ |
| + 0x99, 0x88, 0x31, 0x62, 0x30, 0xe6, 0x40, 0x67, |
| + 0xde, 0xe1, 0x20, 0xf2, 0xaf, 0x7b, 0xe6, 0xcf |
| + ], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) |
| + |
| +PAYLOAD_FILE = "../../tests/fixtures/functions/cleanroom-algorithm1/cleanroom-app.cpk" |
| + |
| + |
| +class DataList: |
| + |
| + def __init__(self, data_name, data_id): |
| + self.data_name = data_name |
| + self.data_id = data_id |
| + |
| + |
| +class Client: |
| + |
| + def __init__(self, user_id, user_password): |
| + self.user_id = user_id |
| + self.user_password = user_password |
| + self.client = AuthenticationService( |
| + AUTHENTICATION_SERVICE_ADDRESS, AS_ROOT_CA_CERT_PATH, |
| + ENCLAVE_INFO_PATH).connect().get_client() |
| + print(f"[+] {self.user_id} login") |
| + token = self.client.user_login(self.user_id, self.user_password) |
| + self.client = FrontendService( |
| + FRONTEND_SERVICE_ADDRESS, AS_ROOT_CA_CERT_PATH, |
| + ENCLAVE_INFO_PATH).connect().get_client() |
| + metadata = {"id": self.user_id, "token": token} |
| + self.client.metadata = metadata |
| + |
| + def register_function(self): |
| + client = self.client |
| + |
| + print(f"[+] {self.user_id} registering the algorithm1 function") |
| + with open(PAYLOAD_FILE, "rb") as f: |
| + payload = f.read() |
| + function_id = client.register_function( |
| + name="diagnosis", |
| + description="algorithm1", |
| + payload=list(payload), |
| + executor_type="cleanroom", |
| + arguments=[FunctionArgument("args"), |
| + FunctionArgument("debug")], |
| + inputs=[FunctionInput("input_file", "RNA data.")], |
| + outputs=[ |
| + FunctionOutput("output_file", "Output data."), |
| + FunctionOutput("log_file", "Log.") |
| + ]) |
| + return function_id |
| + |
| + def create_task(self, function_id): |
| + print(f"[+] {self.user_id} creating the task") |
| + client = self.client |
| + task_id = client.create_task( |
| + function_id=function_id, |
| + function_arguments=({ |
| + "args": "algorithm1_v 100 0 0 0 0 0 5.0 example.shape", |
| + "debug": "true", |
| + }), |
| + executor="cleanroom", |
| + inputs_ownership=[OwnerList("input_file", [USER_DATA_1.user_id])], |
| + outputs_ownership=[ |
| + OwnerList("output_file", [USER_DATA_1.user_id]), |
| + OwnerList("log_file", [USER_DATA_1.user_id]) |
| + ]) |
| + return task_id |
| + |
| + def run_task(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} invoking the task") |
| + client.invoke_task(task_id) |
| + |
| + def register_data(self, task_id, input_url, input_cmac, output_url, |
| + file_key, input_label, output_label): |
| + client = self.client |
| + |
| + print(f"[+] {self.user_id} registering the input file") |
| + url = input_url |
| + cmac = input_cmac |
| + schema = "teaclave-file-128" |
| + key = file_key |
| + iv = [] |
| + input_id = client.register_input_file(url, schema, key, iv, cmac) |
| + print(f"[+] {self.user_id} registering the output file") |
| + url = output_url |
| + schema = "teaclave-file-128" |
| + key = file_key |
| + iv = [] |
| + output_id = client.register_output_file(url, schema, key, iv) |
| + log_id = client.register_output_file( |
| + OUTPUT_FILE_URL_PREFIX + "stderr.enc", schema, key, iv) |
| + print(f"[+] {self.user_id} assigning data to task") |
| + client.assign_data_to_task( |
| + task_id, [DataList(input_label, input_id)], |
| + [DataList(output_label, output_id), |
| + DataList("log_file", log_id)]) |
| + |
| + def approve_task(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} approving task") |
| + client.approve_task(task_id) |
| + |
| + def get_task_result(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} getting task result") |
| + return bytes(client.get_task_result(task_id)) |
| + |
| + |
| +def client_run_once(function_id): |
| + user1 = Client(USER_DATA_1.user_id, USER_DATA_1.password) |
| + task_id = user1.create_task(function_id) |
| + user1.register_data(task_id, USER_DATA_1.input_url, USER_DATA_1.input_cmac, |
| + USER_DATA_1.output_url, USER_DATA_1.key, "input_file", |
| + "output_file") |
| + |
| + # user1.approve_task(task_id) |
| + user1.approve_task(task_id) |
| + |
| + # USER 1 start the computation |
| + user1.run_task(task_id) |
| + |
| + # USER 1 get the result |
| + result_user1 = user1.get_task_result(task_id) |
| + |
| + |
| +def main(): |
| + # Register user |
| + platform_admin = PlatformAdmin("admin", "teaclave") |
| + platform_admin.register_user(USER_DATA_0.user_id, USER_DATA_0.password) |
| + platform_admin.register_user(USER_DATA_1.user_id, USER_DATA_1.password) |
| + while True: |
| + try: |
| + user0 = Client(USER_DATA_0.user_id, USER_DATA_0.password) |
| + function_id = user0.register_function() |
| + break |
| + except Exception as e: |
| + print(f"Python Client: Admin register function got execption: {e}", |
| + flush=True) |
| + traceback.print_tb(e.__traceback__) |
| + |
| + i = 1 |
| + while True: |
| + try: |
| + print(f"Python Client {i}th invocation started...", flush=True) |
| + start = time.time() |
| + client_run_once(function_id) |
| + end = time.time() |
| + elapsed = end - start |
| + print( |
| + f"Python Client {i}th invocation finishied: elapsed {elapsed} seconds...", |
| + flush=True) |
| + i = i + 1 |
| + except Exception as e: |
| + print(f"Python Client {i}th invocation got execption: {e}", |
| + flush=True) |
| + traceback.print_tb(e.__traceback__) |
| + |
| + |
| +if __name__ == '__main__': |
| + main() |
| diff --git a/examples/python/cleanroom_stderr.py b/examples/python/cleanroom_stderr.py |
| new file mode 100644 |
| index 0000000..6c55689 |
| --- /dev/null |
| +++ b/examples/python/cleanroom_stderr.py |
| @@ -0,0 +1,200 @@ |
| +#!/usr/bin/env python3 |
| + |
| +# 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. |
| + |
| +import sys |
| +import json |
| + |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| +from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| + |
| +# User 0: an algorithm provider. |
| +# User 1: a RNA provider. |
| + |
| + |
| +class UserData: |
| + |
| + def __init__(self, |
| + user_id, |
| + password, |
| + input_url="", |
| + output_url="", |
| + input_cmac=[], |
| + key=[]): |
| + self.user_id = user_id |
| + self.password = password |
| + self.input_url = input_url |
| + self.output_url = output_url |
| + self.input_cmac = input_cmac |
| + self.key = key |
| + |
| + |
| +# If you're using `docker-compose` to start the Teaclave server containers, |
| +# please change `localhost` to `teaclave-file-service` |
| +INPUT_FILE_URL_PREFIX = "http://localhost:6789/fixtures/functions/cleanroom-stderr/" |
| +OUTPUT_FILE_URL_PREFIX = "http://localhost:6789/fixtures/functions/cleanroom-stderr/" |
| + |
| +# User0 updates the algorithm. User1 sends the RNA information and gets the results. |
| +USER_DATA_0 = UserData("Algorithm Owner 2", "password", None, None, None, None) |
| + |
| +USER_DATA_1 = UserData("Data Owner 2", "password", |
| + INPUT_FILE_URL_PREFIX + "testseq.enc", |
| + OUTPUT_FILE_URL_PREFIX + "stdout.enc", [ |
| + 0x99, 0x88, 0x31, 0x62, 0x30, 0xe6, 0x40, 0x67, |
| + 0xde, 0xe1, 0x20, 0xf2, 0xaf, 0x7b, 0xe6, 0xcf |
| + ], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) |
| + |
| +PAYLOAD_FILE = "../../tests/fixtures/functions/cleanroom-stderr/app.cpk" |
| + |
| + |
| +class DataList: |
| + |
| + def __init__(self, data_name, data_id): |
| + self.data_name = data_name |
| + self.data_id = data_id |
| + |
| + |
| +class Client: |
| + |
| + def __init__(self, user_id, user_password): |
| + self.user_id = user_id |
| + self.user_password = user_password |
| + with connect_authentication_service() as client: |
| + print(f"[+] {self.user_id} login") |
| + token = client.user_login(self.user_id, self.user_password) |
| + self.client = connect_frontend_service() |
| + metadata = {"id": self.user_id, "token": token} |
| + self.client.metadata = metadata |
| + |
| + def register_function_debug(self): |
| + client = self.client |
| + |
| + print(f"[+] {self.user_id} registering the algorithm1 function") |
| + with open(PAYLOAD_FILE, "rb") as f: |
| + payload = f.read() |
| + function_id = client.register_function( |
| + name="diagnosis", |
| + #name="cleanroom", |
| + description="algorithm1", |
| + payload=list(payload), |
| + executor_type="cleanroom", |
| + arguments=[FunctionArgument("args"), |
| + FunctionArgument("debug")], |
| + inputs=[FunctionInput("input_file", "RNA data.")], |
| + outputs=[ |
| + FunctionOutput("output_file", "Output data."), |
| + FunctionOutput("log_file", "Log.") |
| + ]) |
| + return function_id |
| + |
| + def create_task_debug(self, function_id): |
| + print(f"[+] {self.user_id} creating the task") |
| + client = self.client |
| + args = ["algorithm1_v", "100", "0", "0"] |
| + task_id = client.create_task( |
| + function_id=function_id, |
| + function_arguments=({ |
| + "args": json.dumps(args), |
| + "debug": "true", |
| + }), |
| + executor="cleanroom", |
| + inputs_ownership=[OwnerList("input_file", [USER_DATA_1.user_id])], |
| + outputs_ownership=[ |
| + OwnerList("output_file", [USER_DATA_1.user_id]), |
| + OwnerList("log_file", [USER_DATA_1.user_id]) |
| + ]) |
| + return task_id |
| + |
| + def run_task(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} invoking the task") |
| + client.invoke_task(task_id) |
| + |
| + def register_data_debug(self, task_id, input_url, input_cmac, output_url, |
| + file_key, input_label, output_label): |
| + client = self.client |
| + print(f"[+] {self.user_id} registering the input file") |
| + url = input_url |
| + cmac = input_cmac |
| + schema = "teaclave-file-128" |
| + key = file_key |
| + iv = [] |
| + input_id = client.register_input_file(url, schema, key, iv, cmac) |
| + print(f"[+] {self.user_id} registering the output file") |
| + url = output_url |
| + schema = "teaclave-file-128" |
| + key = file_key |
| + iv = [] |
| + output_id = client.register_output_file(url, schema, key, iv) |
| + log_id = client.register_output_file( |
| + OUTPUT_FILE_URL_PREFIX + "stderr.enc", schema, key, iv) |
| + print(f"[+] {self.user_id} assigning data to task") |
| + client.assign_data_to_task( |
| + task_id, [DataList(input_label, input_id)], |
| + [DataList(output_label, output_id), |
| + DataList("log_file", log_id)]) |
| + |
| + def approve_task(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} approving task") |
| + client.approve_task(task_id) |
| + |
| + def get_task_result(self, task_id): |
| + client = self.client |
| + print(f"[+] {self.user_id} getting task result") |
| + return bytes(client.get_task_result(task_id)) |
| + |
| + |
| +def main(): |
| + print( |
| + "User 0 (Algorithm owner) registers the function and uploads the algorithm." |
| + ) |
| + print( |
| + "User 1 (DATA Owner) creates the task, uploads the secret data, and retrieves the result." |
| + ) |
| + # Register user |
| + platform_admin = PlatformAdmin("admin", "teaclave") |
| + try: |
| + platform_admin.register_user(USER_DATA_0.user_id, USER_DATA_0.password) |
| + platform_admin.register_user(USER_DATA_1.user_id, USER_DATA_1.password) |
| + except Exception: |
| + pass |
| + user0 = Client(USER_DATA_0.user_id, USER_DATA_0.password) |
| + function_id = user0.register_function_debug() |
| + |
| + user1 = Client(USER_DATA_1.user_id, USER_DATA_1.password) |
| + |
| + task_id = user1.create_task_debug(function_id) |
| + user1.register_data_debug(task_id, USER_DATA_1.input_url, |
| + USER_DATA_1.input_cmac, USER_DATA_1.output_url, |
| + USER_DATA_1.key, "input_file", "output_file") |
| + |
| + # user1.approve_task(task_id) |
| + user1.approve_task(task_id) |
| + |
| + ## USER 1 start the computation |
| + user1.run_task(task_id) |
| + |
| + ## USER 1 get the result |
| + result_user1 = user1.get_task_result(task_id) |
| + |
| + print("[+] User 1 result: " + result_user1.decode("utf-8")) |
| + |
| + |
| +if __name__ == '__main__': |
| + main() |
| diff --git a/examples/python/mesapy_deadloop_cancel.py b/examples/python/mesapy_deadloop_cancel.py |
| index a4b0eaa..2bd7206 100644 |
| --- a/examples/python/mesapy_deadloop_cancel.py |
| +++ b/examples/python/mesapy_deadloop_cancel.py |
| @@ -75,22 +75,22 @@ class MesaPyEchoExample: |
| result = client.get_task(task_id) |
| if result["status"] != TaskStatus.Canceled: |
| print("[+] Task is not canceled, cancel again") |
| - try: |
| - client.cancel_task(task_id) |
| - except Exception as e: |
| - # this happens when the task has already been canceled |
| - print(f"[-] cancel task failed, reason: {str(e)}") |
| + client.cancel_task(task_id) |
| |
| try: |
| result = client.get_task_result(task_id) |
| except Exception as e: |
| - # this is expected, since the task is cancelled |
| - print(f"[-] getting result failed, reason: {str(e)}") |
| + print(f"[+] result: {str(e)}") |
| + result = str(e) |
| + |
| + return result |
| |
| |
| def main(): |
| example = MesaPyEchoExample(USER_ID, USER_PASSWORD) |
| - example.deadloop() |
| + rv = example.deadloop() |
| + |
| + print("[+] function return: ", rv) |
| |
| |
| if __name__ == '__main__': |
| diff --git a/examples/python/mesapy_echo.py b/examples/python/mesapy_echo.py |
| index d24c2ae..b60df00 100644 |
| --- a/examples/python/mesapy_echo.py |
| +++ b/examples/python/mesapy_echo.py |
| @@ -19,7 +19,7 @@ |
| |
| import sys |
| |
| -from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| |
| |
| @@ -49,7 +49,7 @@ class MesaPyEchoExample: |
| description="An echo function implemented in Python", |
| executor_type="python", |
| payload=list(payload), |
| - arguments=["message"]) |
| + arguments=[FunctionArgument("message")]) |
| |
| print("[+] creating task") |
| task_id = client.create_task(function_id=function_id, |
| diff --git a/examples/python/mesapy_logistic_reg.py b/examples/python/mesapy_logistic_reg.py |
| index 1838c16..6d00ce5 100644 |
| --- a/examples/python/mesapy_logistic_reg.py |
| +++ b/examples/python/mesapy_logistic_reg.py |
| @@ -23,7 +23,7 @@ An example about Logistic Regression in MesaPy. |
| import sys |
| import binascii |
| from typing import List |
| -from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| |
| from enum import Enum |
| @@ -117,7 +117,7 @@ class ConfigClient: |
| name=functionname, |
| description="worker: %s" % functionname, |
| executor_type=ex.name, |
| - arguments=list(args.keys()), |
| + arguments=[FunctionArgument(arg) for arg in args], |
| payload=list(p_str), |
| inputs=[ |
| FunctionInput(label, "user input data file: %s" % label) |
| diff --git a/examples/python/test_default_arguments.py b/examples/python/test_default_arguments.py |
| new file mode 100644 |
| index 0000000..aca7d5d |
| --- /dev/null |
| +++ b/examples/python/test_default_arguments.py |
| @@ -0,0 +1,77 @@ |
| +#!/usr/bin/env python3 |
| + |
| +# 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. |
| + |
| +import sys |
| + |
| +from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service |
| +from teaclave import FunctionArgument |
| + |
| + |
| +class BuiltinEchoExample: |
| + |
| + def __init__(self, user_id, user_password): |
| + self.user_id = user_id |
| + self.user_password = user_password |
| + |
| + def echo(self, message="Hello, Teaclave!"): |
| + with connect_authentication_service() as client: |
| + print("[+] login") |
| + token = client.user_login(self.user_id, self.user_password) |
| + |
| + with connect_frontend_service() as client: |
| + metadata = {"id": self.user_id, "token": token} |
| + client.metadata = metadata |
| + |
| + print("[+] registering function") |
| + function_id = client.register_function( |
| + name="builtin-echo", |
| + description="Native Echo Function", |
| + executor_type="builtin", |
| + arguments=[ |
| + FunctionArgument("message", "Hello, Cleanroom", False) |
| + ]) |
| + |
| + print("[+] creating task") |
| + task_id = client.create_task(function_id=function_id, |
| + function_arguments={}, |
| + executor="builtin") |
| + |
| + print("[+] invoking task") |
| + client.invoke_task(task_id) |
| + |
| + print("[+] getting result") |
| + result = client.get_task_result(task_id) |
| + print("[+] done") |
| + |
| + return bytes(result) |
| + |
| + |
| +def main(): |
| + example = BuiltinEchoExample(USER_ID, USER_PASSWORD) |
| + if len(sys.argv) > 1: |
| + message = sys.argv[1] |
| + rt = example.echo(message) |
| + else: |
| + rt = example.echo() |
| + |
| + print("[+] function return: ", rt) |
| + |
| + |
| +if __name__ == '__main__': |
| + main() |
| diff --git a/examples/python/test_disable_function.py b/examples/python/test_disable_function.py |
| index 5c51e6d..dbea609 100644 |
| --- a/examples/python/test_disable_function.py |
| +++ b/examples/python/test_disable_function.py |
| @@ -19,7 +19,7 @@ |
| |
| import sys |
| |
| -from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| |
| |
| @@ -50,12 +50,13 @@ class ConfigClient: |
| |
| print(f"[+] {self.user_id} registering function") |
| |
| - function_id = client.register_function(name=func_name, |
| - description=func_name, |
| - executor_type="builtin", |
| - arguments=["num_user"], |
| - inputs=[], |
| - outputs=[]) |
| + function_id = client.register_function( |
| + name=func_name, |
| + description=func_name, |
| + executor_type="builtin", |
| + arguments=[FunctionArgument("num_user")], |
| + inputs=[], |
| + outputs=[]) |
| |
| return function_id |
| |
| diff --git a/examples/python/wasm_c_simple_add.py b/examples/python/wasm_c_simple_add.py |
| index c45175a..b53c5a4 100644 |
| --- a/examples/python/wasm_c_simple_add.py |
| +++ b/examples/python/wasm_c_simple_add.py |
| @@ -19,7 +19,7 @@ |
| |
| import sys |
| |
| -from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap |
| +from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap, FunctionArgument |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| |
| |
| @@ -45,11 +45,13 @@ class WASMAddExample: |
| with open(payload_file, "rb") as f: |
| payload = f.read() |
| |
| - function_id = client.register_function(name="entrypoint", |
| - description="test of wasm", |
| - executor_type="wamr", |
| - payload=list(payload), |
| - arguments=["adder1", "adder2"]) |
| + function_id = client.register_function( |
| + name="entrypoint", |
| + description="test of wasm", |
| + executor_type="wamr", |
| + payload=list(payload), |
| + arguments=[FunctionArgument("adder1"), |
| + FunctionArgument("adder2")]) |
| |
| print("[+] creating task") |
| task_id = client.create_task(function_id=function_id, |
| diff --git a/examples/python/wasm_rust_psi.py b/examples/python/wasm_rust_psi.py |
| index 2713802..53ab0e2 100644 |
| --- a/examples/python/wasm_rust_psi.py |
| +++ b/examples/python/wasm_rust_psi.py |
| @@ -19,7 +19,7 @@ |
| |
| import sys |
| |
| -from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| |
| |
| @@ -102,7 +102,10 @@ class Client: |
| payload=list(payload), |
| executor_type="wamr", |
| arguments=[ |
| - "input1_fid", "input2_fid", "output1_fid", "output2_fid" |
| + FunctionArgument("input1_fid"), |
| + FunctionArgument("input2_fid"), |
| + FunctionArgument("output1_fid"), |
| + FunctionArgument("output2_fid") |
| ], |
| inputs=[ |
| FunctionInput(USER_DATA_0.input_fid, "Client 0 data."), |
| diff --git a/examples/python/wasm_rust_psi_payload/Cargo.lock b/examples/python/wasm_rust_psi_payload/Cargo.lock |
| index 2819d2d..d367651 100644 |
| --- a/examples/python/wasm_rust_psi_payload/Cargo.lock |
| +++ b/examples/python/wasm_rust_psi_payload/Cargo.lock |
| @@ -2,7 +2,7 @@ |
| # It is not intended for manual editing. |
| [[package]] |
| name = "teaclave_context" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| |
| [[package]] |
| name = "wasm_rust_psi_payload" |
| diff --git a/examples/python/wasm_tvm_mnist.py b/examples/python/wasm_tvm_mnist.py |
| index 90d1d09..6f33807 100644 |
| --- a/examples/python/wasm_tvm_mnist.py |
| +++ b/examples/python/wasm_tvm_mnist.py |
| @@ -19,7 +19,7 @@ |
| |
| import sys |
| |
| -from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap |
| +from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap |
| from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin |
| |
| # If you're using `docker-compose` to start the Teaclave server containers, |
| @@ -61,7 +61,7 @@ def main(): |
| description="WAMR TVM MNIST Prediction", |
| payload=list(payload), |
| executor_type="wamr", |
| - arguments=["input_img"], |
| + arguments=[FunctionArgument("input_img")], |
| inputs=[ |
| FunctionInput("input_img", |
| "Input image for handwriting number perdiction") |
| diff --git a/examples/python/wasm_tvm_mnist_payload/Cargo.lock b/examples/python/wasm_tvm_mnist_payload/Cargo.lock |
| index 8af6ccb..5d2ad33 100644 |
| --- a/examples/python/wasm_tvm_mnist_payload/Cargo.lock |
| +++ b/examples/python/wasm_tvm_mnist_payload/Cargo.lock |
| @@ -1632,7 +1632,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_context" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| |
| [[package]] |
| name = "tempfile" |
| diff --git a/examples/rust/builtin_echo/Cargo.lock b/examples/rust/builtin_echo/Cargo.lock |
| index 34be5b6..c3634a3 100644 |
| --- a/examples/rust/builtin_echo/Cargo.lock |
| +++ b/examples/rust/builtin_echo/Cargo.lock |
| @@ -50,7 +50,7 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" |
| |
| [[package]] |
| name = "builtin_echo" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "pem", |
| @@ -359,7 +359,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "protected_fs_rs" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "cfg-if 0.1.10", |
| "libc", |
| @@ -553,7 +553,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_attestation" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "base64 0.13.0", |
| @@ -581,7 +581,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_client_sdk" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "libc", |
| @@ -597,7 +597,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_config" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "log", |
| @@ -608,7 +608,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_crypto" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "hex", |
| @@ -621,7 +621,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_proto" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "base64 0.13.0", |
| @@ -640,7 +640,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_rpc" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "cfg-if 0.1.10", |
| @@ -659,7 +659,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_rpc_proc_macro" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "proc-macro2", |
| "quote", |
| @@ -668,7 +668,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_types" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "hex", |
| diff --git a/examples/rust/builtin_echo/Cargo.toml b/examples/rust/builtin_echo/Cargo.toml |
| index 3f46b0e..95203f0 100644 |
| --- a/examples/rust/builtin_echo/Cargo.toml |
| +++ b/examples/rust/builtin_echo/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "builtin_echo" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "builtin_echo function example using Teaclave client SDK." |
| license = "Apache-2.0" |
| diff --git a/examples/rust/builtin_ordered_set_intersect/Cargo.lock b/examples/rust/builtin_ordered_set_intersect/Cargo.lock |
| index 972321b..4e3bf21 100644 |
| --- a/examples/rust/builtin_ordered_set_intersect/Cargo.lock |
| +++ b/examples/rust/builtin_ordered_set_intersect/Cargo.lock |
| @@ -50,7 +50,7 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" |
| |
| [[package]] |
| name = "builtin_ordered_set_intersect" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "pem", |
| @@ -359,7 +359,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "protected_fs_rs" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "cfg-if 0.1.10", |
| "libc", |
| @@ -553,7 +553,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_attestation" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "base64 0.13.0", |
| @@ -581,7 +581,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_client_sdk" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "libc", |
| @@ -597,7 +597,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_config" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "log", |
| @@ -608,7 +608,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_crypto" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "hex", |
| @@ -621,7 +621,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_proto" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "base64 0.13.0", |
| @@ -640,7 +640,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_rpc" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "cfg-if 0.1.10", |
| @@ -659,7 +659,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_rpc_proc_macro" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "proc-macro2", |
| "quote", |
| @@ -668,7 +668,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_types" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "hex", |
| diff --git a/examples/rust/builtin_ordered_set_intersect/Cargo.toml b/examples/rust/builtin_ordered_set_intersect/Cargo.toml |
| index f297aa7..b4ca1e7 100644 |
| --- a/examples/rust/builtin_ordered_set_intersect/Cargo.toml |
| +++ b/examples/rust/builtin_ordered_set_intersect/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "builtin_ordered_set_intersect" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "builtin_ordered_set_intersect function example using Teaclave client SDK." |
| license = "Apache-2.0" |
| diff --git a/executor/Cargo.toml b/executor/Cargo.toml |
| index 6f3832b..e32219e 100644 |
| --- a/executor/Cargo.toml |
| +++ b/executor/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_executor" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave executor" |
| license = "Apache-2.0" |
| @@ -58,6 +58,9 @@ full_builtin_function = [ |
| "builtin_principal_components_analysis", |
| "builtin_private_join_and_compute", |
| "builtin_rsa_sign", |
| + "builtin_cleanroom_algorithm2_hash", |
| + "builtin_cleanroom_algorithm2_hash_trial", |
| + "builtin_cleanroom_algorithm2_hash_trial_tier2", |
| ] |
| |
| builtin_echo = [] |
| @@ -72,9 +75,13 @@ builtin_ordered_set_intersect = [] |
| builtin_principal_components_analysis = [] |
| builtin_private_join_and_compute = [] |
| builtin_rsa_sign = [] |
| +builtin_cleanroom_algorithm2_hash = [] |
| +builtin_cleanroom_algorithm2_hash_trial = [] |
| +builtin_cleanroom_algorithm2_hash_trial_tier2 = [] |
| + |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| serde_json = { version = "1.0.39" } |
| serde = { version = "1.0.92", features = ["derive"] } |
| diff --git a/executor/context/Cargo.toml b/executor/context/Cargo.toml |
| index 662fa40..05760d1 100644 |
| --- a/executor/context/Cargo.toml |
| +++ b/executor/context/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_executor_context" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave executor" |
| license = "Apache-2.0" |
| diff --git a/executor/src/builtin.rs b/executor/src/builtin.rs |
| index a327432..17ce3dc 100644 |
| --- a/executor/src/builtin.rs |
| +++ b/executor/src/builtin.rs |
| @@ -19,9 +19,10 @@ |
| use std::prelude::v1::*; |
| |
| use teaclave_function::{ |
| - Echo, FaceDetection, GbdtPredict, GbdtTrain, LogisticRegressionPredict, |
| - LogisticRegressionTrain, OnlineDecrypt, OrderedSetIntersect, PasswordCheck, |
| - PrincipalComponentsAnalysis, PrivateJoinAndCompute, RsaSign, |
| + Echo, FaceDetection, GbdtPredict, GbdtTrain, Algorithm2Hash, Algorithm2HashTrial, |
| + Algorithm2HashTrialTier2, LogisticRegressionPredict, LogisticRegressionTrain, OnlineDecrypt, |
| + OrderedSetIntersect, PasswordCheck, PrincipalComponentsAnalysis, PrivateJoinAndCompute, |
| + RsaSign, |
| }; |
| use teaclave_types::{FunctionArguments, FunctionRuntime, TeaclaveExecutor}; |
| |
| @@ -65,6 +66,14 @@ impl TeaclaveExecutor for BuiltinFunctionExecutor { |
| } |
| #[cfg(feature = "builtin_face_detection")] |
| FaceDetection::NAME => FaceDetection::new().run(arguments, runtime), |
| + #[cfg(feature = "builtin_cleanroom_algorithm2_hash")] |
| + Algorithm2Hash::NAME => Algorithm2Hash::new().run(arguments, runtime), |
| + #[cfg(feature = "builtin_cleanroom_algorithm2_hash_trial")] |
| + Algorithm2HashTrial::NAME => Algorithm2HashTrial::new().run(arguments, runtime), |
| + #[cfg(feature = "builtin_cleanroom_algorithm2_hash_trial_tier2")] |
| + Algorithm2HashTrialTier2::NAME => { |
| + Algorithm2HashTrialTier2::new().run(arguments, runtime) |
| + } |
| #[cfg(feature = "builtin_password_check")] |
| PasswordCheck::NAME => PasswordCheck::new().run(arguments, runtime), |
| _ => bail!("Function not found."), |
| diff --git a/executor/src/cleanroom.rs b/executor/src/cleanroom.rs |
| new file mode 100644 |
| index 0000000..bf1e811 |
| --- /dev/null |
| +++ b/executor/src/cleanroom.rs |
| @@ -0,0 +1,547 @@ |
| +// 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 std::prelude::v1::*; |
| + |
| +use teaclave_executor_context::context::reset_thread_context; |
| +use teaclave_executor_context::context::set_thread_context; |
| +use teaclave_executor_context::context::Context; |
| + |
| +use anyhow::anyhow; |
| +use serde::{Deserialize, Serialize}; |
| +use std::ffi::{c_void, CStr, CString}; |
| +use std::os::raw::c_char; |
| +use std::ptr; |
| +use std::time::SystemTime; |
| +#[cfg(feature = "mesalock_sgx")] |
| +use std::untrusted::time::SystemTimeEx; |
| + |
| +use teaclave_types::{FunctionArguments, FunctionRuntime, TeaclaveExecutor}; |
| + |
| +const DEFAULT_HEAP_SIZE: u32 = 0; |
| +const DEFAULT_STACK_SIZE: u32 = 463840; |
| +const DEFAULT_ERROR_BUF_SIZE: usize = 128; |
| + |
| +#[allow(unused)] |
| +#[no_mangle] |
| +pub static mut DEBUG_FLAG: i32 = 0; |
| + |
| +#[repr(C)] |
| +#[derive(Debug)] |
| +struct NativeSymbol { |
| + symbol: *const c_char, |
| + func_ptr: *const c_void, |
| + signature: *const c_char, |
| + attachment: *const c_void, |
| +} |
| + |
| +#[allow(unused)] |
| +#[no_mangle] |
| +pub extern "C" fn rust_printf(c_buf: *const c_char) { |
| + let c_str = unsafe { CStr::from_ptr(c_buf) }; |
| + let str_slice = c_str.to_string_lossy(); |
| + log::debug!("Cleanroom: {:?}", str_slice); |
| +} |
| + |
| +#[allow(unused)] |
| +#[no_mangle] |
| +pub extern "C" fn teaclave_sgx_log(c_buf: *const c_char) { |
| + let c_str = unsafe { CStr::from_ptr(c_buf) }; |
| + let str_slice = c_str.to_string_lossy(); |
| + log::warn!( |
| + "Cleanroom: The ocall function {:?} should not be reachable.", |
| + str_slice |
| + ); |
| +} |
| + |
| +#[derive(Serialize, Deserialize)] |
| +struct Summary { |
| + status: bool, |
| + reason: String, |
| + execution_time: f32, |
| +} |
| + |
| +extern "C" { |
| + |
| + fn wasm_runtime_init() -> bool; |
| + |
| + fn wasm_runtime_load( |
| + buf: *const u8, |
| + size: u32, |
| + error_buf: *mut u8, |
| + error_buf_size: u32, |
| + ) -> *const c_void; |
| + |
| + fn wasm_runtime_set_wasi_args( |
| + module: *const c_void, |
| + dir_list: *const u8, |
| + dir_count: u32, |
| + map_dir_list: *const c_void, |
| + map_dit_list_count: u32, |
| + env_list: *const c_void, |
| + env_count: u32, |
| + argv: *const u8, |
| + argc: u32, |
| + ); |
| + |
| + fn wasm_application_execute_main( |
| + module_inst: *const c_void, |
| + argc: u32, |
| + argv: *const u8, |
| + ) -> bool; |
| + |
| + fn wasm_runtime_instantiate( |
| + module: *const c_void, |
| + stack_size: u32, |
| + heap_size: u32, |
| + error_buf: *mut u8, |
| + error_buf_size: u32, |
| + ) -> *const c_void; |
| + |
| + fn wasm_runtime_get_exception(module_inst: *const c_void) -> *const c_char; |
| + |
| + fn wasm_runtime_deinstantiate(module_inst: *const c_void); |
| + |
| + fn wasm_runtime_unload(module: *const c_void); |
| + |
| + fn wasm_runtime_destroy(); |
| + |
| +} |
| + |
| +fn get_key(arguments: &FunctionArguments, key: &str) -> String { |
| + let args = arguments.clone().into_vec(); |
| + let len = args.len(); |
| + for (i, arg) in args.iter().enumerate() { |
| + if (arg.eq(key)) && i < (len - 1) { |
| + return args[i + 1].clone(); |
| + } |
| + } |
| + String::from("") |
| +} |
| + |
| +#[derive(Default)] |
| +pub struct CleanroomRuntime; |
| + |
| +impl TeaclaveExecutor for CleanroomRuntime { |
| + fn execute( |
| + &self, |
| + _name: String, |
| + arguments: FunctionArguments, |
| + payload: Vec<u8>, |
| + runtime: FunctionRuntime, |
| + ) -> anyhow::Result<String> { |
| + let debug_flag = get_key(&arguments, "debug"); |
| + let argv_string = get_key(&arguments, "args"); |
| + let dir_argv_string = get_key(&arguments, "wdir"); |
| + let current_time = SystemTime::now(); |
| + |
| + if debug_flag.eq("true") { |
| + unsafe { DEBUG_FLAG = 1 }; |
| + } else { |
| + unsafe { DEBUG_FLAG = 0 }; |
| + } |
| + let mut argvs: Vec<String>; |
| + if argv_string.trim().is_empty() { |
| + argvs = Vec::new(); |
| + } else { |
| + argvs = serde_json::from_str(&argv_string) |
| + .map_err(|_| anyhow!("Cleanroom: invalid input arguments"))?; |
| + argvs.retain(|x| (!x.is_empty())); |
| + } |
| + log::warn!("argvs: {:?}", &argvs); |
| + let argv_cstr: Vec<_> = argvs |
| + .iter() |
| + .map(|arg| CString::new(arg.as_str())) |
| + .collect::<Result<_, _>>()?; |
| + |
| + let argv: Vec<_> = argv_cstr |
| + .iter() |
| + .map(|arg| arg.as_bytes_with_nul().as_ptr()) |
| + .collect(); |
| + let argc = argv.len(); |
| + let dir_argvs: Vec<String> = dir_argv_string.split(' ').map(|s| s.to_string()).collect(); |
| + log::debug!("working directory: {:?}", &dir_argvs); |
| + let dir_argv_cstr: Vec<_> = dir_argvs |
| + .iter() |
| + .map(|arg| CString::new(arg.as_str())) |
| + .collect::<Result<_, _>>()?; |
| + |
| + let dir_argv: Vec<_> = dir_argv_cstr |
| + .iter() |
| + .map(|arg| arg.as_bytes_with_nul().as_ptr()) |
| + .collect(); |
| + let dir_argc = dir_argv.len(); |
| + |
| + let mut error_buf = [0u8; DEFAULT_ERROR_BUF_SIZE]; |
| + |
| + set_thread_context(Context::new(runtime))?; |
| + let mut result; |
| + let ret = unsafe { wasm_runtime_init() }; |
| + if !ret { |
| + reset_thread_context()?; |
| + let time_duration = current_time.elapsed()?; |
| + let time_secs = time_duration.as_secs_f32(); |
| + let summary = Summary { |
| + status: false, |
| + reason: "wasm runtime init failed".to_string(), |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + |
| + let module = unsafe { |
| + wasm_runtime_load( |
| + payload.as_ptr(), |
| + payload.len() as u32, |
| + error_buf.as_mut_ptr(), |
| + error_buf.len() as u32, |
| + ) |
| + }; |
| + |
| + rust_printf(error_buf.as_mut_ptr() as *const i8); |
| + if (module as usize) == 0 { |
| + unsafe { wasm_runtime_destroy() }; |
| + reset_thread_context()?; |
| + let time_duration = current_time.elapsed()?; |
| + let time_secs = time_duration.as_secs_f32(); |
| + |
| + let summary = Summary { |
| + status: false, |
| + reason: "wasm runtime load failed".to_string(), |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + |
| + unsafe { |
| + wasm_runtime_set_wasi_args( |
| + module, |
| + dir_argv.as_ptr() as *const u8, |
| + dir_argc as u32, |
| + ptr::null_mut(), |
| + 0, |
| + ptr::null_mut(), |
| + 0, |
| + argv.as_ptr() as *const u8, |
| + argc as u32, |
| + ) |
| + }; |
| + error_buf = [0u8; DEFAULT_ERROR_BUF_SIZE]; |
| + let module_instance = unsafe { |
| + wasm_runtime_instantiate( |
| + module, |
| + DEFAULT_STACK_SIZE, |
| + DEFAULT_HEAP_SIZE, |
| + error_buf.as_mut_ptr(), |
| + error_buf.len() as u32, |
| + ) |
| + }; |
| + |
| + if (module_instance as usize) == 0 { |
| + unsafe { wasm_runtime_unload(module) }; |
| + unsafe { wasm_runtime_destroy() }; |
| + reset_thread_context()?; |
| + let time_duration = current_time.elapsed()?; |
| + let time_secs = time_duration.as_secs_f32(); |
| + let summary = Summary { |
| + status: false, |
| + reason: "wasm runtime instantiate failed".to_string(), |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + |
| + result = unsafe { wasm_application_execute_main(module_instance, 0, ptr::null_mut()) }; |
| + |
| + let exception = unsafe { wasm_runtime_get_exception(module_instance) }; |
| + unsafe { |
| + if !exception.is_null() { |
| + log::debug!( |
| + "Exception: {:?}", |
| + CStr::from_ptr(exception).to_string_lossy(), |
| + ); |
| + result = false; |
| + } |
| + } |
| + |
| + unsafe { wasm_runtime_deinstantiate(module_instance) }; |
| + unsafe { wasm_runtime_unload(module) }; |
| + unsafe { wasm_runtime_destroy() }; |
| + reset_thread_context()?; |
| + let time_duration = current_time.elapsed()?; |
| + let time_secs = time_duration.as_secs_f32(); |
| + |
| + let summary = Summary { |
| + status: result, |
| + reason: "Succeed".to_string(), |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + Ok(summary_result) |
| + } |
| +} |
| + |
| +#[cfg(feature = "enclave_unit_test")] |
| +pub mod tests { |
| + use super::*; |
| + #[cfg(feature = "mesalock_sgx")] |
| + use std::collections::HashMap; |
| + use std::untrusted::fs; |
| + use teaclave_crypto::*; |
| + use teaclave_runtime::*; |
| + use teaclave_test_utils::*; |
| + use teaclave_types::*; |
| + |
| + const IN_STDIN_FILE: &str = "input_file"; |
| + const OUT_STDOUT_FILE: &str = "output_file"; |
| + |
| + pub fn run_tests() -> bool { |
| + run_tests!( |
| + test_readfile, |
| + test_args, |
| + test_stdout, |
| + test_stdin, |
| + test_algorithm1, |
| + test_stderr, |
| + ) |
| + } |
| + |
| + fn test_readfile() { |
| + let mut args = HashMap::new(); |
| + args.insert("args".to_string(), "".to_string()); |
| + args.insert("wdir".to_string(), "data".to_string()); |
| + let args = FunctionArguments::from(args); |
| + let wa_payload = |
| + include_bytes!("../../tests/fixtures/functions/cleanroom-readfile/readfile.wasm"); |
| + |
| + let wa_payload = wa_payload.to_vec(); |
| + let stdin = "fixtures/functions/cleanroom-readfile/stdin"; |
| + let input_info = |
| + StagedFileInfo::new(stdin, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let stdout = "fixtures/functions/cleanroom-readfile/stdout"; |
| + let output_info = |
| + StagedFileInfo::new(stdout, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let config_file = "fixtures/functions/cleanroom-readfile/data/a.txt"; |
| + let config_file_info = StagedFileInfo::new( |
| + config_file, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new(hashmap!(IN_STDIN_FILE => input_info, |
| + "data/a.txt" => config_file_info)); |
| + let output_files = StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info)); |
| + |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + |
| + let function = CleanroomRuntime::default(); |
| + let _summary = function |
| + .execute("".to_string(), args, wa_payload, runtime) |
| + .unwrap(); |
| + |
| + let stdout_result = fs::read_to_string(&stdout).unwrap(); |
| + log::debug!("{:?}", stdout_result); |
| + } |
| + |
| + fn test_stdout() { |
| + let args = HashMap::new(); |
| + |
| + let args = FunctionArguments::from(args); |
| + |
| + let wa_payload = include_bytes!("../../tests/fixtures/functions/cleanroom-stdout/test.aot"); |
| + |
| + let wa_payload = wa_payload.to_vec(); |
| + let input_seq = "fixtures/functions/cleanroom-stdout/stdin"; |
| + let input_info = |
| + StagedFileInfo::new(input_seq, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let output_seq = "fixtures/functions/cleanroom-stdout/stdout"; |
| + let output_info = StagedFileInfo::new( |
| + output_seq, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new(hashmap!(IN_STDIN_FILE => input_info)); |
| + let output_files = StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info)); |
| + |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + |
| + let function = CleanroomRuntime::default(); |
| + let _summary = function |
| + .execute("".to_string(), args, wa_payload, runtime) |
| + .unwrap(); |
| + |
| + let output_data = fs::read_to_string(&output_seq).unwrap(); |
| + log::debug!("Hello world: {:?}", output_data); |
| + } |
| + |
| + fn test_stdin() { |
| + let args = HashMap::new(); |
| + |
| + let args = FunctionArguments::from(args); |
| + |
| + let wa_payload = |
| + include_bytes!("../../tests/fixtures/functions/cleanroom-stdin/getline.wasm"); |
| + |
| + let wa_payload = wa_payload.to_vec(); |
| + let input_seq = "fixtures/functions/cleanroom-stdin/stdin"; |
| + let input_info = |
| + StagedFileInfo::new(input_seq, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + let output_seq = "fixtures/functions/cleanroom-stdin/stdout"; |
| + let output_info = StagedFileInfo::new( |
| + output_seq, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new(hashmap!(IN_STDIN_FILE => input_info)); |
| + let output_files = StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info)); |
| + |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + |
| + let function = CleanroomRuntime::default(); |
| + let _summary = function |
| + .execute("".to_string(), args, wa_payload, runtime) |
| + .unwrap(); |
| + |
| + let output_data = fs::read_to_string(&output_seq).unwrap(); |
| + log::debug!("{:?}", output_data); |
| + } |
| + |
| + fn test_args() { |
| + let mut args = HashMap::new(); |
| + args.insert( |
| + "args".to_string(), |
| + r#"["1", "2", "3", "4", "5", "6", "7"]"#.to_string(), |
| + ); |
| + let args = FunctionArguments::from(args); |
| + let wa_payload = include_bytes!("../../tests/fixtures/functions/cleanroom-args/args.wasm"); |
| + |
| + let wa_payload = wa_payload.to_vec(); |
| + let stdin = "fixtures/functions/cleanroom-args/stdin"; |
| + let input_info = |
| + StagedFileInfo::new(stdin, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let stdout = "fixtures/functions/cleanroom-args/stdout"; |
| + let output_info = |
| + StagedFileInfo::new(stdout, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let input_files = StagedFiles::new(hashmap!(IN_STDIN_FILE => input_info)); |
| + let output_files = StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info)); |
| + |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + |
| + let function = CleanroomRuntime::default(); |
| + let _summary = function |
| + .execute("".to_string(), args, wa_payload, runtime) |
| + .unwrap(); |
| + |
| + let stdout_result = fs::read_to_string(&stdout).unwrap(); |
| + log::debug!("{:?}", stdout_result); |
| + } |
| + |
| + fn test_algorithm1() { |
| + let mut args = HashMap::new(); |
| + args.insert( |
| + "args".to_string(), |
| + r#"["algorithm1_v", "100", "0", "0", "0", "0", "0", "5.0", "example.shape"]"# |
| + .to_string(), |
| + ); |
| + args.insert("wdir".to_string(), ".".to_string()); |
| + let args = FunctionArguments::from(args); |
| + |
| + let wa_payload = |
| + include_bytes!("../../tests/fixtures/functions/cleanroom-algorithm1/algorithm1.aot"); |
| + |
| + let wa_payload = wa_payload.to_vec(); |
| + let stdin = "fixtures/functions/cleanroom-algorithm1/testseq"; |
| + let input_info = |
| + StagedFileInfo::new(stdin, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let stdout = "fixtures/functions/cleanroom-algorithm1/stdout"; |
| + let output_info = |
| + StagedFileInfo::new(stdout, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let config_file = "fixtures/functions/cleanroom-algorithm1/example.shape"; |
| + let config_file_info = StagedFileInfo::new( |
| + config_file, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new( |
| + hashmap!(IN_STDIN_FILE => input_info, "example.shape" => config_file_info), |
| + ); |
| + let output_files = StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info)); |
| + |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + |
| + let function = CleanroomRuntime::default(); |
| + let _summary = function |
| + .execute("".to_string(), args, wa_payload, runtime) |
| + .unwrap(); |
| + |
| + let stdout_result = fs::read_to_string(&stdout).unwrap(); |
| + log::debug!("{:?}", stdout_result); |
| + } |
| + |
| + fn test_stderr() { |
| + let mut args = HashMap::new(); |
| + args.insert("args".to_string(), r#"["1", "12"]"#.to_string()); |
| + args.insert("debug".to_string(), "true".to_string()); |
| + |
| + let args = FunctionArguments::from(args); |
| + |
| + let wa_payload = include_bytes!("../../tests/fixtures/functions/cleanroom-stderr/app.wasm"); |
| + |
| + let wa_payload = wa_payload.to_vec(); |
| + let input_seq = "fixtures/functions/cleanroom-stderr/stdin"; |
| + let input_info = |
| + StagedFileInfo::new(input_seq, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let output_seq = "fixtures/functions/cleanroom-stderr/stdout"; |
| + let output_info = StagedFileInfo::new( |
| + output_seq, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let log_seq = "fixtures/functions/cleanroom-stderr/stderr"; |
| + let log_info = |
| + StagedFileInfo::new(log_seq, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let input_files = StagedFiles::new(hashmap!(IN_STDIN_FILE => input_info)); |
| + let output_files = |
| + StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info,"log_file" => log_info)); |
| + |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + |
| + let function = CleanroomRuntime::default(); |
| + let _summary = function |
| + .execute("cleanroom".to_string(), args, wa_payload, runtime) |
| + .unwrap(); |
| + |
| + let output_data = fs::read_to_string(&output_seq).unwrap(); |
| + log::debug!("Hello world: {:?}", output_data); |
| + } |
| +} |
| diff --git a/executor/src/lib.rs b/executor/src/lib.rs |
| index 86a4c2e..691629b 100644 |
| --- a/executor/src/lib.rs |
| +++ b/executor/src/lib.rs |
| @@ -26,6 +26,7 @@ extern crate log; |
| |
| #[cfg(executor_builtin)] |
| mod builtin; |
| +mod cleanroom; |
| #[cfg(executor_mesapy)] |
| mod mesapy; |
| #[cfg(executor_wamr)] |
| @@ -33,6 +34,7 @@ mod wamr; |
| |
| #[cfg(executor_builtin)] |
| pub use builtin::BuiltinFunctionExecutor; |
| +pub use cleanroom::CleanroomRuntime; |
| #[cfg(executor_mesapy)] |
| pub use mesapy::MesaPy; |
| #[cfg(executor_wamr)] |
| @@ -48,8 +50,9 @@ pub mod tests { |
| v.push(mesapy::tests::run_tests()); |
| #[cfg(executor_builtin)] |
| v.push(builtin::tests::run_tests()); |
| - #[cfg(executor_wamr)] |
| - v.push(wamr::tests::run_tests()); |
| + //#[cfg(executor_wamr)] |
| + //v.push(wamr::tests::run_tests()); |
| + v.push(cleanroom::tests::run_tests()); |
| v.iter().all(|&x| x) |
| } |
| } |
| diff --git a/executor/src/wamr.rs b/executor/src/wamr.rs |
| index 21c9cb8..4840200 100644 |
| --- a/executor/src/wamr.rs |
| +++ b/executor/src/wamr.rs |
| @@ -266,6 +266,7 @@ pub mod tests { |
| use teaclave_test_utils::*; |
| use teaclave_types::*; |
| |
| + #[allow(unused)] |
| pub fn run_tests() -> bool { |
| run_tests!(test_wamr_tvm_mnist, test_wamr_millionaire,) |
| } |
| diff --git a/file_agent/Cargo.lock b/file_agent/Cargo.lock |
| index 2d01445..fdfbc6c 100644 |
| --- a/file_agent/Cargo.lock |
| +++ b/file_agent/Cargo.lock |
| @@ -715,7 +715,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "protected_fs_rs" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "cfg-if 0.1.10", |
| "libc", |
| @@ -1026,7 +1026,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_crypto" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "hex", |
| @@ -1039,7 +1039,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_file_agent" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "base64", |
| @@ -1061,7 +1061,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_test_utils" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "inventory", |
| "teaclave_test_utils_proc_macro", |
| @@ -1078,7 +1078,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_types" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "hex", |
| diff --git a/file_agent/Cargo.toml b/file_agent/Cargo.toml |
| index 6878669..d656ee7 100644 |
| --- a/file_agent/Cargo.toml |
| +++ b/file_agent/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_file_agent" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave file agent for worker" |
| license = "Apache-2.0" |
| @@ -31,7 +31,7 @@ crate-type = ["staticlib", "rlib"] |
| default = [] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| base64 = { version = "0.13.0" } |
| serde_json = { version = "1.0.39" } |
| diff --git a/function/Cargo.toml b/function/Cargo.toml |
| index 2c94ca4..a8e084e 100644 |
| --- a/function/Cargo.toml |
| +++ b/function/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_function" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave built-in functions." |
| license = "Apache-2.0" |
| @@ -43,7 +43,7 @@ enclave_unit_test = [ |
| ] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| serde_json = { version = "1.0.39" } |
| serde = { version = "1.0.92", features = ["derive"] } |
| @@ -63,6 +63,7 @@ teaclave_runtime = { path = "../runtime", optional = true } |
| teaclave_test_utils = { path = "../tests/utils", optional = true } |
| teaclave_executor_context = { path = "../executor/context" } |
| |
| + |
| sgx_cov = { version = "1.1.3", optional = true } |
| sgx_tstd = { version = "1.1.3", features = ["net", "thread", "backtrace"], optional = true } |
| sgx_types = { version = "1.1.3" } |
| diff --git a/function/src/cleanroom_algorithm2.rs b/function/src/cleanroom_algorithm2.rs |
| new file mode 100644 |
| index 0000000..2f07a24 |
| --- /dev/null |
| +++ b/function/src/cleanroom_algorithm2.rs |
| @@ -0,0 +1,325 @@ |
| +// 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 std::prelude::v1::*; |
| + |
| +use teaclave_executor_context::context::reset_thread_context; |
| +use teaclave_executor_context::context::set_thread_context; |
| +use teaclave_executor_context::context::Context; |
| + |
| +use crate::cleanroom_algorithm2_hash::CLEANROOM_NATIVE_DEBUG_FLAG; |
| +use anyhow::anyhow; |
| +use serde::{Deserialize, Serialize}; |
| +use std::ffi::{CStr, CString}; |
| +use std::format; |
| +use std::time::SystemTime; |
| +use teaclave_types::{FunctionArguments, FunctionRuntime}; |
| + |
| +#[cfg(feature = "mesalock_sgx")] |
| +use std::untrusted::time::SystemTimeEx; |
| + |
| +#[derive(Default)] |
| +pub struct Algorithm2; |
| + |
| +const DEFAULT_ERROR_BUF_SIZE: usize = 128; |
| + |
| +#[derive(Serialize, Deserialize)] |
| +struct Summary { |
| + status: bool, |
| + reason: String, |
| + execution_time: f32, |
| +} |
| + |
| +extern "C" { |
| + fn call_algorithm2_classic( |
| + argc: u32, |
| + argv: *const u8, |
| + error_buf: *mut u8, |
| + error_buf_size: u32, |
| + error_code: *mut u32, |
| + ) -> u32; |
| +} |
| + |
| +fn get_key(arguments: &FunctionArguments, key: &str) -> String { |
| + let args = arguments.clone().into_vec(); |
| + let len = args.len(); |
| + for (i, arg) in args.iter().enumerate() { |
| + if (arg.eq(key)) && i < (len - 1) { |
| + return args[i + 1].clone(); |
| + } |
| + } |
| + String::from("") |
| +} |
| + |
| +impl Algorithm2 { |
| + pub const NAME: &'static str = "builtin-cleanroom-algorithm2"; |
| + |
| + pub fn new() -> Self { |
| + Default::default() |
| + } |
| + |
| + pub fn run( |
| + &self, |
| + arguments: FunctionArguments, |
| + runtime: FunctionRuntime, |
| + ) -> anyhow::Result<String> { |
| + let debug_flag = get_key(&arguments, "debug"); |
| + let argv_string = get_key(&arguments, "args"); |
| + let current_time = SystemTime::now(); |
| + log::info!("Hello cleanroom algorithm2: {:?}", arguments.into_vec()); |
| + |
| + if debug_flag.eq("true") { |
| + unsafe { CLEANROOM_NATIVE_DEBUG_FLAG = 1 }; |
| + } else { |
| + unsafe { CLEANROOM_NATIVE_DEBUG_FLAG = 0 }; |
| + } |
| + |
| + let mut argvs: Vec<String>; |
| + if argv_string.trim().is_empty() { |
| + argvs = Vec::new(); |
| + } else { |
| + argvs = serde_json::from_str(&argv_string) |
| + .map_err(|_| anyhow!("Cleanroom: invalid input arguments"))?; |
| + argvs.retain(|x| (!x.is_empty())); |
| + } |
| + log::warn!("argvs: {:?}", &argvs); |
| + let argv_cstr: Vec<_> = argvs |
| + .iter() |
| + .map(|arg| CString::new(arg.as_str())) |
| + .collect::<Result<_, _>>()?; |
| + let argv: Vec<_> = argv_cstr |
| + .iter() |
| + .map(|arg| arg.as_bytes_with_nul().as_ptr()) |
| + .collect(); |
| + let argc = argv.len(); |
| + let mut error_buf = [0u8; DEFAULT_ERROR_BUF_SIZE]; |
| + let mut error_code = 0; |
| + set_thread_context(Context::new(runtime))?; |
| + let ret = unsafe { |
| + call_algorithm2_classic( |
| + argc as u32, |
| + argv.as_ptr() as *const u8, |
| + error_buf.as_mut_ptr(), |
| + error_buf.len() as u32, |
| + &mut error_code, |
| + ) |
| + }; |
| + log::warn!("Return code {:?}", ret); |
| + reset_thread_context()?; |
| + let time_duration = current_time.elapsed()?; |
| + let time_secs = time_duration.as_secs_f32(); |
| + if error_code != 0 { |
| + let buf_str = unsafe { CStr::from_ptr(error_buf.as_mut_ptr() as *const i8) }; |
| + let buf_str_slice = buf_str.to_string_lossy(); |
| + let result_exception = format!( |
| + "Function got exceptions ({}). Reason: {}", |
| + error_code, buf_str_slice, |
| + ); |
| + let summary = Summary { |
| + status: false, |
| + reason: result_exception, |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + if ret != 0 { |
| + let result_error_code = format!( |
| + "Function returned with error code: {}. Please enable the diagnosis mode.", |
| + ret |
| + ); |
| + let summary = Summary { |
| + status: false, |
| + reason: result_error_code, |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + let summary = Summary { |
| + status: true, |
| + reason: "Succeeded".to_string(), |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + Ok(summary_result) |
| + } |
| +} |
| + |
| +#[cfg(feature = "enclave_unit_test")] |
| +pub mod tests { |
| + use super::*; |
| + #[cfg(feature = "mesalock_sgx")] |
| + use std::collections::HashMap; |
| + use std::untrusted::fs; |
| + use teaclave_crypto::*; |
| + use teaclave_runtime::*; |
| + use teaclave_test_utils::*; |
| + use teaclave_types::*; |
| + |
| + const IN_STDIN_FILE: &str = "input_file"; |
| + const OUT_STDOUT_FILE: &str = "output_file"; |
| + |
| + pub fn run_tests() -> bool { |
| + run_tests!( |
| + test_cleanroom_native, |
| + test_algorithm2_stderr_native, |
| + test_algorithm2_exception_native |
| + ) |
| + } |
| + |
| + fn test_cleanroom_native() { |
| + let mut args = HashMap::new(); |
| + args.insert( |
| + "args".to_string(), |
| + r#"["algorithm2", "100", "200"]"#.to_string(), |
| + ); |
| + let args = FunctionArguments::from(args); |
| + |
| + let stdin = "fixtures/functions/cleanroom-algorithm2-hash/stdin"; |
| + let input_info = |
| + StagedFileInfo::new(stdin, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let stdout = "fixtures/functions/cleanroom-algorithm2-hash/stdout"; |
| + let output_info = |
| + StagedFileInfo::new(stdout, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let config_file1 = "fixtures/functions/cleanroom-algorithm2-hash/coding_wheel.txt"; |
| + let config_file_info1 = StagedFileInfo::new( |
| + config_file1, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let config_file2 = |
| + "fixtures/functions/cleanroom-algorithm2-hash/codon_usage_freq_table_human.csv"; |
| + let config_file_info2 = StagedFileInfo::new( |
| + config_file2, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new( |
| + hashmap!(IN_STDIN_FILE => input_info, "./coding_wheel.txt" => config_file_info1, "./codon_usage_freq_table_human.csv" => config_file_info2), |
| + ); |
| + |
| + let output_files = StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info)); |
| + |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + let function = Algorithm2; |
| + |
| + let summary = function.run(args, runtime).unwrap(); |
| + log::warn!("{:?}", summary); |
| + } |
| + |
| + fn test_algorithm2_stderr_native() { |
| + let mut args = HashMap::new(); |
| + args.insert("args".to_string(), r#"["algorithm2"]"#.to_string()); |
| + args.insert("debug".to_string(), "true".to_string()); |
| + let args = FunctionArguments::from(args); |
| + |
| + let stdin = "fixtures/functions/cleanroom-algorithm2-hash/stdin"; |
| + let input_info = |
| + StagedFileInfo::new(stdin, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let stdout = "fixtures/functions/cleanroom-algorithm2-hash/stdout1"; |
| + let output_info = |
| + StagedFileInfo::new(stdout, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let log_seq = "fixtures/functions/cleanroom-algorithm2-hash/stderr1"; |
| + let log_info = |
| + StagedFileInfo::new(log_seq, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let config_file1 = "fixtures/functions/cleanroom-algorithm2-hash/coding_wheel.txt"; |
| + let config_file_info1 = StagedFileInfo::new( |
| + config_file1, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let config_file2 = |
| + "fixtures/functions/cleanroom-algorithm2-hash/codon_usage_freq_table_human.csv"; |
| + let config_file_info2 = StagedFileInfo::new( |
| + config_file2, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new( |
| + hashmap!(IN_STDIN_FILE => input_info, "./coding_wheel.txt" => config_file_info1, "./codon_usage_freq_table_human.csv" => config_file_info2), |
| + ); |
| + |
| + let output_files = |
| + StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info, "log_file" => log_info)); |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + let function = Algorithm2; |
| + |
| + let summary = function.run(args, runtime).unwrap(); |
| + log::warn!("{:?}", summary); |
| + let log_info = fs::read_to_string(&log_seq).unwrap(); |
| + log::warn!("Stderr result: {:?}", log_info); |
| + } |
| + |
| + fn test_algorithm2_exception_native() { |
| + let mut args = HashMap::new(); |
| + args.insert( |
| + "args".to_string(), |
| + r#"["algorithm2", "100", "200"]"#.to_string(), |
| + ); |
| + args.insert("debug".to_string(), "true".to_string()); |
| + let args = FunctionArguments::from(args); |
| + |
| + let stdin = "fixtures/functions/cleanroom-algorithm2-hash/stdin2"; |
| + let input_info = |
| + StagedFileInfo::new(stdin, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let stdout = "fixtures/functions/cleanroom-algorithm2-hash/stdout2"; |
| + let output_info = |
| + StagedFileInfo::new(stdout, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let log_seq = "fixtures/functions/cleanroom-algorithm2-hash/stderr2"; |
| + let log_info = |
| + StagedFileInfo::new(log_seq, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let config_file1 = "fixtures/functions/cleanroom-algorithm2-hash/coding_wheel.txt"; |
| + let config_file_info1 = StagedFileInfo::new( |
| + config_file1, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let config_file2 = |
| + "fixtures/functions/cleanroom-algorithm2-hash/codon_usage_freq_table_human.csv"; |
| + let config_file_info2 = StagedFileInfo::new( |
| + config_file2, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new( |
| + hashmap!(IN_STDIN_FILE => input_info, "./coding_wheel.txt" => config_file_info1, "./codon_usage_freq_table_human.csv" => config_file_info2), |
| + ); |
| + |
| + let output_files = |
| + StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info, "log_file" => log_info)); |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + let function = Algorithm2; |
| + |
| + let summary = function.run(args, runtime).unwrap(); |
| + log::warn!("{:?}", summary); |
| + } |
| +} |
| diff --git a/function/src/cleanroom_algorithm2_hash.rs b/function/src/cleanroom_algorithm2_hash.rs |
| new file mode 100644 |
| index 0000000..f98041a |
| --- /dev/null |
| +++ b/function/src/cleanroom_algorithm2_hash.rs |
| @@ -0,0 +1,338 @@ |
| +// 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 std::prelude::v1::*; |
| + |
| +use teaclave_executor_context::context::reset_thread_context; |
| +use teaclave_executor_context::context::set_thread_context; |
| +use teaclave_executor_context::context::Context; |
| + |
| +use anyhow::anyhow; |
| +use serde::{Deserialize, Serialize}; |
| +use std::ffi::{CStr, CString}; |
| +use std::format; |
| +use std::os::raw::c_char; |
| +use std::time::SystemTime; |
| +use teaclave_types::{FunctionArguments, FunctionRuntime}; |
| + |
| +#[cfg(feature = "mesalock_sgx")] |
| +use std::untrusted::time::SystemTimeEx; |
| + |
| +#[derive(Default)] |
| +pub struct Algorithm2Hash; |
| + |
| +const DEFAULT_ERROR_BUF_SIZE: usize = 128; |
| + |
| +#[allow(unused)] |
| +#[no_mangle] |
| +pub static mut CLEANROOM_NATIVE_DEBUG_FLAG: i32 = 0; |
| + |
| +#[allow(unused)] |
| +#[no_mangle] |
| +pub extern "C" fn cleanroom_native_printf(c_buf: *const c_char) { |
| + let c_str = unsafe { CStr::from_ptr(c_buf) }; |
| + let str_slice = c_str.to_string_lossy(); |
| + log::debug!("Cleanroom Algorithm2 hash: {:?}", str_slice); |
| +} |
| + |
| +#[derive(Serialize, Deserialize)] |
| +struct Summary { |
| + status: bool, |
| + reason: String, |
| + execution_time: f32, |
| +} |
| + |
| +extern "C" { |
| + fn call_algorithm2( |
| + argc: u32, |
| + argv: *const u8, |
| + error_buf: *mut u8, |
| + error_buf_size: u32, |
| + error_code: *mut u32, |
| + ) -> u32; |
| +} |
| + |
| +fn get_key(arguments: &FunctionArguments, key: &str) -> String { |
| + let args = arguments.clone().into_vec(); |
| + let len = args.len(); |
| + for (i, arg) in args.iter().enumerate() { |
| + if (arg.eq(key)) && i < (len - 1) { |
| + return args[i + 1].clone(); |
| + } |
| + } |
| + String::from("") |
| +} |
| + |
| +impl Algorithm2Hash { |
| + pub const NAME: &'static str = "builtin-cleanroom-algorithm2-hash"; |
| + |
| + pub fn new() -> Self { |
| + Default::default() |
| + } |
| + |
| + pub fn run( |
| + &self, |
| + arguments: FunctionArguments, |
| + runtime: FunctionRuntime, |
| + ) -> anyhow::Result<String> { |
| + let debug_flag = get_key(&arguments, "debug"); |
| + let argv_string = get_key(&arguments, "args"); |
| + let current_time = SystemTime::now(); |
| + log::info!("Cleanroom algorithm2 hash: {:?}", arguments.into_vec()); |
| + |
| + if debug_flag.eq("true") { |
| + unsafe { CLEANROOM_NATIVE_DEBUG_FLAG = 1 }; |
| + } else { |
| + unsafe { CLEANROOM_NATIVE_DEBUG_FLAG = 0 }; |
| + } |
| + |
| + let mut argvs: Vec<String>; |
| + if argv_string.trim().is_empty() { |
| + argvs = Vec::new(); |
| + } else { |
| + argvs = serde_json::from_str(&argv_string) |
| + .map_err(|_| anyhow!("Cleanroom: invalid input arguments"))?; |
| + argvs.retain(|x| (!x.is_empty())); |
| + argvs.retain(|x| (!x.starts_with("--"))); |
| + } |
| + log::warn!("argvs: {:?}", &argvs); |
| + let argv_cstr: Vec<_> = argvs |
| + .iter() |
| + .map(|arg| CString::new(arg.as_str())) |
| + .collect::<Result<_, _>>()?; |
| + let argv: Vec<_> = argv_cstr |
| + .iter() |
| + .map(|arg| arg.as_bytes_with_nul().as_ptr()) |
| + .collect(); |
| + let argc = argv.len(); |
| + let mut error_buf = [0u8; DEFAULT_ERROR_BUF_SIZE]; |
| + let mut error_code = 0; |
| + set_thread_context(Context::new(runtime))?; |
| + let ret = unsafe { |
| + call_algorithm2( |
| + argc as u32, |
| + argv.as_ptr() as *const u8, |
| + error_buf.as_mut_ptr(), |
| + error_buf.len() as u32, |
| + &mut error_code, |
| + ) |
| + }; |
| + log::warn!("Return code {:?}", ret); |
| + reset_thread_context()?; |
| + let time_duration = current_time.elapsed()?; |
| + let time_secs = time_duration.as_secs_f32(); |
| + if error_code != 0 { |
| + let buf_str = unsafe { CStr::from_ptr(error_buf.as_mut_ptr() as *const i8) }; |
| + let buf_str_slice = buf_str.to_string_lossy(); |
| + let result_exception = format!( |
| + "Function got exceptions ({}). Reason: {}", |
| + error_code, buf_str_slice, |
| + ); |
| + let summary = Summary { |
| + status: false, |
| + reason: result_exception, |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + if ret != 0 { |
| + let result_error_code = format!( |
| + "Function returned with error code: {}. Please enable the diagnosis mode.", |
| + ret |
| + ); |
| + let summary = Summary { |
| + status: false, |
| + reason: result_error_code, |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + let summary = Summary { |
| + status: true, |
| + reason: "Succeeded".to_string(), |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + Ok(summary_result) |
| + } |
| +} |
| + |
| +#[cfg(feature = "enclave_unit_test")] |
| +pub mod tests { |
| + use super::*; |
| + #[cfg(feature = "mesalock_sgx")] |
| + use std::collections::HashMap; |
| + use std::untrusted::fs; |
| + use teaclave_crypto::*; |
| + use teaclave_runtime::*; |
| + use teaclave_test_utils::*; |
| + use teaclave_types::*; |
| + |
| + const IN_STDIN_FILE: &str = "input_file"; |
| + const OUT_STDOUT_FILE: &str = "output_file"; |
| + |
| + pub fn run_tests() -> bool { |
| + run_tests!( |
| + test_cleanroom_native, |
| + test_algorithm2_stderr_native, |
| + test_algorithm2_exception_native |
| + ) |
| + } |
| + |
| + fn test_cleanroom_native() { |
| + let mut args = HashMap::new(); |
| + args.insert( |
| + "args".to_string(), |
| + r#"["algorithm2", "100", "200"]"#.to_string(), |
| + ); |
| + let args = FunctionArguments::from(args); |
| + |
| + let stdin = "fixtures/functions/cleanroom-algorithm2-hash/stdin"; |
| + let input_info = |
| + StagedFileInfo::new(stdin, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let stdout = "fixtures/functions/cleanroom-algorithm2-hash/stdout"; |
| + let output_info = |
| + StagedFileInfo::new(stdout, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let config_file1 = "fixtures/functions/cleanroom-algorithm2-hash/coding_wheel.txt"; |
| + let config_file_info1 = StagedFileInfo::new( |
| + config_file1, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let config_file2 = |
| + "fixtures/functions/cleanroom-algorithm2-hash/codon_usage_freq_table_human.csv"; |
| + let config_file_info2 = StagedFileInfo::new( |
| + config_file2, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new( |
| + hashmap!(IN_STDIN_FILE => input_info, "./coding_wheel.txt" => config_file_info1, "./codon_usage_freq_table_human.csv" => config_file_info2), |
| + ); |
| + |
| + let output_files = StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info)); |
| + |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + let function = Algorithm2Hash; |
| + |
| + let summary = function.run(args, runtime).unwrap(); |
| + log::warn!("{:?}", summary); |
| + } |
| + |
| + fn test_algorithm2_stderr_native() { |
| + let mut args = HashMap::new(); |
| + args.insert("args".to_string(), r#"["algorithm2"]"#.to_string()); |
| + args.insert("debug".to_string(), "true".to_string()); |
| + let args = FunctionArguments::from(args); |
| + |
| + let stdin = "fixtures/functions/cleanroom-algorithm2-hash/stdin"; |
| + let input_info = |
| + StagedFileInfo::new(stdin, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let stdout = "fixtures/functions/cleanroom-algorithm2-hash/stdout1"; |
| + let output_info = |
| + StagedFileInfo::new(stdout, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let log_seq = "fixtures/functions/cleanroom-algorithm2-hash/stderr1"; |
| + let log_info = |
| + StagedFileInfo::new(log_seq, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let config_file1 = "fixtures/functions/cleanroom-algorithm2-hash/coding_wheel.txt"; |
| + let config_file_info1 = StagedFileInfo::new( |
| + config_file1, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let config_file2 = |
| + "fixtures/functions/cleanroom-algorithm2-hash/codon_usage_freq_table_human.csv"; |
| + let config_file_info2 = StagedFileInfo::new( |
| + config_file2, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new( |
| + hashmap!(IN_STDIN_FILE => input_info, "./coding_wheel.txt" => config_file_info1, "./codon_usage_freq_table_human.csv" => config_file_info2), |
| + ); |
| + |
| + let output_files = |
| + StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info, "log_file" => log_info)); |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + let function = Algorithm2Hash; |
| + |
| + let summary = function.run(args, runtime).unwrap(); |
| + log::warn!("{:?}", summary); |
| + let log_info = fs::read_to_string(&log_seq).unwrap(); |
| + log::warn!("Stderr result: {:?}", log_info); |
| + } |
| + |
| + fn test_algorithm2_exception_native() { |
| + let mut args = HashMap::new(); |
| + args.insert( |
| + "args".to_string(), |
| + r#"["algorithm2", "100", "200"]"#.to_string(), |
| + ); |
| + args.insert("debug".to_string(), "true".to_string()); |
| + let args = FunctionArguments::from(args); |
| + |
| + let stdin = "fixtures/functions/cleanroom-algorithm2-hash/stdin2"; |
| + let input_info = |
| + StagedFileInfo::new(stdin, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let stdout = "fixtures/functions/cleanroom-algorithm2-hash/stdout2"; |
| + let output_info = |
| + StagedFileInfo::new(stdout, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let log_seq = "fixtures/functions/cleanroom-algorithm2-hash/stderr2"; |
| + let log_info = |
| + StagedFileInfo::new(log_seq, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let config_file1 = "fixtures/functions/cleanroom-algorithm2-hash/coding_wheel.txt"; |
| + let config_file_info1 = StagedFileInfo::new( |
| + config_file1, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let config_file2 = |
| + "fixtures/functions/cleanroom-algorithm2-hash/codon_usage_freq_table_human.csv"; |
| + let config_file_info2 = StagedFileInfo::new( |
| + config_file2, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new( |
| + hashmap!(IN_STDIN_FILE => input_info, "./coding_wheel.txt" => config_file_info1, "./codon_usage_freq_table_human.csv" => config_file_info2), |
| + ); |
| + |
| + let output_files = |
| + StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info, "log_file" => log_info)); |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + let function = Algorithm2Hash; |
| + |
| + let summary = function.run(args, runtime).unwrap(); |
| + log::warn!("{:?}", summary); |
| + } |
| +} |
| diff --git a/function/src/cleanroom_algorithm2_hash_trial.rs b/function/src/cleanroom_algorithm2_hash_trial.rs |
| new file mode 100644 |
| index 0000000..1dc38ed |
| --- /dev/null |
| +++ b/function/src/cleanroom_algorithm2_hash_trial.rs |
| @@ -0,0 +1,163 @@ |
| +// 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 std::prelude::v1::*; |
| + |
| +use crate::cleanroom_algorithm2_hash::CLEANROOM_NATIVE_DEBUG_FLAG; |
| +use anyhow::anyhow; |
| +use serde::{Deserialize, Serialize}; |
| +use std::ffi::{CStr, CString}; |
| +use std::format; |
| +use std::time::SystemTime; |
| +use teaclave_executor_context::context::reset_thread_context; |
| +use teaclave_executor_context::context::set_thread_context; |
| +use teaclave_executor_context::context::Context; |
| +use teaclave_types::{FunctionArguments, FunctionRuntime}; |
| + |
| +#[cfg(feature = "mesalock_sgx")] |
| +use std::untrusted::time::SystemTimeEx; |
| + |
| +#[derive(Default)] |
| +pub struct Algorithm2HashTrial; |
| + |
| +const DEFAULT_ERROR_BUF_SIZE: usize = 128; |
| + |
| +#[derive(Serialize, Deserialize)] |
| +struct Summary { |
| + status: bool, |
| + reason: String, |
| + execution_time: f32, |
| +} |
| + |
| +extern "C" { |
| + fn call_algorithm2_trial( |
| + argc: u32, |
| + argv: *const u8, |
| + error_buf: *mut u8, |
| + error_buf_size: u32, |
| + error_code: *mut u32, |
| + ) -> u32; |
| +} |
| + |
| +fn get_key(arguments: &FunctionArguments, key: &str) -> String { |
| + let args = arguments.clone().into_vec(); |
| + let len = args.len(); |
| + for (i, arg) in args.iter().enumerate() { |
| + if (arg.eq(key)) && i < (len - 1) { |
| + return args[i + 1].clone(); |
| + } |
| + } |
| + String::from("") |
| +} |
| + |
| +impl Algorithm2HashTrial { |
| + pub const NAME: &'static str = "builtin-cleanroom-algorithm2-hash-trial"; |
| + |
| + pub fn new() -> Self { |
| + Default::default() |
| + } |
| + |
| + pub fn run( |
| + &self, |
| + arguments: FunctionArguments, |
| + runtime: FunctionRuntime, |
| + ) -> anyhow::Result<String> { |
| + let debug_flag = get_key(&arguments, "debug"); |
| + let argv_string = get_key(&arguments, "args"); |
| + let current_time = SystemTime::now(); |
| + log::info!( |
| + "Cleanroom algorithm2 hash trial: {:?}", |
| + arguments.into_vec() |
| + ); |
| + |
| + if debug_flag.eq("true") { |
| + unsafe { CLEANROOM_NATIVE_DEBUG_FLAG = 1 }; |
| + } else { |
| + unsafe { CLEANROOM_NATIVE_DEBUG_FLAG = 0 }; |
| + } |
| + |
| + let mut argvs: Vec<String>; |
| + if argv_string.trim().is_empty() { |
| + argvs = Vec::new(); |
| + } else { |
| + argvs = serde_json::from_str(&argv_string) |
| + .map_err(|_| anyhow!("Cleanroom: invalid input arguments"))?; |
| + argvs.retain(|x| (!x.is_empty())); |
| + } |
| + log::warn!("argvs: {:?}", &argvs); |
| + let argv_cstr: Vec<_> = argvs |
| + .iter() |
| + .map(|arg| CString::new(arg.as_str())) |
| + .collect::<Result<_, _>>()?; |
| + let argv: Vec<_> = argv_cstr |
| + .iter() |
| + .map(|arg| arg.as_bytes_with_nul().as_ptr()) |
| + .collect(); |
| + let argc = argv.len(); |
| + let mut error_buf = [0u8; DEFAULT_ERROR_BUF_SIZE]; |
| + let mut error_code = 0; |
| + set_thread_context(Context::new(runtime))?; |
| + let ret = unsafe { |
| + call_algorithm2_trial( |
| + argc as u32, |
| + argv.as_ptr() as *const u8, |
| + error_buf.as_mut_ptr(), |
| + error_buf.len() as u32, |
| + &mut error_code, |
| + ) |
| + }; |
| + log::warn!("Return code {:?}", ret); |
| + reset_thread_context()?; |
| + let time_duration = current_time.elapsed()?; |
| + let time_secs = time_duration.as_secs_f32(); |
| + if error_code != 0 { |
| + let buf_str = unsafe { CStr::from_ptr(error_buf.as_mut_ptr() as *const i8) }; |
| + let buf_str_slice = buf_str.to_string_lossy(); |
| + let result_exception = format!( |
| + "Function got exceptions ({}). Reason: {}", |
| + error_code, buf_str_slice, |
| + ); |
| + let summary = Summary { |
| + status: false, |
| + reason: result_exception, |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + if ret != 0 { |
| + let result_error_code = format!( |
| + "Function returned with error code: {}. Please enable the diagnosis mode.", |
| + ret |
| + ); |
| + let summary = Summary { |
| + status: false, |
| + reason: result_error_code, |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + let summary = Summary { |
| + status: true, |
| + reason: "Succeeded".to_string(), |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + Ok(summary_result) |
| + } |
| +} |
| diff --git a/function/src/cleanroom_algorithm2_hash_trial_tier2.rs b/function/src/cleanroom_algorithm2_hash_trial_tier2.rs |
| new file mode 100644 |
| index 0000000..44740b4 |
| --- /dev/null |
| +++ b/function/src/cleanroom_algorithm2_hash_trial_tier2.rs |
| @@ -0,0 +1,207 @@ |
| +// 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 std::prelude::v1::*; |
| + |
| +use crate::cleanroom_algorithm2_hash::CLEANROOM_NATIVE_DEBUG_FLAG; |
| +use anyhow::anyhow; |
| +use serde::{Deserialize, Serialize}; |
| +use std::ffi::{CStr, CString}; |
| +use std::format; |
| +use std::time::SystemTime; |
| +use teaclave_executor_context::context::reset_thread_context; |
| +use teaclave_executor_context::context::set_thread_context; |
| +use teaclave_executor_context::context::Context; |
| +use teaclave_types::{FunctionArguments, FunctionRuntime}; |
| + |
| +#[cfg(feature = "mesalock_sgx")] |
| +use std::untrusted::time::SystemTimeEx; |
| + |
| +#[derive(Default)] |
| +pub struct Algorithm2HashTrialTier2; |
| + |
| +const DEFAULT_ERROR_BUF_SIZE: usize = 128; |
| + |
| +#[derive(Serialize, Deserialize)] |
| +struct Summary { |
| + status: bool, |
| + reason: String, |
| + execution_time: f32, |
| +} |
| + |
| +/** |
| + * Call algorithm2 trial tier2 function wrapper. |
| + * |
| + * [IN] @param argc the number of arguments. The wrapper only proceeds when the argc is 5. |
| + * [IN] @param argv the arguments array. argv[1] = default_beamsize argv[2] = default_lambda argv[3] = candidate_beamsize argv[4] = candidate_lambda. Each array is serialized as a string. Items in the array are splited with ';'. e.g., [1,2,3] is serialized as "1;2;3;" |
| + * [OUT] @param error_buf |
| + * [OUT] @param error_buf_size |
| + * [OUT] @param error_code |
| + * |
| + * @return 0 if the algorithm2 always returns 0. Callers can check the error code and the |
| + * error_buf to know the reason. |
| + */ |
| +extern "C" { |
| + fn call_algorithm2_trial2( |
| + argc: u32, |
| + argv: *const u8, |
| + error_buf: *mut u8, |
| + error_buf_size: u32, |
| + error_code: *mut u32, |
| + ) -> u32; |
| +} |
| + |
| +fn get_key(arguments: &FunctionArguments, key: &str) -> String { |
| + let args = arguments.clone().into_vec(); |
| + let len = args.len(); |
| + for (i, arg) in args.iter().enumerate() { |
| + if (arg.eq(key)) && i < (len - 1) { |
| + return args[i + 1].clone(); |
| + } |
| + } |
| + String::from("") |
| +} |
| + |
| +impl Algorithm2HashTrialTier2 { |
| + pub const NAME: &'static str = "builtin-cleanroom-algorithm2-hash-trial-tier2"; |
| + |
| + pub fn new() -> Self { |
| + Default::default() |
| + } |
| + |
| + pub fn run( |
| + &self, |
| + arguments: FunctionArguments, |
| + runtime: FunctionRuntime, |
| + ) -> anyhow::Result<String> { |
| + let debug_flag = get_key(&arguments, "debug"); |
| + let argv_string = get_key(&arguments, "args"); |
| + let current_time = SystemTime::now(); |
| + let beamsize_default: [i32; 4] = [10, 100, 500, 1000]; |
| + let lambda_default: [f32; 9] = [0.2, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 10.0]; |
| + let beamsize_candidate: [i32; 4] = [5, 6, 8, 50]; |
| + let lambda_candidate: [f32; 2] = [0.02, 0.3]; |
| + log::info!( |
| + "Cleanroom algorithm2 hash trial tier2: {:?}", |
| + arguments.into_vec() |
| + ); |
| + |
| + if debug_flag.eq("true") { |
| + unsafe { CLEANROOM_NATIVE_DEBUG_FLAG = 1 }; |
| + } else { |
| + unsafe { CLEANROOM_NATIVE_DEBUG_FLAG = 0 }; |
| + } |
| + |
| + let mut argvs: Vec<String>; |
| + if argv_string.trim().is_empty() { |
| + argvs = Vec::new(); |
| + } else { |
| + argvs = serde_json::from_str(&argv_string) |
| + .map_err(|_| anyhow!("Cleanroom: invalid input arguments"))?; |
| + argvs.retain(|x| (!x.is_empty())); |
| + } |
| + if argvs.len() != 5 { |
| + log::info!("Use default arguments"); |
| + argvs.clear(); |
| + let argv = "cleanroom".to_string(); |
| + argvs.push(argv); |
| + let argv = beamsize_default |
| + .iter() |
| + .map(|i| format!("{};", i)) |
| + .collect::<String>(); |
| + argvs.push(argv); |
| + let argv = lambda_default |
| + .iter() |
| + .map(|i| format!("{};", i)) |
| + .collect::<String>(); |
| + argvs.push(argv); |
| + let argv = beamsize_candidate |
| + .iter() |
| + .map(|i| format!("{};", i)) |
| + .collect::<String>(); |
| + argvs.push(argv); |
| + let argv = lambda_candidate |
| + .iter() |
| + .map(|i| format!("{};", i)) |
| + .collect::<String>(); |
| + argvs.push(argv); |
| + } else { |
| + log::info!("Use user's arguments"); |
| + } |
| + log::warn!("argvs: {:?}", &argvs); |
| + let argv_cstr: Vec<_> = argvs |
| + .iter() |
| + .map(|arg| CString::new(arg.as_str())) |
| + .collect::<Result<_, _>>()?; |
| + let argv: Vec<_> = argv_cstr |
| + .iter() |
| + .map(|arg| arg.as_bytes_with_nul().as_ptr()) |
| + .collect(); |
| + let argc = argv.len(); |
| + let mut error_buf = [0u8; DEFAULT_ERROR_BUF_SIZE]; |
| + let mut error_code = 0; |
| + set_thread_context(Context::new(runtime))?; |
| + let ret = unsafe { |
| + call_algorithm2_trial2( |
| + argc as u32, |
| + argv.as_ptr() as *const u8, |
| + error_buf.as_mut_ptr(), |
| + error_buf.len() as u32, |
| + &mut error_code, |
| + ) |
| + }; |
| + log::warn!("Return code {:?}", ret); |
| + reset_thread_context()?; |
| + let time_duration = current_time.elapsed()?; |
| + let time_secs = time_duration.as_secs_f32(); |
| + if error_code != 0 { |
| + let buf_str = unsafe { CStr::from_ptr(error_buf.as_mut_ptr() as *const i8) }; |
| + let buf_str_slice = buf_str.to_string_lossy(); |
| + let result_exception = format!( |
| + "Function got exceptions ({}). Reason: {}", |
| + error_code, buf_str_slice, |
| + ); |
| + let summary = Summary { |
| + status: false, |
| + reason: result_exception, |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + if ret != 0 { |
| + let result_error_code = format!( |
| + "Function returned with error code: {}. Please enable the diagnosis mode.", |
| + ret |
| + ); |
| + let summary = Summary { |
| + status: false, |
| + reason: result_error_code, |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + return Ok(summary_result); |
| + } |
| + let summary = Summary { |
| + status: true, |
| + reason: "Succeeded".to_string(), |
| + execution_time: time_secs, |
| + }; |
| + let summary_result = serde_json::to_string(&summary)?; |
| + Ok(summary_result) |
| + } |
| +} |
| diff --git a/function/src/lib.rs b/function/src/lib.rs |
| index 641512c..ce99049 100644 |
| --- a/function/src/lib.rs |
| +++ b/function/src/lib.rs |
| @@ -22,6 +22,10 @@ extern crate sgx_tstd as std; |
| #[cfg(feature = "mesalock_sgx")] |
| use std::prelude::v1::*; |
| |
| +mod cleanroom_algorithm2; |
| +mod cleanroom_algorithm2_hash; |
| +mod cleanroom_algorithm2_hash_trial; |
| +mod cleanroom_algorithm2_hash_trial_tier2; |
| mod echo; |
| mod face_detection; |
| mod gbdt_predict; |
| @@ -35,6 +39,10 @@ mod principal_components_analysis; |
| mod private_join_and_compute; |
| mod rsa_sign; |
| |
| +pub use cleanroom_algorithm2::Algorithm2; |
| +pub use cleanroom_algorithm2_hash::Algorithm2Hash; |
| +pub use cleanroom_algorithm2_hash_trial::Algorithm2HashTrial; |
| +pub use cleanroom_algorithm2_hash_trial_tier2::Algorithm2HashTrialTier2; |
| pub use echo::Echo; |
| pub use face_detection::FaceDetection; |
| pub use gbdt_predict::GbdtPredict; |
| @@ -55,6 +63,8 @@ pub mod tests { |
| |
| pub fn run_tests() -> bool { |
| check_all_passed!( |
| + cleanroom_algorithm2_hash::tests::run_tests(), |
| + cleanroom_algorithm2::tests::run_tests(), |
| echo::tests::run_tests(), |
| face_detection::tests::run_tests(), |
| gbdt_predict::tests::run_tests(), |
| diff --git a/monitoring/prometheus.py b/monitoring/prometheus.py |
| new file mode 100755 |
| index 0000000..a7d7e79 |
| --- /dev/null |
| +++ b/monitoring/prometheus.py |
| @@ -0,0 +1,87 @@ |
| +#!/usr/bin/env python3 |
| +from prometheus_client import start_http_server, Counter |
| +import random |
| +import time |
| +import sys |
| +import re |
| + |
| +c = Counter('cleanroom_cpk_usage', 'Description of counter', |
| + ['user_id', 'function_id', 'result']) |
| +f_c = Counter('cleanroom_cpk_usage_function_id', 'Description of counter', |
| + ['function_id']) |
| +u_c = Counter('cleanroom_cpk_usage_user_id', 'Description of counter', |
| + ['user_id']) |
| + |
| +frontend_service_c = Counter('cleanroom_frontend_service_total', |
| + "Statistics of frontend service", |
| + ['user_id', 'cli_version', 'request']) |
| +authentication_service_c = Counter('cleanroom_authentication_service_total', |
| + "Statistics of authentiction service", |
| + ['user_id', 'cli_version', 'request']) |
| + |
| +storage_service_c = Counter('cleanroom_storage_service_total', |
| + "Statistics of storage service", ['request']) |
| +scheduler_service_c = Counter('cleanroom_scheduler_service_total', |
| + "Statistics of scheduler service", ['request']) |
| +management_service_c = Counter('cleanroom_management_service_total', |
| + "Statistics of management service", ['request']) |
| + |
| + |
| +def escape_ansi(line: str): |
| + ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]') |
| + return ansi_escape.sub('', line) |
| + |
| + |
| +def parse_log(service: str, log: str): |
| + log = escape_ansi(log) |
| + if "teaclave-execution-service" in service: |
| + splits = log.strip().split("[MONITOR] InvokeTask: ")[1].split(",") |
| + print(splits) |
| + user_id = splits[0].strip('"') |
| + function_id = splits[1].strip() |
| + result = splits[2].strip() |
| + |
| + c.labels(user_id, function_id, result).inc() |
| + f_c.labels(function_id).inc() |
| + u_c.labels(user_id).inc() |
| + elif "teaclave-frontend-service" in service: |
| + splits = log.strip().split("[MONITOR]")[1].split(",") |
| + print(splits) |
| + user_id = splits[0].strip().strip('"') |
| + cli_version = splits[1].strip() |
| + request = splits[2].strip() |
| + frontend_service_c.labels(user_id, cli_version, request).inc() |
| + elif "teaclave-authentication-service" in service: |
| + splits = log.strip().split("[MONITOR]")[1].split(",") |
| + print(splits) |
| + user_id = splits[0].strip().strip('"') |
| + cli_version = splits[1].strip() |
| + request = splits[2].strip() |
| + authentication_service_c.labels(user_id, cli_version, request).inc() |
| + elif "teaclave-scheduler-service" in service: |
| + splits = log.strip().split("[MONITOR]")[1].split(",") |
| + request = splits[2].strip() |
| + scheduler_service_c.labels(request).inc() |
| + elif "teaclave-storage-service" in service: |
| + splits = log.strip().split("[MONITOR]")[1].split(",") |
| + request = splits[2].strip() |
| + storage_service_c.labels(request).inc() |
| + elif "teaclave-management-service" in service: |
| + splits = log.strip().split("[MONITOR]")[1].split(",") |
| + request = splits[2].strip() |
| + management_service_c.labels(request).inc() |
| + |
| + |
| +def main(): |
| + start_http_server(9000) |
| + for l in sys.stdin: |
| + try: |
| + service, log = (e.strip() for e in l.split("|")) |
| + if "[MONITOR]" not in log: continue |
| + parse_log(service, log) |
| + except Exception as e: |
| + print(e) |
| + |
| + |
| +if __name__ == '__main__': |
| + main() |
| diff --git a/cleanroom-cli/Makefile b/cleanroom-cli/Makefile |
| new file mode 100644 |
| index 0000000..64b1cc7 |
| --- /dev/null |
| +++ b/cleanroom-cli/Makefile |
| @@ -0,0 +1,29 @@ |
| +PREFIX := install |
| +OS := $(shell uname -s) |
| +ARCH := $(shell uname -m) |
| + |
| +all: local |
| + |
| +local: install |
| + cp -r conf $(PREFIX)/conf |
| + cp ${CURDIR}/../release/services/enclave_info.toml ${CURDIR}/$(PREFIX)/conf/ |
| + tar -C $(PREFIX) -cvf ${CURDIR}/cleanroom-cli-${OS}-${ARCH}.tgz bin conf |
| + |
| +azure: install |
| + cp -r ${CURDIR}/resource/azure/* ${CURDIR}/$(PREFIX)/ |
| + tar -C ${CURDIR}/$(PREFIX) -cvf ${CURDIR}/cleanroom-cli-${OS}-${ARCH}.tgz bin conf env |
| + |
| +install: pyoxidizer |
| + mkdir -p ${CURDIR}/$(PREFIX) |
| + cp -rf ${CURDIR}/build/*/release/install ${CURDIR}/$(PREFIX)/bin |
| + |
| + |
| +pyoxidizer: |
| + pyoxidizer build --release --path ${CURDIR} |
| + |
| +clean: |
| + @rm -rf ${CURDIR}/$(PREFIX) |
| + @rm -rf ${CURDIR}/build ${CURDIR}/web_cli ${CURDIR}/package |
| + @rm -f ${CURDIR}/*.tgz |
| + |
| +.PHONY: clean install deploy |
| diff --git a/cleanroom-cli/conf/dcap_root_cert.pem b/cleanroom-cli/conf/dcap_root_cert.pem |
| new file mode 100644 |
| index 0000000..4746925 |
| --- /dev/null |
| +++ b/cleanroom-cli/conf/dcap_root_cert.pem |
| @@ -0,0 +1,32 @@ |
| +-----BEGIN CERTIFICATE----- |
| +MIIFdzCCA1+gAwIBAgIUYGJXlZ8CxlRx7P6C+oiRsZAf47UwDQYJKoZIhvcNAQEL |
| +BQAwSzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRQwEgYDVQQKDAtUZWFjbGF2 |
| +ZSBDQTEZMBcGA1UEAwwQVGVhY2xhdmUgUm9vdCBDQTAeFw0yMDAyMDUxOTA5MjFa |
| +Fw0zMDAyMDIxOTA5MjFaMEsxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEUMBIG |
| +A1UECgwLVGVhY2xhdmUgQ0ExGTAXBgNVBAMMEFRlYWNsYXZlIFJvb3QgQ0EwggIi |
| +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCpwW+USb44VPeN1zW0DuVv/k7j |
| +FWbzxx60E3laiPk9K/EQp8L/Ma0mdPWb6O5MkY/DgeLp7UFmgTnBsTNERqAwqZrQ |
| +drcyyBb3akLEDuiCQWF6B+jZ8PEoSUvLPW+5QeKHvB0KHVon2Z4qNgVnVWTUk26Z |
| +BUvQjuJHK8GSZx9sS7Aip4s8jkqwWtio7UmRAeOOR5DFj3xZ87BzpWXi/5jD9RLx |
| +ScnjfR7oM3bnwpQBWyaaBiFUuxB0hZX2HoD1cvjiNshka+XtASquf9WQVj1KgBX/ |
| +J3gUz2UYgYKO5Tr5fdtpuOs/Kbk4FBV10uCzqbSm4tR8aehpIlcADguPPgOIMkrb |
| +yWEtidEP5CdVETda6HnUnylOtp0Qb+EgPqzJtGlvjOmTvfAKVDTTO9w0K/NVXEMl |
| +xbaWm0XJgwBM5t4lh8OXw7WmPvCyKYpGfa6lw0CX4S6haMmL2OWYBwcfLSTUntii |
| +ENRuiBwgTPOvq+9WYMLO+NZ+ILg/j6cvbDB+7mYdsYTmF49KxvpianBRZCk5D/8Y |
| +/7Ty/NKJKHG0qNfwcPJcsqndiy8nzlFT31hqdDewBqgpgqqXjTJ/Zgv7iTUJ0ZN4 |
| +T+3bo2hkoXw/nsQp+vu5wk1ErQI0G9DlolJGHNpsgYg6dkNpVgO7FEW9cNp4dZoc |
| +03JgOTfh6fkMD/DMbQIDAQABo1MwUTAdBgNVHQ4EFgQU761M4yztQfbaV8FFK7re |
| +wSRuJOAwHwYDVR0jBBgwFoAU761M4yztQfbaV8FFK7rewSRuJOAwDwYDVR0TAQH/ |
| +BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAmsqK6jP3ETdkLFuVlE7HNFhQP3Sj |
| +LcRnrwcIX4X8Wa1Bfi81Cb6AEbE2LqX1tBd0wIeLv9AgEJr3zJLssCB/yxYhyD3i |
| +La6AP4lxGgckI7XWgwK7BHrDNsWzb5fdp+mn5GAJPzmIWpqIA8Us3UfC08cKhTgL |
| +lRp5h+u2JHjjLN83BY7poKD1hCf5lKd+a5nNHLTLkMrZOBWz3i7nho4M+9YTeIzm |
| +7mI/4UqJtUS/yEYw6SZlj3fVHqGHesGTW0ivPb7YLKslflRMnGlaYFK2w+beb3se |
| +x2L148z2aYBL846feFJ1d+Gvi3FY9W4MzLki+B/9X+aVcIv1OUhQ0v8ARw1gwAOP |
| +6ogYWzs1/fc3sYY/t4awZHcFDcv07UKDoCmzZ+7DHVwF76zgeYjrRq+YUO6fRpUL |
| +xRuFXYNylzUqyDCF4rUAB5GrtUvr+8qpHg20Eh5r/R77atOzlLFAlvMhT7TUw27C |
| +KzHS+OAtUSaRhZfFpDcyCBxTIcWc38K/7ZUKu6O82pudiHnJ2A5UXVqxSAzstJM4 |
| +NEdrMdbIaMx9jiQ+/6JIyrAe1ve/BcFqpOLqEuF6vhBg9du5BdW0JaZDB0jeSFqQ |
| +Lok/lT48ASwddkUHrFjTst3wXRM1KbxbzSSOrvOPPg4eRhjJUqZgL0akxYZEgEg8 |
| +7Y71NCmZxQdvPmI= |
| +-----END CERTIFICATE----- |
| diff --git a/cleanroom-cli/conf/login.conf b/cleanroom-cli/conf/login.conf |
| new file mode 100644 |
| index 0000000..8a1dfc9 |
| --- /dev/null |
| +++ b/cleanroom-cli/conf/login.conf |
| @@ -0,0 +1,4 @@ |
| +[login] |
| +username = |
| +token = |
| + |
| diff --git a/cleanroom-cli/conf/cleanroom.conf b/cleanroom-cli/conf/cleanroom.conf |
| new file mode 100644 |
| index 0000000..7661780 |
| --- /dev/null |
| +++ b/cleanroom-cli/conf/cleanroom.conf |
| @@ -0,0 +1,10 @@ |
| +[address] |
| +authentication_service = localhost:7776 |
| +frontend_service = localhost:7777 |
| +file_service = http://localhost:6789 |
| +cli_service = http://localhost:7801 |
| + |
| +[attestation] |
| +as_root_ca_cert_path = dcap_root_cert.pem |
| +enclave_info_path = enclave_info.toml |
| + |
| diff --git a/cleanroom-cli/install.sh b/cleanroom-cli/install.sh |
| new file mode 100755 |
| index 0000000..ab91b03 |
| --- /dev/null |
| +++ b/cleanroom-cli/install.sh |
| @@ -0,0 +1,193 @@ |
| +#!/bin/sh |
| + |
| +set -e |
| + |
| +if [ -t 1 ]; then |
| + is_tty() { |
| + true |
| + } |
| +else |
| + is_tty() { |
| + false |
| + } |
| +fi |
| + |
| +cleanroomcli_dir="$HOME/.cleanroom" |
| +web_url="https://cli.cleanroom.com/" |
| +enclave_info_url="https://cli.cleanroom.com/enclave_info.toml" |
| + |
| +command_exists() { |
| + command -v "$@" >/dev/null 2>&1 |
| +} |
| + |
| + |
| +# Adapted from code and information by Anton Kochkov (@XVilka) |
| +# Source: https://gist.github.com/XVilka/8346728 |
| +supports_truecolor() { |
| + case "$COLORTERM" in |
| + truecolor|24bit) return 0 ;; |
| + esac |
| + |
| + case "$TERM" in |
| + iterm |\ |
| + tmux-truecolor |\ |
| + linux-truecolor |\ |
| + xterm-truecolor |\ |
| + screen-truecolor) return 0 ;; |
| + esac |
| + |
| + return 1 |
| +} |
| + |
| + |
| +setup_color() { |
| + # Only use colors if connected to a terminal |
| + if ! is_tty; then |
| + FMT_RAINBOW="" |
| + FMT_RED="" |
| + FMT_GREEN="" |
| + FMT_YELLOW="" |
| + FMT_BLUE="" |
| + FMT_BOLD="" |
| + FMT_RESET="" |
| + return |
| + fi |
| + |
| + if supports_truecolor; then |
| + FMT_RAINBOW=" |
| + $(printf '\033[38;2;255;0;0m') |
| + $(printf '\033[38;2;255;97;0m') |
| + $(printf '\033[38;2;247;255;0m') |
| + $(printf '\033[38;2;0;255;30m') |
| + $(printf '\033[38;2;77;0;255m') |
| + $(printf '\033[38;2;168;0;255m') |
| + $(printf '\033[38;2;245;0;172m') |
| + " |
| + else |
| + FMT_RAINBOW=" |
| + $(printf '\033[38;5;196m') |
| + $(printf '\033[38;5;202m') |
| + $(printf '\033[38;5;226m') |
| + $(printf '\033[38;5;082m') |
| + $(printf '\033[38;5;021m') |
| + $(printf '\033[38;5;093m') |
| + $(printf '\033[38;5;163m') |
| + " |
| + fi |
| + |
| + FMT_RED=$(printf '\033[31m') |
| + FMT_GREEN=$(printf '\033[92m') |
| + FMT_YELLOW=$(printf '\033[33m') |
| + FMT_BLUE=$(printf '\033[34m') |
| + FMT_BOLD=$(printf '\033[1m') |
| + FMT_RESET=$(printf '\033[0m') |
| +} |
| + |
| +curl_wrapper(){ |
| + source="$1" |
| + option="$2" |
| + destination="$3" |
| + rm -f "$destination" |
| + curl "$source" "$option" > "$destination" |
| +} |
| + |
| +download_cleanroomcli() { |
| + echo "${FMT_GREEN}Downloading Cleanroom CLI...${FMT_RESET}" |
| + mkdir -p "$cleanroomcli_dir" |
| + current_dir="$PWD" |
| + arch="$(uname -m)" |
| + cd "$cleanroomcli_dir" |
| + OS="$(uname -s)" |
| + case "${OS}" in |
| + Linux*) |
| + if [ "$arch" = "x86_64" ]; then |
| + cli_package_name="cleanroom-cli-${OS}-${arch}.tgz" |
| + else |
| + echo "Not supported architecture: ${OS}-${arch}" |
| + exit 1 |
| + fi; |
| + ;; |
| + Darwin*) |
| + if [ "$arch" = "x86_64" ]; then |
| + cli_package_name="cleanroom-cli-${OS}-${arch}.tgz" |
| + elif [ "$arch" = "arm64" ]; then |
| + cli_package_name="cleanroom-cli-${OS}-${arch}.tgz" |
| + else |
| + echo "Not supported architecture: ${OS}-${arch}" |
| + exit 1 |
| + fi; |
| + ;; |
| + *) |
| + echo "${FMT_YELLOW}${OS}-${arch} is not supported.${FMT_RESET}" |
| + exit 1 |
| + esac |
| + echo "$cli_package_name" |
| + release_url="${web_url}${cli_package_name}" |
| + curl_wrapper $release_url "--progress-bar" $cli_package_name |
| + tar xf $cli_package_name |
| + curl_wrapper $enclave_info_url "-s" "conf/enclave_info.toml" |
| + rm -f $cli_package_name |
| + cd "$current_dir" |
| +} |
| + |
| +matches() { |
| + input="$1" |
| + pattern="$2" |
| + echo "$input" | grep -q "$pattern" |
| +} |
| + |
| +ensure_command_exists() { |
| + cmd="$1" |
| + if ! command_exists "${cmd}"; then |
| + echo "${FMT_YELLOW}${cmd} is not installed.${FMT_RESET} Please install ${cmd} first." |
| + exit 1 |
| + fi |
| +} |
| + |
| +setup_cleanroomcli() { |
| + echo "${FMT_GREEN}Setting up Cleanroom CLI environments...${FMT_RESET}" |
| + output=$(ps u -p $PPID) |
| + parent_shell=${output##* } |
| + if matches "${parent_shell}" "bash"; then |
| + if ! grep -q ". $cleanroomcli_dir/env" "${HOME}"/.bashrc; then |
| + echo ". $cleanroomcli_dir/env" >> "${HOME}"/.bashrc |
| + fi |
| + elif matches "${parent_shell}" "zsh"; then |
| + if ! grep -q ". $cleanroomcli_dir/env" "${HOME}"/.zshrc; then |
| + echo ". $cleanroomcli_dir/env" >> "${HOME}"/.zshrc |
| + fi |
| + else |
| + echo "${FMT_YELLOW}${parent_shell} is not supported at the present. Please use bash or zsh.${FMT_RESET}" |
| + fi |
| +} |
| + |
| +print_success() { |
| + echo "${FMT_GREEN}Setup Cleanroom CLI successfully...${FMT_RESET}" |
| + echo "To get started you may need to restart your current shell or run 'source $HOME/.cleanroom/env'" |
| +} |
| + |
| +check_env() { |
| + if [ -z "${HOME}" ] ; then |
| + echo "HOME environment var is not defined. Please set HOME var by running 'export HOME=<Cleanroom CLI install path>'" |
| + exit 1 |
| + fi |
| +} |
| + |
| +main() { |
| + setup_color |
| + |
| + ensure_command_exists "tar" |
| + ensure_command_exists "grep" |
| + ensure_command_exists "ps" |
| + |
| + check_env |
| + download_cleanroomcli |
| + if ! command_exists "cleanroom-cli"; then |
| + setup_cleanroomcli |
| + fi |
| + print_success |
| + |
| +} |
| + |
| + |
| +main "$@" |
| diff --git a/cleanroom-cli/cleanroom-cli.py b/cleanroom-cli/cleanroom-cli.py |
| new file mode 100755 |
| index 0000000..acba81b |
| --- /dev/null |
| +++ b/cleanroom-cli/cleanroom-cli.py |
| @@ -0,0 +1,1366 @@ |
| +#!/usr/bin/env python3 |
| +# PYTHON_ARGCOMPLETE_OK |
| + |
| +import argparse |
| +import getpass |
| +import sys |
| +import configparser |
| +import urllib.parse |
| +import uuid |
| +import requests |
| +import tempfile |
| +import os |
| +from os import path |
| +from urllib.parse import urljoin |
| +from tabulate import tabulate |
| +import string |
| +import random |
| +import json |
| +import signal |
| +import time |
| +import argcomplete |
| +import pathlib |
| +import jwt |
| +import inspect |
| +import shutil |
| +from datetime import timezone |
| +from datetime import datetime |
| +from packaging.version import parse as parse_version |
| +from typing import Tuple, Dict, List, Any |
| +from urllib.request import Request, urlopen |
| +from typing import Tuple, Dict, List, Any |
| + |
| +__version__ = "0.1.6" |
| + |
| +CURRENT_PATH = path.dirname(path.realpath(__file__)) |
| +CURRENT_DIR = os.path.dirname(path.realpath(__file__)) |
| +sys.path.append(path.join(CURRENT_PATH, "../sdk/python")) |
| +from teaclave import AuthenticationService, FrontendService, FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap, TeaclaveException, FunctionExpirationDate |
| + |
| +CWD = os.getcwd() |
| + |
| +if path.isdir(path.join(CWD, "conf")): |
| + CONFIG_DIR = path.join(CWD, "conf") |
| +elif path.isdir(path.join(pathlib.Path.home(), ".cleanroom/conf")): |
| + CONFIG_DIR = path.join(pathlib.Path.home(), ".cleanroom/conf") |
| +else: |
| + print("Can not find conf files") |
| + exit(1) |
| + |
| +CONFIG_FILE = path.join(CONFIG_DIR, "cleanroom.conf") |
| +LOGIN_CONFIG_FILE = path.join(CONFIG_DIR, "login.conf") |
| +TMP_OUTPUT = path.join(CWD, ".cleanroom_output.txt") |
| +DUMP_REPORT = False |
| + |
| +try: |
| + CONFIG = configparser.ConfigParser() |
| + CONFIG.read(CONFIG_FILE) |
| + LOGIN_CONFIG = configparser.ConfigParser() |
| + LOGIN_CONFIG.read(LOGIN_CONFIG_FILE) |
| + if not CONFIG["address"]["authentication_service"]: |
| + raise Exception("authentication_service address is empty") |
| + |
| + if not CONFIG["address"]["frontend_service"]: |
| + raise Exception("authentication_service address is empty") |
| + |
| + if not CONFIG["address"]["file_service"]: |
| + raise Exception("file_service address is empty") |
| + |
| + if not CONFIG["address"]["cli_service"]: |
| + raise Exception("cli_service address is empty") |
| + |
| + if not CONFIG["attestation"]["as_root_ca_cert_path"]: |
| + raise Exception("as_root_ca_cert_path is empty") |
| + |
| + if not CONFIG["attestation"]["enclave_info_path"]: |
| + raise Exception("enclave_info_path is empty") |
| + |
| + AS_ROOT_CA_CERT_PATH = path.join( |
| + CONFIG_DIR, CONFIG["attestation"]["as_root_ca_cert_path"]) |
| + ENCLAVE_INFO_PATH = path.join(CONFIG_DIR, |
| + CONFIG["attestation"]["enclave_info_path"]) |
| + |
| +except Exception as e: |
| + TeaclaveException(f"Failed to read the config file {CONFIG_FILE}: {e}") |
| + |
| +FILE_SERVICE_AUTH_HEADERS = { |
| + "Authorization": |
| + "Basic 001dda666e88921cfa9cecd5935d387b17b16c70022fe119ce69dee0ec84e3d9" |
| +} |
| + |
| + |
| +def cleanroom_info(info, end='\n'): |
| + print('\033[92m' + info + '\033[0m', end=end, flush=True) |
| + |
| + |
| +def cleanroom_warn(warn, end='\n'): |
| + print('\033[91m' + warn + '\033[0m', end=end, flush=True) |
| + |
| + |
| +class CleanroomException(TeaclaveException): |
| + _cleanroom_error = dict() |
| + _cleanroom_error[0] = ('Invalid funtion ID', |
| + 'Please run list-functions again') |
| + _cleanroom_error[1] = ('Cannot access file services', |
| + 'Please check your Internet Connection') |
| + _cleanroom_error[2] = ('File not found', |
| + 'Please check the location of your input data') |
| + _cleanroom_error[3] = ('Service is under maintanance', |
| + 'Please wait and try later') |
| + _cleanroom_error[4] = ('Invalid input', 'Please enter a valid input') |
| + _cleanroom_error[5] = ( |
| + 'Invalid date format', |
| + 'Please enter a valid date. Format: month/day/year. e.g., 03/01/2021') |
| + |
| + def __init__(self, error_code: int, msg=''): |
| + frame, filename, line_number, function_name, lines, index = inspect.stack( |
| + )[1] |
| + self.function_name = function_name |
| + self.error_code = error_code |
| + self.message = msg |
| + |
| + def __str__(self): |
| + CRED = '\033[91m' |
| + CEND = '\033[0m' |
| + if (self.error_code) in CleanroomException._cleanroom_error: |
| + error = CleanroomException._cleanroom_error[self.error_code][0] |
| + action = CleanroomException._cleanroom_error[self.error_code][1] |
| + return '\n' + CRED + ('Error: {}. Action: {}. {}'.format( |
| + error, action, self.message)) + CEND |
| + return str(self.message) |
| + |
| + |
| +def get_role(config): |
| + if config['login']['token'] == "": |
| + return "NotLogin" |
| + try: |
| + claims = jwt.decode(config['login']['token'], |
| + options={"verify_signature": False}) |
| + role = claims['role'].split("-")[0] |
| + return role |
| + except Exception as e: |
| + return "Unknown" |
| + |
| + |
| +def parse_hostport(hp): |
| + result = urllib.parse.urlsplit('//' + hp) |
| + return result.hostname, result.port |
| + |
| + |
| +def shorten_uuid(fun_uuids): |
| + default_length = 8 |
| + fun_ids = [uuid[-default_length:] for uuid in fun_uuids] |
| + fun_ids_set = set(fun_ids) |
| + if len(fun_ids_set) != len(fun_uuids): |
| + default_length = default_length + 1 |
| + fun_ids = [uuid[-default_length:] for uuid in fun_uuids] |
| + fun_ids_set = set(fun_ids) |
| + return fun_ids |
| + |
| + |
| +def uid_to_id(fun_uid): |
| + username = LOGIN_CONFIG['login']['username'] |
| + with connect_frontend_service() as client: |
| + functions = client.list_functions(username) |
| + fun_uuids = functions['registered_functions'] + functions[ |
| + 'allowed_functions'] |
| + fun_ids = shorten_uuid(fun_uuids) |
| + for i, uuid in enumerate(fun_uuids): |
| + if uuid == fun_uid: |
| + return fun_ids[i] |
| + raise CleanroomException(0) |
| + |
| + |
| +def id_to_uuid(fun_id): |
| + username = LOGIN_CONFIG['login']['username'] |
| + with connect_frontend_service() as client: |
| + functions = client.list_functions(username) |
| + fun_uuids = functions['registered_functions'] + functions[ |
| + 'allowed_functions'] |
| + fun_ids = shorten_uuid(fun_uuids) |
| + for i, v_id in enumerate(fun_ids): |
| + if v_id == fun_id: |
| + return fun_uuids[i] |
| + raise CleanroomException(0) |
| + |
| + |
| +def yes_or_no(question): |
| + cleanroom_info(f'{question} ? (y/n): ') |
| + ans = input().strip().lower() |
| + if ans not in ['y', 'n']: |
| + print(f'{ans} is invalid, please try again...') |
| + return yes_or_no(question) |
| + if ans == 'y': |
| + return True |
| + return False |
| + |
| + |
| +def get_algorithm2_hash_time(beamsize, sequence_length) -> float: |
| + a = 0.266 |
| + b = 0.193 |
| + if sequence_length < beamsize: |
| + beamsize = sequence_length |
| + return a * beamsize + b * sequence_length |
| + |
| + |
| +def connect_authentication_service(): |
| + address = parse_hostport(CONFIG["address"]["authentication_service"]) |
| + if DUMP_REPORT: |
| + dump_report = path.join(CWD, "report") |
| + if not path.isdir(dump_report): |
| + os.mkdir(dump_report) |
| + else: |
| + dump_report = None |
| + client = AuthenticationService( |
| + address, |
| + AS_ROOT_CA_CERT_PATH, |
| + ENCLAVE_INFO_PATH, |
| + dump_report, |
| + ).connect() |
| + client.metadata = {"cli-version": __version__} |
| + |
| + return client |
| + |
| + |
| +def connect_frontend_service(): |
| + address = parse_hostport(CONFIG["address"]["frontend_service"]) |
| + if DUMP_REPORT: |
| + dump_report = path.join(CWD, "report") |
| + if not path.isdir(dump_report): |
| + os.mkdir(dump_report) |
| + else: |
| + dump_report = None |
| + client = FrontendService( |
| + address, |
| + AS_ROOT_CA_CERT_PATH, |
| + ENCLAVE_INFO_PATH, |
| + dump_report, |
| + ).connect() |
| + client.metadata = { |
| + "id": LOGIN_CONFIG['login']['username'], |
| + "token": LOGIN_CONFIG['login']['token'], |
| + "cli-version": __version__ |
| + } |
| + return client |
| + |
| + |
| +def login(args): |
| + if not args.username: |
| + args.username = input("Username: ") |
| + if not args.password: |
| + args.password = getpass.getpass() |
| + with connect_authentication_service() as client: |
| + token = client.user_login(args.username, args.password) |
| + LOGIN_CONFIG['login']['username'] = args.username |
| + LOGIN_CONFIG['login']['token'] = token |
| + with open(LOGIN_CONFIG_FILE, 'w') as f: |
| + LOGIN_CONFIG.write(f) |
| + cleanroom_info(f"Login successfully") |
| + |
| + |
| +def change_password(args): |
| + with connect_authentication_service() as client: |
| + client.metadata.update({ |
| + "id": LOGIN_CONFIG['login']['username'], |
| + "token": LOGIN_CONFIG['login']['token'] |
| + }) |
| + client.user_change_password(args.password) |
| + logout(None) |
| + cleanroom_info(f"Password change successfully, login you new password.") |
| + |
| + |
| +def logout(args): |
| + LOGIN_CONFIG['login']['username'] = "" |
| + LOGIN_CONFIG['login']['token'] = "" |
| + with open(LOGIN_CONFIG_FILE, 'w') as f: |
| + LOGIN_CONFIG.write(f) |
| + cleanroom_info(f"Logout successfully") |
| + |
| + |
| +def update_shell_profile(shell_path): |
| + shell_content = [] |
| + if path.isfile(shell_path): |
| + with open(shell_path) as f: |
| + shell_content = f.readlines() |
| + origin_lines = len(shell_content) |
| + shell_content = [ |
| + line for line in shell_content if ".cleanroom/env" not in line |
| + ] |
| + current_lines = len(shell_content) |
| + if origin_lines != current_lines: |
| + try: |
| + temp_file = tempfile.NamedTemporaryFile( |
| + delete=False, |
| + dir=path.join(pathlib.Path.home(), ".cleanroom")) |
| + with open(temp_file.name, 'w') as f: |
| + for line in shell_content: |
| + f.write(line) |
| + f.flush() |
| + os.replace(temp_file.name, shell_path) |
| + except Exception as e: |
| + if os.path.exists(temp_file.name): |
| + try: |
| + os.unlink(temp_file.name) |
| + except: |
| + pass |
| + |
| + |
| +def uninstall(args): |
| + bashrc_path = path.join(pathlib.Path.home(), ".bashrc") |
| + zshrc_path = path.join(pathlib.Path.home(), ".zshrc") |
| + update_shell_profile(bashrc_path) |
| + update_shell_profile(zshrc_path) |
| + cleanroomcli_path = path.join(pathlib.Path.home(), ".cleanroom") |
| + if path.isdir(cleanroomcli_path): |
| + shutil.rmtree(cleanroomcli_path, ignore_errors=True) |
| + else: |
| + cleanroom_info(f"Cannot find the install directory") |
| + exit(1) |
| + cleanroom_info(f"Uninstall successfully, please restart your shell.") |
| + |
| + |
| +def register_user(args): |
| + with connect_authentication_service() as client: |
| + client.metadata.update({ |
| + "id": LOGIN_CONFIG['login']['username'], |
| + "token": LOGIN_CONFIG['login']['token'] |
| + }) |
| + if args.role: |
| + role = args.role |
| + else: |
| + role = "DataOwner" |
| + if args.attribute: |
| + attribute = args.attribute |
| + else: |
| + if args.role == "DataOwnerManager": |
| + attribute = args.username |
| + else: |
| + attribute = LOGIN_CONFIG['login']['username'] |
| + client.user_register(args.username, args.password, role, attribute) |
| + cleanroom_info(f"Register user successfully: {args.username}") |
| + |
| + |
| +def list_users(_args): |
| + user_list = [] |
| + with connect_authentication_service() as client: |
| + client.metadata.update({ |
| + "id": LOGIN_CONFIG['login']['username'], |
| + "token": LOGIN_CONFIG['login']['token'] |
| + }) |
| + user_list = client.list_users(LOGIN_CONFIG['login']['username']) |
| + |
| + cleanroom_info("List users successfully, managed users: " + |
| + ", ".join(user_list)) |
| + |
| + |
| +def register_cpk(args): |
| + with connect_frontend_service() as client: |
| + with open(args.cpk, "rb") as f: |
| + payload = f.read() |
| + if args.diagnosis: |
| + outputs = [ |
| + FunctionOutput("output_file", "Output data"), |
| + FunctionOutput("log_file", "Log") |
| + ] |
| + else: |
| + outputs = [ |
| + FunctionOutput("output_file", "Output data"), |
| + ] |
| + if args.q: |
| + usage_quota = args.q |
| + else: |
| + usage_quota = -1 |
| + if args.a: |
| + function_arg = FunctionArgument("args", args.a, False) |
| + else: |
| + function_arg = FunctionArgument("args") |
| + function_debug = FunctionArgument("debug") |
| + function_id = client.register_function( |
| + name=args.name, |
| + description=args.description, |
| + payload=list(payload), |
| + executor_type="cleanroom", |
| + arguments=[function_arg, function_debug], |
| + inputs=[FunctionInput("input_file", "Input data")], |
| + outputs=outputs, |
| + user_allowlist=args.user_allowlist, |
| + usage_quota=usage_quota) |
| + cleanroom_info(f"Register CPK successfully: {function_id}") |
| + |
| + |
| +def register_native(args): |
| + with connect_frontend_service() as client: |
| + payload = b"not empty" |
| + if args.diagnosis: |
| + outputs = [ |
| + FunctionOutput("output_file", "Output data"), |
| + FunctionOutput("log_file", "Log") |
| + ] |
| + else: |
| + outputs = [ |
| + FunctionOutput("output_file", "Output data"), |
| + ] |
| + |
| + if args.q: |
| + usage_quota = args.q |
| + else: |
| + usage_quota = -1 |
| + if args.a: |
| + function_arg = FunctionArgument("args", args.a, False) |
| + else: |
| + function_arg = FunctionArgument("args") |
| + function_debug = FunctionArgument("debug") |
| + if args.expired: |
| + try: |
| + date = datetime.strptime(args.expired, "%m/%d/%Y") |
| + utc_time = date.replace(tzinfo=timezone.utc) |
| + utc_timestamp = utc_time.timestamp() |
| + except Exception as e: |
| + raise CleanroomException(5) |
| + expired_date = FunctionExpirationDate(expired=True, |
| + seconds=int(utc_timestamp), |
| + nanos=0) |
| + else: |
| + expired_date = FunctionExpirationDate() |
| + function_id = client.register_function( |
| + name=args.name, |
| + description=args.description, |
| + payload=list(payload), |
| + executor_type="builtin", |
| + arguments=[function_arg, function_debug], |
| + inputs=[ |
| + FunctionInput("input_file", "Input data"), |
| + FunctionInput("./coding_wheel.txt", "Coding wheel"), |
| + FunctionInput("./codon_usage_freq_table_human.csv", |
| + "Codon usage freq table human"), |
| + ], |
| + outputs=outputs, |
| + user_allowlist=args.user_allowlist, |
| + usage_quota=usage_quota, |
| + expiration_date=expired_date) |
| + cleanroom_info(f"Register native function successfully: {function_id}") |
| + |
| + |
| +class CryptoInfo: |
| + |
| + def __init__(self): |
| + self.key = os.urandom(16) |
| + self.iv = os.urandom(12) |
| + self.cmac = None |
| + |
| + |
| +class CryptoInfo: |
| + |
| + def __init__(self): |
| + self.key = os.urandom(16) |
| + self.iv = os.urandom(12) |
| + self.cmac = None |
| + |
| + |
| +def gen_key(): |
| + return CryptoInfo() |
| + |
| + |
| +def gen_password(): |
| + all = string.ascii_letters + string.digits |
| + return "".join(random.sample(all, 8)) |
| + |
| + |
| +CURRENT_RUNNING_TASK_ID = None |
| + |
| + |
| +def signal_handler(sig, frame): |
| + with connect_frontend_service() as client: |
| + if not CURRENT_RUNNING_TASK_ID: |
| + cleanroom_info(f"Ctrl+C pressed. Canceled.") |
| + sys.exit(1) |
| + else: |
| + cleanroom_info( |
| + f"Ctrl+C pressed. Canceling task {CURRENT_RUNNING_TASK_ID}") |
| + |
| + try: |
| + client.cancel_task(CURRENT_RUNNING_TASK_ID) |
| + time.sleep(3) |
| + # cancel twice to make sure the task is canceled |
| + client.cancel_task(CURRENT_RUNNING_TASK_ID) |
| + except: |
| + pass |
| + sys.exit(0) |
| + |
| + |
| +def get_task_time(task_id, input_length, args): |
| + with connect_frontend_service() as client: |
| + task_info = client.get_task(task_id) |
| + function_id = task_info['function_id'] |
| + function_info = client.get_function(function_id) |
| + total_time = 0 |
| + if function_info[ |
| + 'name'] == 'builtin-cleanroom-algorithm2-hash-trial-tier2': |
| + default_beam_size = [10, 100, 500, 1000] |
| + default_lambda = [0.2, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 10.0] |
| + ratio = len(default_lambda) |
| + for beam in default_beam_size: |
| + task_time = get_algorithm2_hash_time(beam, input_length) |
| + total_time = total_time + ratio * task_time |
| + if total_time > 3600.0: |
| + hours = total_time / 3600.0 |
| + if not args.silent: |
| + cleanroom_info( |
| + f'Estimating the execution time: {round(hours, 1)} hours...') |
| + cleanroom_info( |
| + 'Please keep the process running and networking available during the execution.' |
| + ) |
| + if yes_or_no('Continue submitting the task') == False: |
| + exit(1) |
| + elif total_time > 60: |
| + minutes = total_time / 60.0 |
| + if not args.silent: |
| + cleanroom_info( |
| + f'Estimating the execution time: {round(minutes, 1)} minutes...' |
| + ) |
| + cleanroom_info( |
| + 'Please keep the process running and networking available during the execution.' |
| + ) |
| + if yes_or_no('Continue submitting the task') == False: |
| + exit(1) |
| + else: |
| + return |
| + |
| + |
| +def run(args): |
| + start = time.time() |
| + signal.signal(signal.SIGINT, signal_handler) |
| + native = False |
| + function_uuid = id_to_uuid(args.function_id) |
| + with connect_frontend_service() as client: |
| + f = client.get_function(function_uuid) |
| + if "builtin" in f["executor_type"]: native = True |
| + get_function_usage_stats(args) |
| + if native: |
| + result = run_native(args) |
| + else: |
| + result = run_cpk(args) |
| + end = time.time() |
| + elapsed = end - start |
| + result = json.loads(result) |
| + execution = result["execution_time"] |
| + queueing = elapsed - execution |
| + cleanroom_info( |
| + f"Total Time: {elapsed:.2f}s ({queueing:.2f}s queueing, {execution:.2f}s running)" |
| + ) |
| + |
| + if result["status"] == True: |
| + cleanroom_info("Task succeeded!") |
| + else: |
| + cleanroom_info(f"Task failed. {result['reason']}") |
| + if args.output_file != None: |
| + cleanroom_info(f"Output file: {args.output_file}") |
| + else: |
| + with open(TMP_OUTPUT) as f: |
| + print(f.read(), end='') |
| + os.unlink(TMP_OUTPUT) |
| + |
| + |
| +def upload_register_input_file(client, file_path): |
| + input_crypto = gen_key() |
| + if not file_path: |
| + input_data_id = client.register_input_file("placeholder://", |
| + "aes-gcm-128", |
| + list(input_crypto.key), |
| + list(input_crypto.iv), |
| + [0] * 16) |
| + return input_data_id |
| + |
| + if not path.exists(file_path): |
| + raise CleanroomException(2, f"File not found: {file_path}") |
| + |
| + internal_file_service_url = "http://teaclave-file-service:6789/" |
| + file_service_url = CONFIG['address']['file_service'] |
| + with tempfile.TemporaryDirectory() as dirpath: |
| + encrypted_input_file = str(uuid.uuid1()) |
| + input_file_path = path.join(dirpath, encrypted_input_file) |
| + input_crypto = encrypt(file_path, input_file_path, input_crypto) |
| + url = urljoin(file_service_url, encrypted_input_file) |
| + try: |
| + x = requests.put(url, |
| + data=open(input_file_path, 'rb'), |
| + headers=FILE_SERVICE_AUTH_HEADERS) |
| + if x.status_code != 200: |
| + raise CleanroomException(1, "Cannot access file service") |
| + except: |
| + raise CleanroomException(1, "Cannot access file service") |
| + |
| + schema = "aes-gcm-128" |
| + url = urljoin(internal_file_service_url, encrypted_input_file) |
| + input_data_id = client.register_input_file(url, schema, |
| + list(input_crypto.key), |
| + list(input_crypto.iv), |
| + list(input_crypto.cmac)) |
| + return input_data_id |
| + |
| + |
| +def run_native(args): |
| + if not args.arguments: |
| + arguments = [] |
| + elif len(args.arguments) > 1 and args.arguments[0] == "--": |
| + arguments = args.arguments[1:] |
| + else: |
| + raise Exception("Cannot parse arguments") |
| + |
| + output_crypto = gen_key() |
| + diagnosis_crypto = gen_key() |
| + file_service_url = CONFIG['address']['file_service'] |
| + internal_file_service_url = "http://teaclave-file-service:6789/" |
| + |
| + username = [LOGIN_CONFIG['login']['username']] |
| + with connect_frontend_service() as client: |
| + if args.diagnosis: |
| + outputs_ownership = [ |
| + OwnerList("output_file", username), |
| + OwnerList("log_file", username) |
| + ] |
| + debug = "true" |
| + else: |
| + outputs_ownership = [ |
| + OwnerList("output_file", username), |
| + ] |
| + debug = "false" |
| + argument_list = ["cleanroom"] |
| + argument_list.extend(arguments) |
| + arguments = json.dumps(argument_list) |
| + function_uuid = id_to_uuid(args.function_id) |
| + task_id = client.create_task( |
| + function_id=function_uuid, |
| + function_arguments=({ |
| + "args": arguments, |
| + "debug": debug |
| + }), |
| + executor="builtin", |
| + inputs_ownership=[ |
| + OwnerList("input_file", username), |
| + OwnerList("./coding_wheel.txt", username), |
| + OwnerList("./codon_usage_freq_table_human.csv", username), |
| + ], |
| + outputs_ownership=outputs_ownership) |
| + |
| + if args.input_file != None: |
| + input_data_id = upload_register_input_file(client, args.input_file) |
| + with open(args.input_file) as f: |
| + data = f.readlines() |
| + if len(data) > 0: |
| + input_length = len(data[0]) |
| + else: |
| + input_length = 0 |
| + else: |
| + cleanroom_info( |
| + 'If the input sequence is longer than 1024, please use the option -i=<input file path>' |
| + ) |
| + cleanroom_info('Please enter a valid input: ', end='') |
| + sequence = input() |
| + if sequence.strip() == '': |
| + raise CleanroomException(4) |
| + input_length = len(sequence) |
| + plain_input_file = str(uuid.uuid1()) |
| + with tempfile.TemporaryDirectory() as dirpath: |
| + plain_input_file = str(uuid.uuid1()) |
| + input_data_file = path.join(dirpath, plain_input_file) |
| + with open(input_data_file, "w") as f: |
| + f.write(sequence) |
| + input_data_id = upload_register_input_file( |
| + client, input_data_file) |
| + |
| + coding_whell_data_id = upload_register_input_file( |
| + client, args.coding_wheel) |
| + codon_data_id = upload_register_input_file(client, |
| + args.codon_usage_freq_table) |
| + cleanroom_info(f"Creating task with input... done") |
| + encrypted_output_file = str(uuid.uuid1()) |
| + |
| + schema = "aes-gcm-128" |
| + url = urljoin(internal_file_service_url, encrypted_output_file) |
| + output_data_id = client.register_output_file(url, schema, |
| + list(output_crypto.key), |
| + list(output_crypto.iv)) |
| + |
| + if args.diagnosis: |
| + encrypted_diagnosis_file = str(uuid.uuid1()) |
| + url = urljoin(internal_file_service_url, encrypted_diagnosis_file) |
| + diagnosis_data_id = client.register_output_file( |
| + url, schema, list(diagnosis_crypto.key), |
| + list(diagnosis_crypto.iv)) |
| + client.assign_data_to_task(task_id, [ |
| + DataMap("input_file", input_data_id), |
| + DataMap("./coding_wheel.txt", coding_whell_data_id), |
| + DataMap("./codon_usage_freq_table_human.csv", codon_data_id), |
| + ], [ |
| + DataMap("output_file", output_data_id), |
| + DataMap("log_file", diagnosis_data_id) |
| + ]) |
| + else: |
| + client.assign_data_to_task(task_id, [ |
| + DataMap("input_file", input_data_id), |
| + DataMap("./coding_wheel.txt", coding_whell_data_id), |
| + DataMap("./codon_usage_freq_table_human.csv", codon_data_id), |
| + ], [DataMap("output_file", output_data_id)]) |
| + |
| + global CURRENT_RUNNING_TASK_ID |
| + CURRENT_RUNNING_TASK_ID = task_id |
| + get_task_time(task_id, input_length, args) |
| + cleanroom_info("Invoking task...", end=" ") |
| + client.invoke_task(task_id) |
| + cleanroom_info(f"done") |
| + cleanroom_info("Getting result...", end=" ") |
| + attempt = 0 |
| + while True: |
| + try: |
| + result = client.get_task_result(task_id) |
| + break |
| + except socket.error: |
| + attempt = attempt + 1 |
| + if attempt < 3: |
| + cleanroom_warn('Networking failure. Reconnecting...') |
| + continue |
| + else: |
| + raise TeaclaveException(0) |
| + cleanroom_info(f"done") |
| + result = ''.join([chr(c) for c in result]) |
| + |
| + with tempfile.TemporaryDirectory() as dirpath: |
| + output_file_path = path.join(dirpath, encrypted_output_file) |
| + url = urljoin(file_service_url, encrypted_output_file) |
| + x = requests.get(url, headers=FILE_SERVICE_AUTH_HEADERS) |
| + if x.status_code != 200: |
| + raise CleanroomException(1, "Cannot access file service") |
| + with open(output_file_path, "wb") as f: |
| + f.write(x.content) |
| + if args.output_file != None: |
| + decrypt(output_file_path, args.output_file, output_crypto) |
| + else: |
| + decrypt(output_file_path, TMP_OUTPUT, output_crypto) |
| + |
| + if args.diagnosis: |
| + with tempfile.TemporaryDirectory() as dirpath: |
| + output_file_path = path.join(dirpath, encrypted_diagnosis_file) |
| + url = urljoin(file_service_url, encrypted_diagnosis_file) |
| + x = requests.get(url, headers=FILE_SERVICE_AUTH_HEADERS) |
| + if x.status_code != 200: |
| + raise CleanroomException(1, "Cannot access file service") |
| + with open(output_file_path, "wb") as f: |
| + f.write(x.content) |
| + diagnosis_file_path = "diagnosis.txt" |
| + decrypt(output_file_path, "diagnosis.txt", diagnosis_crypto) |
| + cleanroom_info(f"Diagnosis file: {diagnosis_file_path}") |
| + |
| + return result |
| + |
| + |
| +def run_cpk(args): |
| + if not args.arguments: |
| + arguments = [] |
| + elif args.arguments[0] == "--": |
| + arguments = args.arguments[1:] |
| + else: |
| + raise Exception("Cannot parse arguments") |
| + |
| + input_crypto = gen_key() |
| + output_crypto = gen_key() |
| + diagnosis_crypto = gen_key() |
| + file_service_url = CONFIG['address']['file_service'] |
| + internal_file_service_url = "http://teaclave-file-service:6789/" |
| + |
| + username = [LOGIN_CONFIG['login']['username']] |
| + with connect_frontend_service() as client: |
| + if args.diagnosis: |
| + outputs_ownership = [ |
| + OwnerList("output_file", username), |
| + OwnerList("log_file", username) |
| + ] |
| + debug = "true" |
| + else: |
| + outputs_ownership = [ |
| + OwnerList("output_file", username), |
| + ] |
| + debug = "false" |
| + argument_list = ["cleanroom"] |
| + argument_list.extend(arguments) |
| + arguments = json.dumps(argument_list) |
| + |
| + function_uuid = id_to_uuid(args.function_id) |
| + task_id = client.create_task( |
| + function_id=function_uuid, |
| + function_arguments=({ |
| + "args": arguments, |
| + "debug": debug |
| + }), |
| + executor="cleanroom", |
| + inputs_ownership=[OwnerList("input_file", username)], |
| + outputs_ownership=outputs_ownership) |
| + with tempfile.TemporaryDirectory() as dirpath: |
| + encrypted_input_file = str(uuid.uuid1()) |
| + input_file_path = path.join(dirpath, encrypted_input_file) |
| + input_data_file = "" |
| + if args.input_file != None: |
| + input_data_file = args.input_file |
| + else: |
| + cleanroom_info('Please enter a valid input: ', end='') |
| + sequence = input() |
| + if sequence.strip() == '': |
| + raise CleanroomException(4) |
| + plain_input_file = str(uuid.uuid1()) |
| + input_data_file = path.join(dirpath, plain_input_file) |
| + with open(input_data_file, "w") as f: |
| + f.write(sequence) |
| + input_crypto = encrypt(input_data_file, input_file_path, |
| + input_crypto) |
| + url = urljoin(file_service_url, encrypted_input_file) |
| + try: |
| + x = requests.put(url, |
| + data=open(input_file_path, 'rb'), |
| + headers=FILE_SERVICE_AUTH_HEADERS) |
| + if x.status_code != 200: |
| + raise CleanroomException(1, "Cannot access file service") |
| + except: |
| + raise CleanroomException(1, "Cannot access file service") |
| + |
| + schema = "aes-gcm-128" |
| + url = urljoin(internal_file_service_url, encrypted_input_file) |
| + input_data_id = client.register_input_file(url, schema, |
| + list(input_crypto.key), |
| + list(input_crypto.iv), |
| + list(input_crypto.cmac)) |
| + |
| + encrypted_output_file = str(uuid.uuid1()) |
| + |
| + schema = "aes-gcm-128" |
| + url = urljoin(internal_file_service_url, encrypted_output_file) |
| + output_data_id = client.register_output_file(url, schema, |
| + list(output_crypto.key), |
| + list(output_crypto.iv)) |
| + |
| + if args.diagnosis: |
| + encrypted_diagnosis_file = str(uuid.uuid1()) |
| + url = urljoin(internal_file_service_url, encrypted_diagnosis_file) |
| + diagnosis_data_id = client.register_output_file( |
| + url, schema, list(diagnosis_crypto.key), |
| + list(diagnosis_crypto.iv)) |
| + client.assign_data_to_task( |
| + task_id, [DataMap("input_file", input_data_id)], [ |
| + DataMap("output_file", output_data_id), |
| + DataMap("log_file", diagnosis_data_id) |
| + ]) |
| + else: |
| + client.assign_data_to_task( |
| + task_id, [DataMap("input_file", input_data_id)], |
| + [DataMap("output_file", output_data_id)]) |
| + global CURRENT_RUNNING_TASK_ID |
| + CURRENT_RUNNING_TASK_ID = task_id |
| + cleanroom_info("Invoking task...", end=" ") |
| + client.invoke_task(task_id) |
| + cleanroom_info(f"done") |
| + cleanroom_info("Getting result...", end=" ") |
| + result = client.get_task_result(task_id) |
| + cleanroom_info(f"done") |
| + result = ''.join([chr(c) for c in result]) |
| + |
| + with tempfile.TemporaryDirectory() as dirpath: |
| + output_file_path = path.join(dirpath, encrypted_output_file) |
| + url = urljoin(file_service_url, encrypted_output_file) |
| + x = requests.get(url, headers=FILE_SERVICE_AUTH_HEADERS) |
| + if x.status_code != 200: |
| + raise CleanroomException(1, "Cannot access file service") |
| + with open(output_file_path, "wb") as f: |
| + f.write(x.content) |
| + if args.output_file != None: |
| + decrypt(output_file_path, args.output_file, output_crypto) |
| + else: |
| + decrypt(output_file_path, TMP_OUTPUT, output_crypto) |
| + |
| + if args.diagnosis: |
| + with tempfile.TemporaryDirectory() as dirpath: |
| + output_file_path = path.join(dirpath, encrypted_diagnosis_file) |
| + url = urljoin(file_service_url, encrypted_diagnosis_file) |
| + x = requests.get(url, headers=FILE_SERVICE_AUTH_HEADERS) |
| + if x.status_code != 200: |
| + raise CleanroomException(1, "Cannot access file service") |
| + with open(output_file_path, "wb") as f: |
| + f.write(x.content) |
| + diagnosis_file_path = "diagnosis.txt" |
| + decrypt(output_file_path, "diagnosis.txt", diagnosis_crypto) |
| + cleanroom_info(f"Diagnosis file: {diagnosis_file_path}") |
| + |
| + return result |
| + |
| + |
| +def list_functions(args): |
| + |
| + def print_function_table(functions, title, extra=False): |
| + if not functions: return |
| + table = [] |
| + fun_ids = shorten_uuid(functions) |
| + for i, function_id in enumerate(functions): |
| + f = client.get_function(function_id) |
| + description = f['description'][:75] + (f['description'][75:] |
| + and '..') |
| + if extra: |
| + headers = [ |
| + "Function ID", "Owner", "Allowed User Groups", |
| + "Description" |
| + ] |
| + entry = [ |
| + fun_ids[i], f['owner'], ",".join(f['user_allowlist']), |
| + f['description'].replace(';', '\n') |
| + ] |
| + else: |
| + headers = ["Function ID", "Description"] |
| + entry = [fun_ids[i], f['description'].replace(';', '\n')] |
| + table.append(entry) |
| + |
| + print() |
| + cleanroom_info("=== " + title + " ===") |
| + print() |
| + cleanroom_info(tabulate(table, headers=headers, showindex="always")) |
| + |
| + username = LOGIN_CONFIG['login']['username'] |
| + with connect_frontend_service() as client: |
| + functions = client.list_functions(username) |
| + print_function_table(functions['registered_functions'], |
| + "Registered Functions", |
| + extra=True) |
| + print_function_table(functions['allowed_functions'], |
| + "Allowed Functions") |
| + |
| + |
| +def get_function_usage_stats(args): |
| + username = LOGIN_CONFIG['login']['username'] |
| + function_uuid = id_to_uuid(args.function_id) |
| + with connect_frontend_service() as client: |
| + function_usage = client.get_function_usage_stats( |
| + username, function_uuid) |
| + function_quota = function_usage['function_quota'] |
| + current_usage = function_usage['current_usage'] |
| + if (function_quota > 0): |
| + cleanroom_info( |
| + 'Max invocation times: {function_quota}. Current invocation times: {current_usage}.' |
| + .format(function_quota=function_quota, |
| + current_usage=current_usage)) |
| + else: |
| + cleanroom_info( |
| + f'Max invocation times: inf. Current invocation times: {current_usage}.' |
| + ) |
| + |
| + |
| +def reset_user_password(args): |
| + with connect_authentication_service() as client: |
| + client.metadata.update({ |
| + "id": LOGIN_CONFIG['login']['username'], |
| + "token": LOGIN_CONFIG['login']['token'] |
| + }) |
| + password = client.reset_user_password(args.username) |
| + cleanroom_info( |
| + f"Password reset successfully. New password: {password}") |
| + |
| + |
| +def delete_user(args): |
| + with connect_authentication_service() as client: |
| + client.metadata.update({ |
| + "id": LOGIN_CONFIG['login']['username'], |
| + "token": LOGIN_CONFIG['login']['token'] |
| + }) |
| + client.delete_user(args.username) |
| + cleanroom_info(f"User delete successfully.") |
| + |
| + |
| +def delete_function(args): |
| + with connect_frontend_service() as client: |
| + function_uuid = id_to_uuid(args.function) |
| + client.disable_function(function_uuid) |
| + print(f"Function delete successfully.") |
| + |
| + |
| +def upgrade_cli(args): |
| + req = Request(urljoin(CONFIG["address"]["cli_service"], "version"), |
| + headers={'User-Agent': 'Mozilla/5.0'}) |
| + install_scripts_url = urljoin(CONFIG["address"]["cli_service"], |
| + "install.sh") |
| + cmd = 'sh -c "$(curl -kfsSL {url})"'.format(url=install_scripts_url) |
| + try: |
| + version = urlopen(req).read().decode('utf-8') |
| + except: |
| + raise CleanroomException(3) |
| + if parse_version(version) > parse_version(__version__): |
| + cleanroom_info( |
| + "Current version: {v}.".format(v=parse_version(__version__))) |
| + cleanroom_info("Latest version: {v}.".format(v=parse_version(version))) |
| + cleanroom_info("Upgrading...") |
| + os.system(cmd) |
| + else: |
| + cleanroom_info("Current version: {v} is the latest.".format( |
| + v=parse_version(__version__))) |
| + |
| + |
| +def update_enclave_info(args): |
| + req = Request(urljoin(CONFIG["address"]["cli_service"], |
| + "enclave_info.toml"), |
| + headers={'User-Agent': 'Mozilla/5.0'}) |
| + try: |
| + enclave_info = urlopen(req).read() |
| + except: |
| + raise CleanroomException(3) |
| + cleanroom_info("Updating ceritficates from: " + req.full_url) |
| + with open(ENCLAVE_INFO_PATH, "wb") as f: |
| + f.write(enclave_info) |
| + |
| + |
| +def parse_register_cpk(parser): |
| + parser_register_cpk = parser.add_parser('register-cpk', |
| + help='register CPK') |
| + parser_register_cpk.add_argument('-c', |
| + '--cpk', |
| + type=str, |
| + required=True, |
| + help='CPK file path') |
| + parser_register_cpk.add_argument('-n', |
| + '--name', |
| + default="function name", |
| + type=str, |
| + help='function name') |
| + parser_register_cpk.add_argument('-d', |
| + '--description', |
| + default="fucntion description", |
| + type=str, |
| + help='function description') |
| + parser_register_cpk.add_argument('-a', |
| + required=False, |
| + type=str, |
| + help='function arguments') |
| + parser_register_cpk.add_argument('-q', |
| + required=False, |
| + default=-1, |
| + type=int, |
| + help='function available quota') |
| + parser_register_cpk.add_argument( |
| + '-u', |
| + '--user-allowlist', |
| + nargs='+', |
| + required=True, |
| + default="A list of data owner managers can use this function", |
| + type=str, |
| + help='CPK file path') |
| + parser_register_cpk.add_argument('--diagnosis', |
| + action='store_true', |
| + help='enable diagnosis mode') |
| + parser_register_cpk.set_defaults(func=register_cpk) |
| + |
| + |
| +def parse_register_native(parser): |
| + parser_register_native = parser.add_parser('register-native', |
| + help='register native function') |
| + parser_register_native.add_argument('-n', |
| + '--name', |
| + default="function name", |
| + type=str, |
| + help='function name') |
| + parser_register_native.add_argument('-d', |
| + '--description', |
| + default="fucntion description", |
| + type=str, |
| + help='function description') |
| + parser_register_native.add_argument('-a', |
| + required=False, |
| + type=str, |
| + help='function argument') |
| + parser_register_native.add_argument('-q', |
| + default=-1, |
| + required=False, |
| + type=int, |
| + help='function available quota') |
| + parser_register_native.add_argument( |
| + '-e', |
| + '--expired', |
| + required=False, |
| + type=str, |
| + help='function expired-date. format: month/day/year') |
| + parser_register_native.add_argument( |
| + '-u', |
| + '--user-allowlist', |
| + nargs='+', |
| + required=True, |
| + default="A list of data owner managers can use this function", |
| + type=str, |
| + help='CPK file path') |
| + parser_register_native.add_argument('--diagnosis', |
| + action='store_true', |
| + help='enable diagnosis mode') |
| + parser_register_native.set_defaults(func=register_native) |
| + |
| + |
| +def parse_run(parser): |
| + parser_run = parser.add_parser('run', help='run cleanroom function') |
| + parser_run.add_argument('-f', |
| + '--function-id', |
| + required=True, |
| + type=str, |
| + help='function ID') |
| + parser_run.add_argument('-i', |
| + '--input-file', |
| + type=str, |
| + help='input file path') |
| + parser_run.add_argument('-o', |
| + '--output-file', |
| + type=str, |
| + help='output file path') |
| + parser_run.add_argument('--coding-wheel', |
| + type=str, |
| + help='coding wheel file path') |
| + parser_run.add_argument('--codon-usage-freq-table', |
| + type=str, |
| + help='codon usage freq table') |
| + parser_run.add_argument('--diagnosis', |
| + action='store_true', |
| + help='enable diagnosis mode') |
| + parser_run.add_argument('--silent', |
| + action='store_true', |
| + help='silence mode') |
| + parser_run.add_argument('arguments', |
| + nargs=argparse.REMAINDER, |
| + help='arguments of the function') |
| + parser_run.set_defaults(func=run) |
| + |
| + |
| +def parse_register_user(parser): |
| + parser_register_user = parser.add_parser('register-user', |
| + help='register a new user') |
| + parser_register_user.add_argument('-u', |
| + '--username', |
| + type=str, |
| + required=True, |
| + help='username') |
| + parser_register_user.add_argument('-p', |
| + '--password', |
| + required=True, |
| + type=str, |
| + help='password') |
| + parser_register_user.add_argument('-r', '--role', type=str, help='Role') |
| + parser_register_user.add_argument('-a', |
| + '--attribute', |
| + type=str, |
| + help='Attribute') |
| + parser_register_user.set_defaults(func=register_user) |
| + |
| + |
| +def parse_login(parser): |
| + parser_login = parser.add_parser('login', help='login') |
| + parser_login.add_argument( |
| + '-u', |
| + '--username', |
| + type=str, |
| + required=False, |
| + help='username, request interactively if not set') |
| + parser_login.add_argument( |
| + '-p', |
| + '--password', |
| + required=False, |
| + type=str, |
| + help='password, request interactively if not set') |
| + parser_login.set_defaults(func=login) |
| + |
| + |
| +def parse_change_password(parser): |
| + parser_change_password = parser.add_parser('change-password', |
| + help='change current password') |
| + parser_change_password.add_argument('-p', |
| + '--password', |
| + type=str, |
| + required=True, |
| + help='password') |
| + parser_change_password.set_defaults(func=change_password) |
| + |
| + |
| +def parse_delete_user(parser): |
| + parser_delete_user = parser.add_parser('delete-user', help='delete user') |
| + parser_delete_user.add_argument('-u', |
| + '--username', |
| + type=str, |
| + required=True, |
| + help='username') |
| + parser_delete_user.set_defaults(func=delete_user) |
| + |
| + |
| +def parse_delete_function(parser): |
| + parser_delete_function = parser.add_parser('delete-function', |
| + help='delete function') |
| + parser_delete_function.add_argument('-f', |
| + '--function', |
| + type=str, |
| + required=True, |
| + help='function ID') |
| + parser_delete_function.set_defaults(func=delete_function) |
| + |
| + |
| +def parse_check_function_usage(parser): |
| + parser_check_function_usage = parser.add_parser( |
| + 'check-usage', help='check function usage') |
| + parser_check_function_usage.add_argument('-f', |
| + '--function-id', |
| + type=str, |
| + required=True, |
| + help='function ID') |
| + parser_check_function_usage.set_defaults(func=get_function_usage_stats) |
| + |
| + |
| +def parse_list_users(parser): |
| + parser_login = parser.add_parser('list-users', |
| + help='list all managed users') |
| + parser_login.set_defaults(func=list_users) |
| + |
| + |
| +def parse_logout(parser): |
| + parser_logout = parser.add_parser('logout', help='logout') |
| + parser_logout.set_defaults(func=logout) |
| + |
| + |
| +def parse_uninstall(parser): |
| + parser_uninstall = parser.add_parser('uninstall', |
| + help='uninstall Cleanroom CLI') |
| + parser_uninstall.set_defaults(func=uninstall) |
| + |
| + |
| +def parse_list_functions(parser): |
| + parser_run = parser.add_parser('list-functions', |
| + help='list all cleanroom functions') |
| + parser_run.set_defaults(func=list_functions) |
| + |
| + |
| +def parse_reset_user_password(parser): |
| + parser_reset_user = parser.add_parser('reset-user-password', |
| + help='reset user password') |
| + parser_reset_user.add_argument('-u', |
| + '--username', |
| + type=str, |
| + required=True, |
| + help='username') |
| + parser_reset_user.set_defaults(func=reset_user_password) |
| + |
| + |
| +def parse_upgrade(parser): |
| + parser_upgrade = parser.add_parser('upgrade', |
| + help='upgrade cleanroom-cli') |
| + parser_upgrade.set_defaults(func=upgrade_cli) |
| + |
| + |
| +def parse_update_enclave_info(parser): |
| + parser_update_enclave_info = parser.add_parser('update-enclave-info', |
| + help='update enclave info') |
| + parser_update_enclave_info.set_defaults(func=update_enclave_info) |
| + |
| + |
| +def main() -> int: |
| + parser = argparse.ArgumentParser( |
| + prog='cleanroom-cli', |
| + description='Cleanroom Command Line Interface') |
| + parser.add_argument('--version', |
| + action='version', |
| + version='%(prog)s ' + __version__) |
| + parser.add_argument('--dump-report', |
| + action='store_true', |
| + help='dump attestation report') |
| + parser.set_defaults(dump_report=False) |
| + subparsers = parser.add_subparsers() |
| + |
| + parse_login(subparsers) |
| + parse_change_password(subparsers) |
| + parse_logout(subparsers) |
| + parse_upgrade(subparsers) |
| + parse_update_enclave_info(subparsers) |
| + parse_uninstall(subparsers) |
| + |
| + role = get_role(LOGIN_CONFIG) |
| + if role == "DataOwner": |
| + parse_run(subparsers) |
| + parse_check_function_usage(subparsers) |
| + parse_list_functions(subparsers) |
| + elif role == "DataOwnerManager": |
| + parse_run(subparsers) |
| + parse_list_functions(subparsers) |
| + parse_check_function_usage(subparsers) |
| + parse_register_user(subparsers) |
| + parse_reset_user_password(subparsers) |
| + parse_delete_user(subparsers) |
| + parse_list_users(subparsers) |
| + elif role == "FunctionOwner": |
| + parse_register_cpk(subparsers) |
| + parse_run(subparsers) |
| + parse_check_function_usage(subparsers) |
| + parse_list_functions(subparsers) |
| + parse_register_native(subparsers) |
| + parse_delete_function(subparsers) |
| + elif role == "NotLogin": |
| + pass |
| + else: |
| + parse_check_function_usage(subparsers) |
| + parse_register_user(subparsers) |
| + parse_reset_user_password(subparsers) |
| + parse_delete_user(subparsers) |
| + parse_list_users(subparsers) |
| + parse_register_cpk(subparsers) |
| + parse_register_native(subparsers) |
| + parse_run(subparsers) |
| + parse_list_functions(subparsers) |
| + parse_delete_function(subparsers) |
| + |
| + try: |
| + argcomplete.autocomplete(parser) |
| + argcomplete.autocomplete(subparsers) |
| + args = parser.parse_args() |
| + except: |
| + return 1 |
| + |
| + if args.dump_report: |
| + global DUMP_REPORT |
| + DUMP_REPORT = True |
| + |
| + try: |
| + args.func(args) |
| + except AttributeError: |
| + parser.print_help() |
| + return 0 |
| + except CleanroomException as e: |
| + if os.path.exists(TMP_OUTPUT): |
| + os.unlink(TMP_OUTPUT) |
| + print(e, file=sys.stderr) |
| + return 0 |
| + except TeaclaveException as e: |
| + if path.exists(TMP_OUTPUT): |
| + os.unlink(TMP_OUTPUT) |
| + print(e, file=sys.stderr) |
| + if e.error_code == 3: |
| + cleanroom_info("Updating encalve info...") |
| + update_enclave_info(args=None) |
| + cleanroom_info("Please run previous command again...") |
| + return 0 |
| + except Exception as e: |
| + if path.exists(TMP_OUTPUT): |
| + os.unlink(TMP_OUTPUT) |
| + print(e, file=sys.stderr) |
| + return 1 |
| + |
| + return 0 |
| + |
| + |
| +from teaclave import aes_gcm_file_encrypt, aes_gcm_file_decrypt |
| + |
| + |
| +def encrypt(input_file: str, output_file: str, |
| + crypto_info: CryptoInfo) -> CryptoInfo: |
| + crypto_info.cmac = aes_gcm_file_encrypt(crypto_info.key, crypto_info.iv, |
| + input_file, output_file) |
| + return crypto_info |
| + |
| + |
| +def decrypt(input_file: str, output_file: str, crypto_info): |
| + return aes_gcm_file_decrypt(crypto_info.key, crypto_info.iv, input_file, |
| + output_file) |
| + |
| + |
| +if __name__ == "__main__": |
| + sys.exit(main()) |
| diff --git a/cleanroom-cli/pyoxidizer.bzl b/cleanroom-cli/pyoxidizer.bzl |
| new file mode 100644 |
| index 0000000..9008874 |
| --- /dev/null |
| +++ b/cleanroom-cli/pyoxidizer.bzl |
| @@ -0,0 +1,33 @@ |
| +def make_exe(): |
| + dist = default_python_distribution() |
| + policy = dist.make_python_packaging_policy() |
| + policy.allow_files = True |
| + policy.file_scanner_emit_files = True |
| + policy.resources_location = "filesystem-relative:lib" |
| + python_config = dist.make_python_interpreter_config() |
| + python_config.module_search_paths = ["$ORIGIN/lib"] |
| + python_config.run_module = "cleanroom-cli" |
| + exe = dist.to_python_executable( |
| + name="cleanroom-cli", |
| + packaging_policy=policy, |
| + config=python_config, |
| + ) |
| + exe.add_python_resources(exe.read_package_root(CWD, ["cleanroom-cli"])) |
| + exe.add_python_resources(exe.read_package_root("../sdk/python", ["teaclave"])) |
| + for resource in exe.pip_install(["-r", "requirements.txt"]): |
| + if type(resource) == "File" and ".so." in resource.path: |
| + print("Adding " + resource.path + " to bundle") |
| + resource.add_include = True |
| + exe.add_python_resource(resource) |
| + return exe |
| + |
| +def make_install(exe): |
| + files = FileManifest() |
| + files.add_python_resource(".", exe) |
| + |
| + return files |
| + |
| +register_target("exe", make_exe) |
| +register_target("install", make_install, depends=["exe"], default=True) |
| + |
| +resolve_targets() |
| diff --git a/cleanroom-cli/readme-0.0.5.md b/cleanroom-cli/readme-0.0.5.md |
| new file mode 100644 |
| index 0000000..4a93b1e |
| --- /dev/null |
| +++ b/cleanroom-cli/readme-0.0.5.md |
| @@ -0,0 +1,109 @@ |
| +# Cleanroom CLI v0.0.5 |
| +In this document, we will walk you with the steps to invoke a function as |
| +data owners. |
| +There are two roles in the release: `Data owner manager` and `Data owner`. |
| +The `Data owner manager` registers users for the `Data owner`. |
| + |
| +In the current version, we have registered two demo functions in the Teaclave |
| +Cleanroom service. In the future, we will also support the role `function owner`, |
| +who can develop a Cleanroom App with the Cleanroom Development Kit and register |
| +the functions on their owns. |
| + |
| +## Start the Docker |
| +We have prepared a docker image on the DockerHub. Users can get the docker with |
| +the following command. |
| +``` |
| +docker run --rm \ |
| + --net="host" \ |
| + -w /cleanroom_sdk_cli \ |
| + -it organization/cleanroom-cli:0.0.5 \ |
| + bash |
| +``` |
| +In addition, you can use `-v $(pwd):/workspace` to mount a host folder |
| +into the docker container. |
| + |
| +## Data Owner Manager registers users for Data Owner |
| +``` |
| +cd data-owner-manageer |
| +./user-manager.py login -u data_owner_manager -p teaclave |
| +./user-manager.py register-user -u user_A -p teaclave |
| +./user-manager.py register-user -u user_B -p teaclave |
| +./user-manager.py logout |
| +``` |
| + |
| +## Data Owner lists and invokes current available functions |
| +``` |
| +cd data-owner |
| +./cleanroom.py login -u user_A -p teaclave |
| +./cleanroom.py list-functions |
| +``` |
| +We have deployed two functions for the `Data Owner Manager`. |
| +As a data owner, you are expected to see two avaialble functions. Note that the function ids |
| +might be different as shown below. |
| + |
| +``` |
| +=== Allowed Functions === |
| + |
| + Function ID Owner Allowed User Groups Description |
| +-- --------------------------------------------- ------- --------------------- ------------- |
| + 0 function-73bf9a9b-6631-4500-8f61-08a518219e4c admin data_owner_manager algorithm1 |
| + 1 function-98ee3801-6940-4b1a-b78a-a24946b736ef admin data_owner_manager algorithm2 |
| +``` |
| + |
| +After getting the function id, the data owner (login as user_A), can invoke the function and get the result. |
| + |
| +``` |
| +export ALGORITHM1=function-73bf9a9b-6631-4500-8f61-08a518219e4c |
| +export ALGORITHM2=function-98ee3801-6940-4b1a-b78a-a24946b736ef |
| +./cleanroom.py run -f $ALGORITHM1 -i sample_inputs/rna1.txt -o result1.txt |
| +cat result1.txt |
| +GCCUGGUGACCAUAGCGAGUCGGUACCACCCCUUCCCAUCCCGAACAGGACCGUGAAACGACUCCGCGCCGAUGAUAGUGCGGAUUCCCGUGUGAAAGUAGGUCAUCGCCAGGC |
| +(((((((((.....((((((((....(((.(((((.......))..)))...)))...)))))).))(((.........((((....)))).........)))..))))))))) (-35.50) |
| +``` |
| +``` |
| +./cleanroom.py run -f $ALGORITHM2 -i sample_inputs/protein1.txt -o result2.txt |
| +cat result2.txt |
| +using codon table ./codon_usage_freq_table_human.csv |
| +viterbi score 6460-64 |
| +CAI score 0 -nan |
| +runtime no backtrace: 20 s |
| +has bp sequence GGGACCAUCACUGUCGAGGAGCUUAAGAAGCUCCUCGAGCAGUGGAACCUGGUCAUCGGGUUCCUGUUCCUUACGUGGAUCUGCUUGCUGCAGUUCGCGUAUGCGAACAGGAAC |
| +has bp structure ..((((((((((((((((((((((...))))))))))).))))))....))))).....(((((((((((.((((((((.((((.....)))))))))))).).)))))))))) |
| +protein length: 38 |
| +RNA length: 114 |
| +sequence: GGGACCAUCACUGUCGAGGAGCUUAAGAAGCUCCUCGAGCAGUGGAACCUGGUCAUCGGGUUCCUGUUCCUUACGUGGAUCUGCUUGCUGCAGUUCGCGUAUGCGAACAGGAAC |
| +structure: ..((((((((((((((((((((((...))))))))))).))))))....))))).....(((((((((((.((((((((.((((.....)))))))))))).).)))))))))) |
| +free energy: -64.6 |
| +ln CAI: 0 -nan |
| +CAI: 0.743604 |
| +tuples: [] |
| +runtime: 11 s |
| +beam size: -1 |
| +lambda: 0 |
| +s1 size 10000000 |
| +s2 size 10000000 |
| +./cleanroom.py logout |
| +``` |
| +``` |
| +./cleanroom.py run -f $ALGORITHM2 -i sample_inputs/protein1.txt -o result2_args.txt -- -b -1 -l 10.0 -c codon_usage_freq_table_human.csv -s1 30 -s2 19 |
| +cat result2_args.txt |
| +using codon table codon_usage_freq_table_human.csv |
| +viterbi score 5870-58 |
| +CAI score -94.4436 0.779942 |
| +runtime no backtrace: 20 s |
| +has bp sequence GGGACCAUCACUGUCGAGGAGCUUAAGAAGCUCCUCGAGCAGUGGAACCUGGUCAUAGGCUUCCUGUUUCUGACAUGGAUCUGCCUGUUGCAGUUCGCUUAUGCGAACCGCAAC |
| +has bp structure ..((((((((((((((((((((((...))))))))))).))))))....)))))..((((.(((((((...)))).)))...))))(((((.((((((....)))))).))))) |
| +protein length: 38 |
| +RNA length: 114 |
| +sequence: GGGACCAUCACUGUCGAGGAGCUUAAGAAGCUCCUCGAGCAGUGGAACCUGGUCAUAGGCUUCCUGUUUCUGACAUGGAUCUGCCUGUUGCAGUUCGCUUAUGCGAACCGCAAC |
| +structure: ..((((((((((((((((((((((...))))))))))).))))))....)))))..((((.(((((((...)))).)))...))))(((((.((((((....)))))).))))) |
| +free energy: -58.7 |
| +ln CAI: -94.4436 0.779942 |
| +CAI: 0.779942 |
| +tuples: [] |
| +runtime: 11 s |
| +beam size: -1 |
| +lambda: 10 |
| +s1 size 30 |
| +s2 size 19 |
| +``` |
| diff --git a/cleanroom-cli/readme.md b/cleanroom-cli/readme.md |
| new file mode 100644 |
| index 0000000..9a80d09 |
| --- /dev/null |
| +++ b/cleanroom-cli/readme.md |
| @@ -0,0 +1,79 @@ |
| +# Cleanroom CLI v0.0.6 |
| + |
| +This document will walk you through using the Cleanroom CLI to invoke functions and manage users. |
| + |
| +## User: Start the Docker |
| + |
| +Users can obtain the Cleanroom CLI from Docker Hub with the following command. |
| +``` |
| +$ docker run --rm \ |
| + -w /cleanroom_sdk_cli \ |
| + -it organization/cleanroom-cli:0.0.6 \ |
| + bash |
| +``` |
| +Users can use `-v $(pwd):/workspace` to mount a host folder into the docker container. |
| + |
| +## User: login and invoke functions |
| + |
| +Users are required to log in and obtain a valid function ID before invoking a Cleanroom function. |
| +Here is an example. |
| + |
| +```bash |
| +$ cd data-owner |
| +$ ./cleanroom.py login -u <USERNAME> -p <PASSWORD> |
| +$ ./cleanroom.py list-functions |
| + |
| +=== Allowed Functions === |
| + |
| + Function ID Description |
| +-- --------------------------------------------- ----------------------------- |
| + 0 function-e6657fe7-5e48-466a-8c86-181d4082eb95 algorithm1 |
| + 1 function-106503b3-0e78-4a01-b9f3-2ac8ca5b60f1 algorithm2-hash -- <beam> <lambda> |
| + 2 function-6aeae4b3-83b1-4334-8b01-4c561665c0ad algorithm2-hash --diagnosis -- <beam> <lambda> |
| +``` |
| + |
| +In this example, three functions are listed by the currently logged-in user. Each function is shown with `FunctionID`, `Owner`, `AllowedUserGroup`, and `Description`. |
| + |
| +User can select the `FunctionID` based on its `Description` and invoke the function with `./cleanroom.py run -f <FunctionID> -i <InputPath> -o <OutputPath> -- <Args>`. |
| + |
| +Here is an example for invoking the function with the description `algorithm2-hash`. |
| + |
| +***Note that `<Args>` of the `algorithm2-hash` function must follow this covension `-- <beam_size> <lambda>`.*** Otherwise, users would get a `Function returned with error code: 1.` error message. |
| + |
| +```bash |
| +$ export ALGORITHM2=function-106503b3-0e78-4a01-b9f3-2ac8ca5b60f1 |
| +$ ./cleanroom.py run -f $ALGORITHM2 -i sample_inputs/protein1.txt -o result2.txt -- 100 200 |
| +Creating task with input sample_inputs/protein1.txt...done |
| +Invoking task... done, task_id: task-69e5b639-3041-4057-b0c8-e7b03a9068f4 |
| +Getting result... finished |
| +Task succeeded! |
| +Output file: result2.txt |
| +$ cat result2.txt |
| +input protein: GTITVEELKKLLEQWNLVIGFLFLTWICLLQFAYANRN |
| +sequence: GGCACCAUCACCGUGGAGGAGCUGAAGAAGCUGCUGGAGCAGUGGAACCUGGUGAUCGGCUUCCUGUUCCUGACCUGGAUCUGCCUGCUGCAGUUCGCCUACGCCAACCGGAAC |
| +structure: ..........(((.(..((...((.((..((.((((.(((((((((.((.(((.(..(((.....)))..).))).)).)))).))))).))))..)))).))))..))))... |
| +mRNA folding free energy: -31.20 kcal/mol; mRNA CAI: 1.0000 |
| +``` |
| + |
| +## About User management |
| + |
| +Cleanroom assigns privileged users called `Data Owner Manager`. `Data Owner Manager` can manage users with the `./user-manager.py` interface. |
| + |
| +Here is an example. |
| + |
| +```bash |
| +$ cd data-owner-manageer |
| +$ ./user-manager.py login -u <MANAGER> -p <MANAGER_PASSWORD> |
| +$ ./user-manager.py register-user -u <USERA> -p <USERA_PASSWORD> |
| +$ ./user-manager.py register-user -u <USERB> -p <USERB_PASSWORD> |
| +``` |
| + |
| +Compared with the previous version (0.0.5), `Data Owner Manager` can list current |
| +data owners. |
| + |
| +```bash |
| +$ ./user-manager.py list-users |
| +List users successful, managed users: <USERA>, <USERB> |
| +``` |
| + |
| + |
| diff --git a/cleanroom-cli/requirements.txt b/cleanroom-cli/requirements.txt |
| new file mode 100644 |
| index 0000000..db81650 |
| --- /dev/null |
| +++ b/cleanroom-cli/requirements.txt |
| @@ -0,0 +1,8 @@ |
| +toml==0.10.2 |
| +pyOpenSSL==21.0.0 |
| +tabulate==0.8.9 |
| +requests==2.22.0 |
| +argcomplete==2.0.0 |
| +packaging==21.3 |
| +PyJWT==2.3.0 |
| +cryptography==36.0.1 |
| diff --git a/cleanroom-cli/resource/azure/conf/dcap_root_cert.pem b/cleanroom-cli/resource/azure/conf/dcap_root_cert.pem |
| new file mode 100644 |
| index 0000000..c2b2907 |
| --- /dev/null |
| +++ b/cleanroom-cli/resource/azure/conf/dcap_root_cert.pem |
| @@ -0,0 +1,23 @@ |
| +-----BEGIN CERTIFICATE----- |
| +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx |
| +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT |
| +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp |
| +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz |
| +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH |
| +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE |
| +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw |
| +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD |
| +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH |
| +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy |
| +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh |
| +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR |
| +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA |
| +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE |
| +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX |
| +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu |
| +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr |
| +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo |
| +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO |
| +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI |
| +4uJEvlz36hz1 |
| +-----END CERTIFICATE----- |
| diff --git a/cleanroom-cli/resource/azure/conf/login.conf b/cleanroom-cli/resource/azure/conf/login.conf |
| new file mode 100644 |
| index 0000000..8a1dfc9 |
| --- /dev/null |
| +++ b/cleanroom-cli/resource/azure/conf/login.conf |
| @@ -0,0 +1,4 @@ |
| +[login] |
| +username = |
| +token = |
| + |
| diff --git a/cleanroom-cli/resource/azure/conf/cleanroom.conf b/cleanroom-cli/resource/azure/conf/cleanroom.conf |
| new file mode 100644 |
| index 0000000..511c259 |
| --- /dev/null |
| +++ b/cleanroom-cli/resource/azure/conf/cleanroom.conf |
| @@ -0,0 +1,10 @@ |
| +[address] |
| +authentication_service = api.authentication.dev.cleanroom.com:7776 |
| +frontend_service = api.frontend.dev.cleanroom.com:7777 |
| +file_service = http://api.file.dev.cleanroom.com:7789 |
| +cli_service = http://cli.cleanroom.com |
| + |
| +[attestation] |
| +as_root_ca_cert_path = dcap_root_cert.pem |
| +enclave_info_path = enclave_info.toml |
| + |
| diff --git a/cleanroom-cli/resource/azure/env b/cleanroom-cli/resource/azure/env |
| new file mode 100644 |
| index 0000000..d45707a |
| --- /dev/null |
| +++ b/cleanroom-cli/resource/azure/env |
| @@ -0,0 +1,11 @@ |
| +#!/bin/sh |
| +# cleanroom shell setup |
| +# affix colons on either side of $PATH to simplify matching |
| +case ":${PATH}:" in |
| + *:"$HOME/.cleanroom/bin":*) |
| + ;; |
| + *) |
| + # Prepending path in case a system-installed version needs to be overridden |
| + export PATH="$HOME/.cleanroom/bin:$PATH" |
| + ;; |
| +esac |
| diff --git a/cleanroom-cli/run_test.sh b/cleanroom-cli/run_test.sh |
| new file mode 100755 |
| index 0000000..ac23583 |
| --- /dev/null |
| +++ b/cleanroom-cli/run_test.sh |
| @@ -0,0 +1,24 @@ |
| +#!/bin/bash |
| + |
| +set -e |
| + |
| + |
| + |
| +echo "test attestation" |
| +./test/test_attestation.sh |
| + |
| +echo "test user management" |
| +./test/test_user_manage.sh |
| + |
| +echo "test register functions" |
| +./test/test_register_function.sh |
| + |
| +echo "test invoke functions" |
| +./test/test_invoke.sh |
| + |
| +echo "test check function usage" |
| +./test/test_check_usage.sh |
| + |
| +echo "test update enclave info" |
| +./test/test_update.sh |
| + |
| diff --git a/cleanroom-cli/test/install.sh b/cleanroom-cli/test/install.sh |
| new file mode 100755 |
| index 0000000..cc87992 |
| --- /dev/null |
| +++ b/cleanroom-cli/test/install.sh |
| @@ -0,0 +1,30 @@ |
| +#!/bin/sh |
| + |
| +set -e |
| + |
| + |
| +setup_color() { |
| + # Only use colors if connected to a terminal |
| + |
| + FMT_RED=$(printf '\033[31m') |
| + FMT_GREEN=$(printf '\033[92m') |
| + FMT_YELLOW=$(printf '\033[33m') |
| + FMT_BLUE=$(printf '\033[34m') |
| + FMT_BOLD=$(printf '\033[1m') |
| + FMT_RESET=$(printf '\033[0m') |
| +} |
| + |
| + |
| + |
| +print_success() { |
| + echo "${FMT_GREEN}Setup Cleanroom CLI successfully...${FMT_RESET}" |
| + echo "To get started you may need to restart your current shell." |
| +} |
| + |
| +main() { |
| + setup_color |
| + print_success |
| +} |
| + |
| + |
| +main "$@" |
| diff --git a/cleanroom-cli/test/test_attestation.sh b/cleanroom-cli/test/test_attestation.sh |
| new file mode 100755 |
| index 0000000..d99c711 |
| --- /dev/null |
| +++ b/cleanroom-cli/test/test_attestation.sh |
| @@ -0,0 +1,11 @@ |
| +#!/bin/bash |
| + |
| +set -e |
| + |
| +pushd install |
| + |
| +cli="bin/cleanroom-cli" |
| +$cli |
| +$cli login -u admin -p teaclave |
| + |
| +popd |
| \ No newline at end of file |
| diff --git a/cleanroom-cli/test/test_check_usage.sh b/cleanroom-cli/test/test_check_usage.sh |
| new file mode 100755 |
| index 0000000..5b10e6b |
| --- /dev/null |
| +++ b/cleanroom-cli/test/test_check_usage.sh |
| @@ -0,0 +1,15 @@ |
| +#!/bin/bash |
| +set -e |
| +pushd install |
| +cli="bin/cleanroom-cli" |
| +$cli login -u user-trial -p teaclave |
| +$cli list-functions |
| +FUNCID=($($cli list-functions | grep -E "^* +algorithm2-trial")) |
| +ALGORITHM2_TRIAL=${FUNCID[1]} |
| +$cli check-usage -f "$ALGORITHM2_TRIAL" |
| + |
| + |
| +FUNCID=($($cli list-functions | grep -E "^* +algorithm2-trial-tier2")) |
| +ALGORITHM2_TRIAL_TIER2=${FUNCID[1]} |
| +$cli check-usage -f "$ALGORITHM2_TRIAL_TIER2" |
| +popd |
| \ No newline at end of file |
| diff --git a/cleanroom-cli/test/test_invoke.sh b/cleanroom-cli/test/test_invoke.sh |
| new file mode 100755 |
| index 0000000..f2e36c2 |
| --- /dev/null |
| +++ b/cleanroom-cli/test/test_invoke.sh |
| @@ -0,0 +1,67 @@ |
| +#!/bin/bash |
| +set -e |
| + |
| +pushd install |
| +cli="bin/cleanroom-cli" |
| +rna1="GCCUGGUGACCAUAGCGAGUCGGUACCACCCCUUCCCAUCCCGAACAGGACCGUGAAACGACUCCGCGCCGAUGAUAGUGCGGAUUCCCGUGUGAAAGUAGGUCAUCGCCAGGC" |
| +protein1="GTITVEELKKLLEQWNLVIGFLFLTWICLLQFAYANRN" |
| + |
| +$cli login -u admin -p teaclave |
| +$cli login -u user1 -p teaclave |
| +$cli list-functions |
| +FUNCID=($($cli list-functions | grep -E "^* +algorithm1")) |
| +ALGORITHM1=${FUNCID[1]} |
| + |
| +FUNCID=($($cli list-functions | grep -E "^* +algorithm2")) |
| +ALGORITHM2=${FUNCID[1]} |
| + |
| +FUNCID=($($cli list-functions | grep -E "^* +algorithm2 --diagnosis")) |
| +ALGORITHM2_DIS=${FUNCID[1]} |
| + |
| +echo $rna1 > rna1.txt |
| +echo $protein1 > protein1.txt |
| + |
| +echo "running algorithm1 ${ALGORITHM1}" |
| +$cli run -f "$ALGORITHM1" -i rna1.txt -o result1.txt |
| +cat result1.txt |
| + |
| +echo "running algorithm2 ${ALGORITHM2}" |
| +$cli run -f "$ALGORITHM2" -i protein1.txt -o result2.txt -- 100 2 |
| +cat result2.txt |
| + |
| +echo "running algorithm2 with the diagnosis mode ${ALGORITHM2_DIS}" |
| +$cli run -f "$ALGORITHM2_DIS" -i protein1.txt -o result3.txt --diagnosis -- 100 2 |
| +cat result3.txt |
| + |
| +$cli login -u user-trial -p teaclave |
| +$cli list-functions |
| +FUNCID=($($cli list-functions | grep -E "^* +algorithm2-trial")) |
| +ALGORITHM2_TRIAL=${FUNCID[1]} |
| +echo MGDTAKPYFVKRTKDRGTMDDDDFRRGHPQQDYLIIDDHAKGHGSKMEKGLQKKKITPGNYGNTPRKGPCAVSSNPYAFKNPIYSQPAWMNDSHKDQSKRWLSDEHTGNSDNWREFKPGPRIPVINRQRKDSFQENEDGYRWQDTRGCRTVRRLFHKDLTSLETTSEMEAGSPENKKQRSRPRKPRKTRNEENEQDGDLEGPVIDESVLSTKELLGLQQAEERLKRDCIDRLKRRPRNYPTAKYTCRLCDVLIESIAFAHKHIKEKRHKKNIKEKQEEELLTTLPPPTPSQINAVGIAIDKVVQEFGLHNENLEQRLEIKRIMENVFQHKLPDCSLRLYGSSCSRLGFKNSDVNIDIQFPAIMSQPDVLLLVQECLKNSDSFIDVDADFHARVPVVVCREKQSGLLCKVSAGNENACLTTKHLTALGKLEPKLVPLVIAFRYWAKLCSIDRPEEGGLPPYVFALMAIFFLQQRKEPLLPVYLGSWIEGFSLSKLGNFNLQDIEKDVVIWEHTDSAAGDTGITKEEAPRETPIKRGQVSLILDVKHQPSVPVGQLWVELLRFYALEFNLADLVISIRVKELVSRELKDWPKKRIAIEDPYSVKRNVARTLNSQPVFEYILHCLRTTYKYFALPHKITKSSLLKPLNAITCISEHSKEVINHHPDVQTKDDKLKNSVLAQGPGATSSAANTCKVQPLTLKETAESFGSPPKEEMGNEHISVHPENSDCIQADVNSDDYKGDKVYHPETGRKNEKEKVGRKGKHLLTVDQKRGEHVVCGSTRNNESESTLDLEGFQNPTAKECEGLATLDNKADLDGESTEGTEELEDSLNHFTHSVQGQTSEMIPSDEEEEDDEEEEEEEEPRLTINQREDEDGMANEDELDNTYTGSGDEDALSEEDDELGEAAKYEDVKECGKHVERALLVELNKISLKEENVCEEKNSPVDQSDFFYEFSKLIFTKGKSPTVVCSLCKREGHLKKDCPEDFKRIQLEPLPPLTPKFLNILDQVCIQCYKDFSPTIIEDQAREHIRQNLESFIRQDFPGTKLSLFGSSKNGFGFKQSDLDVCMTINGLETAEGLDCVRTIEELARVLRKHSGLRNILPITTAKVPIVKFFHLRSGLEVDISLYNTLALHNTRLLSAYSAIDPRVKYLCYTMKVFTKMCDIGDASRGSLSSYAYTLMVLYFLQQRNPPVIPVLQEIYKGEKKPEIFVDGWNIYFFDQIDELPTYWSECGKNTESVGQLWLGLLRFYTEEFDFKEHVISIRRKSLLTTFKKQWTSKYIVIEDPFDLNHNLGAGLSRKMTNFIMKAFINGRRVFGIPVKGFPKDYPSKMEYFFDPDVLTEGELAPNDRCCRICGKIGHFMKDCPMRRKVRRRRDQEDALNQRYPENKEKRSKEDKEIHNKYTEREVSTKEDKPIQCTPQKAKPMRAAADLGREKILRPPVEKWKRQDDKDLREKRCFICGREGHIKKECPQFKGSSGSLSSKYMTQGKASAKRTQQES | $cli run -f "$ALGORITHM2_TRIAL" --silent |
| + |
| +echo MGDTAKPYFVKRTKDRGTMDDDDFRRGHPQQDYLIIDD | $cli run -f "$ALGORITHM2_TRIAL" |
| + |
| +set +e |
| +$cli list-functions |
| +FUNCID=($($cli list-functions | grep -E "^* +algorithm2-limited-times")) |
| +ALGORITHM2_TRIAL_LIMITED_TIMES=${FUNCID[1]} |
| +echo MGDTAKPYFVKRTKDRGTMDDDDFRRGHPQQDYLIIDD | $cli run -f "$ALGORITHM2_TRIAL_LIMITED_TIMES" --silent |
| +echo MGDTAKPYFVKRTKDRGTMDDDDFRRGHPQQDYLIIDD | $cli run -f "$ALGORITHM2_TRIAL_LIMITED_TIMES" --silent |
| +echo MGDTAKPYFVKRTKDRGTMDDDDFRRGHPQQDYLIIDD | $cli run -f "$ALGORITHM2_TRIAL_LIMITED_TIMES" --silent |
| +echo MGDTAKPYFVKRTKDRGTMDDDDFRRGHPQQDYLIIDD | $cli run -f "$ALGORITHM2_TRIAL_LIMITED_TIMES" --silent |
| + |
| +FUNCID=($($cli list-functions | grep -E "^* +algorithm2-trial-tier2")) |
| +ALGORITHM2_TRIAL_TIER2=${FUNCID[1]} |
| +echo MAVLSKEYGFVLLTGAASFIMVAHLAINVSKARKKYKVEYPIMYSTDPENGHIFNCIQRAHQNTLEVYPPFLFFLAVGGVYHPRIASGLGLAWIVGRVLYAYGYYTGEPSKRSRGALGSIALLGLVGTT| $cli run -f "$ALGORITHM2_TRIAL_TIER2" --silent |
| +echo MGDTAKPYFVKRTKDRGTMDDDDFRRGHPQQDYLIIDD | $cli run -f "$ALGORITHM2_TRIAL_TIER2" --silent |
| + |
| +$cli login -u user-trial1 -p teaclave |
| +FUNCID=($($cli list-functions | grep -E "^* +algorithm2-trial-expired")) |
| +ALGORITHM2_TRIAL_EXPIRED=${FUNCID[1]} |
| +echo MGDTAKPYFVKRTKDRGTMDDDDFRRGHPQQDYLIIDD | $cli run -f "$ALGORITHM2_TRIAL_EXPIRED" |
| + |
| +FUNCID=($($cli list-functions | grep -E "^* +algorithm2-limited-times")) |
| +ALGORITHM2_TRIAL_LIMITED_TIMES=${FUNCID[1]} |
| +echo MGDTAKPYFVKRTKDRGTMDDDDFRRGHPQQDYLIIDD | $cli run -f "$ALGORITHM2_TRIAL_LIMITED_TIMES" |
| + |
| +popd |
| diff --git a/cleanroom-cli/test/test_register_function.sh b/cleanroom-cli/test/test_register_function.sh |
| new file mode 100755 |
| index 0000000..89a39d0 |
| --- /dev/null |
| +++ b/cleanroom-cli/test/test_register_function.sh |
| @@ -0,0 +1,32 @@ |
| +#!/bin/bash |
| +set -e |
| + |
| + |
| +pushd install |
| + |
| +cli="bin/cleanroom-cli" |
| + |
| +$cli login -u admin -p teaclave |
| + |
| +function1_description="algorithm1;option: [Empty];registration_time: 2022-02-08 22:51:33;version: 1.0;" |
| +$cli register-cpk -c ../cpk/algorithm1.cpk -n algorithm1 -d "$function1_description" -u organization |
| + |
| +function2_description="algorithm2;option: --beam <int> --lambda <float>;version: 1.0" |
| +$cli register-native -n builtin-cleanroom-algorithm2-hash -d "$function2_description" -u organization |
| + |
| +function3_description="algorithm2 --diagnosis;version: 1.0 ;option: --beam <int> --lambda <float>" |
| +$cli register-native -n builtin-cleanroom-algorithm2-hash -d "$function3_description" -u organization --diagnosis |
| + |
| +function4_description="algorithm2-trial;option: [Empty];version: 1.0" |
| +$cli register-native -n builtin-cleanroom-algorithm2-hash-trial -d "$function4_description" -u organization-trial |
| + |
| +function5_description="algorithm2-limited-times;option: [Empty];version: 1.0" |
| +$cli register-native -n builtin-cleanroom-algorithm2-hash-trial -d "$function5_description" -q 3 -u organization-trial |
| + |
| +function6_description="algorithm2-trial-tier2;option: [Empty];version: 1.0;usage limits: 10;expired date: 06/01/2022" |
| +$cli register-native -n builtin-cleanroom-algorithm2-hash-trial-tier2 -d "$function6_description" -q 10 -e 06/01/2022 -u organization-trial |
| + |
| +function7_description="algorithm2-trial-expired;option: [Empty];version: 1.0;usage limits: 10;expired date: 01/02/2011" |
| +$cli register-native -n builtin-cleanroom-algorithm2-hash-trial-tier2 -d "$function7_description" -q 10 -e 01/02/2011 -u organization-trial |
| + |
| +popd |
| \ No newline at end of file |
| diff --git a/cleanroom-cli/test/test_update.sh b/cleanroom-cli/test/test_update.sh |
| new file mode 100755 |
| index 0000000..af69745 |
| --- /dev/null |
| +++ b/cleanroom-cli/test/test_update.sh |
| @@ -0,0 +1,35 @@ |
| +#!/bin/bash |
| + |
| +set -e |
| + |
| + |
| +cleanup() { |
| + # gracefully terminate all background services with SIGTERM |
| + [[ -z "$(jobs -p -r)" ]] || kill -s SIGTERM $(jobs -p -r) |
| + wait # wait for resource release |
| + echo "All jobs terminated." |
| +} |
| + |
| +trap cleanup INT TERM ERR |
| + |
| +OS=$(uname -s) |
| +ARCH=$(uname -m) |
| +cp ../release/services/enclave_info.toml test |
| +cp cleanroom-cli-"${OS}"-"${ARCH}".tgz test |
| +python3 -m http.server 7801 -d test & |
| + |
| +pushd install |
| + |
| +# Test updating enclave_info.toml |
| +cli="bin/cleanroom-cli" |
| +$cli login -u admin -p teaclave |
| +rm -f conf/enclave_info.toml |
| +{ |
| + set +e |
| + $cli login -u admin -p teaclave |
| +} |
| + |
| +# Test Upgrading CLI |
| +$cli upgrade |
| +cleanup |
| +popd |
| \ No newline at end of file |
| diff --git a/cleanroom-cli/test/test_user_manage.sh b/cleanroom-cli/test/test_user_manage.sh |
| new file mode 100755 |
| index 0000000..3997f4b |
| --- /dev/null |
| +++ b/cleanroom-cli/test/test_user_manage.sh |
| @@ -0,0 +1,41 @@ |
| +#!/bin/bash |
| +set -e |
| + |
| +pushd install |
| + |
| +cli="bin/cleanroom-cli" |
| +$cli login -u admin -p teaclave |
| +$cli register-user -u organization -p teaclave -r DataOwnerManager |
| +$cli register-user -u organization-trial -p teaclave -r DataOwnerManager |
| +$cli login -u organization -p teaclave |
| +$cli register-user -u user1 -p teaclave |
| +$cli register-user -u user2 -p teaclave |
| +$cli register-user -u user3 -p teaclave |
| +$cli register-user -u user4 -p teaclave |
| +$cli reset-user-password -u user4 |
| +$cli change-password -p new_teaclave |
| +$cli logout |
| +$cli login -u organization -p new_teaclave |
| +$cli delete-user -u user3 |
| +$cli logout |
| + |
| + |
| +$cli login -u organization-trial -p teaclave |
| +$cli register-user -u user-trial -p teaclave |
| +$cli register-user -u user-trial1 -p teaclave |
| + |
| + |
| + |
| +$cli login -u user2 -p teaclave |
| +$cli change-password -p new_teaclave |
| +$cli logout |
| +$cli login -u user2 -p new_teaclave |
| + |
| +echo "User3 loses the access" |
| +$cli logout |
| +{ |
| + set +e |
| + $cli login -u user3 -p teaclave |
| +} |
| + |
| +popd |
| \ No newline at end of file |
| diff --git a/cleanroom-cli/test/version b/cleanroom-cli/test/version |
| new file mode 100644 |
| index 0000000..3eefcb9 |
| --- /dev/null |
| +++ b/cleanroom-cli/test/version |
| @@ -0,0 +1 @@ |
| +1.0.0 |
| diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml |
| index f35f2fd..b095ebf 100644 |
| --- a/rpc/Cargo.toml |
| +++ b/rpc/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_rpc" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave RPC" |
| license = "Apache-2.0" |
| @@ -37,7 +37,7 @@ mesalock_sgx = [ |
| anyhow = { version = "1.0.26" } |
| cfg-if = { version = "0.1.9" } |
| http = { version = "0.2" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| rustls = { version = "0.16.0", features = ["dangerous_configuration"] } |
| serde = { version = "1.0.92", features = ["derive"] } |
| serde_json = { version = "1.0.39" } |
| diff --git a/rpc/proc_macro/Cargo.toml b/rpc/proc_macro/Cargo.toml |
| index 08bf734..55764d7 100644 |
| --- a/rpc/proc_macro/Cargo.toml |
| +++ b/rpc/proc_macro/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_rpc_proc_macro" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| license = "Apache-2.0" |
| edition = "2018" |
| diff --git a/rpc/src/protocol.rs b/rpc/src/protocol.rs |
| index d550850..3f67e53 100644 |
| --- a/rpc/src/protocol.rs |
| +++ b/rpc/src/protocol.rs |
| @@ -18,11 +18,15 @@ |
| #![allow(clippy::nonstandard_macro_braces)] |
| #![allow(clippy::unknown_clippy_lints)] |
| |
| +use log::debug; |
| use log::trace; |
| use serde::{Deserialize, Serialize}; |
| use std::io; |
| use std::prelude::v1::*; |
| +#[cfg(feature = "mesalock_sgx")] |
| +use std::untrusted::time::InstantEx; |
| use std::vec::Vec; |
| +use teaclave_types::profile_highlight; |
| use teaclave_types::TeaclaveServiceResponseError; |
| use thiserror::Error; |
| |
| @@ -80,37 +84,54 @@ where |
| |
| self.transport.read_exact(&mut header)?; |
| let buf_len = u64::from_be_bytes(header); |
| + let name = std::any::type_name::<V>(); |
| + if name.contains("Request") { |
| + debug!( |
| + "[+] Start reading bytes from transport layer {}: {}", |
| + name, buf_len |
| + ); |
| + } |
| if buf_len > self.max_frame_len { |
| return Err(ProtocolError::Other(anyhow::anyhow!( |
| "Exceed max frame length" |
| ))); |
| } |
| |
| - let mut recv_buf: Vec<u8> = vec![0u8; buf_len as usize]; |
| - self.transport.read_exact(&mut recv_buf)?; |
| - |
| - trace!("Recv: {}", std::string::String::from_utf8_lossy(&recv_buf)); |
| - let r: V = serde_json::from_slice(&recv_buf)?; |
| - |
| - Ok(r) |
| + let recv_buf = profile_highlight!(format!("[+] Read Bytes {}: {}", name, buf_len), { |
| + let mut recv_buf: Vec<u8> = vec![0u8; buf_len as usize]; |
| + self.transport.read_exact(&mut recv_buf)?; |
| + recv_buf |
| + }); |
| + |
| + profile_highlight!(format!("Deserialize {}, {} :", name, recv_buf.len()), { |
| + let r: V = serde_json::from_slice(&recv_buf)?; |
| + debug!("[+] Deserialize success: {}, {}", name, recv_buf.len()); |
| + Ok(r) |
| + }) |
| } |
| |
| pub fn write_message<U>(&mut self, message: U) -> std::result::Result<(), ProtocolError> |
| where |
| U: Serialize + std::fmt::Debug, |
| { |
| + let name = std::any::type_name::<U>(); |
| let send_buf = serde_json::to_vec(&message)?; |
| |
| trace!("Send: {}", std::string::String::from_utf8_lossy(&send_buf)); |
| |
| let buf_len = send_buf.len() as u64; |
| - let header = buf_len.to_be_bytes(); |
| + profile_highlight!( |
| + format!("Sent Resonse bytes {}, size {}: ", name, buf_len), |
| + { |
| + let header = buf_len.to_be_bytes(); |
| |
| - self.transport.write_all(&header)?; |
| - self.transport.write_all(&send_buf)?; |
| - self.transport.flush()?; |
| + self.transport.write_all(&header)?; |
| + self.transport.write_all(&send_buf)?; |
| + self.transport.flush()?; |
| |
| - Ok(()) |
| + Ok(()) |
| + } |
| + ) |
| } |
| } |
| |
| diff --git a/rpc/src/transport.rs b/rpc/src/transport.rs |
| index c30bb68..ad82dff 100644 |
| --- a/rpc/src/transport.rs |
| +++ b/rpc/src/transport.rs |
| @@ -19,6 +19,7 @@ use crate::protocol; |
| use crate::Request; |
| use crate::TeaclaveService; |
| use anyhow::Result; |
| +use log::debug; |
| use log::warn; |
| use serde::{Deserialize, Serialize}; |
| use std::prelude::v1::*; |
| @@ -115,6 +116,12 @@ where |
| let response: JsonProtocolResult<U, TeaclaveServiceResponseError> = |
| service.handle_request(request).into(); |
| protocol.write_message(response)?; |
| + debug!( |
| + "[+] {} End handling {} and writing back: {}. Ready for next request...", |
| + std::any::type_name::<X>(), |
| + std::any::type_name::<V>(), |
| + std::any::type_name::<U>() |
| + ); |
| } |
| } |
| } |
| diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml |
| index 30a1814..79ec89b 100644 |
| --- a/runtime/Cargo.toml |
| +++ b/runtime/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_runtime" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave runtime" |
| license = "Apache-2.0" |
| @@ -37,7 +37,7 @@ cov = ["sgx_cov"] |
| enclave_unit_test = ["teaclave_test_utils/mesalock_sgx"] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| |
| teaclave_types = { path = "../types" } |
| diff --git a/scripts/run_teaclave.sh b/scripts/run_teaclave.sh |
| new file mode 100755 |
| index 0000000..98a930c |
| --- /dev/null |
| +++ b/scripts/run_teaclave.sh |
| @@ -0,0 +1,64 @@ |
| +#!/bin/bash |
| + |
| +# 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. |
| + |
| + |
| +set -e |
| + |
| +TEACLAVE_PROJECT_ROOT="/teaclave" |
| +TEACLAVE_SERVICE_INSTALL_DIR="/teaclave/release/services" |
| + |
| + |
| +start_storage_server() { |
| + python3 ${TEACLAVE_PROJECT_ROOT}/tests/scripts/simple_http_server.py 6789 & |
| +} |
| + |
| +wait_port() { |
| + for port in "$@" |
| + do |
| + timeout 20 bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/$0/$1; do sleep 1; done' localhost "$port" |
| + done |
| +} |
| + |
| +cleanup() { |
| + # gracefully terminate all background services with SIGTERM |
| + [[ -z "$(jobs -p -r)" ]] || kill -s SIGTERM $(jobs -p -r) |
| + wait # wait for resource release |
| + echo "All jobs terminated." |
| +} |
| + |
| +pushd ${TEACLAVE_SERVICE_INSTALL_DIR} || exit |
| +trap cleanup INT TERM ERR |
| +./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 |
| + |
| +# Run of execution services separately |
| +./teaclave_execution_service & exe_pid1=$! |
| +sleep 25 # wait for execution services |
| +sleep 3600 |
| +popd |
| +cleanup |
| \ No newline at end of file |
| diff --git a/sdk/payload/wasm/teaclave_context/Cargo.toml b/sdk/payload/wasm/teaclave_context/Cargo.toml |
| index 454e754..3b43659 100644 |
| --- a/sdk/payload/wasm/teaclave_context/Cargo.toml |
| +++ b/sdk/payload/wasm/teaclave_context/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_context" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| edition = "2018" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Contex File interfaces for WASM payloads" |
| diff --git a/sdk/python/teaclave.py b/sdk/python/teaclave.py |
| index e6e7aef..835e21a 100644 |
| --- a/sdk/python/teaclave.py |
| +++ b/sdk/python/teaclave.py |
| @@ -31,9 +31,11 @@ import os |
| import time |
| import ssl |
| import socket |
| +import inspect |
| +import ctypes |
| |
| from typing import Tuple, Dict, List, Any |
| -from enum import IntEnum |
| +from enum import IntEnum, auto |
| |
| import cryptography |
| from cryptography import x509 |
| @@ -45,7 +47,8 @@ from OpenSSL import crypto |
| |
| __all__ = [ |
| 'FrontendService', 'AuthenticationService', 'FunctionInput', |
| - 'FunctionOutput', 'OwnerList', 'DataMap' |
| + 'FunctionOutput', 'FunctionArgument', 'OwnerList', 'DataMap', |
| + 'FunctionExpirationDate' |
| ] |
| |
| Metadata = Dict[str, str] |
| @@ -67,7 +70,59 @@ class Request: |
| |
| |
| class TeaclaveException(Exception): |
| - pass |
| + _teaclave_error = dict() |
| + _teaclave_error[0] = ('Networking error', |
| + 'Please check your Internet connection') |
| + _teaclave_error[1] = ('Remote attestation error', |
| + 'Please check your root certificate') |
| + _teaclave_error[2] = ('Remote attestation error', |
| + 'Please check your root certificate`') |
| + _teaclave_error[3] = ('Remote attestation error', |
| + 'Please check the `enclave_info.toml` file') |
| + _teaclave_error[4] = ('Login error', |
| + 'Please check your username and token') |
| + _teaclave_error[5] = ( |
| + 'Login error', |
| + 'Please ask your administrator to register a user for you') |
| + _teaclave_error[6] = ('Username already exists', |
| + 'Please use a different username') |
| + _teaclave_error[7] = ('Permission Deny', |
| + 'You are not authorized to run the command') |
| + _teaclave_error[8] = ('Authentication error', |
| + 'Please login your account first') |
| + _teaclave_error[9] = ( |
| + 'Invalid Task', |
| + 'Function is registered with the diagnosis mode. Please run with the --diagnosis option' |
| + ) |
| + _teaclave_error[10] = ('Fail to disable function', |
| + 'Only the function owner can delete a function') |
| + _teaclave_error[11] = ('Fail to delete user', |
| + 'Only the user-manager can delete a user') |
| + _teaclave_error[12] = ('Invalid password', |
| + "Please use a different password") |
| + _teaclave_error[13] = ('Authentication error', |
| + "Please login in your account") |
| + _teaclave_error[14] = ('Quota has been used up', |
| + 'This trial account has reached its usage limits') |
| + _teaclave_error[15] = ('The function is expired', |
| + 'Please contact the function owner') |
| + |
| + def __init__(self, error_code: int, msg=''): |
| + frame, filename, line_number, function_name, lines, index = inspect.stack( |
| + )[1] |
| + self.function_name = function_name |
| + self.error_code = error_code |
| + self.message = msg |
| + |
| + def __str__(self): |
| + CRED = '\033[91m' |
| + CEND = '\033[0m' |
| + if (self.error_code) in TeaclaveException._teaclave_error: |
| + error = TeaclaveException._teaclave_error[self.error_code][0] |
| + action = TeaclaveException._teaclave_error[self.error_code][1] |
| + return CRED + ('Error: {}. Action: {}.'.format(error, |
| + action)) + CEND |
| + return str(self.message) |
| |
| |
| class TeaclaveService: |
| @@ -79,7 +134,7 @@ class TeaclaveService: |
| address: Tuple[str, int], |
| as_root_ca_cert_path: str, |
| enclave_info_path: str, |
| - dump_report=False): |
| + dump_report=None): |
| self._context = ssl._create_unverified_context() |
| self._name = name |
| self._address = address |
| @@ -108,17 +163,21 @@ class TeaclaveService: |
| def connect(self): |
| """Establish trusted connection and verify remote attestation report. |
| """ |
| - sock = socket.create_connection(self._address) |
| + try: |
| + sock = socket.create_connection(self._address) |
| + except Exception as e: |
| + raise TeaclaveException(0) |
| channel = self._context.wrap_socket(sock, |
| server_hostname=self._address[0]) |
| cert = channel.getpeercert(binary_form=True) |
| - if not cert: raise TeaclaveException("Peer cert is None") |
| + if not cert: raise TeaclaveException(2) |
| try: |
| self._verify_report(self._as_root_ca_cert_path, |
| self._enclave_info_path, cert, self._name) |
| + except TeaclaveException as e: |
| + raise e |
| except Exception as e: |
| - raise TeaclaveException( |
| - f"Failed to verify attestation report: {e}") |
| + raise TeaclaveException(1) |
| self.channel = channel |
| |
| return self |
| @@ -143,7 +202,10 @@ class TeaclaveService: |
| |
| if self._dump_report: |
| try: |
| - with open(self._name + "_attestation_report.pem", "wb") as f: |
| + with open( |
| + os.path.join(self._dump_report, |
| + self._name + "_attestation_report.pem"), |
| + "wb") as f: |
| f.write( |
| cert.public_bytes(cryptography.hazmat.primitives. |
| serialization.Encoding.PEM)) |
| @@ -163,7 +225,7 @@ class TeaclaveService: |
| ] |
| except: |
| raise TeaclaveException( |
| - "Failed to load singing certificate of the report") |
| + msg="Failed to load singing certificate of the report") |
| |
| # verify signing cert with AS root cert |
| try: |
| @@ -171,13 +233,13 @@ class TeaclaveService: |
| as_root_ca_cert = f.read() |
| except: |
| raise TeaclaveException( |
| - "Failed to open attestation service root certificate") |
| + msg="Failed to open attestation service root certificate") |
| |
| try: |
| as_root_ca_cert = load_certificate(FILETYPE_PEM, as_root_ca_cert) |
| except: |
| raise TeaclaveException( |
| - "Failed to load attestation service root certificate") |
| + msg="Failed to load attestation service root certificate") |
| |
| store = X509Store() |
| store.add_cert(as_root_ca_cert) |
| @@ -193,7 +255,7 @@ class TeaclaveService: |
| # verify report's signature |
| crypto.verify(certs[0], signature, bytes(ext["report"]), 'sha256') |
| except: |
| - raise TeaclaveException("Failed to verify report signature") |
| + raise TeaclaveException(3) |
| |
| report = json.loads(report) |
| quote = report['isvEnclaveQuoteBody'] |
| @@ -207,15 +269,15 @@ class TeaclaveService: |
| try: |
| enclave_info = toml.load(enclave_info_path) |
| except: |
| - raise TeaclaveException("Failed to load enclave info") |
| + raise TeaclaveException(3) |
| |
| # verify mr_enclave and mr_signer |
| enclave_name = "teaclave_" + endpoint_name + "_service" |
| if mr_enclave != enclave_info[enclave_name]["mr_enclave"]: |
| - raise Exception("Failed to verify mr_enclave") |
| + raise TeaclaveException(3) |
| |
| if mr_signer != enclave_info[enclave_name]["mr_signer"]: |
| - raise Exception("Failed to verify mr_signer") |
| + raise TeaclaveException(3) |
| |
| |
| class FunctionInput: |
| @@ -248,6 +310,41 @@ class FunctionOutput: |
| self.optional = optional |
| |
| |
| +class FunctionArgument: |
| + """Function argument for registring. |
| + |
| + Args: |
| + key: Name of the argument. |
| + default_value: A default value of the argument. The default value is "". |
| + allow_overwrite: If allow_overwrite flag is set to be true. The service |
| + will allow the task creator to overwrite the arguement |
| + value when creating tasks. |
| + """ |
| + |
| + def __init__(self, |
| + key: str, |
| + default_value: str = "", |
| + allow_overwrite=True): |
| + self.key = key |
| + self.default_value = default_value |
| + self.allow_overwrite = allow_overwrite |
| + |
| + |
| +class FunctionExpirationDate: |
| + """Function expiration date. |
| + |
| + Args: |
| + expired: |
| + seconds: |
| + nanos: |
| + """ |
| + |
| + def __init__(self, expired=False, seconds: int = 0, nanos: int = 0): |
| + self.expired = expired |
| + self.seconds = seconds |
| + self.nanos = nanos |
| + |
| + |
| class OwnerList: |
| """Defines data ownership. |
| |
| @@ -315,8 +412,9 @@ class UserUpdateRequest(Request): |
| |
| class UserLoginRequest(Request): |
| |
| - def __init__(self, user_id: str, user_password: str): |
| + def __init__(self, metadata: Metadata, user_id: str, user_password: str): |
| self.request = "user_login" |
| + self.metadata = metadata |
| self.id = user_id |
| self.password = user_password |
| |
| @@ -370,7 +468,7 @@ class AuthenticationService(TeaclaveService): |
| address: Tuple[str, int], |
| as_root_ca_cert_path: str, |
| enclave_info_path: str, |
| - dump_report=False): |
| + dump_report=None): |
| super().__init__("authentication", address, as_root_ca_cert_path, |
| enclave_info_path, dump_report) |
| |
| @@ -396,7 +494,10 @@ class AuthenticationService(TeaclaveService): |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to register user ({reason})") |
| + if reason == 'permission denied': |
| + raise TeaclaveException(7) |
| + else: |
| + raise TeaclaveException(6) |
| |
| def user_update(self, user_id: str, user_password: str, role: str, |
| attribute: str): |
| @@ -433,7 +534,8 @@ class AuthenticationService(TeaclaveService): |
| str: User login token. |
| """ |
| self.check_channel() |
| - request = UserLoginRequest(user_id, user_password) |
| + metadata = {"id": user_id} |
| + request = UserLoginRequest(metadata, user_id, user_password) |
| _write_message(self.channel, request) |
| response = _read_message(self.channel) |
| if response["result"] == "ok": |
| @@ -442,7 +544,10 @@ class AuthenticationService(TeaclaveService): |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to login user ({reason})") |
| + if reason == 'user id not found': |
| + raise TeaclaveException(5) |
| + else: |
| + raise TeaclaveException(4) |
| |
| def user_change_password(self, user_password: str): |
| """Change password. |
| @@ -461,7 +566,12 @@ class AuthenticationService(TeaclaveService): |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to change password ({reason})") |
| + if reason == "permission denied": |
| + raise TeaclaveException(7) |
| + elif reason == "authentication failed": |
| + raise TeaclaveException(13) |
| + else: |
| + raise TeaclaveException(12) |
| |
| def reset_user_password(self, user_id: str) -> str: |
| """Reset password of a managed user. |
| @@ -483,7 +593,10 @@ class AuthenticationService(TeaclaveService): |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to reset password ({reason})") |
| + if reason == "permission denied": |
| + raise TeaclaveException(7) |
| + else: |
| + raise TeaclaveException(13) |
| |
| def delete_user(self, user_id: str) -> str: |
| """Delete a user. |
| @@ -502,7 +615,10 @@ class AuthenticationService(TeaclaveService): |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to delete user ({reason})") |
| + if reason == "permission denied": |
| + raise TeaclaveException(7) |
| + else: |
| + raise TeaclaveException(13) |
| |
| def list_users(self, user_id: str) -> str: |
| """List managed users |
| @@ -523,15 +639,28 @@ class AuthenticationService(TeaclaveService): |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to list user ({reason})") |
| + if reason == "permission denied": |
| + raise TeaclaveException(7) |
| + else: |
| + raise TeaclaveException(13) |
| |
| |
| class RegisterFunctionRequest(Request): |
| |
| - def __init__(self, metadata: Metadata, name: str, description: str, |
| - executor_type: str, public: bool, payload: List[int], |
| - arguments: List[str], inputs: List[FunctionInput], |
| - outputs: List[FunctionOutput], user_allowlist: List[str]): |
| + def __init__( |
| + self, |
| + metadata: Metadata, |
| + name: str, |
| + description: str, |
| + executor_type: str, |
| + public: bool, |
| + payload: List[int], |
| + arguments: List[FunctionArgument], |
| + inputs: List[FunctionInput], |
| + outputs: List[FunctionOutput], |
| + user_allowlist: List[str], |
| + usage_quota: int, |
| + expiration_date: FunctionExpirationDate = FunctionExpirationDate()): |
| self.request = "register_function" |
| self.metadata = metadata |
| self.name = name |
| @@ -543,15 +672,26 @@ class RegisterFunctionRequest(Request): |
| self.inputs = inputs |
| self.outputs = outputs |
| self.user_allowlist = user_allowlist |
| + self.usage_quota = usage_quota |
| + self.expiration_date = expiration_date |
| |
| |
| class UpdateFunctionRequest(Request): |
| |
| - def __init__(self, metadata: Metadata, function_id: str, name: str, |
| - description: str, executor_type: str, public: bool, |
| - payload: List[int], arguments: List[str], |
| - inputs: List[FunctionInput], outputs: List[FunctionOutput], |
| - user_allowlist: List[str]): |
| + def __init__( |
| + self, |
| + metadata: Metadata, |
| + function_id: str, |
| + name: str, |
| + description: str, |
| + executor_type: str, |
| + public: bool, |
| + payload: List[int], |
| + arguments: List[str], |
| + inputs: List[FunctionInput], |
| + outputs: List[FunctionOutput], |
| + user_allowlist: List[str], |
| + expiration_date: FunctionExpirationDate = FunctionExpirationDate()): |
| self.request = "update_function" |
| self.metadata = metadata |
| self.function_id = function_id |
| @@ -564,6 +704,7 @@ class UpdateFunctionRequest(Request): |
| self.inputs = inputs |
| self.outputs = outputs |
| self.user_allowlist = user_allowlist |
| + self.expiration_date = expiration_date |
| |
| |
| class ListFunctionsRequest(Request): |
| @@ -598,6 +739,15 @@ class GetFunctionRequest(Request): |
| self.function_id = function_id |
| |
| |
| +class GetFunctionUsageStatsRequest(Request): |
| + |
| + def __init__(self, metadata: Metadata, user_id: str, function_id: str): |
| + self.request = "get_function_usage_stats" |
| + self.metadata = metadata |
| + self.user_id = user_id |
| + self.function_id = function_id |
| + |
| + |
| class RegisterInputFileRequest(Request): |
| |
| def __init__(self, metadata: Metadata, url: str, cmac: List[int], |
| @@ -710,7 +860,7 @@ class FrontendService(TeaclaveService): |
| address: Tuple[str, int], |
| as_root_ca_cert_path: str, |
| enclave_info_path: str, |
| - dump_report=False): |
| + dump_report=None): |
| super().__init__("frontend", address, as_root_ca_cert_path, |
| enclave_info_path, dump_report) |
| |
| @@ -721,17 +871,19 @@ class FrontendService(TeaclaveService): |
| executor_type: str, |
| public: bool = True, |
| payload: List[int] = [], |
| - arguments: List[str] = [], |
| + arguments: List[FunctionArgument] = [], |
| inputs: List[FunctionInput] = [], |
| outputs: List[FunctionOutput] = [], |
| user_allowlist: List[str] = [], |
| - ): |
| + usage_quota: int = -1, |
| + expiration_date: FunctionExpirationDate = FunctionExpirationDate()): |
| self.check_metadata() |
| self.check_channel() |
| request = RegisterFunctionRequest(self.metadata, name, description, |
| executor_type, public, payload, |
| arguments, inputs, outputs, |
| - user_allowlist) |
| + user_allowlist, usage_quota, |
| + expiration_date) |
| _write_message(self.channel, request) |
| response = _read_message(self.channel) |
| if response["result"] == "ok": |
| @@ -740,7 +892,10 @@ class FrontendService(TeaclaveService): |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to register function ({reason})") |
| + if reason == "permission denied": |
| + raise TeaclaveException(7) |
| + else: |
| + raise TeaclaveException(13) |
| |
| def update_function( |
| self, |
| @@ -750,7 +905,7 @@ class FrontendService(TeaclaveService): |
| executor_type: str, |
| public: bool = True, |
| payload: List[int] = [], |
| - arguments: List[str] = [], |
| + arguments: List[FunctionArgument] = [], |
| inputs: List[FunctionInput] = [], |
| outputs: List[FunctionOutput] = [], |
| user_allowlist: List[str] = [], |
| @@ -780,7 +935,13 @@ class FrontendService(TeaclaveService): |
| if response["result"] == "ok": |
| return response["content"] |
| else: |
| - raise TeaclaveException("Failed to list functions") |
| + reason = "unknown" |
| + if "request_error" in response: |
| + reason = response["request_error"] |
| + if reason == "permission denied": |
| + raise TeaclaveException(7) |
| + else: |
| + raise TeaclaveException(13) |
| |
| def get_function(self, function_id: str): |
| self.check_metadata() |
| @@ -794,7 +955,28 @@ class FrontendService(TeaclaveService): |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to get function ({reason})") |
| + if reason == "permission denied": |
| + raise TeaclaveException(7) |
| + else: |
| + raise TeaclaveException(13) |
| + |
| + def get_function_usage_stats(self, user_id: str, function_id: str): |
| + self.check_metadata() |
| + self.check_channel() |
| + request = GetFunctionUsageStatsRequest(self.metadata, user_id, |
| + function_id) |
| + _write_message(self.channel, request) |
| + response = _read_message(self.channel) |
| + if response["result"] == "ok": |
| + return response["content"] |
| + else: |
| + reason = "unknown" |
| + if "request_error" in response: |
| + reason = response["request_error"] |
| + if reason == "permission denied": |
| + raise TeaclaveException(7) |
| + else: |
| + raise TeaclaveException(13) |
| |
| def delete_function(self, function_id: str): |
| self.check_metadata() |
| @@ -816,7 +998,13 @@ class FrontendService(TeaclaveService): |
| if response["result"] == "ok": |
| return response["content"] |
| else: |
| - raise TeaclaveException("Failed to disable function") |
| + reason = "unknown" |
| + if "request_error" in response: |
| + reason = response["request_error"] |
| + if reason == "permission denied": |
| + raise TeaclaveException(7) |
| + else: |
| + raise TeaclaveException(13) |
| |
| def register_input_file(self, url: str, schema: str, key: List[int], |
| iv: List[int], cmac: List[int]): |
| @@ -872,7 +1060,12 @@ class FrontendService(TeaclaveService): |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to create task ({reason})") |
| + if reason == "function expired": |
| + raise TeaclaveException(15) |
| + if reason == "quota has been used up": |
| + raise TeaclaveException(14) |
| + else: |
| + raise TeaclaveException(9) |
| |
| def assign_data_to_task(self, task_id: str, inputs: List[DataMap], |
| outputs: List[DataMap]): |
| @@ -916,7 +1109,10 @@ class FrontendService(TeaclaveService): |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to invoke task ({reason})") |
| + if reason == "quota has been used up": |
| + raise TeaclaveException(14) |
| + else: |
| + raise TeaclaveException(f"Failed to invoke task ({reason})") |
| |
| def cancel_task(self, task_id: str): |
| self.check_metadata() |
| @@ -936,22 +1132,22 @@ class FrontendService(TeaclaveService): |
| self.check_metadata() |
| self.check_channel() |
| request = GetTaskRequest(self.metadata, task_id) |
| - |
| _write_message(self.channel, request) |
| response = _read_message(self.channel) |
| if response["result"] != "ok": |
| reason = "unknown" |
| if "request_error" in response: |
| reason = response["request_error"] |
| - raise TeaclaveException(f"Failed to get task result ({reason})") |
| + raise TeaclaveException(f"Failed to get task ({reason})") |
| return response["content"] |
| |
| def get_task_result(self, task_id: str): |
| - self.check_metadata() |
| - self.check_channel() |
| request = GetTaskRequest(self.metadata, task_id) |
| - |
| + i = 0 |
| while True: |
| + self.check_metadata() |
| + self.check_channel() |
| + i = i + 1 |
| _write_message(self.channel, request) |
| response = _read_message(self.channel) |
| if response["result"] != "ok": |
| @@ -960,7 +1156,10 @@ class FrontendService(TeaclaveService): |
| reason = response["request_error"] |
| raise TeaclaveException( |
| f"Failed to get task result ({reason})") |
| - time.sleep(1) |
| + if i < 20: |
| + time.sleep(i) |
| + else: |
| + time.sleep(20) |
| if response["content"]["status"] == TaskStatus.Finished: |
| break |
| elif response["content"]["status"] == TaskStatus.Canceled: |
| @@ -1028,3 +1227,39 @@ def _read_message(sock: ssl.SSLSocket): |
| raw += data |
| response = json.loads(raw) |
| return response |
| + |
| + |
| +from cryptography.hazmat.primitives.ciphers.aead import AESGCM |
| + |
| +AAD = bytes([0 for i in range(0, 8)]) |
| + |
| + |
| +def aes_gcm_encrypt(key, iv, plaintext): |
| + cipher = AESGCM(key) |
| + ciphertext_with_tag = cipher.encrypt(iv, plaintext, AAD) |
| + return ciphertext_with_tag |
| + |
| + |
| +def aes_gcm_file_encrypt(key, iv, infile, outfile): |
| + with open(infile, mode='rb') as file: |
| + plaintext = file.read() |
| + |
| + ciphertext_with_tag = aes_gcm_encrypt(key, iv, plaintext) |
| + |
| + with open(outfile, mode='wb') as file: |
| + file.write(ciphertext_with_tag) |
| + return ciphertext_with_tag[-16:] |
| + |
| + |
| +def aes_gcm_decrypt(key, iv, ciphertext_with_tag): |
| + cipher = AESGCM(key) |
| + return cipher.decrypt(iv, ciphertext_with_tag, AAD) |
| + |
| + |
| +def aes_gcm_file_decrypt(key, iv, infile, outfile): |
| + with open(infile, mode='rb') as file: |
| + ciphertext_with_tag = file.read() |
| + plaintext = aes_gcm_decrypt(key, iv, ciphertext_with_tag) |
| + with open(outfile, mode='wb') as file: |
| + file.write(plaintext) |
| + return |
| diff --git a/sdk/rust/Cargo.lock b/sdk/rust/Cargo.lock |
| index 6078717..13d41db 100644 |
| --- a/sdk/rust/Cargo.lock |
| +++ b/sdk/rust/Cargo.lock |
| @@ -350,7 +350,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "protected_fs_rs" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "cfg-if 0.1.10", |
| "libc", |
| @@ -544,7 +544,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_attestation" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "base64 0.13.0", |
| @@ -572,7 +572,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_client_sdk" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "libc", |
| @@ -588,7 +588,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_config" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "log", |
| @@ -599,7 +599,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_crypto" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "hex", |
| @@ -612,11 +612,12 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_proto" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "base64 0.13.0", |
| "cfg-if 0.1.10", |
| + "log", |
| "prost", |
| "rand", |
| "serde", |
| @@ -631,7 +632,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_rpc" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "cfg-if 0.1.10", |
| @@ -650,7 +651,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_rpc_proc_macro" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "proc-macro2", |
| "quote", |
| @@ -659,7 +660,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_types" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "anyhow", |
| "hex", |
| diff --git a/sdk/rust/Cargo.toml b/sdk/rust/Cargo.toml |
| index 1f97f89..92799a6 100644 |
| --- a/sdk/rust/Cargo.toml |
| +++ b/sdk/rust/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_client_sdk" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Rust Client SDK" |
| license = "Apache-2.0" |
| diff --git a/sdk/rust/src/lib.rs b/sdk/rust/src/lib.rs |
| index 69c9f3a..6f9510d 100644 |
| --- a/sdk/rust/src/lib.rs |
| +++ b/sdk/rust/src/lib.rs |
| @@ -41,7 +41,7 @@ pub use teaclave_proto::teaclave_frontend_service::{ |
| RegisterOutputFileRequest, RegisterOutputFileResponse, |
| }; |
| pub use teaclave_types::{ |
| - EnclaveInfo, Executor, FileCrypto, FunctionInput, FunctionOutput, TaskResult, |
| + EnclaveInfo, Executor, FileCrypto, FunctionArgument, FunctionInput, FunctionOutput, TaskResult, |
| }; |
| |
| pub mod bindings; |
| @@ -211,7 +211,7 @@ impl FrontendClient { |
| description: &str, |
| executor_type: &str, |
| payload: Option<&[u8]>, |
| - arguments: Option<&[&str]>, |
| + arguments: Option<Vec<FunctionArgument>>, |
| inputs: Option<Vec<FunctionInput>>, |
| outputs: Option<Vec<FunctionOutput>>, |
| ) -> Result<String> { |
| @@ -592,7 +592,7 @@ mod tests { |
| "An native echo function.", |
| "builtin", |
| None, |
| - Some(&["message"]), |
| + Some(vec![FunctionArgument::new("message", "", true)]), |
| None, |
| None, |
| ) |
| diff --git a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.podspec b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.podspec |
| index e6c5194..b4f7740 100644 |
| --- a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.podspec |
| +++ b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.podspec |
| @@ -17,13 +17,13 @@ |
| |
| Pod::Spec.new do |s| |
| s.name = "TeaclaveClientSDK" |
| - s.version = "0.4.0" |
| + s.version = "0.2.0" |
| s.summary = "Teaclave Client SDK." |
| s.homepage = "https://teaclave.apache.org" |
| s.license = "Apache-2.0" |
| s.author = { "Teaclave Contributors" => "dev@teaclave.apache.org" } |
| s.ios.deployment_target = '13.0' |
| - s.source = { :git => "https://github.com/apache/incubator-teaclave.git", :tag => "v0.4.0" } |
| + s.source = { :git => "https://github.com/apache/incubator-teaclave.git", :tag => "v0.2.0" } |
| s.source_files = "TeaclaveClietnSDK", "TeaclaveClientSDK/**/*.{h,swift}", "External" |
| s.module_map = 'TeaclaveClientSDK/TeaclaveClientSDK.modulemap' |
| s.vendored_libraries= 'External/libteaclave_client_sdk.a' |
| diff --git a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.pbxproj b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.pbxproj |
| index b61144c..cedafe4 100644 |
| --- a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.pbxproj |
| +++ b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.pbxproj |
| @@ -394,7 +394,7 @@ |
| "$(PROJECT_DIR)", |
| "$(PROJECT_DIR)/../../rust/target/universal/debug", |
| ); |
| - MARKETING_VERSION = 0.4.0; |
| + MARKETING_VERSION = 0.2.0; |
| MODULEMAP_FILE = "$(SRCROOT)/TeaclaveClientSDK/TeaclaveClientSDK.modulemap"; |
| PRODUCT_BUNDLE_IDENTIFIER = org.apache.teaclave.TeaclaveClientSDK; |
| PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; |
| @@ -433,7 +433,7 @@ |
| "$(PROJECT_DIR)", |
| "$(PROJECT_DIR)/../../rust/target/universal/debug", |
| ); |
| - MARKETING_VERSION = 0.4.0; |
| + MARKETING_VERSION = 0.2.0; |
| MODULEMAP_FILE = "$(SRCROOT)/TeaclaveClientSDK/TeaclaveClientSDK.modulemap"; |
| PRODUCT_BUNDLE_IDENTIFIER = org.apache.teaclave.TeaclaveClientSDK; |
| PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; |
| diff --git a/services/access_control/app/Cargo.toml b/services/access_control/app/Cargo.toml |
| index 63c4c7e..9d44118 100644 |
| --- a/services/access_control/app/Cargo.toml |
| +++ b/services/access_control/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_access_control_service" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Access Control Service" |
| license = "Apache-2.0" |
| diff --git a/services/access_control/enclave/Cargo.toml b/services/access_control/enclave/Cargo.toml |
| index fc8d5dd..d5ee467 100644 |
| --- a/services/access_control/enclave/Cargo.toml |
| +++ b/services/access_control/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_access_control_service_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Access Control Service enclave" |
| license = "Apache-2.0" |
| @@ -46,7 +46,7 @@ enclave_unit_test = ["teaclave_binder/enclave_unit_test", "teaclave_test_utils/m |
| [dependencies] |
| anyhow = { version = "1.0.26" } |
| cfg-if = { version = "0.1.9" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| serde = { version = "1.0.92" } |
| serde_json = { version = "1.0.39" } |
| thiserror = { version = "1.0.9" } |
| diff --git a/services/authentication/app/Cargo.toml b/services/authentication/app/Cargo.toml |
| index 01f42d2..9a41ab0 100644 |
| --- a/services/authentication/app/Cargo.toml |
| +++ b/services/authentication/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_authentication_service" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Authentication Service" |
| license = "Apache-2.0" |
| diff --git a/services/authentication/enclave/Cargo.toml b/services/authentication/enclave/Cargo.toml |
| index 5708e4e..696e9d9 100644 |
| --- a/services/authentication/enclave/Cargo.toml |
| +++ b/services/authentication/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_authentication_service_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Authentication Service enclave" |
| license = "Apache-2.0" |
| @@ -46,7 +46,7 @@ enclave_unit_test = ["teaclave_binder/enclave_unit_test", "teaclave_test_utils/m |
| [dependencies] |
| anyhow = { version = "1.0.26" } |
| cfg-if = { version = "0.1.9" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| serde = { version = "1.0.92" } |
| serde_json = { version = "1.0.39" } |
| |
| diff --git a/services/execution/app/Cargo.toml b/services/execution/app/Cargo.toml |
| index 360d6dc..22e001d 100644 |
| --- a/services/execution/app/Cargo.toml |
| +++ b/services/execution/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_execution_service" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave worker." |
| license = "Apache-2.0" |
| diff --git a/services/execution/enclave/Cargo.toml b/services/execution/enclave/Cargo.toml |
| index b763666..2bf7877 100644 |
| --- a/services/execution/enclave/Cargo.toml |
| +++ b/services/execution/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_execution_service_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Execution Service" |
| license = "Apache-2.0" |
| @@ -46,11 +46,12 @@ cov = ["teaclave_service_enclave_utils/cov"] |
| enclave_unit_test = ["teaclave_binder/enclave_unit_test", "teaclave_test_utils/mesalock_sgx"] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| serde_json = { version = "1.0.39" } |
| serde = { version = "1.0.92", features = ["derive"] } |
| thiserror = { version = "1.0.9" } |
| +bincode = {version = "1.3.1" } |
| gbdt = { version = "0.1.0", features = ["input", "enable_training"] } |
| uuid = { version = "0.8.1", features = ["v4"] } |
| url = { version = "2.1.1", features = ["serde"]} |
| diff --git a/services/execution/enclave/Enclave.config.xml b/services/execution/enclave/Enclave.config.xml |
| index b09351d..b77e739 100644 |
| --- a/services/execution/enclave/Enclave.config.xml |
| +++ b/services/execution/enclave/Enclave.config.xml |
| @@ -22,10 +22,15 @@ |
| <ProdID>0</ProdID> |
| <ISVSVN>0</ISVSVN> |
| <StackMaxSize>0x200000</StackMaxSize> <!-- 2M --> |
| - <HeapMaxSize>0x30000000</HeapMaxSize> <!-- 768M --> |
| + <HeapMaxSize>0x380000000</HeapMaxSize> <!-- 14G --> |
| <TCSNum>22</TCSNum> |
| <TCSPolicy>0</TCSPolicy> |
| <DisableDebug>0</DisableDebug> |
| <MiscSelect>0</MiscSelect> |
| <MiscMask>0xFFFFFFFF</MiscMask> |
| + <ReservedMemMinSize> 0x2000000</ReservedMemMinSize> |
| + <ReservedMemInitSize>0x2000000</ReservedMemInitSize> |
| + <ReservedMemMaxSize> 0x8000000</ReservedMemMaxSize> |
| + <!-- On SGX1 platform, ReservedMemExecutable==1 means set reserved memory as read, write and execute (RWX) --> |
| + <ReservedMemExecutable>1</ReservedMemExecutable> |
| </EnclaveConfiguration> |
| diff --git a/services/execution/enclave/src/coding_wheel.txt b/services/execution/enclave/src/coding_wheel.txt |
| new file mode 100644 |
| index 0000000..909610a |
| --- /dev/null |
| +++ b/services/execution/enclave/src/coding_wheel.txt |
| @@ -0,0 +1,21 @@ |
| +Phe U U CU |
| +Leu C U GCUA U U GA |
| +Ser U C GCUA A G CU |
| +Tyr U A CU |
| +STOP U A GA U G A |
| +Cys U G CU |
| +Trp U G G |
| +Pro C C GCUA |
| +His C A CU |
| +Gln C A GA |
| +Arg C G GCUA A G GA |
| +Ile A U CUA |
| +Met A U G |
| +Thr A C GCUA |
| +Asn A A CU |
| +Lys A A GA |
| +Val G U GCUA |
| +Asp G A CU |
| +Glu G A GA |
| +Gly G G GCUA |
| +Ala G C GCUA |
| \ No newline at end of file |
| diff --git a/services/execution/enclave/src/codon_usage_freq_table_human.csv b/services/execution/enclave/src/codon_usage_freq_table_human.csv |
| new file mode 100644 |
| index 0000000..4e49f4f |
| --- /dev/null |
| +++ b/services/execution/enclave/src/codon_usage_freq_table_human.csv |
| @@ -0,0 +1,65 @@ |
| +#,, |
| +UAA,*,0.28 |
| +UAG,*,0.2 |
| +UGA,*,0.52 |
| +GCU,A,0.26 |
| +GCC,A,0.4 |
| +GCA,A,0.23 |
| +GCG,A,0.11 |
| +UGU,C,0.45 |
| +UGC,C,0.55 |
| +GAU,D,0.46 |
| +GAC,D,0.54 |
| +GAA,E,0.42 |
| +GAG,E,0.58 |
| +UUU,F,0.45 |
| +UUC,F,0.55 |
| +GGU,G,0.16 |
| +GGC,G,0.34 |
| +GGA,G,0.25 |
| +GGG,G,0.25 |
| +CAU,H,0.41 |
| +CAC,H,0.59 |
| +AUU,I,0.36 |
| +AUC,I,0.48 |
| +AUA,I,0.16 |
| +AAA,K,0.42 |
| +AAG,K,0.58 |
| +UUA,L,0.07 |
| +UUG,L,0.13 |
| +CUU,L,0.13 |
| +CUC,L,0.2 |
| +CUA,L,0.07 |
| +CUG,L,0.41 |
| +AUG,M,1 |
| +AAU,N,0.46 |
| +AAC,N,0.54 |
| +CCU,P,0.28 |
| +CCC,P,0.33 |
| +CCA,P,0.27 |
| +CCG,P,0.11 |
| +CAA,Q,0.25 |
| +CAG,Q,0.75 |
| +CGU,R,0.08 |
| +CGC,R,0.19 |
| +CGA,R,0.11 |
| +CGG,R,0.21 |
| +AGA,R,0.2 |
| +AGG,R,0.2 |
| +UCU,S,0.18 |
| +UCC,S,0.22 |
| +UCA,S,0.15 |
| +UCG,S,0.06 |
| +AGU,S,0.15 |
| +AGC,S,0.24 |
| +ACU,T,0.24 |
| +ACC,T,0.36 |
| +ACA,T,0.28 |
| +ACG,T,0.12 |
| +GUU,V,0.18 |
| +GUC,V,0.24 |
| +GUA,V,0.11 |
| +GUG,V,0.47 |
| +UGG,W,1 |
| +UAU,Y,0.43 |
| +UAC,Y,0.57 |
| \ No newline at end of file |
| diff --git a/services/execution/enclave/src/lib.rs b/services/execution/enclave/src/lib.rs |
| index c422765..f012786 100644 |
| --- a/services/execution/enclave/src/lib.rs |
| +++ b/services/execution/enclave/src/lib.rs |
| @@ -129,6 +129,7 @@ pub mod tests { |
| service::tests::test_invoke_echo, |
| service::tests::test_invoke_gbdt_train, |
| task_file_manager::tests::test_input, |
| + task_file_manager::tests::test_placeholder, |
| ) |
| } |
| } |
| diff --git a/services/execution/enclave/src/service.rs b/services/execution/enclave/src/service.rs |
| index 0aa7515..af13087 100644 |
| --- a/services/execution/enclave/src/service.rs |
| +++ b/services/execution/enclave/src/service.rs |
| @@ -1,4 +1,5 @@ |
| // Licensed to the Apache Software Foundation (ASF) under one |
| +// 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 |
| @@ -15,25 +16,60 @@ |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| +use crate::task_file_manager::TaskFileManager; |
| use std::collections::HashMap; |
| use std::path::{Path, PathBuf}; |
| use std::prelude::v1::*; |
| use std::sync::mpsc; |
| use std::sync::{Arc, SgxMutex as Mutex}; |
| use std::thread; |
| - |
| -use crate::task_file_manager::TaskFileManager; |
| use teaclave_proto::teaclave_common::{ExecutorCommand, ExecutorStatus}; |
| use teaclave_proto::teaclave_scheduler_service::*; |
| use teaclave_rpc::endpoint::Endpoint; |
| use teaclave_types::*; |
| use teaclave_worker::Worker; |
| |
| -use anyhow::Result; |
| +use anyhow::{anyhow, Result}; |
| +use serde::{Deserialize, Serialize}; |
| +use std::ffi::OsStr; |
| +use std::os::unix::ffi::OsStrExt; |
| use uuid::Uuid; |
| |
| static WORKER_BASE_DIR: &str = "/tmp/teaclave_agent/"; |
| |
| +#[derive(Debug, Serialize, Deserialize, Clone)] |
| +struct Resource { |
| + name: String, |
| + path: String, |
| + content: Vec<u8>, |
| +} |
| + |
| +#[derive(Debug, Serialize, Deserialize, Clone)] |
| +struct Cpk { |
| + app_name: String, |
| + work_dir: String, |
| + wasm_payload: Vec<u8>, |
| + resource: Vec<Resource>, |
| +} |
| + |
| +impl Cpk { |
| + fn new_from_bytes(data: impl AsRef<[u8]>) -> anyhow::Result<Cpk> { |
| + bincode::deserialize(data.as_ref()).map_err(|_| anyhow!("Invalid cpk format!")) |
| + } |
| + |
| + fn has_resource(&self) -> bool { |
| + !self.resource.is_empty() |
| + } |
| + |
| + fn get_payload(&self) -> Vec<u8> { |
| + self.wasm_payload.clone() |
| + } |
| + |
| + fn get_resource(&self) -> Vec<Resource> { |
| + self.resource.clone() |
| + } |
| +} |
| + |
| #[derive(Clone)] |
| pub(crate) struct TeaclaveExecutionService { |
| worker: Arc<Worker>, |
| @@ -77,7 +113,7 @@ impl TeaclaveExecutionService { |
| let mut task_handle: Option<thread::JoinHandle<()>> = None; |
| |
| loop { |
| - std::thread::sleep(std::time::Duration::from_secs(3)); |
| + std::thread::sleep(std::time::Duration::from_secs(1)); |
| |
| match self.heartbeat() { |
| Ok(ExecutorCommand::Stop) => { |
| @@ -119,18 +155,18 @@ impl TeaclaveExecutionService { |
| Ok(result) => { |
| let task_unwrapped = current_task.as_ref().as_ref().unwrap(); |
| match result { |
| - Ok(_) => log::debug!( |
| - "InvokeTask: {:?}, {:?}, success", |
| - task_unwrapped.task_id, |
| + Ok(_) => log::info!( |
| + "[MONITOR] InvokeTask: {:?}, {:?}, success", |
| + task_unwrapped.user_id, |
| task_unwrapped.function_id |
| ), |
| - Err(_) => log::debug!( |
| - "InvokeTask: {:?}, {:?}, failure", |
| - task_unwrapped.task_id, |
| + Err(_) => log::info!( |
| + "[MONITOR] InvokeTask: {:?}, {:?}, failure", |
| + task_unwrapped.user_id, |
| task_unwrapped.function_id |
| ), |
| } |
| - log::debug!("InvokeTask result: {:?}", result); |
| + log::info!("InvokeTask result: {:?}", result); |
| let task_copy = current_task.clone(); |
| match self |
| .update_task_result(&task_copy.as_ref().as_ref().unwrap().task_id, result) |
| @@ -169,7 +205,7 @@ impl TeaclaveExecutionService { |
| .map_err(|_| anyhow::anyhow!("Cannot lock scheduler client"))? |
| .pull_task(request)?; |
| |
| - log::debug!("pull_stask response: {:?}", response); |
| + log::info!("pull_stask response: {:?}", response); |
| Ok(response.staged_task) |
| } |
| |
| @@ -229,7 +265,7 @@ fn invoke_task(task: &StagedTask, fusion_base: &PathBuf) -> Result<TaskOutputs> |
| )?; |
| let invocation = prepare_task(&task, &file_mgr)?; |
| |
| - log::debug!("Invoke function: {:?}", invocation); |
| + log::info!("Invoke function: {:?}", invocation); |
| let worker = Worker::default(); |
| let summary = worker.invoke_function(invocation)?; |
| |
| @@ -239,15 +275,84 @@ fn invoke_task(task: &StagedTask, fusion_base: &PathBuf) -> Result<TaskOutputs> |
| } |
| |
| fn prepare_task(task: &StagedTask, file_mgr: &TaskFileManager) -> Result<StagedFunction> { |
| - let input_files = file_mgr.prepare_staged_inputs()?; |
| + let mut input_files = file_mgr.prepare_staged_inputs()?; |
| let output_files = file_mgr.prepare_staged_outputs()?; |
| + log::info!("before loading: staged_task:{:?}", task); |
| + |
| + // offload |
| + let function_payload = if !task.function_payload.is_empty() { |
| + let offload_info = OsStr::from_bytes(task.function_payload.as_slice()); |
| + let offload_path = PathBuf::from(offload_info); |
| + log::info!("offload_path: {:?}", offload_path); |
| + let function_payload = std::untrusted::fs::read(&offload_path)?; |
| + log::info!( |
| + "reload function_payload, size =: {:?}", |
| + function_payload.len() |
| + ); |
| + function_payload |
| + } else { |
| + task.function_payload.clone() |
| + }; |
| + |
| + if task.executor_type == ExecutorType::CleanroomRuntime { |
| + let new_cpk = &Cpk::new_from_bytes(&function_payload)?; |
| + let wasm_payload = new_cpk.get_payload(); |
| + let mut arguments = task.function_arguments.clone(); |
| + if new_cpk.has_resource() { |
| + let work_dir = new_cpk.work_dir.to_owned(); |
| + let resource = new_cpk.get_resource(); |
| + for r in resource { |
| + let full_path = &r.path.to_owned(); |
| + let content = r.content; |
| + let fileinfo: StagedFileInfo = |
| + StagedFileInfo::create_with_bytes(full_path, &content)?; |
| + input_files.insert(full_path, fileinfo); |
| + } |
| |
| + // Adding working directory |
| + let args_vec = arguments.into_vec(); |
| + let mut args = HashMap::new(); |
| + args.insert(args_vec[0].to_owned(), args_vec[1].to_owned()); |
| + args.insert("wdir".to_string(), work_dir); |
| + arguments = FunctionArguments::from(args); |
| + } |
| + let staged_function = StagedFunctionBuilder::new() |
| + .executor_type(task.executor_type) |
| + .executor(task.executor) |
| + .name(&task.function_name) |
| + .arguments(arguments) |
| + .payload(wasm_payload) |
| + .input_files(input_files) |
| + .output_files(output_files) |
| + .runtime_name("default") |
| + .build(); |
| + return Ok(staged_function); |
| + } |
| + |
| + if task.executor_type == ExecutorType::Builtin |
| + && task |
| + .function_name |
| + .contains("builtin-cleanroom-algorithm2-hash") |
| + { |
| + let csv_data = include_bytes!("./codon_usage_freq_table_human.csv"); |
| + let coding_wheel_data = include_bytes!("./coding_wheel.txt"); |
| + if !input_files.contain("coding_wheel.txt") { |
| + let fileinfo: StagedFileInfo = |
| + StagedFileInfo::create_with_bytes("coding_wheel.txt", coding_wheel_data)?; |
| + input_files.insert("coding_wheel.txt", fileinfo); |
| + } |
| + if !input_files.contain("codon_usage_freq_table_human.csv") { |
| + let fileinfo: StagedFileInfo = |
| + StagedFileInfo::create_with_bytes("codon_usage_freq_table_human.csv", csv_data)?; |
| + input_files.insert("codon_usage_freq_table_human.csv", fileinfo); |
| + } |
| + } |
| let staged_function = StagedFunctionBuilder::new() |
| .executor_type(task.executor_type) |
| .executor(task.executor) |
| .name(&task.function_name) |
| .arguments(task.function_arguments.clone()) |
| - .payload(task.function_payload.clone()) |
| + .payload(function_payload) |
| .input_files(input_files) |
| .output_files(output_files) |
| .runtime_name("default") |
| diff --git a/services/execution/enclave/src/task_file_manager.rs b/services/execution/enclave/src/task_file_manager.rs |
| index ea71c2b..17235a3 100644 |
| --- a/services/execution/enclave/src/task_file_manager.rs |
| +++ b/services/execution/enclave/src/task_file_manager.rs |
| @@ -66,8 +66,9 @@ impl TaskFileManager { |
| let cwd = Path::new(inter_base.as_ref()).join(task_id.to_string()); |
| let inputs_base = cwd.join("inputs"); |
| let outputs_base = cwd.join("outputs"); |
| - |
| - let inter_inputs = InterInputs::new(&inputs_base, inputs.clone())?; |
| + let mut inputs_tmp = inputs.clone(); |
| + inputs_tmp.placeholder_filter(); |
| + let inter_inputs = InterInputs::new(&inputs_base, inputs_tmp)?; |
| let inter_outputs = InterOutputs::new(&outputs_base, outputs.clone())?; |
| |
| let tfmgr = TaskFileManager { |
| @@ -94,6 +95,16 @@ impl TaskFileManager { |
| self.inter_outputs.upload(&self.fusion_base)?; |
| Ok(auth_tags) |
| } |
| + |
| + #[allow(dead_code)] |
| + pub(crate) fn inputs_num(&self) -> usize { |
| + self.inter_inputs.len() |
| + } |
| + |
| + #[allow(dead_code)] |
| + pub(crate) fn outputs_num(&self) -> usize { |
| + self.inter_outputs.len() |
| + } |
| } |
| |
| impl InterInput { |
| @@ -195,6 +206,11 @@ impl InterInputs { |
| .map(|inter_file| inter_file.to_staged_file_entry()) |
| .collect() |
| } |
| + |
| + #[allow(dead_code)] |
| + pub(crate) fn len(&self) -> usize { |
| + self.inner.len() |
| + } |
| } |
| |
| impl std::iter::FromIterator<InterOutput> for InterOutputs { |
| @@ -277,6 +293,11 @@ impl InterOutputs { |
| handle_file_request(request)?; |
| Ok(()) |
| } |
| + |
| + #[allow(dead_code)] |
| + pub(crate) fn len(&self) -> usize { |
| + self.inner.len() |
| + } |
| } |
| |
| // Staged file is put in $base_dir/${funiq_key}-staged/$original_name |
| @@ -356,4 +377,41 @@ pub mod tests { |
| .unwrap(); |
| file_mgr.upload_outputs().unwrap(); |
| } |
| + |
| + pub fn test_placeholder() { |
| + let key = [0; 16]; |
| + let iv = [1; 12]; |
| + let crypto = AesGcm128Key::new(&key, &iv).unwrap(); |
| + let input_url = |
| + Url::parse("http://localhost:6789/fixtures/functions/gbdt_training/train.aes_gcm_128") |
| + .unwrap(); |
| + let tag = FileAuthTag::from_hex("592f1e607649d89ff2aa8a2841a57cad").unwrap(); |
| + let input_file = FunctionInputFile::new(input_url, tag, crypto); |
| + |
| + let placeholder_url = Url::parse( |
| + "placeholder://localhost:6789/fixtures/functions/gbdt_training/train.aes_gcm_128", |
| + ) |
| + .unwrap(); |
| + let tag = FileAuthTag::from_hex("592f1e607649d89ff2aa8a2841a57cad").unwrap(); |
| + let placeholder_file = FunctionInputFile::new(placeholder_url, tag, crypto); |
| + let inputs = hashmap!("training_data" => input_file, "placeholder" => placeholder_file); |
| + let outputs = hashmap!(); |
| + let task_id = Uuid::new_v4(); |
| + |
| + let file_mgr = TaskFileManager::new( |
| + "/tmp", |
| + "/tmp/fusion_base", |
| + &task_id, |
| + &inputs.into(), |
| + &outputs.into(), |
| + ) |
| + .unwrap(); |
| + file_mgr.prepare_staged_inputs().unwrap(); |
| + file_mgr.prepare_staged_outputs().unwrap(); |
| + |
| + let inputs_num = file_mgr.inputs_num(); |
| + let outputs_num = file_mgr.outputs_num(); |
| + assert!(inputs_num == 1); |
| + assert!(outputs_num == 0); |
| + } |
| } |
| diff --git a/services/frontend/app/Cargo.toml b/services/frontend/app/Cargo.toml |
| index 3b84e6b..517bca0 100644 |
| --- a/services/frontend/app/Cargo.toml |
| +++ b/services/frontend/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_frontend_service" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Frontend Service" |
| license = "Apache-2.0" |
| diff --git a/services/frontend/enclave/Cargo.toml b/services/frontend/enclave/Cargo.toml |
| index 116852a..f342803 100644 |
| --- a/services/frontend/enclave/Cargo.toml |
| +++ b/services/frontend/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_frontend_service_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Frontend Service enclave" |
| license = "Apache-2.0" |
| @@ -46,7 +46,7 @@ enclave_unit_test = ["teaclave_binder/enclave_unit_test", "teaclave_test_utils/m |
| [dependencies] |
| anyhow = { version = "1.0.26" } |
| cfg-if = { version = "0.1.9" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| serde = { version = "1.0.92" } |
| serde_json = { version = "1.0.39" } |
| thiserror = { version = "1.0.9" } |
| diff --git a/services/frontend/enclave/src/service.rs b/services/frontend/enclave/src/service.rs |
| index 9f7a34c..83176ba 100644 |
| --- a/services/frontend/enclave/src/service.rs |
| +++ b/services/frontend/enclave/src/service.rs |
| @@ -32,15 +32,15 @@ use teaclave_proto::teaclave_frontend_service::{ |
| ApproveTaskRequest, ApproveTaskResponse, AssignDataRequest, AssignDataResponse, |
| CancelTaskRequest, CancelTaskResponse, CreateTaskRequest, CreateTaskResponse, |
| DeleteFunctionRequest, DeleteFunctionResponse, DisableFunctionRequest, DisableFunctionResponse, |
| - GetFunctionRequest, GetFunctionResponse, GetInputFileRequest, GetInputFileResponse, |
| - GetOutputFileRequest, GetOutputFileResponse, GetTaskRequest, GetTaskResponse, |
| - InvokeTaskRequest, InvokeTaskResponse, ListFunctionsRequest, ListFunctionsResponse, |
| - RegisterFunctionRequest, RegisterFunctionResponse, RegisterFusionOutputRequest, |
| - RegisterFusionOutputResponse, RegisterInputFileRequest, RegisterInputFileResponse, |
| - RegisterInputFromOutputRequest, RegisterInputFromOutputResponse, RegisterOutputFileRequest, |
| - RegisterOutputFileResponse, TeaclaveFrontend, UpdateFunctionRequest, UpdateFunctionResponse, |
| - UpdateInputFileRequest, UpdateInputFileResponse, UpdateOutputFileRequest, |
| - UpdateOutputFileResponse, |
| + GetFunctionRequest, GetFunctionResponse, GetFunctionUsageStatsRequest, |
| + GetFunctionUsageStatsResponse, GetInputFileRequest, GetInputFileResponse, GetOutputFileRequest, |
| + GetOutputFileResponse, GetTaskRequest, GetTaskResponse, InvokeTaskRequest, InvokeTaskResponse, |
| + ListFunctionsRequest, ListFunctionsResponse, RegisterFunctionRequest, RegisterFunctionResponse, |
| + RegisterFusionOutputRequest, RegisterFusionOutputResponse, RegisterInputFileRequest, |
| + RegisterInputFileResponse, RegisterInputFromOutputRequest, RegisterInputFromOutputResponse, |
| + RegisterOutputFileRequest, RegisterOutputFileResponse, TeaclaveFrontend, UpdateFunctionRequest, |
| + UpdateFunctionResponse, UpdateInputFileRequest, UpdateInputFileResponse, |
| + UpdateOutputFileRequest, UpdateOutputFileResponse, |
| }; |
| use teaclave_proto::teaclave_management_service::TeaclaveManagementClient; |
| use teaclave_rpc::endpoint::Endpoint; |
| @@ -109,6 +109,7 @@ enum Endpoints { |
| GetInputFile, |
| RegisterFunction, |
| GetFunction, |
| + GetFunctionUsageStats, |
| UpdateFunction, |
| ListFunctions, |
| DeleteFunction, |
| @@ -150,7 +151,7 @@ fn authorize(claims: &UserAuthClaims, request: Endpoints) -> bool { |
| | Endpoints::ApproveTask |
| | Endpoints::InvokeTask |
| | Endpoints::CancelTask => role.is_data_owner(), |
| - Endpoints::GetFunction | Endpoints::ListFunctions => { |
| + Endpoints::GetFunctionUsageStats | Endpoints::GetFunction | Endpoints::ListFunctions => { |
| role.is_function_owner() || role.is_data_owner() |
| } |
| } |
| @@ -332,6 +333,18 @@ impl TeaclaveFrontend for TeaclaveFrontendService { |
| ) |
| } |
| |
| + fn get_function_usage_stats( |
| + &self, |
| + request: Request<GetFunctionUsageStatsRequest>, |
| + ) -> TeaclaveServiceResponseResult<GetFunctionUsageStatsResponse> { |
| + authentication_and_forward_to_management!( |
| + self, |
| + request, |
| + get_function_usage_stats, |
| + Endpoints::GetFunctionUsageStats |
| + ) |
| + } |
| + |
| fn delete_function( |
| &self, |
| request: Request<DeleteFunctionRequest>, |
| diff --git a/services/management/app/Cargo.toml b/services/management/app/Cargo.toml |
| index 6484f79..15524cc 100644 |
| --- a/services/management/app/Cargo.toml |
| +++ b/services/management/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_management_service" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Management Service" |
| license = "Apache-2.0" |
| diff --git a/services/management/enclave/Cargo.toml b/services/management/enclave/Cargo.toml |
| index a4bb4ea..cabec59 100644 |
| --- a/services/management/enclave/Cargo.toml |
| +++ b/services/management/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_management_service_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Management Service enclave" |
| license = "Apache-2.0" |
| @@ -46,7 +46,7 @@ enclave_unit_test = ["teaclave_binder/enclave_unit_test", "teaclave_test_utils/m |
| [dependencies] |
| anyhow = { version = "1.0.26" } |
| cfg-if = { version = "0.1.9" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| serde = { version = "1.0.92" } |
| serde_json = { version = "1.0.39" } |
| thiserror = { version = "1.0.9" } |
| @@ -54,6 +54,7 @@ ring = { version = "0.16.5" } |
| rand = { version = "0.7.0" } |
| uuid = { version = "0.8.1", features = ["v4"] } |
| url = { version = "2.1.1", features = ["serde"]} |
| +chrono = { version = "0.4.6" } |
| |
| teaclave_attestation = { path = "../../../attestation" } |
| teaclave_config = { path = "../../../config" } |
| diff --git a/services/management/enclave/src/error.rs b/services/management/enclave/src/error.rs |
| index 952fa30..c7cea37 100644 |
| --- a/services/management/enclave/src/error.rs |
| +++ b/services/management/enclave/src/error.rs |
| @@ -39,14 +39,14 @@ pub(crate) enum ManagementServiceError { |
| InvalidTaskId, |
| #[error("invalid task")] |
| InvalidTask, |
| - #[error("failed to assign data to task")] |
| - TaskAssignDataError, |
| - #[error("failed to approve task")] |
| - TaskApproveError, |
| - #[error("failed to invoke task")] |
| - TaskInvokeError, |
| - #[error("failed to cancel task, reason: {0}")] |
| - TaskCancelError(String), |
| + #[error("failed to change task state")] |
| + TaskStateError, |
| + #[error("failed to offload the payload")] |
| + OffloadError, |
| + #[error("Fusion base directory is not mounted or Offload base directory is not mounted")] |
| + ConfigError, |
| + #[error("quota has been used up")] |
| + QuotaError, |
| } |
| |
| impl From<ManagementServiceError> for TeaclaveServiceResponseError { |
| diff --git a/services/management/enclave/src/lib.rs b/services/management/enclave/src/lib.rs |
| index 45ee3ba..b94aa88 100644 |
| --- a/services/management/enclave/src/lib.rs |
| +++ b/services/management/enclave/src/lib.rs |
| @@ -22,10 +22,12 @@ extern crate sgx_tstd as std; |
| |
| #[macro_use] |
| extern crate log; |
| -use anyhow::{anyhow, Result}; |
| +use anyhow::{anyhow, bail, Result}; |
| |
| use std::prelude::v1::*; |
| +use std::untrusted::path::PathEx; |
| |
| +use crate::error::ManagementServiceError; |
| use teaclave_attestation::{verifier, AttestationConfig, RemoteAttestation}; |
| use teaclave_binder::proto::{ |
| ECallCommand, FinalizeEnclaveInput, FinalizeEnclaveOutput, InitEnclaveInput, InitEnclaveOutput, |
| @@ -94,7 +96,33 @@ fn start_service(config: &RuntimeConfig) -> Result<()> { |
| |
| info!(" Starting Management: setup storage endpoint finished ..."); |
| |
| - let service = service::TeaclaveManagementService::new(storage_service_endpoint)?; |
| + let fusion_base = config.mount.fusion_base_dir.as_path(); |
| + |
| + // We only create this base directory in test_mode |
| + // This directory should be mounted in release mode |
| + #[cfg(test_mode)] |
| + std::untrusted::fs::create_dir_all(&fusion_base)?; |
| + |
| + if !fusion_base.exists() { |
| + log::error!( |
| + " Starting Management: Fusion base directory is not mounted: {}", |
| + fusion_base.display() |
| + ); |
| + bail!(ManagementServiceError::ConfigError); |
| + } |
| + |
| + let offload_base = fusion_base.join("functions"); |
| + std::untrusted::fs::create_dir_all(&offload_base)?; |
| + |
| + if !offload_base.exists() { |
| + log::error!( |
| + " Starting Management: Offload base directory is not mounted: {}", |
| + offload_base.display() |
| + ); |
| + bail!(ManagementServiceError::ConfigError); |
| + } |
| + |
| + let service = service::TeaclaveManagementService::new(storage_service_endpoint, offload_base)?; |
| |
| info!(" Starting Management: start listening ..."); |
| match server.start(service) { |
| diff --git a/services/management/enclave/src/service.rs b/services/management/enclave/src/service.rs |
| index a69124b..790067a 100644 |
| --- a/services/management/enclave/src/service.rs |
| +++ b/services/management/enclave/src/service.rs |
| @@ -17,22 +17,28 @@ |
| |
| use crate::error::ManagementServiceError; |
| use anyhow::anyhow; |
| +use chrono::{DateTime, NaiveDateTime}; |
| use std::convert::TryInto; |
| +use std::os::unix::ffi::OsStrExt; |
| +use std::path::{Path, PathBuf}; |
| use std::prelude::v1::*; |
| use std::sync::{Arc, SgxMutex as Mutex}; |
| +use std::time::SystemTime; |
| +#[cfg(feature = "mesalock_sgx")] |
| +use std::untrusted::time::SystemTimeEx; |
| use teaclave_proto::teaclave_frontend_service::{ |
| ApproveTaskRequest, ApproveTaskResponse, AssignDataRequest, AssignDataResponse, |
| CancelTaskRequest, CancelTaskResponse, CreateTaskRequest, CreateTaskResponse, |
| DeleteFunctionRequest, DeleteFunctionResponse, DisableFunctionRequest, DisableFunctionResponse, |
| - GetFunctionRequest, GetFunctionResponse, GetInputFileRequest, GetInputFileResponse, |
| - GetOutputFileRequest, GetOutputFileResponse, GetTaskRequest, GetTaskResponse, |
| - InvokeTaskRequest, InvokeTaskResponse, ListFunctionsRequest, ListFunctionsResponse, |
| - RegisterFunctionRequest, RegisterFunctionResponse, RegisterFusionOutputRequest, |
| - RegisterFusionOutputResponse, RegisterInputFileRequest, RegisterInputFileResponse, |
| - RegisterInputFromOutputRequest, RegisterInputFromOutputResponse, RegisterOutputFileRequest, |
| - RegisterOutputFileResponse, UpdateFunctionRequest, UpdateFunctionResponse, |
| - UpdateInputFileRequest, UpdateInputFileResponse, UpdateOutputFileRequest, |
| - UpdateOutputFileResponse, |
| + GetFunctionRequest, GetFunctionResponse, GetFunctionUsageStatsRequest, |
| + GetFunctionUsageStatsResponse, GetInputFileRequest, GetInputFileResponse, GetOutputFileRequest, |
| + GetOutputFileResponse, GetTaskRequest, GetTaskResponse, InvokeTaskRequest, InvokeTaskResponse, |
| + ListFunctionsRequest, ListFunctionsResponse, RegisterFunctionRequest, RegisterFunctionResponse, |
| + RegisterFusionOutputRequest, RegisterFusionOutputResponse, RegisterInputFileRequest, |
| + RegisterInputFileResponse, RegisterInputFromOutputRequest, RegisterInputFromOutputResponse, |
| + RegisterOutputFileRequest, RegisterOutputFileResponse, UpdateFunctionRequest, |
| + UpdateFunctionResponse, UpdateInputFileRequest, UpdateInputFileResponse, |
| + UpdateOutputFileRequest, UpdateOutputFileResponse, |
| }; |
| use teaclave_proto::teaclave_management_service::TeaclaveManagement; |
| use teaclave_proto::teaclave_storage_service::{ |
| @@ -54,6 +60,7 @@ use uuid::Uuid; |
| #[derive(Clone)] |
| pub(crate) struct TeaclaveManagementService { |
| storage_client: Arc<Mutex<TeaclaveStorageClient>>, |
| + offload_base: PathBuf, |
| } |
| |
| impl TeaclaveManagement for TeaclaveManagementService { |
| @@ -250,11 +257,41 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| ) -> TeaclaveServiceResponseResult<RegisterFunctionResponse> { |
| let user_id = get_request_user_id(&request)?; |
| |
| - let function = FunctionBuilder::from(request.message) |
| + let mut function = FunctionBuilder::from(request.message) |
| .id(Uuid::new_v4()) |
| .owner(user_id.clone()) |
| .build(); |
| |
| + let offload_name = format!("{}.func", function.uuid().to_string()); |
| + let offload_path = self.offload_base.join(&offload_name); |
| + log::info!("offload_path: {:?}", offload_path); |
| + |
| + //let offload_url = format!("fusion:///TEACLAVE_FUSION_BASE/functions/{}", &offload_name); |
| + //log::info!("offload_url: {:?}", offload_url); |
| + |
| + // Ensure the function expiration date is valid |
| + if function.expiration_date.expired { |
| + let _expired_date = NaiveDateTime::from_timestamp_opt( |
| + function.expiration_date.seconds, |
| + function.expiration_date.nanos as u32, |
| + ) |
| + .ok_or_else(|| anyhow!("Invalid date"))?; |
| + } |
| + |
| + log::info!( |
| + "[MONITOR] Register Function: {:?}, Expired: {:?}, Seconds: {:?}, Nanos: {:?}", |
| + &function.id, |
| + function.expiration_date.expired, |
| + function.expiration_date.seconds, |
| + function.expiration_date.nanos, |
| + ); |
| + |
| + std::untrusted::fs::write(&offload_path, function.payload) |
| + .map_err(|_| ManagementServiceError::OffloadError)?; |
| + |
| + function.payload = offload_path.as_os_str().as_bytes().to_vec(); |
| + log::info!("function payload offloaded: {:?}", function); |
| + log::info!("function key: {:?}", &function.key()); |
| self.write_to_db(&function)?; |
| |
| let mut u = User::default(); |
| @@ -486,25 +523,86 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| } |
| } |
| |
| + fn get_function_usage_stats( |
| + &self, |
| + request: Request<GetFunctionUsageStatsRequest>, |
| + ) -> TeaclaveServiceResponseResult<GetFunctionUsageStatsResponse> { |
| + let user_id = get_request_user_id(&request)?; |
| + let role = get_request_role(&request)?; |
| + let request = request.message; |
| + let function: Function = self |
| + .read_from_db(&request.function_id) |
| + .map_err(|_| ManagementServiceError::InvalidFunctionId)?; |
| + let mut request_group_id = user_id.to_string(); |
| + if let UserRole::DataOwner(s) = &role { |
| + request_group_id = s.into(); |
| + } |
| + match role { |
| + UserRole::DataOwner(a) | UserRole::DataOwnerManager(a) => { |
| + ensure!( |
| + (function.public || function.user_allowlist.contains(&a)), |
| + ManagementServiceError::PermissionDenied |
| + ); |
| + } |
| + UserRole::PlatformAdmin => (), |
| + _ => { |
| + return Err(ManagementServiceError::PermissionDenied.into()); |
| + } |
| + } |
| + let mut u = FunctionUsage::default(); |
| + u.function_id = function.id; |
| + u.group_name = request_group_id; |
| + u.use_numbers = 0; |
| + let external_id = u.external_id(); |
| + let function_usage = self.read_from_db::<FunctionUsage>(&external_id); |
| + let function_current_use_numbers; |
| + match function_usage { |
| + Ok(usage) => { |
| + function_current_use_numbers = usage.use_numbers; |
| + } |
| + Err(_) => { |
| + function_current_use_numbers = 0; |
| + } |
| + } |
| + let function_quota = function.usage_quota; |
| + let response = GetFunctionUsageStatsResponse { |
| + function_quota, |
| + current_usage: function_current_use_numbers, |
| + }; |
| + Ok(response) |
| + } |
| + |
| // access control: none |
| // when a task is created, following rules will be verified: |
| // 1) arugments match function definition |
| // 2) input files match function definition |
| // 3) output files match function definition |
| // 4) requested user_id in the user_allowlist |
| + // 5) if the function |
| fn create_task( |
| &self, |
| request: Request<CreateTaskRequest>, |
| ) -> TeaclaveServiceResponseResult<CreateTaskResponse> { |
| let user_id = get_request_user_id(&request)?; |
| let role = get_request_role(&request)?; |
| - |
| let request = request.message; |
| |
| let function: Function = self |
| .read_from_db(&request.function_id) |
| .map_err(|_| ManagementServiceError::InvalidFunctionId)?; |
| |
| + if function.expiration_date.expired { |
| + let now = DateTime::<chrono::offset::Utc>::from(SystemTime::now()) |
| + .naive_local() |
| + .date(); |
| + let expired_date = NaiveDateTime::from_timestamp_opt( |
| + function.expiration_date.seconds, |
| + function.expiration_date.nanos as u32, |
| + ) |
| + .ok_or_else(|| anyhow!("Invalid date"))?; |
| + ensure!((now <= expired_date.date()), anyhow!("function expired")); |
| + } |
| + |
| match role { |
| UserRole::DataOwner(a) | UserRole::DataOwnerManager(a) => { |
| ensure!( |
| @@ -526,11 +624,9 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| function, |
| ) |
| .map_err(|_| ManagementServiceError::InvalidTask)?; |
| - |
| - log::debug!("CreateTask: {:?}", task); |
| + log::info!("CreateTask: {:?}", task); |
| let ts: TaskState = task.into(); |
| self.write_to_db(&ts)?; |
| - |
| let response = CreateTaskResponse::new(ts.external_id()); |
| Ok(response) |
| } |
| @@ -600,7 +696,7 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| |
| let mut task: Task<Assign> = ts.try_into().map_err(|e| { |
| log::warn!("Assign state error: {:?}", e); |
| - ManagementServiceError::TaskAssignDataError |
| + ManagementServiceError::TaskStateError |
| })?; |
| |
| for (data_name, data_id) in request.inputs.iter() { |
| @@ -643,13 +739,13 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| |
| let mut task: Task<Approve> = ts.try_into().map_err(|e| { |
| log::warn!("Approve state error: {:?}", e); |
| - ManagementServiceError::TaskApproveError |
| + ManagementServiceError::TaskStateError |
| })?; |
| |
| task.approve(&user_id) |
| .map_err(|_| ManagementServiceError::PermissionDenied)?; |
| |
| - log::debug!("ApproveTask: approve:{:?}", task); |
| + log::info!("ApproveTask: approve:{:?}", task); |
| |
| let ts: TaskState = task.into(); |
| self.write_to_db(&ts)?; |
| @@ -665,7 +761,12 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| request: Request<InvokeTaskRequest>, |
| ) -> TeaclaveServiceResponseResult<InvokeTaskResponse> { |
| let user_id = get_request_user_id(&request)?; |
| + let role = get_request_role(&request)?; |
| let request = request.message; |
| + let mut request_group_id = user_id.to_string(); |
| + if let UserRole::DataOwner(s) = &role { |
| + request_group_id = s.into(); |
| + } |
| |
| let ts: TaskState = self |
| .read_from_db(&request.task_id) |
| @@ -683,9 +784,46 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| |
| log::debug!("InvokeTask: get function: {:?}", function); |
| |
| + let mut u = FunctionUsage::default(); |
| + u.function_id = function.id; |
| + u.group_name = request_group_id; |
| + u.use_numbers = 0; |
| + let external_id = u.external_id(); |
| + let function_usage = self.read_from_db::<FunctionUsage>(&external_id); |
| + let function_current_use_numbers; |
| + match function_usage { |
| + Ok(usage) => { |
| + function_current_use_numbers = usage.use_numbers; |
| + } |
| + Err(_) => { |
| + function_current_use_numbers = 0; |
| + } |
| + } |
| + match role { |
| + UserRole::DataOwner(a) | UserRole::DataOwnerManager(a) => { |
| + log::info!( |
| + "[MONITOR] Invoke Task: Function: {:?}, User ID: {:?}, User group: {:?}, Total quota: {:?}, Used quota: {:?}", |
| + &function.id, |
| + &user_id, |
| + &a, |
| + function.usage_quota, |
| + function_current_use_numbers, |
| + ); |
| + if (function.usage_quota <= function_current_use_numbers) |
| + && (function.usage_quota > 0) |
| + { |
| + return Err(ManagementServiceError::QuotaError.into()); |
| + } |
| + } |
| + UserRole::PlatformAdmin => (), |
| + _ => { |
| + return Err(ManagementServiceError::PermissionDenied.into()); |
| + } |
| + } |
| + |
| let mut task: Task<Stage> = ts.try_into().map_err(|e| { |
| log::warn!("Stage state error: {:?}", e); |
| - ManagementServiceError::TaskInvokeError |
| + ManagementServiceError::TaskStateError |
| })?; |
| |
| log::debug!("InvokeTask: get task: {:?}", task); |
| @@ -697,7 +835,8 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| |
| let ts: TaskState = task.into(); |
| self.write_to_db(&ts)?; |
| - |
| + u.use_numbers = function_current_use_numbers + 1; |
| + self.write_to_db(&u)?; |
| Ok(InvokeTaskResponse) |
| } |
| |
| @@ -736,9 +875,7 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| // race will not affect correctness/privacy |
| let mut task: Task<Cancel> = ts.try_into().map_err(|e| { |
| log::warn!("Cancel state error: {:?}", e); |
| - ManagementServiceError::TaskCancelError( |
| - "task has already been canceled".to_string(), |
| - ) |
| + ManagementServiceError::TaskStateError |
| })?; |
| |
| log::debug!("Canceled Task: {:?}", task); |
| @@ -746,9 +883,7 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| task.update_result(TaskResult::Err(TaskFailure { |
| reason: "Task canceled".to_string(), |
| })) |
| - .map_err(|_| { |
| - ManagementServiceError::TaskCancelError("cannot update result".to_string()) |
| - })?; |
| + .map_err(|_| ManagementServiceError::TaskStateError)?; |
| let ts: TaskState = task.into(); |
| self.write_to_db(&ts)?; |
| |
| @@ -761,7 +896,10 @@ impl TeaclaveManagement for TeaclaveManagementService { |
| } |
| |
| impl TeaclaveManagementService { |
| - pub(crate) fn new(storage_service_endpoint: Endpoint) -> anyhow::Result<Self> { |
| + pub(crate) fn new( |
| + storage_service_endpoint: Endpoint, |
| + offload_base: impl AsRef<Path>, |
| + ) -> anyhow::Result<Self> { |
| let mut i = 0; |
| let channel = loop { |
| match storage_service_endpoint.connect() { |
| @@ -775,7 +913,10 @@ impl TeaclaveManagementService { |
| std::thread::sleep(std::time::Duration::from_secs(3)); |
| }; |
| let storage_client = Arc::new(Mutex::new(TeaclaveStorageClient::new(channel)?)); |
| - let service = Self { storage_client }; |
| + let service = Self { |
| + storage_client, |
| + offload_base: offload_base.as_ref().to_owned(), |
| + }; |
| |
| #[cfg(test_mode)] |
| service.add_mock_data()?; |
| @@ -882,6 +1023,8 @@ impl TeaclaveManagementService { |
| let function_output = FunctionOutput::new("output", "output_desc", false); |
| let function_input2 = FunctionInput::new("input2", "input_desc", false); |
| let function_output2 = FunctionOutput::new("output2", "output_desc", false); |
| + let function_arg1 = FunctionArgument::new("arg1", "", true); |
| + let function_arg2 = FunctionArgument::new("arg2", "", true); |
| |
| let function = FunctionBuilder::new() |
| .id(Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap()) |
| @@ -889,13 +1032,15 @@ impl TeaclaveManagementService { |
| .description("mock-desc") |
| .payload(b"mock-payload".to_vec()) |
| .public(true) |
| - .arguments(vec!["arg1".to_string(), "arg2".to_string()]) |
| + .arguments(vec![function_arg1, function_arg2]) |
| .inputs(vec![function_input, function_input2]) |
| .outputs(vec![function_output, function_output2]) |
| .owner("teaclave".to_string()) |
| + .usage_quota(-1) |
| .build(); |
| |
| self.write_to_db(&function)?; |
| + let function_arg1 = FunctionArgument::new("arg1", "", true); |
| |
| let function_output = FunctionOutput::new("output", "output_desc", false); |
| let function = FunctionBuilder::new() |
| @@ -904,12 +1049,14 @@ impl TeaclaveManagementService { |
| .description("mock-desc") |
| .payload(b"mock-payload".to_vec()) |
| .public(true) |
| - .arguments(vec!["arg1".to_string()]) |
| + .arguments(vec![function_arg1]) |
| .outputs(vec![function_output]) |
| .owner("teaclave".to_string()) |
| + .usage_quota(-1) |
| .build(); |
| |
| self.write_to_db(&function)?; |
| + let function_arg1 = FunctionArgument::new("arg1", "", true); |
| |
| let function = FunctionBuilder::new() |
| .id(Uuid::parse_str("00000000-0000-0000-0000-000000000003").unwrap()) |
| @@ -917,9 +1064,10 @@ impl TeaclaveManagementService { |
| .description("Private mock function") |
| .payload(b"mock-payload".to_vec()) |
| .public(false) |
| - .arguments(vec!["arg1".to_string()]) |
| + .arguments(vec![function_arg1]) |
| .owner("mock_user".to_string()) |
| .user_allowlist(vec!["mock_user".to_string(), "mock_user1".to_string()]) |
| + .usage_quota(-1) |
| .build(); |
| |
| self.write_to_db(&function)?; |
| @@ -986,16 +1134,18 @@ pub mod tests { |
| pub fn handle_function() { |
| let function_input = FunctionInput::new("input", "input_desc", false); |
| let function_output = FunctionOutput::new("output", "output_desc", false); |
| + let function_arg = FunctionArgument::new("arg", "", true); |
| let function = FunctionBuilder::new() |
| .id(Uuid::new_v4()) |
| .name("mock_function") |
| .description("mock function") |
| .payload(b"python script".to_vec()) |
| - .arguments(vec!["arg".to_string()]) |
| + .arguments(vec![function_arg]) |
| .inputs(vec![function_input]) |
| .outputs(vec![function_output]) |
| .public(true) |
| .owner("mock_user") |
| + .usage_quota(-1) |
| .build(); |
| assert!(Function::match_prefix(&function.key_string())); |
| let value = function.to_vec().unwrap(); |
| @@ -1004,14 +1154,16 @@ pub mod tests { |
| } |
| |
| pub fn handle_task() { |
| + let function_arg = FunctionArgument::new("arg", "", true); |
| let function = FunctionBuilder::new() |
| .id(Uuid::new_v4()) |
| .name("mock_function") |
| .description("mock function") |
| .payload(b"python script".to_vec()) |
| - .arguments(vec!["arg".to_string()]) |
| + .arguments(vec![function_arg]) |
| .public(true) |
| .owner("mock_user") |
| + .usage_quota(-1) |
| .build(); |
| let function_arguments = FunctionArguments::from_json(json!({"arg": "data"})).unwrap(); |
| |
| @@ -1039,6 +1191,7 @@ pub mod tests { |
| .payload(b"python script".to_vec()) |
| .public(true) |
| .owner("mock_user") |
| + .usage_quota(-1) |
| .build(); |
| |
| let url = Url::parse("s3://bucket_id/path?token=mock_token").unwrap(); |
| diff --git a/services/proto/Cargo.toml b/services/proto/Cargo.toml |
| index 525f0f1..252274a 100644 |
| --- a/services/proto/Cargo.toml |
| +++ b/services/proto/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_proto" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "RPC protocol of Teaclave services." |
| license = "Apache-2.0" |
| @@ -42,7 +42,8 @@ rand = { version = "0.7.0" } |
| serde = { version = "1.0.39", features = ["derive"] } |
| serde_json = { version = "1.0.39" } |
| url = { version = "2.1.1" } |
| -uuid = { version = "0.8.1", features = ["v4"] } |
| +uuid = { version = "0.8.1", features = ["v4"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| |
| sgx_cov = { version = "1.1.3", optional = true } |
| sgx_tstd = { version = "1.1.3", features = ["net", "backtrace"], optional = true } |
| diff --git a/services/proto/proto_gen/Cargo.lock b/services/proto/proto_gen/Cargo.lock |
| index 42835a9..c84bfe1 100644 |
| --- a/services/proto/proto_gen/Cargo.lock |
| +++ b/services/proto/proto_gen/Cargo.lock |
| @@ -489,7 +489,7 @@ dependencies = [ |
| |
| [[package]] |
| name = "teaclave_proto_gen" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| dependencies = [ |
| "askama", |
| "prost", |
| diff --git a/services/proto/proto_gen/Cargo.toml b/services/proto/proto_gen/Cargo.toml |
| index 026ae8e..0772215 100644 |
| --- a/services/proto/proto_gen/Cargo.toml |
| +++ b/services/proto/proto_gen/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_proto_gen" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Generating Rust protocols from protobuf." |
| license = "Apache-2.0" |
| diff --git a/services/proto/proto_gen/templates/proto.j2 b/services/proto/proto_gen/templates/proto.j2 |
| index 84ffdaa..a9a6c70 100644 |
| --- a/services/proto/proto_gen/templates/proto.j2 |
| +++ b/services/proto/proto_gen/templates/proto.j2 |
| @@ -48,9 +48,15 @@ pub trait {{ service.proto_name }} { |
| ) -> teaclave_types::TeaclaveServiceResponseResult<{{ service.proto_name }}Response> { |
| use core::convert::TryFrom; |
| use std::string::ToString; |
| + #[cfg(feature = "mesalock_sgx")] |
| + use std::untrusted::time::InstantEx; |
| match request.message { |
| {%- for m in service.methods %} |
| {{ service.proto_name }}Request::{{ m.proto_name }}(r) => { |
| + profile_highlight!("{{ service.proto_name }}Request::{{ m.proto_name }}", { |
| + log::info!("[MONITOR] {}, {}, {{ service.proto_name }}Request::{{ m.proto_name }}", |
| + request.metadata.get("id").unwrap_or(&"None".to_string()), |
| + request.metadata.get("cli-version").unwrap_or(&"None".to_string())); |
| let r = {{ m.impl_input_type }}::try_from(r) |
| .map_err(|_| teaclave_types::TeaclaveServiceResponseError::InternalError("internal".to_string()))?; |
| let r = teaclave_rpc::Request { |
| @@ -60,6 +66,7 @@ pub trait {{ service.proto_name }} { |
| let response = self.{{ m.name }}(r)?; |
| let response = {{ m.output_type }}::from(response); |
| Ok(response).map({{ service.proto_name }}Response::{{ m.proto_name }}) |
| + }) |
| }, |
| {%- endfor %} |
| } |
| diff --git a/services/proto/src/lib.rs b/services/proto/src/lib.rs |
| index 18c285f..b546096 100644 |
| --- a/services/proto/src/lib.rs |
| +++ b/services/proto/src/lib.rs |
| @@ -27,6 +27,21 @@ pub mod teaclave_management_service; |
| pub mod teaclave_scheduler_service; |
| pub mod teaclave_storage_service; |
| |
| +#[macro_export] |
| +macro_rules! profile_highlight { |
| + ($desc:literal, $blk:block) => {{ |
| + let before = std::time::Instant::now(); |
| + let result = $blk; |
| + let elapsed = before.elapsed().as_secs_f64(); |
| + if elapsed < 0.5 { |
| + log::debug!(" {}: Elapsed time: {:?}", $desc, elapsed); |
| + } else { |
| + log::info!(" {}: Elapsed time: \x1B[1;31m{:?}\x1B[0m", $desc, elapsed); |
| + } |
| + result |
| + }}; |
| +} |
| + |
| macro_rules! include_proto { |
| ($package: tt) => { |
| include!(concat!(env!("OUT_DIR"), concat!("/", $package, ".rs"))); |
| diff --git a/services/proto/src/proto/teaclave_frontend_service.proto b/services/proto/src/proto/teaclave_frontend_service.proto |
| index 31d8fd0..6e77344 100644 |
| --- a/services/proto/src/proto/teaclave_frontend_service.proto |
| +++ b/services/proto/src/proto/teaclave_frontend_service.proto |
| @@ -107,21 +107,35 @@ message FunctionOutput { |
| bool optional = 3; |
| } |
| |
| +message FunctionArgument { |
| + string key = 1; |
| + string default_value = 2; |
| + bool allow_overwrite = 3; |
| +} |
| + |
| message OwnerList { |
| string data_name = 1; |
| repeated string uids = 2; |
| } |
| |
| +message FunctionExpirationDate { |
| + bool expired = 1; |
| + int64 seconds = 2; |
| + int32 nanos = 3; |
| +} |
| + |
| message RegisterFunctionRequest { |
| string name = 1; |
| string description = 2; |
| string executor_type = 3; |
| bool public = 4; |
| bytes payload = 5; |
| - repeated string arguments = 6; |
| + repeated FunctionArgument arguments = 6; |
| repeated FunctionInput inputs = 10; |
| repeated FunctionOutput outputs = 11; |
| repeated string user_allowlist = 12; |
| + int32 usage_quota = 13; |
| + FunctionExpirationDate expiration_date = 14; |
| } |
| |
| message RegisterFunctionResponse { |
| @@ -135,10 +149,12 @@ message UpdateFunctionRequest { |
| string executor_type = 4; |
| bool public = 5; |
| bytes payload = 6; |
| - repeated string arguments = 7; |
| + repeated FunctionArgument arguments = 7; |
| repeated FunctionInput inputs = 10; |
| repeated FunctionOutput outputs = 11; |
| repeated string user_allowlist = 12; |
| + int32 usage_quota = 13; |
| + FunctionExpirationDate expiration_date = 14; |
| } |
| |
| message UpdateFunctionResponse { |
| @@ -156,7 +172,7 @@ message GetFunctionResponse { |
| string owner = 4; |
| bytes payload = 5; |
| bool public = 6; |
| - repeated string arguments = 7; |
| + repeated FunctionArgument arguments = 7; |
| repeated FunctionInput inputs = 10; |
| repeated FunctionOutput outputs = 11; |
| repeated string user_allowlist = 12; |
| @@ -166,6 +182,16 @@ message DeleteFunctionRequest { |
| string function_id = 1; |
| } |
| |
| +message GetFunctionUsageStatsRequest { |
| + string user_id = 1; |
| + string function_id = 2; |
| +} |
| + |
| +message GetFunctionUsageStatsResponse { |
| + int32 function_quota = 1; |
| + int32 current_usage = 2; |
| +} |
| + |
| message DeleteFunctionResponse { } |
| |
| message DisableFunctionRequest { |
| @@ -258,6 +284,7 @@ service TeaclaveFrontend { |
| rpc GetInputFile (GetInputFileRequest) returns (GetInputFileResponse); |
| rpc RegisterFunction (RegisterFunctionRequest) returns (RegisterFunctionResponse); |
| rpc GetFunction (GetFunctionRequest) returns (GetFunctionResponse); |
| + rpc GetFunctionUsageStats (GetFunctionUsageStatsRequest) returns (GetFunctionUsageStatsResponse); |
| rpc UpdateFunction (UpdateFunctionRequest) returns (UpdateFunctionResponse); |
| rpc ListFunctions (ListFunctionsRequest) returns (ListFunctionsResponse); |
| rpc DeleteFunction (DeleteFunctionRequest) returns (DeleteFunctionResponse); |
| diff --git a/services/proto/src/proto/teaclave_management_service.proto b/services/proto/src/proto/teaclave_management_service.proto |
| index d79bd42..7d9639a 100644 |
| --- a/services/proto/src/proto/teaclave_management_service.proto |
| +++ b/services/proto/src/proto/teaclave_management_service.proto |
| @@ -36,6 +36,7 @@ service TeaclaveManagement { |
| rpc RegisterFunction (teaclave_frontend_service_proto.RegisterFunctionRequest) returns (teaclave_frontend_service_proto.RegisterFunctionResponse); |
| rpc UpdateFunction (teaclave_frontend_service_proto.UpdateFunctionRequest) returns (teaclave_frontend_service_proto.UpdateFunctionResponse); |
| rpc GetFunction (teaclave_frontend_service_proto.GetFunctionRequest) returns (teaclave_frontend_service_proto.GetFunctionResponse); |
| + rpc GetFunctionUsageStats (teaclave_frontend_service_proto.GetFunctionUsageStatsRequest) returns (teaclave_frontend_service_proto.GetFunctionUsageStatsResponse); |
| rpc DeleteFunction (teaclave_frontend_service_proto.DeleteFunctionRequest) returns (teaclave_frontend_service_proto.DeleteFunctionResponse); |
| rpc DisableFunction (teaclave_frontend_service_proto.DisableFunctionRequest) returns (teaclave_frontend_service_proto.DisableFunctionResponse); |
| rpc ListFunctions (teaclave_frontend_service_proto.ListFunctionsRequest) returns (teaclave_frontend_service_proto.ListFunctionsResponse); |
| diff --git a/services/proto/src/teaclave_frontend_service.rs b/services/proto/src/teaclave_frontend_service.rs |
| index b353ad0..f64e3b5 100644 |
| --- a/services/proto/src/teaclave_frontend_service.rs |
| +++ b/services/proto/src/teaclave_frontend_service.rs |
| @@ -26,9 +26,9 @@ use std::collections::HashMap; |
| use std::prelude::v1::*; |
| use teaclave_rpc::into_request; |
| use teaclave_types::{ |
| - Executor, ExecutorType, ExternalID, FileAuthTag, FileCrypto, FunctionArguments, |
| - FunctionBuilder, FunctionInput, FunctionOutput, OwnerList, TaskFileOwners, TaskResult, |
| - TaskStatus, UserID, UserList, |
| + Executor, ExecutorType, ExternalID, FileAuthTag, FileCrypto, FunctionArgument, |
| + FunctionArguments, FunctionBuilder, FunctionExpirationDate, FunctionInput, FunctionOutput, |
| + OwnerList, TaskFileOwners, TaskResult, TaskStatus, UserID, UserList, |
| }; |
| use url::Url; |
| |
| @@ -285,10 +285,12 @@ pub struct RegisterFunctionRequest { |
| pub executor_type: ExecutorType, |
| pub payload: Vec<u8>, |
| pub public: bool, |
| - pub arguments: Vec<String>, |
| + pub arguments: Vec<FunctionArgument>, |
| pub inputs: Vec<FunctionInput>, |
| pub outputs: Vec<FunctionOutput>, |
| pub user_allowlist: Vec<String>, |
| + pub usage_quota: i32, |
| + pub expiration_date: FunctionExpirationDate, |
| } |
| |
| #[derive(Default)] |
| @@ -301,6 +303,7 @@ impl RegisterFunctionRequestBuilder { |
| let request = RegisterFunctionRequest { |
| executor_type: ExecutorType::Builtin, |
| public: true, |
| + usage_quota: -1, |
| ..Default::default() |
| }; |
| |
| @@ -332,11 +335,13 @@ impl RegisterFunctionRequestBuilder { |
| self |
| } |
| |
| - pub fn arguments<T: IntoIterator>(mut self, args: T) -> Self |
| - where |
| - <T as IntoIterator>::Item: ToString, |
| - { |
| - self.request.arguments = args.into_iter().map(|x| x.to_string()).collect(); |
| + pub fn usage_quota(mut self, usage_quota: i32) -> Self { |
| + self.request.usage_quota = usage_quota; |
| + self |
| + } |
| + |
| + pub fn arguments(mut self, args: Vec<FunctionArgument>) -> Self { |
| + self.request.arguments = args; |
| self |
| } |
| |
| @@ -355,6 +360,11 @@ impl RegisterFunctionRequestBuilder { |
| self |
| } |
| |
| + pub fn expiration_date(mut self, expiration_date: FunctionExpirationDate) -> Self { |
| + self.request.expiration_date = expiration_date; |
| + self |
| + } |
| + |
| pub fn build(self) -> RegisterFunctionRequest { |
| self.request |
| } |
| @@ -373,6 +383,8 @@ impl From<RegisterFunctionRequest> for FunctionBuilder { |
| .inputs(request.inputs) |
| .outputs(request.outputs) |
| .user_allowlist(request.user_allowlist) |
| + .usage_quota(request.usage_quota) |
| + .expiration_date(request.expiration_date) |
| } |
| } |
| |
| @@ -398,10 +410,12 @@ pub struct UpdateFunctionRequest { |
| pub executor_type: ExecutorType, |
| pub payload: Vec<u8>, |
| pub public: bool, |
| - pub arguments: Vec<String>, |
| + pub arguments: Vec<FunctionArgument>, |
| pub inputs: Vec<FunctionInput>, |
| pub outputs: Vec<FunctionOutput>, |
| pub user_allowlist: Vec<String>, |
| + pub usage_quota: i32, |
| + pub expiration_date: FunctionExpirationDate, |
| } |
| |
| #[derive(Default)] |
| @@ -450,11 +464,13 @@ impl UpdateFunctionRequestBuilder { |
| self |
| } |
| |
| - pub fn arguments<T: IntoIterator>(mut self, args: T) -> Self |
| - where |
| - <T as IntoIterator>::Item: ToString, |
| - { |
| - self.request.arguments = args.into_iter().map(|x| x.to_string()).collect(); |
| + pub fn usage_quota(mut self, usage_quota: i32) -> Self { |
| + self.request.usage_quota = usage_quota; |
| + self |
| + } |
| + |
| + pub fn arguments(mut self, args: Vec<FunctionArgument>) -> Self { |
| + self.request.arguments = args; |
| self |
| } |
| |
| @@ -473,6 +489,11 @@ impl UpdateFunctionRequestBuilder { |
| self |
| } |
| |
| + pub fn expiration_date(mut self, expiration_date: FunctionExpirationDate) -> Self { |
| + self.request.expiration_date = expiration_date; |
| + self |
| + } |
| + |
| pub fn build(self) -> UpdateFunctionRequest { |
| self.request |
| } |
| @@ -492,6 +513,8 @@ impl From<UpdateFunctionRequest> for FunctionBuilder { |
| .inputs(request.inputs) |
| .outputs(request.outputs) |
| .user_allowlist(request.user_allowlist) |
| + .usage_quota(request.usage_quota) |
| + .expiration_date(request.expiration_date) |
| } |
| } |
| |
| @@ -529,12 +552,36 @@ pub struct GetFunctionResponse { |
| pub payload: Vec<u8>, |
| pub public: bool, |
| pub executor_type: ExecutorType, |
| - pub arguments: Vec<String>, |
| + pub arguments: Vec<FunctionArgument>, |
| pub inputs: Vec<FunctionInput>, |
| pub outputs: Vec<FunctionOutput>, |
| pub user_allowlist: Vec<String>, |
| } |
| |
| +#[into_request(TeaclaveManagementRequest::GetFunctionUsageStats)] |
| +#[into_request(TeaclaveFrontendRequest::GetFunctionUsageStats)] |
| +#[derive(Debug)] |
| +pub struct GetFunctionUsageStatsRequest { |
| + pub user_id: UserID, |
| + pub function_id: ExternalID, |
| +} |
| + |
| +impl GetFunctionUsageStatsRequest { |
| + pub fn new(function_id: ExternalID, user_id: UserID) -> Self { |
| + Self { |
| + user_id, |
| + function_id, |
| + } |
| + } |
| +} |
| + |
| +#[into_request(TeaclaveManagementResponse::GetFunctionUsageStats)] |
| +#[derive(Debug)] |
| +pub struct GetFunctionUsageStatsResponse { |
| + pub function_quota: i32, |
| + pub current_usage: i32, |
| +} |
| + |
| #[into_request(TeaclaveManagementRequest::DeleteFunction)] |
| #[into_request(TeaclaveFrontendRequest::DeleteFunction)] |
| #[derive(Debug)] |
| @@ -1109,6 +1156,53 @@ impl From<FunctionOutput> for proto::FunctionOutput { |
| } |
| } |
| |
| +impl std::convert::TryFrom<proto::FunctionArgument> for FunctionArgument { |
| + type Error = Error; |
| + |
| + fn try_from(proto: proto::FunctionArgument) -> Result<Self> { |
| + let ret = Self { |
| + key: proto.key, |
| + default_value: proto.default_value, |
| + allow_overwrite: proto.allow_overwrite, |
| + }; |
| + |
| + Ok(ret) |
| + } |
| +} |
| + |
| +impl From<FunctionArgument> for proto::FunctionArgument { |
| + fn from(arg: FunctionArgument) -> Self { |
| + Self { |
| + key: arg.key, |
| + default_value: arg.default_value, |
| + allow_overwrite: arg.allow_overwrite, |
| + } |
| + } |
| +} |
| + |
| +impl std::convert::TryFrom<proto::FunctionExpirationDate> for FunctionExpirationDate { |
| + type Error = Error; |
| + |
| + fn try_from(proto: proto::FunctionExpirationDate) -> Result<Self> { |
| + let ret = Self { |
| + expired: proto.expired, |
| + seconds: proto.seconds, |
| + nanos: proto.nanos, |
| + }; |
| + Ok(ret) |
| + } |
| +} |
| + |
| +impl From<FunctionExpirationDate> for proto::FunctionExpirationDate { |
| + fn from(expiration_date: FunctionExpirationDate) -> Self { |
| + Self { |
| + expired: expiration_date.expired, |
| + seconds: expiration_date.seconds, |
| + nanos: expiration_date.nanos, |
| + } |
| + } |
| +} |
| + |
| impl std::convert::TryFrom<proto::RegisterFunctionRequest> for RegisterFunctionRequest { |
| type Error = Error; |
| |
| @@ -1123,18 +1217,28 @@ impl std::convert::TryFrom<proto::RegisterFunctionRequest> for RegisterFunctionR |
| .into_iter() |
| .map(FunctionOutput::try_from) |
| .collect(); |
| + let args: Result<Vec<FunctionArgument>> = proto |
| + .arguments |
| + .into_iter() |
| + .map(FunctionArgument::try_from) |
| + .collect(); |
| let executor_type = proto.executor_type.try_into()?; |
| - |
| + let expiration_date: FunctionExpirationDate = proto |
| + .expiration_date |
| + .ok_or_else(|| anyhow!("missing expiration date"))? |
| + .try_into()?; |
| let ret = Self { |
| name: proto.name, |
| description: proto.description, |
| executor_type, |
| payload: proto.payload, |
| public: proto.public, |
| - arguments: proto.arguments, |
| + arguments: args?, |
| inputs: inputs?, |
| outputs: outputs?, |
| user_allowlist: proto.user_allowlist, |
| + usage_quota: proto.usage_quota, |
| + expiration_date, |
| }; |
| Ok(ret) |
| } |
| @@ -1152,6 +1256,11 @@ impl From<RegisterFunctionRequest> for proto::RegisterFunctionRequest { |
| .into_iter() |
| .map(proto::FunctionOutput::from) |
| .collect(); |
| + let arguments: Vec<proto::FunctionArgument> = request |
| + .arguments |
| + .into_iter() |
| + .map(proto::FunctionArgument::from) |
| + .collect(); |
| |
| Self { |
| name: request.name, |
| @@ -1159,10 +1268,12 @@ impl From<RegisterFunctionRequest> for proto::RegisterFunctionRequest { |
| executor_type: request.executor_type.into(), |
| payload: request.payload, |
| public: request.public, |
| - arguments: request.arguments, |
| + arguments, |
| inputs, |
| outputs, |
| user_allowlist: request.user_allowlist, |
| + usage_quota: request.usage_quota, |
| + expiration_date: Some(request.expiration_date.into()), |
| } |
| } |
| } |
| @@ -1201,8 +1312,18 @@ impl std::convert::TryFrom<proto::UpdateFunctionRequest> for UpdateFunctionReque |
| .into_iter() |
| .map(FunctionOutput::try_from) |
| .collect(); |
| + let args: Result<Vec<FunctionArgument>> = proto |
| + .arguments |
| + .into_iter() |
| + .map(FunctionArgument::try_from) |
| + .collect(); |
| let executor_type = proto.executor_type.try_into()?; |
| |
| + let expiration_date: FunctionExpirationDate = proto |
| + .expiration_date |
| + .ok_or_else(|| anyhow!("missing expiration date"))? |
| + .try_into()?; |
| + |
| let ret = Self { |
| function_id, |
| name: proto.name, |
| @@ -1210,10 +1331,12 @@ impl std::convert::TryFrom<proto::UpdateFunctionRequest> for UpdateFunctionReque |
| executor_type, |
| payload: proto.payload, |
| public: proto.public, |
| - arguments: proto.arguments, |
| + arguments: args?, |
| inputs: inputs?, |
| outputs: outputs?, |
| user_allowlist: proto.user_allowlist, |
| + usage_quota: proto.usage_quota, |
| + expiration_date, |
| }; |
| Ok(ret) |
| } |
| @@ -1231,6 +1354,11 @@ impl From<UpdateFunctionRequest> for proto::UpdateFunctionRequest { |
| .into_iter() |
| .map(proto::FunctionOutput::from) |
| .collect(); |
| + let arguments: Vec<proto::FunctionArgument> = request |
| + .arguments |
| + .into_iter() |
| + .map(proto::FunctionArgument::from) |
| + .collect(); |
| |
| Self { |
| function_id: request.function_id.to_string(), |
| @@ -1239,10 +1367,12 @@ impl From<UpdateFunctionRequest> for proto::UpdateFunctionRequest { |
| executor_type: request.executor_type.into(), |
| payload: request.payload, |
| public: request.public, |
| - arguments: request.arguments, |
| + arguments, |
| inputs, |
| outputs, |
| user_allowlist: request.user_allowlist, |
| + usage_quota: request.usage_quota, |
| + expiration_date: Some(request.expiration_date.into()), |
| } |
| } |
| } |
| @@ -1293,6 +1423,52 @@ impl std::convert::TryFrom<proto::DeleteFunctionResponse> for DeleteFunctionResp |
| } |
| } |
| |
| +impl From<GetFunctionUsageStatsRequest> for proto::GetFunctionUsageStatsRequest { |
| + fn from(request: GetFunctionUsageStatsRequest) -> Self { |
| + Self { |
| + user_id: request.user_id.to_string(), |
| + function_id: request.function_id.to_string(), |
| + } |
| + } |
| +} |
| + |
| +impl std::convert::TryFrom<proto::GetFunctionUsageStatsRequest> for GetFunctionUsageStatsRequest { |
| + type Error = Error; |
| + |
| + fn try_from(proto: proto::GetFunctionUsageStatsRequest) -> Result<Self> { |
| + let user_id: UserID = proto.user_id.try_into()?; |
| + let function_id: ExternalID = proto.function_id.try_into()?; |
| + let ret = Self { |
| + user_id, |
| + function_id, |
| + }; |
| + |
| + Ok(ret) |
| + } |
| +} |
| + |
| +impl From<GetFunctionUsageStatsResponse> for proto::GetFunctionUsageStatsResponse { |
| + fn from(request: GetFunctionUsageStatsResponse) -> Self { |
| + Self { |
| + function_quota: request.function_quota, |
| + current_usage: request.current_usage, |
| + } |
| + } |
| +} |
| + |
| +impl std::convert::TryFrom<proto::GetFunctionUsageStatsResponse> for GetFunctionUsageStatsResponse { |
| + type Error = Error; |
| + |
| + fn try_from(proto: proto::GetFunctionUsageStatsResponse) -> Result<Self> { |
| + let ret = Self { |
| + function_quota: proto.function_quota, |
| + current_usage: proto.current_usage, |
| + }; |
| + |
| + Ok(ret) |
| + } |
| +} |
| + |
| impl From<DeleteFunctionResponse> for proto::DeleteFunctionResponse { |
| fn from(_response: DeleteFunctionResponse) -> Self { |
| Self {} |
| @@ -1406,6 +1582,11 @@ impl std::convert::TryFrom<proto::GetFunctionResponse> for GetFunctionResponse { |
| .into_iter() |
| .map(FunctionOutput::try_from) |
| .collect(); |
| + let args: Result<Vec<FunctionArgument>> = proto |
| + .arguments |
| + .into_iter() |
| + .map(FunctionArgument::try_from) |
| + .collect(); |
| let executor_type = proto.executor_type.try_into()?; |
| |
| let ret = Self { |
| @@ -1415,7 +1596,7 @@ impl std::convert::TryFrom<proto::GetFunctionResponse> for GetFunctionResponse { |
| executor_type, |
| payload: proto.payload, |
| public: proto.public, |
| - arguments: proto.arguments, |
| + arguments: args?, |
| inputs: inputs?, |
| outputs: outputs?, |
| user_allowlist: proto.user_allowlist, |
| @@ -1437,6 +1618,11 @@ impl From<GetFunctionResponse> for proto::GetFunctionResponse { |
| .into_iter() |
| .map(proto::FunctionOutput::from) |
| .collect(); |
| + let arguments: Vec<proto::FunctionArgument> = response |
| + .arguments |
| + .into_iter() |
| + .map(proto::FunctionArgument::from) |
| + .collect(); |
| |
| Self { |
| name: response.name, |
| @@ -1445,7 +1631,7 @@ impl From<GetFunctionResponse> for proto::GetFunctionResponse { |
| executor_type: response.executor_type.into(), |
| payload: response.payload, |
| public: response.public, |
| - arguments: response.arguments, |
| + arguments, |
| inputs, |
| outputs, |
| user_allowlist: response.user_allowlist, |
| diff --git a/services/proto/src/teaclave_management_service.rs b/services/proto/src/teaclave_management_service.rs |
| index 6f8cbcb..deb7663 100644 |
| --- a/services/proto/src/teaclave_management_service.rs |
| +++ b/services/proto/src/teaclave_management_service.rs |
| @@ -62,6 +62,10 @@ pub type CreateTaskRequest = crate::teaclave_frontend_service::CreateTaskRequest |
| pub type CreateTaskResponse = crate::teaclave_frontend_service::CreateTaskResponse; |
| pub type GetTaskRequest = crate::teaclave_frontend_service::GetTaskRequest; |
| pub type GetTaskResponse = crate::teaclave_frontend_service::GetTaskResponse; |
| +pub type GetFunctionUsageStatsRequest = |
| + crate::teaclave_frontend_service::GetFunctionUsageStatsRequest; |
| +pub type GetFunctionUsageStatsResponse = |
| + crate::teaclave_frontend_service::GetFunctionUsageStatsResponse; |
| pub type AssignDataRequest = crate::teaclave_frontend_service::AssignDataRequest; |
| pub type AssignDataResponse = crate::teaclave_frontend_service::AssignDataResponse; |
| pub type ApproveTaskRequest = crate::teaclave_frontend_service::ApproveTaskRequest; |
| diff --git a/services/scheduler/app/Cargo.toml b/services/scheduler/app/Cargo.toml |
| index 556aa25..a12d9b5 100644 |
| --- a/services/scheduler/app/Cargo.toml |
| +++ b/services/scheduler/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_scheduler_service" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave worker." |
| license = "Apache-2.0" |
| diff --git a/services/scheduler/enclave/Cargo.toml b/services/scheduler/enclave/Cargo.toml |
| index e991a27..41cdeaf 100644 |
| --- a/services/scheduler/enclave/Cargo.toml |
| +++ b/services/scheduler/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_scheduler_service_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Scheduler Service" |
| license = "Apache-2.0" |
| @@ -44,7 +44,7 @@ cov = ["teaclave_service_enclave_utils/cov"] |
| enclave_unit_test = ["teaclave_binder/enclave_unit_test", "teaclave_test_utils/mesalock_sgx"] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| serde_json = { version = "1.0.39" } |
| serde = { version = "1.0.92", features = ["derive"] } |
| diff --git a/services/scheduler/enclave/src/service.rs b/services/scheduler/enclave/src/service.rs |
| index 2a739ac..970f2f6 100644 |
| --- a/services/scheduler/enclave/src/service.rs |
| +++ b/services/scheduler/enclave/src/service.rs |
| @@ -61,7 +61,7 @@ pub struct TeaclaveSchedulerDeamon { |
| impl TeaclaveSchedulerDeamon { |
| pub fn run(&self) -> Result<()> { |
| loop { |
| - std::thread::sleep(std::time::Duration::from_secs(2)); |
| + std::thread::sleep(std::time::Duration::from_secs(1)); |
| |
| let mut resources = self |
| .resources |
| diff --git a/services/storage/app/Cargo.toml b/services/storage/app/Cargo.toml |
| index 385a8f8..1cde92c 100644 |
| --- a/services/storage/app/Cargo.toml |
| +++ b/services/storage/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_storage_service" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Storage Service" |
| license = "Apache-2.0" |
| diff --git a/services/storage/enclave/Cargo.toml b/services/storage/enclave/Cargo.toml |
| index 98c6c9d..054a197 100644 |
| --- a/services/storage/enclave/Cargo.toml |
| +++ b/services/storage/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_storage_service_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave Storage Service enclave" |
| license = "Apache-2.0" |
| @@ -46,7 +46,7 @@ enclave_unit_test = ["teaclave_binder/enclave_unit_test", "teaclave_test_utils/m |
| [dependencies] |
| anyhow = { version = "1.0.26" } |
| cfg-if = { version = "0.1.9" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| serde = { version = "1.0.92" } |
| thiserror = { version = "1.0.9" } |
| |
| diff --git a/services/storage/enclave/Enclave.config.xml b/services/storage/enclave/Enclave.config.xml |
| index d95a7e5..acd589b 100644 |
| --- a/services/storage/enclave/Enclave.config.xml |
| +++ b/services/storage/enclave/Enclave.config.xml |
| @@ -1,3 +1,4 @@ |
| + |
| <!-- |
| ~ Licensed to the Apache Software Foundation (ASF) under one |
| ~ or more contributor license agreements. See the NOTICE file |
| @@ -21,8 +22,8 @@ |
| <EnclaveConfiguration> |
| <ProdID>0</ProdID> |
| <ISVSVN>0</ISVSVN> |
| - <StackMaxSize>0x400000</StackMaxSize> <!-- 2M --> |
| - <HeapMaxSize>0x30000000</HeapMaxSize> <!-- 768M --> |
| + <StackMaxSize>0x800000</StackMaxSize> <!-- 2M --> |
| + <HeapMaxSize>0x50000000</HeapMaxSize> <!-- 768M --> |
| <TCSNum>22</TCSNum> |
| <TCSPolicy>0</TCSPolicy> |
| <DisableDebug>0</DisableDebug> |
| diff --git a/services/storage/enclave/src/lib.rs b/services/storage/enclave/src/lib.rs |
| index 2e4b262..455240d 100644 |
| --- a/services/storage/enclave/src/lib.rs |
| +++ b/services/storage/enclave/src/lib.rs |
| @@ -24,6 +24,7 @@ extern crate log; |
| |
| use std::cell::RefCell; |
| use std::format; |
| +use std::path::Path; |
| use std::prelude::v1::*; |
| use std::sync::mpsc::channel; |
| use std::thread; |
| @@ -42,6 +43,7 @@ use teaclave_config::RuntimeConfig; |
| use teaclave_proto::teaclave_storage_service::{TeaclaveStorageRequest, TeaclaveStorageResponse}; |
| use teaclave_rpc::config::SgxTrustedTlsServerConfig; |
| use teaclave_rpc::server::SgxTrustedTlsServer; |
| +use teaclave_service_enclave_utils::base_dir_for_db; |
| use teaclave_service_enclave_utils::ServiceEnclave; |
| use teaclave_types::{EnclaveInfo, TeeServiceError, TeeServiceResult}; |
| |
| @@ -80,13 +82,15 @@ fn start_service(config: &RuntimeConfig) -> Result<()> { |
| )?; |
| info!(" Starting Storage: Server config setup finished ..."); |
| |
| + let db_base = base_dir_for_db(&config)?; |
| + |
| let (sender, receiver) = channel(); |
| thread::spawn(move || { |
| info!(" Starting Storage: opening database ..."); |
| #[cfg(test_mode)] |
| - let db = test_mode::create_mock_db(); |
| + let db = test_mode::create_mock_db(db_base); |
| #[cfg(not(test_mode))] |
| - let db = create_teaclave_db(); |
| + let db = create_teaclave_db(db_base); |
| |
| let mut storage_service = service::TeaclaveStorageService::new(RefCell::new(db), receiver); |
| |
| @@ -112,22 +116,30 @@ fn start_service(config: &RuntimeConfig) -> Result<()> { |
| } |
| |
| #[cfg(not(test_mode))] |
| -pub(crate) fn create_teaclave_db() -> DB { |
| - let opt = rusty_leveldb::in_memory(); |
| - let database = DB::open("teaclave_db", opt).expect("cannot open teaclave_db"); |
| +pub(crate) fn create_teaclave_db(base_dir: impl AsRef<Path>) -> DB { |
| + let key = [ |
| + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, |
| + 0x08, |
| + ]; |
| + let db_path = base_dir.as_ref().join("teaclave_db"); |
| + let opt = rusty_leveldb::Options::new_disk_db_with(key); |
| + let database = DB::open(&db_path, opt).expect("cannot open teaclave_db"); |
| + info!("teaclave_db created: {:?}", db_path); |
| database |
| } |
| |
| #[cfg(test_mode)] |
| mod test_mode { |
| use super::*; |
| - pub(crate) fn create_mock_db() -> DB { |
| + pub(crate) fn create_mock_db(base_dir: impl AsRef<Path>) -> DB { |
| let key = [ |
| 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, |
| 0x09, 0x08, |
| ]; |
| let opt = rusty_leveldb::Options::new_disk_db_with(key); |
| - let mut database = DB::open("mock_db", opt).unwrap(); |
| + let db_path = base_dir.as_ref().join("mock_db"); |
| + let mut database = DB::open(&db_path, opt).unwrap(); |
| + info!("mock_db created: {:?}", db_path); |
| database.put(b"test_get_key", b"test_get_value").unwrap(); |
| database |
| .put(b"test_delete_key", b"test_delete_value") |
| diff --git a/services/storage/enclave/src/service.rs b/services/storage/enclave/src/service.rs |
| index 57188c9..9240c89 100644 |
| --- a/services/storage/enclave/src/service.rs |
| +++ b/services/storage/enclave/src/service.rs |
| @@ -132,6 +132,11 @@ impl<'a> DBQueue<'a> { |
| ))), |
| }; |
| |
| + info!( |
| + "DB.Queue[{}]: dequeue, result.len = {}", |
| + std::str::from_utf8(self.key).unwrap(), |
| + &result.len() |
| + ); |
| // update head |
| let head_index = head_index.wrapping_add(1); |
| self.database |
| @@ -187,6 +192,11 @@ impl TeaclaveStorage for TeaclaveStorageService { |
| |
| fn put(&self, request: Request<PutRequest>) -> TeaclaveServiceResponseResult<PutResponse> { |
| let request = request.message; |
| + info!( |
| + "DB.Put: request.key = {}, request.value.len = {}", |
| + std::str::from_utf8(&request.key).unwrap(), |
| + &request.value.len() |
| + ); |
| self.database |
| .borrow_mut() |
| .put(&request.key, &request.value) |
| @@ -204,6 +214,10 @@ impl TeaclaveStorage for TeaclaveStorageService { |
| request: Request<DeleteRequest>, |
| ) -> TeaclaveServiceResponseResult<DeleteResponse> { |
| let request = request.message; |
| + info!( |
| + "DB.Delete: request.key = {}", |
| + std::str::from_utf8(&request.key).unwrap() |
| + ); |
| self.database |
| .borrow_mut() |
| .delete(&request.key) |
| diff --git a/services/utils/service_app_utils/Cargo.toml b/services/utils/service_app_utils/Cargo.toml |
| index 4f16c8e..f2d2672 100644 |
| --- a/services/utils/service_app_utils/Cargo.toml |
| +++ b/services/utils/service_app_utils/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_service_app_utils" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave service app utils" |
| license = "Apache-2.0" |
| @@ -28,7 +28,7 @@ edition = "2018" |
| ctrlc = { version = "3.1.2" } |
| env_logger = { version = "0.7.1" } |
| anyhow = { version = "1.0.26" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| libc = { version = "0.2.66" } |
| signal-hook = { version = "0.1.13" } |
| |
| diff --git a/services/utils/service_enclave_utils/Cargo.toml b/services/utils/service_enclave_utils/Cargo.toml |
| index 4a3bb77..51833f9 100644 |
| --- a/services/utils/service_enclave_utils/Cargo.toml |
| +++ b/services/utils/service_enclave_utils/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_service_enclave_utils" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave enclave utils" |
| license = "Apache-2.0" |
| @@ -36,7 +36,7 @@ cov = ["sgx_cov", "sgx_trts"] |
| [dependencies] |
| anyhow = { version = "1.0.26" } |
| env_logger = { version = "0.7.1" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| |
| teaclave_service_enclave_utils_proc_macro = { path = "./proc_macro" } |
| teaclave_types = { path = "../../../types" } |
| diff --git a/services/utils/service_enclave_utils/proc_macro/Cargo.toml b/services/utils/service_enclave_utils/proc_macro/Cargo.toml |
| index 9624fa9..57d4a51 100644 |
| --- a/services/utils/service_enclave_utils/proc_macro/Cargo.toml |
| +++ b/services/utils/service_enclave_utils/proc_macro/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_service_enclave_utils_proc_macro" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Procedure macro for service enclave utilities" |
| license = "Apache-2.0" |
| diff --git a/services/utils/service_enclave_utils/src/lib.rs b/services/utils/service_enclave_utils/src/lib.rs |
| index 5fb255b..7afe1b3 100644 |
| --- a/services/utils/service_enclave_utils/src/lib.rs |
| +++ b/services/utils/service_enclave_utils/src/lib.rs |
| @@ -22,6 +22,7 @@ extern crate sgx_tstd as std; |
| |
| use log::debug; |
| use log::error; |
| +use log::info; |
| use std::backtrace; |
| use std::path::PathBuf; |
| use std::sync::{Arc, SgxRwLock as RwLock}; |
| @@ -76,8 +77,8 @@ impl ServiceEnclave { |
| pub fn finalize() -> teaclave_types::TeeServiceResult<()> { |
| debug!("Enclave finalizing"); |
| unsafe { |
| - debug!("g_peak_heap_used: {}", g_peak_heap_used); |
| - debug!("g_peak_rsrv_mem_committed: {}", g_peak_rsrv_mem_committed); |
| + info!("g_peak_heap_used: {}", g_peak_heap_used); |
| + info!("g_peak_rsrv_mem_committed: {}", g_peak_rsrv_mem_committed); |
| } |
| |
| #[cfg(feature = "cov")] |
| diff --git a/tests/coding_wheel.txt b/tests/coding_wheel.txt |
| new file mode 100644 |
| index 0000000..909610a |
| --- /dev/null |
| +++ b/tests/coding_wheel.txt |
| @@ -0,0 +1,21 @@ |
| +Phe U U CU |
| +Leu C U GCUA U U GA |
| +Ser U C GCUA A G CU |
| +Tyr U A CU |
| +STOP U A GA U G A |
| +Cys U G CU |
| +Trp U G G |
| +Pro C C GCUA |
| +His C A CU |
| +Gln C A GA |
| +Arg C G GCUA A G GA |
| +Ile A U CUA |
| +Met A U G |
| +Thr A C GCUA |
| +Asn A A CU |
| +Lys A A GA |
| +Val G U GCUA |
| +Asp G A CU |
| +Glu G A GA |
| +Gly G G GCUA |
| +Ala G C GCUA |
| \ No newline at end of file |
| diff --git a/tests/codon_usage_freq_table_human.csv b/tests/codon_usage_freq_table_human.csv |
| new file mode 100644 |
| index 0000000..4e49f4f |
| --- /dev/null |
| +++ b/tests/codon_usage_freq_table_human.csv |
| @@ -0,0 +1,65 @@ |
| +#,, |
| +UAA,*,0.28 |
| +UAG,*,0.2 |
| +UGA,*,0.52 |
| +GCU,A,0.26 |
| +GCC,A,0.4 |
| +GCA,A,0.23 |
| +GCG,A,0.11 |
| +UGU,C,0.45 |
| +UGC,C,0.55 |
| +GAU,D,0.46 |
| +GAC,D,0.54 |
| +GAA,E,0.42 |
| +GAG,E,0.58 |
| +UUU,F,0.45 |
| +UUC,F,0.55 |
| +GGU,G,0.16 |
| +GGC,G,0.34 |
| +GGA,G,0.25 |
| +GGG,G,0.25 |
| +CAU,H,0.41 |
| +CAC,H,0.59 |
| +AUU,I,0.36 |
| +AUC,I,0.48 |
| +AUA,I,0.16 |
| +AAA,K,0.42 |
| +AAG,K,0.58 |
| +UUA,L,0.07 |
| +UUG,L,0.13 |
| +CUU,L,0.13 |
| +CUC,L,0.2 |
| +CUA,L,0.07 |
| +CUG,L,0.41 |
| +AUG,M,1 |
| +AAU,N,0.46 |
| +AAC,N,0.54 |
| +CCU,P,0.28 |
| +CCC,P,0.33 |
| +CCA,P,0.27 |
| +CCG,P,0.11 |
| +CAA,Q,0.25 |
| +CAG,Q,0.75 |
| +CGU,R,0.08 |
| +CGC,R,0.19 |
| +CGA,R,0.11 |
| +CGG,R,0.21 |
| +AGA,R,0.2 |
| +AGG,R,0.2 |
| +UCU,S,0.18 |
| +UCC,S,0.22 |
| +UCA,S,0.15 |
| +UCG,S,0.06 |
| +AGU,S,0.15 |
| +AGC,S,0.24 |
| +ACU,T,0.24 |
| +ACC,T,0.36 |
| +ACA,T,0.28 |
| +ACG,T,0.12 |
| +GUU,V,0.18 |
| +GUC,V,0.24 |
| +GUA,V,0.11 |
| +GUG,V,0.47 |
| +UGG,W,1 |
| +UAU,Y,0.43 |
| +UAC,Y,0.57 |
| \ No newline at end of file |
| diff --git a/tests/fixtures/functions/cleanroom-args/Makefile b/tests/fixtures/functions/cleanroom-args/Makefile |
| new file mode 100644 |
| index 0000000..cfad87d |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-args/Makefile |
| @@ -0,0 +1,15 @@ |
| +CC = $(CRW_SDK_PATH)/bin/clang |
| +CFLAGS += --sysroot=$(CRW_SDK_PATH)/share/wasi-sysroot -Wl,--export=malloc -Wl,--export=free |
| +CXX = $(CRW_SDK_PATH)/bin/clang++ |
| +CXXFLAGS += --sysroot=$(CRW_SDK_PATH)/share/wasi-sysroot -fno-exceptions -Wl,--export=malloc -Wl,--export=free |
| + |
| + |
| +all: wasm |
| + |
| + |
| +wasm: |
| + $(CXX) args.cpp $(CXXFLAGS) -o args.wasm |
| + |
| +clean: |
| + rm -f args.wasm |
| + |
| diff --git a/tests/fixtures/functions/cleanroom-args/args.cpp b/tests/fixtures/functions/cleanroom-args/args.cpp |
| new file mode 100644 |
| index 0000000..2b67643 |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-args/args.cpp |
| @@ -0,0 +1,9 @@ |
| +#include <iostream> |
| + |
| +int main(int argc, char** argv) { |
| + std::cout << "Have " << argc << " arguments:" << std::endl; |
| + for (int i = 0; i < argc; ++i) { |
| + std::cout << argv[i] << std::endl; |
| + } |
| +} |
| + |
| diff --git a/tests/fixtures/functions/cleanroom-args/args.wasm b/tests/fixtures/functions/cleanroom-args/args.wasm |
| new file mode 100755 |
| index 0000000..47a3133 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-args/args.wasm differ |
| diff --git a/tests/fixtures/functions/cleanroom-args/stdin b/tests/fixtures/functions/cleanroom-args/stdin |
| new file mode 100644 |
| index 0000000..e69de29 |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm2-hash/coding_wheel.txt b/tests/fixtures/functions/cleanroom-algorithm2-hash/coding_wheel.txt |
| new file mode 100644 |
| index 0000000..909610a |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-algorithm2-hash/coding_wheel.txt |
| @@ -0,0 +1,21 @@ |
| +Phe U U CU |
| +Leu C U GCUA U U GA |
| +Ser U C GCUA A G CU |
| +Tyr U A CU |
| +STOP U A GA U G A |
| +Cys U G CU |
| +Trp U G G |
| +Pro C C GCUA |
| +His C A CU |
| +Gln C A GA |
| +Arg C G GCUA A G GA |
| +Ile A U CUA |
| +Met A U G |
| +Thr A C GCUA |
| +Asn A A CU |
| +Lys A A GA |
| +Val G U GCUA |
| +Asp G A CU |
| +Glu G A GA |
| +Gly G G GCUA |
| +Ala G C GCUA |
| \ No newline at end of file |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm2-hash/codon_usage_freq_table_human.csv b/tests/fixtures/functions/cleanroom-algorithm2-hash/codon_usage_freq_table_human.csv |
| new file mode 100644 |
| index 0000000..4e49f4f |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-algorithm2-hash/codon_usage_freq_table_human.csv |
| @@ -0,0 +1,65 @@ |
| +#,, |
| +UAA,*,0.28 |
| +UAG,*,0.2 |
| +UGA,*,0.52 |
| +GCU,A,0.26 |
| +GCC,A,0.4 |
| +GCA,A,0.23 |
| +GCG,A,0.11 |
| +UGU,C,0.45 |
| +UGC,C,0.55 |
| +GAU,D,0.46 |
| +GAC,D,0.54 |
| +GAA,E,0.42 |
| +GAG,E,0.58 |
| +UUU,F,0.45 |
| +UUC,F,0.55 |
| +GGU,G,0.16 |
| +GGC,G,0.34 |
| +GGA,G,0.25 |
| +GGG,G,0.25 |
| +CAU,H,0.41 |
| +CAC,H,0.59 |
| +AUU,I,0.36 |
| +AUC,I,0.48 |
| +AUA,I,0.16 |
| +AAA,K,0.42 |
| +AAG,K,0.58 |
| +UUA,L,0.07 |
| +UUG,L,0.13 |
| +CUU,L,0.13 |
| +CUC,L,0.2 |
| +CUA,L,0.07 |
| +CUG,L,0.41 |
| +AUG,M,1 |
| +AAU,N,0.46 |
| +AAC,N,0.54 |
| +CCU,P,0.28 |
| +CCC,P,0.33 |
| +CCA,P,0.27 |
| +CCG,P,0.11 |
| +CAA,Q,0.25 |
| +CAG,Q,0.75 |
| +CGU,R,0.08 |
| +CGC,R,0.19 |
| +CGA,R,0.11 |
| +CGG,R,0.21 |
| +AGA,R,0.2 |
| +AGG,R,0.2 |
| +UCU,S,0.18 |
| +UCC,S,0.22 |
| +UCA,S,0.15 |
| +UCG,S,0.06 |
| +AGU,S,0.15 |
| +AGC,S,0.24 |
| +ACU,T,0.24 |
| +ACC,T,0.36 |
| +ACA,T,0.28 |
| +ACG,T,0.12 |
| +GUU,V,0.18 |
| +GUC,V,0.24 |
| +GUA,V,0.11 |
| +GUG,V,0.47 |
| +UGG,W,1 |
| +UAU,Y,0.43 |
| +UAC,Y,0.57 |
| \ No newline at end of file |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm2-hash/stdin b/tests/fixtures/functions/cleanroom-algorithm2-hash/stdin |
| new file mode 100644 |
| index 0000000..fb9dfbf |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-algorithm2-hash/stdin |
| @@ -0,0 +1 @@ |
| +GTITVEELKKLLEQWNLVIGFLFLTWICLLQFAYANRN |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm2-hash/stdin2 b/tests/fixtures/functions/cleanroom-algorithm2-hash/stdin2 |
| new file mode 100644 |
| index 0000000..f2d207f |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-algorithm2-hash/stdin2 |
| @@ -0,0 +1 @@ |
| +RLSRLRRRSRSLRLLSLLRLLLRSRSLSSSRSSLRRSSRSSLRLLRLRRRLRLLSLLRSRSLRRRRLRLRLLRRRSRRSLLLLSSLSSSLLRRLRLLSSSLLLLLRLSRSLSLLLRSLRSSLSSLLRRLLSLLSSLRLRRLLRRSRLLLSLRSLSRLLSRLSSRRRRSRLRLRRLRSLLRRSRSRSSLLLRRRLRRRSRSRRRLLSSRSRSSRSLRSSSLSLLRRLRLRRSRLLSSLSRSRRLLSLSLSRSSSSSSSLSRLLSLRSRLSSSLSSLLLSSRSSLRSSRLSRRSRSLSLSRSRLLRSLLSLSRLSSLRLRRSSLRSSRLRLLLRLRSRLSLLLLRSSSRSLLLLLLRSSSRRRLRSSRSLRRSLSLRLLLLRSLLLLRSSSLSSLSRRRSSRSLRSRLRLLRLSRSLRRSSLSLSLRSLLLLLSRSRSRSSSRRSLLSRLLLSSRLLSRRRSSSLRSLRRSRSLRRLRLRRLLSRLLLLLRLRRSRSRLLRRLRRLLLLRRRRRRSRLSLLLLLLLLRLRLRLSSSRSLRSRRRSSSSLRLLLSSRRSSSLSLSLSSLRLSLSRLSRLRRSRSRLRLRSSLRRRSSLSRRSRRLLRSRLLRRRRSRSRSRLLSSLSSLRSLSRSRSSLSSSLSLRRLSLLRLLRSSLLRSLSLRRRRRSLSRRSLRRLLSSSSLRSSSLRLSRSLSSSRLSLSSSSSRSLRRLRLLSSLLRSSSLSRLRLLRLSRRSLRRSSSLRSLSLRRLLSSRLLRLRLRSRSLLLRLLRRRLLLSLLRRLLSLSLLRSLLSRSLRRRSSRLLLSSRSRLLRLLRSSSRSRLLSSLLRLSRRLSSSSSSRLLLSSSLLRLLLSSRSSSSRLRLRLSLSLLLRRLSLLLLRLSLLRLSLRRLSSRSLSLSRSSRLSLLRLRRRRRRRLLLSRLRRRLSRLLLLRSSSLRSRRSSLLRSSLSLLLSRRRRRLLLLSLSLLSLLLRSSSSRLRLLRLSSLLLSRSSLSRSLLRSSRRRSLRRRSLRSSLRSRSSSLSLSRSLRSSRLRLRLRRRRLRRSSRRLLRLSSRSSLSSRRSRLSSSRLRSLRLLRRRSRLSRSRRRSRRLSRLSLSLLSSSRSRRSRRLRRLRSLRLSRLRRRRLSSSLSRSSRLRSRRSLRLSLLLLRSRLLSRSLSRSSRLLLRRRRSLLRSSRSRLRLRSLSRSLLLLSRRRLLLLSRRSSSRRRSSLRRSSLSLLLRLRRLRRLSLLSLRRRRRLSSLSRSSSLLSRSLRLSLSLRLSRLLLRRSLLSLRLRRSLRLSRSLLSLSRSRRRSSSLSSSRRLLRSLRSRSSLLSRLSRRSRLSLSRSSRSRLLRRRRLSSLSLSLSLLRLSRSLRLSSSSRRLSRSSSRSSSRLLLSRRLSRSSRLRSSLSSSSLLSLSLRRLLRSLRSRLSLSSRSRRLSSRRRLSRLLSLSLSRSRRLRRRLRLLRLSSSRSSRRSSSRRLLRSSLSSRLLRLLRLSRRLLRRLLSSSLRSS |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm2-hash/stdout.enc b/tests/fixtures/functions/cleanroom-algorithm2-hash/stdout.enc |
| new file mode 100644 |
| index 0000000..cf42d1c |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-algorithm2-hash/stdout.enc differ |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm2/stdin b/tests/fixtures/functions/cleanroom-algorithm2/stdin |
| new file mode 100644 |
| index 0000000..850871e |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-algorithm2/stdin |
| @@ -0,0 +1 @@ |
| +MADSNGTITVEELKKLLEQWNLVIGFLFLTWICLLQFAYANR |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm2/testseq.enc b/tests/fixtures/functions/cleanroom-algorithm2/testseq.enc |
| new file mode 100644 |
| index 0000000..c485ca1 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-algorithm2/testseq.enc differ |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/app.cpk b/tests/fixtures/functions/cleanroom-algorithm1/app.cpk |
| new file mode 100644 |
| index 0000000..b776cd9 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-algorithm1/app.cpk differ |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/cleanroom-app-aot.cpk b/tests/fixtures/functions/cleanroom-algorithm1/cleanroom-app-aot.cpk |
| new file mode 100644 |
| index 0000000..a67ab93 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-algorithm1/cleanroom-app-aot.cpk differ |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/cleanroom-app.cpk b/tests/fixtures/functions/cleanroom-algorithm1/cleanroom-app.cpk |
| new file mode 100644 |
| index 0000000..e4f1f34 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-algorithm1/cleanroom-app.cpk differ |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/cleanroom-diagnostic.cpk b/tests/fixtures/functions/cleanroom-algorithm1/cleanroom-diagnostic.cpk |
| new file mode 100644 |
| index 0000000..2de3035 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-algorithm1/cleanroom-diagnostic.cpk differ |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/example.shape b/tests/fixtures/functions/cleanroom-algorithm1/example.shape |
| new file mode 100644 |
| index 0000000..7ccc399 |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-algorithm1/example.shape |
| @@ -0,0 +1,114 @@ |
| +1 NA |
| +2 NA |
| +3 NA |
| +4 NA |
| +5 NA |
| +6 NA |
| +7 NA |
| +8 NA |
| +9 2.0303 |
| +10 3.4545 |
| +11 3.9093 |
| +12 3.3998 |
| +13 2.4215 |
| +14 1.5185 |
| +15 0.26599 |
| +16 0.044856 |
| +17 0 |
| +18 0.24481 |
| +19 0.26915 |
| +20 0.39516 |
| +21 0.42047 |
| +22 0.29272 |
| +23 0.1189 |
| +24 0.10819 |
| +25 0.06756 |
| +26 0.1099 |
| +27 1.1082 |
| +28 0.51335 |
| +29 0.8531 |
| +30 1.2355 |
| +31 1.5989 |
| +32 1.234 |
| +33 1.014 |
| +34 1.1945 |
| +35 0.098511 |
| +36 0.11049 |
| +37 0.061875 |
| +38 0.10532 |
| +39 0.096157 |
| +40 0.10929 |
| +41 0.042156 |
| +42 0.16029 |
| +43 0.32049 |
| +44 1.1684 |
| +45 1.4619 |
| +46 0.040105 |
| +47 0.0025812 |
| +48 0.034826 |
| +49 0.057291 |
| +50 0.039333 |
| +51 0 |
| +52 0.028677 |
| +53 0.21812 |
| +54 0.022805 |
| +55 0.00021709 |
| +56 0.013873 |
| +57 0.013754 |
| +58 0 |
| +59 0 |
| +60 0 |
| +61 0.25117 |
| +62 0.43657 |
| +63 0.43743 |
| +64 0.50744 |
| +65 0.085134 |
| +66 0.019398 |
| +67 0.023139 |
| +68 0.00074496 |
| +69 0 |
| +70 0 |
| +71 0.39526 |
| +72 0.059399 |
| +73 0.033083 |
| +74 0.01536 |
| +75 0.0031007 |
| +76 0.013488 |
| +77 0.010088 |
| +78 0 |
| +79 0 |
| +80 0 |
| +81 0 |
| +82 0.0076068 |
| +83 0.061887 |
| +84 0.031508 |
| +85 0 |
| +86 0 |
| +87 0.023431 |
| +88 0.045501 |
| +89 0.093281 |
| +90 0.27861 |
| +91 0.3089 |
| +92 2.4142 |
| +93 0.24535 |
| +94 0.18949 |
| +95 0.033237 |
| +96 0 |
| +97 0 |
| +98 0.020459 |
| +99 0.24343 |
| +100 1.5 |
| +101 0.14023 |
| +102 0.40887 |
| +103 0.022548 |
| +104 0.018817 |
| +105 0.013818 |
| +106 0.0041629 |
| +107 0.0095489 |
| +108 0.013491 |
| +109 0 |
| +110 0 |
| +111 0.018041 |
| +112 0.013599 |
| +113 0 |
| +114 0.0035904 |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/algorithm1.aot b/tests/fixtures/functions/cleanroom-algorithm1/algorithm1.aot |
| new file mode 100644 |
| index 0000000..ccb75a8 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-algorithm1/algorithm1.aot differ |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/algorithm1_c b/tests/fixtures/functions/cleanroom-algorithm1/algorithm1_c |
| new file mode 100755 |
| index 0000000..065aa0f |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-algorithm1/algorithm1_c differ |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/algorithm1_v b/tests/fixtures/functions/cleanroom-algorithm1/algorithm1_v |
| new file mode 100755 |
| index 0000000..f68344b |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-algorithm1/algorithm1_v differ |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/stdin b/tests/fixtures/functions/cleanroom-algorithm1/stdin |
| new file mode 100644 |
| index 0000000..6949dd6 |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-algorithm1/stdin |
| @@ -0,0 +1 @@ |
| +GCCUGGUGACCAUAGCGAGUCGGUACCACCCCUUCCCAUCCCGAACAGGACCGUGAAACGACUCCGCGCCGAUGAUAGUGCGGAUUCCCGUGUGAAAGUAGGUCAUCGCCAGGC |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/testseq b/tests/fixtures/functions/cleanroom-algorithm1/testseq |
| new file mode 100644 |
| index 0000000..6949dd6 |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-algorithm1/testseq |
| @@ -0,0 +1 @@ |
| +GCCUGGUGACCAUAGCGAGUCGGUACCACCCCUUCCCAUCCCGAACAGGACCGUGAAACGACUCCGCGCCGAUGAUAGUGCGGAUUCCCGUGUGAAAGUAGGUCAUCGCCAGGC |
| diff --git a/tests/fixtures/functions/cleanroom-algorithm1/testseq.enc b/tests/fixtures/functions/cleanroom-algorithm1/testseq.enc |
| new file mode 100644 |
| index 0000000..e9e7cc4 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-algorithm1/testseq.enc differ |
| diff --git a/tests/fixtures/functions/cleanroom-readfile/Makefile b/tests/fixtures/functions/cleanroom-readfile/Makefile |
| new file mode 100644 |
| index 0000000..7aadce1 |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-readfile/Makefile |
| @@ -0,0 +1,15 @@ |
| +# C program |
| +CC = $(CRW_SDK_PATH)/bin/clang |
| +CFLAGS += --sysroot=$(CRW_SDK_PATH)/share/wasi-sysroot -Wl,--export=malloc -Wl,--export=free |
| + |
| +# C++ Program |
| +CXX = $(CRW_SDK_PATH)/bin/clang++ |
| +CXXFLAGS += --sysroot=$(CRW_SDK_PATH)/share/wasi-sysroot -fno-exceptions -Wl,--export=malloc -Wl,--export=free |
| + |
| +all: wasm |
| + |
| +wasm: |
| + $(CXX) readfile.cpp $(CXXFLAGS) -o readfile.wasm |
| + |
| +clean: |
| + rm -f *.elf *.wasm |
| diff --git a/tests/fixtures/functions/cleanroom-readfile/data/a.txt b/tests/fixtures/functions/cleanroom-readfile/data/a.txt |
| new file mode 100644 |
| index 0000000..7113212 |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-readfile/data/a.txt |
| @@ -0,0 +1,3 @@ |
| +dsfsdafsdafsdafsdafsdafsdaklfjsdaklfjsaldfjsldafjdlsafjsdaklfjsadlfjsda |
| +hello |
| +cleanroom |
| diff --git a/tests/fixtures/functions/cleanroom-readfile/readfile.cpp b/tests/fixtures/functions/cleanroom-readfile/readfile.cpp |
| new file mode 100644 |
| index 0000000..9ee97ba |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-readfile/readfile.cpp |
| @@ -0,0 +1,18 @@ |
| +#include <iostream> |
| +#include <fstream> |
| + |
| + |
| +int main(){ |
| +char line[200]; |
| +std::ifstream rfile; |
| +rfile.open("data/a.txt"); |
| +if (rfile.is_open()) { |
| + while (rfile.getline(line, 200)) { |
| + std::cout << line << std::endl; |
| + } |
| + rfile.close(); |
| +} |
| +else { |
| + std::cout << "can not open the file\n"; |
| +} |
| +} |
| diff --git a/tests/fixtures/functions/cleanroom-readfile/readfile.wasm b/tests/fixtures/functions/cleanroom-readfile/readfile.wasm |
| new file mode 100755 |
| index 0000000..9346ae2 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-readfile/readfile.wasm differ |
| diff --git a/tests/fixtures/functions/cleanroom-readfile/stdin b/tests/fixtures/functions/cleanroom-readfile/stdin |
| new file mode 100644 |
| index 0000000..e69de29 |
| diff --git a/tests/fixtures/functions/cleanroom-stderr/Makefile b/tests/fixtures/functions/cleanroom-stderr/Makefile |
| new file mode 100644 |
| index 0000000..568eeb6 |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-stderr/Makefile |
| @@ -0,0 +1,14 @@ |
| +CXX=$(CRW_SDK_PATH)/bin/clang++ |
| +CXXFLAGS += --sysroot=$(CRW_SDK_PATH)/share/wasi-sysroot -fno-exceptions -Wl,--export=malloc -Wl,--export=free |
| + |
| + |
| +all: wasm |
| + |
| +wasm: |
| + $(CXX) app.cpp $(CXXFLAGS) -o app.wasm |
| + |
| +elf: |
| + g++ app.cpp -o app.elf |
| + |
| +clean: |
| + rm -f *.wasm *.elf |
| diff --git a/tests/fixtures/functions/cleanroom-stderr/app.cpk b/tests/fixtures/functions/cleanroom-stderr/app.cpk |
| new file mode 100644 |
| index 0000000..f0357eb |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-stderr/app.cpk differ |
| diff --git a/tests/fixtures/functions/cleanroom-stderr/app.cpp b/tests/fixtures/functions/cleanroom-stderr/app.cpp |
| new file mode 100644 |
| index 0000000..d377cae |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-stderr/app.cpp |
| @@ -0,0 +1,12 @@ |
| + |
| + |
| +#include <iostream> |
| + |
| +int main(int argc, char** argv) { |
| + if (argc != 5){ |
| + std::cerr << "The number of arguments is not 5"; |
| + } |
| + for (int i = i; i < 5; ++i) { |
| + std::cout << argv[i] << std::endl; |
| + } |
| +} |
| diff --git a/tests/fixtures/functions/cleanroom-stderr/app.wasm b/tests/fixtures/functions/cleanroom-stderr/app.wasm |
| new file mode 100755 |
| index 0000000..3cb3bbe |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-stderr/app.wasm differ |
| diff --git a/tests/fixtures/functions/cleanroom-stderr/stdin b/tests/fixtures/functions/cleanroom-stderr/stdin |
| new file mode 100644 |
| index 0000000..e69de29 |
| diff --git a/tests/fixtures/functions/cleanroom-stderr/testseq.enc b/tests/fixtures/functions/cleanroom-stderr/testseq.enc |
| new file mode 100644 |
| index 0000000..e9e7cc4 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-stderr/testseq.enc differ |
| diff --git a/tests/fixtures/functions/cleanroom-stdin/Makefile b/tests/fixtures/functions/cleanroom-stdin/Makefile |
| new file mode 100644 |
| index 0000000..4ade41c |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-stdin/Makefile |
| @@ -0,0 +1,14 @@ |
| +CC = $(CRW_SDK_PATH)/bin/clang |
| +CFLAGS += --sysroot=$(CRW_SDK_PATH)/share/wasi-sysroot -Wl,--export=malloc -Wl,--export=free |
| +CXX = $(CRW_SDK_PATH)/bin/clang++ |
| +CXXFLAGS += --sysroot=$(CRW_SDK_PATH)/share/wasi-sysroot -fno-exceptions -Wl,--export=malloc -Wl,--export=free |
| + |
| + |
| +all: wasm |
| + |
| + |
| +wasm: |
| + $(CXX) getline.cpp $(CXXFLAGS) -o getline.wasm |
| + |
| +clean: |
| + rm -f getline.wasm |
| diff --git a/tests/fixtures/functions/cleanroom-stdin/getline.cpp b/tests/fixtures/functions/cleanroom-stdin/getline.cpp |
| new file mode 100644 |
| index 0000000..d9c02b2 |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-stdin/getline.cpp |
| @@ -0,0 +1,16 @@ |
| +#include <iostream> |
| +#include <string> |
| + |
| +int main () |
| +{ |
| + std::string name; |
| + |
| + |
| + std::getline (std::cin,name); |
| + std::cout << name; |
| + |
| + |
| + return 0; |
| +} |
| + |
| + |
| diff --git a/tests/fixtures/functions/cleanroom-stdin/getline.wasm b/tests/fixtures/functions/cleanroom-stdin/getline.wasm |
| new file mode 100755 |
| index 0000000..b91d583 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-stdin/getline.wasm differ |
| diff --git a/tests/fixtures/functions/cleanroom-stdin/stdin b/tests/fixtures/functions/cleanroom-stdin/stdin |
| new file mode 100644 |
| index 0000000..7a9a89b |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-stdin/stdin |
| @@ -0,0 +1 @@ |
| +ASDSADSADSADSADSADSADSADAS |
| diff --git a/tests/fixtures/functions/cleanroom-stdout/Makefile b/tests/fixtures/functions/cleanroom-stdout/Makefile |
| new file mode 100644 |
| index 0000000..4dacdf4 |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-stdout/Makefile |
| @@ -0,0 +1,14 @@ |
| +CC = $(CRW_SDK_PATH)/bin/clang |
| +CFLAGS += --sysroot=$(CRW_SDK_PATH)/share/wasi-sysroot -Wl,--export=malloc -Wl,--export=free |
| +CXX = $(CRW_SDK_PATH)/bin/clang++ |
| +CXXFLAGS += --sysroot=$(CRW_SDK_PATH)/share/wasi-sysroot -fno-exceptions -Wl,--export=malloc -Wl,--export=free |
| + |
| + |
| +all: wasm |
| + |
| + |
| +wasm: |
| + $(CC) helloworld.c $(CFLAGS) -o helloworld.wasm |
| + |
| +clean: |
| + rm -f helloworld.wasm |
| diff --git a/tests/fixtures/functions/cleanroom-stdout/helloworld.c b/tests/fixtures/functions/cleanroom-stdout/helloworld.c |
| new file mode 100644 |
| index 0000000..5293dc2 |
| --- /dev/null |
| +++ b/tests/fixtures/functions/cleanroom-stdout/helloworld.c |
| @@ -0,0 +1,6 @@ |
| +#include <stdio.h> |
| + |
| +int main(){ |
| + printf("hello world cleanroom!"); |
| + return 0; |
| +} |
| diff --git a/tests/fixtures/functions/cleanroom-stdout/helloworld.wasm b/tests/fixtures/functions/cleanroom-stdout/helloworld.wasm |
| new file mode 100755 |
| index 0000000..b322577 |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-stdout/helloworld.wasm differ |
| diff --git a/tests/fixtures/functions/cleanroom-stdout/stdin b/tests/fixtures/functions/cleanroom-stdout/stdin |
| new file mode 100644 |
| index 0000000..e69de29 |
| diff --git a/tests/fixtures/functions/cleanroom-stdout/test.aot b/tests/fixtures/functions/cleanroom-stdout/test.aot |
| new file mode 100644 |
| index 0000000..e07d8bb |
| Binary files /dev/null and b/tests/fixtures/functions/cleanroom-stdout/test.aot differ |
| diff --git a/tests/functional/app/Cargo.toml b/tests/functional/app/Cargo.toml |
| index 5184716..734a535 100644 |
| --- a/tests/functional/app/Cargo.toml |
| +++ b/tests/functional/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_functional_tests" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Enclave test driver" |
| license = "Apache-2.0" |
| @@ -25,7 +25,7 @@ build = "build.rs" |
| edition = "2018" |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| env_logger = { version = "0.7.1" } |
| anyhow = { version = "1.0.26" } |
| structopt = { version = "0.3" } |
| diff --git a/tests/functional/enclave/Cargo.toml b/tests/functional/enclave/Cargo.toml |
| index e45af59..6d7d6e5 100644 |
| --- a/tests/functional/enclave/Cargo.toml |
| +++ b/tests/functional/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_functional_tests_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Service Functional Test" |
| license = "Apache-2.0" |
| @@ -48,7 +48,7 @@ cov = ["teaclave_service_enclave_utils/cov"] |
| anyhow = { version = "1.0.26" } |
| inventory = { version = "0.1.6" } |
| lazy_static = { version = "1.4.0" } |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| serde = { version = "1.0.92" } |
| serde_json = { version = "1.0.39" } |
| thiserror = { version = "1.0.9" } |
| diff --git a/tests/functional/enclave/src/end_to_end/builtin_echo.rs b/tests/functional/enclave/src/end_to_end/builtin_echo.rs |
| index 15a1f68..75a33c4 100644 |
| --- a/tests/functional/enclave/src/end_to_end/builtin_echo.rs |
| +++ b/tests/functional/enclave/src/end_to_end/builtin_echo.rs |
| @@ -27,11 +27,12 @@ pub fn test_echo_task_success() { |
| let mut client = |
| create_frontend_client(shared_enclave_info(), FRONTEND_SERVICE_ADDR, cred).unwrap(); |
| |
| + let function_arg = FunctionArgument::new("message", "", true); |
| // Register Function |
| let request = RegisterFunctionRequestBuilder::new() |
| .name("builtin-echo") |
| .description("Native Echo Function") |
| - .arguments(vec!["message"]) |
| + .arguments(vec![function_arg]) |
| .build(); |
| |
| let response = client.register_function(request).unwrap(); |
| diff --git a/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs b/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs |
| index b323666..a47f87b 100644 |
| --- a/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs |
| +++ b/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs |
| @@ -49,15 +49,15 @@ fn register_gbdt_function(client: &mut TeaclaveFrontendClient) -> ExternalID { |
| let fn_input = FunctionInput::new("training_data", "Input traning data file.", false); |
| let fn_output = FunctionOutput::new("trained_model", "Output trained model.", false); |
| let fn_args = vec![ |
| - "feature_size", |
| - "max_depth", |
| - "iterations", |
| - "shrinkage", |
| - "feature_sample_ratio", |
| - "data_sample_ratio", |
| - "min_leaf_size", |
| - "loss", |
| - "training_optimization_level", |
| + FunctionArgument::new("feature_size", "", true), |
| + FunctionArgument::new("max_depth", "", true), |
| + FunctionArgument::new("iterations", "", true), |
| + FunctionArgument::new("shrinkage", "", true), |
| + FunctionArgument::new("feature_sample_ratio", "", true), |
| + FunctionArgument::new("data_sample_ratio", "", true), |
| + FunctionArgument::new("min_leaf_size", "", true), |
| + FunctionArgument::new("loss", "", true), |
| + FunctionArgument::new("training_optimization_level", "", true), |
| ]; |
| |
| // Register Function |
| diff --git a/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs b/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs |
| index 69047de..8668290 100644 |
| --- a/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs |
| +++ b/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs |
| @@ -231,10 +231,11 @@ def entrypoint(argv): |
| "#; |
| |
| let input_spec = FunctionInput::new("InputData", "Lines of Data", false); |
| + let function_arg = FunctionArgument::new("query", "", true); |
| let request = RegisterFunctionRequestBuilder::new() |
| .name("wlc") |
| .description("Mesapy Word Line Count Function") |
| - .arguments(vec!["query"]) |
| + .arguments(vec![function_arg]) |
| .payload(script.into()) |
| .executor_type(ExecutorType::Python) |
| .public(true) |
| diff --git a/tests/functional/enclave/src/end_to_end/mesapy_echo.rs b/tests/functional/enclave/src/end_to_end/mesapy_echo.rs |
| index 42d1fb6..b577e59 100644 |
| --- a/tests/functional/enclave/src/end_to_end/mesapy_echo.rs |
| +++ b/tests/functional/enclave/src/end_to_end/mesapy_echo.rs |
| @@ -33,6 +33,7 @@ def entrypoint(argv): |
| assert argv[1] is not None |
| return argv[1] |
| "; |
| + let function_arg = FunctionArgument::new("message", "", true); |
| // Register Function |
| let request = RegisterFunctionRequestBuilder::new() |
| .name("mesapy_echo_demo") |
| @@ -40,7 +41,7 @@ def entrypoint(argv): |
| .payload(script.into()) |
| .executor_type(ExecutorType::Python) |
| .public(true) |
| - .arguments(vec!["message"]) |
| + .arguments(vec![function_arg]) |
| .build(); |
| |
| let response = client.register_function(request).unwrap(); |
| diff --git a/tests/functional/enclave/src/execution_service.rs b/tests/functional/enclave/src/execution_service.rs |
| index 67af16d..00fe7f5 100644 |
| --- a/tests/functional/enclave/src/execution_service.rs |
| +++ b/tests/functional/enclave/src/execution_service.rs |
| @@ -53,7 +53,7 @@ fn test_execute_function() { |
| let put_request = PutRequest::new(ts.key().as_slice(), ts.to_vec().unwrap().as_slice()); |
| let _put_response = storage_client.put(put_request).unwrap(); |
| |
| - std::thread::sleep(std::time::Duration::from_secs(15)); |
| + std::thread::sleep(std::time::Duration::from_secs(80)); |
| |
| let get_request = GetRequest::new(ts.key().as_slice()); |
| let get_response = storage_client.get(get_request).unwrap(); |
| diff --git a/tests/functional/enclave/src/management_service.rs b/tests/functional/enclave/src/management_service.rs |
| index 7a975b1..9390998 100644 |
| --- a/tests/functional/enclave/src/management_service.rs |
| +++ b/tests/functional/enclave/src/management_service.rs |
| @@ -128,12 +128,13 @@ fn test_get_input_file() { |
| fn test_register_function() { |
| let function_input = FunctionInput::new("input", "input_desc", false); |
| let function_output = FunctionOutput::new("output", "output_desc", false); |
| + let function_arg = FunctionArgument::new("arg", "", true); |
| let request = RegisterFunctionRequestBuilder::new() |
| .name("mock_function") |
| .executor_type(ExecutorType::Python) |
| .payload(b"def entrypoint:\n\treturn".to_vec()) |
| .public(true) |
| - .arguments(vec!["arg"]) |
| + .arguments(vec![function_arg]) |
| .inputs(vec![function_input]) |
| .outputs(vec![function_output]) |
| .build(); |
| @@ -148,12 +149,13 @@ fn test_register_function() { |
| fn test_register_private_function() { |
| let function_input = FunctionInput::new("input", "input_desc", false); |
| let function_output = FunctionOutput::new("output", "output_desc", false); |
| + let function_arg = FunctionArgument::new("arg", "", true); |
| let request = RegisterFunctionRequestBuilder::new() |
| .name("mock_function") |
| .executor_type(ExecutorType::Python) |
| .payload(b"def entrypoint:\n\treturn".to_vec()) |
| .public(false) |
| - .arguments(vec!["arg"]) |
| + .arguments(vec![function_arg]) |
| .inputs(vec![function_input]) |
| .outputs(vec![function_output]) |
| .user_allowlist(vec!["mock_user".to_string()]) |
| @@ -169,12 +171,13 @@ fn test_register_private_function() { |
| fn test_delete_function() { |
| let function_input = FunctionInput::new("input", "input_desc", false); |
| let function_output = FunctionOutput::new("output", "output_desc", false); |
| + let function_arg = FunctionArgument::new("arg", "", true); |
| let request = RegisterFunctionRequestBuilder::new() |
| .name("mock_function") |
| .executor_type(ExecutorType::Python) |
| .payload(b"def entrypoint:\n\treturn".to_vec()) |
| .public(true) |
| - .arguments(vec!["arg"]) |
| + .arguments(vec![function_arg]) |
| .inputs(vec![function_input]) |
| .outputs(vec![function_output]) |
| .build(); |
| @@ -192,12 +195,13 @@ fn test_delete_function() { |
| fn test_disable_function() { |
| let function_input = FunctionInput::new("input", "input_desc", false); |
| let function_output = FunctionOutput::new("output", "output_desc", false); |
| + let function_arg = FunctionArgument::new("arg", "", true); |
| let request = RegisterFunctionRequestBuilder::new() |
| .name("mock_function") |
| .executor_type(ExecutorType::Python) |
| .payload(b"def entrypoint:\n\treturn".to_vec()) |
| .public(true) |
| - .arguments(vec!["arg"]) |
| + .arguments(vec![function_arg]) |
| .inputs(vec![function_input]) |
| .outputs(vec![function_output]) |
| .build(); |
| @@ -215,12 +219,13 @@ fn test_disable_function() { |
| fn test_update_function() { |
| let function_input = FunctionInput::new("input", "input_desc", false); |
| let function_output = FunctionOutput::new("output", "output_desc", false); |
| + let function_arg = FunctionArgument::new("arg", "", true); |
| let request = RegisterFunctionRequestBuilder::new() |
| .name("mock_function") |
| .executor_type(ExecutorType::Python) |
| .payload(b"def entrypoint:\n\treturn".to_vec()) |
| .public(true) |
| - .arguments(vec!["arg"]) |
| + .arguments(vec![function_arg]) |
| .inputs(vec![function_input]) |
| .outputs(vec![function_output]) |
| .build(); |
| @@ -231,13 +236,14 @@ fn test_update_function() { |
| |
| let function_input = FunctionInput::new("input", "input_desc", false); |
| let function_output = FunctionOutput::new("output", "output_desc", false); |
| + let function_arg = FunctionArgument::new("arg", "", true); |
| let request = UpdateFunctionRequestBuilder::new() |
| .function_id(original_id.clone()) |
| .name("mock_function") |
| .executor_type(ExecutorType::Python) |
| .payload(b"def entrypoint:\n\treturn".to_vec()) |
| .public(false) |
| - .arguments(vec!["arg"]) |
| + .arguments(vec![function_arg]) |
| .inputs(vec![function_input]) |
| .outputs(vec![function_output]) |
| .user_allowlist(vec!["mock_user".to_string()]) |
| @@ -266,12 +272,13 @@ fn test_list_functions() { |
| fn test_get_function() { |
| let function_input = FunctionInput::new("input", "input_desc", false); |
| let function_output = FunctionOutput::new("output", "output_desc", false); |
| + let function_arg = FunctionArgument::new("arg", "", true); |
| let request = RegisterFunctionRequestBuilder::new() |
| .name("mock_function") |
| .executor_type(ExecutorType::Python) |
| .payload(b"def entrypoint:\n\treturn".to_vec()) |
| .public(false) |
| - .arguments(vec!["arg"]) |
| + .arguments(vec![function_arg]) |
| .inputs(vec![function_input]) |
| .outputs(vec![function_output]) |
| .build(); |
| diff --git a/tests/integration/app/Cargo.toml b/tests/integration/app/Cargo.toml |
| index b7f858d..a1bf9c2 100644 |
| --- a/tests/integration/app/Cargo.toml |
| +++ b/tests/integration/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_integration_tests" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Integration tests" |
| license = "Apache-2.0" |
| @@ -25,7 +25,7 @@ build = "build.rs" |
| edition = "2018" |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| env_logger = { version = "0.7.1" } |
| anyhow = { version = "1.0.26" } |
| |
| diff --git a/tests/integration/enclave/Cargo.toml b/tests/integration/enclave/Cargo.toml |
| index 8218e51..a856fc5 100644 |
| --- a/tests/integration/enclave/Cargo.toml |
| +++ b/tests/integration/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_integration_tests_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Integration Test" |
| license = "Apache-2.0" |
| @@ -47,7 +47,7 @@ mesalock_sgx = [ |
| cov = ["teaclave_service_enclave_utils/cov"] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| serde = { version = "1.0.92" } |
| serde_json = { version = "1.0.39" } |
| diff --git a/tests/profiling/app/Cargo.toml b/tests/profiling/app/Cargo.toml |
| new file mode 100644 |
| index 0000000..cd85320 |
| --- /dev/null |
| +++ b/tests/profiling/app/Cargo.toml |
| @@ -0,0 +1,41 @@ |
| +# 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. |
| + |
| +[package] |
| +name = "teaclave_profiling" |
| +version = "0.2.0" |
| +authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| +description = "Enclave test driver" |
| +license = "Apache-2.0" |
| +build = "build.rs" |
| +edition = "2018" |
| + |
| +[features] |
| +default = ["teaclave_binder/app_unit_test"] |
| + |
| +[dependencies] |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| +env_logger = { version = "0.7.1" } |
| +anyhow = { version = "1.0.26" } |
| +uuid = { version = "0.8.1", features = ["v4"] } |
| + |
| +teaclave_file_agent = { path = "../../../file_agent" } |
| +teaclave_binder = { path = "../../../binder", features = ["app"] } |
| +teaclave_types = { path = "../../../types" } |
| +teaclave_test_utils = { path = "../../../tests/utils" } |
| + |
| +sgx_types = { version = "1.1.3" } |
| diff --git a/tests/profiling/app/build.rs b/tests/profiling/app/build.rs |
| new file mode 100644 |
| index 0000000..168e837 |
| --- /dev/null |
| +++ b/tests/profiling/app/build.rs |
| @@ -0,0 +1,54 @@ |
| +// 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 std::env; |
| +use std::path::PathBuf; |
| + |
| +fn choose_sgx_dylib(is_sim: bool) { |
| + if is_sim { |
| + println!("cargo:rustc-link-lib=dylib=sgx_urts_sim"); |
| + println!("cargo:rustc-link-lib=dylib=sgx_uae_service_sim"); |
| + } else { |
| + println!("cargo:rustc-link-lib=dylib=sgx_urts"); |
| + println!("cargo:rustc-link-lib=dylib=sgx_uae_service"); |
| + } |
| +} |
| + |
| +fn main() { |
| + let sdk_dir = env::var("SGX_SDK").unwrap_or("/opt/intel/sgxsdk".into()); |
| + println!("cargo:rustc-link-search=native={}/lib64", sdk_dir); |
| + |
| + let out_path = env::var_os("ENCLAVE_OUT_DIR").unwrap_or("out".into()); |
| + let out_dir = &PathBuf::from(out_path); |
| + |
| + println!("cargo:rustc-link-search=native={}", out_dir.display()); |
| + if let Ok(edl_dir) = env::var("TEACLAVE_EDL_DIR") { |
| + println!("cargo:rerun-if-changed={}/Enclave_fa.edl", edl_dir); |
| + } |
| + println!("cargo:rustc-link-lib=static=Enclave_fa_u"); |
| + |
| + let is_sim = match env::var("SGX_MODE") { |
| + Ok(ref v) if v == "SW" => true, |
| + Ok(ref v) if v == "HW" => false, |
| + Err(env::VarError::NotPresent) => false, |
| + _ => { |
| + panic!("Stop build process, wrong SGX_MODE env provided."); |
| + } |
| + }; |
| + |
| + choose_sgx_dylib(is_sim); |
| +} |
| diff --git a/tests/profiling/app/src/main.rs b/tests/profiling/app/src/main.rs |
| new file mode 100644 |
| index 0000000..e0ffae5 |
| --- /dev/null |
| +++ b/tests/profiling/app/src/main.rs |
| @@ -0,0 +1,85 @@ |
| +// 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 log::error; |
| +use std::env; |
| +use std::fs; |
| +use std::io; |
| +use std::io::Write; |
| +use std::time::Instant; |
| +use teaclave_binder::proto::{ECallCommand, RunTestInput, RunTestOutput}; |
| +use teaclave_binder::TeeBinder; |
| +use teaclave_types::TeeServiceResult; |
| +use uuid::Uuid; |
| + |
| +pub use teaclave_file_agent::ocall_handle_file_request; |
| + |
| +fn main() -> anyhow::Result<()> { |
| + env_logger::init_from_env( |
| + env_logger::Env::new() |
| + .filter_or("TEACLAVE_LOG", "RUST_LOG") |
| + .write_style_or("TEACLAVE_LOG_STYLE", "RUST_LOG_STYLE"), |
| + ); |
| + let mut args: Vec<String> = env::args().collect(); |
| + let uuid = Uuid::new_v4().to_string(); |
| + let test_dir = format!("{}{}", "profiling/", uuid); |
| + let stdin_path = format!("{}/{}", test_dir, "stdin"); |
| + let mut seq_buffer = String::new(); |
| + let stdin = io::stdin(); |
| + stdin.read_line(&mut seq_buffer)?; |
| + fs::create_dir_all(test_dir)?; |
| + let mut output = fs::File::create(stdin_path)?; |
| + write!(output, "{}", seq_buffer)?; |
| + args.push(uuid.clone()); |
| + test_app_and_enclave(args); |
| + |
| + let stdout_path = format!("{}/{}/{}", "profiling", uuid, "stdout"); |
| + let contents = fs::read_to_string(stdout_path).expect("Something went wrong reading the file"); |
| + print!("{}", contents); |
| + Ok(()) |
| +} |
| + |
| +fn test_app_and_enclave(args: Vec<String>) { |
| + let tee = TeeBinder::new(env!("CARGO_PKG_NAME")).unwrap(); |
| + tee.run_app_tests(); |
| + run_enclave_tests(&tee, args).unwrap(); |
| + tee.finalize(); |
| +} |
| + |
| +fn start_enclave_unit_test_driver(tee: &TeeBinder, args: Vec<String>) -> anyhow::Result<()> { |
| + let cmd = ECallCommand::RunTest; |
| + let input = RunTestInput::new(args); |
| + let now = Instant::now(); |
| + match tee.invoke::<RunTestInput, TeeServiceResult<RunTestOutput>>(cmd, input) { |
| + Err(e) => { |
| + error!("{:?}", e); |
| + std::process::exit(1); |
| + } |
| + Ok(Err(e)) => { |
| + error!("{:?}", e); |
| + std::process::exit(1); |
| + } |
| + _ => (), |
| + } |
| + println!("Execution time:{}", now.elapsed().as_secs_f32()); |
| + Ok(()) |
| +} |
| + |
| +fn run_enclave_tests(tee: &TeeBinder, args: Vec<String>) -> anyhow::Result<()> { |
| + start_enclave_unit_test_driver(tee, args)?; |
| + Ok(()) |
| +} |
| diff --git a/tests/profiling/enclave/Cargo.toml b/tests/profiling/enclave/Cargo.toml |
| new file mode 100644 |
| index 0000000..8ebbde6 |
| --- /dev/null |
| +++ b/tests/profiling/enclave/Cargo.toml |
| @@ -0,0 +1,87 @@ |
| +# 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. |
| + |
| +[package] |
| +name = "teaclave_profiling_enclave" |
| +version = "0.2.0" |
| +authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| +description = "Enclave Unit Test" |
| +license = "Apache-2.0" |
| +edition = "2018" |
| + |
| +[lib] |
| +name = "teaclave_profiling_enclave" |
| +crate-type = ["staticlib"] |
| + |
| +[features] |
| +default = [] |
| +mesalock_sgx = [ |
| + "sgx_tstd", |
| + "teaclave_binder/mesalock_sgx", |
| + "teaclave_rpc/mesalock_sgx", |
| + "teaclave_service_enclave_utils/mesalock_sgx", |
| + "teaclave_types/mesalock_sgx", |
| + "teaclave_types/enclave_unit_test", |
| + "teaclave_crypto/mesalock_sgx", |
| + "teaclave_crypto/enclave_unit_test", |
| + "teaclave_config/mesalock_sgx", |
| + "teaclave_worker/mesalock_sgx", |
| + "teaclave_worker/enclave_unit_test", |
| + "teaclave_executor/mesalock_sgx", |
| + "teaclave_executor/enclave_unit_test", |
| + "teaclave_function/mesalock_sgx", |
| + "teaclave_function/enclave_unit_test", |
| + "teaclave_runtime/mesalock_sgx", |
| + "teaclave_runtime/enclave_unit_test", |
| + "teaclave_executor_context/mesalock_sgx", |
| + "teaclave_executor_context/enclave_unit_test", |
| + "rusty-leveldb/mesalock_sgx", |
| + "rusty-leveldb/enclave_unit_test", |
| +] |
| +cov = ["teaclave_service_enclave_utils/cov"] |
| + |
| + |
| +full_builtin_function = [ |
| + "builtin_cleanroom_native", |
| +] |
| + |
| +builtin_cleanroom_native = [] |
| + |
| +[dependencies] |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| +anyhow = { version = "1.0.26" } |
| +serde_json = { version = "1.0.39" } |
| +serde = { version = "1.0.92" } |
| +thiserror = { version = "1.0.9" } |
| + |
| +teaclave_worker = { path = "../../../worker" } |
| +teaclave_executor = { path = "../../../executor" } |
| +teaclave_executor_context = { path = "../../../executor/context" } |
| +teaclave_function = { path = "../../../function" } |
| +teaclave_runtime = { path = "../../../runtime" } |
| +rusty-leveldb = { path = "../../../common/rusty_leveldb_sgx", default-features = false, optional = true } |
| + |
| +teaclave_test_utils = { path = "../../utils" } |
| +teaclave_config = { path = "../../../config" } |
| +teaclave_binder = { path = "../../../binder" } |
| +teaclave_rpc = { path = "../../../rpc" } |
| +teaclave_service_enclave_utils = { path = "../../../services/utils/service_enclave_utils" } |
| +teaclave_types = { path = "../../../types" } |
| +teaclave_crypto = { path = "../../../crypto" } |
| + |
| +sgx_tstd = { version = "1.1.3", features = ["net", "thread", "backtrace"], optional = true } |
| +sgx_types = { version = "1.1.3" } |
| diff --git a/tests/profiling/enclave/Enclave.config.xml b/tests/profiling/enclave/Enclave.config.xml |
| new file mode 100644 |
| index 0000000..2b2a339 |
| --- /dev/null |
| +++ b/tests/profiling/enclave/Enclave.config.xml |
| @@ -0,0 +1,36 @@ |
| +<!-- |
| + ~ 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. |
| + ~ |
| +--> |
| +<!-- Please refer to User's Guide for the explanation of each field --> |
| +<EnclaveConfiguration> |
| + <ProdID>0</ProdID> |
| + <ISVSVN>0</ISVSVN> |
| + <StackMaxSize>0x200000</StackMaxSize> |
| + <HeapMaxSize>0x100000000</HeapMaxSize> |
| + <TCSNum>22</TCSNum> |
| + <TCSPolicy>0</TCSPolicy> |
| + <DisableDebug>0</DisableDebug> |
| + <MiscSelect>0</MiscSelect> |
| + <MiscMask>0xFFFFFFFF</MiscMask> |
| + <ReservedMemMinSize> 0x2000000</ReservedMemMinSize> |
| + <ReservedMemInitSize>0x2000000</ReservedMemInitSize> |
| + <ReservedMemMaxSize> 0x8000000</ReservedMemMaxSize> |
| + <!-- On SGX1 platform, ReservedMemExecutable==1 means set reserved memory as read, write and execute (RWX) --> |
| + <ReservedMemExecutable>1</ReservedMemExecutable> |
| +</EnclaveConfiguration> |
| diff --git a/tests/profiling/enclave/src/lib.rs b/tests/profiling/enclave/src/lib.rs |
| new file mode 100644 |
| index 0000000..ad45143 |
| --- /dev/null |
| +++ b/tests/profiling/enclave/src/lib.rs |
| @@ -0,0 +1,108 @@ |
| +// 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_attr(feature = "mesalock_sgx", no_std)] |
| +#[cfg(feature = "mesalock_sgx")] |
| +extern crate sgx_tstd as std; |
| + |
| +#[cfg(feature = "mesalock_sgx")] |
| +use std::collections::HashMap; |
| +use std::format; |
| +use std::prelude::v1::*; |
| +use teaclave_crypto::*; |
| +use teaclave_runtime::*; |
| +use teaclave_types::*; |
| + |
| +const IN_STDIN_FILE: &str = "input_file"; |
| +const OUT_STDOUT_FILE: &str = "output_file"; |
| + |
| +use teaclave_binder::proto::{ |
| + ECallCommand, FinalizeEnclaveInput, FinalizeEnclaveOutput, InitEnclaveInput, InitEnclaveOutput, |
| + RunTestInput, RunTestOutput, |
| +}; |
| +use teaclave_binder::{handle_ecall, register_ecall_handler}; |
| +use teaclave_function::Algorithm2HashTrialTier2; |
| +use teaclave_service_enclave_utils::ServiceEnclave; |
| +use teaclave_types::FunctionArguments; |
| +use teaclave_types::{self, TeeServiceResult}; |
| + |
| +#[handle_ecall] |
| +fn handle_run_test(args: &RunTestInput) -> TeeServiceResult<RunTestOutput> { |
| + let mut args_vec = args.test_names.clone(); |
| + let args_len = args_vec.len(); |
| + let uuid_vec = args_vec.split_off(args_len - 1); |
| + let uuid = uuid_vec[0].clone(); |
| + |
| + let args_json = serde_json::to_string(&args_vec).unwrap(); |
| + let mut args = HashMap::new(); |
| + args.insert("args".to_string(), args_json); |
| + let args = FunctionArguments::from(args); |
| + |
| + let stdin = format!("{}/{}/{}", "profiling", uuid, "stdin"); |
| + let input_info = StagedFileInfo::new(stdin, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let stdout = format!("{}/{}/{}", "profiling", uuid, "stdout"); |
| + let output_info = |
| + StagedFileInfo::new(stdout, TeaclaveFile128Key::random(), FileAuthTag::mock()); |
| + |
| + let config_file1 = "./coding_wheel.txt"; |
| + let config_file_info1 = StagedFileInfo::new( |
| + config_file1, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let config_file2 = "./codon_usage_freq_table_human.csv"; |
| + let config_file_info2 = StagedFileInfo::new( |
| + config_file2, |
| + TeaclaveFile128Key::random(), |
| + FileAuthTag::mock(), |
| + ); |
| + |
| + let input_files = StagedFiles::new( |
| + hashmap!(IN_STDIN_FILE => input_info, "./coding_wheel.txt" => config_file_info1, "./codon_usage_freq_table_human.csv" => config_file_info2), |
| + ); |
| + |
| + let output_files = StagedFiles::new(hashmap!(OUT_STDOUT_FILE => output_info)); |
| + let runtime = Box::new(RawIoRuntime::new(input_files, output_files)); |
| + let function = Algorithm2HashTrialTier2; |
| + |
| + let summary = function.run(args, runtime).unwrap(); |
| + if summary.contains("Succeeded") { |
| + return Ok(RunTestOutput); |
| + } |
| + Err(TeeServiceError::ServiceError) |
| +} |
| + |
| +#[handle_ecall] |
| +fn handle_init_enclave(_: &InitEnclaveInput) -> TeeServiceResult<InitEnclaveOutput> { |
| + ServiceEnclave::init(env!("CARGO_PKG_NAME"))?; |
| + Ok(InitEnclaveOutput) |
| +} |
| + |
| +#[handle_ecall] |
| +fn handle_finalize_enclave(_: &FinalizeEnclaveInput) -> TeeServiceResult<FinalizeEnclaveOutput> { |
| + ServiceEnclave::finalize()?; |
| + Ok(FinalizeEnclaveOutput) |
| +} |
| + |
| +register_ecall_handler!( |
| + type ECallCommand, |
| + (ECallCommand::RunTest, RunTestInput, RunTestOutput), |
| + (ECallCommand::InitEnclave, InitEnclaveInput, InitEnclaveOutput), |
| + (ECallCommand::FinalizeEnclave, FinalizeEnclaveInput, FinalizeEnclaveOutput), |
| +); |
| diff --git a/tests/scripts/auth_http_server.py b/tests/scripts/auth_http_server.py |
| new file mode 100755 |
| index 0000000..3ae5275 |
| --- /dev/null |
| +++ b/tests/scripts/auth_http_server.py |
| @@ -0,0 +1,89 @@ |
| +#!/usr/bin/env python3 |
| + |
| +# 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. |
| + |
| +from http.server import SimpleHTTPRequestHandler, HTTPServer |
| +from socketserver import ThreadingMixIn |
| +import threading |
| +import socketserver |
| +import sys |
| + |
| +key = "" |
| + |
| + |
| +class HTTPRequestHandler(SimpleHTTPRequestHandler): |
| + |
| + def do_HEAD(self): |
| + self.send_response(200) |
| + self.send_header('Content-type', 'text/html') |
| + self.end_headers() |
| + |
| + def do_AUTHHEAD(self): |
| + self.send_response(401) |
| + self.send_header('WWW-Authenticate', 'Basic realm=\"Test\"') |
| + self.send_header('Content-type', 'text/html') |
| + self.end_headers() |
| + |
| + def do_GET(self): |
| + global key |
| + ''' Present frontpage with user authentication. ''' |
| + if self.headers.get('Authorization') == None: |
| + self.do_AUTHHEAD() |
| + pass |
| + elif self.headers.get('Authorization') == 'Basic ' + key: |
| + SimpleHTTPRequestHandler.do_GET(self) |
| + pass |
| + else: |
| + self.do_AUTHHEAD() |
| + pass |
| + |
| + def do_PUT(self): |
| + global key |
| + if self.headers.get('Authorization') == None: |
| + self.do_AUTHHEAD() |
| + pass |
| + elif self.headers.get('Authorization') == 'Basic ' + key: |
| + length = int(self.headers["Content-Length"]) |
| + |
| + path = self.translate_path(self.path) |
| + with open(path, "wb") as dst: |
| + dst.write(self.rfile.read(length)) |
| + |
| + self.send_response(200) |
| + self.end_headers() |
| + else: |
| + self.do_AUTHHEAD() |
| + pass |
| + |
| + |
| +class ThreadingSimpleServer(ThreadingMixIn, HTTPServer): |
| + pass |
| + |
| + |
| +if __name__ == '__main__': |
| + if len(sys.argv) == 3: |
| + port = int(sys.argv[1]) |
| + key = sys.argv[2] |
| + print(key) |
| + else: |
| + print("./auth_http_server.py $port $key") |
| + sys.exit(-1) |
| + socketserver.TCPServer.allow_reuse_address = True |
| + with ThreadingSimpleServer(('0.0.0.0', port), HTTPRequestHandler) as httpd: |
| + print("serving at port", port) |
| + httpd.serve_forever() |
| diff --git a/tests/unit/app/Cargo.toml b/tests/unit/app/Cargo.toml |
| index 836295e..8f50e0c 100644 |
| --- a/tests/unit/app/Cargo.toml |
| +++ b/tests/unit/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_unit_tests" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Enclave test driver" |
| license = "Apache-2.0" |
| @@ -28,7 +28,7 @@ edition = "2018" |
| default = ["teaclave_binder/app_unit_test"] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| env_logger = { version = "0.7.1" } |
| anyhow = { version = "1.0.26" } |
| |
| diff --git a/tests/unit/enclave/Cargo.toml b/tests/unit/enclave/Cargo.toml |
| index 57c750a..6df75a4 100644 |
| --- a/tests/unit/enclave/Cargo.toml |
| +++ b/tests/unit/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_unit_tests_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Enclave Unit Test" |
| license = "Apache-2.0" |
| @@ -71,7 +71,7 @@ mesalock_sgx = [ |
| cov = ["teaclave_service_enclave_utils/cov"] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| serde = { version = "1.0.92" } |
| thiserror = { version = "1.0.9" } |
| diff --git a/tests/unit/enclave/Enclave.config.xml b/tests/unit/enclave/Enclave.config.xml |
| index 8f2d590..3fe846a 100644 |
| --- a/tests/unit/enclave/Enclave.config.xml |
| +++ b/tests/unit/enclave/Enclave.config.xml |
| @@ -22,10 +22,15 @@ |
| <ProdID>0</ProdID> |
| <ISVSVN>0</ISVSVN> |
| <StackMaxSize>0x200000</StackMaxSize> |
| - <HeapMaxSize>0x8000000</HeapMaxSize> |
| + <HeapMaxSize>0x10000000</HeapMaxSize> |
| <TCSNum>22</TCSNum> |
| <TCSPolicy>0</TCSPolicy> |
| <DisableDebug>0</DisableDebug> |
| <MiscSelect>0</MiscSelect> |
| <MiscMask>0xFFFFFFFF</MiscMask> |
| + <ReservedMemMinSize> 0x2000000</ReservedMemMinSize> |
| + <ReservedMemInitSize>0x2000000</ReservedMemInitSize> |
| + <ReservedMemMaxSize> 0x8000000</ReservedMemMaxSize> |
| + <!-- On SGX1 platform, ReservedMemExecutable==1 means set reserved memory as read, write and execute (RWX) --> |
| + <ReservedMemExecutable>1</ReservedMemExecutable> |
| </EnclaveConfiguration> |
| diff --git a/tests/unit/enclave/src/lib.rs b/tests/unit/enclave/src/lib.rs |
| index 5262123..da22cf2 100644 |
| --- a/tests/unit/enclave/src/lib.rs |
| +++ b/tests/unit/enclave/src/lib.rs |
| @@ -53,7 +53,6 @@ fn handle_run_test(_: &RunTestInput) -> TeeServiceResult<RunTestOutput> { |
| |
| #[cfg(not(sgx_sim))] |
| assert!(teaclave_attestation::tests::run_tests()); |
| - |
| Ok(RunTestOutput) |
| } |
| |
| diff --git a/tests/utils/Cargo.toml b/tests/utils/Cargo.toml |
| index f9d25c7..9995c31 100644 |
| --- a/tests/utils/Cargo.toml |
| +++ b/tests/utils/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_test_utils" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave test utility" |
| license = "Apache-2.0" |
| diff --git a/third_party/wamr.patch b/third_party/wamr.patch |
| deleted file mode 100644 |
| index 793b07d..0000000 |
| --- a/third_party/wamr.patch |
| +++ /dev/null |
| @@ -1,651 +0,0 @@ |
| -diff --git a/core/shared/platform/teaclave-sgx/platform_internal.h b/core/shared/platform/teaclave-sgx/platform_internal.h |
| -new file mode 100644 |
| -index 0000000..93417b4 |
| ---- /dev/null |
| -+++ b/core/shared/platform/teaclave-sgx/platform_internal.h |
| -@@ -0,0 +1,58 @@ |
| -+/* |
| -+ * Copyright (C) 2019 Intel Corporation. All rights reserved. |
| -+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| -+ */ |
| -+ |
| -+#ifndef _PLATFORM_INTERNAL_H |
| -+#define _PLATFORM_INTERNAL_H |
| -+ |
| -+#include <inttypes.h> |
| -+#include <stdbool.h> |
| -+#include <assert.h> |
| -+#include <time.h> |
| -+#include <string.h> |
| -+#include <stdio.h> |
| -+#include <stdlib.h> |
| -+#include <math.h> |
| -+#include <unistd.h> |
| -+#include <stdarg.h> |
| -+#include <ctype.h> |
| -+#include <limits.h> |
| -+#include <errno.h> |
| -+#include <sgx_thread.h> |
| -+#include <pthread.h> |
| -+ |
| -+#include "sgx_error.h" |
| -+ |
| -+#ifdef __cplusplus |
| -+extern "C" { |
| -+#endif |
| -+ |
| -+#ifndef BH_PLATFORM_LINUX_SGX |
| -+#define BH_PLATFORM_LINUX_SGX |
| -+#endif |
| -+ |
| -+#define _STACK_SIZE_ADJUSTMENT (32 * 1024) |
| -+ |
| -+/* Stack size of applet threads's native part. */ |
| -+#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) |
| -+ |
| -+/* Default thread priority */ |
| -+#define BH_THREAD_DEFAULT_PRIORITY 0 |
| -+ |
| -+typedef pthread_t korp_thread; |
| -+typedef pthread_t korp_tid; |
| -+typedef pthread_mutex_t korp_mutex; |
| -+typedef pthread_cond_t korp_cond; |
| -+ |
| -+typedef void (*os_print_function_t)(const char* message); |
| -+void os_set_print_function(os_print_function_t pf); |
| -+ |
| -+char *strcpy(char *dest, const char *src); |
| -+ |
| -+#ifdef __cplusplus |
| -+} |
| -+#endif |
| -+ |
| -+#endif /* end of _PLATFORM_INTERNAL_H */ |
| -+ |
| -diff --git a/core/shared/platform/teaclave-sgx/sgx_platform.c b/core/shared/platform/teaclave-sgx/sgx_platform.c |
| -new file mode 100644 |
| -index 0000000..e819f26 |
| ---- /dev/null |
| -+++ b/core/shared/platform/teaclave-sgx/sgx_platform.c |
| -@@ -0,0 +1,172 @@ |
| -+/* |
| -+ * Copyright (C) 2019 Intel Corporation. All rights reserved. |
| -+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| -+ */ |
| -+ |
| -+#include "platform_api_vmcore.h" |
| -+#include "platform_api_extension.h" |
| -+#include "sgx_rsrv_mem_mngr.h" |
| -+ |
| -+#define FIXED_BUFFER_SIZE (1<<9) |
| -+ |
| -+static os_print_function_t print_function = NULL; |
| -+ |
| -+int bh_platform_init() |
| -+{ |
| -+ return 0; |
| -+} |
| -+ |
| -+void |
| -+bh_platform_destroy() |
| -+{ |
| -+} |
| -+ |
| -+void * |
| -+os_malloc(unsigned size) |
| -+{ |
| -+ return malloc(size); |
| -+} |
| -+ |
| -+void * |
| -+os_realloc(void *ptr, unsigned size) |
| -+{ |
| -+ return realloc(ptr, size); |
| -+} |
| -+ |
| -+void |
| -+os_free(void *ptr) |
| -+{ |
| -+ free(ptr); |
| -+} |
| -+ |
| -+int putchar(int c) |
| -+{ |
| -+ return 0; |
| -+} |
| -+ |
| -+int puts(const char *s) |
| -+{ |
| -+ return 0; |
| -+} |
| -+ |
| -+void os_set_print_function(os_print_function_t pf) |
| -+{ |
| -+ print_function = pf; |
| -+} |
| -+ |
| -+int os_printf(const char *message, ...) |
| -+{ |
| -+ if (print_function != NULL) { |
| -+ char msg[FIXED_BUFFER_SIZE] = { '\0' }; |
| -+ va_list ap; |
| -+ va_start(ap, message); |
| -+ vsnprintf(msg, FIXED_BUFFER_SIZE, message, ap); |
| -+ va_end(ap); |
| -+ print_function(msg); |
| -+ } |
| -+ |
| -+ return 0; |
| -+} |
| -+ |
| -+int os_vprintf(const char * format, va_list arg) |
| -+{ |
| -+ if (print_function != NULL) { |
| -+ char msg[FIXED_BUFFER_SIZE] = { '\0' }; |
| -+ vsnprintf(msg, FIXED_BUFFER_SIZE, format, arg); |
| -+ print_function(msg); |
| -+ } |
| -+ |
| -+ return 0; |
| -+} |
| -+ |
| -+char *strcpy(char *dest, const char *src) |
| -+{ |
| -+ const unsigned char *s = src; |
| -+ unsigned char *d = dest; |
| -+ |
| -+ while ((*d++ = *s++)); |
| -+ return dest; |
| -+} |
| -+ |
| -+void* os_mmap(void *hint, size_t size, int prot, int flags) |
| -+{ |
| -+ int mprot = 0; |
| -+ uint64 aligned_size, page_size; |
| -+ void* ret = NULL; |
| -+ sgx_status_t st = 0; |
| -+ |
| -+ page_size = getpagesize(); |
| -+ aligned_size = (size + page_size - 1) & ~(page_size - 1); |
| -+ |
| -+ if (aligned_size >= UINT32_MAX) |
| -+ return NULL; |
| -+ |
| -+ ret = sgx_alloc_rsrv_mem(aligned_size); |
| -+ if (ret == NULL) { |
| -+ os_printf("os_mmap(size=%u, aligned size=%lu, prot=0x%x) failed.", |
| -+ size, aligned_size, prot); |
| -+ return NULL; |
| -+ } |
| -+ |
| -+ if (prot & MMAP_PROT_READ) |
| -+ mprot |= SGX_PROT_READ; |
| -+ if (prot & MMAP_PROT_WRITE) |
| -+ mprot |= SGX_PROT_WRITE; |
| -+ if (prot & MMAP_PROT_EXEC) |
| -+ mprot |= SGX_PROT_EXEC; |
| -+ |
| -+ st = sgx_tprotect_rsrv_mem(ret, aligned_size, mprot); |
| -+ if (st != SGX_SUCCESS) { |
| -+ os_printf("os_mmap(size=%u, prot=0x%x) failed to set protect.", |
| -+ size, prot); |
| -+ sgx_free_rsrv_mem(ret, aligned_size); |
| -+ return NULL; |
| -+ } |
| -+ |
| -+ return ret; |
| -+} |
| -+ |
| -+void os_munmap(void *addr, size_t size) |
| -+{ |
| -+ uint64 aligned_size, page_size; |
| -+ |
| -+ page_size = getpagesize(); |
| -+ aligned_size = (size + page_size - 1) & ~(page_size - 1); |
| -+ sgx_free_rsrv_mem(addr, aligned_size); |
| -+} |
| -+ |
| -+int os_mprotect(void *addr, size_t size, int prot) |
| -+{ |
| -+ int mprot = 0; |
| -+ sgx_status_t st = 0; |
| -+ uint64 aligned_size, page_size; |
| -+ |
| -+ page_size = getpagesize(); |
| -+ aligned_size = (size + page_size - 1) & ~(page_size - 1); |
| -+ |
| -+ if (prot & MMAP_PROT_READ) |
| -+ mprot |= SGX_PROT_READ; |
| -+ if (prot & MMAP_PROT_WRITE) |
| -+ mprot |= SGX_PROT_WRITE; |
| -+ if (prot & MMAP_PROT_EXEC) |
| -+ mprot |= SGX_PROT_EXEC; |
| -+ st = sgx_tprotect_rsrv_mem(addr, aligned_size, mprot); |
| -+ if (st != SGX_SUCCESS) |
| -+ os_printf("os_mprotect(addr=0x%"PRIx64", size=%u, prot=0x%x) failed.", |
| -+ (uintptr_t)addr, size, prot); |
| -+ |
| -+ return (st == SGX_SUCCESS? 0:-1); |
| -+} |
| -+ |
| -+uint64 |
| -+os_time_get_boot_microsecond() |
| -+{ |
| -+ /* TODO */ |
| -+ return 0; |
| -+} |
| -+ |
| -+void |
| -+os_dcache_flush(void) |
| -+{ |
| -+} |
| -+ |
| -diff --git a/core/shared/platform/teaclave-sgx/sgx_rsrv_mem_mngr.h b/core/shared/platform/teaclave-sgx/sgx_rsrv_mem_mngr.h |
| -new file mode 100644 |
| -index 0000000..b32a68b |
| ---- /dev/null |
| -+++ b/core/shared/platform/teaclave-sgx/sgx_rsrv_mem_mngr.h |
| -@@ -0,0 +1,90 @@ |
| -+/* |
| -+ * Copyright (C) 2011-2019 Intel Corporation. All rights reserved. |
| -+ * |
| -+ * Redistribution and use in source and binary forms, with or without |
| -+ * modification, are permitted provided that the following conditions |
| -+ * are met: |
| -+ * |
| -+ * * Redistributions of source code must retain the above copyright |
| -+ * notice, this list of conditions and the following disclaimer. |
| -+ * * Redistributions in binary form must reproduce the above copyright |
| -+ * notice, this list of conditions and the following disclaimer in |
| -+ * the documentation and/or other materials provided with the |
| -+ * distribution. |
| -+ * * Neither the name of Intel Corporation nor the names of its |
| -+ * contributors may be used to endorse or promote products derived |
| -+ * from this software without specific prior written permission. |
| -+ * |
| -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| -+ * |
| -+ */ |
| -+ |
| -+/* |
| -+ * This file is copied from https://github.com/intel/linux-sgx/blob/4589daddd58bec7367a6a9de3fe301e6de17671a/common/inc/internal/sgx_rsrv_mem_mngr.h |
| -+ * The reason we copied here is that the official SGX SDK release has |
| -+ * not included this header file yet. |
| -+ */ |
| -+ |
| -+#pragma once |
| -+ |
| -+#ifndef _SGX_RSRV_MEM_MNGR_H_ |
| -+#define _SGX_RSRV_MEM_MNGR_H_ |
| -+ |
| -+#include "stdint.h" |
| -+#include "sgx_error.h" |
| -+ |
| -+#define SGX_PROT_READ 0x1 /* page can be read */ |
| -+#define SGX_PROT_WRITE 0x2 /* page can be written */ |
| -+#define SGX_PROT_EXEC 0x4 /* page can be executed */ |
| -+#define SGX_PROT_NONE 0x0 /* page can not be accessed */ |
| -+ |
| -+#ifdef __cplusplus |
| -+extern "C" { |
| -+#endif |
| -+ |
| -+ /* Allocate a range of EPC memory from the reserved memory area with RW permission |
| -+ * |
| -+ * Parameters: |
| -+ * Inputs: length [in]: Size of region to be allocated in bytes. Page aligned |
| -+ * Return: Starting address of the new allocated memory area on success; otherwise NULL |
| -+ */ |
| -+ void * sgx_alloc_rsrv_mem(size_t length); |
| -+ |
| -+ |
| -+ /* Free a range of EPC memory from the reserved memory area |
| -+ * |
| -+ * Parameters: |
| -+ * Inputs: addr[in]: Starting address of region to be freed. Page aligned. |
| -+ * length[in]: The length of the memory to be freed in bytes. Page aligned |
| -+ * Return: 0 on success; otherwise -1 |
| -+ */ |
| -+ int sgx_free_rsrv_mem(void * addr, size_t length); |
| -+ |
| -+ |
| -+ /* Modify the access permissions of the pages in the reserved memory area. |
| -+ * |
| -+ * Parameters: |
| -+ * Inputs: addr[in]: Starting address of region which needs to change access permission. Page aligned. |
| -+ * length[in]: The length of the memory to be manipulated in bytes. Page aligned. |
| -+ * prot[in]: The target memory protection. |
| -+ * Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h |
| -+ */ |
| -+ sgx_status_t sgx_tprotect_rsrv_mem(void *addr, size_t len, int prot); |
| -+ |
| -+ |
| -+#ifdef __cplusplus |
| -+} |
| -+#endif |
| -+ |
| -+#endif |
| -+ |
| -diff --git a/core/shared/platform/teaclave-sgx/sgx_thread.c b/core/shared/platform/teaclave-sgx/sgx_thread.c |
| -new file mode 100644 |
| -index 0000000..d1503b4 |
| ---- /dev/null |
| -+++ b/core/shared/platform/teaclave-sgx/sgx_thread.c |
| -@@ -0,0 +1,180 @@ |
| -+/* |
| -+ * Copyright (C) 2019 Intel Corporation. All rights reserved. |
| -+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| -+ */ |
| -+ |
| -+#include "platform_api_vmcore.h" |
| -+#include "platform_api_extension.h" |
| -+ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+typedef struct { |
| -+ thread_start_routine_t start; |
| -+ void *arg; |
| -+} thread_wrapper_arg; |
| -+ |
| -+static void *os_thread_wrapper(void *arg) |
| -+{ |
| -+ thread_wrapper_arg * targ = arg; |
| -+ thread_start_routine_t start_func = targ->start; |
| -+ void *thread_arg = targ->arg; |
| -+ os_printf("THREAD CREATED %p\n", &targ); |
| -+ BH_FREE(targ); |
| -+ start_func(thread_arg); |
| -+ return NULL; |
| -+} |
| -+ |
| -+int os_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start, |
| -+ void *arg, unsigned int stack_size, int prio) |
| -+{ |
| -+ thread_wrapper_arg *targ; |
| -+ |
| -+ assert(tid); |
| -+ assert(start); |
| -+ |
| -+ targ = (thread_wrapper_arg *) BH_MALLOC(sizeof(*targ)); |
| -+ if (!targ) { |
| -+ return BHT_ERROR; |
| -+ } |
| -+ |
| -+ targ->start = start; |
| -+ targ->arg = arg; |
| -+ |
| -+ if (pthread_create(tid, NULL, os_thread_wrapper, targ) != 0) { |
| -+ BH_FREE(targ); |
| -+ return BHT_ERROR; |
| -+ } |
| -+ |
| -+ return BHT_OK; |
| -+} |
| -+ |
| -+int os_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg, |
| -+ unsigned int stack_size) |
| -+{ |
| -+ return os_thread_create_with_prio(tid, start, arg, stack_size, |
| -+ BH_THREAD_DEFAULT_PRIORITY); |
| -+} |
| -+#endif |
| -+ |
| -+korp_tid os_self_thread() |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ return pthread_self(); |
| -+#else |
| -+ return 0; |
| -+#endif |
| -+} |
| -+ |
| -+int os_mutex_init(korp_mutex *mutex) |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; |
| -+ *mutex = m; |
| -+#endif |
| -+ return BHT_OK; |
| -+} |
| -+ |
| -+int os_mutex_destroy(korp_mutex *mutex) |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ pthread_mutex_destroy(mutex); |
| -+#endif |
| -+ return BHT_OK; |
| -+} |
| -+ |
| -+int os_mutex_lock(korp_mutex *mutex) |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ return pthread_mutex_lock(mutex); |
| -+#else |
| -+ return 0; |
| -+#endif |
| -+} |
| -+ |
| -+int os_mutex_unlock(korp_mutex *mutex) |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ return pthread_mutex_unlock(mutex); |
| -+#else |
| -+ return 0; |
| -+#endif |
| -+} |
| -+ |
| -+int os_cond_init(korp_cond *cond) |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ pthread_cond_t c = PTHREAD_COND_INITIALIZER; |
| -+ *cond = c; |
| -+#endif |
| -+ return BHT_OK; |
| -+} |
| -+ |
| -+int os_cond_destroy(korp_cond *cond) |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ pthread_cond_destroy(cond); |
| -+#endif |
| -+ return BHT_OK; |
| -+} |
| -+ |
| -+int os_cond_wait(korp_cond *cond, korp_mutex *mutex) |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ assert(cond); |
| -+ assert(mutex); |
| -+ |
| -+ if (pthread_cond_wait(cond, mutex) != BHT_OK) |
| -+ return BHT_ERROR; |
| -+ |
| -+#endif |
| -+ return BHT_OK; |
| -+} |
| -+ |
| -+int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds) |
| -+{ |
| -+ os_printf("warning: SGX pthread_cond_timedwait isn't supported, " |
| -+ "calling pthread_cond_wait instead!\n"); |
| -+ return BHT_ERROR; |
| -+} |
| -+ |
| -+int os_cond_signal(korp_cond *cond) |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ assert(cond); |
| -+ |
| -+ if (pthread_cond_signal(cond) != BHT_OK) |
| -+ return BHT_ERROR; |
| -+ |
| -+#endif |
| -+ return BHT_OK; |
| -+} |
| -+ |
| -+int os_thread_join(korp_tid thread, void **value_ptr) |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ return pthread_join(thread, value_ptr); |
| -+#else |
| -+ return 0; |
| -+#endif |
| -+} |
| -+ |
| -+int os_thread_detach(korp_tid thread) |
| -+{ |
| -+ /* SGX pthread_detach isn't provided, return directly. */ |
| -+ return 0; |
| -+} |
| -+ |
| -+void os_thread_exit(void *retval) |
| -+{ |
| -+#ifndef SGX_DISABLE_PTHREAD |
| -+ pthread_exit(retval); |
| -+#else |
| -+ return; |
| -+#endif |
| -+} |
| -+ |
| -+uint8 *os_thread_get_stack_boundary() |
| -+{ |
| -+ /* TODO: get sgx stack boundary */ |
| -+ return NULL; |
| -+} |
| -+ |
| -diff --git a/core/shared/platform/teaclave-sgx/shared_platform.cmake b/core/shared/platform/teaclave-sgx/shared_platform.cmake |
| -new file mode 100644 |
| -index 0000000..fa3a7aa |
| ---- /dev/null |
| -+++ b/core/shared/platform/teaclave-sgx/shared_platform.cmake |
| -@@ -0,0 +1,33 @@ |
| -+# Copyright (C) 2019 Intel Corporation. All rights reserved. |
| -+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| -+ |
| -+set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR}) |
| -+ |
| -+add_definitions(-DBH_PLATFORM_LINUX_SGX) |
| -+ |
| -+include_directories(${PLATFORM_SHARED_DIR}) |
| -+include_directories(${PLATFORM_SHARED_DIR}/../include) |
| -+ |
| -+if ("$ENV{SGX_SDK}" STREQUAL "") |
| -+ set (SGX_SDK_DIR "/opt/intel/sgxsdk") |
| -+else() |
| -+ set (SGX_SDK_DIR $ENV{SGX_SDK}) |
| -+endif() |
| -+ |
| -+include_directories (${SGX_SDK_DIR}/include) |
| -+if (NOT BUILD_UNTRUST_PART EQUAL 1) |
| -+ include_directories (${SGX_SDK_DIR}/include/tlibc |
| -+ ${SGX_SDK_DIR}/include/libcxx) |
| -+endif () |
| -+ |
| -+if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1) |
| -+ add_definitions(-DSGX_DISABLE_WASI) |
| -+endif () |
| -+ |
| -+if (NOT WAMR_BUILD_THREAD_MGR EQUAL 1) |
| -+ add_definitions(-DSGX_DISABLE_PTHREAD) |
| -+endif () |
| -+ |
| -+file (GLOB source_all ${PLATFORM_SHARED_DIR}/*.c) |
| -+ |
| -+set (PLATFORM_SHARED_SOURCE ${source_all}) |
| -diff --git a/product-mini/platforms/teaclave-sgx/CMakeLists.txt b/product-mini/platforms/teaclave-sgx/CMakeLists.txt |
| -new file mode 100644 |
| -index 0000000..d4c71d8 |
| ---- /dev/null |
| -+++ b/product-mini/platforms/teaclave-sgx/CMakeLists.txt |
| -@@ -0,0 +1,82 @@ |
| -+# Copyright (C) 2019 Intel Corporation. All rights reserved. |
| -+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| -+ |
| -+cmake_minimum_required (VERSION 2.8) |
| -+ |
| -+project (iwasm) |
| -+ |
| -+set (WAMR_BUILD_PLATFORM "teaclave-sgx") |
| -+ |
| -+# Reset default linker flags |
| -+set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") |
| -+set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") |
| -+ |
| -+# Set WAMR_BUILD_TARGET |
| -+if (NOT DEFINED WAMR_BUILD_TARGET) |
| -+ if (CMAKE_SIZEOF_VOID_P EQUAL 8) |
| -+ # Build as X86_64 by default in 64-bit platform |
| -+ set (WAMR_BUILD_TARGET "X86_64") |
| -+ else () |
| -+ # Build as X86_32 by default in 32-bit platform |
| -+ set (WAMR_BUILD_TARGET "X86_32") |
| -+ endif () |
| -+endif () |
| -+ |
| -+if (NOT CMAKE_BUILD_TYPE) |
| -+ set(CMAKE_BUILD_TYPE Release) |
| -+endif () |
| -+ |
| -+if (NOT DEFINED WAMR_BUILD_INTERP) |
| -+ # Enable Interpreter by default |
| -+ set (WAMR_BUILD_INTERP 1) |
| -+endif () |
| -+ |
| -+if (NOT DEFINED WAMR_BUILD_AOT) |
| -+ # Enable AOT by default |
| -+ # Please install Intel SGX SDKv2.8 or later. |
| -+ set (WAMR_BUILD_AOT 0) |
| -+endif () |
| -+ |
| -+if (NOT DEFINED WAMR_BUILD_JIT) |
| -+ # Disable JIT by default. |
| -+ set (WAMR_BUILD_JIT 0) |
| -+endif () |
| -+ |
| -+if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN) |
| -+ # Enable libc builtin support by default |
| -+ set (WAMR_BUILD_LIBC_BUILTIN 0) |
| -+endif () |
| -+ |
| -+if (NOT DEFINED WAMR_BUILD_LIBC_WASI) |
| -+ # Enable libc wasi support by default |
| -+ set (WAMR_BUILD_LIBC_WASI 0) |
| -+endif () |
| -+ |
| -+if (NOT DEFINED WAMR_BUILD_FAST_INTERP) |
| -+ # Enable fast interpreter |
| -+ set (WAMR_BUILD_FAST_INTERP 0) |
| -+endif () |
| -+ |
| -+if (NOT DEFINED WAMR_BUILD_MULTI_MODULE) |
| -+ # Enable multiple modules |
| -+ set (WAMR_BUILD_MULTI_MODULE 0) |
| -+endif () |
| -+ |
| -+if (NOT DEFINED WAMR_BUILD_LIB_PTHREAD) |
| -+ # Enable pthread library by default |
| -+ set (WAMR_BUILD_LIB_PTHREAD 0) |
| -+endif () |
| -+ |
| -+if (COLLECT_CODE_COVERAGE EQUAL 1) |
| -+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") |
| -+endif () |
| -+ |
| -+set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") |
| -+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -ffunction-sections -fdata-sections \ |
| -+ -Wall -Wno-unused-parameter -Wno-pedantic \ |
| -+ -nostdinc -fvisibility=hidden -fpie" ) |
| -+ |
| -+set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..) |
| -+ |
| -+include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) |
| -+add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE}) |
| diff --git a/third_party/wasm-micro-runtime b/third_party/wasm-micro-runtime |
| index d856af6..f0b16f7 160000 |
| --- a/third_party/wasm-micro-runtime |
| +++ b/third_party/wasm-micro-runtime |
| @@ -1 +1 @@ |
| -Subproject commit d856af6c33591815ab4c890f0606bc99ee8135ad |
| +Subproject commit f0b16f7b5f8e02a1c876eeda7d36d166eae2ec8a |
| diff --git a/tool/app/Cargo.toml b/tool/app/Cargo.toml |
| index 83cad53..df28b19 100644 |
| --- a/tool/app/Cargo.toml |
| +++ b/tool/app/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_sgx_tool" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave SGX Tool" |
| license = "Apache-2.0" |
| @@ -25,7 +25,7 @@ build = "build.rs" |
| edition = "2018" |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| env_logger = { version = "0.7.1" } |
| anyhow = { version = "1.0.26" } |
| serde = { version = "1.0.92", features = ["derive"] } |
| diff --git a/tool/app/src/main.rs b/tool/app/src/main.rs |
| index 6183de3..4d595d2 100644 |
| --- a/tool/app/src/main.rs |
| +++ b/tool/app/src/main.rs |
| @@ -17,20 +17,24 @@ |
| |
| use anyhow::anyhow; |
| use anyhow::Result; |
| +use std::path::PathBuf; |
| use std::process; |
| use structopt::StructOpt; |
| -use teaclave_binder::proto::{ECallCommand, RawJsonInput, RawJsonOutput}; |
| +use teaclave_binder::proto::{ECallCommand, RawJsonInput, RawJsonOutput, SubCmd}; |
| use teaclave_binder::TeeBinder; |
| use teaclave_types::TeeServiceResult; |
| |
| +fn backup_db(opt: &BackupDbOpt) -> anyhow::Result<()> { |
| + let tee = TeeBinder::new(env!("CARGO_PKG_NAME"))?; |
| + start_db_backup(&tee, opt)?; |
| + tee.finalize(); |
| + |
| + Ok(()) |
| +} |
| + |
| fn attestation(opt: &AttestationOpt) -> anyhow::Result<()> { |
| - env_logger::init_from_env( |
| - env_logger::Env::new() |
| - .filter_or("TEACLAVE_LOG", "RUST_LOG") |
| - .write_style_or("TEACLAVE_LOG_STYLE", "RUST_LOG_STYLE"), |
| - ); |
| let tee = TeeBinder::new(env!("CARGO_PKG_NAME"))?; |
| - run(&tee, opt)?; |
| + start_enclave_remote_attestation(&tee, opt)?; |
| tee.finalize(); |
| |
| Ok(()) |
| @@ -39,7 +43,7 @@ fn attestation(opt: &AttestationOpt) -> anyhow::Result<()> { |
| fn start_enclave_remote_attestation(tee: &TeeBinder, opt: &AttestationOpt) -> anyhow::Result<()> { |
| let cmd = ECallCommand::Raw; |
| let json = serde_json::to_string(opt)?; |
| - let input = RawJsonInput::new(json); |
| + let input = RawJsonInput::new(SubCmd::Attestation, json); |
| match tee.invoke::<RawJsonInput, TeeServiceResult<RawJsonOutput>>(cmd, input) { |
| Err(e) => Err(anyhow!("{:?}", e)), |
| Ok(Err(e)) => Err(anyhow!("{:?}", e)), |
| @@ -47,10 +51,15 @@ fn start_enclave_remote_attestation(tee: &TeeBinder, opt: &AttestationOpt) -> an |
| } |
| } |
| |
| -fn run(tee: &TeeBinder, opt: &AttestationOpt) -> anyhow::Result<()> { |
| - start_enclave_remote_attestation(tee, opt)?; |
| - |
| - Ok(()) |
| +fn start_db_backup(tee: &TeeBinder, opt: &BackupDbOpt) -> anyhow::Result<()> { |
| + let cmd = ECallCommand::Raw; |
| + let json = serde_json::to_string(opt)?; |
| + let input = RawJsonInput::new(SubCmd::BackupDb, json); |
| + match tee.invoke::<RawJsonInput, TeeServiceResult<RawJsonOutput>>(cmd, input) { |
| + Err(e) => Err(anyhow!("{:?}", e)), |
| + Ok(Err(e)) => Err(anyhow!("{:?}", e)), |
| + _ => Ok(()), |
| + } |
| } |
| |
| #[derive(Debug, StructOpt)] |
| @@ -60,6 +69,16 @@ struct Opt { |
| command: Command, |
| } |
| |
| +#[derive(Debug, StructOpt, serde::Serialize)] |
| +struct BackupDbOpt { |
| + #[structopt(parse(from_os_str))] |
| + db_old: PathBuf, |
| + #[structopt(parse(from_os_str))] |
| + db_new: PathBuf, |
| + #[structopt(long, default_value = "00000000000000000000000000000000")] |
| + key: String, |
| +} |
| + |
| #[derive(Debug, StructOpt, serde::Serialize)] |
| struct AttestationOpt { |
| /// Attestation algorithm, supported algorithms are "sgx_epid" for IAS |
| @@ -88,6 +107,9 @@ enum Command { |
| /// Dump remote attestationation report |
| #[structopt(name = "attestation")] |
| Attestation(AttestationOpt), |
| + /// Backup DB |
| + #[structopt(name = "backup")] |
| + BackupDb(BackupDbOpt), |
| } |
| |
| fn status() { |
| @@ -188,10 +210,16 @@ fn status() { |
| } |
| |
| fn main() -> Result<()> { |
| + env_logger::init_from_env( |
| + env_logger::Env::new() |
| + .filter_or("TEACLAVE_LOG", "RUST_LOG") |
| + .write_style_or("TEACLAVE_LOG_STYLE", "RUST_LOG_STYLE"), |
| + ); |
| let args = Opt::from_args(); |
| match args.command { |
| Command::Status => status(), |
| Command::Attestation(opt) => attestation(&opt)?, |
| + Command::BackupDb(opt) => backup_db(&opt)?, |
| }; |
| Ok(()) |
| } |
| diff --git a/tool/enclave/Cargo.toml b/tool/enclave/Cargo.toml |
| index b04ef7d..10c84d6 100644 |
| --- a/tool/enclave/Cargo.toml |
| +++ b/tool/enclave/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_sgx_tool_enclave" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave SGX Tool" |
| license = "Apache-2.0" |
| @@ -35,18 +35,21 @@ mesalock_sgx = [ |
| "teaclave_binder/mesalock_sgx", |
| "teaclave_types/mesalock_sgx", |
| "teaclave_service_enclave_utils/mesalock_sgx", |
| + "rusty-leveldb/mesalock_sgx", |
| ] |
| cov = ["teaclave_service_enclave_utils/cov"] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| serde = { version = "1.0.92" } |
| -serde_json = { version = "1.0.39" } |
| -base64 = { version = "0.13.0" } |
| +serde_json = { version = "1.0.39" } |
| +base64 = { version = "0.13.0" } |
| thiserror = { version = "1.0.9" } |
| +hex = { version = "0.4.0" } |
| |
| |
| +rusty-leveldb = { path = "../../common/rusty_leveldb_sgx" } |
| teaclave_attestation = { path = "../../attestation" } |
| teaclave_binder = { path = "../../binder" } |
| teaclave_service_enclave_utils = { path = "../../services/utils/service_enclave_utils" } |
| diff --git a/tool/enclave/src/db.rs b/tool/enclave/src/db.rs |
| new file mode 100644 |
| index 0000000..9d6733c |
| --- /dev/null |
| +++ b/tool/enclave/src/db.rs |
| @@ -0,0 +1,58 @@ |
| +// 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 anyhow::Result; |
| +use rusty_leveldb::LdbIterator; |
| +use rusty_leveldb::{DBReader, Options}; |
| +use std::path::Path; |
| + |
| +pub fn backup_db(db_old: impl AsRef<Path>, db_new: impl AsRef<Path>, key: [u8; 16]) -> Result<()> { |
| + let opt = Options::new_disk_db_with(key); |
| + let mut new_db = rusty_leveldb::DB::open(&db_new, opt).unwrap(); |
| + |
| + let mut count = 0; |
| + log::info!("Backup log files: {:?}", db_old.as_ref()); |
| + let opt = rusty_leveldb::Options::new_disk_db_with(key); |
| + match rusty_leveldb::DB::open(&db_old, opt) { |
| + Ok(mut db) => { |
| + let mut iter = db.new_iter()?; |
| + while iter.advance() { |
| + let (mut k, mut v) = (vec![], vec![]); |
| + iter.current(&mut k, &mut v); |
| + new_db.put(&k, &v)?; |
| + count += 1; |
| + } |
| + log::info!("Finish backup log to new_db: total {:?} entries ", count); |
| + } |
| + Err(e) => { |
| + log::error!("DB normal open failed: {:?}", e); |
| + // backup ldb |
| + log::info!("Backup ldb files: {:?}", db_old.as_ref()); |
| + let opt = Options::new_disk_db_with(key); |
| + let reader = DBReader::new(db_old.as_ref(), opt).unwrap(); |
| + for (k, v) in reader.into_iter() { |
| + new_db.put(&k, &v)?; |
| + count += 1; |
| + } |
| + log::info!("Finish backup ldb to new_db: total {:?} entries ", count); |
| + } |
| + } |
| + |
| + new_db.flush()?; |
| + |
| + Ok(()) |
| +} |
| diff --git a/tool/enclave/src/lib.rs b/tool/enclave/src/lib.rs |
| index 80f8bdf..87a3234 100644 |
| --- a/tool/enclave/src/lib.rs |
| +++ b/tool/enclave/src/lib.rs |
| @@ -20,6 +20,9 @@ |
| #[macro_use] |
| extern crate sgx_tstd as std; |
| |
| +use anyhow::{anyhow, Context}; |
| +use std::convert::TryInto; |
| +use std::path::PathBuf; |
| use std::prelude::v1::*; |
| |
| use serde_json::Value; |
| @@ -28,13 +31,15 @@ use teaclave_attestation::EndorsedAttestationReport; |
| use teaclave_attestation::{key, AttestationConfig}; |
| use teaclave_binder::proto::{ |
| ECallCommand, FinalizeEnclaveInput, FinalizeEnclaveOutput, InitEnclaveInput, InitEnclaveOutput, |
| - RawJsonInput, RawJsonOutput, |
| + RawJsonInput, RawJsonOutput, SubCmd, |
| }; |
| use teaclave_binder::{handle_ecall, register_ecall_handler}; |
| use teaclave_service_enclave_utils::ServiceEnclave; |
| use teaclave_types::TeeServiceError; |
| use teaclave_types::{self, TeeServiceResult}; |
| |
| +mod db; |
| + |
| fn attestation(raw_json_input: &RawJsonInput) -> anyhow::Result<()> { |
| let v: serde_json::Value = serde_json::from_str(&raw_json_input.json)?; |
| let attestation_config = AttestationConfig::new( |
| @@ -66,12 +71,37 @@ fn attestation(raw_json_input: &RawJsonInput) -> anyhow::Result<()> { |
| Ok(()) |
| } |
| |
| +#[derive(Debug, serde::Deserialize)] |
| +struct BackupDbOpt { |
| + db_old: PathBuf, |
| + db_new: PathBuf, |
| + key: String, |
| +} |
| + |
| +fn backup_db(raw_json_input: &RawJsonInput) -> anyhow::Result<()> { |
| + let v: BackupDbOpt = serde_json::from_str(&raw_json_input.json)?; |
| + let key: [u8; 16] = hex::decode(v.key) |
| + .context("Illegal database key provided")? |
| + .try_into() |
| + .map_err(|_| anyhow!("not 16 bytes key"))?; |
| + let db_old = v.db_old; |
| + let db_new = v.db_new; |
| + |
| + db::backup_db(&db_old, &db_new, key)?; |
| + Ok(()) |
| +} |
| + |
| #[handle_ecall] |
| -fn handle_remote_attestation(input: &RawJsonInput) -> TeeServiceResult<RawJsonOutput> { |
| - match attestation(input) { |
| +fn handle_raw_json(input: &RawJsonInput) -> TeeServiceResult<RawJsonOutput> { |
| + let result = match input.sub_cmd { |
| + SubCmd::Attestation => attestation(input), |
| + SubCmd::BackupDb => backup_db(input), |
| + }; |
| + |
| + match result { |
| Ok(_) => Ok(RawJsonOutput::default()), |
| Err(e) => { |
| - log::error!("Failed to start the service: {}", e); |
| + log::error!("Failed to execute command: {}", e); |
| Err(TeeServiceError::ServiceError) |
| } |
| } |
| diff --git a/types/Cargo.toml b/types/Cargo.toml |
| index 293cc29..e1a5df7 100644 |
| --- a/types/Cargo.toml |
| +++ b/types/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_types" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave types" |
| license = "Apache-2.0" |
| @@ -36,7 +36,7 @@ mesalock_sgx = [ |
| enclave_unit_test = ["teaclave_test_utils/mesalock_sgx"] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| sgx_types = { version = "1.1.3" } |
| rand = { version = "0.7.0" } |
| diff --git a/types/src/function.rs b/types/src/function.rs |
| index b2ee267..ca475b2 100644 |
| --- a/types/src/function.rs |
| +++ b/types/src/function.rs |
| @@ -54,6 +54,44 @@ impl FunctionOutput { |
| } |
| } |
| |
| +#[derive(Debug, Deserialize, Serialize)] |
| +pub struct FunctionArgument { |
| + pub key: String, |
| + pub default_value: String, |
| + pub allow_overwrite: bool, |
| +} |
| + |
| +impl FunctionArgument { |
| + pub fn new( |
| + key: impl Into<String>, |
| + default_value: impl Into<String>, |
| + allow_overwrite: bool, |
| + ) -> Self { |
| + Self { |
| + key: key.into(), |
| + default_value: default_value.into(), |
| + allow_overwrite, |
| + } |
| + } |
| +} |
| + |
| +#[derive(Debug, Deserialize, Serialize, Default)] |
| +pub struct FunctionExpirationDate { |
| + pub expired: bool, |
| + pub seconds: i64, |
| + pub nanos: i32, |
| +} |
| + |
| +impl FunctionExpirationDate { |
| + pub fn new(expired: bool, seconds: i64, nanos: i32) -> Self { |
| + Self { |
| + expired, |
| + seconds, |
| + nanos, |
| + } |
| + } |
| +} |
| + |
| const USER_PREFIX: &str = "user"; |
| |
| #[derive(Default, Debug, Deserialize, Serialize)] |
| @@ -83,11 +121,13 @@ pub struct Function { |
| pub public: bool, |
| pub executor_type: ExecutorType, |
| pub payload: Vec<u8>, |
| - pub arguments: Vec<String>, |
| + pub arguments: Vec<FunctionArgument>, |
| pub inputs: Vec<FunctionInput>, |
| pub outputs: Vec<FunctionOutput>, |
| pub owner: UserID, |
| pub user_allowlist: Vec<String>, |
| + pub usage_quota: i32, |
| + pub expiration_date: FunctionExpirationDate, |
| } |
| |
| #[derive(Default)] |
| @@ -132,7 +172,7 @@ impl FunctionBuilder { |
| self |
| } |
| |
| - pub fn arguments(mut self, arguments: Vec<String>) -> Self { |
| + pub fn arguments(mut self, arguments: Vec<FunctionArgument>) -> Self { |
| self.function.arguments = arguments; |
| self |
| } |
| @@ -157,6 +197,16 @@ impl FunctionBuilder { |
| self |
| } |
| |
| + pub fn usage_quota(mut self, usage_quota: i32) -> Self { |
| + self.function.usage_quota = usage_quota; |
| + self |
| + } |
| + |
| + pub fn expiration_date(mut self, expiration_date: FunctionExpirationDate) -> Self { |
| + self.function.expiration_date = expiration_date; |
| + self |
| + } |
| + |
| pub fn build(self) -> Function { |
| self.function |
| } |
| @@ -171,3 +221,22 @@ impl Storable for Function { |
| self.id |
| } |
| } |
| + |
| +const FUNCION_USAGE_PREFIX: &str = "usage"; |
| + |
| +#[derive(Default, Debug, Deserialize, Serialize)] |
| +pub struct FunctionUsage { |
| + pub function_id: Uuid, |
| + pub use_numbers: i32, |
| + pub group_name: String, |
| +} |
| + |
| +impl Storable for FunctionUsage { |
| + fn key_prefix() -> &'static str { |
| + FUNCION_USAGE_PREFIX |
| + } |
| + |
| + fn uuid(&self) -> Uuid { |
| + Uuid::new_v5(&self.function_id, self.group_name.as_bytes()) |
| + } |
| +} |
| diff --git a/types/src/macros.rs b/types/src/macros.rs |
| index 2b5bfb4..8890dc1 100644 |
| --- a/types/src/macros.rs |
| +++ b/types/src/macros.rs |
| @@ -14,7 +14,6 @@ |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| - |
| #[macro_export] |
| macro_rules! hashmap { |
| ($( $key: expr => $value: expr, )+) => { hashmap!($($key => $value),+) }; |
| @@ -24,3 +23,18 @@ macro_rules! hashmap { |
| map |
| }} |
| } |
| + |
| +#[macro_export] |
| +macro_rules! profile_highlight { |
| + ($desc:expr, $blk:block) => {{ |
| + let before = std::time::Instant::now(); |
| + let result = $blk; |
| + let elapsed = before.elapsed().as_secs_f64(); |
| + if elapsed < 0.5 { |
| + log::debug!(" {}: Elapsed time: {:?}", $desc, elapsed); |
| + } else { |
| + log::info!(" {}: Elapsed time: \x1B[1;31m{:?}\x1B[0m", $desc, elapsed); |
| + } |
| + result |
| + }}; |
| +} |
| diff --git a/types/src/staged_file.rs b/types/src/staged_file.rs |
| index 9d11f43..c210680 100644 |
| --- a/types/src/staged_file.rs |
| +++ b/types/src/staged_file.rs |
| @@ -189,6 +189,14 @@ impl StagedFiles { |
| pub fn is_empty(&self) -> bool { |
| self.len() == 0 |
| } |
| + |
| + pub fn insert(&mut self, name: &str, fileinfo: StagedFileInfo) { |
| + self.entries.insert(name.to_owned(), fileinfo); |
| + } |
| + |
| + pub fn contain(&mut self, name: &str) -> bool { |
| + self.entries.contains_key(name) |
| + } |
| } |
| |
| impl std::iter::FromIterator<(String, StagedFileInfo)> for StagedFiles { |
| diff --git a/types/src/staged_function.rs b/types/src/staged_function.rs |
| index 0b5799a..b301bb2 100644 |
| --- a/types/src/staged_function.rs |
| +++ b/types/src/staged_function.rs |
| @@ -101,6 +101,10 @@ impl FunctionArguments { |
| pub fn into_string(self) -> String { |
| ArgumentValue::Object(self.inner).to_string() |
| } |
| + |
| + pub fn insert(&mut self, k: String, v: ArgumentValue) -> Option<ArgumentValue> { |
| + self.inner.insert(k, v) |
| + } |
| } |
| |
| #[derive(Debug, Default)] |
| @@ -115,6 +119,13 @@ pub struct StagedFunction { |
| pub runtime_name: String, |
| } |
| |
| +impl std::fmt::Display for StagedFunction { |
| + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| + write!(f, "name: {}, args: {:?}, payload: {}, input_files: {:?}, output_files: {:?}, exec_type: {:?}, executor: {:?}, runtime_name: {}", |
| + self.name, self.arguments, self.payload.len(), self.input_files, self.output_files, self.executor_type, self.executor, self.runtime_name) |
| + } |
| +} |
| + |
| #[derive(Default)] |
| pub struct StagedFunctionBuilder { |
| function: StagedFunction, |
| diff --git a/types/src/staged_task.rs b/types/src/staged_task.rs |
| index a8cbc09..9291f36 100644 |
| --- a/types/src/staged_task.rs |
| +++ b/types/src/staged_task.rs |
| @@ -43,6 +43,10 @@ impl FunctionInputFiles { |
| pub fn iter(&self) -> Iter<String, FunctionInputFile> { |
| self.inner.iter() |
| } |
| + |
| + pub fn placeholder_filter(&mut self) { |
| + self.inner.retain(|_, v| !v.is_placeholder()); |
| + } |
| } |
| |
| impl IntoIterator for FunctionInputFiles { |
| @@ -139,6 +143,11 @@ impl FunctionInputFile { |
| crypto_info: crypto.into(), |
| } |
| } |
| + |
| + pub fn is_placeholder(&self) -> bool { |
| + let scheme = self.url.scheme(); |
| + scheme.eq("placeholder") |
| + } |
| } |
| |
| impl From<TeaclaveInputFile> for FunctionInputFile { |
| diff --git a/types/src/task_state.rs b/types/src/task_state.rs |
| index 54227d5..68e2325 100644 |
| --- a/types/src/task_state.rs |
| +++ b/types/src/task_state.rs |
| @@ -129,10 +129,24 @@ impl Task<Create> { |
| } |
| |
| //check function compatibility |
| - let fn_args_spec: HashSet<&String> = function.arguments.iter().collect(); |
| + let fn_args_spec: HashSet<&String> = function |
| + .arguments |
| + .iter() |
| + .filter(|arg| arg.allow_overwrite) |
| + .map(|arg| &arg.key) |
| + .collect(); |
| let req_args: HashSet<&String> = req_func_args.inner().keys().collect(); |
| - ensure!(fn_args_spec == req_args, "function_arguments mismatch"); |
| - |
| + ensure!(req_args == fn_args_spec, "function_arguments mismatch"); |
| + |
| + let mut func_args = req_func_args.clone(); |
| + for arg in &function.arguments { |
| + if !arg.allow_overwrite || !func_args.inner().contains_key(&arg.key) { |
| + func_args.insert( |
| + arg.key.clone(), |
| + serde_json::Value::String(arg.default_value.clone()), |
| + ); |
| + } |
| + } |
| // check input fkeys |
| let inputs_spec: HashSet<&String> = function.inputs.iter().map(|f| &f.name).collect(); |
| let mut req_input_fkeys: HashSet<&String> = req_input_owners.keys().collect(); |
| @@ -166,7 +180,7 @@ impl Task<Create> { |
| executor: req_executor, |
| function_id: function.external_id(), |
| function_owner: function.owner.clone(), |
| - function_arguments: req_func_args, |
| + function_arguments: func_args, |
| inputs_ownership: req_input_owners, |
| outputs_ownership: req_output_owners, |
| participants, |
| diff --git a/types/src/worker.rs b/types/src/worker.rs |
| index a3cc5be..343878d 100644 |
| --- a/types/src/worker.rs |
| +++ b/types/src/worker.rs |
| @@ -42,6 +42,7 @@ pub enum ExecutorType { |
| Builtin, |
| Python, |
| WAMicroRuntime, |
| + CleanroomRuntime, |
| } |
| |
| impl std::default::Default for ExecutorType { |
| @@ -58,6 +59,7 @@ impl std::convert::TryFrom<&str> for ExecutorType { |
| "python" => ExecutorType::Python, |
| "builtin" => ExecutorType::Builtin, |
| "wamr" => ExecutorType::WAMicroRuntime, |
| + "cleanroom" => ExecutorType::CleanroomRuntime, |
| _ => anyhow::bail!("Invalid executor type: {}", selector), |
| }; |
| Ok(executor_type) |
| @@ -84,6 +86,7 @@ impl std::fmt::Display for ExecutorType { |
| ExecutorType::Builtin => write!(f, "builtin"), |
| ExecutorType::Python => write!(f, "python"), |
| ExecutorType::WAMicroRuntime => write!(f, "wamr"), |
| + ExecutorType::CleanroomRuntime => write!(f, "cleanroom"), |
| } |
| } |
| } |
| @@ -93,6 +96,7 @@ pub enum Executor { |
| MesaPy, |
| Builtin, |
| WAMicroRuntime, |
| + CleanroomRuntime, |
| } |
| |
| impl std::default::Default for Executor { |
| @@ -109,6 +113,7 @@ impl std::convert::TryFrom<&str> for Executor { |
| "mesapy" => Executor::MesaPy, |
| "builtin" => Executor::Builtin, |
| "wamr" => Executor::WAMicroRuntime, |
| + "cleanroom" => Executor::CleanroomRuntime, |
| _ => anyhow::bail!("Unsupported executor: {}", selector), |
| }; |
| Ok(executor) |
| @@ -129,6 +134,7 @@ impl std::fmt::Display for Executor { |
| Executor::MesaPy => write!(f, "mesapy"), |
| Executor::Builtin => write!(f, "builtin"), |
| Executor::WAMicroRuntime => write!(f, "wamr"), |
| + Executor::CleanroomRuntime => write!(f, "cleanroom"), |
| } |
| } |
| } |
| diff --git a/worker/Cargo.toml b/worker/Cargo.toml |
| index edae189..a5d53cb 100644 |
| --- a/worker/Cargo.toml |
| +++ b/worker/Cargo.toml |
| @@ -17,7 +17,7 @@ |
| |
| [package] |
| name = "teaclave_worker" |
| -version = "0.4.0" |
| +version = "0.2.0" |
| authors = ["Teaclave Contributors <dev@teaclave.apache.org>"] |
| description = "Teaclave worker" |
| license = "Apache-2.0" |
| @@ -39,7 +39,7 @@ cov = ["sgx_cov"] |
| enclave_unit_test = ["teaclave_test_utils/mesalock_sgx"] |
| |
| [dependencies] |
| -log = { version = "0.4.6", features = ["release_max_level_info"] } |
| +log = { version = "0.4.6", features = ["release_max_level_debug"] } |
| anyhow = { version = "1.0.26" } |
| serde_json = { version = "1.0.39" } |
| thiserror = { version = "1.0.9" } |
| diff --git a/worker/src/worker.rs b/worker/src/worker.rs |
| index 27cc419..add9d0a 100644 |
| --- a/worker/src/worker.rs |
| +++ b/worker/src/worker.rs |
| @@ -65,6 +65,10 @@ impl Default for Worker { |
| (ExecutorType::WAMicroRuntime, Executor::WAMicroRuntime), |
| || Box::new(WAMicroRuntime::default()), |
| ); |
| + worker.register_executor( |
| + (ExecutorType::CleanroomRuntime, Executor::CleanroomRuntime), |
| + || Box::new(CleanroomRuntime::default()), |
| + ); |
| |
| worker |
| } |
| @@ -87,6 +91,7 @@ impl Worker { |
| } |
| |
| pub fn invoke_function(&self, function: StagedFunction) -> anyhow::Result<String> { |
| + log::info!("staged function: {}", function); |
| let executor = self.get_executor(function.executor_type, function.executor)?; |
| let runtime = self.get_runtime( |
| &function.runtime_name, |