<commit_before>package timeShift

import (
	"testing"

	"github.com/go-graphite/carbonapi/expr/helper"
	"github.com/go-graphite/carbonapi/expr/metadata"
	"github.com/go-graphite/carbonapi/expr/types"
	"github.com/go-graphite/carbonapi/pkg/parser"
	th "github.com/go-graphite/carbonapi/tests"
)

func init() {
	md := New("")
	evaluator := th.EvaluatorFromFunc(md[0].F)
	metadata.SetEvaluator(evaluator)
	helper.SetEvaluator(evaluator)
	for _, m := range md {
		metadata.RegisterFunction(m.Name, m.F)
	}
}

func TestTimeShift(t *testing.T) {
	var startTime int64 = 86400

	tests := []th.EvalTestItemWithRange{
		// TODO(civil): Do not pass `true` resetEnd parameter in 0.15
		{
			Target: `timeShift(metric1, "0s", true)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{"metric1", startTime, startTime + 6}: {types.MakeMetricData("metric1", []float64{0, 1, 2, 3, 4, 5}, 1, startTime)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'0',true)",
				[]float64{0, 1, 2, 3, 4, 5}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1s", false)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{"metric1", startTime - 1, startTime + 5}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3, 4}, 1, startTime-1)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-1',false)",
				[]float64{-1, 0, 1, 2, 3, 4}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1s", true)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{"metric1", startTime - 1, startTime + 5}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3}, 1, startTime-1)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-1',true)",
				[]float64{-1, 0, 1, 2, 3}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1h", false)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{"metric1", startTime - 60*60, startTime - 60*60 + 6}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3, 4}, 1, startTime-60*60)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-3600',false)",
				[]float64{-1, 0, 1, 2, 3, 4}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1h", true)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{"metric1", startTime - 60*60, startTime - 60*60 + 6}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3, 4}, 1, startTime-60*60)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-3600',true)",
				[]float64{-1, 0, 1, 2, 3, 4}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1d", false)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{"metric1", startTime - 86400, startTime - 86400 + 6}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3, 4}, 1, startTime-86400)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-86400',false)",
				[]float64{-1, 0, 1, 2, 3, 4}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1d", true)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{"metric1", startTime - 86400, startTime - 86400 + 6}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3, 4}, 1, startTime-86400)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-86400',true)",
				[]float64{-1, 0, 1, 2, 3, 4}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
	}

	for _, tt := range tests {
		testName := tt.Target
		t.Run(testName, func(t *testing.T) {
			th.TestEvalExprWithRange(t, &tt)
		})
	}
}
<commit_msg>tests: timeShift refactor (CodeQL)<commit_after>package timeShift

import (
	"testing"

	"github.com/go-graphite/carbonapi/expr/helper"
	"github.com/go-graphite/carbonapi/expr/metadata"
	"github.com/go-graphite/carbonapi/expr/types"
	"github.com/go-graphite/carbonapi/pkg/parser"
	th "github.com/go-graphite/carbonapi/tests"
)

func init() {
	md := New("")
	evaluator := th.EvaluatorFromFunc(md[0].F)
	metadata.SetEvaluator(evaluator)
	helper.SetEvaluator(evaluator)
	for _, m := range md {
		metadata.RegisterFunction(m.Name, m.F)
	}
}

func TestTimeShift(t *testing.T) {
	var startTime int64 = 86400

	tests := []th.EvalTestItemWithRange{
		// TODO(civil): Do not pass `true` resetEnd parameter in 0.15
		{
			Target: `timeShift(metric1, "0s", true)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{Metric: "metric1", From: startTime, Until: startTime + 6}: {types.MakeMetricData("metric1", []float64{0, 1, 2, 3, 4, 5}, 1, startTime)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'0',true)",
				[]float64{0, 1, 2, 3, 4, 5}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1s", false)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{Metric: "metric1", From: startTime - 1, Until: startTime + 5}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3, 4}, 1, startTime-1)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-1',false)",
				[]float64{-1, 0, 1, 2, 3, 4}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1s", true)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{Metric: "metric1", From: startTime - 1, Until: startTime + 5}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3}, 1, startTime-1)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-1',true)",
				[]float64{-1, 0, 1, 2, 3}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1h", false)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{Metric: "metric1", From: startTime - 60*60, Until: startTime - 60*60 + 6}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3, 4}, 1, startTime-60*60)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-3600',false)",
				[]float64{-1, 0, 1, 2, 3, 4}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1h", true)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{Metric: "metric1", From: startTime - 60*60, Until: startTime - 60*60 + 6}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3, 4}, 1, startTime-60*60)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-3600',true)",
				[]float64{-1, 0, 1, 2, 3, 4}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1d", false)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{Metric: "metric1", From: startTime - 86400, Until: startTime - 86400 + 6}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3, 4}, 1, startTime-86400)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-86400',false)",
				[]float64{-1, 0, 1, 2, 3, 4}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
		{
			Target: `timeShift(metric1, "1d", true)`,
			M: map[parser.MetricRequest][]*types.MetricData{
				{Metric: "metric1", From: startTime - 86400, Until: startTime - 86400 + 6}: {types.MakeMetricData("metric1", []float64{-1, 0, 1, 2, 3, 4}, 1, startTime-86400)},
			},
			Want: []*types.MetricData{types.MakeMetricData("timeShift(metric1,'-86400',true)",
				[]float64{-1, 0, 1, 2, 3, 4}, 1, startTime)},
			From:  startTime,
			Until: startTime + 6,
		},
	}

	for _, tt := range tests {
		testName := tt.Target
		t.Run(testName, func(t *testing.T) {
			th.TestEvalExprWithRange(t, &tt)
		})
	}
}
<|endoftext|>


<commit_before>package mackerel

import (
	"bytes"
	"encoding/json"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"time"
)

const (
	defaultBaseURL    = "https://api.mackerelio.com/"
	defaultUserAgent  = "mackerel-client-go"
	apiRequestTimeout = 30 * time.Second
)

// Client api client for mackerel
type Client struct {
	BaseURL           *url.URL
	APIKey            string
	Verbose           bool
	UserAgent         string
	AdditionalHeaders http.Header
	HTTPClient        *http.Client
}

// NewClient returns new mackerel.Client
func NewClient(apikey string) *Client {
	u, _ := url.Parse(defaultBaseURL)
	return &Client{u, apikey, false, defaultUserAgent, http.Header{}, &http.Client{}}
}

// NewClientWithOptions returns new mackerel.Client
func NewClientWithOptions(apikey string, rawurl string, verbose bool) (*Client, error) {
	u, err := url.Parse(rawurl)
	if err != nil {
		return nil, err
	}
	return &Client{u, apikey, verbose, defaultUserAgent, http.Header{}, &http.Client{}}, nil
}

func (c *Client) urlFor(path string) *url.URL {
	newURL, err := url.Parse(c.BaseURL.String())
	if err != nil {
		panic("invalid url passed")
	}

	newURL.Path = path

	return newURL
}

func (c *Client) buildReq(req *http.Request) *http.Request {
	for header, values := range c.AdditionalHeaders {
		for _, v := range values {
			req.Header.Add(header, v)
		}
	}
	req.Header.Set("X-Api-Key", c.APIKey)
	req.Header.Set("User-Agent", c.UserAgent)
	return req
}

// Request request to mackerel and receive response
func (c *Client) Request(req *http.Request) (resp *http.Response, err error) {
	req = c.buildReq(req)

	if c.Verbose {
		dump, err := httputil.DumpRequest(req, true)
		if err == nil {
			log.Printf("%s", dump)
		}
	}

	client := c.HTTPClient
	client.Timeout = apiRequestTimeout
	resp, err = client.Do(req)
	if err != nil {
		return nil, err
	}
	if c.Verbose {
		dump, err := httputil.DumpResponse(resp, true)
		if err == nil {
			log.Printf("%s", dump)
		}
	}
	if resp.StatusCode < 200 || resp.StatusCode > 299 {
		message := extractErrorMessage(resp.Body)
		defer resp.Body.Close()
		if message != "" {
			return nil, &APIError{StatusCode: resp.StatusCode, Message: message}
		}
		return nil, &APIError{StatusCode: resp.StatusCode, Message: resp.Status}
	}
	return resp, nil
}

// PostJSON shortcut method for posting json
func (c *Client) PostJSON(path string, payload interface{}) (*http.Response, error) {
	return c.requestJSON("POST", path, payload)
}

// PutJSON shortcut method for putting json
func (c *Client) PutJSON(path string, payload interface{}) (*http.Response, error) {
	return c.requestJSON("PUT", path, payload)
}

func (c *Client) requestJSON(method string, path string, payload interface{}) (*http.Response, error) {
	var body bytes.Buffer
	err := json.NewEncoder(&body).Encode(payload)
	if err != nil {
		return nil, err
	}

	req, err := http.NewRequest(method, c.urlFor(path).String(), &body)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	return c.Request(req)
}

func closeResponse(resp *http.Response) {
	if resp != nil {
		resp.Body.Close()
	}
}
<commit_msg>set timeout in constructor<commit_after>package mackerel

import (
	"bytes"
	"encoding/json"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"time"
)

const (
	defaultBaseURL    = "https://api.mackerelio.com/"
	defaultUserAgent  = "mackerel-client-go"
	apiRequestTimeout = 30 * time.Second
)

// Client api client for mackerel
type Client struct {
	BaseURL           *url.URL
	APIKey            string
	Verbose           bool
	UserAgent         string
	AdditionalHeaders http.Header
	HTTPClient        *http.Client
}

// NewClient returns new mackerel.Client
func NewClient(apikey string) *Client {
	c, _ := NewClientWithOptions(apikey, defaultBaseURL, false)
	return c
}

// NewClientWithOptions returns new mackerel.Client
func NewClientWithOptions(apikey string, rawurl string, verbose bool) (*Client, error) {
	u, err := url.Parse(rawurl)
	if err != nil {
		return nil, err
	}
	client := &http.Client{}
	client.Timeout = apiRequestTimeout
	return &Client{u, apikey, verbose, defaultUserAgent, http.Header{}, client}, nil
}

func (c *Client) urlFor(path string) *url.URL {
	newURL, err := url.Parse(c.BaseURL.String())
	if err != nil {
		panic("invalid url passed")
	}

	newURL.Path = path

	return newURL
}

func (c *Client) buildReq(req *http.Request) *http.Request {
	for header, values := range c.AdditionalHeaders {
		for _, v := range values {
			req.Header.Add(header, v)
		}
	}
	req.Header.Set("X-Api-Key", c.APIKey)
	req.Header.Set("User-Agent", c.UserAgent)
	return req
}

// Request request to mackerel and receive response
func (c *Client) Request(req *http.Request) (resp *http.Response, err error) {
	req = c.buildReq(req)

	if c.Verbose {
		dump, err := httputil.DumpRequest(req, true)
		if err == nil {
			log.Printf("%s", dump)
		}
	}

	resp, err = c.HTTPClient.Do(req)
	if err != nil {
		return nil, err
	}
	if c.Verbose {
		dump, err := httputil.DumpResponse(resp, true)
		if err == nil {
			log.Printf("%s", dump)
		}
	}
	if resp.StatusCode < 200 || resp.StatusCode > 299 {
		message := extractErrorMessage(resp.Body)
		defer resp.Body.Close()
		if message != "" {
			return nil, &APIError{StatusCode: resp.StatusCode, Message: message}
		}
		return nil, &APIError{StatusCode: resp.StatusCode, Message: resp.Status}
	}
	return resp, nil
}

// PostJSON shortcut method for posting json
func (c *Client) PostJSON(path string, payload interface{}) (*http.Response, error) {
	return c.requestJSON("POST", path, payload)
}

// PutJSON shortcut method for putting json
func (c *Client) PutJSON(path string, payload interface{}) (*http.Response, error) {
	return c.requestJSON("PUT", path, payload)
}

func (c *Client) requestJSON(method string, path string, payload interface{}) (*http.Response, error) {
	var body bytes.Buffer
	err := json.NewEncoder(&body).Encode(payload)
	if err != nil {
		return nil, err
	}

	req, err := http.NewRequest(method, c.urlFor(path).String(), &body)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	return c.Request(req)
}

func closeResponse(resp *http.Response) {
	if resp != nil {
		resp.Body.Close()
	}
}
<|endoftext|>


<commit_before>// +build mage

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"time"

	"github.com/magefile/mage/mg" // mg contains helpful utility functions, like Deps
	"github.com/magefile/mage/sh" // mg contains helpful utility functions, like Deps
	spartamage "github.com/mweagle/Sparta/magefile"
	"github.com/pkg/browser"
)

const localWorkDir = "./.sparta"

var ignoreSubdirectoryPaths = []string{
	".vendor",
	".sparta",
	".vscode",
	"/resources/describe",
}

// Default target to run when none is specified
// If not set, running mage will list available targets
// var Default = Build

func markdownSourceApply(commandParts ...string) error {
	return spartamage.ApplyToSource("md", ignoreSubdirectoryPaths, commandParts...)
}
func goSourceApply(commandParts ...string) error {
	return spartamage.ApplyToSource("go", ignoreSubdirectoryPaths, commandParts...)
}

// EnsureCleanTree ensures that the git tree is clean
func EnsureCleanTree() error {
	cleanTreeScript := [][]string{
		// No dirty trees
		{"git", "diff", "--exit-code"},
	}
	return spartamage.Script(cleanTreeScript)
}

