<commit_before>// Note: I haven't had a chance to test that this works.  This example was
// graciously provided by https://github.com/zimmski
//
// You should be able to set your consumer key, and provide a public key in
// the Jira admin, as documented in:
// https://www.prodpad.com/2013/05/tech-tutorial-oauth-in-jira/
//
// To generate a public/private key pair, do something like:
// $ openssl genrsa -out private_key.pem 4096
// $ openssl rsa -pubout -in private_key.pem -out public_key.pem
// Upload the public key to Jira, and reference the private key via
// the --privatekeyfile flag.
package main

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"

	"github.com/mrjones/oauth"
)

func Usage() {
	fmt.Println("Usage:")
	fmt.Print("go run examples/jira/jira.go")
	fmt.Print("  --consumerkey <consumerkey>")
	fmt.Print("  --privatekeyfile <privatekeyfile>")
	fmt.Print("  --jiraurl <jiraurl>")
	fmt.Println("")
}

func main() {
	var consumerKey *string = flag.String(
		"consumerkey",
		"",
		"Consumer Key from service provider.")

	var privateKeyFile *string = flag.String(
		"privatekeyfile",
		"",
		"File name of a PEM encoded private key.")

	var jiraUrl *string = flag.String(
		"jiraurl",
		"",
		"Base URL of the Jira service.")

	flag.Parse()

	if len(*consumerKey) == 0 || len(*privateKeyFile) == 0 || len(*jiraUrl) == 0 {
		fmt.Println("You must set the --consumerkey, --privatekeyfile and --jiraurl flags.")
		fmt.Println("---")
		Usage()
		os.Exit(1)
	}

	privateKeyFileContents, err := ioutil.ReadFile(*privateKeyFile)
	if err != nil {
		log.Fatal(err)
	}

	block, _ := pem.Decode([]byte(privateKeyFileContents))
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		log.Fatal(err)
	}

	c := oauth.NewRSAConsumer(
		*consumerKey,
		privateKey,
		oauth.ServiceProvider{
			RequestTokenUrl:   *jiraUrl + "/plugins/servlet/oauth/request-token",
			AuthorizeTokenUrl: *jiraUrl + "/plugins/servlet/oauth/authorize",
			AccessTokenUrl:    *jiraUrl + "/plugins/servlet/oauth/access-token",
			HttpMethod:        "POST",
		})

	c.Debug(true)

	c.HttpClient = &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

	requestToken, url, err := c.GetRequestTokenAndUrl("oob")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("(1) Go to: " + url)
	fmt.Println("(2) Grant access, you should get back a verification code.")
	fmt.Println("(3) Enter that verification code here: ")

	verificationCode := ""
	fmt.Scanln(&verificationCode)

	accessToken, err := c.AuthorizeToken(requestToken, verificationCode)
	if err != nil {
		log.Fatal(err)
	}

	response, err := c.Get(*jiraUrl+"/rest/api/2/issue/BULK-1", map[string]string{}, accessToken)
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()

	bits, err := ioutil.ReadAll(response.Body)
	fmt.Println("Data: " + string(bits))

}
<commit_msg>updated jira example to new interface<commit_after>// Note: I haven't had a chance to test that this works.  This example was
// graciously provided by https://github.com/zimmski
//
// You should be able to set your consumer key, and provide a public key in
// the Jira admin, as documented in:
// https://www.prodpad.com/2013/05/tech-tutorial-oauth-in-jira/
//
// To generate a public/private key pair, do something like:
// $ openssl genrsa -out private_key.pem 4096
// $ openssl rsa -pubout -in private_key.pem -out public_key.pem
// Upload the public key to Jira, and reference the private key via
// the --privatekeyfile flag.
package main

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"

	"github.com/mrjones/oauth"
)

func Usage() {
	fmt.Println("Usage:")
	fmt.Print("go run examples/jira/jira.go")
	fmt.Print("  --consumerkey <consumerkey>")
	fmt.Print("  --privatekeyfile <privatekeyfile>")
	fmt.Print("  --jiraurl <jiraurl>")
	fmt.Println("")
}

func main() {
	var consumerKey *string = flag.String(
		"consumerkey",
		"",
		"Consumer Key from service provider.")

	var privateKeyFile *string = flag.String(
		"privatekeyfile",
		"",
		"File name of a PEM encoded private key.")

	var jiraUrl *string = flag.String(
		"jiraurl",
		"",
		"Base URL of the Jira service.")

	flag.Parse()

	if len(*consumerKey) == 0 || len(*privateKeyFile) == 0 || len(*jiraUrl) == 0 {
		fmt.Println("You must set the --consumerkey, --privatekeyfile and --jiraurl flags.")
		fmt.Println("---")
		Usage()
		os.Exit(1)
	}

	privateKeyFileContents, err := ioutil.ReadFile(*privateKeyFile)
	if err != nil {
		log.Fatal(err)
	}

	block, _ := pem.Decode([]byte(privateKeyFileContents))
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		log.Fatal(err)
	}

	c := oauth.NewRSAConsumer(
		*consumerKey,
		privateKey,
		oauth.ServiceProvider{
			RequestTokenUrl:   *jiraUrl + "/plugins/servlet/oauth/request-token",
			AuthorizeTokenUrl: *jiraUrl + "/plugins/servlet/oauth/authorize",
			AccessTokenUrl:    *jiraUrl + "/plugins/servlet/oauth/access-token",
			HttpMethod:        "POST",
		})

	c.Debug(true)

	c.HttpClient = &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

	requestToken, url, err := c.GetRequestTokenAndUrl("oob")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("(1) Go to: " + url)
	fmt.Println("(2) Grant access, you should get back a verification code.")
	fmt.Println("(3) Enter that verification code here: ")

	verificationCode := ""
	fmt.Scanln(&verificationCode)

	accessToken, err := c.AuthorizeToken(requestToken, verificationCode)
	if err != nil {
		log.Fatal(err)
	}

	client, err := c.MakeHttpClient(accessToken)
	if err != nil {
		log.Fatal(err)
	}

	response, err := client.Get(*jiraUrl+"/rest/api/2/issue/BULK-1")
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()

	bits, err := ioutil.ReadAll(response.Body)
	fmt.Println("Data: " + string(bits))

}
<|endoftext|>


<commit_before>package extra

import (
	"io"
	"bufio"
	"errors"
	"fmt"
	"net/http"
	"strings"
	"unicode"

	"github.com/belak/go-seabird"
	"github.com/belak/irc"
)

func init() {
	seabird.RegisterPlugin("bulkcnam", newBulkCNAMPlugin)
}

type bulkCNAMPlugin struct {
	Key string
}

func newBulkCNAMPlugin(b *seabird.Bot, cm *seabird.CommandMux) error {
	p := &bulkCNAMPlugin{}

	err := b.Config("bulkcnam", p)
	if err != nil {
		return err
	}

	cm.Event("cnam", p.bulkCNAMCallback, &seabird.HelpInfo{
		Usage:       "<phone #>",
		Description: "Returns the CNAM of a phone number",
	})

	return nil
}

func (p *bulkCNAMPlugin) bulkCNAMCallback(b *seabird.Bot, m *irc.Message) {
	if !m.FromChannel() {
		return
	}

	r, err := p.BulkCNAM(m.Trailing())
	if err != nil {
		b.MentionReply(m, "Error: %s", err)
		return
	}

	b.MentionReply(m, "%s", r)
}

// This function queries the BulkCNAM API for a Phone #'s
// corresponding CNAM, and returns it
func (p *bulkCNAMPlugin) BulkCNAM(number string) (string, error) {
	for _, digit := range number {
		if !unicode.IsDigit(digit) {
			return "", errors.New("Not a phone number")
		}
	}

	resp, err := http.Get(fmt.Sprintf("http://cnam.bulkcnam.com/?id=%s&did=%s", p.Key, number))
	if err != nil {
		return "", errors.New("BulkCNAM appears to be down")
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return "", errors.New("Server side error occurred")
	}

	in := bufio.NewReader(resp.Body)
	for {
		line, err := in.ReadString('\n')
		if err != nil && err != io.EOF {
			break
		}

		return strings.TrimSpace(line), nil
	}

	return "", errors.New("No results")
}
<commit_msg>fix include path<commit_after>package extra

import (
	"io"
	"bufio"
	"errors"
	"fmt"
	"net/http"
	"strings"
	"unicode"

	"github.com/belak/go-seabird"
	"github.com/go-irc/irc"
)

func init() {
	seabird.RegisterPlugin("bulkcnam", newBulkCNAMPlugin)
}

type bulkCNAMPlugin struct {
	Key string
}

func newBulkCNAMPlugin(b *seabird.Bot, cm *seabird.CommandMux) error {
	p := &bulkCNAMPlugin{}

	err := b.Config("bulkcnam", p)
	if err != nil {
		return err
	}

	cm.Event("cnam", p.bulkCNAMCallback, &seabird.HelpInfo{
		Usage:       "<phone #>",
		Description: "Returns the CNAM of a phone number",
	})

	return nil
}

func (p *bulkCNAMPlugin) bulkCNAMCallback(b *seabird.Bot, m *irc.Message) {
	if !m.FromChannel() {
		return
	}

	r, err := p.BulkCNAM(m.Trailing())
	if err != nil {
		b.MentionReply(m, "Error: %s", err)
		return
	}

	b.MentionReply(m, "%s", r)
}

// This function queries the BulkCNAM API for a Phone #'s
// corresponding CNAM, and returns it
func (p *bulkCNAMPlugin) BulkCNAM(number string) (string, error) {
	for _, digit := range number {
		if !unicode.IsDigit(digit) {
			return "", errors.New("Not a phone number")
		}
	}

	resp, err := http.Get(fmt.Sprintf("http://cnam.bulkcnam.com/?id=%s&did=%s", p.Key, number))
	if err != nil {
		return "", errors.New("BulkCNAM appears to be down")
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return "", errors.New("Server side error occurred")
	}

	in := bufio.NewReader(resp.Body)
	for {
		line, err := in.ReadString('\n')
		if err != nil && err != io.EOF {
			break
		}

		return strings.TrimSpace(line), nil
	}

	return "", errors.New("No results")
}
<|endoftext|>


<commit_before>package logs

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net/url"
	"path/filepath"
	"strings"
	"time"

	"github.com/dokku/dokku/plugins/common"
	"github.com/joncalhoun/qson"
)

type vectorConfig struct {
	Sources map[string]vectorSource `json:"sources"`
	Sinks   map[string]vectorSink   `json:"sinks"`
}

type vectorSource struct {
	Type          string   `json:"type"`
	IncludeLabels []string `json:"include_labels,omitempty"`
}

type vectorSink map[string]interface{}

const vectorContainerName = "vector"

func killVectorContainer() error {
	if !common.ContainerExists(vectorContainerName) {
		return nil
	}

	if err := stopVectorContainer(); err != nil {
		return err
	}

	time.Sleep(10 * time.Second)
	if err := removeVectorContainer(); err != nil {
		return err
	}

	return nil
}

func removeVectorContainer() error {
	if !common.ContainerExists(vectorContainerName) {
		return nil
	}

	cmd := common.NewShellCmd(strings.Join([]string{
		common.DockerBin(), "container", "rm", "-f", vectorContainerName}, " "))

	return common.SuppressOutput(func() error {
		if cmd.Execute() {
			return nil
		}

		if common.ContainerExists(vectorContainerName) {
			return errors.New("Unable to remove vector container")
		}

		return nil
	})
}

func startVectorContainer(vectorImage string) error {
	cmd := common.NewShellCmd(strings.Join([]string{
		common.DockerBin(),
		"container",
		"run", "--detach", "--name", vectorContainerName, common.MustGetEnv("DOKKU_GLOBAL_RUN_ARGS"),
		"--restart", "unless-stopped",
		"--volume", "/var/lib/dokku/data/logs/vector.json:/etc/vector/vector.json",
		"--volume", "/var/run/docker.sock:/var/run/docker.sock",
		"--volume", common.MustGetEnv("DOKKU_LOGS_HOST_DIR") + ":/var/logs/dokku/apps",
		"--volume", common.MustGetEnv("DOKKU_LOGS_HOST_DIR") + "/apps:/var/log/dokku/apps",
		vectorImage,
		"--config", "/etc/vector/vector.json", "--watch-config", "1"}, " "))
	cmd.ShowOutput = false

	if !cmd.Execute() {
		return errors.New("Unable to start vector container")
	}

	return nil
}

func stopVectorContainer() error {
	if !common.ContainerExists(vectorContainerName) {
		return nil
	}

	if !common.ContainerIsRunning(vectorContainerName) {
		return nil
	}

	cmd := common.NewShellCmd(strings.Join([]string{
		common.DockerBin(), "container", "stop", vectorContainerName}, " "))

	return common.SuppressOutput(func() error {
		if cmd.Execute() {
			return nil
		}

		if common.ContainerIsRunning(vectorContainerName) {
			return errors.New("Unable to stop vector container")
		}

		return nil
	})
}

