<commit_before>package main

import (
	"fmt"
	"strings"
	"syscall"
	"time"

	"github.com/datawire/teleproxy/pkg/supervisor"
	"github.com/pkg/errors"
)

// Resource represents one thing managed by playpen daemon. Examples include
// network intercepts (via teleproxy intercept) and cluster connectivity.
type Resource interface {
	Name() string
	IsOkay() bool
	Close() error
}

// ResourceBase has helpers to create a monitored resource
type ResourceBase struct {
	name    string
	doCheck func(*supervisor.Process) error
	doQuit  func(*supervisor.Process) error
	tasks   chan func(*supervisor.Process) error
	okay    bool          // (monitor) cmd is running and check passes
	done    bool          // (Close) to get everything to quit
	end     chan struct{} // (Close) closed when the processor finishes
}

// Name implements Resource
func (rb *ResourceBase) Name() string {
	res := make(chan string)
	rb.tasks <- func(p *supervisor.Process) error {
		res <- rb.name
		return nil
	}
	return <-res
}

// IsOkay returns whether the resource is okay as far as monitoring is aware
func (rb *ResourceBase) IsOkay() bool {
	res := make(chan bool)
	rb.tasks <- func(p *supervisor.Process) error {
		res <- rb.okay
		return nil
	}
	return <-res
}

// Close shuts down this resource
func (rb *ResourceBase) Close() error {
	if rb.tasks != nil {
		rb.tasks <- rb.quit
		<-rb.end // Wait until things have closed
		rb.tasks = nil
	}
	return nil
}

func (rb *ResourceBase) setup(sup *supervisor.Supervisor, name string) {
	rb.name = name
	rb.tasks = make(chan func(*supervisor.Process) error, 1)
	rb.end = make(chan struct{})
	sup.Supervise(&supervisor.Worker{
		Name: name,
		Work: rb.processor,
	})
	sup.Supervise(&supervisor.Worker{
		Name: name + "/shutdown",
		Work: func(p *supervisor.Process) error {
			select {
			case <-p.Shutdown():
				p.Log("daemon is shutting down")
				return rb.Close()
			case <-rb.end:
				p.Log("Close() complete")
				return nil
			}
		},
	})
}

func (rb *ResourceBase) quit(p *supervisor.Process) error {
	p.Log("Close() / resource quit() called")
	return rb.doQuit(p)
}

func (rb *ResourceBase) monitor(p *supervisor.Process) error {
	old := rb.okay
	p.Log("monitor: checking...")
	if err := rb.doCheck(p); err != nil {
		rb.okay = false // Check failed is not okay
		p.Logf("monitor: check failed: %v", err)
	} else {
		p.Log("monitor: check passed")
		rb.okay = true
	}
	MaybeNotify(p, rb.name, old, rb.okay)
	return nil
}

func (rb *ResourceBase) processor(p *supervisor.Process) error {
	ticker := time.NewTicker(3 * time.Second)
	defer ticker.Stop()
	defer close(rb.end)
	p.Ready()
	for {
		var task func(*supervisor.Process) error
		select {
		case fn := <-rb.tasks: // There is work to do
			task = fn
		case <-ticker.C: // Ticker says it's time to monitor
			task = rb.monitor
		}
		if err := task(p); err != nil {
			p.Logf("task failed: %v", err)
			return err
		}
		if rb.done {
			p.Log("done")
			return nil
		}
	}
}

// KCluster is a Kubernetes cluster reference
type KCluster struct {
	context      string
	server       string
	rai          *RunAsInfo
	kargs        []string
	isBridgeOkay func() bool
	ResourceBase
}

// RAI returns the RunAsInfo for this cluster
func (c *KCluster) RAI() *RunAsInfo {
	return c.rai
}

// GetKubectlArgs returns the kubectl command arguments to run a
// kubectl command with this cluster
func (c *KCluster) GetKubectlArgs(args ...string) []string {
	cmdArgs := make([]string, 0, 1+len(c.kargs)+len(args))
	cmdArgs = append(cmdArgs, "kubectl")
	cmdArgs = append(cmdArgs, c.kargs...)
	cmdArgs = append(cmdArgs, args...)
	return cmdArgs
}

// GetKubectlCmd returns a Cmd that runs kubectl with the given arguments and
// the appropriate environment to talk to the cluster
func (c *KCluster) GetKubectlCmd(p *supervisor.Process, args ...string) *supervisor.Cmd {
	return c.rai.Command(p, c.GetKubectlArgs(args...)...)
}

// Context returns the cluster's context name
func (c *KCluster) Context() string {
	return c.context
}

// Server returns the cluster's server configuration
func (c *KCluster) Server() string {
	return c.server
}

// SetBridgeCheck sets the callable used to check whether the Teleproxy bridge
// is functioning. If this is nil/unset, cluster monitoring checks the cluster
// directly (via kubectl)
func (c *KCluster) SetBridgeCheck(isBridgeOkay func() bool) {
	c.isBridgeOkay = isBridgeOkay
}

// check for cluster connectivity
func (c *KCluster) check(p *supervisor.Process) error {
	// If the bridge is okay then the cluster is okay
	if c.isBridgeOkay != nil && c.isBridgeOkay() {
		return nil
	}
	cmd := c.GetKubectlCmd(p, "get", "po", "ohai", "--ignore-not-found")
	return cmd.Run()
}

// TrackKCluster tracks connectivity to a cluster
func TrackKCluster(p *supervisor.Process, rai *RunAsInfo, kargs []string) (*KCluster, error) {
	c := &KCluster{
		rai:   rai,
		kargs: kargs,
	}
	c.doCheck = c.check
	c.doQuit = func(p *supervisor.Process) error { c.done = true; return nil }

	if err := c.check(p); err != nil {
		return nil, errors.Wrap(err, "initial cluster check")
	}

	cmd := c.GetKubectlCmd(p, "config", "current-context")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return nil, errors.Wrap(err, "kubectl config current-context")
	}
	c.context = strings.TrimSpace(string(output))

	cmd = c.GetKubectlCmd(p, "config", "view", "--minify", "-o", "jsonpath={.clusters[0].cluster.server}")
	output, err = cmd.CombinedOutput()
	if err != nil {
		return nil, errors.Wrap(err, "kubectl config view")
	}
	c.server = strings.TrimSpace(string(output))

	c.setup(p.Supervisor(), "cluster")
	return c, nil
}

// crCmd is a handle to a checked retrying command
type crCmd struct {
	args       []string
	rai        *RunAsInfo
	check      func(p *supervisor.Process) error
	startGrace time.Duration
	cmd        *supervisor.Cmd // (run loop) tracks the cmd for killing it
	quitting   bool            // (run loop) enables Close()
	startedAt  time.Time
	ResourceBase
}

// CheckedRetryingCommand launches a command, restarting it repeatedly if it
// quits, and killing and restarting it if it fails the given check.
func CheckedRetryingCommand(
	p *supervisor.Process, name string, args []string, rai *RunAsInfo,
	check func(*supervisor.Process) error, startGrace time.Duration,
) (Resource, error) {
	if check == nil {
		check = func(*supervisor.Process) error { return nil }
	}
	crc := &crCmd{
		args:       args,
		rai:        rai,
		check:      check,
		startGrace: startGrace,
	}
	crc.ResourceBase.doCheck = crc.doCheck
	crc.ResourceBase.doQuit = crc.doQuit
	crc.setup(p.Supervisor(), name)

	if err := crc.launch(p); err != nil {
		return nil, errors.Wrapf(err, "initial launch of %s", name)
	}
	return crc, nil
}

func (crc *crCmd) subprocessEnded(p *supervisor.Process) error {
	p.Log("end: subprocess ended")
	crc.cmd = nil
	if crc.quitting {
		p.Log("end: marking as done")
		crc.done = true
	}
	return nil
}

func (crc *crCmd) launch(p *supervisor.Process) error {
	if crc.cmd != nil {
		panic(fmt.Errorf("launching %s: already launched", crc.name))
	}

	// Launch the subprocess (set up logging using a worker)
	p.Logf("Launching %s...", crc.name)
	launchErr := make(chan error)
	p.Supervisor().Supervise(&supervisor.Worker{
		Name: crc.name + "/out",
		Work: func(p *supervisor.Process) error {
			crc.cmd = crc.rai.Command(p, crc.args...)
			launchErr <- crc.cmd.Start()
			// Wait for the subprocess to end. Another worker will
			// call kill() on shutdown (via quit()) so we don't need
			// to worry about supervisor shutdown ourselves.
			if err := crc.cmd.Wait(); err != nil {
				p.Log(err)
			}
			crc.tasks <- crc.subprocessEnded
			return nil
		},
	})

	// Wait for it to start
	select {
	case err := <-launchErr:
		if err != nil {
			return err
		}
	case <-p.Shutdown():
		return nil
	}
	crc.startedAt = time.Now()
	p.Logf("Launched %s", crc.name)

	return nil
}

func (crc *crCmd) kill(p *supervisor.Process) error {
	if crc.cmd != nil {
		p.Log("kill: sending signal")
		if err := crc.cmd.Process.Signal(syscall.SIGTERM); err != nil {
			p.Logf("kill: failed (ignoring): %v", err)
		}
	} else {
		p.Log("kill: no subprocess to kill")
	}
	return nil
}

func (crc *crCmd) doQuit(p *supervisor.Process) error {
	crc.quitting = true
	return crc.kill(p)
}

// doCheck determines whether the subprocess is running and healthy
func (crc *crCmd) doCheck(p *supervisor.Process) error {
	if crc.cmd == nil {
		if crc.quitting {
			p.Log("check: no subprocess + quitting -> done")
			crc.done = true
			return nil
		}
		p.Log("check: no subprocess -> launch")
		crc.tasks <- crc.launch
		return errors.New("not running")
	}
	if err := crc.check(p); err != nil {
		p.Logf("check: failed: %v", err)
		runTime := time.Since(crc.startedAt)
		if runTime > crc.startGrace {
			// Kill the process because it's in a bad state
			p.Log("check: killing...")
			_ = crc.kill(p)
		} else {
			p.Logf("check: not killing yet (%v < %v)", runTime, crc.startGrace)
		}
		return err // from crc.check() above
	}
	p.Log("check: passed")
	return nil
}
<commit_msg>Hack around losing some races FIXME<commit_after>package main

import (
	"fmt"
	"strings"
	"syscall"
	"time"

	"github.com/datawire/teleproxy/pkg/supervisor"
	"github.com/pkg/errors"
)

// Resource represents one thing managed by playpen daemon. Examples include
// network intercepts (via teleproxy intercept) and cluster connectivity.
type Resource interface {
	Name() string
	IsOkay() bool
	Close() error
}

// ResourceBase has helpers to create a monitored resource
type ResourceBase struct {
	name    string
	doCheck func(*supervisor.Process) error
	doQuit  func(*supervisor.Process) error
	tasks   chan func(*supervisor.Process) error
	okay    bool          // (monitor) cmd is running and check passes
	done    bool          // (Close) to get everything to quit
	end     chan struct{} // (Close) closed when the processor finishes
}

// Name implements Resource
func (rb *ResourceBase) Name() string {
	res := make(chan string)
	rb.tasks <- func(p *supervisor.Process) error {
		res <- rb.name
		return nil
	}
	return <-res
}

// IsOkay returns whether the resource is okay as far as monitoring is aware
func (rb *ResourceBase) IsOkay() bool {
	res := make(chan bool)
	rb.tasks <- func(p *supervisor.Process) error {
		res <- rb.okay
		return nil
	}
	return <-res
}

// Close shuts down this resource
func (rb *ResourceBase) Close() error {
	if rb.tasks != nil {
		rb.tasks <- rb.quit
		<-rb.end // Wait until things have closed
		rb.tasks = nil
	}
	return nil
}

func (rb *ResourceBase) setup(sup *supervisor.Supervisor, name string) {
	rb.name = name
	rb.tasks = make(chan func(*supervisor.Process) error, 10)
	rb.end = make(chan struct{})
	sup.Supervise(&supervisor.Worker{
		Name: name,
		Work: rb.processor,
	})
	sup.Supervise(&supervisor.Worker{
		Name: name + "/shutdown",
		Work: func(p *supervisor.Process) error {
			select {
			case <-p.Shutdown():
				p.Log("daemon is shutting down")
				return rb.Close()
			case <-rb.end:
				p.Log("Close() complete")
				return nil
			}
		},
	})
}

