<commit_before>// Copyright 2014 docker-cluster 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 cluster

import (
	"errors"
	"fmt"
	"net"
	"net/url"
	"sync"
	"time"

	"github.com/fsouza/go-dockerclient"
	"github.com/tsuru/docker-cluster/log"
)

type Container struct {
	Id   string `bson:"_id"`
	Host string
}

// CreateContainer creates a container in the specified node. If no node is
// specified, it will create the container in a node selected by the scheduler.
//
// It returns the container, or an error, in case of failures.
func (c *Cluster) CreateContainer(opts docker.CreateContainerOptions, inactivityTimeout time.Duration, nodes ...string) (string, *docker.Container, error) {
	return c.CreateContainerSchedulerOpts(opts, nil, inactivityTimeout, nodes...)
}

// Similar to CreateContainer but allows arbritary options to be passed to
// the scheduler.
func (c *Cluster) CreateContainerSchedulerOpts(opts docker.CreateContainerOptions, schedulerOpts SchedulerOptions, inactivityTimeout time.Duration, nodes ...string) (string, *docker.Container, error) {
	var (
		addr      string
		container *docker.Container
		err       error
	)
	useScheduler := len(nodes) == 0
	maxTries := 5
	for ; maxTries > 0; maxTries-- {
		if useScheduler {
			node, scheduleErr := c.scheduler.Schedule(c, opts, schedulerOpts)
			if scheduleErr != nil {
				if err != nil {
					scheduleErr = fmt.Errorf("Error in scheduler after previous errors (%s) trying to create container: %s", err.Error(), scheduleErr.Error())
				}
				return addr, nil, scheduleErr
			}
			addr = node.Address
		} else {
			addr = nodes[0]
		}
		if addr == "" {
			return addr, nil, errors.New("CreateContainer needs a non empty node addr")
		}
		err = c.runHookForAddr(HookEventBeforeContainerCreate, addr)
		if err != nil {
			log.Errorf("Error in before create container hook in node %q: %s. Trying again in another node...", addr, err)
		}
		if err == nil {
			container, err = c.createContainerInNode(opts, inactivityTimeout, addr)
			if err == nil {
				c.handleNodeSuccess(addr)
				break
			}
			log.Errorf("Error trying to create container in node %q: %s. Trying again in another node...", addr, err.Error())
		}
		shouldIncrementFailures := false
		isCreateContainerErr := false
		baseErr := err
		if nodeErr, ok := baseErr.(DockerNodeError); ok {
			isCreateContainerErr = nodeErr.cmd == "createContainer"
			baseErr = nodeErr.BaseError()
		}
		if urlErr, ok := baseErr.(*url.Error); ok {
			baseErr = urlErr.Err
		}
		_, isNetErr := baseErr.(*net.OpError)
		if isNetErr || isCreateContainerErr || baseErr == docker.ErrConnectionRefused {
			shouldIncrementFailures = true
		}
		c.handleNodeError(addr, err, shouldIncrementFailures)
		if !useScheduler {
			return addr, nil, err
		}
	}
	if err != nil {
		return addr, nil, fmt.Errorf("CreateContainer: maximum number of tries exceeded, last error: %s", err.Error())
	}
	err = c.storage().StoreContainer(container.ID, addr)
	return addr, container, err
}

func (c *Cluster) createContainerInNode(opts docker.CreateContainerOptions, inactivityTimeout time.Duration, nodeAddress string) (*docker.Container, error) {
	registryServer, _ := parseImageRegistry(opts.Config.Image)
	if registryServer != "" {
		err := c.PullImage(docker.PullImageOptions{
			Repository:        opts.Config.Image,
			InactivityTimeout: inactivityTimeout,
		}, docker.AuthConfiguration{}, nodeAddress)
		if err != nil {
			return nil, err
		}
	}
	node, err := c.getNodeByAddr(nodeAddress)
	if err != nil {
		return nil, err
	}
	cont, err := node.CreateContainer(opts)
	return cont, wrapErrorWithCmd(node, err, "createContainer")
}

// InspectContainer returns information about a container by its ID, getting
// the information from the right node.
func (c *Cluster) InspectContainer(id string) (*docker.Container, error) {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return nil, err
	}
	cont, err := node.InspectContainer(id)
	return cont, wrapError(node, err)
}

// KillContainer kills a container, returning an error in case of failure.
func (c *Cluster) KillContainer(opts docker.KillContainerOptions) error {
	node, err := c.getNodeForContainer(opts.ID)
	if err != nil {
		return err
	}
	return wrapError(node, node.KillContainer(opts))
}

// ListContainers returns a slice of all containers in the cluster matching the
// given criteria.
func (c *Cluster) ListContainers(opts docker.ListContainersOptions) ([]docker.APIContainers, error) {
	nodes, err := c.Nodes()
	if err != nil {
		return nil, err
	}
	var wg sync.WaitGroup
	result := make(chan []docker.APIContainers, len(nodes))
	errs := make(chan error, len(nodes))
	for _, n := range nodes {
		wg.Add(1)
		client, _ := c.getNodeByAddr(n.Address)
		go func(n node) {
			defer wg.Done()
			if containers, err := n.ListContainers(opts); err != nil {
				errs <- wrapError(n, err)
			} else {
				result <- containers
			}
		}(client)
	}
	wg.Wait()
	var group []docker.APIContainers
	for {
		select {
		case containers := <-result:
			group = append(group, containers...)
		case err = <-errs:
		default:
			return group, err
		}
	}
}

// RemoveContainer removes a container from the cluster.
func (c *Cluster) RemoveContainer(opts docker.RemoveContainerOptions) error {
	return c.removeFromStorage(opts)
}

func (c *Cluster) removeFromStorage(opts docker.RemoveContainerOptions) error {
	node, err := c.getNodeForContainer(opts.ID)
	if err != nil {
		return err
	}
	err = node.RemoveContainer(opts)
	if err != nil {
		_, isNoSuchContainer := err.(*docker.NoSuchContainer)
		if !isNoSuchContainer {
			return wrapError(node, err)
		}
	}
	return c.storage().RemoveContainer(opts.ID)
}

func (c *Cluster) StartContainer(id string, hostConfig *docker.HostConfig) error {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return err
	}
	return wrapError(node, node.StartContainer(id, hostConfig))
}

// StopContainer stops a container, killing it after the given timeout, if it
// fails to stop nicely.
func (c *Cluster) StopContainer(id string, timeout uint) error {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return err
	}
	return wrapError(node, node.StopContainer(id, timeout))
}

// RestartContainer restarts a container, killing it after the given timeout,
// if it fails to stop nicely.
func (c *Cluster) RestartContainer(id string, timeout uint) error {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return err
	}
	return wrapError(node, node.RestartContainer(id, timeout))
}

// PauseContainer changes the container to the paused state.
func (c *Cluster) PauseContainer(id string) error {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return err
	}
	return wrapError(node, node.PauseContainer(id))
}

// UnpauseContainer removes the container from the paused state.
func (c *Cluster) UnpauseContainer(id string) error {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return err
	}
	return wrapError(node, node.UnpauseContainer(id))
}

// WaitContainer blocks until the given container stops, returning the exit
// code of the container command.
func (c *Cluster) WaitContainer(id string) (int, error) {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return -1, err
	}
	node.setPersistentClient()
	code, err := node.WaitContainer(id)
	return code, wrapError(node, err)
}

// AttachToContainer attaches to a container, using the given options.
func (c *Cluster) AttachToContainer(opts docker.AttachToContainerOptions) error {
	node, err := c.getNodeForContainer(opts.Container)
	if err != nil {
		return err
	}
	node.setPersistentClient()
	return wrapError(node, node.AttachToContainer(opts))
}

// AttachToContainerNonBlocking attaches to a container and returns a docker.CloseWaiter, using given options.
func (c *Cluster) AttachToContainerNonBlocking(opts docker.AttachToContainerOptions) (docker.CloseWaiter, error) {
	node, err := c.getNodeForContainer(opts.Container)
	if err != nil {
		return nil, err
	}
	node.setPersistentClient()
	return node.AttachToContainerNonBlocking(opts)
}

// Logs retrieves the logs of the specified container.
func (c *Cluster) Logs(opts docker.LogsOptions) error {
	node, err := c.getNodeForContainer(opts.Container)
	if err != nil {
		return err
	}
	return wrapError(node, node.Logs(opts))
}

// CommitContainer commits a container and returns the image id.
func (c *Cluster) CommitContainer(opts docker.CommitContainerOptions) (*docker.Image, error) {
	node, err := c.getNodeForContainer(opts.Container)
	if err != nil {
		return nil, err
	}
	node.setPersistentClient()
	image, err := node.CommitContainer(opts)
	if err != nil {
		return nil, wrapError(node, err)
	}
	key := imageKey(opts.Repository, opts.Tag)
	if key != "" {
		err = c.storage().StoreImage(key, image.ID, node.addr)
		if err != nil {
			return nil, err
		}
	}
	return image, nil
}

// ExportContainer exports a container as a tar and writes
// the result in out.
func (c *Cluster) ExportContainer(opts docker.ExportContainerOptions) error {
	node, err := c.getNodeForContainer(opts.ID)
	if err != nil {
		return err
	}
	return wrapError(node, node.ExportContainer(opts))
}

// TopContainer returns information about running processes inside a container
// by its ID, getting the information from the right node.
func (c *Cluster) TopContainer(id string, psArgs string) (docker.TopResult, error) {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return docker.TopResult{}, err
	}
	result, err := node.TopContainer(id, psArgs)
	return result, wrapError(node, err)
}

func (c *Cluster) getNodeForContainer(container string) (node, error) {
	addr, err := c.storage().RetrieveContainer(container)
	if err != nil {
		return node{}, err
	}
	return c.getNodeByAddr(addr)
}

func (c *Cluster) CreateExec(opts docker.CreateExecOptions) (*docker.Exec, error) {
	node, err := c.getNodeForContainer(opts.Container)
	if err != nil {
		return nil, err
	}
	exec, err := node.CreateExec(opts)
	return exec, wrapError(node, err)
}

func (c *Cluster) StartExec(execId, containerId string, opts docker.StartExecOptions) error {
	node, err := c.getNodeForContainer(containerId)
	if err != nil {
		return err
	}
	node.setPersistentClient()
	return wrapError(node, node.StartExec(execId, opts))
}

func (c *Cluster) ResizeExecTTY(execId, containerId string, height, width int) error {
	node, err := c.getNodeForContainer(containerId)
	if err != nil {
		return err
	}
	return wrapError(node, node.ResizeExecTTY(execId, height, width))
}

func (c *Cluster) InspectExec(execId, containerId string) (*docker.ExecInspect, error) {
	node, err := c.getNodeForContainer(containerId)
	if err != nil {
		return nil, err
	}
	execInspect, err := node.InspectExec(execId)
	if err != nil {
		return nil, wrapError(node, err)
	}
	return execInspect, nil
}

func (c *Cluster) UploadToContainer(containerId string, opts docker.UploadToContainerOptions) error {
	node, err := c.getNodeForContainer(containerId)
	if err != nil {
		return err
	}
	return node.UploadToContainer(containerId, opts)
}
<commit_msg>cluster: set RawJSONStream true for image pull<commit_after>// Copyright 2014 docker-cluster 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 cluster

import (
	"errors"
	"fmt"
	"net"
	"net/url"
	"sync"
	"time"

	"github.com/fsouza/go-dockerclient"
	"github.com/tsuru/docker-cluster/log"
)

type Container struct {
	Id   string `bson:"_id"`
	Host string
}

// CreateContainer creates a container in the specified node. If no node is
// specified, it will create the container in a node selected by the scheduler.
//
// It returns the container, or an error, in case of failures.
func (c *Cluster) CreateContainer(opts docker.CreateContainerOptions, inactivityTimeout time.Duration, nodes ...string) (string, *docker.Container, error) {
	return c.CreateContainerSchedulerOpts(opts, nil, inactivityTimeout, nodes...)
}

