<commit_before>package linux_backend

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"time"

	"github.com/cloudfoundry-incubator/garden"
	"github.com/cloudfoundry-incubator/garden-linux/old/system_info"
	"github.com/pivotal-golang/lager"
)

//go:generate counterfeiter . Container
type Container interface {
	ID() string
	HasProperties(garden.Properties) bool
	GraceTime() time.Duration

	Start() error

	Snapshot(io.Writer) error
	Cleanup()

	garden.Container
}

type ContainerPool interface {
	Setup() error
	Create(garden.ContainerSpec) (Container, error)
	Restore(io.Reader) (Container, error)
	Destroy(Container) error
	Prune(keep map[string]bool) error
	MaxContainers() int
}

type ContainerRepository interface {
	All() []Container
	Add(Container)
	FindByHandle(string) (Container, error)
	Query(filter func(Container) bool) []Container
	Delete(Container)
}

type LinuxBackend struct {
	logger lager.Logger

	containerPool ContainerPool
	systemInfo    system_info.Provider
	snapshotsPath string

	containerRepo ContainerRepository
}

type HandleExistsError struct {
	Handle string
}

func (e HandleExistsError) Error() string {
	return fmt.Sprintf("handle already exists: %s", e.Handle)
}

type FailedToSnapshotError struct {
	OriginalError error
}

func (e FailedToSnapshotError) Error() string {
	return fmt.Sprintf("failed to save snapshot: %s", e.OriginalError)
}

func New(
	logger lager.Logger,
	containerPool ContainerPool,
	containerRepo ContainerRepository,
	systemInfo system_info.Provider,
	snapshotsPath string,
) *LinuxBackend {
	return &LinuxBackend{
		logger: logger.Session("backend"),

		containerPool: containerPool,
		systemInfo:    systemInfo,
		snapshotsPath: snapshotsPath,

		containerRepo: containerRepo,
	}
}

func (b *LinuxBackend) Setup() error {
	return b.containerPool.Setup()
}

func (b *LinuxBackend) Start() error {
	if b.snapshotsPath != "" {
		_, err := os.Stat(b.snapshotsPath)
		if err == nil {
			b.restoreSnapshots()
			os.RemoveAll(b.snapshotsPath)
		}

		err = os.MkdirAll(b.snapshotsPath, 0755)
		if err != nil {
			return err
		}
	}

	keep := map[string]bool{}

	containers := b.containerRepo.All()

	for _, container := range containers {
		keep[container.ID()] = true
	}

	return b.containerPool.Prune(keep)
}

func (b *LinuxBackend) Ping() error {
	return nil
}

func (b *LinuxBackend) Capacity() (garden.Capacity, error) {
	totalMemory, err := b.systemInfo.TotalMemory()
	if err != nil {
		return garden.Capacity{}, err
	}

	totalDisk, err := b.systemInfo.TotalDisk()
	if err != nil {
		return garden.Capacity{}, err
	}

	return garden.Capacity{
		MemoryInBytes: totalMemory,
		DiskInBytes:   totalDisk,
		MaxContainers: uint64(b.containerPool.MaxContainers()),
	}, nil
}

func (b *LinuxBackend) Create(spec garden.ContainerSpec) (garden.Container, error) {
	if _, err := b.containerRepo.FindByHandle(spec.Handle); spec.Handle != "" && err == nil {
		return nil, HandleExistsError{Handle: spec.Handle}
	}

	container, err := b.containerPool.Create(spec)
	if err != nil {
		return nil, err
	}

	err = container.Start()
	if err != nil {
		b.containerPool.Destroy(container)
		return nil, err
	}

	b.containerRepo.Add(container)

	return container, nil
}

func (b *LinuxBackend) Destroy(handle string) error {
	container, err := b.containerRepo.FindByHandle(handle)
	if err != nil {
		return err
	}

	err = b.containerPool.Destroy(container)
	if err != nil {
		return err
	}

	b.containerRepo.Delete(container)

	return nil
}

func (b *LinuxBackend) Containers(props garden.Properties) ([]garden.Container, error) {
	return toGardenContainers(b.containerRepo.Query(withProperties(props))), nil
}

func (b *LinuxBackend) Lookup(handle string) (garden.Container, error) {
	return b.containerRepo.FindByHandle(handle)
}

func (b *LinuxBackend) BulkInfo(handles []string) (map[string]garden.ContainerInfoEntry, error) {
	containers := b.containerRepo.Query(withHandles(handles))

	infos := make(map[string]garden.ContainerInfoEntry)
	for _, container := range containers {
		info, err := container.Info()
		if err != nil {
			infos[container.Handle()] = garden.ContainerInfoEntry{
				Err: garden.NewError(err.Error()),
			}
		} else {
			infos[container.Handle()] = garden.ContainerInfoEntry{
				Info: info,
			}
		}
	}

	return infos, nil
}

func (b *LinuxBackend) BulkMetrics(handles []string) (map[string]garden.ContainerMetricsEntry, error) {
	containers := b.containerRepo.Query(withHandles(handles))

	metrics := make(map[string]garden.ContainerMetricsEntry)
	for _, container := range containers {
		metric, err := container.Metrics()
		if err != nil {
			metrics[container.Handle()] = garden.ContainerMetricsEntry{
				Err: garden.NewError(err.Error()),
			}
		} else {
			metrics[container.Handle()] = garden.ContainerMetricsEntry{
				Metrics: metric,
			}
		}
	}

	return metrics, nil
}

func (b *LinuxBackend) GraceTime(container garden.Container) time.Duration {
	return container.(Container).GraceTime()
}

func (b *LinuxBackend) Stop() {
	for _, container := range b.containerRepo.All() {
		container.Cleanup()
		err := b.saveSnapshot(container)
		if err != nil {
			b.logger.Error("failed-to-save-snapshot", err, lager.Data{
				"container": container.ID(),
			})
		}
	}
}

func (b *LinuxBackend) restoreSnapshots() {
	sLog := b.logger.Session("restore")

	entries, err := ioutil.ReadDir(b.snapshotsPath)
	if err != nil {
		b.logger.Error("failed-to-read-snapshots", err, lager.Data{
			"from": b.snapshotsPath,
		})
	}

	for _, entry := range entries {
		snapshot := path.Join(b.snapshotsPath, entry.Name())

		lLog := sLog.Session("load", lager.Data{
			"snapshot": entry.Name(),
		})

		lLog.Debug("loading")

		file, err := os.Open(snapshot)
		if err != nil {
			lLog.Error("failed-to-open", err)
		}

		_, err = b.restore(file)
		if err != nil {
			lLog.Error("failed-to-restore", err)
		}
	}
}

func (b *LinuxBackend) saveSnapshot(container Container) error {
	if b.snapshotsPath == "" {
		return nil
	}

	b.logger.Info("save-snapshot", lager.Data{
		"container": container.ID(),
	})

	snapshotPath := path.Join(b.snapshotsPath, container.ID())

	snapshot, err := os.Create(snapshotPath)
	if err != nil {
		return &FailedToSnapshotError{err}
	}

	err = container.Snapshot(snapshot)
	if err != nil {
		return &FailedToSnapshotError{err}
	}

	return snapshot.Close()
}

func (b *LinuxBackend) restore(snapshot io.Reader) (garden.Container, error) {
	container, err := b.containerPool.Restore(snapshot)
	if err != nil {
		return nil, err
	}
	b.containerRepo.Add(container)
	return container, nil
}

func withHandles(handles []string) func(Container) bool {
	return func(c Container) bool {
		for _, e := range handles {
			if e == c.Handle() {
				return true
			}
		}
		return false
	}
}

func withProperties(props garden.Properties) func(Container) bool {
	return func(c Container) bool {
		return c.HasProperties(props)
	}
}

func toGardenContainers(cs []Container) []garden.Container {
	var result []garden.Container
	for _, c := range cs {
		result = append(result, c)
	}

	return result
}
<commit_msg>Mount sysfs<commit_after>package linux_backend

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"syscall"
	"time"

	"github.com/cloudfoundry-incubator/garden"
	"github.com/cloudfoundry-incubator/garden-linux/old/system_info"
	"github.com/pivotal-golang/lager"
)

//go:generate counterfeiter . Container
type Container interface {
	ID() string
	HasProperties(garden.Properties) bool
	GraceTime() time.Duration

	Start() error

	Snapshot(io.Writer) error
	Cleanup()

	garden.Container
}

type ContainerPool interface {
	Setup() error
	Create(garden.ContainerSpec) (Container, error)
	Restore(io.Reader) (Container, error)
	Destroy(Container) error
	Prune(keep map[string]bool) error
	MaxContainers() int
}

type ContainerRepository interface {
	All() []Container
	Add(Container)
	FindByHandle(string) (Container, error)
	Query(filter func(Container) bool) []Container
	Delete(Container)
}

type LinuxBackend struct {
	logger lager.Logger

	containerPool ContainerPool
	systemInfo    system_info.Provider
	snapshotsPath string

	containerRepo ContainerRepository
}

type HandleExistsError struct {
	Handle string
}

func (e HandleExistsError) Error() string {
	return fmt.Sprintf("handle already exists: %s", e.Handle)
}

type FailedToSnapshotError struct {
	OriginalError error
}

func (e FailedToSnapshotError) Error() string {
	return fmt.Sprintf("failed to save snapshot: %s", e.OriginalError)
}

func New(
	logger lager.Logger,
	containerPool ContainerPool,
	containerRepo ContainerRepository,
	systemInfo system_info.Provider,
	snapshotsPath string,
) *LinuxBackend {
	return &LinuxBackend{
		logger: logger.Session("backend"),

		containerPool: containerPool,
		systemInfo:    systemInfo,
		snapshotsPath: snapshotsPath,

		containerRepo: containerRepo,
	}
}

func (b *LinuxBackend) Setup() error {
	return b.containerPool.Setup()
}

func (b *LinuxBackend) Start() error {
	if b.snapshotsPath != "" {
		_, err := os.Stat(b.snapshotsPath)
		if err == nil {
			b.restoreSnapshots()
			os.RemoveAll(b.snapshotsPath)
		}

		err = os.MkdirAll(b.snapshotsPath, 0755)
		if err != nil {
			return err
		}
	}

	keep := map[string]bool{}

	containers := b.containerRepo.All()

	for _, container := range containers {
		keep[container.ID()] = true
	}

	if err := mountSysFs(); err != nil {
		return err
	}

	return b.containerPool.Prune(keep)
}

func (b *LinuxBackend) Ping() error {
	return nil
}

func (b *LinuxBackend) Capacity() (garden.Capacity, error) {
	totalMemory, err := b.systemInfo.TotalMemory()
	if err != nil {
		return garden.Capacity{}, err
	}

	totalDisk, err := b.systemInfo.TotalDisk()
	if err != nil {
		return garden.Capacity{}, err
	}

	return garden.Capacity{
		MemoryInBytes: totalMemory,
		DiskInBytes:   totalDisk,
		MaxContainers: uint64(b.containerPool.MaxContainers()),
	}, nil
}

func (b *LinuxBackend) Create(spec garden.ContainerSpec) (garden.Container, error) {
	if _, err := b.containerRepo.FindByHandle(spec.Handle); spec.Handle != "" && err == nil {
		return nil, HandleExistsError{Handle: spec.Handle}
	}

	container, err := b.containerPool.Create(spec)
	if err != nil {
		return nil, err
	}

	err = container.Start()
	if err != nil {
		b.containerPool.Destroy(container)
		return nil, err
	}

	b.containerRepo.Add(container)

	return container, nil
}

func (b *LinuxBackend) Destroy(handle string) error {
	container, err := b.containerRepo.FindByHandle(handle)
	if err != nil {
		return err
	}

	err = b.containerPool.Destroy(container)
	if err != nil {
		return err
	}

	b.containerRepo.Delete(container)

	return nil
}

func (b *LinuxBackend) Containers(props garden.Properties) ([]garden.Container, error) {
	return toGardenContainers(b.containerRepo.Query(withProperties(props))), nil
}

func (b *LinuxBackend) Lookup(handle string) (garden.Container, error) {
	return b.containerRepo.FindByHandle(handle)
}

