<commit_before>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials"
	healthpb "google.golang.org/grpc/health/grpc_health_v1"
	"google.golang.org/grpc/status"
)

var (
	flAddr          string
	flService       string
	flUserAgent     string
	flConnTimeout   time.Duration
	flRPCTimeout    time.Duration
	flTLS           bool
	flTLSNoVerify   bool
	flTLSCACert     string
	flTLSClientCert string
	flTLSClientKey  string
	flTLSServerName string
	flVerbose       bool
)

const (
	// StatusInvalidArguments indicates specified invalid arguments.
	StatusInvalidArguments = 1
	// StatusConnectionFailure indicates connection failed.
	StatusConnectionFailure = 2
	// StatusRPCFailure indicates rpc failed.
	StatusRPCFailure = 3
	// StatusUnhealthy indicates rpc succeeded but indicates unhealthy service.
	StatusUnhealthy = 4
)

func init() {
	log.SetFlags(0)
	flag.StringVar(&flAddr, "addr", "", "(required) tcp host:port to connect")
	flag.StringVar(&flService, "service", "", "service name to check (default: \"\")")
	flag.StringVar(&flUserAgent, "user-agent", "grpc_health_probe", "user-agent header value of health check requests")
	// timeouts
	flag.DurationVar(&flConnTimeout, "connect-timeout", time.Second, "timeout for establishing connection")
	flag.DurationVar(&flRPCTimeout, "rpc-timeout", time.Second, "timeout for health check rpc")
	// tls settings
	flag.BoolVar(&flTLS, "tls", false, "use TLS (default: false, INSECURE plaintext transport)")
	flag.BoolVar(&flTLSNoVerify, "tls-no-verify", false, "(with -tls) don't verify the certificate (INSECURE) presented by the server (default: false)")
	flag.StringVar(&flTLSCACert, "tls-ca-cert", "", "(with -tls, optional) file containing trusted certificates for verifying server")
	flag.StringVar(&flTLSClientCert, "tls-client-cert", "", "(with -tls, optional) client certificate for authenticating to the server (requires -tls-client-key)")
	flag.StringVar(&flTLSClientKey, "tls-client-key", "", "(with -tls) client private key for authenticating to the server (requires -tls-client-cert)")
	flag.StringVar(&flTLSServerName, "tls-server-name", "", "(with -tls) override the hostname used to verify the server certificate")
	flag.BoolVar(&flVerbose, "v", false, "verbose logs")

	flag.Parse()

	argError := func(s string, v ...interface{}) {
		log.Printf("error: "+s, v...)
		os.Exit(StatusInvalidArguments)
	}

	if flAddr == "" {
		argError("-addr not specified")
	}
	if flConnTimeout <= 0 {
		argError("-connect-timeout must be greater than zero (specified: %v)", flConnTimeout)
	}
	if flRPCTimeout <= 0 {
		argError("-rpc-timeout must be greater than zero (specified: %v)", flRPCTimeout)
	}
	if !flTLS && flTLSNoVerify {
		argError("specified -tls-no-verify without specifying -tls")
	}
	if !flTLS && flTLSCACert != "" {
		argError("specified -tls-ca-cert without specifying -tls")
	}
	if !flTLS && flTLSClientCert != "" {
		argError("specified -tls-client-cert without specifying -tls")
	}
	if !flTLS && flTLSServerName != "" {
		argError("specified -tls-server-name without specifying -tls")
	}
	if flTLSClientCert != "" && flTLSClientKey == "" {
		argError("specified -tls-client-cert without specifying -tls-client-key")
	}
	if flTLSClientCert == "" && flTLSClientKey != "" {
		argError("specified -tls-client-key without specifying -tls-client-cert")
	}
	if flTLSNoVerify && flTLSCACert != "" {
		argError("cannot specify -tls-ca-cert with -tls-no-verify (CA cert would not be used)")
	}
	if flTLSNoVerify && flTLSServerName != "" {
		argError("cannot specify -tls-server-name with -tls-no-verify (server name would not be used)")
	}

	if flVerbose {
		log.Printf("parsed options:")
		log.Printf("> addr=%s conn_timeout=%v rpc_timeout=%v", flAddr, flConnTimeout, flRPCTimeout)
		log.Printf("> tls=%v", flTLS)
		if flTLS {
			log.Printf("  > no-verify=%v ", flTLSNoVerify)
			log.Printf("  > ca-cert=%s", flTLSCACert)
			log.Printf("  > client-cert=%s", flTLSClientCert)
			log.Printf("  > client-key=%s", flTLSClientKey)
			log.Printf("  > server-name=%s", flTLSServerName)
		}
	}
}

func buildCredentials(skipVerify bool, caCerts, clientCert, clientKey, serverName string) (credentials.TransportCredentials, error) {
	var cfg tls.Config

	if clientCert != "" && clientKey != "" {
		keyPair, err := tls.LoadX509KeyPair(clientCert, clientKey)
		if err != nil {
			return nil, fmt.Errorf("failed to load tls client cert/key pair. error=%v", err)
		}
		cfg.Certificates = []tls.Certificate{keyPair}
	}

	if skipVerify {
		cfg.InsecureSkipVerify = true
	} else if caCerts != "" {
		// override system roots
		rootCAs := x509.NewCertPool()
		pem, err := ioutil.ReadFile(caCerts)
		if err != nil {
			return nil, fmt.Errorf("failed to load root CA certificates from file (%s) error=%v", caCerts, err)
		}
		if !rootCAs.AppendCertsFromPEM(pem) {
			return nil, fmt.Errorf("no root CA certs parsed from file %s", caCerts)
		}
		cfg.RootCAs = rootCAs
	}
	if serverName != "" {
		cfg.ServerName = serverName
	}
	return credentials.NewTLS(&cfg), nil
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		sig := <-c
		if sig == os.Interrupt {
			log.Printf("cancellation received")
			cancel()
			return
		}
	}()

	opts := []grpc.DialOption{
		grpc.WithUserAgent(flUserAgent),
		grpc.WithBlock()}
	if flTLS {
		creds, err := buildCredentials(flTLSNoVerify, flTLSCACert, flTLSClientCert, flTLSClientKey, flTLSServerName)
		if err != nil {
			log.Printf("failed to initialize tls credentials. error=%v", err)
			os.Exit(StatusInvalidArguments)
		}
		opts = append(opts, grpc.WithTransportCredentials(creds))
	} else {
		opts = append(opts, grpc.WithInsecure())
	}

	if flVerbose {
		log.Print("establishing connection")
	}
	connStart := time.Now()
	dialCtx, cancel2 := context.WithTimeout(ctx, flConnTimeout)
	defer cancel2()
	conn, err := grpc.DialContext(dialCtx, flAddr, opts...)
	if err != nil {
		if err == context.DeadlineExceeded {
			log.Printf("timeout: failed to connect service %q within %v", flAddr, flConnTimeout)
		} else {
			log.Printf("error: failed to connect service at %q: %+v", flAddr, err)
		}
		os.Exit(StatusConnectionFailure)
	}
	connDuration := time.Since(connStart)
	defer conn.Close()
	if flVerbose {
		log.Printf("connection establisted (took %v)", connDuration)
	}

	rpcStart := time.Now()
	rpcCtx, rpcCancel := context.WithTimeout(ctx, flRPCTimeout)
	defer rpcCancel()
	resp, err := healthpb.NewHealthClient(conn).Check(rpcCtx, &healthpb.HealthCheckRequest{Service: flService})
	if err != nil {
		if stat, ok := status.FromError(err); ok && stat.Code() == codes.Unimplemented {
			log.Printf("error: this server does not implement the grpc health protocol (grpc.health.v1.Health)")
		} else if stat, ok := status.FromError(err); ok && stat.Code() == codes.DeadlineExceeded {
			log.Printf("timeout: health rpc did not complete within %v", flRPCTimeout)
		} else {
			log.Printf("error: health rpc failed: %+v", err)
		}
		os.Exit(StatusRPCFailure)
	}
	rpcDuration := time.Since(rpcStart)

	if resp.GetStatus() != healthpb.HealthCheckResponse_SERVING {
		log.Printf("service unhealthy (responded with %q)", resp.GetStatus().String())
		os.Exit(StatusUnhealthy)
	}
	if flVerbose {
		log.Printf("time elapsed: connect=%v rpc=%v", connDuration, rpcDuration)
	}
	log.Printf("status: %v", resp.GetStatus().String())
}
<commit_msg>Close connection before exiting (#36)<commit_after>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials"
	healthpb "google.golang.org/grpc/health/grpc_health_v1"
	"google.golang.org/grpc/status"
)

var (
	flAddr          string
	flService       string
	flUserAgent     string
	flConnTimeout   time.Duration
	flRPCTimeout    time.Duration
	flTLS           bool
	flTLSNoVerify   bool
	flTLSCACert     string
	flTLSClientCert string
	flTLSClientKey  string
	flTLSServerName string
	flVerbose       bool
)

const (
	// StatusInvalidArguments indicates specified invalid arguments.
	StatusInvalidArguments = 1
	// StatusConnectionFailure indicates connection failed.
	StatusConnectionFailure = 2
	// StatusRPCFailure indicates rpc failed.
	StatusRPCFailure = 3
	// StatusUnhealthy indicates rpc succeeded but indicates unhealthy service.
	StatusUnhealthy = 4
)

func init() {
	log.SetFlags(0)
	flag.StringVar(&flAddr, "addr", "", "(required) tcp host:port to connect")
	flag.StringVar(&flService, "service", "", "service name to check (default: \"\")")
	flag.StringVar(&flUserAgent, "user-agent", "grpc_health_probe", "user-agent header value of health check requests")
	// timeouts
	flag.DurationVar(&flConnTimeout, "connect-timeout", time.Second, "timeout for establishing connection")
	flag.DurationVar(&flRPCTimeout, "rpc-timeout", time.Second, "timeout for health check rpc")
	// tls settings
	flag.BoolVar(&flTLS, "tls", false, "use TLS (default: false, INSECURE plaintext transport)")
	flag.BoolVar(&flTLSNoVerify, "tls-no-verify", false, "(with -tls) don't verify the certificate (INSECURE) presented by the server (default: false)")
	flag.StringVar(&flTLSCACert, "tls-ca-cert", "", "(with -tls, optional) file containing trusted certificates for verifying server")
	flag.StringVar(&flTLSClientCert, "tls-client-cert", "", "(with -tls, optional) client certificate for authenticating to the server (requires -tls-client-key)")
	flag.StringVar(&flTLSClientKey, "tls-client-key", "", "(with -tls) client private key for authenticating to the server (requires -tls-client-cert)")
	flag.StringVar(&flTLSServerName, "tls-server-name", "", "(with -tls) override the hostname used to verify the server certificate")
	flag.BoolVar(&flVerbose, "v", false, "verbose logs")

	flag.Parse()

	argError := func(s string, v ...interface{}) {
		log.Printf("error: "+s, v...)
		os.Exit(StatusInvalidArguments)
	}

	if flAddr == "" {
		argError("-addr not specified")
	}
	if flConnTimeout <= 0 {
		argError("-connect-timeout must be greater than zero (specified: %v)", flConnTimeout)
	}
	if flRPCTimeout <= 0 {
		argError("-rpc-timeout must be greater than zero (specified: %v)", flRPCTimeout)
	}
	if !flTLS && flTLSNoVerify {
		argError("specified -tls-no-verify without specifying -tls")
	}
	if !flTLS && flTLSCACert != "" {
		argError("specified -tls-ca-cert without specifying -tls")
	}
	if !flTLS && flTLSClientCert != "" {
		argError("specified -tls-client-cert without specifying -tls")
	}
	if !flTLS && flTLSServerName != "" {
		argError("specified -tls-server-name without specifying -tls")
	}
	if flTLSClientCert != "" && flTLSClientKey == "" {
		argError("specified -tls-client-cert without specifying -tls-client-key")
	}
	if flTLSClientCert == "" && flTLSClientKey != "" {
		argError("specified -tls-client-key without specifying -tls-client-cert")
	}
	if flTLSNoVerify && flTLSCACert != "" {
		argError("cannot specify -tls-ca-cert with -tls-no-verify (CA cert would not be used)")
	}
	if flTLSNoVerify && flTLSServerName != "" {
		argError("cannot specify -tls-server-name with -tls-no-verify (server name would not be used)")
	}

	if flVerbose {
		log.Printf("parsed options:")
		log.Printf("> addr=%s conn_timeout=%v rpc_timeout=%v", flAddr, flConnTimeout, flRPCTimeout)
		log.Printf("> tls=%v", flTLS)
		if flTLS {
			log.Printf("  > no-verify=%v ", flTLSNoVerify)
			log.Printf("  > ca-cert=%s", flTLSCACert)
			log.Printf("  > client-cert=%s", flTLSClientCert)
			log.Printf("  > client-key=%s", flTLSClientKey)
			log.Printf("  > server-name=%s", flTLSServerName)
		}
	}
}

