<commit_before>package main

import (
	"fmt"
	"time"
	"bytes"
	"os/exec"
)

//  only modeling the parts of the responses as I need them
type kubectlItem struct {
	Metadata	struct {
		Name 		string	`json:"name"`
		Uid		string	`json:"uid"`
	} 				`json:"metadata"`
	Spec	interface{}	`json:"spec"`
	Status	 struct {
		Replicas	int	`json:"replicas"`
	}				`json:"status"`
}

type kubectlService struct {
	Status		struct {
		LoadBalancer	struct {
			Ingress	[]struct {
				IP	string 	`json:"ip"`
			} 			`json:"ingress"`
		}				`json:"loadBalancer"`
	} 					`json:"status"`
}

func addExtraArgs(run_args []string, optional_args, env_args map[string]string) ([]string) {
	for k, v := range optional_args {
		run_args = append(run_args, "--" + k + "=" +v)
	}
	for k, v := range env_args {
		run_args = append(run_args, "--env=" + k + "=" + v)
	}

	return run_args
}

func CreateKubeRC(name, dockerImage, external_port string, optional_args, env_args map[string]string) (string, error) {
	kubectl_cmd := "kubectl"
	kubectl_run_args :=[]string{"run", name, "--image=" + dockerImage, "--output=json"}
	kubectl_run_args = addExtraArgs(kubectl_run_args, optional_args, env_args)
	run_replicacontroler := exec.Command(kubectl_cmd, kubectl_run_args...)
	var stdout, stderr bytes.Buffer
	run_replicacontroler.Stdout = &stdout
	run_replicacontroler.Stderr = &stderr
	err := run_replicacontroler.Run()
	if err != nil {
		return "", fmt.Errorf("Error creating replicacontroler named %q with error %q", name, stderr.String())
	}

	var runReturn kubectlItem
	err = parseJSON(&runReturn, stdout.String())
	if err != nil {
		return "", err
	}
	uid := runReturn.Metadata.Uid

	var ex_err error
	if external_port != "" {
		ex_err = expose_rc_externally(name, external_port)
	}

	return uid,ex_err
}

func expose_rc_externally(name, external_port string) (error) {
	expose_rc := exec.Command("kubectl", "expose", "rc", name, "--port=" + external_port, "--type=LoadBalancer", "--output=json")
	var stdout, stderr bytes.Buffer
	expose_rc.Stdout = &stdout
	expose_rc.Stderr = &stderr
	err := expose_rc.Run()
	if err != nil {
		return fmt.Errorf("Error creating external load balancer on a specific port: %q", stderr.String())
	}

	// wait at most 10 minutes for external ip to be set
	exip_set := false
	for i := 0; i < (10 * 6) && !exip_set; i++ {
		time.Sleep(10 * time.Second)
		exip, err := fetchExternalIp(name)
		if err != nil {
			return err
		}

		if exip != "" {
			exip_set = true
		}
	}

	return nil
}

//  calling function needs to handle if the read is successful but the rc is dead or has no replicas
func ReadKubeRC(name, external_port string) (int, string, error) {
	get_replicacontrolers := exec.Command("kubectl", "get", "rc", name, "--output=json")
	var stdout, stderr bytes.Buffer
	get_replicacontrolers.Stdout = &stdout
	get_replicacontrolers.Stderr = &stderr
	err := get_replicacontrolers.Run()
	if err != nil {
		return -1, "", fmt.Errorf("Error listing replica controlers: %q", stderr.String())
	}

	var getReturn kubectlItem
	err = parseJSON(&getReturn, stdout.String())
	if err != nil {
		return -1, "", err
	}

	var ex_err error
	var external_ip string
	if external_port != "" {
		external_ip, ex_err = fetchExternalIp(name)
	}
	return getReturn.Status.Replicas, external_ip, ex_err
}

func fetchExternalIp(name string) (string, error) {
	get_services := exec.Command("kubectl", "get", "services", name, "--output=json")
	var stdout, stderr bytes.Buffer
	get_services.Stdout = &stdout
	get_services.Stderr = &stderr
	err := get_services.Run()
	if err != nil {
		return "", fmt.Errorf("Error fetching services information for this cluster: %q", stderr.String())
	}

	var getReturn kubectlService
	err = parseJSON(&getReturn, stdout.String())
	if err != nil {
		return "", err
	}

	var ex_ip string
	if len(getReturn.Status.LoadBalancer.Ingress) != 0 {
		ex_ip = getReturn.Status.LoadBalancer.Ingress[0].IP
	}

	return ex_ip, nil
}

func DeleteKubeRC(name, external_port string) (error) {
	if external_port != "" {
		err := deleteLoadBalanacerService(name)
		if err != nil {
			return err
		}
	}
	delete_replicacontrolers := exec.Command("kubectl", "delete", "rc", name)
	var stdout, stderr bytes.Buffer
	delete_replicacontrolers.Stdout = &stdout
	delete_replicacontrolers.Stderr = &stderr
	err := delete_replicacontrolers.Run()
	if err != nil {
		return  fmt.Errorf("Error deleting replica controler: %q", stderr.String())
	}

	return nil
}

func deleteLoadBalanacerService(name string) (error) {
	delete_loadbalancer_service := exec.Command("kubectl", "delete", "svc", name)
	var stdout, stderr bytes.Buffer
	delete_loadbalancer_service.Stdout = &stdout
	delete_loadbalancer_service.Stderr = &stderr
	err := delete_loadbalancer_service.Run()
	if err != nil {
		return  fmt.Errorf("Error deleting service: %q", stderr.String())
	}

	return nil
}
<commit_msg>Update container_engine_replicacontroler.go<commit_after>package main

import (
	"fmt"
	"time"
	"bytes"
	"os/exec"
)

//  only modeling the parts of the responses as I need them
type kubectlItem struct {
	Metadata	struct {
		Name 		string	`json:"name"`
		Uid		string	`json:"uid"`
	} 				`json:"metadata"`
	Spec	interface{}	`json:"spec"`
	Status	 struct {
		Replicas	int	`json:"replicas"`
	}				`json:"status"`
}

type kubectlService struct {
	Status		struct {
		LoadBalancer	struct {
			Ingress	[]struct {
				IP	string 	`json:"ip"`
			} 			`json:"ingress"`
		}				`json:"loadBalancer"`
	} 					`json:"status"`
}

func addExtraArgs(run_args []string, optional_args, env_args map[string]string) ([]string) {
	for k, v := range optional_args {
		run_args = append(run_args, "--" + k + "=" +v)
	}
	for k, v := range env_args {
		run_args = append(run_args, "--env=" + k + "=" + v)
	}

	return run_args
}

func CreateKubeRC(name, dockerImage, external_port string, optional_args, env_args map[string]string) (string, error) {
	kubectl_cmd := "kubectl"
	kubectl_run_args :=[]string{"--verbosity=debug", "--quiet","run", name, "--image=" + dockerImage, "--output=json"}
	kubectl_run_args = addExtraArgs(kubectl_run_args, optional_args, env_args)
	run_replicacontroler := exec.Command(kubectl_cmd, kubectl_run_args...)
	var stdout, stderr bytes.Buffer
	run_replicacontroler.Stdout = &stdout
	run_replicacontroler.Stderr = &stderr
	err := run_replicacontroler.Run()
	if err != nil {
		return "", fmt.Errorf("Error creating replicacontroler named %q with error %q", name, stderr.String())
	}

	var runReturn kubectlItem
	err = parseJSON(&runReturn, stdout.String())
	if err != nil {
		return "", err
	}
	uid := runReturn.Metadata.Uid

	var ex_err error
	if external_port != "" {
		ex_err = expose_rc_externally(name, external_port)
	}

	return uid,ex_err
}

func expose_rc_externally(name, external_port string) (error) {
	expose_rc := exec.Command("kubectl", "expose", "rc", name, "--port=" + external_port, "--type=LoadBalancer", "--output=json")
	var stdout, stderr bytes.Buffer
	expose_rc.Stdout = &stdout
	expose_rc.Stderr = &stderr
	err := expose_rc.Run()
	if err != nil {
		return fmt.Errorf("Error creating external load balancer on a specific port: %q", stderr.String())
	}

	// wait at most 10 minutes for external ip to be set
	exip_set := false
	for i := 0; i < (10 * 6) && !exip_set; i++ {
		time.Sleep(10 * time.Second)
		exip, err := fetchExternalIp(name)
		if err != nil {
			return err
		}

		if exip != "" {
			exip_set = true
		}
	}

	return nil
}

//  calling function needs to handle if the read is successful but the rc is dead or has no replicas
func ReadKubeRC(name, external_port string) (int, string, error) {
	get_replicacontrolers := exec.Command("kubectl", "--verbosity=debug", "--quiet","get", "rc", name, "--output=json")
	var stdout, stderr bytes.Buffer
	get_replicacontrolers.Stdout = &stdout
	get_replicacontrolers.Stderr = &stderr
	err := get_replicacontrolers.Run()
	if err != nil {
		return -1, "", fmt.Errorf("Error listing replica controlers: %q", stderr.String())
	}

	var getReturn kubectlItem
	err = parseJSON(&getReturn, stdout.String())
	if err != nil {
		return -1, "", err
	}

	var ex_err error
	var external_ip string
	if external_port != "" {
		external_ip, ex_err = fetchExternalIp(name)
	}
	return getReturn.Status.Replicas, external_ip, ex_err
}

func fetchExternalIp(name string) (string, error) {
	get_services := exec.Command("kubectl", "get", "services", name, "--output=json")
	var stdout, stderr bytes.Buffer
	get_services.Stdout = &stdout
	get_services.Stderr = &stderr
	err := get_services.Run()
	if err != nil {
		return "", fmt.Errorf("Error fetching services information for this cluster: %q", stderr.String())
	}

	var getReturn kubectlService
	err = parseJSON(&getReturn, stdout.String())
	if err != nil {
		return "", err
	}

	var ex_ip string
	if len(getReturn.Status.LoadBalancer.Ingress) != 0 {
		ex_ip = getReturn.Status.LoadBalancer.Ingress[0].IP
	}

	return ex_ip, nil
}

func DeleteKubeRC(name, external_port string) (error) {
	if external_port != "" {
		err := deleteLoadBalanacerService(name)
		if err != nil {
			return err
		}
	}
	delete_replicacontrolers := exec.Command("kubectl", "delete", "rc", name)
	var stdout, stderr bytes.Buffer
	delete_replicacontrolers.Stdout = &stdout
	delete_replicacontrolers.Stderr = &stderr
	err := delete_replicacontrolers.Run()
	if err != nil {
		return  fmt.Errorf("Error deleting replica controler: %q", stderr.String())
	}

	return nil
}

