<commit_before>package main

import (
	"flag"
	"fmt"
	ggio "github.com/gogo/protobuf/io"
	p2p_peer "github.com/ipfs/go-libp2p-peer"
	p2p_pstore "github.com/ipfs/go-libp2p-peerstore"
	p2p_host "github.com/libp2p/go-libp2p/p2p/host"
	p2p_net "github.com/libp2p/go-libp2p/p2p/net"
	mc "github.com/mediachain/concat/mc"
	pb "github.com/mediachain/concat/proto"
	"log"
	"os"
	"sync"
)

type Directory struct {
	mc.Identity
	host  p2p_host.Host
	peers map[p2p_peer.ID]p2p_pstore.PeerInfo
	mx    sync.Mutex
}

func (dir *Directory) registerHandler(s p2p_net.Stream) {
	defer s.Close()

	pid := s.Conn().RemotePeer()
	log.Printf("directory/register: new stream from %s\n", pid.Pretty())

	r := ggio.NewDelimitedReader(s, mc.MaxMessageSize)
	req := new(pb.RegisterPeer)

	for {
		err := r.ReadMsg(req)
		if err != nil {
			break
		}

		if req.Info == nil {
			log.Printf("directory/register: empty peer info from %s\n", pid.Pretty())
			break
		}

		pinfo, err := mc.PBToPeerInfo(req.Info)
		if err != nil {
			log.Printf("directory/register: bad peer info from %s\n", pid.Pretty())
			break
		}

		if pinfo.ID != pid {
			log.Printf("directory/register: bogus peer info from %s\n", pid.Pretty())
			break
		}

		dir.registerPeer(pinfo)

		req.Reset()
	}

	dir.unregisterPeer(pid)
}

func (dir *Directory) lookupHandler(s p2p_net.Stream) {
	defer s.Close()

	pid := s.Conn().RemotePeer()
	log.Printf("directory/lookup: new stream from %s\n", pid.Pretty())

	r := ggio.NewDelimitedReader(s, mc.MaxMessageSize)
	w := ggio.NewDelimitedWriter(s)
	req := new(pb.LookupPeerRequest)
	resp := new(pb.LookupPeerResponse)

	for {
		err := r.ReadMsg(req)
		if err != nil {
			break
		}

		pid, err := p2p_peer.IDFromString(req.Id)
		if err != nil {
			log.Printf("directory/lookup: bad request from %s\n", pid.Pretty())
			break
		}

		pinfo, ok := dir.lookupPeer(pid)
		if ok {
			var pbpi pb.PeerInfo
			mc.PBFromPeerInfo(&pbpi, pinfo)
			resp.Peer = &pbpi
		}

		err = w.WriteMsg(resp)
		if err != nil {
			break
		}

		req.Reset()
		resp.Reset()
	}
}

func (dir *Directory) listHandler(s p2p_net.Stream) {

}

func (dir *Directory) registerPeer(info p2p_pstore.PeerInfo) {
	log.Printf("directory: register %s\n", info.ID.Pretty())
	dir.mx.Lock()
	dir.peers[info.ID] = info
	dir.mx.Unlock()
}

func (dir *Directory) unregisterPeer(pid p2p_peer.ID) {
	log.Printf("directory: unregister %s\n", pid.Pretty())
	dir.mx.Lock()
	delete(dir.peers, pid)
	dir.mx.Unlock()
}

func (dir *Directory) lookupPeer(pid p2p_peer.ID) (p2p_pstore.PeerInfo, bool) {
	dir.mx.Lock()
	pinfo, ok := dir.peers[pid]
	dir.mx.Unlock()
	return pinfo, ok
}

