<commit_before>package main

import (
	"crypto/tls"
	"flag"
	"github.com/coreos/etcd/store"
	"github.com/coreos/go-raft"
	"io/ioutil"
	"os"
	"strings"
	"time"
)

//------------------------------------------------------------------------------
//
// Initialization
//
//------------------------------------------------------------------------------

var (
	verbose     bool
	veryVerbose bool

	machines     string
	machinesFile string

	cluster []string

	argInfo Info
	dirPath string

	force bool

	maxSize int

	snapshot bool

	retryTimes int

	maxClusterSize int

	cpuprofile string
)

func init() {
	flag.BoolVar(&verbose, "v", false, "verbose logging")
	flag.BoolVar(&veryVerbose, "vv", false, "very verbose logging")

	flag.StringVar(&machines, "C", "", "the ip address and port of a existing machines in the cluster, sepearate by comma")
	flag.StringVar(&machinesFile, "CF", "", "the file contains a list of existing machines in the cluster, seperate by comma")

	flag.StringVar(&argInfo.Name, "n", "default-name", "the node name (required)")
	flag.StringVar(&argInfo.EtcdURL, "c", "127.0.0.1:4001", "the hostname:port for etcd client communication")
	flag.StringVar(&argInfo.RaftURL, "s", "127.0.0.1:7001", "the hostname:port for raft server communication")
	flag.StringVar(&argInfo.WebURL, "w", "", "the hostname:port of web interface")

	flag.StringVar(&argInfo.RaftTLS.CAFile, "serverCAFile", "", "the path of the CAFile")
	flag.StringVar(&argInfo.RaftTLS.CertFile, "serverCert", "", "the cert file of the server")
	flag.StringVar(&argInfo.RaftTLS.KeyFile, "serverKey", "", "the key file of the server")

	flag.StringVar(&argInfo.EtcdTLS.CAFile, "clientCAFile", "", "the path of the client CAFile")
	flag.StringVar(&argInfo.EtcdTLS.CertFile, "clientCert", "", "the cert file of the client")
	flag.StringVar(&argInfo.EtcdTLS.KeyFile, "clientKey", "", "the key file of the client")

	flag.StringVar(&dirPath, "d", ".", "the directory to store log and snapshot")

	flag.BoolVar(&force, "f", false, "force new node configuration if existing is found (WARNING: data loss!)")

	flag.BoolVar(&snapshot, "snapshot", false, "open or close snapshot")

	flag.IntVar(&maxSize, "m", 1024, "the max size of result buffer")

	flag.IntVar(&retryTimes, "r", 3, "the max retry attempts when trying to join a cluster")

	flag.IntVar(&maxClusterSize, "maxsize", 9, "the max size of the cluster")

	flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file")
}

const (
	ElectionTimeout  = 200 * time.Millisecond
	HeartbeatTimeout = 50 * time.Millisecond

	// Timeout for internal raft http connection
	// The original timeout for http is 45 seconds
	// which is too long for our usage.
	HTTPTimeout   = 10 * time.Second
	RetryInterval = 10
)

//------------------------------------------------------------------------------
//
// Typedefs
//
//------------------------------------------------------------------------------

type TLSInfo struct {
	CertFile string `json:"CertFile"`
	KeyFile  string `json:"KeyFile"`
	CAFile   string `json:"CAFile"`
}

type Info struct {
	Name string `json:"name"`

	RaftURL string `json:"raftURL"`
	EtcdURL string `json:"etcdURL"`
	WebURL  string `json:"webURL"`

	RaftTLS TLSInfo `json:"raftTLS"`
	EtcdTLS TLSInfo `json:"etcdTLS"`
}

type TLSConfig struct {
	Scheme string
	Server tls.Config
	Client tls.Config
}

type EtcdServer struct {
}

//------------------------------------------------------------------------------
//
// Variables
//
//------------------------------------------------------------------------------

var etcdStore *store.Store

//------------------------------------------------------------------------------
//
// Functions
//
//------------------------------------------------------------------------------

//--------------------------------------
// Main
//--------------------------------------

func main() {
	flag.Parse()

	if cpuprofile != "" {
		runCPUProfile()
	}

	if veryVerbose {
		verbose = true
		raft.SetLogLevel(raft.Debug)
	}

	if machines != "" {
		cluster = strings.Split(machines, ",")
	} else if machinesFile != "" {
		b, err := ioutil.ReadFile(machinesFile)
		if err != nil {
			fatalf("Unable to read the given machines file: %s", err)
		}
		cluster = strings.Split(string(b), ",")
	}

	// Check TLS arguments
	raftTLSConfig, ok := tlsConfigFromInfo(argInfo.RaftTLS)
	if !ok {
		fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
	}

	etcdTLSConfig, ok := tlsConfigFromInfo(argInfo.EtcdTLS)
	if !ok {
		fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
	}

	argInfo.Name = strings.TrimSpace(argInfo.Name)
	if argInfo.Name == "" {
		fatal("ERROR: server name required. e.g. '-n=server_name'")
	}

	// Check host name arguments
	argInfo.RaftURL = sanitizeURL(argInfo.RaftURL, raftTLSConfig.Scheme)
	argInfo.EtcdURL = sanitizeURL(argInfo.EtcdURL, etcdTLSConfig.Scheme)
	argInfo.WebURL = sanitizeURL(argInfo.WebURL, "http")

	// Read server info from file or grab it from user.
	if err := os.MkdirAll(dirPath, 0744); err != nil {
		fatalf("Unable to create path: %s", err)
	}

	info := getInfo(dirPath)

	// Create etcd key-value store
	etcdStore = store.CreateStore(maxSize)
	snapConf = newSnapshotConf()

	// Create etcd and raft server
	e = newEtcdServer(info.Name, info.EtcdURL, &etcdTLSConfig, &info.EtcdTLS)
	r = newRaftServer(info.Name, info.RaftURL, &raftTLSConfig, &info.RaftTLS)

	startWebInterface()
	r.ListenAndServe()
	e.ListenAndServe()

}
<commit_msg>remove unused struct<commit_after>package main

import (
	"crypto/tls"
	"flag"
	"github.com/coreos/etcd/store"
	"github.com/coreos/go-raft"
	"io/ioutil"
	"os"
	"strings"
	"time"
)

//------------------------------------------------------------------------------
//
// Initialization
//
//------------------------------------------------------------------------------

var (
	verbose     bool
	veryVerbose bool

	machines     string
	machinesFile string

	cluster []string

	argInfo Info
	dirPath string

	force bool

	maxSize int

	snapshot bool

	retryTimes int

	maxClusterSize int

	cpuprofile string
)

func init() {
	flag.BoolVar(&verbose, "v", false, "verbose logging")
	flag.BoolVar(&veryVerbose, "vv", false, "very verbose logging")

	flag.StringVar(&machines, "C", "", "the ip address and port of a existing machines in the cluster, sepearate by comma")
	flag.StringVar(&machinesFile, "CF", "", "the file contains a list of existing machines in the cluster, seperate by comma")

	flag.StringVar(&argInfo.Name, "n", "default-name", "the node name (required)")
	flag.StringVar(&argInfo.EtcdURL, "c", "127.0.0.1:4001", "the hostname:port for etcd client communication")
	flag.StringVar(&argInfo.RaftURL, "s", "127.0.0.1:7001", "the hostname:port for raft server communication")
	flag.StringVar(&argInfo.WebURL, "w", "", "the hostname:port of web interface")

	flag.StringVar(&argInfo.RaftTLS.CAFile, "serverCAFile", "", "the path of the CAFile")
	flag.StringVar(&argInfo.RaftTLS.CertFile, "serverCert", "", "the cert file of the server")
	flag.StringVar(&argInfo.RaftTLS.KeyFile, "serverKey", "", "the key file of the server")

	flag.StringVar(&argInfo.EtcdTLS.CAFile, "clientCAFile", "", "the path of the client CAFile")
	flag.StringVar(&argInfo.EtcdTLS.CertFile, "clientCert", "", "the cert file of the client")
	flag.StringVar(&argInfo.EtcdTLS.KeyFile, "clientKey", "", "the key file of the client")

	flag.StringVar(&dirPath, "d", ".", "the directory to store log and snapshot")

	flag.BoolVar(&force, "f", false, "force new node configuration if existing is found (WARNING: data loss!)")

	flag.BoolVar(&snapshot, "snapshot", false, "open or close snapshot")

	flag.IntVar(&maxSize, "m", 1024, "the max size of result buffer")

	flag.IntVar(&retryTimes, "r", 3, "the max retry attempts when trying to join a cluster")

	flag.IntVar(&maxClusterSize, "maxsize", 9, "the max size of the cluster")

	flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file")
}

const (
	ElectionTimeout  = 200 * time.Millisecond
	HeartbeatTimeout = 50 * time.Millisecond

	// Timeout for internal raft http connection
	// The original timeout for http is 45 seconds
	// which is too long for our usage.
	HTTPTimeout   = 10 * time.Second
	RetryInterval = 10
)

//------------------------------------------------------------------------------
//
// Typedefs
//
//------------------------------------------------------------------------------

type TLSInfo struct {
	CertFile string `json:"CertFile"`
	KeyFile  string `json:"KeyFile"`
	CAFile   string `json:"CAFile"`
}

type Info struct {
	Name string `json:"name"`

	RaftURL string `json:"raftURL"`
	EtcdURL string `json:"etcdURL"`
	WebURL  string `json:"webURL"`

	RaftTLS TLSInfo `json:"raftTLS"`
	EtcdTLS TLSInfo `json:"etcdTLS"`
}

type TLSConfig struct {
	Scheme string
	Server tls.Config
	Client tls.Config
}

//------------------------------------------------------------------------------
//
// Variables
//
//------------------------------------------------------------------------------

var etcdStore *store.Store

//------------------------------------------------------------------------------
//
// Functions
//
//------------------------------------------------------------------------------

//--------------------------------------
// Main
//--------------------------------------

func main() {
	flag.Parse()

	if cpuprofile != "" {
		runCPUProfile()
	}

	if veryVerbose {
		verbose = true
		raft.SetLogLevel(raft.Debug)
	}

	if machines != "" {
		cluster = strings.Split(machines, ",")
	} else if machinesFile != "" {
		b, err := ioutil.ReadFile(machinesFile)
		if err != nil {
			fatalf("Unable to read the given machines file: %s", err)
		}
		cluster = strings.Split(string(b), ",")
	}

	// Check TLS arguments
	raftTLSConfig, ok := tlsConfigFromInfo(argInfo.RaftTLS)
	if !ok {
		fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
	}

	etcdTLSConfig, ok := tlsConfigFromInfo(argInfo.EtcdTLS)
	if !ok {
		fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
	}

	argInfo.Name = strings.TrimSpace(argInfo.Name)
	if argInfo.Name == "" {
		fatal("ERROR: server name required. e.g. '-n=server_name'")
	}

	// Check host name arguments
	argInfo.RaftURL = sanitizeURL(argInfo.RaftURL, raftTLSConfig.Scheme)
	argInfo.EtcdURL = sanitizeURL(argInfo.EtcdURL, etcdTLSConfig.Scheme)
	argInfo.WebURL = sanitizeURL(argInfo.WebURL, "http")

	// Read server info from file or grab it from user.
	if err := os.MkdirAll(dirPath, 0744); err != nil {
		fatalf("Unable to create path: %s", err)
	}

	info := getInfo(dirPath)

	// Create etcd key-value store
	etcdStore = store.CreateStore(maxSize)
	snapConf = newSnapshotConf()

	// Create etcd and raft server
	e = newEtcdServer(info.Name, info.EtcdURL, &etcdTLSConfig, &info.EtcdTLS)
	r = newRaftServer(info.Name, info.RaftURL, &raftTLSConfig, &info.RaftTLS)

	startWebInterface()
	r.ListenAndServe()
	e.ListenAndServe()

}
<|endoftext|>


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