func sinkValueToConfig(appName string, sinkValue string) (vectorSink, error) {
	var data vectorSink
	if strings.Contains(sinkValue, "://") {
		parts := strings.SplitN(sinkValue, "://", 2)
		parts[0] = strings.ReplaceAll(parts[0], "_", "-")
		sinkValue = strings.Join(parts, "://")
	}
	u, err := url.Parse(sinkValue)
	if err != nil {
		return data, err
	}

	if u.Query().Get("sinks") != "" {
		return data, errors.New("Invalid option sinks")
	}

	u.Scheme = strings.ReplaceAll(u.Scheme, "-", "_")

	query := u.RawQuery
	if strings.HasPrefix(query, "&") {
		query = strings.TrimPrefix(query, "&")
	}

	b, err := qson.ToJSON(query)
	if err != nil {
		return data, err
	}

	if err := json.Unmarshal(b, &data); err != nil {
		return data, err
	}

	data["type"] = u.Scheme
	data["inputs"] = []string{"docker-source:" + appName}
	if appName == "--global" {
		data["inputs"] = []string{"docker-global-source"}
	}
	if appName == "--null" {
		data["inputs"] = []string{"docker-null-source"}
	}

	return data, nil
}

func writeVectorConfig() error {
	apps, _ := common.UnfilteredDokkuApps()
	data := vectorConfig{
		Sources: map[string]vectorSource{},
		Sinks:   map[string]vectorSink{},
	}
	for _, appName := range apps {
		value := common.PropertyGet("logs", appName, "vector-sink")
		if value == "" {
			continue
		}

		appName = strings.ReplaceAll(appName, ".", "-")
		sink, err := sinkValueToConfig(appName, value)
		if err != nil {
			return err
		}

		data.Sources[fmt.Sprintf("docker-source:%s", appName)] = vectorSource{
			Type:          "docker_logs",
			IncludeLabels: []string{fmt.Sprintf("com.dokku.app-name=%s", appName)},
		}

		data.Sinks[fmt.Sprintf("docker-sink:%s", appName)] = sink
	}

	value := common.PropertyGet("logs", "--global", "vector-sink")
	if value != "" {
		sink, err := sinkValueToConfig("--global", value)
		if err != nil {
			return err
		}

		data.Sources["docker-global-source"] = vectorSource{
			Type:          "docker_logs",
			IncludeLabels: []string{"com.dokku.app-name"},
		}

		data.Sinks["docker-global-sink"] = sink
	}

	if len(data.Sources) == 0 {
		// pull from no containers
		data.Sources["docker-null-source"] = vectorSource{
			Type:          "docker_logs",
			IncludeLabels: []string{"com.dokku.vector-null"},
		}
	}

	if len(data.Sinks) == 0 {
		// write logs to a blackhole
		sink, err := sinkValueToConfig("--null", VectorDefaultSink)
		if err != nil {
			return err
		}

		data.Sinks["docker-null-sink"] = sink
	}

	b, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		return err
	}

	b = bytes.Replace(b, []byte("\\u0026"), []byte("&"), -1)

	vectorConfig := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "logs", "vector.json")
	if err := common.WriteSliceToFile(vectorConfig, []string{string(b)}); err != nil {
		return err
	}

	return nil
}
<commit_msg>remove --watch-config argument on startVectorContainer<commit_after>package logs

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net/url"
	"path/filepath"
	"strings"
	"time"

	"github.com/dokku/dokku/plugins/common"
	"github.com/joncalhoun/qson"
)

type vectorConfig struct {
	Sources map[string]vectorSource `json:"sources"`
	Sinks   map[string]vectorSink   `json:"sinks"`
}

type vectorSource struct {
	Type          string   `json:"type"`
	IncludeLabels []string `json:"include_labels,omitempty"`
}

type vectorSink map[string]interface{}

const vectorContainerName = "vector"

func killVectorContainer() error {
	if !common.ContainerExists(vectorContainerName) {
		return nil
	}

	if err := stopVectorContainer(); err != nil {
		return err
	}

	time.Sleep(10 * time.Second)
	if err := removeVectorContainer(); err != nil {
		return err
	}

	return nil
}

func removeVectorContainer() error {
	if !common.ContainerExists(vectorContainerName) {
		return nil
	}

	cmd := common.NewShellCmd(strings.Join([]string{
		common.DockerBin(), "container", "rm", "-f", vectorContainerName}, " "))

	return common.SuppressOutput(func() error {
		if cmd.Execute() {
			return nil
		}

		if common.ContainerExists(vectorContainerName) {
			return errors.New("Unable to remove vector container")
		}

		return nil
	})
}

func startVectorContainer(vectorImage string) error {
	cmd := common.NewShellCmd(strings.Join([]string{
		common.DockerBin(),
		"container",
		"run", "--detach", "--name", vectorContainerName, common.MustGetEnv("DOKKU_GLOBAL_RUN_ARGS"),
		"--restart", "unless-stopped",
		"--volume", "/var/lib/dokku/data/logs/vector.json:/etc/vector/vector.json",
		"--volume", "/var/run/docker.sock:/var/run/docker.sock",
		"--volume", common.MustGetEnv("DOKKU_LOGS_HOST_DIR") + ":/var/logs/dokku/apps",
		"--volume", common.MustGetEnv("DOKKU_LOGS_HOST_DIR") + "/apps:/var/log/dokku/apps",
		vectorImage,
		"--config", "/etc/vector/vector.json", "--watch-config"}, " "))
	cmd.ShowOutput = false

	if !cmd.Execute() {
		return errors.New("Unable to start vector container")
	}

	return nil
}

func stopVectorContainer() error {
	if !common.ContainerExists(vectorContainerName) {
		return nil
	}

	if !common.ContainerIsRunning(vectorContainerName) {
		return nil
	}

	cmd := common.NewShellCmd(strings.Join([]string{
		common.DockerBin(), "container", "stop", vectorContainerName}, " "))

	return common.SuppressOutput(func() error {
		if cmd.Execute() {
			return nil
		}

		if common.ContainerIsRunning(vectorContainerName) {
			return errors.New("Unable to stop vector container")
		}

		return nil
	})
}

func sinkValueToConfig(appName string, sinkValue string) (vectorSink, error) {
	var data vectorSink
	if strings.Contains(sinkValue, "://") {
		parts := strings.SplitN(sinkValue, "://", 2)
		parts[0] = strings.ReplaceAll(parts[0], "_", "-")
		sinkValue = strings.Join(parts, "://")
	}
	u, err := url.Parse(sinkValue)
	if err != nil {
		return data, err
	}

	if u.Query().Get("sinks") != "" {
		return data, errors.New("Invalid option sinks")
	}

	u.Scheme = strings.ReplaceAll(u.Scheme, "-", "_")

	query := u.RawQuery
	if strings.HasPrefix(query, "&") {
		query = strings.TrimPrefix(query, "&")
	}

	b, err := qson.ToJSON(query)
	if err != nil {
		return data, err
	}

	if err := json.Unmarshal(b, &data); err != nil {
		return data, err
	}

	data["type"] = u.Scheme
	data["inputs"] = []string{"docker-source:" + appName}
	if appName == "--global" {
		data["inputs"] = []string{"docker-global-source"}
	}
	if appName == "--null" {
		data["inputs"] = []string{"docker-null-source"}
	}

	return data, nil
}

func writeVectorConfig() error {
	apps, _ := common.UnfilteredDokkuApps()
	data := vectorConfig{
		Sources: map[string]vectorSource{},
		Sinks:   map[string]vectorSink{},
	}
	for _, appName := range apps {
		value := common.PropertyGet("logs", appName, "vector-sink")
		if value == "" {
			continue
		}

		appName = strings.ReplaceAll(appName, ".", "-")
		sink, err := sinkValueToConfig(appName, value)
		if err != nil {
			return err
		}

		data.Sources[fmt.Sprintf("docker-source:%s", appName)] = vectorSource{
			Type:          "docker_logs",
			IncludeLabels: []string{fmt.Sprintf("com.dokku.app-name=%s", appName)},
		}

		data.Sinks[fmt.Sprintf("docker-sink:%s", appName)] = sink
	}

	value := common.PropertyGet("logs", "--global", "vector-sink")
	if value != "" {
		sink, err := sinkValueToConfig("--global", value)
		if err != nil {
			return err
		}

		data.Sources["docker-global-source"] = vectorSource{
			Type:          "docker_logs",
			IncludeLabels: []string{"com.dokku.app-name"},
		}

		data.Sinks["docker-global-sink"] = sink
	}

	if len(data.Sources) == 0 {
		// pull from no containers
		data.Sources["docker-null-source"] = vectorSource{
			Type:          "docker_logs",
			IncludeLabels: []string{"com.dokku.vector-null"},
		}
	}

	if len(data.Sinks) == 0 {
		// write logs to a blackhole
		sink, err := sinkValueToConfig("--null", VectorDefaultSink)
		if err != nil {
			return err
		}

		data.Sinks["docker-null-sink"] = sink
	}

	b, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		return err
	}

	b = bytes.Replace(b, []byte("\\u0026"), []byte("&"), -1)

	vectorConfig := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "logs", "vector.json")
	if err := common.WriteSliceToFile(vectorConfig, []string{string(b)}); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package assert

import (
	"fmt"
	"io"
	"os"
)

type location struct {
	Test     string
	FileName string
	Line     int
}

type errorLogger interface {
	Log(location *location, message string)
}

var theLogger errorLogger = &errorLoggerImpl{writer: os.Stdout}

type errorLoggerImpl struct {
	writer       io.Writer
	prevTestName string
	prevTestLine int
}

const (
	failOutput                  = "\n--- FAIL: %s\n\t%s:%d\n\t\t%s\n"
	failOutputWithoutFailLine   = "\t%s:%d\n\t\t%s\n"
	failOutputWithoutLineNumber = "\t\t%s\n"
)

func (logger *errorLoggerImpl) Log(location *location, message string) {
	args := []interface{}{location.Test, location.FileName, location.Line, message}
	if logger.prevTestName != location.Test {
		fmt.Fprintf(logger.writer, failOutput, args...)
	} else if logger.prevTestLine != location.Line {
		fmt.Fprintf(logger.writer, failOutputWithoutFailLine, args[1:]...)
	} else {
		fmt.Fprintf(logger.writer, failOutputWithoutLineNumber, message)
	}
	logger.prevTestName = location.Test
	logger.prevTestLine = location.Line
}
<commit_msg>refactoring: simplified Log method<commit_after>package assert

import (
	"fmt"
	"io"
	"os"
)

type location struct {
	Test     string
	FileName string
	Line     int
}

type errorLogger interface {
	Log(location *location, message string)
}

var theLogger errorLogger = &errorLoggerImpl{writer: os.Stdout}

type errorLoggerImpl struct {
	writer       io.Writer
	prevTestName string
	prevTestLine int
}

const (
	formatHeaderFull  = "\n--- FAIL: %s\n\t%s:%d\n"
	formatHeaderShort = "\t%s:%d\n"
	formatMessage     = "\t\t%s\n"
)

func (logger *errorLoggerImpl) Log(location *location, message string) {
	if logger.prevTestName != location.Test {
		fmt.Fprintf(logger.writer, formatHeaderFull, location.Test, location.FileName, location.Line)
	} else if logger.prevTestLine != location.Line {
		fmt.Fprintf(logger.writer, formatHeaderShort, location.FileName, location.Line)
	}
	fmt.Fprintf(logger.writer, formatMessage, message)
	logger.prevTestName = location.Test
	logger.prevTestLine = location.Line
}
<|endoftext|>


<commit_before>package base

import (
	"crypto/aes"
	"crypto/cipher"
	"math/big"
	"fmt"
)

var FIXED_KEY Key = []byte{83, 36, 191, 126, 172, 151, 226, 234, 140, 225, 71, 219, 216, 96, 130, 209, 17,
	13, 67, 12, 74, 207, 217, 7, 20, 13, 151, 20, 179, 221, 190, 245}

var aesprf cipher.Block

type DKC interface {
	E(A, B, T, X Key) Key
	D(A, B, T, P Key) Key
}

func init() {
	a, err := aes.NewCipher(FIXED_KEY)
	if err != nil {
		panic(err)
	}
	aesprf = a
}

//--- Ga

func GaDKC_E(A, B, T, X Key) Key {
	K := XorKey(A, B)
	K = XorKey(K, T)
	ciphertext := make([]byte, aes.BlockSize)
	aesprf.Encrypt(ciphertext, K)

	rho := XorKey(ciphertext, K)
	return XorKey(rho, X)
}

func GaDKC_D(A, B, T, P Key) Key {
	K := XorKey(A, B)
	K = XorKey(K, T)
	ciphertext := make([]byte, aes.BlockSize)
	aesprf.Encrypt(ciphertext, K)

	rho := XorKey(ciphertext, K)
	return XorKey(rho, P)
}

//--- GaX

func GaXDKC_E(A, B, T, X Key) Key {
	fmt.Println("hello")
	if len(A) != 16 || len(B) != 16 {
		panic("Doubling approach won't work")
	}
	A2i := new(big.Int)
	A2i.SetBytes(A)
	A2i.Lsh(A2i, 1)
	// log.Printf("A=%v, A2i = %v\n", A, A2i)
	A2 := make([]byte, 16)
	copy(A2, A2i.Bytes()[max(len(A2i.Bytes())-16, 0):])

	B4i := new(big.Int)
	B4i.SetBytes(B)
	B4i.Lsh(B4i, 2)
	B4 := make([]byte, 16)
	copy(B4, B4i.Bytes()[max(len(B4i.Bytes())-16, 0):])

	K := XorKey(A2, B4)
	K = XorKey(K, T)

	ciphertext := make([]byte, aes.BlockSize)
	aesprf.Encrypt(ciphertext, K)

	rho := XorKey(ciphertext, K)
	return XorKey(rho, X)
}