func main() {
	port := flag.Int("l", 9000, "Listen port")
	home := flag.String("d", "/tmp/mcdir", "Directory home")
	flag.Parse()

	err := os.MkdirAll(*home, 0755)
	if err != nil {
		log.Fatal(err)
	}

	id, err := mc.NodeIdentity(*home)
	if err != nil {
		log.Fatal(err)
	}

	addr, err := mc.ParseAddress(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", *port))
	if err != nil {
		log.Fatal(err)
	}

	host, err := mc.NewHost(id, addr)
	if err != nil {
		log.Fatal(err)
	}

	dir := &Directory{Identity: id, host: host, peers: make(map[p2p_peer.ID]p2p_pstore.PeerInfo)}
	host.SetStreamHandler("/mediachain/dir/register", dir.registerHandler)
	host.SetStreamHandler("/mediachain/dir/lookup", dir.lookupHandler)
	host.SetStreamHandler("/mediachain/dir/list", dir.listHandler)

	log.Printf("I am %s/%s", addr, id.Pretty())
	select {}
}
<commit_msg>mcid: fix subtle shadowing bug (error handler would have a nil pid)<commit_after>package main

import (
	"flag"
	"fmt"
	ggio "github.com/gogo/protobuf/io"
	p2p_peer "github.com/ipfs/go-libp2p-peer"
	p2p_pstore "github.com/ipfs/go-libp2p-peerstore"
	p2p_host "github.com/libp2p/go-libp2p/p2p/host"
	p2p_net "github.com/libp2p/go-libp2p/p2p/net"
	mc "github.com/mediachain/concat/mc"
	pb "github.com/mediachain/concat/proto"
	"log"
	"os"
	"sync"
)

type Directory struct {
	mc.Identity
	host  p2p_host.Host
	peers map[p2p_peer.ID]p2p_pstore.PeerInfo
	mx    sync.Mutex
}

func (dir *Directory) registerHandler(s p2p_net.Stream) {
	defer s.Close()

	pid := s.Conn().RemotePeer()
	log.Printf("directory/register: new stream from %s\n", pid.Pretty())

	r := ggio.NewDelimitedReader(s, mc.MaxMessageSize)
	req := new(pb.RegisterPeer)

	for {
		err := r.ReadMsg(req)
		if err != nil {
			break
		}

		if req.Info == nil {
			log.Printf("directory/register: empty peer info from %s\n", pid.Pretty())
			break
		}

		pinfo, err := mc.PBToPeerInfo(req.Info)
		if err != nil {
			log.Printf("directory/register: bad peer info from %s\n", pid.Pretty())
			break
		}

		if pinfo.ID != pid {
			log.Printf("directory/register: bogus peer info from %s\n", pid.Pretty())
			break
		}

		dir.registerPeer(pinfo)

		req.Reset()
	}

	dir.unregisterPeer(pid)
}

func (dir *Directory) lookupHandler(s p2p_net.Stream) {
	defer s.Close()

	pid := s.Conn().RemotePeer()
	log.Printf("directory/lookup: new stream from %s\n", pid.Pretty())

	r := ggio.NewDelimitedReader(s, mc.MaxMessageSize)
	w := ggio.NewDelimitedWriter(s)
	req := new(pb.LookupPeerRequest)
	resp := new(pb.LookupPeerResponse)

	for {
		err := r.ReadMsg(req)
		if err != nil {
			break
		}

		xid, err := p2p_peer.IDB58Decode(req.Id)
		if err != nil {
			log.Printf("directory/lookup: bad request from %s\n", pid.Pretty())
			break
		}

		pinfo, ok := dir.lookupPeer(xid)
		if ok {
			var pbpi pb.PeerInfo
			mc.PBFromPeerInfo(&pbpi, pinfo)
			resp.Peer = &pbpi
		}

		err = w.WriteMsg(resp)
		if err != nil {
			break
		}

		req.Reset()
		resp.Reset()
	}
}

func (dir *Directory) listHandler(s p2p_net.Stream) {

}

func (dir *Directory) registerPeer(info p2p_pstore.PeerInfo) {
	log.Printf("directory: register %s\n", info.ID.Pretty())
	dir.mx.Lock()
	dir.peers[info.ID] = info
	dir.mx.Unlock()
}

func (dir *Directory) unregisterPeer(pid p2p_peer.ID) {
	log.Printf("directory: unregister %s\n", pid.Pretty())
	dir.mx.Lock()
	delete(dir.peers, pid)
	dir.mx.Unlock()
}

func (dir *Directory) lookupPeer(pid p2p_peer.ID) (p2p_pstore.PeerInfo, bool) {
	dir.mx.Lock()
	pinfo, ok := dir.peers[pid]
	dir.mx.Unlock()
	return pinfo, ok
}

func main() {
	port := flag.Int("l", 9000, "Listen port")
	home := flag.String("d", "/tmp/mcdir", "Directory home")
	flag.Parse()

	err := os.MkdirAll(*home, 0755)
	if err != nil {
		log.Fatal(err)
	}

	id, err := mc.NodeIdentity(*home)
	if err != nil {
		log.Fatal(err)
	}

	addr, err := mc.ParseAddress(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", *port))
	if err != nil {
		log.Fatal(err)
	}

	host, err := mc.NewHost(id, addr)
	if err != nil {
		log.Fatal(err)
	}

	dir := &Directory{Identity: id, host: host, peers: make(map[p2p_peer.ID]p2p_pstore.PeerInfo)}
	host.SetStreamHandler("/mediachain/dir/register", dir.registerHandler)
	host.SetStreamHandler("/mediachain/dir/lookup", dir.lookupHandler)
	host.SetStreamHandler("/mediachain/dir/list", dir.listHandler)

	log.Printf("I am %s/%s", addr, id.Pretty())
	select {}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"code.google.com/p/go.crypto/ssh"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"time"
)

// An SSHConnection manages an SSH connection to a server.
type SSHConnection struct {
	client *ssh.ClientConn
	logger *log.Logger
}

type singlePassword struct {
	password string
}

func (pw singlePassword) Password(user string) (string, error) {
	return pw.password, nil
}

type singleKeyring struct {
	signer ssh.Signer
}

func newSingleKeyring(path, passphrase string) (*singleKeyring, error) {
	privateKey, err := parseSSHKey(path, passphrase)
	if err != nil {
		return nil, err
	}

	signer, err := ssh.NewSignerFromKey(privateKey)
	if err != nil {
		return nil, err
	}

	return &singleKeyring{signer: signer}, nil
}

func (sk *singleKeyring) Key(i int) (ssh.PublicKey, error) {
	if i != 0 {
		return nil, nil
	}

	return sk.signer.PublicKey(), nil
}

func (sk *singleKeyring) Sign(i int, rand io.Reader, data []byte) ([]byte, error) {
	if i != 0 {
		return nil, fmt.Errorf("unknown key %d", i)
	}

	return sk.signer.Sign(rand, data)
}

func parseSSHKey(path, passphrase string) (*rsa.PrivateKey, error) {
	file, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	block, _ := pem.Decode(file)

	der, err := x509.DecryptPEMBlock(block, []byte(passphrase))
	if err != nil {
		return nil, err
	}

	return x509.ParsePKCS1PrivateKey(der)
}

func clientAuthFromSSHInfo(info VMSSHInfo) (auths []ssh.ClientAuth, err error) {
	if info.SSHKeyPath != "" {
		keyring, err := newSingleKeyring(info.SSHKeyPath, info.SSHKeyPassphrase)
		if err != nil {
			return nil, err
		}

		auths = append(auths, ssh.ClientAuthKeyring(keyring))
	}
	if info.Password != "" {
		auths = append(auths, ssh.ClientAuthPassword(singlePassword{info.Password}))
	}

	return
}

// NewSSHConnection creates an SSH connection using the connection information
// for the given server.
func NewSSHConnection(server VM, logPrefix string) (*SSHConnection, error) {
	sshInfo := server.SSHInfo()

	dial := func(info VMSSHInfo) (*ssh.ClientConn, error) {
		conn, err := net.DialTimeout("tcp", sshInfo.Addr, 5*time.Second)
		if err != nil {
			return nil, err
		}

		auths, err := clientAuthFromSSHInfo(sshInfo)
		if err != nil {
			return nil, err
		}
		sshConfig := &ssh.ClientConfig{
			User: sshInfo.Username,
			Auth: auths,
		}

		return ssh.Client(conn, sshConfig)
	}

	var client *ssh.ClientConn
	var err error
	for i := 0; i < 3; i++ {
		client, err = dial(sshInfo)
		if err == nil {
			break
		}
	}

	logger := log.New(os.Stdout, fmt.Sprintf("%s-ssh: ", logPrefix), log.Ldate|log.Ltime)
	return &SSHConnection{client: client, logger: logger}, err
}

// Start starts the given command and returns as soon as the command has
// started. It does not wait for the command to finish. The returned channel
// will send the exit code and then close when the command is finished. If the
// exit code sent is -1 then there was an error running the build.
func (c *SSHConnection) Start(cmd string, output io.Writer) (<-chan int, error) {
	session, err := c.createSession()
	if err != nil {
		return nil, err
	}

	session.Stdout = output
	session.Stderr = output

	err = session.Start(cmd)

	exitCodeChan := make(chan int, 1)
	go func() {
		defer session.Close()
		err := session.Wait()
		if err == nil {
			exitCodeChan <- 0
		} else {
			switch err := err.(type) {
			case *ssh.ExitError:
				if err.ExitStatus() != 0 {
					exitCodeChan <- err.ExitStatus()
				} else {
					c.logger.Printf("SSHConnection.Start: An error occurred while running the command: %v\n", err)
					exitCodeChan <- -1
				}
			default:
				c.logger.Printf("SSHConnection.Start: An I/O error occurred: %v\n", err)
				exitCodeChan <- -1
			}
		}
		close(exitCodeChan)
	}()

	return exitCodeChan, err
}

// Run runs a command and blocks until the command has finished. An error is
// returned if the command exited with a non-zero command.
func (c *SSHConnection) Run(cmd string) error {
	session, err := c.createSession()
	if err != nil {
		return err
	}
	defer session.Close()

	return session.Run(cmd)
}

func (c *SSHConnection) createSession() (*ssh.Session, error) {
	session, err := c.client.NewSession()
	if err != nil {
		return nil, err
	}

	return session, session.RequestPty("xterm", 80, 40, ssh.TerminalModes{})
}

// UploadFile uploads the given content to the file on the remote server given
// by the path.
func (c *SSHConnection) UploadFile(path string, content []byte) error {
	session, err := c.client.NewSession()
	if err != nil {
		return err
	}
	defer session.Close()

	stdin, err := session.StdinPipe()
	if err != nil {
		return err
	}

	go func() {
		io.Copy(stdin, bytes.NewReader(content))
		stdin.Close()
	}()

	return session.Run(fmt.Sprintf("cat > %s", path))
}

// Close closes the SSH connection.
func (c *SSHConnection) Close() {
	c.client.Close()
}
<commit_msg>ssh: Add a sleep when retrying the dialing<commit_after>package main

import (
	"bytes"
	"code.google.com/p/go.crypto/ssh"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"time"
)

// An SSHConnection manages an SSH connection to a server.
type SSHConnection struct {
	client *ssh.ClientConn
	logger *log.Logger
}

type singlePassword struct {
	password string
}

func (pw singlePassword) Password(user string) (string, error) {
	return pw.password, nil
}

type singleKeyring struct {
	signer ssh.Signer
}

func newSingleKeyring(path, passphrase string) (*singleKeyring, error) {
	privateKey, err := parseSSHKey(path, passphrase)
	if err != nil {
		return nil, err
	}

	signer, err := ssh.NewSignerFromKey(privateKey)
	if err != nil {
		return nil, err
	}

	return &singleKeyring{signer: signer}, nil
}

func (sk *singleKeyring) Key(i int) (ssh.PublicKey, error) {
	if i != 0 {
		return nil, nil
	}

	return sk.signer.PublicKey(), nil
}

func (sk *singleKeyring) Sign(i int, rand io.Reader, data []byte) ([]byte, error) {
	if i != 0 {
		return nil, fmt.Errorf("unknown key %d", i)
	}

	return sk.signer.Sign(rand, data)
}

func parseSSHKey(path, passphrase string) (*rsa.PrivateKey, error) {
	file, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	block, _ := pem.Decode(file)

	der, err := x509.DecryptPEMBlock(block, []byte(passphrase))
	if err != nil {
		return nil, err
	}

	return x509.ParsePKCS1PrivateKey(der)
}

func clientAuthFromSSHInfo(info VMSSHInfo) (auths []ssh.ClientAuth, err error) {
	if info.SSHKeyPath != "" {
		keyring, err := newSingleKeyring(info.SSHKeyPath, info.SSHKeyPassphrase)
		if err != nil {
			return nil, err
		}

		auths = append(auths, ssh.ClientAuthKeyring(keyring))
	}
	if info.Password != "" {
		auths = append(auths, ssh.ClientAuthPassword(singlePassword{info.Password}))
	}

	return
}

// NewSSHConnection creates an SSH connection using the connection information
// for the given server.
func NewSSHConnection(server VM, logPrefix string) (*SSHConnection, error) {
	sshInfo := server.SSHInfo()

	dial := func(info VMSSHInfo) (*ssh.ClientConn, error) {
		conn, err := net.DialTimeout("tcp", sshInfo.Addr, 5*time.Second)
		if err != nil {
			return nil, err
		}

		auths, err := clientAuthFromSSHInfo(sshInfo)
		if err != nil {
			return nil, err
		}
		sshConfig := &ssh.ClientConfig{
			User: sshInfo.Username,
			Auth: auths,
		}

		return ssh.Client(conn, sshConfig)
	}

	var client *ssh.ClientConn
	var err error
	for i := 0; i < 3; i++ {
		client, err = dial(sshInfo)
		if err == nil {
			break
		}
		time.Sleep(2 * time.Second)
	}

	logger := log.New(os.Stdout, fmt.Sprintf("%s-ssh: ", logPrefix), log.Ldate|log.Ltime)
	return &SSHConnection{client: client, logger: logger}, err
}

// Start starts the given command and returns as soon as the command has
// started. It does not wait for the command to finish. The returned channel
// will send the exit code and then close when the command is finished. If the
// exit code sent is -1 then there was an error running the build.
func (c *SSHConnection) Start(cmd string, output io.Writer) (<-chan int, error) {
	session, err := c.createSession()
	if err != nil {
		return nil, err
	}

	session.Stdout = output
	session.Stderr = output

	err = session.Start(cmd)

	exitCodeChan := make(chan int, 1)
	go func() {
		defer session.Close()
		err := session.Wait()
		if err == nil {
			exitCodeChan <- 0
		} else {
			switch err := err.(type) {
			case *ssh.ExitError:
				if err.ExitStatus() != 0 {
					exitCodeChan <- err.ExitStatus()
				} else {
					c.logger.Printf("SSHConnection.Start: An error occurred while running the command: %v\n", err)
					exitCodeChan <- -1
				}
			default:
				c.logger.Printf("SSHConnection.Start: An I/O error occurred: %v\n", err)
				exitCodeChan <- -1
			}
		}
		close(exitCodeChan)
	}()

	return exitCodeChan, err
}

// Run runs a command and blocks until the command has finished. An error is
// returned if the command exited with a non-zero command.
func (c *SSHConnection) Run(cmd string) error {
	session, err := c.createSession()
	if err != nil {
		return err
	}
	defer session.Close()

	return session.Run(cmd)
}

func (c *SSHConnection) createSession() (*ssh.Session, error) {
	session, err := c.client.NewSession()
	if err != nil {
		return nil, err
	}

	return session, session.RequestPty("xterm", 80, 40, ssh.TerminalModes{})
}

// UploadFile uploads the given content to the file on the remote server given
// by the path.
func (c *SSHConnection) UploadFile(path string, content []byte) error {
	session, err := c.client.NewSession()
	if err != nil {
		return err
	}
	defer session.Close()

	stdin, err := session.StdinPipe()
	if err != nil {
		return err
	}

	go func() {
		io.Copy(stdin, bytes.NewReader(content))
		stdin.Close()
	}()

	return session.Run(fmt.Sprintf("cat > %s", path))
}

// Close closes the SSH connection.
func (c *SSHConnection) Close() {
	c.client.Close()
}
<|endoftext|>


<commit_before>package geom

import (
	"fmt"
	"math"

	"github.com/phil-mansfield/num/rand"
)

// Tetra is a tetrahedron with points inside a box with periodic boundary
// conditions.
//
// NOTE: To speed up computations, Tetra contains a number of non-trivial
// private fields. If there is a need to store a large number of tetrahedra,
// it is advised to construct a slice of [4]Points instead and switch to
// Tetra instances only for calculations.
type Tetra struct {
	Corners [4]Vec
	volume  float64
	bary    Vec
	width   float64
	vb      volumeBuffer
	sb      sampleBuffer

	volumeValid, baryValid bool
}

type TetraIdxs struct {
	Corners [4]int64
}

type volumeBuffer struct {
	buf1, buf2, buf3 Vec
}

type sampleBuffer struct {
	d, c [4]Vec
}

const (
	eps = 1e-6

	TetraDirCount = 6
)

var (
	dirs = [TetraDirCount][2][3]int64{
		{{1, 0, 0}, {1, 1, 0}},
		{{1, 0, 0}, {1, 0, 1}},
		{{0, 1, 0}, {1, 1, 0}},
		{{0, 0, 1}, {1, 0, 1}},
		{{0, 1, 0}, {0, 1, 1}},
		{{0, 0, 1}, {0, 1, 1}},
	}
)

// NewTetra creates a new tetrahedron with corners at the specified positions
// within a periodic box of the given width.
func NewTetra(c1, c2, c3, c4 *Vec, width float64) (t *Tetra, ok bool) {
	t = &Tetra{}
	return t, t.Init(c1, c2, c3, c4, width)
}

// Init initializes a tetrahedron to correspond to the given corners. It returns
// true if all the given pointers are valid and the tetrahedron was properly
// initialized and false otherwise. This behavior is chosen so that this
// function interacts nicely with ParticleManagers.
func (t *Tetra) Init(c1, c2, c3, c4 *Vec, width float64) (ok bool) {
	t.volumeValid = false
	t.baryValid = false

	if c1 == nil || c2 == nil || c3 == nil || c4 == nil {
		return false
	}

	t.Corners[0] = *c1
	t.Corners[1] = *c2
	t.Corners[2] = *c3
	t.Corners[3] = *c4

	t.width = width

	// Remaining fields are buffers and need not be initialized.

	return true
}

// NewTetraIdxs creates a collection of indices corresponding to a tetrhedron
// with an anchor point at the given index. The parameter dir selects a
// particular tetrahedron configuration and must line in the range
// [0, TetraDirCount).
func NewTetraIdxs(idx, gridWidth int64, dir int) *TetraIdxs {
	idxs := &TetraIdxs{}
	return idxs.Init(idx, gridWidth, dir)
}

// Init initializes a TetraIdxs collection using the same rules as NewTetraIdxs.
func (idxs *TetraIdxs) Init(idx, gridWidth int64, dir int) *TetraIdxs {
	return nil
}

// Volume computes the volume of a tetrahedron.
func (t *Tetra) Volume() float64 {
	if t.volumeValid {
		return t.volume
	}

	t.volume = math.Abs(t.signedVolume(
		&t.Corners[0], &t.Corners[1], &t.Corners[2], &t.Corners[3]),
	)

	t.volumeValid = true
	return t.volume
}

// Contains returns true if a tetrahedron contains the given point and false
// otherwise.
func (t *Tetra) Contains(v *Vec) bool {
	vol := t.Volume()

	// (my appologies for the gross code here)
	vi := t.signedVolume(v, &t.Corners[0], &t.Corners[1], &t.Corners[2])
	volSum := math.Abs(vi)
	sign := math.Signbit(vi)
	if volSum > vol * (1 + eps) {
		return false
	}

	vi = t.signedVolume(v, &t.Corners[1], &t.Corners[3], &t.Corners[2])
	if math.Signbit(vi) != sign {
		return false
	}
	volSum += math.Abs(vi)
	if volSum > vol * (1 + eps) {
		return false
	}

	vi = t.signedVolume(v, &t.Corners[0], &t.Corners[3], &t.Corners[1])
	if math.Signbit(vi) != sign {
		return false
	}
	volSum += math.Abs(vi)
	if volSum > vol * (1 + eps) {
		return false
	}

	vi = t.signedVolume(v, &t.Corners[0], &t.Corners[2], &t.Corners[3])
	if math.Signbit(vi) != sign {
		return false
	}
	volSum += math.Abs(vi)
	return epsEq(volSum, vol, eps)
}

func epsEq(x, y, eps float64) bool {
	return (x == 0 && y == 0) || math.Abs((x - y) / x) <= eps
}

// TODO: Think about whether or not this actually does what you want with the
// sign bit.
func (t *Tetra) signedVolume(c1, c2, c3, c4 *Vec) float64 {
	c2.SubAt(c1, t.width, &t.vb.buf1)
	c3.SubAt(c1, t.width, &t.vb.buf2)
	c4.SubAt(c1, t.width, &t.vb.buf3)

	t.vb.buf2.CrossSelf(&t.vb.buf3)

	return t.vb.buf1.Dot(&t.vb.buf2) / 6.0
}

// CellBounds returns the bounding box of a tetrahedron, aligned to the given
// grid. The indices returned represent a tetrahedron whose barycenter is
// within the fundamental domain of the grid. As such, the returned indices
// may not be within the domain [0, g.Width).
func (t *Tetra) CellBounds(g *Grid) *CellBounds {
	return t.CellBoundsAt(g, &CellBounds{})
}

// CellBoundsAt returns the same quantity as CellBounds, but the result is
// placed at the given location.
func (t *Tetra) CellBoundsAt(g *Grid, out *CellBounds) *CellBounds {
	bary := t.Barycenter()

	for i := 0; i < 4; i++ {
		t.Corners[i].SubAt(bary, t.width, &t.sb.c[i])
	}

	var minDs, maxDs [3]float32

	for i := 0; i < 4; i++ {
		for d := 0; d < 3; d++ {
			if d == 0 {
				minDs[d], maxDs[d] = t.sb.c[i][d], t.sb.c[i][d]
			} else {
				minDs[d], maxDs[d] = minMax(t.sb.c[i][d], minDs[d], maxDs[d])
			}
		}
	}

	mult := float64(g.Width) / t.width
	for d := 0; d < 3; d++ {
		fIdx := float64(bary[d] + minDs[d]) * mult
		out.Min[d] =  int(math.Floor(fIdx)) - g.Origin[d]
		fIdx = float64(bary[d] + maxDs[d]) * mult
		out.Max[d] = int(math.Ceil(fIdx)) - g.Origin[d]
	}

	return out
}

func minMax(x, oldMin, oldMax float32) (min, max float32) {
	if x > oldMax {
		return oldMin, x
	} else if x < oldMin {
		return x, oldMax
	} else {
		return oldMin, oldMax
	}
}

// Sample fills a buffer of vecotrs with points generated uniformly at random
// from within a tetrahedron. The length of randBuf must be three times the
// length of vecBuf.
func (t *Tetra) Sample(gen *rand.Generator, randBuf []float64, vecBuf []Vec) {
	if len(randBuf) != len(vecBuf) *3 {
		panic(fmt.Sprintf("buf len %d not long enough for %d points.",
			len(randBuf), len(vecBuf)))
	}

	gen.UniformAt(0.0, 1.0, randBuf)
	bary := t.Barycenter()

	// Some gross code to prevent allocations. cs are the displacement vectors
	// to the corners and the ds are the barycentric components of the random
	// points.
	for i := 0; i < 4; i++ {
		t.Corners[i].SubAt(bary, t.width, &t.sb.c[i])
		t.sb.d[i].ScaleSelf(0.0)
	}

	for i := range vecBuf {
		// Generate three of the four barycentric coordinates
		t1, t2, t3 := randBuf[i*3], randBuf[i*3+1], randBuf[i*3+2]

		if t1+t2+t3 < 1.0 {
			continue
		} else if t2+t3 > 1.0 {
			t1, t2, t3 = t1, 1.0-t3, 1.0-t1-t2
		} else {
			t1, t2, t3 = 1.0-t2-t3, t2, t1+t2+t3-1.0
		}

		// Solve for the last one.
		t4 := 1.0 - t1 - t2 - t3

		t.sb.c[0].ScaleAt(t1, &t.sb.d[0])
		t.sb.c[1].ScaleAt(t2, &t.sb.d[1])
		t.sb.c[2].ScaleAt(t3, &t.sb.d[2])
		t.sb.c[3].ScaleAt(t4, &t.sb.d[3])

		t.sb.c[0].AddAt(&t.sb.c[1], &vecBuf[i])
		vecBuf[i].AddSelf(&t.sb.c[2]).AddSelf(&t.sb.c[3])
	}
}

// Barycenter computes the barycenter of a tetrahedron.
func (t *Tetra) Barycenter() *Vec {
	if t.baryValid {
		return &t.bary
	}

	// This is a bit more involved than normal because of the periodic boundary
	// conditions. The idea is to interpret the points as angles on a circle.
	wTwoPi := 2.0 * math.Pi / t.width

	for d := 0; d < 3; d++ {
		xiSum, zetaSum := 0.0, 0.0

		for i := 0; i < 4; i++ {
			theta := float64(t.Corners[i][d]) * wTwoPi
			zeta, xi := math.Sincos(theta)

			xiSum += xi
			zetaSum += zeta
		}

		zetaBar, xiBar := zetaSum/4.0, xiSum/4.0
		t.bary[d] = float32((math.Atan2(-zetaBar, -xiBar) + math.Pi) / wTwoPi)
	}

	t.baryValid = true
	return &t.bary
}
<commit_msg>Changed implementation of Tetra.Barycenter() because previous implementation was too inaccurate and slow.<commit_after>package geom

import (
	"fmt"
	"math"

	"github.com/phil-mansfield/num/rand"
)

// Tetra is a tetrahedron with points inside a box with periodic boundary
// conditions.
//
// NOTE: To speed up computations, Tetra contains a number of non-trivial
// private fields. If there is a need to store a large number of tetrahedra,
// it is advised to construct a slice of [4]Points instead and switch to
// Tetra instances only for calculations.
type Tetra struct {
	Corners [4]Vec
	volume  float64
	bary    Vec
	width   float64
	vb      volumeBuffer
	sb      sampleBuffer

	volumeValid, baryValid bool
}

type TetraIdxs struct {
	Corners [4]int64
}

type volumeBuffer struct {
	buf1, buf2, buf3 Vec
}

type sampleBuffer struct {
	d, c [4]Vec
}

const (
	eps = 1e-6

	TetraDirCount = 6
)

var (
	dirs = [TetraDirCount][2][3]int64{
		{{1, 0, 0}, {1, 1, 0}},
		{{1, 0, 0}, {1, 0, 1}},
		{{0, 1, 0}, {1, 1, 0}},
		{{0, 0, 1}, {1, 0, 1}},
		{{0, 1, 0}, {0, 1, 1}},
		{{0, 0, 1}, {0, 1, 1}},
	}
)

// NewTetra creates a new tetrahedron with corners at the specified positions
// within a periodic box of the given width.
func NewTetra(c1, c2, c3, c4 *Vec, width float64) (t *Tetra, ok bool) {
	t = &Tetra{}
	return t, t.Init(c1, c2, c3, c4, width)
}

// Init initializes a tetrahedron to correspond to the given corners. It returns
// true if all the given pointers are valid and the tetrahedron was properly
// initialized and false otherwise. This behavior is chosen so that this
// function interacts nicely with ParticleManagers.
func (t *Tetra) Init(c1, c2, c3, c4 *Vec, width float64) (ok bool) {
	t.volumeValid = false
	t.baryValid = false

	if c1 == nil || c2 == nil || c3 == nil || c4 == nil {
		return false
	}

	c1.ModAt(width, &t.Corners[0])
	c2.ModAt(width, &t.Corners[1])
	c3.ModAt(width, &t.Corners[2])
	c4.ModAt(width, &t.Corners[3])

	t.width = width

	// Remaining fields are buffers and need not be initialized.

	return true
}

// NewTetraIdxs creates a collection of indices corresponding to a tetrhedron
// with an anchor point at the given index. The parameter dir selects a
// particular tetrahedron configuration and must line in the range
// [0, TetraDirCount).
func NewTetraIdxs(idx, gridWidth int64, dir int) *TetraIdxs {
	idxs := &TetraIdxs{}
	return idxs.Init(idx, gridWidth, dir)
}

// Init initializes a TetraIdxs collection using the same rules as NewTetraIdxs.
func (idxs *TetraIdxs) Init(idx, gridWidth int64, dir int) *TetraIdxs {
	return nil
}

// Volume computes the volume of a tetrahedron.
func (t *Tetra) Volume() float64 {
	if t.volumeValid {
		return t.volume
	}

	t.volume = math.Abs(t.signedVolume(
		&t.Corners[0], &t.Corners[1], &t.Corners[2], &t.Corners[3]),
	)

	t.volumeValid = true
	return t.volume
}

// Contains returns true if a tetrahedron contains the given point and false
// otherwise.
func (t *Tetra) Contains(v *Vec) bool {
	vol := t.Volume()

	// (my appologies for the gross code here)
	vi := t.signedVolume(v, &t.Corners[0], &t.Corners[1], &t.Corners[2])
	volSum := math.Abs(vi)
	sign := math.Signbit(vi)
	if volSum > vol * (1 + eps) {
		return false
	}

	vi = t.signedVolume(v, &t.Corners[1], &t.Corners[3], &t.Corners[2])
	if math.Signbit(vi) != sign {
		return false
	}
	volSum += math.Abs(vi)
	if volSum > vol * (1 + eps) {
		return false
	}

	vi = t.signedVolume(v, &t.Corners[0], &t.Corners[3], &t.Corners[1])
	if math.Signbit(vi) != sign {
		return false
	}
	volSum += math.Abs(vi)
	if volSum > vol * (1 + eps) {
		return false
	}

	vi = t.signedVolume(v, &t.Corners[0], &t.Corners[2], &t.Corners[3])
	if math.Signbit(vi) != sign {
		return false
	}
	return true
}

func epsEq(x, y, eps float64) bool {
	return (x == 0 && y == 0) || math.Abs((x - y) / x) <= eps
}

// TODO: Think about whether or not this actually does what you want with the
// sign bit.
func (t *Tetra) signedVolume(c1, c2, c3, c4 *Vec) float64 {
	c2.SubAt(c1, t.width, &t.vb.buf1)
	c3.SubAt(c1, t.width, &t.vb.buf2)
	c4.SubAt(c1, t.width, &t.vb.buf3)

	t.vb.buf2.CrossSelf(&t.vb.buf3)

	return t.vb.buf1.Dot(&t.vb.buf2) / 6.0
}

// CellBounds returns the bounding box of a tetrahedron, aligned to the given
// grid. The indices returned represent a tetrahedron whose barycenter is
// within the fundamental domain of the grid. As such, the returned indices
// may not be within the domain [0, g.Width).
func (t *Tetra) CellBounds(g *Grid) *CellBounds {
	return t.CellBoundsAt(g, &CellBounds{})
}

// CellBoundsAt returns the same quantity as CellBounds, but the result is
// placed at the given location.
func (t *Tetra) CellBoundsAt(g *Grid, out *CellBounds) *CellBounds {
	bary := t.Barycenter()

	for i := 0; i < 4; i++ {
		t.Corners[i].SubAt(bary, t.width, &t.sb.c[i])
	}

	var minDs, maxDs [3]float32

	for i := 0; i < 4; i++ {
		for d := 0; d < 3; d++ {
			if d == 0 {
				minDs[d], maxDs[d] = t.sb.c[i][d], t.sb.c[i][d]
			} else {
				minDs[d], maxDs[d] = minMax(t.sb.c[i][d], minDs[d], maxDs[d])
			}
		}
	}

	mult := float64(g.Width) / t.width
	for d := 0; d < 3; d++ {
		fIdx := float64(bary[d] + minDs[d]) * mult
		out.Min[d] =  int(math.Floor(fIdx)) - g.Origin[d]
		fIdx = float64(bary[d] + maxDs[d]) * mult
		out.Max[d] = int(math.Ceil(fIdx)) - g.Origin[d]
	}

	return out
}

func minMax(x, oldMin, oldMax float32) (min, max float32) {
	if x > oldMax {
		return oldMin, x
	} else if x < oldMin {
		return x, oldMax
	} else {
		return oldMin, oldMax
	}
}

// Sample fills a buffer of vecotrs with points generated uniformly at random
// from within a tetrahedron. The length of randBuf must be three times the
// length of vecBuf.
func (t *Tetra) Sample(gen *rand.Generator, randBuf []float64, vecBuf []Vec) {
	if len(randBuf) != len(vecBuf) *3 {
		panic(fmt.Sprintf("buf len %d not long enough for %d points.",
			len(randBuf), len(vecBuf)))
	}

	gen.UniformAt(0.0, 1.0, randBuf)
	bary := t.Barycenter()

	// Some gross code to prevent allocations. cs are the displacement vectors
	// to the corners and the ds are the barycentric components of the random
	// points.
	for i := 0; i < 4; i++ {
		t.Corners[i].SubAt(bary, t.width, &t.sb.c[i])
		t.sb.d[i].ScaleSelf(0.0)
	}

	for i := range vecBuf {
		// Generate three of the four barycentric coordinates
		t1, t2, t3 := randBuf[i*3], randBuf[i*3+1], randBuf[i*3+2]

		if t1+t2+t3 < 1.0 {
			continue
		} else if t2+t3 > 1.0 {
			t1, t2, t3 = t1, 1.0-t3, 1.0-t1-t2
		} else {
			t1, t2, t3 = 1.0-t2-t3, t2, t1+t2+t3-1.0
		}

		// Solve for the last one.
		t4 := 1.0 - t1 - t2 - t3

		t.sb.c[0].ScaleAt(t1, &t.sb.d[0])
		t.sb.c[1].ScaleAt(t2, &t.sb.d[1])
		t.sb.c[2].ScaleAt(t3, &t.sb.d[2])
		t.sb.c[3].ScaleAt(t4, &t.sb.d[3])

		t.sb.c[0].AddAt(&t.sb.c[1], &vecBuf[i])
		vecBuf[i].AddSelf(&t.sb.c[2]).AddSelf(&t.sb.c[3])
	}
}

// Barycenter computes the barycenter of a tetrahedron.
func (t *Tetra) Barycenter() *Vec {
	if t.baryValid {
		return &t.bary
	}

	buf1, buf2 := &t.vb.buf1, &t.vb.buf2
	center(&t.Corners[0], &t.Corners[1], buf1, t.width)
	center(&t.Corners[2], &t.Corners[3], buf2, t.width)
	center(buf1, buf2, &t.bary, t.width)
	t.bary.ModSelf(t.width)
	t.baryValid = true

	return &t.bary
}

func center(r1, r2, out *Vec, width float64) {
	r1.SubAt(r2, width, out).AddSelf(r2).AddSelf(r2).ScaleSelf(0.5)
}
<|endoftext|>


<commit_before>package host

import "strings"

// ZipURL returns the URL of the zip archive given a github repository URL.
func ZipURL(url string) string {
	url = strings.TrimSuffix(url, "/")
	url = strings.TrimPrefix(url, "/")

	if strings.HasSuffix(url, "zip/master") {
		return url
	}

	// BUG filepath.Join trims slashes use url.Join
	return "https://codeload.github.com/" + url + "/zip/master"
}
<commit_msg>Refactor github zip URL calculation<commit_after>package host

import (
	"path/filepath"
	"strings"
)

// ZipURL returns the URL of the zip archive given a github repository URL.
func ZipURL(url string) string {
	url = strings.TrimSuffix(strings.TrimPrefix(url, "/"), "/")

	if strings.HasSuffix(url, "zip/master") {
		return url
	}

	return "https://codeload.github.com/" + filepath.Join(url, "/zip/master")
}
<|endoftext|>


<commit_before>package gomoney

import "testing"

func TestNewCurrency(t *testing.T) {
	btc := NewCurrency(
		"BTC",
		"Bitcoin",
		"Ƀ",
		"Satoshi",
		1000000,
		",",
		".")
    if btc == nil {
      t.Fail()
    }
}
<commit_msg>Format code.<commit_after>package gomoney

import "testing"

func TestNewCurrency(t *testing.T) {
	btc := NewCurrency(
		"BTC",
		"Bitcoin",
		"Ƀ",
		"Satoshi",
		1000000,
		",",
		".")
	if btc == nil {
		t.Fail()
	}
}
<|endoftext|>


<commit_before>// Copyright 2009 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 rpc

/*
	Some HTML presented at http://machine:port/debug/rpc
	Lists services, their methods, and some statistics, still rudimentary.
*/

import (
	"fmt"
	"net/http"
	"sort"
	"text/template"
)

const debugText = `

	<title>Services</title>
	{{range .}}

	Service {{.Name}}

		Method	Calls
		{{range .Method}}

			{{.Name}}({{.Type.ArgType}}, {{.Type.ReplyType}}) error
			{{.Type.NumCalls}}

		{{end}}

	{{end}}

	`

var debug = template.Must(template.New("RPC debug").Parse(debugText))

// If set, print log statements for internal and I/O errors.
var debugLog = false

type debugMethod struct {
	Type *methodType
	Name string
}

type methodArray []debugMethod

type debugService struct {
	Service *service
	Name    string
	Method  methodArray
}

type serviceArray []debugService

func (s serviceArray) Len() int           { return len(s) }
func (s serviceArray) Less(i, j int) bool { return s[i].Name < s[j].Name }
func (s serviceArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func (m methodArray) Len() int           { return len(m) }
func (m methodArray) Less(i, j int) bool { return m[i].Name < m[j].Name }
func (m methodArray) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }

type debugHTTP struct {
	*Server
}

// Runs at /debug/rpc
func (server debugHTTP) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// Build a sorted version of the data.
	var services = make(serviceArray, len(server.serviceMap))
	i := 0
	server.mu.Lock()
	for sname, service := range server.serviceMap {
		services[i] = debugService{service, sname, make(methodArray, len(service.method))}
		j := 0
		for mname, method := range service.method {
			services[i].Method[j] = debugMethod{method, mname}
			j++
		}
		sort.Sort(services[i].Method)
		i++
	}
	server.mu.Unlock()
	sort.Sort(services)
	err := debug.Execute(w, services)
	if err != nil {
		fmt.Fprintln(w, "rpc: error executing template:", err.Error())
	}
}
<commit_msg>net/rpc: use html/template to render html<commit_after>// Copyright 2009 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 rpc

/*
	Some HTML presented at http://machine:port/debug/rpc
	Lists services, their methods, and some statistics, still rudimentary.
*/

import (
	"fmt"
	"html/template"
	"net/http"
	"sort"
)

const debugText = `

	<title>Services</title>
	{{range .}}

	Service {{.Name}}

		Method	Calls
		{{range .Method}}

			{{.Name}}({{.Type.ArgType}}, {{.Type.ReplyType}}) error
			{{.Type.NumCalls}}

		{{end}}

	{{end}}

	`

var debug = template.Must(template.New("RPC debug").Parse(debugText))

// If set, print log statements for internal and I/O errors.
var debugLog = false

type debugMethod struct {
	Type *methodType
	Name string
}

type methodArray []debugMethod

type debugService struct {
	Service *service
	Name    string
	Method  methodArray
}

type serviceArray []debugService

func (s serviceArray) Len() int           { return len(s) }
func (s serviceArray) Less(i, j int) bool { return s[i].Name < s[j].Name }
func (s serviceArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func (m methodArray) Len() int           { return len(m) }
func (m methodArray) Less(i, j int) bool { return m[i].Name < m[j].Name }
func (m methodArray) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }

type debugHTTP struct {
	*Server
}

// Runs at /debug/rpc
func (server debugHTTP) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// Build a sorted version of the data.
	var services = make(serviceArray, len(server.serviceMap))
	i := 0
	server.mu.Lock()
	for sname, service := range server.serviceMap {
		services[i] = debugService{service, sname, make(methodArray, len(service.method))}
		j := 0
		for mname, method := range service.method {
			services[i].Method[j] = debugMethod{method, mname}
			j++
		}
		sort.Sort(services[i].Method)
		i++
	}
	server.mu.Unlock()
	sort.Sort(services)
	err := debug.Execute(w, services)
	if err != nil {
		fmt.Fprintln(w, "rpc: error executing template:", err.Error())
	}
}
<|endoftext|>


