ENT-1012 - Make SGX builds IntelliJ-friendly (#208)

* ENT-1012 - Use non-privileged user

* ENT-1012 - Build and run containerised tests from IntelliJ

* ENT-1012 - Remove trusty source in container

* ENT-1012 - Make debug target toggleable

* ENT-1012 - Inform when ready to attach debugger

* ENT-1012 - Update reference to user home folder
This commit is contained in:
Tommy Lillehagen 2017-12-19 10:19:35 +00:00 committed by GitHub
parent 0aa56f55b8
commit fbcdc23434
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 188 additions and 92 deletions

View File

@ -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

View File

@ -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

View File

@ -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") }
}

View File

@ -0,0 +1,57 @@
String[] runArgs(List<String> prefix, List<String> 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
}

View File

@ -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} \