func GaXDKC_D(A, B, T, P Key) Key {
	if len(A) != 16 || len(B) != 16 {
		panic("Doubling approach won't work")
	}
	A2i := new(big.Int)
	A2i.SetBytes(A)
	A2i.Lsh(A2i, 1)
	A2 := make([]byte, 16)
	copy(A2, A2i.Bytes()[max(len(A2i.Bytes())-16, 0):])

	B4i := new(big.Int)
	B4i.SetBytes(B)
	B4i.Lsh(B4i, 2)
	B4 := make([]byte, 16)
	copy(B4, B4i.Bytes()[max(len(B4i.Bytes())-16, 0):])

	K := XorKey(A2, B4)
	K = XorKey(K, T)

	ciphertext := make([]byte, aes.BlockSize)
	aesprf.Encrypt(ciphertext, K)

	rho := XorKey(ciphertext, K)
	return XorKey(rho, P)
}

func max(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}
<commit_msg>resolved<commit_after>package base

import (
	"crypto/aes"
	"crypto/cipher"
	"math/big"
)

var FIXED_KEY Key = []byte{83, 36, 191, 126, 172, 151, 226, 234, 140, 225, 71, 219, 216, 96, 130, 209, 17,
	13, 67, 12, 74, 207, 217, 7, 20, 13, 151, 20, 179, 221, 190, 245}

var aesprf cipher.Block

type DKC interface {
	E(A, B, T, X Key) Key
	D(A, B, T, P Key) Key
}

func init() {
	a, err := aes.NewCipher(FIXED_KEY)
	if err != nil {
		panic(err)
	}
	aesprf = a
}

//--- Ga

func GaDKC_E(A, B, T, X Key) Key {
	K := XorKey(A, B)
	K = XorKey(K, T)
	ciphertext := make([]byte, aes.BlockSize)
	aesprf.Encrypt(ciphertext, K)

	rho := XorKey(ciphertext, K)
	return XorKey(rho, X)
}

func GaDKC_D(A, B, T, P Key) Key {
	K := XorKey(A, B)
	K = XorKey(K, T)
	ciphertext := make([]byte, aes.BlockSize)
	aesprf.Encrypt(ciphertext, K)

	rho := XorKey(ciphertext, K)
	return XorKey(rho, P)
}

//--- GaX

func GaXDKC_E(A, B, T, X Key) Key {
	if len(A) != 16 || len(B) != 16 {
		panic("Doubling approach won't work")
	}
	A2i := new(big.Int)
	A2i.SetBytes(A)
	A2i.Lsh(A2i, 1)
	// log.Printf("A=%v, A2i = %v\n", A, A2i)
	A2 := make([]byte, 16)
	copy(A2, A2i.Bytes()[max(len(A2i.Bytes())-16, 0):])

	B4i := new(big.Int)
	B4i.SetBytes(B)
	B4i.Lsh(B4i, 2)
	B4 := make([]byte, 16)
	copy(B4, B4i.Bytes()[max(len(B4i.Bytes())-16, 0):])

	K := XorKey(A2, B4)
	K = XorKey(K, T)

	ciphertext := make([]byte, aes.BlockSize)
	aesprf.Encrypt(ciphertext, K)

	rho := XorKey(ciphertext, K)
	return XorKey(rho, X)
}

func GaXDKC_D(A, B, T, P Key) Key {
	if len(A) != 16 || len(B) != 16 {
		panic("Doubling approach won't work")
	}
	A2i := new(big.Int)
	A2i.SetBytes(A)
	A2i.Lsh(A2i, 1)
	A2 := make([]byte, 16)
	copy(A2, A2i.Bytes()[max(len(A2i.Bytes())-16, 0):])

	B4i := new(big.Int)
	B4i.SetBytes(B)
	B4i.Lsh(B4i, 2)
	B4 := make([]byte, 16)
	copy(B4, B4i.Bytes()[max(len(B4i.Bytes())-16, 0):])

	K := XorKey(A2, B4)
	K = XorKey(K, T)

	ciphertext := make([]byte, aes.BlockSize)
	aesprf.Encrypt(ciphertext, K)

	rho := XorKey(ciphertext, K)
	return XorKey(rho, P)
}

func max(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}
<|endoftext|>


<commit_before>package postal

import (
	"log"
	"time"

	"github.com/cloudfoundry-incubator/notifications/db"
	"github.com/cloudfoundry-incubator/notifications/gobble"
	"github.com/cloudfoundry-incubator/notifications/postal/common"
	"github.com/cloudfoundry-incubator/notifications/v1/services"
	"github.com/pivotal-golang/lager"
	"github.com/rcrowley/go-metrics"
)

type DeliveryJobProcessor interface {
	Process(job *gobble.Job, logger lager.Logger) error
}

type v2DeliveryJobProcessor interface {
	Process(delivery common.Delivery, logger lager.Logger) error
}

type campaignJobProcessor interface {
	Process(conn services.ConnectionInterface, uaaHost string, job gobble.Job, logger lager.Logger) error
}

type messageStatusUpdater interface {
	Update(conn db.ConnectionInterface, messageID, messageStatus, campaignID string, logger lager.Logger)
}

type deliveryFailureHandler interface {
	Handle(job common.Retryable, logger lager.Logger)
}

type DeliveryWorkerConfig struct {
	ID                     int
	UAAHost                string
	Logger                 lager.Logger
	Queue                  gobble.QueueInterface
	DBTrace                bool
	Database               db.DatabaseInterface
	CampaignJobProcessor   campaignJobProcessor
	DeliveryFailureHandler deliveryFailureHandler
	MessageStatusUpdater   messageStatusUpdater
}

type DeliveryWorker struct {
	gobble.Worker

	uaaHost                string
	DeliveryJobProcessor   DeliveryJobProcessor
	V2DeliveryJobProcessor v2DeliveryJobProcessor
	logger                 lager.Logger
	database               db.DatabaseInterface
	campaignJobProcessor   campaignJobProcessor
	deliveryFailureHandler deliveryFailureHandler
	messageStatusUpdater   messageStatusUpdater
}

func NewDeliveryWorker(v1DeliveryJobProcessor DeliveryJobProcessor, config DeliveryWorkerConfig) DeliveryWorker {
	worker := DeliveryWorker{
		DeliveryJobProcessor:   v1DeliveryJobProcessor,
		uaaHost:                config.UAAHost,
		logger:                 config.Logger,
		database:               config.Database,
		campaignJobProcessor:   config.CampaignJobProcessor,
		deliveryFailureHandler: config.DeliveryFailureHandler,
		messageStatusUpdater:   config.MessageStatusUpdater,
	}
	ticker := gobble.NewTicker(time.NewTicker, 30*time.Second)
	heartbeater := gobble.NewHeartbeater(config.Queue, ticker)
	worker.Worker = gobble.NewWorker(config.ID, config.Queue, worker.Deliver, heartbeater)

	return worker
}

func (worker DeliveryWorker) Deliver(job *gobble.Job) {
	var typedJob struct {
		JobType string
	}

	err := job.Unmarshal(&typedJob)
	if err != nil {
		metrics.GetOrRegisterCounter("notifications.worker.panic.json", nil).Inc(1)

		log.Printf("Error: Could not unmarshal %+v", job)
		worker.deliveryFailureHandler.Handle(job, worker.logger)
		return
	}

	worker.DeliveryJobProcessor.Process(job, worker.logger)
}
<commit_msg>Logging: Remove unmarshal logging details.<commit_after>package postal

import (
	"time"

	"github.com/cloudfoundry-incubator/notifications/db"
	"github.com/cloudfoundry-incubator/notifications/gobble"
	"github.com/cloudfoundry-incubator/notifications/postal/common"
	"github.com/cloudfoundry-incubator/notifications/v1/services"
	"github.com/pivotal-golang/lager"
	"github.com/rcrowley/go-metrics"
)

type DeliveryJobProcessor interface {
	Process(job *gobble.Job, logger lager.Logger) error
}

type v2DeliveryJobProcessor interface {
	Process(delivery common.Delivery, logger lager.Logger) error
}

type campaignJobProcessor interface {
	Process(conn services.ConnectionInterface, uaaHost string, job gobble.Job, logger lager.Logger) error
}

type messageStatusUpdater interface {
	Update(conn db.ConnectionInterface, messageID, messageStatus, campaignID string, logger lager.Logger)
}

type deliveryFailureHandler interface {
	Handle(job common.Retryable, logger lager.Logger)
}

type DeliveryWorkerConfig struct {
	ID                     int
	UAAHost                string
	Logger                 lager.Logger
	Queue                  gobble.QueueInterface
	DBTrace                bool
	Database               db.DatabaseInterface
	CampaignJobProcessor   campaignJobProcessor
	DeliveryFailureHandler deliveryFailureHandler
	MessageStatusUpdater   messageStatusUpdater
}

type DeliveryWorker struct {
	gobble.Worker

	uaaHost                string
	DeliveryJobProcessor   DeliveryJobProcessor
	V2DeliveryJobProcessor v2DeliveryJobProcessor
	logger                 lager.Logger
	database               db.DatabaseInterface
	campaignJobProcessor   campaignJobProcessor
	deliveryFailureHandler deliveryFailureHandler
	messageStatusUpdater   messageStatusUpdater
}

func NewDeliveryWorker(v1DeliveryJobProcessor DeliveryJobProcessor, config DeliveryWorkerConfig) DeliveryWorker {
	worker := DeliveryWorker{
		DeliveryJobProcessor:   v1DeliveryJobProcessor,
		uaaHost:                config.UAAHost,
		logger:                 config.Logger,
		database:               config.Database,
		campaignJobProcessor:   config.CampaignJobProcessor,
		deliveryFailureHandler: config.DeliveryFailureHandler,
		messageStatusUpdater:   config.MessageStatusUpdater,
	}
	ticker := gobble.NewTicker(time.NewTicker, 30*time.Second)
	heartbeater := gobble.NewHeartbeater(config.Queue, ticker)
	worker.Worker = gobble.NewWorker(config.ID, config.Queue, worker.Deliver, heartbeater)

	return worker
}

func (worker DeliveryWorker) Deliver(job *gobble.Job) {
	var typedJob struct {
		JobType string
	}

	err := job.Unmarshal(&typedJob)
	if err != nil {
		metrics.GetOrRegisterCounter("notifications.worker.panic.json", nil).Inc(1)

		worker.deliveryFailureHandler.Handle(job, worker.logger)
		return
	}

	worker.DeliveryJobProcessor.Process(job, worker.logger)
}
<|endoftext|>


<commit_before>package docker

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strconv"
	"strings"
	"sync"
	"time"

	docker "github.com/fsouza/go-dockerclient"

	"github.com/weaveworks/scope/report"
)

// These constants are keys used in node metadata
const (
	ContainerName    = "docker_container_name"
	ContainerCommand = "docker_container_command"
	ContainerPorts   = "docker_container_ports"
	ContainerCreated = "docker_container_created"

	NetworkRxDropped = "network_rx_dropped"
	NetworkRxBytes   = "network_rx_bytes"
	NetworkRxErrors  = "network_rx_errors"
	NetworkTxPackets = "network_tx_packets"
	NetworkTxDropped = "network_tx_dropped"
	NetworkRxPackets = "network_rx_packets"
	NetworkTxErrors  = "network_tx_errors"
	NetworkTxBytes   = "network_tx_bytes"

	MemoryMaxUsage = "memory_max_usage"
	MemoryUsage    = "memory_usage"
	MemoryFailcnt  = "memory_failcnt"
	MemoryLimit    = "memory_limit"

	CPUPercpuUsage       = "cpu_per_cpu_usage"
	CPUUsageInUsermode   = "cpu_usage_in_usermode"
	CPUTotalUsage        = "cpu_total_usage"
	CPUUsageInKernelmode = "cpu_usage_in_kernelmode"
	CPUSystemCPUUsage    = "cpu_system_cpu_usage"
)

// Exported for testing
var (
	DialStub          = net.Dial
	NewClientConnStub = newClientConn
)

func newClientConn(c net.Conn, r *bufio.Reader) ClientConn {
	return httputil.NewClientConn(c, r)
}

// ClientConn is exported for testing
type ClientConn interface {
	Do(req *http.Request) (resp *http.Response, err error)
	Close() error
}

// Container represents a Docker container
type Container interface {
	ID() string
	Image() string
	PID() int
	GetNodeMetadata() report.NodeMetadata

	StartGatheringStats() error
	StopGatheringStats()
}

type container struct {
	sync.RWMutex
	container   *docker.Container
	statsConn   ClientConn
	latestStats *docker.Stats
}

// NewContainer creates a new Container
func NewContainer(c *docker.Container) Container {
	return &container{container: c}
}

func (c *container) ID() string {
	return c.container.ID
}

func (c *container) Image() string {
	return c.container.Image
}

func (c *container) PID() int {
	return c.container.State.Pid
}