<commit_before>package gosolar

import (
	"encoding/json"
	"fmt"
	"testing"
)

// TestRemoveNCMNodes will test the getRemoveNCMNodesRequest function for stability
func TestRemoveNCMNodes(t *testing.T) {
	testGuids := []string{"guid1", "guid2"}
	expectedReq := [][]string{testGuids}
	expectedEndpoint := "Invoke/Cirrus.Nodes/RemoveNodes"
	actualReq, actualEndpoint := getRemoveNCMNodesRequest(testGuids)
	if actualEndpoint != expectedEndpoint {
		t.Fatalf("Invalid endpoint. Expected [%s] recieved [%s].", expectedEndpoint, actualEndpoint)
	}
	err := lazyCompare(expectedReq, actualReq)
	if err != nil {
		t.Fatalf("Invalid request: %v", err)
	}
}

// lazyCompare will take two interfaces and compare them for length and that their marshaled
// forms are equal on the byte level.
func lazyCompare(expected, actual interface{}) error {
	expectedBytes, err := json.Marshal(expected)
	if err != nil {
		return err
	}
	actualBytes, err := json.Marshal(actual)
	if err != nil {
		return err
	}
	elen := len(expectedBytes)
	alen := len(actualBytes)
	if elen != alen {
		return fmt.Errorf("Length discrepency. Expected length [%d] recieved length [%d].", elen, alen)
	}
	for i, actualByte := range actualBytes {
		expectedByte := expectedBytes[i]
		if actualByte != expectedByte {
			return fmt.Errorf("Byte discrepency. Expected [%X] recieved length [%X].", expectedByte, actualByte)
		}
	}
	return nil
}
<commit_msg>Remove stale testing for ncm_go<commit_after><|endoftext|>


