diff --git a/sgx-jvm/containers/core/Dockerfile b/sgx-jvm/containers/core/Dockerfile index 6907b1696b..e5969391ce 100644 --- a/sgx-jvm/containers/core/Dockerfile +++ b/sgx-jvm/containers/core/Dockerfile @@ -12,10 +12,6 @@ ENV LANG C.UTF-8 ENV DEBIAN_FRONTEND noninteractive RUN apt-get update -qqy RUN apt-get install -qqy software-properties-common apt-utils -RUN add-apt-repository \ - "deb http://archive.ubuntu.com/ubuntu/ trusty main restricted" -RUN add-apt-repository \ - "deb http://archive.ubuntu.com/ubuntu/ trusty universe" RUN apt-get update -qqy # Install dependencies (lock versions) @@ -33,7 +29,7 @@ RUN apt-get install -qqy \ git=1:2.7.4-0ubuntu1.3 \ libcurl3=7.47.0-1ubuntu2.5 \ libcurl4-openssl-dev=7.47.0-1ubuntu2.5 \ - libprotobuf8=2.5.0-9ubuntu1 \ + libprotobuf-dev=2.6.1-1.3 \ libssl-dev=1.0.2g-1ubuntu4.10 \ libtool=2.4.6-0.1 \ libunwind8=1.1-4.1 \ @@ -42,47 +38,13 @@ RUN apt-get install -qqy \ openjdk-8-jdk=8u151-b12-0ubuntu0.16.04.2 \ openssl=1.0.2g-1ubuntu4.10 \ patch=2.7.5-1 \ - proguard=5.2.1-3 \ + protobuf-compiler=2.6.1-1.3 \ python2.7=2.7.12-1ubuntu0~16.04.2 \ unzip=6.0-20ubuntu1 \ wget=1.17.1-1ubuntu1.3 \ zip=3.0-11 \ zlib1g-dev=1:1.2.8.dfsg-2ubuntu4.1 -RUN apt-get install -qqy -t trusty \ - protobuf-compiler=2.6.1-1.3 \ - libprotobuf-dev=2.6.1-1.3 - -# Environment - -ENV SHELL /bin/bash -ENV HOME /root -ENV CODE /code -ENV SGX_SDK /sgx - -# Volumes and work directory - -VOLUME ${HOME} -VOLUME ${CODE} -VOLUME ${SGX_SDK} -RUN mkdir -p ${HOME} -RUN mkdir -p ${CODE} -RUN mkdir -p ${SGX_SDK} -WORKDIR ${CODE} - -# Expose ports for remote GDB and Java debugging, and test servers - -EXPOSE 2000 5005 8080 9080 - -# Set up Java and SGX environment - -ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64 - -ENV SGX_BIN ${SGX_SDK}/sgxsdk/bin:${SGX_SDK}/sgxsdk/bin/x64 -ENV PATH ${PATH}:${JAVA_HOME}/jre/bin:${JAVA_HOME}/bin:${SGX_BIN} - -ENV LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:${CODE}/sgx-jvm/linux-sgx/build/linux - # Set Python 2.7 as the default version RUN ln -fs \ @@ -102,3 +64,37 @@ RUN mkdir -p /var/run/aesmd/ # Update ProGuard to version 6 beta ADD dependencies/proguard6.0beta1.tar.gz /usr/share/ + +# Expose ports for remote GDB and Java debugging, and test servers + +EXPOSE 2000 5005 8080 9080 + +# Environment + +ENV SHELL /bin/bash +ENV CODE /code +ENV HOME /home +ENV USER_HOME ${HOME} +ENV GRADLE_USER_HOME ${HOME}/.gradle +ENV SGX_SDK /sgx + +# Volumes and work directory + +VOLUME ${CODE} +VOLUME ${HOME} +VOLUME ${SGX_SDK} +RUN mkdir -p ${CODE} +RUN mkdir -p ${HOME} +RUN mkdir -p ${SGX_SDK} +RUN echo "PS1='container> '" > ${HOME}/.bashrc +WORKDIR ${CODE} + +# Set up Java and SGX environment + +ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64 +ENV _JAVA_OPTIONS=-Duser.home=${HOME} + +ENV SGX_BIN ${SGX_SDK}/sgxsdk/bin:${SGX_SDK}/sgxsdk/bin/x64 +ENV PATH ${PATH}:${JAVA_HOME}/jre/bin:${JAVA_HOME}/bin:${SGX_BIN} + +ENV LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:${CODE}/sgx-jvm/linux-sgx/build/linux diff --git a/sgx-jvm/remote-attestation/host/Makefile b/sgx-jvm/remote-attestation/host/Makefile index fab45e1cf5..2174c4ead4 100644 --- a/sgx-jvm/remote-attestation/host/Makefile +++ b/sgx-jvm/remote-attestation/host/Makefile @@ -1,17 +1,13 @@ -.PHONY: host host-native docs \ - unit-tests unit-tests-force \ - integration-tests integration-tests-force \ - run run-local run-remote run-sgx \ - clean +.PHONY: host host-native docs clean \ + unit-tests integration-tests \ + run run-local run-remote run-sgx # === GENERAL PARAMETERS ========================================================================== SHELL = /bin/bash MAKEFILE_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) -GRADLE ?= $(MAKEFILE_DIR)/../gradlew - -# TODO Update to Dokka 0.9.16 (when available) to fix: https://github.com/Kotlin/dokka/issues/184 -DOKKA_FILTER = grep -v "Can't find node by signature" +GRADLE_HOME ?= $(MAKEFILE_DIR)/../.gradle/ +GRADLE ?= $(MAKEFILE_DIR)/../gradlew -g $(GRADLE_HOME) # === PSEUDO TARGETS ============================================================================== @@ -22,51 +18,27 @@ host-native: make -C native all docs: - $(GRADLE) dokka | $(DOKKA_FILTER) + $(GRADLE) cleanDokka dokka -docs-force: - rm -rf $(MAKEFILE_DIR)/build/javadoc - $(GRADLE) dokka | $(DOKKA_FILTER) +unit-tests: + $(GRADLE) --rerun-tasks -q -Pdebug=$(DEBUG) test -unit-tests: host-native - $(GRADLE) test - -unit-tests-force: host-native - $(GRADLE) cleanTest test - -integration-tests: host-native - $(GRADLE) integrationTest - -integration-tests-force: host-native - $(GRADLE) cleanIntegrationTest integrationTest - -~/.classpath: - $(GRADLE) -q getClasspath > ~/.classpath +integration-tests: + $(GRADLE) --rerun-tasks -q -Pdebug=$(DEBUG) integrationTest clean: $(GRADLE) clean - rm -f ~/.classpath # === TEST TARGETS ================================================================================ -JAVA_PROG = $(JAVA_HOME)/bin/java -SGX_GDB = /sgx/sgxsdk/bin/sgx-gdb -HOST = localhost:2000 -MAIN_CLASS = net.corda.sgx.cli.Program -JVM_DEFS = -Dcorda.sgx.enclave.path=/code/sgx-jvm/remote-attestation/enclave/build \ - -Djava.library.path=/code/sgx-jvm/remote-attestation/host/native/build \ - -Dfile.encoding=US-ASCII -Duser.country=US -Duser.language=en -Duser.variant \ - -Dattestation.home=/code/sgx-jvm/remote-attestation/host/build/logs -JVM_ARGS = -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 +run: + $(GRADLE) -q -Pdebug=$(DEBUG) runFlow -run: ~/.classpath - $(JAVA_PROG) $(JVM_DEFS) $(JVM_ARGS) -cp `cat ~/.classpath` $(MAIN_CLASS) +run-local: + $(GRADLE) -q -Pdebug=$(DEBUG) runFlowWithNativeDebugger -run-local: ~/.classpath - gdb --args $(JAVA_PROG) $(JVM_DEFS) $(JVM_ARGS) -cp `cat ~/.classpath` $(MAIN_CLASS) +run-sgx: + $(GRADLE) -q -Pdebug=$(DEBUG) runFlowWithNativeSgxDebugger -run-sgx: ~/.classpath - $(SGX_GDB) --args $(JAVA_PROG) $(JVM_DEFS) $(JVM_ARGS) -cp `cat ~/.classpath` $(MAIN_CLASS) - -run-remote: ~/.classpath - gdbserver $(HOST) $(JAVA_PROG) $(JVM_DEFS) $(JVM_ARGS) -cp `cat ~/.classpath` $(MAIN_CLASS) +run-remote: + $(GRADLE) -q -Pdebug=$(DEBUG) runFlowWithNativeDebugServer diff --git a/sgx-jvm/remote-attestation/host/build.gradle b/sgx-jvm/remote-attestation/host/build.gradle index 8307f092ec..bfd7ffec32 100644 --- a/sgx-jvm/remote-attestation/host/build.gradle +++ b/sgx-jvm/remote-attestation/host/build.gradle @@ -6,7 +6,24 @@ buildscript { ext.nativeBuildDir = "$projectDir/native/build" ext.enclaveBuildDir = "$projectDir/../enclave/build" - ext.debugArgs = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005" + + if (!project.hasProperty("debug")) { + ext.debug = false + } else { + ext.debug = (ext.debug == "1" || ext.debug == "yes" || ext.debug == "true") + } + + if (!project.hasProperty("debugPort")) { + ext.debugPort = 5005 + } else { + ext.debugPort = Integer.parseInt(ext.debugPort.toString()) + } + + if (ext.debug) { + ext.debugArgs = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,timeout=10000,address=$debugPort" + } else { + ext.debugArgs = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$debugPort" + } repositories { mavenLocal() @@ -19,6 +36,7 @@ buildscript { } } +apply from: 'utilities.gradle' apply plugin: 'kotlin' apply plugin: 'application' apply plugin: 'org.jetbrains.dokka' @@ -75,8 +93,60 @@ tasks.withType(Test) { jvmArgs "$debugArgs" } -task getClasspath(type: Task) { - doLast { - println sourceSets.main.runtimeClasspath.collect { it.toString() }.join(":") - } +task cleanEnclave(type: Exec) { + commandLine containerArgs("enclave", "clean") +} + +task cleanJniLibrary(type: Exec) { + commandLine containerArgs("host/native", "clean") +} + +clean.dependsOn.addAll 'cleanEnclave', 'cleanJniLibrary' + +task buildEnclave(type: Exec) { + commandLine containerArgs("enclave", "all") +} + +task buildJniLibrary(type: Exec, dependsOn: ['buildEnclave', 'classes']) { + commandLine containerArgs("host/native", "all") +} + +task runFlow(type: Exec, dependsOn: ['buildJniLibrary']) { + commandLine runArgs(["java"], ["net.corda.sgx.cli.Program"]) +} + +task runFlowWithNativeDebugger(type: Exec, dependsOn: ['buildJniLibrary']) { + commandLine runArgs(["gdb", "--args", "java"], ["net.corda.sgx.cli.Program"]) +} + +task runFlowWithNativeSgxDebugger(type: Exec, dependsOn: ['buildJniLibrary']) { + commandLine runArgs(["sgx-gdb", "--args", "java"], ["net.corda.sgx.cli.Program"]) +} + +task runFlowWithNativeDebugServer(type: Exec, dependsOn: ['buildJniLibrary']) { + commandLine runArgs(["gdbserver", "localhost:2000", "java"], ["net.corda.sgx.cli.Program"]) +} + +task runUnitTestsInContainer(type: Task, dependsOn: ['buildJniLibrary']) { + doLast { containerDebugWait("$projectDir", "host", "unit-tests") } +} + +task runIntegrationTestsInContainer(type: Task, dependsOn: ['buildJniLibrary']) { + doLast { containerDebugWait("$projectDir", "host", "integration-tests") } +} + +task runFlowInContainer(type: Task, dependsOn: ['buildJniLibrary']) { + doLast { containerDebugWait("$projectDir", "host", "run") } +} + +task debugUnitTestsInContainer(type: Task, dependsOn: ['buildJniLibrary']) { + doLast { containerDebugWait("$projectDir", "host", "DEBUG=1", "unit-tests") } +} + +task debugIntegrationTestsInContainer(type: Task, dependsOn: ['buildJniLibrary']) { + doLast { containerDebugWait("$projectDir", "host", "DEBUG=1", "integration-tests") } +} + +task debugFlowInContainer(type: Task, dependsOn: ['buildJniLibrary']) { + doLast { containerDebugWait("$projectDir", "host", "DEBUG=1", "run") } } diff --git a/sgx-jvm/remote-attestation/host/utilities.gradle b/sgx-jvm/remote-attestation/host/utilities.gradle new file mode 100644 index 0000000000..2215d8092b --- /dev/null +++ b/sgx-jvm/remote-attestation/host/utilities.gradle @@ -0,0 +1,57 @@ +String[] runArgs(List prefix, List args) { + return [ + *prefix, + "-Dcorda.sgx.enclave.path=/code/sgx-jvm/remote-attestation/enclave/build", + "-Djava.library.path=/code/sgx-jvm/remote-attestation/host/native/build", + "-Dattestation.home=/code/sgx-jvm/remote-attestation/host/build/logs", + "-Dfile.encoding=US-ASCII", "-Duser.country=US", "-Duser.language=en", "-Duser.variant", + "-cp", sourceSets.main.runtimeClasspath.collect { it.toString() }.join(":"), + "$debugArgs", *args + ] +} + +String[] containerArgs(String project, String... args) { + return [ + "bash", "$projectDir/../../tools/sx/sx", "build", + "remote-attestation/$project", *args + ] +} + +def execWait(String[] command, String directory, String ready) { + ProcessBuilder builder = new ProcessBuilder(command) + builder.redirectErrorStream(true) + builder.directory(new File(directory)) + Process process = builder.start() + + if (ready == null) { + process.waitFor() + return + } + + InputStream stdout = process.getInputStream() + BufferedReader reader = new BufferedReader(new + InputStreamReader(stdout)) + + def line + while ((line = reader.readLine()) != null) { + println line + if (line.contains(ready)) { + println "Command $command is ready" + break + } + } + + stdout.close() +} + +def containerDebugWait(String directory, String project, String... args) { + def ready = "Listening for transport dt_socket at address:" + execWait(containerArgs(project, args), directory, ready) +} + +ext { + runArgs = this.&runArgs + containerArgs = this.&containerArgs + containerDebugWait = this.&containerDebugWait +} + diff --git a/sgx-jvm/tools/sx/sx b/sgx-jvm/tools/sx/sx index fc906b5557..bd24de30c9 100755 --- a/sgx-jvm/tools/sx/sx +++ b/sgx-jvm/tools/sx/sx @@ -341,9 +341,10 @@ in_container() { --network host \ --add-host="localhost:${docker_ip}" \ -v ${CODE}:/code \ - -v ${HOME}/.container:/root \ + -v ${HOME}/.container:/home \ -v ${HOME}/.container/sgx:/sgx \ -e "PORT=${ISV_PORT}" \ + -u `id -u`:`id -g` \ ${ports} \ ${isgx_device} \ ${mei0_device} \