func deleteLoadBalanacerService(name string) (error) {
	delete_loadbalancer_service := exec.Command("kubectl", "delete", "svc", name)
	var stdout, stderr bytes.Buffer
	delete_loadbalancer_service.Stdout = &stdout
	delete_loadbalancer_service.Stderr = &stderr
	err := delete_loadbalancer_service.Run()
	if err != nil {
		return  fmt.Errorf("Error deleting service: %q", stderr.String())
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2015 tsuru-autoscale authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package datasource

import (
	"encoding/json"
	"errors"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/tsuru/tsuru-autoscale/db"
	"gopkg.in/check.v1"
)

func Test(t *testing.T) { check.TestingT(t) }

type S struct {
	conn *db.Storage
}

func (s *S) SetUpSuite(c *check.C) {
	var err error
	s.conn, err = db.Conn()
	c.Assert(err, check.IsNil)
}

var _ = check.Suite(&S{})

type testHandler struct{}

func (h *testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	content := `{"name":"Paul"}`
	w.Write([]byte(content))
}

func (s *S) TestHttpDataSourceGet(c *check.C) {
	h := testHandler{}
	ts := httptest.NewServer(&h)
	defer ts.Close()
	ds := DataSource{Method: "POST", URL: ts.URL}
	type dataType struct {
		Name string
	}
	data := dataType{}
	result, err := ds.Get()
	c.Assert(err, check.IsNil)
	err = json.Unmarshal([]byte(result), &data)
	c.Assert(err, check.IsNil)
	c.Assert(data.Name, check.Equals, "Paul")
}

func (s *S) TestNew(c *check.C) {
	dsConfigTests := []struct {
		conf *DataSource
		err  error
	}{
		{&DataSource{URL: "http://tsuru.io", Method: "GET"}, nil},
		{&DataSource{URL: "http://tsuru.io"}, errors.New("datasource: method required")},
		{&DataSource{Method: ""}, errors.New("datasource: url required")},
	}
	for _, tt := range dsConfigTests {
		err := New(tt.conf)
		c.Check(err, check.DeepEquals, tt.err)
	}
}

func (s *S) TestGet(c *check.C) {
	ds := DataSource{
		Name: "xpto",
	}
	s.conn.DataSources().Insert(&ds)
	instance, err := Get(ds.Name)
	c.Assert(err, check.IsNil)
	c.Assert(instance, check.DeepEquals, &ds)

}
<commit_msg>fix datasource tests.<commit_after>// Copyright 2015 tsuru-autoscale authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package datasource

import (
	"encoding/json"
	"errors"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/tsuru/tsuru-autoscale/db"
	"gopkg.in/check.v1"
)

func Test(t *testing.T) { check.TestingT(t) }

type S struct {
	conn *db.Storage
}

func (s *S) SetUpSuite(c *check.C) {
	var err error
	s.conn, err = db.Conn()
	c.Assert(err, check.IsNil)
}

var _ = check.Suite(&S{})

type testHandler struct{}

func (h *testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	content := `{"name":"Paul"}`
	w.Write([]byte(content))
}

func (s *S) TestHttpDataSourceGet(c *check.C) {
	h := testHandler{}
	ts := httptest.NewServer(&h)
	defer ts.Close()
	ds := DataSource{Method: "POST", URL: ts.URL}
	type dataType struct {
		Name string
	}
	data := dataType{}
	result, err := ds.Get()
	c.Assert(err, check.IsNil)
	err = json.Unmarshal([]byte(result), &data)
	c.Assert(err, check.IsNil)
	c.Assert(data.Name, check.Equals, "Paul")
}

func (s *S) TestNew(c *check.C) {
	dsConfigTests := []struct {
		conf *DataSource
		err  error
	}{
		{&DataSource{URL: "http://tsuru.io", Method: "GET"}, nil},
		{&DataSource{URL: "http://tsuru.io"}, errors.New("datasource: method required")},
		{&DataSource{Method: ""}, errors.New("datasource: url required")},
	}
	for _, tt := range dsConfigTests {
		err := New(tt.conf)
		c.Check(err, check.DeepEquals, tt.err)
	}
}

func (s *S) TestGet(c *check.C) {
	ds := DataSource{
		Name:    "xpto",
		Headers: nil,
	}
	s.conn.DataSources().Insert(&ds)
	instance, err := Get(ds.Name)
	c.Assert(err, check.IsNil)
	c.Assert(instance, check.DeepEquals, &ds)

}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/jangler/impulse"
	"github.com/jangler/minipkg/wave"
)

const description = `
Dump all samples from the given IT modules to the working directory.
`

func parseFlags() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s <file>...\n", os.Args[0])
		fmt.Fprint(os.Stderr, description)
		os.Exit(2)
	}
	flag.Parse()
	if flag.NArg() == 0 {
		flag.Usage()
	}
}

func dumpSample(source string, index int, sample *impulse.Sample) error {
	waveFile := wave.File{
		Channels:       1,
		SampleRate:     int(sample.Speed),
		BytesPerSample: 1,
		Data:           sample.Data,
	}
	if sample.Flags&impulse.StereoSample != 0 {
		waveFile.Channels = 2
	}
	if sample.Flags&impulse.Quality16Bit != 0 {
		waveFile.BytesPerSample = 2
	}

	filename := fmt.Sprintf("%s-%03d.wav", source[:len(source)-3], index)
	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	return waveFile.Write(file)
}

func dumpFile(filename string) error {
	file, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	module, err := impulse.ReadModule(file)
	if err != nil {
		return err
	}

	for i, sample := range module.Samples {
		if err := dumpSample(filename, i, sample); err != nil {
			fmt.Fprintf(os.Stderr, "%s: %s: %v\n", os.Args[0], filename, err)
		}
	}
	return nil
}

func main() {
	parseFlags()
	for _, arg := range flag.Args() {
		if err := dumpFile(arg); err != nil {
			fmt.Fprintf(os.Stderr, "%s: %s: %v\n", os.Args[0], arg, err)
		}
	}
}
<commit_msg>Add -its flag to itdump<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/jangler/impulse"
	"github.com/jangler/minipkg/wave"
)

const description = `
Dump all samples from the given IT modules to the working directory.
`

var itsFlag bool

func parseFlags() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s <file>...\n", os.Args[0])
		fmt.Fprintln(os.Stderr, description)
		fmt.Fprintln(os.Stderr, "Options:")
		flag.PrintDefaults()
		os.Exit(2)
	}
	flag.BoolVar(&itsFlag, "its", itsFlag, "dump in ITS format instead of WAV")
	flag.Parse()
	if flag.NArg() == 0 {
		flag.Usage()
	}
}

func dumpSample(source string, index int, sample *impulse.Sample) error {
	ext := "wav"
	if itsFlag {
		ext = "its"
	}
	filename := fmt.Sprintf("%s-%03d.%s", source[:len(source)-3], index, ext)
	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	if itsFlag {
		return sample.Write(file)
	} else {
		waveFile := wave.File{
			Channels:       1,
			SampleRate:     int(sample.Speed),
			BytesPerSample: 1,
			Data:           sample.Data,
		}
		if sample.Flags&impulse.StereoSample != 0 {
			waveFile.Channels = 2
		}
		if sample.Flags&impulse.Quality16Bit != 0 {
			waveFile.BytesPerSample = 2
		}
		return waveFile.Write(file)
	}
}

func dumpFile(filename string) error {
	file, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	module, err := impulse.ReadModule(file)
	if err != nil {
		return err
	}

	for i, sample := range module.Samples {
		if err := dumpSample(filename, i, sample); err != nil {
			fmt.Fprintf(os.Stderr, "%s: %s: %v\n", os.Args[0], filename, err)
		}
	}
	return nil
}

func main() {
	parseFlags()
	for _, arg := range flag.Args() {
		if err := dumpFile(arg); err != nil {
			fmt.Fprintf(os.Stderr, "%s: %s: %v\n", os.Args[0], arg, err)
		}
	}
}
<|endoftext|>


<commit_before>package httpcontext

import (
	"io"
	"net/http"
)

// Set sets a context value on req.
// It currently accomplishes this by replacing the http.Request’s Body with
// a ContextReadCloser, which wraps the original io.ReadCloser.
// See “Invasion of the Body Snatchers.”
func Set(req *http.Request, key interface{}, value interface{}) {
	crc := getContextReadCloser(req)
	crc.Context()[key] = value
}

// Get gets a context value from req.
// Returns nil if key is not present in the request context.
func Get(req *http.Request, key interface{}) interface{} {
	crc := getContextReadCloser(req)
	if value, ok := crc.Context()[key]; ok {
		return value
	}
	return nil
}

// GetOk gets a context value from req.
// Returns (nil, false) if key is not present in the request context.
func GetOk(req *http.Request, key interface{}) (interface{}, bool) {
	crc := getContextReadCloser(req)
	if value, ok := crc.Context()[key]; ok {
		return value, ok
	}
	return nil, false
}

// ContextReadCloser implements the io.ReadCloser interface
// with two additional methods: Context() and SetContext().
type ContextReadCloser interface {
	io.ReadCloser
	Context() map[interface{}]interface{}
}

type contextReadCloser struct {
	io.ReadCloser
	context map[interface{}]interface{}
}

func (crc *contextReadCloser) Context() map[interface{}]interface{} {
	return crc.context
}

func getContextReadCloser(req *http.Request) ContextReadCloser {
	crc, ok := req.Body.(ContextReadCloser)
	if !ok {
		crc = &contextReadCloser{
			ReadCloser: req.Body,
			context:    make(map[interface{}]interface{}),
		}
		req.Body = crc
	}
	return crc
}
<commit_msg>Tweak documentation.<commit_after>package httpcontext

import (
	"io"
	"net/http"
)

// Set sets a context value on req.
// It currently accomplishes this by replacing the http.Request’s Body with
// a ContextReadCloser, which wraps the original io.ReadCloser.
// See “Invasion of the Body Snatchers.”
func Set(req *http.Request, key interface{}, value interface{}) {
	crc := getContextReadCloser(req)
	crc.Context()[key] = value
}

// Get gets a context value from req.
// Returns nil if key not found in the request context.
func Get(req *http.Request, key interface{}) interface{} {
	crc := getContextReadCloser(req)
	if value, ok := crc.Context()[key]; ok {
		return value
	}
	return nil
}

// GetOk gets a context value from req.
// Returns (nil, false) if key not found in the request context.
func GetOk(req *http.Request, key interface{}) (interface{}, bool) {
	crc := getContextReadCloser(req)
	if value, ok := crc.Context()[key]; ok {
		return value, ok
	}
	return nil, false
}

// ContextReadCloser implements the io.ReadCloser interface
// with two additional methods: Context() and SetContext().
type ContextReadCloser interface {
	io.ReadCloser
	Context() map[interface{}]interface{}
}

type contextReadCloser struct {
	io.ReadCloser
	context map[interface{}]interface{}
}

func (crc *contextReadCloser) Context() map[interface{}]interface{} {
	return crc.context
}

func getContextReadCloser(req *http.Request) ContextReadCloser {
	crc, ok := req.Body.(ContextReadCloser)
	if !ok {
		crc = &contextReadCloser{
			ReadCloser: req.Body,
			context:    make(map[interface{}]interface{}),
		}
		req.Body = crc
	}
	return crc
}
<|endoftext|>


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

package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/tools/go/buildutil"
	"golang.org/x/tools/go/packages"
	"golang.org/x/vuln/client"
	"golang.org/x/vuln/exp/govulncheck"
	gvc "golang.org/x/vuln/internal/govulncheck"
	"golang.org/x/vuln/vulncheck"
)

var (
	jsonFlag    = flag.Bool("json", false, "output JSON")
	verboseFlag = flag.Bool("v", false, "print a full call stack for each vulnerability")
	testFlag    = flag.Bool("test", false, "analyze test files. Only valid for source code.")
	tagsFlag    buildutil.TagsFlag

	// testmode flags. See main_testmode.go.
	dirFlag string
)

func init() {
	flag.Var(&tagsFlag, "tags", "comma-separated `list` of build tags")
}

const (
	envGOVULNDB = "GOVULNDB"
	vulndbHost  = "https://vuln.go.dev"
)

func main() {
	flag.Usage = func() {
		fmt.Fprint(os.Stderr, `usage:
	govulncheck [flags] package...
	govulncheck [flags] binary

`)
		flag.PrintDefaults()
		fmt.Fprintf(os.Stderr, `
For details, see https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck.
`)
	}
	flag.Parse()

	if len(flag.Args()) == 0 {
		flag.Usage()
		os.Exit(1)
	}

	patterns := flag.Args()

	sourceAnalysis := true
	if len(patterns) == 1 && isFile(patterns[0]) {
		sourceAnalysis = false
	}
	validateFlags(sourceAnalysis)

	if err := doGovulncheck(patterns, sourceAnalysis); err != nil {
		die(fmt.Sprintf("govulncheck: %v", err))
	}
}

// doGovulncheck performs main govulncheck functionality and exits the
// program upon success with an appropriate exit status. Otherwise,
// returns an error.
func doGovulncheck(patterns []string, sourceAnalysis bool) error {
	ctx := context.Background()
	dir := filepath.FromSlash(dirFlag)

	dbs := []string{vulndbHost}
	if db := os.Getenv(envGOVULNDB); db != "" {
		dbs = strings.Split(db, ",")
	}
	dbClient, err := client.NewClient(dbs, client.Options{
		HTTPCache: govulncheck.DefaultCache(),
	})
	if err != nil {
		return err
	}

	if !*jsonFlag {
		// Print intro message when in text or verbose mode
		fmt.Println(introMessage)
	}

	// config GoVersion is "", which means use current
	// Go version at path.
	cfg := &govulncheck.Config{Client: dbClient}
	var res *govulncheck.Result
	if sourceAnalysis {
		pkgs, err := loadPackages(patterns, dir)
		if err != nil {
			// Try to provide a meaningful and actionable error message.
			if !fileExists(filepath.Join(dir, "go.mod")) {
				return errNoGoMod
			}
			if !fileExists(filepath.Join(dir, "go.sum")) {
				return errNoGoSum
			}
			if isGoVersionMismatchError(err) {
				return fmt.Errorf("%v\n\n%v", errGoVersionMismatch, err)
			}
			return err
		}
		res, err = govulncheck.Source(ctx, cfg, pkgs)
	} else {
		f, err := os.Open(patterns[0])
		if err != nil {
			return err
		}
		defer f.Close()
		res, err = gvc.Binary(ctx, cfg, f)
	}
	if err != nil {
		return err
	}

	if *jsonFlag {
		// Following golang.org/x/tools/go/analysis/singlechecker,
		// return 0 exit code in -json mode.
		if err := printJSON(res); err != nil {
			return err
		}
		os.Exit(0)
	}

	printText(res, *verboseFlag, sourceAnalysis)
	// Return exit status -3 if some vulnerabilities are actually
	// called in source mode or just present in binary mode.
	//
	// This follows the style from
	// golang.org/x/tools/go/analysis/singlechecker,
	// which fails with 3 if there are some findings.
	if sourceAnalysis {
		for _, v := range res.Vulns {
			if v.IsCalled() {
				os.Exit(3)
			}
		}
	} else if len(res.Vulns) > 0 {
		os.Exit(3)
	}
	os.Exit(0)
	return nil
}