func (rb *ResourceBase) quit(p *supervisor.Process) error {
	p.Log("Close() / resource quit() called")
	return rb.doQuit(p)
}

func (rb *ResourceBase) monitor(p *supervisor.Process) error {
	old := rb.okay
	p.Log("monitor: checking...")
	if err := rb.doCheck(p); err != nil {
		rb.okay = false // Check failed is not okay
		p.Logf("monitor: check failed: %v", err)
	} else {
		p.Log("monitor: check passed")
		rb.okay = true
	}
	MaybeNotify(p, rb.name, old, rb.okay)
	return nil
}

func (rb *ResourceBase) processor(p *supervisor.Process) error {
	ticker := time.NewTicker(3 * time.Second)
	defer ticker.Stop()
	defer close(rb.end)
	p.Ready()
	for {
		var task func(*supervisor.Process) error
		select {
		case fn := <-rb.tasks: // There is work to do
			task = fn
		case <-ticker.C: // Ticker says it's time to monitor
			task = rb.monitor
		}
		if err := task(p); err != nil {
			p.Logf("task failed: %v", err)
			return err
		}
		if rb.done {
			p.Log("done")
			return nil
		}
	}
}

// KCluster is a Kubernetes cluster reference
type KCluster struct {
	context      string
	server       string
	rai          *RunAsInfo
	kargs        []string
	isBridgeOkay func() bool
	ResourceBase
}

// RAI returns the RunAsInfo for this cluster
func (c *KCluster) RAI() *RunAsInfo {
	return c.rai
}

// GetKubectlArgs returns the kubectl command arguments to run a
// kubectl command with this cluster
func (c *KCluster) GetKubectlArgs(args ...string) []string {
	cmdArgs := make([]string, 0, 1+len(c.kargs)+len(args))
	cmdArgs = append(cmdArgs, "kubectl")
	cmdArgs = append(cmdArgs, c.kargs...)
	cmdArgs = append(cmdArgs, args...)
	return cmdArgs
}

// GetKubectlCmd returns a Cmd that runs kubectl with the given arguments and
// the appropriate environment to talk to the cluster
func (c *KCluster) GetKubectlCmd(p *supervisor.Process, args ...string) *supervisor.Cmd {
	return c.rai.Command(p, c.GetKubectlArgs(args...)...)
}

// Context returns the cluster's context name
func (c *KCluster) Context() string {
	return c.context
}

// Server returns the cluster's server configuration
func (c *KCluster) Server() string {
	return c.server
}

// SetBridgeCheck sets the callable used to check whether the Teleproxy bridge
// is functioning. If this is nil/unset, cluster monitoring checks the cluster
// directly (via kubectl)
func (c *KCluster) SetBridgeCheck(isBridgeOkay func() bool) {
	c.isBridgeOkay = isBridgeOkay
}

// check for cluster connectivity
func (c *KCluster) check(p *supervisor.Process) error {
	// If the bridge is okay then the cluster is okay
	if c.isBridgeOkay != nil && c.isBridgeOkay() {
		return nil
	}
	cmd := c.GetKubectlCmd(p, "get", "po", "ohai", "--ignore-not-found")
	return cmd.Run()
}

// TrackKCluster tracks connectivity to a cluster
func TrackKCluster(p *supervisor.Process, rai *RunAsInfo, kargs []string) (*KCluster, error) {
	c := &KCluster{
		rai:   rai,
		kargs: kargs,
	}
	c.doCheck = c.check
	c.doQuit = func(p *supervisor.Process) error { c.done = true; return nil }

	if err := c.check(p); err != nil {
		return nil, errors.Wrap(err, "initial cluster check")
	}

	cmd := c.GetKubectlCmd(p, "config", "current-context")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return nil, errors.Wrap(err, "kubectl config current-context")
	}
	c.context = strings.TrimSpace(string(output))

	cmd = c.GetKubectlCmd(p, "config", "view", "--minify", "-o", "jsonpath={.clusters[0].cluster.server}")
	output, err = cmd.CombinedOutput()
	if err != nil {
		return nil, errors.Wrap(err, "kubectl config view")
	}
	c.server = strings.TrimSpace(string(output))

	c.setup(p.Supervisor(), "cluster")
	return c, nil
}

// crCmd is a handle to a checked retrying command
type crCmd struct {
	args       []string
	rai        *RunAsInfo
	check      func(p *supervisor.Process) error
	startGrace time.Duration
	cmd        *supervisor.Cmd // (run loop) tracks the cmd for killing it
	quitting   bool            // (run loop) enables Close()
	startedAt  time.Time
	ResourceBase
}

// CheckedRetryingCommand launches a command, restarting it repeatedly if it
// quits, and killing and restarting it if it fails the given check.
func CheckedRetryingCommand(
	p *supervisor.Process, name string, args []string, rai *RunAsInfo,
	check func(*supervisor.Process) error, startGrace time.Duration,
) (Resource, error) {
	if check == nil {
		check = func(*supervisor.Process) error { return nil }
	}
	crc := &crCmd{
		args:       args,
		rai:        rai,
		check:      check,
		startGrace: startGrace,
	}
	crc.ResourceBase.doCheck = crc.doCheck
	crc.ResourceBase.doQuit = crc.doQuit
	crc.setup(p.Supervisor(), name)

	if err := crc.launch(p); err != nil {
		return nil, errors.Wrapf(err, "initial launch of %s", name)
	}
	return crc, nil
}

func (crc *crCmd) subprocessEnded(p *supervisor.Process) error {
	p.Log("end: subprocess ended")
	crc.cmd = nil
	if crc.quitting {
		p.Log("end: marking as done")
		crc.done = true
	}
	return nil
}

func (crc *crCmd) launch(p *supervisor.Process) error {
	if crc.cmd != nil {
		panic(fmt.Errorf("launching %s: already launched", crc.name))
	}

	// Launch the subprocess (set up logging using a worker)
	p.Logf("Launching %s...", crc.name)
	launchErr := make(chan error)
	p.Supervisor().Supervise(&supervisor.Worker{
		Name: crc.name + "/out",
		Work: func(p *supervisor.Process) error {
			crc.cmd = crc.rai.Command(p, crc.args...)
			launchErr <- crc.cmd.Start()
			// Wait for the subprocess to end. Another worker will
			// call kill() on shutdown (via quit()) so we don't need
			// to worry about supervisor shutdown ourselves.
			if err := crc.cmd.Wait(); err != nil {
				p.Log(err)
			}
			crc.tasks <- crc.subprocessEnded
			return nil
		},
	})

	// Wait for it to start
	select {
	case err := <-launchErr:
		if err != nil {
			return err
		}
	case <-p.Shutdown():
		return nil
	}
	crc.startedAt = time.Now()
	p.Logf("Launched %s", crc.name)

	return nil
}

func (crc *crCmd) kill(p *supervisor.Process) error {
	if crc.cmd != nil {
		p.Log("kill: sending signal")
		if err := crc.cmd.Process.Signal(syscall.SIGTERM); err != nil {
			p.Logf("kill: failed (ignoring): %v", err)
		}
	} else {
		p.Log("kill: no subprocess to kill")
	}
	return nil
}

func (crc *crCmd) doQuit(p *supervisor.Process) error {
	crc.quitting = true
	return crc.kill(p)
}

// doCheck determines whether the subprocess is running and healthy
func (crc *crCmd) doCheck(p *supervisor.Process) error {
	if crc.cmd == nil {
		if crc.quitting {
			p.Log("check: no subprocess + quitting -> done")
			crc.done = true
			return nil
		}
		p.Log("check: no subprocess -> launch")
		crc.tasks <- crc.launch
		return errors.New("not running")
	}
	if err := crc.check(p); err != nil {
		p.Logf("check: failed: %v", err)
		runTime := time.Since(crc.startedAt)
		if runTime > crc.startGrace {
			// Kill the process because it's in a bad state
			p.Log("check: killing...")
			_ = crc.kill(p)
		} else {
			p.Logf("check: not killing yet (%v < %v)", runTime, crc.startGrace)
		}
		return err // from crc.check() above
	}
	p.Log("check: passed")
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/timeredbull/tsuru/cmd"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
)

type Service struct{}

func (c *Service) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "service",
		Usage:   "service (init|list|create|remove|update) [args]",
		Desc:    "manage services.",
		MinArgs: 1,
	}
}

func (c *Service) Subcommands() map[string]interface{} {
	return map[string]interface{}{
		"create": &ServiceCreate{},
	}
}

type ServiceCreate struct{}

func (c *ServiceCreate) Info() *cmd.Info {
	desc := "Creates a service based on a passed manifest. The manifest format should be a yaml and follow the standard described in the documentation (should link to it here)"
	return &cmd.Info{
		Name:  "create",
		Usage: "service create path/to/manifesto",
		Desc:  desc,
	}
}

func (c *ServiceCreate) Run(context *cmd.Context, client cmd.Doer) error {
	manifest := context.Args[0]
	f, err := os.Open(manifest)
	if err != nil {
		return err
	}
	url := cmd.GetUrl("/service")
	var b []byte
	f.Read(b)
	body := strings.NewReader(string(b))
	request, err := http.NewRequest("POST", url, body)
	if err != nil {
		return err
	}
	r, err := client.Do(request)
	if err != nil {
		return err
	}
	b, err = ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}
	io.WriteString(context.Stdout, string(b))
	return nil
}
<commit_msg>Joining struct declarations in service cli<commit_after>package main

import (
	"github.com/timeredbull/tsuru/cmd"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
)

type Service struct{}
type ServiceCreate struct{}

func (c *Service) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "service",
		Usage:   "service (init|list|create|remove|update) [args]",
		Desc:    "manage services.",
		MinArgs: 1,
	}
}

func (c *Service) Subcommands() map[string]interface{} {
	return map[string]interface{}{
		"create": &ServiceCreate{},
	}
}

func (c *ServiceCreate) Info() *cmd.Info {
	desc := "Creates a service based on a passed manifest. The manifest format should be a yaml and follow the standard described in the documentation (should link to it here)"
	return &cmd.Info{
		Name:  "create",
		Usage: "service create path/to/manifesto",
		Desc:  desc,
	}
}

func (c *ServiceCreate) Run(context *cmd.Context, client cmd.Doer) error {
	manifest := context.Args[0]
	f, err := os.Open(manifest)
	if err != nil {
		return err
	}
	url := cmd.GetUrl("/service")
	var b []byte
	f.Read(b)
	body := strings.NewReader(string(b))
	request, err := http.NewRequest("POST", url, body)
	if err != nil {
		return err
	}
	r, err := client.Do(request)
	if err != nil {
		return err
	}
	b, err = ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}
	io.WriteString(context.Stdout, string(b))
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/binary"
	"log"
	"math"
	"os"
	"os/exec"
)

func play_main(args []string) {
	// 3 seconds of 207.5 Hz
	buf := make([]byte, 3*48000*4)
	for i := 0; i < 3*48000; i++ {
		var t float64 = float64(i) / 48000.0
		y := int(math.Sin(415.0*t*math.Pi) * 10000.0)
		binary.LittleEndian.PutUint16(buf[4*i:], uint16(y))
		binary.LittleEndian.PutUint16(buf[4*i+2:], uint16(y))
	}

	var n, i int

	mpl := exec.Command(Config.Tools.MPlayer, "-noconsolecontrols", "-cache", "1024", "-rawaudio", "rate=48000:channels=2:samplesize=2", "-demuxer", "rawaudio", "-")

	mpl.Stdout = os.Stdout
	mpl.Stderr = os.Stderr

	output, err := mpl.StdinPipe()
	if err != nil {
		log.Fatal(err)
	}

	mpl.Start()
	defer mpl.Wait()

	i = 0
	n = 0
	for err == nil {
		i, err = output.Write(buf[n:])
		n += i
		if n >= len(buf) {
			break
		}
	}

	output.Close()
}
<commit_msg>Make MPlayer really quiet<commit_after>package main

import (
	"encoding/binary"
	"log"
	"math"
	"os"
	"os/exec"
)