// Similar to CreateContainer but allows arbritary options to be passed to
// the scheduler.
func (c *Cluster) CreateContainerSchedulerOpts(opts docker.CreateContainerOptions, schedulerOpts SchedulerOptions, inactivityTimeout time.Duration, nodes ...string) (string, *docker.Container, error) {
	var (
		addr      string
		container *docker.Container
		err       error
	)
	useScheduler := len(nodes) == 0
	maxTries := 5
	for ; maxTries > 0; maxTries-- {
		if useScheduler {
			node, scheduleErr := c.scheduler.Schedule(c, opts, schedulerOpts)
			if scheduleErr != nil {
				if err != nil {
					scheduleErr = fmt.Errorf("Error in scheduler after previous errors (%s) trying to create container: %s", err.Error(), scheduleErr.Error())
				}
				return addr, nil, scheduleErr
			}
			addr = node.Address
		} else {
			addr = nodes[0]
		}
		if addr == "" {
			return addr, nil, errors.New("CreateContainer needs a non empty node addr")
		}
		err = c.runHookForAddr(HookEventBeforeContainerCreate, addr)
		if err != nil {
			log.Errorf("Error in before create container hook in node %q: %s. Trying again in another node...", addr, err)
		}
		if err == nil {
			container, err = c.createContainerInNode(opts, inactivityTimeout, addr)
			if err == nil {
				c.handleNodeSuccess(addr)
				break
			}
			log.Errorf("Error trying to create container in node %q: %s. Trying again in another node...", addr, err.Error())
		}
		shouldIncrementFailures := false
		isCreateContainerErr := false
		baseErr := err
		if nodeErr, ok := baseErr.(DockerNodeError); ok {
			isCreateContainerErr = nodeErr.cmd == "createContainer"
			baseErr = nodeErr.BaseError()
		}
		if urlErr, ok := baseErr.(*url.Error); ok {
			baseErr = urlErr.Err
		}
		_, isNetErr := baseErr.(*net.OpError)
		if isNetErr || isCreateContainerErr || baseErr == docker.ErrConnectionRefused {
			shouldIncrementFailures = true
		}
		c.handleNodeError(addr, err, shouldIncrementFailures)
		if !useScheduler {
			return addr, nil, err
		}
	}
	if err != nil {
		return addr, nil, fmt.Errorf("CreateContainer: maximum number of tries exceeded, last error: %s", err.Error())
	}
	err = c.storage().StoreContainer(container.ID, addr)
	return addr, container, err
}

func (c *Cluster) createContainerInNode(opts docker.CreateContainerOptions, inactivityTimeout time.Duration, nodeAddress string) (*docker.Container, error) {
	registryServer, _ := parseImageRegistry(opts.Config.Image)
	if registryServer != "" {
		err := c.PullImage(docker.PullImageOptions{
			Repository:        opts.Config.Image,
			InactivityTimeout: inactivityTimeout,
			RawJSONStream:     true,
		}, docker.AuthConfiguration{}, nodeAddress)
		if err != nil {
			return nil, err
		}
	}
	node, err := c.getNodeByAddr(nodeAddress)
	if err != nil {
		return nil, err
	}
	cont, err := node.CreateContainer(opts)
	return cont, wrapErrorWithCmd(node, err, "createContainer")
}

// InspectContainer returns information about a container by its ID, getting
// the information from the right node.
func (c *Cluster) InspectContainer(id string) (*docker.Container, error) {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return nil, err
	}
	cont, err := node.InspectContainer(id)
	return cont, wrapError(node, err)
}

// KillContainer kills a container, returning an error in case of failure.
func (c *Cluster) KillContainer(opts docker.KillContainerOptions) error {
	node, err := c.getNodeForContainer(opts.ID)
	if err != nil {
		return err
	}
	return wrapError(node, node.KillContainer(opts))
}

// ListContainers returns a slice of all containers in the cluster matching the
// given criteria.
func (c *Cluster) ListContainers(opts docker.ListContainersOptions) ([]docker.APIContainers, error) {
	nodes, err := c.Nodes()
	if err != nil {
		return nil, err
	}
	var wg sync.WaitGroup
	result := make(chan []docker.APIContainers, len(nodes))
	errs := make(chan error, len(nodes))
	for _, n := range nodes {
		wg.Add(1)
		client, _ := c.getNodeByAddr(n.Address)
		go func(n node) {
			defer wg.Done()
			if containers, err := n.ListContainers(opts); err != nil {
				errs <- wrapError(n, err)
			} else {
				result <- containers
			}
		}(client)
	}
	wg.Wait()
	var group []docker.APIContainers
	for {
		select {
		case containers := <-result:
			group = append(group, containers...)
		case err = <-errs:
		default:
			return group, err
		}
	}
}

// RemoveContainer removes a container from the cluster.
func (c *Cluster) RemoveContainer(opts docker.RemoveContainerOptions) error {
	return c.removeFromStorage(opts)
}

func (c *Cluster) removeFromStorage(opts docker.RemoveContainerOptions) error {
	node, err := c.getNodeForContainer(opts.ID)
	if err != nil {
		return err
	}
	err = node.RemoveContainer(opts)
	if err != nil {
		_, isNoSuchContainer := err.(*docker.NoSuchContainer)
		if !isNoSuchContainer {
			return wrapError(node, err)
		}
	}
	return c.storage().RemoveContainer(opts.ID)
}

func (c *Cluster) StartContainer(id string, hostConfig *docker.HostConfig) error {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return err
	}
	return wrapError(node, node.StartContainer(id, hostConfig))
}

// StopContainer stops a container, killing it after the given timeout, if it
// fails to stop nicely.
func (c *Cluster) StopContainer(id string, timeout uint) error {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return err
	}
	return wrapError(node, node.StopContainer(id, timeout))
}

// RestartContainer restarts a container, killing it after the given timeout,
// if it fails to stop nicely.
func (c *Cluster) RestartContainer(id string, timeout uint) error {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return err
	}
	return wrapError(node, node.RestartContainer(id, timeout))
}

// PauseContainer changes the container to the paused state.
func (c *Cluster) PauseContainer(id string) error {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return err
	}
	return wrapError(node, node.PauseContainer(id))
}

// UnpauseContainer removes the container from the paused state.
func (c *Cluster) UnpauseContainer(id string) error {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return err
	}
	return wrapError(node, node.UnpauseContainer(id))
}

// WaitContainer blocks until the given container stops, returning the exit
// code of the container command.
func (c *Cluster) WaitContainer(id string) (int, error) {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return -1, err
	}
	node.setPersistentClient()
	code, err := node.WaitContainer(id)
	return code, wrapError(node, err)
}

// AttachToContainer attaches to a container, using the given options.
func (c *Cluster) AttachToContainer(opts docker.AttachToContainerOptions) error {
	node, err := c.getNodeForContainer(opts.Container)
	if err != nil {
		return err
	}
	node.setPersistentClient()
	return wrapError(node, node.AttachToContainer(opts))
}

// AttachToContainerNonBlocking attaches to a container and returns a docker.CloseWaiter, using given options.
func (c *Cluster) AttachToContainerNonBlocking(opts docker.AttachToContainerOptions) (docker.CloseWaiter, error) {
	node, err := c.getNodeForContainer(opts.Container)
	if err != nil {
		return nil, err
	}
	node.setPersistentClient()
	return node.AttachToContainerNonBlocking(opts)
}

// Logs retrieves the logs of the specified container.
func (c *Cluster) Logs(opts docker.LogsOptions) error {
	node, err := c.getNodeForContainer(opts.Container)
	if err != nil {
		return err
	}
	return wrapError(node, node.Logs(opts))
}

// CommitContainer commits a container and returns the image id.
func (c *Cluster) CommitContainer(opts docker.CommitContainerOptions) (*docker.Image, error) {
	node, err := c.getNodeForContainer(opts.Container)
	if err != nil {
		return nil, err
	}
	node.setPersistentClient()
	image, err := node.CommitContainer(opts)
	if err != nil {
		return nil, wrapError(node, err)
	}
	key := imageKey(opts.Repository, opts.Tag)
	if key != "" {
		err = c.storage().StoreImage(key, image.ID, node.addr)
		if err != nil {
			return nil, err
		}
	}
	return image, nil
}

// ExportContainer exports a container as a tar and writes
// the result in out.
func (c *Cluster) ExportContainer(opts docker.ExportContainerOptions) error {
	node, err := c.getNodeForContainer(opts.ID)
	if err != nil {
		return err
	}
	return wrapError(node, node.ExportContainer(opts))
}

// TopContainer returns information about running processes inside a container
// by its ID, getting the information from the right node.
func (c *Cluster) TopContainer(id string, psArgs string) (docker.TopResult, error) {
	node, err := c.getNodeForContainer(id)
	if err != nil {
		return docker.TopResult{}, err
	}
	result, err := node.TopContainer(id, psArgs)
	return result, wrapError(node, err)
}

func (c *Cluster) getNodeForContainer(container string) (node, error) {
	addr, err := c.storage().RetrieveContainer(container)
	if err != nil {
		return node{}, err
	}
	return c.getNodeByAddr(addr)
}

func (c *Cluster) CreateExec(opts docker.CreateExecOptions) (*docker.Exec, error) {
	node, err := c.getNodeForContainer(opts.Container)
	if err != nil {
		return nil, err
	}
	exec, err := node.CreateExec(opts)
	return exec, wrapError(node, err)
}

func (c *Cluster) StartExec(execId, containerId string, opts docker.StartExecOptions) error {
	node, err := c.getNodeForContainer(containerId)
	if err != nil {
		return err
	}
	node.setPersistentClient()
	return wrapError(node, node.StartExec(execId, opts))
}

func (c *Cluster) ResizeExecTTY(execId, containerId string, height, width int) error {
	node, err := c.getNodeForContainer(containerId)
	if err != nil {
		return err
	}
	return wrapError(node, node.ResizeExecTTY(execId, height, width))
}

func (c *Cluster) InspectExec(execId, containerId string) (*docker.ExecInspect, error) {
	node, err := c.getNodeForContainer(containerId)
	if err != nil {
		return nil, err
	}
	execInspect, err := node.InspectExec(execId)
	if err != nil {
		return nil, wrapError(node, err)
	}
	return execInspect, nil
}

func (c *Cluster) UploadToContainer(containerId string, opts docker.UploadToContainerOptions) error {
	node, err := c.getNodeForContainer(containerId)
	if err != nil {
		return err
	}
	return node.UploadToContainer(containerId, opts)
}
<|endoftext|>


<commit_before>package cluster

import (
	"time"

	"github.com/AsynkronIT/protoactor-go/actor"
	"github.com/AsynkronIT/protoactor-go/remote"
)

var (
	pidCacheActorPid *actor.PID
)

func spawnPidCacheActor() {
	props := actor.FromProducer(newPidCacheActor())
	pidCacheActorPid, _ = actor.SpawnNamed(props, "PidCache")

}
func newPidCacheActor() actor.Producer {
	return func() actor.Actor {
		return &pidCachePartitionActor{}
	}
}

type pidCachePartitionActor struct {
	Cache        map[string]*actor.PID
	ReverseCache map[string]string
}

type pidCacheRequest struct {
	name string
	kind string
}

func (p *pidCacheRequest) Hash() string {
	return p.name
}

func (a *pidCachePartitionActor) Receive(ctx actor.Context) {
	switch msg := ctx.Message().(type) {
	case *actor.Started:
		a.Cache = make(map[string]*actor.PID)
		a.ReverseCache = make(map[string]string)

	case *pidCacheRequest:
		if pid, ok := a.Cache[msg.name]; ok {
			//name was in cache, exit early
			ctx.Respond(&remote.ActorPidResponse{Pid: pid})
			return
		}
		name := msg.name
		kind := msg.kind

		address := getNode(name, kind)
		remotePID := partitionForKind(address, kind)

		//re-package the request as a remote.ActorPidRequest
		req := &remote.ActorPidRequest{
			Kind: kind,
			Name: name,
		}
		//ask the DHT partition for this name to give us a PID
		f := remotePID.RequestFuture(req, 5*time.Second)
		ctx.AwaitFuture(f, func(r interface{}, err error) {
			if err != nil {
				return
			}
			response, ok := r.(*remote.ActorPidResponse)
			if !ok {
				return
			}

			a.Cache[name] = response.Pid
			//make a lookup from pid to name
			a.ReverseCache[response.Pid.String()] = name
			//watch the pid so we know if the node or pid dies
			ctx.Watch(response.Pid)
			//tell the original requester that we have a response
			ctx.Respond(response)
		})

	case *actor.Terminated:
		key := msg.Who.String()
		//get the virtual name from the pid
		name, ok := a.ReverseCache[key]
		if !ok {
			//we don't have it, just ignore
			return
		}
		//drop both lookups as this actor is now dead
		delete(a.Cache, name)
		delete(a.ReverseCache, key)
	}
}
<commit_msg>Update pid_cache.go<commit_after>package cluster

import (
	"time"

	"github.com/AsynkronIT/protoactor-go/actor"
	"github.com/AsynkronIT/protoactor-go/remote"
)

var (
	pidCacheActorPid *actor.PID
)