func validateFlags(source bool) {
	if !source {
		if *testFlag {
			die("govulncheck: the -test flag is invalid for binaries")
		}
		if tagsFlag != nil {
			die("govulncheck: the -tags flag is invalid for binaries")
		}
	}
}

func isFile(path string) bool {
	s, err := os.Stat(path)
	if err != nil {
		return false
	}
	return !s.IsDir()
}

func die(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format+"\n", args...)
	os.Exit(1)
}

// loadPackages loads the packages matching patterns at dir using build tags
// provided by tagsFlag. Uses load mode needed for vulncheck analysis. If the
// packages contain errors, a packageError is returned containing a list of
// the errors, along with the packages themselves.
func loadPackages(patterns []string, dir string) ([]*vulncheck.Package, error) {
	var buildFlags []string
	if tagsFlag != nil {
		buildFlags = []string{fmt.Sprintf("-tags=%s", strings.Join(tagsFlag, ","))}
	}

	cfg := &packages.Config{Dir: dir, Tests: *testFlag}
	cfg.Mode |= packages.NeedName | packages.NeedImports | packages.NeedTypes |
		packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedDeps |
		packages.NeedModule
	cfg.BuildFlags = buildFlags

	pkgs, err := packages.Load(cfg, patterns...)
	vpkgs := vulncheck.Convert(pkgs)
	if err != nil {
		return nil, err
	}
	var perrs []packages.Error
	packages.Visit(pkgs, nil, func(p *packages.Package) {
		perrs = append(perrs, p.Errors...)
	})
	if len(perrs) > 0 {
		err = &packageError{perrs}
	}
	return vpkgs, err
}
<commit_msg>cmd/govulncheck: do not shadow err in doGovulncheck.<commit_after>// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/tools/go/buildutil"
	"golang.org/x/tools/go/packages"
	"golang.org/x/vuln/client"
	"golang.org/x/vuln/exp/govulncheck"
	gvc "golang.org/x/vuln/internal/govulncheck"
	"golang.org/x/vuln/vulncheck"
)

var (
	jsonFlag    = flag.Bool("json", false, "output JSON")
	verboseFlag = flag.Bool("v", false, "print a full call stack for each vulnerability")
	testFlag    = flag.Bool("test", false, "analyze test files. Only valid for source code.")
	tagsFlag    buildutil.TagsFlag

	// testmode flags. See main_testmode.go.
	dirFlag string
)

func init() {
	flag.Var(&tagsFlag, "tags", "comma-separated `list` of build tags")
}

const (
	envGOVULNDB = "GOVULNDB"
	vulndbHost  = "https://vuln.go.dev"
)

func main() {
	flag.Usage = func() {
		fmt.Fprint(os.Stderr, `usage:
	govulncheck [flags] package...
	govulncheck [flags] binary

`)
		flag.PrintDefaults()
		fmt.Fprintf(os.Stderr, `
For details, see https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck.
`)
	}
	flag.Parse()

	if len(flag.Args()) == 0 {
		flag.Usage()
		os.Exit(1)
	}

	patterns := flag.Args()

	sourceAnalysis := true
	if len(patterns) == 1 && isFile(patterns[0]) {
		sourceAnalysis = false
	}
	validateFlags(sourceAnalysis)

	if err := doGovulncheck(patterns, sourceAnalysis); err != nil {
		die(fmt.Sprintf("govulncheck: %v", err))
	}
}

// doGovulncheck performs main govulncheck functionality and exits the
// program upon success with an appropriate exit status. Otherwise,
// returns an error.
func doGovulncheck(patterns []string, sourceAnalysis bool) error {
	ctx := context.Background()
	dir := filepath.FromSlash(dirFlag)

	dbs := []string{vulndbHost}
	if db := os.Getenv(envGOVULNDB); db != "" {
		dbs = strings.Split(db, ",")
	}
	dbClient, err := client.NewClient(dbs, client.Options{
		HTTPCache: govulncheck.DefaultCache(),
	})
	if err != nil {
		return err
	}

	if !*jsonFlag {
		// Print intro message when in text or verbose mode
		fmt.Println(introMessage)
	}

	// config GoVersion is "", which means use current
	// Go version at path.
	cfg := &govulncheck.Config{Client: dbClient}
	var res *govulncheck.Result
	if sourceAnalysis {
		var pkgs []*vulncheck.Package
		pkgs, err = loadPackages(patterns, dir)
		if err != nil {
			// Try to provide a meaningful and actionable error message.
			if !fileExists(filepath.Join(dir, "go.mod")) {
				return errNoGoMod
			}
			if !fileExists(filepath.Join(dir, "go.sum")) {
				return errNoGoSum
			}
			if isGoVersionMismatchError(err) {
				return fmt.Errorf("%v\n\n%v", errGoVersionMismatch, err)
			}
			return err
		}
		res, err = govulncheck.Source(ctx, cfg, pkgs)
	} else {
		var f *os.File
		f, err = os.Open(patterns[0])
		if err != nil {
			return err
		}
		defer f.Close()
		res, err = gvc.Binary(ctx, cfg, f)
	}
	if err != nil {
		return err
	}

	if *jsonFlag {
		// Following golang.org/x/tools/go/analysis/singlechecker,
		// return 0 exit code in -json mode.
		if err := printJSON(res); err != nil {
			return err
		}
		os.Exit(0)
	}

	printText(res, *verboseFlag, sourceAnalysis)
	// Return exit status -3 if some vulnerabilities are actually
	// called in source mode or just present in binary mode.
	//
	// This follows the style from
	// golang.org/x/tools/go/analysis/singlechecker,
	// which fails with 3 if there are some findings.
	if sourceAnalysis {
		for _, v := range res.Vulns {
			if v.IsCalled() {
				os.Exit(3)
			}
		}
	} else if len(res.Vulns) > 0 {
		os.Exit(3)
	}
	os.Exit(0)
	return nil
}

func validateFlags(source bool) {
	if !source {
		if *testFlag {
			die("govulncheck: the -test flag is invalid for binaries")
		}
		if tagsFlag != nil {
			die("govulncheck: the -tags flag is invalid for binaries")
		}
	}
}

func isFile(path string) bool {
	s, err := os.Stat(path)
	if err != nil {
		return false
	}
	return !s.IsDir()
}

func die(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format+"\n", args...)
	os.Exit(1)
}

// loadPackages loads the packages matching patterns at dir using build tags
// provided by tagsFlag. Uses load mode needed for vulncheck analysis. If the
// packages contain errors, a packageError is returned containing a list of
// the errors, along with the packages themselves.
func loadPackages(patterns []string, dir string) ([]*vulncheck.Package, error) {
	var buildFlags []string
	if tagsFlag != nil {
		buildFlags = []string{fmt.Sprintf("-tags=%s", strings.Join(tagsFlag, ","))}
	}

	cfg := &packages.Config{Dir: dir, Tests: *testFlag}
	cfg.Mode |= packages.NeedName | packages.NeedImports | packages.NeedTypes |
		packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedDeps |
		packages.NeedModule
	cfg.BuildFlags = buildFlags

	pkgs, err := packages.Load(cfg, patterns...)
	vpkgs := vulncheck.Convert(pkgs)
	if err != nil {
		return nil, err
	}
	var perrs []packages.Error
	packages.Visit(pkgs, nil, func(p *packages.Package) {
		perrs = append(perrs, p.Errors...)
	})
	if len(perrs) > 0 {
		err = &packageError{perrs}
	}
	return vpkgs, err
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/Symantec/Dominator/imageserver/httpd"
	imageserverRpcd "github.com/Symantec/Dominator/imageserver/rpcd"
	"github.com/Symantec/Dominator/imageserver/scanner"
	"github.com/Symantec/Dominator/lib/constants"
	"github.com/Symantec/Dominator/lib/logbuf"
	"github.com/Symantec/Dominator/objectserver/filesystem"
	objectserverRpcd "github.com/Symantec/Dominator/objectserver/rpcd"
	"log"
	"net/rpc"
	"os"
)

var (
	debug    = flag.Bool("debug", false, "If true, show debugging output")
	imageDir = flag.String("imageDir", "/var/lib/imageserver",
		"Name of image server data directory.")
	logbufLines = flag.Uint("logbufLines", 1024,
		"Number of lines to store in the log buffer")
	objectDir = flag.String("objectDir", "/var/lib/objectserver",
		"Name of image server data directory.")
	portNum = flag.Uint("portNum", constants.ImageServerPortNumber,
		"Port number to allocate and listen on for HTTP/RPC")
)

func main() {
	flag.Parse()
	if os.Geteuid() == 0 {
		fmt.Fprintln(os.Stderr, "Do not run the Image Server as root")
		os.Exit(1)
	}
	circularBuffer := logbuf.New(*logbufLines)
	logger := log.New(circularBuffer, "", log.LstdFlags)
	objSrv, err := filesystem.NewObjectServer(*objectDir, logger)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot create ObjectServer\t%s\n", err)
		os.Exit(1)
	}
	imdb, err := scanner.LoadImageDataBase(*imageDir, objSrv)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot load image database\t%s\n", err)
		os.Exit(1)
	}
	imageserverRpcd.Setup(imdb, logger)
	rpcHtmlWriter := objectserverRpcd.Setup(objSrv, logger)
	rpc.HandleHTTP()
	httpd.AddHtmlWriter(imdb)
	httpd.AddHtmlWriter(rpcHtmlWriter)
	httpd.AddHtmlWriter(circularBuffer)
	if err = httpd.StartServer(*portNum, imdb, false); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to create http server\t%s\n", err)
		os.Exit(1)
	}
}
<commit_msg>Add /image-count metric to imageserver.<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/Symantec/Dominator/imageserver/httpd"
	imageserverRpcd "github.com/Symantec/Dominator/imageserver/rpcd"
	"github.com/Symantec/Dominator/imageserver/scanner"
	"github.com/Symantec/Dominator/lib/constants"
	"github.com/Symantec/Dominator/lib/logbuf"
	"github.com/Symantec/Dominator/objectserver/filesystem"
	objectserverRpcd "github.com/Symantec/Dominator/objectserver/rpcd"
	"github.com/Symantec/tricorder/go/tricorder"
	"github.com/Symantec/tricorder/go/tricorder/units"
	"log"
	"net/rpc"
	"os"
)

var (
	debug    = flag.Bool("debug", false, "If true, show debugging output")
	imageDir = flag.String("imageDir", "/var/lib/imageserver",
		"Name of image server data directory.")
	logbufLines = flag.Uint("logbufLines", 1024,
		"Number of lines to store in the log buffer")
	objectDir = flag.String("objectDir", "/var/lib/objectserver",
		"Name of image server data directory.")
	portNum = flag.Uint("portNum", constants.ImageServerPortNumber,
		"Port number to allocate and listen on for HTTP/RPC")
)

func main() {
	flag.Parse()
	if os.Geteuid() == 0 {
		fmt.Fprintln(os.Stderr, "Do not run the Image Server as root")
		os.Exit(1)
	}
	circularBuffer := logbuf.New(*logbufLines)
	logger := log.New(circularBuffer, "", log.LstdFlags)
	objSrv, err := filesystem.NewObjectServer(*objectDir, logger)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot create ObjectServer\t%s\n", err)
		os.Exit(1)
	}
	imdb, err := scanner.LoadImageDataBase(*imageDir, objSrv)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot load image database\t%s\n", err)
		os.Exit(1)
	}
	tricorder.RegisterMetric("/image-count",
		func() uint { return imdb.CountImages() },
		units.None, "number of images")
	imageserverRpcd.Setup(imdb, logger)
	rpcHtmlWriter := objectserverRpcd.Setup(objSrv, logger)
	rpc.HandleHTTP()
	httpd.AddHtmlWriter(imdb)
	httpd.AddHtmlWriter(rpcHtmlWriter)
	httpd.AddHtmlWriter(circularBuffer)
	if err = httpd.StartServer(*portNum, imdb, false); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to create http server\t%s\n", err)
		os.Exit(1)
	}
}
<|endoftext|>


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

package cmd

import (
	"bufio"
	"context"
	"errors"
	"math/rand"
	"net/http"
	"path"
	"sort"
	"time"

	"github.com/gorilla/mux"
	"github.com/minio/minio/pkg/dsync"
)

const (
	// Lock maintenance interval.
	lockMaintenanceInterval = 30 * time.Second

	// Lock validity check interval.
	lockValidityCheckInterval = 30 * time.Second
)

// To abstract a node over network.
type lockRESTServer struct {
	ll *localLocker
}

func (l *lockRESTServer) writeErrorResponse(w http.ResponseWriter, err error) {
	w.WriteHeader(http.StatusForbidden)
	w.Write([]byte(err.Error()))
}

// IsValid - To authenticate and verify the time difference.
func (l *lockRESTServer) IsValid(w http.ResponseWriter, r *http.Request) bool {
	if l.ll == nil {
		l.writeErrorResponse(w, errLockNotInitialized)
		return false
	}

	if err := storageServerRequestValidate(r); err != nil {
		l.writeErrorResponse(w, err)
		return false
	}
	return true
}