func (c *container) StartGatheringStats() error {
	c.Lock()
	defer c.Unlock()

	if c.statsConn != nil {
		return fmt.Errorf("already gather stats for container %s", c.container.ID)
	}

	go func() {
		log.Printf("docker container: collecting stats for %s", c.container.ID)
		req, err := http.NewRequest("GET", fmt.Sprintf("/containers/%s/stats", c.container.ID), nil)
		if err != nil {
			log.Printf("docker container: %v", err)
			return
		}
		req.Header.Set("User-Agent", "weavescope")

		url, err := url.Parse(endpoint)
		if err != nil {
			log.Printf("docker container: %v", err)
			return
		}

		dial, err := DialStub(url.Scheme, url.Path)
		if err != nil {
			log.Printf("docker container: %v", err)
			return
		}

		conn := NewClientConnStub(dial, nil)
		resp, err := conn.Do(req)
		if err != nil {
			log.Printf("docker container: %v", err)
			return
		}

		c.Lock()
		c.statsConn = conn
		c.Unlock()

		defer func() {
			c.Lock()
			defer c.Unlock()

			log.Printf("docker container: stopped collecting stats for %s", c.container.ID)
			c.statsConn = nil
			c.latestStats = nil
		}()

		stats := &docker.Stats{}
		decoder := json.NewDecoder(resp.Body)

		for err := decoder.Decode(&stats); err != io.EOF; err = decoder.Decode(&stats) {
			if err != nil {
				log.Printf("docker container: error reading event %v", err)
				return
			}

			c.Lock()
			c.latestStats = stats
			c.Unlock()

			stats = &docker.Stats{}
		}
	}()

	return nil
}

func (c *container) StopGatheringStats() {
	c.Lock()
	defer c.Unlock()

	if c.statsConn == nil {
		return
	}

	c.statsConn.Close()
	c.statsConn = nil
	c.latestStats = nil
	return
}

func (c *container) ports() string {
	if c.container.NetworkSettings == nil {
		return ""
	}

	ports := []string{}
	for port, bindings := range c.container.NetworkSettings.Ports {
		if len(bindings) == 0 {
			ports = append(ports, fmt.Sprintf("%s", port))
			continue
		}
		for _, b := range bindings {
			ports = append(ports, fmt.Sprintf("%s:%s->%s", b.HostIP, b.HostPort, port))
		}
	}

	return strings.Join(ports, ", ")
}

func (c *container) GetNodeMetadata() report.NodeMetadata {
	c.RLock()
	defer c.RUnlock()

	result := report.MakeNodeMetadataWith(map[string]string{
		ContainerID:      c.ID(),
		ContainerName:    strings.TrimPrefix(c.container.Name, "/"),
		ContainerPorts:   c.ports(),
		ContainerCreated: c.container.Created.Format(time.RFC822),
		ContainerCommand: c.container.Path + " " + strings.Join(c.container.Args, " "),
		ImageID:          c.container.Image,
	})

	if c.latestStats == nil {
		return result
	}

	result.Merge(report.MakeNodeMetadataWith(map[string]string{
		NetworkRxDropped: strconv.FormatUint(c.latestStats.Network.RxDropped, 10),
		NetworkRxBytes:   strconv.FormatUint(c.latestStats.Network.RxBytes, 10),
		NetworkRxErrors:  strconv.FormatUint(c.latestStats.Network.RxErrors, 10),
		NetworkTxPackets: strconv.FormatUint(c.latestStats.Network.TxPackets, 10),
		NetworkTxDropped: strconv.FormatUint(c.latestStats.Network.TxDropped, 10),
		NetworkRxPackets: strconv.FormatUint(c.latestStats.Network.RxPackets, 10),
		NetworkTxErrors:  strconv.FormatUint(c.latestStats.Network.TxErrors, 10),
		NetworkTxBytes:   strconv.FormatUint(c.latestStats.Network.TxBytes, 10),

		MemoryMaxUsage: strconv.FormatUint(c.latestStats.MemoryStats.MaxUsage, 10),
		MemoryUsage:    strconv.FormatUint(c.latestStats.MemoryStats.Usage, 10),
		MemoryFailcnt:  strconv.FormatUint(c.latestStats.MemoryStats.Failcnt, 10),
		MemoryLimit:    strconv.FormatUint(c.latestStats.MemoryStats.Limit, 10),

		//		CPUPercpuUsage:       strconv.FormatUint(stats.CPUStats.CPUUsage.PercpuUsage, 10),
		CPUUsageInUsermode:   strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.UsageInUsermode, 10),
		CPUTotalUsage:        strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.TotalUsage, 10),
		CPUUsageInKernelmode: strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.UsageInKernelmode, 10),
		CPUSystemCPUUsage:    strconv.FormatUint(c.latestStats.CPUStats.SystemCPUUsage, 10),
	}))
	return result
}
<commit_msg>Change log message to make it clear this probably isn't an error.<commit_after>package docker

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strconv"
	"strings"
	"sync"
	"time"

	docker "github.com/fsouza/go-dockerclient"

	"github.com/weaveworks/scope/report"
)

// These constants are keys used in node metadata
const (
	ContainerName    = "docker_container_name"
	ContainerCommand = "docker_container_command"
	ContainerPorts   = "docker_container_ports"
	ContainerCreated = "docker_container_created"

	NetworkRxDropped = "network_rx_dropped"
	NetworkRxBytes   = "network_rx_bytes"
	NetworkRxErrors  = "network_rx_errors"
	NetworkTxPackets = "network_tx_packets"
	NetworkTxDropped = "network_tx_dropped"
	NetworkRxPackets = "network_rx_packets"
	NetworkTxErrors  = "network_tx_errors"
	NetworkTxBytes   = "network_tx_bytes"

	MemoryMaxUsage = "memory_max_usage"
	MemoryUsage    = "memory_usage"
	MemoryFailcnt  = "memory_failcnt"
	MemoryLimit    = "memory_limit"

	CPUPercpuUsage       = "cpu_per_cpu_usage"
	CPUUsageInUsermode   = "cpu_usage_in_usermode"
	CPUTotalUsage        = "cpu_total_usage"
	CPUUsageInKernelmode = "cpu_usage_in_kernelmode"
	CPUSystemCPUUsage    = "cpu_system_cpu_usage"
)

// Exported for testing
var (
	DialStub          = net.Dial
	NewClientConnStub = newClientConn
)

func newClientConn(c net.Conn, r *bufio.Reader) ClientConn {
	return httputil.NewClientConn(c, r)
}

// ClientConn is exported for testing
type ClientConn interface {
	Do(req *http.Request) (resp *http.Response, err error)
	Close() error
}

// Container represents a Docker container
type Container interface {
	ID() string
	Image() string
	PID() int
	GetNodeMetadata() report.NodeMetadata

	StartGatheringStats() error
	StopGatheringStats()
}

type container struct {
	sync.RWMutex
	container   *docker.Container
	statsConn   ClientConn
	latestStats *docker.Stats
}

// NewContainer creates a new Container
func NewContainer(c *docker.Container) Container {
	return &container{container: c}
}

func (c *container) ID() string {
	return c.container.ID
}

func (c *container) Image() string {
	return c.container.Image
}

func (c *container) PID() int {
	return c.container.State.Pid
}

func (c *container) StartGatheringStats() error {
	c.Lock()
	defer c.Unlock()

	if c.statsConn != nil {
		return fmt.Errorf("already gather stats for container %s", c.container.ID)
	}

	go func() {
		log.Printf("docker container: collecting stats for %s", c.container.ID)
		req, err := http.NewRequest("GET", fmt.Sprintf("/containers/%s/stats", c.container.ID), nil)
		if err != nil {
			log.Printf("docker container: %v", err)
			return
		}
		req.Header.Set("User-Agent", "weavescope")

		url, err := url.Parse(endpoint)
		if err != nil {
			log.Printf("docker container: %v", err)
			return
		}

		dial, err := DialStub(url.Scheme, url.Path)
		if err != nil {
			log.Printf("docker container: %v", err)
			return
		}

		conn := NewClientConnStub(dial, nil)
		resp, err := conn.Do(req)
		if err != nil {
			log.Printf("docker container: %v", err)
			return
		}

		c.Lock()
		c.statsConn = conn
		c.Unlock()

		defer func() {
			c.Lock()
			defer c.Unlock()

			log.Printf("docker container: stopped collecting stats for %s", c.container.ID)
			c.statsConn = nil
			c.latestStats = nil
		}()

		stats := &docker.Stats{}
		decoder := json.NewDecoder(resp.Body)

		for err := decoder.Decode(&stats); err != io.EOF; err = decoder.Decode(&stats) {
			if err != nil {
				log.Printf("docker container: error reading event, did container stop? %v", err)
				return
			}

			c.Lock()
			c.latestStats = stats
			c.Unlock()

			stats = &docker.Stats{}
		}
	}()

	return nil
}

func (c *container) StopGatheringStats() {
	c.Lock()
	defer c.Unlock()

	if c.statsConn == nil {
		return
	}

	c.statsConn.Close()
	c.statsConn = nil
	c.latestStats = nil
	return
}

func (c *container) ports() string {
	if c.container.NetworkSettings == nil {
		return ""
	}

	ports := []string{}
	for port, bindings := range c.container.NetworkSettings.Ports {
		if len(bindings) == 0 {
			ports = append(ports, fmt.Sprintf("%s", port))
			continue
		}
		for _, b := range bindings {
			ports = append(ports, fmt.Sprintf("%s:%s->%s", b.HostIP, b.HostPort, port))
		}
	}

	return strings.Join(ports, ", ")
}

func (c *container) GetNodeMetadata() report.NodeMetadata {
	c.RLock()
	defer c.RUnlock()

	result := report.MakeNodeMetadataWith(map[string]string{
		ContainerID:      c.ID(),
		ContainerName:    strings.TrimPrefix(c.container.Name, "/"),
		ContainerPorts:   c.ports(),
		ContainerCreated: c.container.Created.Format(time.RFC822),
		ContainerCommand: c.container.Path + " " + strings.Join(c.container.Args, " "),
		ImageID:          c.container.Image,
	})

	if c.latestStats == nil {
		return result
	}

	result.Merge(report.MakeNodeMetadataWith(map[string]string{
		NetworkRxDropped: strconv.FormatUint(c.latestStats.Network.RxDropped, 10),
		NetworkRxBytes:   strconv.FormatUint(c.latestStats.Network.RxBytes, 10),
		NetworkRxErrors:  strconv.FormatUint(c.latestStats.Network.RxErrors, 10),
		NetworkTxPackets: strconv.FormatUint(c.latestStats.Network.TxPackets, 10),
		NetworkTxDropped: strconv.FormatUint(c.latestStats.Network.TxDropped, 10),
		NetworkRxPackets: strconv.FormatUint(c.latestStats.Network.RxPackets, 10),
		NetworkTxErrors:  strconv.FormatUint(c.latestStats.Network.TxErrors, 10),
		NetworkTxBytes:   strconv.FormatUint(c.latestStats.Network.TxBytes, 10),

		MemoryMaxUsage: strconv.FormatUint(c.latestStats.MemoryStats.MaxUsage, 10),
		MemoryUsage:    strconv.FormatUint(c.latestStats.MemoryStats.Usage, 10),
		MemoryFailcnt:  strconv.FormatUint(c.latestStats.MemoryStats.Failcnt, 10),
		MemoryLimit:    strconv.FormatUint(c.latestStats.MemoryStats.Limit, 10),

		//		CPUPercpuUsage:       strconv.FormatUint(stats.CPUStats.CPUUsage.PercpuUsage, 10),
		CPUUsageInUsermode:   strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.UsageInUsermode, 10),
		CPUTotalUsage:        strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.TotalUsage, 10),
		CPUUsageInKernelmode: strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.UsageInKernelmode, 10),
		CPUSystemCPUUsage:    strconv.FormatUint(c.latestStats.CPUStats.SystemCPUUsage, 10),
	}))
	return result
}
<|endoftext|>


<commit_before>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package libkb

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"net"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/keybase/go-framed-msgpack-rpc/rpc"

	"h12.me/socks"
)

type ClientConfig struct {
	Host       string
	Port       int
	UseTLS     bool // XXX unused?
	URL        *url.URL
	RootCAs    *x509.CertPool
	Prefix     string
	UseCookies bool
	Timeout    time.Duration
}

type Client struct {
	cli    *http.Client
	config *ClientConfig
}

var hostRE = regexp.MustCompile("^([^:]+)(:([0-9]+))?$")

func SplitHost(joined string) (host string, port int, err error) {
	match := hostRE.FindStringSubmatch(joined)
	if match == nil {
		err = fmt.Errorf("Invalid host/port found: %s", joined)
	} else {
		host = match[1]
		port = 0
		if len(match[3]) > 0 {
			port, err = strconv.Atoi(match[3])
			if err != nil {
				err = fmt.Errorf("Could not convert port in host %s", joined)
			}
		}
	}
	return
}

func ParseCA(raw string) (*x509.CertPool, error) {
	ret := x509.NewCertPool()
	ok := ret.AppendCertsFromPEM([]byte(raw))
	var err error
	if !ok {
		err = fmt.Errorf("Could not read CA for keybase.io")
		ret = nil
	}
	return ret, err
}

func ShortCA(raw string) string {
	parts := strings.Split(raw, "\n")
	if len(parts) >= 3 {
		parts = parts[0:3]
	}
	return strings.Join(parts, " ") + "..."
}