func spawnPidCacheActor() {
	props := actor.FromProducer(newPidCacheActor())
	pidCacheActorPid, _ = actor.SpawnNamed(props, "PidCache")
}

func newPidCacheActor() actor.Producer {
	return func() actor.Actor {
		return &pidCachePartitionActor{}
	}
}

type pidCachePartitionActor struct {
	Cache        map[string]*actor.PID
	ReverseCache map[string]string
}

type pidCacheRequest struct {
	name string
	kind string
}

func (p *pidCacheRequest) Hash() string {
	return p.name
}

func (a *pidCachePartitionActor) Receive(ctx actor.Context) {
	switch msg := ctx.Message().(type) {
	case *actor.Started:
		a.Cache = make(map[string]*actor.PID)
		a.ReverseCache = make(map[string]string)

	case *pidCacheRequest:
		if pid, ok := a.Cache[msg.name]; ok {
			//name was in cache, exit early
			ctx.Respond(&remote.ActorPidResponse{Pid: pid})
			return
		}
		name := msg.name
		kind := msg.kind

		address := getNode(name, kind)
		remotePID := partitionForKind(address, kind)

		//re-package the request as a remote.ActorPidRequest
		req := &remote.ActorPidRequest{
			Kind: kind,
			Name: name,
		}
		//ask the DHT partition for this name to give us a PID
		f := remotePID.RequestFuture(req, 5*time.Second)
		ctx.AwaitFuture(f, func(r interface{}, err error) {
			if err != nil {
				return
			}
			response, ok := r.(*remote.ActorPidResponse)
			if !ok {
				return
			}

			a.Cache[name] = response.Pid
			//make a lookup from pid to name
			a.ReverseCache[response.Pid.String()] = name
			//watch the pid so we know if the node or pid dies
			ctx.Watch(response.Pid)
			//tell the original requester that we have a response
			ctx.Respond(response)
		})

	case *actor.Terminated:
		key := msg.Who.String()
		//get the virtual name from the pid
		name, ok := a.ReverseCache[key]
		if !ok {
			//we don't have it, just ignore
			return
		}
		//drop both lookups as this actor is now dead
		delete(a.Cache, name)
		delete(a.ReverseCache, key)
	}
}
<|endoftext|>


<commit_before>// GENERATED CODE - DO NOT EDIT
package routes

import "github.com/robfig/revel"

type tApp struct {}
var App tApp

func (_ tApp) Search(
		query string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "query", query)
	return revel.MainRouter.Reverse("App.Search", args).Url
}

func (_ tApp) Details(
		query string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "query", query)
	return revel.MainRouter.Reverse("App.Details", args).Url
}

func (_ tApp) SearchGet(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.SearchGet", args).Url
}

func (_ tApp) About(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.About", args).Url
}

func (_ tApp) Resources(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.Resources", args).Url
}

func (_ tApp) SavePhrase(
		phrase string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "phrase", phrase)
	return revel.MainRouter.Reverse("App.SavePhrase", args).Url
}

func (_ tApp) Register(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.Register", args).Url
}

func (_ tApp) LoginPage(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.LoginPage", args).Url
}

func (_ tApp) Profile(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.Profile", args).Url
}

func (_ tApp) SaveUser(
		user interface{},
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "user", user)
	return revel.MainRouter.Reverse("App.SaveUser", args).Url
}

func (_ tApp) Login(
		email string,
		password string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "email", email)
	revel.Unbind(args, "password", password)
	return revel.MainRouter.Reverse("App.Login", args).Url
}

func (_ tApp) Logout(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.Logout", args).Url
}

func (_ tApp) Index(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.Index", args).Url
}

type tTestRunner struct {}
var TestRunner tTestRunner

func (_ tTestRunner) Index(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("TestRunner.Index", args).Url
}

func (_ tTestRunner) Run(
		suite string,
		test string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "suite", suite)
	revel.Unbind(args, "test", test)
	return revel.MainRouter.Reverse("TestRunner.Run", args).Url
}

func (_ tTestRunner) List(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("TestRunner.List", args).Url
}

type tStatic struct {}
var Static tStatic

func (_ tStatic) Serve(
		prefix string,
		filepath string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "prefix", prefix)
	revel.Unbind(args, "filepath", filepath)
	return revel.MainRouter.Reverse("Static.Serve", args).Url
}

func (_ tStatic) ServeModule(
		moduleName string,
		prefix string,
		filepath string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "moduleName", moduleName)
	revel.Unbind(args, "prefix", prefix)
	revel.Unbind(args, "filepath", filepath)
	return revel.MainRouter.Reverse("Static.ServeModule", args).Url
}

<commit_msg>routes... :camel: :dash:<commit_after>// GENERATED CODE - DO NOT EDIT
package routes

import "github.com/robfig/revel"

type tApp struct {}
var App tApp

func (_ tApp) Search(
		query string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "query", query)
	return revel.MainRouter.Reverse("App.Search", args).Url
}

func (_ tApp) Details(
		query string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "query", query)
	return revel.MainRouter.Reverse("App.Details", args).Url
}

func (_ tApp) SearchGet(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.SearchGet", args).Url
}

func (_ tApp) About(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.About", args).Url
}

func (_ tApp) Resources(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.Resources", args).Url
}

func (_ tApp) SavePhrase(
		phrase string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "phrase", phrase)
	return revel.MainRouter.Reverse("App.SavePhrase", args).Url
}

func (_ tApp) Register(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.Register", args).Url
}

func (_ tApp) LoginPage(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.LoginPage", args).Url
}

func (_ tApp) Profile(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.Profile", args).Url
}

func (_ tApp) SaveUser(
		user interface{},
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "user", user)
	return revel.MainRouter.Reverse("App.SaveUser", args).Url
}

func (_ tApp) Login(
		email string,
		password string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "email", email)
	revel.Unbind(args, "password", password)
	return revel.MainRouter.Reverse("App.Login", args).Url
}

func (_ tApp) Logout(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.Logout", args).Url
}

func (_ tApp) Index(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("App.Index", args).Url
}

type tStatic struct {}
var Static tStatic

func (_ tStatic) Serve(
		prefix string,
		filepath string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "prefix", prefix)
	revel.Unbind(args, "filepath", filepath)
	return revel.MainRouter.Reverse("Static.Serve", args).Url
}

func (_ tStatic) ServeModule(
		moduleName string,
		prefix string,
		filepath string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "moduleName", moduleName)
	revel.Unbind(args, "prefix", prefix)
	revel.Unbind(args, "filepath", filepath)
	return revel.MainRouter.Reverse("Static.ServeModule", args).Url
}

type tTestRunner struct {}
var TestRunner tTestRunner

func (_ tTestRunner) Index(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("TestRunner.Index", args).Url
}

func (_ tTestRunner) Run(
		suite string,
		test string,
		) string {
	args := make(map[string]string)

	revel.Unbind(args, "suite", suite)
	revel.Unbind(args, "test", test)
	return revel.MainRouter.Reverse("TestRunner.Run", args).Url
}

func (_ tTestRunner) List(
		) string {
	args := make(map[string]string)

	return revel.MainRouter.Reverse("TestRunner.List", args).Url
}

<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"net/url"
	"os"
	"os/signal"
	"path/filepath"
	"time"

	"github.com/gorilla/websocket"
	"github.com/mohae/autofact/conf"
	czap "github.com/mohae/zap"
	"github.com/uber-go/zap"
)

const (
	addressVar = "address"
	aVar       = "a"
	portVar    = "port"
	pVar       = "p"
)

var (
	connFile    = "autofact.json"
	collectFile = "autocollect.json"
	// This is the default directory for autofact-client app data.
	autofactPath    = "$HOME/.autofact"
	autofactEnvName = "AUTOFACT_PATH"
	// configuration info
	connConf    conf.Conn
	collectConf conf.Collect

	// client configuration: used for serverless

	serverless bool
)

// Vars for logging and local data output, if applicable.
var (
	log      zap.Logger // application log
	loglevel = zap.LevelFlag("loglevel", zap.WarnLevel, "log level")
	logDest  string
	logOut   *os.File

	data     czap.Logger // use mohae's fork to support level description override
	dataDest string
	dataOut  *os.File
)

// TODO: reconcile these flags with config file usage.  Probably add contour
// to handle this after the next refactor of contour.
// TODO: make connectInterval/period handling consistent, e.g. should they be
// flags, what is precedence in relation to Conn?
func init() {
	flag.StringVar(&connConf.ServerAddress, addressVar, "127.0.0.1", "the server address")
	flag.StringVar(&connConf.ServerAddress, aVar, "127.0.0.1", "the server address (short)")
	flag.StringVar(&connConf.ServerPort, portVar, "8675", "the connection port")
	flag.StringVar(&connConf.ServerPort, pVar, "8675", "the connection port (short)")
	flag.StringVar(&logDest, "logdestination", "stderr", "log output destination; if empty stderr will be used")
	flag.StringVar(&logDest, "l", "stderr", "log output; if empty stderr will be used")
	flag.StringVar(&dataDest, "datadestination", "stdout", "serverless mode data output destination, if empty stderr will be used")
	flag.StringVar(&dataDest, "d", "stdout", "serverless mode data output destination, if empty stderr will be used")
	flag.BoolVar(&serverless, "serverless", false, "serverless: the client will run standalone and write the collected data to the log")
	connConf.ConnectInterval.Duration = 5 * time.Second
	connConf.ConnectPeriod.Duration = 15 * time.Minute

	// override czap description for InfoLevel
	czap.WarnString = "data"
}

func main() {
	// Load the AUTOPATH value
	tmp := os.Getenv(autofactEnvName)
	if tmp != "" {
		autofactPath = tmp
	}
	autofactPath = os.ExpandEnv(autofactPath)

	// make sure the autofact path exists (create if it doesn't)
	err := os.MkdirAll(autofactPath, 0760)
	if err != nil {
		fmt.Fprintf(os.Stderr, "unable to create AUTOFACT_PATH: %s\n", err)
		fmt.Fprintln(os.Stderr, "startup error: exiting")
		os.Exit(1)
	}

	// finalize the paths
	connFile = filepath.Join(autofactPath, connFile)

	// process the settings: this gets read first just in case flags override
	var connMsg string
	err = connConf.Load(connFile)
	if err != nil {
		// capture the error for logging once it is setup and continue.  An error
		// is not a show stopper as the file may not exist if this is the first
		// time autofact has run on this node.
		connMsg = fmt.Sprintf("using default connection settings")
	}

	// Parse the flags.
	flag.Parse()

	// now that everything is parsed; set up logging
	SetLogging()
	defer CloseOut()
	// if there was an error reading the connection configuration and this isn't
	// being run serverless, log it
	if connMsg != "" && !serverless {
		log.Warn(
			err.Error(),
			zap.String("op", fmt.Sprintf("load %s", connFile)),
			zap.String("conf", connMsg),
		)
	}

	// if serverless: load the collection configuration
	if serverless {
		collectFile = filepath.Join(autofactPath, collectFile)
		err = collectConf.Load(collectFile)
		if err != nil {
			log.Warn(
				err.Error(),
				zap.String("op", fmt.Sprintf("load %s", collectFile)),
				zap.String("conf", "using default collect settings"),
			)
			collectConf.UseDefaults()
		}
	}

	// TODO add env var support

	// get a client
	c := NewClient(connConf, collectFile)
	c.AutoPath = autofactPath

	// handle signals
	go handleSignals(c)

	// doneCh is used to signal that the connection has been closed
	doneCh := make(chan struct{})

	// Set up the output destination.
	if serverless { // open the datafile to use
		SetDataOut()
	} else { // connect to the server
		// connect to the Server
		c.ServerURL = url.URL{Scheme: "ws", Host: fmt.Sprintf("%s:%s", c.ServerAddress, c.ServerPort), Path: "/client"}

		// must have a connection before doing anything
		for i := 0; i < 3; i++ {
			connected := c.Connect()
			if connected {
				break
			}
			// retry on fail until retry attempts have been exceeded
		}
		if !c.IsConnected() {
			log.Error(
				"unable to connect",
				zap.String("server", c.ServerURL.String()),
			)
			CloseOut() // defer doesn't run on fatal
			os.Exit(1)
		}
	}

	// set up the data processing
	if serverless {
		// since there isn't a server pull for healthbeat, a local ticker is started
		go c.HealthbeatLocal(doneCh)
	} else {
		// assign the
		c.LoadAvg = LoadAvgFB
		go c.Listen(doneCh)
		go c.MemInfo(doneCh)
		go c.CPUUtilization(doneCh)
		go c.NetUsage(doneCh)
		// start the connection handler
		go c.MessageWriter(doneCh)
	}
	// start the go routines for socket communications
	if !serverless {
		// if connected, save the conf: this will also save the ClientID
		err = c.Conn.Save()
		if err != nil {
			log.Error(
				err.Error(),
				zap.String("op", "save conn"),
				zap.String("file", c.Conn.Filename),
			)
		}
	}
	<-doneCh
}