// GenerateBuildInfo creates the automatic buildinfo.go file so that we can
// stamp the SHA into the binaries we build...
func GenerateBuildInfo() error {
	mg.SerialDeps(EnsureCleanTree)

	// The first thing we need is the `git` SHA
	cmd := exec.Command("git", "rev-parse", "HEAD")
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	if err != nil {
		return err
	}
	stdOutResult := strings.TrimSpace(string(stdout.Bytes()))

	// Super = update the buildinfo data
	buildInfoTemplate := `package sparta

// THIS FILE IS AUTOMATICALLY GENERATED
// DO NOT EDIT
// CREATED: %s

// SpartaGitHash is the commit hash of this Sparta library
const SpartaGitHash = "%s"
`
	updatedInfo := fmt.Sprintf(buildInfoTemplate, time.Now().UTC(), stdOutResult)
	// Write it to the output location...
	writeErr := ioutil.WriteFile("./buildinfo.go", []byte(updatedInfo), os.ModePerm)

	if writeErr != nil {
		return writeErr
	}
	commitGenerateCommands := [][]string{
		{"git", "diff"},
		{"git", "commit", "-a", "-m", `"Autogenerated build info"`},
	}
	return spartamage.Script(commitGenerateCommands)

}

// GenerateConstants runs the set of commands that update the embedded CONSTANTS
// for both local and AWS Lambda execution
func GenerateConstants() error {
	generateCommands := [][]string{
		// Create the embedded version
		{"go", "run", "$GOPATH/src/github.com/mjibson/esc/main.go", "-o", "./CONSTANTS.go", "-private", "-pkg", "sparta", "./resources"},
		//Create a secondary CONSTANTS_AWSBINARY.go file with empty content.
		{"go", "run", "$GOPATH/src/github.com/mjibson/esc/main.go", "-o", "./CONSTANTS_AWSBINARY.go", "-private", "-pkg", "sparta", "./resources/awsbinary/README.md"},
		//The next step will insert the
		// build tags at the head of each file so that they are mutually exclusive
		{"go", "run", "./cmd/insertTags/main.go", "./CONSTANTS", "!lambdabinary"},
		{"go", "run", "./cmd/insertTags/main.go", "./CONSTANTS_AWSBINARY", "lambdabinary"},
		{"git", "commit", "-a", "-m", "Autogenerated constants"},
	}
	return spartamage.Script(generateCommands)
}

// InstallBuildRequirements installs or updates the dependent
// packages that aren't referenced by the source, but are needed
// to build the Sparta source
func InstallBuildRequirements() error {
	spartamage.Log("`go get` update flags (env.GO_GET_FLAG): %s", os.Getenv("GO_GET_FLAG"))

	requirements := []string{
		"github.com/golang/dep/...",
		"honnef.co/go/tools/cmd/megacheck",
		"honnef.co/go/tools/cmd/gosimple",
		"honnef.co/go/tools/cmd/unused",
		"honnef.co/go/tools/cmd/staticcheck",
		"golang.org/x/tools/cmd/goimports",
		"github.com/fzipp/gocyclo",
		"golang.org/x/lint/golint",
		"github.com/mjibson/esc",
		"github.com/securego/gosec/cmd/gosec/...",
		"github.com/alexkohler/prealloc",
		"github.com/client9/misspell/cmd/misspell",
	}
	for _, eachDep := range requirements {
		cmdErr := sh.Run("go",
			"get",
			os.Getenv("GO_GET_FLAG"),
			eachDep)
		if cmdErr != nil {
			return cmdErr
		}
	}
	return nil
}

// EnsurePrealloc ensures that slices that could be preallocated are enforced
func EnsurePrealloc() error {
	// Super run some commands
	preallocCommand := [][]string{
		[]string{"prealloc", "-set_exit_status", "./..."},
	}
	return spartamage.Script(preallocCommand)
}

// EnsureSpelling ensures that there are no misspellings in the source
func EnsureSpelling() error {
	goSpelling := func() error {
		return goSourceApply("misspell", "-error")
	}
	mdSpelling := func() error {
		return markdownSourceApply("misspell", "-error")
	}
	mg.SerialDeps(
		goSpelling,
		mdSpelling)
	return nil
}

// EnsureVet ensures that the source has been `go vet`ted
func EnsureVet() error {
	return goSourceApply("go", "tool", "vet")
}

// EnsureLint ensures that the source is `golint`ed
func EnsureLint() error {
	return goSourceApply("golint")
}

// EnsureFormatted ensures that the source code is formatted with goimports
func EnsureFormatted() error {
	return goSourceApply("goimports", "-e", "-w")
}

// EnsureStaticChecks ensures that the source code passes static code checks
func EnsureStaticChecks() error {
	// Megacheck
	megacheckErr := sh.Run("megacheck",
		"-ignore",
		"github.com/mweagle/Sparta/CONSTANTS.go:*")
	if megacheckErr != nil {
		return megacheckErr
	}
	// Gosec
	if mg.Verbose() {
		return sh.Run("gosec",
			"-exclude=G204,G505,G401",
			"./...")
	}
	return sh.Run("gosec",
		"-exclude=G204,G505,G401",
		"-quiet",
		"./...")
}

// EnsureAllPreconditions ensures that the source passes *ALL* static `ensure*`
// precondition steps
func EnsureAllPreconditions() error {
	mg.SerialDeps(
		InstallBuildRequirements,
		EnsureVet,
		EnsureLint,
		EnsureFormatted,
		EnsureStaticChecks,
		EnsureSpelling,
		EnsurePrealloc,
	)
	return nil
}

// EnsureTravisBuildEnvironment is the command that sets up the Travis
// environment to run the build.
func EnsureTravisBuildEnvironment() error {
	mg.SerialDeps(InstallBuildRequirements)

	// Super run some commands
	travisComands := [][]string{
		[]string{"dep", "version"},
		[]string{"dep", "ensure", "-v"},
		[]string{"rsync", "-a", "--quiet", "--remove-source-files", "./vendor/", "$GOPATH/src"},
	}
	return spartamage.Script(travisComands)
}

// Build the application
func Build() error {
	mg.Deps(EnsureAllPreconditions)
	return sh.Run("go", "build", ".")
}

// Clean the working directory
func Clean() error {
	cleanCommands := [][]string{
		[]string{"go", "clean", "."},
		[]string{"rm", "-rf", "./graph.html"},
		[]string{"rsync", "-a", "--quiet", "--remove-source-files", "./vendor/", "$GOPATH/src"},
	}
	return spartamage.Script(cleanCommands)
}

// Describe runs the `TestDescribe` test to generate a describe HTML output
// file at graph.html
func Describe() error {
	describeCommands := [][]string{
		[]string{"rm", "-rf", "./graph.html"},
		[]string{"go", "test", "-v", "-run", "TestDescribe"},
	}
	return spartamage.Script(describeCommands)
}

// Publish the latest source
func Publish() error {
	mg.SerialDeps(GenerateBuildInfo)

	describeCommands := [][]string{
		[]string{"git", "push", "origin"},
	}
	return spartamage.Script(describeCommands)
}

// Test runs the Sparta tests
func Test() error {
	mg.SerialDeps(
		EnsureAllPreconditions,
	)
	verboseFlag := ""
	if mg.Verbose() {
		verboseFlag = "-v"
	}
	testCommand := [][]string{
		[]string{"go", "test", verboseFlag, "-cover", "-race", "./..."},
	}
	return spartamage.Script(testCommand)
}

// TestCover runs the test and opens up the resulting report
func TestCover() error {
	mg.SerialDeps(
		EnsureAllPreconditions,
	)
	coverageReport := fmt.Sprintf("%s/cover.out", localWorkDir)
	testCoverCommands := [][]string{
		[]string{"go", "test", fmt.Sprintf("-coverprofile=%s", coverageReport), "."},
		[]string{"go", "tool", "cover", fmt.Sprintf("-html=%s", coverageReport)},
		[]string{"rm", coverageReport},
		[]string{"open", fmt.Sprintf("%s/cover.html", localWorkDir)},
	}
	return spartamage.Script(testCoverCommands)
}

// TravisBuild is the task to build in the context of a Travis CI pipeline
func TravisBuild() error {
	mg.SerialDeps(EnsureTravisBuildEnvironment,
		Build,
		Test)
	return nil
}

// CompareAgainstMasterBranch is a convenience function to show the comparisons
// of the current pushed branch against the master branch
func CompareAgainstMasterBranch() error {
	// Get the current branch, open a browser
	// to the change...
	// The first thing we need is the `git` branch
	cmd := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD")
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	if err != nil {
		return err
	}
	stdOutResult := strings.TrimSpace(string(stdout.Bytes()))
	githubURL := fmt.Sprintf("https://github.com/mweagle/Sparta/compare/master...%s", stdOutResult)
	return browser.OpenURL(githubURL)
}
<commit_msg>Tree src dir<commit_after>// +build mage

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"time"

	"github.com/magefile/mage/mg" // mg contains helpful utility functions, like Deps
	"github.com/magefile/mage/sh" // mg contains helpful utility functions, like Deps
	spartamage "github.com/mweagle/Sparta/magefile"
	"github.com/pkg/browser"
)

const localWorkDir = "./.sparta"

var ignoreSubdirectoryPaths = []string{
	".vendor",
	".sparta",
	".vscode",
	"/resources/describe",
}

// Default target to run when none is specified
// If not set, running mage will list available targets
// var Default = Build

func markdownSourceApply(commandParts ...string) error {
	return spartamage.ApplyToSource("md", ignoreSubdirectoryPaths, commandParts...)
}
func goSourceApply(commandParts ...string) error {
	return spartamage.ApplyToSource("go", ignoreSubdirectoryPaths, commandParts...)
}

// EnsureCleanTree ensures that the git tree is clean
func EnsureCleanTree() error {
	cleanTreeScript := [][]string{
		// No dirty trees
		{"git", "diff", "--exit-code"},
	}
	return spartamage.Script(cleanTreeScript)
}

// GenerateBuildInfo creates the automatic buildinfo.go file so that we can
// stamp the SHA into the binaries we build...
func GenerateBuildInfo() error {
	mg.SerialDeps(EnsureCleanTree)

	// The first thing we need is the `git` SHA
	cmd := exec.Command("git", "rev-parse", "HEAD")
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	if err != nil {
		return err
	}
	stdOutResult := strings.TrimSpace(string(stdout.Bytes()))

	// Super = update the buildinfo data
	buildInfoTemplate := `package sparta

// THIS FILE IS AUTOMATICALLY GENERATED
// DO NOT EDIT
// CREATED: %s

// SpartaGitHash is the commit hash of this Sparta library
const SpartaGitHash = "%s"
`
	updatedInfo := fmt.Sprintf(buildInfoTemplate, time.Now().UTC(), stdOutResult)
	// Write it to the output location...
	writeErr := ioutil.WriteFile("./buildinfo.go", []byte(updatedInfo), os.ModePerm)

	if writeErr != nil {
		return writeErr
	}
	commitGenerateCommands := [][]string{
		{"git", "diff"},
		{"git", "commit", "-a", "-m", `"Autogenerated build info"`},
	}
	return spartamage.Script(commitGenerateCommands)

}

// GenerateConstants runs the set of commands that update the embedded CONSTANTS
// for both local and AWS Lambda execution
func GenerateConstants() error {
	generateCommands := [][]string{
		// Create the embedded version
		{"go", "run", "$GOPATH/src/github.com/mjibson/esc/main.go", "-o", "./CONSTANTS.go", "-private", "-pkg", "sparta", "./resources"},
		//Create a secondary CONSTANTS_AWSBINARY.go file with empty content.
		{"go", "run", "$GOPATH/src/github.com/mjibson/esc/main.go", "-o", "./CONSTANTS_AWSBINARY.go", "-private", "-pkg", "sparta", "./resources/awsbinary/README.md"},
		//The next step will insert the
		// build tags at the head of each file so that they are mutually exclusive
		{"go", "run", "./cmd/insertTags/main.go", "./CONSTANTS", "!lambdabinary"},
		{"go", "run", "./cmd/insertTags/main.go", "./CONSTANTS_AWSBINARY", "lambdabinary"},
		{"git", "commit", "-a", "-m", "Autogenerated constants"},
	}
	return spartamage.Script(generateCommands)
}

// InstallBuildRequirements installs or updates the dependent
// packages that aren't referenced by the source, but are needed
// to build the Sparta source
func InstallBuildRequirements() error {
	spartamage.Log("`go get` update flags (env.GO_GET_FLAG): %s", os.Getenv("GO_GET_FLAG"))

	requirements := []string{
		"github.com/golang/dep/...",
		"honnef.co/go/tools/cmd/megacheck",
		"honnef.co/go/tools/cmd/gosimple",
		"honnef.co/go/tools/cmd/unused",
		"honnef.co/go/tools/cmd/staticcheck",
		"golang.org/x/tools/cmd/goimports",
		"github.com/fzipp/gocyclo",
		"golang.org/x/lint/golint",
		"github.com/mjibson/esc",
		"github.com/securego/gosec/cmd/gosec/...",
		"github.com/alexkohler/prealloc",
		"github.com/client9/misspell/cmd/misspell",
	}
	for _, eachDep := range requirements {
		cmdErr := sh.Run("go",
			"get",
			os.Getenv("GO_GET_FLAG"),
			eachDep)
		if cmdErr != nil {
			return cmdErr
		}
	}
	return nil
}

// EnsurePrealloc ensures that slices that could be preallocated are enforced
func EnsurePrealloc() error {
	// Super run some commands
	preallocCommand := [][]string{
		[]string{"prealloc", "-set_exit_status", "./..."},
	}
	return spartamage.Script(preallocCommand)
}

// EnsureSpelling ensures that there are no misspellings in the source
func EnsureSpelling() error {
	goSpelling := func() error {
		return goSourceApply("misspell", "-error")
	}
	mdSpelling := func() error {
		return markdownSourceApply("misspell", "-error")
	}
	mg.SerialDeps(
		goSpelling,
		mdSpelling)
	return nil
}

// EnsureVet ensures that the source has been `go vet`ted
func EnsureVet() error {
	return goSourceApply("go", "tool", "vet")
}

// EnsureLint ensures that the source is `golint`ed
func EnsureLint() error {
	return goSourceApply("golint")
}

// EnsureFormatted ensures that the source code is formatted with goimports
func EnsureFormatted() error {
	return goSourceApply("goimports", "-e", "-w")
}