// Package httptrace provides mechanisms to trace the events within
// HTTP client requests.
package httptrace

import (
	"context"
	"crypto/tls"
	"internal/nettrace"
	"net"
	"reflect"
	"time"
)

// unique type to prevent assignment.
type clientEventContextKey struct{}

// ContextClientTrace returns the ClientTrace associated with the
// provided context. If none, it returns nil.
func ContextClientTrace(ctx context.Context) *ClientTrace {
	trace, _ := ctx.Value(clientEventContextKey{}).(*ClientTrace)
	return trace
}

// WithClientTrace returns a new context based on the provided parent
// ctx. HTTP client requests made with the returned context will use
// the provided trace hooks, in addition to any previous hooks
// registered with ctx. Any hooks defined in the provided trace will
// be called first.
func WithClientTrace(ctx context.Context, trace *ClientTrace) context.Context {
	if trace == nil {
		panic("nil trace")
	}
	old := ContextClientTrace(ctx)
	trace.compose(old)

	ctx = context.WithValue(ctx, clientEventContextKey{}, trace)
	if trace.hasNetHooks() {
		nt := &nettrace.Trace{
			ConnectStart: trace.ConnectStart,
			ConnectDone:  trace.ConnectDone,
		}
		if trace.DNSStart != nil {
			nt.DNSStart = func(name string) {
				trace.DNSStart(DNSStartInfo{Host: name})
			}
		}
		if trace.DNSDone != nil {
			nt.DNSDone = func(netIPs []interface{}, coalesced bool, err error) {
				addrs := make([]net.IPAddr, len(netIPs))
				for i, ip := range netIPs {
					addrs[i] = ip.(net.IPAddr)
				}
				trace.DNSDone(DNSDoneInfo{
					Addrs:     addrs,
					Coalesced: coalesced,
					Err:       err,
				})
			}
		}
		ctx = context.WithValue(ctx, nettrace.TraceKey{}, nt)
	}
	return ctx
}

// ClientTrace is a set of hooks to run at various stages of an outgoing
// HTTP request. Any particular hook may be nil. Functions may be
// called concurrently from different goroutines, starting after the
// call to Transport.RoundTrip and ending either when RoundTrip
// returns an error, or when the Response.Body is closed.
type ClientTrace struct {
	// GetConn is called before a connection is created or
	// retrieved from an idle pool. The hostPort is the
	// "host:port" of the target or proxy. GetConn is called even
	// if there's already an idle cached connection available.
	GetConn func(hostPort string)

	// GotConn is called after a successful connection is
	// obtained. There is no hook for failure to obtain a
	// connection; instead, use the error from
	// Transport.RoundTrip.
	GotConn func(GotConnInfo)

	// PutIdleConn is called when the connection is returned to
	// the idle pool. If err is nil, the connection was
	// successfully returned to the idle pool. If err is non-nil,
	// it describes why not. PutIdleConn is not called if
	// connection reuse is disabled via Transport.DisableKeepAlives.
	// PutIdleConn is called before the caller's Response.Body.Close
	// call returns.
	// For HTTP/2, this hook is not currently used.
	PutIdleConn func(err error)

	// GotFirstResponseByte is called when the first byte of the response
	// headers is available.
	GotFirstResponseByte func()

	// Got100Continue is called if the server replies with a "100
	// Continue" response.
	Got100Continue func()

	// DNSStart is called when a DNS lookup begins.
	DNSStart func(DNSStartInfo)

	// DNSDone is called when a DNS lookup ends.
	DNSDone func(DNSDoneInfo)

	// ConnectStart is called when a new connection's Dial begins.
	// If net.Dialer.DualStack (IPv6 "Happy Eyeballs") support is
	// enabled, this may be called multiple times.
	ConnectStart func(network, addr string)

	// ConnectDone is called when a new connection's Dial
	// completes. The provided err indicates whether the
	// connection completedly successfully.
	// If net.Dialer.DualStack ("Happy Eyeballs") support is
	// enabled, this may be called multiple times.
	ConnectDone func(network, addr string, err error)

	// TLSHandshakeStart is called when the TLS handshake is started. When
	// connecting to a HTTPS site via a HTTP proxy, the handshake happens after
	// the CONNECT request is processed by the proxy.
	TLSHandshakeStart func()

	// TLSHandshakeDone is called after the TLS handshake with either the
	// successful handshake's connection state, or a non-nil error on handshake
	// failure.
	TLSHandshakeDone func(tls.ConnectionState, error)

	// WroteHeaders is called after the Transport has written
	// the request headers.
	WroteHeaders func()

	// Wait100Continue is called if the Request specified
	// "Expected: 100-continue" and the Transport has written the
	// request headers but is waiting for "100 Continue" from the
	// server before writing the request body.
	Wait100Continue func()

	// WroteRequest is called with the result of writing the
	// request and any body.
	WroteRequest func(WroteRequestInfo)
}

// WroteRequestInfo contains information provided to the WroteRequest
// hook.
type WroteRequestInfo struct {
	// Err is any error encountered while writing the Request.
	Err error
}

// compose modifies t such that it respects the previously-registered hooks in old,
// subject to the composition policy requested in t.Compose.
func (t *ClientTrace) compose(old *ClientTrace) {
	if old == nil {
		return
	}
	tv := reflect.ValueOf(t).Elem()
	ov := reflect.ValueOf(old).Elem()
	structType := tv.Type()
	for i := 0; i < structType.NumField(); i++ {
		tf := tv.Field(i)
		hookType := tf.Type()
		if hookType.Kind() != reflect.Func {
			continue
		}
		of := ov.Field(i)
		if of.IsNil() {
			continue
		}
		if tf.IsNil() {
			tf.Set(of)
			continue
		}

		// Make a copy of tf for tf to call. (Otherwise it
		// creates a recursive call cycle and stack overflows)
		tfCopy := reflect.ValueOf(tf.Interface())

		// We need to call both tf and of in some order.
		newFunc := reflect.MakeFunc(hookType, func(args []reflect.Value) []reflect.Value {
			tfCopy.Call(args)
			return of.Call(args)
		})
		tv.Field(i).Set(newFunc)
	}
}

// DNSStartInfo contains information about a DNS request.
type DNSStartInfo struct {
	Host string
}

// DNSDoneInfo contains information about the results of a DNS lookup.
type DNSDoneInfo struct {
	// Addrs are the IPv4 and/or IPv6 addresses found in the DNS
	// lookup. The contents of the slice should not be mutated.
	Addrs []net.IPAddr

	// Err is any error that occurred during the DNS lookup.
	Err error

	// Coalesced is whether the Addrs were shared with another
	// caller who was doing the same DNS lookup concurrently.
	Coalesced bool
}

func (t *ClientTrace) hasNetHooks() bool {
	if t == nil {
		return false
	}
	return t.DNSStart != nil || t.DNSDone != nil || t.ConnectStart != nil || t.ConnectDone != nil
}

// GotConnInfo is the argument to the ClientTrace.GotConn function and
// contains information about the obtained connection.
type GotConnInfo struct {
	// Conn is the connection that was obtained. It is owned by
	// the http.Transport and should not be read, written or
	// closed by users of ClientTrace.
	Conn net.Conn

	// Reused is whether this connection has been previously
	// used for another HTTP request.
	Reused bool

	// WasIdle is whether this connection was obtained from an
	// idle pool.
	WasIdle bool

	// IdleTime reports how long the connection was previously
	// idle, if WasIdle is true.
	IdleTime time.Duration
}
<commit_msg>net/http/httptrace: clarify ClientTrace docs<commit_after>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package httptrace provides mechanisms to trace the events within
// HTTP client requests.
package httptrace

import (
	"context"
	"crypto/tls"
	"internal/nettrace"
	"net"
	"reflect"
	"time"
)

// unique type to prevent assignment.
type clientEventContextKey struct{}

// ContextClientTrace returns the ClientTrace associated with the
// provided context. If none, it returns nil.
func ContextClientTrace(ctx context.Context) *ClientTrace {
	trace, _ := ctx.Value(clientEventContextKey{}).(*ClientTrace)
	return trace
}

// WithClientTrace returns a new context based on the provided parent
// ctx. HTTP client requests made with the returned context will use
// the provided trace hooks, in addition to any previous hooks
// registered with ctx. Any hooks defined in the provided trace will
// be called first.
func WithClientTrace(ctx context.Context, trace *ClientTrace) context.Context {
	if trace == nil {
		panic("nil trace")
	}
	old := ContextClientTrace(ctx)
	trace.compose(old)

	ctx = context.WithValue(ctx, clientEventContextKey{}, trace)
	if trace.hasNetHooks() {
		nt := &nettrace.Trace{
			ConnectStart: trace.ConnectStart,
			ConnectDone:  trace.ConnectDone,
		}
		if trace.DNSStart != nil {
			nt.DNSStart = func(name string) {
				trace.DNSStart(DNSStartInfo{Host: name})
			}
		}
		if trace.DNSDone != nil {
			nt.DNSDone = func(netIPs []interface{}, coalesced bool, err error) {
				addrs := make([]net.IPAddr, len(netIPs))
				for i, ip := range netIPs {
					addrs[i] = ip.(net.IPAddr)
				}
				trace.DNSDone(DNSDoneInfo{
					Addrs:     addrs,
					Coalesced: coalesced,
					Err:       err,
				})
			}
		}
		ctx = context.WithValue(ctx, nettrace.TraceKey{}, nt)
	}
	return ctx
}

// ClientTrace is a set of hooks to run at various stages of an outgoing
// HTTP request. Any particular hook may be nil. Functions may be
// called concurrently from different goroutines and some may be called
// after the request has completed or failed.
type ClientTrace struct {
	// GetConn is called before a connection is created or
	// retrieved from an idle pool. The hostPort is the
	// "host:port" of the target or proxy. GetConn is called even
	// if there's already an idle cached connection available.
	GetConn func(hostPort string)

	// GotConn is called after a successful connection is
	// obtained. There is no hook for failure to obtain a
	// connection; instead, use the error from
	// Transport.RoundTrip.
	GotConn func(GotConnInfo)

	// PutIdleConn is called when the connection is returned to
	// the idle pool. If err is nil, the connection was
	// successfully returned to the idle pool. If err is non-nil,
	// it describes why not. PutIdleConn is not called if
	// connection reuse is disabled via Transport.DisableKeepAlives.
	// PutIdleConn is called before the caller's Response.Body.Close
	// call returns.
	// For HTTP/2, this hook is not currently used.
	PutIdleConn func(err error)

	// GotFirstResponseByte is called when the first byte of the response
	// headers is available.
	GotFirstResponseByte func()

	// Got100Continue is called if the server replies with a "100
	// Continue" response.
	Got100Continue func()

	// DNSStart is called when a DNS lookup begins.
	DNSStart func(DNSStartInfo)

	// DNSDone is called when a DNS lookup ends.
	DNSDone func(DNSDoneInfo)

	// ConnectStart is called when a new connection's Dial begins.
	// If net.Dialer.DualStack (IPv6 "Happy Eyeballs") support is
	// enabled, this may be called multiple times.
	ConnectStart func(network, addr string)

	// ConnectDone is called when a new connection's Dial
	// completes. The provided err indicates whether the
	// connection completedly successfully.
	// If net.Dialer.DualStack ("Happy Eyeballs") support is
	// enabled, this may be called multiple times.
	ConnectDone func(network, addr string, err error)

	// TLSHandshakeStart is called when the TLS handshake is started. When
	// connecting to a HTTPS site via a HTTP proxy, the handshake happens after
	// the CONNECT request is processed by the proxy.
	TLSHandshakeStart func()

	// TLSHandshakeDone is called after the TLS handshake with either the
	// successful handshake's connection state, or a non-nil error on handshake
	// failure.
	TLSHandshakeDone func(tls.ConnectionState, error)

	// WroteHeaders is called after the Transport has written
	// the request headers.
	WroteHeaders func()

	// Wait100Continue is called if the Request specified
	// "Expected: 100-continue" and the Transport has written the
	// request headers but is waiting for "100 Continue" from the
	// server before writing the request body.
	Wait100Continue func()

	// WroteRequest is called with the result of writing the
	// request and any body.
	WroteRequest func(WroteRequestInfo)
}