<commit_before>// Copyright 2009 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 testing

import (
	"flag"
	"fmt"
	"os"
	"runtime"
	"time"
)

var matchBenchmarks = flag.String("test.bench", "", "regular expression to select benchmarks to run")
var benchTime = flag.Float64("test.benchtime", 1, "approximate run time for each benchmark, in seconds")

// An internal type but exported because it is cross-package; part of the implementation
// of gotest.
type InternalBenchmark struct {
	Name string
	F    func(b *B)
}

// B is a type passed to Benchmark functions to manage benchmark
// timing and to specify the number of iterations to run.
type B struct {
	N         int
	benchmark InternalBenchmark
	ns        int64
	bytes     int64
	start     int64
}

// StartTimer starts timing a test.  This function is called automatically
// before a benchmark starts, but it can also used to resume timing after
// a call to StopTimer.
func (b *B) StartTimer() { b.start = time.Nanoseconds() }

// StopTimer stops timing a test.  This can be used to pause the timer
// while performing complex initialization that you don't
// want to measure.
func (b *B) StopTimer() {
	if b.start > 0 {
		b.ns += time.Nanoseconds() - b.start
	}
	b.start = 0
}

// ResetTimer stops the timer and sets the elapsed benchmark time to zero.
func (b *B) ResetTimer() {
	b.start = 0
	b.ns = 0
}

// SetBytes records the number of bytes processed in a single operation.
// If this is called, the benchmark will report ns/op and MB/s.
func (b *B) SetBytes(n int64) { b.bytes = n }

func (b *B) nsPerOp() int64 {
	if b.N <= 0 {
		return 0
	}
	return b.ns / int64(b.N)
}

// runN runs a single benchmark for the specified number of iterations.
func (b *B) runN(n int) {
	// Try to get a comparable environment for each run
	// by clearing garbage from previous runs.
	runtime.GC()
	b.N = n
	b.ResetTimer()
	b.StartTimer()
	b.benchmark.F(b)
	b.StopTimer()
}

func min(x, y int) int {
	if x > y {
		return y
	}
	return x
}

func max(x, y int) int {
	if x < y {
		return y
	}
	return x
}

// roundDown10 rounds a number down to the nearest power of 10.
func roundDown10(n int) int {
	var tens = 0
	// tens = floor(log_10(n))
	for n > 10 {
		n = n / 10
		tens++
	}
	// result = 10^tens
	result := 1
	for i := 0; i < tens; i++ {
		result *= 10
	}
	return result
}

// roundUp rounds x up to a number of the form [1eX, 2eX, 5eX].
func roundUp(n int) int {
	base := roundDown10(n)
	if n < (2 * base) {
		return 2 * base
	}
	if n < (5 * base) {
		return 5 * base
	}
	return 10 * base
}

// run times the benchmark function.  It gradually increases the number
// of benchmark iterations until the benchmark runs for a second in order
// to get a reasonable measurement.  It prints timing information in this form
//		testing.BenchmarkHello	100000		19 ns/op
func (b *B) run() BenchmarkResult {
	// Run the benchmark for a single iteration in case it's expensive.
	n := 1
	b.runN(n)
	// Run the benchmark for at least the specified amount of time.
	time := int64(*benchTime * 1e9)
	for b.ns < time && n < 1e9 {
		last := n
		// Predict iterations/sec.
		if b.nsPerOp() == 0 {
			n = 1e9
		} else {
			n = int(time / b.nsPerOp())
		}
		// Run more iterations than we think we'll need for a second (1.5x).
		// Don't grow too fast in case we had timing errors previously.
		// Be sure to run at least one more than last time.
		n = max(min(n+n/2, 100*last), last+1)
		// Round up to something easy to read.
		n = roundUp(n)
		b.runN(n)
	}
	return BenchmarkResult{b.N, b.ns, b.bytes}
}

// The results of a benchmark run.
type BenchmarkResult struct {
	N     int   // The number of iterations.
	Ns    int64 // The total time taken.
	Bytes int64 // Bytes processed in one iteration.
}