// EnsureStaticChecks ensures that the source code passes static code checks
func EnsureStaticChecks() error {
	// Megacheck
	megacheckErr := sh.Run("megacheck",
		"-ignore",
		"github.com/mweagle/Sparta/CONSTANTS.go:*")
	if megacheckErr != nil {
		return megacheckErr
	}
	// Gosec
	if mg.Verbose() {
		return sh.Run("gosec",
			"-exclude=G204,G505,G401",
			"./...")
	}
	return sh.Run("gosec",
		"-exclude=G204,G505,G401",
		"-quiet",
		"./...")
}

// EnsureAllPreconditions ensures that the source passes *ALL* static `ensure*`
// precondition steps
func EnsureAllPreconditions() error {
	mg.SerialDeps(
		InstallBuildRequirements,
		EnsureVet,
		EnsureLint,
		EnsureFormatted,
		EnsureStaticChecks,
		EnsureSpelling,
		EnsurePrealloc,
	)
	return nil
}

// EnsureTravisBuildEnvironment is the command that sets up the Travis
// environment to run the build.
func EnsureTravisBuildEnvironment() error {
	mg.SerialDeps(InstallBuildRequirements)

	// Super run some commands
	travisComands := [][]string{
		[]string{"dep", "version"},
		[]string{"dep", "ensure", "-v"},
		[]string{"rsync", "-a", "--quiet", "--remove-source-files", "./vendor/", "$GOPATH/src"},
		[]string{"tree", "-d", "-L", "2", "$GOPATH/src"},
	}
	return spartamage.Script(travisComands)
}

// Build the application
func Build() error {
	mg.Deps(EnsureAllPreconditions)
	return sh.Run("go", "build", ".")
}

// Clean the working directory
func Clean() error {
	cleanCommands := [][]string{
		[]string{"go", "clean", "."},
		[]string{"rm", "-rf", "./graph.html"},
		[]string{"rsync", "-a", "--quiet", "--remove-source-files", "./vendor/", "$GOPATH/src"},
	}
	return spartamage.Script(cleanCommands)
}

// Describe runs the `TestDescribe` test to generate a describe HTML output
// file at graph.html
func Describe() error {
	describeCommands := [][]string{
		[]string{"rm", "-rf", "./graph.html"},
		[]string{"go", "test", "-v", "-run", "TestDescribe"},
	}
	return spartamage.Script(describeCommands)
}

// Publish the latest source
func Publish() error {
	mg.SerialDeps(GenerateBuildInfo)

	describeCommands := [][]string{
		[]string{"git", "push", "origin"},
	}
	return spartamage.Script(describeCommands)
}

// Test runs the Sparta tests
func Test() error {
	mg.SerialDeps(
		EnsureAllPreconditions,
	)
	verboseFlag := ""
	if mg.Verbose() {
		verboseFlag = "-v"
	}
	testCommand := [][]string{
		[]string{"go", "test", verboseFlag, "-cover", "-race", "./..."},
	}
	return spartamage.Script(testCommand)
}

// TestCover runs the test and opens up the resulting report
func TestCover() error {
	mg.SerialDeps(
		EnsureAllPreconditions,
	)
	coverageReport := fmt.Sprintf("%s/cover.out", localWorkDir)
	testCoverCommands := [][]string{
		[]string{"go", "test", fmt.Sprintf("-coverprofile=%s", coverageReport), "."},
		[]string{"go", "tool", "cover", fmt.Sprintf("-html=%s", coverageReport)},
		[]string{"rm", coverageReport},
		[]string{"open", fmt.Sprintf("%s/cover.html", localWorkDir)},
	}
	return spartamage.Script(testCoverCommands)
}

// TravisBuild is the task to build in the context of a Travis CI pipeline
func TravisBuild() error {
	mg.SerialDeps(EnsureTravisBuildEnvironment,
		Build,
		Test)
	return nil
}

// CompareAgainstMasterBranch is a convenience function to show the comparisons
// of the current pushed branch against the master branch
func CompareAgainstMasterBranch() error {
	// Get the current branch, open a browser
	// to the change...
	// The first thing we need is the `git` branch
	cmd := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD")
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	if err != nil {
		return err
	}
	stdOutResult := strings.TrimSpace(string(stdout.Bytes()))
	githubURL := fmt.Sprintf("https://github.com/mweagle/Sparta/compare/master...%s", stdOutResult)
	return browser.OpenURL(githubURL)
}
<|endoftext|>


<commit_before>package session

