Skip to content

Commit

Permalink
Rust Oak Loader (#749)
Browse files Browse the repository at this point in the history
This change adds a Rust version of the Oak Loader.

Fixes #723
  • Loading branch information
ipetr0v authored Apr 8, 2020
1 parent 5bb4e7a commit 3619cab
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 21 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ members = [
"experimental/split_grpc/proxy",
"experimental/split_grpc/server",
"oak/server/rust/oak_abi",
"oak/server/rust/oak_loader",
"oak/server/rust/oak_runtime",
"runner",
"sdk/rust/oak",
Expand All @@ -35,6 +36,7 @@ members = [
# Oak.
oak = { path = "sdk/rust/oak" }
oak_abi = { path = "oak/server/rust/oak_abi" }
oak_loader = { path = "oak/server/rust/oak_loader" }
oak_runtime = { path = "oak/server/rust/oak_runtime" }
oak_tests = { path = "sdk/rust/oak_tests" }
oak_utils = { path = "sdk/rust/oak_utils" }
Expand Down
13 changes: 13 additions & 0 deletions oak/server/rust/oak_loader/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "oak_loader"
version = "0.1.0"
authors = ["Ivan Petrov <[email protected]>"]
edition = "2018"
license = "Apache-2.0"

[dependencies]
env_logger = "*"
log = "*"
oak_runtime = "=0.1.0"
prost = "*"
structopt = "*"
71 changes: 71 additions & 0 deletions oak/server/rust/oak_loader/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// Copyright 2020 The Project Oak Authors
//
// Licensed 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.
//

//! An utility binary to run Oak Runtime.
//!
//! To invoke, run the following command from the root of the repository:
//!
//! ```
//! cargo run --package=oak_loader -- --application=<APP_CONFIG_PATH>
//! ```

use log::info;
use oak_runtime::{configure_and_run, proto::ApplicationConfiguration};
use prost::Message;
use std::{fs::File, io::Read, thread::park};
use structopt::StructOpt;

#[derive(StructOpt, Clone)]
#[structopt(about = "Oak Loader")]
pub struct Opt {
#[structopt(long, help = "Application configuration file")]
application: String,
// TODO(#806): Make arguments non-optional once TLS support is enabled.
#[structopt(long, help = "Path to the PEM-encoded CA root certificate")]
ca_cert: Option<String>,
#[structopt(long, help = "Path to the private key")]
private_key: Option<String>,
#[structopt(long, help = "Path to the PEM-encoded certificate chain")]
cert_chain: Option<String>,
}

fn read_file(filename: &str) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let mut file = File::open(filename)
.map_err(|error| format!("Failed to open file <{}>: {:?}", filename, error))?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)
.map_err(|error| format!("Failed to read file <{}>: {:?}", filename, error))?;
Ok(buffer)
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
info!("Loading Oak Runtime");

let opt = Opt::from_args();
let app_config = {
let buffer = read_file(&opt.application)?;
ApplicationConfiguration::decode(&buffer[..])
.map_err(|error| format!("Failed to decode application configuration: {:?}", error))?
};

// Spawns a new thread corresponding to an initial Wasm Oak node.
configure_and_run(app_config).map_err(|error| format!("Runtime error: {:?}", error))?;
// Park current thread.
park();

Ok(())
}
23 changes: 15 additions & 8 deletions scripts/build_server
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Build the specified version of the Oak Runtime server.
-s Server type:
- base: base version of the server (default)
- rust: Rust version of the server
- arm: server for ARM architecture
- asan: server with address sanitizer
- tsan: server with thread santizer
Expand All @@ -23,6 +24,8 @@ Build the specified version of the Oak Runtime server.
case "${OPTARG}" in
base)
config='clang';;
rust)
config='rust';;
arm)
config='armv8';;
asan)
Expand All @@ -39,12 +42,16 @@ Build the specified version of the Oak Runtime server.
esac
done

bazel_build_flags+=(
"--config=${config}"
)
if [[ "${config}" == "rust" ]]; then
cargo build --package=oak_loader
else
bazel_build_flags+=(
"--config=${config}"
)

# Use a different output_base so that we don't lose incremental state.
# See https://docs.bazel.build/versions/master/command-line-reference.html#flag--output_base.
bazel --output_base="${CACHE_DIR}/$config" build "${bazel_build_flags[@]}" \
//oak/server/loader:oak_runner \
//oak/server/storage:storage_server
# Use a different output_base so that we don't lose incremental state.
# See https://docs.bazel.build/versions/master/command-line-reference.html#flag--output_base.
bazel --output_base="${CACHE_DIR}/$config" build "${bazel_build_flags[@]}" \
//oak/server/loader:oak_runner \
//oak/server/storage:storage_server
fi
4 changes: 4 additions & 0 deletions scripts/common
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ set -o errexit
set -o nounset
set -o xtrace

# Set the default Rust log level.
# https://docs.rs/env_logger
export RUST_LOG='info'

