mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
* Support _FILE postfixes for environment variables to be loaded from files * fix gofmt error
109 lines
2.3 KiB
Go
109 lines
2.3 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/signal"
|
|
"runtime"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/fnproject/fn/api/common"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
func init() {
|
|
// gin is not nice by default, this can get set in logging initialization
|
|
gin.SetMode(gin.ReleaseMode)
|
|
}
|
|
|
|
func getEnv(key, fallback string) string {
|
|
if value, ok := os.LookupEnv(key); ok {
|
|
return value
|
|
} else if value, ok := os.LookupEnv(key + "_FILE"); ok {
|
|
dat, err := ioutil.ReadFile(value)
|
|
if err == nil {
|
|
return string(dat)
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvInt(key string, fallback int) int {
|
|
if value, ok := os.LookupEnv(key); ok {
|
|
// linter liked this better than if/else
|
|
var err error
|
|
var i int
|
|
if i, err = strconv.Atoi(value); err != nil {
|
|
panic(err) // not sure how to handle this
|
|
}
|
|
return i
|
|
} else if value, ok := os.LookupEnv(key + "_FILE"); ok {
|
|
dat, err := ioutil.ReadFile(value)
|
|
if err == nil {
|
|
var err error
|
|
var i int
|
|
if i, err = strconv.Atoi(strings.TrimSpace(string(dat))); err != nil {
|
|
panic(err) // not sure how to handle this
|
|
}
|
|
return i
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func contextWithSignal(ctx context.Context, signals ...os.Signal) (context.Context, context.CancelFunc) {
|
|
newCTX, halt := context.WithCancel(ctx)
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, signals...)
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-c:
|
|
common.Logger(ctx).Info("Halting...")
|
|
halt()
|
|
return
|
|
case <-ctx.Done():
|
|
common.Logger(ctx).Info("Halting... Original server context canceled.")
|
|
halt()
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
return newCTX, halt
|
|
}
|
|
|
|
// Installs a child process reaper if init process
|
|
func installChildReaper() {
|
|
// assume responsibilities of init process if running as init process for Linux
|
|
if runtime.GOOS != "linux" || os.Getpid() != 1 {
|
|
return
|
|
}
|
|
|
|
var sigs = make(chan os.Signal, 1)
|
|
signal.Notify(sigs, syscall.SIGCHLD)
|
|
|
|
// we run this forever and leak a go routine. As init, we must
|
|
// reap our children until the very end, so this is OK.
|
|
go func() {
|
|
for {
|
|
<-sigs
|
|
for {
|
|
var status syscall.WaitStatus
|
|
var rusage syscall.Rusage
|
|
|
|
pid, err := syscall.Wait4(-1, &status, syscall.WNOHANG, &rusage)
|
|
// no children
|
|
if pid <= 0 {
|
|
break
|
|
}
|
|
|
|
logrus.Infof("Child terminated pid=%d err=%v status=%v usage=%v", pid, err, status, rusage)
|
|
}
|
|
}
|
|
}()
|
|
}
|