Преглед изворни кода

Add IncludeOS Mana framework (C++ unikernel) (#2936)

* Add .gitattributes to repo to ensure all files always have Linux line endings except powershell scripts

* Add C++ IncludeOS Mana Framework (plaintext test only)

* Use Docker to build and run IncludeOS-Mana
* Freeze IncludeOS to dev@807b424, v0.11.0-bundle fails on build
Ciaran Courtney пре 7 година
родитељ
комит
9253134c5e

+ 7 - 0
.gitattributes

@@ -0,0 +1,7 @@
+# disable line endings normalisation
+* -text
+
+# ensure Linux/Win specific files retain native line endings
+*.sh text eol=lf
+*.py text eol=lf
+*.ps1 text eol=crlf

+ 3 - 0
.travis.yml

@@ -8,6 +8,8 @@ group: deprecated-2017Q2
 language: generic
 python:
   - "2.7"
+services:
+  - docker
 
 env:
   matrix:
@@ -26,6 +28,7 @@ env:
     - "TESTDIR=C++/ffead-cpp"
     - "TESTDIR=C++/cpoll_cppsp"
     - "TESTDIR=C++/cutelyst"
+    - "TESTDIR=C++/includeos-mana"
     - "TESTDIR=C++/silicon"
     - "TESTDIR=C++/treefrog"
     - "TESTDIR=C++/ulib"

+ 2 - 0
frameworks/C++/includeos-mana/.gitignore

@@ -0,0 +1,2 @@
+build/
+IncludeOS/

+ 45 - 0
frameworks/C++/includeos-mana/CMakeLists.txt

@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 2.8.9)
+
+# IncludeOS install location
+if (NOT DEFINED ENV{INCLUDEOS_PREFIX})
+  set(ENV{INCLUDEOS_PREFIX} /usr/local)
+endif()
+include($ENV{INCLUDEOS_PREFIX}/includeos/pre.service.cmake)
+
+# Name of your project
+project (mana_simple)
+
+# Human-readable name of your service
+set(SERVICE_NAME "Mana Simple Example")
+
+# Name of your service binary
+set(BINARY       "mana_simple")
+
+# Source files to be linked with OS library parts to form bootable image
+set(SOURCES
+  service.cpp
+  )
+
+
+# DRIVERS / PLUGINS:
+
+if ("$ENV{PLATFORM}" STREQUAL "x86_solo5")
+  set(DRIVERS
+      solo5net
+    )
+else()
+  set(DRIVERS
+      virtionet
+    )
+endif()
+
+
+# THIRD PARTY LIBRARIES:
+
+set(LIBRARIES
+  "libmana.a"
+  )
+
+
+# include service build script
+include($ENV{INCLUDEOS_PREFIX}/includeos/post.service.cmake)

+ 11 - 0
frameworks/C++/includeos-mana/Dockerfile.build

@@ -0,0 +1,11 @@
+FROM includeos/includeos-common:0.10.0.1
+
+VOLUME /service
+WORKDIR /service
+
+CMD cd build && \
+  export INCLUDEOS_PREFIX=/home/ubuntu/IncludeOS_install && \
+  export CC=clang-3.8 && \
+  export CXX=clang++-3.8 && \
+  cmake .. && \
+  make

+ 36 - 0
frameworks/C++/includeos-mana/Dockerfile.common