func (b *LinuxBackend) BulkInfo(handles []string) (map[string]garden.ContainerInfoEntry, error) {
	containers := b.containerRepo.Query(withHandles(handles))

	infos := make(map[string]garden.ContainerInfoEntry)
	for _, container := range containers {
		info, err := container.Info()
		if err != nil {
			infos[container.Handle()] = garden.ContainerInfoEntry{
				Err: garden.NewError(err.Error()),
			}
		} else {
			infos[container.Handle()] = garden.ContainerInfoEntry{
				Info: info,
			}
		}
	}

	return infos, nil
}

func (b *LinuxBackend) BulkMetrics(handles []string) (map[string]garden.ContainerMetricsEntry, error) {
	containers := b.containerRepo.Query(withHandles(handles))

	metrics := make(map[string]garden.ContainerMetricsEntry)
	for _, container := range containers {
		metric, err := container.Metrics()
		if err != nil {
			metrics[container.Handle()] = garden.ContainerMetricsEntry{
				Err: garden.NewError(err.Error()),
			}
		} else {
			metrics[container.Handle()] = garden.ContainerMetricsEntry{
				Metrics: metric,
			}
		}
	}

	return metrics, nil
}

func (b *LinuxBackend) GraceTime(container garden.Container) time.Duration {
	return container.(Container).GraceTime()
}

func (b *LinuxBackend) Stop() {
	for _, container := range b.containerRepo.All() {
		container.Cleanup()
		err := b.saveSnapshot(container)
		if err != nil {
			b.logger.Error("failed-to-save-snapshot", err, lager.Data{
				"container": container.ID(),
			})
		}
	}
}

func (b *LinuxBackend) restoreSnapshots() {
	sLog := b.logger.Session("restore")

	entries, err := ioutil.ReadDir(b.snapshotsPath)
	if err != nil {
		b.logger.Error("failed-to-read-snapshots", err, lager.Data{
			"from": b.snapshotsPath,
		})
	}

	for _, entry := range entries {
		snapshot := path.Join(b.snapshotsPath, entry.Name())

		lLog := sLog.Session("load", lager.Data{
			"snapshot": entry.Name(),
		})

		lLog.Debug("loading")

		file, err := os.Open(snapshot)
		if err != nil {
			lLog.Error("failed-to-open", err)
		}

		_, err = b.restore(file)
		if err != nil {
			lLog.Error("failed-to-restore", err)
		}
	}
}

func (b *LinuxBackend) saveSnapshot(container Container) error {
	if b.snapshotsPath == "" {
		return nil
	}

	b.logger.Info("save-snapshot", lager.Data{
		"container": container.ID(),
	})

	snapshotPath := path.Join(b.snapshotsPath, container.ID())

	snapshot, err := os.Create(snapshotPath)
	if err != nil {
		return &FailedToSnapshotError{err}
	}

	err = container.Snapshot(snapshot)
	if err != nil {
		return &FailedToSnapshotError{err}
	}

	return snapshot.Close()
}

func (b *LinuxBackend) restore(snapshot io.Reader) (garden.Container, error) {
	container, err := b.containerPool.Restore(snapshot)
	if err != nil {
		return nil, err
	}
	b.containerRepo.Add(container)
	return container, nil
}

func withHandles(handles []string) func(Container) bool {
	return func(c Container) bool {
		for _, e := range handles {
			if e == c.Handle() {
				return true
			}
		}
		return false
	}
}

func withProperties(props garden.Properties) func(Container) bool {
	return func(c Container) bool {
		return c.HasProperties(props)
	}
}

func toGardenContainers(cs []Container) []garden.Container {
	var result []garden.Container
	for _, c := range cs {
		result = append(result, c)
	}

	return result
}