func (r BenchmarkResult) NsPerOp() int64 {
	if r.N <= 0 {
		return 0
	}
	return r.Ns / int64(r.N)
}

func (r BenchmarkResult) mbPerSec() float64 {
	if r.Bytes <= 0 || r.Ns <= 0 || r.N <= 0 {
		return 0
	}
	return float64(r.Bytes) * float64(r.N) / float64(r.Ns) * 1e3
}

func (r BenchmarkResult) String() string {
	mbs := r.mbPerSec()
	mb := ""
	if mbs != 0 {
		mb = fmt.Sprintf("\t%7.2f MB/s", mbs)
	}
	nsop := r.NsPerOp()
	ns := fmt.Sprintf("%10d ns/op", nsop)
	if r.N > 0 && nsop < 100 {
		// The format specifiers here make sure that
		// the ones digits line up for all three possible formats.
		if nsop < 10 {
			ns = fmt.Sprintf("%13.2f ns/op", float64(r.Ns)/float64(r.N))
		} else {
			ns = fmt.Sprintf("%12.1f ns/op", float64(r.Ns)/float64(r.N))
		}
	}
	return fmt.Sprintf("%8d\t%s%s", r.N, ns, mb)
}

// An internal function but exported because it is cross-package; part of the implementation
// of gotest.
func RunBenchmarks(matchString func(pat, str string) (bool, os.Error), benchmarks []InternalBenchmark) {
	// If no flag was specified, don't run benchmarks.
	if len(*matchBenchmarks) == 0 {
		return
	}
	for _, Benchmark := range benchmarks {
		matched, err := matchString(*matchBenchmarks, Benchmark.Name)
		if err != nil {
			println("invalid regexp for -test.bench:", err.String())
			os.Exit(1)
		}
		if !matched {
			continue
		}
		for _, procs := range cpuList {
			runtime.GOMAXPROCS(procs)
			b := &B{benchmark: Benchmark}
			r := b.run()
			benchName := Benchmark.Name
			if procs != 1 {
				benchName = fmt.Sprintf("%s-%d", Benchmark.Name, procs)
			}
			print(fmt.Sprintf("%s\t%v\n", benchName, r))
			if p := runtime.GOMAXPROCS(-1); p != procs {
				print(fmt.Sprintf("%s left GOMAXPROCS set to %d\n", benchName, p))
			}
		}
	}
}

// Benchmark benchmarks a single function. Useful for creating
// custom benchmarks that do not use gotest.
func Benchmark(f func(b *B)) BenchmarkResult {
	b := &B{benchmark: InternalBenchmark{"", f}}
	return b.run()
}
<commit_msg>testing: make ResetTimer not start/stop the timer<commit_after>// Copyright 2009 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 testing

import (
	"flag"
	"fmt"
	"os"
	"runtime"
	"time"
)

var matchBenchmarks = flag.String("test.bench", "", "regular expression to select benchmarks to run")
var benchTime = flag.Float64("test.benchtime", 1, "approximate run time for each benchmark, in seconds")

// An internal type but exported because it is cross-package; part of the implementation
// of gotest.
type InternalBenchmark struct {
	Name string
	F    func(b *B)
}

// B is a type passed to Benchmark functions to manage benchmark
// timing and to specify the number of iterations to run.
type B struct {
	N         int
	benchmark InternalBenchmark
	ns        int64
	bytes     int64
	start     int64
}

// StartTimer starts timing a test.  This function is called automatically
// before a benchmark starts, but it can also used to resume timing after
// a call to StopTimer.
func (b *B) StartTimer() {
	if b.start == 0 {
		b.start = time.Nanoseconds()
	}
}

// StopTimer stops timing a test.  This can be used to pause the timer
// while performing complex initialization that you don't
// want to measure.
func (b *B) StopTimer() {
	if b.start > 0 {
		b.ns += time.Nanoseconds() - b.start
	}
	b.start = 0
}

// ResetTimer sets the elapsed benchmark time to zero.
// It does not affect whether the timer is running.
func (b *B) ResetTimer() {
	if b.start > 0 {
		b.start = time.Nanoseconds()
	}
	b.ns = 0
}

// SetBytes records the number of bytes processed in a single operation.
// If this is called, the benchmark will report ns/op and MB/s.
func (b *B) SetBytes(n int64) { b.bytes = n }

func (b *B) nsPerOp() int64 {
	if b.N <= 0 {
		return 0
	}
	return b.ns / int64(b.N)
}

// runN runs a single benchmark for the specified number of iterations.
func (b *B) runN(n int) {
	// Try to get a comparable environment for each run
	// by clearing garbage from previous runs.
	runtime.GC()
	b.N = n
	b.ResetTimer()
	b.StartTimer()
	b.benchmark.F(b)
	b.StopTimer()
}

func min(x, y int) int {
	if x > y {
		return y
	}
	return x
}

func max(x, y int) int {
	if x < y {
		return y
	}
	return x
}

// roundDown10 rounds a number down to the nearest power of 10.
func roundDown10(n int) int {
	var tens = 0
	// tens = floor(log_10(n))
	for n > 10 {
		n = n / 10
		tens++
	}
	// result = 10^tens
	result := 1
	for i := 0; i < tens; i++ {
		result *= 10
	}
	return result
}

// roundUp rounds x up to a number of the form [1eX, 2eX, 5eX].
func roundUp(n int) int {
	base := roundDown10(n)
	if n < (2 * base) {
		return 2 * base
	}
	if n < (5 * base) {
		return 5 * base
	}
	return 10 * base
}

// run times the benchmark function.  It gradually increases the number
// of benchmark iterations until the benchmark runs for a second in order
// to get a reasonable measurement.  It prints timing information in this form
//		testing.BenchmarkHello	100000		19 ns/op
func (b *B) run() BenchmarkResult {
	// Run the benchmark for a single iteration in case it's expensive.
	n := 1
	b.runN(n)
	// Run the benchmark for at least the specified amount of time.
	time := int64(*benchTime * 1e9)
	for b.ns < time && n < 1e9 {
		last := n
		// Predict iterations/sec.
		if b.nsPerOp() == 0 {
			n = 1e9
		} else {
			n = int(time / b.nsPerOp())
		}
		// Run more iterations than we think we'll need for a second (1.5x).
		// Don't grow too fast in case we had timing errors previously.
		// Be sure to run at least one more than last time.
		n = max(min(n+n/2, 100*last), last+1)
		// Round up to something easy to read.
		n = roundUp(n)
		b.runN(n)
	}
	return BenchmarkResult{b.N, b.ns, b.bytes}
}

// The results of a benchmark run.
type BenchmarkResult struct {
	N     int   // The number of iterations.
	Ns    int64 // The total time taken.
	Bytes int64 // Bytes processed in one iteration.
}

func (r BenchmarkResult) NsPerOp() int64 {
	if r.N <= 0 {
		return 0
	}
	return r.Ns / int64(r.N)
}

func (r BenchmarkResult) mbPerSec() float64 {
	if r.Bytes <= 0 || r.Ns <= 0 || r.N <= 0 {
		return 0
	}
	return float64(r.Bytes) * float64(r.N) / float64(r.Ns) * 1e3
}

func (r BenchmarkResult) String() string {
	mbs := r.mbPerSec()
	mb := ""
	if mbs != 0 {
		mb = fmt.Sprintf("\t%7.2f MB/s", mbs)
	}
	nsop := r.NsPerOp()
	ns := fmt.Sprintf("%10d ns/op", nsop)
	if r.N > 0 && nsop < 100 {
		// The format specifiers here make sure that
		// the ones digits line up for all three possible formats.
		if nsop < 10 {
			ns = fmt.Sprintf("%13.2f ns/op", float64(r.Ns)/float64(r.N))
		} else {
			ns = fmt.Sprintf("%12.1f ns/op", float64(r.Ns)/float64(r.N))
		}
	}
	return fmt.Sprintf("%8d\t%s%s", r.N, ns, mb)
}

// An internal function but exported because it is cross-package; part of the implementation
// of gotest.
func RunBenchmarks(matchString func(pat, str string) (bool, os.Error), benchmarks []InternalBenchmark) {
	// If no flag was specified, don't run benchmarks.
	if len(*matchBenchmarks) == 0 {
		return
	}
	for _, Benchmark := range benchmarks {
		matched, err := matchString(*matchBenchmarks, Benchmark.Name)
		if err != nil {
			println("invalid regexp for -test.bench:", err.String())
			os.Exit(1)
		}
		if !matched {
			continue
		}
		for _, procs := range cpuList {
			runtime.GOMAXPROCS(procs)
			b := &B{benchmark: Benchmark}
			r := b.run()
			benchName := Benchmark.Name
			if procs != 1 {
				benchName = fmt.Sprintf("%s-%d", Benchmark.Name, procs)
			}
			print(fmt.Sprintf("%s\t%v\n", benchName, r))
			if p := runtime.GOMAXPROCS(-1); p != procs {
				print(fmt.Sprintf("%s left GOMAXPROCS set to %d\n", benchName, p))
			}
		}
	}
}

// Benchmark benchmarks a single function. Useful for creating
// custom benchmarks that do not use gotest.
func Benchmark(f func(b *B)) BenchmarkResult {
	b := &B{benchmark: InternalBenchmark{"", f}}
	return b.run()
}
<|endoftext|>


<commit_before>// Package sss implements the Shamir Secret Sharing algorithm over GF(2^8).
// This package has not been audited by cryptography or security professionals.
package sss

import (
	"crypto/rand"
)

// Split the given secret into N shares of which K are required to recover the
// secret. Returns a map of share IDs (1-255) to shares.
func Split(n, k int, secret []byte) (map[int][]byte, error) {
	shares := make(map[int][]byte, n)

	for _, b := range secret {
		p, err := randPoly(k-1, element(b), rand.Reader)
		if err != nil {
			return nil, err
		}

		for x := 1; x <= n; x++ {
			y := p.eval(element(x))
			shares[x] = append(shares[x], byte(y))
		}
	}

	return shares, nil
}

// Combine the given shares into the original secret.
// N.B.: There is no way to know whether the returned value is, in fact, the
// original secret.
func Combine(shares map[int][]byte) []byte {
	var secret []byte
	for _, v := range shares {
		secret = make([]byte, len(v))
		break
	}

	points := make([][2]element, len(shares))
	for i := range secret {
		p := 0
		for k, v := range shares {
			points[p][0] = element(k)
			points[p][1] = element(v[i])
			p++
		}

		s := interpolate(points, 0)
		secret[i] = byte(s)
	}

	return secret
}
<commit_msg>Improved documentation.<commit_after>// Package sss implements Shamir's Secret Sharing algorithm over GF(2^8).
//
// Shamir's Secret Sharing algorithm allows you to securely share a secret with
// N people, allowing the recovery of that secret if K of those people combine
// their shares.
//
// It begins by encoding a secret as a number (e.g., 42), and generating N random
// polynomial equations of degree K-1 which have an X-intercept equal to the
// secret. Given K=3, the following equations might be generated:
//
//     f1(x) =  78x^2 +  19x + 42
//     f2(x) = 128x^2 + 171x + 42
//     etc.
//
// These polynomials are then evaluated for values of X > 0:
//
//     f1(1) = 139
//     f2(2) = 896
//     etc.
//
// These (x, y) pairs are the shares given to the parties. In order to combine
// shares to recover the secret, these (x, y) pairs  are used as the input points
// for Lagrange interpolation, which produces a polynomial which matches the
// given points. This polynomial can be evaluated for f(0), producing the secret
// value--the common x-intercept for all the generated polynomials.
//
// If fewer than K shares are combined, the interpolated polynomial will be
// wrong, and the result of f(0) will not be the secret.
//
// This package constructs polynomials over the field GF(2^8) for each byte of
// the secret, allowing for much faster splitting and combining.
//
// This package has not been audited by cryptography or security professionals.
package sss

import (
	"crypto/rand"
)

// Split the given secret into N shares of which K are required to recover the
// secret. Returns a map of share IDs (1-255) to shares.
func Split(n, k int, secret []byte) (map[int][]byte, error) {
	shares := make(map[int][]byte, n)

	for _, b := range secret {
		p, err := randPoly(k-1, element(b), rand.Reader)
		if err != nil {
			return nil, err
		}

		for x := 1; x <= n; x++ {
			y := p.eval(element(x))
			shares[x] = append(shares[x], byte(y))
		}
	}

	return shares, nil
}