func buildCredentials(skipVerify bool, caCerts, clientCert, clientKey, serverName string) (credentials.TransportCredentials, error) {
	var cfg tls.Config

	if clientCert != "" && clientKey != "" {
		keyPair, err := tls.LoadX509KeyPair(clientCert, clientKey)
		if err != nil {
			return nil, fmt.Errorf("failed to load tls client cert/key pair. error=%v", err)
		}
		cfg.Certificates = []tls.Certificate{keyPair}
	}

	if skipVerify {
		cfg.InsecureSkipVerify = true
	} else if caCerts != "" {
		// override system roots
		rootCAs := x509.NewCertPool()
		pem, err := ioutil.ReadFile(caCerts)
		if err != nil {
			return nil, fmt.Errorf("failed to load root CA certificates from file (%s) error=%v", caCerts, err)
		}
		if !rootCAs.AppendCertsFromPEM(pem) {
			return nil, fmt.Errorf("no root CA certs parsed from file %s", caCerts)
		}
		cfg.RootCAs = rootCAs
	}
	if serverName != "" {
		cfg.ServerName = serverName
	}
	return credentials.NewTLS(&cfg), nil
}

func main() {
	retcode := 0
	defer func() { os.Exit(retcode) }()

	ctx, cancel := context.WithCancel(context.Background())

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		sig := <-c
		if sig == os.Interrupt {
			log.Printf("cancellation received")
			cancel()
			return
		}
	}()

	opts := []grpc.DialOption{
		grpc.WithUserAgent(flUserAgent),
		grpc.WithBlock()}
	if flTLS {
		creds, err := buildCredentials(flTLSNoVerify, flTLSCACert, flTLSClientCert, flTLSClientKey, flTLSServerName)
		if err != nil {
			log.Printf("failed to initialize tls credentials. error=%v", err)
			retcode = StatusInvalidArguments
			return
		}
		opts = append(opts, grpc.WithTransportCredentials(creds))
	} else {
		opts = append(opts, grpc.WithInsecure())
	}

	if flVerbose {
		log.Print("establishing connection")
	}
	connStart := time.Now()
	dialCtx, cancel2 := context.WithTimeout(ctx, flConnTimeout)
	defer cancel2()
	conn, err := grpc.DialContext(dialCtx, flAddr, opts...)
	if err != nil {
		if err == context.DeadlineExceeded {
			log.Printf("timeout: failed to connect service %q within %v", flAddr, flConnTimeout)
		} else {
			log.Printf("error: failed to connect service at %q: %+v", flAddr, err)
		}
		retcode = StatusConnectionFailure
		return
	}
	connDuration := time.Since(connStart)
	defer conn.Close()
	if flVerbose {
		log.Printf("connection establisted (took %v)", connDuration)
	}

	rpcStart := time.Now()
	rpcCtx, rpcCancel := context.WithTimeout(ctx, flRPCTimeout)
	defer rpcCancel()
	resp, err := healthpb.NewHealthClient(conn).Check(rpcCtx, &healthpb.HealthCheckRequest{Service: flService})
	if err != nil {
		if stat, ok := status.FromError(err); ok && stat.Code() == codes.Unimplemented {
			log.Printf("error: this server does not implement the grpc health protocol (grpc.health.v1.Health)")
		} else if stat, ok := status.FromError(err); ok && stat.Code() == codes.DeadlineExceeded {
			log.Printf("timeout: health rpc did not complete within %v", flRPCTimeout)
		} else {
			log.Printf("error: health rpc failed: %+v", err)
		}
		retcode = StatusRPCFailure
		return
	}
	rpcDuration := time.Since(rpcStart)

	if resp.GetStatus() != healthpb.HealthCheckResponse_SERVING {
		log.Printf("service unhealthy (responded with %q)", resp.GetStatus().String())
		retcode = StatusUnhealthy
		return
	}
	if flVerbose {
		log.Printf("time elapsed: connect=%v rpc=%v", connDuration, rpcDuration)
	}
	log.Printf("status: %v", resp.GetStatus().String())
}
<|endoftext|>


<commit_before>package gopwt

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"syscall"

	"github.com/mattn/go-isatty"
)

var (
	termw    = 0
	testdata = flag.String("testdata", "testdata", "name of test data directories. e.g. -testdata testdata,migrations")
	verbose  = false
)

func Empower() {
	if os.Getenv("GOPWT_OFF") != "" {
		return
	}

	if err := doMain(); err != nil {
		fmt.Fprintln(os.Stderr, err.Error())

		if exiterr, ok := err.(*exec.ExitError); ok {
			if s, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				os.Exit(s.ExitStatus())
			} else {
				panic(fmt.Errorf("Unimplemented for system where exec.ExitError.Sys() is not syscall.WaitStatus."))
			}
		}

		os.Exit(127)
	}
	os.Exit(0)
}
func doMain() error {
	if runtime.Version() == "go1.4" {
		return fmt.Errorf("go1.4 is not supported. please bump to go1.4.1 or later")
	}

	if !flag.Parsed() {
		flag.Parse()
	}

	flag.VisitAll(func(f *flag.Flag) {
		if f.Name == "test.v" {
			if f.Value.String() == "false" {
				verbose = true
			}
		}
	})

	if isatty.IsTerminal(os.Stdout.Fd()) {
		termw = getTermCols(os.Stdin.Fd())
	}

	tempGoPath, err := ioutil.TempDir(os.TempDir(), "")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tempGoPath)

	root := flag.Arg(0)

	pkgInfo, err := newPackageInfo(root)
	if err != nil {
		return err
	}

	err = rewrite(tempGoPath, pkgInfo)
	if err != nil {
		return err
	}

	err = runTest(tempGoPath, pkgInfo, os.Stdout, os.Stderr)
	if err != nil {
		return err
	}

	return nil
}

func rewrite(tempGoPath string, pkgInfo *packageInfo) error {
	tempGoSrcDir := filepath.Join(tempGoPath, "src")

	err := filepath.Walk(pkgInfo.dirPath, func(path string, fInfo os.FileInfo, err error) error {
		if fInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
			return nil
		}

		if !fInfo.IsDir() {
			return nil
		}

		files, err := ioutil.ReadDir(path)
		if err != nil {
			return err
		}
		if !containsGoFile(files) {
			// sub-packages maybe have gofiles, even if itself don't has gofiles
			if containsDirectory(files) {
				return nil
			}
			return filepath.SkipDir
		}

		rel, err := filepath.Rel(pkgInfo.dirPath, path)
		if err != nil {
			return err
		}

		for _, tdata := range strings.Split(*testdata, ",") {
			if strings.Split(rel, "/")[0] == tdata {
				return filepath.SkipDir
			}
		}

		if rel != "." {
			if filepath.HasPrefix(rel, ".") {
				return filepath.SkipDir
			}

			if !pkgInfo.recursive {
				return filepath.SkipDir
			}
		}

		importPath := filepath.Join(pkgInfo.importPath, rel)

		err = os.MkdirAll(filepath.Join(tempGoSrcDir, importPath), os.ModePerm)
		if err != nil {
			return err
		}

		err = rewritePackage(path, importPath, tempGoSrcDir)
		if err != nil {
			return err
		}

		return nil
	})

	if err != nil {
		return err
	}

	return nil
}

func runTest(goPath string, pkgInfo *packageInfo, stdout, stderr io.Writer) error {
	err := os.Setenv("GOPATH", goPath+":"+os.Getenv("GOPATH"))
	if err != nil {
		return err
	}

	cmd := exec.Command("go", "test")

	if verbose {
		cmd.Args = append(cmd.Args, "-v")
	}
	cmd.Dir = path.Join(goPath, "src", pkgInfo.importPath)
	// cmd.Args = append(cmd.Args, pkgInfo.ToGoTestArg())
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	return cmd.Run()
}
<commit_msg>fix(gopwt): wtf<commit_after>package gopwt

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"syscall"

	"github.com/mattn/go-isatty"
)

var (
	termw    = 0
	testdata = flag.String("testdata", "testdata", "name of test data directories. e.g. -testdata testdata,migrations")
	verbose  = false
)

func Empower() {
	if os.Getenv("GOPWT_OFF") != "" {
		return
	}

	if err := doMain(); err != nil {
		fmt.Fprintln(os.Stderr, err.Error())

		if exiterr, ok := err.(*exec.ExitError); ok {
			if s, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				os.Exit(s.ExitStatus())
			} else {
				panic(fmt.Errorf("Unimplemented for system where exec.ExitError.Sys() is not syscall.WaitStatus."))
			}
		}

		os.Exit(127)
	}
	os.Exit(0)
}
func doMain() error {
	if runtime.Version() == "go1.4" {
		return fmt.Errorf("go1.4 is not supported. please bump to go1.4.1 or later")
	}

	if !flag.Parsed() {
		flag.Parse()
	}

	flag.VisitAll(func(f *flag.Flag) {
		if f.Name == "test.v" {
			if f.Value.String() != "false" {
				verbose = true
			}
		}
	})

	if isatty.IsTerminal(os.Stdout.Fd()) {
		termw = getTermCols(os.Stdin.Fd())
	}

	tempGoPath, err := ioutil.TempDir(os.TempDir(), "")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tempGoPath)

	root := flag.Arg(0)

	pkgInfo, err := newPackageInfo(root)
	if err != nil {
		return err
	}

	err = rewrite(tempGoPath, pkgInfo)
	if err != nil {
		return err
	}

	err = runTest(tempGoPath, pkgInfo, os.Stdout, os.Stderr)
	if err != nil {
		return err
	}

	return nil
}

func rewrite(tempGoPath string, pkgInfo *packageInfo) error {
	tempGoSrcDir := filepath.Join(tempGoPath, "src")

	err := filepath.Walk(pkgInfo.dirPath, func(path string, fInfo os.FileInfo, err error) error {
		if fInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
			return nil
		}

		if !fInfo.IsDir() {
			return nil
		}

		files, err := ioutil.ReadDir(path)
		if err != nil {
			return err
		}
		if !containsGoFile(files) {
			// sub-packages maybe have gofiles, even if itself don't has gofiles
			if containsDirectory(files) {
				return nil
			}
			return filepath.SkipDir
		}

		rel, err := filepath.Rel(pkgInfo.dirPath, path)
		if err != nil {
			return err
		}

		for _, tdata := range strings.Split(*testdata, ",") {
			if strings.Split(rel, "/")[0] == tdata {
				return filepath.SkipDir
			}
		}

		if rel != "." {
			if filepath.HasPrefix(rel, ".") {
				return filepath.SkipDir
			}

			if !pkgInfo.recursive {
				return filepath.SkipDir
			}
		}

		importPath := filepath.Join(pkgInfo.importPath, rel)

		err = os.MkdirAll(filepath.Join(tempGoSrcDir, importPath), os.ModePerm)
		if err != nil {
			return err
		}

		err = rewritePackage(path, importPath, tempGoSrcDir)
		if err != nil {
			return err
		}

		return nil
	})

	if err != nil {
		return err
	}

	return nil
}