// GenClientConfigForInternalAPI pulls the information out of the environment configuration,
// and build a Client config that will be used in all API server
// requests
func (e *Env) GenClientConfigForInternalAPI() (*ClientConfig, error) {
	serverURI := e.GetServerURI()

	if e.GetTorMode().Enabled() {
		serverURI = e.GetTorHiddenAddress()
	}

	if serverURI == "" {
		err := fmt.Errorf("Cannot find a server URL")
		return nil, err
	}
	url, err := url.Parse(serverURI)
	if err != nil {
		return nil, err
	}

	if url.Scheme == "" {
		return nil, fmt.Errorf("Server URL missing Scheme")
	}

	if url.Host == "" {
		return nil, fmt.Errorf("Server URL missing Host")
	}

	useTLS := (url.Scheme == "https")
	host, port, e2 := SplitHost(url.Host)
	if e2 != nil {
		return nil, e2
	}
	var rootCAs *x509.CertPool
	if rawCA := e.GetBundledCA(host); len(rawCA) > 0 {
		rootCAs, err = ParseCA(rawCA)
		if err != nil {
			err = fmt.Errorf("In parsing CAs for %s: %s", host, err)
			return nil, err
		}
		G.Log.Debug(fmt.Sprintf("Using special root CA for %s: %s",
			host, ShortCA(rawCA)))
	}

	// If we're using proxies, they might have their own CAs.
	if rootCAs, err = GetProxyCAs(rootCAs, e.config); err != nil {
		return nil, err
	}

	ret := &ClientConfig{host, port, useTLS, url, rootCAs, url.Path, true, e.GetAPITimeout()}
	return ret, nil
}

func (e *Env) GenClientConfigForScrapers() (*ClientConfig, error) {
	return &ClientConfig{
		UseCookies: true,
		Timeout:    e.GetScraperTimeout(),
	}, nil
}

func NewClient(e *Env, config *ClientConfig, needCookie bool) *Client {
	var jar *cookiejar.Jar
	if needCookie && (config == nil || config.UseCookies) && e.GetTorMode().UseCookies() {
		jar, _ = cookiejar.New(nil)
	}

	var xprt http.Transport
	var timeout time.Duration

	xprt.Dial = func(network, addr string) (c net.Conn, err error) {
		c, err = net.Dial(network, addr)
		if err != nil {
			return c, err
		}
		if err = rpc.DisableSigPipe(c); err != nil {
			return c, err
		}
		return c, nil
	}

	if (config != nil && config.RootCAs != nil) || e.GetTorMode().Enabled() {
		if config != nil && config.RootCAs != nil {
			xprt.TLSClientConfig = &tls.Config{RootCAs: config.RootCAs}
		}
		if e.GetTorMode().Enabled() {
			dialSocksProxy := socks.DialSocksProxy(socks.SOCKS5, e.GetTorProxy())
			xprt.Dial = dialSocksProxy
		} else {
			xprt.Proxy = http.ProxyFromEnvironment
		}
	}
	if config == nil || config.Timeout == 0 {
		timeout = HTTPDefaultTimeout
	} else {
		timeout = config.Timeout
	}

	ret := &Client{
		cli:    &http.Client{Timeout: timeout},
		config: config,
	}
	if jar != nil {
		ret.cli.Jar = jar
	}

	ret.cli.Transport = &xprt
	return ret
}
<commit_msg>enable proxy for localhost in dev mode<commit_after>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package libkb

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"net"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/keybase/go-framed-msgpack-rpc/rpc"

	"h12.me/socks"
)

type ClientConfig struct {
	Host       string
	Port       int
	UseTLS     bool // XXX unused?
	URL        *url.URL
	RootCAs    *x509.CertPool
	Prefix     string
	UseCookies bool
	Timeout    time.Duration
}

type Client struct {
	cli    *http.Client
	config *ClientConfig
}

var hostRE = regexp.MustCompile("^([^:]+)(:([0-9]+))?$")

func SplitHost(joined string) (host string, port int, err error) {
	match := hostRE.FindStringSubmatch(joined)
	if match == nil {
		err = fmt.Errorf("Invalid host/port found: %s", joined)
	} else {
		host = match[1]
		port = 0
		if len(match[3]) > 0 {
			port, err = strconv.Atoi(match[3])
			if err != nil {
				err = fmt.Errorf("Could not convert port in host %s", joined)
			}
		}
	}
	return
}

func ParseCA(raw string) (*x509.CertPool, error) {
	ret := x509.NewCertPool()
	ok := ret.AppendCertsFromPEM([]byte(raw))
	var err error
	if !ok {
		err = fmt.Errorf("Could not read CA for keybase.io")
		ret = nil
	}
	return ret, err
}

func ShortCA(raw string) string {
	parts := strings.Split(raw, "\n")
	if len(parts) >= 3 {
		parts = parts[0:3]
	}
	return strings.Join(parts, " ") + "..."
}

// GenClientConfigForInternalAPI pulls the information out of the environment configuration,
// and build a Client config that will be used in all API server
// requests
func (e *Env) GenClientConfigForInternalAPI() (*ClientConfig, error) {
	serverURI := e.GetServerURI()

	if e.GetTorMode().Enabled() {
		serverURI = e.GetTorHiddenAddress()
	}

	if serverURI == "" {
		err := fmt.Errorf("Cannot find a server URL")
		return nil, err
	}
	url, err := url.Parse(serverURI)
	if err != nil {
		return nil, err
	}

	if url.Scheme == "" {
		return nil, fmt.Errorf("Server URL missing Scheme")
	}

	if url.Host == "" {
		return nil, fmt.Errorf("Server URL missing Host")
	}

	useTLS := (url.Scheme == "https")
	host, port, e2 := SplitHost(url.Host)
	if e2 != nil {
		return nil, e2
	}
	var rootCAs *x509.CertPool
	if rawCA := e.GetBundledCA(host); len(rawCA) > 0 {
		rootCAs, err = ParseCA(rawCA)
		if err != nil {
			err = fmt.Errorf("In parsing CAs for %s: %s", host, err)
			return nil, err
		}
		G.Log.Debug(fmt.Sprintf("Using special root CA for %s: %s",
			host, ShortCA(rawCA)))
	}

	// If we're using proxies, they might have their own CAs.
	if rootCAs, err = GetProxyCAs(rootCAs, e.config); err != nil {
		return nil, err
	}

	ret := &ClientConfig{host, port, useTLS, url, rootCAs, url.Path, true, e.GetAPITimeout()}
	return ret, nil
}

func (e *Env) GenClientConfigForScrapers() (*ClientConfig, error) {
	return &ClientConfig{
		UseCookies: true,
		Timeout:    e.GetScraperTimeout(),
	}, nil
}

func NewClient(e *Env, config *ClientConfig, needCookie bool) *Client {
	var jar *cookiejar.Jar
	if needCookie && (config == nil || config.UseCookies) && e.GetTorMode().UseCookies() {
		jar, _ = cookiejar.New(nil)
	}

	var xprt http.Transport
	var timeout time.Duration

	xprt.Dial = func(network, addr string) (c net.Conn, err error) {
		c, err = net.Dial(network, addr)
		if err != nil {
			return c, err
		}
		if err = rpc.DisableSigPipe(c); err != nil {
			return c, err
		}
		return c, nil
	}

	if (config != nil && config.RootCAs != nil) || e.GetTorMode().Enabled() {
		if config != nil && config.RootCAs != nil {
			xprt.TLSClientConfig = &tls.Config{RootCAs: config.RootCAs}
		}
		if e.GetTorMode().Enabled() {
			dialSocksProxy := socks.DialSocksProxy(socks.SOCKS5, e.GetTorProxy())
			xprt.Dial = dialSocksProxy
		} else {
			xprt.Proxy = http.ProxyFromEnvironment
		}
	}

	if !e.GetTorMode().Enabled() && e.GetRunMode() == DevelRunMode {
		xprt.Proxy = func(req *http.Request) (*url.URL, error) {
			// Make a fake copy request with the url set to keybase.io
			// Because ProxyFromEnvironment refuses to proxy for localhost.
			// This makes localhost requests get proxied.
			// The Host can be anything and is only used to != "localhost".
			url2 := *req.URL
			url2.Host = "keybase.io"
			req2 := req
			req2.URL = &url2
			u, err := http.ProxyFromEnvironment(req2)
			return u, err
		}
	}

	if config == nil || config.Timeout == 0 {
		timeout = HTTPDefaultTimeout
	} else {
		timeout = config.Timeout
	}

	ret := &Client{
		cli:    &http.Client{Timeout: timeout},
		config: config,
	}
	if jar != nil {
		ret.cli.Jar = jar
	}

	ret.cli.Transport = &xprt
	return ret
}
<|endoftext|>


<commit_before>package ethwire

import (
	"bytes"
	"errors"
	"fmt"
	"github.com/ethereum/eth-go/ethutil"
	"net"
	"time"
)

// Message:
// [4 bytes token] RLP([TYPE, DATA])
// Refer to http://wiki.ethereum.org/index.php/Wire_Protocol

// The magic token which should be the first 4 bytes of every message.
var MagicToken = []byte{34, 64, 8, 145}

type MsgType byte

const (
	// Values are given explicitly instead of by iota because these values are
	// defined by the wire protocol spec; it is easier for humans to ensure
	// correctness when values are explicit.
	MsgHandshakeTy  = 0x00
	MsgDiscTy       = 0x01
	MsgPingTy       = 0x02
	MsgPongTy       = 0x03
	MsgGetPeersTy   = 0x10
	MsgPeersTy      = 0x11
	MsgTxTy         = 0x12
	MsgBlockTy      = 0x13
	MsgGetChainTy   = 0x14
	MsgNotInChainTy = 0x15
	MsgGetTxsTy     = 0x16

	MsgTalkTy = 0xff
)

var msgTypeToString = map[MsgType]string{
	MsgHandshakeTy:  "Handshake",
	MsgDiscTy:       "Disconnect",
	MsgPingTy:       "Ping",
	MsgPongTy:       "Pong",
	MsgGetPeersTy:   "Get peers",
	MsgPeersTy:      "Peers",
	MsgTxTy:         "Transactions",
	MsgBlockTy:      "Blocks",
	MsgGetChainTy:   "Get chain",
	MsgGetTxsTy:     "Get Txs",
	MsgNotInChainTy: "Not in chain",
}

func (mt MsgType) String() string {
	return msgTypeToString[mt]
}

type Msg struct {
	Type MsgType // Specifies how the encoded data should be interpreted
	//Data []byte
	Data *ethutil.Value
}

func NewMessage(msgType MsgType, data interface{}) *Msg {
	return &Msg{
		Type: msgType,
		Data: ethutil.NewValue(data),
	}
}

func ReadMessage(data []byte) (msg *Msg, remaining []byte, done bool, err error) {
	if len(data) == 0 {
		return nil, nil, true, nil
	}

	if len(data) <= 8 {
		return nil, remaining, false, errors.New("Invalid message")
	}

	// Check if the received 4 first bytes are the magic token
	if bytes.Compare(MagicToken, data[:4]) != 0 {
		return nil, nil, false, fmt.Errorf("MagicToken mismatch. Received %v", data[:4])
	}

	messageLength := ethutil.BytesToNumber(data[4:8])
	remaining = data[8+messageLength:]
	if int(messageLength) > len(data[8:]) {
		return nil, nil, false, fmt.Errorf("message length %d, expected %d", len(data[8:]), messageLength)
	}

	message := data[8 : 8+messageLength]
	decoder := ethutil.NewValueFromBytes(message)
	// Type of message
	t := decoder.Get(0).Uint()
	// Actual data
	d := decoder.SliceFrom(1)

	msg = &Msg{
		Type: MsgType(t),
		Data: d,
	}

	return
}

func bufferedRead(conn net.Conn) ([]byte, error) {
	return nil, nil
}

// The basic message reader waits for data on the given connection, decoding
// and doing a few sanity checks such as if there's a data type and
// unmarhals the given data
func ReadMessages(conn net.Conn) (msgs []*Msg, err error) {
	// The recovering function in case anything goes horribly wrong
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("ethwire.ReadMessage error: %v", r)
		}
	}()

	// Buff for writing network message to
	//buff := make([]byte, 1440)
	var buff []byte
	var totalBytes int
	for {
		// Give buffering some time
		conn.SetReadDeadline(time.Now().Add(20 * time.Millisecond))
		// Create a new temporarily buffer
		b := make([]byte, 1440)
		// Wait for a message from this peer
		n, _ := conn.Read(b)
		if err != nil && n == 0 {
			if err.Error() != "EOF" {
				fmt.Println("err now", err)
				return nil, err
			} else {
				fmt.Println("IOF NOW")
				break
			}

			// Messages can't be empty
		} else if n == 0 {
			break
		}

		buff = append(buff, b[:n]...)
		totalBytes += n
	}

	// Reslice buffer
	buff = buff[:totalBytes]
	msg, remaining, done, err := ReadMessage(buff)
	for ; done != true; msg, remaining, done, err = ReadMessage(remaining) {
		//log.Println("rx", msg)

		if msg != nil {
			msgs = append(msgs, msg)
		}
	}

	return
}