func mountSysFs() error {
	mntpoint, err := os.Stat("/sys")
	if err != nil {
		return err
	}

	parent, err := os.Stat("/")
	if err != nil {
		return err
	}

	//mount sysfs if not mounted already
	if mntpoint.Sys().(*syscall.Stat_t).Dev == parent.Sys().(*syscall.Stat_t).Dev {
		err = syscall.Mount("sysfs", "/sys", "sysfs", uintptr(0), "")
		if err != nil {
			return fmt.Errorf("Mounting sysfs failed: %s", err)
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/paulkramme/toml"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	fmt.Println("BTSOOT - Copyright (c) 2017 Paul Kramme All Rights Reserved.")

	ConfigLocation := flag.String("config", "./btsoot.conf", "Specifies configfile location")
	flag.Parse()

	var Config Configuration

	_, err := toml.DecodeFile(*ConfigLocation, &Config)
	if err != nil {
		fmt.Println("Couldn't find or open config file.")
		panic(err)
	}

	f, err := os.OpenFile(Config.LogFileLocation, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()
	log.SetOutput(f)

	// NOTE: Create a spacer in the log
	log.Println("\n\n\n\n\n")

	ProcessList := CreateMasterProcessList()

	// NOTE: Init standard threads...
	go UpdateProcess(ProcessList[UpdateThreadID])
	go WebServer(ProcessList[WebserverThreadID])
	go ScanningProcess(ProcessList[ScanThreadID])
	signals := make(chan os.Signal)

	log.Println("Startup complete...")

	// NOTE: Wait for SIGINT
	signal.Notify(signals, syscall.SIGINT)
	<-signals
	log.Println("Exiting...")
	KillAll(ProcessList)
	time.Sleep(1 * time.Second) // wait for scanners
}
<commit_msg>Add database opening<commit_after>package main

import (
	"database/sql"
	"flag"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
	"github.com/paulkramme/toml"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	fmt.Println("BTSOOT - Copyright (c) 2017 Paul Kramme All Rights Reserved.")

	ConfigLocation := flag.String("config", "./btsoot.conf", "Specifies configfile location")
	flag.Parse()

	var Config Configuration

	_, err := toml.DecodeFile(*ConfigLocation, &Config)
	if err != nil {
		fmt.Println("Couldn't find or open config file.")
		panic(err)
	}

	f, err := os.OpenFile(Config.LogFileLocation, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()
	log.SetOutput(f)

	// NOTE: Create a spacer in the log
	log.Println("\n\n\n\n\n")

	db, err := sql.Open("sqlite3", Config.DBFileLocation)
	if err != nil {
		log.Fatal(err)
	}
	err = db.Ping()
	if err != nil {
		panic(err)
	}
	log.Println("Database connection established.")

	ProcessList := CreateMasterProcessList()

	// NOTE: Init standard threads...
	go UpdateProcess(ProcessList[UpdateThreadID])
	go WebServer(ProcessList[WebserverThreadID])
	go ScanningProcess(ProcessList[ScanThreadID])
	signals := make(chan os.Signal)

	log.Println("Startup complete...")

	// NOTE: Wait for SIGINT
	signal.Notify(signals, syscall.SIGINT)
	<-signals
	log.Println("Exiting...")
	KillAll(ProcessList)
	time.Sleep(1 * time.Second) // wait for scanners
}
<|endoftext|>


<commit_before>package impl

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

	"tools/lib/cmdline"
	"tools/lib/util"
)

// cmdGo represents the 'go' command of the veyron tool.
var cmdGo = &cmdline.Command{
	Run:   runGo,
	Name:  "go",
	Short: "Execute the go tool using the veyron environment",
	Long: `
Wrapper around the 'go' tool that can be used for compilation of
veyron Go sources. It takes care of veyron-specific setup, such as
setting up the Go specific environment variables or making sure that
VDL generated files are regenerated before compilation.

In particular, the tool invokes the following command before invoking
any go tool commands that compile veyron Go code:

vdl generate -lang=go all
`,
	ArgsName: "<arg ...>",
	ArgsLong: "<arg ...> is a list of arguments for the go tool.",
}

func runGo(command *cmdline.Command, args []string) error {
	if len(args) == 0 {
		return command.UsageErrorf("not enough arguments")
	}
	return setupAndGo(util.HostPlatform(), command, args)
}

// cmdXGo represents the 'xgo' command of the veyron tool.
var cmdXGo = &cmdline.Command{
	Run:   runXGo,
	Name:  "xgo",
	Short: "Execute the go tool using the veyron environment and cross-compilation",
	Long: `
Wrapper around the 'go' tool that can be used for cross-compilation of
veyron Go sources. It takes care of veyron-specific setup, such as
setting up the Go specific environment variables or making sure that
VDL generated files are regenerated before compilation.

In particular, the tool invokes the following command before invoking
any go tool commands that compile veyron Go code:

vdl generate -lang=go all

`,
	ArgsName: "<platform> <arg ...>",
	ArgsLong: `
<platform> is the cross-compilation target and has the general format
<arch><sub>-<os> or <arch><sub>-<os>-<env> where:
- <arch> is the platform architecture (e.g. 386, amd64 or arm)
- <sub> is the platform sub-architecture (e.g. v6 or v7 for arm)
- <os> is the platform operating system (e.g. linux or darwin)
- <env> is the platform environment (e.g. gnu or android)

<arg ...> is a list of arguments for the go tool."
`,
}

func runXGo(command *cmdline.Command, args []string) error {
	if len(args) < 2 {
		return command.UsageErrorf("not enough arguments")
	}
	platform, err := util.ParsePlatform(args[0])
	if err != nil {
		return err
	}
	return setupAndGo(platform, command, args[1:])
}

func setupAndGo(platform util.Platform, command *cmdline.Command, args []string) error {
	// First set up the environment for the host platform, and run vdl.
	if err := util.SetupVeyronEnvironment(util.HostPlatform()); err != nil {
		return err
	}
	switch args[0] {
	case "build", "install", "run", "test":
		if err := generateVDL(); err != nil {
			return err
		}
	}
	// Now set up the specified platform, and run go.
	if err := util.SetupVeyronEnvironment(platform); err != nil {
		return err
	}
	goCmd := exec.Command("go", args...)
	goCmd.Stdout = command.Stdout()
	goCmd.Stderr = command.Stderr()
	return translateExitCode(goCmd.Run())
}

func generateVDL() error {
	if novdlFlag {
		return nil
	}
	root, err := util.VeyronRoot()
	if err != nil {
		return err
	}
	// Initialize args with the *.go files under the vdl directory to run.
	args := []string{"run"}
	vdlDir := filepath.Join(root, "veyron", "go", "src", "veyron.io", "veyron", "veyron2", "vdl", "vdl")
	fis, err := ioutil.ReadDir(vdlDir)
	if err != nil {
		return fmt.Errorf("ReadDir(%v) failed: %v", vdlDir, err)
	}
	for _, fi := range fis {
		if strings.HasSuffix(fi.Name(), ".go") {
			args = append(args, filepath.Join(vdlDir, fi.Name()))
		}
	}
	// TODO(toddw): We should probably only generate vdl for the packages
	// specified for the corresponding "go" command.  This isn't trivial; we'd
	// need to grab the transitive go dependencies for the specified packages, and
	// then look for transitive vdl dependencies based on that set.
	args = append(args, "generate", "-lang=go", "all")
	vdlCmd := exec.Command("go", args...)
	if out, err := vdlCmd.CombinedOutput(); err != nil {
		return fmt.Errorf("failed to generate vdl: %v\n%v\n%s", err, strings.Join(vdlCmd.Args, " "), out)
	}
	return nil
}

// cmdGoExt represents the 'goext' command of the veyron tool.
var cmdGoExt = &cmdline.Command{
	Name:     "goext",
	Short:    "Veyron extensions of the go tool",
	Long:     "Veyron extension of the go tool.",
	Children: []*cmdline.Command{cmdGoExtDistClean},
}

// cmdGoExtDistClean represents the 'distclean' sub-command of 'goext'
// command of the veyron tool.
var cmdGoExtDistClean = &cmdline.Command{
	Run:   runGoExtDistClean,
	Name:  "distclean",
	Short: "Restore the veyron Go repositories to their pristine state",
	Long: `
Unlike the 'go clean' command, which only removes object files for
packages in the source tree, the 'goext disclean' command removes all
object files from veyron Go workspaces. This functionality is needed
to avoid accidental use of stale object files that correspond to
packages that no longer exist in the source tree.
`,
}

func runGoExtDistClean(command *cmdline.Command, _ []string) error {
	if err := util.SetupVeyronEnvironment(util.HostPlatform()); err != nil {
		return err
	}
	goPath := os.Getenv("GOPATH")
	failed := false
	for _, workspace := range strings.Split(goPath, ":") {
		if workspace == "" {
			continue
		}
		for _, name := range []string{"bin", "pkg"} {
			dir := filepath.Join(workspace, name)
			// TODO(jsimsa): Use the new logging library
			// for this when it is checked in.
			fmt.Fprintf(command.Stdout(), "Removing %v\n", dir)
			if err := os.RemoveAll(dir); err != nil {
				failed = true
				fmt.Fprintf(command.Stderr(), "RemoveAll(%v) failed: %v", dir, err)
			}
		}
	}
	if failed {
		return cmdline.ErrExitCode(2)
	}
	return nil
}
<commit_msg>tools/xgo Use "$GOROOT/bin/go" instead of "go" GOROOT is available<commit_after>package impl

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

	"tools/lib/cmdline"
	"tools/lib/util"
)

// cmdGo represents the 'go' command of the veyron tool.
var cmdGo = &cmdline.Command{
	Run:   runGo,
	Name:  "go",
	Short: "Execute the go tool using the veyron environment",
	Long: `
Wrapper around the 'go' tool that can be used for compilation of
veyron Go sources. It takes care of veyron-specific setup, such as
setting up the Go specific environment variables or making sure that
VDL generated files are regenerated before compilation.

In particular, the tool invokes the following command before invoking
any go tool commands that compile veyron Go code:

vdl generate -lang=go all
`,
	ArgsName: "<arg ...>",
	ArgsLong: "<arg ...> is a list of arguments for the go tool.",
}

func runGo(command *cmdline.Command, args []string) error {
	if len(args) == 0 {
		return command.UsageErrorf("not enough arguments")
	}
	return setupAndGo(util.HostPlatform(), command, args)
}

// cmdXGo represents the 'xgo' command of the veyron tool.
var cmdXGo = &cmdline.Command{
	Run:   runXGo,
	Name:  "xgo",
	Short: "Execute the go tool using the veyron environment and cross-compilation",
	Long: `
Wrapper around the 'go' tool that can be used for cross-compilation of
veyron Go sources. It takes care of veyron-specific setup, such as
setting up the Go specific environment variables or making sure that
VDL generated files are regenerated before compilation.

In particular, the tool invokes the following command before invoking
any go tool commands that compile veyron Go code:

vdl generate -lang=go all

`,
	ArgsName: "<platform> <arg ...>",
	ArgsLong: `
<platform> is the cross-compilation target and has the general format
<arch><sub>-<os> or <arch><sub>-<os>-<env> where:
- <arch> is the platform architecture (e.g. 386, amd64 or arm)
- <sub> is the platform sub-architecture (e.g. v6 or v7 for arm)
- <os> is the platform operating system (e.g. linux or darwin)
- <env> is the platform environment (e.g. gnu or android)

<arg ...> is a list of arguments for the go tool."
`,
}

func runXGo(command *cmdline.Command, args []string) error {
	if len(args) < 2 {
		return command.UsageErrorf("not enough arguments")
	}
	platform, err := util.ParsePlatform(args[0])
	if err != nil {
		return err
	}
	return setupAndGo(platform, command, args[1:])
}

func setupAndGo(platform util.Platform, command *cmdline.Command, args []string) error {
	// First set up the environment for the host platform, and run vdl.
	if err := util.SetupVeyronEnvironment(util.HostPlatform()); err != nil {
		return err
	}
	switch args[0] {
	case "build", "install", "run", "test":
		if err := generateVDL(); err != nil {
			return err
		}
	}
	// Now set up the specified platform, and run go.
	if err := util.SetupVeyronEnvironment(platform); err != nil {
		return err
	}

	gocommand := "go"
	if goroot := os.Getenv("GOROOT"); goroot != "" {
		gocommand = filepath.Join(goroot, "bin", "go")
	}

	goCmd := exec.Command(gocommand, args...)
	goCmd.Stdout = command.Stdout()
	goCmd.Stderr = command.Stderr()
	return translateExitCode(goCmd.Run())
}

func generateVDL() error {
	if novdlFlag {
		return nil
	}
	root, err := util.VeyronRoot()
	if err != nil {
		return err
	}
	// Initialize args with the *.go files under the vdl directory to run.
	args := []string{"run"}
	vdlDir := filepath.Join(root, "veyron", "go", "src", "veyron.io", "veyron", "veyron2", "vdl", "vdl")
	fis, err := ioutil.ReadDir(vdlDir)
	if err != nil {
		return fmt.Errorf("ReadDir(%v) failed: %v", vdlDir, err)
	}
	for _, fi := range fis {
		if strings.HasSuffix(fi.Name(), ".go") {
			args = append(args, filepath.Join(vdlDir, fi.Name()))
		}
	}
	// TODO(toddw): We should probably only generate vdl for the packages
	// specified for the corresponding "go" command.  This isn't trivial; we'd
	// need to grab the transitive go dependencies for the specified packages, and
	// then look for transitive vdl dependencies based on that set.
	args = append(args, "generate", "-lang=go", "all")
	vdlCmd := exec.Command("go", args...)
	if out, err := vdlCmd.CombinedOutput(); err != nil {
		return fmt.Errorf("failed to generate vdl: %v\n%v\n%s", err, strings.Join(vdlCmd.Args, " "), out)
	}
	return nil
}

// cmdGoExt represents the 'goext' command of the veyron tool.
var cmdGoExt = &cmdline.Command{
	Name:     "goext",
	Short:    "Veyron extensions of the go tool",
	Long:     "Veyron extension of the go tool.",
	Children: []*cmdline.Command{cmdGoExtDistClean},
}

// cmdGoExtDistClean represents the 'distclean' sub-command of 'goext'
// command of the veyron tool.
var cmdGoExtDistClean = &cmdline.Command{
	Run:   runGoExtDistClean,
	Name:  "distclean",
	Short: "Restore the veyron Go repositories to their pristine state",
	Long: `
Unlike the 'go clean' command, which only removes object files for
packages in the source tree, the 'goext disclean' command removes all
object files from veyron Go workspaces. This functionality is needed
to avoid accidental use of stale object files that correspond to
packages that no longer exist in the source tree.
`,
}

func runGoExtDistClean(command *cmdline.Command, _ []string) error {
	if err := util.SetupVeyronEnvironment(util.HostPlatform()); err != nil {
		return err
	}
	goPath := os.Getenv("GOPATH")
	failed := false
	for _, workspace := range strings.Split(goPath, ":") {
		if workspace == "" {
			continue
		}
		for _, name := range []string{"bin", "pkg"} {
			dir := filepath.Join(workspace, name)
			// TODO(jsimsa): Use the new logging library
			// for this when it is checked in.
			fmt.Fprintf(command.Stdout(), "Removing %v\n", dir)
			if err := os.RemoveAll(dir); err != nil {
				failed = true
				fmt.Fprintf(command.Stderr(), "RemoveAll(%v) failed: %v", dir, err)
			}
		}
	}
	if failed {
		return cmdline.ErrExitCode(2)
	}
	return nil
}
<|endoftext|>


<commit_before>package adcom1

import "encoding/json"

// Geo object encapsulates various methods for specifying a geographic location.
// When subordinate to a Device object, it indicates the location of the device which can also be interpreted as the user's current location.
// When subordinate to a User object, it indicates the location of the user's home base (i.e., not necessarily their current location).
//
// The lat and lon attributes should only be passed if they conform to the accuracy depicted in the type attribute.
// For example, the centroid of a large region (e.g., postal code) should not be passed.
type Geo struct {
	// Attribute:
	//   type
	// Type:
	//   integer
	// Definition:
	//   Source of location data; recommended when passing lat/lon.
	//   Refer to List: Location Types.
	Type LocationType `json:"type,omitempty"`

	// Attribute:
	//   lat
	// Type:
	//   float
	// Definition:
	//   Latitude from -90.0 to +90.0, where negative is south.
	Lat float64 `json:"lat,omitempty"`

	// Attribute:
	//   lon
	// Type:
	//   float
	// Definition:
	//   Longitude from -180.0 to +180.0, where negative is west.
	Lon float64 `json:"lon,omitempty"`

	// Attribute:
	//   accur
	// Type:
	//   integer
	// Definition:
	//   Estimated location accuracy in meters; recommended when lat/lon are specified and derived from a device's location services (i.e., type = 1).
	//   Note that this is the accuracy as reported from the device.
	//   Consult OS specific documentation (e.g., Android, iOS) for exact interpretation.
	Accur int64 `json:"accur,omitempty"`

	// Attribute:
	//   lastfix
	// Type:
	//   integer
	// Definition:
	//   Number of seconds since this geolocation fix was established.
	//   Note that devices may cache location data across multiple fetches.
	//   Ideally, this value should be from the time the actual fix was taken.
	LastFix int64 `json:"lastfix,omitempty"`

	// Attribute:
	//   ipserv
	// Type:
	//   integer
	// Definition:
	//   Service or provider used to determine geolocation from IP address if applicable (i.e., type = 2).
	//   Refer to List: IP Location Services.
	IPServ IPLocationService `json:"ipserv,omitempty"`

	// Attribute:
	//   country
	// Type:
	//   string
	// Definition:
	//   Country code using ISO-3166-1-alpha-2.
	//   Note that alpha-3 codes may be encountered and vendors are encouraged to be tolerant of them.
	Country string `json:"country,omitempty"`

	// Attribute:
	//   region
	// Type:
	//   string
	// Definition:
	//   Region code using ISO-3166-2; 2-letter state code if USA.
	Region string `json:"region,omitempty"`

	// Attribute:
	//   metro
	// Type:
	//   string
	// Definition:
	//   Regional marketing areas such as Nielsen's DMA codes or other similar taxonomy to be agreed among vendors prior to use.
	//   Note that DMA is a trademarked asset of The Nielsen Company.
	//   Vendors are encouraged to ensure their use of DMAs is properly licensed.
	Metro string `json:"metro,omitempty"`

	// Attribute:
	//   city
	// Type:
	//   string
	// Definition:
	//   City using United Nations Code for Trade & Transport Locations “UN/LOCODE” with the space between country and city suppressed (e.g., Boston MA, USA = “USBOS”).
	//   Refer to UN/LOCODE Code List.
	City string `json:"city,omitempty"`

	// Attribute:
	//   zip
	// Type:
	//   string
	// Definition:
	//   ZIP or postal code.
	ZIP string `json:"zip,omitempty"`

	// Attribute:
	//   utcoffset
	// Type:
	//   integer
	// Definition:
	//   Local time as the number +/- of minutes from UTC.
	// Dev note:
	//   This field is kept as `int` to follow type choice for timezone offset in std. `time` package.
	UTCOffset int64 `json:"utcoffset,omitempty"`

	// Attribute:
	//   ext
	// Type:
	//   object
	// Definition:
	//   Optional vendor-specific extensions.
	Ext json.RawMessage `json:"ext,omitempty"`
}
<commit_msg>types: fix comments after mass-replace<commit_after>package adcom1

import "encoding/json"

// Geo object encapsulates various methods for specifying a geographic location.
// When subordinate to a Device object, it indicates the location of the device which can also be interpreted as the user's current location.
// When subordinate to a User object, it indicates the location of the user's home base (i.e., not necessarily their current location).
//
// The lat and lon attributes should only be passed if they conform to the accuracy depicted in the type attribute.
// For example, the centroid of a large region (e.g., postal code) should not be passed.
type Geo struct {
	// Attribute:
	//   type
	// Type:
	//   integer
	// Definition:
	//   Source of location data; recommended when passing lat/lon.
	//   Refer to List: Location Types.
	Type LocationType `json:"type,omitempty"`

	// Attribute:
	//   lat
	// Type:
	//   float
	// Definition:
	//   Latitude from -90.0 to +90.0, where negative is south.
	Lat float64 `json:"lat,omitempty"`

	// Attribute:
	//   lon
	// Type:
	//   float
	// Definition:
	//   Longitude from -180.0 to +180.0, where negative is west.
	Lon float64 `json:"lon,omitempty"`

	// Attribute:
	//   accur
	// Type:
	//   integer
	// Definition:
	//   Estimated location accuracy in meters; recommended when lat/lon are specified and derived from a device's location services (i.e., type = 1).
	//   Note that this is the accuracy as reported from the device.
	//   Consult OS specific documentation (e.g., Android, iOS) for exact interpretation.
	Accur int64 `json:"accur,omitempty"`

	// Attribute:
	//   lastfix
	// Type:
	//   integer
	// Definition:
	//   Number of seconds since this geolocation fix was established.
	//   Note that devices may cache location data across multiple fetches.
	//   Ideally, this value should be from the time the actual fix was taken.
	LastFix int64 `json:"lastfix,omitempty"`

	// Attribute:
	//   ipserv
	// Type:
	//   integer
	// Definition:
	//   Service or provider used to determine geolocation from IP address if applicable (i.e., type = 2).
	//   Refer to List: IP Location Services.
	IPServ IPLocationService `json:"ipserv,omitempty"`

	// Attribute:
	//   country
	// Type:
	//   string
	// Definition:
	//   Country code using ISO-3166-1-alpha-2.
	//   Note that alpha-3 codes may be encountered and vendors are encouraged to be tolerant of them.
	Country string `json:"country,omitempty"`

	// Attribute:
	//   region
	// Type:
	//   string
	// Definition:
	//   Region code using ISO-3166-2; 2-letter state code if USA.
	Region string `json:"region,omitempty"`

	// Attribute:
	//   metro
	// Type:
	//   string
	// Definition:
	//   Regional marketing areas such as Nielsen's DMA codes or other similar taxonomy to be agreed among vendors prior to use.
	//   Note that DMA is a trademarked asset of The Nielsen Company.
	//   Vendors are encouraged to ensure their use of DMAs is properly licensed.
	Metro string `json:"metro,omitempty"`

	// Attribute:
	//   city
	// Type:
	//   string
	// Definition:
	//   City using United Nations Code for Trade & Transport Locations “UN/LOCODE” with the space between country and city suppressed (e.g., Boston MA, USA = “USBOS”).
	//   Refer to UN/LOCODE Code List.
	City string `json:"city,omitempty"`

	// Attribute:
	//   zip
	// Type:
	//   string
	// Definition:
	//   ZIP or postal code.
	ZIP string `json:"zip,omitempty"`

	// Attribute:
	//   utcoffset
	// Type:
	//   integer
	// Definition:
	//   Local time as the number +/- of minutes from UTC.
	UTCOffset int64 `json:"utcoffset,omitempty"`

	// Attribute:
	//   ext
	// Type:
	//   object
	// Definition:
	//   Optional vendor-specific extensions.
	Ext json.RawMessage `json:"ext,omitempty"`
}
<|endoftext|>


<commit_before>// Copyright 2015 The Cockroach Authors.
//
// 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.
//
// Author: Tobias Schottdorf (tobias.schottdorf@gmail.com)

package tracing

import (
	"bytes"
	"encoding/gob"

	"golang.org/x/net/context"

	basictracer "github.com/opentracing/basictracer-go"
	opentracing "github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
)

// Snowball is set as Baggage on traces which are used for snowball tracing.
const Snowball = "sb"

// A CallbackRecorder immediately invokes itself on received trace spans.
type CallbackRecorder func(sp basictracer.RawSpan)

// RecordSpan implements basictracer.SpanRecorder.
func (cr CallbackRecorder) RecordSpan(sp basictracer.RawSpan) {
	cr(sp)
}

// JoinOrNew creates a new Span joined to the provided DelegatingCarrier or
// creates Span from the given tracer.
func JoinOrNew(tr opentracing.Tracer, carrier *Span, opName string) (opentracing.Span, error) {
	if carrier != nil {
		sp, err := tr.Join(opName, basictracer.Delegator, carrier)
		switch err {
		case nil:
			sp.LogEvent(opName)
			return sp, nil
		case opentracing.ErrTraceNotFound:
		default:
			return nil, err
		}
	}
	return tr.StartSpan(opName), nil
}

// JoinOrNewSnowball returns a Span which records directly via the specified
// callback. If the given DelegatingCarrier is nil, a new Span is created.
// otherwise, the created Span is a child.
func JoinOrNewSnowball(opName string, carrier *Span, callback func(sp basictracer.RawSpan)) (opentracing.Span, error) {
	tr := basictracer.NewWithOptions(defaultOptions(callback))
	sp, err := JoinOrNew(tr, carrier, opName)
	if err == nil {
		// We definitely want to sample a Snowball trace.
		// This must be set *before* SetBaggageItem, as that will otherwise be ignored.
		ext.SamplingPriority.Set(sp, 1)
		sp.SetBaggageItem(Snowball, "1")
	}
	return sp, err
}

func defaultOptions(recorder func(basictracer.RawSpan)) basictracer.Options {
	opts := basictracer.DefaultOptions()
	opts.ShouldSample = func(traceID int64) bool { return false }
	opts.TrimUnsampledSpans = true
	opts.Recorder = CallbackRecorder(recorder)
	opts.NewSpanEventListener = basictracer.NetTraceIntegrator
	opts.DebugAssertUseAfterFinish = true // provoke crash on use-after-Finish
	return opts
}

// newTracer implements NewTracer and allows that function to be mocked out via Disable().
var newTracer = func() opentracing.Tracer {
	return basictracer.NewWithOptions(defaultOptions(func(_ basictracer.RawSpan) {}))
}

// NewTracer creates a Tracer which records to the net/trace
// endpoint.
func NewTracer() opentracing.Tracer {
	return newTracer()
}

// SpanFromContext returns the Span obtained from the context or, if none is
// found, a new one started through the tracer. Callers should call (or defer)
// the returned cleanup func as well to ensure that the span is Finish()ed, but
// callers should *not* attempt to call Finish directly -- in the case where the
// span was obtained from the context, it is not the caller's to Finish.
func SpanFromContext(opName string, tracer opentracing.Tracer, ctx context.Context) (opentracing.Span, func()) {
	sp := opentracing.SpanFromContext(ctx)
	if sp == nil {
		sp = tracer.StartSpan(opName)
		return sp, sp.Finish
	}
	return sp, func() {}
}

// Disable is for benchmarking use and causes all future tracers to deal in
// no-ops. Calling the returned closure undoes this effect. There is no
// synchronization, so no moving parts are allowed while Disable and the
// closure are called.
func Disable() func() {
	orig := newTracer
	newTracer = func() opentracing.Tracer { return opentracing.NoopTracer{} }
	return func() {
		newTracer = orig
	}
}

// EncodeRawSpan encodes a raw span into bytes, using the given dest slice
// as a buffer.
func EncodeRawSpan(rawSpan *basictracer.RawSpan, dest []byte) ([]byte, error) {
	// This is not a greatly efficient (but convenient) use of gob.
	buf := bytes.NewBuffer(dest[:0])
	err := gob.NewEncoder(buf).Encode(rawSpan)
	return buf.Bytes(), err
}

// DecodeRawSpan unmarshals into the given RawSpan.
func DecodeRawSpan(enc []byte, dest *basictracer.RawSpan) error {
	return gob.NewDecoder(bytes.NewBuffer(enc)).Decode(dest)
}
<commit_msg>Add tracing.EnsureContext<commit_after>// Copyright 2015 The Cockroach Authors.
//
// 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.
//
// Author: Tobias Schottdorf (tobias.schottdorf@gmail.com)

package tracing

import (
	"bytes"
	"encoding/gob"

	"golang.org/x/net/context"

	"github.com/cockroachdb/cockroach/util/caller"
	basictracer "github.com/opentracing/basictracer-go"
	opentracing "github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
)

// Snowball is set as Baggage on traces which are used for snowball tracing.
const Snowball = "sb"

// A CallbackRecorder immediately invokes itself on received trace spans.
type CallbackRecorder func(sp basictracer.RawSpan)

// RecordSpan implements basictracer.SpanRecorder.
func (cr CallbackRecorder) RecordSpan(sp basictracer.RawSpan) {
	cr(sp)
}

// JoinOrNew creates a new Span joined to the provided DelegatingCarrier or
// creates Span from the given tracer.
func JoinOrNew(tr opentracing.Tracer, carrier *Span, opName string) (opentracing.Span, error) {
	if carrier != nil {
		sp, err := tr.Join(opName, basictracer.Delegator, carrier)
		switch err {
		case nil:
			sp.LogEvent(opName)
			return sp, nil
		case opentracing.ErrTraceNotFound:
		default:
			return nil, err
		}
	}
	return tr.StartSpan(opName), nil
}

// JoinOrNewSnowball returns a Span which records directly via the specified
// callback. If the given DelegatingCarrier is nil, a new Span is created.
// otherwise, the created Span is a child.
func JoinOrNewSnowball(opName string, carrier *Span, callback func(sp basictracer.RawSpan)) (opentracing.Span, error) {
	tr := basictracer.NewWithOptions(defaultOptions(callback))
	sp, err := JoinOrNew(tr, carrier, opName)
	if err == nil {
		// We definitely want to sample a Snowball trace.
		// This must be set *before* SetBaggageItem, as that will otherwise be ignored.
		ext.SamplingPriority.Set(sp, 1)
		sp.SetBaggageItem(Snowball, "1")
	}
	return sp, err
}

func defaultOptions(recorder func(basictracer.RawSpan)) basictracer.Options {
	opts := basictracer.DefaultOptions()
	opts.ShouldSample = func(traceID int64) bool { return false }
	opts.TrimUnsampledSpans = true
	opts.Recorder = CallbackRecorder(recorder)
	opts.NewSpanEventListener = basictracer.NetTraceIntegrator
	opts.DebugAssertUseAfterFinish = true // provoke crash on use-after-Finish
	return opts
}

// newTracer implements NewTracer and allows that function to be mocked out via Disable().
var newTracer = func() opentracing.Tracer {
	return basictracer.NewWithOptions(defaultOptions(func(_ basictracer.RawSpan) {}))
}

// NewTracer creates a Tracer which records to the net/trace
// endpoint.
func NewTracer() opentracing.Tracer {
	return newTracer()
}

// EnsureContext checks whether the given context.Context contains a Span. If
// not, it creates one using the provided Tracer and wraps it in the returned
// Span. The returned closure must be called after the request has been fully
// processed.
func EnsureContext(ctx context.Context, tracer opentracing.Tracer) (context.Context, func()) {
	_, _, funcName := caller.Lookup(1)
	if opentracing.SpanFromContext(ctx) == nil {
		sp := tracer.StartSpan(funcName)
		return opentracing.ContextWithSpan(ctx, sp), sp.Finish
	}
	return ctx, func() {}
}

// SpanFromContext returns the Span obtained from the context or, if none is
// found, a new one started through the tracer. Callers should call (or defer)
// the returned cleanup func as well to ensure that the span is Finish()ed, but
// callers should *not* attempt to call Finish directly -- in the case where the
// span was obtained from the context, it is not the caller's to Finish.
func SpanFromContext(opName string, tracer opentracing.Tracer, ctx context.Context) (opentracing.Span, func()) {
	sp := opentracing.SpanFromContext(ctx)
	if sp == nil {
		sp = tracer.StartSpan(opName)
		return sp, sp.Finish
	}
	return sp, func() {}
}

// Disable is for benchmarking use and causes all future tracers to deal in
// no-ops. Calling the returned closure undoes this effect. There is no
// synchronization, so no moving parts are allowed while Disable and the
// closure are called.
func Disable() func() {
	orig := newTracer
	newTracer = func() opentracing.Tracer { return opentracing.NoopTracer{} }
	return func() {
		newTracer = orig
	}
}

// EncodeRawSpan encodes a raw span into bytes, using the given dest slice
// as a buffer.
func EncodeRawSpan(rawSpan *basictracer.RawSpan, dest []byte) ([]byte, error) {
	// This is not a greatly efficient (but convenient) use of gob.
	buf := bytes.NewBuffer(dest[:0])
	err := gob.NewEncoder(buf).Encode(rawSpan)
	return buf.Bytes(), err
}

// DecodeRawSpan unmarshals into the given RawSpan.
func DecodeRawSpan(enc []byte, dest *basictracer.RawSpan) error {
	return gob.NewDecoder(bytes.NewBuffer(enc)).Decode(dest)
}
<|endoftext|>


<commit_before>package check

import (
	"appengine"
	"encoding/json"
	"errors"
	"net/http"
	"strings"
	"techtraits.com/graphite"
	"techtraits.com/klaxon/rest/alert"
	"techtraits.com/klaxon/rest/project"
	"techtraits.com/klaxon/router"
	"techtraits.com/log"
)

func init() {
	router.Register("/rest/internal/check/{project_id}", router.POST, nil, nil, checkProject)
}

func checkProject(request router.Request) (int, []byte) {

	//Check that Project exists
	projectDto, err := project.GetProjectDTOFromGAE(request.GetPathParams()["project_id"], request.GetContext())

	//TODO: Check if project is enabled
	if err != nil && strings.Contains(err.Error(), "no such entity") {
		log.Errorf(request.GetContext(), "Error retriving project: %v", err)
		return http.StatusNotFound, []byte(err.Error())
	} else if err != nil {
		log.Errorf(request.GetContext(), "Error retriving project: %v", err)
		return http.StatusInternalServerError, []byte(err.Error())
	} else {
		projectObj, err := projectDto.GetProject()
		status, err := verifyProject(projectObj, err, request.GetContext())
		if err == nil {
			return processAlerts(projectObj, request.GetContext())
		} else {
			return status, []byte(err.Error())
		}
	}

}

func verifyProject(projectObj project.Project, err error, context appengine.Context) (int, error) {
	if err != nil {
		log.Warnf(context, "Error polling graphite %v ", err.Error())
		return http.StatusInternalServerError, err
	} else if projectObj.GetConfig()["graphite.baseurl"] == "" {
		log.Warnf(context, "Error polling graphite, property graphite.base missing for project ")
		return http.StatusInternalServerError, errors.New("Property graphite.base missing for project")
	} else if projectObj.GetConfig()["graphite.lookback"] == "" {
		log.Warnf(context, "Error polling graphite, property graphite.lookback missing for project ")
		return http.StatusInternalServerError, errors.New("Property graphite.lookback missing for project")
	} else {
		return 0, nil
	}
}

func processAlerts(projectObj project.Project, context appengine.Context) (int, []byte) {

	//Get Alerts for Project
	alerts, err := alert.GetAlertsFromGAE(projectObj.GetName(), context)
	if err != nil {
		log.Errorf(context, "Error retriving alerts: %v", err)
		return http.StatusInternalServerError, []byte(err.Error())
	} else {
		alertChecks := make([]alert.Check, 0)
		graphiteReader, _ := graphite.MakeGraphiteReader(projectObj.GetConfig()["graphite.baseurl"],
			projectObj.GetConfig()["graphite.lookback"], context)

		for _, projectAlert := range alerts {
			alertCheck := processAlert(projectAlert, context, graphiteReader, alertChecks)
			alertChecks = append(alertChecks, alertCheck)
		}

		alertBytes, err := json.MarshalIndent(alertChecks, "", "	")

		if err != nil {
			log.Errorf(context, "Error marshalling response %v", err)
			return http.StatusInternalServerError, []byte(err.Error())
		}
		return http.StatusOK, alertBytes
	}
}

func processAlert(projectAlert alert.Alert, context appengine.Context,
	graphiteReader graphite.GraphiteReader, alertChecks []alert.Check) alert.Check {

	value, err := graphiteReader.ReadValue(projectAlert.Target)
	if err != nil {
		log.Errorf(context, "Error processing Alert: %v", err)
		saveChangeIfNeeded(projectAlert, projectAlert.PreviousState != alert.UNKNOWN, alert.UNKNOWN, context)
		return alert.Check{projectAlert.Project, projectAlert.Name, projectAlert.PreviousState,
			alert.UNKNOWN, projectAlert.PreviousState != alert.UNKNOWN, 0}

	} else {
		changed, previous, current := projectAlert.CheckAlertStatusChange(value)
		saveChangeIfNeeded(projectAlert, changed, current, context)
		return alert.Check{projectAlert.Project, projectAlert.Name, previous, current, changed, value}
	}
}

func saveChangeIfNeeded(projectAlert alert.Alert, changed bool, current alert.ALERT_STATE, context appengine.Context) {
	if changed {
		projectAlert.PreviousState = current
		alert.SaveAlertToGAE(projectAlert, context)
	}
}
<commit_msg>Sending email when alert is triggered using subscriptions, first implementation<commit_after>package check

import (
	"appengine"
	"appengine/mail"
	"encoding/json"
	"errors"
	"net/http"
	"strings"
	"techtraits.com/graphite"
	"techtraits.com/klaxon/rest/alert"
	"techtraits.com/klaxon/rest/project"
	"techtraits.com/klaxon/rest/subscription"
	"techtraits.com/klaxon/router"
	"techtraits.com/log"
)

func init() {
	router.Register("/rest/internal/check/{project_id}", router.POST, nil, nil, checkProject)
}

//TODO: Check if project is enabled
func checkProject(request router.Request) (int, []byte) {

	//Get The project
	projectId := request.GetPathParams()["project_id"]
	projectObj, getProjectStatus, getProjectError := getProject(projectId, request.GetContext())
	//Get Alerts
	alerts, getAlertStatus, getAlertsError := getAlerts(projectId, request.GetContext())
	//Get Subscriptions
	subscriptions, getSubsStatus, getSubsError := getSubscriptions(projectId, request.GetContext())

	if getProjectError == nil && getAlertsError == nil && getSubsError == nil {
		//Check Alerts
		return processAlerts(projectObj, alerts, subscriptions, request.GetContext())
	} else {
		return processError(getProjectStatus, getAlertStatus, getSubsStatus,
			getProjectError, getAlertsError, getSubsError)
	}

}

func getProject(projectId string, context appengine.Context) (project.Project, int, error) {
	projectDto, err := project.GetProjectDTOFromGAE(projectId, context)
	if err != nil && strings.Contains(err.Error(), "no such entity") {
		log.Errorf(context, "Error retriving project: %v", err)
		return nil, http.StatusNotFound, err
	} else if err != nil {
		log.Errorf(context, "Error retriving project: %v", err)
		return nil, http.StatusInternalServerError, err
	} else {
		projectObj, err := projectDto.GetProject()
		status, err := verifyProject(projectObj, err, context)
		if err != nil {
			return nil, status, err
		} else {
			return projectObj, 0, nil
		}
	}
}

func verifyProject(projectObj project.Project, err error, context appengine.Context) (int, error) {
	if err != nil {
		log.Warnf(context, "Error polling graphite %v ", err.Error())
		return http.StatusInternalServerError, err
	} else if projectObj.GetConfig()["graphite.baseurl"] == "" {
		log.Warnf(context, "Error polling graphite, property graphite.base missing for project ")
		return http.StatusInternalServerError, errors.New("Property graphite.base missing for project")
	} else if projectObj.GetConfig()["graphite.lookback"] == "" {
		log.Warnf(context, "Error polling graphite, property graphite.lookback missing for project ")
		return http.StatusInternalServerError, errors.New("Property graphite.lookback missing for project")
	} else {
		return 0, nil
	}
}

func getAlerts(projectId string, context appengine.Context) ([]alert.Alert, int, error) {
	//Get Alerts for Project
	alerts, err := alert.GetAlertsFromGAE(projectId, context)
	if err != nil {
		log.Errorf(context, "Error retriving alerts: %v", err)
		return nil, http.StatusInternalServerError, err
	} else {
		return alerts, http.StatusOK, nil
	}
}

func getSubscriptions(projectId string, context appengine.Context) ([]subscription.Subscription, int, error) {
	//Get Subscriptions for Project
	subscriptions, err := subscription.GetSubscriptionsFromGAE(projectId, context)
	if err != nil {
		log.Errorf(context, "Error retriving subscriptions: %v", err)
		return nil, http.StatusInternalServerError, err
	} else {
		return subscriptions, http.StatusOK, nil
	}
}

func processAlerts(projectObj project.Project, alerts []alert.Alert,
	subscriptions []subscription.Subscription, context appengine.Context) (int, []byte) {

	graphiteReader, _ := graphite.MakeGraphiteReader(projectObj.GetConfig()["graphite.baseurl"],
		projectObj.GetConfig()["graphite.lookback"], context)

	alertChecks := make([]alert.Check, 0)

	for _, projectAlert := range alerts {
		//TODO Make this in to a go routine
		alertCheck := processAlert(projectAlert, context, graphiteReader, subscriptions, alertChecks)
		alertChecks = append(alertChecks, alertCheck)
	}

	alertBytes, err := json.MarshalIndent(alertChecks, "", "	")

	if err != nil {
		log.Errorf(context, "Error marshalling response %v", err)
		return http.StatusInternalServerError, []byte(err.Error())
	} else {
		return http.StatusOK, alertBytes
	}

}

func processAlert(projectAlert alert.Alert, context appengine.Context,
	graphiteReader graphite.GraphiteReader, subscriptions []subscription.Subscription,
	alertChecks []alert.Check) alert.Check {

	value, err := graphiteReader.ReadValue(projectAlert.Target)
	if err != nil {
		log.Errorf(context, "Error processing Alert: %v", err)
		saveChangeIfNeeded(projectAlert, projectAlert.PreviousState != alert.UNKNOWN, alert.UNKNOWN, context)
		return alert.Check{projectAlert.Project, projectAlert.Name, projectAlert.PreviousState,
			alert.UNKNOWN, projectAlert.PreviousState != alert.UNKNOWN, 0}

	} else {
		changed, previous, current := projectAlert.CheckAlertStatusChange(value)
		saveChangeIfNeeded(projectAlert, changed, current, context)
		check := alert.Check{projectAlert.Project, projectAlert.Name, previous, current, changed, value}
		triggerSubscriptionsIfNeeded(check, subscriptions, context)
		return check
	}
}

func saveChangeIfNeeded(projectAlert alert.Alert, changed bool, current alert.ALERT_STATE, context appengine.Context) {
	if changed {
		projectAlert.PreviousState = current
		alert.SaveAlertToGAE(projectAlert, context)
	}
}

func triggerSubscriptionsIfNeeded(check alert.Check, subscriptions []subscription.Subscription,
	context appengine.Context) {
	for _, subscription := range subscriptions {
		log.Infof(context, "Firing Subscrption for check %v", subscription, check)

		//url := createConfirmationURL(r)
		msg := &mail.Message{
			Sender:  "Klaxon <0xfffffff@gmail.com>",
			To:      []string{subscription.Target},
			Subject: "Alert Triggered",
			Body:    "Alert Triggered",
		}
		if err := mail.Send(context, msg); err != nil {
			log.Errorf(context, "Couldn't send email: %v", err)
		}

	}
}

func processError(getProjectStatus int, getAlertStatus int, getSubsStatus int,
	getProjectError error, getAlertsError error, getSubsError error) (int, []byte) {

	if getProjectError != nil {
		return getProjectStatus, []byte(getProjectError.Error())
	} else if getAlertsError != nil {
		return getAlertStatus, []byte(getAlertsError.Error())
	} else if getSubsError != nil {
		return getSubsStatus, []byte(getSubsError.Error())
	} else {
		return http.StatusInternalServerError, []byte("Unknown server error")
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime

import (
	"runtime/internal/sys"
	"unsafe"
)

func dumpregs(c *sigctxt) {
	print("r1      ", hex(c.r1()), "\n")
	print("r2      ", hex(c.r2()), "\n")
	print("r3      ", hex(c.r3()), "\n")
	print("r4      ", hex(c.r4()), "\n")
	print("r5      ", hex(c.r5()), "\n")
	print("r6      ", hex(c.r6()), "\n")
	print("r7      ", hex(c.r7()), "\n")
	print("r8      ", hex(c.r8()), "\n")
	print("r9      ", hex(c.r9()), "\n")
	print("r10     ", hex(c.r10()), "\n")
	print("r11     ", hex(c.r11()), "\n")
	print("r12     ", hex(c.r12()), "\n")
	print("r13     ", hex(c.r13()), "\n")
	print("r16     ", hex(c.r16()), "\n")
	print("r17     ", hex(c.r17()), "\n")
	print("r18     ", hex(c.r18()), "\n")
	print("r19     ", hex(c.r19()), "\n")
	print("r20     ", hex(c.r20()), "\n")
	print("r21     ", hex(c.r21()), "\n")
	print("r22     ", hex(c.r22()), "\n")
	print("r23     ", hex(c.r23()), "\n")
	print("r24     ", hex(c.r24()), "\n")
	print("r25     ", hex(c.r25()), "\n")
	print("r26     ", hex(c.r26()), "\n")
	print("r27     ", hex(c.r27()), "\n")
	print("r28     ", hex(c.r28()), "\n")
	print("r29     ", hex(c.r29()), "\n")
	print("r31     ", hex(c.r31()), "\n")
	print("lr      ", hex(c.lr()), "\n")
	print("sp      ", hex(c.sp()), "\n")
	print("fp      ", hex(c.fp()), "\n")
	print("pc      ", hex(c.pc()), "\n")
	print("npc     ", hex(c.npc()), "\n")
	print("fault   ", hex(c.fault()), "\n")
}

var crashing int32

// May run during STW, so write barriers are not allowed.
//
//go:nowritebarrierrec
func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
	_g_ := getg()
	c := &sigctxt{info, ctxt}

	if sig == _SIGPROF {
		sigprof(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.lr()), gp, _g_.m)
		return
	}

	flags := int32(_SigThrow)
	if sig < uint32(len(sigtable)) {
		flags = sigtable[sig].flags
	}
	if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
		// Make it look like a call to the signal func.
		// Have to pass arguments out of band since
		// augmenting the stack frame would break
		// the unwinding code.
		gp.sig = sig
		gp.sigcode0 = uintptr(c.sigcode())
		gp.sigcode1 = uintptr(c.fault())
		gp.sigpc = uintptr(c.pc())

		// We arrange lr, and pc to pretend the panicking
		// function calls sigpanic directly.
		// Always save LR to stack so that panics in leaf
		// functions are correctly handled. This smashes
		// the stack frame but we're not going back there
		// anyway.
		fp := c.sp()
		sp := c.sp() - (sys.SpAlign + sys.MinFrameSize) // needs only sizeof uint64, but must align the stack
		c.set_sp(sp)
		c.set_fp(fp)
		*(*uint64)(unsafe.Pointer(uintptr(sp + 120))) = c.lr()

		pc := uintptr(gp.sigpc)

		// If we don't recognize the PC as code
		// but we do recognize the link register as code,
		// then assume this was a call to non-code and treat like
		// pc == 0, to make unwinding show the context.
		if pc != 0 && findfunc(pc) == nil && findfunc(uintptr(c.lr())) != nil {
			pc = 0
		}

		// Don't bother saving PC if it's zero, which is
		// probably a call to a nil func: the old link register
		// is more useful in the stack trace.
		if pc != 0 {
			c.set_lr(uint64(pc))
		}

		// In case we are panicking from external C code
		c.set_r3(uint64(uintptr(unsafe.Pointer(gp))))
		c.set_npc(uint64(funcPC(sigpanic)))
		c.set_pc(uint64(funcPC(sigpanic)))
		return
	}

	if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
		if sigsend(sig) {
			return
		}
	}

	if c.sigcode() == _SI_USER && signal_ignored(sig) {
		return
	}

	if flags&_SigKill != 0 {
		dieFromSignal(int32(sig))
	}

	if flags&_SigThrow == 0 {
		return
	}

	_g_.m.throwing = 1
	_g_.m.caughtsig.set(gp)

	if crashing == 0 {
		startpanic()
	}

	if sig < uint32(len(sigtable)) {
		print(sigtable[sig].name, "\n")
	} else {
		print("Signal ", sig, "\n")
	}

	print("PC=", hex(c.pc()), " m=", _g_.m.id, "\n")
	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
		print("signal arrived during cgo execution\n")
		gp = _g_.m.lockedg
	}
	print("\n")

	level, _, docrash := gotraceback()
	if level > 0 {
		goroutineheader(gp)
		tracebacktrap(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.lr()), gp)
		if crashing > 0 && gp != _g_.m.curg && _g_.m.curg != nil && readgstatus(_g_.m.curg)&^_Gscan == _Grunning {
			// tracebackothers on original m skipped this one; trace it now.
			goroutineheader(_g_.m.curg)
			traceback(^uintptr(0), ^uintptr(0), 0, gp)
		} else if crashing == 0 {
			tracebackothers(gp)
			print("\n")
		}
		dumpregs(c)
	}

	if docrash {
		crashing++
		if crashing < sched.mcount {
			// There are other m's that need to dump their stacks.
			// Relay SIGQUIT to the next m by sending it to the current process.
			// All m's that have already received SIGQUIT have signal masks blocking
			// receipt of any signals, so the SIGQUIT will go to an m that hasn't seen it yet.
			// When the last m receives the SIGQUIT, it will fall through to the call to
			// crash below. Just in case the relaying gets botched, each m involved in
			// the relay sleeps for 5 seconds and then does the crash/exit itself.
			// In expected operation, the last m has received the SIGQUIT and run
			// crash/exit and the process is gone, all long before any of the
			// 5-second sleeps have finished.
			print("\n-----\n\n")
			raiseproc(_SIGQUIT)
			usleep(5 * 1000 * 1000)
		}
		crash()
	}

	exit(2)
}
<commit_msg>runtime: fix size of sigpanic frame<commit_after>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime

import (
	"runtime/internal/sys"
	"unsafe"
)

func dumpregs(c *sigctxt) {
	print("r1      ", hex(c.r1()), "\n")
	print("r2      ", hex(c.r2()), "\n")
	print("r3      ", hex(c.r3()), "\n")
	print("r4      ", hex(c.r4()), "\n")
	print("r5      ", hex(c.r5()), "\n")
	print("r6      ", hex(c.r6()), "\n")
	print("r7      ", hex(c.r7()), "\n")
	print("r8      ", hex(c.r8()), "\n")
	print("r9      ", hex(c.r9()), "\n")
	print("r10     ", hex(c.r10()), "\n")
	print("r11     ", hex(c.r11()), "\n")
	print("r12     ", hex(c.r12()), "\n")
	print("r13     ", hex(c.r13()), "\n")
	print("r16     ", hex(c.r16()), "\n")
	print("r17     ", hex(c.r17()), "\n")
	print("r18     ", hex(c.r18()), "\n")
	print("r19     ", hex(c.r19()), "\n")
	print("r20     ", hex(c.r20()), "\n")
	print("r21     ", hex(c.r21()), "\n")
	print("r22     ", hex(c.r22()), "\n")
	print("r23     ", hex(c.r23()), "\n")
	print("r24     ", hex(c.r24()), "\n")
	print("r25     ", hex(c.r25()), "\n")
	print("r26     ", hex(c.r26()), "\n")
	print("r27     ", hex(c.r27()), "\n")
	print("r28     ", hex(c.r28()), "\n")
	print("r29     ", hex(c.r29()), "\n")
	print("r31     ", hex(c.r31()), "\n")
	print("lr      ", hex(c.lr()), "\n")
	print("sp      ", hex(c.sp()), "\n")
	print("fp      ", hex(c.fp()), "\n")
	print("pc      ", hex(c.pc()), "\n")
	print("npc     ", hex(c.npc()), "\n")
	print("fault   ", hex(c.fault()), "\n")
}