func getLockArgs(r *http.Request) (args dsync.LockArgs, err error) {
	args = dsync.LockArgs{
		Owner:  r.URL.Query().Get(lockRESTOwner),
		UID:    r.URL.Query().Get(lockRESTUID),
		Source: r.URL.Query().Get(lockRESTSource),
	}

	var resources []string
	bio := bufio.NewScanner(r.Body)
	for bio.Scan() {
		resources = append(resources, bio.Text())
	}

	if err := bio.Err(); err != nil {
		return args, err
	}

	sort.Strings(resources)
	args.Resources = resources
	return args, nil
}

// HealthHandler returns success if request is authenticated.
func (l *lockRESTServer) HealthHandler(w http.ResponseWriter, r *http.Request) {
	l.IsValid(w, r)
}

// LockHandler - Acquires a lock.
func (l *lockRESTServer) LockHandler(w http.ResponseWriter, r *http.Request) {
	if !l.IsValid(w, r) {
		l.writeErrorResponse(w, errors.New("Invalid request"))
		return
	}

	args, err := getLockArgs(r)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}

	success, err := l.ll.Lock(r.Context(), args)
	if err == nil && !success {
		err = errLockConflict
	}
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}
}

// UnlockHandler - releases the acquired lock.
func (l *lockRESTServer) UnlockHandler(w http.ResponseWriter, r *http.Request) {
	if !l.IsValid(w, r) {
		l.writeErrorResponse(w, errors.New("Invalid request"))
		return
	}

	args, err := getLockArgs(r)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}

	_, err = l.ll.Unlock(args)
	// Ignore the Unlock() "reply" return value because if err == nil, "reply" is always true
	// Consequently, if err != nil, reply is always false
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}
}

// LockHandler - Acquires an RLock.
func (l *lockRESTServer) RLockHandler(w http.ResponseWriter, r *http.Request) {
	if !l.IsValid(w, r) {
		l.writeErrorResponse(w, errors.New("Invalid request"))
		return
	}

	args, err := getLockArgs(r)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}

	success, err := l.ll.RLock(r.Context(), args)
	if err == nil && !success {
		err = errLockConflict
	}
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}
}

// RUnlockHandler - releases the acquired read lock.
func (l *lockRESTServer) RUnlockHandler(w http.ResponseWriter, r *http.Request) {
	if !l.IsValid(w, r) {
		l.writeErrorResponse(w, errors.New("Invalid request"))
		return
	}

	args, err := getLockArgs(r)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}

	// Ignore the RUnlock() "reply" return value because if err == nil, "reply" is always true.
	// Consequently, if err != nil, reply is always false
	if _, err = l.ll.RUnlock(args); err != nil {
		l.writeErrorResponse(w, err)
		return
	}
}

// ExpiredHandler - query expired lock status.
func (l *lockRESTServer) ExpiredHandler(w http.ResponseWriter, r *http.Request) {
	if !l.IsValid(w, r) {
		l.writeErrorResponse(w, errors.New("Invalid request"))
		return
	}

	args, err := getLockArgs(r)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}

	expired, err := l.ll.Expired(r.Context(), args)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}
	if !expired {
		l.writeErrorResponse(w, errLockNotExpired)
		return
	}
}

// nameLockRequesterInfoPair is a helper type for lock maintenance
type nameLockRequesterInfoPair struct {
	name string
	lri  lockRequesterInfo
}

// getLongLivedLocks returns locks that are older than a certain time and
// have not been 'checked' for validity too soon enough
func getLongLivedLocks(interval time.Duration) map[Endpoint][]nameLockRequesterInfoPair {
	nlripMap := make(map[Endpoint][]nameLockRequesterInfoPair)
	for endpoint, locker := range globalLockServers {
		rslt := []nameLockRequesterInfoPair{}
		locker.mutex.Lock()
		for name, lriArray := range locker.lockMap {
			for idx := range lriArray {
				// Check whether enough time has gone by since last check
				if time.Since(lriArray[idx].TimeLastCheck) >= interval {
					rslt = append(rslt, nameLockRequesterInfoPair{
						name: name,
						lri:  lriArray[idx],
					})
					lriArray[idx].TimeLastCheck = UTCNow()
				}
			}
		}
		nlripMap[endpoint] = rslt
		locker.mutex.Unlock()
	}
	return nlripMap
}

// lockMaintenance loops over locks that have been active for some time and checks back
// with the original server whether it is still alive or not
//
// Following logic inside ignores the errors generated for Dsync.Active operation.
// - server at client down
// - some network error (and server is up normally)
//
// We will ignore the error, and we will retry later to get a resolve on this lock
func lockMaintenance(ctx context.Context, interval time.Duration) error {
	objAPI := newObjectLayerFn()
	if objAPI == nil {
		return nil
	}

	z, ok := objAPI.(*erasureZones)
	if !ok {
		return nil
	}

	type nlock struct {
		locks  int
		writer bool
	}

	updateNlocks := func(nlripsMap map[string]nlock, name string, writer bool) {
		nlk, ok := nlripsMap[name]
		if !ok {
			nlripsMap[name] = nlock{
				locks:  1,
				writer: writer,
			}
		} else {
			nlk.locks++
			nlripsMap[name] = nlk
		}
	}

	allLockersFn := z.GetAllLockers

	// Validate if long lived locks are indeed clean.
	// Get list of long lived locks to check for staleness.
	for lendpoint, nlrips := range getLongLivedLocks(interval) {
		nlripsMap := make(map[string]nlock, len(nlrips))
		for _, nlrip := range nlrips {
			// Locks are only held on first zone, make sure that
			// we only look for ownership of locks from endpoints
			// on first zone.
			for _, c := range allLockersFn() {
				if !c.IsOnline() {
					updateNlocks(nlripsMap, nlrip.name, nlrip.lri.Writer)
					continue
				}

				ctx, cancel := context.WithTimeout(GlobalContext, 5*time.Second)

				// Call back to original server verify whether the lock is
				// still active (based on name & uid)
				expired, err := c.Expired(ctx, dsync.LockArgs{
					Owner:     nlrip.lri.Owner,
					UID:       nlrip.lri.UID,
					Resources: []string{nlrip.name},
				})
				cancel()
				if err != nil {
					updateNlocks(nlripsMap, nlrip.name, nlrip.lri.Writer)
					continue
				}

				if !expired {
					updateNlocks(nlripsMap, nlrip.name, nlrip.lri.Writer)
				}
			}

			// Read locks we assume quorum for be N/2 success
			quorum := getReadQuorum(objAPI.SetDriveCount())
			if nlrip.lri.Writer {
				quorum = getWriteQuorum(objAPI.SetDriveCount())
			}

			// less than the quorum, we have locks expired.
			if nlripsMap[nlrip.name].locks < quorum {
				// The lock is no longer active at server that originated
				// the lock, attempt to remove the lock.
				globalLockServers[lendpoint].mutex.Lock()
				// Purge the stale entry if it exists.
				globalLockServers[lendpoint].removeEntryIfExists(nlrip)
				globalLockServers[lendpoint].mutex.Unlock()
			}

		}
	}

	return nil
}

// Start lock maintenance from all lock servers.
func startLockMaintenance(ctx context.Context) {
	// Wait until the object API is ready
	// no need to start the lock maintenance
	// if ObjectAPI is not initialized.
	for {
		objAPI := newObjectLayerFn()
		if objAPI == nil {
			time.Sleep(time.Second)
			continue
		}
		break
	}

	// Initialize a new ticker with a minute between each ticks.
	ticker := time.NewTicker(lockMaintenanceInterval)
	// Stop the timer upon service closure and cleanup the go-routine.
	defer ticker.Stop()

	r := rand.New(rand.NewSource(UTCNow().UnixNano()))
	for {
		// Verifies every minute for locks held more than 2 minutes.
		select {
		case <-ctx.Done():
			return
		case <-ticker.C:
			// Start with random sleep time, so as to avoid
			// "synchronous checks" between servers
			duration := time.Duration(r.Float64() * float64(lockMaintenanceInterval))
			time.Sleep(duration)
			if err := lockMaintenance(ctx, lockValidityCheckInterval); err != nil {
				// Sleep right after an error.
				duration := time.Duration(r.Float64() * float64(lockMaintenanceInterval))
				time.Sleep(duration)
			}
		}
	}
}

