diff --git a/deploy_stack.sh b/deploy_stack.sh index c55fc2714710120af18e1a25c2056208cbb7a99b..a900d6d5c75bcce423e10528767f07bb38e67f18 100755 --- a/deploy_stack.sh +++ b/deploy_stack.sh @@ -1,4 +1,4 @@ #!/bin/sh echo "Deploying stack" -docker stack rm func ; docker stack deploy func --compose-file docker-compose.yml +docker stack deploy func --compose-file docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml index e613213bde54a1ade3e1653926c2e0b6d9a4d602..cf66e1daf0c45439a02e416a4287254075cd552d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -104,6 +104,15 @@ services: no_proxy: "gateway" https_proxy: $https_proxy + markdown: + image: alexellis2/faas-markdownrender:latest + depends_on: + - gateway + networks: + - functions + environment: + no_proxy: "gateway" + https_proxy: $https_proxy # alexacolorchange: # image: alexellis2/faas-alexachangecolorintent diff --git a/gateway/assets/index.html b/gateway/assets/index.html index 43b0c7ce7faa59fd005269a8719c2dff6727b5b7..6f6f5d13814b6fba7066556c8e6f9e6293032be3 100644 --- a/gateway/assets/index.html +++ b/gateway/assets/index.html @@ -50,11 +50,11 @@ </div> <div flex></div> </md-content> + <md-content flex layout="column" ng-repeat="function in functions" ng-show="function.name == selectedFunction.name"> <md-card md-theme="default" md-theme-watch> <md-card-title> - <md-card-title-text> <span class="md-headline"> @@ -77,12 +77,44 @@ <input ng-model="function.image" type="text" readonly="readonly"> </md-input-container> </div> - <md-card-title-text> - </md-card-title> </md-card> - + <md-card> + <md-card-title> + <md-card-title-text> + + <span class="md-headline"> + Invoke function + </span> + <div layout-gt-sm="row"> + <md-input-container class="md-block" flex-gt-sm> + <button ng-click="fireRequest()" class="md-raised md-button md-ink-ripple" type="button"> + <span class="ng-scope">Invoke</span><div class="md-ripple-container"></div> + </button> + </md-input-container> + </div> + <div layout-gt-sm="row"> + <md-input-container class="md-block" flex-gt-sm> + <label>Request body</label> + <textarea ng-model="invocation.request" cols="80" rows="4"></textarea> + </md-input-container> + </div> + <div layout-gt-sm="row"> + <md-input-container class="md-block" flex-gt-sm> + <label>Response status</label> + <input ng-model="invocationStatus" type="text" readonly="readonly"> + </md-input-container> + </div> + <div layout-gt-sm="row"> + <md-input-container class="md-block" flex-gt-sm> + <label>Response body</label> + <textarea ng-model="invocationResponse" cols="80" rows=10></textarea> + </md-input-container> + </div> + <md-card-title-text> + </md-card-title> + </md-card> </md-content> </section> </div> diff --git a/gateway/assets/script/bootstrap.js b/gateway/assets/script/bootstrap.js index 43ca49e0b74dc73c56abb574ae4da33f49db7c5b..d147be427e1203a974787c7ea3258616f8ab1d21 100644 --- a/gateway/assets/script/bootstrap.js +++ b/gateway/assets/script/bootstrap.js @@ -3,11 +3,55 @@ var app = angular.module('faasGateway', ['ngMaterial']); app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', function($scope, $log, $http, $location, $timeout) { $scope.functions = []; + $scope.invocationRequest = ""; + $scope.invocationResponse = ""; + $scope.invocationStatus = ""; + $scope.invocation = { + }; + $scope.invocation.request = "" setInterval(function() { - fetch(); + refreshData(); }, 1000); + $scope.fireRequest = function() { + $http({url:"/function/"+$scope.selectedFunction.name, data: $scope.invocation.request, method: "POST", headers: {"Content-Type": "text/plain"}, responseType: "text"}). + then(function(response) { + $scope.invocationResponse = response.data; + $scope.invocationStatus = response.status; + }).catch(function(error1) { + $scope.invocationResponse = error1; + $scope.invocationStatus = null; + }); + + // console.log("POST /function/"+ $scope.selectedFunction.name); + // console.log("Body: " + $scope.invocation.request); + }; + + var refreshData = function () { + var previous = $scope.functions; + + var cl = function(previousItems) { + $http.get("/system/functions").then(function(response) { + if(response && response.data) { + if(previousItems.length !=response.data.length) { + $scope.functions = response.data; + } else { + for(var i =0;i<$scope.functions.length;i++) { + for(var j =0;j<response.data.length;j++) { + if($scope.functions[i].name == response.data[j].name) { + $scope.functions[i].replicas=response.data[j].replicas; + $scope.functions[i].invocationCount=response.data[j].invocationCount; + } + } + } + } + } + }); + }; + cl(previous); + } + var fetch = function() { $http.get("/system/functions").then(function(response) { $scope.functions = response.data; @@ -15,7 +59,12 @@ app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', func }; $scope.showFunction = function(fn) { - $scope.selectedFunction = fn; + if($scope.selectedFunction!=fn) { + $scope.selectedFunction = fn; + $scope.invocation.request = ""; + $scope.invocationResponse = ""; + $scope.invocationStatus = ""; + } }; // TODO: popup + form to create new Docker service. diff --git a/gateway/build.sh b/gateway/build.sh index 8e34c77983e60f1eb1e26614bfa55da0df077f25..c000c144704ebe43cd898b0889860d1d52afadb2 100755 --- a/gateway/build.sh +++ b/gateway/build.sh @@ -10,4 +10,4 @@ docker rm -f gateway_extract echo Building alexellis2/faas-gateway:latest -docker build -t alexellis2/faas-gateway:latest-dev4 . +docker build --no-cache -t alexellis2/faas-gateway:latest-dev4 . diff --git a/sample-functions/MarkdownRender/Dockerfile b/sample-functions/MarkdownRender/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..1ef8f96015c171738127a59cb7bc44004b479f8f --- /dev/null +++ b/sample-functions/MarkdownRender/Dockerfile @@ -0,0 +1,16 @@ +FROM alpine:latest + +WORKDIR /root/ + +EXPOSE 8080 +ENV http_proxy "" +ENV https_proxy "" + +ADD https://github.com/alexellis/faas/releases/download/v0.3-alpha/fwatchdog /usr/bin +RUN chmod +x /usr/bin/fwatchdog +# COPY fwatchdog /usr/bin/ + +COPY app . + +ENV fprocess="/root/app" +CMD ["fwatchdog"] diff --git a/sample-functions/MarkdownRender/Dockerfile.build b/sample-functions/MarkdownRender/Dockerfile.build new file mode 100644 index 0000000000000000000000000000000000000000..f8697c190f512831fcd25489ce5a7462cce98c9c --- /dev/null +++ b/sample-functions/MarkdownRender/Dockerfile.build @@ -0,0 +1,10 @@ +FROM golang:1.7.3 +RUN mkdir -p /go/src/app +COPY handler.go /go/src/app +WORKDIR /go/src/app +RUN go get github.com/microcosm-cc/bluemonday && \ + go get github.com/russross/blackfriday + +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . + +CMD ["echo"] diff --git a/sample-functions/MarkdownRender/MarkdownRender b/sample-functions/MarkdownRender/MarkdownRender new file mode 100755 index 0000000000000000000000000000000000000000..7063de3120af1e619e8b760ef0e65cf64667d363 Binary files /dev/null and b/sample-functions/MarkdownRender/MarkdownRender differ diff --git a/sample-functions/MarkdownRender/app b/sample-functions/MarkdownRender/app new file mode 100755 index 0000000000000000000000000000000000000000..6dcb3f568012871530382c4914881a22c739918c Binary files /dev/null and b/sample-functions/MarkdownRender/app differ diff --git a/sample-functions/MarkdownRender/build.sh b/sample-functions/MarkdownRender/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..12a2f2857161f8cbb054cf91558a63285f33c42f --- /dev/null +++ b/sample-functions/MarkdownRender/build.sh @@ -0,0 +1,12 @@ +#!/bin/sh +echo Building alexellis2/faas-markdownrender:build + +docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \ + -t alexellis2/faas-markdownrender . -f Dockerfile.build + +docker create --name render_extract alexellis2/faas-markdownrender +docker cp render_extract:/go/src/app/app ./app +docker rm -f render_extract + +echo Building alexellis2/faas-markdownrender:latest +docker build --no-cache -t alexellis2/faas-markdownrender:latest . diff --git a/sample-functions/MarkdownRender/handler.go b/sample-functions/MarkdownRender/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..748d05601a575fa44174a17e6ff7c6e10401dc2e --- /dev/null +++ b/sample-functions/MarkdownRender/handler.go @@ -0,0 +1,17 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" + + "github.com/microcosm-cc/bluemonday" + "github.com/russross/blackfriday" +) + +func main() { + input, _ := ioutil.ReadAll(os.Stdin) + unsafe := blackfriday.MarkdownCommon([]byte(input)) + html := bluemonday.UGCPolicy().SanitizeBytes(unsafe) + fmt.Println(string(html)) +}