// WroteRequestInfo contains information provided to the WroteRequest
// hook.
type WroteRequestInfo struct {
	// Err is any error encountered while writing the Request.
	Err error
}

// compose modifies t such that it respects the previously-registered hooks in old,
// subject to the composition policy requested in t.Compose.
func (t *ClientTrace) compose(old *ClientTrace) {
	if old == nil {
		return
	}
	tv := reflect.ValueOf(t).Elem()
	ov := reflect.ValueOf(old).Elem()
	structType := tv.Type()
	for i := 0; i < structType.NumField(); i++ {
		tf := tv.Field(i)
		hookType := tf.Type()
		if hookType.Kind() != reflect.Func {
			continue
		}
		of := ov.Field(i)
		if of.IsNil() {
			continue
		}
		if tf.IsNil() {
			tf.Set(of)
			continue
		}

		// Make a copy of tf for tf to call. (Otherwise it
		// creates a recursive call cycle and stack overflows)
		tfCopy := reflect.ValueOf(tf.Interface())

		// We need to call both tf and of in some order.
		newFunc := reflect.MakeFunc(hookType, func(args []reflect.Value) []reflect.Value {
			tfCopy.Call(args)
			return of.Call(args)
		})
		tv.Field(i).Set(newFunc)
	}
}

// DNSStartInfo contains information about a DNS request.
type DNSStartInfo struct {
	Host string
}

// DNSDoneInfo contains information about the results of a DNS lookup.
type DNSDoneInfo struct {
	// Addrs are the IPv4 and/or IPv6 addresses found in the DNS
	// lookup. The contents of the slice should not be mutated.
	Addrs []net.IPAddr

	// Err is any error that occurred during the DNS lookup.
	Err error

	// Coalesced is whether the Addrs were shared with another
	// caller who was doing the same DNS lookup concurrently.
	Coalesced bool
}

func (t *ClientTrace) hasNetHooks() bool {
	if t == nil {
		return false
	}
	return t.DNSStart != nil || t.DNSDone != nil || t.ConnectStart != nil || t.ConnectDone != nil
}

// GotConnInfo is the argument to the ClientTrace.GotConn function and
// contains information about the obtained connection.
type GotConnInfo struct {
	// Conn is the connection that was obtained. It is owned by
	// the http.Transport and should not be read, written or
	// closed by users of ClientTrace.
	Conn net.Conn

	// Reused is whether this connection has been previously
	// used for another HTTP request.
	Reused bool

	// WasIdle is whether this connection was obtained from an
	// idle pool.
	WasIdle bool

	// IdleTime reports how long the connection was previously
	// idle, if WasIdle is true.
	IdleTime time.Duration
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"regexp"

	"github.com/mitchellh/go-homedir"
	"github.com/monochromegane/conflag"
)

func (c *CLI) FlagParse(args []string) error {
	style, err := c.getCommandType(args)
	if err != nil {
		return err
	}
	if style == SUBCOMMAND {
		args = args[:len(args)-1]
	}

	return c.parse(args)
}

func (c *CLI) getCommandType(args []string) (s CommandStyle, err error) {
	s = ALIAS
	switch {
	case regexp.MustCompile(`/?xdg-open$`).MatchString(args[0]):
		c.Type = OPEN
		return
	case regexp.MustCompile(`/?pbpaste`).MatchString(args[0]):
		c.Type = PASTE
		return
	case regexp.MustCompile(`/?pbcopy`).MatchString(args[0]):
		c.Type = COPY
		return
	}

	del := func(i int) {
		copy(args[i+1:], args[i+2:])
		args[len(args)-1] = ""
	}

	s = SUBCOMMAND
	for i, v := range args[1:] {
		switch v {
		case "open":
			c.Type = OPEN
			del(i)
			return
		case "paste":
			c.Type = PASTE
			del(i)
			return
		case "copy":
			c.Type = COPY
			del(i)
			return
		case "server":
			c.Type = SERVER
			del(i)
			return
		}
	}

	return s, fmt.Errorf("Unknown SubCommand\n\n" + Usage)
}

func (c *CLI) flags() *flag.FlagSet {
	flags := flag.NewFlagSet("lemonade", flag.ContinueOnError)
	flags.IntVar(&c.Port, "port", 2489, "TCP port number")
	flags.StringVar(&c.Allow, "allow", "0.0.0.0/0,::/0", "Allow IP range")
	flags.StringVar(&c.Host, "host", "localhost", "Destination host name.")
	flags.BoolVar(&c.Help, "help", false, "Show this message")
	flags.BoolVar(&c.TransLoopback, "trans-loopback", true, "Translate loopback address")
	flags.BoolVar(&c.TransLocalfile, "trans-localfile", true, "Translate local file")
	return flags
}

func (c *CLI) parse(args []string) error {
	flags := c.flags()

	confPath, err := homedir.Expand("~/.config/lemonade.toml")
	if err == nil {
		if confArgs, err := conflag.ArgsFrom(confPath); err == nil {
			flags.Parse(confArgs)
		}
	}

	var arg string
	err = flags.Parse(args[1:])
	if err != nil {
		return err
	}
	if c.Type == PASTE || c.Type == SERVER {
		return nil
	}

	for 0 < flags.NArg() {
		arg = flags.Arg(0)
		err := flags.Parse(flags.Args()[1:])
		if err != nil {
			return err
		}

	}

	if c.Help {
		return nil
	}

	if arg != "" {
		c.DataSource = arg
	} else {
		b, err := ioutil.ReadAll(c.In)
		if err != nil {
			return err
		}
		c.DataSource = string(b)
	}

	return nil
}
<commit_msg>Tiny fix for command name matching.<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"regexp"

	"github.com/mitchellh/go-homedir"
	"github.com/monochromegane/conflag"
)

func (c *CLI) FlagParse(args []string) error {
	style, err := c.getCommandType(args)
	if err != nil {
		return err
	}
	if style == SUBCOMMAND {
		args = args[:len(args)-1]
	}

	return c.parse(args)
}

func (c *CLI) getCommandType(args []string) (s CommandStyle, err error) {
	s = ALIAS
	switch {
	case regexp.MustCompile(`/?xdg-open$`).MatchString(args[0]):
		c.Type = OPEN
		return
	case regexp.MustCompile(`/?pbpaste$`).MatchString(args[0]):
		c.Type = PASTE
		return
	case regexp.MustCompile(`/?pbcopy$`).MatchString(args[0]):
		c.Type = COPY
		return
	}

	del := func(i int) {
		copy(args[i+1:], args[i+2:])
		args[len(args)-1] = ""
	}

	s = SUBCOMMAND
	for i, v := range args[1:] {
		switch v {
		case "open":
			c.Type = OPEN
			del(i)
			return
		case "paste":
			c.Type = PASTE
			del(i)
			return
		case "copy":
			c.Type = COPY
			del(i)
			return
		case "server":
			c.Type = SERVER
			del(i)
			return
		}
	}

	return s, fmt.Errorf("Unknown SubCommand\n\n" + Usage)
}

func (c *CLI) flags() *flag.FlagSet {
	flags := flag.NewFlagSet("lemonade", flag.ContinueOnError)
	flags.IntVar(&c.Port, "port", 2489, "TCP port number")
	flags.StringVar(&c.Allow, "allow", "0.0.0.0/0,::/0", "Allow IP range")
	flags.StringVar(&c.Host, "host", "localhost", "Destination host name.")
	flags.BoolVar(&c.Help, "help", false, "Show this message")
	flags.BoolVar(&c.TransLoopback, "trans-loopback", true, "Translate loopback address")
	flags.BoolVar(&c.TransLocalfile, "trans-localfile", true, "Translate local file")
	return flags
}

func (c *CLI) parse(args []string) error {
	flags := c.flags()

	confPath, err := homedir.Expand("~/.config/lemonade.toml")
	if err == nil {
		if confArgs, err := conflag.ArgsFrom(confPath); err == nil {
			flags.Parse(confArgs)
		}
	}

	var arg string
	err = flags.Parse(args[1:])
	if err != nil {
		return err
	}
	if c.Type == PASTE || c.Type == SERVER {
		return nil
	}

	for 0 < flags.NArg() {
		arg = flags.Arg(0)
		err := flags.Parse(flags.Args()[1:])
		if err != nil {
			return err
		}

	}

	if c.Help {
		return nil
	}

	if arg != "" {
		c.DataSource = arg
	} else {
		b, err := ioutil.ReadAll(c.In)
		if err != nil {
			return err
		}
		c.DataSource = string(b)
	}

	return nil
}
<|endoftext|>


<commit_before>package newt

/*
#cgo CFLAGS: -I/opt/local/include
#cgo LDFLAGS: -L/opt/local/lib -lnewt

#include <stdio.h>
#include <stdlib.h>
#include <newt.h>
*/
import "C"

import (
    "unsafe"
)

func Form(vertBar *Component, helpTag string, flags int) Component {
    var c Component
    t := C.CString(helpTag)
    defer C.free(unsafe.Pointer(t))
    if vertBar != nil {
        c.c = C.newtForm(vertBar.c, unsafe.Pointer(t), C.int(flags))
    } else {
        c.c = C.newtForm(nil, unsafe.Pointer(t), C.int(flags))
    }
    return c
}

func FormSetTimer(form Component, millisecs int) {
    C.newtFormSetTimer(form.c, C.int(millisecs))
}

func FormWatchFd(form Component, fd, fdFlags int) {
    C.newtFormWatchFd(form.c, C.int(fd), C.int(fdFlags))
}

func FormSetSize(c Component) {
    C.newtFormSetSize(c.c)
}

func FormGetCurrent(form Component) Component {
    var c Component
    c.c = C.newtFormGetCurrent(form.c)
    return c
}

func FormSetBackground(c Component, color int) {
    C.newtFormSetBackground(c.c, C.int(color))
}

func FormSetCurrent(form, c Component) {
    C.newtFormSetCurrent(form.c, c.c)
}

func FormAddComponent(form, c Component) {
    C.newtFormAddComponent(form.c, c.c)
}

func FormAddComponents(form Component, args ...Component) {
    for _, v := range args {
        FormAddComponent(form, v)
    }
    // C.newtFormAddComponents(form.c, args)
}

func FormSetHeight(c Component, height int) {
    C.newtFormSetHeight(c.c, C.int(height))
}

func FormSetWidth(c Component, width int) {
    C.newtFormSetWidth(c.c, C.int(width))
}

func RunForm(form Component) Component {
    var c Component
    c.c = C.newtRunForm(form.c)
    return c
}

func FormRun(form Component) ExitStruct {
    // panic
    var es ExitStruct
    C.newtFormRun(form.c, &es.es)
    return es
}

func DrawForm(form Component) {
    C.newtDrawForm(form.c)
}