// registerLockRESTHandlers - register lock rest router.
func registerLockRESTHandlers(router *mux.Router, endpointZones EndpointZones) {
	for _, ep := range endpointZones {
		for _, endpoint := range ep.Endpoints {
			if !endpoint.IsLocal {
				continue
			}

			lockServer := &lockRESTServer{
				ll: newLocker(endpoint),
			}

			subrouter := router.PathPrefix(path.Join(lockRESTPrefix, endpoint.Path)).Subrouter()
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodHealth).HandlerFunc(httpTraceHdrs(lockServer.HealthHandler))
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodLock).HandlerFunc(httpTraceHdrs(lockServer.LockHandler))
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodRLock).HandlerFunc(httpTraceHdrs(lockServer.RLockHandler))
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodUnlock).HandlerFunc(httpTraceHdrs(lockServer.UnlockHandler))
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodRUnlock).HandlerFunc(httpTraceHdrs(lockServer.RUnlockHandler))
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodExpired).HandlerFunc(httpTraceAll(lockServer.ExpiredHandler))

			globalLockServers[endpoint] = lockServer.ll
		}
	}

	go startLockMaintenance(GlobalContext)
}
<commit_msg>fix: allow locker to be niladic<commit_after>/*
 * Minio Cloud Storage, (C) 2019 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cmd

import (
	"bufio"
	"context"
	"errors"
	"math/rand"
	"net/http"
	"path"
	"sort"
	"time"

	"github.com/gorilla/mux"
	"github.com/minio/minio/pkg/dsync"
)

const (
	// Lock maintenance interval.
	lockMaintenanceInterval = 30 * time.Second

	// Lock validity check interval.
	lockValidityCheckInterval = 30 * time.Second
)

// To abstract a node over network.
type lockRESTServer struct {
	ll *localLocker
}

func (l *lockRESTServer) writeErrorResponse(w http.ResponseWriter, err error) {
	w.WriteHeader(http.StatusForbidden)
	w.Write([]byte(err.Error()))
}

// IsValid - To authenticate and verify the time difference.
func (l *lockRESTServer) IsValid(w http.ResponseWriter, r *http.Request) bool {
	if l.ll == nil {
		l.writeErrorResponse(w, errLockNotInitialized)
		return false
	}

	if err := storageServerRequestValidate(r); err != nil {
		l.writeErrorResponse(w, err)
		return false
	}
	return true
}

func getLockArgs(r *http.Request) (args dsync.LockArgs, err error) {
	args = dsync.LockArgs{
		Owner:  r.URL.Query().Get(lockRESTOwner),
		UID:    r.URL.Query().Get(lockRESTUID),
		Source: r.URL.Query().Get(lockRESTSource),
	}

	var resources []string
	bio := bufio.NewScanner(r.Body)
	for bio.Scan() {
		resources = append(resources, bio.Text())
	}

	if err := bio.Err(); err != nil {
		return args, err
	}

	sort.Strings(resources)
	args.Resources = resources
	return args, nil
}

// HealthHandler returns success if request is authenticated.
func (l *lockRESTServer) HealthHandler(w http.ResponseWriter, r *http.Request) {
	l.IsValid(w, r)
}

// LockHandler - Acquires a lock.
func (l *lockRESTServer) LockHandler(w http.ResponseWriter, r *http.Request) {
	if !l.IsValid(w, r) {
		l.writeErrorResponse(w, errors.New("Invalid request"))
		return
	}

	args, err := getLockArgs(r)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}

	success, err := l.ll.Lock(r.Context(), args)
	if err == nil && !success {
		err = errLockConflict
	}
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}
}

// UnlockHandler - releases the acquired lock.
func (l *lockRESTServer) UnlockHandler(w http.ResponseWriter, r *http.Request) {
	if !l.IsValid(w, r) {
		l.writeErrorResponse(w, errors.New("Invalid request"))
		return
	}

	args, err := getLockArgs(r)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}

	_, err = l.ll.Unlock(args)
	// Ignore the Unlock() "reply" return value because if err == nil, "reply" is always true
	// Consequently, if err != nil, reply is always false
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}
}

// LockHandler - Acquires an RLock.
func (l *lockRESTServer) RLockHandler(w http.ResponseWriter, r *http.Request) {
	if !l.IsValid(w, r) {
		l.writeErrorResponse(w, errors.New("Invalid request"))
		return
	}

	args, err := getLockArgs(r)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}

	success, err := l.ll.RLock(r.Context(), args)
	if err == nil && !success {
		err = errLockConflict
	}
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}
}

// RUnlockHandler - releases the acquired read lock.
func (l *lockRESTServer) RUnlockHandler(w http.ResponseWriter, r *http.Request) {
	if !l.IsValid(w, r) {
		l.writeErrorResponse(w, errors.New("Invalid request"))
		return
	}

	args, err := getLockArgs(r)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}

	// Ignore the RUnlock() "reply" return value because if err == nil, "reply" is always true.
	// Consequently, if err != nil, reply is always false
	if _, err = l.ll.RUnlock(args); err != nil {
		l.writeErrorResponse(w, err)
		return
	}
}

// ExpiredHandler - query expired lock status.
func (l *lockRESTServer) ExpiredHandler(w http.ResponseWriter, r *http.Request) {
	if !l.IsValid(w, r) {
		l.writeErrorResponse(w, errors.New("Invalid request"))
		return
	}

	args, err := getLockArgs(r)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}

	expired, err := l.ll.Expired(r.Context(), args)
	if err != nil {
		l.writeErrorResponse(w, err)
		return
	}
	if !expired {
		l.writeErrorResponse(w, errLockNotExpired)
		return
	}
}

// nameLockRequesterInfoPair is a helper type for lock maintenance
type nameLockRequesterInfoPair struct {
	name string
	lri  lockRequesterInfo
}

// getLongLivedLocks returns locks that are older than a certain time and
// have not been 'checked' for validity too soon enough
func getLongLivedLocks(interval time.Duration) map[Endpoint][]nameLockRequesterInfoPair {
	nlripMap := make(map[Endpoint][]nameLockRequesterInfoPair)
	for endpoint, locker := range globalLockServers {
		rslt := []nameLockRequesterInfoPair{}
		locker.mutex.Lock()
		for name, lriArray := range locker.lockMap {
			for idx := range lriArray {
				// Check whether enough time has gone by since last check
				if time.Since(lriArray[idx].TimeLastCheck) >= interval {
					rslt = append(rslt, nameLockRequesterInfoPair{
						name: name,
						lri:  lriArray[idx],
					})
					lriArray[idx].TimeLastCheck = UTCNow()
				}
			}
		}
		nlripMap[endpoint] = rslt
		locker.mutex.Unlock()
	}
	return nlripMap
}

// lockMaintenance loops over locks that have been active for some time and checks back
// with the original server whether it is still alive or not
//
// Following logic inside ignores the errors generated for Dsync.Active operation.
// - server at client down
// - some network error (and server is up normally)
//
// We will ignore the error, and we will retry later to get a resolve on this lock
func lockMaintenance(ctx context.Context, interval time.Duration) error {
	objAPI := newObjectLayerFn()
	if objAPI == nil {
		return nil
	}

	z, ok := objAPI.(*erasureZones)
	if !ok {
		return nil
	}

	type nlock struct {
		locks  int
		writer bool
	}

	updateNlocks := func(nlripsMap map[string]nlock, name string, writer bool) {
		nlk, ok := nlripsMap[name]
		if !ok {
			nlripsMap[name] = nlock{
				locks:  1,
				writer: writer,
			}
		} else {
			nlk.locks++
			nlripsMap[name] = nlk
		}
	}

	allLockersFn := z.GetAllLockers

	// Validate if long lived locks are indeed clean.
	// Get list of long lived locks to check for staleness.
	for lendpoint, nlrips := range getLongLivedLocks(interval) {
		nlripsMap := make(map[string]nlock, len(nlrips))
		for _, nlrip := range nlrips {
			// Locks are only held on first zone, make sure that
			// we only look for ownership of locks from endpoints
			// on first zone.
			for _, c := range allLockersFn() {
				if !c.IsOnline() || c == nil {
					updateNlocks(nlripsMap, nlrip.name, nlrip.lri.Writer)
					continue
				}

				ctx, cancel := context.WithTimeout(GlobalContext, 5*time.Second)

				// Call back to original server verify whether the lock is
				// still active (based on name & uid)
				expired, err := c.Expired(ctx, dsync.LockArgs{
					Owner:     nlrip.lri.Owner,
					UID:       nlrip.lri.UID,
					Resources: []string{nlrip.name},
				})
				cancel()
				if err != nil {
					updateNlocks(nlripsMap, nlrip.name, nlrip.lri.Writer)
					continue
				}

				if !expired {
					updateNlocks(nlripsMap, nlrip.name, nlrip.lri.Writer)
				}
			}

			// Read locks we assume quorum for be N/2 success
			quorum := getReadQuorum(objAPI.SetDriveCount())
			if nlrip.lri.Writer {
				quorum = getWriteQuorum(objAPI.SetDriveCount())
			}

			// less than the quorum, we have locks expired.
			if nlripsMap[nlrip.name].locks < quorum {
				// The lock is no longer active at server that originated
				// the lock, attempt to remove the lock.
				globalLockServers[lendpoint].mutex.Lock()
				// Purge the stale entry if it exists.
				globalLockServers[lendpoint].removeEntryIfExists(nlrip)
				globalLockServers[lendpoint].mutex.Unlock()
			}

		}
	}

	return nil
}

// Start lock maintenance from all lock servers.
func startLockMaintenance(ctx context.Context) {
	// Wait until the object API is ready
	// no need to start the lock maintenance
	// if ObjectAPI is not initialized.
	for {
		objAPI := newObjectLayerFn()
		if objAPI == nil {
			time.Sleep(time.Second)
			continue
		}
		break
	}

	// Initialize a new ticker with a minute between each ticks.
	ticker := time.NewTicker(lockMaintenanceInterval)
	// Stop the timer upon service closure and cleanup the go-routine.
	defer ticker.Stop()

	r := rand.New(rand.NewSource(UTCNow().UnixNano()))
	for {
		// Verifies every minute for locks held more than 2 minutes.
		select {
		case <-ctx.Done():
			return
		case <-ticker.C:
			// Start with random sleep time, so as to avoid
			// "synchronous checks" between servers
			duration := time.Duration(r.Float64() * float64(lockMaintenanceInterval))
			time.Sleep(duration)
			if err := lockMaintenance(ctx, lockValidityCheckInterval); err != nil {
				// Sleep right after an error.
				duration := time.Duration(r.Float64() * float64(lockMaintenanceInterval))
				time.Sleep(duration)
			}
		}
	}
}

// registerLockRESTHandlers - register lock rest router.
func registerLockRESTHandlers(router *mux.Router, endpointZones EndpointZones) {
	for _, ep := range endpointZones {
		for _, endpoint := range ep.Endpoints {
			if !endpoint.IsLocal {
				continue
			}

			lockServer := &lockRESTServer{
				ll: newLocker(endpoint),
			}

			subrouter := router.PathPrefix(path.Join(lockRESTPrefix, endpoint.Path)).Subrouter()
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodHealth).HandlerFunc(httpTraceHdrs(lockServer.HealthHandler))
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodLock).HandlerFunc(httpTraceHdrs(lockServer.LockHandler))
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodRLock).HandlerFunc(httpTraceHdrs(lockServer.RLockHandler))
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodUnlock).HandlerFunc(httpTraceHdrs(lockServer.UnlockHandler))
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodRUnlock).HandlerFunc(httpTraceHdrs(lockServer.RUnlockHandler))
			subrouter.Methods(http.MethodPost).Path(lockRESTVersionPrefix + lockRESTMethodExpired).HandlerFunc(httpTraceAll(lockServer.ExpiredHandler))

			globalLockServers[endpoint] = lockServer.ll
		}
	}

	go startLockMaintenance(GlobalContext)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"regexp"
	"strconv"

	"github.com/PuerkitoBio/goquery"
	"github.com/dustin/go-humanize"
	"github.com/gophergala2016/magopie"
)

var thePirateBay = site{
	Site: magopie.Site{
		ID:      "tpb",
		Name:    "The Pirate Bay",
		URL:     "https://thepiratebay.se",
		Enabled: true,
	},
	search: func(term string) ([]magopie.Torrent, error) {
		url := fmt.Sprintf(
			"https://thepiratebay.se/search/%s/0/7/0",
			url.QueryEscape(term),
		)

		res, err := http.DefaultClient.Get(url)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()

		if res.StatusCode != 200 {
			return nil, ErrFailedRequest
		}

		return tpbParse(res.Body)
	},
}

func tpbParse(r io.Reader) ([]magopie.Torrent, error) {
	doc, err := goquery.NewDocumentFromReader(r)
	if err != nil {
		return nil, err
	}

	var torrents []magopie.Torrent
	doc.Find("table#searchResult tr").Each(func(i int, s *goquery.Selection) {
		// First child is header row
		if i <= 0 {
			return
		}

		magnet, ok := s.Find("div.detName + a").Attr("href")
		if !ok {
			return
		}

		// hash gets ripped from magnet
		hash, err := hashFromMagnet(magnet)
		if err != nil {
			log.Print(err)
			return
		}

		seed, err := strconv.Atoi(s.Children().Eq(2).Text())
		if err != nil {
			log.Print(err)
			seed = 0
		}

		leech, err := strconv.Atoi(s.Children().Eq(3).Text())
		if err != nil {
			log.Print(err)
			leech = 0
		}

		// Need to rip human-friendly filesize from description and make it ugly
		details := s.Find("font.detDesc").Text()
		size, err := bytesFromDetails(details)
		if err != nil {
			log.Print(err)
			size = 0
		}

		t := magopie.Torrent{
			ID:        hash,
			Title:     s.Find("div.detName a").Text(),
			MagnetURI: magnet,
			SiteID:    "tpb",
			Seeders:   seed,
			Leechers:  leech,
			Size:      size,
		}

		torrents = append(torrents, t)
	})

	return torrents, nil
}

func hashFromMagnet(m string) (string, error) {
	re := regexp.MustCompile(`magnet:\?xt=urn:btih:([^&]+)`)
	match := re.FindStringSubmatch(m)

	if len(match) <= 0 {
		return "", ErrHashlessMagnet
	}

	return match[1], nil
}

func bytesFromDetails(d string) (int, error) {
	re := regexp.MustCompile(`, Size ([^,]+)`)
	match := re.FindStringSubmatch(d)

	if len(match) <= 0 {
		return 0, ErrCannotFindFileSize
	}

	bytes, err := humanize.ParseBigBytes(match[1])
	if err != nil {
		log.Print(err)
		return 0, err
	}

	return int(bytes.Int64()), nil
}
<commit_msg>Improve magent hash parsing<commit_after>package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"regexp"
	"strconv"

	"github.com/PuerkitoBio/goquery"
	"github.com/dustin/go-humanize"
	"github.com/gophergala2016/magopie"
)

var thePirateBay = site{
	Site: magopie.Site{
		ID:      "tpb",
		Name:    "The Pirate Bay",
		URL:     "https://thepiratebay.se",
		Enabled: true,
	},
	search: func(term string) ([]magopie.Torrent, error) {
		url := fmt.Sprintf(
			"https://thepiratebay.se/search/%s/0/7/0",
			url.QueryEscape(term),
		)

		res, err := http.DefaultClient.Get(url)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()

		if res.StatusCode != 200 {
			return nil, ErrFailedRequest
		}

		return tpbParse(res.Body)
	},
}

func tpbParse(r io.Reader) ([]magopie.Torrent, error) {
	doc, err := goquery.NewDocumentFromReader(r)
	if err != nil {
		return nil, err
	}

	var torrents []magopie.Torrent
	doc.Find("table#searchResult tr").Each(func(i int, s *goquery.Selection) {
		// First child is header row
		if i <= 0 {
			return
		}

		magnet, ok := s.Find("div.detName + a").Attr("href")
		if !ok {
			return
		}

		// hash gets ripped from magnet
		hash, err := hashFromMagnet(magnet)
		if err != nil {
			log.Print(err)
			return
		}

		seed, err := strconv.Atoi(s.Children().Eq(2).Text())
		if err != nil {
			log.Print(err)
			seed = 0
		}

		leech, err := strconv.Atoi(s.Children().Eq(3).Text())
		if err != nil {
			log.Print(err)
			leech = 0
		}

		// Need to rip human-friendly filesize from description and make it ugly
		details := s.Find("font.detDesc").Text()
		size, err := bytesFromDetails(details)
		if err != nil {
			log.Print(err)
			size = 0
		}

		t := magopie.Torrent{
			ID:        hash,
			Title:     s.Find("div.detName a").Text(),
			MagnetURI: magnet,
			SiteID:    "tpb",
			Seeders:   seed,
			Leechers:  leech,
			Size:      size,
		}

		torrents = append(torrents, t)
	})

	return torrents, nil
}

// btihRE finds the BTIH hash from the xt segment of a Magnet URI
var btihRE = regexp.MustCompile(`urn:btih:(.+)`)

func hashFromMagnet(m string) (string, error) {
	parsed, err := url.Parse(m)
	if err != nil {
		return "", err
	}

	matches := btihRE.FindStringSubmatch(parsed.Query().Get("xt"))
	if len(matches) <= 0 {
		return "", ErrHashlessMagnet
	}

	return matches[1], nil
}

func bytesFromDetails(d string) (int, error) {
	re := regexp.MustCompile(`, Size ([^,]+)`)
	match := re.FindStringSubmatch(d)

	if len(match) <= 0 {
		return 0, ErrCannotFindFileSize
	}

	bytes, err := humanize.ParseBigBytes(match[1])
	if err != nil {
		log.Print(err)
		return 0, err
	}

	return int(bytes.Int64()), nil
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/containers/image/v5/docker"
	"github.com/containers/image/v5/transports/alltransports"
	"github.com/containers/image/v5/types"
	"github.com/docker/distribution/reference"
	"github.com/pkg/errors"
	"github.com/urfave/cli"
	"strings"

	"io"
)

// tagListOutput is the output format of (skopeo list-tags), primarily so that we can format it with a simple json.MarshalIndent.
type tagListOutput struct {
	Repository string
	Tags       []string
}

type tagsOptions struct {
	global *globalOptions
	image  *imageOptions
}

func tagsCmd(global *globalOptions) cli.Command {
	sharedFlags, sharedOpts := sharedImageFlags()
	imageFlags, imageOpts := dockerImageFlags(global, sharedOpts, "", "")

	opts := tagsOptions{
		global: global,
		image:  imageOpts,
	}

	return cli.Command{
		Name:  "list-tags",
		Usage: "List tags in the transport/repository specified by the REPOSITORY-NAME",
		Description: `
	Return the list of tags from the transport/repository "REPOSITORY-NAME"

    Supported transports:
	docker

	See skopeo-list-tags(1) section "REPOSITORY NAMES" for the expected format
	`,
		ArgsUsage: "REPOSITORY-NAME",
		Flags:     append(sharedFlags, imageFlags...),
		Action:    commandAction(opts.run),
	}
}

// Customized version of the alltransports.ParseImageName and docker.ParseReference that does not place a default tag in the reference
// Would really love to not have this, but needed to enforce tag-less and digest-less names
func parseDockerRepositoryReference(refString string) (types.ImageReference, error) {
	if !strings.HasPrefix(refString, docker.Transport.Name()+"://") {
		return nil, errors.Errorf("docker: image reference %s does not start with %s://", refString, docker.Transport.Name())
	}

	parts := strings.SplitN(refString, ":", 2)
	if len(parts) != 2 {
		return nil, errors.Errorf(`Invalid image name "%s", expected colon-separated transport:reference`, refString)
	}

	ref, err := reference.ParseNormalizedNamed(strings.TrimPrefix(parts[1], "//"))
	if err != nil {
		return nil, err
	}

	if !reference.IsNameOnly(ref) {
		return nil, errors.New(`No tag or digest allowed in reference`)
	}

	// Checks ok, now return a reference. This is a hack because the tag listing code expects a full image reference even though the tag is ignored
	return docker.NewReference(reference.TagNameOnly(ref))
}

// List the tags from a repository contained in the imgRef reference. Any tag value in the reference is ignored
func listDockerTags(ctx context.Context, sys *types.SystemContext, imgRef types.ImageReference) (string, []string, error) {
	repositoryName := imgRef.DockerReference().Name()

	tags, err := docker.GetRepositoryTags(ctx, sys, imgRef)
	if err != nil {
		return ``, nil, fmt.Errorf("Error listing repository tags: %v", err)
	}
	return repositoryName, tags, nil
}

func (opts *tagsOptions) run(args []string, stdout io.Writer) (retErr error) {
	ctx, cancel := opts.global.commandTimeoutContext()
	defer cancel()

	if len(args) != 1 {
		return errorShouldDisplayUsage{errors.New("Exactly one non-option argument expected")}
	}

	sys, err := opts.image.newSystemContext()
	if err != nil {
		return err
	}

	transport := alltransports.TransportFromImageName(args[0])
	if transport == nil {
		return fmt.Errorf("Invalid %q: does not specify a transport", args[0])
	}

	if transport.Name() != docker.Transport.Name() {
		return fmt.Errorf("Unsupported transport '%v' for tag listing. Only '%v' currently supported", transport.Name(), docker.Transport.Name())
	}

	// Do transport-specific parsing and validation to get an image reference
	imgRef, err := parseDockerRepositoryReference(args[0])
	if err != nil {
		return err
	}

	repositoryName, tagListing, err := listDockerTags(ctx, sys, imgRef)
	if err != nil {
		return err
	}

	outputData := tagListOutput{
		Repository: repositoryName,
		Tags:       tagListing,
	}

	out, err := json.MarshalIndent(outputData, "", "    ")
	if err != nil {
		return err
	}
	_, err = fmt.Fprintf(stdout, "%s\n", string(out))

	return err
}
<commit_msg>Fix wrong import of docker reference<commit_after>package main

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/containers/image/v5/docker"
	"github.com/containers/image/v5/docker/reference"
	"github.com/containers/image/v5/transports/alltransports"
	"github.com/containers/image/v5/types"
	"github.com/pkg/errors"
	"github.com/urfave/cli"
	"strings"

	"io"
)

// tagListOutput is the output format of (skopeo list-tags), primarily so that we can format it with a simple json.MarshalIndent.
type tagListOutput struct {
	Repository string
	Tags       []string
}

type tagsOptions struct {
	global *globalOptions
	image  *imageOptions
}

func tagsCmd(global *globalOptions) cli.Command {
	sharedFlags, sharedOpts := sharedImageFlags()
	imageFlags, imageOpts := dockerImageFlags(global, sharedOpts, "", "")

	opts := tagsOptions{
		global: global,
		image:  imageOpts,
	}

	return cli.Command{
		Name:  "list-tags",
		Usage: "List tags in the transport/repository specified by the REPOSITORY-NAME",
		Description: `
	Return the list of tags from the transport/repository "REPOSITORY-NAME"

    Supported transports:
	docker

	See skopeo-list-tags(1) section "REPOSITORY NAMES" for the expected format
	`,
		ArgsUsage: "REPOSITORY-NAME",
		Flags:     append(sharedFlags, imageFlags...),
		Action:    commandAction(opts.run),
	}
}

// Customized version of the alltransports.ParseImageName and docker.ParseReference that does not place a default tag in the reference
// Would really love to not have this, but needed to enforce tag-less and digest-less names
func parseDockerRepositoryReference(refString string) (types.ImageReference, error) {
	if !strings.HasPrefix(refString, docker.Transport.Name()+"://") {
		return nil, errors.Errorf("docker: image reference %s does not start with %s://", refString, docker.Transport.Name())
	}

	parts := strings.SplitN(refString, ":", 2)
	if len(parts) != 2 {
		return nil, errors.Errorf(`Invalid image name "%s", expected colon-separated transport:reference`, refString)
	}

	ref, err := reference.ParseNormalizedNamed(strings.TrimPrefix(parts[1], "//"))
	if err != nil {
		return nil, err
	}

	if !reference.IsNameOnly(ref) {
		return nil, errors.New(`No tag or digest allowed in reference`)
	}

	// Checks ok, now return a reference. This is a hack because the tag listing code expects a full image reference even though the tag is ignored
	return docker.NewReference(reference.TagNameOnly(ref))
}

// List the tags from a repository contained in the imgRef reference. Any tag value in the reference is ignored
func listDockerTags(ctx context.Context, sys *types.SystemContext, imgRef types.ImageReference) (string, []string, error) {
	repositoryName := imgRef.DockerReference().Name()

	tags, err := docker.GetRepositoryTags(ctx, sys, imgRef)
	if err != nil {
		return ``, nil, fmt.Errorf("Error listing repository tags: %v", err)
	}
	return repositoryName, tags, nil
}

func (opts *tagsOptions) run(args []string, stdout io.Writer) (retErr error) {
	ctx, cancel := opts.global.commandTimeoutContext()
	defer cancel()

	if len(args) != 1 {
		return errorShouldDisplayUsage{errors.New("Exactly one non-option argument expected")}
	}

	sys, err := opts.image.newSystemContext()
	if err != nil {
		return err
	}

	transport := alltransports.TransportFromImageName(args[0])
	if transport == nil {
		return fmt.Errorf("Invalid %q: does not specify a transport", args[0])
	}

	if transport.Name() != docker.Transport.Name() {
		return fmt.Errorf("Unsupported transport '%v' for tag listing. Only '%v' currently supported", transport.Name(), docker.Transport.Name())
	}

	// Do transport-specific parsing and validation to get an image reference
	imgRef, err := parseDockerRepositoryReference(args[0])
	if err != nil {
		return err
	}

	repositoryName, tagListing, err := listDockerTags(ctx, sys, imgRef)
	if err != nil {
		return err
	}

	outputData := tagListOutput{
		Repository: repositoryName,
		Tags:       tagListing,
	}

	out, err := json.MarshalIndent(outputData, "", "    ")
	if err != nil {
		return err
	}
	_, err = fmt.Fprintf(stdout, "%s\n", string(out))

	return err
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/CTSRD-SOAAP/gosoaap"
)

type Analyses []string

func (a *Analyses) Set(value string) error {
	*a = strings.Split(value, ",")
	return nil
}

func (a Analyses) String() string {
	return strings.Join(a, ", ")
}

var (
	intersectionDepth = flag.Int("intersection-depth", 3,
		"how many calls to trace back from a leaf node when looking"+
			" for call graph intersections")
)

func main() {
	//
	// Command-line arguments:
	//
	legend := flag.Bool("legend", false,
		"emit a Dot legend rather than an actual graph")

	analyses := Analyses{"vuln"}
	flag.Var(&analyses, "analyses",
		"SOAAP analysis results to graph (options: "+
			strings.Join(soaap.GraphAnalyses(), ", ")+
			")")

	groupBy := flag.String("group-by", "", "group nodes by file, sandbox, etc.")

	output := flag.String("output", "-", "output file")

	binout := flag.Bool("binary", false, "write binary output")
	simplify := flag.Bool("simplify", false, "simplify callgraph")

	flag.Parse()

	var input string
	switch len(flag.Args()) {
	case 0:
		input = "-"

	case 1:
		input = flag.Args()[0]

	default:
		printUsage()
		return
	}

	//
	// Load input file:
	//
	var f *os.File
	var err error

	if input == "-" {
		f = os.Stdin
	} else {
		f, err = os.Open(input)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error: %s\n", err)
			return
		}
	}

	//
	// Open output file:
	//
	var out *os.File
	if *output == "-" {
		out = os.Stdout
	} else {
		out, err = os.Create(*output)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error: %s\n", err)
			return
		}
	}

	//
	// The call/dataflow graph to transform and output.
	//
	var graph soaap.CallGraph

	//
	// Special case: legend of possible node types.
	//
	if *legend {
		graph = soaap.Legend()

	} else if strings.HasSuffix(f.Name(), ".graph") {

		// Load binary graph file.
		report(fmt.Sprintf("Loading binary graph data from '%s'...", f.Name()))
		graph, err = soaap.LoadGraph(f, report)

	} else {

		// Load SOAAP results.
		report(fmt.Sprintf("Loading SOAAP results from '%s'...", f.Name()))
		graph, err = analyzeResultsFile(f, analyses)
	}

	if err != nil {
		fmt.Fprintf(os.Stderr, "\nerror: %s\n", err)
		os.Exit(1)
	}

	nodes, edges, flows := graph.Size()
	fmt.Printf("Result: %d nodes, %d calls and %d flows\n",
		nodes, edges, flows)

	//
	// Apply any requested transformations:
	//
	if *simplify {
		graph = graph.Simplified()
		nodes, edges, flows = graph.Size()
		fmt.Printf("Simplified: %d nodes, %d calls and %d flows\n",
			nodes, edges, flows)
	}

	//
	// Output the results:
	//
	if *binout {
		err = graph.Save(out)
	} else {
		err = graph.WriteDot(out, *groupBy)
	}

	if err != nil {
		fmt.Fprintf(os.Stderr, "error writing output: %s\n", err)
		os.Exit(1)
	}
}

func analyzeResultsFile(f *os.File, analyses []string) (soaap.CallGraph, error) {
	//
	// Combine callgraphs of the requested analyses:
	//
	results, err := soaap.LoadResults(f, report)
	if err != nil {
		return soaap.CallGraph{}, err
	}

	fmt.Println("Initializing empty call graph")
	graph := soaap.NewCallGraph()

	for _, analysis := range analyses {
		graph, err = soaap.ApplyAnalysis(
			analysis, &graph, &results, *intersectionDepth, report)
	}

	return graph, err
}

func printUsage() {
	fmt.Fprintf(os.Stderr,
		"Usage:  soaap-graph [options] <input file>\n\n")

	fmt.Fprintf(os.Stderr, "Options:\n")
	flag.PrintDefaults()
}

func report(progress string) {
	fmt.Println(progress)
	os.Stdout.Sync()
}
<commit_msg>Let `soaap-graph -legend` box the legend.<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/CTSRD-SOAAP/gosoaap"
)

type Analyses []string

func (a *Analyses) Set(value string) error {
	*a = strings.Split(value, ",")
	return nil
}

func (a Analyses) String() string {
	return strings.Join(a, ", ")
}

var (
	intersectionDepth = flag.Int("intersection-depth", 3,
		"how many calls to trace back from a leaf node when looking"+
			" for call graph intersections")
)

func main() {
	//
	// Command-line arguments:
	//
	legend := flag.Bool("legend", false,
		"emit a Dot legend rather than an actual graph")

	analyses := Analyses{"vuln"}
	flag.Var(&analyses, "analyses",
		"SOAAP analysis results to graph (options: "+
			strings.Join(soaap.GraphAnalyses(), ", ")+
			")")

	groupBy := flag.String("group-by", "", "group nodes by file, sandbox, etc.")

	output := flag.String("output", "-", "output file")

	binout := flag.Bool("binary", false, "write binary output")
	simplify := flag.Bool("simplify", false, "simplify callgraph")

	flag.Parse()

	var input string
	switch len(flag.Args()) {
	case 0:
		input = "-"

	case 1:
		input = flag.Args()[0]

	default:
		printUsage()
		return
	}

	//
	// Load input file:
	//
	var f *os.File
	var err error

	if input == "-" {
		f = os.Stdin
	} else {
		f, err = os.Open(input)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error: %s\n", err)
			return
		}
	}

	//
	// Open output file:
	//
	var out *os.File
	if *output == "-" {
		out = os.Stdout
	} else {
		out, err = os.Create(*output)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error: %s\n", err)
			return
		}
	}

	//
	// The call/dataflow graph to transform and output.
	//
	var graph soaap.CallGraph

	//
	// Special case: legend of possible node types.
	//
	if *legend {
		graph = soaap.Legend()

	} else if strings.HasSuffix(f.Name(), ".graph") {

		// Load binary graph file.
		report(fmt.Sprintf("Loading binary graph data from '%s'...", f.Name()))
		graph, err = soaap.LoadGraph(f, report)

	} else {

		// Load SOAAP results.
		report(fmt.Sprintf("Loading SOAAP results from '%s'...", f.Name()))
		graph, err = analyzeResultsFile(f, analyses)
	}

	if err != nil {
		fmt.Fprintf(os.Stderr, "\nerror: %s\n", err)
		os.Exit(1)
	}

	nodes, edges, flows := graph.Size()
	fmt.Printf("Result: %d nodes, %d calls and %d flows\n",
		nodes, edges, flows)

	//
	// Apply any requested transformations:
	//
	if *simplify {
		graph = graph.Simplified()
		nodes, edges, flows = graph.Size()
		fmt.Printf("Simplified: %d nodes, %d calls and %d flows\n",
			nodes, edges, flows)
	}

	//
	// Output the results:
	//
	grouping := *groupBy
	if *legend {
		grouping = "tags"
	}

	if *binout {
		err = graph.Save(out)
	} else {
		err = graph.WriteDot(out, grouping)
	}

	if err != nil {
		fmt.Fprintf(os.Stderr, "error writing output: %s\n", err)
		os.Exit(1)
	}
}

func analyzeResultsFile(f *os.File, analyses []string) (soaap.CallGraph, error) {
	//
	// Combine callgraphs of the requested analyses:
	//
	results, err := soaap.LoadResults(f, report)
	if err != nil {
		return soaap.CallGraph{}, err
	}

	fmt.Println("Initializing empty call graph")
	graph := soaap.NewCallGraph()

	for _, analysis := range analyses {
		graph, err = soaap.ApplyAnalysis(
			analysis, &graph, &results, *intersectionDepth, report)
	}

	return graph, err
}

func printUsage() {
	fmt.Fprintf(os.Stderr,
		"Usage:  soaap-graph [options] <input file>\n\n")

	fmt.Fprintf(os.Stderr, "Options:\n")
	flag.PrintDefaults()
}

func report(progress string) {
	fmt.Println(progress)
	os.Stdout.Sync()
}
<|endoftext|>


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

// tsuru-admin is under development.
package main

import (
	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/cmd/tsuru-base"
	"github.com/tsuru/tsuru/provision"
	_ "github.com/tsuru/tsuru/provision/docker"
	"os"
)

const (
	version = "0.4.1"
	header  = "Supported-Tsuru-Admin"
)

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header, nil)
	m.Register(tsuru.AppList{})
	m.Register(&tsuru.SetCName{})
	m.Register(&tsuru.UnsetCName{})
	m.Register(&tokenGen{})
	m.Register(&logRemove{})
	m.Register(&changeQuota{})
	m.Register(&platformAdd{})
	m.Register(&platformUpdate{})
	registerProvisionersCommands(m)
	return m
}

func registerProvisionersCommands(m *cmd.Manager) {
	provisioners := provision.Registry()
	for _, p := range provisioners {
		if c, ok := p.(cmd.AdminCommandable); ok {
			commands := c.AdminCommands()
			for _, cmd := range commands {
				m.Register(cmd)
			}
		}
	}
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	args := os.Args[1:]
	manager.Run(args)
}
<commit_msg>cmd/tsuru-admin: bump to 0.4.2<commit_after>// Copyright 2014 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// tsuru-admin is under development.
package main

import (
	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/cmd/tsuru-base"
	"github.com/tsuru/tsuru/provision"
	_ "github.com/tsuru/tsuru/provision/docker"
	"os"
)

const (
	version = "0.4.2"
	header  = "Supported-Tsuru-Admin"
)

func buildManager(name string) *cmd.Manager {
	m := cmd.BuildBaseManager(name, version, header, nil)
	m.Register(tsuru.AppList{})
	m.Register(&tsuru.SetCName{})
	m.Register(&tsuru.UnsetCName{})
	m.Register(&tokenGen{})
	m.Register(&logRemove{})
	m.Register(&changeQuota{})
	m.Register(&platformAdd{})
	m.Register(&platformUpdate{})
	registerProvisionersCommands(m)
	return m
}

func registerProvisionersCommands(m *cmd.Manager) {
	provisioners := provision.Registry()
	for _, p := range provisioners {
		if c, ok := p.(cmd.AdminCommandable); ok {
			commands := c.AdminCommands()
			for _, cmd := range commands {
				m.Register(cmd)
			}
		}
	}
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	args := os.Args[1:]
	manager.Run(args)
}
<|endoftext|>


<commit_before>/*
	This file is part of go-ethereum

	go-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	go-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with go-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @authors
 * 	Jeffrey Wilcke <i@jev.io>
 */
