<commit_before>// Copyright (c) 2014, Google Inc.  All rights reserved.
//
// 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 tao

// This provides a server stub for LinuxHost's Tao RPC interface. This code is
// (mostly) extremely dull and, ideally, would be generated automatically. The
// only mildly interesting thing it does is hold some state associated with each
// connection, and pass that as a parameter to each server function.

import (
	"errors"
	"fmt"
	"io"
	"net/rpc"

	"github.com/golang/protobuf/proto"
	"github.com/jlmucb/cloudproxy/go/tao/auth"
	"github.com/jlmucb/cloudproxy/go/util/protorpc"
)

// LinuxHostTaoServer is a server stub for LinuxHost's Tao RPC interface.
type LinuxHostTaoServer struct {
	lh    *LinuxHost
	child *LinuxHostChild
}

type linuxHostTaoServerStub LinuxHostTaoServer

// NewLinuxHostTaoServer returns a new server stub for LinuxHost's Tao RPC
// interface.
func NewLinuxHostTaoServer(host *LinuxHost, child *LinuxHostChild) LinuxHostTaoServer {
	return LinuxHostTaoServer{host, child}
}

// Serve listens on sock for new connections and services them.
func (server LinuxHostTaoServer) Serve(conn io.ReadWriteCloser) error {
	s := rpc.NewServer()
	err := s.RegisterName("Tao", linuxHostTaoServerStub(server))
	if err != nil {
		return err
	}
	s.ServeCodec(protorpc.NewServerCodec(conn))
	return nil
}

// GetTaoName is the server stub for Tao.GetTaoName.
func (server linuxHostTaoServerStub) GetTaoName(r *RPCRequest, s *RPCResponse) error {
	s.Data = auth.Marshal(server.lh.GetTaoName(server.child))
	return nil
}

// ExtendTaoName is the server stub for Tao.ExtendTaoName.
func (server linuxHostTaoServerStub) ExtendTaoName(r *RPCRequest, s *RPCResponse) error {
	ext, err := auth.UnmarshalSubPrin(r.Data)
	if err != nil {
		return err
	}
	return server.lh.ExtendTaoName(server.child, ext)
}

// GetRandomBytes is the server stub for Tao.GetRandomBytes.
func (server linuxHostTaoServerStub) GetRandomBytes(r *RPCRequest, s *RPCResponse) error {
	if r.Size == nil || *r.Size <= 0 {
		return newError("invalid size")
	}
	data, err := server.lh.GetRandomBytes(server.child, int(*r.Size))
	s.Data = data
	return err
}

// GetSharedSecret is the server stub for Tao.GetSharedSecret.
func (server linuxHostTaoServerStub) GetSharedSecret(r *RPCRequest, s *RPCResponse) error {
	if r.Size == nil || *r.Size <= 0 {
		return newError("invalid size")
	}
	if r.Policy == nil {
		return newError("missing policy")
	}
	data, err := server.lh.GetSharedSecret(server.child, int(*r.Size), *r.Policy)
	s.Data = data
	return err
}

// Seal is the server stub for Tao.Seal.
func (server linuxHostTaoServerStub) Seal(r *RPCRequest, s *RPCResponse) error {
	if r.Policy == nil {
		return newError("missing policy")
	}
	data, err := server.lh.Seal(server.child, r.Data, *r.Policy)
	s.Data = data
	return err
}

// Unseal is the server stub for Tao.Unseal.
func (server linuxHostTaoServerStub) Unseal(r *RPCRequest, s *RPCResponse) error {
	data, policy, err := server.lh.Unseal(server.child, r.Data)
	s.Data = data
	s.Policy = proto.String(policy)
	return err
}

// Attest is the server stub for Tao.Attest.
func (server linuxHostTaoServerStub) Attest(r *RPCRequest, s *RPCResponse) error {
	stmt, err := auth.UnmarshalForm(r.Data)
	if err != nil {
		return err
	}
	var issuer *auth.Prin
	if r.Issuer != nil {
		p, err := auth.UnmarshalPrin(r.Issuer)
		if err != nil {
			return err
		}
		issuer = &p
	}
	a, err := server.lh.Attest(server.child, issuer, r.Time, r.Expiration, stmt)
	if err != nil {
		return err
	}
	s.Data, err = proto.Marshal(a)
	return err
}

// InitCounter initializes counter.
func (server linuxHostTaoServerStub) InitCounter(r *RPCRequest, s *RPCResponse) error {
	if r.Label == nil ||  r.Counter == nil {
		return errors.New("Label or counter unspecified")
	}
	err := server.lh.InitCounter(server.child, *r.Label, *r.Counter)
	return err
}

// GetCounter gets counter
func (server linuxHostTaoServerStub) GetCounter(r *RPCRequest, s *RPCResponse) error {
	if r.Label == nil {
		return errors.New("Label unspecified")
	}
	c, err := server.lh.GetCounter(server.child, *r.Label)
	if err != nil {
		return err
	}
	s.Counter = &c
	return err
}

// RollbackProtectedSeal does a rollback protected seal
func (server linuxHostTaoServerStub) RollbackProtectedSeal(r *RPCRequest, s *RPCResponse) error {
	fmt.Printf("linuxHostTaoServerStub.RollbackProtectedSeal called %s\n", server.child.ChildSubprin.String()) // REMOVE
	if r.Label == nil {
		return errors.New("Label unspecified")
	}
	if r.Policy == nil {
		return errors.New("Policy unspecified")
	}
	sealed, err := server.lh.RollbackProtectedSeal(server.child, *r.Label, r.Data, *r.Policy)
	if err != nil {
		return err
	}
	s.Data = sealed
	return err
}

// RollbackProtectedUnseal does a rollback protected Unseal
func (server linuxHostTaoServerStub) RollbackProtectedUnseal(r *RPCRequest, s *RPCResponse) error {
	fmt.Printf("linuxHostTaoServerStub.RollbackProtectedUnseal called %s\n", server.child.ChildSubprin.String()) // REMOVE
	if r.Data == nil {
		return errors.New("Data unspecified")
	}
	data, policy, err := server.lh.RollbackProtectedUnseal(server.child, r.Data)
	if err != nil {
		return err
	}
	s.Data = data
	s.Policy = &policy
	return nil
}

<commit_msg>Print on InitCounter and GetCounter entry<commit_after>// Copyright (c) 2014, Google Inc.  All rights reserved.
//
// 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 tao

// This provides a server stub for LinuxHost's Tao RPC interface. This code is
// (mostly) extremely dull and, ideally, would be generated automatically. The
// only mildly interesting thing it does is hold some state associated with each
// connection, and pass that as a parameter to each server function.

import (
	"errors"
	"fmt"
	"io"
	"net/rpc"

	"github.com/golang/protobuf/proto"
	"github.com/jlmucb/cloudproxy/go/tao/auth"
	"github.com/jlmucb/cloudproxy/go/util/protorpc"
)

// LinuxHostTaoServer is a server stub for LinuxHost's Tao RPC interface.
type LinuxHostTaoServer struct {
	lh    *LinuxHost
	child *LinuxHostChild
}

type linuxHostTaoServerStub LinuxHostTaoServer

// NewLinuxHostTaoServer returns a new server stub for LinuxHost's Tao RPC
// interface.
func NewLinuxHostTaoServer(host *LinuxHost, child *LinuxHostChild) LinuxHostTaoServer {
	return LinuxHostTaoServer{host, child}
}

// Serve listens on sock for new connections and services them.
func (server LinuxHostTaoServer) Serve(conn io.ReadWriteCloser) error {
	s := rpc.NewServer()
	err := s.RegisterName("Tao", linuxHostTaoServerStub(server))
	if err != nil {
		return err
	}
	s.ServeCodec(protorpc.NewServerCodec(conn))
	return nil
}

// GetTaoName is the server stub for Tao.GetTaoName.
func (server linuxHostTaoServerStub) GetTaoName(r *RPCRequest, s *RPCResponse) error {
	s.Data = auth.Marshal(server.lh.GetTaoName(server.child))
	return nil
}

// ExtendTaoName is the server stub for Tao.ExtendTaoName.
func (server linuxHostTaoServerStub) ExtendTaoName(r *RPCRequest, s *RPCResponse) error {
	ext, err := auth.UnmarshalSubPrin(r.Data)
	if err != nil {
		return err
	}
	return server.lh.ExtendTaoName(server.child, ext)
}

// GetRandomBytes is the server stub for Tao.GetRandomBytes.
func (server linuxHostTaoServerStub) GetRandomBytes(r *RPCRequest, s *RPCResponse) error {
	if r.Size == nil || *r.Size <= 0 {
		return newError("invalid size")
	}
	data, err := server.lh.GetRandomBytes(server.child, int(*r.Size))
	s.Data = data
	return err
}

// GetSharedSecret is the server stub for Tao.GetSharedSecret.
func (server linuxHostTaoServerStub) GetSharedSecret(r *RPCRequest, s *RPCResponse) error {
	if r.Size == nil || *r.Size <= 0 {
		return newError("invalid size")
	}
	if r.Policy == nil {
		return newError("missing policy")
	}
	data, err := server.lh.GetSharedSecret(server.child, int(*r.Size), *r.Policy)
	s.Data = data
	return err
}

// Seal is the server stub for Tao.Seal.
func (server linuxHostTaoServerStub) Seal(r *RPCRequest, s *RPCResponse) error {
	if r.Policy == nil {
		return newError("missing policy")
	}
	data, err := server.lh.Seal(server.child, r.Data, *r.Policy)
	s.Data = data
	return err
}

// Unseal is the server stub for Tao.Unseal.
func (server linuxHostTaoServerStub) Unseal(r *RPCRequest, s *RPCResponse) error {
	data, policy, err := server.lh.Unseal(server.child, r.Data)
	s.Data = data
	s.Policy = proto.String(policy)
	return err
}

// Attest is the server stub for Tao.Attest.
func (server linuxHostTaoServerStub) Attest(r *RPCRequest, s *RPCResponse) error {
	stmt, err := auth.UnmarshalForm(r.Data)
	if err != nil {
		return err
	}
	var issuer *auth.Prin
	if r.Issuer != nil {
		p, err := auth.UnmarshalPrin(r.Issuer)
		if err != nil {
			return err
		}
		issuer = &p
	}
	a, err := server.lh.Attest(server.child, issuer, r.Time, r.Expiration, stmt)
	if err != nil {
		return err
	}
	s.Data, err = proto.Marshal(a)
	return err
}

// InitCounter initializes counter.
func (server linuxHostTaoServerStub) InitCounter(r *RPCRequest, s *RPCResponse) error {
	fmt.Printf("linuxHostTaoServerStub.InitCounter called %s\n", server.child.ChildSubprin.String()) // REMOVE
	if r.Label == nil ||  r.Counter == nil {
		return errors.New("Label or counter unspecified")
	}
	err := server.lh.InitCounter(server.child, *r.Label, *r.Counter)
	return err
}

// GetCounter gets counter
func (server linuxHostTaoServerStub) GetCounter(r *RPCRequest, s *RPCResponse) error {
	fmt.Printf("linuxHostTaoServerStub.GetCounter called %s\n", server.child.ChildSubprin.String()) // REMOVE
	if r.Label == nil {
		return errors.New("Label unspecified")
	}
	c, err := server.lh.GetCounter(server.child, *r.Label)
	if err != nil {
		return err
	}
	s.Counter = &c
	return err
}

// RollbackProtectedSeal does a rollback protected seal
func (server linuxHostTaoServerStub) RollbackProtectedSeal(r *RPCRequest, s *RPCResponse) error {
	fmt.Printf("linuxHostTaoServerStub.RollbackProtectedSeal called %s\n", server.child.ChildSubprin.String()) // REMOVE
	if r.Label == nil {
		return errors.New("Label unspecified")
	}
	if r.Policy == nil {
		return errors.New("Policy unspecified")
	}
	sealed, err := server.lh.RollbackProtectedSeal(server.child, *r.Label, r.Data, *r.Policy)
	if err != nil {
		return err
	}
	s.Data = sealed
	return err
}

// RollbackProtectedUnseal does a rollback protected Unseal
func (server linuxHostTaoServerStub) RollbackProtectedUnseal(r *RPCRequest, s *RPCResponse) error {
	fmt.Printf("linuxHostTaoServerStub.RollbackProtectedUnseal called %s\n", server.child.ChildSubprin.String()) // REMOVE
	if r.Data == nil {
		return errors.New("Data unspecified")
	}
	data, policy, err := server.lh.RollbackProtectedUnseal(server.child, r.Data)
	if err != nil {
		return err
	}
	s.Data = data
	s.Policy = &policy
	return nil
}

<|endoftext|>


<commit_before>// +build linux

package namespaces