func runTest(goPath string, pkgInfo *packageInfo, stdout, stderr io.Writer) error {
	err := os.Setenv("GOPATH", goPath+":"+os.Getenv("GOPATH"))
	if err != nil {
		return err
	}

	cmd := exec.Command("go", "test")

	if verbose {
		cmd.Args = append(cmd.Args, "-v")
	}
	cmd.Dir = path.Join(goPath, "src", pkgInfo.importPath)
	// cmd.Args = append(cmd.Args, pkgInfo.ToGoTestArg())
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	return cmd.Run()
}
<|endoftext|>


<commit_before>// Copyright 2014 tsuru-admin authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// tsuru-admin is under development.
package main

import (
	"os"

	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/provision"
	_ "github.com/tsuru/tsuru/provision/docker"
)

const (
	version = "0.8.0"
	header  = "Supported-Tsuru-Admin"
)

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header, nil)
	m.Register(&tokenGen{})
	m.Register(&logRemove{})
	m.Register(&platformAdd{})
	m.Register(&platformUpdate{})
	m.Register(&platformRemove{})
	m.RegisterDeprecated(&machineList{}, "machines-list")
	m.Register(&machineDestroy{})
	m.Register(&appLockDelete{})
	m.Register(viewUserQuota{})
	m.Register(changeUserQuota{})
	m.Register(viewAppQuota{})
	m.Register(changeAppQuota{})
	m.Register(&planCreate{})
	m.Register(&planRemove{})
	m.Register(&templateList{})
	m.Register(&templateAdd{})
	m.Register(&templateRemove{})
	registerProvisionersCommands(m)
	return m
}

func registerProvisionersCommands(m *cmd.Manager) {
	provisioners := provision.Registry()
	for _, p := range provisioners {
		if c, ok := p.(cmd.AdminCommandable); ok {
			commands := c.AdminCommands()
			for _, cmd := range commands {
				m.Register(cmd)
			}
		}
	}
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	args := os.Args[1:]
	manager.Run(args)
}
<commit_msg>main: bump to 0.8.1<commit_after>// Copyright 2014 tsuru-admin authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// tsuru-admin is under development.
package main

import (
	"os"

	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/provision"
	_ "github.com/tsuru/tsuru/provision/docker"
)

const (
	version = "0.8.1"
	header  = "Supported-Tsuru-Admin"
)

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header, nil)
	m.Register(&tokenGen{})
	m.Register(&logRemove{})
	m.Register(&platformAdd{})
	m.Register(&platformUpdate{})
	m.Register(&platformRemove{})
	m.RegisterDeprecated(&machineList{}, "machines-list")
	m.Register(&machineDestroy{})
	m.Register(&appLockDelete{})
	m.Register(viewUserQuota{})
	m.Register(changeUserQuota{})
	m.Register(viewAppQuota{})
	m.Register(changeAppQuota{})
	m.Register(&planCreate{})
	m.Register(&planRemove{})
	m.Register(&templateList{})
	m.Register(&templateAdd{})
	m.Register(&templateRemove{})
	registerProvisionersCommands(m)
	return m
}

func registerProvisionersCommands(m *cmd.Manager) {
	provisioners := provision.Registry()
	for _, p := range provisioners {
		if c, ok := p.(cmd.AdminCommandable); ok {
			commands := c.AdminCommands()
			for _, cmd := range commands {
				m.Register(cmd)
			}
		}
	}
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	args := os.Args[1:]
	manager.Run(args)
}
<|endoftext|>