import (
	"crypto/rand"
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

// Session - интерфейс структуры сессии.
// Все реализации сессий в проекте будут удовлетворять этому интерфейсу.
type Session interface {
	ID() string

	GetInt(key string) int
	SetInt(key string, val int)

	// TODO: Добавить поддержку разных типов данных.
	// GetFloat(key string) float64
	// SetFloat(key string, val float64)
	//
	// GetBytes(key string) []byte
	// SetBytes(key string, val []byte)
	//
	// GetString(key string) string
	// SetString(key string, val string)
}

var mapSession = make(map[string]*imSession)

type imSession struct {
	id string
	mp map[string]int
}

func (s *imSession) ID() string {
	return s.id
}

func (s *imSession) GetInt(key string) int {
	return s.mp[key]
}

func (s *imSession) SetInt(key string, val int) {
	if key == "" {
		return
	}
	s.mp[key] = val
}

func sessionInit(c *gin.Context) *imSession {
	session := imSession{}

	hash := make([]byte, 6)
	rand.Read(hash)

	session.id = fmt.Sprintf("%x", hash)
	session.mp = make(map[string]int)

	mapSession[session.id] = &session

	http.SetCookie(c.Writer, &http.Cookie{
		Name:  "SessID",
		Value: session.id,
	})
	return &session
}

func hasSession(c *gin.Context) (string, bool) {
	st, err := c.Request.Cookie("SessID")
	if err != nil {
		return "", false
	}
	return st.Value, true
}

// FromContext получает сессию из контекста gin.
// Если данные о сессии не содержатся в куки запроса, создает новую сессию.
// Иначе возвращает созданную ранее.
func FromContext(c *gin.Context) Session {
	if c == nil {
		return nil
	}
	key, ok := hasSession(c)
	if ok {
		ses, ok := mapSession[key]
		if ok {
			return ses
		}
	}
	return sessionInit(c)
}
<commit_msg>Cache session id in gin context<commit_after>package session

import (
	"crypto/rand"
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

// Session - интерфейс структуры сессии.
// Все реализации сессий в проекте будут удовлетворять этому интерфейсу.
type Session interface {
	ID() string

	GetInt(key string) int
	SetInt(key string, val int)

	// TODO: Добавить поддержку разных типов данных.
	// GetFloat(key string) float64
	// SetFloat(key string, val float64)
	//
	// GetBytes(key string) []byte
	// SetBytes(key string, val []byte)
	//
	// GetString(key string) string
	// SetString(key string, val string)
}

var mapSession = make(map[string]*imSession)

type imSession struct {
	id string
	mp map[string]int
}

func (s *imSession) ID() string {
	return s.id
}

func (s *imSession) GetInt(key string) int {
	return s.mp[key]
}

func (s *imSession) SetInt(key string, val int) {
	if key == "" {
		return
	}
	s.mp[key] = val
}

func sessionInit(c *gin.Context) *imSession {
	session := imSession{}

	hash := make([]byte, 6)
	rand.Read(hash)

	session.id = fmt.Sprintf("%x", hash)
	session.mp = make(map[string]int)

	mapSession[session.id] = &session

	http.SetCookie(c.Writer, &http.Cookie{
		Name:  "SessID",
		Value: session.id,
	})
	return &session
}

func hasSession(c *gin.Context) (string, bool) {
	st, err := c.Request.Cookie("SessID")
	if err != nil {
		return "", false
	}
	return st.Value, true
}

// FromContext получает сессию из контекста gin.
// Если данные о сессии не содержатся в куки запроса, создает новую сессию.
// Иначе возвращает созданную ранее.
func FromContext(c *gin.Context) Session {
	if c == nil {
		return nil
	}

	iid, exists := c.Get("session_id")
	if exists {
		id := iid.(string)
		ses, ok := mapSession[id]
		if ok {
			return ses
		}
	}

	key, ok := hasSession(c)
	if ok {
		ses, ok := mapSession[key]
		if ok {
			c.Set("session_id", key)
			return ses
		}
	}

	ses := sessionInit(c)
	c.Set("session_id", ses.ID())
	return ses
}
<|endoftext|>


<commit_before>package app

import (
	"log"
	"net/url"
	"sync"
	"time"
)

var StatisticsMap = &HostMap{hostmap: make(map[string]*URLMap)}

type Statistics struct {
	Path       string
	RequestNum int64
	MinTime    time.Duration
	MaxTime    time.Duration
	TotalTime  time.Duration
}

type URLMap struct {
	Host       string
	RequsetNum int64
	lock       sync.RWMutex
	pathmap    map[string]*Statistics
}

func (this *URLMap) addPath(path string) *Statistics {
	stat := &Statistics{Path: path}
	this.pathmap[path] = stat
	return stat
}

type HostMap struct {
	hostmap map[string]*URLMap
}

func (this *HostMap) addHost(host string) *URLMap {
	urlmap := &URLMap{
		pathmap:    make(map[string]*Statistics),
		RequsetNum: 0,
		Host:       host,
	}
	this.hostmap[host] = urlmap
	return urlmap
}

func (this *HostMap) AddStatistic(URL *url.URL) {
	host := URL.Host
	path := URL.Path
	if path == "" {
		path = "/"
	}
	urlmap, ok := StatisticsMap.hostmap[host]
	if !ok {
		urlmap = this.addHost(host)
	}
	urlmap.RequsetNum++

	pathStat, pok := urlmap.pathmap[path]
	if !pok {
		pathStat = urlmap.addPath(path)
	}
	pathStat.RequestNum++
	log.Printf("%s, %#v\n", host, urlmap)
	log.Printf("%s, %#v\n", path, pathStat)
}

func AddStat(URL *url.URL) {
	StatisticsMap.AddStatistic(URL)
}
<commit_msg>add lock<commit_after>package app

import (
	"log"
	"net/url"
	"sync"
	"time"
)

var StatisticsMap = &HostMap{hostmap: make(map[string]*URLMap)}

type Statistics struct {
	Path       string
	RequestNum int64
	MinTime    time.Duration
	MaxTime    time.Duration
	TotalTime  time.Duration
}

type URLMap struct {
	Host       string
	RequsetNum int64
	lock       sync.RWMutex
	pathmap    map[string]*Statistics
}

func (this *URLMap) addPath(path string) *Statistics {
	stat := &Statistics{Path: path}
	this.pathmap[path] = stat
	return stat
}

type HostMap struct {
	hostmap map[string]*URLMap
}

func (this *HostMap) addHost(host string) *URLMap {
	urlmap := &URLMap{
		pathmap:    make(map[string]*Statistics),
		RequsetNum: 0,
		Host:       host,
	}
	this.hostmap[host] = urlmap
	return urlmap
}

func (this *HostMap) AddStatistic(URL *url.URL) {
	host := URL.Host
	path := URL.Path
	if path == "" {
		path = "/"
	}
	urlmap, ok := StatisticsMap.hostmap[host]
	if !ok {
		urlmap = this.addHost(host)
	}
	urlmap.lock.Lock()
	defer urlmap.lock.Unlock()
	urlmap.RequsetNum++

	pathStat, pok := urlmap.pathmap[path]
	if !pok {
		pathStat = urlmap.addPath(path)
	}
	pathStat.RequestNum++
	log.Printf("%s, %#v\n", host, urlmap)
	log.Printf("%s, %#v\n", path, pathStat)
}

func AddStat(URL *url.URL) {
	StatisticsMap.AddStatistic(URL)
}
<|endoftext|>


<commit_before>package session

import (
	"crypto/rand"
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type Session interface {
	ID() string

	GetInt(key string) int
	SetInt(key string, val int)

	// TODO: Добавить поддержку разных типов данных.
	// GetFloat(key string) float64
	// SetFloat(key string, val float64)
	//
	// GetBytes(key string) []byte
	// SetBytes(key string, val []byte)
	//
	// GetString(key string) string
	// SetString(key string, val string)
}

// Получает сессию из контекста gin.
// Если данные о сессии не содержатся в куки запроса, создает новую сессию.
// Иначе возвращает созданную ранее.

var mapSession = make(map[string]*imSession)

type imSession struct {
	id string
	mp map[string]int
}

func (s *imSession) ID() string {
	return s.id
}

func (s *imSession) GetInt(key string) int {
	return s.mp[key]
}

func (s *imSession) SetInt(key string, val int) {
	if key == "" {
		return
	}
	s.mp[key] = val
}

func sessionInit(c *gin.Context) *imSession {
	session := imSession{}

	hash := make([]byte, 6)
	rand.Read(hash)

	session.id = fmt.Sprintf("%x", hash)
	session.mp = make(map[string]int)

	mapSession[session.id] = &session

	http.SetCookie(c.Writer, &http.Cookie{
		Name:  "SessID",
		Value: session.id,
	})
	return &session
}

func hasSession(c *gin.Context) (string, bool) {
	st, err := c.Request.Cookie("SessID")
	if err != nil {
		return "", false
	}
	return st.Value, true
}

func FromContext(c *gin.Context) Session {
	if c == nil {
		return nil
	}
	key, ok := hasSession(c)
	if ok {
		ses, ok := mapSession[key]
		if ok {
			return ses
		} else {
			return sessionInit(c)
		}
	}
	return sessionInit(c)
}
<commit_msg>Move comment back<commit_after>package session

import (
	"crypto/rand"
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type Session interface {
	ID() string

	GetInt(key string) int
	SetInt(key string, val int)

	// TODO: Добавить поддержку разных типов данных.
	// GetFloat(key string) float64
	// SetFloat(key string, val float64)
	//
	// GetBytes(key string) []byte
	// SetBytes(key string, val []byte)
	//
	// GetString(key string) string
	// SetString(key string, val string)
}

var mapSession = make(map[string]*imSession)

type imSession struct {
	id string
	mp map[string]int
}

func (s *imSession) ID() string {
	return s.id
}

func (s *imSession) GetInt(key string) int {
	return s.mp[key]
}

func (s *imSession) SetInt(key string, val int) {
	if key == "" {
		return
	}
	s.mp[key] = val
}

func sessionInit(c *gin.Context) *imSession {
	session := imSession{}

	hash := make([]byte, 6)
	rand.Read(hash)

	session.id = fmt.Sprintf("%x", hash)
	session.mp = make(map[string]int)

	mapSession[session.id] = &session

	http.SetCookie(c.Writer, &http.Cookie{
		Name:  "SessID",
		Value: session.id,
	})
	return &session
}

func hasSession(c *gin.Context) (string, bool) {
	st, err := c.Request.Cookie("SessID")
	if err != nil {
		return "", false
	}
	return st.Value, true
}

// Получает сессию из контекста gin.
// Если данные о сессии не содержатся в куки запроса, создает новую сессию.
// Иначе возвращает созданную ранее.
func FromContext(c *gin.Context) Session {
	if c == nil {
		return nil
	}
	key, ok := hasSession(c)
	if ok {
		ses, ok := mapSession[key]
		if ok {
			return ses
		} else {
			return sessionInit(c)
		}
	}
	return sessionInit(c)
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os/exec"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"../godump978"
	rtl "github.com/jpoirier/gortlsdr"
)

type UAT struct {
	dev     *rtl.Context
	indexID int
}

type ES struct {
	dev     *rtl.Context
	indexID int
}

var UATDev *UAT
var ESDev *ES

var uat_shutdown chan int
var uat_wg *sync.WaitGroup = &sync.WaitGroup{}

var es_shutdown chan int
var es_wg *sync.WaitGroup = &sync.WaitGroup{}

var maxSignalStrength int

func (e *ES) read() {
	defer es_wg.Done()
	log.Println("Entered ES read() ...")
	cmd := exec.Command("/usr/bin/dump1090", "--net", "--device-index", strconv.Itoa(e.indexID))
	err := cmd.Start()
	if err != nil {
		log.Printf("Error executing /usr/bin/dump1090: %s\n", err.Error())
		return
	}
	log.Println("Executed /usr/bin/dump1090 successfully...")
	for {
		select {
		default:
			time.Sleep(1 * time.Second)
		case <-es_shutdown:
			log.Println("ES read(): shutdown msg received, calling cmd.Process.Kill() ...")
			cmd.Process.Kill()
			log.Println("\t kill successful...")
			return
		}
	}
}

func (u *UAT) read() {
	defer uat_wg.Done()
	log.Println("Entered UAT read() ...")
	var buffer = make([]uint8, rtl.DefaultBufLength)
	for {
		select {
		default:
			nRead, err := u.dev.ReadSync(buffer, rtl.DefaultBufLength)
			if err != nil {
				log.Printf("\tReadSync Failed - error: %s\n", err)
				break
			}
			// log.Printf("\tReadSync %d\n", nRead)
			if nRead > 0 {
				buf := buffer[:nRead]
				godump978.InChan <- buf
			}
		case <-uat_shutdown:
			log.Println("UAT read(): shutdown msg received...")
			return
		}
	}
}

func (e *ES) sdrConfig() (err error) {
	return
}

// Read 978MHz from SDR.
func (u *UAT) sdrConfig() (err error) {
	log.Printf("===== UAT Device name: %s =====\n", rtl.GetDeviceName(u.indexID))
	if u.dev, err = rtl.Open(u.indexID); err != nil {
		log.Printf("\tUAT Open Failed...\n")
		return
	}
	log.Printf("\tGetTunerType: %s\n", u.dev.GetTunerType())

	//---------- Set Tuner Gain ----------
	err = u.dev.SetTunerGainMode(true)
	if err != nil {
		u.dev.Close()
		log.Printf("\tSetTunerGainMode Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tSetTunerGainMode Successful\n")
	}

	tgain := 480
	err = u.dev.SetTunerGain(tgain)
	if err != nil {
		u.dev.Close()
		log.Printf("\tSetTunerGain Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tSetTunerGain Successful\n")
	}

	//---------- Get/Set Sample Rate ----------
	samplerate := 2083334
	err = u.dev.SetSampleRate(samplerate)
	if err != nil {
		u.dev.Close()
		log.Printf("\tSetSampleRate Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tSetSampleRate - rate: %d\n", samplerate)
	}
	log.Printf("\tGetSampleRate: %d\n", u.dev.GetSampleRate())

	//---------- Get/Set Xtal Freq ----------
	rtlFreq, tunerFreq, err := u.dev.GetXtalFreq()
	if err != nil {
		u.dev.Close()
		log.Printf("\tGetXtalFreq Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tGetXtalFreq - Rtl: %d, Tuner: %d\n", rtlFreq, tunerFreq)
	}

	newRTLFreq := 28800000
	newTunerFreq := 28800000
	err = u.dev.SetXtalFreq(newRTLFreq, newTunerFreq)
	if err != nil {
		u.dev.Close()
		log.Printf("\tSetXtalFreq Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tSetXtalFreq - Center freq: %d, Tuner freq: %d\n",
			newRTLFreq, newTunerFreq)
	}

	//---------- Get/Set Center Freq ----------
	err = u.dev.SetCenterFreq(978000000)
	if err != nil {
		u.dev.Close()
		log.Printf("\tSetCenterFreq 978MHz Failed, error: %s\n", err)
		return
	} else {
		log.Printf("\tSetCenterFreq 978MHz Successful\n")
	}

	log.Printf("\tGetCenterFreq: %d\n", u.dev.GetCenterFreq())

	//---------- Set Bandwidth ----------
	bw := 1000000
	log.Printf("\tSetting Bandwidth: %d\n", bw)
	if err = u.dev.SetTunerBw(bw); err != nil {
		u.dev.Close()
		log.Printf("\tSetTunerBw %d Failed, error: %s\n", bw, err)
		return
	} else {
		log.Printf("\tSetTunerBw %d Successful\n", bw)
	}

	if err = u.dev.ResetBuffer(); err != nil {
		u.dev.Close()
		log.Printf("\tResetBuffer Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tResetBuffer Successful\n")
	}
	//---------- Get/Set Freq Correction ----------
	freqCorr := u.dev.GetFreqCorrection()
	log.Printf("\tGetFreqCorrection: %d\n", freqCorr)
	err = u.dev.SetFreqCorrection(globalSettings.PPM)
	// librtlsdr returned error code inconsistencies, i.e.
	// error code -2 means the current value is the same as
	// the PPM value we sent (dev->corr == PPM)
	if err != nil && err != -2 {
		u.dev.Close()
		log.Printf("\tSetFreqCorrection %d Failed, error: %s\n", globalSettings.PPM, err)
		return
	} else {
		log.Printf("\tSetFreqCorrection %d Successful\n", globalSettings.PPM)
	}
	return
}

// Read from the godump978 channel - on or off.
func uatReader() {
	log.Println("Entered uatReader() ...")
	for {
		uat := <-godump978.OutChan
		o, msgtype := parseInput(uat)
		if o != nil && msgtype != 0 {
			relayMessage(msgtype, o)
		}
	}
}

func (u *UAT) shutdown() {
	log.Println("Entered UAT shutdown() ...")
	close(uat_shutdown) // signal to shutdown
	log.Println("UAT shutdown(): closing device ...")
	u.dev.Close() // preempt the blocking ReadSync call
	log.Println("UAT shutdown(): calling uat_wg.Wait() ...")
	uat_wg.Wait() // Wait for the goroutine to shutdown
	log.Println("UAT shutdown(): uat_wg.Wait() returned...")
}

func (e *ES) shutdown() {
	log.Println("Entered ES shutdown() ...")
	close(es_shutdown) // signal to shutdown
	log.Println("ES shutdown(): calling es_wg.Wait() ...")
	es_wg.Wait() // Wait for the goroutine to shutdown
	log.Println("ES shutdown(): es_wg.Wait() returned...")
}

var devMap = map[int]string{0: "", 1: ""}

// Watch for config/device changes.
func sdrWatcher() {
	for {
		time.Sleep(1 * time.Second)
		count := rtl.GetDeviceCount()
		atomic.StoreUint32(&globalStatus.Devices, uint32(count))
		log.Println("DeviceCount...", count)

		// support two and only two dongles
		if count > 2 {
			count = 2
		}

		// cleanup if necessary
		if count < 1 || (!globalSettings.UAT_Enabled && !globalSettings.ES_Enabled) {
			log.Println("doing cleanup...")
			if UATDev != nil {
				UATDev.shutdown()
				UATDev = nil
			}
			if ESDev != nil {
				ESDev.shutdown()
				ESDev = nil
			}
			continue
		}

		if count == 1 {
			if UATDev != nil && ESDev == nil {
				UATDev.indexID = 0
			} else if UATDev == nil && ESDev != nil {
				ESDev.indexID = 0
			}
		}

		ids := []string{"", ""}
		for i := 0; i < count; i++ {
			// manufact, product, serial, err
			_, _, s, _ := rtl.GetDeviceUsbStrings(i)
			ids[i] = s
		}

		// UAT specific handling
		// When count is one, favor UAT in the case where the user
		// has enabled both UAT and ES via the web interface.
		id := 0
		if globalSettings.UAT_Enabled {
			log.Println("globalSettings.UAT_Enabled == true")
			if count == 1 {
				if ESDev != nil {
					ESDev.shutdown()
					ESDev = nil
				}
			} else { // count == 2
				if UATDev == nil && ESDev != nil {
					if ESDev.indexID == 0 {
						id = 1
					}
				}
			}

			if UATDev == nil {
				log.Println("\tUATDev == nil")
				// preference check based on stratux
				// hardware serial when it exists
				serial := ids[id]
				if strings.HasPrefix(serial, "stratux:1090") {
					log.Println("Settings conflict: 978UAT set via WebUI but hardware serial says stratux:1090")
				} else {
					UATDev = &UAT{indexID: id}
					if err := UATDev.sdrConfig(); err != nil {
						log.Printf("UATDev = &UAT{indexID: id} failed: %s\n", err)
						UATDev = nil
					} else {
						if UATDev == nil {
							log.Println("XXXXXXX UATDev == nil this shouldn't be nil")
						}
						uat_shutdown = make(chan int)
						uat_wg.Add(1)
						go UATDev.read()
					}
				}
			}
		} else if UATDev != nil {
			UATDev.shutdown()
			UATDev = nil
			if count == 1 && ESDev != nil {
				ESDev.indexID = 0
			}
		}

		// ES specific handling
		id = 0
		if globalSettings.ES_Enabled {
			log.Println("globalSettings.ES_Enabled == true")
			if count == 1 {
				if globalSettings.UAT_Enabled {
					// defer to the UAT handler
					goto End
				}
			} else { // count == 2
				if ESDev == nil && UATDev != nil {
					if UATDev.indexID == 0 {
						id = 1
					}
				}
			}

			if ESDev == nil {
				log.Println("\tESDev == nil")
				// preference check based on stratux
				// hardware serial when it exists
				serial := ids[id]
				if strings.HasPrefix(serial, "stratux:978") {
					log.Println("Settings conflict: 1090ES set via WebUI but hardware serial says stratux:978")
				} else {
					ESDev = &ES{indexID: id}
					if err := ESDev.sdrConfig(); err != nil {
						log.Printf("ESDev = &ES{indexID: id} failed: %s\n", err)
						ESDev = nil
					} else {
						if ESDev == nil {
							log.Println("XXXXXXX ESDev == nil this shouldn't be nil")
						}
						es_shutdown = make(chan int)
						es_wg.Add(1)
						go ESDev.read()
					}
				}
			}
		} else if ESDev != nil {
			ESDev.shutdown()
			ESDev = nil
			if count == 1 && UATDev != nil {
				UATDev.indexID = 0
			}
		}
	End:
	}
}

func sdrInit() {
	go sdrWatcher()
	go uatReader()
	godump978.Dump978Init()
	go godump978.ProcessDataFromChannel()
}
<commit_msg>better/fixed error GetFreqCorrection handling<commit_after>package main

import (
	"log"
	"os/exec"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"../godump978"
	rtl "github.com/jpoirier/gortlsdr"
)

type UAT struct {
	dev     *rtl.Context
	indexID int
}

type ES struct {
	dev     *rtl.Context
	indexID int
}

var UATDev *UAT
var ESDev *ES

var uat_shutdown chan int
var uat_wg *sync.WaitGroup = &sync.WaitGroup{}

var es_shutdown chan int
var es_wg *sync.WaitGroup = &sync.WaitGroup{}

var maxSignalStrength int

func (e *ES) read() {
	defer es_wg.Done()
	log.Println("Entered ES read() ...")
	cmd := exec.Command("/usr/bin/dump1090", "--net", "--device-index", strconv.Itoa(e.indexID))
	err := cmd.Start()
	if err != nil {
		log.Printf("Error executing /usr/bin/dump1090: %s\n", err.Error())
		return
	}
	log.Println("Executed /usr/bin/dump1090 successfully...")
	for {
		select {
		default:
			time.Sleep(1 * time.Second)
		case <-es_shutdown:
			log.Println("ES read(): shutdown msg received, calling cmd.Process.Kill() ...")
			cmd.Process.Kill()
			log.Println("\t kill successful...")
			return
		}
	}
}

func (u *UAT) read() {
	defer uat_wg.Done()
	log.Println("Entered UAT read() ...")
	var buffer = make([]uint8, rtl.DefaultBufLength)
	for {
		select {
		default:
			nRead, err := u.dev.ReadSync(buffer, rtl.DefaultBufLength)
			if err != nil {
				log.Printf("\tReadSync Failed - error: %s\n", err)
				break
			}
			// log.Printf("\tReadSync %d\n", nRead)
			if nRead > 0 {
				buf := buffer[:nRead]
				godump978.InChan <- buf
			}
		case <-uat_shutdown:
			log.Println("UAT read(): shutdown msg received...")
			return
		}
	}
}

func (e *ES) sdrConfig() (err error) {
	return
}

// Read 978MHz from SDR.
func (u *UAT) sdrConfig() (err error) {
	log.Printf("===== UAT Device name: %s =====\n", rtl.GetDeviceName(u.indexID))
	if u.dev, err = rtl.Open(u.indexID); err != nil {
		log.Printf("\tUAT Open Failed...\n")
		return
	}
	log.Printf("\tGetTunerType: %s\n", u.dev.GetTunerType())

	//---------- Set Tuner Gain ----------
	err = u.dev.SetTunerGainMode(true)
	if err != nil {
		u.dev.Close()
		log.Printf("\tSetTunerGainMode Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tSetTunerGainMode Successful\n")
	}

	tgain := 480
	err = u.dev.SetTunerGain(tgain)
	if err != nil {
		u.dev.Close()
		log.Printf("\tSetTunerGain Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tSetTunerGain Successful\n")
	}

	//---------- Get/Set Sample Rate ----------
	samplerate := 2083334
	err = u.dev.SetSampleRate(samplerate)
	if err != nil {
		u.dev.Close()
		log.Printf("\tSetSampleRate Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tSetSampleRate - rate: %d\n", samplerate)
	}
	log.Printf("\tGetSampleRate: %d\n", u.dev.GetSampleRate())

	//---------- Get/Set Xtal Freq ----------
	rtlFreq, tunerFreq, err := u.dev.GetXtalFreq()
	if err != nil {
		u.dev.Close()
		log.Printf("\tGetXtalFreq Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tGetXtalFreq - Rtl: %d, Tuner: %d\n", rtlFreq, tunerFreq)
	}

	newRTLFreq := 28800000
	newTunerFreq := 28800000
	err = u.dev.SetXtalFreq(newRTLFreq, newTunerFreq)
	if err != nil {
		u.dev.Close()
		log.Printf("\tSetXtalFreq Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tSetXtalFreq - Center freq: %d, Tuner freq: %d\n",
			newRTLFreq, newTunerFreq)
	}

	//---------- Get/Set Center Freq ----------
	err = u.dev.SetCenterFreq(978000000)
	if err != nil {
		u.dev.Close()
		log.Printf("\tSetCenterFreq 978MHz Failed, error: %s\n", err)
		return
	} else {
		log.Printf("\tSetCenterFreq 978MHz Successful\n")
	}

	log.Printf("\tGetCenterFreq: %d\n", u.dev.GetCenterFreq())

	//---------- Set Bandwidth ----------
	bw := 1000000
	log.Printf("\tSetting Bandwidth: %d\n", bw)
	if err = u.dev.SetTunerBw(bw); err != nil {
		u.dev.Close()
		log.Printf("\tSetTunerBw %d Failed, error: %s\n", bw, err)
		return
	} else {
		log.Printf("\tSetTunerBw %d Successful\n", bw)
	}

	if err = u.dev.ResetBuffer(); err != nil {
		u.dev.Close()
		log.Printf("\tResetBuffer Failed - error: %s\n", err)
		return
	} else {
		log.Printf("\tResetBuffer Successful\n")
	}
	//---------- Get/Set Freq Correction ----------
	freqCorr := u.dev.GetFreqCorrection()
	log.Printf("\tGetFreqCorrection: %d\n", freqCorr)
	// avoid librtlsdr error code inconsistency, i.e.
	// error code -2 means the stored value is the same as
	// the PPM value we sent (dev->corr == PPM)
	if freqCorr != globalSettings.PPM
		err = u.dev.SetFreqCorrection(globalSettings.PPM)
		if err != nil{
			// just print a warning
			log.Printf("\tSetFreqCorrection %d Failed, error: %s\n", globalSettings.PPM, err)
		} else {
			log.Printf("\tSetFreqCorrection %d Successful\n", globalSettings.PPM)
		}
	}
	return
}

// Read from the godump978 channel - on or off.
func uatReader() {
	log.Println("Entered uatReader() ...")
	for {
		uat := <-godump978.OutChan
		o, msgtype := parseInput(uat)
		if o != nil && msgtype != 0 {
			relayMessage(msgtype, o)
		}
	}
}

func (u *UAT) shutdown() {
	log.Println("Entered UAT shutdown() ...")
	close(uat_shutdown) // signal to shutdown
	log.Println("UAT shutdown(): closing device ...")
	u.dev.Close() // preempt the blocking ReadSync call
	log.Println("UAT shutdown(): calling uat_wg.Wait() ...")
	uat_wg.Wait() // Wait for the goroutine to shutdown
	log.Println("UAT shutdown(): uat_wg.Wait() returned...")
}

func (e *ES) shutdown() {
	log.Println("Entered ES shutdown() ...")
	close(es_shutdown) // signal to shutdown
	log.Println("ES shutdown(): calling es_wg.Wait() ...")
	es_wg.Wait() // Wait for the goroutine to shutdown
	log.Println("ES shutdown(): es_wg.Wait() returned...")
}

var devMap = map[int]string{0: "", 1: ""}

// Watch for config/device changes.
func sdrWatcher() {
	for {
		time.Sleep(1 * time.Second)
		count := rtl.GetDeviceCount()
		atomic.StoreUint32(&globalStatus.Devices, uint32(count))
		log.Println("DeviceCount...", count)

		// support two and only two dongles
		if count > 2 {
			count = 2
		}

		// cleanup if necessary
		if count < 1 || (!globalSettings.UAT_Enabled && !globalSettings.ES_Enabled) {
			log.Println("doing cleanup...")
			if UATDev != nil {
				UATDev.shutdown()
				UATDev = nil
			}
			if ESDev != nil {
				ESDev.shutdown()
				ESDev = nil
			}
			continue
		}

		if count == 1 {
			if UATDev != nil && ESDev == nil {
				UATDev.indexID = 0
			} else if UATDev == nil && ESDev != nil {
				ESDev.indexID = 0
			}
		}

		ids := []string{"", ""}
		for i := 0; i < count; i++ {
			// manufact, product, serial, err
			_, _, s, _ := rtl.GetDeviceUsbStrings(i)
			ids[i] = s
		}

		// UAT specific handling
		// When count is one, favor UAT in the case where the user
		// has enabled both UAT and ES via the web interface.
		id := 0
		if globalSettings.UAT_Enabled {
			log.Println("globalSettings.UAT_Enabled == true")
			if count == 1 {
				if ESDev != nil {
					ESDev.shutdown()
					ESDev = nil
				}
			} else { // count == 2
				if UATDev == nil && ESDev != nil {
					if ESDev.indexID == 0 {
						id = 1
					}
				}
			}

			if UATDev == nil {
				log.Println("\tUATDev == nil")
				// preference check based on stratux
				// hardware serial when it exists
				serial := ids[id]
				if strings.HasPrefix(serial, "stratux:1090") {
					log.Println("Settings conflict: 978UAT set via WebUI but hardware serial says stratux:1090")
				} else {
					UATDev = &UAT{indexID: id}
					if err := UATDev.sdrConfig(); err != nil {
						log.Printf("UATDev = &UAT{indexID: id} failed: %s\n", err)
						UATDev = nil
					} else {
						if UATDev == nil {
							log.Println("XXXXXXX UATDev == nil this shouldn't be nil")
						}
						uat_shutdown = make(chan int)
						uat_wg.Add(1)
						go UATDev.read()
					}
				}
			}
		} else if UATDev != nil {
			UATDev.shutdown()
			UATDev = nil
			if count == 1 && ESDev != nil {
				ESDev.indexID = 0
			}
		}

		// ES specific handling
		id = 0
		if globalSettings.ES_Enabled {
			log.Println("globalSettings.ES_Enabled == true")
			if count == 1 {
				if globalSettings.UAT_Enabled {
					// defer to the UAT handler
					goto End
				}
			} else { // count == 2
				if ESDev == nil && UATDev != nil {
					if UATDev.indexID == 0 {
						id = 1
					}
				}
			}

			if ESDev == nil {
				log.Println("\tESDev == nil")
				// preference check based on stratux
				// hardware serial when it exists
				serial := ids[id]
				if strings.HasPrefix(serial, "stratux:978") {
					log.Println("Settings conflict: 1090ES set via WebUI but hardware serial says stratux:978")
				} else {
					ESDev = &ES{indexID: id}
					if err := ESDev.sdrConfig(); err != nil {
						log.Printf("ESDev = &ES{indexID: id} failed: %s\n", err)
						ESDev = nil
					} else {
						if ESDev == nil {
							log.Println("XXXXXXX ESDev == nil this shouldn't be nil")
						}
						es_shutdown = make(chan int)
						es_wg.Add(1)
						go ESDev.read()
					}
				}
			}
		} else if ESDev != nil {
			ESDev.shutdown()
			ESDev = nil
			if count == 1 && UATDev != nil {
				UATDev.indexID = 0
			}
		}
	End:
	}
}

func sdrInit() {
	go sdrWatcher()
	go uatReader()
	godump978.Dump978Init()
	go godump978.ProcessDataFromChannel()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/nutrun/lentil"
	"io/ioutil"
	"log"
	"net/smtp"
	"os"
	"os/exec"
	"os/signal"
	"strings"
	"syscall"
	"time"
)

type Listener struct {
	q        *lentil.Beanstalkd
	verbose  bool
	jobqueue *JobQueue
	sig      os.Signal
	proc     *os.Process
}

func NewListener(verbose, inclusive bool, filter []string) (*Listener, error) {
	this := new(Listener)
	q, err := lentil.Dial(Config.QueueAddr)

	if err != nil {
		return nil, err
	}

	this.q = q
	this.verbose = verbose
	this.jobqueue = NewJobQueue(this.q, inclusive, filter)
	return this, nil
}

func (this *Listener) execute(msg map[string]string) {
	workdir := msg["workdir"]
	e := os.Chdir(workdir)
	if e != nil {
		this.catch(msg, e)
	}
	messagetokens := strings.Split(msg["cmd"], " ")
	command := messagetokens[0]
	args := messagetokens[1:len(messagetokens)]
	cmd := exec.Command(command, args...)
	f, e := os.Create(msg["out"])
	if e != nil {
		this.catch(msg, e)
		return
	}
	cmd.Stderr = f
	cmd.Stdout = f
	e = cmd.Start()
	if e != nil {
		this.catch(msg, e)
	}
	this.proc = cmd.Process
	e = cmd.Wait()
	if e != nil {
		this.catch(msg, e)
	}
	this.proc = nil
	f.Close()
}

func (this *Listener) run() {
	go this.trap()

listenerloop:
	for {
		if this.sig != nil {
			os.Exit(0)
		}
		Config.Load()
		job, e := this.jobqueue.Next()
		if e != nil {
			if strings.Contains(e.Error(), "TIMED_OUT") {
				time.Sleep(time.Second)
				goto listenerloop
			}
			log.Fatal(e)
		}
		if this.verbose {
			log.Printf("RUNNING: %s", job.Body)
		}
		msg := make(map[string]string)
		json.Unmarshal([]byte(job.Body), &msg)
		this.execute(msg)
		e = this.jobqueue.Delete(job.Id)
		if e != nil {
			this.catch(msg, e)
		}
	}
}

// Log and email errors
func (this *Listener) catch(msg map[string]string, e error) {
	log.Printf("ERROR: %s\n", e.Error())
	this.mail(msg, e)
	this.publishError(msg, e)

}

func (this *Listener) publishError(msg map[string]string, e error) {
	err := this.q.Use(Config.errorQueue)
	if err != nil {
		log.Printf("ERROR: %s\n", err)
		return
	}
	msg["error"] = e.Error()
	msg["log"] = this.readLog(msg)
	payload, err := json.Marshal(msg)
	if err != nil {
		log.Printf("ERROR: %s\n", err)
		return
	}
	_, err = this.q.Put(0, 0, 60*60, payload)
	if err != nil {
		log.Printf("ERROR: %s\n", err)
	}
}

func (this *Listener) readLog(msg map[string]string) string {
	content := make([]byte, 0)
	info, err := os.Stat(msg["out"])
	if err != nil {
		content = []byte(fmt.Sprintf("Could not read job log from [%s]. %s", msg["out"], err.Error()))
		return string(content)
	}
	if info.Size() > 104857 {
		content = []byte(fmt.Sprintf("Could send job log [%s]. File too big", msg["out"]))
	} else {
		content, err = ioutil.ReadFile(msg["out"])
		if err != nil {
			content = []byte(fmt.Sprintf("Could not read job log from [%s]", msg["out"]))
		}
	}
	return string(content)

}

func (this *Listener) mail(msg map[string]string, e error) {
	if Config.SmtpServerAddr == "" {
		return
	}
	if len(msg["mailto"]) < 1 { //no email addresses
		return
	}
	to := strings.Split(msg["mailto"], ",")
	subject := fmt.Sprintf("Subject: FAILED: %s\r\n\r\n", msg["cmd"])
	hostname, _ := os.Hostname()
	content := []byte(this.readLog(msg))
	mail := fmt.Sprintf("%s%s", subject, fmt.Sprintf("Ran on [%s]\n%s\n%s\n%s", hostname, subject, e, content))
	e = smtp.SendMail(Config.SmtpServerAddr, nil, Config.MailFrom, to, []byte(mail))
	if e != nil {
		log.Printf("ERROR: %s\n", e)
	}
}

// Wait for currently running job to finish before exiting on SIGTERM and SIGINT
func (this *Listener) trap() {
	receivedSignal := make(chan os.Signal)
	signal.Notify(receivedSignal, syscall.SIGTERM, syscall.SIGINT)
	this.sig = <-receivedSignal
	if this.sig.String() == syscall.SIGTERM.String() {
		log.Printf("Got signal %d. Killing current job.", this.sig)
		if this.proc != nil {
			this.proc.Kill()
		}
		os.Exit(1)
	}
	log.Printf("Got signal %d. Waiting for current job to complete. sig term is [%v]", this.sig, syscall.SIGTERM)
}
<commit_msg>fixed some glow shie<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/nutrun/lentil"
	"io/ioutil"
	"log"
	"net/smtp"
	"os"
	"os/exec"
	"os/signal"
	"strings"
	"syscall"
	"time"
)

type Listener struct {
	q        *lentil.Beanstalkd
	verbose  bool
	jobqueue *JobQueue
	sig      os.Signal
	proc     *os.Process
}

func NewListener(verbose, inclusive bool, filter []string) (*Listener, error) {
	this := new(Listener)
	q, err := lentil.Dial(Config.QueueAddr)

	if err != nil {
		return nil, err
	}

	this.q = q
	this.verbose = verbose
	this.jobqueue = NewJobQueue(this.q, inclusive, filter)
	return this, nil
}

func (this *Listener) execute(msg map[string]string) {
	workdir := msg["workdir"]
	e := os.Chdir(workdir)
	if e != nil {
		this.catch(msg, e)
		return
	}
	messagetokens := strings.Split(msg["cmd"], " ")
	command := messagetokens[0]
	args := messagetokens[1:len(messagetokens)]
	cmd := exec.Command(command, args...)
	f, e := os.Create(msg["out"])
	if e != nil {
		this.catch(msg, e)
		return
	}

	defer f.Close()

	cmd.Stderr = f
	cmd.Stdout = f

	e = cmd.Start()
	if e != nil {
		this.catch(msg, e)
		return
	}

	this.proc = cmd.Process
	e = cmd.Wait()

	if e != nil {
		this.catch(msg, e)
	}
	this.proc = nil
}

func (this *Listener) run() {
	go this.trap()

listenerloop:
	for {
		if this.sig != nil {
			os.Exit(0)
		}
		Config.Load()
		job, e := this.jobqueue.Next()
		if e != nil {
			if strings.Contains(e.Error(), "TIMED_OUT") {
				time.Sleep(time.Second)
				goto listenerloop
			}
			log.Fatal(e)
		}
		if this.verbose {
			log.Printf("RUNNING: %s", job.Body)
		}
		msg := make(map[string]string)
		json.Unmarshal([]byte(job.Body), &msg)
		this.execute(msg)
		e = this.jobqueue.Delete(job.Id)
		if e != nil {
			this.catch(msg, e)
		}
	}
}

// Log and email errors
func (this *Listener) catch(msg map[string]string, e error) {
	log.Printf("ERROR: %s\n", e.Error())
	this.mail(msg, e)
	this.publishError(msg, e)
}

func (this *Listener) publishError(msg map[string]string, e error) {
	err := this.q.Use(Config.errorQueue)
	if err != nil {
		log.Printf("ERROR: %s\n", err)
		return
	}
	msg["error"] = e.Error()
	msg["log"] = this.readLog(msg)
	payload, err := json.Marshal(msg)
	if err != nil {
		log.Printf("ERROR: %s\n", err)
		return
	}
	_, err = this.q.Put(0, 0, 60*60, payload)
	if err != nil {
		log.Printf("ERROR: %s\n", err)
	}
}

func (this *Listener) readLog(msg map[string]string) string {
	content := make([]byte, 0)
	info, err := os.Stat(msg["out"])
	if err != nil {
		content = []byte(fmt.Sprintf("Could not read job log from [%s]. %s", msg["out"], err.Error()))
		return string(content)
	}
	if info.Size() > 104857 {
		content = []byte(fmt.Sprintf("Could send job log [%s]. File too big", msg["out"]))
	} else {
		content, err = ioutil.ReadFile(msg["out"])
		if err != nil {
			content = []byte(fmt.Sprintf("Could not read job log from [%s]", msg["out"]))
		}
	}
	return string(content)

}

func (this *Listener) mail(msg map[string]string, e error) {
	if Config.SmtpServerAddr == "" {
		return
	}
	if len(msg["mailto"]) < 1 { //no email addresses
		return
	}
	to := strings.Split(msg["mailto"], ",")
	subject := fmt.Sprintf("Subject: FAILED: %s\r\n\r\n", msg["cmd"])
	hostname, _ := os.Hostname()
	content := []byte(this.readLog(msg))
	mail := fmt.Sprintf("%s%s", subject, fmt.Sprintf("Ran on [%s]\n%s\n%s\n%s", hostname, subject, e, content))
	e = smtp.SendMail(Config.SmtpServerAddr, nil, Config.MailFrom, to, []byte(mail))
	if e != nil {
		log.Printf("ERROR: %s\n", e)
	}
}

// Wait for currently running job to finish before exiting on SIGTERM and SIGINT
func (this *Listener) trap() {
	receivedSignal := make(chan os.Signal)
	signal.Notify(receivedSignal, syscall.SIGTERM, syscall.SIGINT)
	this.sig = <-receivedSignal
	if this.sig.String() == syscall.SIGTERM.String() {
		log.Printf("Got signal %d. Killing current job.", this.sig)
		if this.proc != nil {
			this.proc.Kill()
		}
		os.Exit(1)
	}
	log.Printf("Got signal %d. Waiting for current job to complete. sig term is [%v]", this.sig, syscall.SIGTERM)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"image"
	"image/png"
	"io/ioutil"
	"log"
	"os"
)

// App Icon
type AppIconItem struct {
	Size     string `json:"size"`
	Idiom    string `json:"idiom"`
	Filename string `json:"filename"`
	Scale    string `json:"scale"`

	image image.Image
}

type AppIconContents struct {
	Images []AppIconItem `json:"images"`
	Info   struct {
		Version int    `json:"version"`
		Author  string `json:"author"`
	}
}

func (icon AppIconContents) Save(dir string) {
	// Create a path
	sep := string(os.PathSeparator)
	path := fmt.Sprintf("%s%sImages.xcassets%sAppIcon.appiconset", dir, sep, sep)

	// Make a folder called Images.xcassets
	err := os.MkdirAll(path, 0777)
	if err != nil {
		log.Fatal(err)
	}

	// Copy all the images
	for _, image_info := range icon.Images {
		if image_info.image != nil {
			new_path := fmt.Sprintf("%s%s%s", path, sep, image_info.Filename)
			out, err := os.Create(new_path)
			if err != nil {
				log.Print(err)
			}
			defer out.Close()
			png.Encode(out, image_info.image)
		}
	}

	// Copy contents.json
	contents_file_path := fmt.Sprintf("%s%sContents.json", path, sep)
	data, err := json.Marshal(icon)
	ioutil.WriteFile(contents_file_path, data, 0644)
}
<commit_msg>Pretty print contents.json file<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"image"
	"image/png"
	"io/ioutil"
	"log"
	"os"
)

// App Icon
type AppIconItem struct {
	Size     string `json:"size"`
	Idiom    string `json:"idiom"`
	Filename string `json:"filename"`
	Scale    string `json:"scale"`

	image image.Image
}

type AppIconContents struct {
	Images []AppIconItem `json:"images"`
	Info   struct {
		Version int    `json:"version"`
		Author  string `json:"author"`
	}
}

func (icon AppIconContents) Save(dir string) {
	// Create a path
	sep := string(os.PathSeparator)
	path := fmt.Sprintf("%s%sImages.xcassets%sAppIcon.appiconset", dir, sep, sep)

	// Make a folder called Images.xcassets
	err := os.MkdirAll(path, 0777)
	if err != nil {
		log.Fatal(err)
	}

	// Copy all the images
	for _, image_info := range icon.Images {
		if image_info.image != nil {
			new_path := fmt.Sprintf("%s%s%s", path, sep, image_info.Filename)
			out, err := os.Create(new_path)
			if err != nil {
				log.Print(err)
			}
			defer out.Close()
			png.Encode(out, image_info.image)
		}
	}

	// Copy contents.json
	contents_file_path := fmt.Sprintf("%s%sContents.json", path, sep)
	data, err := json.Marshal(icon)

	var out bytes.Buffer
	json.Indent(&out, []byte(data), "", "  ")

	ioutil.WriteFile(contents_file_path, out.Bytes(), 0644)
}
<|endoftext|>


<commit_before>package types

// block.go defines the Block type for Sia, and provides some helper functions
// for working with blocks.

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/encoding"
)