import (
	"encoding/json"
	"io"
	"os"
	"os/exec"
	"syscall"

	"github.com/docker/libcontainer"
	"github.com/docker/libcontainer/cgroups"
	"github.com/docker/libcontainer/cgroups/fs"
	"github.com/docker/libcontainer/cgroups/systemd"
	"github.com/docker/libcontainer/network"
	"github.com/docker/libcontainer/system"
)

// TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work.
// Move this to libcontainer package.
// Exec performs setup outside of a namespace so that a container can be
// executed.  Exec is a high level function for working with container namespaces.
func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Writer, console, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) {
	var err error

	// create a pipe so that we can syncronize with the namespaced process and
	// pass the state and configuration to the child process
	parent, child, err := newInitPipe()
	if err != nil {
		return -1, err
	}
	defer parent.Close()

	command := createCommand(container, console, dataPath, os.Args[0], child, args)
	// Note: these are only used in non-tty mode
	// if there is a tty for the container it will be opened within the namespace and the
	// fds will be duped to stdin, stdiout, and stderr
	command.Stdin = stdin
	command.Stdout = stdout
	command.Stderr = stderr

	if err := command.Start(); err != nil {
		child.Close()
		return -1, err
	}
	child.Close()

	terminate := func(terr error) (int, error) {
		// TODO: log the errors for kill and wait
		command.Process.Kill()
		command.Wait()
		return -1, terr
	}

	started, err := system.GetProcessStartTime(command.Process.Pid)
	if err != nil {
		return terminate(err)
	}

	// Do this before syncing with child so that no children
	// can escape the cgroup
	cgroupPaths, err := SetupCgroups(container, command.Process.Pid)
	if err != nil {
		return terminate(err)
	}
	defer cgroups.RemovePaths(cgroupPaths)

	var networkState network.NetworkState
	if err := InitializeNetworking(container, command.Process.Pid, &networkState); err != nil {
		return terminate(err)
	}
	// send the state to the container's init process then shutdown writes for the parent
	if err := json.NewEncoder(parent).Encode(networkState); err != nil {
		return terminate(err)
	}
	// shutdown writes for the parent side of the pipe
	if err := syscall.Shutdown(int(parent.Fd()), syscall.SHUT_WR); err != nil {
		return terminate(err)
	}

	state := &libcontainer.State{
		InitPid:       command.Process.Pid,
		InitStartTime: started,
		NetworkState:  networkState,
		CgroupPaths:   cgroupPaths,
	}

	if err := libcontainer.SaveState(dataPath, state); err != nil {
		return terminate(err)
	}
	defer libcontainer.DeleteState(dataPath)

	// wait for the child process to fully complete and receive an error message
	// if one was encoutered
	var ierr *initError
	if err := json.NewDecoder(parent).Decode(&ierr); err != nil && err != io.EOF {
		return terminate(err)
	}
	if ierr != nil {
		return terminate(ierr)
	}

	if startCallback != nil {
		startCallback()
	}

	if err := command.Wait(); err != nil {
		if _, ok := err.(*exec.ExitError); !ok {
			return -1, err
		}
	}
	if !container.Namespaces.Contains(libcontainer.NEWPID) {
		killAllPids(container)
	}
	return command.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(), nil
}

// killAllPids itterates over all of the container's processes
// sending a SIGKILL to each process.
func killAllPids(container *libcontainer.Config) error {
	var (
		procs   []*os.Process
		freeze  = fs.Freeze
		getPids = fs.GetPids
	)
	if systemd.UseSystemd() {
		freeze = systemd.Freeze
		getPids = systemd.GetPids
	}
	freeze(container.Cgroups, cgroups.Frozen)
	pids, err := getPids(container.Cgroups)
	if err != nil {
		return err
	}
	for _, pid := range pids {
		// TODO: log err without aborting if we are unable to find
		// a single PID
		if p, err := os.FindProcess(pid); err == nil {
			procs = append(procs, p)
			p.Kill()
		}
	}
	freeze(container.Cgroups, cgroups.Thawed)
	for _, p := range procs {
		p.Wait()
	}
	return err
}

// DefaultCreateCommand will return an exec.Cmd with the Cloneflags set to the proper namespaces
// defined on the container's configuration and use the current binary as the init with the
// args provided
//
// console: the /dev/console to setup inside the container
// init: the program executed inside the namespaces
// root: the path to the container json file and information
// pipe: sync pipe to synchronize the parent and child processes
// args: the arguments to pass to the container to run as the user's program
func DefaultCreateCommand(container *libcontainer.Config, console, dataPath, init string, pipe *os.File, args []string) *exec.Cmd {
	// get our binary name from arg0 so we can always reexec ourself
	env := []string{
		"console=" + console,
		"pipe=3",
		"data_path=" + dataPath,
	}

	command := exec.Command(init, append([]string{"init", "--"}, args...)...)
	// make sure the process is executed inside the context of the rootfs
	command.Dir = container.RootFs
	command.Env = append(os.Environ(), env...)

	if command.SysProcAttr == nil {
		command.SysProcAttr = &syscall.SysProcAttr{}
	}
	command.SysProcAttr.Cloneflags = uintptr(GetNamespaceFlags(container.Namespaces))

	command.SysProcAttr.Pdeathsig = syscall.SIGKILL
	command.ExtraFiles = []*os.File{pipe}

	return command
}

// SetupCgroups applies the cgroup restrictions to the process running in the container based
// on the container's configuration
func SetupCgroups(container *libcontainer.Config, nspid int) (map[string]string, error) {
	if container.Cgroups != nil {
		c := container.Cgroups
		if systemd.UseSystemd() {
			return systemd.Apply(c, nspid)
		}
		return fs.Apply(c, nspid)
	}
	return map[string]string{}, nil
}