<commit_before>/*-
 * Copyright 2016 Square Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"bufio"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/square/certigo/jceks"
	"golang.org/x/crypto/pkcs12"
	"gopkg.in/alecthomas/kingpin.v2"
)

var (
	app = kingpin.New("certigo", "A command line certificate examination utility.")

	dump     = app.Command("dump", "Display information about a certificate.")
	dumpFile = dump.Arg("file", "Certificate file to dump.").Required().String()
	dumpType = dump.Flag("format", "Format of given input. If unspecified, certigo guesses based on file extension").Short('f').String()
)

var fileExtToFormat = map[string]string{
	".pem":   "PEM",
	".crt":   "PEM",
	".p12":   "PKCS12",
	".pfx":   "PKCS12",
	".jceks": "JCEKS",
}

func main() {
	switch kingpin.MustParse(app.Parse(os.Args[1:])) {
	case dump.FullCommand(): // Dump certificate
		format, ok := formatForFile(*dumpFile, *dumpType)
		if !ok {
			fmt.Fprint(os.Stderr, "unable to guess file type\n")
			os.Exit(1)
		}

		certs, err := getCerts(*dumpFile, format)
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s\n", err)
			os.Exit(1)
		}

		for i, cert := range certs {
			fmt.Println("CERTIFICATE", i+1)
			displayCert(cert)
			fmt.Println()
		}
	}
}

// formatForFile returns the file format (either from flags or
// based on file extension).
func formatForFile(filename, format string) (string, bool) {
	if format == "" {
		guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))]
		return guess, ok
	}
	return format, true
}

// getCerts takes in a filename and format type and returns an
// array of all the certificates found in that file. If no format
// is specified for the file, getCerts guesses what format was used
// based on the file extension used in the file name. If it can't
// guess based on this it returns and error.
func getCerts(file, format string) ([]*x509.Certificate, error) {
	var certs []*x509.Certificate
	data, _ := ioutil.ReadFile(file)
	switch format {
	case "PEM":
		block, data := pem.Decode(data)
		for block != nil {
			cert, err := x509.ParseCertificate(block.Bytes)
			if err != nil {
				return nil, err
			}
			certs = append(certs, cert)
			block, data = pem.Decode(data)
		}
	case "PKCS12":
		scanner := bufio.NewReader(os.Stdin)
		fmt.Print("Enter password: ")
		password, _ := scanner.ReadString('\n')
		blocks, err := pkcs12.ToPEM(data, strings.TrimSuffix(password, "\n"))
		if err != nil {
			return nil, err
		}
		for _, block := range blocks {
			if block.Type == "CERTIFICATE" {
				cert, err := x509.ParseCertificate(block.Bytes)
				if err != nil {
					return nil, err
				}
				certs = append(certs, cert)
			}
		}
	case "JKS":
		scanner := bufio.NewReader(os.Stdin)
		fmt.Print("Enter password: ")
		password, _ := scanner.ReadString('\n')
		keyStore, err := jceks.Load(file, []byte(strings.TrimSuffix(password, "\n")))
		if err != nil {
			return nil, err
		}
		for _, certName := range keyStore.ListCerts() {
			cert, _ := keyStore.GetCert(certName)
			if err != nil {
				return nil, err
			}
			certs = append(certs, cert)
		}
	default:
		return nil, fmt.Errorf("unknown file type: %s", format)
	}
	return certs, nil
}
<commit_msg>Changed case checking for user input of JKS to check for JCEKS<commit_after>/*-
 * Copyright 2016 Square Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"bufio"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/square/certigo/jceks"
	"golang.org/x/crypto/pkcs12"
	"gopkg.in/alecthomas/kingpin.v2"
)

var (
	app = kingpin.New("certigo", "A command line certificate examination utility.")

	dump     = app.Command("dump", "Display information about a certificate.")
	dumpFile = dump.Arg("file", "Certificate file to dump.").Required().String()
	dumpType = dump.Flag("format", "Format of given input. If unspecified, certigo guesses based on file extension").Short('f').String()
)

var fileExtToFormat = map[string]string{
	".pem":   "PEM",
	".crt":   "PEM",
	".p12":   "PKCS12",
	".pfx":   "PKCS12",
	".jceks": "JCEKS",
}

func main() {
	switch kingpin.MustParse(app.Parse(os.Args[1:])) {
	case dump.FullCommand(): // Dump certificate
		format, ok := formatForFile(*dumpFile, *dumpType)
		if !ok {
			fmt.Fprint(os.Stderr, "unable to guess file type\n")
			os.Exit(1)
		}

		certs, err := getCerts(*dumpFile, format)
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s\n", err)
			os.Exit(1)
		}

		for i, cert := range certs {
			fmt.Println("CERTIFICATE", i+1)
			displayCert(cert)
			fmt.Println()
		}
	}
}

// formatForFile returns the file format (either from flags or
// based on file extension).
func formatForFile(filename, format string) (string, bool) {
	if format == "" {
		guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))]
		return guess, ok
	}
	return format, true
}

// getCerts takes in a filename and format type and returns an
// array of all the certificates found in that file. If no format
// is specified for the file, getCerts guesses what format was used
// based on the file extension used in the file name. If it can't
// guess based on this it returns and error.
func getCerts(file, format string) ([]*x509.Certificate, error) {
	var certs []*x509.Certificate
	data, _ := ioutil.ReadFile(file)
	switch format {
	case "PEM":
		block, data := pem.Decode(data)
		for block != nil {
			cert, err := x509.ParseCertificate(block.Bytes)
			if err != nil {
				return nil, err
			}
			certs = append(certs, cert)
			block, data = pem.Decode(data)
		}
	case "PKCS12":
		scanner := bufio.NewReader(os.Stdin)
		fmt.Print("Enter password: ")
		password, _ := scanner.ReadString('\n')
		blocks, err := pkcs12.ToPEM(data, strings.TrimSuffix(password, "\n"))
		if err != nil {
			return nil, err
		}
		for _, block := range blocks {
			if block.Type == "CERTIFICATE" {
				cert, err := x509.ParseCertificate(block.Bytes)
				if err != nil {
					return nil, err
				}
				certs = append(certs, cert)
			}
		}
	case "JCEKS":
		scanner := bufio.NewReader(os.Stdin)
		fmt.Print("Enter password: ")
		password, _ := scanner.ReadString('\n')
		keyStore, err := jceks.Load(file, []byte(strings.TrimSuffix(password, "\n")))
		if err != nil {
			return nil, err
		}
		for _, certName := range keyStore.ListCerts() {
			cert, _ := keyStore.GetCert(certName)
			if err != nil {
				return nil, err
			}
			certs = append(certs, cert)
		}
	default:
		return nil, fmt.Errorf("unknown file type: %s", format)
	}
	return certs, nil
}
<|endoftext|>


<commit_before>// Logs the status of a user from Lotus Notes SameTime Instant Messager.
// Usage:
//
//    go run main.go -userid=USER_ID
//
// @requires Lotus Notes 8+, Google Go 1.2
// @project https://github.com/LarryBattle/SameTimeTrackStatus/
// @author Larry Battle
// @version 0.1.0
// @todo Add new flags : -users=id1,id2,id3 -verbose=bool -api_url=string
// @todo add check for Lotus Notes and setting.
// @todo refactor into objects; webapi, storage, cli, settings, user
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"
)

const (
	VERSION             = "0.1.0"
	TIME_STAMP_FORMAT   = "01/02/2006 03:04:05pm"
	DEFAULT_OUTPUT_FILE = "output.txt"
)

var (
	sametime_getstatus_URL = `http://localhost:59449/stwebapi/getstatus?userId=`
	outputFile             string
	userId                 string
	showVersion            bool
)

// Used to only contain the essenential properties from the json response
type essential_ST_JSON struct {
	TimeStamp     string `json:"timestamp"`
	UnixTimeStamp int64  `json:"unixTimestamp"`
	DisplayName   string `json:"displayName"`
	Status        int    `json:"status"`
	StatusMessage string `json:"statusMessage"`
	UserName      string `json:"username"`
}

// Processes the flag information.
func processFlags() {
	flag.StringVar(&userId, "userid", "", "REQUIRED. Sametime User Id. Try your id if you don't know.")
	flag.StringVar(&outputFile, "output", DEFAULT_OUTPUT_FILE, "Output file to store logs. Defaults to output.txt")
	flag.BoolVar(&showVersion, "version", false, "Shows version information.")
	flag.Parse()
}

// Checks if all required flags are set.
func checkSettings() {
	if showVersion {
		fmt.Printf("Version %s\n", VERSION)
		os.Exit(1)
	}
	if userId == "" {
		fmt.Println("The argument `userid` is required.")
		os.Exit(1)
	}
}

// Shows a message when the tool is called.
func printGreeting() {
	fmt.Println(`SameTime IM Status Tracking Tool by Larry Battle`)
}
func checkError(e error) {
	if e != nil {
		panic(e)
	}
}

// Returns a date time timestamp
func getTimeStamp() string {
	return time.Now().Format(TIME_STAMP_FORMAT)
}

// Returns the timestamp used by Javascript.
// Ex. new Date( timestamp )
func getJSTimeStamp() int64 {
	return time.Now().UnixNano() / 1e6
}

// Returns only the desired properties from the json response
func extractInfoFromJSON(json_string []byte) []byte {
	var obj essential_ST_JSON
	json.Unmarshal(json_string, &obj)
	obj.TimeStamp = getTimeStamp()
	obj.UnixTimeStamp = getJSTimeStamp()
	b, err := json.Marshal(obj)
	checkError(err)
	return b
}

// Returns the JSON response from a `getstatus` webapi call for a specific userId
func getSameTimeStatusOfUser(userId string) []byte {
	res, err := http.Get(sametime_getstatus_URL + userId)
	checkError(err)
	defer res.Body.Close()
	json_response, err := ioutil.ReadAll(res.Body)
	checkError(err)
	return json_response
}

// Appends a string with a new line to a file
func appendStringToFile(filename string, data []byte) {
	f, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0660)
	defer f.Close()
	checkError(err)
	_, err = f.WriteString(string(data) + "\n")
	checkError(err)
}

// Sends status request then saves response to a file.
func logSameTimeStatus(userId string) {
	appendStringToFile(outputFile, extractInfoFromJSON(getSameTimeStatusOfUser(userId)))
}

// Calls a function every t times.
func startCounter(t time.Duration, fn func()) {
	i := 0
	for _ = range time.Tick(t) {
		i++
		log.Println("Logging status #", i)
		fn()
	}
}
func main() {
	printGreeting()
	processFlags()
	checkSettings()
	log.Printf("Saving status for %s to %s\n", userId, outputFile)
	startCounter(2*time.Second, func() {
		logSameTimeStatus(userId)
	})
}
<commit_msg>Update main.go<commit_after>// Logs the status of a user from Lotus Notes SameTime Instant Messager.
// Usage:
//
//    go run main.go -userid=USER_ID
//
// @requires Lotus Notes 8+, Google Go 1.2
// @project https://github.com/LarryBattle/SameTimeTrackStatus/
// @author Larry Battle
// @version 0.1.1
// @todo Add new flags : -users=id1,id2,id3 -verbose=bool -api_url=string -interval=#minutes
// @todo add check for Lotus Notes and setting.
// @todo refactor into objects; webapi, storage, cli, settings, user
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"
)

const (
	VERSION             = "0.1.1"
	TIME_STAMP_FORMAT   = "01/02/2006 03:04:05pm"
	DEFAULT_OUTPUT_FILE = "output.txt"
)

var (
	sametime_getstatus_URL = `http://localhost:59449/stwebapi/getstatus?userId=`
	outputFile             string
	userId                 string
	showVersion            bool
	numOfMinutes	uint
)

// Used to only contain the essenential properties from the json response
type essential_ST_JSON struct {
	TimeStamp     string `json:"timestamp"`
	UnixTimeStamp int64  `json:"unixTimestamp"`
	DisplayName   string `json:"displayName"`
	Status        int    `json:"status"`
	StatusMessage string `json:"statusMessage"`
	UserName      string `json:"username"`
}

// Processes the flag information.
func processFlags() {
	flag.StringVar(&userId, "userid", "", "REQUIRED. Sametime User Id. Try your id if you don't know.")
	flag.StringVar(&outputFile, "output", DEFAULT_OUTPUT_FILE, "Output file to store logs.")
	flag.BoolVar(&showVersion, "version", false, "Shows version information.")
	flag.UintVar(&numOfMinutes, "interval", 5, "Interval to check status.")
	flag.Parse()
}

// Checks if all required flags are set.
func checkSettings() {
	if showVersion {
		fmt.Printf("Version %s\n", VERSION)
		os.Exit(1)
	}
	if userId == "" {
		fmt.Println("The argument `userid` is required.")
		os.Exit(1)
	}
	if numOfMinutes < 1 || 200 < numOfMinutes {
		fmt.Println("The argument `userid` is required.")
		os.Exit(1)
	}
}

// Shows a message when the tool is called.
func printGreeting() {
	fmt.Println(`SameTime IM Status Tracking Tool by Larry Battle`)
}
func checkError(e error) {
	if e != nil {
		panic(e)
	}
}

// Returns a date time timestamp
func getTimeStamp() string {
	return time.Now().Format(TIME_STAMP_FORMAT)
}

// Returns the timestamp used by Javascript.
// Ex. new Date( timestamp )
func getJSTimeStamp() int64 {
	return time.Now().UnixNano() / 1e6
}

// Returns only the desired properties from the json response
func extractInfoFromJSON(json_string []byte) []byte {
	var obj essential_ST_JSON
	json.Unmarshal(json_string, &obj)
	obj.TimeStamp = getTimeStamp()
	obj.UnixTimeStamp = getJSTimeStamp()
	b, err := json.Marshal(obj)
	checkError(err)
	return b
}

// Returns the JSON response from a `getstatus` webapi call for a specific userId
func getSameTimeStatusOfUser(userId string) []byte {
	res, err := http.Get(sametime_getstatus_URL + userId)
	checkError(err)
	defer res.Body.Close()
	json_response, err := ioutil.ReadAll(res.Body)
	checkError(err)
	return json_response
}

// Appends a string with a new line to a file
func appendStringToFile(filename string, data []byte) {
	f, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0660)
	defer f.Close()
	checkError(err)
	_, err = f.WriteString(string(data) + "\n")
	checkError(err)
}

// Sends status request then saves response to a file.
func logSameTimeStatus(userId string) {
	appendStringToFile(outputFile, extractInfoFromJSON(getSameTimeStatusOfUser(userId)))
}

// Calls a function every t times.
func startCounter(t time.Duration, fn func()) {
	i := 0
	for _ = range time.Tick(t) {
		i++
		log.Println("Logging status #", i)
		fn()
	}
}
func main() {
	printGreeting()
	processFlags()
	checkSettings()
	log.Printf("Every %d minutes: Saving status for %s to %s\n", numOfMinutes, userId, outputFile)
	startCounter( time.Duration(numOfMinutes) *time.Minute, func() {
		logSameTimeStatus(userId)
	})
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"io/ioutil"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"strconv"
	"time"

	"github.com/grafana/grafana/pkg/cmd"
	"github.com/grafana/grafana/pkg/log"
	"github.com/grafana/grafana/pkg/login"
	"github.com/grafana/grafana/pkg/metrics"
	"github.com/grafana/grafana/pkg/plugins"
	"github.com/grafana/grafana/pkg/services/eventpublisher"
	"github.com/grafana/grafana/pkg/services/notifications"
	"github.com/grafana/grafana/pkg/services/search"
	"github.com/grafana/grafana/pkg/services/sqlstore"
	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/social"
)

var version = "master"
var commit = "NA"
var buildstamp string

var configFile = flag.String("config", "", "path to config file")
var homePath = flag.String("homepath", "", "path to grafana install/home path, defaults to working directory")
var pidFile = flag.String("pidfile", "", "path to pid file")

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	buildstampInt64, _ := strconv.ParseInt(buildstamp, 10, 64)

	setting.BuildVersion = version
	setting.BuildCommit = commit
	setting.BuildStamp = buildstampInt64

	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)
		<-c
		os.Exit(0)
	}()

	flag.Parse()

	writePIDFile()
	initRuntime()

	search.Init()
	login.Init()
	social.NewOAuthService()
	eventpublisher.Init()
	plugins.Init()

	if err := notifications.Init(); err != nil {
		log.Fatal(3, "Notification service failed to initialize", err)
	}

	if setting.ReportingEnabled {
		go metrics.StartUsageReportLoop()
	}

	cmd.StartServer()

	log.Close()
}

func initRuntime() {
	setting.NewConfigContext(&setting.CommandLineArgs{
		Config:   *configFile,
		HomePath: *homePath,
		Args:     flag.Args(),
	})

	log.Info("Starting Grafana")
	log.Info("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0))
	setting.LogConfigurationInfo()

	sqlstore.NewEngine()
	sqlstore.EnsureAdminUser()
}

func writePIDFile() {
	if *pidFile == "" {
		return
	}

	// Ensure the required directory structure exists.
	err := os.MkdirAll(filepath.Dir(*pidFile), 0700)
	if err != nil {
		log.Fatal(3, "Failed to verify pid directory", err)
	}

	// Retrieve the PID and write it.
	pid := strconv.Itoa(os.Getpid())
	if err := ioutil.WriteFile(*pidFile, []byte(pid), 0644); err != nil {
		log.Fatal(3, "Failed to write pidfile", err)
	}
}
<commit_msg>fix(shutdown flow): improved shutdown flow and log closing, listing to kill and and SIGTERM as well, closes #2516<commit_after>package main

import (
	"flag"
	"io/ioutil"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"strconv"
	"syscall"
	"time"

	"github.com/grafana/grafana/pkg/cmd"
	"github.com/grafana/grafana/pkg/log"
	"github.com/grafana/grafana/pkg/login"
	"github.com/grafana/grafana/pkg/metrics"
	"github.com/grafana/grafana/pkg/plugins"
	"github.com/grafana/grafana/pkg/services/eventpublisher"
	"github.com/grafana/grafana/pkg/services/notifications"
	"github.com/grafana/grafana/pkg/services/search"
	"github.com/grafana/grafana/pkg/services/sqlstore"
	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/social"
)

var version = "master"
var commit = "NA"
var buildstamp string

var configFile = flag.String("config", "", "path to config file")
var homePath = flag.String("homepath", "", "path to grafana install/home path, defaults to working directory")
var pidFile = flag.String("pidfile", "", "path to pid file")
var exitChan = make(chan int)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	buildstampInt64, _ := strconv.ParseInt(buildstamp, 10, 64)

	setting.BuildVersion = version
	setting.BuildCommit = commit
	setting.BuildStamp = buildstampInt64

	go listenToSystemSignels()

	flag.Parse()
	writePIDFile()
	initRuntime()

	search.Init()
	login.Init()
	social.NewOAuthService()
	eventpublisher.Init()
	plugins.Init()

	if err := notifications.Init(); err != nil {
		log.Fatal(3, "Notification service failed to initialize", err)
	}

	if setting.ReportingEnabled {
		go metrics.StartUsageReportLoop()
	}

	cmd.StartServer()
	exitChan <- 0
}

func initRuntime() {
	setting.NewConfigContext(&setting.CommandLineArgs{
		Config:   *configFile,
		HomePath: *homePath,
		Args:     flag.Args(),
	})

	log.Info("Starting Grafana")
	log.Info("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0))
	setting.LogConfigurationInfo()

	sqlstore.NewEngine()
	sqlstore.EnsureAdminUser()
}

func writePIDFile() {
	if *pidFile == "" {
		return
	}

	// Ensure the required directory structure exists.
	err := os.MkdirAll(filepath.Dir(*pidFile), 0700)
	if err != nil {
		log.Fatal(3, "Failed to verify pid directory", err)
	}

	// Retrieve the PID and write it.
	pid := strconv.Itoa(os.Getpid())
	if err := ioutil.WriteFile(*pidFile, []byte(pid), 0644); err != nil {
		log.Fatal(3, "Failed to write pidfile", err)
	}
}

func listenToSystemSignels() {
	signalChan := make(chan os.Signal, 1)
	code := 0

	signal.Notify(signalChan, os.Interrupt)
	signal.Notify(signalChan, os.Kill)
	signal.Notify(signalChan, syscall.SIGTERM)

	select {
	case sig := <-signalChan:
		log.Info("Received signal %s. shutting down", sig)
	case code = <-exitChan:
		switch code {
		case 0:
			log.Info("Shutting down")
		default:
			log.Warn("Shutting down")
		}
	}

	log.Close()
	os.Exit(code)
}
<|endoftext|>


<commit_before>package main

import "flag"
import "fmt"
import "log"
import "strconv"
import "time"
import "net"
//import "os"
import "encoding/json"
//import "github.com/Shopify/sarama"
import "github.com/google/gopacket"
import "github.com/google/gopacket/pcap"
import "github.com/google/gopacket/layers"

/*
    logging to file
    debug logging
    ttlcache for failed queries
    documentation
release v1

    stats output
    perf testing
    TCP flow support
release v2

    logging to kafka
    add PF_RING support
release v3

    maybe use something with a larger keyspace than the query ID for the conntable map
    maybe not so many string conversions?
    maybe move the dnsLogEntry struct -> JSON encoding to the log channel?
    add more Types to gopacket
*/

