15960d4269
* WIP creating admin node service - WIP changing the process pkg to accept multiple services - WIP looping over services passed to process - add netstate/service.go file and abstract it for service processing * implement goroutine to launch each process * goroutines working with multiple services * code review fixes * more code updates for review * Add pkg lock and mod files back in * code review updates * update process.Main with better concurrent error handling * Update error handling and pass ctx to StartService * Update error handling with channel implementation * Merge in upstream changes - Simplify error handling channels * updates * Updates per reviewable * fix test * Setup test exec * Scaffold test setup * process main test working * update admin process test * Test multiple processes done * Add error classes for testing, test main logger error * Updates to tests * Update how process.Main() handles configs * Complete merge * Update Gopkg and add Copyright * Fix cyclical import issue - Added .coverprofile to gitignore - Update admin main.go function call * remove unnecessary line * Updates * DRY up cmd/netstate package * update service function calls * updates * Trying no-ops in examples * rename netstate to pointerdb * trying to fix merge * dep ensure and run tests * remove flag.Parse * Update deps * Skip offending test in pkg/process, to be fixed later
97 lines
2.0 KiB
Go
97 lines
2.0 KiB
Go
// Copyright (C) 2018 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package process
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
homedir "github.com/mitchellh/go-homedir"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/pflag"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
func defaultConfigPath(name string) string {
|
|
if name == "" {
|
|
name = filepath.Base(os.Args[0])
|
|
}
|
|
path := filepath.Join(".storj", fmt.Sprintf("%s.json", name))
|
|
home, err := homedir.Dir()
|
|
if err != nil {
|
|
log.Println(err)
|
|
return path
|
|
}
|
|
return filepath.Join(home, path)
|
|
}
|
|
|
|
// Execute runs a *cobra.Command and sets up Storj-wide process configuration
|
|
// like a configuration file and logging.
|
|
func Execute(cmd *cobra.Command) {
|
|
cfgFile := flag.String("config", defaultConfigPath(cmd.Name()),
|
|
"config file")
|
|
|
|
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
|
|
|
|
cobra.OnInitialize(func() {
|
|
viper.BindPFlags(cmd.Flags())
|
|
viper.SetEnvPrefix("storj")
|
|
viper.AutomaticEnv()
|
|
if *cfgFile != "" {
|
|
viper.SetConfigFile(*cfgFile)
|
|
viper.ReadInConfig()
|
|
}
|
|
})
|
|
|
|
Must(cmd.Execute())
|
|
}
|
|
|
|
// ConfigEnvironment sets up a standard Viper environment and parses CLI flags
|
|
func ConfigEnvironment() error {
|
|
cfgFile := flag.String("config", defaultConfigPath(""), "config file")
|
|
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
|
|
pflag.Parse()
|
|
viper.BindPFlags(pflag.CommandLine)
|
|
viper.SetEnvPrefix("storj")
|
|
viper.AutomaticEnv()
|
|
if *cfgFile != "" {
|
|
viper.SetConfigFile(*cfgFile)
|
|
viper.ReadInConfig()
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Main runs a Service
|
|
func Main(configFn func() error, s ...Service) error {
|
|
configFn()
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
errors := make(chan error, len(s))
|
|
|
|
for _, service := range s {
|
|
go func(ctx context.Context, s Service, ch <-chan error) {
|
|
errors <- CtxService(s)(&cobra.Command{}, pflag.Args())
|
|
}(ctx, service, errors)
|
|
}
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
return nil
|
|
case err := <-errors:
|
|
cancel()
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Must checks for errors
|
|
func Must(err error) {
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|