func SetLogging() {
	// if logfile is empty, use Stderr
	var err error
	if logDest == "" || logDest == "stderr" {
		logOut = os.Stderr
		goto newLog
	}
	if logDest == "stdout" {
		logOut = os.Stdout
		goto newLog
	}
	logOut, err = os.OpenFile(logDest, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0664)
	if err != nil {
		panic(err)
	}
newLog:
	log = zap.New(
		zap.NewJSONEncoder(
			zap.RFC3339Formatter("ts"),
		),
		zap.Output(logOut),
	)
	log.SetLevel(*loglevel)
}

func SetDataOut() {
	var err error
	if dataDest == "" || dataDest == "stdout" {
		dataOut = os.Stdout
		goto newData
	}
	if dataDest == "stderr" {
		dataOut = os.Stderr
		goto newData
	}
	dataOut, err = os.OpenFile(dataDest, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0664)
	if err != nil {
		log.Fatal(
			err.Error(),
			zap.String("op", "open datafile"),
			zap.String("filename", dataDest),
		)
	}
newData:
	data = czap.New(
		czap.NewJSONEncoder(
			czap.RFC3339Formatter("ts"),
		),
		czap.Output(dataOut),
	)
	data.SetLevel(czap.WarnLevel)
}

// CloseOut closes the local output destinations before shutdown.
func CloseOut() {
	if logOut != nil {
		logOut.Close()
	}
	// If running serverless, close the data file.
	if serverless {
		dataOut.Close()
	}
}

func handleSignals(c *Client) {
	ch := make(chan os.Signal, 1)
	signal.Notify(ch, os.Interrupt)
	v := <-ch
	log.Info(
		"os signal received: shutting down autofact",
		zap.Object("signal", v.String()),
	)
	// If there's a connection send a close signal
	if c.IsConnected() {
		log.Debug(
			"closing connection",
			zap.String("op", "shutdown"),
		)
		c.WS.WriteMessage(websocket.CloseMessage, []byte(string(c.Conn.ID)+" shutting down"))
	}
	CloseOut()

	os.Exit(1)
}
<commit_msg>save default settings as the collectFile when one doesn't already exist<commit_after>package main

import (
	"flag"
	"fmt"
	"net/url"
	"os"
	"os/signal"
	"path/filepath"
	"time"

	"github.com/gorilla/websocket"
	"github.com/mohae/autofact/conf"
	czap "github.com/mohae/zap"
	"github.com/uber-go/zap"
)

const (
	addressVar = "address"
	aVar       = "a"
	portVar    = "port"
	pVar       = "p"
)

var (
	connFile    = "autofact.json"
	collectFile = "autocollect.json"
	// This is the default directory for autofact-client app data.
	autofactPath    = "$HOME/.autofact"
	autofactEnvName = "AUTOFACT_PATH"
	// configuration info
	connConf    conf.Conn
	collectConf conf.Collect

	// client configuration: used for serverless

	serverless bool
)

// Vars for logging and local data output, if applicable.
var (
	log      zap.Logger // application log
	loglevel = zap.LevelFlag("loglevel", zap.WarnLevel, "log level")
	logDest  string
	logOut   *os.File

	data     czap.Logger // use mohae's fork to support level description override
	dataDest string
	dataOut  *os.File
)

// TODO: reconcile these flags with config file usage.  Probably add contour
// to handle this after the next refactor of contour.
// TODO: make connectInterval/period handling consistent, e.g. should they be
// flags, what is precedence in relation to Conn?
func init() {
	flag.StringVar(&connConf.ServerAddress, addressVar, "127.0.0.1", "the server address")
	flag.StringVar(&connConf.ServerAddress, aVar, "127.0.0.1", "the server address (short)")
	flag.StringVar(&connConf.ServerPort, portVar, "8675", "the connection port")
	flag.StringVar(&connConf.ServerPort, pVar, "8675", "the connection port (short)")
	flag.StringVar(&logDest, "logdestination", "stderr", "log output destination; if empty stderr will be used")
	flag.StringVar(&logDest, "l", "stderr", "log output; if empty stderr will be used")
	flag.StringVar(&dataDest, "datadestination", "stdout", "serverless mode data output destination, if empty stderr will be used")
	flag.StringVar(&dataDest, "d", "stdout", "serverless mode data output destination, if empty stderr will be used")
	flag.BoolVar(&serverless, "serverless", false, "serverless: the client will run standalone and write the collected data to the log")
	connConf.ConnectInterval.Duration = 5 * time.Second
	connConf.ConnectPeriod.Duration = 15 * time.Minute

	// override czap description for InfoLevel
	czap.WarnString = "data"
}

func main() {
	// Load the AUTOPATH value
	tmp := os.Getenv(autofactEnvName)
	if tmp != "" {
		autofactPath = tmp
	}
	autofactPath = os.ExpandEnv(autofactPath)

	// make sure the autofact path exists (create if it doesn't)
	err := os.MkdirAll(autofactPath, 0760)
	if err != nil {
		fmt.Fprintf(os.Stderr, "unable to create AUTOFACT_PATH: %s\n", err)
		fmt.Fprintln(os.Stderr, "startup error: exiting")
		os.Exit(1)
	}

	// finalize the paths
	connFile = filepath.Join(autofactPath, connFile)

	// process the settings: this gets read first just in case flags override
	var connMsg string
	err = connConf.Load(connFile)
	if err != nil {
		// capture the error for logging once it is setup and continue.  An error
		// is not a show stopper as the file may not exist if this is the first
		// time autofact has run on this node.
		connMsg = fmt.Sprintf("using default connection settings")
	}

	// Parse the flags.
	flag.Parse()

	// now that everything is parsed; set up logging
	SetLogging()
	defer CloseOut()
	// if there was an error reading the connection configuration and this isn't
	// being run serverless, log it
	if connMsg != "" && !serverless {
		log.Warn(
			err.Error(),
			zap.String("op", fmt.Sprintf("load %s", connFile)),
			zap.String("conf", connMsg),
		)
	}

	// if serverless: load the collection configuration
	if serverless {
		collectFile = filepath.Join(autofactPath, collectFile)
		err = collectConf.Load(collectFile)
		if err != nil {
			log.Warn(
				err.Error(),
				zap.String("op", fmt.Sprintf("load %s", collectFile)),
				zap.String("conf", "using default collect settings"),
			)
			collectConf.UseDefaults()
			err = collectConf.SaveAsJSON(collectFile)
			if err != nil {
				log.Warn(
					err.Error(),
					zap.String("op", fmt.Sprintf("save %s", collectFile)),
				)
			}
		}
	}

	// TODO add env var support

	// get a client
	c := NewClient(connConf, collectFile)
	c.AutoPath = autofactPath

	// handle signals
	go handleSignals(c)

	// doneCh is used to signal that the connection has been closed
	doneCh := make(chan struct{})

	// Set up the output destination.
	if serverless { // open the datafile to use
		SetDataOut()
	} else { // connect to the server
		// connect to the Server
		c.ServerURL = url.URL{Scheme: "ws", Host: fmt.Sprintf("%s:%s", c.ServerAddress, c.ServerPort), Path: "/client"}

		// must have a connection before doing anything
		for i := 0; i < 3; i++ {
			connected := c.Connect()
			if connected {
				break
			}
			// retry on fail until retry attempts have been exceeded
		}
		if !c.IsConnected() {
			log.Error(
				"unable to connect",
				zap.String("server", c.ServerURL.String()),
			)
			CloseOut() // defer doesn't run on fatal
			os.Exit(1)
		}
	}

	// set up the data processing
	if serverless {
		// since there isn't a server pull for healthbeat, a local ticker is started
		go c.HealthbeatLocal(doneCh)
	} else {
		// assign the
		c.LoadAvg = LoadAvgFB
		go c.Listen(doneCh)
		go c.MemInfo(doneCh)
		go c.CPUUtilization(doneCh)
		go c.NetUsage(doneCh)
		// start the connection handler
		go c.MessageWriter(doneCh)
	}
	// start the go routines for socket communications
	if !serverless {
		// if connected, save the conf: this will also save the ClientID
		err = c.Conn.Save()
		if err != nil {
			log.Error(
				err.Error(),
				zap.String("op", "save conn"),
				zap.String("file", c.Conn.Filename),
			)
		}
	}
	<-doneCh
}

func SetLogging() {
	// if logfile is empty, use Stderr
	var err error
	if logDest == "" || logDest == "stderr" {
		logOut = os.Stderr
		goto newLog
	}
	if logDest == "stdout" {
		logOut = os.Stdout
		goto newLog
	}
	logOut, err = os.OpenFile(logDest, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0664)
	if err != nil {
		panic(err)
	}
newLog:
	log = zap.New(
		zap.NewJSONEncoder(
			zap.RFC3339Formatter("ts"),
		),
		zap.Output(logOut),
	)
	log.SetLevel(*loglevel)
}

func SetDataOut() {
	var err error
	if dataDest == "" || dataDest == "stdout" {
		dataOut = os.Stdout
		goto newData
	}
	if dataDest == "stderr" {
		dataOut = os.Stderr
		goto newData
	}
	dataOut, err = os.OpenFile(dataDest, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0664)
	if err != nil {
		log.Fatal(
			err.Error(),
			zap.String("op", "open datafile"),
			zap.String("filename", dataDest),
		)
	}
newData:
	data = czap.New(
		czap.NewJSONEncoder(
			czap.RFC3339Formatter("ts"),
		),
		czap.Output(dataOut),
	)
	data.SetLevel(czap.WarnLevel)
}

// CloseOut closes the local output destinations before shutdown.
func CloseOut() {
	if logOut != nil {
		logOut.Close()
	}
	// If running serverless, close the data file.
	if serverless {
		dataOut.Close()
	}
}

func handleSignals(c *Client) {
	ch := make(chan os.Signal, 1)
	signal.Notify(ch, os.Interrupt)
	v := <-ch
	log.Info(
		"os signal received: shutting down autofact",
		zap.Object("signal", v.String()),
	)
	// If there's a connection send a close signal
	if c.IsConnected() {
		log.Debug(
			"closing connection",
			zap.String("op", "shutdown"),
		)
		c.WS.WriteMessage(websocket.CloseMessage, []byte(string(c.Conn.ID)+" shutting down"))
	}
	CloseOut()

	os.Exit(1)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"expvar"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"syscall"
	"time"

	"github.com/ekanite/ekanite"
	"github.com/ekanite/ekanite/input"
)

var (
	stats = expvar.NewMap("ekanite")
)

// Program parameters
var datadir string
var tcpIface string
var udpIface string
var queryIface string
var batchSize int
var batchTimeout int
var indexMaxPending int
var gomaxprocs int
var numShards int
var retentionPeriod string
var cpuProfile string
var memProfile string
var noReport bool

// Flag set
var fs *flag.FlagSet

// Types
const (
	DefaultDataDir         = "/var/opt/ekanite"
	DefaultBatchSize       = 300
	DefaultBatchTimeout    = 1000
	DefaultIndexMaxPending = 1000
	DefaultNumShards       = 16
	DefaultRetentionPeriod = "168h"
	DefaultQueryAddr       = "localhost:9950"
	DefaultDiagsIface      = "localhost:9951"
	DefaultTCPServer       = "localhost:5514"
)