func play_main(args []string) {
	// 3 seconds of 207.5 Hz
	buf := make([]byte, 3*48000*4)
	for i := 0; i < 3*48000; i++ {
		var t float64 = float64(i) / 48000.0
		y := int(math.Sin(415.0*t*math.Pi) * 10000.0)
		binary.LittleEndian.PutUint16(buf[4*i:], uint16(y))
		binary.LittleEndian.PutUint16(buf[4*i+2:], uint16(y))
	}

	var n, i int

	mpl := exec.Command(Config.Tools.MPlayer,
		"-really-quiet",
		"-noconsolecontrols", "-nomouseinput", "-nolirc",
		"-cache", "1024",
		"-rawaudio", "rate=48000:channels=2:samplesize=2",
		"-demuxer", "rawaudio",
		"-")

	mpl.Stdout = os.Stdout
	mpl.Stderr = os.Stderr

	output, err := mpl.StdinPipe()
	if err != nil {
		log.Fatal(err)
	}

	mpl.Start()
	defer mpl.Wait()

	i = 0
	n = 0
	for err == nil {
		i, err = output.Write(buf[n:])
		n += i
		if n >= len(buf) {
			break
		}
	}

	output.Close()
}
<|endoftext|>


<commit_before>package atomicfile

import (
	"io/ioutil"
	"os"
	"path/filepath"
)

func WriteFile(filename string, data []byte, perm os.FileMode) error {
	// find the dirname of the filename

	d := filepath.Dir(filename)
	if err := os.MkdirAll(d, 0755); err != nil {
		return err
	}

	tempfile, err := ioutil.TempFile(d, filepath.Base(filename))
	if err != nil {
		return err
	}
	name := tempfile.Name()
	defer os.Remove(name)

	if err := tempfile.Close(); err != nil {
		return err
	}

	if err := ioutil.WriteFile(name, data, perm); err != nil {
		return err
	}
	return os.Rename(name, filename)
}
<commit_msg>golint<commit_after>package atomicfile

import (
	"io/ioutil"
	"os"
	"path/filepath"
)

// WriteFile will write the given data to the filename in an atomic manner so that
// partial writes are not possible.
func WriteFile(filename string, data []byte, perm os.FileMode) error {
	// find the dirname of the filename

	d := filepath.Dir(filename)
	if err := os.MkdirAll(d, 0755); err != nil {
		return err
	}

	tempfile, err := ioutil.TempFile(d, filepath.Base(filename))
	if err != nil {
		return err
	}
	name := tempfile.Name()
	defer os.Remove(name)

	if err := tempfile.Close(); err != nil {
		return err
	}

	if err := ioutil.WriteFile(name, data, perm); err != nil {
		return err
	}
	return os.Rename(name, filename)
}
<|endoftext|>


<commit_before>package ssh

import (
	"bytes"
	"code.google.com/p/go.crypto/ssh"
	"fmt"
	"github.com/mitchellh/packer/packer"
	"io"
	"log"
	"net"
	"path/filepath"
)

type comm struct {
	client *ssh.ClientConn
}

// Creates a new packer.Communicator implementation over SSH. This takes
// an already existing TCP connection and SSH configuration.
func New(c net.Conn, config *ssh.ClientConfig) (result *comm, err error) {
	client, err := ssh.Client(c, config)
	result = &comm{client}
	return
}

func (c *comm) Start(cmd string) (remote *packer.RemoteCommand, err error) {
	session, err := c.client.NewSession()
	if err != nil {
		return
	}

	// Create the buffers to store our stdin/stdout/stderr
	stdin := new(bytes.Buffer)
	stdout := new(bytes.Buffer)
	stderr := new(bytes.Buffer)

	// Setup our session
	session.Stdin = stdin
	session.Stdout = stdout
	session.Stderr = stderr

	// Setup the remote command
	remote = &packer.RemoteCommand{
		stdin,
		stdout,
		stderr,
		false,
		-1,
	}

	log.Printf("starting remote command: %s", cmd)
	err = session.Start(cmd + "\n")
	if err != nil {
		return
	}

	// Start a goroutine to wait for the session to end and set the
	// exit boolean and status.
	go func() {
		defer session.Close()

		err := session.Wait()
		remote.ExitStatus = 0
		if err != nil {
			exitErr, ok := err.(*ssh.ExitError)
			if ok {
				remote.ExitStatus = exitErr.ExitStatus()
			}
		}

		remote.Exited = true
	}()

	return
}

func (c *comm) Upload(path string, input io.Reader) error {
	session, err := c.client.NewSession()
	if err != nil {
		return err
	}

	defer session.Close()

	// Get a pipe to stdin so that we can send data down
	w, err := session.StdinPipe()
	if err != nil {
		return err
	}

	// Set stderr/stdout to a bytes buffer
	stderr := new(bytes.Buffer)
	stdout := new(bytes.Buffer)
	session.Stderr = stderr
	session.Stdout = stdout

	// We only want to close once, so we nil w after we close it,
	// and only close in the defer if it hasn't been closed already.
	defer func() {
		if w != nil {
			w.Close()
		}
	}()

	// The target directory and file for talking the SCP protocol
	target_dir := filepath.Dir(path)
	target_file := filepath.Base(path)

	// Start the sink mode on the other side
	// TODO(mitchellh): There are probably issues with shell escaping the path
	log.Println("Starting remote scp process in sink mode")
	if err = session.Start("scp -vt " + target_dir); err != nil {
		return err
	}

	// Determine the length of the upload content by copying it
	// into an in-memory buffer. Note that this means what we upload
	// must fit into memory.
	log.Println("Copying input data into in-memory buffer so we can get the length")
	input_memory := new(bytes.Buffer)
	if _, err = io.Copy(input_memory, input); err != nil {
		return err
	}

	// Start the protocol
	fmt.Fprintln(w, "C0644", input_memory.Len(), target_file)
	io.Copy(w, input_memory)
	fmt.Fprint(w, "\x00") // XXX(mitchellh): WHY?

	// Close the stdin, which sends an EOF, and then set w to nil so that
	// our defer func doesn't close it again since that is unsafe with
	// the Go SSH package.
	w.Close()
	w = nil

	// Wait for the SCP connection to close, meaning it has consumed all
	// our data and has completed. Or has errored.
	err = session.Wait()
	if err != nil {
		exitErr, ok := err.(*ssh.ExitError)
		if !ok {
			// This wasn't an exit error, so something fatal happened
			return err
		}

		// Otherwise, we have an ExitErorr, meaning we can just read
		// the exit status
		log.Printf("exit status: %d", exitErr.ExitStatus())
	}

	// TODO(mitchellh): Check for return data (expect a 0 or error)
	log.Printf("scp stdout: %s", stdout.String())
	log.Printf("scp stderr: %s", stderr.String())

	return nil
}

func (c *comm) Download(string, io.Writer) error {
	return nil
}
<commit_msg>communicator/ssh: Return error if non-zero exit status on Upload<commit_after>package ssh

import (
	"bytes"
	"code.google.com/p/go.crypto/ssh"
	"fmt"
	"github.com/mitchellh/packer/packer"
	"io"
	"log"
	"net"
	"path/filepath"
)

type comm struct {
	client *ssh.ClientConn
}

// Creates a new packer.Communicator implementation over SSH. This takes
// an already existing TCP connection and SSH configuration.
func New(c net.Conn, config *ssh.ClientConfig) (result *comm, err error) {
	client, err := ssh.Client(c, config)
	result = &comm{client}
	return
}

func (c *comm) Start(cmd string) (remote *packer.RemoteCommand, err error) {
	session, err := c.client.NewSession()
	if err != nil {
		return
	}

	// Create the buffers to store our stdin/stdout/stderr
	stdin := new(bytes.Buffer)
	stdout := new(bytes.Buffer)
	stderr := new(bytes.Buffer)

	// Setup our session
	session.Stdin = stdin
	session.Stdout = stdout
	session.Stderr = stderr

	// Setup the remote command
	remote = &packer.RemoteCommand{
		stdin,
		stdout,
		stderr,
		false,
		-1,
	}

	log.Printf("starting remote command: %s", cmd)
	err = session.Start(cmd + "\n")
	if err != nil {
		return
	}

	// Start a goroutine to wait for the session to end and set the
	// exit boolean and status.
	go func() {
		defer session.Close()

		err := session.Wait()
		remote.ExitStatus = 0
		if err != nil {
			exitErr, ok := err.(*ssh.ExitError)
			if ok {
				remote.ExitStatus = exitErr.ExitStatus()
			}
		}

		remote.Exited = true
	}()

	return
}

func (c *comm) Upload(path string, input io.Reader) error {
	session, err := c.client.NewSession()
	if err != nil {
		return err
	}

	defer session.Close()

	// Get a pipe to stdin so that we can send data down
	w, err := session.StdinPipe()
	if err != nil {
		return err
	}

	// Set stderr/stdout to a bytes buffer
	stderr := new(bytes.Buffer)
	stdout := new(bytes.Buffer)
	session.Stderr = stderr
	session.Stdout = stdout

	// We only want to close once, so we nil w after we close it,
	// and only close in the defer if it hasn't been closed already.
	defer func() {
		if w != nil {
			w.Close()
		}
	}()

	// The target directory and file for talking the SCP protocol
	target_dir := filepath.Dir(path)
	target_file := filepath.Base(path)

	// Start the sink mode on the other side
	// TODO(mitchellh): There are probably issues with shell escaping the path
	log.Println("Starting remote scp process in sink mode")
	if err = session.Start("scp -vt " + target_dir); err != nil {
		return err
	}

	// Determine the length of the upload content by copying it
	// into an in-memory buffer. Note that this means what we upload
	// must fit into memory.
	log.Println("Copying input data into in-memory buffer so we can get the length")
	input_memory := new(bytes.Buffer)
	if _, err = io.Copy(input_memory, input); err != nil {
		return err
	}

	// Start the protocol
	fmt.Fprintln(w, "C0644", input_memory.Len(), target_file)
	io.Copy(w, input_memory)
	fmt.Fprint(w, "\x00") // XXX(mitchellh): WHY?

	// Close the stdin, which sends an EOF, and then set w to nil so that
	// our defer func doesn't close it again since that is unsafe with
	// the Go SSH package.
	w.Close()
	w = nil

	// Wait for the SCP connection to close, meaning it has consumed all
	// our data and has completed. Or has errored.
	err = session.Wait()
	if err != nil {
		if exitErr, ok := err.(*ssh.ExitError); ok {
			// Otherwise, we have an ExitErorr, meaning we can just read
			// the exit status
			log.Printf("non-zero exit status: %d", exitErr.ExitStatus())
		}

		return err
	}

	// TODO(mitchellh): Check for return data (expect a 0 or error)
	log.Printf("scp stdout: %s", stdout.String())
	log.Printf("scp stderr: %s", stderr.String())

	return nil
}

func (c *comm) Download(string, io.Writer) error {
	return nil
}
<|endoftext|>


<commit_before>package orm

import (
	"fmt"
	"gnd.la/log"
	"gnd.la/orm/codec"
	"gnd.la/orm/driver"
	"gnd.la/orm/query"
	"gnd.la/types"
	"gnd.la/util"
	"reflect"
	"regexp"
	"sort"
	"strings"
	"time"
)

type nameRegistry map[string]*model
type typeRegistry map[reflect.Type]*model

var (
	// these keep track of the registered models,
	// using the driver tags as the key.
	_nameRegistry = map[string]nameRegistry{}
	_typeRegistry = map[string]typeRegistry{}
	timeType      = reflect.TypeOf(time.Time{})
	referencesRe  = regexp.MustCompile("([\\w\\.]+)(\\((\\w+)\\))?")
)