const (
	// BlockHeaderSize is the size, in bytes, of a block header.
	// 32 (ParentID) + 8 (Nonce) + 8 (Timestamp) + 32 (MerkleRoot)
	BlockHeaderSize = 80
)

type (
	// A Block is a summary of changes to the state that have occurred since the
	// previous block. Blocks reference the ID of the previous block (their
	// "parent"), creating the linked-list commonly known as the blockchain. Their
	// primary function is to bundle together transactions on the network. Blocks
	// are created by "miners," who collect transactions from other nodes, and
	// then try to pick a Nonce that results in a block whose BlockID is below a
	// given Target.
	Block struct {
		ParentID     BlockID         `json:"parentid"`
		Nonce        BlockNonce      `json:"nonce"`
		Timestamp    Timestamp       `json:"timestamp"`
		MinerPayouts []SiacoinOutput `json:"minerpayouts"`
		Transactions []Transaction   `json:"transactions"`
	}

	// A BlockHeader, when encoded, is an 80-byte constant size field
	// containing enough information to do headers-first block downloading.
	// Hashing the header results in the block ID.
	BlockHeader struct {
		ParentID   BlockID     `json:"parentid"`
		Nonce      BlockNonce  `json:"nonce"`
		Timestamp  Timestamp   `json:"timestamp"`
		MerkleRoot crypto.Hash `json:"merkleroot"`
	}

	BlockHeight uint64
	BlockID     crypto.Hash
	BlockNonce  [8]byte
)