func FormAddHotKey(c Component, key int) {
    C.newtFormAddHotKey(c.c, C.int(key))
}

func FormGetScrollPosition(c Component) int {
    return int(C.newtFormGetScrollPosition(c.c))
}

func FormSetScrollPosition(c Component, position int) {
    C.newtFormSetScrollPosition(c.c, C.int(position))
}

func FormDestroy(c Component) {
    C.newtFormDestroy(c.c)
}
<commit_msg>outdated comment removed<commit_after>package newt

/*
#cgo CFLAGS: -I/opt/local/include
#cgo LDFLAGS: -L/opt/local/lib -lnewt

#include <stdio.h>
#include <stdlib.h>
#include <newt.h>
*/
import "C"

import (
    "unsafe"
)

func Form(vertBar *Component, helpTag string, flags int) Component {
    var c Component
    t := C.CString(helpTag)
    defer C.free(unsafe.Pointer(t))
    if vertBar != nil {
        c.c = C.newtForm(vertBar.c, unsafe.Pointer(t), C.int(flags))
    } else {
        c.c = C.newtForm(nil, unsafe.Pointer(t), C.int(flags))
    }
    return c
}

func FormSetTimer(form Component, millisecs int) {
    C.newtFormSetTimer(form.c, C.int(millisecs))
}

func FormWatchFd(form Component, fd, fdFlags int) {
    C.newtFormWatchFd(form.c, C.int(fd), C.int(fdFlags))
}

func FormSetSize(c Component) {
    C.newtFormSetSize(c.c)
}

func FormGetCurrent(form Component) Component {
    var c Component
    c.c = C.newtFormGetCurrent(form.c)
    return c
}

func FormSetBackground(c Component, color int) {
    C.newtFormSetBackground(c.c, C.int(color))
}

func FormSetCurrent(form, c Component) {
    C.newtFormSetCurrent(form.c, c.c)
}

func FormAddComponent(form, c Component) {
    C.newtFormAddComponent(form.c, c.c)
}

func FormAddComponents(form Component, args ...Component) {
    for _, v := range args {
        FormAddComponent(form, v)
    }
    // C.newtFormAddComponents(form.c, args)
}

func FormSetHeight(c Component, height int) {
    C.newtFormSetHeight(c.c, C.int(height))
}

func FormSetWidth(c Component, width int) {
    C.newtFormSetWidth(c.c, C.int(width))
}

func RunForm(form Component) Component {
    var c Component
    c.c = C.newtRunForm(form.c)
    return c
}

func FormRun(form Component) ExitStruct {
    var es ExitStruct
    C.newtFormRun(form.c, &es.es)
    return es
}

func DrawForm(form Component) {
    C.newtDrawForm(form.c)
}

func FormAddHotKey(c Component, key int) {
    C.newtFormAddHotKey(c.c, C.int(key))
}

func FormGetScrollPosition(c Component) int {
    return int(C.newtFormGetScrollPosition(c.c))
}

func FormSetScrollPosition(c Component, position int) {
    C.newtFormSetScrollPosition(c.c, C.int(position))
}

func FormDestroy(c Component) {
    C.newtFormDestroy(c.c)
}
<|endoftext|>


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

// Freq (frequency) counts how many times each distinct
// Unicode code point appears in the input. The -bytes
// option counts bytes instead. The table is then printed
// to standard output, one count per line. Nothing is
// printed for a code point if its count is zero.

package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"os"
	"strconv"
)

var (
	countBytes bool
)

func init() {
	flag.BoolVar(&countBytes, "bytes", false, "count bytes (default is runes)")
	flag.BoolVar(&countBytes, "b", false, "alias for -bytes")
}

func main() {
	flag.Parse()
	if flag.NArg() == 0 {
		read("<stdin>", os.Stdin)
	}
	for _, file := range flag.Args() {
		f, err := os.Open(file)
		if err != nil {
			fmt.Fprintln(os.Stderr, "freq:", err)
			os.Exit(1)
		}
		read(file, f)
		f.Close()
	}
	print()
}

// We lazily fill in the intermediate arrays, each 256 entries long.
// Unicode is 22 bits, so we only need 3 levels max.
// Indexing starts with the uppermost byte, so the innermost array
// (of uint64 elements) represents 256 consecutive code points.
type Counts [256]*[256]*[256]uint64

var counts = new(Counts) // Allocate the top level; we know we'll need it unless the input is empty.
var errors uint64        // Special count to distinguish FFFD from real errors.

func (c *Counts) Inc(r rune) {
	b2 := (r >> 16) & 0xFF
	b1 := (r >> 8) & 0xFF
	b0 := (r >> 0) & 0xFF
	c2 := (*c)[b2]
	if c2 == nil {
		c2 = new([256]*[256]uint64)
		(*c)[b2] = c2
	}
	c1 := c2[b1]
	if c1 == nil {
		c1 = new([256]uint64)
		c2[b1] = c1
	}
	c1[b0]++
}

func read(file string, f *os.File) {
	if countBytes {
		readBytes(file, f)
	} else {
		readRunes(file, f)
	}
}

func readBytes(file string, f *os.File) {
	buf := bufio.NewReader(f)
	for {
		byte, err := buf.ReadByte()
		if err != nil {
			if err == io.EOF {
				return
			}
			fmt.Fprintf(os.Stderr, "freq: %s: %s\n", file, err)
			os.Exit(1)
		}
		counts.Inc(rune(byte))
	}
}

func readRunes(file string, f *os.File) {
	buf := bufio.NewReader(f)
	for {
		rune, width, err := buf.ReadRune()
		if err != nil {
			if err == io.EOF {
				return
			}
			fmt.Fprintf(os.Stderr, "freq: %s: %s\n", file, err)
			os.Exit(1)
		}
		if rune == 0xFFFD && width == 1 {
			errors++
		} else {
			counts.Inc(rune)
		}
	}
}

func print() {
	if countBytes {
		printCounts("%.2x %c\t%d\n", "%.2x -\t%d\n")
	} else {
		printCounts("%.4x %c\t%d\n", "%.4x -\t%d\n")
	}
}

func printCounts(printable, unprintable string) {
	for b2 := range *counts {
		c2 := (*counts)[b2]
		if c2 == nil {
			continue
		}
		for b1 := range c2 {
			c1 := c2[b1]
			if c1 == nil {
				continue
			}
			for b0, count := range c1 {
				if count == 0 {
					continue
				}
				var r rune = rune((b2 << 16) | (b1 << 8) | b0)
				if strconv.IsPrint(r) {
					fmt.Printf(printable, r, r, count)
				} else {
					fmt.Printf(unprintable, r, count)
				}
			}
		}
	}
	if errors > 0 {
		fmt.Printf("error -\t%d\n", errors)
	}
}
<commit_msg>freq: override printability of ascii space so there are always 3 space-delimited columns<commit_after>// Copyright 2012 The rspace Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Freq (frequency) counts how many times each distinct
// Unicode code point appears in the input. The -bytes
// option counts bytes instead. The table is then printed
// to standard output, one count per line. Nothing is
// printed for a code point if its count is zero.

package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"os"
	"strconv"
)

var (
	countBytes bool
)

func init() {
	flag.BoolVar(&countBytes, "bytes", false, "count bytes (default is runes)")
	flag.BoolVar(&countBytes, "b", false, "alias for -bytes")
}

func main() {
	flag.Parse()
	if flag.NArg() == 0 {
		read("<stdin>", os.Stdin)
	}
	for _, file := range flag.Args() {
		f, err := os.Open(file)
		if err != nil {
			fmt.Fprintln(os.Stderr, "freq:", err)
			os.Exit(1)
		}
		read(file, f)
		f.Close()
	}
	print()
}

// We lazily fill in the intermediate arrays, each 256 entries long.
// Unicode is 22 bits, so we only need 3 levels max.
// Indexing starts with the uppermost byte, so the innermost array
// (of uint64 elements) represents 256 consecutive code points.
type Counts [256]*[256]*[256]uint64

var counts = new(Counts) // Allocate the top level; we know we'll need it unless the input is empty.
var errors uint64        // Special count to distinguish FFFD from real errors.

func (c *Counts) Inc(r rune) {
	b2 := (r >> 16) & 0xFF
	b1 := (r >> 8) & 0xFF
	b0 := (r >> 0) & 0xFF
	c2 := (*c)[b2]
	if c2 == nil {
		c2 = new([256]*[256]uint64)
		(*c)[b2] = c2
	}
	c1 := c2[b1]
	if c1 == nil {
		c1 = new([256]uint64)
		c2[b1] = c1
	}
	c1[b0]++
}

func read(file string, f *os.File) {
	if countBytes {
		readBytes(file, f)
	} else {
		readRunes(file, f)
	}
}

func readBytes(file string, f *os.File) {
	buf := bufio.NewReader(f)
	for {
		byte, err := buf.ReadByte()
		if err != nil {
			if err == io.EOF {
				return
			}
			fmt.Fprintf(os.Stderr, "freq: %s: %s\n", file, err)
			os.Exit(1)
		}
		counts.Inc(rune(byte))
	}
}

func readRunes(file string, f *os.File) {
	buf := bufio.NewReader(f)
	for {
		rune, width, err := buf.ReadRune()
		if err != nil {
			if err == io.EOF {
				return
			}
			fmt.Fprintf(os.Stderr, "freq: %s: %s\n", file, err)
			os.Exit(1)
		}
		if rune == 0xFFFD && width == 1 {
			errors++
		} else {
			counts.Inc(rune)
		}
	}
}

func print() {
	if countBytes {
		printCounts("%.2x %c\t%d\n", "%.2x -\t%d\n")
	} else {
		printCounts("%.4x %c\t%d\n", "%.4x -\t%d\n")
	}
}

func printCounts(printable, unprintable string) {
	for b2 := range *counts {
		c2 := (*counts)[b2]
		if c2 == nil {
			continue
		}
		for b1 := range c2 {
			c1 := c2[b1]
			if c1 == nil {
				continue
			}
			for b0, count := range c1 {
				if count == 0 {
					continue
				}
				var r rune = rune((b2 << 16) | (b1 << 8) | b0)
				if r != ' ' && strconv.IsPrint(r) {
					fmt.Printf(printable, r, r, count)
				} else {
					fmt.Printf(unprintable, r, count)
				}
			}
		}
	}
	if errors > 0 {
		fmt.Printf("error -\t%d\n", errors)
	}
}
<|endoftext|>


<commit_before>// This package implements a provisioner for Packer that executes
// shell scripts within the remote machine.
package shell

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"github.com/mitchellh/iochan"
	"github.com/mitchellh/mapstructure"
	"github.com/mitchellh/packer/packer"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"text/template"
)

const DefaultRemotePath = "/tmp/script.sh"

type config struct {
	// An inline script to execute. Multiple strings are all executed
	// in the context of a single shell.
	Inline []string

	// The local path of the shell script to upload and execute.
	Path string

	// An array of multiple scripts to run.
	Scripts []string

	// The remote path where the local shell script will be uploaded to.
	// This should be set to a writable file that is in a pre-existing directory.
	RemotePath string `mapstructure:"remote_path"`

	// The command used to execute the script. The '{{ .Path }}' variable
	// should be used to specify where the script goes.
	ExecuteCommand string `mapstructure:"execute_command"`
}

type Provisioner struct {
	config config
}

type ExecuteCommandTemplate struct {
	Path string
}