// Register registers a struct for future usage with the ORMs with
// the same driver. If you're using ORM instances with different drivers
// (e.g. postgres and mongodb)  you must register each object type with each
// driver (by creating an ORM of each type, calling Register() and then
// CommitTables()). The first returned value is a Table object, which must be
// using when querying the ORM in cases when an object is not provided
// (like e.g. Count()). If you want to use the same type in multiple
// tables, you must register it for every table and then use the Table
// object returned to specify on which table you want to operate. If
// no table is specified, the first registered table will be used.
func (o *Orm) Register(t interface{}, opt *Options) (*Table, error) {
	s, err := types.NewStruct(t, o.dtags())
	if err != nil {
		switch err {
		case types.ErrNoStruct:
			return nil, fmt.Errorf("only structs can be registered as models (tried to register %T)", t)
		case types.ErrNoFields:
			return nil, fmt.Errorf("type %T has no fields", t)
		}
		return nil, err
	}
	var table string
	if opt != nil {
		table = opt.Table
	}
	if table == "" {
		table = defaultTableName(s.Type)
	}
	if _nameRegistry[o.tags] == nil {
		_nameRegistry[o.tags] = nameRegistry{}
		_typeRegistry[o.tags] = typeRegistry{}
	}
	if _, ok := _nameRegistry[o.tags][table]; ok {
		return nil, fmt.Errorf("duplicate ORM table name %q", table)
	}
	fields, references, err := o.fields(table, s)
	if err != nil {
		return nil, err
	}
	var name string
	if opt != nil && opt.Name != "" {
		name = opt.Name
	} else {
		name = typeName(s.Type)
	}
	if opt != nil {
		if len(opt.PrimaryKey) > 0 {
			if fields.PrimaryKey >= 0 {
				return nil, fmt.Errorf("duplicate primary key in model %q. tags define %q as PK, options define %v",
					name, fields.QNames[fields.PrimaryKey], opt.PrimaryKey)
			}
			fields.CompositePrimaryKey = make([]int, len(opt.PrimaryKey))
			for ii, v := range opt.PrimaryKey {
				pos, ok := fields.QNameMap[v]
				if !ok {
					return nil, fmt.Errorf("can't map qualified name %q on model %q when creating composite key", v, name)
				}
				fields.CompositePrimaryKey[ii] = pos
			}
		}
	}
	model := &model{
		fields:     fields,
		name:       name,
		shortName:  s.Type.Name(),
		references: references,
		options:    opt,
		table:      table,
		tags:       o.tags,
	}
	_nameRegistry[o.tags][table] = model
	// The first registered table is the default for the type
	typ := model.Type()
	if _, ok := _typeRegistry[o.tags][typ]; !ok || opt != nil && opt.Default {
		_typeRegistry[o.tags][typ] = model
	}
	log.Debugf("Registered model %v (%q) with tags %q", typ, name, o.tags)
	return &Table{model: &joinModel{model: model}}, nil
}

// MustRegister works like Register, but panics if there's an
// error.
func (o *Orm) MustRegister(t interface{}, opt *Options) *Table {
	tbl, err := o.Register(t, opt)
	if err != nil {
		panic(err)
	}
	return tbl
}

// Initialize resolves model references and creates tables and
// indexes required by the registered models. You MUST call it
// AFTER all the models have been registered and BEFORE starting
// to use the ORM from several goroutines (for performance reasons,
// the access to some shared resources from several ORM instances
// is not thread safe).
func (o *Orm) Initialize() error {
	nr := _nameRegistry[o.tags]
	// Resolve references
	names := make(map[string]*model)
	for _, v := range nr {
		names[v.name] = v
	}
	for _, v := range nr {
		if c := len(v.references); c > 0 {
			v.fields.References = make(map[string]*driver.Reference, c)
			for k, r := range v.references {
				referenced := names[r.model]
				if referenced == nil {
					if !strings.Contains(r.model, ".") {
						referenced = names[v.Type().PkgPath()+"."+r.model]
					}
					if referenced == nil {
						return fmt.Errorf("can't find referenced model %q from model %q", r.model, v.name)
					}
				}
				if r.field == "" {
					// Map to PK
					if pk := referenced.fields.PrimaryKey; pk >= 0 {
						r.field = referenced.fields.QNames[pk]
					} else {
						return fmt.Errorf("referenced model %q does not have a non-composite primary key. Please, specify a field", r.model)
					}
				}
				_, ft, err := v.fields.Map(k)
				if err != nil {
					return err
				}
				_, fkt, err := referenced.fields.Map(r.field)
				if err != nil {
					return err
				}
				if ft != fkt {
					return fmt.Errorf("type mismatch: referenced field %q in model %q is of type %s, field %q in model %q is of type %s",
						r.field, referenced.name, fkt, k, v.name, ft)
				}
				v.fields.References[k] = &driver.Reference{
					Model: referenced,
					Field: r.field,
				}
				if v.modelReferences == nil {
					v.modelReferences = make(map[*model][]*join)
					v.modelReferences[referenced] = append(v.modelReferences[referenced], &join{
						model: &joinModel{model: referenced},
						q:     Eq(v.fullName(k), query.F(referenced.fullName(r.field))),
					})
				}
				if referenced.modelReferences == nil {
					referenced.modelReferences = make(map[*model][]*join)
					referenced.modelReferences[v] = append(referenced.modelReferences[v], &join{
						model: &joinModel{model: v},
						q:     Eq(referenced.fullName(r.field), query.F(v.fullName(k))),
					})
				}
			}
		}
	}
	models := make([]driver.Model, 0, len(nr))
	for _, v := range nr {
		models = append(models, v)
	}
	// Sort models to the ones with FKs are created after
	// the models they reference
	sort.Sort(sortModels(models))
	return o.driver.MakeTables(models)
}

// MustInitialize works like Initialize, but panics if
// there's an error.
func (o *Orm) MustInitialize() {
	if err := o.Initialize(); err != nil {
		panic(err)
	}
}

func (o *Orm) fields(table string, s *types.Struct) (*driver.Fields, map[string]*reference, error) {
	methods, err := driver.MakeMethods(s.Type)
	if err != nil {
		return nil, nil, err
	}
	fields := &driver.Fields{
		Struct:     s,
		PrimaryKey: -1,
		Methods:    methods,
	}
	var references map[string]*reference
	for ii, v := range s.QNames {
		// XXX: Check if this quoting is enough
		fields.QuotedNames = append(fields.QuotedNames, fmt.Sprintf("\"%s\".\"%s\"", table, s.MNames[ii]))
		t := s.Types[ii]
		k := t.Kind()
		ftag := s.Tags[ii]
		// Check encoded types
		if c := codec.FromTag(ftag); c != nil {
			if err := c.Try(t, o.dtags()); err != nil {
				return nil, nil, fmt.Errorf("can't encode field %q as %s: %s", v, c.Name(), err)
			}
		} else if ftag.CodecName() != "" {
			return nil, nil, fmt.Errorf("can't find ORM codec %q. Perhaps you missed an import?", ftag.CodecName())
		} else {
			switch k {
			case reflect.Array, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map:
				return nil, nil, fmt.Errorf("field %q in struct %v has invalid type %v", v, t, k)
			}
		}
		fields.OmitEmpty = append(fields.OmitEmpty, ftag.Has("omitempty") || (ftag.Has("auto_increment") && !ftag.Has("notomitempty")))
		// Struct has flattened types, but we need to original type
		// to determine if it should be nullempty by default
		field := s.Type.FieldByIndex(s.Indexes[ii])
		fields.NullEmpty = append(fields.NullEmpty, ftag.Has("nullempty") || (defaultsToNullEmpty(field.Type, ftag) && !ftag.Has("notnullempty")))
		if ftag.Has("primary_key") {
			if fields.PrimaryKey >= 0 {
				return nil, nil, fmt.Errorf("duplicate primary_key in struct %v (%s and %s)", s.Type, s.QNames[fields.PrimaryKey], v)
			}
			fields.PrimaryKey = ii
			if ftag.Has("auto_increment") && (k == reflect.Int || k == reflect.Int8 || k == reflect.Int16 || k == reflect.Int32 || k == reflect.Int64) {
				fields.IntegerAutoincrementPk = true
			}
		}
		if ref := ftag.Value("references"); ref != "" {
			m := referencesRe.FindStringSubmatch(ref)
			if len(m) != 4 {
				return nil, nil, fmt.Errorf("field %q has invalid references %q. Must be in the form references=Model or references=Model(Field)", v, ref)
			}
			if references == nil {
				references = make(map[string]*reference)
			}
			references[v] = &reference{model: m[1], field: m[3]}
		}
	}
	return fields, references, nil
}

func (o *Orm) dtags() []string {
	return append(o.driver.Tags(), "orm")
}

// returns wheter the kind defaults to nullempty option
func defaultsToNullEmpty(typ reflect.Type, t *types.Tag) bool {
	if t.Has("references") {
		return true
	}
	switch typ.Kind() {
	case reflect.Slice, reflect.Ptr, reflect.Interface, reflect.String:
		return true
	case reflect.Struct:
		return typ == timeType
	}
	return false
}

// Returns the default table name for a type
func defaultTableName(typ reflect.Type) string {
	n := typ.Name()
	if p := typ.PkgPath(); p != "main" {
		n = strings.Replace(p, "/", "_", -1) + n
	}
	return util.CamelCaseToLower(n, "_")
}

func typeName(typ reflect.Type) string {
	if p := typ.PkgPath(); p != "main" {
		return p + "." + typ.Name()
	}
	return typ.Name()
}
<commit_msg>Make fields with a codec default to nullempty<commit_after>package orm

import (
	"fmt"
	"gnd.la/log"
	"gnd.la/orm/codec"
	"gnd.la/orm/driver"
	"gnd.la/orm/query"
	"gnd.la/types"
	"gnd.la/util"
	"reflect"
	"regexp"
	"sort"
	"strings"
	"time"
)

type nameRegistry map[string]*model
type typeRegistry map[reflect.Type]*model

var (
	// these keep track of the registered models,
	// using the driver tags as the key.
	_nameRegistry = map[string]nameRegistry{}
	_typeRegistry = map[string]typeRegistry{}
	timeType      = reflect.TypeOf(time.Time{})
	referencesRe  = regexp.MustCompile("([\\w\\.]+)(\\((\\w+)\\))?")
)

// Register registers a struct for future usage with the ORMs with
// the same driver. If you're using ORM instances with different drivers
// (e.g. postgres and mongodb)  you must register each object type with each
// driver (by creating an ORM of each type, calling Register() and then
// CommitTables()). The first returned value is a Table object, which must be
// using when querying the ORM in cases when an object is not provided
// (like e.g. Count()). If you want to use the same type in multiple
// tables, you must register it for every table and then use the Table
// object returned to specify on which table you want to operate. If
// no table is specified, the first registered table will be used.
func (o *Orm) Register(t interface{}, opt *Options) (*Table, error) {
	s, err := types.NewStruct(t, o.dtags())
	if err != nil {
		switch err {
		case types.ErrNoStruct:
			return nil, fmt.Errorf("only structs can be registered as models (tried to register %T)", t)
		case types.ErrNoFields:
			return nil, fmt.Errorf("type %T has no fields", t)
		}
		return nil, err
	}
	var table string
	if opt != nil {
		table = opt.Table
	}
	if table == "" {
		table = defaultTableName(s.Type)
	}
	if _nameRegistry[o.tags] == nil {
		_nameRegistry[o.tags] = nameRegistry{}
		_typeRegistry[o.tags] = typeRegistry{}
	}
	if _, ok := _nameRegistry[o.tags][table]; ok {
		return nil, fmt.Errorf("duplicate ORM table name %q", table)
	}
	fields, references, err := o.fields(table, s)
	if err != nil {
		return nil, err
	}
	var name string
	if opt != nil && opt.Name != "" {
		name = opt.Name
	} else {
		name = typeName(s.Type)
	}
	if opt != nil {
		if len(opt.PrimaryKey) > 0 {
			if fields.PrimaryKey >= 0 {
				return nil, fmt.Errorf("duplicate primary key in model %q. tags define %q as PK, options define %v",
					name, fields.QNames[fields.PrimaryKey], opt.PrimaryKey)
			}
			fields.CompositePrimaryKey = make([]int, len(opt.PrimaryKey))
			for ii, v := range opt.PrimaryKey {
				pos, ok := fields.QNameMap[v]
				if !ok {
					return nil, fmt.Errorf("can't map qualified name %q on model %q when creating composite key", v, name)
				}
				fields.CompositePrimaryKey[ii] = pos
			}
		}
	}
	model := &model{
		fields:     fields,
		name:       name,
		shortName:  s.Type.Name(),
		references: references,
		options:    opt,
		table:      table,
		tags:       o.tags,
	}
	_nameRegistry[o.tags][table] = model
	// The first registered table is the default for the type
	typ := model.Type()
	if _, ok := _typeRegistry[o.tags][typ]; !ok || opt != nil && opt.Default {
		_typeRegistry[o.tags][typ] = model
	}
	log.Debugf("Registered model %v (%q) with tags %q", typ, name, o.tags)
	return &Table{model: &joinModel{model: model}}, nil
}