/*

DNS log entry struct and helper functions

*/
type dnsLogEntry struct {
    Query_ID        uint16          `json:"query_id"`
    Response_Code   int             `json:"response_code"`
	Question        string          `json:"question"`
	Question_Type   string          `json:"question_type"`
	Answer          string          `json:"answer"`
	Answer_Type     string          `json:"answer_type"`
	TTL             uint32          `json:"ttl"`
	Server          net.IP          `json:"server"`
	Client          net.IP          `json:"client"`
	Timestamp       string          `json:"timestamp"`

	encoded []byte  //to hold the marshaled data structure
	err     error   //encoding errors
}

func (dle *dnsLogEntry) ensureEncoded() {
	if dle.encoded == nil && dle.err == nil {
		dle.encoded, dle.err = json.Marshal(dle)
	}
}

func (dle *dnsLogEntry) Length() int {
	dle.ensureEncoded()
	return len(dle.encoded)
}

func (dle *dnsLogEntry) Encode() ([]byte, error) {
	dle.ensureEncoded()
	return dle.encoded, dle.err
}

/* validate if DNS, make conntable entry and output
   to log channel if there is a match
   */
func handlePacket(packets chan gopacket.Packet, logC chan dnsLogEntry){

    //DNS IDs are stored as uint16s by the gopacket DNS layer
    //TODO: fix the memory leak of failed lookups by making this a ttlcache
    var conntable = make(map[uint16]*layers.DNS)

    for packet := range packets {
        //TODO: there must be a better way of doing this with gopacket
        var srcIP net.IP
        var dstIP net.IP

        if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
            ipData, _ := ipLayer.(*layers.IPv4)
            srcIP = ipData.SrcIP
            dstIP = ipData.DstIP
        }else if ipLayer := packet.Layer(layers.LayerTypeIPv6); ipLayer != nil {
            ipData, _ := ipLayer.(*layers.IPv6)
            srcIP = ipData.SrcIP
            dstIP = ipData.DstIP
        }else{
            //non-IP transport?  Ignore this packet
            //TODO: debug message here
            continue
        }

        if dnsLayer := packet.Layer(layers.LayerTypeDNS); dnsLayer != nil {
            // Get actual DNS data from this layer
            dns, _ := dnsLayer.(*layers.DNS)

            //skip non-query stuff (Updates, AXFRs, etc)
            if dns.OpCode != layers.DNSOpCodeQuery {
                //TODO: debug message here "saw non query packet with ID NNNN"
                continue
            }

            //this is a Query Response packet
            if dns.QR == true{
                if question, ok := conntable[dns.ID]; ok != false {
                    //We have both legs of the connection, so drop the connection from the table
                    //TODO: debug message here "got second leg of query ID NNNN"
                    delete(conntable, question.ID)

                    /*
                        http://forums.devshed.com/dns-36/dns-packet-question-section-1-a-183026.html
                        multiple questions isn't really a thing, so we'll loop over the answers and
                        insert the question section from the original query.  This means a successful
                        ANY query may result in a lot of seperate log entries.  The query ID will be
                        the same on all of those entries, however, so you can rebuild the query that
                        way.
                    */

                    /*
                        The gopacket DNS layer doesn't have a lot of good String()
                        conversion methods, so we have to do a lot of that ourselves
                        here.  Much of this should move back into gopacket.  Also a
                        little worried about the perf impact of doing string conversions
                        in this thread...

                    */

                    var questionType string

                    switch question.Questions[0].Type {
                        default:
                            questionType = strconv.Itoa(int(question.Questions[0].Type))
                        case layers.DNSTypeA:
                            questionType = "A"
                        case layers.DNSTypeAAAA:
                            questionType = "AAAA"
                        case layers.DNSTypeCNAME:
                            questionType = "CNAME"
                        case layers.DNSTypeMX:
                            questionType = "MX"
                        case layers.DNSTypeNS:
                            questionType = "NS"
                        case layers.DNSTypePTR:
                            questionType = "PTR"
                        case layers.DNSTypeTXT:
                            questionType = "TXT"
                        case layers.DNSTypeSOA:
                            questionType = "SOA"
                        case layers.DNSTypeSRV:
                            questionType = "SRV"
                        case 255:   //ANY query per http://tools.ietf.org/html/rfc1035#page-12
                            questionType = "ANY"
                    }

                    //a response code of 0 means success
                    if dns.ResponseCode != 0 {

                        //TODO: debug message here "query failure code N for query ID NNNN"

                        logEntry := dnsLogEntry{
                            Query_ID:       dns.ID,
    		            	Question:       string(question.Questions[0].Name),
    		            	Response_Code:  int(dns.ResponseCode),
                			Question_Type:  questionType,
    			            Answer:         dns.ResponseCode.String(),
                			Answer_Type:    "",
    			            TTL:            0,
    			            //this is the answer packet, which comes from the server...
    			            Server:         srcIP,
    			            //...and goes to the client
    			            Client:         dstIP,
    			            Timestamp:      time.Now().UTC().Format(time.RFC3339),
                		}

                		//marshal to JSON.  Maybe we should do this in the log thread?
                		//encoded, _ := logEntry.Encode()
                        //
                        //logC <- string(encoded)

                        logC <- logEntry

                        continue

                    }

                    for _, answer := range dns.Answers {

                        var answerString string
                        var typeString string

                        switch answer.Type {
                            default:
                                //take a blind stab...at least this shouldn't *lose* data
                                answerString = string(answer.Data)
                                typeString = strconv.Itoa(int(answer.Type))
                            case layers.DNSTypeA:
                                answerString = answer.IP.String()
                                typeString = "A"
                            case layers.DNSTypeAAAA:
                                answerString = answer.IP.String()
                                typeString = "AAAA"
                            case layers.DNSTypeCNAME:
                                answerString = string(answer.CNAME)
                                typeString = "CNAME"
                            case layers.DNSTypeMX:
                                //TODO: add the priority
                                answerString = string(answer.MX.Name)
                                typeString = "MX"
                            case layers.DNSTypeNS:
                                answerString = string(answer.NS)
                                typeString = "NS"
                            case layers.DNSTypePTR:
                                answerString = string(answer.PTR)
                                typeString = "PTR"
                            case layers.DNSTypeTXT:
                                answerString = string(answer.TXT)
                                typeString = "TXT"
                            case layers.DNSTypeSOA:
                                //TODO: rebuild the full SOA string
                                answerString = string(answer.SOA.RName)
                                typeString = "SOA"
                            case layers.DNSTypeSRV:
                                //TODO: rebuild the full SRV string
                                answerString = string(answer.SRV.Name)
                                typeString = "SRV"
                        }

                        logEntry := dnsLogEntry{
                            Query_ID:       dns.ID,
    		            	Question:       string(question.Questions[0].Name),
    		            	Response_Code:  int(dns.ResponseCode),
                			Question_Type:  questionType,
    			            Answer:         answerString,
                			Answer_Type:    typeString,
    			            TTL:            answer.TTL,
    			            //this is the answer packet, which comes from the server...
    			            Server:         srcIP,
    			            //...and goes to the client
    			            Client:         dstIP,
    			            Timestamp:      time.Now().UTC().Format(time.RFC3339),
                		}

                		//marshal to JSON.  Maybe we should do this in the log thread?
                		//encoded, _ := logEntry.Encode()
                        //
                        //logC <- string(encoded)

                        logC <- logEntry

                    }
                }else{
                    //This might happen if we get a query ID collision
                    //TODO: debug message here
                    log.Println("got a Query Response and can't find a query!")
                    continue
                }
            }else{
                //This is the initial query.  save it for later.
                //TODO: debug message here "got first leg of query ID NNNN"
                conntable[dns.ID] = dns
            }
        }
    }
}

func logConn(logC chan dnsLogEntry){
    for message := range logC {
        //marshal to JSON.  Maybe we should do this in the log thread?
        encoded, _ := message.Encode()

        fmt.Println(string(encoded))
    }
}

func main(){

    var dev = flag.String("dev", "", "Capture Device")
//    var kafka_brokers   = flag.String("kafka_brokers", os.Getenv("KAFKA_PEERS"), "The Kafka brokers to connect to, as a comma separated list")
//    var kafka_topic = flag.String("kafka_topic","","Kafka topic for output")
    var bpf = flag.String("bpf","port 53","BPF Filter")
    var pcapFile = flag.String("pcap","","pcap file")
//    var logfile = flag.String("logfile","","log file (recommended for debug only")

    flag.Parse()

    var handle *pcap.Handle
    var err error

    if(*dev != ""){
        handle, err = pcap.OpenLive(*dev, 65536, true, pcap.BlockForever)
        if err != nil {log.Fatal(err) }
    }else if(*pcapFile != ""){
        handle, err = pcap.OpenOffline(*pcapFile)
        if err != nil { log.Fatal(err) }
    }else{
        log.Fatal("You must specify either a capture device or a pcap file")
    }

    defer handle.Close()

    err = handle.SetBPFFilter(*bpf)
    if err != nil { log.Fatal(err) }

    /* spin up logging thread */
    var logChan = make(chan dnsLogEntry)
    go logConn(logChan)

    /* init channels for the packet handlers and kick off handler threads */
    var channels [8]chan gopacket.Packet
    for i := 0; i < 8; i++ {
        channels[i] = make(chan gopacket.Packet)
        go handlePacket(channels[i], logChan)
    }

    // Use the handle as a packet source to process all packets
    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
    for packet := range packetSource.Packets() {
        // Dispatch packets here
        if net := packet.NetworkLayer(); net != nil {
            /*  load balance the processiing over 8 threads
                FashHash is consistant for A->B and B->A hashes, which simplifies
                our connection tracking problem a bit by letting us keep
                per-worker connection pools instead of a global pool.
            */
            channels[int(net.NetworkFlow().FastHash()) & 0x7] <- packet
        }
    }
}
<commit_msg>implement a fan-out logging pattern that enables multiple logging sinks<commit_after>package main

import "flag"
import "fmt"
import "log"
import "strconv"
import "time"
import "net"
import "os"
import "encoding/json"
//import "github.com/Shopify/sarama"
import "github.com/google/gopacket"
import "github.com/google/gopacket/pcap"
import "github.com/google/gopacket/layers"

/*
    -logging to file
    debug logging
    ttlcache for failed queries
    -documentation
release v1

    stats output
    perf testing
    TCP flow support
release v2

    logging to kafka
    add PF_RING support
release v3

    maybe use something with a larger keyspace than the query ID for the conntable map
    maybe not so many string conversions?
    maybe move the dnsLogEntry struct -> JSON encoding to the log channel?
    add more Types to gopacket
*/

/*

DNS log entry struct and helper functions

*/
type dnsLogEntry struct {
    Query_ID        uint16          `json:"query_id"`
    Response_Code   int             `json:"response_code"`
	Question        string          `json:"question"`
	Question_Type   string          `json:"question_type"`
	Answer          string          `json:"answer"`
	Answer_Type     string          `json:"answer_type"`
	TTL             uint32          `json:"ttl"`
	Server          net.IP          `json:"server"`
	Client          net.IP          `json:"client"`
	Timestamp       string          `json:"timestamp"`

	encoded []byte  //to hold the marshaled data structure
	err     error   //encoding errors
}

func (dle *dnsLogEntry) ensureEncoded() {
	if dle.encoded == nil && dle.err == nil {
		dle.encoded, dle.err = json.Marshal(dle)
	}
}