package utils

import (
	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/eth"
	"github.com/ethereum/go-ethereum/ethutil"
	"github.com/ethereum/go-ethereum/event/filter"
	"github.com/ethereum/go-ethereum/logger"
	"github.com/ethereum/go-ethereum/state"
	"github.com/ethereum/go-ethereum/ui/qt"
	"github.com/ethereum/go-ethereum/websocket"
	"github.com/ethereum/go-ethereum/xeth"
)

var wslogger = logger.NewLogger("WS")

func args(v ...interface{}) []interface{} {
	return v
}

type WebSocketServer struct {
	eth           *eth.Ethereum
	filterManager *filter.FilterManager
}

func NewWebSocketServer(eth *eth.Ethereum) *WebSocketServer {
	filterManager := filter.NewFilterManager(eth.EventMux())
	go filterManager.Start()

	return &WebSocketServer{eth, filterManager}
}

func (self *WebSocketServer) Serv() {
	pipe := xeth.NewJSXEth(self.eth)

	wsServ := websocket.NewServer("/eth", ":40404")
	wsServ.MessageFunc(func(c *websocket.Client, msg *websocket.Message) {
		switch msg.Call {
		case "compile":
			data := ethutil.NewValue(msg.Args)
			bcode, err := ethutil.Compile(data.Get(0).Str(), false)
			if err != nil {
				c.Write(args(nil, err.Error()), msg.Id)
			}

			code := ethutil.Bytes2Hex(bcode)
			c.Write(args(code, nil), msg.Id)
		case "eth_blockByNumber":
			args := msg.Arguments()

			block := pipe.BlockByNumber(int32(args.Get(0).Uint()))
			c.Write(block, msg.Id)

		case "eth_blockByHash":
			args := msg.Arguments()

			c.Write(pipe.BlockByHash(args.Get(0).Str()), msg.Id)

		case "eth_transact":
			if mp, ok := msg.Args[0].(map[string]interface{}); ok {
				object := mapToTxParams(mp)
				c.Write(
					args(pipe.Transact(pipe.Key().PrivateKey, object["to"], object["value"], object["gas"], object["gasPrice"], object["data"])),
					msg.Id,
				)

			}
		case "eth_gasPrice":
			c.Write("10000000000000", msg.Id)
		case "eth_coinbase":
			c.Write(pipe.CoinBase(), msg.Id)

		case "eth_listening":
			c.Write(pipe.IsListening(), msg.Id)

		case "eth_mining":
			c.Write(pipe.IsMining(), msg.Id)

		case "eth_peerCount":
			c.Write(pipe.PeerCount(), msg.Id)

		case "eth_countAt":
			args := msg.Arguments()

			c.Write(pipe.TxCountAt(args.Get(0).Str()), msg.Id)

		case "eth_codeAt":
			args := msg.Arguments()

			c.Write(len(pipe.CodeAt(args.Get(0).Str())), msg.Id)

		case "eth_storageAt":
			args := msg.Arguments()

			c.Write(pipe.StorageAt(args.Get(0).Str(), args.Get(1).Str()), msg.Id)

		case "eth_balanceAt":
			args := msg.Arguments()

			c.Write(pipe.BalanceAt(args.Get(0).Str()), msg.Id)

		case "eth_accounts":
			c.Write(pipe.Accounts(), msg.Id)

		case "eth_newFilter":
			if mp, ok := msg.Args[0].(map[string]interface{}); ok {
				var id int
				filter := qt.NewFilterFromMap(mp, self.eth)
				filter.MessageCallback = func(messages state.Messages) {
					c.Event(toMessages(messages), "eth_changed", id)
				}
				id = self.filterManager.InstallFilter(filter)
				c.Write(id, msg.Id)
			}
		case "eth_newFilterString":
			var id int
			filter := core.NewFilter(self.eth)
			filter.BlockCallback = func(block *types.Block) {
				c.Event(nil, "eth_changed", id)
			}
			id = self.filterManager.InstallFilter(filter)
			c.Write(id, msg.Id)
		case "eth_filterLogs":
			filter := self.filterManager.GetFilter(int(msg.Arguments().Get(0).Uint()))
			if filter != nil {
				c.Write(toMessages(filter.Find()), msg.Id)
			}
		}

	})

	wsServ.Listen()
}