var crashing int32

// May run during STW, so write barriers are not allowed.
//
//go:nowritebarrierrec
func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
	_g_ := getg()
	c := &sigctxt{info, ctxt}

	if sig == _SIGPROF {
		sigprof(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.lr()), gp, _g_.m)
		return
	}

	flags := int32(_SigThrow)
	if sig < uint32(len(sigtable)) {
		flags = sigtable[sig].flags
	}
	if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
		// Make it look like a call to the signal func.
		// Have to pass arguments out of band since
		// augmenting the stack frame would break
		// the unwinding code.
		gp.sig = sig
		gp.sigcode0 = uintptr(c.sigcode())
		gp.sigcode1 = uintptr(c.fault())
		gp.sigpc = uintptr(c.pc())

		// We arrange lr, and pc to pretend the panicking
		// function calls sigpanic directly.
		// Always save LR to stack so that panics in leaf
		// functions are correctly handled. This smashes
		// the stack frame but we're not going back there
		// anyway.
		fp := c.sp()
		sp := c.sp() - sys.MinFrameSize
		c.set_sp(sp)
		c.set_fp(fp)
		*(*uint64)(unsafe.Pointer(uintptr(sp + 120))) = c.lr()

		pc := uintptr(gp.sigpc)

		// If we don't recognize the PC as code
		// but we do recognize the link register as code,
		// then assume this was a call to non-code and treat like
		// pc == 0, to make unwinding show the context.
		if pc != 0 && findfunc(pc) == nil && findfunc(uintptr(c.lr())) != nil {
			pc = 0
		}

		// Don't bother saving PC if it's zero, which is
		// probably a call to a nil func: the old link register
		// is more useful in the stack trace.
		if pc != 0 {
			c.set_lr(uint64(pc))
		}

		// In case we are panicking from external C code
		c.set_r3(uint64(uintptr(unsafe.Pointer(gp))))
		c.set_npc(uint64(funcPC(sigpanic)))
		c.set_pc(uint64(funcPC(sigpanic)))
		return
	}

	if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
		if sigsend(sig) {
			return
		}
	}

	if c.sigcode() == _SI_USER && signal_ignored(sig) {
		return
	}

	if flags&_SigKill != 0 {
		dieFromSignal(int32(sig))
	}

	if flags&_SigThrow == 0 {
		return
	}

	_g_.m.throwing = 1
	_g_.m.caughtsig.set(gp)

	if crashing == 0 {
		startpanic()
	}

	if sig < uint32(len(sigtable)) {
		print(sigtable[sig].name, "\n")
	} else {
		print("Signal ", sig, "\n")
	}

	print("PC=", hex(c.pc()), " m=", _g_.m.id, "\n")
	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
		print("signal arrived during cgo execution\n")
		gp = _g_.m.lockedg
	}
	print("\n")

	level, _, docrash := gotraceback()
	if level > 0 {
		goroutineheader(gp)
		tracebacktrap(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.lr()), gp)
		if crashing > 0 && gp != _g_.m.curg && _g_.m.curg != nil && readgstatus(_g_.m.curg)&^_Gscan == _Grunning {
			// tracebackothers on original m skipped this one; trace it now.
			goroutineheader(_g_.m.curg)
			traceback(^uintptr(0), ^uintptr(0), 0, gp)
		} else if crashing == 0 {
			tracebackothers(gp)
			print("\n")
		}
		dumpregs(c)
	}

	if docrash {
		crashing++
		if crashing < sched.mcount {
			// There are other m's that need to dump their stacks.
			// Relay SIGQUIT to the next m by sending it to the current process.
			// All m's that have already received SIGQUIT have signal masks blocking
			// receipt of any signals, so the SIGQUIT will go to an m that hasn't seen it yet.
			// When the last m receives the SIGQUIT, it will fall through to the call to
			// crash below. Just in case the relaying gets botched, each m involved in
			// the relay sleeps for 5 seconds and then does the crash/exit itself.
			// In expected operation, the last m has received the SIGQUIT and run
			// crash/exit and the process is gone, all long before any of the
			// 5-second sleeps have finished.
			print("\n-----\n\n")
			raiseproc(_SIGQUIT)
			usleep(5 * 1000 * 1000)
		}
		crash()
	}

	exit(2)
}
<|endoftext|>