// The basic message writer takes care of writing data over the given
// connection and does some basic error checking
func WriteMessage(conn net.Conn, msg *Msg) error {
	var pack []byte

	// Encode the type and the (RLP encoded) data for sending over the wire
	encoded := ethutil.NewValue(append([]interface{}{byte(msg.Type)}, msg.Data.Slice()...)).Encode()
	payloadLength := ethutil.NumberToBytes(uint32(len(encoded)), 32)

	// Write magic token and payload length (first 8 bytes)
	pack = append(MagicToken, payloadLength...)
	pack = append(pack, encoded...)
	//fmt.Printf("payload %v (%v) %q\n", msg.Type, conn.RemoteAddr(), encoded)

	// Write to the connection
	_, err := conn.Write(pack)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Increased deadline<commit_after>package ethwire

import (
	"bytes"
	"errors"
	"fmt"
	"github.com/ethereum/eth-go/ethutil"
	"net"
	"time"
)

// Message:
// [4 bytes token] RLP([TYPE, DATA])
// Refer to http://wiki.ethereum.org/index.php/Wire_Protocol

// The magic token which should be the first 4 bytes of every message.
var MagicToken = []byte{34, 64, 8, 145}

type MsgType byte

const (
	// Values are given explicitly instead of by iota because these values are
	// defined by the wire protocol spec; it is easier for humans to ensure
	// correctness when values are explicit.
	MsgHandshakeTy  = 0x00
	MsgDiscTy       = 0x01
	MsgPingTy       = 0x02
	MsgPongTy       = 0x03
	MsgGetPeersTy   = 0x10
	MsgPeersTy      = 0x11
	MsgTxTy         = 0x12
	MsgBlockTy      = 0x13
	MsgGetChainTy   = 0x14
	MsgNotInChainTy = 0x15
	MsgGetTxsTy     = 0x16

	MsgTalkTy = 0xff
)

var msgTypeToString = map[MsgType]string{
	MsgHandshakeTy:  "Handshake",
	MsgDiscTy:       "Disconnect",
	MsgPingTy:       "Ping",
	MsgPongTy:       "Pong",
	MsgGetPeersTy:   "Get peers",
	MsgPeersTy:      "Peers",
	MsgTxTy:         "Transactions",
	MsgBlockTy:      "Blocks",
	MsgGetChainTy:   "Get chain",
	MsgGetTxsTy:     "Get Txs",
	MsgNotInChainTy: "Not in chain",
}

func (mt MsgType) String() string {
	return msgTypeToString[mt]
}

type Msg struct {
	Type MsgType // Specifies how the encoded data should be interpreted
	//Data []byte
	Data *ethutil.Value
}

func NewMessage(msgType MsgType, data interface{}) *Msg {
	return &Msg{
		Type: msgType,
		Data: ethutil.NewValue(data),
	}
}

func ReadMessage(data []byte) (msg *Msg, remaining []byte, done bool, err error) {
	defer func() {
		if r := recover(); r != nil {
			panic(fmt.Sprintf("message error %d %v", len(data), data))
		}
	}()

	if len(data) == 0 {
		return nil, nil, true, nil
	}

	if len(data) <= 8 {
		return nil, remaining, false, errors.New("Invalid message")
	}

	// Check if the received 4 first bytes are the magic token
	if bytes.Compare(MagicToken, data[:4]) != 0 {
		return nil, nil, false, fmt.Errorf("MagicToken mismatch. Received %v", data[:4])
	}

	messageLength := ethutil.BytesToNumber(data[4:8])
	remaining = data[8+messageLength:]
	if int(messageLength) > len(data[8:]) {
		return nil, nil, false, fmt.Errorf("message length %d, expected %d", len(data[8:]), messageLength)
	}

	message := data[8 : 8+messageLength]
	decoder := ethutil.NewValueFromBytes(message)
	// Type of message
	t := decoder.Get(0).Uint()
	// Actual data
	d := decoder.SliceFrom(1)

	msg = &Msg{
		Type: MsgType(t),
		Data: d,
	}

	return
}

func bufferedRead(conn net.Conn) ([]byte, error) {
	return nil, nil
}

// The basic message reader waits for data on the given connection, decoding
// and doing a few sanity checks such as if there's a data type and
// unmarhals the given data
func ReadMessages(conn net.Conn) (msgs []*Msg, err error) {
	// The recovering function in case anything goes horribly wrong
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("ethwire.ReadMessage error: %v", r)
		}
	}()

	// Buff for writing network message to
	//buff := make([]byte, 1440)
	var buff []byte
	var totalBytes int
	for {
		// Give buffering some time
		conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
		// Create a new temporarily buffer
		b := make([]byte, 1440)
		// Wait for a message from this peer
		n, _ := conn.Read(b)
		if err != nil && n == 0 {
			if err.Error() != "EOF" {
				fmt.Println("err now", err)
				return nil, err
			} else {
				break
			}

			// Messages can't be empty
		} else if n == 0 {
			break
		}

		buff = append(buff, b[:n]...)
		totalBytes += n
	}

	// Reslice buffer
	buff = buff[:totalBytes]
	msg, remaining, done, err := ReadMessage(buff)
	for ; done != true; msg, remaining, done, err = ReadMessage(remaining) {
		//log.Println("rx", msg)

		if msg != nil {
			msgs = append(msgs, msg)
		}
	}

	return
}

// The basic message writer takes care of writing data over the given
// connection and does some basic error checking
func WriteMessage(conn net.Conn, msg *Msg) error {
	var pack []byte

	// Encode the type and the (RLP encoded) data for sending over the wire
	encoded := ethutil.NewValue(append([]interface{}{byte(msg.Type)}, msg.Data.Slice()...)).Encode()
	payloadLength := ethutil.NumberToBytes(uint32(len(encoded)), 32)

	// Write magic token and payload length (first 8 bytes)
	pack = append(MagicToken, payloadLength...)
	pack = append(pack, encoded...)
	//fmt.Printf("payload %v (%v) %q\n", msg.Type, conn.RemoteAddr(), encoded)

	// Write to the connection
	_, err := conn.Write(pack)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/md5"
	"crypto/tls"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/corpix/uarand"
	"golang.org/x/net/http2"
)

var (
	TargetURL    string
	Method       string
	TargetsParam string
	TargetPid    int
	TargetAid    int
	Targets      []string
	Pumps        int
	Chance       int
	MinInterval  int
	MaxInterval  int
)

func init() {
	flag.StringVar(&TargetURL, "url", "", "Target url")
	flag.StringVar(&Method, "m", "", "Pump method")
	flag.StringVar(&TargetsParam, "t", "", "Targets")
	flag.IntVar(&TargetPid, "pid", 0, "Target pid")
	flag.IntVar(&TargetAid, "aid", 0, "Target aid")
	flag.IntVar(&Pumps, "a", 10, "How many pumps?")
	flag.IntVar(&Chance, "c", 75, "Chance")
	flag.IntVar(&MinInterval, "min", 3, "min sec")
	flag.IntVar(&MaxInterval, "max", 10, "max sec")
}

func getClient() (client *http.Client, err error) {
	tlsConfig := &tls.Config{}
	client = &http.Client{Timeout: 20 * time.Second}
	client.Transport = &http2.Transport{TLSClientConfig: tlsConfig}

	return client, nil
}

func main() {
	fmt.Println("Esketit!!!")
	flag.Parse()

	if len(TargetURL) <= 0 {
		flag.PrintDefaults()
		log.Fatalln("No target url specified.")
	}
	if len(Method) <= 0 {
		flag.PrintDefaults()
		log.Fatalln("No method specified.")
	}

	rand.Seed(time.Now().UnixNano())

	parts := strings.Split(TargetsParam, ",")
	ids := make([]int, len(parts))
	for i, p := range parts {
		id, _ := strconv.Atoi(p)
		ids[i] = id
	}

	client, _ := getClient()
	sem := make(chan byte, 4)
	var wg sync.WaitGroup

	for idx := 0; idx < Pumps; idx++ {
		switch Method {
		case "pump1":
			if len(TargetsParam) <= 0 {
				log.Fatalln("No targets specified.")
			}
			for _, id := range ids {
				sem <- 1
				wg.Add(1)
				go func(cid int) {
					v := false
					ch := rand.Intn(100)
					if ch <= Chance {
						v = true
					}
					fmt.Printf("%s ID=%d  ch=%d  v=%t\n", Method, cid, ch, v)
					pump1(client, cid, v)
					time.Sleep(time.Duration(rand.Intn(MaxInterval)+MinInterval) * time.Second)
					<-sem
					wg.Done()
				}(id)
			}
		case "pump2":
			if TargetPid <= 0 || TargetAid <= 0 {
				log.Fatalln("No targets specified.")
			}
			sem <- 1
			wg.Add(1)
			go func() {
				fmt.Printf("%s %d=%d \n", Method, TargetPid, TargetAid)
				pump2(client, TargetPid, TargetAid)
				time.Sleep(time.Duration(rand.Intn(MaxInterval-MinInterval)+MinInterval) * time.Second)
				<-sem
				wg.Done()
			}()
		default:
			log.Fatalf("Wrong pump: %s\n", Method)
		}
	}
	wg.Wait()
	close(sem)

	fmt.Printf("Done. Pumps=%d\n", Pumps)
}

func pump1(client *http.Client, cid int, yes bool) {
	data := url.Values{}
	data.Set("comment"+"_id", strconv.Itoa(cid))
	if yes {
		data.Set("mark", "plus")
	} else {
		data.Set("mark", "minus")
	}
	data.Set("MIME Type", "application/x-www-form-urlencoded")

	req, _ := http.NewRequest(http.MethodPost, TargetURL, strings.NewReader(data.Encode()))
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
	req.Header.Add("User-Agent", uarand.GetRandom())
	req.Header.Add("X-Requested-With", "XMLHttpRequest")

	tok := make([]byte, 64)
	rand.Read(tok)
	hash := fmt.Sprintf("%x", md5.Sum(tok))
	req.Header.Add("Cookie", fmt.Sprintf("ruid=_%s", hash))

	// reqOut, err := httputil.DumpRequest(req, true)
	// fmt.Println(string(reqOut))

	resp, err := client.Do(req)
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	defer resp.Body.Close()

	// rout, _ := httputil.DumpResponse(resp, true)
	// fmt.Println(string(rout))
}

func pump2(client *http.Client, pid int, aid int) {
	data := url.Values{}
	data.Set("poll"+"_id", strconv.Itoa(pid))
	data.Set("poll"+"_answer", strconv.Itoa(aid))
	data.Set("MIME Type", "application/x-www-form-urlencoded")

	req, _ := http.NewRequest(http.MethodPost, TargetURL, strings.NewReader(data.Encode()))
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
	req.Header.Add("User-Agent", uarand.GetRandom())
	req.Header.Add("X-Requested-With", "XMLHttpRequest")

	tok := make([]byte, 64)
	rand.Read(tok)
	hash := fmt.Sprintf("%x", md5.Sum(tok))
	req.Header.Add("Cookie", fmt.Sprintf("ruid=_%s", hash))

	// reqOut, err := httputil.DumpRequest(req, true)
	// fmt.Println(string(reqOut))

	resp, err := client.Do(req)
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	defer resp.Body.Close()

	//rout, _ := httputil.DumpResponse(resp, true)
	//fmt.Println(string(rout))
}
<commit_msg>Print idx<commit_after>package main

import (
	"crypto/md5"
	"crypto/tls"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/corpix/uarand"
	"golang.org/x/net/http2"
)

var (
	TargetURL    string
	Method       string
	TargetsParam string
	TargetPid    int
	TargetAid    int
	Targets      []string
	Pumps        int
	Chance       int
	MinInterval  int
	MaxInterval  int
)

func init() {
	flag.StringVar(&TargetURL, "url", "", "Target url")
	flag.StringVar(&Method, "m", "", "Pump method")
	flag.StringVar(&TargetsParam, "t", "", "Targets")
	flag.IntVar(&TargetPid, "pid", 0, "Target pid")
	flag.IntVar(&TargetAid, "aid", 0, "Target aid")
	flag.IntVar(&Pumps, "a", 10, "How many pumps?")
	flag.IntVar(&Chance, "c", 75, "Chance")
	flag.IntVar(&MinInterval, "min", 3, "min sec")
	flag.IntVar(&MaxInterval, "max", 10, "max sec")
}

func getClient() (client *http.Client, err error) {
	tlsConfig := &tls.Config{}
	client = &http.Client{Timeout: 20 * time.Second}
	client.Transport = &http2.Transport{TLSClientConfig: tlsConfig}

	return client, nil
}