// Combine the given shares into the original secret.
// N.B.: There is no way to know whether the returned value is, in fact, the
// original secret.
func Combine(shares map[int][]byte) []byte {
	var secret []byte
	for _, v := range shares {
		secret = make([]byte, len(v))
		break
	}

	points := make([][2]element, len(shares))
	for i := range secret {
		p := 0
		for k, v := range shares {
			points[p][0] = element(k)
			points[p][1] = element(v[i])
			p++
		}

		s := interpolate(points, 0)
		secret[i] = byte(s)
	}

	return secret
}
<|endoftext|>


<commit_before>package mgr

import (
	"github.com/analogj/capsulecd/pkg/pipeline"
	"net/http"
	"github.com/analogj/capsulecd/pkg/errors"
	"fmt"
	"github.com/analogj/capsulecd/pkg/config"
)

func Create(mgrType string, pipelineData *pipeline.Data, config config.Interface, client *http.Client) (Interface, error) {

	var mgr Interface

	switch mgrType {
	//empty/generic package manager. Noop.
	case "generic":
		mgr = new(mgrGeneric)

	//chef dependency managers
	case "berkshelf":
		mgr = new(mgrChefBerkshelf)

	//golang dependency managers
	case "dep":
		mgr = new(mgrGolangDep)
	case "glide":
		mgr = new(mgrGolangGlide)

	//node dependency managers
	case "npm":
		mgr = new(mgrNodeNpm)
	case "yarn":
		mgr = new(mgrNodeYarn)

	//python dependency managers
	case "pip":
		mgr = new(mgrPythonPip)

	//ruby dependency managers
	case "bundler":
		mgr = new(mgrRubyBundler)

	default:
		return nil, errors.ScmUnspecifiedError(fmt.Sprintf("Unknown Packager Manager Type: %s", mgrType))
	}

	if err := mgr.Init(pipelineData, config, client); err != nil {
		return nil, err
	}
	return mgr, nil
}

func Detect(packageType string, pipelineData *pipeline.Data, config config.Interface, client *http.Client) (Interface, error) {

	var mgrType string
	mgrType = "unknown"

	switch packageType {
	//chef dependency managers
	case "chef":
		if DetectChefBerkshelf(pipelineData, config, client) {
			mgrType = "berkshelf"
		} else { //default
			mgrType = "berkshelf"
		}

	//golang dependency managers
	case "golang":
		if DetectGolangDep(pipelineData, config, client) {
			mgrType = "dep"
		} else if DetectGolangGlide(pipelineData, config, client) {
			mgrType = "glide"
		} else { //default
			mgrType = "dep"
		}

	//node dependency managers
	case "node":
		if DetectNodeNpm(pipelineData, config, client) {
			mgrType = "npm"
		} else if DetectNodeYarn(pipelineData, config, client) {
			mgrType = "yarn"
		} else { //default
			mgrType = "npm"
		}

	//python dependency managers
	case "python":
		if DetectPythonPip(pipelineData, config, client) {
			mgrType = "pip"
		} else { //default
			mgrType = "pip"
		}

	//ruby dependency managers
	case "ruby":
		if DetectRubyBundler(pipelineData, config, client) {
			mgrType = "bundler"
		} else { //default
			mgrType = "bundler"
		}

	//empty/generic package manager. Noop.
	case "generic":
		mgrType = "generic"

	default:
		return nil, errors.MgrUnspecifiedError(fmt.Sprintf("Unknown Dependency Manager for Package Type (%s): %s", packageType, mgrType))
	}

	return Create(mgrType, pipelineData, config, client )
}
<commit_msg>package manager is a bterrer name than dependency manager.<commit_after>package mgr

import (
	"github.com/analogj/capsulecd/pkg/pipeline"
	"net/http"
	"github.com/analogj/capsulecd/pkg/errors"
	"fmt"
	"github.com/analogj/capsulecd/pkg/config"
)

func Create(mgrType string, pipelineData *pipeline.Data, config config.Interface, client *http.Client) (Interface, error) {

	var mgr Interface

	switch mgrType {
	//empty/generic package manager. Noop.
	case "generic":
		mgr = new(mgrGeneric)

	//chef dependency managers
	case "berkshelf":
		mgr = new(mgrChefBerkshelf)

	//golang dependency managers
	case "dep":
		mgr = new(mgrGolangDep)
	case "glide":
		mgr = new(mgrGolangGlide)

	//node dependency managers
	case "npm":
		mgr = new(mgrNodeNpm)
	case "yarn":
		mgr = new(mgrNodeYarn)

	//python dependency managers
	case "pip":
		mgr = new(mgrPythonPip)

	//ruby dependency managers
	case "bundler":
		mgr = new(mgrRubyBundler)

	default:
		return nil, errors.ScmUnspecifiedError(fmt.Sprintf("Unknown Packager Manager Type: %s", mgrType))
	}

	if err := mgr.Init(pipelineData, config, client); err != nil {
		return nil, err
	}
	return mgr, nil
}

func Detect(packageType string, pipelineData *pipeline.Data, config config.Interface, client *http.Client) (Interface, error) {

	var mgrType string
	mgrType = "unknown"

	switch packageType {
	//chef dependency managers
	case "chef":
		if DetectChefBerkshelf(pipelineData, config, client) {
			mgrType = "berkshelf"
		} else { //default
			mgrType = "berkshelf"
		}

	//golang dependency managers
	case "golang":
		if DetectGolangDep(pipelineData, config, client) {
			mgrType = "dep"
		} else if DetectGolangGlide(pipelineData, config, client) {
			mgrType = "glide"
		} else { //default
			mgrType = "dep"
		}

	//node dependency managers
	case "node":
		if DetectNodeNpm(pipelineData, config, client) {
			mgrType = "npm"
		} else if DetectNodeYarn(pipelineData, config, client) {
			mgrType = "yarn"
		} else { //default
			mgrType = "npm"
		}

	//python dependency managers
	case "python":
		if DetectPythonPip(pipelineData, config, client) {
			mgrType = "pip"
		} else { //default
			mgrType = "pip"
		}

	//ruby dependency managers
	case "ruby":
		if DetectRubyBundler(pipelineData, config, client) {
			mgrType = "bundler"
		} else { //default
			mgrType = "bundler"
		}

	//empty/generic package manager. Noop.
	case "generic":
		mgrType = "generic"

	default:
		return nil, errors.MgrUnspecifiedError(fmt.Sprintf("Unknown Package Manager for Package Type (%s): %s", packageType, mgrType))
	}

	return Create(mgrType, pipelineData, config, client )
}
<|endoftext|>


<commit_before>//  Copyright (c) 2015 Couchbase, 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 ghistogram provides a simple histogram of uint64's that
// avoids heap allocations (garbage creation) during data processing.
package ghistogram

import (
	"bytes"
	"fmt"
	"math"
	"strconv"
)

// Histogram is a simple uint64 histogram implementation that avoids
// heap allocations during its processing of incoming data points.
//
// It was motivated for tracking simple performance timings.
//
// The histogram bins are split across the two arrays of Ranges and
// Counts, where len(Ranges) == len(Counts).  These arrays are public
// in case users wish to use reflection or JSON marhsaling.
//
// An optional growth factor for bin sizes is supported - see
// NewHistogram() binGrowthFactor parameter.
//
// Concurrent usage of a Histogram is the responsibility of the user
// (e.g., use your own locking).
type Histogram struct {
	// Ranges holds the lower domain bounds of bins, so bin i has data
	// point domain of "[Ranges[i], Ranges[i+1])".  Related,
	// Ranges[0] == 0 and Ranges[1] == binFirst.
	Ranges []uint64

	// Counts holds the event counts for bins.
	Counts []uint64

	MinDataPoint uint64
	MaxDataPoint uint64
}

// NewHistogram creates a new, ready to use Histogram.  The numBins
// must be >= 2.  The binFirst is the width of the first bin.  The
// binGrowthFactor must be > 1.0 or 0.0.
//
// A special case of binGrowthFactor of 0.0 means the the allocated
// bins will have constant, non-growing size or "width".
func NewHistogram(
	numBins int,
	binFirst uint64,
	binGrowthFactor float64) *Histogram {
	gh := &Histogram{
		Ranges: make([]uint64, numBins),
		Counts: make([]uint64, numBins),

		MinDataPoint: math.MaxUint64,
		MaxDataPoint: 0,
	}

	gh.Ranges[0] = 0
	gh.Ranges[1] = binFirst

	for i := 2; i < len(gh.Ranges); i++ {
		if binGrowthFactor == 0.0 {
			gh.Ranges[i] = gh.Ranges[i-1] + binFirst
		} else {
			gh.Ranges[i] =
				uint64(math.Ceil(binGrowthFactor * float64(gh.Ranges[i-1])))
		}
	}

	return gh
}

// Add increases the count in the bin for the given dataPoint.
func (gh *Histogram) Add(dataPoint uint64, count uint64) {
	idx := search(gh.Ranges, dataPoint)
	if idx >= 0 {
		gh.Counts[idx] += count
	}
	if gh.MinDataPoint > count {
		gh.MinDataPoint = count
	}
	if gh.MaxDataPoint < count {
		gh.MaxDataPoint = count
	}
}

// Finds the last arr index where the arr entry <= dataPoint.
func search(arr []uint64, dataPoint uint64) int {
	i, j := 0, len(arr)

	for i < j {
		h := i + (j-i)/2 // Avoids h overflow, where i <= h < j.
		if dataPoint >= arr[h] {
			i = h + 1
		} else {
			j = h
		}
	}

	return i - 1
}

// AddAll adds all the Counts from the src histogram into this
// histogram.  The src and this histogram must either have the same
// exact creation parameters.
func (gh *Histogram) AddAll(src *Histogram) {
	for i := 0; i < len(src.Counts); i++ {
		gh.Counts[i] += src.Counts[i]
	}
	if gh.MinDataPoint > src.MinDataPoint {
		gh.MinDataPoint = src.MinDataPoint
	}
	if gh.MaxDataPoint < src.MaxDataPoint {
		gh.MaxDataPoint = src.MaxDataPoint
	}
}

// Graph emits an ascii graph to the optional bufOut, allocating a
// bufOut if none is supplied.  Returns the bufOut.  Each line emitted
// will have the given, optional prefix.
//
// For example:
//       0+  10=2 10.00% ********
//      10+  10=1 10.00% ****
//      20+  10=3 10.00% ************
func (gh *Histogram) EmitGraph(prefix []byte,
	bufOut *bytes.Buffer) *bytes.Buffer {
	ranges := gh.Ranges
	rangesN := len(ranges)
	counts := gh.Counts
	countsN := len(counts)

	if bufOut == nil {
		bufOut = bytes.NewBuffer(make([]byte, 0, 80*countsN))
	}

	var totCount uint64
	var maxCount uint64
	for _, c := range counts {
		totCount += c
		if maxCount < c {
			maxCount = c
		}
	}
	totCountF := float64(totCount)
	maxCountF := float64(maxCount)

	widthRange := len(strconv.Itoa(int(ranges[rangesN-1])))
	widthWidth := len(strconv.Itoa(int(ranges[rangesN-1] - ranges[rangesN-2])))
	widthCount := len(strconv.Itoa(int(maxCount)))

	// Each line looks like: "[prefix]START+WIDTH=COUNT PCT% BAR\n"
	f := fmt.Sprintf("%%%dd+%%%dd=%%%dd%% 7.2f%%%%",
		widthRange, widthWidth, widthCount)

	var runCount uint64 // Running total while emitting lines.

	barLen := float64(len(bar))

	for i, c := range counts {
		if prefix != nil {
			bufOut.Write(prefix)
		}

		var width uint64
		if i < countsN-1 {
			width = uint64(ranges[i+1] - ranges[i])
		}

		runCount += c
		fmt.Fprintf(bufOut, f, ranges[i], width, c,
			100.0*(float64(runCount)/totCountF))

		if c > 0 {
			bufOut.Write([]byte(" "))
			barWant := int(math.Floor(barLen * (float64(c) / maxCountF)))
			bufOut.Write(bar[0:barWant])
		}

		bufOut.Write([]byte("\n"))
	}

	return bufOut
}

var bar = []byte("******************************")
<commit_msg>renamed bufOut to out<commit_after>//  Copyright (c) 2015 Couchbase, 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 ghistogram provides a simple histogram of uint64's that
// avoids heap allocations (garbage creation) during data processing.
package ghistogram

import (
	"bytes"
	"fmt"
	"math"
	"strconv"
)