<commit_before>package api

import (
	"cf"
	"cf/configuration"
	"cf/net"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
	testapi "testhelpers/api"
	testnet "testhelpers/net"
	"testing"
)

func TestCreateServiceBinding(t *testing.T) {
	req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{
		Method:   "POST",
		Path:     "/v2/service_bindings",
		Matcher:  testnet.RequestBodyMatcher(`{"app_guid":"my-app-guid","service_instance_guid":"my-service-instance-guid"}`),
		Response: testnet.TestResponse{Status: http.StatusCreated},
	})

	ts, handler, repo := createServiceBindingRepo(t, req)
	defer ts.Close()

	apiResponse := repo.Create("my-service-instance-guid", "my-app-guid")
	assert.True(t, handler.AllRequestsCalled())
	assert.False(t, apiResponse.IsNotSuccessful())
}

func TestCreateServiceBindingIfError(t *testing.T) {
	req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{
		Method:  "POST",
		Path:    "/v2/service_bindings",
		Matcher: testnet.RequestBodyMatcher(`{"app_guid":"my-app-guid","service_instance_guid":"my-service-instance-guid"}`),
		Response: testnet.TestResponse{
			Status: http.StatusBadRequest,
			Body:   `{"code":90003,"description":"The app space binding to service is taken: 7b959018-110a-4913-ac0a-d663e613cdea 346bf237-7eef-41a7-b892-68fb08068f09"}`,
		},
	})

	ts, handler, repo := createServiceBindingRepo(t, req)
	defer ts.Close()

	apiResponse := repo.Create("my-service-instance-guid", "my-app-guid")

	assert.True(t, handler.AllRequestsCalled())
	assert.True(t, apiResponse.IsNotSuccessful())
	assert.Equal(t, apiResponse.ErrorCode, "90003")
}