func main() {
	fmt.Println("Esketit!!!")
	flag.Parse()

	if len(TargetURL) <= 0 {
		flag.PrintDefaults()
		log.Fatalln("No target url specified.")
	}
	if len(Method) <= 0 {
		flag.PrintDefaults()
		log.Fatalln("No method specified.")
	}

	rand.Seed(time.Now().UnixNano())

	parts := strings.Split(TargetsParam, ",")
	ids := make([]int, len(parts))
	for i, p := range parts {
		id, _ := strconv.Atoi(p)
		ids[i] = id
	}

	client, _ := getClient()
	sem := make(chan byte, 4)
	var wg sync.WaitGroup

	for idx := 0; idx < Pumps; idx++ {
		switch Method {
		case "pump1":
			if len(TargetsParam) <= 0 {
				log.Fatalln("No targets specified.")
			}
			for _, id := range ids {
				sem <- 1
				wg.Add(1)
				go func(cid int) {
					v := false
					ch := rand.Intn(100)
					if ch <= Chance {
						v = true
					}
					fmt.Printf("%s ID=%d  ch=%d  v=%t\n", Method, cid, ch, v)
					pump1(client, cid, v)
					time.Sleep(time.Duration(rand.Intn(MaxInterval)+MinInterval) * time.Second)
					<-sem
					wg.Done()
				}(id)
			}
		case "pump2":
			if TargetPid <= 0 || TargetAid <= 0 {
				log.Fatalln("No targets specified.")
			}
			sem <- 1
			wg.Add(1)
			go func(i int) {
				fmt.Printf("%s I=%d %d=%d \n", Method, i, TargetPid, TargetAid)
				pump2(client, TargetPid, TargetAid)
				time.Sleep(time.Duration(rand.Intn(MaxInterval-MinInterval)+MinInterval) * time.Second)
				<-sem
				wg.Done()
			}(idx)
		default:
			log.Fatalf("Wrong pump: %s\n", Method)
		}
	}
	wg.Wait()
	close(sem)

	fmt.Printf("Done. Pumps=%d\n", Pumps)
}

func pump1(client *http.Client, cid int, yes bool) {
	data := url.Values{}
	data.Set("comment"+"_id", strconv.Itoa(cid))
	if yes {
		data.Set("mark", "plus")
	} else {
		data.Set("mark", "minus")
	}
	data.Set("MIME Type", "application/x-www-form-urlencoded")

	req, _ := http.NewRequest(http.MethodPost, TargetURL, strings.NewReader(data.Encode()))
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
	req.Header.Add("User-Agent", uarand.GetRandom())
	req.Header.Add("X-Requested-With", "XMLHttpRequest")

	tok := make([]byte, 64)
	rand.Read(tok)
	hash := fmt.Sprintf("%x", md5.Sum(tok))
	req.Header.Add("Cookie", fmt.Sprintf("ruid=_%s", hash))

	// reqOut, err := httputil.DumpRequest(req, true)
	// fmt.Println(string(reqOut))

	resp, err := client.Do(req)
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	defer resp.Body.Close()

	// rout, _ := httputil.DumpResponse(resp, true)
	// fmt.Println(string(rout))
}

func pump2(client *http.Client, pid int, aid int) {
	data := url.Values{}
	data.Set("poll"+"_id", strconv.Itoa(pid))
	data.Set("poll"+"_answer", strconv.Itoa(aid))
	data.Set("MIME Type", "application/x-www-form-urlencoded")

	req, _ := http.NewRequest(http.MethodPost, TargetURL, strings.NewReader(data.Encode()))
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
	req.Header.Add("User-Agent", uarand.GetRandom())
	req.Header.Add("X-Requested-With", "XMLHttpRequest")

	tok := make([]byte, 64)
	rand.Read(tok)
	hash := fmt.Sprintf("%x", md5.Sum(tok))
	req.Header.Add("Cookie", fmt.Sprintf("ruid=_%s", hash))

	// reqOut, err := httputil.DumpRequest(req, true)
	// fmt.Println(string(reqOut))

	resp, err := client.Do(req)
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	defer resp.Body.Close()

	//rout, _ := httputil.DumpResponse(resp, true)
	//fmt.Println(string(rout))
}
<|endoftext|>


<commit_before>// Copyright 2020 The LUCI 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 sink

import (
	"context"
	"encoding/hex"
	"fmt"
	"sync/atomic"

	"github.com/golang/protobuf/proto"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"

	"go.chromium.org/luci/common/clock"
	"go.chromium.org/luci/common/data/rand/mathrand"
	"go.chromium.org/luci/common/logging"

	"go.chromium.org/luci/resultdb/internal/services/recorder"
	sinkpb "go.chromium.org/luci/resultdb/sink/proto/v1"
)

// sinkServer implements sinkpb.SinkServer.
type sinkServer struct {
	cfg           ServerConfig
	ac            *artifactChannel
	tc            *testResultChannel
	resultIDBase  string
	resultCounter uint32
}

func newSinkServer(ctx context.Context, cfg ServerConfig) (sinkpb.SinkServer, error) {
	// random bytes to generate a ResultID when ResultID unspecified in
	// a TestResult.
	bytes := make([]byte, 4)
	if _, err := mathrand.Read(ctx, bytes); err != nil {
		return nil, err
	}

	ctx = metadata.AppendToOutgoingContext(
		ctx, recorder.UpdateTokenMetadataKey, cfg.UpdateToken)
	ss := &sinkServer{
		cfg:          cfg,
		ac:           newArtifactChannel(ctx, &cfg),
		tc:           newTestResultChannel(ctx, &cfg),
		resultIDBase: hex.EncodeToString(bytes),
	}

	return &sinkpb.DecoratedSink{
		Service: ss,
		Prelude: authTokenPrelude(cfg.AuthToken),
	}, nil
}

// closeSinkServer closes the dispatcher channels and blocks until they are fully drained,
// or the context is cancelled.
func closeSinkServer(ctx context.Context, s sinkpb.SinkServer) {
	ss := s.(*sinkpb.DecoratedSink).Service.(*sinkServer)

	logging.Infof(ctx, "SinkServer: draining TestResult channel started")
	ss.tc.closeAndDrain(ctx)
	logging.Infof(ctx, "SinkServer: draining TestResult channel ended")

	logging.Infof(ctx, "SinkServer: draining Artifact channel started")
	ss.ac.closeAndDrain(ctx)
	logging.Infof(ctx, "SinkServer: draining Artifact channel ended")
}

// authTokenValue returns the value of the Authorization HTTP header that all requests must
// have.
func authTokenValue(authToken string) string {
	return fmt.Sprintf("%s %s", AuthTokenPrefix, authToken)
}

// authTokenValidator is a factory function generating a pRPC prelude that validates
// a given HTTP request with the auth key.
func authTokenPrelude(authToken string) func(context.Context, string, proto.Message) (context.Context, error) {
	expected := authTokenValue(authToken)
	missingKeyErr := status.Errorf(codes.Unauthenticated, "Authorization header is missing")

	return func(ctx context.Context, _ string, _ proto.Message) (context.Context, error) {
		md, ok := metadata.FromIncomingContext(ctx)
		if !ok {
			return nil, missingKeyErr
		}
		tks := md.Get(AuthTokenKey)
		if len(tks) == 0 {
			return nil, missingKeyErr
		}
		for _, tk := range tks {
			if tk == expected {
				return ctx, nil
			}
		}
		return nil, status.Errorf(codes.PermissionDenied, "no valid auth_token found")
	}
}

// ReportTestResults implement sinkpb.SinkServer.
func (s *sinkServer) ReportTestResults(ctx context.Context, in *sinkpb.ReportTestResultsRequest) (*sinkpb.ReportTestResultsResponse, error) {
	now := clock.Now(ctx).UTC()

	for _, tr := range in.TestResults {
		tr.TestId = s.cfg.TestIDPrefix + tr.GetTestId()

		// assign a random, unique ID if resultID omitted.
		if tr.ResultId == "" {
			tr.ResultId = fmt.Sprintf("%s-%.5d", s.resultIDBase, atomic.AddUint32(&s.resultCounter, 1))
		}
		if err := validateTestResult(now, tr); err != nil {
			return nil, status.Errorf(codes.InvalidArgument, "bad request: %s", err)
		}
	}
	s.ac.schedule(in.TestResults...)
	s.tc.schedule(in.TestResults...)

	// TODO(1017288) - set `TestResultNames` in the response
	return &sinkpb.ReportTestResultsResponse{}, nil
}
<commit_msg>[ResultSink] Update file artifact's content type if omitted<commit_after>// Copyright 2020 The LUCI 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 sink

import (
	"context"
	"encoding/hex"
	"fmt"
	"path"
	"sync/atomic"

	"github.com/golang/protobuf/proto"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"

	"go.chromium.org/luci/common/clock"
	"go.chromium.org/luci/common/data/rand/mathrand"
	"go.chromium.org/luci/common/logging"

	"go.chromium.org/luci/resultdb/internal/services/recorder"
	sinkpb "go.chromium.org/luci/resultdb/sink/proto/v1"
)

// sinkServer implements sinkpb.SinkServer.
type sinkServer struct {
	cfg           ServerConfig
	ac            *artifactChannel
	tc            *testResultChannel
	resultIDBase  string
	resultCounter uint32
}

func newSinkServer(ctx context.Context, cfg ServerConfig) (sinkpb.SinkServer, error) {
	// random bytes to generate a ResultID when ResultID unspecified in
	// a TestResult.
	bytes := make([]byte, 4)
	if _, err := mathrand.Read(ctx, bytes); err != nil {
		return nil, err
	}

	ctx = metadata.AppendToOutgoingContext(
		ctx, recorder.UpdateTokenMetadataKey, cfg.UpdateToken)
	ss := &sinkServer{
		cfg:          cfg,
		ac:           newArtifactChannel(ctx, &cfg),
		tc:           newTestResultChannel(ctx, &cfg),
		resultIDBase: hex.EncodeToString(bytes),
	}

	return &sinkpb.DecoratedSink{
		Service: ss,
		Prelude: authTokenPrelude(cfg.AuthToken),
	}, nil
}

// closeSinkServer closes the dispatcher channels and blocks until they are fully drained,
// or the context is cancelled.
func closeSinkServer(ctx context.Context, s sinkpb.SinkServer) {
	ss := s.(*sinkpb.DecoratedSink).Service.(*sinkServer)

	logging.Infof(ctx, "SinkServer: draining TestResult channel started")
	ss.tc.closeAndDrain(ctx)
	logging.Infof(ctx, "SinkServer: draining TestResult channel ended")

	logging.Infof(ctx, "SinkServer: draining Artifact channel started")
	ss.ac.closeAndDrain(ctx)
	logging.Infof(ctx, "SinkServer: draining Artifact channel ended")
}

// authTokenValue returns the value of the Authorization HTTP header that all requests must
// have.
func authTokenValue(authToken string) string {
	return fmt.Sprintf("%s %s", AuthTokenPrefix, authToken)
}

// authTokenValidator is a factory function generating a pRPC prelude that validates
// a given HTTP request with the auth key.
func authTokenPrelude(authToken string) func(context.Context, string, proto.Message) (context.Context, error) {
	expected := authTokenValue(authToken)
	missingKeyErr := status.Errorf(codes.Unauthenticated, "Authorization header is missing")

	return func(ctx context.Context, _ string, _ proto.Message) (context.Context, error) {
		md, ok := metadata.FromIncomingContext(ctx)
		if !ok {
			return nil, missingKeyErr
		}
		tks := md.Get(AuthTokenKey)
		if len(tks) == 0 {
			return nil, missingKeyErr
		}
		for _, tk := range tks {
			if tk == expected {
				return ctx, nil
			}
		}
		return nil, status.Errorf(codes.PermissionDenied, "no valid auth_token found")
	}
}

// ReportTestResults implement sinkpb.SinkServer.
func (s *sinkServer) ReportTestResults(ctx context.Context, in *sinkpb.ReportTestResultsRequest) (*sinkpb.ReportTestResultsResponse, error) {
	now := clock.Now(ctx).UTC()

	for _, tr := range in.TestResults {
		tr.TestId = s.cfg.TestIDPrefix + tr.GetTestId()

		// assign a random, unique ID if resultID omitted.
		if tr.ResultId == "" {
			tr.ResultId = fmt.Sprintf("%s-%.5d", s.resultIDBase, atomic.AddUint32(&s.resultCounter, 1))
		}

		for _, a := range tr.GetArtifacts() {
			updateArtifactContentType(a)
		}

		if err := validateTestResult(now, tr); err != nil {
			return nil, status.Errorf(codes.InvalidArgument, "bad request: %s", err)
		}
	}
	s.ac.schedule(in.TestResults...)
	s.tc.schedule(in.TestResults...)

	// TODO(1017288) - set `TestResultNames` in the response
	return &sinkpb.ReportTestResultsResponse{}, nil
}

