<commit_before>package qtypes_plugin

import (
	"fmt"
	"log"
	"strconv"
	"strings"
	"github.com/pkg/errors"
	"github.com/zpatrick/go-config"

	"github.com/qframe/types/helper"
	"github.com/qframe/types/qchannel"
	"github.com/qframe/types/ticker"
)

const (
	version = "0.1.3"
)

type Base struct {
	BaseVersion 	string
	Version 		string
	QChan 			qtypes_qchannel.QChan
	Cfg 			*config.Config
	MyID			int
	Typ				string
	Pkg				string
	Name 			string
	LogOnlyPlugs 	[]string
	MsgCount		map[string]float64
	LocalCfg 		map[string]string

}

func NewBase(qChan qtypes_qchannel.QChan, cfg *config.Config) Base {
	b := Base{
		QChan: qChan,
		Cfg: cfg,
		LogOnlyPlugs:   []string{},
		MsgCount:       map[string]float64{
			"received": 0.0,
			"loopDrop": 0.0,
			"inputDrop": 0.0,
			"successDrop": 0.0,
		},
	}
	b.LocalCfg, _  = cfg.Settings()
	logPlugs, err := cfg.String("log.only-plugins")
	if err == nil {
		b.LogOnlyPlugs = strings.Split(logPlugs, ",")
	}
	return b
}

func (p *Base) CfgString(path string) (string, error) {
	key := fmt.Sprintf("%s.%s.%s", p.Typ, p.Name, path)
	if res, ok := p.LocalCfg[key]; ok {
		return res, nil
	}
	if res, ok := p.LocalCfg[path]; ok {
		return res, nil
	}
	return "", errors.New("Could not find "+key)
}

func (p *Base) CfgStringOr(path, alt string) string {
	res, err := p.CfgString(path)
	if err != nil {
		return alt
	}
	return res
}

func (p *Base) CfgInt(path string) (int, error) {
	key := fmt.Sprintf("%s.%s.%s", p.Typ, p.Name, path)
	if res, ok := p.LocalCfg[key]; ok {
		return strconv.Atoi(res)
	}
	return 0, errors.New("Could not find "+key)
}

func (p *Base) CfgIntOr(path string, alt int) int {
	res, err := p.CfgInt(path)
	if err != nil {
		return alt
	}
	return res
}

func (p *Base) CfgBool(path string) (bool, error) {
	key := fmt.Sprintf("%s.%s.%s", p.Typ, p.Name, path)
	if res, ok := p.LocalCfg[key]; ok {
		switch res {
		case "true":
			return true, nil
		case "false":
			return false, nil
		default:
			return false, errors.New(fmt.Sprintf("Key '%s' neither false not true, but %s: ", key, res))

		}
	}
	return false, errors.New("Could not find "+key)
}

func (p *Base) CfgBoolOr(path string, alt bool) bool {
	res, err := p.CfgBool(path)
	if err != nil {
		return alt
	}
	return res
}

func (p *Base) GetInputs() (res []string) {
	inStr, err := p.CfgString("inputs")
	if err == nil {
		res = strings.Split(inStr, ",")
	}
	return res
}

func (p *Base) GetCfgItems(key string) []string {
	inStr, err := p.CfgString(key)
	if err != nil {
		inStr = ""
	}
	return strings.Split(inStr, ",")
}

func (p *Base) Log(logLevel, msg string) {
	if len(p.LogOnlyPlugs) != 0 && ! qtypes_helper.IsItem(p.LogOnlyPlugs, p.Name) {
		return
	}
	// TODO: Setup in each Log() invocation seems rude
	log.SetFlags(log.LstdFlags | log.Lmicroseconds)
	dL, _ := p.Cfg.StringOr("log.level", "info")
	dI := qtypes_helper.LogStrToInt(dL)
	lI := qtypes_helper.LogStrToInt(logLevel)
	lMsg := fmt.Sprintf("[%+6s] %15s Name:%-10s >> %s", strings.ToUpper(logLevel), p.Pkg, p.Name, msg)
	if lI == 0 {
		log.Panic(lMsg)
	} else if dI >= lI {
		log.Println(lMsg)
	}
}

func (p *Base) StartTicker(name string, durMs int) qtypes_ticker.Ticker {
	p.Log("info", fmt.Sprintf("Start ticker '%s' with duration of %dms", name, durMs))
	ticker := qtypes_ticker.NewTicker(name, durMs)
	go ticker.DispatchTicker(p.QChan)
	return ticker
}

/*
func (p *Base) DispatchMsgCount() {

	tickMs := p.CfgIntOr("count-ticker-ms", 5000)
	p.Log("info", fmt.Sprintf("Dispatch goroutine to send MsgCount every %dms", tickMs))
	ticker := time.NewTicker(time.Duration(tickMs)*time.Millisecond).C
	pre := map[string]float64{}
	for {
		tick := <-ticker
		pre = p.SendMsgCount(tick, pre)
	}
}

func (p *Base) SendMsgCount(tick time.Time, pre map[string]float64) map[string]float64 {
	dims := map[string]string{
		"plugin_name": p.Name,
		"plugin_version": p.Version,
		"plugin_type": p.Typ,
	}
	qm := NewExt(p.Name, "none", Counter, 0.0, dims, tick, false)
	for k,v := range p.MsgCount {
		if _, ok := pre[k]; !ok {
			pre[k] = v
		} else if pre[k] == v {
			continue
		}
		qm.Name = fmt.Sprintf("msg.%s", k)
		p.Log("debug", fmt.Sprintf("Send MsgCount %s=%f", qm.Name,v))
		qm.Value = float64(v)
		p.QChan.SendData(qm)
	}
	return pre
}
*/<commit_msg>missed to put the BaseVersion into the NewBase()<commit_after>package qtypes_plugin

import (
	"fmt"
	"log"
	"strconv"
	"strings"
	"github.com/pkg/errors"
	"github.com/zpatrick/go-config"

	"github.com/qframe/types/helper"
	"github.com/qframe/types/qchannel"
	"github.com/qframe/types/ticker"
)

const (
	version = "0.1.3"
)

type Base struct {
	BaseVersion 	string
	Version 		string
	QChan 			qtypes_qchannel.QChan
	Cfg 			*config.Config
	MyID			int
	Typ				string
	Pkg				string
	Name 			string
	LogOnlyPlugs 	[]string
	MsgCount		map[string]float64
	LocalCfg 		map[string]string

}

func NewBase(qChan qtypes_qchannel.QChan, cfg *config.Config) Base {
	b := Base{
		BaseVersion: version,
		QChan: qChan,
		Cfg: cfg,
		LogOnlyPlugs:   []string{},
		MsgCount:       map[string]float64{
			"received": 0.0,
			"loopDrop": 0.0,
			"inputDrop": 0.0,
			"successDrop": 0.0,
		},
	}
	b.LocalCfg, _  = cfg.Settings()
	logPlugs, err := cfg.String("log.only-plugins")
	if err == nil {
		b.LogOnlyPlugs = strings.Split(logPlugs, ",")
	}
	return b
}

func (p *Base) CfgString(path string) (string, error) {
	key := fmt.Sprintf("%s.%s.%s", p.Typ, p.Name, path)
	if res, ok := p.LocalCfg[key]; ok {
		return res, nil
	}
	if res, ok := p.LocalCfg[path]; ok {
		return res, nil
	}
	return "", errors.New("Could not find "+key)
}

func (p *Base) CfgStringOr(path, alt string) string {
	res, err := p.CfgString(path)
	if err != nil {
		return alt
	}
	return res
}

func (p *Base) CfgInt(path string) (int, error) {
	key := fmt.Sprintf("%s.%s.%s", p.Typ, p.Name, path)
	if res, ok := p.LocalCfg[key]; ok {
		return strconv.Atoi(res)
	}
	return 0, errors.New("Could not find "+key)
}

func (p *Base) CfgIntOr(path string, alt int) int {
	res, err := p.CfgInt(path)
	if err != nil {
		return alt
	}
	return res
}

func (p *Base) CfgBool(path string) (bool, error) {
	key := fmt.Sprintf("%s.%s.%s", p.Typ, p.Name, path)
	if res, ok := p.LocalCfg[key]; ok {
		switch res {
		case "true":
			return true, nil
		case "false":
			return false, nil
		default:
			return false, errors.New(fmt.Sprintf("Key '%s' neither false not true, but %s: ", key, res))

		}
	}
	return false, errors.New("Could not find "+key)
}

func (p *Base) CfgBoolOr(path string, alt bool) bool {
	res, err := p.CfgBool(path)
	if err != nil {
		return alt
	}
	return res
}

func (p *Base) GetInputs() (res []string) {
	inStr, err := p.CfgString("inputs")
	if err == nil {
		res = strings.Split(inStr, ",")
	}
	return res
}

func (p *Base) GetCfgItems(key string) []string {
	inStr, err := p.CfgString(key)
	if err != nil {
		inStr = ""
	}
	return strings.Split(inStr, ",")
}

func (p *Base) Log(logLevel, msg string) {
	if len(p.LogOnlyPlugs) != 0 && ! qtypes_helper.IsItem(p.LogOnlyPlugs, p.Name) {
		return
	}
	// TODO: Setup in each Log() invocation seems rude
	log.SetFlags(log.LstdFlags | log.Lmicroseconds)
	dL, _ := p.Cfg.StringOr("log.level", "info")
	dI := qtypes_helper.LogStrToInt(dL)
	lI := qtypes_helper.LogStrToInt(logLevel)
	lMsg := fmt.Sprintf("[%+6s] %15s Name:%-10s >> %s", strings.ToUpper(logLevel), p.Pkg, p.Name, msg)
	if lI == 0 {
		log.Panic(lMsg)
	} else if dI >= lI {
		log.Println(lMsg)
	}
}

func (p *Base) StartTicker(name string, durMs int) qtypes_ticker.Ticker {
	p.Log("info", fmt.Sprintf("Start ticker '%s' with duration of %dms", name, durMs))
	ticker := qtypes_ticker.NewTicker(name, durMs)
	go ticker.DispatchTicker(p.QChan)
	return ticker
}

/*
func (p *Base) DispatchMsgCount() {

	tickMs := p.CfgIntOr("count-ticker-ms", 5000)
	p.Log("info", fmt.Sprintf("Dispatch goroutine to send MsgCount every %dms", tickMs))
	ticker := time.NewTicker(time.Duration(tickMs)*time.Millisecond).C
	pre := map[string]float64{}
	for {
		tick := <-ticker
		pre = p.SendMsgCount(tick, pre)
	}
}

func (p *Base) SendMsgCount(tick time.Time, pre map[string]float64) map[string]float64 {
	dims := map[string]string{
		"plugin_name": p.Name,
		"plugin_version": p.Version,
		"plugin_type": p.Typ,
	}
	qm := NewExt(p.Name, "none", Counter, 0.0, dims, tick, false)
	for k,v := range p.MsgCount {
		if _, ok := pre[k]; !ok {
			pre[k] = v
		} else if pre[k] == v {
			continue
		}
		qm.Name = fmt.Sprintf("msg.%s", k)
		p.Log("debug", fmt.Sprintf("Send MsgCount %s=%f", qm.Name,v))
		qm.Value = float64(v)
		p.QChan.SendData(qm)
	}
	return pre
}
*/<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/gopher-net/ipvlan-docker-plugin/plugin/ipvlan"
)

const (
	version      = "0.1"
	ipvlanSocket = "ipvlan.sock"
	pluginPath   = "/usr/share/docker/plugins/"
)

func main() {

	var flagSocket = cli.StringFlag{
		Name:  "socket, s",
		Value: ipvlanSocket, // Move spec file to /run/docker/plugins/ per docker PR #13951
		Usage: "listening unix socket",
	}
	var flagDebug = cli.BoolFlag{
		Name:  "debug, d",
		Usage: "enable debugging",
	}
	app := cli.NewApp()
	app.Name = "ipvlan"
	app.Usage = "IPVlan Docker Libnetwork Plugin  - (all default cli values are overidable using the flags below)"
	app.Version = "0.0.1"
	app.Flags = []cli.Flag{
		flagDebug,
		flagSocket,
		ipvlan.FlagIpvlanEthIface,
		ipvlan.FlagIpVlanMode,
		ipvlan.FlagGateway,
		ipvlan.FlagSubnet,
		ipvlan.FlagMtu,
	}
	app.Before = initEnv
	app.Action = Run
	app.Run(os.Args)
}