var deleteBindingReq = testapi.NewCloudControllerTestRequest(testnet.TestRequest{
	Method:   "DELETE",
	Path:     "/v2/service_bindings/service-binding-2-guid",
	Response: testnet.TestResponse{Status: http.StatusOK},
})

func TestDeleteServiceBinding(t *testing.T) {
	ts, handler, repo := createServiceBindingRepo(t, deleteBindingReq)
	defer ts.Close()

	serviceInstance := cf.ServiceInstance{}
	serviceInstance.Guid = "my-service-instance-guid"

	binding := cf.ServiceBindingFields{}
	binding.Url = "/v2/service_bindings/service-binding-1-guid"
	binding.AppGuid = "app-1-guid"
	binding2 := cf.ServiceBindingFields{}
	binding2.Url = "/v2/service_bindings/service-binding-2-guid"
	binding2.AppGuid = "app-2-guid"
	serviceInstance.ServiceBindings = []cf.ServiceBindingFields{binding, binding2}

	found, apiResponse := repo.Delete(serviceInstance, "app-2-guid")

	assert.True(t, handler.AllRequestsCalled())
	assert.False(t, apiResponse.IsNotSuccessful())
	assert.True(t, found)
}

func TestDeleteServiceBindingWhenBindingDoesNotExist(t *testing.T) {
	ts, handler, repo := createServiceBindingRepo(t, deleteBindingReq)
	defer ts.Close()

	serviceInstance := cf.ServiceInstance{}
	serviceInstance.Guid = "my-service-instance-guid"

	found, apiResponse := repo.Delete(serviceInstance, "app-2-guid")

	assert.False(t, handler.AllRequestsCalled())
	assert.False(t, apiResponse.IsNotSuccessful())
	assert.False(t, found)
}

func createServiceBindingRepo(t *testing.T, req testnet.TestRequest) (ts *httptest.Server, handler *testnet.TestHandler, repo ServiceBindingRepository) {
	ts, handler = testnet.NewTLSServer(t, []testnet.TestRequest{req})
	space := cf.SpaceFields{}
	space.Guid = "my-space-guid"
	config := &configuration.Configuration{
		AccessToken: "BEARER my_access_token",
		SpaceFields: space,
		Target:      ts.URL,
	}

	gateway := net.NewCloudControllerGateway()
	repo = NewCloudControllerServiceBindingRepository(config, gateway)
	return
}
<commit_msg>Remove warning in test about requests not being called<commit_after>package api

import (
	"cf"
	"cf/configuration"
	"cf/net"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
	testapi "testhelpers/api"
	testnet "testhelpers/net"
	"testing"
)

func TestCreateServiceBinding(t *testing.T) {
	req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{
		Method:   "POST",
		Path:     "/v2/service_bindings",
		Matcher:  testnet.RequestBodyMatcher(`{"app_guid":"my-app-guid","service_instance_guid":"my-service-instance-guid"}`),
		Response: testnet.TestResponse{Status: http.StatusCreated},
	})

	ts, handler, repo := createServiceBindingRepo(t, []testnet.TestRequest{req})
	defer ts.Close()

	apiResponse := repo.Create("my-service-instance-guid", "my-app-guid")
	assert.True(t, handler.AllRequestsCalled())
	assert.False(t, apiResponse.IsNotSuccessful())
}

func TestCreateServiceBindingIfError(t *testing.T) {
	req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{
		Method:  "POST",
		Path:    "/v2/service_bindings",
		Matcher: testnet.RequestBodyMatcher(`{"app_guid":"my-app-guid","service_instance_guid":"my-service-instance-guid"}`),
		Response: testnet.TestResponse{
			Status: http.StatusBadRequest,
			Body:   `{"code":90003,"description":"The app space binding to service is taken: 7b959018-110a-4913-ac0a-d663e613cdea 346bf237-7eef-41a7-b892-68fb08068f09"}`,
		},
	})

	ts, handler, repo := createServiceBindingRepo(t, []testnet.TestRequest{req})
	defer ts.Close()

	apiResponse := repo.Create("my-service-instance-guid", "my-app-guid")

	assert.True(t, handler.AllRequestsCalled())
	assert.True(t, apiResponse.IsNotSuccessful())
	assert.Equal(t, apiResponse.ErrorCode, "90003")
}

var deleteBindingReq = testapi.NewCloudControllerTestRequest(testnet.TestRequest{
	Method:   "DELETE",
	Path:     "/v2/service_bindings/service-binding-2-guid",
	Response: testnet.TestResponse{Status: http.StatusOK},
})

func TestDeleteServiceBinding(t *testing.T) {
	ts, handler, repo := createServiceBindingRepo(t, []testnet.TestRequest{deleteBindingReq})
	defer ts.Close()

	serviceInstance := cf.ServiceInstance{}
	serviceInstance.Guid = "my-service-instance-guid"

	binding := cf.ServiceBindingFields{}
	binding.Url = "/v2/service_bindings/service-binding-1-guid"
	binding.AppGuid = "app-1-guid"
	binding2 := cf.ServiceBindingFields{}
	binding2.Url = "/v2/service_bindings/service-binding-2-guid"
	binding2.AppGuid = "app-2-guid"
	serviceInstance.ServiceBindings = []cf.ServiceBindingFields{binding, binding2}

	found, apiResponse := repo.Delete(serviceInstance, "app-2-guid")

	assert.True(t, handler.AllRequestsCalled())
	assert.False(t, apiResponse.IsNotSuccessful())
	assert.True(t, found)
}

func TestDeleteServiceBindingWhenBindingDoesNotExist(t *testing.T) {
	ts, handler, repo := createServiceBindingRepo(t, []testnet.TestRequest{})
	defer ts.Close()

	serviceInstance := cf.ServiceInstance{}
	serviceInstance.Guid = "my-service-instance-guid"

	found, apiResponse := repo.Delete(serviceInstance, "app-2-guid")

	assert.Equal(t, handler.CallCount, 0)
	assert.False(t, apiResponse.IsNotSuccessful())
	assert.False(t, found)
}

func createServiceBindingRepo(t *testing.T, requests []testnet.TestRequest) (ts *httptest.Server, handler *testnet.TestHandler, repo ServiceBindingRepository) {
	ts, handler = testnet.NewTLSServer(t, requests)
	space := cf.SpaceFields{}
	space.Guid = "my-space-guid"
	config := &configuration.Configuration{
		AccessToken: "BEARER my_access_token",
		SpaceFields: space,
		Target:      ts.URL,
	}

	gateway := net.NewCloudControllerGateway()
	repo = NewCloudControllerServiceBindingRepository(config, gateway)
	return
}
<|endoftext|>


<commit_before>package repository

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"path/filepath"

	"github.com/agl/ed25519"

	. "gopkg.in/check.v1"
)

type NIBStoreTest struct {
	dir                string
	repository         *Repository
	nibStore           *NIBStore
	storage            ContentStorage
	transactionManager *TransactionManager
}

var _ = Suite(&NIBStoreTest{})

func (t *NIBStoreTest) SetUpTest(c *C) {
	t.dir = c.MkDir()
	t.repository = New(filepath.Join(t.dir, "repo"))
	t.repository.Create()

	pubKey, privKey, err := ed25519.GenerateKey(
		bytes.NewBufferString("just some deterministic 'random' bytes"))
	c.Assert(err, IsNil)

	err = t.repository.keys.SetSigningPrivateKey(*privKey)
	c.Assert(err, IsNil)
	signingPubKey, err := t.repository.keys.SigningPublicKey()
	c.Assert(*pubKey, DeepEquals, signingPubKey)

	fileStorage := FileContentStorage{
		StoragePath: filepath.Join(t.dir, "nibs"),
	}
	err = fileStorage.CreateDir()
	c.Assert(err, IsNil)

	t.storage = fileStorage

	transactionStorage := FileContentStorage{
		StoragePath: filepath.Join(t.dir, "transactions"),
	}
	err = transactionStorage.CreateDir()
	c.Assert(err, IsNil)

	t.transactionManager = newTransactionManager(
		transactionStorage,
		t.repository.GetManagementDir())
	t.nibStore = newNIBStore(
		t.storage,
		t.repository.keys,
		t.transactionManager,
	)
}

func (t *NIBStoreTest) getTestNIB() *NIB {
	n := &NIB{ID: "test"}
	n.AppendRevision(&Revision{})
	n.AppendRevision(&Revision{})
	return n
}

func (t *NIBStoreTest) addTestNIB(c *C) *NIB {
	n := t.getTestNIB()
	err := t.nibStore.Add(n)
	c.Assert(err, IsNil)
	return n
}

// It should be able to add a NIB
func (t *NIBStoreTest) TestNibAddition(c *C) {
	testNib := t.addTestNIB(c)
	c.Assert(testNib.ID, Not(Equals), "")
}

// It should create a transaction with the NIBs ID on
// addition.
func (t *NIBStoreTest) TestTransactionAddition(c *C) {
	testNib := t.addTestNIB(c)
	transaction, err := t.transactionManager.CurrentTransaction()
	c.Assert(err, IsNil)
	c.Assert(transaction.NIBIDs, DeepEquals, []string{testNib.ID})
}

func (t *NIBStoreTest) TestNibGet(c *C) {
	testNib := t.addTestNIB(c)
	nib, err := t.nibStore.Get(testNib.ID)
	c.Assert(err, IsNil)
	c.Assert(nib.ID, Equals, testNib.ID)
}

func (t *NIBStoreTest) TestNibGetSignatureMangled(c *C) {
	testNib := t.addTestNIB(c)
	reader, err := t.storage.Get(testNib.ID)
	data, err := ioutil.ReadAll(reader)
	c.Assert(err, IsNil)
	data[len(data)-1] = 50
	t.storage.Set(testNib.ID, bytes.NewReader(data))
	_, err = t.nibStore.Get(testNib.ID)
	c.Assert(err, NotNil)
}

func (t *NIBStoreTest) TestNibGetContentMangled(c *C) {
	testNib := t.addTestNIB(c)
	reader, err := t.storage.Get(testNib.ID)
	data, err := ioutil.ReadAll(reader)
	c.Assert(err, IsNil)
	data[0] = 50
	t.storage.Set(testNib.ID, bytes.NewReader(data))
	_, err = t.nibStore.Get(testNib.ID)
	c.Assert(err, NotNil)
}

func (t *NIBStoreTest) TestNibExistsPositive(c *C) {
	testNib := t.addTestNIB(c)
	c.Assert(t.nibStore.Exists(testNib.ID), Equals, true)
}

func (t *NIBStoreTest) TestNibExistsNegative(c *C) {
	c.Assert(t.nibStore.Exists("Does not exist"), Equals, false)
}