func main() {
	fs = flag.NewFlagSet("", flag.ExitOnError)
	var (
		datadir         = fs.String("datadir", DefaultDataDir, "Set data directory.")
		batchSize       = fs.Int("batchsize", DefaultBatchSize, "Indexing batch size.")
		batchTimeout    = fs.Int("batchtime", DefaultBatchTimeout, "Indexing batch timeout, in milliseconds.")
		indexMaxPending = fs.Int("maxpending", DefaultIndexMaxPending, "Maximum pending index events.")
		tcpIface        = fs.String("tcp", DefaultTCPServer, "Syslog server TCP bind address in the form host:port. If empty, not started.")
		udpIface        = fs.String("udp", "", "Syslog server UDP bind address in the form host:port. If not set, not started.")
		diagIface       = fs.String("diag", DefaultDiagsIface, "expvar and pprof bind address in the form host:port. If not set, not started.")
		queryIface      = fs.String("query", DefaultQueryAddr, "TCP Bind address for query server in the form host:port.")
		numShards       = fs.Int("numshards", DefaultNumShards, "Set number of shards per index.")
		retentionPeriod = fs.String("retention", DefaultRetentionPeriod, "Data retention period. Minimum is 24 hours")
		cpuProfile      = fs.String("cpuprof", "", "Where to write CPU profiling data. Not written if not set")
		memProfile      = fs.String("memprof", "", "Where to write memory profiling data. Not written if not set")
		noReport        = fs.Bool("noreport", false, "Do not report anonymous data on launch.")
	)
	fs.Usage = printHelp
	fs.Parse(os.Args[1:])

	absDataDir, err := filepath.Abs(*datadir)
	if err != nil {
		log.Fatalf("failed to get absolute data path for '%s': %s", *datadir, err.Error())
	}

	// Get the retention period.
	retention, err := time.ParseDuration(*retentionPeriod)
	if err != nil {
		log.Fatalf("failed to parse retention period '%s'", *retentionPeriod)
	}

	log.SetFlags(log.LstdFlags)
	log.SetPrefix("[ekanite] ")
	log.Printf("ekanite started using %s for index storage", absDataDir)

	runtime.GOMAXPROCS(runtime.NumCPU())
	log.Println("GOMAXPROCS set to", runtime.GOMAXPROCS(0))

	// Start the expvar handler if requested.
	if *diagIface != "" {
		sock, err := net.Listen("tcp", *diagIface)
		if err != nil {
			log.Fatalf("failed to create diag server: %s", err.Error())
		}
		go func() {
			log.Printf("diags now available at %s", *diagIface)
			http.Serve(sock, nil)
		}()
	}

	// Create and open the Engine.
	engine := ekanite.NewEngine(absDataDir)
	if engine == nil {
		log.Fatalf("failed to create indexing engine at %s", absDataDir)
	}
	engine.NumShards = *numShards
	engine.RetentionPeriod = retention

	if err := engine.Open(); err != nil {
		log.Fatalf("failed to open engine: %s", err.Error())
	}
	log.Printf("engine opened with shard number of %d, retention period of %s",
		engine.NumShards, engine.RetentionPeriod)

	// Start the query server.
	server := ekanite.NewServer(*queryIface, engine)
	if server == nil {
		log.Fatal("failed to create query server")
	}
	if err := server.Start(); err != nil {
		log.Fatalf("failed to start query server: %s", err.Error())
	}
	log.Printf("query server listening to %s", *queryIface)

	// Create and start the batcher.
	batcherTimeout := time.Duration(*batchTimeout) * time.Millisecond
	batcher := ekanite.NewBatcher(engine, *batchSize, batcherTimeout, *indexMaxPending)
	if batcher == nil {
		log.Fatal("failed to create indexing batcher")
	}

	errChan := make(chan error)
	if err := batcher.Start(errChan); err != nil {
		log.Fatalf("failed to start indexing batcher: %s", err.Error())
	}
	log.Printf("batching configured with size %d, timeout %s, max pending %d",
		*batchSize, batcherTimeout, *indexMaxPending)

	// Start draining batcher errors.
	go func() {
		for {
			select {
			case err := <-errChan:
				if err != nil {
					log.Printf("error indexing batch: %s", err.Error())
				}
			}
		}
	}()

	// Start TCP collector if requested.
	if *tcpIface != "" {
		collector := input.NewCollector("tcp", *tcpIface, nil)
		if collector == nil {
			log.Fatalf("failed to created TCP collector bound to %s", *tcpIface)
		}
		if err := collector.Start(batcher.C()); err != nil {
			log.Fatalf("failed to start TCP collector: %s", err.Error())
		}
		log.Printf("TCP collector listening to %s", *tcpIface)
	}

	// Start UDP collector if requested.
	if *udpIface != "" {
		collector := input.NewCollector("udp", *udpIface, nil)
		if collector == nil {
			log.Fatalf("failed to created UDP collector for to %s", *udpIface)
		}
		if err := collector.Start(batcher.C()); err != nil {
			log.Fatalf("failed to start UDP collector: %s", err.Error())
		}
		log.Printf("UDP collector listening to %s", *tcpIface)
	}

	// Start profiling.
	startProfile(*cpuProfile, *memProfile)

	if !*noReport {
		reportLaunch()
	}

	stats.Set("launch", time.Now().UTC())

	signalCh := make(chan os.Signal, 1)
	signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
	// Block until one of the signals above is received
	select {
	case <-signalCh:
		log.Println("signal received, shutting down...")
	}

	stopProfile()
}

// prof stores the file locations of active profiles.
var prof struct {
	cpu *os.File
	mem *os.File
}

// StartProfile initializes the cpu and memory profile, if specified.
func startProfile(cpuprofile, memprofile string) {
	if cpuprofile != "" {
		f, err := os.Create(cpuprofile)
		if err != nil {
			log.Fatalf("cpuprofile: %v", err)
		}
		log.Printf("writing CPU profile to: %s\n", cpuprofile)
		prof.cpu = f
		pprof.StartCPUProfile(prof.cpu)
	}

	if memprofile != "" {
		f, err := os.Create(memprofile)
		if err != nil {
			log.Fatalf("memprofile: %v", err)
		}
		log.Printf("writing memory profile to: %s\n", memprofile)
		prof.mem = f
		runtime.MemProfileRate = 4096
	}

}

// StopProfile closes the cpu and memory profiles if they are running.
func stopProfile() {
	if prof.cpu != nil {
		pprof.StopCPUProfile()
		prof.cpu.Close()
		log.Println("CPU profile stopped")
	}
	if prof.mem != nil {
		pprof.Lookup("heap").WriteTo(prof.mem, 0)
		prof.mem.Close()
		log.Println("memory profile stopped")
	}
}

func printHelp() {
	fmt.Println("ekanite [options]")
	fs.PrintDefaults()
}

func reportLaunch() {
	json := fmt.Sprintf(`{"os": "%s", "arch": "%s", "gomaxprocs": %d, "numcpu": %d, "numshards": %d, "app": "ekanited"}`,
		runtime.GOOS, runtime.GOARCH, runtime.GOMAXPROCS(0), runtime.NumCPU(), numShards)
	data := bytes.NewBufferString(json)
	client := http.Client{Timeout: time.Duration(5 * time.Second)}
	go client.Post("https://logs-01.loggly.com/inputs/8a0edd84-92ba-46e4-ada8-c529d0f105af/tag/reporting/",
		"application/json", data)
}
<commit_msg>Configure TLS if cert and key supplied<commit_after>package main

import (
	"bytes"
	"crypto/rand"
	"crypto/tls"
	"crypto/x509"
	"expvar"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"syscall"
	"time"

	"github.com/ekanite/ekanite"
	"github.com/ekanite/ekanite/input"
)

var (
	stats = expvar.NewMap("ekanite")
)

// Program parameters
var datadir string
var tcpIface string
var udpIface string
var caPemPath string
var caKeyPath string
var queryIface string
var batchSize int
var batchTimeout int
var indexMaxPending int
var gomaxprocs int
var numShards int
var retentionPeriod string
var cpuProfile string
var memProfile string
var noReport bool

// Flag set
var fs *flag.FlagSet

// Types
const (
	DefaultDataDir         = "/var/opt/ekanite"
	DefaultBatchSize       = 300
	DefaultBatchTimeout    = 1000
	DefaultIndexMaxPending = 1000
	DefaultNumShards       = 16
	DefaultRetentionPeriod = "168h"
	DefaultQueryAddr       = "localhost:9950"
	DefaultDiagsIface      = "localhost:9951"
	DefaultTCPServer       = "localhost:5514"
)

func main() {
	fs = flag.NewFlagSet("", flag.ExitOnError)
	var (
		datadir         = fs.String("datadir", DefaultDataDir, "Set data directory.")
		batchSize       = fs.Int("batchsize", DefaultBatchSize, "Indexing batch size.")
		batchTimeout    = fs.Int("batchtime", DefaultBatchTimeout, "Indexing batch timeout, in milliseconds.")
		indexMaxPending = fs.Int("maxpending", DefaultIndexMaxPending, "Maximum pending index events.")
		tcpIface        = fs.String("tcp", DefaultTCPServer, "Syslog server TCP bind address in the form host:port. If empty, not started.")
		udpIface        = fs.String("udp", "", "Syslog server UDP bind address in the form host:port. If not set, not started.")
		diagIface       = fs.String("diag", DefaultDiagsIface, "expvar and pprof bind address in the form host:port. If not set, not started.")
		caPemPath       = fs.String("pem", "", "path to CA PEM file for TLS-enabled TCP server. If not set, TLS not activated")
		caKeyPath       = fs.String("pem", "", "path to CA key file for TLS-enabled TCP server. If not set, TLS not activated")
		queryIface      = fs.String("query", DefaultQueryAddr, "TCP Bind address for query server in the form host:port.")
		numShards       = fs.Int("numshards", DefaultNumShards, "Set number of shards per index.")
		retentionPeriod = fs.String("retention", DefaultRetentionPeriod, "Data retention period. Minimum is 24 hours")
		cpuProfile      = fs.String("cpuprof", "", "Where to write CPU profiling data. Not written if not set")
		memProfile      = fs.String("memprof", "", "Where to write memory profiling data. Not written if not set")
		noReport        = fs.Bool("noreport", false, "Do not report anonymous data on launch.")
	)
	fs.Usage = printHelp
	fs.Parse(os.Args[1:])

	absDataDir, err := filepath.Abs(*datadir)
	if err != nil {
		log.Fatalf("failed to get absolute data path for '%s': %s", *datadir, err.Error())
	}

	// Get the retention period.
	retention, err := time.ParseDuration(*retentionPeriod)
	if err != nil {
		log.Fatalf("failed to parse retention period '%s'", *retentionPeriod)
	}

	log.SetFlags(log.LstdFlags)
	log.SetPrefix("[ekanite] ")
	log.Printf("ekanite started using %s for index storage", absDataDir)

	runtime.GOMAXPROCS(runtime.NumCPU())
	log.Println("GOMAXPROCS set to", runtime.GOMAXPROCS(0))

	// Start the expvar handler if requested.
	if *diagIface != "" {
		sock, err := net.Listen("tcp", *diagIface)
		if err != nil {
			log.Fatalf("failed to create diag server: %s", err.Error())
		}
		go func() {
			log.Printf("diags now available at %s", *diagIface)
			http.Serve(sock, nil)
		}()
	}

	// Create and open the Engine.
	engine := ekanite.NewEngine(absDataDir)
	if engine == nil {
		log.Fatalf("failed to create indexing engine at %s", absDataDir)
	}
	engine.NumShards = *numShards
	engine.RetentionPeriod = retention

	if err := engine.Open(); err != nil {
		log.Fatalf("failed to open engine: %s", err.Error())
	}
	log.Printf("engine opened with shard number of %d, retention period of %s",
		engine.NumShards, engine.RetentionPeriod)

	// Start the query server.
	server := ekanite.NewServer(*queryIface, engine)
	if server == nil {
		log.Fatal("failed to create query server")
	}
	if err := server.Start(); err != nil {
		log.Fatalf("failed to start query server: %s", err.Error())
	}
	log.Printf("query server listening to %s", *queryIface)

	// Create and start the batcher.
	batcherTimeout := time.Duration(*batchTimeout) * time.Millisecond
	batcher := ekanite.NewBatcher(engine, *batchSize, batcherTimeout, *indexMaxPending)
	if batcher == nil {
		log.Fatal("failed to create indexing batcher")
	}

	errChan := make(chan error)
	if err := batcher.Start(errChan); err != nil {
		log.Fatalf("failed to start indexing batcher: %s", err.Error())
	}
	log.Printf("batching configured with size %d, timeout %s, max pending %d",
		*batchSize, batcherTimeout, *indexMaxPending)

	// Start draining batcher errors.
	go func() {
		for {
			select {
			case err := <-errChan:
				if err != nil {
					log.Printf("error indexing batch: %s", err.Error())
				}
			}
		}
	}()

	// Start TCP collector if requested.
	if *tcpIface != "" {
		var tlsConfig *tls.Config
		if *caPemPath != "" && *caKeyPath != "" {
			tlsConfig, err = newTLSConfig(*caPemPath, *caKeyPath)
			if err != nil {
				log.Fatalf("failed to configure TLS: %s", err.Error())
			}
			log.Printf("TLS successfully configured")
		}

		collector := input.NewCollector("tcp", *tcpIface, tlsConfig)
		if collector == nil {
			log.Fatalf("failed to created TCP collector bound to %s", *tcpIface)
		}
		if err := collector.Start(batcher.C()); err != nil {
			log.Fatalf("failed to start TCP collector: %s", err.Error())
		}
		log.Printf("TCP collector listening to %s", *tcpIface)
	}

	// Start UDP collector if requested.
	if *udpIface != "" {
		collector := input.NewCollector("udp", *udpIface, nil)
		if collector == nil {
			log.Fatalf("failed to created UDP collector for to %s", *udpIface)
		}
		if err := collector.Start(batcher.C()); err != nil {
			log.Fatalf("failed to start UDP collector: %s", err.Error())
		}
		log.Printf("UDP collector listening to %s", *tcpIface)
	}

	// Start profiling.
	startProfile(*cpuProfile, *memProfile)

	if !*noReport {
		reportLaunch()
	}

	stats.Set("launch", time.Now().UTC())

	signalCh := make(chan os.Signal, 1)
	signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
	// Block until one of the signals above is received
	select {
	case <-signalCh:
		log.Println("signal received, shutting down...")
	}

	stopProfile()
}