// MustRegister works like Register, but panics if there's an
// error.
func (o *Orm) MustRegister(t interface{}, opt *Options) *Table {
	tbl, err := o.Register(t, opt)
	if err != nil {
		panic(err)
	}
	return tbl
}

// Initialize resolves model references and creates tables and
// indexes required by the registered models. You MUST call it
// AFTER all the models have been registered and BEFORE starting
// to use the ORM from several goroutines (for performance reasons,
// the access to some shared resources from several ORM instances
// is not thread safe).
func (o *Orm) Initialize() error {
	nr := _nameRegistry[o.tags]
	// Resolve references
	names := make(map[string]*model)
	for _, v := range nr {
		names[v.name] = v
	}
	for _, v := range nr {
		if c := len(v.references); c > 0 {
			v.fields.References = make(map[string]*driver.Reference, c)
			for k, r := range v.references {
				referenced := names[r.model]
				if referenced == nil {
					if !strings.Contains(r.model, ".") {
						referenced = names[v.Type().PkgPath()+"."+r.model]
					}
					if referenced == nil {
						return fmt.Errorf("can't find referenced model %q from model %q", r.model, v.name)
					}
				}
				if r.field == "" {
					// Map to PK
					if pk := referenced.fields.PrimaryKey; pk >= 0 {
						r.field = referenced.fields.QNames[pk]
					} else {
						return fmt.Errorf("referenced model %q does not have a non-composite primary key. Please, specify a field", r.model)
					}
				}
				_, ft, err := v.fields.Map(k)
				if err != nil {
					return err
				}
				_, fkt, err := referenced.fields.Map(r.field)
				if err != nil {
					return err
				}
				if ft != fkt {
					return fmt.Errorf("type mismatch: referenced field %q in model %q is of type %s, field %q in model %q is of type %s",
						r.field, referenced.name, fkt, k, v.name, ft)
				}
				v.fields.References[k] = &driver.Reference{
					Model: referenced,
					Field: r.field,
				}
				if v.modelReferences == nil {
					v.modelReferences = make(map[*model][]*join)
					v.modelReferences[referenced] = append(v.modelReferences[referenced], &join{
						model: &joinModel{model: referenced},
						q:     Eq(v.fullName(k), query.F(referenced.fullName(r.field))),
					})
				}
				if referenced.modelReferences == nil {
					referenced.modelReferences = make(map[*model][]*join)
					referenced.modelReferences[v] = append(referenced.modelReferences[v], &join{
						model: &joinModel{model: v},
						q:     Eq(referenced.fullName(r.field), query.F(v.fullName(k))),
					})
				}
			}
		}
	}
	models := make([]driver.Model, 0, len(nr))
	for _, v := range nr {
		models = append(models, v)
	}
	// Sort models to the ones with FKs are created after
	// the models they reference
	sort.Sort(sortModels(models))
	return o.driver.MakeTables(models)
}

// MustInitialize works like Initialize, but panics if
// there's an error.
func (o *Orm) MustInitialize() {
	if err := o.Initialize(); err != nil {
		panic(err)
	}
}

func (o *Orm) fields(table string, s *types.Struct) (*driver.Fields, map[string]*reference, error) {
	methods, err := driver.MakeMethods(s.Type)
	if err != nil {
		return nil, nil, err
	}
	fields := &driver.Fields{
		Struct:     s,
		PrimaryKey: -1,
		Methods:    methods,
	}
	var references map[string]*reference
	for ii, v := range s.QNames {
		// XXX: Check if this quoting is enough
		fields.QuotedNames = append(fields.QuotedNames, fmt.Sprintf("\"%s\".\"%s\"", table, s.MNames[ii]))
		t := s.Types[ii]
		k := t.Kind()
		ftag := s.Tags[ii]
		// Check encoded types
		if c := codec.FromTag(ftag); c != nil {
			if err := c.Try(t, o.dtags()); err != nil {
				return nil, nil, fmt.Errorf("can't encode field %q as %s: %s", v, c.Name(), err)
			}
		} else if ftag.CodecName() != "" {
			return nil, nil, fmt.Errorf("can't find ORM codec %q. Perhaps you missed an import?", ftag.CodecName())
		} else {
			switch k {
			case reflect.Array, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map:
				return nil, nil, fmt.Errorf("field %q in struct %v has invalid type %v", v, t, k)
			}
		}
		fields.OmitEmpty = append(fields.OmitEmpty, ftag.Has("omitempty") || (ftag.Has("auto_increment") && !ftag.Has("notomitempty")))
		// Struct has flattened types, but we need to original type
		// to determine if it should be nullempty by default
		field := s.Type.FieldByIndex(s.Indexes[ii])
		fields.NullEmpty = append(fields.NullEmpty, ftag.Has("nullempty") || (defaultsToNullEmpty(field.Type, ftag) && !ftag.Has("notnullempty")))
		if ftag.Has("primary_key") {
			if fields.PrimaryKey >= 0 {
				return nil, nil, fmt.Errorf("duplicate primary_key in struct %v (%s and %s)", s.Type, s.QNames[fields.PrimaryKey], v)
			}
			fields.PrimaryKey = ii
			if ftag.Has("auto_increment") && (k == reflect.Int || k == reflect.Int8 || k == reflect.Int16 || k == reflect.Int32 || k == reflect.Int64) {
				fields.IntegerAutoincrementPk = true
			}
		}
		if ref := ftag.Value("references"); ref != "" {
			m := referencesRe.FindStringSubmatch(ref)
			if len(m) != 4 {
				return nil, nil, fmt.Errorf("field %q has invalid references %q. Must be in the form references=Model or references=Model(Field)", v, ref)
			}
			if references == nil {
				references = make(map[string]*reference)
			}
			references[v] = &reference{model: m[1], field: m[3]}
		}
	}
	return fields, references, nil
}

func (o *Orm) dtags() []string {
	return append(o.driver.Tags(), "orm")
}

// returns wheter the kind defaults to nullempty option
func defaultsToNullEmpty(typ reflect.Type, t *types.Tag) bool {
	if t.Has("references") || t.Has("codec") {
		return true
	}
	switch typ.Kind() {
	case reflect.Slice, reflect.Ptr, reflect.Interface, reflect.String:
		return true
	case reflect.Struct:
		return typ == timeType
	}
	return false
}

// Returns the default table name for a type
func defaultTableName(typ reflect.Type) string {
	n := typ.Name()
	if p := typ.PkgPath(); p != "main" {
		n = strings.Replace(p, "/", "_", -1) + n
	}
	return util.CamelCaseToLower(n, "_")
}

func typeName(typ reflect.Type) string {
	if p := typ.PkgPath(); p != "main" {
		return p + "." + typ.Name()
	}
	return typ.Name()
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Square, Inc

package misc

import (
	"bufio"
	"errors"
	"fmt"
	"io/ioutil"
	"math"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"strconv"
	"strings"

	"github.com/square/inspect/metrics"
)

type Interface interface{}

func ParseUint(in string) uint64 {
	out, err := strconv.ParseUint(in, 10, 64) // decimal, 64bit
	if err != nil {
		return 0
	}
	return out
}

func ParseFloat(in string) float64 {
	out, err := strconv.ParseFloat(in, 64) // float, 64bit
	if err != nil {
		return math.NaN()
	}
	return out
}

func ReadUintFromFile(path string) uint64 {
	f, err := os.Open(path)
	defer f.Close()
	if err != nil {
		return 0
	}

	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		return ParseUint(scanner.Text())
	}
	return 0
}

// InitializeMetrics initializes all Counters/Gauges types defined for the instance
// with Metrics Context by using reflection
func InitializeMetrics(c Interface, m *metrics.MetricContext, prefix string, register bool) {
	s := reflect.ValueOf(c).Elem()
	typeOfT := s.Type()
	for i := 0; i < s.NumField(); i++ {
		f := s.Field(i)
		if f.Kind().String() != "ptr" {
			continue
		}
		if f.Type().Elem() == reflect.TypeOf(metrics.Gauge{}) {
			name := prefix + "." + typeOfT.Field(i).Name
			g := metrics.NewGauge()
			if register {
				m.Register(g, name)
			}
			f.Set(reflect.ValueOf(g))
		}
		if f.Type().Elem() == reflect.TypeOf(metrics.Counter{}) {
			name := prefix + "." + typeOfT.Field(i).Name
			g := metrics.NewCounter()
			if register {
				m.Register(g, name)
			}
			f.Set(reflect.ValueOf(g))
		}
	}
	return
}

// SetMetrics sets values for all counters/gauges defined
func SetMetrics(m *metrics.MetricContext, s Interface, keys []string, values []string) {
	// Get all fields we care about
	sv := reflect.ValueOf(s).Elem()
	st := sv.Type()
	for i := 0; i < sv.NumField(); i++ {
		metric := sv.Field(i)
		name := st.Field(i).Name
		metricType := metric.Type().String()
		if metricType == "*metrics.Gauge" {
			g := metric.Interface().(*metrics.Gauge)
			strValue, err := extractValue(name, keys, values)
			if err == nil {
				i, err := strconv.ParseInt(strValue, 0, 64)
				if err == nil {
					g.Set(float64(i))
				}
			}
		}
		if metricType == "*metrics.Counter" {
			c := metric.Interface().(*metrics.Counter)
			strValue, err := extractValue(name, keys, values)
			if err == nil {
				c.Set(ParseUint(strValue))
			}
		}
	}
}

// find if the metric name we have is present in data we just parsed
func extractValue(name string, keys []string, values []string) (string, error) {
	idx := 0
	for i, key := range keys {
		if key == name {
			idx = i
			break
		}
	}
	if idx < len(values) {
		return values[idx], nil
	}
	return "", errors.New("Not found")
}

// UnregisterMetrics un-registers all counters/gauges defined for the instance
func UnregisterMetrics(c Interface, m *metrics.MetricContext, prefix string) {
	s := reflect.ValueOf(c).Elem()
	typeOfT := s.Type()
	for i := 0; i < s.NumField(); i++ {
		f := s.Field(i)
		if f.Kind().String() != "ptr" {
			continue
		}
		if f.Type().Elem() == reflect.TypeOf(metrics.Gauge{}) ||
			f.Type().Elem() == reflect.TypeOf(metrics.Counter{}) {
			name := prefix + "." + typeOfT.Field(i).Name
			m.Unregister(f.Interface(), name)
		}
	}
	return
}

// move these to cgroup library
// discover where memory subsystem is mounted

func FindCgroupMount(subsystem string) (string, error) {

	file, err := os.Open("/proc/mounts")
	if err != nil {
		return "", err
	}
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		f := regexp.MustCompile("[\\s]+").Split(scanner.Text(), 6)
		if f[2] == "cgroup" {
			for _, o := range strings.Split(f[3], ",") {
				if o == subsystem {
					return f[1], nil
				}
			}
		}
	}

	return "", errors.New("no cgroup mount found")
}

func FindCgroups(mountpoint string) ([]string, error) {
	cgroups := make([]string, 0, 128)

	_ = filepath.Walk(
		mountpoint,
		func(path string, f os.FileInfo, _ error) error {
			if f.IsDir() && path != mountpoint {
				// skip cgroups with no tasks
				dat, err := ioutil.ReadFile(path + "/" + "tasks")
				if err == nil && len(dat) > 0 {
					cgroups = append(cgroups, path)
				}
			}
			return nil
		})

	return cgroups, nil
}

type ByteSize float64

const (
	_           = iota
	KB ByteSize = 1 << (10 * iota)
	MB
	GB
	TB
	PB
	EB
	ZB
	YB
)

func (b ByteSize) String() string {
	switch {
	case b >= YB:
		return fmt.Sprintf("%.2fYB", b/YB)
	case b >= ZB:
		return fmt.Sprintf("%.2fZB", b/ZB)
	case b >= EB:
		return fmt.Sprintf("%.2fEB", b/EB)
	case b >= PB:
		return fmt.Sprintf("%.2fPB", b/PB)
	case b >= TB:
		return fmt.Sprintf("%.2fTB", b/TB)
	case b >= GB:
		return fmt.Sprintf("%.2fGB", b/GB)
	case b >= MB:
		return fmt.Sprintf("%.2fMB", b/MB)
	case b >= KB:
		return fmt.Sprintf("%.2fKB", b/KB)
	}
	return fmt.Sprintf("%.2fB", b)
}