@@ -0,0 +1,36 @@
+FROM ubuntu:xenial
+
+RUN apt-get update && apt-get -y install \
+    git \
+    lsb-release \
+    net-tools \
+    sudo \
+    wget \
+    && rm -rf /var/lib/apt/lists/*
+
+RUN useradd -m ubuntu && echo "ubuntu:ubuntu" | chpasswd && adduser ubuntu sudo
+
+# Enable passwordless sudo for users under the "sudo" group
+RUN sed -i.bkp -e \
+      's/%sudo\s\+ALL=(ALL\(:ALL\)\?)\s\+ALL/%sudo ALL=NOPASSWD:ALL/g' \
+      /etc/sudoers
+
+USER ubuntu
+ENV INCLUDEOS_PREFIX=/home/ubuntu/IncludeOS_install
+
+# Triggers new build if there are changes to head
+ADD https://api.github.com/repos/hioa-cs/IncludeOS/git/refs/heads/dev version.json
+
+# TAG can be specified when building with --build-arg TAG=...
+ARG TAG=15bb0ab61b59252782d9aa5fe29df5115208e638
+RUN echo "cloning $TAG"
+RUN cd ~ && pwd && \
+  git clone https://github.com/hioa-cs/IncludeOS.git && \
+  cd IncludeOS && \
+  git checkout $TAG && \
+  git submodule update --init --recursive && \
+  git fetch --tags
+
+RUN cd ~ && pwd && \
+  cd IncludeOS && \
+  ./install.sh -n

+ 9 - 0
frameworks/C++/includeos-mana/Dockerfile.qemu

@@ -0,0 +1,9 @@
+FROM includeos/includeos-common:0.10.0.1
+
+VOLUME /service/build
+WORKDIR /service/build
+
+ENTRYPOINT ["qemu-system-x86_64", "-nographic", "-m", "128", "-net", "nic,model=virtio", "-net", "user,hostfwd=tcp::8080-:80"]
+
+# working example i.e. curl <docker_ip>:8080
+#sudo qemu-system-x86_64 -nographic -m 128 -net nic,model=virtio -net user,hostfwd=tcp::8080-:80 -kernel $INCLUDEOS_PREFIX/chainloader -initrd mana_simple.img

+ 31 - 0
frameworks/C++/includeos-mana/README.md

@@ -0,0 +1,31 @@
+# Mana Benchmarking Test
+
+[Mana](https://github.com/includeos/mana) is a web framework for modern C++, designed to be run on the IncludeOS unikernel.
+
+### Features
+
+* Serve static content from a disk with just a few lines of code.
+* RESTful API service reading and posting JSON.
+* Real-time information about the server with an interactive Dashboard
+
+
+### Test URLs
+
+[/plaintext](http://www.techempower.com/benchmarks/#section=plaintext)
+----------
+```
+HTTP/1.1 200 OK
+Server: IncludeOS/v0.11.0
+Content-Type: text/plain
+Date: Mon, 01 Jan 1970 00:00:01 GMT
+Content-Length: 13
+
+Hello, world!
+```
+
+
+### TODO
+
+* Initial test run will fail (apart from on Travis CI) due to docker failing to run as non-root user until session is logged out and back in.
+* Travis run will fail at "Building IncludeOS Mana server" step (CMake file does not exist error)
+* IncludeOS-Mana eventually becomes unresponsive after benchmark has been running for >10sec and QEMU CPU will be 100%

+ 13 - 0
frameworks/C++/includeos-mana/_env_vars.sh

@@ -0,0 +1,13 @@
+if [ -z "$IROOT" ]; then
+  IROOT=$HOME/FrameworkBenchmarks/installs
+fi
+
+echo "IROOT=$IROOT"
+echo "TROOT=$TROOT"
+export INCLUDEOS_PREFIX=$IROOT/IncludeOS_install
+echo "INCLUDEOS_PREFIX=$INCLUDEOS_PREFIX"
+
+export PATH=$PATH:$INCLUDEOS_PREFIX/bin
+
+export CC=/usr/bin/clang-3.8
+export CXX=/usr/bin/clang++-3.8

+ 24 - 0
frameworks/C++/includeos-mana/benchmark_config.json

@@ -0,0 +1,24 @@
+{
+  "framework": "includeos-mana",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "plaintext_url": "/plaintext",
+      "port": 8080,
+      "approach": "Stripped",
+      "classification": "Platform",
+      "database": "None",
+      "framework": "Mana",
+      "language": "C++",
+      "flavor": "None",
+      "orm": "Raw",
+      "platform": "None",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "IncludeOS Mana",
+      "notes": "",
+      "versus": ""
+    }
+  }]
+}

+ 65 - 0
frameworks/C++/includeos-mana/service.cpp

@@ -0,0 +1,65 @@
+// This file is a part of the IncludeOS unikernel - www.includeos.org
+//
+// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
+// and Alfred Bratterud
+//
+// 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.
+
+#include <service>
+#include <os>
+#include <net/inet4>
+#include <mana/server.hpp>
+
+using namespace mana;
+using namespace std::string_literals;
+
+std::unique_ptr<mana::Server> server_;
+
+void Service::start(const std::string&)
+{
+  /** IP STACK SETUP **/
+  // Bring up IPv4 stack on network interface 0
+  auto& stack = net::Inet4::ifconfig(5.0,
+    [] (bool timeout) {
+      printf("DHCP resolution %s\n", timeout ? "failed" : "succeeded");
+      if (timeout)
+      {
+        /**
+         * Default Manual config. Can only be done after timeout to work
+         * with DHCP offers going to unicast IP (e.g. in GCE)
+         **/
+        net::Inet4::stack().network_config({ 10,0,0,42 },     // IP
+                                           { 255,255,255,0 }, // Netmask
+                                           { 10,0,0,1 },      // Gateway
+                                           { 8,8,8,8 });      // DNS
+      }
+    });
+
+  // Create a router
+  Router router;
+  // Setup a route on GET /
+  router.on_get("/plaintext", [](auto, auto res) {
+    res->source().set_status_code(http::OK);
+    res->header().add_field(http::header::Server, "IncludeOS/" + OS::version());
+    res->header().add_field(http::header::Content_Type, "text/plain");
+    res->header().add_field(http::header::Date, "Mon, 01 Jan 1970 00:00:01 GMT");
+    res->source().add_body("Hello, world!"s);
+    res->send();
+  });
+  INFO("Router", "Registered routes:\n%s", router.to_string().c_str());
+
+  // Create and setup the server
+  server_ = std::make_unique<Server>(stack.tcp());
+  server_->set_routes(router).listen(80);
+
+}