func newTLSConfig(caPemPath, caKeyPath string) (*tls.Config, error) {
	var config *tls.Config

	caPem, err := ioutil.ReadFile(caPemPath)
	if err != nil {
		return nil, err
	}
	ca, err := x509.ParseCertificate(caPem)
	if err != nil {
		return nil, err
	}

	caKey, err := ioutil.ReadFile(caKeyPath)
	if err != nil {
		return nil, err
	}
	key, err := x509.ParsePKCS1PrivateKey(caKey)
	if err != nil {
		return nil, err
	}
	pool := x509.NewCertPool()
	pool.AddCert(ca)

	cert := tls.Certificate{
		Certificate: [][]byte{caPem},
		PrivateKey:  key,
	}

	config = &tls.Config{
		ClientAuth:   tls.RequireAndVerifyClientCert,
		Certificates: []tls.Certificate{cert},
		ClientCAs:    pool,
	}

	config.Rand = rand.Reader

	return config, nil
}

// prof stores the file locations of active profiles.
var prof struct {
	cpu *os.File
	mem *os.File
}

// StartProfile initializes the cpu and memory profile, if specified.
func startProfile(cpuprofile, memprofile string) {
	if cpuprofile != "" {
		f, err := os.Create(cpuprofile)
		if err != nil {
			log.Fatalf("cpuprofile: %v", err)
		}
		log.Printf("writing CPU profile to: %s\n", cpuprofile)
		prof.cpu = f
		pprof.StartCPUProfile(prof.cpu)
	}

	if memprofile != "" {
		f, err := os.Create(memprofile)
		if err != nil {
			log.Fatalf("memprofile: %v", err)
		}
		log.Printf("writing memory profile to: %s\n", memprofile)
		prof.mem = f
		runtime.MemProfileRate = 4096
	}

}

// StopProfile closes the cpu and memory profiles if they are running.
func stopProfile() {
	if prof.cpu != nil {
		pprof.StopCPUProfile()
		prof.cpu.Close()
		log.Println("CPU profile stopped")
	}
	if prof.mem != nil {
		pprof.Lookup("heap").WriteTo(prof.mem, 0)
		prof.mem.Close()
		log.Println("memory profile stopped")
	}
}

func printHelp() {
	fmt.Println("ekanite [options]")
	fs.PrintDefaults()
}

func reportLaunch() {
	json := fmt.Sprintf(`{"os": "%s", "arch": "%s", "gomaxprocs": %d, "numcpu": %d, "numshards": %d, "app": "ekanited"}`,
		runtime.GOOS, runtime.GOARCH, runtime.GOMAXPROCS(0), runtime.NumCPU(), numShards)
	data := bytes.NewBufferString(json)
	client := http.Client{Timeout: time.Duration(5 * time.Second)}
	go client.Post("https://logs-01.loggly.com/inputs/8a0edd84-92ba-46e4-ada8-c529d0f105af/tag/reporting/",
		"application/json", data)
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301  USA

package main

import (
	"fmt"
	"os"
	"runtime"

	"github.com/ethereum/go-ethereum/chain"
	"github.com/ethereum/go-ethereum/cmd/utils"
	"github.com/ethereum/go-ethereum/ethutil"
	"github.com/ethereum/go-ethereum/logger"
)

const (
	ClientIdentifier = "Ethereum(G)"
	Version          = "0.7.5"
)

var clilogger = logger.NewLogger("CLI")

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	utils.HandleInterrupt()

	// precedence: code-internal flag default < config file < environment variables < command line
	Init() // parsing command line

	// If the difftool option is selected ignore all other log output
	if DiffTool || Dump {
		LogLevel = 0
	}

	utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
	ethutil.Config.Diff = DiffTool
	ethutil.Config.DiffType = DiffType

	utils.InitDataDir(Datadir)

	utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile)

	db := utils.NewDatabase()
	err := utils.DBSanityCheck(db)
	if err != nil {
		fmt.Println(err)

		os.Exit(1)
	}

	keyManager := utils.NewKeyManager(KeyStore, Datadir, db)

	// create, import, export keys
	utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)

	clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier)

	ethereum := utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer)

	if Dump {
		var block *chain.Block

		if len(DumpHash) == 0 && DumpNumber == -1 {
			block = ethereum.ChainManager().CurrentBlock
		} else if len(DumpHash) > 0 {
			block = ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(DumpHash))
		} else {
			block = ethereum.ChainManager().GetBlockByNumber(uint64(DumpNumber))
		}

		if block == nil {
			fmt.Fprintln(os.Stderr, "block not found")

			// We want to output valid JSON
			fmt.Println("{}")

			os.Exit(1)
		}

		fmt.Printf("RLP: %x\nstate: %x\nhash: %x\n", ethutil.Rlp(block), block.GetRoot(), block.Hash())

		// Leave the Println. This needs clean output for piping
		fmt.Printf("%s\n", block.State().Dump())

		fmt.Println(block)

		os.Exit(0)
	}

	if ShowGenesis {
		utils.ShowGenesis(ethereum)
	}

	if StartMining {
		utils.StartMining(ethereum)
	}

	// better reworked as cases
	if StartJsConsole {
		InitJsConsole(ethereum)
	} else if len(InputFile) > 0 {
		ExecJsFile(ethereum, InputFile)
	}

	if StartRpc {
		utils.StartRpc(ethereum, RpcPort)
	}

	if StartWebSockets {
		utils.StartWebSockets(ethereum)
	}

	utils.StartEthereum(ethereum, UseSeed)

	// this blocks the thread
	ethereum.WaitForShutdown()
	logger.Flush()
}
<commit_msg>Remove failing Printf<commit_after>// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301  USA

package main

import (
	"fmt"
	"os"
	"runtime"

	"github.com/ethereum/go-ethereum/chain"
	"github.com/ethereum/go-ethereum/cmd/utils"
	"github.com/ethereum/go-ethereum/ethutil"
	"github.com/ethereum/go-ethereum/logger"
)

const (
	ClientIdentifier = "Ethereum(G)"
	Version          = "0.7.5"
)

var clilogger = logger.NewLogger("CLI")

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	utils.HandleInterrupt()

	// precedence: code-internal flag default < config file < environment variables < command line
	Init() // parsing command line

	// If the difftool option is selected ignore all other log output
	if DiffTool || Dump {
		LogLevel = 0
	}

	utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
	ethutil.Config.Diff = DiffTool
	ethutil.Config.DiffType = DiffType

	utils.InitDataDir(Datadir)

	utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile)

	db := utils.NewDatabase()
	err := utils.DBSanityCheck(db)
	if err != nil {
		fmt.Println(err)

		os.Exit(1)
	}

	keyManager := utils.NewKeyManager(KeyStore, Datadir, db)

	// create, import, export keys
	utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)

	clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier)

	ethereum := utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer)

	if Dump {
		var block *chain.Block

		if len(DumpHash) == 0 && DumpNumber == -1 {
			block = ethereum.ChainManager().CurrentBlock
		} else if len(DumpHash) > 0 {
			block = ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(DumpHash))
		} else {
			block = ethereum.ChainManager().GetBlockByNumber(uint64(DumpNumber))
		}

		if block == nil {
			fmt.Fprintln(os.Stderr, "block not found")

			// We want to output valid JSON
			fmt.Println("{}")

			os.Exit(1)
		}

		// block.GetRoot() does not exist
		//fmt.Printf("RLP: %x\nstate: %x\nhash: %x\n", ethutil.Rlp(block), block.GetRoot(), block.Hash())

		// Leave the Println. This needs clean output for piping
		fmt.Printf("%s\n", block.State().Dump())

		fmt.Println(block)

		os.Exit(0)
	}

	if ShowGenesis {
		utils.ShowGenesis(ethereum)
	}

	if StartMining {
		utils.StartMining(ethereum)
	}

	// better reworked as cases
	if StartJsConsole {
		InitJsConsole(ethereum)
	} else if len(InputFile) > 0 {
		ExecJsFile(ethereum, InputFile)
	}

	if StartRpc {
		utils.StartRpc(ethereum, RpcPort)
	}

	if StartWebSockets {
		utils.StartWebSockets(ethereum)
	}

	utils.StartEthereum(ethereum, UseSeed)

	// this blocks the thread
	ethereum.WaitForShutdown()
	logger.Flush()
}
<|endoftext|>


<commit_before>package main

type InstanceMetadata struct {
	ID         string
	Name       string
	Version    string
	Hostname   string
	Zone       string
	Project    string
	InternalIP string
	ExternalIP string
	LBRequest  string
	ClientIP   string
	Error      string
}

const (
	html = `<!doctype html>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/css/materialize.min.css">

<title>Frontend Web Server</title>

Backend that serviced this request

	  Name
	  {{.Name}}

	  Version
	  {{.Version}}

	  Instance ID
	  {{.ID}}

	  Hostname
	  {{.Hostname}}

	  Zone
	  {{.Zone}}

	  Project
	  {{.Project}}

	  Internal IP
	  {{.InternalIP}}

	  External IP
	  {{.ExternalIP}}

Proxy that handled this request

	  Request Headers

{{.LBRequest}}

		Error
		{{.Error}}

`
)
<commit_msg>Add color comment<commit_after>package main

type InstanceMetadata struct {
	ID         string
	Name       string
	Version    string
	Hostname   string
	Zone       string
	Project    string
	InternalIP string
	ExternalIP string
	LBRequest  string
	ClientIP   string
	Error      string
}

const (
	html = `<!doctype html>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/css/materialize.min.css">

<title>Frontend Web Server</title>

Backend that serviced this request

	  Name
	  {{.Name}}

	  Version
	  {{.Version}}

	  Instance ID
	  {{.ID}}

	  Hostname
	  {{.Hostname}}

	  Zone
	  {{.Zone}}

	  Project
	  {{.Project}}

	  Internal IP
	  {{.InternalIP}}

	  External IP
	  {{.ExternalIP}}

Proxy that handled this request

	  Request Headers

{{.LBRequest}}

		Error
		{{.Error}}

`
)
<|endoftext|>


<commit_before>package sandbox

import (
	"github.com/Shopify/go-lua"
)

type WorldState struct {
	Lighting map[Direction]float64
}

type NewState struct {
	MoveDir Direction
}

type Node struct {
	resume  chan<- WorldState
	respond <-chan NewState
}

func (n *Node) Update(state WorldState) <-chan NewState {
	n.resume <- state
	return n.respond
}

func AddNode(program string) *Node {
	// Make the communication channels
	resume := make(chan WorldState)
	respond := make(chan NewState)

	n := Node{
		resume:  resume,
		respond: respond,
	}

	go runNode(internalNode{
		program: program,
		resume:  resume,
		respond: respond,
	})

	return &n
}

type internalNode struct {
	program string
	resume  <-chan WorldState
	respond chan<- NewState
}

type Direction int

const (
	Left Direction = iota
	Right
	Up
	Down
)

func addIntFunc(l *lua.State, name string, fn func(*lua.State, int) int) {
	l.PushGoFunction(func(l *lua.State) int {
		if l.Top() != 1 {
			l.PushString("Wrong number of arguments")
			l.Error()
			return 0
		}

		i, ok := l.ToInteger(1)
		if !ok {
			l.PushString("Wrong argument type")
			l.Error()
			return 0
		}

		return fn(l, i)
	})

	l.SetGlobal(name)
}

func addVoidFunc(l *lua.State, name string, fn func(*lua.State) int) {
	l.PushGoFunction(func(l *lua.State) int {
		if l.Top() != 0 {
			l.PushString("Too many arguments to void function")
			l.Error()
			return 0
		}

		return fn(l)
	})

	l.SetGlobal(name)
}