func initEnv(ctx *cli.Context) error {
	socketFile := ctx.String("socket")
	// Default loglevel is Info
	if ctx.Bool("debug") {
		log.SetLevel(log.DebugLevel)
	} else {
		log.SetLevel(log.InfoLevel)
	}
	log.SetOutput(os.Stderr)
	initSock(socketFile)
	return nil
}

// Run initializes the driver
func Run(ctx *cli.Context) {
	var d ipvlan.Driver
	var err error
	if d, err = ipvlan.New(version, ctx); err != nil {
		log.Fatalf("unable to create driver: %s", err)
	}
	log.Info("IPVlan network driver initialized successfully")

	// concatenate the absolute path to the spec file handle
	absSocket := fmt.Sprint(pluginPath, ctx.String("socket"))
	if err := d.Listen(absSocket); err != nil {
		log.Fatal(err)
	}
}

// removeSock if an old filehandle exists remove it
func removeSock(absFile string) {
	err := os.RemoveAll(absFile)
	if err != nil {
		log.Fatalf("Unable to remove the old socket file [ %s ] due to: %s", absFile, err)
	}
}

// initSock create the plugin filepath if it does not already exist
func initSock(socketFile string) {
	if err := os.MkdirAll(pluginPath, 0755); err != nil && !os.IsExist(err) {
		log.Warnf("Could not create net plugin path directory: [ %s ]", err)
	}
	// concatenate the absolute path to the spec file handle
	absFile := fmt.Sprint(pluginPath, socketFile)
	// If the plugin socket file already exists, remove it.
	if _, err := os.Stat(absFile); err == nil {
		log.Debugf("socket file [ %s ] already exists, unlinking the old file handle..", absFile)
		removeSock(absFile)
	}
	log.Debugf("The plugin absolute path and handle is [ %s ]", absFile)
}
<commit_msg>Upate the plugin socket file/location <commit_after>package main

import (
	"fmt"
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/gopher-net/ipvlan-docker-plugin/plugin/ipvlan"
)

const (
	version      = "0.1"
	ipvlanSocket = "ipvlan.sock"
	pluginPath   = "/run/docker/plugins/"
)

func main() {

	var flagSocket = cli.StringFlag{
		Name:  "socket, s",
		Value: ipvlanSocket,
		Usage: "listening unix socket",
	}
	var flagDebug = cli.BoolFlag{
		Name:  "debug, d",
		Usage: "enable debugging",
	}
	app := cli.NewApp()
	app.Name = "ipvlan"
	app.Usage = "IPVlan Docker Libnetwork Plugin  - (all default cli values are overidable using the flags below)"
	app.Version = "0.0.1"
	app.Flags = []cli.Flag{
		flagDebug,
		flagSocket,
		ipvlan.FlagIpvlanEthIface,
		ipvlan.FlagIpVlanMode,
		ipvlan.FlagGateway,
		ipvlan.FlagSubnet,
		ipvlan.FlagMtu,
	}
	app.Before = initEnv
	app.Action = Run
	app.Run(os.Args)
}

func initEnv(ctx *cli.Context) error {
	socketFile := ctx.String("socket")
	// Default loglevel is Info
	if ctx.Bool("debug") {
		log.SetLevel(log.DebugLevel)
	} else {
		log.SetLevel(log.InfoLevel)
	}
	log.SetOutput(os.Stderr)
	initSock(socketFile)
	return nil
}

// Run initializes the driver
func Run(ctx *cli.Context) {
	var d ipvlan.Driver
	var err error
	if d, err = ipvlan.New(version, ctx); err != nil {
		log.Fatalf("unable to create driver: %s", err)
	}
	log.Info("IPVlan network driver initialized successfully")

	// concatenate the absolute path to the spec file handle
	absSocket := fmt.Sprint(pluginPath, ctx.String("socket"))
	if err := d.Listen(absSocket); err != nil {
		log.Fatal(err)
	}
}

// removeSock if an old filehandle exists remove it
func removeSock(absFile string) {
	err := os.RemoveAll(absFile)
	if err != nil {
		log.Fatalf("Unable to remove the old socket file [ %s ] due to: %s", absFile, err)
	}
}

// initSock create the plugin filepath if it does not already exist
func initSock(socketFile string) {
	if err := os.MkdirAll(pluginPath, 0755); err != nil && !os.IsExist(err) {
		log.Warnf("Could not create net plugin path directory: [ %s ]", err)
	}
	// concatenate the absolute path to the spec file handle
	absFile := fmt.Sprint(pluginPath, socketFile)
	// If the plugin socket file already exists, remove it.
	if _, err := os.Stat(absFile); err == nil {
		log.Debugf("socket file [ %s ] already exists, unlinking the old file handle..", absFile)
		removeSock(absFile)
	}
	log.Debugf("The plugin absolute path and handle is [ %s ]", absFile)
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"strings"
	"testing"
)

func TestInitialiseKubeconfig(t *testing.T) {

	cmd := make([]string, 2)
	cmd[0] = "install"
	cmd[1] = "--debug"

	plugin := Plugin{
		Config: Config{
			APIServer:     "http://myapiserver",
			Token:         "secret-token",
			HelmCommand:   cmd,
			Namespace:     "default",
			SkipTLSVerify: true,
		},
	}

	configfile := "config3.test"
	initialiseKubeconfig(&plugin.Config, "kubeconfig", configfile)
	data, err := ioutil.ReadFile(configfile)
	if err != nil {
		t.Errorf("Error reading file %v", err)
	}
	kubeConfigStr := string(data)

	if !strings.Contains(kubeConfigStr, "secret-token") {
		t.Errorf("Kubeconfig doesn't render token")
	}
	if !strings.Contains(kubeConfigStr, "http://myapiserver") {
		t.Errorf("Kubeconfig doesn't render APIServer")
	}

}

func TestGetHelmCommand(t *testing.T) {
	plugin := &Plugin{
		Config: Config{
			APIServer:     "http://myapiserver",
			Token:         "secret-token",
			HelmCommand:   nil,
			Namespace:     "default",
			SkipTLSVerify: true,
			Debug:         true,
			DryRun:        true,
			Chart:         "./chart/test",
			Release:       "test-release",
		},
	}
	setHelmCommand(plugin)
	res := strings.Join(plugin.Config.HelmCommand[:], " ")
	expected := "upgrade --install test-release ./chart/test --debug --dry-run"
	if res != expected {
		t.Errorf("Result is %s and we expected %s", res, expected)
	}
}
<commit_msg>add values to test<commit_after>package main

import (
	"io/ioutil"
	"strings"
	"testing"
)

func TestInitialiseKubeconfig(t *testing.T) {

	cmd := make([]string, 2)
	cmd[0] = "install"
	cmd[1] = "--debug"

	plugin := Plugin{
		Config: Config{
			APIServer:     "http://myapiserver",
			Token:         "secret-token",
			HelmCommand:   cmd,
			Namespace:     "default",
			SkipTLSVerify: true,
		},
	}

	configfile := "config3.test"
	initialiseKubeconfig(&plugin.Config, "kubeconfig", configfile)
	data, err := ioutil.ReadFile(configfile)
	if err != nil {
		t.Errorf("Error reading file %v", err)
	}
	kubeConfigStr := string(data)

	if !strings.Contains(kubeConfigStr, "secret-token") {
		t.Errorf("Kubeconfig doesn't render token")
	}
	if !strings.Contains(kubeConfigStr, "http://myapiserver") {
		t.Errorf("Kubeconfig doesn't render APIServer")
	}

}

func TestGetHelmCommand(t *testing.T) {
	plugin := &Plugin{
		Config: Config{
			APIServer:     "http://myapiserver",
			Token:         "secret-token",
			HelmCommand:   nil,
			Namespace:     "default",
			SkipTLSVerify: true,
			Debug:         true,
			DryRun:        true,
			Chart:         "./chart/test",
			Release:       "test-release",
			Values:        "image.tag=v.0.1.0,nameOverride=my-over-app",
		},
	}
	setHelmCommand(plugin)
	res := strings.Join(plugin.Config.HelmCommand[:], " ")
	expected := "upgrade --install test-release ./chart/test --debug --set image.tag=v.0.1.0,nameOverride=my-over-app --dry-run"
	if res != expected {
		t.Errorf("Result is %s and we expected %s", res, expected)
	}
}
<|endoftext|>


<commit_before>package system

import (
	"bufio"
	"bytes"
	"fmt"
	"runtime"

	"github.com/shirou/gopsutil/host"
	"github.com/shirou/gopsutil/load"

	"github.com/influxdata/telegraf"
	"github.com/influxdata/telegraf/plugins/inputs"
)

type SystemStats struct{}

func (_ *SystemStats) Description() string {
	return "Read metrics about system load & uptime"
}

func (_ *SystemStats) SampleConfig() string { return "" }

func (_ *SystemStats) Gather(acc telegraf.Accumulator) error {
	loadavg, err := load.Avg()
	if err != nil {
		return err
	}

	hostinfo, err := host.Info()
	if err != nil {
		return err
	}

	users, err := host.Users()
	if err != nil {
		return err
	}

	acc.AddGauge("system", map[string]interface{}{
		"load1":   loadavg.Load1,
		"load5":   loadavg.Load5,
		"load15":  loadavg.Load15,
		"n_users": len(users),
		"n_cpus":  runtime.NumCPU(),
	}, nil)
	acc.AddCounter("system", map[string]interface{}{
		"uptime":        hostinfo.Uptime,
		"uptime_format": format_uptime(hostinfo.Uptime),
	}, nil)

	return nil
}

func format_uptime(uptime uint64) string {
	buf := new(bytes.Buffer)
	w := bufio.NewWriter(buf)

	days := uptime / (60 * 60 * 24)

	if days != 0 {
		s := ""
		if days > 1 {
			s = "s"
		}
		fmt.Fprintf(w, "%d day%s, ", days, s)
	}

	minutes := uptime / 60
	hours := minutes / 60
	hours %= 24
	minutes %= 60

	fmt.Fprintf(w, "%2d:%02d", hours, minutes)

	w.Flush()
	return buf.String()
}