// InitializeNetworking creates the container's network stack outside of the namespace and moves
// interfaces into the container's net namespaces if necessary
func InitializeNetworking(container *libcontainer.Config, nspid int, networkState *network.NetworkState) error {
	for _, config := range container.Networks {
		strategy, err := network.GetStrategy(config.Type)
		if err != nil {
			return err
		}
		if err := strategy.Create((*network.Network)(config), nspid, networkState); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Fix exit codes when dying on a signal<commit_after>// +build linux

package namespaces

import (
	"encoding/json"
	"io"
	"os"
	"os/exec"
	"syscall"

	"github.com/docker/libcontainer"
	"github.com/docker/libcontainer/cgroups"
	"github.com/docker/libcontainer/cgroups/fs"
	"github.com/docker/libcontainer/cgroups/systemd"
	"github.com/docker/libcontainer/network"
	"github.com/docker/libcontainer/system"
)

const (
	EXIT_SIGNAL_OFFSET = 128
)

// TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work.
// Move this to libcontainer package.
// Exec performs setup outside of a namespace so that a container can be
// executed.  Exec is a high level function for working with container namespaces.
func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Writer, console, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) {
	var err error

	// create a pipe so that we can syncronize with the namespaced process and
	// pass the state and configuration to the child process
	parent, child, err := newInitPipe()
	if err != nil {
		return -1, err
	}
	defer parent.Close()

	command := createCommand(container, console, dataPath, os.Args[0], child, args)
	// Note: these are only used in non-tty mode
	// if there is a tty for the container it will be opened within the namespace and the
	// fds will be duped to stdin, stdiout, and stderr
	command.Stdin = stdin
	command.Stdout = stdout
	command.Stderr = stderr

	if err := command.Start(); err != nil {
		child.Close()
		return -1, err
	}
	child.Close()

	terminate := func(terr error) (int, error) {
		// TODO: log the errors for kill and wait
		command.Process.Kill()
		command.Wait()
		return -1, terr
	}

	started, err := system.GetProcessStartTime(command.Process.Pid)
	if err != nil {
		return terminate(err)
	}

	// Do this before syncing with child so that no children
	// can escape the cgroup
	cgroupPaths, err := SetupCgroups(container, command.Process.Pid)
	if err != nil {
		return terminate(err)
	}
	defer cgroups.RemovePaths(cgroupPaths)

	var networkState network.NetworkState
	if err := InitializeNetworking(container, command.Process.Pid, &networkState); err != nil {
		return terminate(err)
	}
	// send the state to the container's init process then shutdown writes for the parent
	if err := json.NewEncoder(parent).Encode(networkState); err != nil {
		return terminate(err)
	}
	// shutdown writes for the parent side of the pipe
	if err := syscall.Shutdown(int(parent.Fd()), syscall.SHUT_WR); err != nil {
		return terminate(err)
	}

	state := &libcontainer.State{
		InitPid:       command.Process.Pid,
		InitStartTime: started,
		NetworkState:  networkState,
		CgroupPaths:   cgroupPaths,
	}

	if err := libcontainer.SaveState(dataPath, state); err != nil {
		return terminate(err)
	}
	defer libcontainer.DeleteState(dataPath)

	// wait for the child process to fully complete and receive an error message
	// if one was encoutered
	var ierr *initError
	if err := json.NewDecoder(parent).Decode(&ierr); err != nil && err != io.EOF {
		return terminate(err)
	}
	if ierr != nil {
		return terminate(ierr)
	}

	if startCallback != nil {
		startCallback()
	}

	if err := command.Wait(); err != nil {
		if _, ok := err.(*exec.ExitError); !ok {
			return -1, err
		}
	}
	if !container.Namespaces.Contains(libcontainer.NEWPID) {
		killAllPids(container)
	}

	waitStatus := command.ProcessState.Sys().(syscall.WaitStatus)
	if waitStatus.Signaled() {
		return EXIT_SIGNAL_OFFSET + int(waitStatus.Signal()), nil
	}
	return waitStatus.ExitStatus(), nil
}

// killAllPids itterates over all of the container's processes
// sending a SIGKILL to each process.
func killAllPids(container *libcontainer.Config) error {
	var (
		procs   []*os.Process
		freeze  = fs.Freeze
		getPids = fs.GetPids
	)
	if systemd.UseSystemd() {
		freeze = systemd.Freeze
		getPids = systemd.GetPids
	}
	freeze(container.Cgroups, cgroups.Frozen)
	pids, err := getPids(container.Cgroups)
	if err != nil {
		return err
	}
	for _, pid := range pids {
		// TODO: log err without aborting if we are unable to find
		// a single PID
		if p, err := os.FindProcess(pid); err == nil {
			procs = append(procs, p)
			p.Kill()
		}
	}
	freeze(container.Cgroups, cgroups.Thawed)
	for _, p := range procs {
		p.Wait()
	}
	return err
}

// DefaultCreateCommand will return an exec.Cmd with the Cloneflags set to the proper namespaces
// defined on the container's configuration and use the current binary as the init with the
// args provided
//
// console: the /dev/console to setup inside the container
// init: the program executed inside the namespaces
// root: the path to the container json file and information
// pipe: sync pipe to synchronize the parent and child processes
// args: the arguments to pass to the container to run as the user's program
func DefaultCreateCommand(container *libcontainer.Config, console, dataPath, init string, pipe *os.File, args []string) *exec.Cmd {
	// get our binary name from arg0 so we can always reexec ourself
	env := []string{
		"console=" + console,
		"pipe=3",
		"data_path=" + dataPath,
	}

	command := exec.Command(init, append([]string{"init", "--"}, args...)...)
	// make sure the process is executed inside the context of the rootfs
	command.Dir = container.RootFs
	command.Env = append(os.Environ(), env...)

	if command.SysProcAttr == nil {
		command.SysProcAttr = &syscall.SysProcAttr{}
	}
	command.SysProcAttr.Cloneflags = uintptr(GetNamespaceFlags(container.Namespaces))

	command.SysProcAttr.Pdeathsig = syscall.SIGKILL
	command.ExtraFiles = []*os.File{pipe}

	return command
}

// SetupCgroups applies the cgroup restrictions to the process running in the container based
// on the container's configuration
func SetupCgroups(container *libcontainer.Config, nspid int) (map[string]string, error) {
	if container.Cgroups != nil {
		c := container.Cgroups
		if systemd.UseSystemd() {
			return systemd.Apply(c, nspid)
		}
		return fs.Apply(c, nspid)
	}
	return map[string]string{}, nil
}

// InitializeNetworking creates the container's network stack outside of the namespace and moves
// interfaces into the container's net namespaces if necessary
func InitializeNetworking(container *libcontainer.Config, nspid int, networkState *network.NetworkState) error {
	for _, config := range container.Networks {
		strategy, err := network.GetStrategy(config.Type)
		if err != nil {
			return err
		}
		if err := strategy.Create((*network.Network)(config), nspid, networkState); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package namesys

import (
	"context"
	"strings"
	"time"
	"fmt"

	pb "github.com/ipfs/go-ipfs/namesys/pb"
	path "github.com/ipfs/go-ipfs/path"
	logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
	lru "gx/ipfs/QmVYxfoJQiZijTgPNHCHgHELvQpbsJNTg6Crmc3dQkj3yy/golang-lru"
	mh "gx/ipfs/QmYDds3421prZgqKbLpEK7T9Aa2eVdQ7o3YarX1LVLdP2J/go-multihash"
	proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
	u "gx/ipfs/Qmb912gdngC1UWwTkhuW8knyRbcWeu5kqkxBpveLmW8bSr/go-ipfs-util"
	routing "gx/ipfs/QmbkGVaN9W6RYJK4Ws5FvMKXKDqdRQ5snhtaa92qP6L8eU/go-libp2p-routing"
	cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
	ds "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore"
	ci "gx/ipfs/QmfWDLQjGjVe4fr5CoztYW2DYYjRysMJrFe1RCsXLPTf46/go-libp2p-crypto"
)

var log = logging.Logger("namesys")
var cachePrefix = "IPNSPERSISENTCACHE_"

// routingResolver implements NSResolver for the main IPFS SFS-like naming
type routingResolver struct {
	routing routing.ValueStore
	datastore ds.Datastore
	cache *lru.Cache
}

func (r *routingResolver) cacheGet(name string) (path.Path, bool) {
	if r.cache == nil {
		return "", false
	}

	ientry, ok := r.cache.Get(name)
	if !ok {
		return "", false
	}

	entry, ok := ientry.(cacheEntry)
	if !ok {
		// should never happen, purely for sanity
		log.Panicf("unexpected type %T in cache for %q.", ientry, name)
	}

	if time.Now().Before(entry.eol) {
		return entry.val, true
	}

	r.cache.Remove(name)

	return "", false
}

func (r *routingResolver) cacheSet(name string, val path.Path, rec *pb.IpnsEntry) {
	if r.cache == nil {
		return
	}

	// if completely unspecified, just use one minute
	ttl := DefaultResolverCacheTTL
	if rec.Ttl != nil {
		recttl := time.Duration(rec.GetTtl())
		if recttl >= 0 {
			ttl = recttl
		}
	}

	cacheTil := time.Now().Add(ttl)
	eol, ok := checkEOL(rec)
	if ok && eol.Before(cacheTil) {
		cacheTil = eol
	}

	r.cache.Add(name, cacheEntry{
		val: val,
		eol: cacheTil,
	})
}

type cacheEntry struct {
	val path.Path
	eol time.Time
}

// NewRoutingResolver constructs a name resolver using the IPFS Routing system
// to implement SFS-like naming on top.
// cachesize is the limit of the number of entries in the lru cache. Setting it
// to '0' will disable caching.
func NewRoutingResolver(route routing.ValueStore, cachesize int, ds ds.Datastore) *routingResolver {
	if route == nil {
		panic("attempt to create resolver with nil routing system")
	}

	var cache *lru.Cache
	if cachesize > 0 {
		cache, _ = lru.New(cachesize)
	}

	return &routingResolver{
		routing:   route,
		cache:     cache,
		datastore: ds,
	}
}

// Resolve implements Resolver.
func (r *routingResolver) Resolve(ctx context.Context, name string) (path.Path, error) {
	return r.ResolveN(ctx, name, DefaultDepthLimit)
}

// ResolveN implements Resolver.
func (r *routingResolver) ResolveN(ctx context.Context, name string, depth int) (path.Path, error) {
	return resolve(ctx, r, name, depth, "/ipns/")
}

// resolveOnce implements resolver. Uses the IPFS routing system to
// resolve SFS-like names.
func (r *routingResolver) resolveOnce(ctx context.Context, name string) (path.Path, error) {
	log.Debugf("RoutingResolve: '%s'", name)
	cached, ok := r.cacheGet(name)
	if ok {
		return cached, nil
	}

	name = strings.TrimPrefix(name, "/ipns/")
	hash, err := mh.FromB58String(name)
	if err != nil {
		// name should be a multihash. if it isn't, error out here.
		log.Warningf("RoutingResolve: bad input hash: [%s]\n", name)
		return "", err
	}

	// use the routing system to get the name.
	// /ipns/<name>
	h := []byte("/ipns/" + string(hash))

	var entry *pb.IpnsEntry
	var pubkey ci.PubKey
	var val []byte

	resp := make(chan error, 2)
	go func() {
		ipnsKey := string(h)
		val, err := r.routing.GetValue(ctx, ipnsKey)
		if err != nil {
			log.Warning("RoutingResolve get failed.")
			resp <- err
			return
		}

		entry = new(pb.IpnsEntry)
		err = proto.Unmarshal(val, entry)
		if err != nil {
			resp <- err
			return
		}

		resp <- nil
	}()

	go func() {
		// name should be a public key retrievable from ipfs
		pubk, err := routing.GetPublicKey(r.routing, ctx, hash)
		if err != nil {
			resp <- err
			return
		}

		pubkey = pubk
		resp <- nil
	}()

	for i := 0; i < 2; i++ {
		err = <-resp
		if err != nil {
			val, err := r.datastore.Get(ds.NewKey(cachePrefix + name))
			if err != nil {
				return "", err
			}
			entry := new(pb.IpnsEntry)
			err = proto.Unmarshal(val.([]byte), entry)
			if err != nil {
				return "", err
			}
			p, err := path.ParsePath(string(entry.GetValue()))
			if err != nil {
				return "", err
			}
			return p, nil
		}
	}

	// check sig with pk
	if ok, err := pubkey.Verify(ipnsEntryDataForSig(entry), entry.GetSignature()); err != nil || !ok {
		return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pubkey)
	}

	// ok sig checks out. this is a valid name.

	// check for old style record:
	valh, err := mh.Cast(entry.GetValue())
	if err != nil {
		// Not a multihash, probably a new record
		p, err := path.ParsePath(string(entry.GetValue()))
		if err != nil {
			return "", err
		}

		r.cacheSet(name, p, entry)
		go r.datastore.Put(ds.NewKey(cachePrefix + name), val)
		return p, nil
	} else {
		// Its an old style multihash record
		log.Warning("Detected old style multihash record")
		p := path.FromCid(cid.NewCidV0(valh))
		r.cacheSet(name, p, entry)
		go r.datastore.Put(ds.NewKey(cachePrefix + name), val)
		return p, nil
	}
}

func checkEOL(e *pb.IpnsEntry) (time.Time, bool) {
	if e.GetValidityType() == pb.IpnsEntry_EOL {
		eol, err := u.ParseRFC3339(string(e.GetValidity()))
		if err != nil {
			return time.Time{}, false
		}
		return eol, true
	}
	return time.Time{}, false
}
<commit_msg>Fix bug saving ipns record to database<commit_after>package namesys

import (
	"context"
	"strings"
	"time"
	"fmt"

	pb "github.com/ipfs/go-ipfs/namesys/pb"
	path "github.com/ipfs/go-ipfs/path"
	logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
	lru "gx/ipfs/QmVYxfoJQiZijTgPNHCHgHELvQpbsJNTg6Crmc3dQkj3yy/golang-lru"
	mh "gx/ipfs/QmYDds3421prZgqKbLpEK7T9Aa2eVdQ7o3YarX1LVLdP2J/go-multihash"
	proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
	u "gx/ipfs/Qmb912gdngC1UWwTkhuW8knyRbcWeu5kqkxBpveLmW8bSr/go-ipfs-util"
	routing "gx/ipfs/QmbkGVaN9W6RYJK4Ws5FvMKXKDqdRQ5snhtaa92qP6L8eU/go-libp2p-routing"
	cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
	ds "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore"
	ci "gx/ipfs/QmfWDLQjGjVe4fr5CoztYW2DYYjRysMJrFe1RCsXLPTf46/go-libp2p-crypto"
)

var log = logging.Logger("namesys")
var cachePrefix = "IPNSPERSISENTCACHE_"

// routingResolver implements NSResolver for the main IPFS SFS-like naming
type routingResolver struct {
	routing routing.ValueStore
	datastore ds.Datastore
	cache *lru.Cache
}

func (r *routingResolver) cacheGet(name string) (path.Path, bool) {
	if r.cache == nil {
		return "", false
	}

	ientry, ok := r.cache.Get(name)
	if !ok {
		return "", false
	}

	entry, ok := ientry.(cacheEntry)
	if !ok {
		// should never happen, purely for sanity
		log.Panicf("unexpected type %T in cache for %q.", ientry, name)
	}

	if time.Now().Before(entry.eol) {
		return entry.val, true
	}

	r.cache.Remove(name)

	return "", false
}

func (r *routingResolver) cacheSet(name string, val path.Path, rec *pb.IpnsEntry) {
	if r.cache == nil {
		return
	}

	// if completely unspecified, just use one minute
	ttl := DefaultResolverCacheTTL
	if rec.Ttl != nil {
		recttl := time.Duration(rec.GetTtl())
		if recttl >= 0 {
			ttl = recttl
		}
	}

	cacheTil := time.Now().Add(ttl)
	eol, ok := checkEOL(rec)
	if ok && eol.Before(cacheTil) {
		cacheTil = eol
	}

	r.cache.Add(name, cacheEntry{
		val: val,
		eol: cacheTil,
	})
}

type cacheEntry struct {
	val path.Path
	eol time.Time
}

// NewRoutingResolver constructs a name resolver using the IPFS Routing system
// to implement SFS-like naming on top.
// cachesize is the limit of the number of entries in the lru cache. Setting it
// to '0' will disable caching.
func NewRoutingResolver(route routing.ValueStore, cachesize int, ds ds.Datastore) *routingResolver {
	if route == nil {
		panic("attempt to create resolver with nil routing system")
	}

	var cache *lru.Cache
	if cachesize > 0 {
		cache, _ = lru.New(cachesize)
	}

	return &routingResolver{
		routing:   route,
		cache:     cache,
		datastore: ds,
	}
}

// Resolve implements Resolver.
func (r *routingResolver) Resolve(ctx context.Context, name string) (path.Path, error) {
	return r.ResolveN(ctx, name, DefaultDepthLimit)
}

// ResolveN implements Resolver.
func (r *routingResolver) ResolveN(ctx context.Context, name string, depth int) (path.Path, error) {
	return resolve(ctx, r, name, depth, "/ipns/")
}

// resolveOnce implements resolver. Uses the IPFS routing system to
// resolve SFS-like names.
func (r *routingResolver) resolveOnce(ctx context.Context, name string) (path.Path, error) {
	log.Debugf("RoutingResolve: '%s'", name)
	cached, ok := r.cacheGet(name)
	if ok {
		return cached, nil
	}

	name = strings.TrimPrefix(name, "/ipns/")
	hash, err := mh.FromB58String(name)
	if err != nil {
		// name should be a multihash. if it isn't, error out here.
		log.Warningf("RoutingResolve: bad input hash: [%s]\n", name)
		return "", err
	}

	// use the routing system to get the name.
	// /ipns/<name>
	h := []byte("/ipns/" + string(hash))

	var entry *pb.IpnsEntry
	var pubkey ci.PubKey
	var val []byte

	resp := make(chan error, 2)
	go func() {
		ipnsKey := string(h)
		val, err = r.routing.GetValue(ctx, ipnsKey)
		if err != nil {
			log.Warning("RoutingResolve get failed.")
			resp <- err
			return
		}

		entry = new(pb.IpnsEntry)
		err = proto.Unmarshal(val, entry)
		if err != nil {
			resp <- err
			return
		}

		resp <- nil
	}()

	go func() {
		// name should be a public key retrievable from ipfs
		pubk, err := routing.GetPublicKey(r.routing, ctx, hash)
		if err != nil {
			resp <- err
			return
		}

		pubkey = pubk
		resp <- nil
	}()

	for i := 0; i < 2; i++ {
		err = <-resp
		if err != nil {
			val, err := r.datastore.Get(ds.NewKey(cachePrefix + name))
			if err != nil {
				return "", err
			}
			entry := new(pb.IpnsEntry)
			err = proto.Unmarshal(val.([]byte), entry)
			if err != nil {
				return "", err
			}
			p, err := path.ParsePath(string(entry.GetValue()))
			if err != nil {
				return "", err
			}
			return p, nil
		}
	}

	// check sig with pk
	if ok, err := pubkey.Verify(ipnsEntryDataForSig(entry), entry.GetSignature()); err != nil || !ok {
		return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pubkey)
	}

	// ok sig checks out. this is a valid name.

	// check for old style record:
	valh, err := mh.Cast(entry.GetValue())
	if err != nil {
		// Not a multihash, probably a new record
		p, err := path.ParsePath(string(entry.GetValue()))
		if err != nil {
			return "", err
		}

		r.cacheSet(name, p, entry)
		go r.datastore.Put(ds.NewKey(cachePrefix + name), val)
		return p, nil
	} else {
		// Its an old style multihash record
		log.Warning("Detected old style multihash record")
		p := path.FromCid(cid.NewCidV0(valh))
		r.cacheSet(name, p, entry)
		go r.datastore.Put(ds.NewKey(cachePrefix + name), val)
		return p, nil
	}
}

func checkEOL(e *pb.IpnsEntry) (time.Time, bool) {
	if e.GetValidityType() == pb.IpnsEntry_EOL {
		eol, err := u.ParseRFC3339(string(e.GetValidity()))
		if err != nil {
			return time.Time{}, false
		}
		return eol, true
	}
	return time.Time{}, false
}
<|endoftext|>


<commit_before>package dind

import (
	"crypto/tls"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/davecgh/go-spew/spew"
	"github.com/docker/machine/libmachine/drivers"
	"github.com/docker/machine/libmachine/mcnflag"
	"github.com/docker/machine/libmachine/ssh"
	"github.com/docker/machine/libmachine/state"
	"github.com/samalba/dockerclient"
)

type Driver struct {
	*drivers.BaseDriver
	Id            string
	ContainerHost string
	DockerHost    string
	CertPath      string
	BeingCreated  bool
}

func NewDriver(hostName, artifactPath string) Driver {
	return Driver{
		BaseDriver: &drivers.BaseDriver{
			MachineName:  hostName,
			ArtifactPath: artifactPath,
		},
	}
}

func (d *Driver) newDockerClient() (*dockerclient.DockerClient, error) {
	if d.DockerHost == "" {
		d.DockerHost = os.Getenv("DOCKER_HOST")
	}

	if d.CertPath == "" {
		d.CertPath = os.Getenv("DOCKER_CERT_PATH")
	}

	tlsc := &tls.Config{}

	cert, err := tls.LoadX509KeyPair(filepath.Join(d.CertPath, "cert.pem"), filepath.Join(d.CertPath, "key.pem"))
	if err != nil {
		return nil, fmt.Errorf("Error loading x509 key pair: %s", err)
	}

	tlsc.Certificates = append(tlsc.Certificates, cert)
	tlsc.InsecureSkipVerify = true

	dc, err := dockerclient.NewDockerClient(d.DockerHost, tlsc)
	if err != nil {
		return nil, fmt.Errorf("Error getting Docker Client: %s", err)
	}

	return dc, nil
}

func (d *Driver) GetCreateFlags() []mcnflag.Flag {
	return []mcnflag.Flag{}
}

func (d *Driver) Create() error {
	d.BeingCreated = true

	dc, err := d.newDockerClient()
	if err != nil {
		return err
	}

	u, err := url.Parse(os.Getenv("DOCKER_HOST"))
	if err != nil {
		return fmt.Errorf("Error parsing URL from DOCKER_HOST: %s", err)
	}

	d.ContainerHost = strings.Split(u.Host, ":")[0]

	containerConfig := &dockerclient.ContainerConfig{
		Image: "nathanleclaire/docker-machine-dind",
		HostConfig: dockerclient.HostConfig{
			PublishAllPorts: true,
			Privileged:      true,
		},
	}

	id, err := dc.CreateContainer(containerConfig, d.MachineName)
	if err != nil {
		return fmt.Errorf("Error creating container: %s", err)
	}

	d.Id = id

	if err := d.Start(); err != nil {
		return err
	}

	if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil {
		return err
	}

	f, err := os.Open(d.GetSSHKeyPath() + ".pub")
	if err != nil {
		return fmt.Errorf("Error opening pub key file: %s", err)
	}

	pubKey, err := ioutil.ReadAll(f)
	if err != nil {
		return fmt.Errorf("Error reading from pub key file: %s", err)
	}

	execConfig := &dockerclient.ExecConfig{
		Cmd:       []string{"sh", "-c", fmt.Sprintf("echo %q >/root/.ssh/authorized_keys", strings.TrimSpace(string(pubKey)))},
		Container: d.Id,
	}

	spew.Dump(execConfig)

	execId, err := dc.ExecCreate(execConfig)
	if err != nil {
		return fmt.Errorf("Error creating exec: %s", err)
	}

	if err := dc.ExecStart(execId, execConfig); err != nil {
		return fmt.Errorf("Error starting exec: %s", err)
	}

	return nil
}

func (d *Driver) DriverName() string {
	return "dind"
}

func (d *Driver) GetIP() (string, error) {
	return d.ContainerHost, nil
}

func (d *Driver) GetMachineName() string {
	return d.MachineName
}

func (d *Driver) GetSSHHostname() (string, error) {
	return d.ContainerHost, nil
}

func (d *Driver) getExposedPort(containerPort string) (int, error) {
	dc, err := d.newDockerClient()
	if err != nil {
		return 0, err
	}

	info, err := dc.InspectContainer(d.Id)
	if err != nil {
		return 0, fmt.Errorf("Error inspecting container: %s", err)
	}

	exposedPort, err := strconv.Atoi(info.NetworkSettings.Ports[fmt.Sprintf("%s/tcp", containerPort)][0].HostPort)
	if err != nil {
		return 0, fmt.Errorf("Error parsing host port to int: %s")
	}

	return exposedPort, nil
}

func (d *Driver) GetSSHPort() (int, error) {
	return d.getExposedPort("22")
}

func (d *Driver) GetSSHUsername() string {
	return "root"
}

func (d *Driver) GetURL() (string, error) {
	if d.BeingCreated {
		// HACK: First time on creation, trick provisioning into using 2376 for the URL.
		d.BeingCreated = false
		return fmt.Sprintf("tcp://%s:2376", d.ContainerHost), nil
	}
	dockerPort, err := d.getExposedPort("2376")
	if err != nil {
		return "", fmt.Errorf("Error trying to get exposed port: %s", err)
	}
	return fmt.Sprintf("tcp://%s:%d", d.ContainerHost, dockerPort), nil
}

func (d *Driver) GetState() (state.State, error) {
	dc, err := d.newDockerClient()
	if err != nil {
		return state.Error, err
	}

	info, err := dc.InspectContainer(d.Id)
	if err != nil {
		return state.Error, fmt.Errorf("Error inspecting container: %s", err)
	}

	if info.State.Running {
		return state.Running, nil
	}

	return state.Stopped, nil
}

func (d *Driver) Kill() error {
	return nil
}

func (d *Driver) PreCreateCheck() error {
	return nil
}

func (d *Driver) Remove() error {
	dc, err := d.newDockerClient()
	if err != nil {
		return err
	}

	return dc.RemoveContainer(d.Id, true, true)
}

func (d *Driver) Restart() error {
	return nil
}

func (d *Driver) SetConfigFromFlags(opts drivers.DriverOptions) error {
	spew.Dump(opts)
	return nil
}

func (d *Driver) Start() error {
	dc, err := d.newDockerClient()
	if err != nil {
		return err
	}

	return dc.StartContainer(d.Id, nil)
}

func (d *Driver) Stop() error {
	return nil
}
<commit_msg>Add some new features to driver<commit_after>package dind

import (
	"crypto/tls"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/davecgh/go-spew/spew"
	"github.com/docker/machine/libmachine/drivers"
	"github.com/docker/machine/libmachine/mcnflag"
	"github.com/docker/machine/libmachine/ssh"
	"github.com/docker/machine/libmachine/state"
	"github.com/samalba/dockerclient"
)

type Driver struct {
	*drivers.BaseDriver
	Id            string
	ContainerHost string
	DindImage     string
	DockerHost    string
	CertPath      string
	BeingCreated  bool
}

func NewDriver(hostName, artifactPath string) Driver {
	return Driver{
		BaseDriver: &drivers.BaseDriver{
			MachineName:  hostName,
			ArtifactPath: artifactPath,
		},
	}
}

func (d *Driver) newDockerClient() (*dockerclient.DockerClient, error) {
	if d.DockerHost == "" {
		d.DockerHost = os.Getenv("DOCKER_HOST")
	}

	if d.CertPath == "" {
		d.CertPath = os.Getenv("DOCKER_CERT_PATH")
	}

	tlsc := &tls.Config{}

	cert, err := tls.LoadX509KeyPair(filepath.Join(d.CertPath, "cert.pem"), filepath.Join(d.CertPath, "key.pem"))
	if err != nil {
		return nil, fmt.Errorf("Error loading x509 key pair: %s", err)
	}

	tlsc.Certificates = append(tlsc.Certificates, cert)
	tlsc.InsecureSkipVerify = true

	dc, err := dockerclient.NewDockerClient(d.DockerHost, tlsc)
	if err != nil {
		return nil, fmt.Errorf("Error getting Docker Client: %s", err)
	}

	return dc, nil
}

func (d *Driver) GetCreateFlags() []mcnflag.Flag {
	return []mcnflag.Flag{
		mcnflag.Flag{
			Name:  "dind-image",
			Usage: "Image to run for the Docker-in-Docker stack.",
			Value: "nathanleclaire/docker-machine-dind",
		},
	}
}

func (d *Driver) Create() error {
	d.BeingCreated = true

	dc, err := d.newDockerClient()
	if err != nil {
		return err
	}

	u, err := url.Parse(os.Getenv("DOCKER_HOST"))
	if err != nil {
		return fmt.Errorf("Error parsing URL from DOCKER_HOST: %s", err)
	}

	d.ContainerHost = strings.Split(u.Host, ":")[0]

	containerConfig := &dockerclient.ContainerConfig{
		Image: d.DindImage,
		HostConfig: dockerclient.HostConfig{
			PublishAllPorts: true,
			Privileged:      true,
		},
	}

	id, err := dc.CreateContainer(containerConfig, d.MachineName)
	if err != nil {
		return fmt.Errorf("Error creating container: %s", err)
	}

	d.Id = id

	if err := d.Start(); err != nil {
		return err
	}

	if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil {
		return err
	}

	f, err := os.Open(d.GetSSHKeyPath() + ".pub")
	if err != nil {
		return fmt.Errorf("Error opening pub key file: %s", err)
	}

	pubKey, err := ioutil.ReadAll(f)
	if err != nil {
		return fmt.Errorf("Error reading from pub key file: %s", err)
	}

	execConfig := &dockerclient.ExecConfig{
		Cmd:       []string{"sh", "-c", fmt.Sprintf("echo %q >/root/.ssh/authorized_keys", strings.TrimSpace(string(pubKey)))},
		Container: d.Id,
	}

	spew.Dump(execConfig)

	execId, err := dc.ExecCreate(execConfig)
	if err != nil {
		return fmt.Errorf("Error creating exec: %s", err)
	}

	if err := dc.ExecStart(execId, execConfig); err != nil {
		return fmt.Errorf("Error starting exec: %s", err)
	}

	return nil
}

func (d *Driver) DriverName() string {
	return "dind"
}

func (d *Driver) GetIP() (string, error) {
	return d.ContainerHost, nil
}

func (d *Driver) GetMachineName() string {
	return d.MachineName
}

func (d *Driver) GetSSHHostname() (string, error) {
	return d.ContainerHost, nil
}

func (d *Driver) getExposedPort(containerPort string) (int, error) {
	dc, err := d.newDockerClient()
	if err != nil {
		return 0, err
	}

	info, err := dc.InspectContainer(d.Id)
	if err != nil {
		return 0, fmt.Errorf("Error inspecting container: %s", err)
	}

	exposedPort, err := strconv.Atoi(info.NetworkSettings.Ports[fmt.Sprintf("%s/tcp", containerPort)][0].HostPort)
	if err != nil {
		return 0, fmt.Errorf("Error parsing host port to int: %s")
	}

	return exposedPort, nil
}

func (d *Driver) GetSSHPort() (int, error) {
	return d.getExposedPort("22")
}

func (d *Driver) GetSSHUsername() string {
	return "root"
}

func (d *Driver) GetURL() (string, error) {
	if d.BeingCreated {
		// HACK: First time on creation, trick provisioning into using 2376 for the URL.
		d.BeingCreated = false
		return fmt.Sprintf("tcp://%s:2376", d.ContainerHost), nil
	}

	s, err := d.GetState()
	if err != nil {
		return "", fmt.Errorf("Error getting state: %s", err)
	}

	if s != state.Running {
		return "", nil
	}

	dockerPort, err := d.getExposedPort("2376")
	if err != nil {
		return "", fmt.Errorf("Error trying to get exposed port: %s", err)
	}

	return fmt.Sprintf("tcp://%s:%d", d.ContainerHost, dockerPort), nil
}

func (d *Driver) GetState() (state.State, error) {
	dc, err := d.newDockerClient()
	if err != nil {
		return state.Error, err
	}

	info, err := dc.InspectContainer(d.Id)
	if err != nil {
		return state.Error, fmt.Errorf("Error inspecting container: %s", err)
	}

	spew.Dump(info)

	if info.State.Running {
		return state.Running, nil
	}

	return state.Stopped, nil
}

func (d *Driver) Kill() error {
	return nil
}

func (d *Driver) PreCreateCheck() error {
	return nil
}

func (d *Driver) Remove() error {
	dc, err := d.newDockerClient()
	if err != nil {
		return err
	}

	return dc.RemoveContainer(d.Id, true, true)
}

func (d *Driver) Restart() error {
	return nil
}

func (d *Driver) SetConfigFromFlags(opts drivers.DriverOptions) error {
	spew.Dump(opts)
	d.DindImage = opts.String("dind-image")
	return nil
}

func (d *Driver) Start() error {
	dc, err := d.newDockerClient()
	if err != nil {
		return err
	}

	return dc.StartContainer(d.Id, nil)
}

func (d *Driver) Stop() error {
	dc, err := d.newDockerClient()
	if err != nil {
		return err
	}

	return dc.StopContainer(d.Id, 10)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math"
	"os"

	"github.com/krasoffski/gomill/htcmap"
)

const (
	width   = 600
	height  = 320
	cells   = 100
	xyrange = 30.0
	xyscale = width / 2 / xyrange
	zscale  = height * 0.4
	angle   = math.Pi / 6
)

var (
	sin30 = math.Sin(angle)
	cos30 = math.Cos(angle)
)

// Point represents dot on three dimensional system of coordinates
type Point struct {
	X, Y, Z float64
}

// Isom transforms Point from 3 dimensional system to isometric.
func (p *Point) Isom() (float64, float64) {
	sx := width/2 + (p.X-p.Y)*cos30*xyscale
	sy := height/2 + (p.X+p.Y)*sin30*xyscale - p.Z*zscale
	return sx, sy
}

// NewPoint transform given cell with indexes i and j to coordinates and
// executes function of two variables using created coordinates. If successful,
// a pointer to Point returned or error in case function returns non-real value.
func NewPoint(i, j int, xyrange float64) (*Point, error) {
	// Transforming cell indexes to coordinates.
	x := xyrange * (float64(i)/cells - 0.5)
	y := xyrange * (float64(j)/cells - 0.5)
	z := f1(x, y)
	if math.IsNaN(z) || math.IsInf(z, +1) || math.IsInf(z, -1) {
		return nil, fmt.Errorf("error: function returned non real number")
	}
	return &Point{X: x, Y: y, Z: z}, nil
}

type Polygon struct {
	A, B, C, D *Point
}

func createPolygons(numCells int, xyrange float64) []*Polygon {
	polygons := make([]*Polygon, 0, numCells*numCells)

	for i := 0; i < numCells; i++ {
		for j := 0; j < numCells; j++ {
			a, aErr := NewPoint(i+1, j, xyrange)
			b, bErr := NewPoint(i, j, xyrange)
			c, cErr := NewPoint(i, j+1, xyrange)
			d, dErr := NewPoint(i+1, j+1, xyrange)

			// Skipping cell with non-real points.
			if aErr != nil || bErr != nil || cErr != nil || dErr != nil {
				continue
			}
			polygons = append(polygons, &Polygon{A: a, B: b, C: c, D: d})
		}
	}
	return polygons
}

func main() {

	polygons := createPolygons(cells, xyrange)

	if len(polygons) == 0 {
		fmt.Fprintln(os.Stderr, "error: no real points are exist")
		os.Exit(1)
	}
	min, max := polygons[0].A.Z, polygons[0].A.Z
	for _, t := range polygons {
		min = math.Min(min, t.A.Z)
		max = math.Max(max, t.A.Z)
	}
	fmt.Printf("<svg xmlns='http://www.w3.org/2000/svg' "+
		"width='%d' height='%d'>\n", width, height)

	colorRange := htcmap.NewRange(min, max)

	for _, t := range polygons {

		ax, ay := t.A.Isom()
		bx, by := t.B.Isom()
		cx, cy := t.C.Isom()
		dx, dy := t.D.Isom()

		c := colorRange.AsStr(t.B.Z)
		fmt.Printf("<polygon points='%g,%g %g,%g %g,%g %g,%g' "+
			"style='stroke:green; fill:%s; stroke-width:0.7'/>\n",
			ax, ay, bx, by, cx, cy, dx, dy, c)
	}
	fmt.Println("</svg>")
}

func f1(x, y float64) float64 {
	r := math.Hypot(x, y)
	return math.Sin(r) / r
}

func f2(x, y float64) float64 {
	return x * math.Exp(-x*x-y*y)
}
<commit_msg>Removing global consts. Broken!<commit_after>package main

import (
	"fmt"
	"math"
	"os"

	"github.com/krasoffski/gomill/htcmap"
)

type Settings struct {
	Width   float64
	Height  float64
	Cells   float64
	XYRange float64
	XYScale float64
	ZScale  float64
	Angle   float64
}

func DefaultSettings() *Settings {
	s := new(Settings)
	s.Width = 600
	s.Height = 320
	s.Cells = 100
	s.XYRange = 30.0
	s.XYScale = 10
	s.ZScale = 128
	s.Angle = math.Pi / 6
}

// Point represents dot on three dimensional system of coordinates
type Point struct {
	X, Y, Z float64
}

// Isom transforms Point from 3 dimensional system to isometric.
func (p *Point) Isom() (float64, float64) {
	sx := width/2 + (p.X-p.Y)*math.Cos(angle)*xyscale
	sy := height/2 + (p.X+p.Y)*math.Sin(angle)*xyscale - p.Z*zscale
	return sx, sy
}

// NewPoint transform given cell with indexes i, j and xyrange  to coordinates
// X and Y and executes function of two variables using created coordinates.
// If successful, a pointer to Point returned or error in case function returns
// non-real value like Nan, -Inf or +Inf.
func NewPoint(i, j int, xyrange float64) (*Point, error) {
	// Transforming cell indexes to coordinates.
	x := xyrange * (float64(i)/cells - 0.5)
	y := xyrange * (float64(j)/cells - 0.5)
	z := f1(x, y)
	if math.IsNaN(z) || math.IsInf(z, +1) || math.IsInf(z, -1) {
		return nil, fmt.Errorf("error: function returned non real number")
	}
	return &Point{X: x, Y: y, Z: z}, nil
}

type Polygon struct {
	A, B, C, D *Point
}

func createPolygons(numCells int, xyrange float64) []*Polygon {
	polygons := make([]*Polygon, 0, numCells*numCells)

	for i := 0; i < numCells; i++ {
		for j := 0; j < numCells; j++ {
			a, aErr := NewPoint(i+1, j, xyrange)
			b, bErr := NewPoint(i, j, xyrange)
			c, cErr := NewPoint(i, j+1, xyrange)
			d, dErr := NewPoint(i+1, j+1, xyrange)

			// Skipping cell with non-real points.
			if aErr != nil || bErr != nil || cErr != nil || dErr != nil {
				continue
			}
			polygons = append(polygons, &Polygon{A: a, B: b, C: c, D: d})
		}
	}
	return polygons
}

func main() {

	polygons := createPolygons(cells, xyrange)

	if len(polygons) == 0 {
		fmt.Fprintln(os.Stderr, "error: no real points are exist")
		os.Exit(1)
	}
	min, max := polygons[0].A.Z, polygons[0].A.Z
	for _, t := range polygons {
		min = math.Min(min, t.A.Z)
		max = math.Max(max, t.A.Z)
	}
	fmt.Printf("<svg xmlns='http://www.w3.org/2000/svg' "+
		"width='%d' height='%d'>\n", width, height)

	colorRange := htcmap.NewRange(min, max)

	for _, t := range polygons {

		ax, ay := t.A.Isom()
		bx, by := t.B.Isom()
		cx, cy := t.C.Isom()
		dx, dy := t.D.Isom()

		c := colorRange.AsStr(t.B.Z)
		fmt.Printf("<polygon points='%g,%g %g,%g %g,%g %g,%g' "+
			"style='stroke:green; fill:%s; stroke-width:0.7'/>\n",
			ax, ay, bx, by, cx, cy, dx, dy, c)
	}
	fmt.Println("</svg>")
}

func f1(x, y float64) float64 {
	r := math.Hypot(x, y)
	return math.Sin(r) / r
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"path/filepath"
)

var (
	aflag = flag.Bool("a", false, "Print entries for all files.")
	sflag = flag.Bool("s", false, "Print only a final summary.")
)

func init() {
	log.SetPrefix("du: ")
	log.SetFlags(0)
	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, "Usage: du [options] [path ...]")
		flag.PrintDefaults()
	}
	flag.Parse()
}