func addDirFunc(l *lua.State, name string, fn func(*lua.State, Direction) int) {
	l.PushGoFunction(func(l *lua.State) int {
		argCount := l.Top()
		if argCount != 1 {
			l.PushString("incorrect number of arguments") // XXX Include name of function
			l.Error()
			return 0
		}

		s, ok := l.ToString(1)
		if !ok {
			l.PushString("incorrect type of argument") // XXX Include name of function
			l.Error()
			return 0
		}

		var d Direction
		if s == "left" {
			d = Left
		} else if s == "right" {
			d = Right
		} else if s == "up" {
			d = Up
		} else if s == "down" {
			d = Down
		}

		return fn(l, d)
	})

	l.SetGlobal(name)
}

func runNode(node internalNode) {
	l := lua.NewState()

	world := <-node.resume

	addDirFunc(l, "grow", func(l *lua.State, d Direction) int {
		var state NewState
		state.MoveDir = d

		// Send a response and wait
		node.respond <- state
		world = <-node.resume

		return 0
	})

	addDirFunc(l, "lighting", func(l *lua.State, d Direction) int {
		l.PushNumber(world.Lighting[d])
		return 1
	})

	lua.LoadString(l, node.program)
}
<commit_msg>I think i wrote something or something<commit_after>package main

import (
	"fmt"
	"github.com/Shopify/go-lua"
	"time"
)

type WorldState struct {
	Lighting map[Direction]float64
}

type NewState struct {
	MoveDir Direction
}

type Node struct {
	resume  chan<- WorldState
	respond <-chan NewState
}

func (n *Node) Update(state WorldState) <-chan NewState {
	n.resume <- state
	return n.respond
}

func AddNode(program string) *Node {
	// Make the communication channels
	resume := make(chan WorldState)
	respond := make(chan NewState)

	n := Node{
		resume:  resume,
		respond: respond,
	}

	in := internalNode{
		program: program,
		resume:  resume,
		respond: respond,
	}

	go runNode(in)

	return &n
}

type internalNode struct {
	program string
	resume  <-chan WorldState
	respond chan<- NewState
}

type Direction int

const (
	Left Direction = iota
	Right
	Up
	Down
)

func watchLuaThread(l *lua.State, d time.Duration) {
	end_time := time.Now().Add(d)
	setLuaTimeoutHook(l, 500, func() {
		if time.Now().After(end_time) {
			panic("AAAAHHHH!!!")
		}
	})
	l.ProtectedCall(0, lua.MultipleReturns, 0)
}

func setLuaTimeoutHook(l *lua.State, count int, callback func()) {
	lua.SetDebugHook(l, func(l *lua.State, ar lua.Debug) {
		callback()
	}, lua.MaskCount, count)
}

func addIntFunc(l *lua.State, name string, fn func(*lua.State, int) int) {
	l.PushGoFunction(func(l *lua.State) int {
		if l.Top() != 1 {
			l.PushString("Wrong number of arguments")
			l.Error()
			return 0
		}

		i, ok := l.ToInteger(1)
		if !ok {
			l.PushString("Wrong argument type")
			l.Error()
			return 0
		}

		return fn(l, i)
	})

	l.SetGlobal(name)
}

func addVoidFunc(l *lua.State, name string, fn func(*lua.State) int) {
	l.PushGoFunction(func(l *lua.State) int {
		if l.Top() != 0 {
			l.PushString("Too many arguments to void function")
			l.Error()
			return 0
		}

		return fn(l)
	})

	l.SetGlobal(name)
}

func addDirFunc(l *lua.State, name string, fn func(*lua.State, Direction) int) {
	l.PushGoFunction(func(l *lua.State) int {
		argCount := l.Top()
		if argCount != 1 {
			l.PushString("incorrect number of arguments") // XXX Include name of function
			l.Error()
			return 0
		}

		s, ok := l.ToString(1)
		if !ok {
			l.PushString("incorrect type of argument") // XXX Include name of function
			l.Error()
			return 0
		}

		var d Direction
		if s == "left" {
			d = Left
		} else if s == "right" {
			d = Right
		} else if s == "up" {
			d = Up
		} else if s == "down" {
			d = Down
		}

		return fn(l, d)
	})

	l.SetGlobal(name)
}

func runNode(node internalNode) {
	defer func() {
		if r := recover(); r != nil {
			close(node.respond)
		}
	}()

	l := lua.NewState()

	world := <-node.resume

	addDirFunc(l, "grow", func(l *lua.State, d Direction) int {
		var state NewState
		state.MoveDir = d

		// Send a response and wait
		node.respond <- state
		world = <-node.resume

		return 0
	})

	addDirFunc(l, "lighting", func(l *lua.State, d Direction) int {
		l.PushNumber(world.Lighting[d])
		return 1
	})

	lua.LoadString(l, node.program)
	watchLuaThread(l, time.Duration(500)*time.Millisecond)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/immortal/immortal"
	"os"
)

var version string

func main() {
	parser := &immortal.Parse{
		UserFinder: &immortal.User{},
	}

	// flag set
	fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
	fs.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [-v -ctrl] [-d dir] [-e dir] [-f pidfile] [-l logfile] [-logger logger] [-p child_pidfile] [-P supervisor_pidfile] [-u user] command\n\n   command\n        The command with arguments if any, to supervise\n\n", os.Args[0])
		fs.PrintDefaults()
	}

	flags, err := immortal.ParseArgs(parser, fs)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	//	 if -v print version
	if flags.Version {
		fmt.Printf("%s\n", version)
		os.Exit(0)
	}

	fmt.Printf("%#v", flags)
}
<commit_msg>	modified:   cmd/immortal/main.go<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/immortal/immortal"
	"github.com/immortal/natcasesort"
	"os"
	"sort"
)

var version string

func main() {
	parser := &immortal.Parse{
		UserFinder: &immortal.User{},
	}

	// flag set
	fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
	fs.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [-v -ctrl] [-d dir] [-e dir] [-f pidfile] [-l logfile] [-logger logger] [-p child_pidfile] [-P supervisor_pidfile] [-u user] command\n\n   command\n        The command with arguments if any, to supervise\n\n", os.Args[0])

		var flags []string
		fs.VisitAll(func(f *flag.Flag) {
			flags = append(flags, f.Name)
		})
		sort.Sort(natcasesort.Sort(flags))
		for _, v := range flags {
			f := fs.Lookup(v)
			s := fmt.Sprintf("  -%s", f.Name)
			name, usage := flag.UnquoteUsage(f)
			if len(name) > 0 {
				s += " " + name
			}
			if len(s) <= 4 {
				s += "\t"
			} else {
				s += "\n    \t"
			}
			s += usage
			fmt.Println(s)
		}
	}

	flags, err := immortal.ParseArgs(parser, fs)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	// if -v print version
	if flags.Version {
		fmt.Printf("%s\n", version)
		os.Exit(0)
	}

	fmt.Printf("%#v", flags)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	"github.com/hoffie/larasync/api"
	"github.com/hoffie/larasync/repository"
)

// uploader handles uploads from server to client
type uploader struct {
	client *api.Client
	r      *repository.ClientRepository
}

// pushAll ensures that the remote state is synced with the local state.
func (ul *uploader) pushAll() error {
	return ul.uploadNIBs()
}

// uploadNIBs uploads all local NIBs and content of the NIBs to
// the server.
func (ul *uploader) uploadNIBs() error {
	r := ul.r
	nibs, err := r.GetAllNibs()
	if err != nil {
		return fmt.Errorf("unable to get NIB list (%s)", err)
	}

	for nib := range nibs {
		err = ul.uploadNIB(nib)
		if err != nil {
			return err
		}
	}

	return nil
}

// uploadNIB uploads a single passed NIB to the remote server.
func (ul *uploader) uploadNIB(nib *repository.NIB) error {
	r := ul.r
	client := ul.client
	objectIDs := nib.AllObjectIDs()

	for _, objectID := range objectIDs {
		err := ul.uploadObject(objectID)
		if err != nil {
			return err
		}
	}
	nibReader, err := r.GetNIBReader(nib.ID)
	if err != nil {
		return err
	}
	defer nibReader.Close()

	//FIXME We currently assume that the server will prevent us
	// from overwriting data we are not supposed to be overwriting.
	// This will be implemented as part of #105
	err = client.PutNIB(nib.ID, nibReader)
	if err != nil {
		return fmt.Errorf("uploading nib %s failed (%s)", nib.ID, err)
	}

	return nil
}

func (ul *uploader) uploadObject(objectID string) error {
	r := ul.r
	client := ul.client

	object, err := r.GetObjectData(objectID)
	if err != nil {
		return fmt.Errorf("unable to load object %s (%s)\n", objectID, err)
	}
	defer object.Close()
	//FIXME We currently upload all objects, even multiple times
	// in some cases and even although they may already exist on
	// the server. This is not as well performing as it might be.
	err = client.PutObject(objectID, object)
	if err != nil {
		return fmt.Errorf("uploading object %s failed (%s)", objectID, err)
	}
	return nil
}
<commit_msg>cmd/lara: remove obsolete comment regarding #105<commit_after>package main

import (
	"fmt"

	"github.com/hoffie/larasync/api"
	"github.com/hoffie/larasync/repository"
)

// uploader handles uploads from server to client
type uploader struct {
	client *api.Client
	r      *repository.ClientRepository
}

// pushAll ensures that the remote state is synced with the local state.
func (ul *uploader) pushAll() error {
	return ul.uploadNIBs()
}

// uploadNIBs uploads all local NIBs and content of the NIBs to
// the server.
func (ul *uploader) uploadNIBs() error {
	r := ul.r
	nibs, err := r.GetAllNibs()
	if err != nil {
		return fmt.Errorf("unable to get NIB list (%s)", err)
	}

	for nib := range nibs {
		err = ul.uploadNIB(nib)
		if err != nil {
			return err
		}
	}

	return nil
}

// uploadNIB uploads a single passed NIB to the remote server.
func (ul *uploader) uploadNIB(nib *repository.NIB) error {
	r := ul.r
	client := ul.client
	objectIDs := nib.AllObjectIDs()

	for _, objectID := range objectIDs {
		err := ul.uploadObject(objectID)
		if err != nil {
			return err
		}
	}
	nibReader, err := r.GetNIBReader(nib.ID)
	if err != nil {
		return err
	}
	defer nibReader.Close()

	err = client.PutNIB(nib.ID, nibReader)
	if err != nil {
		return fmt.Errorf("uploading nib %s failed (%s)", nib.ID, err)
	}

	return nil
}