type BitSize float64

const (
	_          = iota
	Kb BitSize = 1 << (10 * iota)
	Mb
	Gb
	Tb
	Pb
	Eb
	Zb
	Yb
)

func (b BitSize) String() string {
	switch {
	case b >= Yb:
		return fmt.Sprintf("%.2fYb", b/Yb)
	case b >= Zb:
		return fmt.Sprintf("%.2fZb", b/Zb)
	case b >= Eb:
		return fmt.Sprintf("%.2fEb", b/Eb)
	case b >= Pb:
		return fmt.Sprintf("%.2fPb", b/Pb)
	case b >= Tb:
		return fmt.Sprintf("%.2fTb", b/Tb)
	case b >= Gb:
		return fmt.Sprintf("%.2fGb", b/Gb)
	case b >= Mb:
		return fmt.Sprintf("%.2fMb", b/Mb)
	case b >= Kb:
		return fmt.Sprintf("%.2fKb", b/Kb)
	}
	return fmt.Sprintf("%.2fb", b)
}

const (
	CGROUP_BLKIO uint8 = iota
	CGROUP_CPU
	CGROUP_CPUACCT
	CGROUP_CPUSET
	CGROUP_DEVICES
	CGROUP_FREEZER
	CGROUP_MEMORY
	CGROUP_NET_CLS
	CGROUP_NS
)
<commit_msg>docs and general cleanup<commit_after>// Copyright (c) 2014 Square, Inc

package misc

import (
	"bufio"
	"errors"
	"fmt"
	"io/ioutil"
	"math"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"strconv"
	"strings"

	"github.com/square/inspect/metrics"
)

// Interface represents an empty interface
type Interface interface{}

// ParseUint extracts an unsigned integer from input and returns it. Zero
// is returned on error.
func ParseUint(in string) uint64 {
	out, err := strconv.ParseUint(in, 10, 64) // decimal, 64bit
	if err != nil {
		return 0
	}
	return out
}

// ParseFloat extracts a float64 number from input and returns it. math.NaN()
// is returned on error.
func ParseFloat(in string) float64 {
	out, err := strconv.ParseFloat(in, 64) // float, 64bit
	if err != nil {
		return math.NaN()
	}
	return out
}

// ReadUintFromFile extracts an unsigned integer from specified file input. Zero
// is returned on error.
func ReadUintFromFile(path string) uint64 {
	f, err := os.Open(path)
	defer f.Close()
	if err != nil {
		return 0
	}

	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		return ParseUint(scanner.Text())
	}
	return 0
}

// InitializeMetrics initializes all Counters/Gauges types defined for the instance
// with Metrics Context by using reflection
func InitializeMetrics(c Interface, m *metrics.MetricContext, prefix string, register bool) {
	s := reflect.ValueOf(c).Elem()
	typeOfT := s.Type()
	for i := 0; i < s.NumField(); i++ {
		f := s.Field(i)
		if f.Kind().String() != "ptr" {
			continue
		}
		if f.Type().Elem() == reflect.TypeOf(metrics.Gauge{}) {
			name := prefix + "." + typeOfT.Field(i).Name
			g := metrics.NewGauge()
			if register {
				m.Register(g, name)
			}
			f.Set(reflect.ValueOf(g))
		}
		if f.Type().Elem() == reflect.TypeOf(metrics.Counter{}) {
			name := prefix + "." + typeOfT.Field(i).Name
			g := metrics.NewCounter()
			if register {
				m.Register(g, name)
			}
			f.Set(reflect.ValueOf(g))
		}
	}
	return
}

// SetMetrics sets values for all counters/gauges defined
func SetMetrics(m *metrics.MetricContext, s Interface, keys []string, values []string) {
	// Get all fields we care about
	sv := reflect.ValueOf(s).Elem()
	st := sv.Type()
	for i := 0; i < sv.NumField(); i++ {
		metric := sv.Field(i)
		name := st.Field(i).Name
		metricType := metric.Type().String()
		if metricType == "*metrics.Gauge" {
			g := metric.Interface().(*metrics.Gauge)
			strValue, err := extractValue(name, keys, values)
			if err == nil {
				i, err := strconv.ParseInt(strValue, 0, 64)
				if err == nil {
					g.Set(float64(i))
				}
			}
		}
		if metricType == "*metrics.Counter" {
			c := metric.Interface().(*metrics.Counter)
			strValue, err := extractValue(name, keys, values)
			if err == nil {
				c.Set(ParseUint(strValue))
			}
		}
	}
}

// unexported

// find if the metric name we have is present in data we just parsed
func extractValue(name string, keys []string, values []string) (string, error) {
	idx := 0
	for i, key := range keys {
		if key == name {
			idx = i
			break
		}
	}
	if idx < len(values) {
		return values[idx], nil
	}
	return "", errors.New("Not found")
}

// UnregisterMetrics un-registers all counters/gauges defined for the instance
func UnregisterMetrics(c Interface, m *metrics.MetricContext, prefix string) {
	s := reflect.ValueOf(c).Elem()
	typeOfT := s.Type()
	for i := 0; i < s.NumField(); i++ {
		f := s.Field(i)
		if f.Kind().String() != "ptr" {
			continue
		}
		if f.Type().Elem() == reflect.TypeOf(metrics.Gauge{}) ||
			f.Type().Elem() == reflect.TypeOf(metrics.Counter{}) {
			name := prefix + "." + typeOfT.Field(i).Name
			m.Unregister(f.Interface(), name)
		}
	}
	return
}

// FindCgroupMount returns the file system mount point where the input
// subsystem is mounted at.
// TODO: move these to cgroup library
func FindCgroupMount(subsystem string) (string, error) {

	file, err := os.Open("/proc/mounts")
	if err != nil {
		return "", err
	}
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		f := regexp.MustCompile("[\\s]+").Split(scanner.Text(), 6)
		if f[2] == "cgroup" {
			for _, o := range strings.Split(f[3], ",") {
				if o == subsystem {
					return f[1], nil
				}
			}
		}
	}

	return "", errors.New("no cgroup mount found")
}

// FindCgroups returns all cgroups with atleast one active task attached
// for the input subsystem.
func FindCgroups(mountpoint string) ([]string, error) {
	cgroups := make([]string, 0, 128)

	_ = filepath.Walk(
		mountpoint,
		func(path string, f os.FileInfo, _ error) error {
			if f.IsDir() && path != mountpoint {
				// skip cgroups with no tasks
				dat, err := ioutil.ReadFile(path + "/" + "tasks")
				if err == nil && len(dat) > 0 {
					cgroups = append(cgroups, path)
				}
			}
			return nil
		})

	return cgroups, nil
}

// ByteSize represents a float64 with human readable methods
type ByteSize float64

// Constants for different byte sizes
const (
	_           = iota
	KB ByteSize = 1 << (10 * iota)
	MB
	GB
	TB
	PB
	EB
	ZB
	YB
)

// String returns human readable representation of ByteSize
func (b ByteSize) String() string {
	switch {
	case b >= YB:
		return fmt.Sprintf("%.2fYB", b/YB)
	case b >= ZB:
		return fmt.Sprintf("%.2fZB", b/ZB)
	case b >= EB:
		return fmt.Sprintf("%.2fEB", b/EB)
	case b >= PB:
		return fmt.Sprintf("%.2fPB", b/PB)
	case b >= TB:
		return fmt.Sprintf("%.2fTB", b/TB)
	case b >= GB:
		return fmt.Sprintf("%.2fGB", b/GB)
	case b >= MB:
		return fmt.Sprintf("%.2fMB", b/MB)
	case b >= KB:
		return fmt.Sprintf("%.2fKB", b/KB)
	}
	return fmt.Sprintf("%.2fB", b)
}

// BitSize represents a float64 with methods for human readable output
type BitSize float64

// Constants for different bit sizes
const (
	_          = iota
	Kb BitSize = 1 << (10 * iota)
	Mb
	Gb
	Tb
	Pb
	Eb
	Zb
	Yb
)

// String returns human readable representation of ByteSize
func (b BitSize) String() string {
	switch {
	case b >= Yb:
		return fmt.Sprintf("%.2fYb", b/Yb)
	case b >= Zb:
		return fmt.Sprintf("%.2fZb", b/Zb)
	case b >= Eb:
		return fmt.Sprintf("%.2fEb", b/Eb)
	case b >= Pb:
		return fmt.Sprintf("%.2fPb", b/Pb)
	case b >= Tb:
		return fmt.Sprintf("%.2fTb", b/Tb)
	case b >= Gb:
		return fmt.Sprintf("%.2fGb", b/Gb)
	case b >= Mb:
		return fmt.Sprintf("%.2fMb", b/Mb)
	case b >= Kb:
		return fmt.Sprintf("%.2fKb", b/Kb)
	}
	return fmt.Sprintf("%.2fb", b)
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"sort"
	"time"

	"github.com/gonuts/binary"
	"github.com/hashicorp/serf/client"
)

type serfMasterElector struct {
	ConfigVersion int64
	MasterState   <-chan bool // Submits the current master state as soon as it changes
	iAmMaster     bool
	masterState   chan bool
	members       []memberNode
	MyName        string
	myStart       int64
	serfClient    *client.RPCClient
}

type memberInfo struct {
	ConfigVersion int64
	Name          string
	StartTime     int64
}

type memberNode struct {
	LastContact time.Time
	Info        *memberInfo
}

type byStartTime []memberNode

func (bst byStartTime) Len() int      { return len(bst) }
func (bst byStartTime) Swap(i, j int) { bst[i], bst[j] = bst[j], bst[i] }
func (bst byStartTime) Less(i, j int) bool {
	if bst[i].Info.ConfigVersion < bst[j].Info.ConfigVersion {
		// If i has an older config version than j rank it below
		return false
	} else if bst[i].Info.ConfigVersion > bst[j].Info.ConfigVersion {
		// If the config version is bigger, rank it up
		return true
	}
	// If the config version is identical, bigger uptime (=lesser start time) wins
	return bst[i].Info.StartTime < bst[j].Info.StartTime
}

func newSerfMasterElector() *serfMasterElector {
	stateChan := make(chan bool, 1)
	return &serfMasterElector{
		ConfigVersion: 0,
		MasterState:   stateChan,
		iAmMaster:     false,
		masterState:   stateChan,
	}
}

func (s *serfMasterElector) marshal(v interface{}) []byte {
	res, err := binary.Marshal(v)
	if err != nil {
		log.Fatal(err)
	}
	return res
}

func (s *serfMasterElector) unmarshal(b []byte, v interface{}) {
	err := binary.Unmarshal(b, v)
	if err != nil {
		log.Fatal(err)
	}
}

func (s *serfMasterElector) handleMasterElectionMessage(info *memberInfo) {
	member := memberNode{
		Info:        info,
		LastContact: time.Now(),
	}
	s.members = append(s.members, member)
	s.doMasterElection()
}

func (s *serfMasterElector) handleMemberQuitMessage(member string) {
	newMembers := []memberNode{}
	for _, v := range s.members {
		if v.Info.Name != member {
			newMembers = append(newMembers, v)
		}
	}
	s.members = newMembers
	s.doMasterElection()
}

func (s *serfMasterElector) doMasterElection() {
	newMembers := []memberNode{}
	for _, v := range s.members {
		if time.Now().Sub(v.LastContact) < time.Second*15 {
			newMembers = append(newMembers, v)
		}
	}
	s.members = newMembers

	sort.Sort(byStartTime(s.members))
	newState := s.members[0].Info.Name == s.MyName
	if newState != s.iAmMaster {
		s.masterState <- newState
	}
	s.iAmMaster = newState
	log.Printf("AmIMaster? %v", s.iAmMaster)
}