func (dle *dnsLogEntry) Length() int {
	dle.ensureEncoded()
	return len(dle.encoded)
}

func (dle *dnsLogEntry) Encode() ([]byte, error) {
	dle.ensureEncoded()
	return dle.encoded, dle.err
}

/* validate if DNS, make conntable entry and output
   to log channel if there is a match
   */
func handlePacket(packets chan gopacket.Packet, logC chan dnsLogEntry){

    //DNS IDs are stored as uint16s by the gopacket DNS layer
    //TODO: fix the memory leak of failed lookups by making this a ttlcache
    var conntable = make(map[uint16]*layers.DNS)

    for packet := range packets {
        //TODO: there must be a better way of doing this with gopacket
        var srcIP net.IP
        var dstIP net.IP

        if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
            ipData, _ := ipLayer.(*layers.IPv4)
            srcIP = ipData.SrcIP
            dstIP = ipData.DstIP
        }else if ipLayer := packet.Layer(layers.LayerTypeIPv6); ipLayer != nil {
            ipData, _ := ipLayer.(*layers.IPv6)
            srcIP = ipData.SrcIP
            dstIP = ipData.DstIP
        }else{
            //non-IP transport?  Ignore this packet
            //TODO: debug message here
            continue
        }

        if dnsLayer := packet.Layer(layers.LayerTypeDNS); dnsLayer != nil {
            // Get actual DNS data from this layer
            dns, _ := dnsLayer.(*layers.DNS)

            //skip non-query stuff (Updates, AXFRs, etc)
            if dns.OpCode != layers.DNSOpCodeQuery {
                //TODO: debug message here "saw non query packet with ID NNNN"
                continue
            }

            //this is a Query Response packet
            if dns.QR == true{
                if question, ok := conntable[dns.ID]; ok != false {
                    //We have both legs of the connection, so drop the connection from the table
                    //TODO: debug message here "got second leg of query ID NNNN"
                    delete(conntable, question.ID)

                    /*
                        http://forums.devshed.com/dns-36/dns-packet-question-section-1-a-183026.html
                        multiple questions isn't really a thing, so we'll loop over the answers and
                        insert the question section from the original query.  This means a successful
                        ANY query may result in a lot of seperate log entries.  The query ID will be
                        the same on all of those entries, however, so you can rebuild the query that
                        way.
                    */

                    /*
                        The gopacket DNS layer doesn't have a lot of good String()
                        conversion methods, so we have to do a lot of that ourselves
                        here.  Much of this should move back into gopacket.  Also a
                        little worried about the perf impact of doing string conversions
                        in this thread...

                    */

                    var questionType string

                    switch question.Questions[0].Type {
                        default:
                            questionType = strconv.Itoa(int(question.Questions[0].Type))
                        case layers.DNSTypeA:
                            questionType = "A"
                        case layers.DNSTypeAAAA:
                            questionType = "AAAA"
                        case layers.DNSTypeCNAME:
                            questionType = "CNAME"
                        case layers.DNSTypeMX:
                            questionType = "MX"
                        case layers.DNSTypeNS:
                            questionType = "NS"
                        case layers.DNSTypePTR:
                            questionType = "PTR"
                        case layers.DNSTypeTXT:
                            questionType = "TXT"
                        case layers.DNSTypeSOA:
                            questionType = "SOA"
                        case layers.DNSTypeSRV:
                            questionType = "SRV"
                        case 255:   //ANY query per http://tools.ietf.org/html/rfc1035#page-12
                            questionType = "ANY"
                    }

                    //a response code of 0 means success
                    if dns.ResponseCode != 0 {

                        //TODO: debug message here "query failure code N for query ID NNNN"

                        logEntry := dnsLogEntry{
                            Query_ID:       dns.ID,
    		            	Question:       string(question.Questions[0].Name),
    		            	Response_Code:  int(dns.ResponseCode),
                			Question_Type:  questionType,
    			            Answer:         dns.ResponseCode.String(),
                			Answer_Type:    "",
    			            TTL:            0,
    			            //this is the answer packet, which comes from the server...
    			            Server:         srcIP,
    			            //...and goes to the client
    			            Client:         dstIP,
    			            Timestamp:      time.Now().UTC().Format(time.RFC3339),
                		}

                		//marshal to JSON.  Maybe we should do this in the log thread?
                		//encoded, _ := logEntry.Encode()
                        //
                        //logC <- string(encoded)

                        logC <- logEntry

                        continue

                    }

                    for _, answer := range dns.Answers {

                        var answerString string
                        var typeString string

                        switch answer.Type {
                            default:
                                //take a blind stab...at least this shouldn't *lose* data
                                answerString = string(answer.Data)
                                typeString = strconv.Itoa(int(answer.Type))
                            case layers.DNSTypeA:
                                answerString = answer.IP.String()
                                typeString = "A"
                            case layers.DNSTypeAAAA:
                                answerString = answer.IP.String()
                                typeString = "AAAA"
                            case layers.DNSTypeCNAME:
                                answerString = string(answer.CNAME)
                                typeString = "CNAME"
                            case layers.DNSTypeMX:
                                //TODO: add the priority
                                answerString = string(answer.MX.Name)
                                typeString = "MX"
                            case layers.DNSTypeNS:
                                answerString = string(answer.NS)
                                typeString = "NS"
                            case layers.DNSTypePTR:
                                answerString = string(answer.PTR)
                                typeString = "PTR"
                            case layers.DNSTypeTXT:
                                answerString = string(answer.TXT)
                                typeString = "TXT"
                            case layers.DNSTypeSOA:
                                //TODO: rebuild the full SOA string
                                answerString = string(answer.SOA.RName)
                                typeString = "SOA"
                            case layers.DNSTypeSRV:
                                //TODO: rebuild the full SRV string
                                answerString = string(answer.SRV.Name)
                                typeString = "SRV"
                        }

                        logEntry := dnsLogEntry{
                            Query_ID:       dns.ID,
    		            	Question:       string(question.Questions[0].Name),
    		            	Response_Code:  int(dns.ResponseCode),
                			Question_Type:  questionType,
    			            Answer:         answerString,
                			Answer_Type:    typeString,
    			            TTL:            answer.TTL,
    			            //this is the answer packet, which comes from the server...
    			            Server:         srcIP,
    			            //...and goes to the client
    			            Client:         dstIP,
    			            Timestamp:      time.Now().UTC().Format(time.RFC3339),
                		}

                        logC <- logEntry

                    }
                }else{
                    //This might happen if we get a query ID collision
                    //TODO: debug message here
                    log.Println("got a Query Response and can't find a query!")
                    continue
                }
            }else{
                //This is the initial query.  save it for later.
                //TODO: debug message here "got first leg of query ID NNNN"
                conntable[dns.ID] = dns
            }
        }
    }
}

//Round-robin log messages to log sinks
func logConn(logC chan dnsLogEntry, stdout bool, file bool, kafka bool,
            filename string, kafka_brokers string, kafka_topic string){

    var logs []chan dnsLogEntry

    if stdout {
        stdoutChan := make(chan dnsLogEntry)
        logs = append(logs, stdoutChan)
        go logConnStdout(stdoutChan)
    }

    if file {
        fileChan := make(chan dnsLogEntry)
        logs = append(logs, fileChan)
        go logConnFile(fileChan, filename)
    }

    if kafka && false {
        kafkaChan := make(chan dnsLogEntry)
        logs = append(logs, kafkaChan)
        go logConnKafka(kafkaChan, kafka_brokers, kafka_topic)
    }

    for message := range logC {
        for _, logChan := range logs {
            logChan <- message
        }
    }
}

func logConnStdout(logC chan dnsLogEntry){
    for message := range logC {
        //marshal to JSON.  Maybe we should do this in the log thread?
        encoded, _ := message.Encode()
        fmt.Println(string(encoded))
    }
}

func logConnFile(logC chan dnsLogEntry, filename string){

    f, err := os.OpenFile(filename, os.O_WRONLY | os.O_CREATE | os.O_APPEND, 0666)
    if err != nil {
        panic(err)
    }

    defer f.Close()

    for message := range logC {
        //marshal to JSON.  Maybe we should do this in the log thread?
        encoded, _ := message.Encode()
        f.WriteString(string(encoded)+"\n")
    }
}

func logConnKafka(logC chan dnsLogEntry, kafka_brokers string, kafka_topic string){
    for message := range logC {
        //marshal to JSON.  Maybe we should do this in the log thread?
        encoded, _ := message.Encode()
        fmt.Println("Kafka: "+string(encoded))
    }
}

func main(){

    var dev = flag.String("dev", "", "Capture Device")
    var kafka_brokers   = flag.String("kafka_brokers", os.Getenv("KAFKA_PEERS"), "The Kafka brokers to connect to, as a comma separated list")
    var kafka_topic = flag.String("kafka_topic","","Kafka topic for output")
    var bpf = flag.String("bpf","port 53","BPF Filter")
    var pcapFile = flag.String("pcap","","pcap file")
    var logfile = flag.String("logfile","","log file (recommended for debug only")
    var quiet = flag.Bool("quiet", false, "do not log to stdout")

    flag.Parse()

    var handle *pcap.Handle
    var err error

    if(*dev != ""){
        handle, err = pcap.OpenLive(*dev, 65536, true, pcap.BlockForever)
        if err != nil {log.Fatal(err) }
    }else if(*pcapFile != ""){
        handle, err = pcap.OpenOffline(*pcapFile)
        if err != nil { log.Fatal(err) }
    }else{
        log.Fatal("You must specify either a capture device or a pcap file")
    }

    defer handle.Close()

    err = handle.SetBPFFilter(*bpf)
    if err != nil { log.Fatal(err) }

    /* spin up logging thread */
    var logChan = make(chan dnsLogEntry)
    var log_file bool = false
    var log_kafka bool = false

    if *logfile != "" {
        log_file = true
    }

    if *kafka_brokers != "" && *kafka_topic != "" {
        log_kafka = true
    }

    go logConn(logChan, !*quiet, log_file, log_kafka, *logfile, *kafka_brokers, *kafka_topic)

    /* init channels for the packet handlers and kick off handler threads */
    var channels [8]chan gopacket.Packet
    for i := 0; i < 8; i++ {
        channels[i] = make(chan gopacket.Packet)
        go handlePacket(channels[i], logChan)
    }

    // Use the handle as a packet source to process all packets
    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
    for packet := range packetSource.Packets() {
        // Dispatch packets here
        if net := packet.NetworkLayer(); net != nil {
            /*  load balance the processiing over 8 threads
                FashHash is consistant for A->B and B->A hashes, which simplifies
                our connection tracking problem a bit by letting us keep
                per-worker connection pools instead of a global pool.
            */
            channels[int(net.NetworkFlow().FastHash()) & 0x7] <- packet
        }
    }
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/user"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/boltdb/bolt"
	"github.com/chzyer/readline"
)

var db *bolt.DB

// commandInfo struct is stored as the value to commands
type commandInfo struct {
	time  time.Time
	count int
}

func (ci commandInfo) String() string {
	return fmt.Sprintf("%s:%d", ci.time.String(), ci.count)
}

func (ci commandInfo) Update(ciString string) commandInfo {
	info := strings.Split(os.Getenv("PATH"), ":")
	newCI := commandInfo{}

	count, err := strconv.Atoi(info[1])
	if err != nil {
		count = 0
	}

	newCI.time = time.Now()
	newCI.count = count + 1

	return newCI
}

func (ci commandInfo) NewFromString(ciString string) commandInfo {
	info := strings.Split(os.Getenv("PATH"), ":")
	newCI := commandInfo{}

	date, err := time.Parse(time.RFC3339, info[0])
	if err != nil {
		date = time.Now()
	}

	count, err := strconv.Atoi(info[1])
	if err != nil {
		count = 0
	}

	newCI.time = date
	newCI.count = count

	return newCI
}