# See https://pantheon.corp.google.com/gcr/images/oak-ci/GLOBAL/oak
readonly DOCKER_IMAGE_NAME='gcr.io/oak-ci/oak'
readonly SERVER_DOCKER_IMAGE_NAME='gcr.io/oak-ci/oak-server'
Expand Down
13 changes: 9 additions & 4 deletions scripts/run_example
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,35 @@ source "${SCRIPTS_DIR}/common"
language="rust"
server="base"
buildargs=""
while getopts "s:l:de:h" opt; do
serverargs=""
while getopts "s:l:de:vh" opt; do
case "${opt}" in
h)
echo -e "Usage: ${0} [-h] [-s base|asan|tsan|none] [-l rust|cpp] [-d] -e EXAMPLE [-- CLIENT_ARGS]
echo -e "Usage: ${0} [-h] [-s base|asan|tsan|none] [-l rust|cpp] [-d] -e EXAMPLE [-- CLIENT_ARGS] [-v]
Build and run the given example Oak Application and client.
Options:
-e Example application name (required)
-s Server type used to run examples:
- base: base version of the server (default)
- rust: Rust version of the server
- asan: server with address sanitizer
- tsan: server with thread sanitizer
- none: run an application client without a server
-d Build C++ code for example using debug mode
-l Example application variant:
- rust (used by default)
- cpp
-v Enable verbose/debug output for the server
-h Print Help (this message) and exit
Options after -- will be passed to the example client program."
exit 0;;
l)
language="${OPTARG}";;
s)
case "${OPTARG}" in
base|asan|tsan|none)
base|rust|asan|tsan|none)
server="${OPTARG}";;
*)
echo "Invalid server type: ${OPTARG}"
Expand All @@ -42,6 +45,8 @@ Options after -- will be passed to the example client program."
buildargs='-d';;
e)
readonly EXAMPLE="${OPTARG}";;
v)
serverargs='-v';;
*)
echo "Invalid argument: ${OPTARG}"
exit 1;;
Expand All @@ -68,7 +73,7 @@ if [[ "${server}" != "none" ]]; then
# The server is being built before running, so the build process will not happen in the
# background.
"${SCRIPTS_DIR}/build_server" -s "${server}"
"${SCRIPTS_DIR}/run_server" -s "${server}" -l "${language}" -e "${EXAMPLE}" &
"${SCRIPTS_DIR}/run_server" ${serverargs} -s "${server}" -l "${language}" -e "${EXAMPLE}" &
readonly SERVER_PID=$!

function stop_server {
Expand Down
30 changes: 21 additions & 9 deletions scripts/run_server
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ source "${SCRIPTS_DIR}/common"

language="rust"
server="base"
while getopts "s:a:l:e:h" opt; do
while getopts "s:a:l:e:vh" opt; do
case "${opt}" in
h)
echo -e "Usage: ${0} [-s base|arm|asan|tsan] [-l rust|cpp] (-a APPLICATION | -e EXAMPLE)
echo -e "Usage: ${0} [-s base|arm|asan|tsan] [-l rust|cpp] (-a APPLICATION | -e EXAMPLE) [-v]
Run a particular Oak Application in the Oak Runtime.
Either the -a APPLICATION or the -e EXAMPLE option is required.
Expand All @@ -18,19 +18,21 @@ Either the -a APPLICATION or the -e EXAMPLE option is required.
-e Example application name
-s Server type:
- base: base version of the server (default)
- rust: Rust version of the server
- arm: server for ARM architecture
- asan: server with address sanitizer
- tsan: server with thread santizer
-l Example application variant (if -e specified):
- rust (used by default)
- cpp
-v Enable verbose/debug output
-h Print Help (this message) and exit"
exit 0;;
l)
language="${OPTARG}";;
s)
case "${OPTARG}" in
base|arm|asan|tsan)
base|rust|arm|asan|tsan)
server="${OPTARG}";;
*)
echo "Invalid server type: ${OPTARG}"
Expand All @@ -40,6 +42,8 @@ Either the -a APPLICATION or the -e EXAMPLE option is required.
readonly APPLICATION="${OPTARG}";;
e)
readonly EXAMPLE="${OPTARG}";;
v)
RUST_LOG='debug';;
*)
echo "Invalid argument: ${OPTARG}"
exit 1;;
Expand Down Expand Up @@ -73,9 +77,17 @@ fi

# Launching the server requires a `--application=<dir>/config.bin` flag.
# `exec` is necessary for the `run_example` script to be able to get a PID of a background server.
# We use a different symlink prefix for clang-based artifacts.
exec ./bazel-clang-bin/oak/server/loader/oak_runner \
--application="${APPLICATION}" \
--ca_cert="${SCRIPTS_DIR}/../examples/certs/local/ca.pem" \
--cert_chain="${SCRIPTS_DIR}/../examples/certs/local/local.pem" \
--private_key="${SCRIPTS_DIR}/../examples/certs/local/local.key"
if [[ "${server}" == "rust" ]]; then
exec cargo run --package=oak_loader -- \
--application="${APPLICATION}" \
--ca-cert="${SCRIPTS_DIR}/../examples/certs/local/ca.pem" \
--cert-chain="${SCRIPTS_DIR}/../examples/certs/local/local.pem" \
--private-key="${SCRIPTS_DIR}/../examples/certs/local/local.key"
else
# We use a different symlink prefix for clang-based artifacts.
exec ./bazel-clang-bin/oak/server/loader/oak_runner \
--application="${APPLICATION}" \
--ca_cert="${SCRIPTS_DIR}/../examples/certs/local/ca.pem" \
--cert_chain="${SCRIPTS_DIR}/../examples/certs/local/local.pem" \
--private_key="${SCRIPTS_DIR}/../examples/certs/local/local.key"
fi

0 comments on commit 3619cab

Please sign in to comment.