func toMessages(messages state.Messages) (msgs []xeth.JSMessage) {
	msgs = make([]xeth.JSMessage, len(messages))
	for i, msg := range messages {
		msgs[i] = xeth.NewJSMessage(msg)
	}

	return
}

func StartWebSockets(eth *eth.Ethereum) {
	wslogger.Infoln("Starting WebSockets")

	sock := NewWebSocketServer(eth)
	go sock.Serv()
}

// TODO This is starting to become a generic method. Move to utils
func mapToTxParams(object map[string]interface{}) map[string]string {
	// Default values
	if object["from"] == nil {
		object["from"] = ""
	}
	if object["to"] == nil {
		object["to"] = ""
	}
	if object["value"] == nil {
		object["value"] = ""
	}
	if object["gas"] == nil {
		object["gas"] = ""
	}
	if object["gasPrice"] == nil {
		object["gasPrice"] = ""
	}

	var dataStr string
	var data []string
	if str, ok := object["data"].(string); ok {
		data = []string{str}
	}

	for _, str := range data {
		if ethutil.IsHex(str) {
			str = str[2:]

			if len(str) != 64 {
				str = ethutil.LeftPadString(str, 64)
			}
		} else {
			str = ethutil.Bytes2Hex(ethutil.LeftPadBytes(ethutil.Big(str).Bytes(), 32))
		}

		dataStr += str
	}
	object["data"] = dataStr

	conv := make(map[string]string)
	for key, value := range object {
		if v, ok := value.(string); ok {
			conv[key] = v
		}
	}

	return conv
}
<commit_msg>removed accidental qt dep<commit_after>/*
	This file is part of go-ethereum

	go-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	go-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with go-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @authors
 * 	Jeffrey Wilcke <i@jev.io>
 */
package utils

import (
	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/eth"
	"github.com/ethereum/go-ethereum/ethutil"
	"github.com/ethereum/go-ethereum/event/filter"
	"github.com/ethereum/go-ethereum/logger"
	"github.com/ethereum/go-ethereum/state"
	"github.com/ethereum/go-ethereum/ui"
	"github.com/ethereum/go-ethereum/websocket"
	"github.com/ethereum/go-ethereum/xeth"
)

var wslogger = logger.NewLogger("WS")

func args(v ...interface{}) []interface{} {
	return v
}

type WebSocketServer struct {
	eth           *eth.Ethereum
	filterManager *filter.FilterManager
}

func NewWebSocketServer(eth *eth.Ethereum) *WebSocketServer {
	filterManager := filter.NewFilterManager(eth.EventMux())
	go filterManager.Start()

	return &WebSocketServer{eth, filterManager}
}