func init() {
	inputs.Add("system", func() telegraf.Input {
		return &SystemStats{}
	})
}
<commit_msg>Allow using system plugin in Windows (#3127)<commit_after>package system

import (
	"bufio"
	"bytes"
	"fmt"
	"runtime"
	"strings"

	"github.com/shirou/gopsutil/host"
	"github.com/shirou/gopsutil/load"

	"github.com/influxdata/telegraf"
	"github.com/influxdata/telegraf/plugins/inputs"
)

type SystemStats struct{}

func (_ *SystemStats) Description() string {
	return "Read metrics about system load & uptime"
}

func (_ *SystemStats) SampleConfig() string { return "" }

func (_ *SystemStats) Gather(acc telegraf.Accumulator) error {
	loadavg, err := load.Avg()
	if err != nil && !strings.Contains(err.Error(), "not implemented") {
		return err
	}

	hostinfo, err := host.Info()
	if err != nil {
		return err
	}

	users, err := host.Users()
	if err != nil {
		return err
	}

	acc.AddGauge("system", map[string]interface{}{
		"load1":   loadavg.Load1,
		"load5":   loadavg.Load5,
		"load15":  loadavg.Load15,
		"n_users": len(users),
		"n_cpus":  runtime.NumCPU(),
	}, nil)
	acc.AddCounter("system", map[string]interface{}{
		"uptime":        hostinfo.Uptime,
		"uptime_format": format_uptime(hostinfo.Uptime),
	}, nil)

	return nil
}

func format_uptime(uptime uint64) string {
	buf := new(bytes.Buffer)
	w := bufio.NewWriter(buf)

	days := uptime / (60 * 60 * 24)

	if days != 0 {
		s := ""
		if days > 1 {
			s = "s"
		}
		fmt.Fprintf(w, "%d day%s, ", days, s)
	}

	minutes := uptime / 60
	hours := minutes / 60
	hours %= 24
	minutes %= 60

	fmt.Fprintf(w, "%2d:%02d", hours, minutes)

	w.Flush()
	return buf.String()
}

func init() {
	inputs.Add("system", func() telegraf.Input {
		return &SystemStats{}
	})
}
<|endoftext|>


<commit_before>// Copyright 2018 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package prometheus

import (
	"runtime"
	"testing"
	"time"

	dto "github.com/prometheus/client_model/go"
)

func TestGoCollectorGoroutines(t *testing.T) {
	var (
		c               = NewGoCollector()
		metricCh        = make(chan Metric)
		waitCh          = make(chan struct{})
		endGoroutineCh  = make(chan struct{})
		endCollectionCh = make(chan struct{})
		old             = -1
	)
	defer func() {
		close(endGoroutineCh)
		// Drain the collect channel to prevent goroutine leak.
		for {
			select {
			case <-metricCh:
			case <-endCollectionCh:
				return
			}
		}
	}()

	go func() {
		c.Collect(metricCh)
		go func(c <-chan struct{}) {
			<-c
		}(endGoroutineCh)
		<-waitCh
		c.Collect(metricCh)
		close(endCollectionCh)
	}()

	for {
		select {
		case m := <-metricCh:
			// m can be Gauge or Counter,
			// currently just test the go_goroutines Gauge
			// and ignore others.
			if m.Desc().fqName != "go_goroutines" {
				continue
			}
			pb := &dto.Metric{}
			m.Write(pb)
			if pb.GetGauge() == nil {
				continue
			}

			if old == -1 {
				old = int(pb.GetGauge().GetValue())
				close(waitCh)
				continue
			}

			if diff := int(pb.GetGauge().GetValue()) - old; diff != 1 {
				// TODO: This is flaky in highly concurrent situations.
				t.Errorf("want 1 new goroutine, got %d", diff)
			}
		case <-time.After(1 * time.Second):
			t.Fatalf("expected collect timed out")
		}
		break
	}
}

func TestGoCollectorGC(t *testing.T) {
	var (
		c               = NewGoCollector()
		metricCh        = make(chan Metric)
		waitCh          = make(chan struct{})
		endCollectionCh = make(chan struct{})
		oldGC           uint64
		oldPause        float64
	)

	go func() {
		c.Collect(metricCh)
		// force GC
		runtime.GC()
		<-waitCh
		c.Collect(metricCh)
		close(endCollectionCh)
	}()

	defer func() {
		// Drain the collect channel to prevent goroutine leak.
		for {
			select {
			case <-metricCh:
			case <-endCollectionCh:
				return
			}
		}
	}()

	first := true
	for {
		select {
		case metric := <-metricCh:
			pb := &dto.Metric{}
			metric.Write(pb)
			if pb.GetSummary() == nil {
				continue
			}
			if len(pb.GetSummary().Quantile) != 5 {
				t.Errorf("expected 4 buckets, got %d", len(pb.GetSummary().Quantile))
			}
			for idx, want := range []float64{0.0, 0.25, 0.5, 0.75, 1.0} {
				if *pb.GetSummary().Quantile[idx].Quantile != want {
					t.Errorf("bucket #%d is off, got %f, want %f", idx, *pb.GetSummary().Quantile[idx].Quantile, want)
				}
			}
			if first {
				first = false
				oldGC = *pb.GetSummary().SampleCount
				oldPause = *pb.GetSummary().SampleSum
				close(waitCh)
				continue
			}
			if diff := *pb.GetSummary().SampleCount - oldGC; diff != 1 {
				t.Errorf("want 1 new garbage collection run, got %d", diff)
			}
			if diff := *pb.GetSummary().SampleSum - oldPause; diff <= 0 {
				t.Errorf("want moar pause, got %f", diff)
			}
		case <-time.After(1 * time.Second):
			t.Fatalf("expected collect timed out")
		}
		break
	}
}

func TestGoCollectorMemStats(t *testing.T) {
	var (
		c   = NewGoCollector().(*goCollector)
		got uint64
	)

	checkCollect := func(want uint64) {
		metricCh := make(chan Metric)
		endCh := make(chan struct{})

		go func() {
			c.Collect(metricCh)
			close(endCh)
		}()
	Collect:
		for {
			select {
			case metric := <-metricCh:
				if metric.Desc().fqName != "go_memstats_alloc_bytes" {
					continue Collect
				}
				pb := &dto.Metric{}
				metric.Write(pb)
				got = uint64(pb.GetGauge().GetValue())
			case <-endCh:
				break Collect
			}
		}
		if want != got {
			t.Errorf("unexpected value of go_memstats_alloc_bytes, want %d, got %d", want, got)
		}
	}

	// Speed up the timing to make the tast faster.
	c.msMaxWait = time.Millisecond
	c.msMaxAge = 10 * time.Millisecond

	// Scenario 1: msRead responds slowly, no previous memstats available,
	// msRead is executed anyway.
	c.msRead = func(ms *runtime.MemStats) {
		time.Sleep(3 * time.Millisecond)
		ms.Alloc = 1
	}
	checkCollect(1)
	// Now msLast is set.
	c.msMtx.Lock()
	if want, got := uint64(1), c.msLast.Alloc; want != got {
		t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got)
	}
	c.msMtx.Unlock()

	// Scenario 2: msRead responds fast, previous memstats available, new
	// value collected.
	c.msRead = func(ms *runtime.MemStats) {
		ms.Alloc = 2
	}
	checkCollect(2)
	// msLast is set, too.
	c.msMtx.Lock()
	if want, got := uint64(2), c.msLast.Alloc; want != got {
		t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got)
	}
	c.msMtx.Unlock()

	// Scenario 3: msRead responds slowly, previous memstats available, old
	// value collected.
	c.msRead = func(ms *runtime.MemStats) {
		time.Sleep(3 * time.Millisecond)
		ms.Alloc = 3
	}
	checkCollect(2)
	// After waiting, new value is still set in msLast.
	time.Sleep(12 * time.Millisecond)
	c.msMtx.Lock()
	if want, got := uint64(3), c.msLast.Alloc; want != got {
		t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got)
	}
	c.msMtx.Unlock()

	// Scenario 4: msRead responds slowly, previous memstats is too old, new
	// value collected.
	c.msRead = func(ms *runtime.MemStats) {
		time.Sleep(3 * time.Millisecond)
		ms.Alloc = 4
	}
	checkCollect(4)
	c.msMtx.Lock()
	if want, got := uint64(4), c.msLast.Alloc; want != got {
		t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got)
	}
	c.msMtx.Unlock()
}
<commit_msg>Unflake TestGoCollectorGC<commit_after>// Copyright 2018 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package prometheus

import (
	"runtime"
	"testing"
	"time"

	dto "github.com/prometheus/client_model/go"
)

func TestGoCollectorGoroutines(t *testing.T) {
	var (
		c               = NewGoCollector()
		metricCh        = make(chan Metric)
		waitCh          = make(chan struct{})
		endGoroutineCh  = make(chan struct{})
		endCollectionCh = make(chan struct{})
		old             = -1
	)
	defer func() {
		close(endGoroutineCh)
		// Drain the collect channel to prevent goroutine leak.
		for {
			select {
			case <-metricCh:
			case <-endCollectionCh:
				return
			}
		}
	}()

	go func() {
		c.Collect(metricCh)
		go func(c <-chan struct{}) {
			<-c
		}(endGoroutineCh)
		<-waitCh
		c.Collect(metricCh)
		close(endCollectionCh)
	}()

	for {
		select {
		case m := <-metricCh:
			// m can be Gauge or Counter,
			// currently just test the go_goroutines Gauge
			// and ignore others.
			if m.Desc().fqName != "go_goroutines" {
				continue
			}
			pb := &dto.Metric{}
			m.Write(pb)
			if pb.GetGauge() == nil {
				continue
			}

			if old == -1 {
				old = int(pb.GetGauge().GetValue())
				close(waitCh)
				continue
			}

			if diff := int(pb.GetGauge().GetValue()) - old; diff != 1 {
				// TODO: This is flaky in highly concurrent situations.
				t.Errorf("want 1 new goroutine, got %d", diff)
			}
		case <-time.After(1 * time.Second):
			t.Fatalf("expected collect timed out")
		}
		break
	}
}

func TestGoCollectorGC(t *testing.T) {
	var (
		c               = NewGoCollector()
		metricCh        = make(chan Metric)
		waitCh          = make(chan struct{})
		endCollectionCh = make(chan struct{})
		oldGC           uint64
		oldPause        float64
	)

	go func() {
		c.Collect(metricCh)
		// force GC
		runtime.GC()
		<-waitCh
		c.Collect(metricCh)
		close(endCollectionCh)
	}()

	defer func() {
		// Drain the collect channel to prevent goroutine leak.
		for {
			select {
			case <-metricCh:
			case <-endCollectionCh:
				return
			}
		}
	}()

	first := true
	for {
		select {
		case metric := <-metricCh:
			pb := &dto.Metric{}
			metric.Write(pb)
			if pb.GetSummary() == nil {
				continue
			}
			if len(pb.GetSummary().Quantile) != 5 {
				t.Errorf("expected 4 buckets, got %d", len(pb.GetSummary().Quantile))
			}
			for idx, want := range []float64{0.0, 0.25, 0.5, 0.75, 1.0} {
				if *pb.GetSummary().Quantile[idx].Quantile != want {
					t.Errorf("bucket #%d is off, got %f, want %f", idx, *pb.GetSummary().Quantile[idx].Quantile, want)
				}
			}
			if first {
				first = false
				oldGC = *pb.GetSummary().SampleCount
				oldPause = *pb.GetSummary().SampleSum
				close(waitCh)
				continue
			}
			if diff := *pb.GetSummary().SampleCount - oldGC; diff < 1 {
				t.Errorf("want at least 1 new garbage collection run, got %d", diff)
			}
			if diff := *pb.GetSummary().SampleSum - oldPause; diff <= 0 {
				t.Errorf("want an increase in pause time, got a change of %f", diff)
			}
		case <-time.After(1 * time.Second):
			t.Fatalf("expected collect timed out")
		}
		break
	}
}

func TestGoCollectorMemStats(t *testing.T) {
	var (
		c   = NewGoCollector().(*goCollector)
		got uint64
	)

	checkCollect := func(want uint64) {
		metricCh := make(chan Metric)
		endCh := make(chan struct{})

		go func() {
			c.Collect(metricCh)
			close(endCh)
		}()
	Collect:
		for {
			select {
			case metric := <-metricCh:
				if metric.Desc().fqName != "go_memstats_alloc_bytes" {
					continue Collect
				}
				pb := &dto.Metric{}
				metric.Write(pb)
				got = uint64(pb.GetGauge().GetValue())
			case <-endCh:
				break Collect
			}
		}
		if want != got {
			t.Errorf("unexpected value of go_memstats_alloc_bytes, want %d, got %d", want, got)
		}
	}

	// Speed up the timing to make the tast faster.
	c.msMaxWait = time.Millisecond
	c.msMaxAge = 10 * time.Millisecond

	// Scenario 1: msRead responds slowly, no previous memstats available,
	// msRead is executed anyway.
	c.msRead = func(ms *runtime.MemStats) {
		time.Sleep(3 * time.Millisecond)
		ms.Alloc = 1
	}
	checkCollect(1)
	// Now msLast is set.
	c.msMtx.Lock()
	if want, got := uint64(1), c.msLast.Alloc; want != got {
		t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got)
	}
	c.msMtx.Unlock()

	// Scenario 2: msRead responds fast, previous memstats available, new
	// value collected.
	c.msRead = func(ms *runtime.MemStats) {
		ms.Alloc = 2
	}
	checkCollect(2)
	// msLast is set, too.
	c.msMtx.Lock()
	if want, got := uint64(2), c.msLast.Alloc; want != got {
		t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got)
	}
	c.msMtx.Unlock()

	// Scenario 3: msRead responds slowly, previous memstats available, old
	// value collected.
	c.msRead = func(ms *runtime.MemStats) {
		time.Sleep(3 * time.Millisecond)
		ms.Alloc = 3
	}
	checkCollect(2)
	// After waiting, new value is still set in msLast.
	time.Sleep(12 * time.Millisecond)
	c.msMtx.Lock()
	if want, got := uint64(3), c.msLast.Alloc; want != got {
		t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got)
	}
	c.msMtx.Unlock()

	// Scenario 4: msRead responds slowly, previous memstats is too old, new
	// value collected.
	c.msRead = func(ms *runtime.MemStats) {
		time.Sleep(3 * time.Millisecond)
		ms.Alloc = 4
	}
	checkCollect(4)
	c.msMtx.Lock()
	if want, got := uint64(4), c.msLast.Alloc; want != got {
		t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got)
	}
	c.msMtx.Unlock()
}
<|endoftext|>