+ 24 - 0
frameworks/C++/includeos-mana/setup.sh

@@ -0,0 +1,24 @@
+#!/bin/bash
+
+INCLUDEOS_VERSION='807b42488614e4963304ee6ecef75e000f6f7be1'
+
+#fw_depends clang-3.8
+fw_depends docker
+
+# fail fast
+set -e
+
+# from https://github.com/includeos/includeos-docker-images.git 2017-08-13
+echo "Installing IncludeOS"
+docker build --tag includeos/includeos-common:0.10.0.1 --build-arg TAG=$INCLUDEOS_VERSION -f Dockerfile.common .
+docker build --tag includeos/includeos-build:0.10.0.1 -f Dockerfile.build .
+docker build --tag includeos/includeos-qemu:0.10.0.1 -f Dockerfile.qemu .
+
+echo "Building IncludeOS Mana server"
+rm -fr build
+mkdir build
+cd build
+docker run --rm -v $(dirname $PWD):/service includeos/includeos-build:0.10.0.1
+
+echo "Booting IncludeOS Mana server"
+docker run -p 8080:8080 --rm -v $(pwd):/service/build includeos/includeos-qemu:0.10.0.1 mana_simple.img

+ 1 - 0
frameworks/C++/includeos-mana/source_code

@@ -0,0 +1 @@
+includeos-mana/service.cpp

+ 19 - 0
toolset/setup/linux/systools/docker.sh

@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# Based on https://gist.github.com/EvgenyOrekhov/1ed8a4466efd0a59d73a11d753c0167b
+
+(fw_installed docker || which docker) && return 0
+
+#set -euo pipefail
+#IFS=$'\n\t'
+
+sudo apt-get -y install apt-transport-https ca-certificates \
+    && sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D \
+    && echo "deb https://apt.dockerproject.org/repo ubuntu-$(lsb_release --codename --short) main" \
+        | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null \
+    && sudo apt-get update \
+    && sudo apt-get -y install "linux-image-extra-$(uname -r)" linux-image-extra-virtual \
+    && sudo apt-get -y install docker-engine \
+    && sudo usermod -aG docker "$USER" \
+    && echo -e "\nDocker installed successfully\n" \
+    && touch $IROOT/docker.installed