func (ul *uploader) uploadObject(objectID string) error {
	r := ul.r
	client := ul.client

	object, err := r.GetObjectData(objectID)
	if err != nil {
		return fmt.Errorf("unable to load object %s (%s)\n", objectID, err)
	}
	defer object.Close()
	//FIXME We currently upload all objects, even multiple times
	// in some cases and even although they may already exist on
	// the server. This is not as well performing as it might be.
	err = client.PutObject(objectID, object)
	if err != nil {
		return fmt.Errorf("uploading object %s failed (%s)", objectID, err)
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2016 The prometheus-operator 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.

package main

import (
	"flag"
	"fmt"
	"net"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"

	"github.com/coreos/prometheus-operator/pkg/alertmanager"
	"github.com/coreos/prometheus-operator/pkg/analytics"
	"github.com/coreos/prometheus-operator/pkg/api"
	"github.com/coreos/prometheus-operator/pkg/prometheus"
	"github.com/go-kit/kit/log"
)

var (
	cfg              prometheus.Config
	analyticsEnabled bool
)

func init() {
	flagset := flag.NewFlagSet(os.Args[0], flag.ExitOnError)

	flagset.StringVar(&cfg.Host, "apiserver", "", "API Server addr, e.g. ' - NOT RECOMMENDED FOR PRODUCTION - http://127.0.0.1:8080'. Omit parameter to run in on-cluster mode and utilize the service account token.")
	flagset.StringVar(&cfg.TLSConfig.CertFile, "cert-file", "", " - NOT RECOMMENDED FOR PRODUCTION - Path to public TLS certificate file.")
	flagset.StringVar(&cfg.TLSConfig.KeyFile, "key-file", "", "- NOT RECOMMENDED FOR PRODUCTION - Path to private TLS certificate file.")
	flagset.StringVar(&cfg.TLSConfig.CAFile, "ca-file", "", "- NOT RECOMMENDED FOR PRODUCTION - Path to TLS CA file.")
	flagset.BoolVar(&cfg.TLSInsecure, "tls-insecure", false, "- NOT RECOMMENDED FOR PRODUCTION - Don't verify API server's CA certificate.")
	flagset.BoolVar(&analyticsEnabled, "analytics", true, "Send analytical event (Cluster Created/Deleted etc.) to Google Analytics")

	flagset.Parse(os.Args[1:])
}

func Main() int {
	logger := log.NewContext(log.NewLogfmtLogger(os.Stdout)).
		With("ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)

	if analyticsEnabled {
		analytics.Enable()
	}

	po, err := prometheus.New(cfg, logger.With("component", "prometheusoperator"))
	if err != nil {
		fmt.Fprint(os.Stderr, err)
		return 1
	}

	ao, err := alertmanager.New(cfg, logger.With("component", "alertmanageroperator"))
	if err != nil {
		fmt.Fprint(os.Stderr, err)
		return 1
	}

	web, err := api.New(cfg, logger.With("component", "api"))
	if err != nil {
		fmt.Fprint(os.Stderr, err)
		return 1
	}

	mux := http.DefaultServeMux
	web.Register(mux)
	l, err := net.Listen("tcp", ":8080")
	if err != nil {
		fmt.Fprint(os.Stderr, err)
		return 1
	}

	stopc := make(chan struct{})
	errc := make(chan error)
	var wg sync.WaitGroup

	wg.Add(1)
	go func() {
		if err := po.Run(stopc); err != nil {
			errc <- err
		}
		wg.Done()
	}()

	wg.Add(1)
	go func() {
		if err := ao.Run(stopc); err != nil {
			errc <- err
		}
		wg.Done()
	}()

	go func() {
		if err := http.Serve(l, nil); err != nil {
			errc <- err
		}
	}()

	term := make(chan os.Signal)
	signal.Notify(term, os.Interrupt, syscall.SIGTERM)
	select {
	case <-term:
		logger.Log("msg", "Received SIGTERM, exiting gracefully...")
		l.Close()
		close(stopc)
		wg.Wait()
	case err := <-errc:
		logger.Log("msg", "Unhandled error received. Exiting...", "err", err)
		l.Close()
		close(stopc)
		wg.Wait()
		return 1
	}

	return 0
}

func main() {
	os.Exit(Main())
}
<commit_msg>Properly exit on error<commit_after>// Copyright 2016 The prometheus-operator 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.

package main

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

	"golang.org/x/sync/errgroup"

	"github.com/coreos/prometheus-operator/pkg/alertmanager"
	"github.com/coreos/prometheus-operator/pkg/analytics"
	"github.com/coreos/prometheus-operator/pkg/api"
	"github.com/coreos/prometheus-operator/pkg/prometheus"
	"github.com/go-kit/kit/log"
)

var (
	cfg              prometheus.Config
	analyticsEnabled bool
)

func init() {
	flagset := flag.NewFlagSet(os.Args[0], flag.ExitOnError)

	flagset.StringVar(&cfg.Host, "apiserver", "", "API Server addr, e.g. ' - NOT RECOMMENDED FOR PRODUCTION - http://127.0.0.1:8080'. Omit parameter to run in on-cluster mode and utilize the service account token.")
	flagset.StringVar(&cfg.TLSConfig.CertFile, "cert-file", "", " - NOT RECOMMENDED FOR PRODUCTION - Path to public TLS certificate file.")
	flagset.StringVar(&cfg.TLSConfig.KeyFile, "key-file", "", "- NOT RECOMMENDED FOR PRODUCTION - Path to private TLS certificate file.")
	flagset.StringVar(&cfg.TLSConfig.CAFile, "ca-file", "", "- NOT RECOMMENDED FOR PRODUCTION - Path to TLS CA file.")
	flagset.BoolVar(&cfg.TLSInsecure, "tls-insecure", false, "- NOT RECOMMENDED FOR PRODUCTION - Don't verify API server's CA certificate.")
	flagset.BoolVar(&analyticsEnabled, "analytics", true, "Send analytical event (Cluster Created/Deleted etc.) to Google Analytics")

	flagset.Parse(os.Args[1:])
}

func Main() int {
	logger := log.NewContext(log.NewLogfmtLogger(os.Stdout)).
		With("ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)

	if analyticsEnabled {
		analytics.Enable()
	}

	po, err := prometheus.New(cfg, logger.With("component", "prometheusoperator"))
	if err != nil {
		fmt.Fprint(os.Stderr, err)
		return 1
	}

	ao, err := alertmanager.New(cfg, logger.With("component", "alertmanageroperator"))
	if err != nil {
		fmt.Fprint(os.Stderr, err)
		return 1
	}

	web, err := api.New(cfg, logger.With("component", "api"))
	if err != nil {
		fmt.Fprint(os.Stderr, err)
		return 1
	}

	web.Register(http.DefaultServeMux)
	l, err := net.Listen("tcp", ":8080")
	if err != nil {
		fmt.Fprint(os.Stderr, err)
		return 1
	}

	ctx, cancel := context.WithCancel(context.Background())
	wg, ctx := errgroup.WithContext(ctx)

	wg.Go(func() error { return po.Run(ctx.Done()) })
	wg.Go(func() error { return ao.Run(ctx.Done()) })

	go http.Serve(l, nil)

	term := make(chan os.Signal)
	signal.Notify(term, os.Interrupt, syscall.SIGTERM)

	select {
	case <-term:
		logger.Log("msg", "Received SIGTERM, exiting gracefully...")
	case <-ctx.Done():
	}

	cancel()
	if err := wg.Wait(); err != nil {
		logger.Log("msg", "Unhandled error received. Exiting...", "err", err)
		return 1
	}

	return 0
}

func main() {
	os.Exit(Main())
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var RootCmd = &cobra.Command{
	Use: "tmsh",
	Run: func(cmd *cobra.Command, args []string) {
		cmd.Usage()
	},
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of tmsh-cli command.",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("tmsh v0.2.0")
	},
}

var execCmd = &cobra.Command{
	Use:   "exec [tmsh command]",
	Short: "Execute any command of TMSH",
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) < 1 {
			cmd.Usage()
			os.Exit(2)
		}

		bigip := NewSession()
		defer bigip.Close()

		ret, err := bigip.ExecuteCommand(args[0])
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

		fmt.Println(ret)
	},
}

func init() {
	cobra.OnInitialize()

	RootCmdFlags := RootCmd.Flags()
	RootCmdFlags.StringP("user", "u", "", "TMSH SSH username [$TMSH_USER]")
	RootCmdFlags.StringP("password", "p", "", "TMSH SSH passsord [$TMSH_PASSWORD]")
	RootCmdFlags.StringP("host", "H", "", "TMSH SSH host [$TMSH_HOST]")
	RootCmdFlags.StringP("port", "P", "22", "TMSH SSH port [$TMSH_PORT]")

	viper.AutomaticEnv()
	viper.BindPFlag("TMSH_USER", RootCmdFlags.Lookup("user"))
	viper.BindPFlag("TMSH_PASSWORD", RootCmdFlags.Lookup("password"))
	viper.BindPFlag("TMSH_HOST", RootCmdFlags.Lookup("host"))
	viper.BindPFlag("TMSH_PORT", RootCmdFlags.Lookup("port"))

	RootCmd.AddCommand(versionCmd)
	RootCmd.AddCommand(execCmd)
}
<commit_msg>Fix flag settings<commit_after>package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var RootCmd = &cobra.Command{
	Use: "tmsh",
	Run: func(cmd *cobra.Command, args []string) {
		cmd.Usage()
	},
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of tmsh-cli command.",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("tmsh v0.2.0")
	},
}

var execCmd = &cobra.Command{
	Use:   "exec [tmsh command]",
	Short: "Execute any command of TMSH",
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) < 1 {
			cmd.Usage()
			os.Exit(2)
		}

		bigip := NewSession()
		defer bigip.Close()

		ret, err := bigip.ExecuteCommand(args[0])
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

		fmt.Println(ret)
	},
}

func init() {
	cobra.OnInitialize()

	RootCmd.PersistentFlags().StringP("user", "u", "", "TMSH SSH username [$TMSH_USER]")
	RootCmd.PersistentFlags().StringP("password", "p", "", "TMSH SSH passsord [$TMSH_PASSWORD]")
	RootCmd.PersistentFlags().StringP("host", "H", "", "TMSH SSH host [$TMSH_HOST]")
	RootCmd.PersistentFlags().StringP("port", "P", "22", "TMSH SSH port [$TMSH_PORT]")

	flags := RootCmd.PersistentFlags()

	viper.AutomaticEnv()
	viper.BindPFlag("TMSH_USER", flags.Lookup("user"))
	viper.BindPFlag("TMSH_PASSWORD", flags.Lookup("password"))
	viper.BindPFlag("TMSH_HOST", flags.Lookup("host"))
	viper.BindPFlag("TMSH_PORT", flags.Lookup("port"))

	RootCmd.AddCommand(versionCmd)
	RootCmd.AddCommand(execCmd)
}
<|endoftext|>


<commit_before>// Copyright 2017 The go-interpreter 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 main

import (
	"flag"
	"log"
	"os"

	"github.com/go-interpreter/wagon/exec"
	"github.com/go-interpreter/wagon/validate"
	"github.com/go-interpreter/wagon/wasm"
)

func main() {
	log.SetPrefix("wasm-run: ")
	log.SetFlags(0)

	verbose := flag.Bool("v", false, "enable/disable verbose mode")
	verify := flag.Bool("verify-module", false, "run module verification")

	flag.Parse()

	if flag.NArg() < 1 {
		flag.Usage()
		flag.PrintDefaults()
		os.Exit(1)
	}

	wasm.SetDebugMode(*verbose)

	f, err := os.Open(flag.Arg(0))
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	m, err := wasm.ReadModule(f, nil)
	if err != nil {
		log.Fatalf("could not read module: %v", err)
	}

	if *verify {
		err = validate.VerifyModule(m)
		if err != nil {
			log.Fatalf("could not verify module: %v", err)
		}
	}

	if m.Export == nil {
		log.Fatalf("module has no export section")
	}

	vm, err := exec.NewVM(m)
	if err != nil {
		log.Fatalf("could not create VM: %v", err)
	}

	for i, e := range m.Export.Entries {
		log.Printf("%q: %#v", i, e)
		o, err := vm.ExecCode(int64(e.Index))
		if err != nil {
			log.Printf("err=%v", err)
		}
		log.Printf("%[1]v (%[1]T)", o)
	}
}
<commit_msg>cmd/wasm-run: protect against not handled yet exported function types<commit_after>// Copyright 2017 The go-interpreter 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 main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"github.com/go-interpreter/wagon/exec"
	"github.com/go-interpreter/wagon/validate"
	"github.com/go-interpreter/wagon/wasm"
)

func main() {
	log.SetPrefix("wasm-run: ")
	log.SetFlags(0)

	verbose := flag.Bool("v", false, "enable/disable verbose mode")
	verify := flag.Bool("verify-module", false, "run module verification")

	flag.Parse()

	if flag.NArg() < 1 {
		flag.Usage()
		flag.PrintDefaults()
		os.Exit(1)
	}

	wasm.SetDebugMode(*verbose)

	f, err := os.Open(flag.Arg(0))
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	m, err := wasm.ReadModule(f, nil)
	if err != nil {
		log.Fatalf("could not read module: %v", err)
	}

	if *verify {
		err = validate.VerifyModule(m)
		if err != nil {
			log.Fatalf("could not verify module: %v", err)
		}
	}

	if m.Export == nil {
		log.Fatalf("module has no export section")
	}

	vm, err := exec.NewVM(m)
	if err != nil {
		log.Fatalf("could not create VM: %v", err)
	}

	for name, e := range m.Export.Entries {
		i := int64(e.Index)
		fidx := m.Function.Types[int(i)]
		ftype := m.Types.Entries[int(fidx)]
		switch len(ftype.ReturnTypes) {
		case 1:
			fmt.Printf("%s() %s => ", name, ftype.ReturnTypes[0])
		case 0:
			fmt.Printf("%s() => ", name)
		default:
			log.Printf("running exported functions with more than one return value is not supported")
			continue
		}
		if len(ftype.ParamTypes) > 0 {
			log.Printf("running exported functions with input parameters is not supported")
			continue
		}
		o, err := vm.ExecCode(i)
		if err != nil {
			fmt.Printf("\n")
			log.Printf("err=%v", err)
		}
		if len(ftype.ReturnTypes) == 0 {
			fmt.Printf("\n")
			continue
		}
		fmt.Printf("%[1]v (%[1]T)\n", o)
	}
}
<|endoftext|>