<commit_before>/*
Copyright 2020 The Kubernetes Authors.

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

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

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

package fakejira

import (
	"context"
	"github.com/andygrunwald/go-jira"
	"reflect"
	"testing"
)

func TestFakeClient_SearchWithContext(t *testing.T) {
	s := make(map[SearchRequest]SearchResponse)
	issueList := []jira.Issue{
		{
			ID:     "123",
			Fields: &jira.IssueFields{Project: jira.Project{Name: "test"}},
		},
		{
			ID:     "1234",
			Fields: &jira.IssueFields{Project: jira.Project{Name: "test"}},
		},
		{
			ID:     "12345",
			Fields: &jira.IssueFields{Project: jira.Project{Name: "test"}},
		},
	}
	searchOptions := &jira.SearchOptions{MaxResults: 50, StartAt: 0}

	s[SearchRequest{query: "project=test", options: searchOptions}] = SearchResponse{
		issues:   issueList,
		response: &jira.Response{StartAt: 0, MaxResults: 3, Total: 3},
		error:    nil,
	}
	fakeClient := &FakeClient{SearchResponses: s}
	r, v, err := fakeClient.SearchWithContext(context.Background(), "project=test", searchOptions)
	if err != nil {
		t.Fatalf("unexpected error")
	}
	if !reflect.DeepEqual(r, issueList) || !reflect.DeepEqual(&jira.Response{StartAt: 0, MaxResults: 3, Total: 3}, v) {
		t.Fatalf("unexpected response")
	}
	r, v, err = fakeClient.SearchWithContext(context.Background(), "unknown_query=test", searchOptions)
	if r != nil && v != nil && err == nil {
		t.Fatal("unexpected result")
	}
}
<commit_msg>fix unit tests based on review<commit_after>/*
Copyright 2020 The Kubernetes Authors.

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

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

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

package fakejira

import (
	"context"
	"github.com/andygrunwald/go-jira"
	"reflect"
	"testing"
)

func TestFakeClient_SearchWithContext(t *testing.T) {
	s := make(map[SearchRequest]SearchResponse)
	issueList := []jira.Issue{
		{
			ID:     "123",
			Fields: &jira.IssueFields{Project: jira.Project{Name: "test"}},
		},
		{
			ID:     "1234",
			Fields: &jira.IssueFields{Project: jira.Project{Name: "test"}},
		},
		{
			ID:     "12345",
			Fields: &jira.IssueFields{Project: jira.Project{Name: "test"}},
		},
	}
	searchOptions := &jira.SearchOptions{MaxResults: 50, StartAt: 0}

	s[SearchRequest{query: "project=test", options: searchOptions}] = SearchResponse{
		issues:   issueList,
		response: &jira.Response{StartAt: 0, MaxResults: 3, Total: 3},
		error:    nil,
	}
	fakeClient := &FakeClient{SearchResponses: s}

	r, v, err := fakeClient.SearchWithContext(context.Background(), "project=test", searchOptions)
	if err != nil {
		t.Fatalf("unexpected error from search: %s", err)
	}
	if !reflect.DeepEqual(r, issueList) {
		t.Fatalf("incorrect issues from search; actual response: %v, expected response: %v", r, issueList)
	}
	metadata := &jira.Response{StartAt: 0, MaxResults: 3, Total: 3}
	if !reflect.DeepEqual(metadata, v) {
		t.Fatalf("incorrect metadata from search; actual metadata: %v, expected metadata: %v", v, metadata)
	}

	r, v, err = fakeClient.SearchWithContext(context.Background(), "unknown_query=fail", searchOptions)
	if r != nil {
		t.Fatalf("expected empty result for an invalid query, but got: %v", r)
	}
	if r != nil {
		t.Fatalf("expected no metadata for an invalid query, but got: %v", v)
	}
	if err == nil {
		t.Fatal("expected invalid query to fail, but got no error")
	}
}
<|endoftext|>


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

// +build !plan9

package lockedfile

import (
	"os"

	"cmd/go/internal/lockedfile/internal/filelock"
)

func openFile(name string, flag int, perm os.FileMode) (*os.File, error) {
	// On BSD systems, we could add the O_SHLOCK or O_EXLOCK flag to the OpenFile
	// call instead of locking separately, but we have to support separate locking
	// calls for Linux and Windows anyway, so it's simpler to use that approach
	// consistently.

	f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
	if err != nil {
		return nil, err
	}

	switch flag & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR) {
	case os.O_WRONLY, os.O_RDWR:
		err = filelock.Lock(f)
	default:
		err = filelock.RLock(f)
	}
	if err == nil && flag&os.O_TRUNC == os.O_TRUNC {
		if err = f.Truncate(0); err != nil {
			// The documentation for os.O_TRUNC says “if possible, truncate file when
			// opened”, but doesn't define “possible” (golang.org/issue/28699).
			// We'll treat regular files (and symlinks to regular files) as “possible”
			// and ignore errors for the rest.
			if fi, statErr := f.Stat(); statErr == nil && !fi.Mode().IsRegular() {
				err = nil
			}
		}
	}

	if err != nil {
		filelock.Unlock(f)
		f.Close()
		return nil, err
	}

	return f, nil
}

func closeFile(f *os.File) error {
	// Since locking syscalls operate on file descriptors, we must unlock the file
	// while the descriptor is still valid — that is, before the file is closed —
	// and avoid unlocking files that are already closed.
	err := filelock.Unlock(f)

	if closeErr := f.Close(); err == nil {
		err = closeErr
	}
	return err
}
<commit_msg>cmd/go/internal/lockedfile: fix filelock.Unlock() called twice<commit_after>// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !plan9

package lockedfile

import (
	"os"

	"cmd/go/internal/lockedfile/internal/filelock"
)

func openFile(name string, flag int, perm os.FileMode) (*os.File, error) {
	// On BSD systems, we could add the O_SHLOCK or O_EXLOCK flag to the OpenFile
	// call instead of locking separately, but we have to support separate locking
	// calls for Linux and Windows anyway, so it's simpler to use that approach
	// consistently.

	f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
	if err != nil {
		return nil, err
	}

	switch flag & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR) {
	case os.O_WRONLY, os.O_RDWR:
		err = filelock.Lock(f)
	default:
		err = filelock.RLock(f)
	}
	if err != nil {
		f.Close()
		return nil, err
	}

	if flag&os.O_TRUNC == os.O_TRUNC {
		if err := f.Truncate(0); err != nil {
			// The documentation for os.O_TRUNC says “if possible, truncate file when
			// opened”, but doesn't define “possible” (golang.org/issue/28699).
			// We'll treat regular files (and symlinks to regular files) as “possible”
			// and ignore errors for the rest.
			if fi, statErr := f.Stat(); statErr != nil || fi.Mode().IsRegular() {
				filelock.Unlock(f)
				f.Close()
				return nil, err
			}
		}
	}

	return f, nil
}

func closeFile(f *os.File) error {
	// Since locking syscalls operate on file descriptors, we must unlock the file
	// while the descriptor is still valid — that is, before the file is closed —
	// and avoid unlocking files that are already closed.
	err := filelock.Unlock(f)

	if closeErr := f.Close(); err == nil {
		err = closeErr
	}
	return err
}
<|endoftext|>


<commit_before><commit_msg>keep track of simulated time for every instance<commit_after><|endoftext|>


<commit_before><commit_msg>debug output<commit_after><|endoftext|>


<commit_before><commit_msg>Try to connect function<commit_after><|endoftext|>


<commit_before>package version

// Version tells us the app version string
const Version = "2.6-indev"
<commit_msg>Bump version to 2.6<commit_after>package version

// Version tells us the app version string
const Version = "2.6"
<|endoftext|>


<commit_before>/*
Copyright 2019 The Kubernetes Authors.

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

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

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

// verify that dependencies are up-to-date across different files
package main

import (
	"flag"
	"log"
	"strings"

	"bufio"
	"io/ioutil"
	"os"
	"regexp"

	"gopkg.in/yaml.v2"
)

type dependencies struct {
	Dependencies []*dependency `yaml:"dependencies"`
}

type dependency struct {
	Name     string     `yaml:"name"`
	Version  string     `yaml:"version"`
	RefPaths []*refPath `yaml:"refPaths"`
}

type refPath struct {
	Path  string `yaml:"path"`
	Match string `yaml:"match"`
}

func main() {

	flag.Parse()

	args := flag.Args()

	if len(args) == 0 {
		log.Fatalf("usage: verifydependency <file>")
	}
	externalDepsFilePath := args[0]
	externalDepsFile, err := ioutil.ReadFile(externalDepsFilePath)
	if err != nil {
		panic(err)
	}

	mismatchErrorMessage := "ERROR: %v indicates that %v should be at version %v, but the following files didn't match:\n\n" +
		"%v\n\nif you are changing the version of %v, make sure all of the following files are updated with the newest version including %v\n" +
		"then run ./hack/verify-external-dependencies-version.sh\n\n"
	externalDeps := &dependencies{}
	var pathsToUpdate []string
	err = yaml.Unmarshal(externalDepsFile, externalDeps)
	if err != nil {
		panic(err)
	}

	for _, dep := range externalDeps.Dependencies {
		for _, refPath := range dep.RefPaths {
			file, err := os.Open(refPath.Path)
			if err != nil {
				log.Fatalf("error opening file %v : %v", refPath.Path, err)
			}
			matcher := regexp.MustCompile(refPath.Match)
			depFileScanner := bufio.NewScanner(file)
			var found bool
			for depFileScanner.Scan() {
				line := depFileScanner.Text()
				if matcher.MatchString(line) && strings.Contains(line, dep.Version) {
					found = true
					break
				}
			}
			if !found {
				pathsToUpdate = append(pathsToUpdate, refPath.Path)
			}
		}
		if len(pathsToUpdate) > 0 {
			log.Fatalf(mismatchErrorMessage, externalDepsFilePath, dep.Name, dep.Version, strings.Join(pathsToUpdate, "\n"), dep.Name, externalDepsFilePath)
		}
	}

}
<commit_msg>Close the file after reading in verifydependencies#main<commit_after>/*
Copyright 2019 The Kubernetes Authors.

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

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

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

// verify that dependencies are up-to-date across different files
package main

import (
	"flag"
	"log"
	"strings"

	"bufio"
	"io/ioutil"
	"os"
	"regexp"

	"gopkg.in/yaml.v2"
)

type dependencies struct {
	Dependencies []*dependency `yaml:"dependencies"`
}

type dependency struct {
	Name     string     `yaml:"name"`
	Version  string     `yaml:"version"`
	RefPaths []*refPath `yaml:"refPaths"`
}

type refPath struct {
	Path  string `yaml:"path"`
	Match string `yaml:"match"`
}

func main() {

	flag.Parse()

	args := flag.Args()

	if len(args) == 0 {
		log.Fatalf("usage: verifydependency <file>")
	}
	externalDepsFilePath := args[0]
	externalDepsFile, err := ioutil.ReadFile(externalDepsFilePath)
	if err != nil {
		panic(err)
	}

	mismatchErrorMessage := "ERROR: %v indicates that %v should be at version %v, but the following files didn't match:\n\n" +
		"%v\n\nif you are changing the version of %v, make sure all of the following files are updated with the newest version including %v\n" +
		"then run ./hack/verify-external-dependencies-version.sh\n\n"
	externalDeps := &dependencies{}
	var pathsToUpdate []string
	err = yaml.Unmarshal(externalDepsFile, externalDeps)
	if err != nil {
		panic(err)
	}

	for _, dep := range externalDeps.Dependencies {
		for _, refPath := range dep.RefPaths {
			func() {
				file, err := os.Open(refPath.Path)
				if err != nil {
					log.Fatalf("error opening file %v : %v", refPath.Path, err)
				}
				defer file.Close()
				matcher := regexp.MustCompile(refPath.Match)
				depFileScanner := bufio.NewScanner(file)
				var found bool
				for depFileScanner.Scan() {
					line := depFileScanner.Text()
					if matcher.MatchString(line) && strings.Contains(line, dep.Version) {
						found = true
						break
					}
				}
				if !found {
					pathsToUpdate = append(pathsToUpdate, refPath.Path)
				}
			}()
		}
		if len(pathsToUpdate) > 0 {
			log.Fatalf(mismatchErrorMessage, externalDepsFilePath, dep.Name, dep.Version, strings.Join(pathsToUpdate, "\n"), dep.Name, externalDepsFilePath)
		}
	}

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net"

	"golang.org/x/crypto/ssh"

	"github.com/tg123/sshpiper/sshpiperd/auditor"
	"github.com/tg123/sshpiper/sshpiperd/challenger"
	"github.com/tg123/sshpiper/sshpiperd/registry"
	"github.com/tg123/sshpiper/sshpiperd/upstream"
	"log"
)

type piperdConfig struct {
	ListenAddr   string `short:"l" long:"listen" description:"Listening Address" default:"0.0.0.0" env:"SSHPIPERD_LISTENADDR" ini-name:"listen-address"`
	Port         uint   `short:"p" long:"port" description:"Listening Port" default:"2222" env:"SSHPIPERD_PORT" ini-name:"listen-port"`
	PiperKeyFile string `short:"i" long:"server-key" description:"Server key file for SSH Piper" default:"/etc/ssh/ssh_host_rsa_key" env:"SSHPIPERD_SERVER_KEY" ini-name:"server-key"`

	UpstreamDriver   string `short:"u" long:"upstream-driver" description:"Upstream provider driver" default:"workingdir" env:"SSHPIPERD_UPSTREAM_DRIVER" ini-name:"upstream-driver"`
	ChallengerDriver string `short:"c" long:"challenger-driver" description:"Additional challenger name, e.g. pam, empty for no additional challenge" env:"SSHPIPERD_CHALLENGER" ini-name:"challenger-driver"`
	AuditorDriver    string `long:"auditor-driver" description:"Auditor for ssh connections piped by SSH Piper" env:"SSHPIPERD_AUDITOR" ini-name:"auditor-driver"`

	BannerText string `long:"banner-text" description:"Display a banner before authentication, would be ignored if banner file was set" env:"SSHPIPERD_BANNERTEXT" ini-name:"banner-text" `
	BannerFile string `long:"banner-file" description:"Display a banner from file before authentication" env:"SSHPIPERD_BANNERFILE" ini-name:"banner-file" `
}

func getAndInstall(reg, name string, get func(n string) registry.Plugin, install func(plugin registry.Plugin) error, logger *log.Logger) error {
	if name == "" {
		return nil
	}

	p := get(name)

	if p == nil {
		return fmt.Errorf("%v driver %v not found", reg, name)
	}

	err := p.Init(logger)
	if err != nil {
		return err
	}
	return install(p)
}

func installDrivers(piper *ssh.PiperConfig, config *piperdConfig, logger *log.Logger) (auditor.Provider, error) {

	// install upstreamProvider driver
	if config.UpstreamDriver == "" {
		return nil, fmt.Errorf("must provider upstream driver")
	}

	var bigbro auditor.Provider

	for _, d := range []struct {
		reg     string
		name    string
		get     func(n string) registry.Plugin
		install func(plugin registry.Plugin) error
	}{
		// upstream driver
		{
			"Upstream",
			config.UpstreamDriver,
			func(n string) registry.Plugin {
				return upstream.Get(n)
			},
			func(plugin registry.Plugin) error {
				handler := plugin.(upstream.Provider).GetHandler()

				if handler == nil {
					return fmt.Errorf("upstream driver return nil handler")
				}

				piper.FindUpstream = handler
				return nil
			},
		},
		// challenger driver
		{
			"Challenger",
			config.ChallengerDriver,
			func(n string) registry.Plugin {
				return challenger.Get(n)
			},
			func(plugin registry.Plugin) error {
				handler := plugin.(challenger.Provider).GetHandler()

				if handler == nil {
					return fmt.Errorf("challenger driver return nil handler")
				}

				piper.AdditionalChallenge = handler
				return nil
			},
		},
		// auditor driver
		{
			"Auditor",
			config.AuditorDriver,
			func(n string) registry.Plugin {
				return auditor.Get(n)
			},
			func(plugin registry.Plugin) error {
				bigbro = plugin.(auditor.Provider)
				return nil
			},
		},
	} {
		err := getAndInstall(d.reg, d.name, d.get, d.install, logger)
		if err != nil {
			return nil, err
		}
	}

	return bigbro, nil
}

func startPiper(config *piperdConfig, logger *log.Logger) error {

	logger.Println("sshpiper is about to start")

	piper := &ssh.PiperConfig{}

	// drivers
	bigbro, err := installDrivers(piper, config, logger)
	if err != nil {
		return err
	}

	// listeners
	privateBytes, err := ioutil.ReadFile(config.PiperKeyFile)
	if err != nil {
		return err
	}

	private, err := ssh.ParsePrivateKey(privateBytes)
	if err != nil {
		return err
	}

	piper.AddHostKey(private)

	listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.ListenAddr, config.Port))
	if err != nil {
		return fmt.Errorf("failed to listen for connection: %v", err)
	}
	defer listener.Close()

	// banner
	if config.BannerFile != "" {

		piper.BannerCallback = func(conn ssh.ConnMetadata) string {

			msg, err := ioutil.ReadFile(config.BannerFile)

			if err != nil {
				logger.Printf("failed to read banner file: %v", err)
				return ""
			}

			return string(msg)
		}
	} else if config.BannerText != "" {
		piper.BannerCallback = func(conn ssh.ConnMetadata) string {
			return config.BannerText + "\n"
		}
	}

	logger.Printf("sshpiperd started")

	for {
		conn, err := listener.Accept()
		if err != nil {
			logger.Printf("failed to accept connection: %v", err)
			continue
		}

		logger.Printf("connection accepted: %v", conn.RemoteAddr())

		go func(c net.Conn) {
			p, err := ssh.NewSSHPiperConn(c, piper)

			if err != nil {
				logger.Printf("connection from %v establishing failed reason: %v", c.RemoteAddr(), err)
				return
			}

			if bigbro != nil {
				a, err := bigbro.Create(p.DownstreamConnMeta())
				if err != nil {
					logger.Printf("connection from %v failed to create auditor reason: %v", c.RemoteAddr(), err)
					return
				}
				defer a.Close()

				p.HookUpstreamMsg = a.GetUpstreamHook()
				p.HookDownstreamMsg = a.GetDownstreamHook()
			}

			err = p.Wait()
			logger.Printf("connection from %v closed reason: %v", c.RemoteAddr(), err)
		}(conn)
	}
}
<commit_msg>add option login-grace-time<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net"
	"time"

	"golang.org/x/crypto/ssh"

	"log"

	"github.com/tg123/sshpiper/sshpiperd/auditor"
	"github.com/tg123/sshpiper/sshpiperd/challenger"
	"github.com/tg123/sshpiper/sshpiperd/registry"
	"github.com/tg123/sshpiper/sshpiperd/upstream"
)

type piperdConfig struct {
	ListenAddr     string        `short:"l" long:"listen" description:"Listening Address" default:"0.0.0.0" env:"SSHPIPERD_LISTENADDR" ini-name:"listen-address"`
	Port           uint          `short:"p" long:"port" description:"Listening Port" default:"2222" env:"SSHPIPERD_PORT" ini-name:"listen-port"`
	PiperKeyFile   string        `short:"i" long:"server-key" description:"Server key file for SSH Piper" default:"/etc/ssh/ssh_host_rsa_key" env:"SSHPIPERD_SERVER_KEY" ini-name:"server-key"`
	LoginGraceTime time.Duration `long:"login-grace-time" description:"Piper disconnects after this time if the pipe has not successfully established" default:"30s" env:"SSHPIPERD_LOGIN_GRACETIME" ini-name:"login-grace-time"`

	UpstreamDriver   string `short:"u" long:"upstream-driver" description:"Upstream provider driver" default:"workingdir" env:"SSHPIPERD_UPSTREAM_DRIVER" ini-name:"upstream-driver"`
	ChallengerDriver string `short:"c" long:"challenger-driver" description:"Additional challenger name, e.g. pam, empty for no additional challenge" env:"SSHPIPERD_CHALLENGER" ini-name:"challenger-driver"`
	AuditorDriver    string `long:"auditor-driver" description:"Auditor for ssh connections piped by SSH Piper" env:"SSHPIPERD_AUDITOR" ini-name:"auditor-driver"`

	BannerText string `long:"banner-text" description:"Display a banner before authentication, would be ignored if banner file was set" env:"SSHPIPERD_BANNERTEXT" ini-name:"banner-text" `
	BannerFile string `long:"banner-file" description:"Display a banner from file before authentication" env:"SSHPIPERD_BANNERFILE" ini-name:"banner-file" `
}

func getAndInstall(reg, name string, get func(n string) registry.Plugin, install func(plugin registry.Plugin) error, logger *log.Logger) error {
	if name == "" {
		return nil
	}

	p := get(name)

	if p == nil {
		return fmt.Errorf("%v driver %v not found", reg, name)
	}

	err := p.Init(logger)
	if err != nil {
		return err
	}
	return install(p)
}

func installDrivers(piper *ssh.PiperConfig, config *piperdConfig, logger *log.Logger) (auditor.Provider, error) {

	// install upstreamProvider driver
	if config.UpstreamDriver == "" {
		return nil, fmt.Errorf("must provider upstream driver")
	}

	var bigbro auditor.Provider

	for _, d := range []struct {
		reg     string
		name    string
		get     func(n string) registry.Plugin
		install func(plugin registry.Plugin) error
	}{
		// upstream driver
		{
			"Upstream",
			config.UpstreamDriver,
			func(n string) registry.Plugin {
				return upstream.Get(n)
			},
			func(plugin registry.Plugin) error {
				handler := plugin.(upstream.Provider).GetHandler()

				if handler == nil {
					return fmt.Errorf("upstream driver return nil handler")
				}

				piper.FindUpstream = handler
				return nil
			},
		},
		// challenger driver
		{
			"Challenger",
			config.ChallengerDriver,
			func(n string) registry.Plugin {
				return challenger.Get(n)
			},
			func(plugin registry.Plugin) error {
				handler := plugin.(challenger.Provider).GetHandler()

				if handler == nil {
					return fmt.Errorf("challenger driver return nil handler")
				}

				piper.AdditionalChallenge = handler
				return nil
			},
		},
		// auditor driver
		{
			"Auditor",
			config.AuditorDriver,
			func(n string) registry.Plugin {
				return auditor.Get(n)
			},
			func(plugin registry.Plugin) error {
				bigbro = plugin.(auditor.Provider)
				return nil
			},
		},
	} {
		err := getAndInstall(d.reg, d.name, d.get, d.install, logger)
		if err != nil {
			return nil, err
		}
	}

	return bigbro, nil
}

func startPiper(config *piperdConfig, logger *log.Logger) error {

	logger.Println("sshpiper is about to start")

	piper := &ssh.PiperConfig{}

	// drivers
	bigbro, err := installDrivers(piper, config, logger)
	if err != nil {
		return err
	}

	// listeners
	privateBytes, err := ioutil.ReadFile(config.PiperKeyFile)
	if err != nil {
		return err
	}

	private, err := ssh.ParsePrivateKey(privateBytes)
	if err != nil {
		return err
	}

	piper.AddHostKey(private)

	listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.ListenAddr, config.Port))
	if err != nil {
		return fmt.Errorf("failed to listen for connection: %v", err)
	}
	defer listener.Close()

	// banner
	if config.BannerFile != "" {

		piper.BannerCallback = func(conn ssh.ConnMetadata) string {

			msg, err := ioutil.ReadFile(config.BannerFile)

			if err != nil {
				logger.Printf("failed to read banner file: %v", err)
				return ""
			}

			return string(msg)
		}
	} else if config.BannerText != "" {
		piper.BannerCallback = func(conn ssh.ConnMetadata) string {
			return config.BannerText + "\n"
		}
	}

	logger.Printf("sshpiperd started")

	for {
		conn, err := listener.Accept()
		if err != nil {
			logger.Printf("failed to accept connection: %v", err)
			continue
		}

		logger.Printf("connection accepted: %v", conn.RemoteAddr())

		go func(c net.Conn) {
			defer c.Close()

			pipec := make(chan *ssh.PiperConn, 0)
			errorc := make(chan error, 0)

			go func() {
				p, err := ssh.NewSSHPiperConn(c, piper)

				if err != nil {
					errorc <- err
					return
				}

				pipec <- p
			}()

			var p *ssh.PiperConn

			select {
			case p = <-pipec:
			case err := <-errorc:
				logger.Printf("connection from %v establishing failed reason: %v", c.RemoteAddr(), err)
				return
			case <-time.After(config.LoginGraceTime):
				logger.Printf("pipe establishing timeout, disconnected connection from %v", c.RemoteAddr())
				return
			}

			defer p.Close()

			if bigbro != nil {
				a, err := bigbro.Create(p.DownstreamConnMeta())
				if err != nil {
					logger.Printf("connection from %v failed to create auditor reason: %v", c.RemoteAddr(), err)
					return
				}
				defer a.Close()

				p.HookUpstreamMsg = a.GetUpstreamHook()
				p.HookDownstreamMsg = a.GetDownstreamHook()
			}

			err = p.Wait()
			logger.Printf("connection from %v closed reason: %v", c.RemoteAddr(), err)
		}(conn)
	}
}
<|endoftext|>


<commit_before>package starbound

import (
	"bytes"
	"compress/zlib"
	"encoding/binary"
	"errors"
	"io"
)

var (
	ErrDidNotReachLeaf  = errors.New("starbound: did not reach a leaf node")
	ErrInvalidHeader    = errors.New("starbound: invalid header")
	ErrInvalidKeyLength = errors.New("starbound: invalid key length")
	ErrInvalidSBON      = errors.New("starbound: invalid SBON data")
	ErrKeyNotFound      = errors.New("starbound: key not found")
)

type Tile struct {
	ForegroundMaterial    int16
	ForegroundHueShift    uint8
	ForegroundVariant     uint8
	ForegroundMod         int16
	ForegroundModHueShift uint8
	BackgroundMaterial    int16
	BackgroundHueShift    uint8
	BackgroundVariant     uint8
	BackgroundMod         int16
	BackgroundModHueShift uint8
	Liquid                uint8
	LiquidLevel           float32
	LiquidPressure        float32
	LiquidInfinite        uint8 // bool
	Collision             uint8
	DungeonID             uint16
	Biome1, Biome2        uint8
	Indestructible        uint8 // bool
}

// NewWorld creates and initializes a new World using r as the data source.
func NewWorld(r io.ReaderAt) (w *World, err error) {
	db, err := NewBTreeDB5(r)
	if err != nil {
		return
	}
	if db.Name != "World4" || db.KeySize != 5 {
		return nil, ErrInvalidHeader
	}
	return &World{db}, nil
}

// A World is a representation of a Starbound world, enabling read access to
// individual regions in the world as well as its metadata.
type World struct {
	*BTreeDB5
}

func (w *World) Get(layer, x, y int) (data []byte, err error) {
	src, err := w.GetReader(layer, x, y)
	if err != nil {
		return
	}
	dst := new(bytes.Buffer)
	_, err = io.Copy(dst, src)
	if err != nil {
		return
	}
	return dst.Bytes(), nil
}

func (w *World) GetReader(layer, x, y int) (r io.Reader, err error) {
	key := []byte{byte(layer), byte(x >> 8), byte(x), byte(y >> 8), byte(y)}
	lr, err := w.BTreeDB5.GetReader(key)
	if err != nil {
		return nil, err
	}
	return zlib.NewReader(lr)
}

func (w *World) GetTiles(x, y int) (t []Tile, err error) {
	r, err := w.GetReader(1, x, y)
	if err != nil {
		return
	}
	// Ignore the first three bytes.
	// TODO: Do something with these bytes?
	discard := make([]byte, 3)
	_, err = io.ReadFull(r, discard)
	if err != nil {
		return
	}
	t = make([]Tile, 1024) // 32x32 tiles in a region
	err = binary.Read(r, binary.BigEndian, t)
	return
}

// Reads a 32-bit integer from the provided buffer and offset.
func getInt(data []byte, n int) int {
	return int(data[n])<<24 | int(data[n+1])<<16 | int(data[n+2])<<8 | int(data[n+3])
}

type logger interface {
	Fatalf(format string, args ...interface{})
}
<commit_msg>Add VersionedJSON read support<commit_after>package starbound

import (
	"bytes"
	"compress/zlib"
	"encoding/binary"
	"errors"
	"io"
)

var (
	ErrDidNotReachLeaf  = errors.New("starbound: did not reach a leaf node")
	ErrInvalidHeader    = errors.New("starbound: invalid header")
	ErrInvalidKeyLength = errors.New("starbound: invalid key length")
	ErrInvalidSBON      = errors.New("starbound: invalid SBON data")
	ErrKeyNotFound      = errors.New("starbound: key not found")
)

type Tile struct {
	ForegroundMaterial    int16
	ForegroundHueShift    uint8
	ForegroundVariant     uint8
	ForegroundMod         int16
	ForegroundModHueShift uint8
	BackgroundMaterial    int16
	BackgroundHueShift    uint8
	BackgroundVariant     uint8
	BackgroundMod         int16
	BackgroundModHueShift uint8
	Liquid                uint8
	LiquidLevel           float32
	LiquidPressure        float32
	LiquidInfinite        uint8 // bool
	Collision             uint8
	DungeonID             uint16
	Biome1, Biome2        uint8
	Indestructible        uint8 // bool
}

// NewWorld creates and initializes a new World using r as the data source.
func NewWorld(r io.ReaderAt) (w *World, err error) {
	db, err := NewBTreeDB5(r)
	if err != nil {
		return
	}
	if db.Name != "World4" || db.KeySize != 5 {
		return nil, ErrInvalidHeader
	}
	return &World{db}, nil
}

// A World is a representation of a Starbound world, enabling read access to
// individual regions in the world as well as its metadata.
type World struct {
	*BTreeDB5
}

func (w *World) Get(layer, x, y int) (data []byte, err error) {
	src, err := w.GetReader(layer, x, y)
	if err != nil {
		return
	}
	dst := new(bytes.Buffer)
	_, err = io.Copy(dst, src)
	if err != nil {
		return
	}
	return dst.Bytes(), nil
}

func (w *World) GetReader(layer, x, y int) (r io.Reader, err error) {
	key := []byte{byte(layer), byte(x >> 8), byte(x), byte(y >> 8), byte(y)}
	lr, err := w.BTreeDB5.GetReader(key)
	if err != nil {
		return nil, err
	}
	return zlib.NewReader(lr)
}

func (w *World) GetTiles(x, y int) (t []Tile, err error) {
	r, err := w.GetReader(1, x, y)
	if err != nil {
		return
	}
	// Ignore the first three bytes.
	// TODO: Do something with these bytes?
	discard := make([]byte, 3)
	_, err = io.ReadFull(r, discard)
	if err != nil {
		return
	}
	t = make([]Tile, 1024) // 32x32 tiles in a region
	err = binary.Read(r, binary.BigEndian, t)
	return
}

func ReadVersionedJSON(r io.Reader) (v VersionedJSON, err error) {
	// Read the name of the data structure.
	v.Name, err = ReadString(r)
	if err != nil {
		return
	}
	// Read unknown byte which is always 0x01.
	buf := make([]byte, 1)
	_, err = io.ReadFull(r, buf)
	if err != nil {
		return
	}
	if buf[0] != 1 {
		return v, ErrInvalidHeader
	}
	// Read the data structure version.
	var version int32
	err = binary.Read(r, binary.BigEndian, &version)
	if err != nil {
		return
	}
	v.Version = int(version)
	// Finally, read the JSON-like data itself.
	v.Data, err = ReadDynamic(r)
	return
}

// VersionedJSON represents a JSON-compatible data structure which additionally
// has a name and version associated with it so that the reader may migrate the
// structure based on the name/version.
type VersionedJSON struct {
	Name    string
	Version int
	Data    interface{}
}

// Reads a 32-bit integer from the provided buffer and offset.
func getInt(data []byte, n int) int {
	return int(data[n])<<24 | int(data[n+1])<<16 | int(data[n+2])<<8 | int(data[n+3])
}

type logger interface {
	Fatalf(format string, args ...interface{})
}
<|endoftext|>


<commit_before>package stats

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"time"

	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

var _env_monitor_shard bool
var _env_stop_chunk_number int64 = 40
var _env_shards []string
var _env_mongos string
var _shard_connections []Shard
var _shard_num int64 = 3        //FIXME need findout
var _shard_chunk_number []int64 // count how many chunk per shard
//var _shard_session *mgo.Session
var _shard_mongos_session *mgo.Session

var _shard_monitor_channel *time.Ticker

// struct for Shard
type Shard struct {
	Name    string `bson:"name"`
	Url     string `bson:"url"`
	Session *mgo.Session
}

type ShardChunk struct {
	Id    string `bson:"_id"`
	Count int64  `bson:"count"`
}

// helper
func getShardName(i int64) string {
	return fmt.Sprintf("shard%04d", i)
}

func getShardNumber(name string) int64 {
	i, err := strconv.ParseInt(string(name[5:]), 10, 64)
	if err != nil {
		log.Fatalln("Failed to parse shard name ", name)
	}
	return i
}

// goal here is to monitor shard cluster
func monitorShardCluster() {
	_shard_monitor_channel = time.NewTicker(time.Second * time.Duration(10)) // monitor every 10 seconds

	// count chunk for every shard
	// this is the aggregation pipeline:
	//     db.chunks.aggregate([{$project: {shard: 1, _id: 0}}, {$group: {_id: "$shard", count: {$sum: 1}}}])}}})
	//         { "_id" : "shard0002", "count" : 2 }
	//         { "_id" : "shard0001", "count" : 1 }
	//         { "_id" : "shard0000", "count" : 1 }

	var _t_total_chunk int64
	_chunks := []ShardChunk{}

	for {
		_t_total_chunk = 0
		_shard_mongos_session.DB("config").C("chunks").Pipe(
			[]bson.M{
				{"$project": bson.M{"shard": 1, "_id": 0}},
				{"$group": bson.M{"_id": "$shard", "count": bson.M{"$sum": 1}}},
			}).All(&_chunks)

		for i := 0; i < len(_chunks); i++ {
			_t_total_chunk += ShardChunk(_chunks[i]).Count
			_shard_chunk_number[getShardNumber(_chunks[i].Id)] = _chunks[i].Count
		}
		log.Printf("%v\t%d\n", _shard_chunk_number, _t_total_chunk)
		<-_shard_monitor_channel.C
	}
}

// to initilize connection to the shard and some initial variables
func initShardCluster() {
	var err error

	// create connection pool
	_shard_connections = make([]Shard, len(_env_shards), len(_env_shards))
	for i, url := range _env_shards {
		_shard_connections[i].Name = ""
		_shard_connections[i].Url = url
		_shard_connections[i].Session, err = mgo.Dial(url)

		if err != nil {
			log.Fatalln("Cannot open mongo connection to ", url)
		}
	}

	// create connection to mongos
	_shard_mongos_session, err = mgo.Dial(_env_mongos)

	if err != nil {
		log.Fatalln("Cannot open mongos connection to ", _env_mongos)
	}
}

func init() {
	// hack for test
	os.Setenv("HT_MONITOR_SHARD", "true")
	os.Setenv("HT_MONGOS_URL", "54.68.41.49:27017")

	s := os.Getenv("HT_MONITOR_SHARD")
	if s != "" {
		_env_monitor_shard = true
	}

	if !_env_monitor_shard {
		// stop init if not monitoring
		return
	}

	s = os.Getenv("HT_MONGOS_URL")
	if s != "" {
		_env_mongos = s
	}

	s = os.Getenv("HT_SHARDS")
	if s != "" {
		_env_shards = strings.Fields(s)
		_env_monitor_shard = true

		if len(_env_shards) == 0 {
			log.Fatalln("HT_SHARDS, if set, must have at least one mongod URL")
		}
	}

	// a few special cases for test shard/auto-split
	_shard_chunk_number = make([]int64, 3, 3)

	initShardCluster()
	go monitorShardCluster()
}
<commit_msg>auto shard<commit_after>package stats

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"time"

	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

var _env_monitor_shard bool
var _env_stop_chunk_number int64 = 40
var _env_shards []string
var _env_mongos string
var _shard_connections []Shard
var _shard_num int64 = 3        //FIXME need findout
var _shard_chunk_number []int64 // count how many chunk per shard
//var _shard_session *mgo.Session
var _shard_mongos_session *mgo.Session

var _shard_monitor_channel *time.Ticker

// struct for Shard
type Shard struct {
	Name    string `bson:"name"`
	Url     string `bson:"url"`
	Session *mgo.Session
}

type ShardChunk struct {
	Id    string `bson:"_id"`
	Count int64  `bson:"count"`
}

// helper
func getShardName(i int64) string {
	return fmt.Sprintf("shard%04d", i)
}

func getShardNumber(name string) int64 {
	i, err := strconv.ParseInt(string(name[5:]), 10, 64)
	if err != nil {
		log.Fatalln("Failed to parse shard name ", name)
	}
	return i
}

// goal here is to monitor shard cluster
func monitorShardCluster() {
	_shard_monitor_channel = time.NewTicker(time.Second * time.Duration(10)) // monitor every 10 seconds

	var _t_total_chunk int64
	var _t_chunk_size struct {
		Size int64 `bson:"value"`
	}

	_chunks := []ShardChunk{}

	for {
		_t_total_chunk = 0

		// count chunk for every shard
		// this is the aggregation pipeline:
		//     db.chunks.aggregate([{$project: {shard: 1, _id: 0}}, {$group: {_id: "$shard", count: {$sum: 1}}}])}}})
		//         { "_id" : "shard0002", "count" : 2 }
		//         { "_id" : "shard0001", "count" : 1 }
		//         { "_id" : "shard0000", "count" : 1 }
		_shard_mongos_session.DB("config").C("chunks").Pipe(
			[]bson.M{
				{"$project": bson.M{"shard": 1, "_id": 0}},
				{"$group": bson.M{"_id": "$shard", "count": bson.M{"$sum": 1}}},
			}).All(&_chunks)

		for i := 0; i < len(_chunks); i++ {
			_t_total_chunk += ShardChunk(_chunks[i]).Count
			_shard_chunk_number[getShardNumber(_chunks[i].Id)] = _chunks[i].Count
		}

		// to get chunk size
		// > db.settings.find()
		//      { "_id" : "chunksize", "value" : 64 })
		_shard_mongos_session.DB("config").C("settings").Find(bson.M{"_id": "chunksize"}).One(&_t_chunk_size)

		log.Printf("%v\t%d\t%d\n", _shard_chunk_number, _t_total_chunk, _t_chunk_size.Size)
		<-_shard_monitor_channel.C
	}
}

// to initilize connection to the shard and some initial variables
func initShardCluster() {
	var err error

	// create connection pool
	_shard_connections = make([]Shard, len(_env_shards), len(_env_shards))
	for i, url := range _env_shards {
		_shard_connections[i].Name = ""
		_shard_connections[i].Url = url
		_shard_connections[i].Session, err = mgo.Dial(url)

		if err != nil {
			log.Fatalln("Cannot open mongo connection to ", url)
		}
	}

	// create connection to mongos
	_shard_mongos_session, err = mgo.Dial(_env_mongos)

	if err != nil {
		log.Fatalln("Cannot open mongos connection to ", _env_mongos)
	}

	// make sure sharding and collection is setup properly

	// 1. drop db
	_shard_mongos_session.DB("htest1").DropDatabase()

	// 2. insert one doc into collection
	_shard_mongos_session.DB("htest1").C("htest1").Insert(bson.M{"a": 100})

	// 3. enable sharding
	err = _shard_mongos_session.DB("admin").Run(bson.D{{"enableSharding", "htest1"}}, nil)
	if err != nil {
		log.Fatalln("Failed to shard DB with error: ", err)
	}

	err = _shard_mongos_session.DB("htest1").C("htest1").EnsureIndex(mgo.Index{Key: []string{"$hashed:_id"}})
	if err != nil {
		log.Fatalln("Failed to create hashed index for collection with error: ", err)
	}

	err = _shard_mongos_session.DB("admin").Run(bson.D{{"shardCollection", "htest1.htest1"}, {"key", bson.M{"_id": "hashed"}}}, nil)
	if err != nil {
		log.Fatalln("Failed to shard collection with error: ", err)
	}

}

func init() {
	// hack for test
	os.Setenv("HT_MONITOR_SHARD", "true")
	os.Setenv("HT_MONGOS_URL", "54.68.41.49:27017")

	s := os.Getenv("HT_MONITOR_SHARD")
	if s != "" {
		_env_monitor_shard = true
	}

	if !_env_monitor_shard {
		// stop init if not monitoring
		return
	}

	s = os.Getenv("HT_MONGOS_URL")
	if s != "" {
		_env_mongos = s
	}

	s = os.Getenv("HT_SHARDS")
	if s != "" {
		_env_shards = strings.Fields(s)
		_env_monitor_shard = true

		if len(_env_shards) == 0 {
			log.Fatalln("HT_SHARDS, if set, must have at least one mongod URL")
		}
	}

	// a few special cases for test shard/auto-split
	_shard_chunk_number = make([]int64, 3, 3)

	initShardCluster()
	go monitorShardCluster()
}
<|endoftext|>


<commit_before>package streamtools

import (
	"github.com/bitly/go-simplejson"
	"log"
)

var StreamToStdOut ExportFunction = func(inChan chan simplejson.Json) {
	for {
		select {
		case m := <-inChan:
			blob, err := m.MarshalJSON()
			if err != nil {
				log.Fatalln(err)
			}
			log.Println(string(blob))
		}
	}
}
<commit_msg>micro comments<commit_after>package streamtools

import (
	"github.com/bitly/go-simplejson"
	"log"
)

// StreamToStdOut simply prints the JSON string of each message.
var StreamToStdOut ExportFunction = func(inChan chan simplejson.Json) {
	for {
		select {
		case m := <-inChan:
			blob, err := m.MarshalJSON()
			if err != nil {
				log.Fatalln(err)
			}
			log.Println(string(blob))
		}
	}
}
<|endoftext|>


<commit_before>package getaredis

import "time"

func CleanRedisInstances(ctx *context) (containerNames []string) {
	var instances = make([]Instance, 0)
	containerNames = make([]string, 0)
	var maxTimeStamp = time.Now().Add(-1 * time.Second * 60 * 60 * time.Duration(ctx.config.MaxInstanceTime))
	ctx.db.Model(&Instance{}).Where("running = 1 AND created_at < ?", maxTimeStamp).Find(&instances)

	for _, instance := range instances {
		ctx.RemoveContainer(instance.HostedAtIP, instance.ContainerID)
		containerNames = append(containerNames, instance.Name)
	}
	ctx.db.Model(&Instance{}).Where("running = 1 AND created_at < ?", maxTimeStamp).UpdateColumn("running", false)

	return
}

func MonitorHosts(ctx *context) (startedHosts bool, deletedHosts []string, err error) {
	hosts := ctx.ListHosts()
	deletedHosts = make([]string, 0)
	zeros := 0
	for _, host := range hosts {
		if host.NumberOfContainers == 0 {
			zeros++
		}
	}
	if zeros == 0 || len(hosts) < 2 {
		err = ctx.NewHost()
		if err != nil {
			return
		}
		if len(hosts) == 0 {
			err = ctx.NewHost()
			if err != nil {
				return
			}
		}
		startedHosts = true
		return
	} else if zeros > 1 && len(hosts) > 2 {
		for _, host := range hosts {
			if zeros == 1 {
				break
			}
			if host.NumberOfContainers == 0 {
				err = ctx.DeleteHost(host.PublicIP)
				zeros--
				deletedHosts = append(deletedHosts, host.PublicIP)
			}
		}
	}
	return
}
<commit_msg>Removing the initial droplet special case<commit_after>package getaredis

import "time"

func CleanRedisInstances(ctx *context) (containerNames []string) {
	var instances = make([]Instance, 0)
	containerNames = make([]string, 0)
	var maxTimeStamp = time.Now().Add(-1 * time.Second * 60 * 60 * time.Duration(ctx.config.MaxInstanceTime))
	ctx.db.Model(&Instance{}).Where("running = 1 AND created_at < ?", maxTimeStamp).Find(&instances)

	for _, instance := range instances {
		ctx.RemoveContainer(instance.HostedAtIP, instance.ContainerID)
		containerNames = append(containerNames, instance.Name)
	}
	ctx.db.Model(&Instance{}).Where("running = 1 AND created_at < ?", maxTimeStamp).UpdateColumn("running", false)

	return
}

func MonitorHosts(ctx *context) (startedHosts bool, deletedHosts []string, err error) {
	hosts := ctx.ListHosts()
	deletedHosts = make([]string, 0)
	zeros := 0
	for _, host := range hosts {
		if host.NumberOfContainers == 0 {
			zeros++
		}
	}
	if zeros == 0 {
		err = ctx.NewHost()
		if err != nil {
			return
		}
		startedHosts = true
		return
	} else if zeros > 1 {
		for _, host := range hosts {
			if zeros == 1 {
				break
			}
			if host.NumberOfContainers == 0 {
				err = ctx.DeleteHost(host.PublicIP)
				zeros--
				deletedHosts = append(deletedHosts, host.PublicIP)
			}
		}
	}
	return
}
<|endoftext|>


<commit_before>package goutility

import "encoding/json"

func MarshalToJSON(v interface{}) ([]byte, ErrorTypeInterface) {
	rawData, error := json.Marshal(v)
	if error != nil {
		return nil, MakeMashalError(v, error)
	}

	return rawData, nil
}

func MarshalIndentToJSON(v interface{}, prefix string, indent string) ([]byte, ErrorTypeInterface) {
	rawData, error := json.MarshalIndent(v, prefix, indent)
	if error != nil {
		return nil, MakeMashalError(v, error)
	}

	return rawData, nil
}

func UnmarshalFromJSON(data []byte, v interface{}) ErrorTypeInterface {
	error := json.Unmarshal(data, v)
	if error != nil {
		return MakeUnmashalError(v, error)
	}

	return nil
}
<commit_msg>JSON Safe Time (automarshal/unmarshal)<commit_after>package goutility

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"
)

func MarshalToJSON(v interface{}) ([]byte, ErrorTypeInterface) {
	rawData, error := json.Marshal(v)
	if error != nil {
		return nil, MakeMashalError(v, error)
	}

	return rawData, nil
}

func MarshalIndentToJSON(v interface{}, prefix string, indent string) ([]byte, ErrorTypeInterface) {
	rawData, error := json.MarshalIndent(v, prefix, indent)
	if error != nil {
		return nil, MakeMashalError(v, error)
	}

	return rawData, nil
}

func UnmarshalFromJSON(data []byte, v interface{}) ErrorTypeInterface {
	error := json.Unmarshal(data, v)
	if error != nil {
		return MakeUnmashalError(v, error)
	}

	return nil
}

// region JSON Safe Time

type JSONSafeTime struct {
	time.Time
}

func (this *JSONSafeTime) Format() string {
	return time.RFC3339Nano
}

func (this *JSONSafeTime) UnmarshalJSON(b []byte) (err error) {
	string := strings.Trim(string(b), "\"")
	if string == "null" {
		this.Time = time.Time{}
		return
	}
	this.Time, err = time.Parse(this.Format(), string)
	return
}

func (this *JSONSafeTime) MarshalJSON() ([]byte, error) {
	if this.Time.UnixNano() == (time.Time{}).UnixNano() {
		return []byte("null"), nil
	}
	return []byte(fmt.Sprintf("\"%s\"", this.Time.Format(this.Format()))), nil
}

// endregion
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"log"
	"net"
	"os"
	"strings"
)

func List(fname string) (chan net.IP, error) {
	c := make(chan net.IP)
	file, err := os.Open(fname)
	if err != nil {
		return nil, err
	}
	go func() {
		scanner := bufio.NewScanner(file)
		defer file.Close()
		defer close(c)
		for scanner.Scan() {
			line := scanner.Text()
			if strings.HasPrefix(line, "#") {
				continue
			}
			c <- net.ParseIP(line)
		}
		log.Println("list done")
	}()
	return c, nil
}
<commit_msg>Minor cleanup<commit_after>package main

import (
	"bufio"
	"log"
	"net"
	"os"
	"strings"
)

func List(fname string) (chan net.IP, error) {
	file, err := os.Open(fname)
	if err != nil {
		return nil, err
	}
	c := make(chan net.IP)
	go func() {
		scanner := bufio.NewScanner(file)
		defer file.Close()
		defer close(c)
		for scanner.Scan() {
			line := scanner.Text()
			if strings.HasPrefix(line, "#") {
				continue
			}
			c <- net.ParseIP(line)
		}
		log.Println("list done")
	}()
	return c, nil
}
<|endoftext|>


<commit_before>package llog

import (
	"fmt"
	"io"
	"sync"
)

// Level represents log levels which are sorted based on the underlying number associated to it.
type Level uint8

// Definitions of available levels: Debug < Info < Warning < Error.
const (
	Debug Level = iota
	Info
	Warning
	Error
)

var (
	// levelName stores one letter representations for each level.
	levelPrefix = [4]rune{'D', 'I', 'W', 'E'}
)

// Log is an instance of a Log with a specific level set.
type Log struct {
	sync.Mutex
	io.Writer
	level Level
}

// New creates a new instance of Log that will log to the provided io.Writer only if the method used
// for logging is enabled for the provided level.
func New(w io.Writer, l Level) Log {
	return Log{Writer: w, level: l}
}

// Debug writes to the Log only if the log's level is set to Debug.
func (l *Log) Debug(msg ...interface{}) error {
	return l.log(Debug, msg...)
}

// Debugf writes a message formatted (as fmt.Printf) to the Log only if the log's level is set to Debug.
func (l *Log) Debugf(fmtStr string, msg ...interface{}) error {
	return l.logf(Debug, fmtStr, msg...)
}

// Info writes to the Log only if the log's level is set to Info.
func (l *Log) Info(msg ...interface{}) error {
	return l.log(Info, msg...)
}

// Infof writes a message formatted (as fmt.Printf) to the Log only if the log's level is set to Info.
func (l *Log) Infof(fmtStr string, msg ...interface{}) error {
	return l.logf(Info, fmtStr, msg...)
}

// Warning writes to the Log only if the log's level is set to Warning.
func (l *Log) Warning(msg ...interface{}) error {
	return l.log(Warning, msg...)
}

// Warningf writes a message formatted (as fmt.Printf) to the Log only if the log's level is set to Warning.
func (l *Log) Warningf(fmtStr string, msg ...interface{}) error {
	return l.logf(Warning, fmtStr, msg...)
}

// Error writes to the Log only if the log's level is set to Error.
func (l *Log) Error(msg ...interface{}) error {
	return l.log(Error, msg...)
}

// Errorf writes a message formatted (as fmt.Printf) to the Log only if the log's level is set to Error.
func (l *Log) Errorf(fmtStr string, msg ...interface{}) error {
	return l.logf(Error, fmtStr, msg...)
}

// log is called by all the other leveled logging functions.
func (l *Log) log(level Level, msg ...interface{}) error {
	if l.level > level {
		return nil
	}

	l.Lock()
	_, err := fmt.Fprintln(l, msg...)
	l.Unlock()
	return err
}

// logf is called by all the other leveled formatted logging functions.
func (l *Log) logf(level Level, fmtStr string, msg ...interface{}) error {
	if l.level > level {
		return nil
	}

	fmtStr = fmtStr + "\n"

	l.Lock()
	_, err := fmt.Fprintf(l, fmtStr, msg...)
	l.Unlock()
	return err
}
<commit_msg>Make Log fields private<commit_after>package llog

import (
	"fmt"
	"io"
	"sync"
)

// Level represents log levels which are sorted based on the underlying number associated to it.
type Level uint8

// Definitions of available levels: Debug < Info < Warning < Error.
const (
	Debug Level = iota
	Info
	Warning
	Error
)

var (
	// levelName stores one letter representations for each level.
	levelPrefix = [4]rune{'D', 'I', 'W', 'E'}
)

// Log is an instance of a Log with a specific level set.
type Log struct {
	m     sync.Mutex
	w     io.Writer
	level Level
}

// New creates a new instance of Log that will log to the provided io.Writer only if the method used
// for logging is enabled for the provided level.
func New(w io.Writer, l Level) Log {
	return Log{w: w, level: l}
}

// Debug writes to the Log only if the log's level is set to Debug.
func (l *Log) Debug(msg ...interface{}) error {
	return l.log(Debug, msg...)
}

// Debugf writes a message formatted (as fmt.Printf) to the Log only if the log's level is set to Debug.
func (l *Log) Debugf(fmtStr string, msg ...interface{}) error {
	return l.logf(Debug, fmtStr, msg...)
}

// Info writes to the Log only if the log's level is set to Info.
func (l *Log) Info(msg ...interface{}) error {
	return l.log(Info, msg...)
}

// Infof writes a message formatted (as fmt.Printf) to the Log only if the log's level is set to Info.
func (l *Log) Infof(fmtStr string, msg ...interface{}) error {
	return l.logf(Info, fmtStr, msg...)
}

// Warning writes to the Log only if the log's level is set to Warning.
func (l *Log) Warning(msg ...interface{}) error {
	return l.log(Warning, msg...)
}

// Warningf writes a message formatted (as fmt.Printf) to the Log only if the log's level is set to Warning.
func (l *Log) Warningf(fmtStr string, msg ...interface{}) error {
	return l.logf(Warning, fmtStr, msg...)
}

// Error writes to the Log only if the log's level is set to Error.
func (l *Log) Error(msg ...interface{}) error {
	return l.log(Error, msg...)
}

// Errorf writes a message formatted (as fmt.Printf) to the Log only if the log's level is set to Error.
func (l *Log) Errorf(fmtStr string, msg ...interface{}) error {
	return l.logf(Error, fmtStr, msg...)
}

// log is called by all the other leveled logging functions.
func (l *Log) log(level Level, msg ...interface{}) error {
	if l.level > level {
		return nil
	}

	l.m.Lock()
	_, err := fmt.Fprintln(l.w, msg...)
	l.m.Unlock()
	return err
}

// logf is called by all the other leveled formatted logging functions.
func (l *Log) logf(level Level, fmtStr string, msg ...interface{}) error {
	if l.level > level {
		return nil
	}

	fmtStr = fmtStr + "\n"

	l.m.Lock()
	_, err := fmt.Fprintf(l.w, fmtStr, msg...)
	l.m.Unlock()
	return err
}
<|endoftext|>


<commit_before><commit_msg>fix logic errors in new tls stats tracking<commit_after><|endoftext|>


<commit_before><commit_msg>Forgot to add 'flags' to the table struct<commit_after><|endoftext|>


<commit_before><commit_msg>chore: bump version to 0.11.0 (#331)<commit_after><|endoftext|>


<commit_before>package main

import (
	"strings"
	"fmt"
	"jvmgo/classpath"
)

func main() {
	cmd := parseCmd()

	if cmd.ShowVersion {
		fmt.Println("Version 0.0.1")
	} else if cmd.ShowHelp || cmd.ClassName == "" {
		printCmdUsage()
	} else {
		startJVM(cmd)
	}
}

func startJVM(cmd *Cmd) {
	fmt.Printf("Classpath: %s, className: %s, arguments: %v\n", cmd.Classpath, cmd.ClassName, cmd.Arguments)

	classloader := classpath.Parse(cmd.JrePath, cmd.Classpath)
	className := strings.Replace(cmd.ClassName, ".", "/", -1)
	classData, _, err := classloader.ReadClass(className)

	if err != nil {
		fmt.Printf("Could not find or load main class %s\n", cmd.ClassName)

		return
	}

	fmt.Printf("Class data: %v\n", classData)
}<commit_msg>Update imports<commit_after>package main

import (
	"strings"
	"fmt"
	"github.com/Frederick-S/jvmgo/classpath"
)

func main() {
	cmd := parseCmd()

	if cmd.ShowVersion {
		fmt.Println("Version 0.0.1")
	} else if cmd.ShowHelp || cmd.ClassName == "" {
		printCmdUsage()
	} else {
		startJVM(cmd)
	}
}

func startJVM(cmd *Cmd) {
	fmt.Printf("Classpath: %s, className: %s, arguments: %v\n", cmd.Classpath, cmd.ClassName, cmd.Arguments)

	classloader := classpath.Parse(cmd.JrePath, cmd.Classpath)
	className := strings.Replace(cmd.ClassName, ".", "/", -1)
	classData, _, err := classloader.ReadClass(className)

	if err != nil {
		fmt.Printf("Could not find or load main class %s\n", cmd.ClassName)

		return
	}

	fmt.Printf("Class data: %v\n", classData)
}<|endoftext|>


<commit_before>package main

import (
	att "github.com/gillesdemey/All-Things-Go/lib/allthingstalk"
	gp "github.com/gillesdemey/All-Things-Go/lib/grovepi"
	"log"
	"time"
)

func main() {

	device := att.Device{
		DeviceId:  "jEGkKxDP9INnpsXciju0r9M",
		ClientId:  "5454c20f30721aacc441ae6a",
		ClientKey: "f4jjslau4l4",
	}

	device.Setup()

	log.Printf("Device: %+v\n", device)

	/**
	 * Create the sensors
	 */
	button := att.IODevice{
		Name:        "Button",
		Pin:         2,
		Id:          "my-button",
		Type:        "sensor",
		Description: "This is my button",
		Profile: att.Profile{
			Type: "bool",
		},
	}

	led := att.IODevice{
		Name:        "LED",
		Pin:         3,
		Id:          "my-led",
		Type:        "actuator",
		Description: "This is my LED",
		Profile: att.Profile{
			Type: "int",
		},
	}

	/**
	 * Register IO Devices
	 */
	device.RegisterAsset(&button)
	device.RegisterAsset(&led)

	/**
	 * Initialize the GrovePi shield
	 */
	grovepi := *gp.InitGrovePi(0x04)

	grovepi.PinMode(button.Pin, "input")
	grovepi.PinMode(led.Pin, "output")

	log.Printf("GrovePi: %+v\n", grovepi)

	/**
	 * Send LED commands
	 */

	var status byte

	status, _ = grovepi.DigitalRead(led.Pin)

	status = invertByte(status)
	grovepi.DigitalWrite(led.Pin, status)

	time.Sleep(500 * time.Millisecond)

	status = invertByte(status)
	grovepi.DigitalWrite(led.Pin, status)

}