// CalculateCoinbase calculates the coinbase for a given height. The coinbase
// equation is:
//
//     coinbase := max(InitialCoinbase - height, MinimumCoinbase) * SiacoinPrecision
func CalculateCoinbase(height BlockHeight) Currency {
	base := InitialCoinbase - uint64(height)
	if uint64(height) > InitialCoinbase || base < MinimumCoinbase {
		base = MinimumCoinbase
	}
	return NewCurrency64(base).Mul(SiacoinPrecision)
}

// CalculateNumSiacoins calculates the number of siacoins in circulation at a
// given height.
func CalculateNumSiacoins(height BlockHeight) Currency {
	deflationBlocks := BlockHeight(InitialCoinbase - MinimumCoinbase)
	avgDeflationSiacoins := CalculateCoinbase(0).Add(CalculateCoinbase(height)).Div(NewCurrency64(2))
	if height <= deflationBlocks {
		deflationSiacoins := avgDeflationSiacoins.Mul(NewCurrency64(uint64(height + 1)))
		return deflationSiacoins
	}
	deflationSiacoins := avgDeflationSiacoins.Mul(NewCurrency64(uint64(deflationBlocks + 1)))
	trailingSiacoins := NewCurrency64(uint64(height - deflationBlocks)).Mul(CalculateCoinbase(height))
	return deflationSiacoins.Add(trailingSiacoins)
}

// ID returns the ID of a Block, which is calculated by hashing the header.
func (h BlockHeader) ID() BlockID {
	return BlockID(crypto.HashObject(h))
}

// CalculateSubsidy takes a block and a height and determines the block
// subsidy.
func (b Block) CalculateSubsidy(height BlockHeight) Currency {
	subsidy := CalculateCoinbase(height)
	for _, txn := range b.Transactions {
		for _, fee := range txn.MinerFees {
			subsidy = subsidy.Add(fee)
		}
	}
	return subsidy
}

// Header returns the header of a block.
func (b Block) Header() BlockHeader {
	return BlockHeader{
		ParentID:   b.ParentID,
		Nonce:      b.Nonce,
		Timestamp:  b.Timestamp,
		MerkleRoot: b.MerkleRoot(),
	}
}

// ID returns the ID of a Block, which is calculated by hashing the
// concatenation of the block's parent's ID, nonce, and the result of the
// b.MerkleRoot(). It is equivalent to calling block.Header().ID()
func (b Block) ID() BlockID {
	return b.Header().ID()
}

// MerkleRoot calculates the Merkle root of a Block. The leaves of the Merkle
// tree are composed of the Timestamp, the miner outputs (one leaf per
// payout), and the transactions (one leaf per transaction).
func (b Block) MerkleRoot() crypto.Hash {
	tree := crypto.NewTree()
	for _, payout := range b.MinerPayouts {
		tree.PushObject(payout)
	}
	for _, txn := range b.Transactions {
		tree.PushObject(txn)
	}
	return tree.Root()
}

// MinerPayoutID returns the ID of the miner payout at the given index, which
// is calculated by hashing the concatenation of the BlockID and the payout
// index.
func (b Block) MinerPayoutID(i uint64) SiacoinOutputID {
	return SiacoinOutputID(crypto.HashAll(
		b.ID(),
		i,
	))
}

// MarshalSia implements the encoding.SiaMarshaler interface.
func (b Block) MarshalSia(w io.Writer) error {
	w.Write(b.ParentID[:])
	w.Write(b.Nonce[:])
	w.Write(encoding.EncUint64(uint64(b.Timestamp)))
	return encoding.NewEncoder(w).EncodeAll(b.MinerPayouts, b.Transactions)
}

// UnmarshalSia implements the encoding.SiaUnmarshaler interface.
func (b *Block) UnmarshalSia(r io.Reader) error {
	io.ReadFull(r, b.ParentID[:])
	io.ReadFull(r, b.Nonce[:])
	tsBytes := make([]byte, 8)
	io.ReadFull(r, tsBytes)
	b.Timestamp = Timestamp(encoding.DecUint64(tsBytes))
	return encoding.NewDecoder(r).DecodeAll(&b.MinerPayouts, &b.Transactions)
}