func main() {
	args := flag.Args()
	if len(args) == 0 {
		args = []string{"."}
	}
	for _, path := range args {
		du(path)
	}
}

func du(path string) {
	total := walk(path)
	if *sflag {
		print(path, total)
	}
}

func walk(path string) int64 {
	fi, err := os.Lstat(path)
	if err != nil {
		log.Print(err)
		return 0
	}
	var size int64
	if fi.IsDir() {
		f, err := os.Open(path)
		if err != nil {
			log.Print(err)
			return 0
		}
		entries, err := f.Readdirnames(0)
		if err != nil {
			log.Print(err)
			return 0
		}
		f.Close()
		for _, entry := range entries {
			size += walk(path + "/" + entry)
		}
	} else {
		size = (fi.Size() + 1023) / 1024
	}
	if !*sflag && (fi.IsDir() || *aflag) {
		print(path, size)
	}
	return size
}

func print(path string, size int64) {
	fmt.Fprintf(os.Stdout, "%d\t%s\n", size, filepath.Clean(path))
}
<commit_msg>du: fix rounding<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"path/filepath"
)

var (
	aflag = flag.Bool("a", false, "Print entries for all files.")
	sflag = flag.Bool("s", false, "Print only a final summary.")
)

func init() {
	log.SetPrefix("du: ")
	log.SetFlags(0)
	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, "Usage: du [options] [path ...]")
		flag.PrintDefaults()
	}
	flag.Parse()
}