func (p *Provisioner) Prepare(raws ...interface{}) error {
	for _, raw := range raws {
		if err := mapstructure.Decode(raw, &p.config); err != nil {
			return err
		}
	}

	if p.config.ExecuteCommand == "" {
		p.config.ExecuteCommand = "sh {{.Path}}"
	}

	if p.config.Inline != nil && len(p.config.Inline) == 0 {
		p.config.Inline = nil
	}

	if p.config.RemotePath == "" {
		p.config.RemotePath = DefaultRemotePath
	}

	if p.config.Scripts == nil {
		p.config.Scripts = make([]string, 0)
	}

	errs := make([]error, 0)

	if p.config.Path != "" && len(p.config.Scripts) > 0 {
		errs = append(errs, errors.New("Only one of path or scripts can be specified."))
	}

	if p.config.Path != "" {
		p.config.Scripts = []string{p.config.Path}
	}

	if len(p.config.Scripts) == 0 && p.config.Inline == nil {
		errs = append(errs, errors.New("Either a script file or inline script must be specified."))
	} else if len(p.config.Scripts) > 0 && p.config.Inline != nil {
		errs = append(errs, errors.New("Only a script file or an inline script can be specified, not both."))
	}

	for _, path := range p.config.Scripts {
		if _, err := os.Stat(path); err != nil {
			errs = append(errs, fmt.Errorf("Bad script '%s': %s", path, err))
		}
	}

	if len(errs) > 0 {
		return &packer.MultiError{errs}
	}

	return nil
}

func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) {
	scripts := make([]string, len(p.config.Scripts))
	copy(scripts, p.config.Scripts)

	// If we have an inline script, then turn that into a temporary
	// shell script and use that.
	if p.config.Inline != nil {
		tf, err := ioutil.TempFile("", "packer-shell")
		if err != nil {
			ui.Error(fmt.Sprintf("Error preparing shell script: %s", err))
			return
		}
		defer os.Remove(tf.Name())

		// Set the path to the temporary file
		scripts = append(scripts, tf.Name())

		// Write our contents to it
		writer := bufio.NewWriter(tf)
		for _, command := range p.config.Inline {
			if _, err := writer.WriteString(command + "\n"); err != nil {
				ui.Error(fmt.Sprintf("Error preparing shell script: %s", err))
				return
			}
		}

		if err := writer.Flush(); err != nil {
			ui.Error(fmt.Sprintf("Error preparing shell script: %s", err))
			return
		}

		tf.Close()
	}

	for _, path := range scripts {
		ui.Say(fmt.Sprintf("Provisioning with shell script: %s", path))

		log.Printf("Opening %s for reading", path)
		f, err := os.Open(path)
		if err != nil {
			ui.Error(fmt.Sprintf("Error opening shell script: %s", err))
			return
		}

		log.Printf("Uploading %s => %s", path, p.config.RemotePath)
		err = comm.Upload(p.config.RemotePath, f)
		if err != nil {
			ui.Error(fmt.Sprintf("Error uploading shell script: %s", err))
			return
		}

		// Compile the command
		var command bytes.Buffer
		t := template.Must(template.New("command").Parse(p.config.ExecuteCommand))
		t.Execute(&command, &ExecuteCommandTemplate{p.config.RemotePath})

		// Setup the remote command
		stdout_r, stdout_w := io.Pipe()
		stderr_r, stderr_w := io.Pipe()

		var cmd packer.RemoteCmd
		cmd.Command = command.String()
		cmd.Stdout = stdout_w
		cmd.Stderr = stderr_w

		log.Printf("Executing command: %s", cmd.Command)
		err = comm.Start(&cmd)
		if err != nil {
			ui.Error(fmt.Sprintf("Failed executing command: %s", err))
			return
		}

		exitChan := make(chan int, 1)
		stdoutChan := iochan.DelimReader(stdout_r, '\n')
		stderrChan := iochan.DelimReader(stderr_r, '\n')

		go func() {
			defer stdout_w.Close()
			defer stderr_w.Close()

			cmd.Wait()
			exitChan <- cmd.ExitStatus
		}()

	OutputLoop:
		for {
			select {
			case output := <-stderrChan:
				ui.Message(strings.TrimSpace(output))
			case output := <-stdoutChan:
				ui.Message(strings.TrimSpace(output))
			case exitStatus := <-exitChan:
				log.Printf("shell provisioner exited with status %d", exitStatus)

				if exitStatus != 0 {
					ui.Error(fmt.Sprintf("Script excited with non-zero exit status: %d", exitStatus))
				}

				break OutputLoop
			}
		}

		// Make sure we finish off stdout/stderr because we may have gotten
		// a message from the exit channel first.
		for output := range stdoutChan {
			ui.Message(output)
		}

		for output := range stderrChan {
			ui.Message(output)
		}
	}
}
<commit_msg>provisioner/shell: Error if a script fails<commit_after>// This package implements a provisioner for Packer that executes
// shell scripts within the remote machine.
package shell

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"github.com/mitchellh/iochan"
	"github.com/mitchellh/mapstructure"
	"github.com/mitchellh/packer/packer"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"text/template"
)

const DefaultRemotePath = "/tmp/script.sh"

type config struct {
	// An inline script to execute. Multiple strings are all executed
	// in the context of a single shell.
	Inline []string

	// The local path of the shell script to upload and execute.
	Path string

	// An array of multiple scripts to run.
	Scripts []string

	// The remote path where the local shell script will be uploaded to.
	// This should be set to a writable file that is in a pre-existing directory.
	RemotePath string `mapstructure:"remote_path"`

	// The command used to execute the script. The '{{ .Path }}' variable
	// should be used to specify where the script goes.
	ExecuteCommand string `mapstructure:"execute_command"`
}

type Provisioner struct {
	config config
}

type ExecuteCommandTemplate struct {
	Path string
}

func (p *Provisioner) Prepare(raws ...interface{}) error {
	for _, raw := range raws {
		if err := mapstructure.Decode(raw, &p.config); err != nil {
			return err
		}
	}

	if p.config.ExecuteCommand == "" {
		p.config.ExecuteCommand = "sh {{.Path}}"
	}

	if p.config.Inline != nil && len(p.config.Inline) == 0 {
		p.config.Inline = nil
	}

	if p.config.RemotePath == "" {
		p.config.RemotePath = DefaultRemotePath
	}

	if p.config.Scripts == nil {
		p.config.Scripts = make([]string, 0)
	}

	errs := make([]error, 0)

	if p.config.Path != "" && len(p.config.Scripts) > 0 {
		errs = append(errs, errors.New("Only one of path or scripts can be specified."))
	}

	if p.config.Path != "" {
		p.config.Scripts = []string{p.config.Path}
	}

	if len(p.config.Scripts) == 0 && p.config.Inline == nil {
		errs = append(errs, errors.New("Either a script file or inline script must be specified."))
	} else if len(p.config.Scripts) > 0 && p.config.Inline != nil {
		errs = append(errs, errors.New("Only a script file or an inline script can be specified, not both."))
	}

	for _, path := range p.config.Scripts {
		if _, err := os.Stat(path); err != nil {
			errs = append(errs, fmt.Errorf("Bad script '%s': %s", path, err))
		}
	}

	if len(errs) > 0 {
		return &packer.MultiError{errs}
	}

	return nil
}

func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
	scripts := make([]string, len(p.config.Scripts))
	copy(scripts, p.config.Scripts)

	// If we have an inline script, then turn that into a temporary
	// shell script and use that.
	if p.config.Inline != nil {
		tf, err := ioutil.TempFile("", "packer-shell")
		if err != nil {
			return fmt.Errorf("Error preparing shell script: %s", err)
		}
		defer os.Remove(tf.Name())

		// Set the path to the temporary file
		scripts = append(scripts, tf.Name())

		// Write our contents to it
		writer := bufio.NewWriter(tf)
		for _, command := range p.config.Inline {
			if _, err := writer.WriteString(command + "\n"); err != nil {
				return fmt.Errorf("Error preparing shell script: %s", err)
			}
		}

		if err := writer.Flush(); err != nil {
			return fmt.Errorf("Error preparing shell script: %s", err)
		}

		tf.Close()
	}

	for _, path := range scripts {
		ui.Say(fmt.Sprintf("Provisioning with shell script: %s", path))

		log.Printf("Opening %s for reading", path)
		f, err := os.Open(path)
		if err != nil {
			return fmt.Errorf("Error opening shell script: %s", err)
		}

		log.Printf("Uploading %s => %s", path, p.config.RemotePath)
		err = comm.Upload(p.config.RemotePath, f)
		if err != nil {
			return fmt.Errorf("Error uploading shell script: %s", err)
		}

		// Compile the command
		var command bytes.Buffer
		t := template.Must(template.New("command").Parse(p.config.ExecuteCommand))
		t.Execute(&command, &ExecuteCommandTemplate{p.config.RemotePath})

		// Setup the remote command
		stdout_r, stdout_w := io.Pipe()
		stderr_r, stderr_w := io.Pipe()

		var cmd packer.RemoteCmd
		cmd.Command = command.String()
		cmd.Stdout = stdout_w
		cmd.Stderr = stderr_w

		log.Printf("Executing command: %s", cmd.Command)
		err = comm.Start(&cmd)
		if err != nil {
			return fmt.Errorf("Failed executing command: %s", err)
		}

		exitChan := make(chan int, 1)
		stdoutChan := iochan.DelimReader(stdout_r, '\n')
		stderrChan := iochan.DelimReader(stderr_r, '\n')

		go func() {
			defer stdout_w.Close()
			defer stderr_w.Close()

			cmd.Wait()
			exitChan <- cmd.ExitStatus
		}()

	OutputLoop:
		for {
			select {
			case output := <-stderrChan:
				ui.Message(strings.TrimSpace(output))
			case output := <-stdoutChan:
				ui.Message(strings.TrimSpace(output))
			case exitStatus := <-exitChan:
				log.Printf("shell provisioner exited with status %d", exitStatus)

				if exitStatus != 0 {
					return fmt.Errorf("Script exited with non-zero exit status: %d", exitStatus)
				}

				break OutputLoop
			}
		}

		// Make sure we finish off stdout/stderr because we may have gotten
		// a message from the exit channel first.
		for output := range stdoutChan {
			ui.Message(output)
		}

		for output := range stderrChan {
			ui.Message(output)
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package ftls

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"net"
)

var (
	DefaultMinVersion = uint16(tls.VersionTLS12)
	DefaultCipherSet  = []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}
)

type Ftsl struct {
	c *Config
}

type Config struct {
	StrictClientVerify bool
	MutualTLS          bool
	InsecureSkipVerify bool
	MinVersion         uint16
	CipherSet          []uint16
	CertFile           string
	KeyFile            string
	CAFile             string
}

// DefaultServerFTLSConf returns a ftls config with the most commonly used config set.
func DefaultServerFTLSConf(CertFile, KeyFile, CAFile string) *Config {
	return &Config{
		StrictClientVerify: true,
		MutualTLS:          true,
		InsecureSkipVerify: false,
		MinVersion:         DefaultMinVersion,
		CipherSet:          DefaultCipherSet,
		CertFile:           CertFile,
		KeyFile:            KeyFile,
		CAFile:             CAFile,
	}
}

// DefaultClientFTLSConf returns a ftls config with the most commonly used config set.
func DefaultClientFTLSConf(CertFile, KeyFile, CAFile string) *Config {
	return &Config{
		MutualTLS:          true,
		InsecureSkipVerify: false,
		MinVersion:         DefaultMinVersion,
		CertFile:           CertFile,
		KeyFile:            KeyFile,
		CAFile:             CAFile,
	}
}