// MarshalJSON marshales a block id as a hex string.
func (bid BlockID) MarshalJSON() ([]byte, error) {
	return json.Marshal(bid.String())
}

// String prints the block id in hex.
func (bid BlockID) String() string {
	return fmt.Sprintf("%x", bid[:])
}

// UnmarshalJSON decodes the json hex string of the block id.
func (bid *BlockID) UnmarshalJSON(b []byte) error {
	if len(b) != crypto.HashSize*2+2 {
		return crypto.ErrHashWrongLen
	}

	var bidBytes []byte
	_, err := fmt.Sscanf(string(b[1:len(b)-1]), "%x", &bidBytes)
	if err != nil {
		return errors.New("could not unmarshal BlockID: " + err.Error())
	}
	copy(bid[:], bidBytes)
	return nil
}
<commit_msg>Fix types.Block.MerkleRoot() docstring<commit_after>package types

// block.go defines the Block type for Sia, and provides some helper functions
// for working with blocks.

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/encoding"
)

const (
	// BlockHeaderSize is the size, in bytes, of a block header.
	// 32 (ParentID) + 8 (Nonce) + 8 (Timestamp) + 32 (MerkleRoot)
	BlockHeaderSize = 80
)

type (
	// A Block is a summary of changes to the state that have occurred since the
	// previous block. Blocks reference the ID of the previous block (their
	// "parent"), creating the linked-list commonly known as the blockchain. Their
	// primary function is to bundle together transactions on the network. Blocks
	// are created by "miners," who collect transactions from other nodes, and
	// then try to pick a Nonce that results in a block whose BlockID is below a
	// given Target.
	Block struct {
		ParentID     BlockID         `json:"parentid"`
		Nonce        BlockNonce      `json:"nonce"`
		Timestamp    Timestamp       `json:"timestamp"`
		MinerPayouts []SiacoinOutput `json:"minerpayouts"`
		Transactions []Transaction   `json:"transactions"`
	}

	// A BlockHeader, when encoded, is an 80-byte constant size field
	// containing enough information to do headers-first block downloading.
	// Hashing the header results in the block ID.
	BlockHeader struct {
		ParentID   BlockID     `json:"parentid"`
		Nonce      BlockNonce  `json:"nonce"`
		Timestamp  Timestamp   `json:"timestamp"`
		MerkleRoot crypto.Hash `json:"merkleroot"`
	}

	BlockHeight uint64
	BlockID     crypto.Hash
	BlockNonce  [8]byte
)

// CalculateCoinbase calculates the coinbase for a given height. The coinbase
// equation is:
//
//     coinbase := max(InitialCoinbase - height, MinimumCoinbase) * SiacoinPrecision
func CalculateCoinbase(height BlockHeight) Currency {
	base := InitialCoinbase - uint64(height)
	if uint64(height) > InitialCoinbase || base < MinimumCoinbase {
		base = MinimumCoinbase
	}
	return NewCurrency64(base).Mul(SiacoinPrecision)
}

// CalculateNumSiacoins calculates the number of siacoins in circulation at a
// given height.
func CalculateNumSiacoins(height BlockHeight) Currency {
	deflationBlocks := BlockHeight(InitialCoinbase - MinimumCoinbase)
	avgDeflationSiacoins := CalculateCoinbase(0).Add(CalculateCoinbase(height)).Div(NewCurrency64(2))
	if height <= deflationBlocks {
		deflationSiacoins := avgDeflationSiacoins.Mul(NewCurrency64(uint64(height + 1)))
		return deflationSiacoins
	}
	deflationSiacoins := avgDeflationSiacoins.Mul(NewCurrency64(uint64(deflationBlocks + 1)))
	trailingSiacoins := NewCurrency64(uint64(height - deflationBlocks)).Mul(CalculateCoinbase(height))
	return deflationSiacoins.Add(trailingSiacoins)
}

// ID returns the ID of a Block, which is calculated by hashing the header.
func (h BlockHeader) ID() BlockID {
	return BlockID(crypto.HashObject(h))
}

// CalculateSubsidy takes a block and a height and determines the block
// subsidy.
func (b Block) CalculateSubsidy(height BlockHeight) Currency {
	subsidy := CalculateCoinbase(height)
	for _, txn := range b.Transactions {
		for _, fee := range txn.MinerFees {
			subsidy = subsidy.Add(fee)
		}
	}
	return subsidy
}

// Header returns the header of a block.
func (b Block) Header() BlockHeader {
	return BlockHeader{
		ParentID:   b.ParentID,
		Nonce:      b.Nonce,
		Timestamp:  b.Timestamp,
		MerkleRoot: b.MerkleRoot(),
	}
}

// ID returns the ID of a Block, which is calculated by hashing the
// concatenation of the block's parent's ID, nonce, and the result of the
// b.MerkleRoot(). It is equivalent to calling block.Header().ID()
func (b Block) ID() BlockID {
	return b.Header().ID()
}

// MerkleRoot calculates the Merkle root of a Block. The leaves of the Merkle
// tree are composed of the miner outputs (one leaf per payout), and the
// transactions (one leaf per transaction).
func (b Block) MerkleRoot() crypto.Hash {
	tree := crypto.NewTree()
	for _, payout := range b.MinerPayouts {
		tree.PushObject(payout)
	}
	for _, txn := range b.Transactions {
		tree.PushObject(txn)
	}
	return tree.Root()
}

// MinerPayoutID returns the ID of the miner payout at the given index, which
// is calculated by hashing the concatenation of the BlockID and the payout
// index.
func (b Block) MinerPayoutID(i uint64) SiacoinOutputID {
	return SiacoinOutputID(crypto.HashAll(
		b.ID(),
		i,
	))
}

// MarshalSia implements the encoding.SiaMarshaler interface.
func (b Block) MarshalSia(w io.Writer) error {
	w.Write(b.ParentID[:])
	w.Write(b.Nonce[:])
	w.Write(encoding.EncUint64(uint64(b.Timestamp)))
	return encoding.NewEncoder(w).EncodeAll(b.MinerPayouts, b.Transactions)
}

// UnmarshalSia implements the encoding.SiaUnmarshaler interface.
func (b *Block) UnmarshalSia(r io.Reader) error {
	io.ReadFull(r, b.ParentID[:])
	io.ReadFull(r, b.Nonce[:])
	tsBytes := make([]byte, 8)
	io.ReadFull(r, tsBytes)
	b.Timestamp = Timestamp(encoding.DecUint64(tsBytes))
	return encoding.NewDecoder(r).DecodeAll(&b.MinerPayouts, &b.Transactions)
}

// MarshalJSON marshales a block id as a hex string.
func (bid BlockID) MarshalJSON() ([]byte, error) {
	return json.Marshal(bid.String())
}

// String prints the block id in hex.
func (bid BlockID) String() string {
	return fmt.Sprintf("%x", bid[:])
}

// UnmarshalJSON decodes the json hex string of the block id.
func (bid *BlockID) UnmarshalJSON(b []byte) error {
	if len(b) != crypto.HashSize*2+2 {
		return crypto.ErrHashWrongLen
	}

	var bidBytes []byte
	_, err := fmt.Sscanf(string(b[1:len(b)-1]), "%x", &bidBytes)
	if err != nil {
		return errors.New("could not unmarshal BlockID: " + err.Error())
	}
	copy(bid[:], bidBytes)
	return nil
}
<|endoftext|>


<commit_before>// +build linux

package firewall

import (
	"fmt"
	"github.com/flexiant/concerto/utils"
)

func driverName() string {
	return "iptables"
}

func apply(policy Policy) error {
	utils.RunCmd("/sbin/iptables -w -N CONCERTO")
	utils.RunCmd("/sbin/iptables -w -F CONCERTO")
	utils.RunCmd("/sbin/iptables -w -P INPUT DROP")

	_, exitCode, _, _ := utils.RunCmd("/sbin/iptables -w -C INPUT -i lo -j ACCEPT")
	if exitCode != 0 {
		utils.RunCmd("/sbin/iptables -w -A INPUT -i lo -j ACCEPT")
	}

	_, exitCode, _, _ := utils.RunCmd("/sbin/iptables -w -C INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT")
	if exitCode != 0 {
		utils.RunCmd("/sbin/iptables -w -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT")
	}

	for _, rule := range policy.Rules {
		utils.RunCmd(fmt.Sprintf("/sbin/iptables -w -A CONCERTO -s %s -p %s --dport %d:%d -j ACCEPT", rule.Cidr, rule.Protocol, rule.MinPort, rule.MaxPort))
	}

	_, exitCode, _, _ := utils.RunCmd("/sbin/iptables -w -C INPUT -j CONCERTO")
	if exitCode != 0 {
		utils.RunCmd("/sbin/iptables -w -A INPUT -j CONCERTO")
	}

	return nil
}

func flush() error {
	utils.RunCmd("/sbin/iptables -w -P INPUT ACCEPT")
	utils.RunCmd("/sbin/iptables -w -F CONCERTO")
	utils.RunCmd("/sbin/iptables -w -X CONCERTO")
	return nil
}
<commit_msg>Minor modification to Iptables<commit_after>// +build linux

package firewall

import (
	"fmt"
	"github.com/flexiant/concerto/utils"
)

func driverName() string {
	return "iptables"
}

func apply(policy Policy) error {
	var exitCode int
	utils.RunCmd("/sbin/iptables -w -N CONCERTO")
	utils.RunCmd("/sbin/iptables -w -F CONCERTO")
	utils.RunCmd("/sbin/iptables -w -P INPUT DROP")

	_, exitCode, _, _ = utils.RunCmd("/sbin/iptables -w -C INPUT -i lo -j ACCEPT")
	if exitCode != 0 {
		utils.RunCmd("/sbin/iptables -w -A INPUT -i lo -j ACCEPT")
	}

	_, exitCode, _, _ = utils.RunCmd("/sbin/iptables -w -C INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT")
	if exitCode != 0 {
		utils.RunCmd("/sbin/iptables -w -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT")
	}

	for _, rule := range policy.Rules {
		utils.RunCmd(fmt.Sprintf("/sbin/iptables -w -A CONCERTO -s %s -p %s --dport %d:%d -j ACCEPT", rule.Cidr, rule.Protocol, rule.MinPort, rule.MaxPort))
	}

	_, exitCode, _, _ = utils.RunCmd("/sbin/iptables -w -C INPUT -j CONCERTO")
	if exitCode != 0 {
		utils.RunCmd("/sbin/iptables -w -A INPUT -j CONCERTO")
	}

	return nil
}

func flush() error {
	utils.RunCmd("/sbin/iptables -w -P INPUT ACCEPT")
	utils.RunCmd("/sbin/iptables -w -F CONCERTO")
	utils.RunCmd("/sbin/iptables -w -X CONCERTO")
	return nil
}
<|endoftext|>


<commit_before>package switchboard

import (
	"sync"

	"github.com/pivotal-golang/lager"
)

type Backends interface {
	All() <-chan Backend
	Any() Backend
	Active() Backend
	SetHealthy(backend Backend)
	SetUnhealthy(backend Backend)
	Healthy() <-chan Backend
	ActivityChannels() (<-chan struct{}, <-chan struct{})
}

type backends struct {
	mutex        sync.RWMutex
	all          map[Backend]bool
	active       Backend
	logger       lager.Logger
	activeChan   chan struct{}
	inactiveChan chan struct{}
}

func NewBackends(backendIPs []string, backendPorts []uint, healthcheckPorts []uint, logger lager.Logger) Backends {
	b := &backends{
		logger:       logger,
		all:          make(map[Backend]bool),
		activeChan:   make(chan struct{}),
		inactiveChan: make(chan struct{}, 1),
	}

	for i, ip := range backendIPs {
		backend := NewBackend(
			ip,
			backendPorts[i],
			healthcheckPorts[i],
			logger,
		)

		b.all[backend] = true
	}

	if len(b.all) > 0 {
		b.active = b.unsafeNextHealthy()
	} else {
		select {
		case b.inactiveChan <- struct{}{}:
		default:
		}
	}

	return b
}

func (b *backends) ActivityChannels() (<-chan struct{}, <-chan struct{}) {
	return b.activeChan, b.inactiveChan
}

// Maintains a lock while iterating over all backends
func (b *backends) All() <-chan Backend {
	ch := make(chan Backend, len(b.all))

	go func() {
		b.mutex.RLock()
		defer b.mutex.RUnlock()

		for backend := range b.all {
			ch <- backend
		}
		close(ch)
	}()

	return ch
}

// Maintains a lock while iterating over healthy backends
func (b *backends) Healthy() <-chan Backend {
	c := make(chan Backend, len(b.all))

	go func() {
		b.mutex.RLock()
		defer b.mutex.RUnlock()

		for backend, healthy := range b.all {
			if healthy {
				c <- backend
			}
		}

		close(c)
	}()

	return c
}

func (b *backends) Any() Backend {
	b.mutex.RLock()
	defer b.mutex.RUnlock()

	for backend := range b.all {
		return backend
	}

	return nil
}

func (b *backends) Active() Backend {
	b.mutex.Lock()
	defer b.mutex.Unlock()

	return b.active
}

func (b *backends) SetHealthy(backend Backend) {
	b.mutex.Lock()
	defer b.mutex.Unlock()
	knownBackend := b.unsafeSetHealth(backend, true)
	b.logger.Info("Backend became healthy again.")
	if b.active == nil {
		b.active = knownBackend
		if b.active != nil {
			b.logger.Info("Recovering from down cluster, new active backend...")
			select {
			case b.activeChan <- struct{}{}:
			default:
			}
		}
	}
}