// Histogram is a simple uint64 histogram implementation that avoids
// heap allocations during its processing of incoming data points.
//
// It was motivated for tracking simple performance timings.
//
// The histogram bins are split across the two arrays of Ranges and
// Counts, where len(Ranges) == len(Counts).  These arrays are public
// in case users wish to use reflection or JSON marhsaling.
//
// An optional growth factor for bin sizes is supported - see
// NewHistogram() binGrowthFactor parameter.
//
// Concurrent usage of a Histogram is the responsibility of the user
// (e.g., use your own locking).
type Histogram struct {
	// Ranges holds the lower domain bounds of bins, so bin i has data
	// point domain of "[Ranges[i], Ranges[i+1])".  Related,
	// Ranges[0] == 0 and Ranges[1] == binFirst.
	Ranges []uint64

	// Counts holds the event counts for bins.
	Counts []uint64

	MinDataPoint uint64
	MaxDataPoint uint64
}

// NewHistogram creates a new, ready to use Histogram.  The numBins
// must be >= 2.  The binFirst is the width of the first bin.  The
// binGrowthFactor must be > 1.0 or 0.0.
//
// A special case of binGrowthFactor of 0.0 means the the allocated
// bins will have constant, non-growing size or "width".
func NewHistogram(
	numBins int,
	binFirst uint64,
	binGrowthFactor float64) *Histogram {
	gh := &Histogram{
		Ranges: make([]uint64, numBins),
		Counts: make([]uint64, numBins),

		MinDataPoint: math.MaxUint64,
		MaxDataPoint: 0,
	}

	gh.Ranges[0] = 0
	gh.Ranges[1] = binFirst

	for i := 2; i < len(gh.Ranges); i++ {
		if binGrowthFactor == 0.0 {
			gh.Ranges[i] = gh.Ranges[i-1] + binFirst
		} else {
			gh.Ranges[i] =
				uint64(math.Ceil(binGrowthFactor * float64(gh.Ranges[i-1])))
		}
	}

	return gh
}

// Add increases the count in the bin for the given dataPoint.
func (gh *Histogram) Add(dataPoint uint64, count uint64) {
	idx := search(gh.Ranges, dataPoint)
	if idx >= 0 {
		gh.Counts[idx] += count
	}
	if gh.MinDataPoint > count {
		gh.MinDataPoint = count
	}
	if gh.MaxDataPoint < count {
		gh.MaxDataPoint = count
	}
}

// Finds the last arr index where the arr entry <= dataPoint.
func search(arr []uint64, dataPoint uint64) int {
	i, j := 0, len(arr)

	for i < j {
		h := i + (j-i)/2 // Avoids h overflow, where i <= h < j.
		if dataPoint >= arr[h] {
			i = h + 1
		} else {
			j = h
		}
	}

	return i - 1
}

// AddAll adds all the Counts from the src histogram into this
// histogram.  The src and this histogram must either have the same
// exact creation parameters.
func (gh *Histogram) AddAll(src *Histogram) {
	for i := 0; i < len(src.Counts); i++ {
		gh.Counts[i] += src.Counts[i]
	}
	if gh.MinDataPoint > src.MinDataPoint {
		gh.MinDataPoint = src.MinDataPoint
	}
	if gh.MaxDataPoint < src.MaxDataPoint {
		gh.MaxDataPoint = src.MaxDataPoint
	}
}

// Graph emits an ascii graph to the optional out buffer, allocating a
// out buffer if none was supplied.  Returns the out buffer.  Each
// line emitted may have an optional prefix.
//
// For example:
//       0+  10=2 10.00% ********
//      10+  10=1 10.00% ****
//      20+  10=3 10.00% ************
func (gh *Histogram) EmitGraph(prefix []byte,
	out *bytes.Buffer) *bytes.Buffer {
	ranges := gh.Ranges
	rangesN := len(ranges)
	counts := gh.Counts
	countsN := len(counts)

	if out == nil {
		out = bytes.NewBuffer(make([]byte, 0, 80*countsN))
	}

	var totCount uint64
	var maxCount uint64
	for _, c := range counts {
		totCount += c
		if maxCount < c {
			maxCount = c
		}
	}
	totCountF := float64(totCount)
	maxCountF := float64(maxCount)

	widthRange := len(strconv.Itoa(int(ranges[rangesN-1])))
	widthWidth := len(strconv.Itoa(int(ranges[rangesN-1] - ranges[rangesN-2])))
	widthCount := len(strconv.Itoa(int(maxCount)))

	// Each line looks like: "[prefix]START+WIDTH=COUNT PCT% BAR\n"
	f := fmt.Sprintf("%%%dd+%%%dd=%%%dd%% 7.2f%%%%",
		widthRange, widthWidth, widthCount)

	var runCount uint64 // Running total while emitting lines.

	barLen := float64(len(bar))

	for i, c := range counts {
		if prefix != nil {
			out.Write(prefix)
		}

		var width uint64
		if i < countsN-1 {
			width = uint64(ranges[i+1] - ranges[i])
		}

		runCount += c
		fmt.Fprintf(out, f, ranges[i], width, c,
			100.0*(float64(runCount)/totCountF))

		if c > 0 {
			out.Write([]byte(" "))
			barWant := int(math.Floor(barLen * (float64(c) / maxCountF)))
			out.Write(bar[0:barWant])
		}

		out.Write([]byte("\n"))
	}

	return out
}

var bar = []byte("******************************")
<|endoftext|>


<commit_before>package mount

import (
	"errors"
	"fmt"
	"strings"
	"sync"
	"syscall"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/docker/pkg/mount"
)

// Ops defines the interface for keep track of volume driver mounts.
type Ops interface {
	// String representation of the mount table
	String() string
	// Load mount table for all devices that match the prefix. An empty prefix may
	// be provided.
	Load(devPrefix string) error
	// Inspect mount table for specified device. ErrEnoent may be returned.
	Inspect(device string) (Info, error)
	// Exists returns true if the device is mounted at specified path.
	// returned if the device does not exists.
	Exists(device, path string) (bool, error)
	// Mount device at mountpoint or increment refcnt if device is already mounted
	// at specified mountpoint.
	Mount(Minor int32, device, path, fs string, flags uintptr, data string) error
	// Unmount device at mountpoint or decrement refcnt. If device has no
	// mountpoints left after this operation, it is removed from the matrix.
	// ErrEnoent is returned if the device or mountpoint for the device is not found.
	Unmount(device, path string) error
}

// DeviceMap map device name to Info
type DeviceMap map[string]*Info

// PathInfo is a reference counted path
type PathInfo struct {
	Path string
	ref  int
}

// Info per device
type Info struct {
	Device     string
	Minor      int
	Mountpoint []PathInfo
	Fs         string
}

// Matrix implements Ops and keeps track of active mounts for volume drivers.
type Matrix struct {
	sync.Mutex
	mounts DeviceMap
}

var (
	// ErrEnoent is returned for a non existent mount point
	ErrEnoent = errors.New("Mountpath is not mounted")
	// ErrEinval is returned is fields for an entry do no match
	// existing fields
	ErrEinval = errors.New("Invalid arguments for mount entry")
)

// New instance of Matrix
func New(devPrefix string) (*Matrix, error) {
	m := &Matrix{
		mounts: make(DeviceMap),
	}
	err := m.Load(devPrefix)
	if err != nil {
		return nil, err
	}
	return m, nil
}

// Exists scans mountpaths for specified device and returns true if path is one of the
// mountpaths. ErrEnoent may be retuned if the device is not found
func (m *Matrix) Exists(devPath string, path string) (bool, error) {
	m.Lock()
	defer m.Unlock()

	v, ok := m.mounts[devPath]
	if !ok {
		return false, ErrEnoent
	}
	for _, p := range v.Mountpoint {
		if p.Path == path {
			return true, nil
		}
	}
	return false, nil
}

// Mount new mountpoint for specified device.
func (m *Matrix) Mount(minor int, device, path, fs string, flags uintptr, data string) error {
	m.Lock()
	defer m.Unlock()

	info, ok := m.mounts[device]
	if !ok {
		info = &Info{
			Device:     device,
			Mountpoint: make([]PathInfo, 8),
			Minor:      minor,
			Fs:         fs,
		}
		m.mounts[device] = info
	}

	// Validate input params
	if fs != info.Fs {
		log.Warnf("%s Existing mountpoint has fs %q cannot change to %q",
			device, info.Fs, fs)
		return ErrEinval
	}

	// Try to find the mountpoint. If it already exists, then increment refcnt
	for _, p := range info.Mountpoint {
		if p.Path == path {
			p.ref++
			return nil
		}
	}
	// The device is not mounted at path, mount it and add to its mountpoints.
	err := syscall.Mount(device, path, fs, flags, data)
	if err != nil {
		return err
	}
	info.Mountpoint = append(info.Mountpoint, PathInfo{Path: path, ref: 1})
	return nil
}

// Unmount device at mountpoint or decrement refcnt. If device has no
// mountpoints left after this operation, it is removed from the matrix.
// ErrEnoent is returned if the device or mountpoint for the device is not found.
func (m *Matrix) Unmount(device, path string) error {
	m.Lock()
	defer m.Unlock()

	info, ok := m.mounts[device]
	if !ok {
		return ErrEnoent
	}
	for i, p := range info.Mountpoint {
		if p.Path == path {
			p.ref--
			// Unmount only if refcnt is 0
			if p.ref == 0 {
				err := syscall.Unmount(path, 0)
				if err != nil {
					return err
				}
				// Blow away this mountpoint.
				info.Mountpoint[i] = info.Mountpoint[len(info.Mountpoint)-1]
				info.Mountpoint = info.Mountpoint[0 : len(info.Mountpoint)-1]
				// If the device has no more mountpoints, remove it from the map
				if len(info.Mountpoint) == 0 {
					delete(m.mounts, device)
				}
			}
			return nil
		}
	}
	return ErrEnoent
}

// String representation of Matrix
func (m *Matrix) String() string {
	return fmt.Sprintf("%#v", *m)
}

// Load mount table
func (m *Matrix) Load(devPrefix string) error {
	info, err := mount.GetMounts()
	if err != nil {
		return err
	}
	for _, v := range info {
		if !strings.HasPrefix(v.Source, devPrefix) {
			continue
		}
		mount, ok := m.mounts[v.Source]
		if !ok {
			mount = &Info{
				Device:     v.Source,
				Fs:         v.Fstype,
				Minor:      v.Minor,
				Mountpoint: make([]PathInfo, 0),
			}
			m.mounts[v.Source] = mount
		}
		// Allow Load to be called multiple times.
		for _, p := range mount.Mountpoint {
			if p.Path == v.Mountpoint {
				continue
			}
		}
		// XXX Reconstruct refs.
		mount.Mountpoint = append(mount.Mountpoint, PathInfo{Path: v.Mountpoint, ref: 1})
	}
	return nil
}
<commit_msg>add function to determine runtime device mounts<commit_after>// +build linux

package mount

import (
	"errors"
	"fmt"
	"strings"
	"sync"
	"syscall"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/docker/pkg/mount"
)

// Ops defines the interface for keep track of volume driver mounts.
type Ops interface {
	// String representation of the mount table
	String() string
	// Load mount table for all devices that match the prefix. An empty prefix may
	// be provided.
	Load(devPrefix string) error
	// Inspect mount table for specified device. ErrEnoent may be returned.
	Inspect(device string) (Info, error)
	// HasMounts determines returns the number of mounts for the device.
	HasMounts(devPath string)
	// Exists returns true if the device is mounted at specified path.
	// returned if the device does not exists.
	Exists(device, path string) (bool, error)
	// Mount device at mountpoint or increment refcnt if device is already mounted
	// at specified mountpoint.
	Mount(Minor int32, device, path, fs string, flags uintptr, data string) error
	// Unmount device at mountpoint or decrement refcnt. If device has no
	// mountpoints left after this operation, it is removed from the matrix.
	// ErrEnoent is returned if the device or mountpoint for the device is not found.
	Unmount(device, path string) error
}

// DeviceMap map device name to Info
type DeviceMap map[string]*Info

// PathInfo is a reference counted path
type PathInfo struct {
	Path string
	ref  int
}

// Info per device
type Info struct {
	Device     string
	Minor      int
	Mountpoint []PathInfo
	Fs         string
}

// Matrix implements Ops and keeps track of active mounts for volume drivers.
type Matrix struct {
	sync.Mutex
	mounts DeviceMap
}

var (
	// ErrEnoent is returned for a non existent mount point
	ErrEnoent = errors.New("Mountpath is not mounted")
	// ErrEinval is returned is fields for an entry do no match
	// existing fields
	ErrEinval = errors.New("Invalid arguments for mount entry")
)