// NewClientTLSConfig constructs a client tls.Conf from provide ftls Config.
func NewClientTLSConfig(c *Config) (*tls.Config, error) {
	cert, err := tls.LoadX509KeyPair(c.CertFile, c.KeyFile)
	if err != nil {
		return &tls.Config{}, fmt.Errorf("Unable to load cert %s %s: %s", c.CertFile, c.KeyFile, err.Error())
	}
	clientCertPool := x509.NewCertPool()
	if c.CAFile != "" {
		clientCACert, err := ioutil.ReadFile(c.CAFile)
		if err != nil {
			return &tls.Config{}, fmt.Errorf("Unable to load CA cert %s: %s", c.CAFile, err.Error())
		}
		clientCertPool.AppendCertsFromPEM(clientCACert)
	}
	if c.MutualTLS {
		tlsConf := &tls.Config{
			Certificates: []tls.Certificate{cert},
			RootCAs:      clientCertPool,
			CipherSuites: c.CipherSet,
			MinVersion:   DefaultMinVersion,
		}
		tlsConf.BuildNameToCertificate()
		return tlsConf, nil
	}
	return &tls.Config{RootCAs: clientCertPool, InsecureSkipVerify: c.InsecureSkipVerify}, nil
}

// NewServerTLSConfig constructs a server tls.Conf from the provided ftls Config.
func NewServerTLSConfig(c *Config) (*tls.Config, error) {
	tlsConf := &tls.Config{}
	if c.MutualTLS {
		caCert, err := ioutil.ReadFile(c.CAFile)
		if err != nil {
			return nil, fmt.Errorf("Unable to load ca cert %s: %s", c.CAFile, err.Error())
		}
		clientCertPool := x509.NewCertPool()
		if ok := clientCertPool.AppendCertsFromPEM(caCert); !ok {
			return nil, fmt.Errorf("Unable to append cert %s to pool.", c.CAFile)
		}
		strictness := tls.RequireAndVerifyClientCert
		if !c.StrictClientVerify {
			strictness = tls.RequireAnyClientCert
		}
		tlsConf = &tls.Config{
			ClientAuth:               strictness,
			ClientCAs:                clientCertPool,
			CipherSuites:             c.CipherSet,
			PreferServerCipherSuites: true,
			MinVersion:               DefaultMinVersion,
		}
		tlsConf.BuildNameToCertificate()
	}
	cert, err := tls.LoadX509KeyPair(c.CertFile, c.KeyFile)
	if err != nil {
		return nil, err
	}
	tlsConf.Certificates = []tls.Certificate{cert}
	tlsConf.InsecureSkipVerify = c.InsecureSkipVerify
	return tlsConf, nil
}

func VerifyClientAddrMatch(c *tls.Conn) error {
	err := c.Handshake()
	if err != nil {
		return err
	}
	addr, _, err := net.SplitHostPort(c.RemoteAddr().String())
	if err != nil {
		return err
	}
	return c.ConnectionState().VerifiedChains[0][0].VerifyHostname(addr)
}
<commit_msg>Add grpc dial opt shortcut<commit_after>package ftls

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"net"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

var (
	DefaultMinVersion = uint16(tls.VersionTLS12)
	DefaultCipherSet  = []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}
)

type Ftsl struct {
	c *Config
}

type Config struct {
	StrictClientVerify bool
	MutualTLS          bool
	InsecureSkipVerify bool
	MinVersion         uint16
	CipherSet          []uint16
	CertFile           string
	KeyFile            string
	CAFile             string
}

// DefaultServerFTLSConf returns a ftls config with the most commonly used config set.
func DefaultServerFTLSConf(CertFile, KeyFile, CAFile string) *Config {
	return &Config{
		StrictClientVerify: true,
		MutualTLS:          true,
		InsecureSkipVerify: false,
		MinVersion:         DefaultMinVersion,
		CipherSet:          DefaultCipherSet,
		CertFile:           CertFile,
		KeyFile:            KeyFile,
		CAFile:             CAFile,
	}
}

// DefaultClientFTLSConf returns a ftls config with the most commonly used config set.
func DefaultClientFTLSConf(CertFile, KeyFile, CAFile string) *Config {
	return &Config{
		MutualTLS:          true,
		InsecureSkipVerify: false,
		MinVersion:         DefaultMinVersion,
		CertFile:           CertFile,
		KeyFile:            KeyFile,
		CAFile:             CAFile,
	}
}

// NewClientTLSConfig constructs a client tls.Conf from provide ftls Config.
func NewClientTLSConfig(c *Config) (*tls.Config, error) {
	cert, err := tls.LoadX509KeyPair(c.CertFile, c.KeyFile)
	if err != nil {
		return &tls.Config{}, fmt.Errorf("Unable to load cert %s %s: %s", c.CertFile, c.KeyFile, err.Error())
	}
	clientCertPool := x509.NewCertPool()
	if c.CAFile != "" {
		clientCACert, err := ioutil.ReadFile(c.CAFile)
		if err != nil {
			return &tls.Config{}, fmt.Errorf("Unable to load CA cert %s: %s", c.CAFile, err.Error())
		}
		clientCertPool.AppendCertsFromPEM(clientCACert)
	}
	if c.MutualTLS {
		tlsConf := &tls.Config{
			Certificates: []tls.Certificate{cert},
			RootCAs:      clientCertPool,
			CipherSuites: c.CipherSet,
			MinVersion:   DefaultMinVersion,
		}
		tlsConf.BuildNameToCertificate()
		return tlsConf, nil
	}
	return &tls.Config{RootCAs: clientCertPool, InsecureSkipVerify: c.InsecureSkipVerify}, nil
}

// NewServerTLSConfig constructs a server tls.Conf from the provided ftls Config.
func NewServerTLSConfig(c *Config) (*tls.Config, error) {
	tlsConf := &tls.Config{}
	if c.MutualTLS {
		caCert, err := ioutil.ReadFile(c.CAFile)
		if err != nil {
			return nil, fmt.Errorf("Unable to load ca cert %s: %s", c.CAFile, err.Error())
		}
		clientCertPool := x509.NewCertPool()
		if ok := clientCertPool.AppendCertsFromPEM(caCert); !ok {
			return nil, fmt.Errorf("Unable to append cert %s to pool.", c.CAFile)
		}
		strictness := tls.RequireAndVerifyClientCert
		if !c.StrictClientVerify {
			strictness = tls.RequireAnyClientCert
		}
		tlsConf = &tls.Config{
			ClientAuth:               strictness,
			ClientCAs:                clientCertPool,
			CipherSuites:             c.CipherSet,
			PreferServerCipherSuites: true,
			MinVersion:               DefaultMinVersion,
		}
		tlsConf.BuildNameToCertificate()
	}
	cert, err := tls.LoadX509KeyPair(c.CertFile, c.KeyFile)
	if err != nil {
		return nil, err
	}
	tlsConf.Certificates = []tls.Certificate{cert}
	tlsConf.InsecureSkipVerify = c.InsecureSkipVerify
	return tlsConf, nil
}

func NewGRPCClientDialOpt(c *Config) (grpc.DialOption, error) {
	var opt grpc.DialOption
	tlsConf, err := NewClientTLSConfig(c)
	if err != nil {
		return opt, err
	}
	return grpc.WithTransportCredentials(credentials.NewTLS(tlsConf)), nil
}

func VerifyClientAddrMatch(c *tls.Conn) error {
	err := c.Handshake()
	if err != nil {
		return err
	}
	addr, _, err := net.SplitHostPort(c.RemoteAddr().String())
	if err != nil {
		return err
	}
	return c.ConnectionState().VerifiedChains[0][0].VerifyHostname(addr)
}
<|endoftext|>


