diff --git a/Makefile b/Makefile index c4bd709..7a85625 100644 --- a/Makefile +++ b/Makefile @@ -1,55 +1,50 @@ +NEBULA_CMD_PATH = "./cmd/nebula" BUILD_NUMBER ?= dev+$(shell date -u '+%Y%m%d%H%M%S') GO111MODULE = on export GO111MODULE -all: - make bin-linux - make bin-arm - make bin-arm6 - make bin-arm64 - make bin-darwin - make bin-windows +all: bin-linux bin-arm bin-arm6 bin-arm64 bin-darwin bin-windows bin: - go build -ldflags "-X main.Build=$(BUILD_NUMBER)" -o ./nebula ./cmd/nebula + go build -ldflags "-X main.Build=$(BUILD_NUMBER)" -o ./nebula ${NEBULA_CMD_PATH} go build -ldflags "-X main.Build=$(BUILD_NUMBER)" -o ./nebula-cert ./cmd/nebula-cert install: - go install -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula + go install -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} go install -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert bin-arm: mkdir -p build/arm - GOARCH=arm GOOS=linux go build -o build/arm/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula + GOARCH=arm GOOS=linux go build -o build/arm/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} GOARCH=arm GOOS=linux go build -o build/arm/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert bin-arm6: mkdir -p build/arm6 - GOARCH=arm GOARM=6 GOOS=linux go build -o build/arm6/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula + GOARCH=arm GOARM=6 GOOS=linux go build -o build/arm6/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} GOARCH=arm GOARM=6 GOOS=linux go build -o build/arm6/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert bin-arm64: mkdir -p build/arm64 - GOARCH=arm64 GOOS=linux go build -o build/arm64/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula + GOARCH=arm64 GOOS=linux go build -o build/arm64/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} GOARCH=arm64 GOOS=linux go build -o build/arm64/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert bin-vagrant: - GOARCH=amd64 GOOS=linux go build -o nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula + GOARCH=amd64 GOOS=linux go build -o nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} GOARCH=amd64 GOOS=linux go build -ldflags "-X main.Build=$(BUILD_NUMBER)" -o ./nebula-cert ./cmd/nebula-cert bin-darwin: mkdir -p build/darwin - GOARCH=amd64 GOOS=darwin go build -o build/darwin/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula + GOARCH=amd64 GOOS=darwin go build -o build/darwin/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} GOARCH=amd64 GOOS=darwin go build -o build/darwin/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert bin-windows: mkdir -p build/windows - GOARCH=amd64 GOOS=windows go build -o build/windows/nebula.exe -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula + GOARCH=amd64 GOOS=windows go build -o build/windows/nebula.exe -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} GOARCH=amd64 GOOS=windows go build -o build/windows/nebula-cert.exe -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert bin-linux: mkdir -p build/linux - GOARCH=amd64 GOOS=linux go build -o build/linux/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula + GOARCH=amd64 GOOS=linux go build -o build/linux/nebula -ldflags "-X main.Build=$(BUILD_NUMBER)" ${NEBULA_CMD_PATH} GOARCH=amd64 GOOS=linux go build -o build/linux/nebula-cert -ldflags "-X main.Build=$(BUILD_NUMBER)" ./cmd/nebula-cert release: all @@ -91,6 +86,13 @@ nebula.pb.go: nebula.proto .FORCE cert/cert.pb.go: cert/cert.proto .FORCE $(MAKE) -C cert cert.pb.go +service: + @echo > /dev/null + $(eval NEBULA_CMD_PATH := "./cmd/nebula-service") +ifeq ($(words $(MAKECMDGOALS)),1) + $(MAKE) service ${.DEFAULT_GOAL} --no-print-directory +endif + .FORCE: -.PHONY: test test-cov-html bench bench-cpu bench-cpu-long bin proto release +.PHONY: test test-cov-html bench bench-cpu bench-cpu-long bin proto release service .DEFAULT_GOAL := bin diff --git a/cmd/nebula-service/main.go b/cmd/nebula-service/main.go new file mode 100644 index 0000000..7e0634e --- /dev/null +++ b/cmd/nebula-service/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/slackhq/nebula" +) + +// A version string that can be set with +// +// -ldflags "-X main.Build=SOMEVERSION" +// +// at compile-time. +var Build string + +func main() { + serviceFlag := flag.String("service", "", "Control the system service.") + configPath := flag.String("config", "", "Path to either a file or directory to load configuration from") + configTest := flag.Bool("test", false, "Test the config and print the end result. Non zero exit indicates a faulty config") + printVersion := flag.Bool("version", false, "Print version") + printUsage := flag.Bool("help", false, "Print command line usage") + + flag.Parse() + + if *printVersion { + fmt.Printf("Version: %s\n", Build) + os.Exit(0) + } + + if *printUsage { + flag.Usage() + os.Exit(0) + } + + if *serviceFlag != "" { + doService(configPath, configTest, Build, serviceFlag) + os.Exit(1) + } + + if *configPath == "" { + fmt.Println("-config flag must be set") + flag.Usage() + os.Exit(1) + } + + nebula.Main(*configPath, *configTest, Build) +} diff --git a/cmd/nebula-service/service.go b/cmd/nebula-service/service.go new file mode 100644 index 0000000..5d88160 --- /dev/null +++ b/cmd/nebula-service/service.go @@ -0,0 +1,98 @@ +package main + +import ( + "log" + "os" + "path/filepath" + + "github.com/kardianos/service" + "github.com/slackhq/nebula" +) + +var logger service.Logger + +type program struct { + exit chan struct{} + configPath *string + configTest *bool + build string +} + +func (p *program) Start(s service.Service) error { + logger.Info("Nebula service starting.") + p.exit = make(chan struct{}) + // Start should not block. + go p.run() + return nil +} + +func (p *program) run() error { + nebula.Main(*p.configPath, *p.configTest, Build) + return nil +} + +func (p *program) Stop(s service.Service) error { + logger.Info("Nebula service stopping.") + close(p.exit) + return nil +} + +func doService(configPath *string, configTest *bool, build string, serviceFlag *string) { + + if *configPath == "" { + ex, err := os.Executable() + if err != nil { + panic(err) + } + *configPath = filepath.Dir(ex) + "/config.yaml" + } + + svcConfig := &service.Config{ + Name: "Nebula", + DisplayName: "Nebula Network Service", + Description: "Nebula network connectivity daemon for encrypted communications", + Arguments: []string{"-service", "run", "-config", *configPath}, + } + + prg := &program{ + configPath: configPath, + configTest: configTest, + build: build, + } + + s, err := service.New(prg, svcConfig) + if err != nil { + log.Fatal(err) + } + + errs := make(chan error, 5) + logger, err = s.Logger(errs) + if err != nil { + log.Fatal(err) + } + + go func() { + for { + err := <-errs + if err != nil { + log.Print(err) + } + } + }() + + switch *serviceFlag { + case "run": + err = s.Run() + if err != nil { + logger.Error(err) + } + default: + err := service.Control(s, *serviceFlag) + if err != nil { + log.Printf("Valid actions: %q\n", service.ControlAction) + log.Fatal(err) + } + return + } + +} diff --git a/go.mod b/go.mod index 5a44be8..1a07997 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 github.com/golang/protobuf v1.3.1 github.com/imdario/mergo v0.3.7 + github.com/kardianos/service v1.0.0 github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/miekg/dns v1.1.12 diff --git a/go.sum b/go.sum index 376506f..4d1f789 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kardianos/service v1.0.0 h1:HgQS3mFfOlyntWX8Oke98JcJLqt1DBcHR4kxShpYef0= +github.com/kardianos/service v1.0.0/go.mod h1:8CzDhVuCuugtsHyZoTvsOBuvonN/UDBvl0kH+BUxvbo= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -97,6 +99,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=