After running my first c example in rumprun a few years ago the next language I wanted to try out was Go. Unfortunately there were no Go unikernels at the time so we sponsored one for rumprun. That was 3 years ago.
When we decided to start writing our own unikernel implementation a while back ago Go was again the very first thing after simple C programs we wanted to support. Not only do we use the latest Go releases but we've spent a lot of time ensuring we play nicely with the Go codebase as it has design characteristics that are not as common in other languages. Not only that but the Go team is continuously refactoring the underlying code from release to release to the result that if all you are touching is the API it exposes than you are fine but if you are mucking around at the syscall barrier like we are things can easily and often break. So it's a great bellweather on how the underlying kernel is doing.
Anyways, enough with history - let's run your first Go unikernel!
I'm assuming that you already have Go installed and working and that you've written some Go code before - if not I'd encourage you to check out this first. First thing you need to do is download OPS:curl https://ops.city/get.sh -sSfL | sh
mkdir testing && cd testing
package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}
GOOS=linux go build main.go
go build main.go
➜ testing ls -lh testing
-rwxr-xr-x 1 eyberg staff 1.8M Feb 25 10:18 testing
➜ testing file testing
testing: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically
linked, not stripped
➜ testing ops run testing
Finding dependent shared libs
booting /Users/eyberg/.ops/images/testing.img ...
assigned: 10.0.2.15
Hello World!
exit_group
exit status 1
➜ testing ls -lh ~/.ops/images/testing.img
-rw-r--r-- 1 eyberg staff 4.4M Feb 25 10:21
/Users/eyberg/.ops/images/testing.img
package main
import (
"log"
"net/http"
)
func main() {
fs := http.FileServer(http.Dir("static"))
http.Handle("/", fs)
log.Println("Listening...on 8080")
http.ListenAndServe(":8080", nil)
}
GOOS=linux go build main.go
hello from inside some html
{ "Dirs" : ["static"] }
➜ testing ops run -p 8080 -c config.json testing
Finding dependent shared libs
booting /Users/eyberg/.ops/images/testing.img ...
assigned: 10.0.2.15
2019/02/25 18:49:49 Listening...on 8080
➜ nvm-web git:(master) ✗ curl -XGET http://127.0.0.1:8080/
hello from inside some html