func (b *backends) SetUnhealthy(backend Backend) {
	b.mutex.Lock()
	defer b.mutex.Unlock()
	knownBackend := b.unsafeSetHealth(backend, false)
	if b.active == knownBackend {
		b.active = b.unsafeNextHealthy()
		b.logger.Info("Active backend became unhealthy. Switching over to next available...")
		if b.active == nil {
			b.logger.Info("All backends unhealthy! No currently active backend.")
			select {
			case b.inactiveChan <- struct{}{}:
			default:
			}
		} else {
			b.logger.Info("Successfully failed over to next available backend!")
		}
	}
}

func (b *backends) unsafeNextHealthy() Backend {
	for backend, healthy := range b.all {
		if healthy {
			return backend
		}
	}
	return nil
}

func (b *backends) unsafeSetHealth(backend Backend, healthy bool) Backend {
	_, found := b.all[backend]
	if found {
		b.all[backend] = healthy
		return backend
	}
	return nil
}
<commit_msg>Avoid race by locking before reading len(b.all)<commit_after>package switchboard

import (
	"sync"

	"github.com/pivotal-golang/lager"
)

type Backends interface {
	All() <-chan Backend
	Any() Backend
	Active() Backend
	SetHealthy(backend Backend)
	SetUnhealthy(backend Backend)
	Healthy() <-chan Backend
	ActivityChannels() (<-chan struct{}, <-chan struct{})
}

type backends struct {
	mutex        sync.RWMutex
	all          map[Backend]bool
	active       Backend
	logger       lager.Logger
	activeChan   chan struct{}
	inactiveChan chan struct{}
}

func NewBackends(backendIPs []string, backendPorts []uint, healthcheckPorts []uint, logger lager.Logger) Backends {
	b := &backends{
		logger:       logger,
		all:          make(map[Backend]bool),
		activeChan:   make(chan struct{}),
		inactiveChan: make(chan struct{}, 1),
	}

	for i, ip := range backendIPs {
		backend := NewBackend(
			ip,
			backendPorts[i],
			healthcheckPorts[i],
			logger,
		)

		b.all[backend] = true
	}

	if len(b.all) > 0 {
		b.active = b.unsafeNextHealthy()
	} else {
		select {
		case b.inactiveChan <- struct{}{}:
		default:
		}
	}

	return b
}

func (b *backends) ActivityChannels() (<-chan struct{}, <-chan struct{}) {
	return b.activeChan, b.inactiveChan
}

// Maintains a lock while iterating over all backends
func (b *backends) All() <-chan Backend {
	b.mutex.RLock()

	ch := make(chan Backend, len(b.all))
	go func() {
		defer b.mutex.RUnlock()

		for backend := range b.all {
			ch <- backend
		}
		close(ch)
	}()

	return ch
}

// Maintains a lock while iterating over healthy backends
func (b *backends) Healthy() <-chan Backend {
	b.mutex.RLock()

	c := make(chan Backend, len(b.all))
	go func() {
		defer b.mutex.RUnlock()

		for backend, healthy := range b.all {
			if healthy {
				c <- backend
			}
		}

		close(c)
	}()

	return c
}

func (b *backends) Any() Backend {
	b.mutex.RLock()
	defer b.mutex.RUnlock()

	for backend := range b.all {
		return backend
	}

	return nil
}

func (b *backends) Active() Backend {
	b.mutex.Lock()
	defer b.mutex.Unlock()

	return b.active
}

func (b *backends) SetHealthy(backend Backend) {
	b.mutex.Lock()
	defer b.mutex.Unlock()
	knownBackend := b.unsafeSetHealth(backend, true)
	b.logger.Info("Backend became healthy again.")
	if b.active == nil {
		b.active = knownBackend
		if b.active != nil {
			b.logger.Info("Recovering from down cluster, new active backend...")
			select {
			case b.activeChan <- struct{}{}:
			default:
			}
		}
	}
}

func (b *backends) SetUnhealthy(backend Backend) {
	b.mutex.Lock()
	defer b.mutex.Unlock()
	knownBackend := b.unsafeSetHealth(backend, false)
	if b.active == knownBackend {
		b.active = b.unsafeNextHealthy()
		b.logger.Info("Active backend became unhealthy. Switching over to next available...")
		if b.active == nil {
			b.logger.Info("All backends unhealthy! No currently active backend.")
			select {
			case b.inactiveChan <- struct{}{}:
			default:
			}
		} else {
			b.logger.Info("Successfully failed over to next available backend!")
		}
	}
}

func (b *backends) unsafeNextHealthy() Backend {
	for backend, healthy := range b.all {
		if healthy {
			return backend
		}
	}
	return nil
}

func (b *backends) unsafeSetHealth(backend Backend, healthy bool) Backend {
	_, found := b.all[backend]
	if found {
		b.all[backend] = healthy
		return backend
	}
	return nil
}
<|endoftext|>


<commit_before>package test

import (
	//"libxml"
	"gokogiri/libxml/help"
	"gokogiri/libxml/tree"
	"testing"
	"io/ioutil"
)

func TestEncodingRead(t *testing.T) {
	docContent, err := ioutil.ReadFile("htmldata/google-cn.html")
	if err != nil {
		t.Errorf("Err: %v", err.String())
	}
	doc := tree.HtmlParseString(string(docContent), "utf8")
	root := doc.RootElement()
	head := root.FirstElement()
	body := head.Next()
	title := head.First().Next().Content()
	licenseCode := body.First().Next().Next().Next().First().Next().Content()

	if title != "Google" {
		t.Errorf("the English string does not match")
	}

	if licenseCode != "ICP证合字B2-20070004号" {
		t.Errorf("the English & Chinese string does not match")
	}
	doc.Free()
	help.XmlCleanUpParser()
	if help.XmlMemoryAllocation() != 0 {
		t.Errorf("Memeory leaks %d!!!", help.XmlMemoryAllocation())
		help.XmlMemoryLeakReport()
	}
}

func TestEncodingSetContent(t *testing.T) {
	docContent, err := ioutil.ReadFile("htmldata/google-cn.html")
	if err != nil {
		t.Errorf("Err: %v", err.String())
	}
	doc := tree.HtmlParseString(string(docContent), "utf8")
	root := doc.RootElement()
	head := root.FirstElement()
	body := head.Next()
	title := head.First().Next().Content()
	licenseCode := body.First().Next().Next().Next().First().Next().Content()

	if title != "Google" {
		t.Errorf("the English string does not match")
	}

	if licenseCode != "ICP证合字B2-20070004号" {
		t.Errorf("the English & Chinese string does not match")
	}

	newStr := "你好，Moovweb"
	body.SetContent("
"+newStr+"
")
	newContent := body.First().Content()

	if newContent != newStr {
		t.Errorf("the new content of English and Chinese does not match after setting content")
	}

	doc.Free()
	help.XmlCleanUpParser()
	if help.XmlMemoryAllocation() != 0 {
		t.Errorf("Memeory leaks %d!!!", help.XmlMemoryAllocation())
		help.XmlMemoryLeakReport()
	}
}

func TestEncodingHTMLFragment(t *testing.T) {
	content, err := ioutil.ReadFile("htmldata/fragment.html")
	if err != nil {
		t.Errorf("Err: %v\n", err.String())
	}

	doc := tree.HtmlParseFragment(string(content), "utf-8") // vs "utf8" ?
	newContent := doc.RootElement()
	rawContent := newContent.Content()

	if rawContent != string(content) {
		t.Errorf("Result of HtmlParseFragment() : [%v]\ndoesn't match original content: [%v]", newContent, string(content))
	}
}

func TestEncodingAppendChild(t *testing.T) {
	// Within the tree.HtmlParseFragment() method, using just an xml doc or just an html doc works,
	// but appending the html nodes to the xml doc breaks encoding somehow.

	content, err := ioutil.ReadFile("htmldata/fragment.html")
	if err != nil {
		t.Errorf("Err: %v\n", err.String())
	}

	controlXmlDoc := XmlParseString("<root>" + string(content) + "</root>", encoding)
	testXmlDoc := XmlParseString("<root></root>", encoding)

	htmlDoc := HtmlParseStringWithOptions(""+content, "", encoding, DefaultHtmlParseOptions())
	defer htmlDoc.Free()

	tmpNode := htmlDoc.RootElement().First()
	if strings.Index(strings.ToLower(content), "<body") < 0 {
		tmpNode = tmpNode.First()
	}

	//append all children of tmpRoot to root.
	root := testXmlDoc.RootElement()
	child := tmpNode

	for child != nil {
		nextChild := child.Next()
		root.AppendChildNode(child)
		child = nextChild
	}

	// Now compare the differences:

	testXmlContent := testXmlDoc.RootElement().Content()
	controlXmlContent := controlXmlDoc.RootElement().Content()

	if testXmlContent != controlXmlContent {
		t.Errorf("Result of appending children messed up the encoding.\nPure xml: [%v]\nXml w appended nodes:[%v]\n", controlXmlContent, testXmlContent)
	}

	if string(content) != testXmlContent {
		t.Errorf("Result of Appending children : [%v]\ndoesn't match original content: [%v]", testXmlContent, string(content))
	}

}
<commit_msg>clean up the test a bit. the test not passing<commit_after>package test

import (
	//"libxml"
	"gokogiri/libxml/help"
	"gokogiri/libxml/tree"
	"testing"
	"io/ioutil"
	//"strings"
)

func TestEncodingRead(t *testing.T) {
	docContent, err := ioutil.ReadFile("htmldata/google-cn.html")
	if err != nil {
		t.Errorf("Err: %v", err.String())
	}
	doc := tree.HtmlParseString(string(docContent), "utf8")
	root := doc.RootElement()
	head := root.FirstElement()
	body := head.Next()
	title := head.First().Next().Content()
	licenseCode := body.First().Next().Next().Next().First().Next().Content()

	if title != "Google" {
		t.Errorf("the English string does not match")
	}

	if licenseCode != "ICP证合字B2-20070004号" {
		t.Errorf("the English & Chinese string does not match")
	}
	doc.Free()
	help.XmlCleanUpParser()
	if help.XmlMemoryAllocation() != 0 {
		t.Errorf("Memeory leaks %d!!!", help.XmlMemoryAllocation())
		help.XmlMemoryLeakReport()
	}
}

func TestEncodingSetContent(t *testing.T) {
	docContent, err := ioutil.ReadFile("htmldata/google-cn.html")
	if err != nil {
		t.Errorf("Err: %v", err.String())
	}
	doc := tree.HtmlParseString(string(docContent), "utf8")
	root := doc.RootElement()
	head := root.FirstElement()
	body := head.Next()
	title := head.First().Next().Content()
	licenseCode := body.First().Next().Next().Next().First().Next().Content()

	if title != "Google" {
		t.Errorf("the English string does not match")
	}

	if licenseCode != "ICP证合字B2-20070004号" {
		t.Errorf("the English & Chinese string does not match")
	}

	newStr := "你好，Moovweb"
	body.SetContent("
"+newStr+"
")
	newContent := body.First().Content()

	if newContent != newStr {
		t.Errorf("the new content of English and Chinese does not match after setting content")
	}

	doc.Free()
	help.XmlCleanUpParser()
	if help.XmlMemoryAllocation() != 0 {
		t.Errorf("Memeory leaks %d!!!", help.XmlMemoryAllocation())
		help.XmlMemoryLeakReport()
	}
}

func TestEncodingHTMLFragment(t *testing.T) {
	content, err := ioutil.ReadFile("htmldata/fragment.html")
	if err != nil {
		t.Errorf("Err: %v\n", err.String())
	}

	doc := tree.HtmlParseFragment(string(content), "utf-8") // vs "utf8" ?
	newContent := doc.RootElement()
	rawContent := newContent.Content()

	if rawContent != string(content) {
		t.Errorf("Result of HtmlParseFragment() : [%v]\ndoesn't match original content: [%v]", newContent, string(content))
	}
	doc.Free()
	help.XmlCleanUpParser()
	if help.XmlMemoryAllocation() != 0 {
		t.Errorf("Memeory leaks %d!!!", help.XmlMemoryAllocation())
		help.XmlMemoryLeakReport()
	}
}

func TestEncodingAppendChild(t *testing.T) {
	// Within the tree.HtmlParseFragment() method, using just an xml doc or just an html doc works,
	// but appending the html nodes to the xml doc breaks encoding somehow.

	content, err := ioutil.ReadFile("htmldata/fragment.html")
	if err != nil {
		t.Errorf("Err: %v\n", err.String())
	}
	encoding := "utf-8"
	controlXmlDoc := tree.XmlParseString("<root>" + string(content) + "</root>", encoding)
	testXmlDoc := tree.XmlParseString("<root></root>", encoding)

	htmlDoc := tree.HtmlParseStringWithOptions(""+string(content), "", encoding, tree.DefaultHtmlParseOptions())
	/*
	tmpNode := htmlDoc.RootElement().First()
	if strings.Index(strings.ToLower(string(content)), "<body") < 0 {
		tmpNode = tmpNode.First()
	}

	//append all children of tmpRoot to root.
	root := testXmlDoc.RootElement()
	child := tmpNode

	for child != nil {
		nextChild := child.Next()
		root.AppendChildNode(child)
		child = nextChild
	}

	// Now compare the differences:

	testXmlContent := testXmlDoc.RootElement().Content()
	controlXmlContent := controlXmlDoc.RootElement().Content()

	if testXmlContent != controlXmlContent {
		t.Errorf("Result of appending children messed up the encoding.\nPure xml: [%v]\nXml w appended nodes:[%v]\n", controlXmlContent, testXmlContent)
	}

	if string(content) != testXmlContent {
		t.Errorf("Result of Appending children : [%v]\ndoesn't match original content: [%v]", testXmlContent, string(content))
	}
	*/
	htmlDoc.Free()
	testXmlDoc.Free()
	controlXmlDoc.Free()
	help.XmlCleanUpParser()
	if help.XmlMemoryAllocation() != 0 {
		t.Errorf("Memeory leaks %d!!!", help.XmlMemoryAllocation())
		help.XmlMemoryLeakReport()
	}
}
<|endoftext|>