func (s *serfMasterElector) Run(serfAddress string) {
	s.myStart = time.Now().Unix()

	serfClient, err := client.NewRPCClient(serfAddress)
	if err != nil {
		log.Fatal(err)
	}

	msgChan := make(chan map[string]interface{}, 5)
	tick := time.NewTicker(time.Second * 10).C

	serfClient.Stream("", msgChan)

	stats, _ := serfClient.Stats()
	s.MyName = stats["agent"]["name"]

	defer serfClient.UserEvent("MemberQuit", s.marshal(s.MyName), false)

	for {
		select {
		case msg := <-msgChan:
			switch {
			case msg["Event"] == "user" && msg["Name"] == "MasterElection":
				payload := memberInfo{}
				s.unmarshal(msg["Payload"].([]byte), &payload)
				log.Printf("MasterElection: %s %s", payload.Name, payload.StartTime)
				s.handleMasterElectionMessage(&payload)
			case msg["Event"] == "user" && msg["Name"] == "MemberQuit":
				var name string
				s.unmarshal(msg["Payload"].([]byte), &name)
				s.handleMemberQuitMessage(name)
			default:
				log.Printf("Message: %q\n", msg)
			}
		case <-tick:
			serfClient.UserEvent("MasterElection", s.marshal(&memberInfo{
				ConfigVersion: s.ConfigVersion,
				Name:          s.MyName,
				StartTime:     s.myStart,
			}), false)
		}
	}

	err = serfClient.Close()
	if err != nil {
		log.Fatal(err)
	}
}

func (s *serfMasterElector) IsMaster() bool {
	return s.iAmMaster
}
<commit_msg>Made output of serf module optional<commit_after>package main

import (
	"log"
	"sort"
	"time"

	"github.com/gonuts/binary"
	"github.com/hashicorp/serf/client"
)

type serfMasterElector struct {
	ConfigVersion int64
	Debug         bool
	MasterState   <-chan bool // Submits the current master state as soon as it changes
	iAmMaster     bool
	masterState   chan bool
	members       []memberNode
	MyName        string
	myStart       int64
	serfClient    *client.RPCClient
}

type memberInfo struct {
	ConfigVersion int64
	Name          string
	StartTime     int64
}

type memberNode struct {
	LastContact time.Time
	Info        *memberInfo
}

type byStartTime []memberNode

func (bst byStartTime) Len() int      { return len(bst) }
func (bst byStartTime) Swap(i, j int) { bst[i], bst[j] = bst[j], bst[i] }
func (bst byStartTime) Less(i, j int) bool {
	if bst[i].Info.ConfigVersion < bst[j].Info.ConfigVersion {
		// If i has an older config version than j rank it below
		return false
	} else if bst[i].Info.ConfigVersion > bst[j].Info.ConfigVersion {
		// If the config version is bigger, rank it up
		return true
	}
	// If the config version is identical, bigger uptime (=lesser start time) wins
	return bst[i].Info.StartTime < bst[j].Info.StartTime
}

func newSerfMasterElector() *serfMasterElector {
	stateChan := make(chan bool, 1)
	return &serfMasterElector{
		ConfigVersion: 0,
		Debug:         false,
		MasterState:   stateChan,
		iAmMaster:     false,
		masterState:   stateChan,
	}
}

func (s *serfMasterElector) marshal(v interface{}) []byte {
	res, err := binary.Marshal(v)
	if err != nil {
		log.Fatal(err)
	}
	return res
}

func (s *serfMasterElector) unmarshal(b []byte, v interface{}) {
	err := binary.Unmarshal(b, v)
	if err != nil {
		log.Fatal(err)
	}
}

func (s *serfMasterElector) handleMasterElectionMessage(info *memberInfo) {
	member := memberNode{
		Info:        info,
		LastContact: time.Now(),
	}
	s.members = append(s.members, member)
	s.doMasterElection()
}

func (s *serfMasterElector) handleMemberQuitMessage(member string) {
	newMembers := []memberNode{}
	for _, v := range s.members {
		if v.Info.Name != member {
			newMembers = append(newMembers, v)
		}
	}
	s.members = newMembers
	s.doMasterElection()
}

func (s *serfMasterElector) doMasterElection() {
	newMembers := []memberNode{}
	for _, v := range s.members {
		if time.Now().Sub(v.LastContact) < time.Second*15 {
			newMembers = append(newMembers, v)
		}
	}
	s.members = newMembers

	sort.Sort(byStartTime(s.members))
	newState := s.members[0].Info.Name == s.MyName
	if newState != s.iAmMaster {
		s.masterState <- newState
	}
	s.iAmMaster = newState
	if s.Debug {
		log.Printf("AmIMaster? %v", s.iAmMaster)
	}
}

func (s *serfMasterElector) Run(serfAddress string) {
	s.myStart = time.Now().Unix()

	serfClient, err := client.NewRPCClient(serfAddress)
	if err != nil {
		log.Fatal(err)
	}

	msgChan := make(chan map[string]interface{}, 5)
	tick := time.NewTicker(time.Second * 10).C

	serfClient.Stream("", msgChan)

	stats, _ := serfClient.Stats()
	s.MyName = stats["agent"]["name"]

	defer serfClient.UserEvent("MemberQuit", s.marshal(s.MyName), false)

	for {
		select {
		case msg := <-msgChan:
			switch {
			case msg["Event"] == "user" && msg["Name"] == "MasterElection":
				payload := memberInfo{}
				s.unmarshal(msg["Payload"].([]byte), &payload)
				if s.Debug {
					log.Printf("MasterElection: %s %s", payload.Name, payload.StartTime)
				}
				s.handleMasterElectionMessage(&payload)
			case msg["Event"] == "user" && msg["Name"] == "MemberQuit":
				var name string
				s.unmarshal(msg["Payload"].([]byte), &name)
				s.handleMemberQuitMessage(name)
			default:
				if s.Debug {
					log.Printf("Message: %q\n", msg)
				}
			}
		case <-tick:
			serfClient.UserEvent("MasterElection", s.marshal(&memberInfo{
				ConfigVersion: s.ConfigVersion,
				Name:          s.MyName,
				StartTime:     s.myStart,
			}), false)
		}
	}

	err = serfClient.Close()
	if err != nil {
		log.Fatal(err)
	}
}

func (s *serfMasterElector) IsMaster() bool {
	return s.iAmMaster
}
<|endoftext|>


<commit_before>package main

import (
	"strings"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/docker/swarm/discovery"
)

func join(c *cli.Context) {

	if c.String("discovery") == "" {
		log.Fatal("--discovery required to join a cluster")
	}

	d, err := discovery.New(c.String("discovery"), c.Int("heartbeat"))
	if err != nil {
		log.Fatal(err)
	}

	addr := c.String("addr")
	addrParts := strings.SplitN(addr, ":", 2)
	if len(addrParts) != 2 {
		log.Fatal("--addr should be of the form ip:port")
	}

	if err := d.Register(addr); err != nil {
		log.Fatal(err)
	}

	hb := time.Duration(c.Int("heartbeat"))
	for {
		time.Sleep(hb * time.Second)
		if err := d.Register(c.String("addr")); err != nil {
			log.Error(err)
		}
	}
}
<commit_msg>improve addr validation<commit_after>package main

import (
	"regexp"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/docker/swarm/discovery"
)