func (self *WebSocketServer) Serv() {
	pipe := xeth.NewJSXEth(self.eth)

	wsServ := websocket.NewServer("/eth", ":40404")
	wsServ.MessageFunc(func(c *websocket.Client, msg *websocket.Message) {
		switch msg.Call {
		case "compile":
			data := ethutil.NewValue(msg.Args)
			bcode, err := ethutil.Compile(data.Get(0).Str(), false)
			if err != nil {
				c.Write(args(nil, err.Error()), msg.Id)
			}

			code := ethutil.Bytes2Hex(bcode)
			c.Write(args(code, nil), msg.Id)
		case "eth_blockByNumber":
			args := msg.Arguments()

			block := pipe.BlockByNumber(int32(args.Get(0).Uint()))
			c.Write(block, msg.Id)

		case "eth_blockByHash":
			args := msg.Arguments()

			c.Write(pipe.BlockByHash(args.Get(0).Str()), msg.Id)

		case "eth_transact":
			if mp, ok := msg.Args[0].(map[string]interface{}); ok {
				object := mapToTxParams(mp)
				c.Write(
					args(pipe.Transact(pipe.Key().PrivateKey, object["to"], object["value"], object["gas"], object["gasPrice"], object["data"])),
					msg.Id,
				)

			}
		case "eth_gasPrice":
			c.Write("10000000000000", msg.Id)
		case "eth_coinbase":
			c.Write(pipe.CoinBase(), msg.Id)

		case "eth_listening":
			c.Write(pipe.IsListening(), msg.Id)

		case "eth_mining":
			c.Write(pipe.IsMining(), msg.Id)

		case "eth_peerCount":
			c.Write(pipe.PeerCount(), msg.Id)

		case "eth_countAt":
			args := msg.Arguments()

			c.Write(pipe.TxCountAt(args.Get(0).Str()), msg.Id)

		case "eth_codeAt":
			args := msg.Arguments()

			c.Write(len(pipe.CodeAt(args.Get(0).Str())), msg.Id)

		case "eth_storageAt":
			args := msg.Arguments()

			c.Write(pipe.StorageAt(args.Get(0).Str(), args.Get(1).Str()), msg.Id)

		case "eth_balanceAt":
			args := msg.Arguments()

			c.Write(pipe.BalanceAt(args.Get(0).Str()), msg.Id)

		case "eth_accounts":
			c.Write(pipe.Accounts(), msg.Id)

		case "eth_newFilter":
			if mp, ok := msg.Args[0].(map[string]interface{}); ok {
				var id int
				filter := ui.NewFilterFromMap(mp, self.eth)
				filter.MessageCallback = func(messages state.Messages) {
					c.Event(toMessages(messages), "eth_changed", id)
				}
				id = self.filterManager.InstallFilter(filter)
				c.Write(id, msg.Id)
			}
		case "eth_newFilterString":
			var id int
			filter := core.NewFilter(self.eth)
			filter.BlockCallback = func(block *types.Block) {
				c.Event(nil, "eth_changed", id)
			}
			id = self.filterManager.InstallFilter(filter)
			c.Write(id, msg.Id)
		case "eth_filterLogs":
			filter := self.filterManager.GetFilter(int(msg.Arguments().Get(0).Uint()))
			if filter != nil {
				c.Write(toMessages(filter.Find()), msg.Id)
			}
		}

	})

	wsServ.Listen()
}

func toMessages(messages state.Messages) (msgs []xeth.JSMessage) {
	msgs = make([]xeth.JSMessage, len(messages))
	for i, msg := range messages {
		msgs[i] = xeth.NewJSMessage(msg)
	}

	return
}

func StartWebSockets(eth *eth.Ethereum) {
	wslogger.Infoln("Starting WebSockets")

	sock := NewWebSocketServer(eth)
	go sock.Serv()
}

// TODO This is starting to become a generic method. Move to utils
func mapToTxParams(object map[string]interface{}) map[string]string {
	// Default values
	if object["from"] == nil {
		object["from"] = ""
	}
	if object["to"] == nil {
		object["to"] = ""
	}
	if object["value"] == nil {
		object["value"] = ""
	}
	if object["gas"] == nil {
		object["gas"] = ""
	}
	if object["gasPrice"] == nil {
		object["gasPrice"] = ""
	}

	var dataStr string
	var data []string
	if str, ok := object["data"].(string); ok {
		data = []string{str}
	}

	for _, str := range data {
		if ethutil.IsHex(str) {
			str = str[2:]

			if len(str) != 64 {
				str = ethutil.LeftPadString(str, 64)
			}
		} else {
			str = ethutil.Bytes2Hex(ethutil.LeftPadBytes(ethutil.Big(str).Bytes(), 32))
		}

		dataStr += str
	}
	object["data"] = dataStr

	conv := make(map[string]string)
	for key, value := range object {
		if v, ok := value.(string); ok {
			conv[key] = v
		}
	}

	return conv
}
<|endoftext|>


<commit_before>package sqlx

import (
	"flag"
	"log"
	"os"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3"
)

var db *sqlx.DB

var sqlite3 = `
CREATE TABLE users (
    id integer NOT NULL PRIMARY KEY,
    name varchar(255) NOT NULL,
    recovery char(36) NOT NULL DEFAULT "",
    digest blob NOT NULL,
    email varchar(255) NOT NULL UNIQUE,
    location varchar(255) NOT NULL DEFAULT "UTC"
);

CREATE TABLE posts (
    id integer NOT NULL PRIMARY KEY,
    title varchar(255) NOT NULL,
    content text NOT NULL,
    markdown text NOT NULL,
    slug varchar(255) NOT NULL,
    author integer NOT NULL,
    excerpt varchar(255) NOT NULL,
    viewcount integer unsigned NOT NULL DEFAULT 0,
    published bool NOT NULL DEFAULT false,
    created integer unsigned NOT NULL,
    updated integer unsigned NOT NULL,
    timeoffset integer NOT NULL DEFAULT 0
);`

var postgres = `
CREATE TABLE "users" (
    "id" serial NOT NULL PRIMARY KEY,
    "name" varchar(255) NOT NULL,
    "recovery" char(36) NOT NULL DEFAULT '',
    "digest" bytea NOT NULL,
    "email" varchar(255) NOT NULL UNIQUE,
    "location" varchar(255) NOT NULL DEFAULT 'UTC'
);

CREATE TABLE "posts" (
    "id" serial NOT NULL PRIMARY KEY,
    "title" varchar(255) NOT NULL,
    "content" text NOT NULL,
    "markdown" text NOT NULL,
    "slug" varchar(255) NOT NULL,
    "author" integer NOT NULL,
    "excerpt" varchar(255) NOT NULL,
    "viewcount" integer NOT NULL DEFAULT '0',
    "published" bool NOT NULL DEFAULT false,
    "created" integer NOT NULL,
    "updated" integer NOT NULL,
    "timeoffset" integer NOT NULL DEFAULT '0'
);`

// var mysql = `
// CREATE DATABASE vertigo;
// USE vertigo;

// CREATE TABLE IF NOT EXISTS users (
//     id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
//     name varchar(255) NOT NULL,
//     recovery char(36) NOT NULL DEFAULT "",
//     digest blob NOT NULL,
//     email varchar(255) NOT NULL UNIQUE,
//     location varchar(255) NOT NULL DEFAULT "UTC"
// );

// CREATE TABLE IF NOT EXISTS posts (
//     id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
//     title varchar(255) NOT NULL,
//     content text NOT NULL,
//     markdown text NOT NULL,
//     slug varchar(255) NOT NULL,
//     author integer NOT NULL,
//     excerpt varchar(255) NOT NULL,
//     viewcount integer unsigned NOT NULL DEFAULT 0,
//     published bool NOT NULL DEFAULT false,
//     created integer unsigned NOT NULL,
//     updated integer unsigned NOT NULL,
//     timeoffset integer NOT NULL DEFAULT 0
// );`

func Drop() {
	db.MustExec("DROP TABLE users")
	db.MustExec("DROP TABLE posts")
	os.Remove("settings.json")
	os.Remove("vertigo.db")
}

var Driver = flag.String("driver", "sqlite3", "Database driver to use (sqlite3, mysql, postgres)")
var Source = flag.String("source", "vertigo.db", "Database data source")

func init() {

	flag.Parse()

	conn, err := sqlx.Connect(*Driver, *Source)
	if err != nil {
		log.Fatal("sqlx connect:", err)
	}

	var schema string
	switch *Driver {
	case "sqlite3":
		schema = sqlite3
	// case "mysql":
	//     schema = mysql
	case "postgres":
		schema = postgres
	}

	conn.Exec(schema)

	log.Println("sqlx: using", *Driver)

	db = conn
}
<commit_msg>add experimental mysql driver<commit_after>package sqlx

import (
	"flag"
	"log"
	"net/url"
	"os"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3"
)

var db *sqlx.DB

var sqlite3 = `
CREATE TABLE users (
    id integer NOT NULL PRIMARY KEY,
    name varchar(255) NOT NULL,
    recovery char(36) NOT NULL DEFAULT "",
    digest blob NOT NULL,
    email varchar(255) NOT NULL UNIQUE,
    location varchar(255) NOT NULL DEFAULT "UTC"
);

CREATE TABLE posts (
    id integer NOT NULL PRIMARY KEY,
    title varchar(255) NOT NULL,
    content text NOT NULL,
    markdown text NOT NULL,
    slug varchar(255) NOT NULL,
    author integer NOT NULL,
    excerpt varchar(255) NOT NULL,
    viewcount integer unsigned NOT NULL DEFAULT 0,
    published bool NOT NULL DEFAULT false,
    created integer unsigned NOT NULL,
    updated integer unsigned NOT NULL,
    timeoffset integer NOT NULL DEFAULT 0
);`

var postgres = `
CREATE TABLE "users" (
    "id" serial NOT NULL PRIMARY KEY,
    "name" varchar(255) NOT NULL,
    "recovery" char(36) NOT NULL DEFAULT '',
    "digest" bytea NOT NULL,
    "email" varchar(255) NOT NULL UNIQUE,
    "location" varchar(255) NOT NULL DEFAULT 'UTC'
);

CREATE TABLE "posts" (
    "id" serial NOT NULL PRIMARY KEY,
    "title" varchar(255) NOT NULL,
    "content" text NOT NULL,
    "markdown" text NOT NULL,
    "slug" varchar(255) NOT NULL,
    "author" integer NOT NULL,
    "excerpt" varchar(255) NOT NULL,
    "viewcount" integer NOT NULL DEFAULT '0',
    "published" bool NOT NULL DEFAULT false,
    "created" integer NOT NULL,
    "updated" integer NOT NULL,
    "timeoffset" integer NOT NULL DEFAULT '0'
);`

var mysql = `
CREATE DATABASE vertigo;
USE vertigo;

CREATE TABLE IF NOT EXISTS users (
    id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name varchar(255) NOT NULL,
    recovery char(36) NOT NULL DEFAULT "",
    digest blob NOT NULL,
    email varchar(255) NOT NULL UNIQUE,
    location varchar(255) NOT NULL DEFAULT "UTC"
);

CREATE TABLE IF NOT EXISTS posts (
    id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
    title varchar(255) NOT NULL,
    content text NOT NULL,
    markdown text NOT NULL,
    slug varchar(255) NOT NULL,
    author integer NOT NULL,
    excerpt varchar(255) NOT NULL,
    viewcount integer unsigned NOT NULL DEFAULT 0,
    published bool NOT NULL DEFAULT false,
    created integer unsigned NOT NULL,
    updated integer unsigned NOT NULL,
    timeoffset integer NOT NULL DEFAULT 0
);`

func Drop() {
	db.MustExec("DROP TABLE users")
	db.MustExec("DROP TABLE posts")
	os.Remove("settings.json")
	os.Remove("vertigo.db")
}

var Driver = flag.String("driver", "sqlite3", "Database driver to use (sqlite3, mysql, postgres)")
var Source = flag.String("source", "vertigo.db", "Database data source")

func connect(driver, source string) {
	conn, err := sqlx.Connect(driver, source)
	if err != nil {
		log.Fatal("sqlx connect:", err)
	}

	var schema string
	switch driver {
	case "sqlite3":
		schema = sqlite3
	case "mysql":
		schema = mysql
	case "postgres":
		schema = postgres
	}

	conn.Exec(schema)

	log.Println("sqlx: using", driver)

	db = conn
}

func init() {

	flag.Parse()

	log.Println(*Driver, *Source)

	if os.Getenv("DATABASE_URL") != "" {
		u, err := url.Parse(os.Getenv("DATABASE_URL"))
		if err != nil {
			log.Fatal("database url parameter could not be parsed")
		}
		if u.Scheme != "postgres" && u.Scheme != "mysql" {
			log.Fatal("unsupported database type")
		}
		connect(u.Scheme, os.Getenv("DATABASE_URL"))
		return
	}

	connect(*Driver, *Source)
}
<|endoftext|>


<commit_before><commit_msg>fixing random and reflexion<commit_after><|endoftext|>