func invertByte(b byte) byte {
	return byte(int(b) ^ 1)
}
<commit_msg>less verbose<commit_after>package main

import (
	att "github.com/gillesdemey/All-Things-Go/lib/allthingstalk"
	gp "github.com/gillesdemey/All-Things-Go/lib/grovepi"
	"time"
)

func main() {

	device := att.Device{
		DeviceId:  "jEGkKxDP9INnpsXciju0r9M",
		ClientId:  "5454c20f30721aacc441ae6a",
		ClientKey: "f4jjslau4l4",
	}

	device.Setup()

	/**
	 * Create the sensors
	 */
	button := att.IODevice{
		Name:        "Button",
		Pin:         2,
		Id:          "my-button",
		Type:        "sensor",
		Description: "This is my button",
		Profile: att.Profile{
			Type: "bool",
		},
	}

	led := att.IODevice{
		Name:        "LED",
		Pin:         3,
		Id:          "my-led",
		Type:        "actuator",
		Description: "This is my LED",
		Profile: att.Profile{
			Type: "int",
		},
	}

	/**
	 * Register IO Devices
	 */
	device.RegisterAsset(&button)
	device.RegisterAsset(&led)

	/**
	 * Initialize the GrovePi shield
	 */
	grovepi := *gp.InitGrovePi(0x04)

	grovepi.PinMode(button.Pin, "input")
	grovepi.PinMode(led.Pin, "output")

	/**
	 * Send LED commands
	 */

	var status byte

	status, _ = grovepi.DigitalRead(led.Pin)

	status = invertByte(status)
	grovepi.DigitalWrite(led.Pin, status)

	time.Sleep(500 * time.Millisecond)

	status = invertByte(status)
	grovepi.DigitalWrite(led.Pin, status)

}

func invertByte(b byte) byte {
	return byte(int(b) ^ 1)
}
<|endoftext|>