func main() {
	args := flag.Args()
	if len(args) == 0 {
		args = []string{"."}
	}
	for _, path := range args {
		du(path)
	}
}

func du(path string) {
	total := walk(path)
	if *sflag {
		print(path, total)
	}
}

func walk(path string) int64 {
	fi, err := os.Lstat(path)
	if err != nil {
		log.Print(err)
		return 0
	}
	var size int64
	if fi.IsDir() {
		f, err := os.Open(path)
		if err != nil {
			log.Print(err)
			return 0
		}
		entries, err := f.Readdirnames(0)
		if err != nil {
			log.Print(err)
			return 0
		}
		f.Close()
		for _, entry := range entries {
			size += walk(path + "/" + entry)
		}
	} else {
		size = fi.Size()
	}
	if !*sflag && (fi.IsDir() || *aflag) {
		print(path, size)
	}
	return size
}

func print(path string, size int64) {
	fmt.Fprintf(os.Stdout, "%d\t%s\n", (size+512)/1024, filepath.Clean(path))
}
<|endoftext|>


<commit_before>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 ogletest

import (
	"errors"
	"fmt"
	"math"
	"reflect"
)

// Equals returns a matcher that matches any value v such that v == x, with the
// exception that if x is a numeric type, Equals(x) will match equivalent
// numeric values of any type.
func Equals(x interface{}) Matcher {
	v := reflect.ValueOf(x)

	// The == operator is not defined for array or struct types.
	if v.Kind() == reflect.Array || v.Kind() == reflect.Struct {
		panic(fmt.Sprintf("ogletest.Equals: unsupported type", v.Kind()))
	}

	// The == operator is not defined for non-nil slices.
	if v.Kind() == reflect.Slice && v.Pointer() != uintptr(0) {
		panic(fmt.Sprintf("ogletest.Equals: non-nil slice"))
	}

	return &equalsMatcher{v}
}

type equalsMatcher struct {
	expectedValue reflect.Value
}

////////////////////////////////////////////////////////////
// Numeric types
////////////////////////////////////////////////////////////

func isSignedInteger(v reflect.Value) bool {
	k := v.Kind()
	return k >= reflect.Int && k <= reflect.Int64
}

func isUnsignedInteger(v reflect.Value) bool {
	k := v.Kind()
	return k >= reflect.Uint && k <= reflect.Uint64
}

func isInteger(v reflect.Value) bool {
	return isSignedInteger(v) || isUnsignedInteger(v)
}

func isFloat(v reflect.Value) bool {
	k := v.Kind()
	return k == reflect.Float32 || k == reflect.Float64
}

func isComplex(v reflect.Value) bool {
	k := v.Kind()
	return k == reflect.Complex64 || k == reflect.Complex128
}