func (t *NIBStoreTest) TestNibVerificationSignatureError(c *C) {
	testNib := t.addTestNIB(c)
	reader, err := t.storage.Get(testNib.ID)
	data, err := ioutil.ReadAll(reader)
	c.Assert(err, IsNil)
	data[len(data)-1] = 50

	c.Assert(
		t.nibStore.VerifyContent(data), Equals, ErrSignatureVerification,
	)
}

func (t *NIBStoreTest) TestNibVerificationMarshallingError(c *C) {
	testNib := t.addTestNIB(c)
	reader, err := t.storage.Get(testNib.ID)
	data, err := ioutil.ReadAll(reader)
	c.Assert(err, IsNil)
	data[0] = 50

	c.Assert(
		t.nibStore.VerifyContent(data), Equals, ErrUnMarshalling,
	)
}

func (t *NIBStoreTest) TestNibVerification(c *C) {
	testNib := t.addTestNIB(c)
	reader, err := t.storage.Get(testNib.ID)
	c.Assert(err, IsNil)

	data, err := ioutil.ReadAll(reader)
	c.Assert(err, IsNil)

	c.Assert(
		t.nibStore.VerifyContent(data), IsNil)
}

// It should return all added bytes
func (t *NIBStoreTest) TestGetAllBytes(c *C) {
	for i := 0; i < 100; i++ {
		nib := t.getTestNIB()
		nib.ID = fmt.Sprintf("test%d", i)
		t.nibStore.Add(nib)
	}
	found := 0

	channel, err := t.nibStore.GetAllBytes()
	c.Assert(err, IsNil)

	for _ = range channel {
		found++
	}

	c.Assert(found, Equals, 100)
}

// It should Return all nib bytes
func (t *NIBStoreTest) TestGetAll(c *C) {
	for i := 0; i < 100; i++ {
		nib := t.getTestNIB()
		nib.ID = fmt.Sprintf("test%d", i)
		t.nibStore.Add(nib)
	}
	seen := []string{}

	channel, err := t.nibStore.GetAll()
	c.Assert(err, IsNil)

	for nib := range channel {
		if nib == nil {
			c.Error("error from channel")
			return
		}
		for _, existingNib := range seen {
			if existingNib == nib.ID {
				c.Error("Double nib found.")
			}
		}
		seen = append(seen, nib.ID)
	}

	c.Assert(len(seen), Equals, 100)

}

func (t *NIBStoreTest) TestGetFrom(c *C) {
	for i := 0; i < 100; i++ {
		nib := t.getTestNIB()
		nib.ID = fmt.Sprintf("test%d", i)
		t.nibStore.Add(nib)
	}

	transaction, err := t.transactionManager.CurrentTransaction()
	c.Assert(err, IsNil)
	for i := 0; i < 5; i++ {
		transaction, err = t.transactionManager.Get(transaction.PreviousID)
		c.Assert(err, IsNil)
	}

	expectedIds := []string{}
	for i := 95; i < 100; i++ {
		expectedIds = append(expectedIds, fmt.Sprintf("test%d", i))
	}
	foundIds := []string{}
	channel, err := t.nibStore.GetFrom(transaction.ID)

	for nib := range channel {
		foundIds = append(foundIds, nib.ID)
	}

	c.Assert(expectedIds, DeepEquals, foundIds)
}

func (t *NIBStoreTest) TestGetBytesFrom(c *C) {
	for i := 0; i < 100; i++ {
		nib := t.getTestNIB()
		nib.ID = fmt.Sprintf("test%d", i)
		t.nibStore.Add(nib)
	}

	transaction, err := t.transactionManager.CurrentTransaction()
	c.Assert(err, IsNil)
	for i := 0; i < 5; i++ {
		transaction, err = t.transactionManager.Get(transaction.PreviousID)
		c.Assert(err, IsNil)
	}

	channel, err := t.nibStore.GetBytesFrom(transaction.ID)

	found := 0
	for _ = range channel {
		found++
	}

	c.Assert(found, Equals, 5)
}
<commit_msg>repository: Fixed issues with the NIBStoreTests.<commit_after>package repository

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"path/filepath"

	"github.com/agl/ed25519"

	. "gopkg.in/check.v1"
)

type NIBStoreTest struct {
	dir                string
	repository         *Repository
	nibStore           *NIBStore
	storage            ContentStorage
	transactionManager *TransactionManager
}

var _ = Suite(&NIBStoreTest{})

func (t *NIBStoreTest) SetUpTest(c *C) {
	t.dir = c.MkDir()
	t.repository = New(filepath.Join(t.dir, "repo"))
	t.repository.Create()

	pubKey, privKey, err := ed25519.GenerateKey(
		bytes.NewBufferString("just some deterministic 'random' bytes"))
	c.Assert(err, IsNil)

	err = t.repository.keys.SetSigningPrivateKey(*privKey)
	c.Assert(err, IsNil)
	signingPubKey, err := t.repository.keys.SigningPublicKey()
	c.Assert(*pubKey, DeepEquals, signingPubKey)

	fileStorage := &FileContentStorage{
		StoragePath: filepath.Join(t.dir, "nibs"),
	}
	err = fileStorage.CreateDir()
	c.Assert(err, IsNil)

	t.storage = fileStorage

	transactionStorage := &FileContentStorage{
		StoragePath: filepath.Join(t.dir, "transactions"),
	}
	err = transactionStorage.CreateDir()
	c.Assert(err, IsNil)

	t.transactionManager = newTransactionManager(
		transactionStorage,
		t.repository.GetManagementDir())
	t.nibStore = newNIBStore(
		t.storage,
		t.repository.keys,
		t.transactionManager,
	)
}

func (t *NIBStoreTest) getTestNIB() *NIB {
	n := &NIB{ID: "test"}
	n.AppendRevision(&Revision{})
	n.AppendRevision(&Revision{})
	return n
}

func (t *NIBStoreTest) addTestNIB(c *C) *NIB {
	n := t.getTestNIB()
	err := t.nibStore.Add(n)
	c.Assert(err, IsNil)
	return n
}

// It should be able to add a NIB
func (t *NIBStoreTest) TestNibAddition(c *C) {
	testNib := t.addTestNIB(c)
	c.Assert(testNib.ID, Not(Equals), "")
}

// It should create a transaction with the NIBs ID on
// addition.
func (t *NIBStoreTest) TestTransactionAddition(c *C) {
	testNib := t.addTestNIB(c)
	transaction, err := t.transactionManager.CurrentTransaction()
	c.Assert(err, IsNil)
	c.Assert(transaction.NIBIDs, DeepEquals, []string{testNib.ID})
}

func (t *NIBStoreTest) TestNibGet(c *C) {
	testNib := t.addTestNIB(c)
	nib, err := t.nibStore.Get(testNib.ID)
	c.Assert(err, IsNil)
	c.Assert(nib.ID, Equals, testNib.ID)
}

func (t *NIBStoreTest) TestNibGetSignatureMangled(c *C) {
	testNib := t.addTestNIB(c)
	reader, err := t.storage.Get(testNib.ID)
	data, err := ioutil.ReadAll(reader)
	c.Assert(err, IsNil)
	data[len(data)-1] = 50
	t.storage.Set(testNib.ID, bytes.NewReader(data))
	_, err = t.nibStore.Get(testNib.ID)
	c.Assert(err, NotNil)
}

func (t *NIBStoreTest) TestNibGetContentMangled(c *C) {
	testNib := t.addTestNIB(c)
	reader, err := t.storage.Get(testNib.ID)
	data, err := ioutil.ReadAll(reader)
	c.Assert(err, IsNil)
	data[0] = 50
	t.storage.Set(testNib.ID, bytes.NewReader(data))
	_, err = t.nibStore.Get(testNib.ID)
	c.Assert(err, NotNil)
}

func (t *NIBStoreTest) TestNibExistsPositive(c *C) {
	testNib := t.addTestNIB(c)
	c.Assert(t.nibStore.Exists(testNib.ID), Equals, true)
}

func (t *NIBStoreTest) TestNibExistsNegative(c *C) {
	c.Assert(t.nibStore.Exists("Does not exist"), Equals, false)
}

func (t *NIBStoreTest) TestNibVerificationSignatureError(c *C) {
	testNib := t.addTestNIB(c)
	reader, err := t.storage.Get(testNib.ID)
	data, err := ioutil.ReadAll(reader)
	c.Assert(err, IsNil)
	data[len(data)-1] = 50

	c.Assert(
		t.nibStore.VerifyContent(data), Equals, ErrSignatureVerification,
	)
}

func (t *NIBStoreTest) TestNibVerificationMarshallingError(c *C) {
	testNib := t.addTestNIB(c)
	reader, err := t.storage.Get(testNib.ID)
	data, err := ioutil.ReadAll(reader)
	c.Assert(err, IsNil)
	data[0] = 50

	c.Assert(
		t.nibStore.VerifyContent(data), Equals, ErrUnMarshalling,
	)
}

func (t *NIBStoreTest) TestNibVerification(c *C) {
	testNib := t.addTestNIB(c)
	reader, err := t.storage.Get(testNib.ID)
	c.Assert(err, IsNil)

	data, err := ioutil.ReadAll(reader)
	c.Assert(err, IsNil)

	c.Assert(
		t.nibStore.VerifyContent(data), IsNil)
}

// It should return all added bytes
func (t *NIBStoreTest) TestGetAllBytes(c *C) {
	for i := 0; i < 100; i++ {
		nib := t.getTestNIB()
		nib.ID = fmt.Sprintf("test%d", i)
		t.nibStore.Add(nib)
	}
	found := 0

	channel, err := t.nibStore.GetAllBytes()
	c.Assert(err, IsNil)

	for _ = range channel {
		found++
	}

	c.Assert(found, Equals, 100)
}

// It should Return all nib bytes
func (t *NIBStoreTest) TestGetAll(c *C) {
	for i := 0; i < 100; i++ {
		nib := t.getTestNIB()
		nib.ID = fmt.Sprintf("test%d", i)
		t.nibStore.Add(nib)
	}
	seen := []string{}

	channel, err := t.nibStore.GetAll()
	c.Assert(err, IsNil)

	for nib := range channel {
		if nib == nil {
			c.Error("error from channel")
			return
		}
		for _, existingNib := range seen {
			if existingNib == nib.ID {
				c.Error("Double nib found.")
			}
		}
		seen = append(seen, nib.ID)
	}

	c.Assert(len(seen), Equals, 100)

}

func (t *NIBStoreTest) TestGetFrom(c *C) {
	for i := 0; i < 100; i++ {
		nib := t.getTestNIB()
		nib.ID = fmt.Sprintf("test%d", i)
		t.nibStore.Add(nib)
	}

	transaction, err := t.transactionManager.CurrentTransaction()
	c.Assert(err, IsNil)
	for i := 0; i < 5; i++ {
		transaction, err = t.transactionManager.Get(transaction.PreviousID)
		c.Assert(err, IsNil)
	}

	expectedIds := []string{}
	for i := 95; i < 100; i++ {
		expectedIds = append(expectedIds, fmt.Sprintf("test%d", i))
	}
	foundIds := []string{}
	channel, err := t.nibStore.GetFrom(transaction.ID)

	for nib := range channel {
		foundIds = append(foundIds, nib.ID)
	}

	c.Assert(expectedIds, DeepEquals, foundIds)
}

func (t *NIBStoreTest) TestGetBytesFrom(c *C) {
	for i := 0; i < 100; i++ {
		nib := t.getTestNIB()
		nib.ID = fmt.Sprintf("test%d", i)
		t.nibStore.Add(nib)
	}

	transaction, err := t.transactionManager.CurrentTransaction()
	c.Assert(err, IsNil)
	for i := 0; i < 5; i++ {
		transaction, err = t.transactionManager.Get(transaction.PreviousID)
		c.Assert(err, IsNil)
	}

	channel, err := t.nibStore.GetBytesFrom(transaction.ID)

	found := 0
	for _ = range channel {
		found++
	}

	c.Assert(found, Equals, 5)
}
<|endoftext|>