func join(c *cli.Context) {

	if c.String("discovery") == "" {
		log.Fatal("--discovery required to join a cluster")
	}

	d, err := discovery.New(c.String("discovery"), c.Int("heartbeat"))
	if err != nil {
		log.Fatal(err)
	}

	addr := c.String("addr")
	if m, _ := regexp.MatchString("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}:[0-9]{1,5}$", addr); !m {
		log.Fatal("--addr should be of the form ip:port")
	}

	if err := d.Register(addr); err != nil {
		log.Fatal(err)
	}

	hb := time.Duration(c.Int("heartbeat"))
	for {
		time.Sleep(hb * time.Second)
		if err := d.Register(c.String("addr")); err != nil {
			log.Error(err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"io/ioutil"
	"log"
	"math"
	"os"
	"sort"
	"strconv"
	"text/template"
)

type Site struct {
	Config Config
	Posts  []Post
}

var site Site

func newSite(cfg Config) Site {
	site = Site{Config: cfg}
	return site
}

func (s Site) generateSite() {
	// Delete the site folder and create it again
	if err := os.RemoveAll(s.Config.Public); err != nil {
		log.Fatal(err)
	}
	if err := os.Mkdir(s.Config.Public, 0755); err != nil {
		log.Fatal(err)
	}

	// Get all the posts and convert them
	dirlist, err := ioutil.ReadDir(s.Config.Posts)
	if err != nil {
		log.Fatal(err)
	}

	for _, f := range dirlist {
		// load the post
		p := loadPost(s.Config.Posts + "/" + f.Name())

		// Add the post to post slice
		s.Posts = append(s.Posts, p)

		// create the path
		if err := os.MkdirAll(s.Config.Public+p.Permalink, 0755); err != nil {
			log.Fatal(err)
		}

		// convert & write
		if err := ioutil.WriteFile(s.Config.Public+p.Permalink+"index.html", []byte(p.convertPost()), 0755); err != nil {
			log.Fatal(err)
		}
	}

	// Sort the posts by date
	sort.Sort(ByDate(s.Posts))

	// Copy all necessary to the site folder (css, js and assets)
	if err := copyDir(s.Config.Templates+"/css", s.Config.Public+"/css"); err != nil {
		log.Fatal(err)
	}
	if err := copyDir(s.Config.Templates+"/js", s.Config.Public+"/js"); err != nil {
		log.Fatal(err)
	}
	if err := copyDir(s.Config.Templates+"/fonts", s.Config.Public+"/fonts"); err != nil {
		log.Fatal(err)
	}
	if err := copyDir(s.Config.Templates+"/images", s.Config.Public+"/images"); err != nil {
		log.Fatal(err)
	}

	// Generate the index main page
	index := s.generateIndex()
	if err := ioutil.WriteFile(s.Config.Public+"/index.html", []byte(index[0]), 0755); err != nil {
		log.Fatal(err)
	}

	index = index[1:len(index)]

	// Now the rest of the pages (if existent)
	if len(index) <= 0 {
		return
	}

	for i, page := range index {
		path := s.Config.Public + "/p/" + strconv.Itoa(i+1)
		if err := os.MkdirAll(path, 0755); err != nil {
			log.Fatal(err)
		}

		if err := ioutil.WriteFile(path+"/index.html", []byte(page), 0755); err != nil {
			log.Fatal(err)
		}
	}
}

func (s Site) generateIndex() []string {
	var htmlPages []string

	// Read the index template used and parse it
	template_file := s.Config.Templates + "/index.html"
	layout, err := ioutil.ReadFile(template_file)
	if err != nil {
		log.Fatal(err)
	}
	indexTemplate := template.Must(template.New("index").Parse(string(layout)))

	// Pagination
	pages := int(math.Ceil(float64(len(s.Posts)) / float64(s.Config.PostsPerPage)))

	for i := 0; i < pages; i++ {
		var st, ed int
		var next, prev string

		posts := i*s.Config.PostsPerPage + s.Config.PostsPerPage
		if posts >= len(s.Posts) {
			st = i * s.Config.PostsPerPage
			ed = len(s.Posts)
		} else {
			st = i * s.Config.PostsPerPage
			ed = i*s.Config.PostsPerPage + s.Config.PostsPerPage
		}

		next = "/p/" + strconv.Itoa(i+1)
		prev = "/p/" + strconv.Itoa(i-1)

		switch {
		case i <= 0:
			prev = ""
		case i >= pages-1:
			next = ""
		case i == 1:
			prev = "/"
		}

		data := struct {
			Config       Config
			Posts        []Post
			PreviousPage string
			NextPage     string
		}{
			s.Config,
			s.Posts[st:ed],
			prev,
			next,
		}

		// Run the template
		htmlIndex := &bytes.Buffer{}
		if err := indexTemplate.Execute(htmlIndex, data); err != nil {
			log.Fatal(err)
		}

		htmlPages = append(htmlPages, htmlIndex.String())

	}

	return htmlPages
}
<commit_msg>Fixed paginator<commit_after>package main

import (
	"bytes"
	"io/ioutil"
	"log"
	"math"
	"os"
	"sort"
	"strconv"
	"text/template"
)

type Site struct {
	Config Config
	Posts  []Post
}

var site Site

func newSite(cfg Config) Site {
	site = Site{Config: cfg}
	return site
}

func (s Site) generateSite() {
	// Delete the site folder and create it again
	if err := os.RemoveAll(s.Config.Public); err != nil {
		log.Fatal(err)
	}
	if err := os.Mkdir(s.Config.Public, 0755); err != nil {
		log.Fatal(err)
	}

	// Get all the posts and convert them
	dirlist, err := ioutil.ReadDir(s.Config.Posts)
	if err != nil {
		log.Fatal(err)
	}

	for _, f := range dirlist {
		// load the post
		p := loadPost(s.Config.Posts + "/" + f.Name())

		// Add the post to post slice
		s.Posts = append(s.Posts, p)

		// create the path
		if err := os.MkdirAll(s.Config.Public+p.Permalink, 0755); err != nil {
			log.Fatal(err)
		}

		// convert & write
		if err := ioutil.WriteFile(s.Config.Public+p.Permalink+"index.html", []byte(p.convertPost()), 0755); err != nil {
			log.Fatal(err)
		}
	}

	// Sort the posts by date
	sort.Sort(ByDate(s.Posts))

	// Copy all necessary to the site folder (css, js and assets)
	if err := copyDir(s.Config.Templates+"/css", s.Config.Public+"/css"); err != nil {
		log.Fatal(err)
	}
	if err := copyDir(s.Config.Templates+"/js", s.Config.Public+"/js"); err != nil {
		log.Fatal(err)
	}
	if err := copyDir(s.Config.Templates+"/fonts", s.Config.Public+"/fonts"); err != nil {
		log.Fatal(err)
	}
	if err := copyDir(s.Config.Templates+"/images", s.Config.Public+"/images"); err != nil {
		log.Fatal(err)
	}

	// Generate the index main page
	index := s.generateIndex()
	if err := ioutil.WriteFile(s.Config.Public+"/index.html", []byte(index[0]), 0755); err != nil {
		log.Fatal(err)
	}

	index = index[1:len(index)]

	// Now the rest of the pages (if existent)
	if len(index) <= 0 {
		return
	}

	for i, page := range index {
		path := s.Config.Public + "/p/" + strconv.Itoa(i+1)
		if err := os.MkdirAll(path, 0755); err != nil {
			log.Fatal(err)
		}

		if err := ioutil.WriteFile(path+"/index.html", []byte(page), 0755); err != nil {
			log.Fatal(err)
		}
	}
}

func (s Site) generateIndex() []string {
	var htmlPages []string

	// Read the index template used and parse it
	template_file := s.Config.Templates + "/index.html"
	layout, err := ioutil.ReadFile(template_file)
	if err != nil {
		log.Fatal(err)
	}
	indexTemplate := template.Must(template.New("index").Parse(string(layout)))

	// Pagination
	pages := int(math.Ceil(float64(len(s.Posts)) / float64(s.Config.PostsPerPage)))

	for i := 0; i < pages; i++ {
		var st, ed int
		var next, prev string

		posts := i*s.Config.PostsPerPage + s.Config.PostsPerPage
		if posts >= len(s.Posts) {
			st = i * s.Config.PostsPerPage
			ed = len(s.Posts)
		} else {
			st = i * s.Config.PostsPerPage
			ed = i*s.Config.PostsPerPage + s.Config.PostsPerPage
		}

		next = "/p/" + strconv.Itoa(i+1)
		prev = "/p/" + strconv.Itoa(i-1)

		switch {
		// First page
		case i <= 0:
			prev = ""
		// Second page when = 2 pages
		case i-1 == 0 && i >= pages-1:
			prev = "/"
			next = ""
		// Second page
		case i-1 == 0:
			prev = "/"
		// Last page
		case i >= pages-1:
			next = ""
		}

		data := struct {
			Config       Config
			Posts        []Post
			PreviousPage string
			NextPage     string
		}{
			s.Config,
			s.Posts[st:ed],
			prev,
			next,
		}

		// Run the template
		htmlIndex := &bytes.Buffer{}
		if err := indexTemplate.Execute(htmlIndex, data); err != nil {
			log.Fatal(err)
		}

		htmlPages = append(htmlPages, htmlIndex.String())

	}

	return htmlPages
}
<|endoftext|>


<commit_before>package toolbox

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"strings"
)

//IsCompleteJSON returns true if supplied represent complete JSON
func IsCompleteJSON(candidate string) bool {
	candidate = strings.Trim(candidate, "\n \t\r")
	if candidate == "" {
		return false
	}
	curlyStart := strings.Count(candidate, "{")
	curlyEnd := strings.Count(candidate, "}")
	squareStart := strings.Count(candidate, "[")
	squareEnd := strings.Count(candidate, "]")
	if !(curlyStart == curlyEnd && squareStart == squareEnd) {
		return false
	}
	var err error
	if strings.HasPrefix(candidate, "{") {
		_, err = JSONToMap(candidate)
	} else {
		_, err = JSONToSlice(candidate)
	}
	return err == nil
}

//NewLineDelimitedJSON returns JSON for supplied multi line JSON
func NewLineDelimitedJSON(candidate string) ([]interface{}, error) {
	var result = make([]interface{}, 0)
	lines := getMultilineContent(candidate)
	for _, line := range lines {
		aStruct, err := JSONToInterface(line)
		if err != nil {
			return nil, err
		}
		result = append(result, aStruct)
	}
	return result, nil
}

func getMultilineContent(multiLineText string) []string {
	multiLineText = strings.TrimSpace(multiLineText)
	if multiLineText == "" {
		return []string{}
	}
	lines := strings.Split(multiLineText, "\n")
	var result = make([]string, 0)
	for _, line := range lines {
		if strings.Trim(line, " \r") == "" {
			continue
		}
		result = append(result, line)
	}
	return result
}

//IsNewLineDelimitedJSON returns true if supplied content is multi line delimited JSON
func IsNewLineDelimitedJSON(candidate string) bool {
	lines := getMultilineContent(candidate)
	if len(lines) <= 1 {
		return false
	}
	return IsCompleteJSON(lines[0]) && IsCompleteJSON(lines[1])
}

//JSONToInterface converts JSON source to an interface (either map or slice)
func JSONToInterface(source interface{}) (interface{}, error) {
	var reader io.Reader
	switch value := source.(type) {
	case io.Reader:
		reader = value
	case []byte:
		reader = bytes.NewReader(value)
	case string:
		reader = strings.NewReader(value)
	default:
		return nil, fmt.Errorf("unsupported type: %T", source)
	}
	var result interface{}
	if content, err := ioutil.ReadAll(reader); err == nil {
		text := string(content)
		if IsNewLineDelimitedJSON(text) {
			return NewLineDelimitedJSON(text)
		}
		reader = strings.NewReader(text)
	}
	err := jsonDecoderFactory{}.Create(reader).Decode(&result)
	return result, err
}

//JSONToMap converts JSON source into map
func JSONToMap(source interface{}) (map[string]interface{}, error) {
	var reader io.Reader
	switch value := source.(type) {
	case io.Reader:
		reader = value
	case []byte:
		reader = bytes.NewReader(value)
	case string:
		reader = strings.NewReader(value)
	default:
		return nil, fmt.Errorf("unsupported type: %T", source)
	}
	var result = make(map[string]interface{})
	err := jsonDecoderFactory{}.Create(reader).Decode(&result)
	return result, err
}

//JSONToSlice converts JSON source into slice
func JSONToSlice(source interface{}) ([]interface{}, error) {
	var reader io.Reader
	switch value := source.(type) {
	case io.Reader:
		reader = value
	case []byte:
		reader = bytes.NewReader(value)
	case string:
		reader = strings.NewReader(value)
	default:
		return nil, fmt.Errorf("unsupported type: %T", source)
	}
	var result = make([]interface{}, 0)
	err := jsonDecoderFactory{}.Create(reader).Decode(&result)
	return result, err
}

//AsJSONText converts data structure int text JSON
func AsJSONText(source interface{}) (string, error) {
	if IsStruct(source) || IsMap(source) || IsSlice(source) {
		buf := new(bytes.Buffer)
		err := NewJSONEncoderFactory().Create(buf).Encode(source)
		return buf.String(), err
	}
	return "", fmt.Errorf("unsupported type: %T", source)
}
<commit_msg>added printindentJSON<commit_after>package toolbox

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"strings"
	"encoding/json"
)

//IsCompleteJSON returns true if supplied represent complete JSON
func IsCompleteJSON(candidate string) bool {
	candidate = strings.Trim(candidate, "\n \t\r")
	if candidate == "" {
		return false
	}
	curlyStart := strings.Count(candidate, "{")
	curlyEnd := strings.Count(candidate, "}")
	squareStart := strings.Count(candidate, "[")
	squareEnd := strings.Count(candidate, "]")
	if !(curlyStart == curlyEnd && squareStart == squareEnd) {
		return false
	}
	var err error
	if strings.HasPrefix(candidate, "{") {
		_, err = JSONToMap(candidate)
	} else {
		_, err = JSONToSlice(candidate)
	}
	return err == nil
}

//NewLineDelimitedJSON returns JSON for supplied multi line JSON
func NewLineDelimitedJSON(candidate string) ([]interface{}, error) {
	var result = make([]interface{}, 0)
	lines := getMultilineContent(candidate)
	for _, line := range lines {
		aStruct, err := JSONToInterface(line)
		if err != nil {
			return nil, err
		}
		result = append(result, aStruct)
	}
	return result, nil
}

func getMultilineContent(multiLineText string) []string {
	multiLineText = strings.TrimSpace(multiLineText)
	if multiLineText == "" {
		return []string{}
	}
	lines := strings.Split(multiLineText, "\n")
	var result = make([]string, 0)
	for _, line := range lines {
		if strings.Trim(line, " \r") == "" {
			continue
		}
		result = append(result, line)
	}
	return result
}

//IsNewLineDelimitedJSON returns true if supplied content is multi line delimited JSON
func IsNewLineDelimitedJSON(candidate string) bool {
	lines := getMultilineContent(candidate)
	if len(lines) <= 1 {
		return false
	}
	return IsCompleteJSON(lines[0]) && IsCompleteJSON(lines[1])
}

//JSONToInterface converts JSON source to an interface (either map or slice)
func JSONToInterface(source interface{}) (interface{}, error) {
	var reader io.Reader
	switch value := source.(type) {
	case io.Reader:
		reader = value
	case []byte:
		reader = bytes.NewReader(value)
	case string:
		reader = strings.NewReader(value)
	default:
		return nil, fmt.Errorf("unsupported type: %T", source)
	}
	var result interface{}
	if content, err := ioutil.ReadAll(reader); err == nil {
		text := string(content)
		if IsNewLineDelimitedJSON(text) {
			return NewLineDelimitedJSON(text)
		}
		reader = strings.NewReader(text)
	}
	err := jsonDecoderFactory{}.Create(reader).Decode(&result)
	return result, err
}

//JSONToMap converts JSON source into map
func JSONToMap(source interface{}) (map[string]interface{}, error) {
	var reader io.Reader
	switch value := source.(type) {
	case io.Reader:
		reader = value
	case []byte:
		reader = bytes.NewReader(value)
	case string:
		reader = strings.NewReader(value)
	default:
		return nil, fmt.Errorf("unsupported type: %T", source)
	}
	var result = make(map[string]interface{})
	err := jsonDecoderFactory{}.Create(reader).Decode(&result)
	return result, err
}

//JSONToSlice converts JSON source into slice
func JSONToSlice(source interface{}) ([]interface{}, error) {
	var reader io.Reader
	switch value := source.(type) {
	case io.Reader:
		reader = value
	case []byte:
		reader = bytes.NewReader(value)
	case string:
		reader = strings.NewReader(value)
	default:
		return nil, fmt.Errorf("unsupported type: %T", source)
	}
	var result = make([]interface{}, 0)
	err := jsonDecoderFactory{}.Create(reader).Decode(&result)
	return result, err
}

//AsJSONText converts data structure int text JSON
func AsJSONText(source interface{}) (string, error) {
	if IsStruct(source) || IsMap(source) || IsSlice(source) {
		buf := new(bytes.Buffer)
		err := NewJSONEncoderFactory().Create(buf).Encode(source)
		return buf.String(), err
	}
	return "", fmt.Errorf("unsupported type: %T", source)
}

//AsIndentJSONText converts data structure int text JSON
func AsIndentJSONText(source interface{}) (string, error) {
	if IsStruct(source) || IsMap(source) || IsSlice(source) {
		buf, err := json.MarshalIndent(source, "", "\t")
		if err != nil {
			return "", err
		}
		return string(buf), nil
	}
	return "", fmt.Errorf("unsupported type: %T", source)
}
<|endoftext|>