// New instance of Matrix
func New(devPrefix string) (*Matrix, error) {
	m := &Matrix{
		mounts: make(DeviceMap),
	}
	err := m.Load(devPrefix)
	if err != nil {
		return nil, err
	}
	return m, nil
}

// HasMounts determines returns the number of mounts for the device.
func (m *Matrix) HasMounts(devPath string) int {
	m.Lock()
	defer m.Unlock()

	v, ok := m.mounts[devPath]
	if !ok {
		return 0
	}
	return len(v.Mountpoint)
}

// Exists scans mountpaths for specified device and returns true if path is one of the
// mountpaths. ErrEnoent may be retuned if the device is not found
func (m *Matrix) Exists(devPath string, path string) (bool, error) {
	m.Lock()
	defer m.Unlock()

	v, ok := m.mounts[devPath]
	if !ok {
		return false, ErrEnoent
	}
	for _, p := range v.Mountpoint {
		if p.Path == path {
			return true, nil
		}
	}
	return false, nil
}

// Mount new mountpoint for specified device.
func (m *Matrix) Mount(minor int, device, path, fs string, flags uintptr, data string) error {
	m.Lock()
	defer m.Unlock()

	info, ok := m.mounts[device]
	if !ok {
		info = &Info{
			Device:     device,
			Mountpoint: make([]PathInfo, 8),
			Minor:      minor,
			Fs:         fs,
		}
		m.mounts[device] = info
	}

	// Validate input params
	if fs != info.Fs {
		log.Warnf("%s Existing mountpoint has fs %q cannot change to %q",
			device, info.Fs, fs)
		return ErrEinval
	}

	// Try to find the mountpoint. If it already exists, then increment refcnt
	for _, p := range info.Mountpoint {
		if p.Path == path {
			p.ref++
			return nil
		}
	}
	// The device is not mounted at path, mount it and add to its mountpoints.
	err := syscall.Mount(device, path, fs, flags, data)
	if err != nil {
		return err
	}
	info.Mountpoint = append(info.Mountpoint, PathInfo{Path: path, ref: 1})
	return nil
}

// Unmount device at mountpoint or decrement refcnt. If device has no
// mountpoints left after this operation, it is removed from the matrix.
// ErrEnoent is returned if the device or mountpoint for the device is not found.
func (m *Matrix) Unmount(device, path string) error {
	m.Lock()
	defer m.Unlock()

	info, ok := m.mounts[device]
	if !ok {
		return ErrEnoent
	}
	for i, p := range info.Mountpoint {
		if p.Path == path {
			p.ref--
			// Unmount only if refcnt is 0
			if p.ref == 0 {
				err := syscall.Unmount(path, 0)
				if err != nil {
					return err
				}
				// Blow away this mountpoint.
				info.Mountpoint[i] = info.Mountpoint[len(info.Mountpoint)-1]
				info.Mountpoint = info.Mountpoint[0 : len(info.Mountpoint)-1]
				// If the device has no more mountpoints, remove it from the map
				if len(info.Mountpoint) == 0 {
					delete(m.mounts, device)
				}
			}
			return nil
		}
	}
	return ErrEnoent
}

// String representation of Matrix
func (m *Matrix) String() string {
	return fmt.Sprintf("%#v", *m)
}

// Load mount table
func (m *Matrix) Load(devPrefix string) error {
	info, err := mount.GetMounts()
	if err != nil {
		return err
	}
	for _, v := range info {
		if !strings.HasPrefix(v.Source, devPrefix) {
			continue
		}
		mount, ok := m.mounts[v.Source]
		if !ok {
			mount = &Info{
				Device:     v.Source,
				Fs:         v.Fstype,
				Minor:      v.Minor,
				Mountpoint: make([]PathInfo, 0),
			}
			m.mounts[v.Source] = mount
		}
		// Allow Load to be called multiple times.
		for _, p := range mount.Mountpoint {
			if p.Path == v.Mountpoint {
				continue
			}
		}
		// XXX Reconstruct refs.
		mount.Mountpoint = append(mount.Mountpoint, PathInfo{Path: v.Mountpoint, ref: 1})
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright © 2017 The Kubicorn 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 scp

import (
	"fmt"
	"github.com/kris-nova/kubicorn/cutil/logger"
	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"
	"golang.org/x/crypto/ssh/terminal"
	"io/ioutil"
)

type SecureCopier struct {
	RemoteUser     string
	RemoteAddress  string
	RemotePort     string
	PrivateKeyPath string
}

func NewSecureCopier(remoteUser, remoteAddress, remotePort, privateKeyPath string) *SecureCopier {
	return &SecureCopier{
		RemoteUser: remoteUser,
		RemoteAddress: remoteAddress,
		RemotePort: remotePort,
		PrivateKeyPath: privateKeyPath,
	}
}

func (s *SecureCopier) ReadBytes(remotePath string) ([]byte, error) {
	pemBytes, err := ioutil.ReadFile(s.PrivateKeyPath)
	if err != nil {
		return nil, err
	}
	signer, err := GetSigner(pemBytes)
	if err != nil {
		return nil, err
	}
	auths := []ssh.AuthMethod{
		ssh.PublicKeys(signer),
	}

	sshConfig := &ssh.ClientConfig{
		User:            s.RemoteUser,
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Auth:            auths,
	}
	sshConfig.SetDefaults()
	conn, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s",s.RemoteAddress, s.RemotePort), sshConfig)
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	c, err := sftp.NewClient(conn)
	if err != nil {
		return nil, err
	}
	defer c.Close()
	r, err := c.Open(remotePath)
	if err != nil {
		return nil, err
	}
	defer r.Close()
	bytes, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}
	return bytes, nil
}

func (s *SecureCopier) Write(localPath, remotePath string) error {
	logger.Critical("Write not yet implemented!")
	return nil
}

func GetSigner(pemBytes []byte) (ssh.Signer, error) {
	signerwithoutpassphrase, err := ssh.ParsePrivateKey(pemBytes)
	if err != nil {
		logger.Warning(err.Error())
		fmt.Print("SSH Key Passphrase [none]: ")
		passPhrase, err := terminal.ReadPassword(0)
		if err != nil {
			return nil, err
		}
		signerwithpassphrase, err := ssh.ParsePrivateKeyWithPassphrase(pemBytes, passPhrase)
		if err != nil {
			return nil, err
		} else {
			return signerwithpassphrase, err
		}
	} else {
		return signerwithoutpassphrase, err
	}
}
<commit_msg>scp: make scp use ssh-agent<commit_after>// Copyright © 2017 The Kubicorn 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 scp

import (
	"golang.org/x/crypto/ssh/agent"
	"net"
	"os"
	"fmt"
	"github.com/kris-nova/kubicorn/cutil/logger"
	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"
	"golang.org/x/crypto/ssh/terminal"
	"io/ioutil"
)

type SecureCopier struct {
	RemoteUser     string
	RemoteAddress  string
	RemotePort     string
	PrivateKeyPath string
}

func NewSecureCopier(remoteUser, remoteAddress, remotePort, privateKeyPath string) *SecureCopier {
	return &SecureCopier{
		RemoteUser: remoteUser,
		RemoteAddress: remoteAddress,
		RemotePort: remotePort,
		PrivateKeyPath: privateKeyPath,
	}
}

func (s *SecureCopier) ReadBytes(remotePath string) ([]byte, error) {
	sshConfig := &ssh.ClientConfig{
		User:            s.RemoteUser,
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	agent := sshAgent()
	if agent != nil {
		auths := []ssh.AuthMethod{
			agent,
		}
		sshConfig.Auth = auths
	} else {
		pemBytes, err := ioutil.ReadFile(s.PrivateKeyPath)
		if err != nil {
			return nil, err
		}
		signer, err := GetSigner(pemBytes)
		if err != nil {
			return nil, err
		}
		auths := []ssh.AuthMethod{
			ssh.PublicKeys(signer),
		}
		sshConfig.Auth = auths
	}

	sshConfig.SetDefaults()
	conn, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s",s.RemoteAddress, s.RemotePort), sshConfig)
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	c, err := sftp.NewClient(conn)
	if err != nil {
		return nil, err
	}
	defer c.Close()
	r, err := c.Open(remotePath)
	if err != nil {
		return nil, err
	}
	defer r.Close()
	bytes, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}
	return bytes, nil
}

func (s *SecureCopier) Write(localPath, remotePath string) error {
	logger.Critical("Write not yet implemented!")
	return nil
}

func GetSigner(pemBytes []byte) (ssh.Signer, error) {
	signerwithoutpassphrase, err := ssh.ParsePrivateKey(pemBytes)
	if err != nil {
		logger.Warning(err.Error())
		fmt.Print("SSH Key Passphrase [none]: ")
		fmt.Println("")
		passPhrase, err := terminal.ReadPassword(0)
		if err != nil {
			return nil, err
		}
		signerwithpassphrase, err := ssh.ParsePrivateKeyWithPassphrase(pemBytes, passPhrase)
		if err != nil {
			return nil, err
		} else {
			return signerwithpassphrase, err
		}
	} else {
		return signerwithoutpassphrase, err
	}
}

func sshAgent() ssh.AuthMethod {
	if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
		return ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers)
	}
	return nil
}<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"net/http"

	log "github.com/Sirupsen/logrus"
	"github.com/elazarl/goproxy"
	"gopkg.in/yaml.v2"
)

func main() {
	log.SetLevel(log.DebugLevel)
	log.SetFormatter(&log.TextFormatter{FullTimestamp: true})

	filename := "cuttle.yml"
	bytes, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Errorf("Failed to load configuration from %s.", filename)
		log.Fatal(err)
	}

	var cfg Config
	if err := yaml.Unmarshal(bytes, &cfg); err != nil {
		log.Errorf("Malformed YAML in %s.", filename)
		log.Fatal(err)
	}

	zones := make([]Zone, len(cfg.Zones))
	for i, c := range cfg.Zones {
		zones[i] = *NewZone(c.Host, c.Shared, c.Control, c.Limit)
	}

	// Config proxy.
	proxy := goproxy.NewProxyHttpServer()

	proxy.OnRequest().DoFunc(
		func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
			for _, zone := range zones {
				if !zone.MatchHost(r.URL.Host) {
					continue
				}

				// Acquire permission to forward request to upstream server.
				zone.GetController(r.URL.Host).Acquire()

				// Forward request.
				log.Infof("Main: Forwarding request to %s", r.URL)
				return r, nil
			}

			// Forward request without rate limit.
			log.Warnf("Main: No zone is applied to %s", r.URL)
			log.Infof("Main: Forwarding request to %s", r.URL)
			return r, nil
		})

	log.Fatal(http.ListenAndServe(cfg.Addr, proxy))
}

type Config struct {
	Addr    string

	Zones []ZoneConfig
}

type ZoneConfig struct {
	Host    string
	Shared  bool
	Control string
	Limit   int
}
<commit_msg>Set Addr to ':8123' as default<commit_after>package main

import (
	"io/ioutil"
	"net/http"

	log "github.com/Sirupsen/logrus"
	"github.com/elazarl/goproxy"
	"gopkg.in/yaml.v2"
)

func main() {
	log.SetLevel(log.DebugLevel)
	log.SetFormatter(&log.TextFormatter{FullTimestamp: true})

	filename := "cuttle.yml"
	bytes, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Errorf("Failed to load configuration from %s.", filename)
		log.Fatal(err)
	}

	cfg := Config{Addr: ":8123"}
	if err := yaml.Unmarshal(bytes, &cfg); err != nil {
		log.Errorf("Malformed YAML in %s.", filename)
		log.Fatal(err)
	}

	zones := make([]Zone, len(cfg.Zones))
	for i, c := range cfg.Zones {
		zones[i] = *NewZone(c.Host, c.Shared, c.Control, c.Limit)
	}

	// Config proxy.
	proxy := goproxy.NewProxyHttpServer()

	proxy.OnRequest().DoFunc(
		func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
			for _, zone := range zones {
				if !zone.MatchHost(r.URL.Host) {
					continue
				}

				// Acquire permission to forward request to upstream server.
				zone.GetController(r.URL.Host).Acquire()

				// Forward request.
				log.Infof("Main: Forwarding request to %s", r.URL)
				return r, nil
			}

			// Forward request without rate limit.
			log.Warnf("Main: No zone is applied to %s", r.URL)
			log.Infof("Main: Forwarding request to %s", r.URL)
			return r, nil
		})

	log.Fatal(http.ListenAndServe(cfg.Addr, proxy))
}

type Config struct {
	Addr    string

	Zones []ZoneConfig
}

type ZoneConfig struct {
	Host    string
	Shared  bool
	Control string
	Limit   int
}
<|endoftext|>