func main() {
	// Setup flags
	// statsPtr := flag.Bool("stats", false, "show stats and usage of `r`")
	// completePtr := flag.String("complete", "", "show all results for `r`")
	commandPtr := flag.Bool("command", false, "show last command selected from `r`")
	addPtr := flag.String("add", "", "show stats and usage of `r`")
	flag.Parse()

	// Setup bolt db
	usr, err := user.Current()
	if err != nil {
		log.Fatal(err)
	}
	boltPath := filepath.Join(usr.HomeDir, ".r.db")
	// It will be created if it doesn't exist.
	db, err = bolt.Open(boltPath, 0600, nil)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// Check if `results` flag is passed
	// if *completePtr != "" {
	// 	results := showResults(*completePtr)
	// 	for _, result := range results {
	// 		fmt.Println(result)
	// 	}
	// 	os.Exit(0)
	// }

	if *commandPtr {
		printLastCommand()
		os.Exit(0)
	}

	// Check if `add` flag is passed
	if *addPtr != "" {
		args := strings.Split(*addPtr, ":")
		err := add(args[0], args[1])
		if err != nil {
			log.Fatal(err)
		}

		os.Exit(0)
	}

	// reset last command to blank
	// set line as stored command
	err = db.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte("command"))
		if err != nil {
			return err
		}

		err = b.Put([]byte("command"), []byte(""))
		if err != nil {
			return err
		}
		return nil
	})

	if err != nil {
		log.Fatal(err)
	}

	readLine()
}

// readLine used the readline library create a prompt to
// show the command history
func readLine() {
	// create completer from results
	results, err := showResults()
	if err != nil {
		log.Panic(err)
	}

	var pcItems []*readline.PrefixCompleter
	for _, result := range results {
		pcItems = append(pcItems, readline.PcItem(result))
	}
	var completer = readline.NewPrefixCompleter(pcItems...)

	rl, err := readline.NewEx(&readline.Config{
		Prompt:       "> ",
		AutoComplete: completer,
	})
	if err != nil {
		log.Panic(err)
	}
	defer rl.Close()

	for {
		line, err := rl.Readline()
		if err != nil { // io.EOF
			break
		}

		// Only execute if the command typed is in the list of results
		if !containsCmd(strings.TrimSpace(line), results) {
			fmt.Println("Command not found in `r` history.")
			os.Exit(0)
		}

		// set line as stored command
		err = db.Update(func(tx *bolt.Tx) error {
			b, err := tx.CreateBucketIfNotExists([]byte("command"))
			if err != nil {
				return err
			}

			err = b.Put([]byte("command"), []byte(line))
			if err != nil {
				return err
			}
			return nil
		})

		if err != nil {
			log.Fatal(err)
		}

		os.Exit(0)
	}
}

// printLastCommand is used with the --command flag
// it shows the last command selected from the readline prompt
func printLastCommand() {
	var val string
	db.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte("command"))
		if err != nil {
			return err
		}

		val = string(b.Get([]byte("command")))
		return nil
	})

	fmt.Println(val)
}

// showResults reads the boltdb and returns the command history
// based on your current working directory
func showResults() ([]string, error) {
	wd, err := os.Getwd()
	if err != nil {
		return nil, err
	}

	// results := []string{"git status", "git clone", "go install", "cd /Users/jesse/", "cd /Users/jesse/gocode/src/github.com/jesselucas", "ls -Glah"}
	var results []string
	err = db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte("DirectoryBucket"))
		pathBucket := b.Bucket([]byte(wd))
		return pathBucket.ForEach(func(k, v []byte) error {
			results = append(results, string(k))
			return nil
		})
	})

	if err != nil {
		return nil, err
	}

	return results, nil

	// filter
	// var filtered []string
	// for _, result := range results {
	// 	if strings.HasPrefix(result, input) {
	// 		filtered = append(filtered, result)
	// 	}
	// }
	//
	// return filtered

}

// add checks if command being passed is in the listCommands
// then stores the command and workding directory
func add(path string, promptCmd string) error {
	// get the first command in the promptCmd string
	cmd := strings.Split(promptCmd, " ")[0]

	commands, err := listCommands()
	if err != nil {
		return err
	}

	// check if the command is valid
	if !containsCmd(cmd, commands) {
		return nil
	}

	// Add command to db
	// fmt.Printf("adding. cmd: %s, path: %s \n", promptCmd, path)
	return db.Update(func(tx *bolt.Tx) error {
		directoryBucket, err := tx.CreateBucketIfNotExists([]byte("DirectoryBucket"))
		if err != nil {
			return err
		}

		pathBucket, err := directoryBucket.CreateBucketIfNotExists([]byte(path))
		if err != nil {
			return err
		}

		// Store path and command for contextual path sorting
		cmdBucket, err := tx.CreateBucketIfNotExists([]byte("CommandBucket"))
		if err != nil {
			return err
		}

		// Don't store if the command is r
		if cmd == "r" {
			return nil
		}

		// TODO first look up command and then increment it's count

		// Create commandInfo struct
		ci := commandInfo{}
		ci.time = time.Now()
		ci.count = 1

		// Check if there is a command info value already
		v := cmdBucket.Get([]byte(promptCmd))
		if v != nil {
			// There is a previous command info value
			// Let's update the count and time
			ci = ci.Update(string(v))
		}

		err = cmdBucket.Put([]byte(promptCmd), []byte(ci.String()))
		if err != nil {
			return err
		}

		// Now let's do the same thing for the pathBucket
		v = pathBucket.Get([]byte(promptCmd))
		if v != nil {
			// There is a previous command info value
			// Let's update the count and time
			ci = ci.Update(string(v))
		}

		err = pathBucket.Put([]byte(promptCmd), []byte(ci.String()))

		if err != nil {
			return err
		}

		return nil
	})
}

// containsCmd checks if a command string is is in a slice of strings
func containsCmd(cmd string, commands []string) bool {
	for _, c := range commands {
		// check first command against list of commands
		if c == cmd {
			return true
		}
	}
	return false
}

// listCommands use $PATH to find directories
// Then reads each directory and looks for executables
func listCommands() ([]string, error) {
	// Split $PATH directories into slice
	paths := strings.Split(os.Getenv("PATH"), ":")
	var commands []string

	// created buffered error chan
	errc := make(chan error, 1)

	// sync go routines
	var wg sync.WaitGroup

	// find commands appends results to commands slice
	findCommands := func(p string) {
		defer wg.Done()

		files, err := ioutil.ReadDir(p)
		if err != nil {
			errc <- err // write err into error chan
			return
		}

		for _, f := range files {
			m := f.Mode()

			// Check if file is executable
			if m&0111 != 0 {
				commands = append(commands, f.Name())
			}
		}

		errc <- nil // write nil into error chan
	}

	// Check each path for commands
	for _, p := range paths {
		wg.Add(1)
		go findCommands(p)

		// read any error that is in error chan
		if err := <-errc; err != nil {
			return nil, err
		}
	}

	wg.Wait() // Wait for the paths to be checked

	return commands, nil
}

// stats TODO print stats and usage of r
func stats() {
	fmt.Println("stats")
}
<commit_msg>Fixing time parsing<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/user"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/boltdb/bolt"
	"github.com/chzyer/readline"
)

var db *bolt.DB

// commandInfo struct is stored as the value to commands
type commandInfo struct {
	time  time.Time
	count int
}

func (ci commandInfo) String() string {
	// Store the time in RFC3339 format for easy parsing
	return fmt.Sprintf("%s%s%d", ci.time.Format(time.RFC3339), ",", ci.count)
}

func (ci commandInfo) Update(ciString string) commandInfo {
	info := strings.Split(ciString, ",")
	newCI := commandInfo{}

	count, err := strconv.Atoi(info[1])
	if err != nil {
		count = 0
	}

	newCI.time = time.Now()
	newCI.count = count + 1

	return newCI
}

func (ci commandInfo) NewFromString(ciString string) commandInfo {
	info := strings.Split(ciString, ",")
	newCI := commandInfo{}

	// Parse the time as RFC3339 format
	date, err := time.Parse(time.RFC3339, info[0])
	if err != nil {
		date = time.Now()
	}

	count, err := strconv.Atoi(info[1])
	if err != nil {
		count = 0
	}

	newCI.time = date
	newCI.count = count

	return newCI
}

func main() {
	// Setup flags
	// statsPtr := flag.Bool("stats", false, "show stats and usage of `r`")
	// completePtr := flag.String("complete", "", "show all results for `r`")
	commandPtr := flag.Bool("command", false, "show last command selected from `r`")
	addPtr := flag.String("add", "", "show stats and usage of `r`")
	flag.Parse()

	// Setup bolt db
	usr, err := user.Current()
	if err != nil {
		log.Fatal(err)
	}
	boltPath := filepath.Join(usr.HomeDir, ".r.db")
	// It will be created if it doesn't exist.
	db, err = bolt.Open(boltPath, 0600, nil)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// Check if `results` flag is passed
	// if *completePtr != "" {
	// 	results := showResults(*completePtr)
	// 	for _, result := range results {
	// 		fmt.Println(result)
	// 	}
	// 	os.Exit(0)
	// }

	if *commandPtr {
		printLastCommand()
		os.Exit(0)
	}

	// Check if `add` flag is passed
	if *addPtr != "" {
		args := strings.Split(*addPtr, ":")
		err := add(args[0], args[1])
		if err != nil {
			log.Fatal(err)
		}

		os.Exit(0)
	}

	// reset last command to blank
	// set line as stored command
	err = db.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte("command"))
		if err != nil {
			return err
		}

		err = b.Put([]byte("command"), []byte(""))
		if err != nil {
			return err
		}
		return nil
	})

	if err != nil {
		log.Fatal(err)
	}

	readLine()
}

// readLine used the readline library create a prompt to
// show the command history
func readLine() {
	// create completer from results
	results, err := showResults()
	if err != nil {
		log.Panic(err)
	}

	var pcItems []*readline.PrefixCompleter
	for _, result := range results {
		pcItems = append(pcItems, readline.PcItem(result))
	}
	var completer = readline.NewPrefixCompleter(pcItems...)

	rl, err := readline.NewEx(&readline.Config{
		Prompt:       "> ",
		AutoComplete: completer,
	})
	if err != nil {
		log.Panic(err)
	}
	defer rl.Close()

	for {
		line, err := rl.Readline()
		if err != nil { // io.EOF
			break
		}

		// Only execute if the command typed is in the list of results
		if !containsCmd(strings.TrimSpace(line), results) {
			fmt.Println("Command not found in `r` history.")
			os.Exit(0)
		}

		// set line as stored command
		err = db.Update(func(tx *bolt.Tx) error {
			b, err := tx.CreateBucketIfNotExists([]byte("command"))
			if err != nil {
				return err
			}

			err = b.Put([]byte("command"), []byte(line))
			if err != nil {
				return err
			}
			return nil
		})

		if err != nil {
			log.Fatal(err)
		}

		os.Exit(0)
	}
}

// printLastCommand is used with the --command flag
// it shows the last command selected from the readline prompt
func printLastCommand() {
	var val string
	db.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte("command"))
		if err != nil {
			return err
		}

		val = string(b.Get([]byte("command")))
		return nil
	})

	fmt.Println(val)
}

// showResults reads the boltdb and returns the command history
// based on your current working directory
func showResults() ([]string, error) {
	wd, err := os.Getwd()
	if err != nil {
		return nil, err
	}

	// results := []string{"git status", "git clone", "go install", "cd /Users/jesse/", "cd /Users/jesse/gocode/src/github.com/jesselucas", "ls -Glah"}
	var results []string
	err = db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte("DirectoryBucket"))
		pathBucket := b.Bucket([]byte(wd))
		return pathBucket.ForEach(func(k, v []byte) error {
			ci := commandInfo{}
			fmt.Printf("%s: %s \n", string(k), string(v))
			fmt.Printf("%s: %s \n", string(k), ci.NewFromString(string(v)))
			results = append(results, string(k))
			return nil
		})
	})

	if err != nil {
		return nil, err
	}

	return results, nil

	// filter
	// var filtered []string
	// for _, result := range results {
	// 	if strings.HasPrefix(result, input) {
	// 		filtered = append(filtered, result)
	// 	}
	// }
	//
	// return filtered

}