<commit_before>/* Copyright 2019 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package gonids

func FuzzParseRule(data []byte) int {
	r, err := ParseRule(string(data))
	if err != nil {
		// Handle parse error
		return 0
	}
	r.OptimizeHTTP()
	return 1
}
<commit_msg>Add comment for exported function.<commit_after>/* Copyright 2019 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package gonids

// FuzzParseRule is used by OSS-Fuzz to fuzz the library.
func FuzzParseRule(data []byte) int {
	r, err := ParseRule(string(data))
	if err != nil {
		// Handle parse error
		return 0
	}
	r.OptimizeHTTP()
	return 1
}
<|endoftext|>


<commit_before>// Copyright 2015 Davis Webb
// Copyright 2015 Luke Shumaker

package store

import (
	"github.com/jinzhu/gorm"
	he "httpentity"
	"httpentity/util"
	"io"
	"net/http"
	"strings"
	"time"
)

var _ he.NetEntity = &Session{}
var fileSession he.Entity = newFileSession()

// Model /////////////////////////////////////////////////////////////

type Session struct {
	Id       string
	UserId   string
	LastUsed time.Time
}

func (o Session) schema(db *gorm.DB) {
	table := db.CreateTable(&o)
	table.AddForeignKey("user_id", "users(id)", "RESTRICT", "RESTRICT")
}

func NewSession(db *gorm.DB, user *User, password string) *Session {
	if user == nil || !user.CheckPassword(password) {
		return nil
	}
	o := Session{
		Id:       randomString(24),
		UserId:   user.Id,
		LastUsed: time.Now(),
	}
	if err := db.Create(&o).Error; err != nil {
		panic(err)
	}
	return &o
}

func GetSessionById(db *gorm.DB, id string) *Session {
	var o Session
	if result := db.First(&o, "id = ?", id); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func (o *Session) Delete(db *gorm.DB) {
	db.Delete(o)
}

func (o *Session) Save(db *gorm.DB) {
	if err := db.Save(o).Error; err != nil {
		panic(err)
	}
}

// View //////////////////////////////////////////////////////////////

func (sess *Session) Encoders() map[string]func(io.Writer) error {
	dat := map[string]string{
		"session_id": sess.Id,
	}
	return defaultEncoders(dat)
}

// File ("Controller") ///////////////////////////////////////////////

type t_fileSession struct {
	methods map[string]func(he.Request) he.Response
}

func newFileSession() t_fileSession {
	r := t_fileSession{}
	r.methods = map[string]func(he.Request) he.Response{
		"POST": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			badbody := req.StatusBadRequest(heutil.NetString("submitted body not what expected"))
			hash, ok := req.Entity.(map[string]interface{}); if !ok { return badbody }
			username, ok := hash["username"].(string)      ; if !ok { return badbody }
			password, ok := hash["password"].(string)      ; if !ok { return badbody }
			if len(hash) != 2                                       { return badbody }

			var user *User
			if strings.Contains(username, "@") {
				user = GetUserByAddress(db, "email", username)
			} else {
				user = GetUserById(db, username)
			}

			sess := NewSession(db, user, password)
			if sess == nil {
				return req.StatusUnauthorized(heutil.NetString("Incorrect username/password"))
			} else {
				ret := req.StatusOK(sess)
				cookie := &http.Cookie{
					Name:     "session_id",
					Value:    sess.Id,
					Secure:   req.Scheme == "https",
					HttpOnly: req.Scheme == "http",
				}
				ret.Headers.Add("Set-Cookie", cookie.String())
				return ret
			}
		},
		"DELETE": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			sess := req.Things["session"].(*Session)
			if sess != nil {
				sess.Delete(db)
			}
			return req.StatusNoContent()
		},
	}
	return r
}

func (d t_fileSession) Methods() map[string]func(he.Request) he.Response {
	return d.methods
}

func (d t_fileSession) Subentity(name string, request he.Request) he.Entity {
	return nil
}
<commit_msg>have the session creation also return the canonicalized user_id.<commit_after>// Copyright 2015 Davis Webb
// Copyright 2015 Luke Shumaker

package store

import (
	"github.com/jinzhu/gorm"
	he "httpentity"
	"httpentity/util"
	"io"
	"net/http"
	"strings"
	"time"
)

var _ he.NetEntity = &Session{}
var fileSession he.Entity = newFileSession()

// Model /////////////////////////////////////////////////////////////

type Session struct {
	Id       string    `json:"session_id"`
	UserId   string    `json:"user_id"`
	LastUsed time.Time `json:"-"`
}

func (o Session) schema(db *gorm.DB) {
	table := db.CreateTable(&o)
	table.AddForeignKey("user_id", "users(id)", "RESTRICT", "RESTRICT")
}

func NewSession(db *gorm.DB, user *User, password string) *Session {
	if user == nil || !user.CheckPassword(password) {
		return nil
	}
	o := Session{
		Id:       randomString(24),
		UserId:   user.Id,
		LastUsed: time.Now(),
	}
	if err := db.Create(&o).Error; err != nil {
		panic(err)
	}
	return &o
}

func GetSessionById(db *gorm.DB, id string) *Session {
	var o Session
	if result := db.First(&o, "id = ?", id); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func (o *Session) Delete(db *gorm.DB) {
	db.Delete(o)
}

func (o *Session) Save(db *gorm.DB) {
	if err := db.Save(o).Error; err != nil {
		panic(err)
	}
}

// View //////////////////////////////////////////////////////////////

func (sess *Session) Encoders() map[string]func(io.Writer) error {
	return defaultEncoders(sess)
}

// File ("Controller") ///////////////////////////////////////////////

type t_fileSession struct {
	methods map[string]func(he.Request) he.Response
}

func newFileSession() t_fileSession {
	r := t_fileSession{}
	r.methods = map[string]func(he.Request) he.Response{
		"POST": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			badbody := req.StatusBadRequest(heutil.NetString("submitted body not what expected"))
			hash, ok := req.Entity.(map[string]interface{}); if !ok { return badbody }
			username, ok := hash["username"].(string)      ; if !ok { return badbody }
			password, ok := hash["password"].(string)      ; if !ok { return badbody }
			if len(hash) != 2                                       { return badbody }

			var user *User
			if strings.Contains(username, "@") {
				user = GetUserByAddress(db, "email", username)
			} else {
				user = GetUserById(db, username)
			}

			sess := NewSession(db, user, password)
			if sess == nil {
				return req.StatusUnauthorized(heutil.NetString("Incorrect username/password"))
			} else {
				ret := req.StatusOK(sess)
				cookie := &http.Cookie{
					Name:     "session_id",
					Value:    sess.Id,
					Secure:   req.Scheme == "https",
					HttpOnly: req.Scheme == "http",
				}
				ret.Headers.Add("Set-Cookie", cookie.String())
				return ret
			}
		},
		"DELETE": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			sess := req.Things["session"].(*Session)
			if sess != nil {
				sess.Delete(db)
			}
			return req.StatusNoContent()
		},
	}
	return r
}

func (d t_fileSession) Methods() map[string]func(he.Request) he.Response {
	return d.methods
}

func (d t_fileSession) Subentity(name string, request he.Request) he.Entity {
	return nil
}
<|endoftext|>


<commit_before>package gelf

import (
	"log"
	"os"
	"strings"
	"time"

	"github.com/Graylog2/go-gelf/gelf"
	"github.com/gliderlabs/logspout/router"
)

var hostname string

func init() {
	hostname, _ = os.Hostname()
	router.AdapterFactories.Register(New, "gelf")
}

// Adapter is an adapter that streams UDP JSON to Graylog
type Adapter struct {
	route *router.Route
}

// New creates a GelfAdapter with UDP as the default transport.
func New(route *router.Route) (router.LogAdapter, error) {
	// test the address, but don't use this writer
	writer, err := gelf.NewWriter(route.Address)
	if err != nil {
		return nil, err
	}
	writer.Close()

	return &Adapter{
		route: route,
	}, nil
}

func streamSome(writer *gelf.Writer, logstream chan *router.Message, cancel <-chan time.Time) {
	for {
		select {
		case msg := <-logstream:
			if err := writer.WriteMessage(&gelf.Message{
				Version:  "1.1",
				Host:     hostname, // Running as a container cannot discover the Docker Hostname
				Short:    msg.Data,
				TimeUnix: float64(msg.Time.UnixNano()/int64(time.Millisecond)) / 1000.0,
				Level:    gelf.LOG_INFO, // TODO: be smarter about this? stdout vs. stderr are not log levels
				Extra: map[string]interface{}{
					"_container_id":   msg.Container.ID,
					"_container_name": msg.Container.Name,
					"_image_id":       msg.Container.Image,
					"_image_name":     msg.Container.Config.Image,
					"_command":        strings.Join(msg.Container.Config.Cmd, " "),
					"_created":        msg.Container.Created,
				},
			}); err != nil {
				log.Printf("error sending GELF message: %s", err)
			}

		case <-cancel:
			return
		}
	}
}

func dropSome(logstream chan *router.Message, cancel <-chan time.Time) {
	for {
		select {
		case msg := <-logstream:
			log.Printf("dropping log message: %s", msg.Data)
		case <-cancel:
			return
		}
	}
}

// Stream implements the router.LogAdapter interface.
func (a *Adapter) Stream(logstream chan *router.Message) {
	for {
		writer, err := gelf.NewWriter(a.route.Address)
		if err != nil {
			log.Printf("error dialing %s: %s", a.route.Address, err)

			// Try redial after 5 seconds
			dropSome(logstream, time.After(5*time.Second))
		} else {
			log.Printf("dialed %s", a.route.Address)

			// Redial after 1 minute. Maybe DNS changed?
			streamSome(writer, logstream, time.After(1*time.Minute))
		}
	}
}
<commit_msg>Disable compression for localhost use.<commit_after>package gelf

import (
	"compress/flate"
	"log"
	"os"
	"strings"
	"time"

	"github.com/Graylog2/go-gelf/gelf"
	"github.com/gliderlabs/logspout/router"
)

var hostname string

func init() {
	hostname, _ = os.Hostname()
	router.AdapterFactories.Register(New, "gelf")
}

// Adapter is an adapter that streams UDP JSON to Graylog
type Adapter struct {
	route *router.Route
}

// New creates a GelfAdapter with UDP as the default transport.
func New(route *router.Route) (router.LogAdapter, error) {
	// test the address, but don't use this writer
	writer, err := gelf.NewWriter(route.Address)
	if err != nil {
		return nil, err
	}
	writer.Close()

	return &Adapter{
		route: route,
	}, nil
}

func streamSome(writer *gelf.Writer, logstream chan *router.Message, cancel <-chan time.Time) {
	for {
		select {
		case msg := <-logstream:
			if err := writer.WriteMessage(&gelf.Message{
				Version:  "1.1",
				Host:     hostname, // Running as a container cannot discover the Docker Hostname
				Short:    msg.Data,
				TimeUnix: float64(msg.Time.UnixNano()/int64(time.Millisecond)) / 1000.0,
				Level:    gelf.LOG_INFO, // TODO: be smarter about this? stdout vs. stderr are not log levels
				Extra: map[string]interface{}{
					"_container_id":   msg.Container.ID,
					"_container_name": msg.Container.Name,
					"_image_id":       msg.Container.Image,
					"_image_name":     msg.Container.Config.Image,
					"_command":        strings.Join(msg.Container.Config.Cmd, " "),
					"_created":        msg.Container.Created,
				},
			}); err != nil {
				log.Printf("error sending GELF message: %s", err)
			}

		case <-cancel:
			return
		}
	}
}

func dropSome(logstream chan *router.Message, cancel <-chan time.Time) {
	for {
		select {
		case msg := <-logstream:
			log.Printf("dropping log message: %s", msg.Data)
		case <-cancel:
			return
		}
	}
}

// Stream implements the router.LogAdapter interface.
func (a *Adapter) Stream(logstream chan *router.Message) {
	for {
		writer, err := gelf.NewWriter(a.route.Address)
		if err != nil {
			log.Printf("error dialing %s: %s", a.route.Address, err)

			// Try redial after 5 seconds
			dropSome(logstream, time.After(5*time.Second))
		} else {
			log.Printf("dialed %s", a.route.Address)
		// intended to forward logs to a service on localhost
		writer.CompressionLevel = flate.NoCompression

			// Redial after 1 minute. Maybe DNS changed?
			streamSome(writer, logstream, time.After(1*time.Minute))
		}
	}
}
<|endoftext|>


<commit_before>package container

import (
	"strings"

	"github.com/docker/distribution/reference"
	"github.com/docker/engine-api/types"
	enginecontainer "github.com/docker/engine-api/types/container"
	"github.com/docker/engine-api/types/events"
	"github.com/docker/engine-api/types/filters"
	"github.com/docker/engine-api/types/network"
	"github.com/docker/swarm-v2/agent/exec"
	"github.com/docker/swarm-v2/api"
)

// containerConfig converts task properties into docker container compatible
// components.
type containerConfig struct {
	task    *api.Task
	runtime *api.ContainerSpec // resolved container specification.
	popts   types.ImagePullOptions
}

// newContainerConfig returns a validated container config. No methods should
// return an error if this function returns without error.
func newContainerConfig(t *api.Task) (*containerConfig, error) {
	c := &containerConfig{task: t}

	runtime := t.Spec.GetContainer()
	if runtime == nil {
		return nil, exec.ErrRuntimeUnsupported
	}

	if runtime.Image == nil {
		return nil, ErrImageRequired
	}

	if runtime.Image.Reference == "" {
		return nil, ErrImageRequired
	}

	c.runtime = runtime

	var err error
	c.popts, err = c.buildPullOptions()
	if err != nil {
		return nil, err
	}

	return c, nil
}

func (c *containerConfig) name() string {
	const prefix = "com.docker.cluster.task"
	return strings.Join([]string{prefix, c.task.NodeID, c.task.JobID, c.task.ID}, ".")
}

func (c *containerConfig) image() string {
	return c.runtime.Image.Reference
}

func (c *containerConfig) config() *enginecontainer.Config {
	return &enginecontainer.Config{
		Cmd:   c.runtime.Command, // TODO(stevvooe): Fall back to entrypoint+args
		Env:   c.runtime.Env,
		Image: c.image(),
	}
}

func (c *containerConfig) hostConfig() *enginecontainer.HostConfig {
	return &enginecontainer.HostConfig{}
}

func (c *containerConfig) networkingConfig() *network.NetworkingConfig {
	return &network.NetworkingConfig{}
}

func (c *containerConfig) pullOptions() types.ImagePullOptions {
	return c.popts
}

func (c *containerConfig) buildPullOptions() (types.ImagePullOptions, error) {
	var ref reference.NamedTagged
	named, err := reference.ParseNamed(c.image())
	if err != nil {
		return types.ImagePullOptions{}, err
	}

	if namedtagged, ok := named.(reference.NamedTagged); !ok {
		tagged, err := reference.WithTag(named, "latest")
		if err != nil {
			return types.ImagePullOptions{}, err
		}
		ref = tagged
	} else {
		ref = namedtagged
	}

	return types.ImagePullOptions{
		ImageID: ref.Name(),
		Tag:     ref.Tag(),
	}, nil
}

func (c containerConfig) eventFilter() filters.Args {
	filter := filters.NewArgs()
	filter.Add("type", events.ContainerEventType)
	filter.Add("name", c.name())
	return filter
}
<commit_msg>agent/exec/container: handle image digests<commit_after>package container

import (
	"strings"

	"github.com/docker/distribution/reference"
	"github.com/docker/engine-api/types"
	enginecontainer "github.com/docker/engine-api/types/container"
	"github.com/docker/engine-api/types/events"
	"github.com/docker/engine-api/types/filters"
	"github.com/docker/engine-api/types/network"
	"github.com/docker/swarm-v2/agent/exec"
	"github.com/docker/swarm-v2/api"
)

// containerConfig converts task properties into docker container compatible
// components.
type containerConfig struct {
	task    *api.Task
	runtime *api.ContainerSpec // resolved container specification.
	popts   types.ImagePullOptions
}

// newContainerConfig returns a validated container config. No methods should
// return an error if this function returns without error.
func newContainerConfig(t *api.Task) (*containerConfig, error) {
	c := &containerConfig{task: t}

	runtime := t.Spec.GetContainer()
	if runtime == nil {
		return nil, exec.ErrRuntimeUnsupported
	}

	if runtime.Image == nil {
		return nil, ErrImageRequired
	}

	if runtime.Image.Reference == "" {
		return nil, ErrImageRequired
	}

	c.runtime = runtime

	var err error
	c.popts, err = c.buildPullOptions()
	if err != nil {
		return nil, err
	}

	return c, nil
}

func (c *containerConfig) name() string {
	const prefix = "com.docker.cluster.task"
	return strings.Join([]string{prefix, c.task.NodeID, c.task.JobID, c.task.ID}, ".")
}

func (c *containerConfig) image() string {
	return c.runtime.Image.Reference
}

func (c *containerConfig) config() *enginecontainer.Config {
	return &enginecontainer.Config{
		Cmd:   c.runtime.Command, // TODO(stevvooe): Fall back to entrypoint+args
		Env:   c.runtime.Env,
		Image: c.image(),
	}
}

func (c *containerConfig) hostConfig() *enginecontainer.HostConfig {
	return &enginecontainer.HostConfig{}
}

func (c *containerConfig) networkingConfig() *network.NetworkingConfig {
	return &network.NetworkingConfig{}
}

func (c *containerConfig) pullOptions() types.ImagePullOptions {
	return c.popts
}

func (c *containerConfig) buildPullOptions() (types.ImagePullOptions, error) {
	named, err := reference.ParseNamed(c.image())
	if err != nil {
		return types.ImagePullOptions{}, err
	}

	var (
		name = named.Name()
		tag  = "latest"
	)

	// replace tag with more specific item from ref
	switch v := named.(type) {
	case reference.Canonical:
		tag = v.Digest().String()
	case reference.NamedTagged:
		tag = v.Tag()

	}

	return types.ImagePullOptions{
		ImageID: name,
		Tag:     tag,
	}, nil
}

func (c containerConfig) eventFilter() filters.Args {
	filter := filters.NewArgs()
	filter.Add("type", events.ContainerEventType)
	filter.Add("name", c.name())
	return filter
}
<|endoftext|>


<commit_before>package loggerutils

import (
	"bufio"
	"context"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/docker/docker/daemon/logger"
	"github.com/docker/docker/pkg/tailfile"
	"gotest.tools/assert"
)

func TestTailFiles(t *testing.T) {
	s1 := strings.NewReader("Hello.\nMy name is Inigo Montoya.\n")
	s2 := strings.NewReader("I'm serious.\nDon't call me Shirley!\n")
	s3 := strings.NewReader("Roads?\nWhere we're going we don't need roads.\n")

	files := []SizeReaderAt{s1, s2, s3}
	watcher := logger.NewLogWatcher()
	createDecoder := func(r io.Reader) func() (*logger.Message, error) {
		scanner := bufio.NewScanner(r)
		return func() (*logger.Message, error) {
			if !scanner.Scan() {
				return nil, scanner.Err()
			}
			// some comment
			return &logger.Message{Line: scanner.Bytes(), Timestamp: time.Now()}, nil
		}
	}

	tailReader := func(ctx context.Context, r SizeReaderAt, lines int) (io.Reader, int, error) {
		return tailfile.NewTailReader(ctx, r, lines)
	}

	for desc, config := range map[string]logger.ReadConfig{} {
		t.Run(desc, func(t *testing.T) {
			started := make(chan struct{})
			go func() {
				close(started)
				tailFiles(files, watcher, createDecoder, tailReader, config)
			}()
			<-started
		})
	}

	config := logger.ReadConfig{Tail: 2}
	started := make(chan struct{})
	go func() {
		close(started)
		tailFiles(files, watcher, createDecoder, tailReader, config)
	}()
	<-started

	select {
	case <-time.After(60 * time.Second):
		t.Fatal("timeout waiting for tail line")
	case err := <-watcher.Err:
		assert.Assert(t, err)
	case msg := <-watcher.Msg:
		assert.Assert(t, msg != nil)
		assert.Assert(t, string(msg.Line) == "Roads?", string(msg.Line))
	}

	select {
	case <-time.After(60 * time.Second):
		t.Fatal("timeout waiting for tail line")
	case err := <-watcher.Err:
		assert.Assert(t, err)
	case msg := <-watcher.Msg:
		assert.Assert(t, msg != nil)
		assert.Assert(t, string(msg.Line) == "Where we're going we don't need roads.", string(msg.Line))
	}
}

func TestFollowLogsConsumerGone(t *testing.T) {
	lw := logger.NewLogWatcher()

	f, err := ioutil.TempFile("", t.Name())
	assert.NilError(t, err)
	defer func() {
		f.Close()
		os.Remove(f.Name())
	}()

	makeDecoder := func(rdr io.Reader) func() (*logger.Message, error) {
		return func() (*logger.Message, error) {
			return &logger.Message{}, nil
		}
	}

	followLogsDone := make(chan struct{})
	var since, until time.Time
	go func() {
		followLogs(f, lw, make(chan interface{}), makeDecoder, since, until)
		close(followLogsDone)
	}()

	select {
	case <-lw.Msg:
	case err := <-lw.Err:
		assert.NilError(t, err)
	case <-followLogsDone:
		t.Fatal("follow logs finished unexpectedly")
	case <-time.After(10 * time.Second):
		t.Fatal("timeout waiting for log message")
	}

	lw.ConsumerGone()
	select {
	case <-followLogsDone:
	case <-time.After(20 * time.Second):
		t.Fatal("timeout waiting for followLogs() to finish")
	}
}
<commit_msg>TestFollowLogsProducerGone: add<commit_after>package loggerutils

import (
	"bufio"
	"context"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/docker/docker/daemon/logger"
	"github.com/docker/docker/pkg/tailfile"
	"gotest.tools/assert"
)

func TestTailFiles(t *testing.T) {
	s1 := strings.NewReader("Hello.\nMy name is Inigo Montoya.\n")
	s2 := strings.NewReader("I'm serious.\nDon't call me Shirley!\n")
	s3 := strings.NewReader("Roads?\nWhere we're going we don't need roads.\n")

	files := []SizeReaderAt{s1, s2, s3}
	watcher := logger.NewLogWatcher()
	createDecoder := func(r io.Reader) func() (*logger.Message, error) {
		scanner := bufio.NewScanner(r)
		return func() (*logger.Message, error) {
			if !scanner.Scan() {
				return nil, scanner.Err()
			}
			// some comment
			return &logger.Message{Line: scanner.Bytes(), Timestamp: time.Now()}, nil
		}
	}

	tailReader := func(ctx context.Context, r SizeReaderAt, lines int) (io.Reader, int, error) {
		return tailfile.NewTailReader(ctx, r, lines)
	}

	for desc, config := range map[string]logger.ReadConfig{} {
		t.Run(desc, func(t *testing.T) {
			started := make(chan struct{})
			go func() {
				close(started)
				tailFiles(files, watcher, createDecoder, tailReader, config)
			}()
			<-started
		})
	}

	config := logger.ReadConfig{Tail: 2}
	started := make(chan struct{})
	go func() {
		close(started)
		tailFiles(files, watcher, createDecoder, tailReader, config)
	}()
	<-started

	select {
	case <-time.After(60 * time.Second):
		t.Fatal("timeout waiting for tail line")
	case err := <-watcher.Err:
		assert.Assert(t, err)
	case msg := <-watcher.Msg:
		assert.Assert(t, msg != nil)
		assert.Assert(t, string(msg.Line) == "Roads?", string(msg.Line))
	}

	select {
	case <-time.After(60 * time.Second):
		t.Fatal("timeout waiting for tail line")
	case err := <-watcher.Err:
		assert.Assert(t, err)
	case msg := <-watcher.Msg:
		assert.Assert(t, msg != nil)
		assert.Assert(t, string(msg.Line) == "Where we're going we don't need roads.", string(msg.Line))
	}
}

func TestFollowLogsConsumerGone(t *testing.T) {
	lw := logger.NewLogWatcher()

	f, err := ioutil.TempFile("", t.Name())
	assert.NilError(t, err)
	defer func() {
		f.Close()
		os.Remove(f.Name())
	}()

	makeDecoder := func(rdr io.Reader) func() (*logger.Message, error) {
		return func() (*logger.Message, error) {
			return &logger.Message{}, nil
		}
	}

	followLogsDone := make(chan struct{})
	var since, until time.Time
	go func() {
		followLogs(f, lw, make(chan interface{}), makeDecoder, since, until)
		close(followLogsDone)
	}()

	select {
	case <-lw.Msg:
	case err := <-lw.Err:
		assert.NilError(t, err)
	case <-followLogsDone:
		t.Fatal("follow logs finished unexpectedly")
	case <-time.After(10 * time.Second):
		t.Fatal("timeout waiting for log message")
	}

	lw.ConsumerGone()
	select {
	case <-followLogsDone:
	case <-time.After(20 * time.Second):
		t.Fatal("timeout waiting for followLogs() to finish")
	}
}

func TestFollowLogsProducerGone(t *testing.T) {
	lw := logger.NewLogWatcher()

	f, err := ioutil.TempFile("", t.Name())
	assert.NilError(t, err)
	defer os.Remove(f.Name())

	var sent, received, closed int
	makeDecoder := func(rdr io.Reader) func() (*logger.Message, error) {
		return func() (*logger.Message, error) {
			if closed == 1 {
				closed++
				t.Logf("logDecode() closed after sending %d messages\n", sent)
				return nil, io.EOF
			} else if closed > 1 {
				t.Fatal("logDecode() called after closing!")
				return nil, io.EOF
			}
			sent++
			return &logger.Message{}, nil
		}
	}
	var since, until time.Time

	followLogsDone := make(chan struct{})
	go func() {
		followLogs(f, lw, make(chan interface{}), makeDecoder, since, until)
		close(followLogsDone)
	}()

	// read 1 message
	select {
	case <-lw.Msg:
		received++
	case err := <-lw.Err:
		assert.NilError(t, err)
	case <-followLogsDone:
		t.Fatal("followLogs() finished unexpectedly")
	case <-time.After(10 * time.Second):
		t.Fatal("timeout waiting for log message")
	}

	// "stop" the "container"
	closed = 1
	lw.ProducerGone()

	// should receive all the messages sent
	readDone := make(chan struct{})
	go func() {
		defer close(readDone)
		for {
			select {
			case <-lw.Msg:
				received++
				if received == sent {
					return
				}
			case err := <-lw.Err:
				assert.NilError(t, err)
			}
		}
	}()
	select {
	case <-readDone:
	case <-time.After(30 * time.Second):
		t.Fatalf("timeout waiting for log messages to be read (sent: %d, received: %d", sent, received)
	}

	t.Logf("messages sent: %d, received: %d", sent, received)

	// followLogs() should be done by now
	select {
	case <-followLogsDone:
	case <-time.After(30 * time.Second):
		t.Fatal("timeout waiting for followLogs() to finish")
	}

	select {
	case <-lw.WatchConsumerGone():
		t.Fatal("consumer should not have exited")
	default:
	}
}
<|endoftext|>