mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
fn: support for dotnet (#326)
* Add initial support for dotnet * Initial work on dotnet example * fn: fix docker incantation * fn: .gitignore * Add README.md for dotnet example * Update docs
This commit is contained in:
committed by
C Cirello
parent
52d0dc941c
commit
717d8455e9
3
examples/hash/.gitignore
vendored
Normal file
3
examples/hash/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
dotnet.*
|
||||||
|
func.yaml
|
||||||
|
project.lock.json
|
||||||
53
examples/hash/README.md
Normal file
53
examples/hash/README.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# Using dotnet with functions
|
||||||
|
|
||||||
|
Make sure you downloaded and installed [dotnet](https://www.microsoft.com/net/core). Now create an empty dotnet project in the directory of your function:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet new
|
||||||
|
```
|
||||||
|
|
||||||
|
By default dotnet creates a ```Program.cs``` file with a main method. To make it work with IronFunction's `fn` tool please rename it to ```func.cs```.
|
||||||
|
Now change the code as you desire to do whatever magic you need it to do. Once done you can now create an iron function out of it.
|
||||||
|
|
||||||
|
## Creating an IronFunction
|
||||||
|
Simply run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fn init <username>/<funcname>
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create the ```func.yaml``` file required by functions, which can be built by running:
|
||||||
|
|
||||||
|
## Push to docker
|
||||||
|
```bash
|
||||||
|
fn push
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create a docker image and push the image to docker.
|
||||||
|
|
||||||
|
## Publishing to IronFunctions
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fn routes create <app_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates a full path in the form of `http://<host>:<port>/r/<app_name>/<function>`
|
||||||
|
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fn run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Calling
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fn call <app_name> <funcname>
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://<host>:<port>/r/<app_name>/<function>
|
||||||
|
```
|
||||||
65
examples/hash/func.cs
Executable file
65
examples/hash/func.cs
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace ConsoleApplication
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
// if nothing is being piped in, then exit
|
||||||
|
if (!IsPipedInput())
|
||||||
|
return;
|
||||||
|
|
||||||
|
var input = Console.In.ReadToEnd();
|
||||||
|
var stream = DownloadRemoteImageFile(input);
|
||||||
|
var hash = CreateChecksum(stream);
|
||||||
|
Console.WriteLine(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsPipedInput()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool isKey = Console.KeyAvailable;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static byte[] DownloadRemoteImageFile(string uri)
|
||||||
|
{
|
||||||
|
|
||||||
|
var request = System.Net.WebRequest.CreateHttp(uri);
|
||||||
|
var response = request.GetResponseAsync().Result;
|
||||||
|
var stream = response.GetResponseStream();
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
stream.CopyTo(ms);
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static string CreateChecksum(byte[] stream)
|
||||||
|
{
|
||||||
|
using (var md5 = MD5.Create())
|
||||||
|
{
|
||||||
|
var hash = md5.ComputeHash(stream);
|
||||||
|
var sBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
// Loop through each byte of the hashed data
|
||||||
|
// and format each one as a hexadecimal string.
|
||||||
|
for (int i = 0; i < hash.Length; i++)
|
||||||
|
{
|
||||||
|
sBuilder.Append(hash[i].ToString("x2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the hexadecimal string.
|
||||||
|
return sBuilder.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
examples/hash/project.json
Executable file
19
examples/hash/project.json
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"buildOptions": {
|
||||||
|
"debugType": "portable",
|
||||||
|
"emitEntryPoint": true
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"frameworks": {
|
||||||
|
"netcoreapp1.1": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"type": "platform",
|
||||||
|
"version": "1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": "dnxcore50"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -132,6 +132,7 @@ var acceptableFnRuntimes = map[string]string{
|
|||||||
"ruby": "iron/ruby",
|
"ruby": "iron/ruby",
|
||||||
"scala": "iron/scala",
|
"scala": "iron/scala",
|
||||||
"rust": "corey/rust-alpine",
|
"rust": "corey/rust-alpine",
|
||||||
|
"dotnet": "microsoft/dotnet:runtime",
|
||||||
}
|
}
|
||||||
|
|
||||||
const tplDockerfile = `FROM {{ .BaseImage }}
|
const tplDockerfile = `FROM {{ .BaseImage }}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ var (
|
|||||||
".rb": "ruby",
|
".rb": "ruby",
|
||||||
".py": "python",
|
".py": "python",
|
||||||
".rs": "rust",
|
".rs": "rust",
|
||||||
|
".cs": "dotnet",
|
||||||
}
|
}
|
||||||
|
|
||||||
fnInitRuntimes []string
|
fnInitRuntimes []string
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ func GetLangHelper(lang string) (LangHelper, error) {
|
|||||||
return &PythonHelper{}, nil
|
return &PythonHelper{}, nil
|
||||||
case "rust":
|
case "rust":
|
||||||
return &RustLangHelper{}, nil
|
return &RustLangHelper{}, nil
|
||||||
|
case "dotnet":
|
||||||
|
return &DotNetLangHelper{}, nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("No language helper found for %v", lang)
|
return nil, fmt.Errorf("No language helper found for %v", lang)
|
||||||
}
|
}
|
||||||
|
|||||||
42
fn/langs/dotnet.go
Normal file
42
fn/langs/dotnet.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package langs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DotNetLangHelper struct{}
|
||||||
|
|
||||||
|
func (lh *DotNetLangHelper) Entrypoint() string {
|
||||||
|
return "dotnet dotnet.dll"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lh *DotNetLangHelper) HasPreBuild() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreBuild for Go builds the binary so the final image can be as small as possible
|
||||||
|
func (lh *DotNetLangHelper) PreBuild() error {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(
|
||||||
|
"docker", "run",
|
||||||
|
"--rm", "-v",
|
||||||
|
wd+":/dotnet", "-w", "/dotnet", "microsoft/dotnet",
|
||||||
|
"/bin/sh", "-c", "dotnet restore && dotnet publish -c release -b /tmp -o .",
|
||||||
|
)
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("error running docker build: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lh *DotNetLangHelper) AfterBuild() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user