// add checks if command being passed is in the listCommands
// then stores the command and workding directory
func add(path string, promptCmd string) error {
	// get the first command in the promptCmd string
	cmd := strings.Split(promptCmd, " ")[0]

	commands, err := listCommands()
	if err != nil {
		return err
	}

	// check if the command is valid
	if !containsCmd(cmd, commands) {
		return nil
	}

	// Add command to db
	// fmt.Printf("adding. cmd: %s, path: %s \n", promptCmd, path)
	return db.Update(func(tx *bolt.Tx) error {
		directoryBucket, err := tx.CreateBucketIfNotExists([]byte("DirectoryBucket"))
		if err != nil {
			return err
		}

		pathBucket, err := directoryBucket.CreateBucketIfNotExists([]byte(path))
		if err != nil {
			return err
		}

		// Store path and command for contextual path sorting
		cmdBucket, err := tx.CreateBucketIfNotExists([]byte("CommandBucket"))
		if err != nil {
			return err
		}

		// Don't store if the command is r
		if cmd == "r" {
			return nil
		}

		// TODO first look up command and then increment it's count

		// Create commandInfo struct
		ci := commandInfo{}
		ci.time = time.Now()
		ci.count = 1

		// Check if there is a command info value already
		v := cmdBucket.Get([]byte(promptCmd))
		if v != nil {
			// There is a previous command info value
			// Let's update the count and time
			ci = ci.Update(string(v))
		}

		err = cmdBucket.Put([]byte(promptCmd), []byte(ci.String()))
		if err != nil {
			return err
		}

		// Now let's do the same thing for the pathBucket
		v = pathBucket.Get([]byte(promptCmd))
		if v != nil {
			// There is a previous command info value
			// Let's update the count and time
			ci = ci.Update(string(v))
			fmt.Println(ci)
		}

		err = pathBucket.Put([]byte(promptCmd), []byte(ci.String()))
		if err != nil {
			return err
		}

		return nil
	})
}

// containsCmd checks if a command string is is in a slice of strings
func containsCmd(cmd string, commands []string) bool {
	for _, c := range commands {
		// check first command against list of commands
		if c == cmd {
			return true
		}
	}
	return false
}

// listCommands use $PATH to find directories
// Then reads each directory and looks for executables
func listCommands() ([]string, error) {
	// Split $PATH directories into slice
	paths := strings.Split(os.Getenv("PATH"), ":")
	var commands []string

	// created buffered error chan
	errc := make(chan error, 1)

	// sync go routines
	var wg sync.WaitGroup

	// find commands appends results to commands slice
	findCommands := func(p string) {
		defer wg.Done()

		files, err := ioutil.ReadDir(p)
		if err != nil {
			errc <- err // write err into error chan
			return
		}

		for _, f := range files {
			m := f.Mode()

			// Check if file is executable
			if m&0111 != 0 {
				commands = append(commands, f.Name())
			}
		}

		errc <- nil // write nil into error chan
	}

	// Check each path for commands
	for _, p := range paths {
		wg.Add(1)
		go findCommands(p)

		// read any error that is in error chan
		if err := <-errc; err != nil {
			return nil, err
		}
	}

	wg.Wait() // Wait for the paths to be checked

	return commands, nil
}

// stats TODO print stats and usage of r
func stats() {
	fmt.Println("stats")
}
<|endoftext|>


<commit_before>package main

import (
  "fmt"
  "os"
  "flag"
)

var (
  Version string
  Build string
)

func main() {
  pwd, err := os.Getwd()
  if (err != nil) {
    fmt.Println("Error: could not determine your current directory: ", err)
    os.Exit(1)
  }

  // Setup usage arguments and options.
  cmdName := "docker-unisync"
  flag.Usage = func() {
    fmt.Printf("Example usage:\n\t%v [options] DOCKER-MACHINE-NAME...", cmdName)
    fmt.Println("\nOptions:")
    flag.PrintDefaults()
  }

  help := flag.Bool("help", false, "Show this message")
  verbose := flag.Bool("verbose", false, "Verbose output")
  showVersion := flag.Bool("version", false, "Show version")

  flag.Parse()

  if *showVersion {
    fmt.Printf("%v version %v, build %v\n", cmdName, Version, Build)
    return
  }

  if *help {
    flag.Usage()
    return
  }

  fmt.Println(*help)
  fmt.Println(*verbose)
  fmt.Println("Hello, yo!")
  fmt.Println(pwd)
}
<commit_msg>Formatting updates.<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
)

var (
	Version string
	Build   string
)

func main() {
	pwd, err := os.Getwd()
	if err != nil {
		fmt.Println("Error: could not determine your current directory: ", err)
		os.Exit(1)
	}

	// Setup usage arguments and options.
	cmdName := "docker-unisync"
	flag.Usage = func() {
		fmt.Printf("Example usage:\n\t%v [options] DOCKER-MACHINE-NAME...", cmdName)
		fmt.Println("\nOptions:")
		flag.PrintDefaults()
	}

	help := flag.Bool("help", false, "Show this message")
	verbose := flag.Bool("verbose", false, "Verbose output")
	showVersion := flag.Bool("version", false, "Show version")

	flag.Parse()

	if *showVersion {
		fmt.Printf("%v version %v, build %v\n", cmdName, Version, Build)
		return
	}

	if *help {
		flag.Usage()
		return
	}

	fmt.Println(*help)
	fmt.Println(*verbose)
	fmt.Println("Hello, yo!")
	fmt.Println(pwd)
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"
	"fmt"
	"net/http"
	"os"

	"cloud.google.com/go/profiler"
	"contrib.go.opencensus.io/exporter/stackdriver"
	"github.com/metal-tile/land/dqn"
	"github.com/metal-tile/land/firedb"
	"github.com/sinmetal/gcpmetadata"
	"go.opencensus.io/trace"
)

func main() {
	projectID, err := gcpmetadata.GetProjectID()
	if err != nil {
		panic(err)
	}

	if err := profiler.Start(profiler.Config{Service: "land", ServiceVersion: "0.0.1"}); err != nil {
		fmt.Printf("failed stackdriver.profiler.Start %+v", err)
	}
	exporter, err := stackdriver.NewExporter(stackdriver.Options{
		ProjectID: projectID,
	})
	if err != nil {
		panic(err)
	}
	trace.RegisterExporter(exporter)

	hs, err := os.Hostname()
	if err != nil {
		fmt.Printf("Fail os.Hostname. %s\n", err.Error())
	}
	fmt.Printf("Hostname is %s\n", hs)
	fmt.Println("")
	fmt.Println(os.Environ())

	onlyFuncActivate := flag.String("onlyFuncActivate", "", "Activate only specified function")
	flag.Parse()
	fmt.Printf("onlyFuncActivate is %s\n", *onlyFuncActivate)

	ctx := context.Background()
	firedb.SetUp(ctx, projectID)

	ch := make(chan error)

	fieldStore := firedb.NewFieldStore()
	if *onlyFuncActivate == "" || *onlyFuncActivate == "field" {
		fmt.Println("Start WatchField")
		go func() {
			ch <- fieldStore.Watch(ctx, "world-default20170908-land-home")
		}()
	}

	playerStore := firedb.NewPlayerStore()
	if *onlyFuncActivate == "" || *onlyFuncActivate == "playerPosition" {
		fmt.Println("Start WatchPlayerPositions")
		go func() {
			ch <- playerStore.Watch(ctx, "world-default-player-position")
		}()
	}

	if *onlyFuncActivate == "" || *onlyFuncActivate == "monster" {
		fmt.Println("Start Monster Control")
		go func() {
			c := &MonsterClient{
				DQN:         dqn.NewClient(),
				PlayerStore: playerStore,
			}
			ch <- RunControlMonster(c)
		}()
	}

	if *onlyFuncActivate == "" || *onlyFuncActivate == "watchPassivePlayer" {
		fmt.Println("Start WatchPassivePlayer")
		go func() {
			ch <- WatchPassivePlayer()
		}()
	}

	// Debug HTTP Handler
	go func() {
		http.HandleFunc("/", helthHandler)
		http.HandleFunc("/field", fieldHandler)
		http.HandleFunc("/player", playerHandler)
		http.HandleFunc("/healthz", helthHandler)
		http.ListenAndServe(":8080", nil)
	}()

	err = <-ch
	fmt.Printf("%+v", err)
}
<commit_msg>エラーハンドリングしそこねていたのを修正<commit_after>package main

import (
	"context"
	"flag"
	"fmt"
	"net/http"
	"os"

	"cloud.google.com/go/profiler"
	"contrib.go.opencensus.io/exporter/stackdriver"
	"github.com/metal-tile/land/dqn"
	"github.com/metal-tile/land/firedb"
	"github.com/sinmetal/gcpmetadata"
	"go.opencensus.io/trace"
)

func main() {
	projectID, err := gcpmetadata.GetProjectID()
	if err != nil {
		panic(err)
	}

	if err := profiler.Start(profiler.Config{Service: "land", ServiceVersion: "0.0.1"}); err != nil {
		fmt.Printf("failed stackdriver.profiler.Start %+v", err)
	}
	exporter, err := stackdriver.NewExporter(stackdriver.Options{
		ProjectID: projectID,
	})
	if err != nil {
		panic(err)
	}
	trace.RegisterExporter(exporter)

	hs, err := os.Hostname()
	if err != nil {
		fmt.Printf("Fail os.Hostname. %s\n", err.Error())
	}
	fmt.Printf("Hostname is %s\n", hs)
	fmt.Println("")
	fmt.Println(os.Environ())

	onlyFuncActivate := flag.String("onlyFuncActivate", "", "Activate only specified function")
	flag.Parse()
	fmt.Printf("onlyFuncActivate is %s\n", *onlyFuncActivate)

	ctx := context.Background()
	if err := firedb.SetUp(ctx, projectID); err != nil {
		panic(err)
	}

	ch := make(chan error)

	fieldStore := firedb.NewFieldStore()
	if *onlyFuncActivate == "" || *onlyFuncActivate == "field" {
		fmt.Println("Start WatchField")
		go func() {
			ch <- fieldStore.Watch(ctx, "world-default20170908-land-home")
		}()
	}

	playerStore := firedb.NewPlayerStore()
	if *onlyFuncActivate == "" || *onlyFuncActivate == "playerPosition" {
		fmt.Println("Start WatchPlayerPositions")
		go func() {
			ch <- playerStore.Watch(ctx, "world-default-player-position")
		}()
	}

	if *onlyFuncActivate == "" || *onlyFuncActivate == "monster" {
		fmt.Println("Start Monster Control")
		go func() {
			c := &MonsterClient{
				DQN:         dqn.NewClient(),
				PlayerStore: playerStore,
			}
			ch <- RunControlMonster(c)
		}()
	}

	if *onlyFuncActivate == "" || *onlyFuncActivate == "watchPassivePlayer" {
		fmt.Println("Start WatchPassivePlayer")
		go func() {
			ch <- WatchPassivePlayer()
		}()
	}

	// Debug HTTP Handler
	go func() {
		http.HandleFunc("/", helthHandler)
		http.HandleFunc("/field", fieldHandler)
		http.HandleFunc("/player", playerHandler)
		http.HandleFunc("/healthz", helthHandler)
		if err := http.ListenAndServe(":8080", nil); err != nil {
			panic(err)
		}
	}()

	err = <-ch
	fmt.Printf("%+v", err)
}
<|endoftext|>


<commit_before>package main

func main() {
}
<commit_msg>Added http<commit_after>package main

import (
	"os"
	"net/http"
	"log"
	"fmt"
)

func getEnv(key string, defVal string) (env string) {
	env = os.Getenv(key)

	if env == "" {
		env = defVal
	}
	return
}

func main() {
	host := getEnv("HOST", "")
	port := getEnv("PORT", "8080")
	wsPort := getEnv("WSPORT", "8080")
//	mongoURL := getEnv("MONGOHQ_URL", "localhost")

	bind := fmt.Sprintf("%s:%s", host, port)
	log.Println("Starting server on", bind, "with websocket on port", wsPort)

	err := http.ListenAndServe(bind, nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<|endoftext|>