func updateArtifactContentType(a *sinkpb.Artifact) {
	if a.GetFilePath() == "" || a.GetContentType() != "" {
		return
	}

	switch path.Ext(a.GetFilePath()) {
	case ".txt":
		a.ContentType = "text/plain"
	case ".html":
		a.ContentType = "text/html"
	case ".png":
		a.ContentType = "image/png"
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"
	"os/exec"
	"regexp"
	"strings"
	"time"

	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	pb "github.com/brotherlogic/gobuildslave/proto"
)

// RunJob - runs the job
func (s *Server) RunJob(ctx context.Context, req *pb.RunRequest) (*pb.RunResponse, error) {
	if !req.GetJob().GetBreakout() &&
		(s.Registry.Identifier == "clust6" ||
			s.Registry.Identifier == "clust3" ||
			s.Registry.Identifier == "clust7" ||
			s.Registry.Identifier == "clust8" ||
			s.Registry.Identifier == "clust4") {
		return &pb.RunResponse{}, fmt.Errorf("we only run the basic set of jobs")
	}

	if req.GetBits() > 0 && s.Bits != int(req.GetBits()) {
		return &pb.RunResponse{}, status.Errorf(codes.FailedPrecondition, "Cannot run %v bits on this server", req.GetBits())
	}

	if !s.doesBuild && !req.Job.Breakout {
		return &pb.RunResponse{}, status.Errorf(codes.FailedPrecondition, "Refusing to build")
	}
	s.nMut.Lock()
	defer s.nMut.Unlock()
	if _, ok := s.njobs[req.GetJob().GetName()]; ok {
		return &pb.RunResponse{}, fmt.Errorf("Already running this job!")
	}

	if len(s.njobs) > s.maxJobs && !req.GetJob().GetBreakout() {
		return nil, status.Errorf(codes.FailedPrecondition, "We're running %v jobs, can't run no more", len(s.njobs))
	}

	s.CtxLog(ctx, "Running %v")

	s.njobs[req.GetJob().GetName()] = &pb.JobAssignment{Job: req.GetJob(), LastTransitionTime: time.Now().Unix(), Bits: int32(s.Bits)}
	go s.nmonitor(s.njobs[req.GetJob().GetName()])

	return &pb.RunResponse{}, nil
}

// KillJob - kills the job
func (s *Server) KillJob(ctx context.Context, req *pb.KillRequest) (*pb.KillResponse, error) {
	s.nMut.Lock()
	defer s.nMut.Unlock()

	if _, ok := s.njobs[req.GetJob().GetName()]; !ok {
		return nil, fmt.Errorf("Job was not running")
	}

	s.njobs[req.GetJob().GetName()].State = pb.State_KILLING
	return &pb.KillResponse{}, nil
}

//UpdateJob - updates the job
func (s *Server) UpdateJob(ctx context.Context, req *pb.UpdateRequest) (*pb.UpdateResponse, error) {
	s.nMut.Lock()
	defer s.nMut.Unlock()
	if _, ok := s.njobs[req.GetJob().GetName()]; !ok {
		return nil, fmt.Errorf("Job was not running")
	}

	s.njobs[req.GetJob().GetName()].State = pb.State_UPDATE_STARTING
	return &pb.UpdateResponse{}, nil
}

// ListJobs - lists the jobs
func (s *Server) ListJobs(ctx context.Context, req *pb.ListRequest) (*pb.ListResponse, error) {
	s.nMut.Lock()
	defer s.nMut.Unlock()
	resp := &pb.ListResponse{}
	for _, job := range s.njobs {
		resp.Jobs = append(resp.Jobs, job)
	}
	return resp, nil
}

func extractBitRate(output string) (string, string) {
	matcher := regexp.MustCompile("Rate=(.*?) ")
	matches := matcher.FindStringSubmatch(output)

	matcher2 := regexp.MustCompile("Access Point. ([A-F0-9:]*)")
	matches2 := matcher2.FindStringSubmatch(output)
	if len(matches) > 0 && len(matches2) > 0 {
		return strings.TrimRight(matches[1], " "), strings.TrimRight(matches2[1], " ")
	}
	return "", ""
}

// SlaveConfig gets the config for this slave
func (s *Server) SlaveConfig(ctx context.Context, req *pb.ConfigRequest) (*pb.ConfigResponse, error) {
	disks := s.disker.getDisks()
	requirements := make([]*pb.Requirement, 0)
	for _, disk := range disks {
		requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_DISK, Properties: disk})
	}
	requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_SERVER, Properties: s.Registry.Identifier})
	if s.Registry.Identifier == "monitoring" {
		requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_EXTERNAL, Properties: "external_ready"})
	}

	data, err := exec.Command("/usr/bin/lsusb").Output()
	if err != nil {
		return nil, fmt.Errorf("error listing usb components: %v", err)
	}
	s.Log(fmt.Sprintf("USBRES: %v", string(data)))
	if strings.Contains(string(data), "TSP100II") {
		requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_RECEIPT_PRINTER})
	}

	out, _ := exec.Command("/sbin/iwconfig").Output()
	br, ap := extractBitRate(string(out))
	s.accessPoint = ap
	requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_NETWORK, Properties: br})
	requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_ACCESS_POINT, Properties: ap})

	requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_BITS, Properties: fmt.Sprintf("%v", s.Bits)})

	out, _ = exec.Command("cat", "/sys/firmware/devicetree/base/model").Output()
	requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_HOST_TYPE, Properties: string(out)})

	// Add in the printer

	return &pb.ConfigResponse{Config: &pb.SlaveConfig{Requirements: requirements}}, nil
}
<commit_msg>Convert to FP<commit_after>package main

import (
	"context"
	"fmt"
	"os/exec"
	"regexp"
	"strings"
	"time"

	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	pb "github.com/brotherlogic/gobuildslave/proto"
)

// RunJob - runs the job
func (s *Server) RunJob(ctx context.Context, req *pb.RunRequest) (*pb.RunResponse, error) {
	if !req.GetJob().GetBreakout() &&
		(s.Registry.Identifier == "clust6" ||
			s.Registry.Identifier == "clust3" ||
			s.Registry.Identifier == "clust7" ||
			s.Registry.Identifier == "clust8" ||
			s.Registry.Identifier == "clust4") {
		return &pb.RunResponse{}, status.Errorf(codes.FailedPrecondition, "we only run the basic set of jobs")
	}

	if req.GetBits() > 0 && s.Bits != int(req.GetBits()) {
		return &pb.RunResponse{}, status.Errorf(codes.FailedPrecondition, "Cannot run %v bits on this server", req.GetBits())
	}

	if !s.doesBuild && !req.Job.Breakout {
		return &pb.RunResponse{}, status.Errorf(codes.FailedPrecondition, "Refusing to build")
	}
	s.nMut.Lock()
	defer s.nMut.Unlock()
	if _, ok := s.njobs[req.GetJob().GetName()]; ok {
		return &pb.RunResponse{}, fmt.Errorf("Already running this job!")
	}

	if len(s.njobs) > s.maxJobs && !req.GetJob().GetBreakout() {
		return nil, status.Errorf(codes.FailedPrecondition, "We're running %v jobs, can't run no more", len(s.njobs))
	}

	s.CtxLog(ctx, "Running %v")

	s.njobs[req.GetJob().GetName()] = &pb.JobAssignment{Job: req.GetJob(), LastTransitionTime: time.Now().Unix(), Bits: int32(s.Bits)}
	go s.nmonitor(s.njobs[req.GetJob().GetName()])

	return &pb.RunResponse{}, nil
}

// KillJob - kills the job
func (s *Server) KillJob(ctx context.Context, req *pb.KillRequest) (*pb.KillResponse, error) {
	s.nMut.Lock()
	defer s.nMut.Unlock()

	if _, ok := s.njobs[req.GetJob().GetName()]; !ok {
		return nil, fmt.Errorf("Job was not running")
	}

	s.njobs[req.GetJob().GetName()].State = pb.State_KILLING
	return &pb.KillResponse{}, nil
}

//UpdateJob - updates the job
func (s *Server) UpdateJob(ctx context.Context, req *pb.UpdateRequest) (*pb.UpdateResponse, error) {
	s.nMut.Lock()
	defer s.nMut.Unlock()
	if _, ok := s.njobs[req.GetJob().GetName()]; !ok {
		return nil, fmt.Errorf("Job was not running")
	}

	s.njobs[req.GetJob().GetName()].State = pb.State_UPDATE_STARTING
	return &pb.UpdateResponse{}, nil
}

// ListJobs - lists the jobs
func (s *Server) ListJobs(ctx context.Context, req *pb.ListRequest) (*pb.ListResponse, error) {
	s.nMut.Lock()
	defer s.nMut.Unlock()
	resp := &pb.ListResponse{}
	for _, job := range s.njobs {
		resp.Jobs = append(resp.Jobs, job)
	}
	return resp, nil
}

func extractBitRate(output string) (string, string) {
	matcher := regexp.MustCompile("Rate=(.*?) ")
	matches := matcher.FindStringSubmatch(output)

	matcher2 := regexp.MustCompile("Access Point. ([A-F0-9:]*)")
	matches2 := matcher2.FindStringSubmatch(output)
	if len(matches) > 0 && len(matches2) > 0 {
		return strings.TrimRight(matches[1], " "), strings.TrimRight(matches2[1], " ")
	}
	return "", ""
}

// SlaveConfig gets the config for this slave
func (s *Server) SlaveConfig(ctx context.Context, req *pb.ConfigRequest) (*pb.ConfigResponse, error) {
	disks := s.disker.getDisks()
	requirements := make([]*pb.Requirement, 0)
	for _, disk := range disks {
		requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_DISK, Properties: disk})
	}
	requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_SERVER, Properties: s.Registry.Identifier})
	if s.Registry.Identifier == "monitoring" {
		requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_EXTERNAL, Properties: "external_ready"})
	}

	data, err := exec.Command("/usr/bin/lsusb").Output()
	if err != nil {
		return nil, fmt.Errorf("error listing usb components: %v", err)
	}
	s.Log(fmt.Sprintf("USBRES: %v", string(data)))
	if strings.Contains(string(data), "TSP100II") {
		requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_RECEIPT_PRINTER})
	}

	out, _ := exec.Command("/sbin/iwconfig").Output()
	br, ap := extractBitRate(string(out))
	s.accessPoint = ap
	requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_NETWORK, Properties: br})
	requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_ACCESS_POINT, Properties: ap})

	requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_BITS, Properties: fmt.Sprintf("%v", s.Bits)})

	out, _ = exec.Command("cat", "/sys/firmware/devicetree/base/model").Output()
	requirements = append(requirements, &pb.Requirement{Category: pb.RequirementCategory_HOST_TYPE, Properties: string(out)})

	// Add in the printer

	return &pb.ConfigResponse{Config: &pb.SlaveConfig{Requirements: requirements}}, nil
}
<|endoftext|>


<commit_before>// comm project rpn.go
package comm

func opr_level(opr string) int {
	switch opr {
	case "+":
		fallthrough
	case "-":
		return 1
	case "*":
		fallthrough
	case "/":
		fallthrough
	case "%":
		return 2
	case "(":
		fallthrough
	default:
		return 0
	}
}

func Get_RPN(expression string, split string) string {
	str_rpn := ""
	str_tmp := ""
	ch := ""
	rpn := NewStack()
	opr := NewStack()

	for _, v := range expression {
		ch = string(v)
		if ch == " " {
			continue
		}

		switch ch {
		case "(":
			if str_tmp != "" {
				rpn.Push(str_tmp)
				str_tmp = ""
			}
			opr.Push(ch)
		case ")":
			if str_tmp != "" {
				rpn.Push(str_tmp)
				str_tmp = ""
			}
			str := ""
			for !opr.Empty() {
				str = opr.Pop().(string)
				if str == "(" {
					break
				}
				rpn.Push(str)
			}
		case "+":
			fallthrough
		case "-":
			fallthrough
		case "*":
			fallthrough
		case "%":
			fallthrough
		case "/":
			if str_tmp != "" {
				rpn.Push(str_tmp)
				str_tmp = ""
			}

			for !opr.Empty() {
				if opr_level(opr.Top().(string)) >= opr_level(ch) {
					rpn.Push(opr.Pop())
				} else {
					break
				}
			}
			opr.Push(ch)
		default:
			str_tmp += ch
		}
	}
	if str_tmp != "" {
		rpn.Push(str_tmp)
	}

	for !opr.Empty() {
		rpn.Push(opr.Pop())
	}

	for e := rpn.List().Front(); e != nil; e = e.Next() {
		str_rpn += e.Value.(string) + split
	}

	opr.Clean()
	rpn.Clean()

	return str_rpn[:len(str_rpn)-len(split)]
}
<commit_msg>modify rpn.go<commit_after>// comm project rpn.go
package comm

func opr_level(opr string) int {
	switch opr {
	case "+", "-":
		return 1
	case "*", "/", "%":
		return 2
	case "(":
		fallthrough
	default:
		return 0
	}
}

func Get_RPN(expression string, split string) string {
	str_rpn := ""
	str_tmp := ""
	ch := ""
	rpn := NewStack()
	opr := NewStack()

	for _, v := range expression {
		ch = string(v)
		if ch == " " {
			continue
		}

		switch ch {
		case "(":
			if str_tmp != "" {
				rpn.Push(str_tmp)
				str_tmp = ""
			}
			opr.Push(ch)
		case ")":
			if str_tmp != "" {
				rpn.Push(str_tmp)
				str_tmp = ""
			}
			str := ""
			for !opr.Empty() {
				str = opr.Pop().(string)
				if str == "(" {
					break
				}
				rpn.Push(str)
			}
		case "+", "-", "*", "%", "/":
			if str_tmp != "" {
				rpn.Push(str_tmp)
				str_tmp = ""
			}

			for !opr.Empty() {
				if opr_level(opr.Top().(string)) >= opr_level(ch) {
					rpn.Push(opr.Pop())
				} else {
					break
				}
			}
			opr.Push(ch)
		default:
			str_tmp += ch
		}
	}
	if str_tmp != "" {
		rpn.Push(str_tmp)
	}

	for !opr.Empty() {
		rpn.Push(opr.Pop())
	}

	for e := rpn.List().Front(); e != nil; e = e.Next() {
		str_rpn += e.Value.(string) + split
	}

	opr.Clean()
	rpn.Clean()

	return str_rpn[:len(str_rpn)-len(split)]
}
<|endoftext|>