action compiler
diff --git a/README.md b/README.md
index 89ddcdf..ca09760 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,3 @@
# incubator-openwhisk-runtime-rust
+
+Work in Progress! Do not use...
diff --git a/rust1.32/Dockerfile b/rust1.32/Dockerfile
new file mode 100644
index 0000000..07a6bb9
--- /dev/null
+++ b/rust1.32/Dockerfile
@@ -0,0 +1,25 @@
+#
+# 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 actionloop/actionloop-v2:latest as builder
+FROM rust:1.32
+COPY --from=builder /bin/proxy /bin/proxy
+RUN mkdir -p /action
+ADD compile /bin/compile
+ADD compile.launcher.rs /bin/compile.launcher.rs
+ENV OW_COMPILER=/bin/compile
+WORKDIR /action
+ENTRYPOINT ["/bin/proxy"]
diff --git a/rust1.32/Makefile b/rust1.32/Makefile
new file mode 100644
index 0000000..46598eb
--- /dev/null
+++ b/rust1.32/Makefile
@@ -0,0 +1,12 @@
+USER?=openwhisk
+IMAGE=actionloop-rust-v1.32
+
+.PHONY: build
+
+build:
+ docker build -t $(USER)/$(IMAGE) .
+
+devel: build
+ docker run -ti -p 8080:8080 --entrypoint=bash \
+ -v $(PWD):/mnt -e OW_COMPILER=/mnt/compile \
+ $(USER)/$(IMAGE)
diff --git a/rust1.32/compile b/rust1.32/compile
new file mode 100755
index 0000000..0c3228d
--- /dev/null
+++ b/rust1.32/compile
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+"""Rust Action Builder
+#
+# 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 __future__ import print_function
+import os, sys, codecs, subprocess
+from os.path import abspath, exists, dirname
+import tempfile
+
+## utils
+# write a file creating intermediate directories
+def write_file(file, body):
+ os.makedirs(dirname(file), mode=0o755, exist_ok=True)
+ with open(file, mode="w", encoding="utf-8") as f:
+ f.write(body)
+
+# copy a file eventually replacing a substring
+def copy_replace(src, dst, match=None, replacement=""):
+ with codecs.open(src, 'r', 'utf-8') as s:
+ body = s.read()
+ if match:
+ body = body.replace(match, replacement)
+ write_file(dst, body)
+
+## cargo
+cargo_action = """[package]
+name = "actions"
+version = "0.1.0"
+
+[dependencies]
+serde_json = "1.0"
+"""
+
+cargo_actionloop = """[package]
+name = "action_loop"
+version = "0.1.0"
+authors = ["Roberto Diaz <roberto@theagilemonkeys.com>"]
+
+[dependencies]
+serde_json = "1.0"
+libc = "0.2.49"
+actions = { path = "../actions" }
+"""
+
+cargo_workspace = """
+[workspace]
+
+members = [
+"action_loop",
+"actions",
+]
+"""
+
+def build():
+ pass
+
+def sources(main, src_dir, tgt_dir, launcher):
+ src_file = abspath("%s/exec" % src_dir)
+
+ # move exec in the right place
+ if exists(src_file):
+ os.makedirs(src_dir+"/src", mode=0o755, exist_ok=True)
+ copy_replace(src_file, src_dir+"/src/exec__.rs")
+
+ # add a cargo.toml if needed
+ cargo_action_file = src_dir+"/Cargo.toml"
+ if not exists(cargo_action_file):
+ write_file(cargo_action_file, cargo_action)
+
+ # write the boilerplate in a temp dir
+ os.makedirs("/tmp/src", mode=0o755, exist_ok=True)
+ tmp_dir = tempfile.mkdtemp(prefix='/tmp/src/')
+ copy_replace(launcher, tmp_dir+"/action_loop/src/main.rs",
+ "use actions::main as actionMain;",
+ "use actions::%s as actionMain;" % main )
+ write_file(tmp_dir+"/action_loop/Cargo.toml", cargo_actionloop)
+ write_file(tmp_dir+"/Cargo.toml", cargo_workspace)
+ os.rename(src_dir, tmp_dir+"/actions")
+ return tmp_dir
+
+if __name__ == '__main__':
+ if len(sys.argv) < 4:
+ sys.stdout.write("usage: <main-function> <source-dir> <target-dir>\n")
+ sys.stdout.flush()
+ sys.exit(1)
+ dir = sources(sys.argv[1], abspath(sys.argv[2]), abspath(sys.argv[3]), abspath(sys.argv[0]+".launcher.rs"))
+ print(dir)
+ sys.stdout.flush()
+ sys.stderr.flush()
diff --git a/rust1.32/compile.launcher.rs b/rust1.32/compile.launcher.rs
new file mode 100644
index 0000000..9f50140
--- /dev/null
+++ b/rust1.32/compile.launcher.rs
@@ -0,0 +1,41 @@
+extern crate serde_json;
+extern crate actions;
+extern crate libc;
+
+use std::env;
+use std::io::{self, Write, stdout, stderr};
+use std::fs::File;
+use std::os::unix::io::FromRawFd;
+use std::collections::HashMap;
+use serde_json::{Value, Error};
+use actions::main as actionMain;
+
+fn main() {
+ loop {
+ let mut buffer = String::new();
+ io::stdin().read_line(&mut buffer).unwrap();
+ let parsed_input:Result<HashMap<String,Value>,Error> = serde_json::from_str(&buffer);
+ let mut payload:HashMap<String, Value> = HashMap::new();
+ match parsed_input {
+ Ok(n) => {
+ for (key, val) in n {
+ if key == "value" {
+ let mut unparsed_payload:Result<HashMap<String,Value>,Error> = serde_json::from_value(val);
+ match unparsed_payload {
+ Ok(value) => payload = value,
+ Err(_) => eprintln!("Error parsing value json")
+ }
+ } else {
+ env::set_var(format!("__OW_{}", key.to_uppercase()), val.to_string());
+ }
+ }
+ }
+ Err(e) => eprintln!("Error: {}", e)
+ }
+ let action_results = actionMain(payload);
+ let mut fd3 = unsafe { File::from_raw_fd(3) };
+ write!(&mut fd3, "{}", action_results);
+ stdout().flush();
+ stderr().flush();
+ }
+}