func checkAgainstInt64(e int64, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE

	switch {
	case isSignedInteger(c):
		if c.Int() == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		u := c.Uint()
		if u <= math.MaxInt64 && int64(u) == e {
			res = MATCH_TRUE
		}

	// Turn around the various floating point types so that the checkAgainst*
	// functions for them can deal with precision issues.
	case isFloat(c), isComplex(c):
		return Equals(c.Interface()).Matches(e)

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

func checkAgainstUint64(e uint64, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE

	switch {
	case isSignedInteger(c):
		i := c.Int()
		if i >= 0 && uint64(i) == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		if c.Uint() == e {
			res = MATCH_TRUE
		}

	// Turn around the various floating point types so that the checkAgainst*
	// functions for them can deal with precision issues.
	case isFloat(c), isComplex(c):
		return Equals(c.Interface()).Matches(e)

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

func checkAgainstFloat32(e float32, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE

	switch {
	case isSignedInteger(c):
		if float32(c.Int()) == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		if float32(c.Uint()) == e {
			res = MATCH_TRUE
		}

	case isFloat(c):
		// Compare using float32 to avoid a false sense of precision; otherwise
		// e.g. Equals(float32(0.1)) won't match float32(0.1).
		if float32(c.Float()) == e {
			res = MATCH_TRUE
		}

	case isComplex(c):
		comp := c.Complex()
		rl := real(comp)
		im := imag(comp)

		// Compare using float32 to avoid a false sense of precision; otherwise
		// e.g. Equals(float32(0.1)) won't match (0.1 + 0i).
		if im == 0 && float32(rl) == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

func checkAgainstFloat64(e float64, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE

	ck := c.Kind()

	switch {
	case isSignedInteger(c):
		if float64(c.Int()) == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		if float64(c.Uint()) == e {
			res = MATCH_TRUE
		}

	// If the actual value is lower precision, turn the comparison around so we
	// apply the low-precision rules. Otherwise, e.g. Equals(0.1) may not match
	// float32(0.1).
	case ck == reflect.Float32 || ck == reflect.Complex64:
		return Equals(c.Interface()).Matches(e)

		// Otherwise, compare with double precision.
	case isFloat(c):
		if c.Float() == e {
			res = MATCH_TRUE
		}

	case isComplex(c):
		comp := c.Complex()
		rl := real(comp)
		im := imag(comp)

		if im == 0 && rl == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

func checkAgainstComplex64(e complex64, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE
	realPart := real(e)
	imaginaryPart := imag(e)

	switch {
	case isInteger(c) || isFloat(c):
		// If we have no imaginary part, then we should just compare against the
		// real part. Otherwise, we can't be equal.
		if imaginaryPart != 0 {
			res = MATCH_FALSE
			return
		}

		return checkAgainstFloat32(realPart, c)

	case isComplex(c):
		// Compare using complex64 to avoid a false sense of precision; otherwise
		// e.g. Equals(0.1 + 0i) won't match float32(0.1).
		if complex64(c.Complex()) == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

func checkAgainstComplex128(e complex128, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE
	realPart := real(e)
	imaginaryPart := imag(e)

	switch {
	case isInteger(c) || isFloat(c):
		// If we have no imaginary part, then we should just compare against the
		// real part. Otherwise, we can't be equal.
		if imaginaryPart != 0 {
			res = MATCH_FALSE
			return
		}

		return checkAgainstFloat64(realPart, c)

	case isComplex(c):
		if c.Complex() == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

////////////////////////////////////////////////////////////
// Other types
////////////////////////////////////////////////////////////

func checkAgainstBool(e bool, c reflect.Value) (res MatchResult, err error) {
	if c.Kind() != reflect.Bool {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a bool")
		return
	}

	res = MATCH_FALSE
	if c.Bool() == e {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstUintptr(e uintptr, c reflect.Value) (res MatchResult, err error) {
	if c.Kind() != reflect.Uintptr {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a uintptr")
		return
	}

	res = MATCH_FALSE
	if uintptr(c.Uint()) == e {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstChan(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Create a description of e's type, e.g. "chan int".
	typeStr := fmt.Sprintf("%s %s", e.Type().ChanDir(), e.Type().Elem())

	// Make sure c is a chan of the correct type.
	if c.Kind() != reflect.Chan ||
		c.Type().ChanDir() != e.Type().ChanDir() ||
		c.Type().Elem() != e.Type().Elem() {
		res = MATCH_UNDEFINED
		err = errors.New(fmt.Sprintf("which is not a %s", typeStr))
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstFunc(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Make sure c is a function.
	if c.Kind() != reflect.Func {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a function")
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstMap(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Make sure c is a map.
	if c.Kind() != reflect.Map {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a map")
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstPtr(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Create a description of e's type, e.g. "*int".
	typeStr := fmt.Sprintf("*%v", e.Type().Elem())

	// Make sure c is a pointer of the correct type.
	if c.Kind() != reflect.Ptr ||
		c.Type().Elem() != e.Type().Elem() {
		res = MATCH_UNDEFINED
		err = errors.New(fmt.Sprintf("which is not a %s", typeStr))
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstSlice(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Create a description of e's type, e.g. "[]int".
	typeStr := fmt.Sprintf("[]%v", e.Type().Elem())

	// Make sure c is a slice of the correct type.
	if c.Kind() != reflect.Slice ||
		c.Type().Elem() != e.Type().Elem() {
		res = MATCH_UNDEFINED
		err = errors.New(fmt.Sprintf("which is not a %s", typeStr))
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstString(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Make sure c is a string.
	if c.Kind() != reflect.String {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a string")
		return
	}

	res = MATCH_FALSE
	if c.String() == e.String() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstUnsafePointer(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Make sure c is a pointer.
	if c.Kind() != reflect.UnsafePointer {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a unsafe.Pointer")
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

////////////////////////////////////////////////////////////
// Public implementation
////////////////////////////////////////////////////////////

func (m *equalsMatcher) Matches(candidate interface{}) (MatchResult, error) {
	e := m.expectedValue
	c := reflect.ValueOf(candidate)
	ek := e.Kind()

	switch {
	case ek == reflect.Bool:
		return checkAgainstBool(e.Bool(), c)

	case isSignedInteger(e):
		return checkAgainstInt64(e.Int(), c)

	case isUnsignedInteger(e):
		return checkAgainstUint64(e.Uint(), c)

	case ek == reflect.Uintptr:
		return checkAgainstUintptr(uintptr(e.Uint()), c)

	case ek == reflect.Float32:
		return checkAgainstFloat32(float32(e.Float()), c)

	case ek == reflect.Float64:
		return checkAgainstFloat64(e.Float(), c)

	case ek == reflect.Complex64:
		return checkAgainstComplex64(complex64(e.Complex()), c)

	case ek == reflect.Complex128:
		return checkAgainstComplex128(complex128(e.Complex()), c)

	case ek == reflect.Chan:
		return checkAgainstChan(e, c)

	case ek == reflect.Func:
		return checkAgainstFunc(e, c)

	case ek == reflect.Map:
		return checkAgainstMap(e, c)

	case ek == reflect.Ptr:
		return checkAgainstPtr(e, c)

	case ek == reflect.Slice:
		return checkAgainstSlice(e, c)

	case ek == reflect.String:
		return checkAgainstString(e, c)

	case ek == reflect.UnsafePointer:
		return checkAgainstUnsafePointer(e, c)
	}

	panic(fmt.Sprintf("equalsMatcher.Matches: unexpected kind: %v", ek))
}

func (m *equalsMatcher) Description() string {
	// Special case: handle nil.
	if !m.expectedValue.IsValid() {
		return "is nil"
	}

	return fmt.Sprintf("%v", m.expectedValue.Interface())
}
<commit_msg>Added support for nil.<commit_after>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 ogletest

import (
	"errors"
	"fmt"
	"math"
	"reflect"
)

// Equals returns a matcher that matches any value v such that v == x, with the
// exception that if x is a numeric type, Equals(x) will match equivalent
// numeric values of any type.
func Equals(x interface{}) Matcher {
	v := reflect.ValueOf(x)

	// The == operator is not defined for array or struct types.
	if v.Kind() == reflect.Array || v.Kind() == reflect.Struct {
		panic(fmt.Sprintf("ogletest.Equals: unsupported type", v.Kind()))
	}

	// The == operator is not defined for non-nil slices.
	if v.Kind() == reflect.Slice && v.Pointer() != uintptr(0) {
		panic(fmt.Sprintf("ogletest.Equals: non-nil slice"))
	}

	return &equalsMatcher{v}
}

type equalsMatcher struct {
	expectedValue reflect.Value
}

////////////////////////////////////////////////////////////
// Numeric types
////////////////////////////////////////////////////////////

func isSignedInteger(v reflect.Value) bool {
	k := v.Kind()
	return k >= reflect.Int && k <= reflect.Int64
}

func isUnsignedInteger(v reflect.Value) bool {
	k := v.Kind()
	return k >= reflect.Uint && k <= reflect.Uint64
}

func isInteger(v reflect.Value) bool {
	return isSignedInteger(v) || isUnsignedInteger(v)
}

func isFloat(v reflect.Value) bool {
	k := v.Kind()
	return k == reflect.Float32 || k == reflect.Float64
}

func isComplex(v reflect.Value) bool {
	k := v.Kind()
	return k == reflect.Complex64 || k == reflect.Complex128
}

func checkAgainstInt64(e int64, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE

	switch {
	case isSignedInteger(c):
		if c.Int() == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		u := c.Uint()
		if u <= math.MaxInt64 && int64(u) == e {
			res = MATCH_TRUE
		}

	// Turn around the various floating point types so that the checkAgainst*
	// functions for them can deal with precision issues.
	case isFloat(c), isComplex(c):
		return Equals(c.Interface()).Matches(e)

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

func checkAgainstUint64(e uint64, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE

	switch {
	case isSignedInteger(c):
		i := c.Int()
		if i >= 0 && uint64(i) == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		if c.Uint() == e {
			res = MATCH_TRUE
		}

	// Turn around the various floating point types so that the checkAgainst*
	// functions for them can deal with precision issues.
	case isFloat(c), isComplex(c):
		return Equals(c.Interface()).Matches(e)

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

func checkAgainstFloat32(e float32, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE

	switch {
	case isSignedInteger(c):
		if float32(c.Int()) == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		if float32(c.Uint()) == e {
			res = MATCH_TRUE
		}

	case isFloat(c):
		// Compare using float32 to avoid a false sense of precision; otherwise
		// e.g. Equals(float32(0.1)) won't match float32(0.1).
		if float32(c.Float()) == e {
			res = MATCH_TRUE
		}

	case isComplex(c):
		comp := c.Complex()
		rl := real(comp)
		im := imag(comp)

		// Compare using float32 to avoid a false sense of precision; otherwise
		// e.g. Equals(float32(0.1)) won't match (0.1 + 0i).
		if im == 0 && float32(rl) == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

func checkAgainstFloat64(e float64, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE

	ck := c.Kind()

	switch {
	case isSignedInteger(c):
		if float64(c.Int()) == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		if float64(c.Uint()) == e {
			res = MATCH_TRUE
		}

	// If the actual value is lower precision, turn the comparison around so we
	// apply the low-precision rules. Otherwise, e.g. Equals(0.1) may not match
	// float32(0.1).
	case ck == reflect.Float32 || ck == reflect.Complex64:
		return Equals(c.Interface()).Matches(e)

		// Otherwise, compare with double precision.
	case isFloat(c):
		if c.Float() == e {
			res = MATCH_TRUE
		}

	case isComplex(c):
		comp := c.Complex()
		rl := real(comp)
		im := imag(comp)

		if im == 0 && rl == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

func checkAgainstComplex64(e complex64, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE
	realPart := real(e)
	imaginaryPart := imag(e)

	switch {
	case isInteger(c) || isFloat(c):
		// If we have no imaginary part, then we should just compare against the
		// real part. Otherwise, we can't be equal.
		if imaginaryPart != 0 {
			res = MATCH_FALSE
			return
		}

		return checkAgainstFloat32(realPart, c)

	case isComplex(c):
		// Compare using complex64 to avoid a false sense of precision; otherwise
		// e.g. Equals(0.1 + 0i) won't match float32(0.1).
		if complex64(c.Complex()) == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

func checkAgainstComplex128(e complex128, c reflect.Value) (res MatchResult, err error) {
	res = MATCH_FALSE
	realPart := real(e)
	imaginaryPart := imag(e)

	switch {
	case isInteger(c) || isFloat(c):
		// If we have no imaginary part, then we should just compare against the
		// real part. Otherwise, we can't be equal.
		if imaginaryPart != 0 {
			res = MATCH_FALSE
			return
		}

		return checkAgainstFloat64(realPart, c)

	case isComplex(c):
		if c.Complex() == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which is not numeric")
	}

	return
}

////////////////////////////////////////////////////////////
// Other types
////////////////////////////////////////////////////////////

func checkAgainstBool(e bool, c reflect.Value) (res MatchResult, err error) {
	if c.Kind() != reflect.Bool {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a bool")
		return
	}

	res = MATCH_FALSE
	if c.Bool() == e {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstUintptr(e uintptr, c reflect.Value) (res MatchResult, err error) {
	if c.Kind() != reflect.Uintptr {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a uintptr")
		return
	}

	res = MATCH_FALSE
	if uintptr(c.Uint()) == e {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstChan(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Create a description of e's type, e.g. "chan int".
	typeStr := fmt.Sprintf("%s %s", e.Type().ChanDir(), e.Type().Elem())

	// Make sure c is a chan of the correct type.
	if c.Kind() != reflect.Chan ||
		c.Type().ChanDir() != e.Type().ChanDir() ||
		c.Type().Elem() != e.Type().Elem() {
		res = MATCH_UNDEFINED
		err = errors.New(fmt.Sprintf("which is not a %s", typeStr))
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstFunc(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Make sure c is a function.
	if c.Kind() != reflect.Func {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a function")
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstMap(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Make sure c is a map.
	if c.Kind() != reflect.Map {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a map")
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstPtr(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Create a description of e's type, e.g. "*int".
	typeStr := fmt.Sprintf("*%v", e.Type().Elem())

	// Make sure c is a pointer of the correct type.
	if c.Kind() != reflect.Ptr ||
		c.Type().Elem() != e.Type().Elem() {
		res = MATCH_UNDEFINED
		err = errors.New(fmt.Sprintf("which is not a %s", typeStr))
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstSlice(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Create a description of e's type, e.g. "[]int".
	typeStr := fmt.Sprintf("[]%v", e.Type().Elem())

	// Make sure c is a slice of the correct type.
	if c.Kind() != reflect.Slice ||
		c.Type().Elem() != e.Type().Elem() {
		res = MATCH_UNDEFINED
		err = errors.New(fmt.Sprintf("which is not a %s", typeStr))
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstString(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Make sure c is a string.
	if c.Kind() != reflect.String {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a string")
		return
	}

	res = MATCH_FALSE
	if c.String() == e.String() {
		res = MATCH_TRUE
	}
	return
}

func checkAgainstUnsafePointer(e reflect.Value, c reflect.Value) (res MatchResult, err error) {
	// Make sure c is a pointer.
	if c.Kind() != reflect.UnsafePointer {
		res = MATCH_UNDEFINED
		err = errors.New("which is not a unsafe.Pointer")
		return
	}

	res = MATCH_FALSE
	if c.Pointer() == e.Pointer() {
		res = MATCH_TRUE
	}
	return
}

func checkForNil(c reflect.Value) (res MatchResult, err error) {
	// Make it is legal to call IsNil.
	switch c.Kind() {
	case reflect.Chan:
	case reflect.Func:
	case reflect.Interface:
	case reflect.Map:
	case reflect.Ptr:
	case reflect.Slice:

	default:
		res = MATCH_UNDEFINED
		err = errors.New("which cannot be compared to nil")
		return
	}

	if c.IsNil() {
		res = MATCH_TRUE
	}
	return
}

////////////////////////////////////////////////////////////
// Public implementation
////////////////////////////////////////////////////////////

func (m *equalsMatcher) Matches(candidate interface{}) (MatchResult, error) {
	e := m.expectedValue
	c := reflect.ValueOf(candidate)
	ek := e.Kind()

	switch {
	case ek == reflect.Bool:
		return checkAgainstBool(e.Bool(), c)

	case isSignedInteger(e):
		return checkAgainstInt64(e.Int(), c)

	case isUnsignedInteger(e):
		return checkAgainstUint64(e.Uint(), c)

	case ek == reflect.Uintptr:
		return checkAgainstUintptr(uintptr(e.Uint()), c)

	case ek == reflect.Float32:
		return checkAgainstFloat32(float32(e.Float()), c)

	case ek == reflect.Float64:
		return checkAgainstFloat64(e.Float(), c)

	case ek == reflect.Complex64:
		return checkAgainstComplex64(complex64(e.Complex()), c)

	case ek == reflect.Complex128:
		return checkAgainstComplex128(complex128(e.Complex()), c)

	case ek == reflect.Chan:
		return checkAgainstChan(e, c)

	case ek == reflect.Func:
		return checkAgainstFunc(e, c)

	case ek == reflect.Map:
		return checkAgainstMap(e, c)

	case ek == reflect.Ptr:
		return checkAgainstPtr(e, c)

	case ek == reflect.Slice:
		return checkAgainstSlice(e, c)

	case ek == reflect.String:
		return checkAgainstString(e, c)

	case ek == reflect.UnsafePointer:
		return checkAgainstUnsafePointer(e, c)

	case ek == reflect.Invalid:
		return checkForNil(c)
	}

	panic(fmt.Sprintf("equalsMatcher.Matches: unexpected kind: %v", ek))
}

func (m *equalsMatcher) Description() string {
	// Special case: handle nil.
	if !m.expectedValue.IsValid() {
		return "is nil"
	}

	return fmt.Sprintf("%v", m.expectedValue.Interface())
}
<|endoftext|>


<commit_before>package client

import "errors"

// Signals that an end of file or stream has been reached unexpectedly.
var ErrEOF = errors.New("End of file reached")

// Happens when a compressed message is empty.
var ErrNoDataToUncompress = errors.New("No data to uncompress")

// A mapping for Kafka error code 0.
var ErrNoError = errors.New("No error - it worked!")

// A mapping for Kafka error code -1.
var ErrUnknown = errors.New("An unexpected server error")

// A mapping for Kafka error code 1.
var ErrOffsetOutOfRange = errors.New("The requested offset is outside the range of offsets maintained by the server for the given topic/partition.")

// A mapping for Kafka error code 2.
var ErrInvalidMessage = errors.New("Message contents does not match its CRC")

// A mapping for Kafka error code 3.
var ErrUnknownTopicOrPartition = errors.New("This request is for a topic or partition that does not exist on this broker.")

// A mapping for Kafka error code 4.
var ErrInvalidMessageSize = errors.New("The message has a negative size")

// A mapping for Kafka error code 5.
var ErrLeaderNotAvailable = errors.New("In the middle of a leadership election and there is currently no leader for this partition and hence it is unavailable for writes.")

// A mapping for Kafka error code 6.
var ErrNotLeaderForPartition = errors.New("You've just attempted to send messages to a replica that is not the leader for some partition. It indicates that the clients metadata is out of date.")

// A mapping for Kafka error code 7.
var ErrRequestTimedOut = errors.New("Request exceeds the user-specified time limit in the request.")

// A mapping for Kafka error code 8.
var ErrBrokerNotAvailable = errors.New("Broker is likely not alive.")

// A mapping for Kafka error code 9.
var ErrReplicaNotAvailable = errors.New("Replica is expected on a broker, but is not (this can be safely ignored).")

// A mapping for Kafka error code 10.
var ErrMessageSizeTooLarge = errors.New("You've just attempted to produce a message of size larger than broker is allowed to accept.")

// A mapping for Kafka error code 11.
var ErrStaleControllerEpochCode = errors.New("Broker-to-broker communication fault.")

// A mapping for Kafka error code 12.
var ErrOffsetMetadataTooLargeCode = errors.New("You've jsut specified a string larger than configured maximum for offset metadata.")

// A mapping for Kafka error code 14.
var ErrOffsetsLoadInProgressCode = errors.New("Offset loading is in progress. (Usually happens after a leader change for that offsets topic partition).")

// A mapping for Kafka error code 15.
var ErrConsumerCoordinatorNotAvailableCode = errors.New("Offsets topic has not yet been created.")

// A mapping for Kafka error code 16.
var ErrNotCoordinatorForConsumerCode = errors.New("There is no coordinator for this consumer.")

// A mapping for Kafka error code 17
var ErrInvalidTopicCode = errors.New("Attempt to access an invalid topic.")

// A mapping for Kafka error code 18
var ErrRecordListTooLarge = errors.New("Message batch exceeds the maximum configured segment size.")

// A mapping for Kafka error code 19
var ErrNotEnoughReplicas = errors.New("The number of in-sync replicas is lower than the configured minimum.")

// A mapping for Kafka error code 20
var ErrNotEnoughReplicasAfterAppend = errors.New("The message was written to the log, but with fewer in-sync replicas than required.")

// A mapping for Kafka error code 21
var ErrInvalidRequiredAcks = errors.New("The requested requiredAcks is invalid.")

// A mapping for Kafka error code 22
var ErrIllegalGeneration = errors.New("The generation id provided in the request is not the current generation.")

// A mapping for Kafka error code 23
var ErrInconsistentGroupProtocol = errors.New("Provided protocol type or set of protocols is not compatible with the current group.")

// A mapping for Kafka error code 24
var ErrInvalidGroupID = errors.New("The groupId is empty or null.")

// A mapping for Kafka error code 25
var ErrUnknownMemberID = errors.New("The memberId is not in the current generation.")

// A mapping for Kafka error code 26
var ErrInvalidSessionTimeout = errors.New("The requested session timeout is outside of the allowed range on the broker.")

// A mapping for Kafka error code 27
var ErrRebalanceInProgress = errors.New("The coordinator has begun rebalancing the group. This indicates to the client that it should rejoin the group.")

// A mapping for Kafka error code 28
var ErrInvalidCommitOffsetSize = errors.New("Offset commit was rejected because of oversize metadata.")

// A mapping for Kafka error code 29
var ErrTopicAuthorizationFailed = errors.New("The client is not authorized to access the requested topic.")

// A mapping for Kafka error code 30
var ErrGroupAuthorizationFailed = errors.New("The client is not authorized to access a particular groupId.")

// A mapping for Kafka error code 31
var ErrClusterAuthorizationFailed = errors.New("The client is not authorized to use an inter-broker or administrative API.")

// ErrFailedToGetMetadata happens when TopicMetadataResponse does not contain metadata for requested topic.
var ErrFailedToGetMetadata = errors.New("Failed to get topic metadata.")

// ErrFailedToGetLeader happens when TopicMetadataResponse does not contain leader metadata for requested topic and partition.
var ErrFailedToGetLeader = errors.New("Failed to get leader.")

// Mapping between Kafka error codes and actual error messages.
var BrokerErrors = map[int16]error{
	-1: ErrUnknown,
	0:  ErrNoError,
	1:  ErrOffsetOutOfRange,
	2:  ErrInvalidMessage,
	3:  ErrUnknownTopicOrPartition,
	4:  ErrInvalidMessageSize,
	5:  ErrLeaderNotAvailable,
	6:  ErrNotLeaderForPartition,
	7:  ErrRequestTimedOut,
	8:  ErrBrokerNotAvailable,
	9:  ErrReplicaNotAvailable,
	10: ErrMessageSizeTooLarge,
	11: ErrStaleControllerEpochCode,
	12: ErrOffsetMetadataTooLargeCode,
	14: ErrOffsetsLoadInProgressCode,
	15: ErrConsumerCoordinatorNotAvailableCode,
	16: ErrNotCoordinatorForConsumerCode,
	17: ErrInvalidTopicCode,
	18: ErrRecordListTooLarge,
	19: ErrNotEnoughReplicas,
	20: ErrNotEnoughReplicasAfterAppend,
	21: ErrInvalidRequiredAcks,
	22: ErrIllegalGeneration,
	23: ErrInconsistentGroupProtocol,
	24: ErrInvalidGroupID,
	25: ErrUnknownMemberID,
	26: ErrInvalidSessionTimeout,
	27: ErrRebalanceInProgress,
	28: ErrInvalidCommitOffsetSize,
	29: ErrTopicAuthorizationFailed,
	30: ErrGroupAuthorizationFailed,
	31: ErrClusterAuthorizationFailed,
}

// ClientConfig validation errors

// ErrNoClientConfig happens when trying to create a new client without a configuration.
var ErrNoClientConfig = errors.New("ClientConfig cannot be nil.")

// ErrConfigNoBrokers happens when trying to create a new client without bootstrap brokers specified.
var ErrConfigNoBrokers = errors.New("BrokerList must have at least one broker.")

// ErrConfigInvalidReadTimeout happens when trying to create a new client with too small ReadTimeout value.
var ErrConfigInvalidReadTimeout = errors.New("ReadTimeout must be at least 1ms.")

// ErrConfigInvalidWriteTimeout happens when trying to create a new client with too small WriteTimeout value.
var ErrConfigInvalidWriteTimeout = errors.New("WriteTimeout must be at least 1ms.")

// ErrConfigInvalidConnectTimeout happens when trying to create a new client with too small ConnectTimeout value.
var ErrConfigInvalidConnectTimeout = errors.New("ConnectTimeout must be at least 1ms.")

// ErrConfigInvalidKeepAliveTimeout happens when trying to create a new client with too small KeepAliveTimeout value.
var ErrConfigInvalidKeepAliveTimeout = errors.New("KeepAliveTimeout must be at least 1ms.")

// ErrConfigInvalidFetchSize happens when trying to create a new client with too small FetchSize value.
var ErrConfigInvalidFetchSize = errors.New("FetchSize cannot be less than 1.")

// ErrConfigInvalidMetadataRetries happens when trying to create a new client with too small MetadataRetries value.
var ErrConfigInvalidMetadataRetries = errors.New("MetadataRetries cannot be less than 0.")

// ErrConfigInvalidMetadataBackoff happens when trying to create a new client with too small MetadataBackoff value.
var ErrConfigInvalidMetadataBackoff = errors.New("MetadataBackoff must be at least 1ms.")

// ErrConfigInvalidMetadataTTL happens when trying to create a new client with too small MetadataTTL value.
var ErrConfigInvalidMetadataTTL = errors.New("MetadataTTL must be at least 1ms.")

// ErrConfigInvalidCommitOffsetRetries happens when trying to create a new client with too small CommitOffsetRetries value.
var ErrConfigInvalidCommitOffsetRetries = errors.New("CommitOffsetRetries cannot be less than 0.")

// ErrConfigInvalidCommitOffsetBackoff happens when trying to create a new client with too small CommitOffsetBackoff value.
var ErrConfigInvalidCommitOffsetBackoff = errors.New("CommitOffsetBackoff must be at least 1ms.")

// ErrConfigInvalidConsumerMetadataRetries happens when trying to create a new client with too small ConsumerMetadataRetries value.
var ErrConfigInvalidConsumerMetadataRetries = errors.New("ConsumerMetadataRetries cannot be less than 0.")

// ErrConfigInvalidConsumerMetadataBackoff happens when trying to create a new client with too small ConsumerMetadataBackoff value.
var ErrConfigInvalidConsumerMetadataBackoff = errors.New("ConsumerMetadataBackoff must be at least 1ms.")

// ErrConfigEmptyClientID happens when trying to create a new client with empty ClientID value.
var ErrConfigEmptyClientID = errors.New("ClientID cannot be empty.")
<commit_msg>Fix godoc for errors<commit_after>package client

import "errors"

// ErrEOF signals that an end of file or stream has been reached unexpectedly.
var ErrEOF = errors.New("End of file reached")

// ErrNoDataToUncompress happens when a compressed message is empty.
var ErrNoDataToUncompress = errors.New("No data to uncompress")

// ErrNoError is a mapping for Kafka error code 0.
var ErrNoError = errors.New("No error - it worked!")

// ErrUnknown is a mapping for Kafka error code -1.
var ErrUnknown = errors.New("An unexpected server error")

// ErrOffsetOutOfRange is a mapping for Kafka error code 1.
var ErrOffsetOutOfRange = errors.New("The requested offset is outside the range of offsets maintained by the server for the given topic/partition.")

// ErrInvalidMessage is a mapping for Kafka error code 2.
var ErrInvalidMessage = errors.New("Message contents does not match its CRC")

// ErrUnknownTopicOrPartition is a mapping for Kafka erfror code 3.
var ErrUnknownTopicOrPartition = errors.New("This request is for a topic or partition that does not exist on this broker.")

// ErrInvalidMessageSize is a mapping for Kafka error code 4.
var ErrInvalidMessageSize = errors.New("The message has a negative size")

// ErrLeaderNotAvailable is a mapping for Kafka error code 5.
var ErrLeaderNotAvailable = errors.New("In the middle of a leadership election and there is currently no leader for this partition and hence it is unavailable for writes.")

// ErrNotLeaderForPartition is a mapping for Kafka error code 6.
var ErrNotLeaderForPartition = errors.New("You've just attempted to send messages to a replica that is not the leader for some partition. It indicates that the clients metadata is out of date.")

// ErrRequestTimedOut is a mapping for Kafka error code 7.
var ErrRequestTimedOut = errors.New("Request exceeds the user-specified time limit in the request.")

// ErrBrokerNotAvailable is a mapping for Kafka error code 8.
var ErrBrokerNotAvailable = errors.New("Broker is likely not alive.")

// ErrReplicaNotAvailable is a mapping for Kafka error code 9.
var ErrReplicaNotAvailable = errors.New("Replica is expected on a broker, but is not (this can be safely ignored).")

// ErrMessageSizeTooLarge is a mapping for Kafka error code 10.
var ErrMessageSizeTooLarge = errors.New("You've just attempted to produce a message of size larger than broker is allowed to accept.")

// ErrStaleControllerEpochCode is a mapping for Kafka error code 11.
var ErrStaleControllerEpochCode = errors.New("Broker-to-broker communication fault.")

// ErrOffsetMetadataTooLargeCode is a mapping for Kafka error code 12.
var ErrOffsetMetadataTooLargeCode = errors.New("You've jsut specified a string larger than configured maximum for offset metadata.")

// ErrOffsetsLoadInProgressCode is a mapping for Kafka error code 14.
var ErrOffsetsLoadInProgressCode = errors.New("Offset loading is in progress. (Usually happens after a leader change for that offsets topic partition).")

// ErrConsumerCoordinatorNotAvailableCode is a mapping for Kafka error code 15.
var ErrConsumerCoordinatorNotAvailableCode = errors.New("Offsets topic has not yet been created.")

// ErrNotCoordinatorForConsumerCode is a mapping for Kafka error code 16.
var ErrNotCoordinatorForConsumerCode = errors.New("There is no coordinator for this consumer.")

// ErrInvalidTopicCode is a mapping for Kafka error code 17
var ErrInvalidTopicCode = errors.New("Attempt to access an invalid topic.")

// ErrRecordListTooLarge is a mapping for Kafka error code 18
var ErrRecordListTooLarge = errors.New("Message batch exceeds the maximum configured segment size.")

// ErrNotEnoughReplicas is a mapping for Kafka error code 19
var ErrNotEnoughReplicas = errors.New("The number of in-sync replicas is lower than the configured minimum.")

// ErrNotEnoughReplicasAfterAppend is a mapping for Kafka error code 20
var ErrNotEnoughReplicasAfterAppend = errors.New("The message was written to the log, but with fewer in-sync replicas than required.")

// ErrInvalidRequiredAcks is a mapping for Kafka error code 21
var ErrInvalidRequiredAcks = errors.New("The requested requiredAcks is invalid.")

// ErrIllegalGeneration is a mapping for Kafka error code 22
var ErrIllegalGeneration = errors.New("The generation id provided in the request is not the current generation.")

// ErrInconsistentGroupProtocol is a mapping for Kafka error code 23
var ErrInconsistentGroupProtocol = errors.New("Provided protocol type or set of protocols is not compatible with the current group.")

// ErrInvalidGroupID is a mapping for Kafka error code 24
var ErrInvalidGroupID = errors.New("The groupId is empty or null.")

// ErrUnknownMemberID is a mapping for Kafka error code 25
var ErrUnknownMemberID = errors.New("The memberId is not in the current generation.")

// ErrInvalidSessionTimeout is a mapping for Kafka error code 26
var ErrInvalidSessionTimeout = errors.New("The requested session timeout is outside of the allowed range on the broker.")

// ErrRebalanceInProgress is a mapping for Kafka error code 27
var ErrRebalanceInProgress = errors.New("The coordinator has begun rebalancing the group. This indicates to the client that it should rejoin the group.")

// ErrInvalidCommitOffsetSize is a mapping for Kafka error code 28
var ErrInvalidCommitOffsetSize = errors.New("Offset commit was rejected because of oversize metadata.")

// ErrTopicAuthorizationFailed is a mapping for Kafka error code 29
var ErrTopicAuthorizationFailed = errors.New("The client is not authorized to access the requested topic.")

// ErrGroupAuthorizationFailed is a mapping for Kafka error code 30
var ErrGroupAuthorizationFailed = errors.New("The client is not authorized to access a particular groupId.")

// ErrClusterAuthorizationFailed is a mapping for Kafka error code 31
var ErrClusterAuthorizationFailed = errors.New("The client is not authorized to use an inter-broker or administrative API.")

// ErrFailedToGetMetadata happens when TopicMetadataResponse does not contain metadata for requested topic.
var ErrFailedToGetMetadata = errors.New("Failed to get topic metadata.")

// ErrFailedToGetLeader happens when TopicMetadataResponse does not contain leader metadata for requested topic and partition.
var ErrFailedToGetLeader = errors.New("Failed to get leader.")

// BrokerErrors are mappings between Kafka error codes and actual error messages.
var BrokerErrors = map[int16]error{
	-1: ErrUnknown,
	0:  ErrNoError,
	1:  ErrOffsetOutOfRange,
	2:  ErrInvalidMessage,
	3:  ErrUnknownTopicOrPartition,
	4:  ErrInvalidMessageSize,
	5:  ErrLeaderNotAvailable,
	6:  ErrNotLeaderForPartition,
	7:  ErrRequestTimedOut,
	8:  ErrBrokerNotAvailable,
	9:  ErrReplicaNotAvailable,
	10: ErrMessageSizeTooLarge,
	11: ErrStaleControllerEpochCode,
	12: ErrOffsetMetadataTooLargeCode,
	14: ErrOffsetsLoadInProgressCode,
	15: ErrConsumerCoordinatorNotAvailableCode,
	16: ErrNotCoordinatorForConsumerCode,
	17: ErrInvalidTopicCode,
	18: ErrRecordListTooLarge,
	19: ErrNotEnoughReplicas,
	20: ErrNotEnoughReplicasAfterAppend,
	21: ErrInvalidRequiredAcks,
	22: ErrIllegalGeneration,
	23: ErrInconsistentGroupProtocol,
	24: ErrInvalidGroupID,
	25: ErrUnknownMemberID,
	26: ErrInvalidSessionTimeout,
	27: ErrRebalanceInProgress,
	28: ErrInvalidCommitOffsetSize,
	29: ErrTopicAuthorizationFailed,
	30: ErrGroupAuthorizationFailed,
	31: ErrClusterAuthorizationFailed,
}

// ClientConfig validation errors

// ErrNoClientConfig happens when trying to create a new client without a configuration.
var ErrNoClientConfig = errors.New("ClientConfig cannot be nil.")

// ErrConfigNoBrokers happens when trying to create a new client without bootstrap brokers specified.
var ErrConfigNoBrokers = errors.New("BrokerList must have at least one broker.")

// ErrConfigInvalidReadTimeout happens when trying to create a new client with too small ReadTimeout value.
var ErrConfigInvalidReadTimeout = errors.New("ReadTimeout must be at least 1ms.")

// ErrConfigInvalidWriteTimeout happens when trying to create a new client with too small WriteTimeout value.
var ErrConfigInvalidWriteTimeout = errors.New("WriteTimeout must be at least 1ms.")

// ErrConfigInvalidConnectTimeout happens when trying to create a new client with too small ConnectTimeout value.
var ErrConfigInvalidConnectTimeout = errors.New("ConnectTimeout must be at least 1ms.")

// ErrConfigInvalidKeepAliveTimeout happens when trying to create a new client with too small KeepAliveTimeout value.
var ErrConfigInvalidKeepAliveTimeout = errors.New("KeepAliveTimeout must be at least 1ms.")

// ErrConfigInvalidFetchSize happens when trying to create a new client with too small FetchSize value.
var ErrConfigInvalidFetchSize = errors.New("FetchSize cannot be less than 1.")

// ErrConfigInvalidMetadataRetries happens when trying to create a new client with too small MetadataRetries value.
var ErrConfigInvalidMetadataRetries = errors.New("MetadataRetries cannot be less than 0.")

// ErrConfigInvalidMetadataBackoff happens when trying to create a new client with too small MetadataBackoff value.
var ErrConfigInvalidMetadataBackoff = errors.New("MetadataBackoff must be at least 1ms.")

// ErrConfigInvalidMetadataTTL happens when trying to create a new client with too small MetadataTTL value.
var ErrConfigInvalidMetadataTTL = errors.New("MetadataTTL must be at least 1ms.")

// ErrConfigInvalidCommitOffsetRetries happens when trying to create a new client with too small CommitOffsetRetries value.
var ErrConfigInvalidCommitOffsetRetries = errors.New("CommitOffsetRetries cannot be less than 0.")

// ErrConfigInvalidCommitOffsetBackoff happens when trying to create a new client with too small CommitOffsetBackoff value.
var ErrConfigInvalidCommitOffsetBackoff = errors.New("CommitOffsetBackoff must be at least 1ms.")

// ErrConfigInvalidConsumerMetadataRetries happens when trying to create a new client with too small ConsumerMetadataRetries value.
var ErrConfigInvalidConsumerMetadataRetries = errors.New("ConsumerMetadataRetries cannot be less than 0.")

// ErrConfigInvalidConsumerMetadataBackoff happens when trying to create a new client with too small ConsumerMetadataBackoff value.
var ErrConfigInvalidConsumerMetadataBackoff = errors.New("ConsumerMetadataBackoff must be at least 1ms.")

// ErrConfigEmptyClientID happens when trying to create a new client with empty ClientID value.
var ErrConfigEmptyClientID = errors.New("ClientID cannot be empty.")
<|endoftext|>