<commit_before>package main

import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"reflect"
	"strings"

	"github.com/spf13/cobra"

	"github.com/NebulousLabs/Sia/api"
	"github.com/NebulousLabs/Sia/build"
)

var (
	addr         string
	force        bool
	initPassword bool
)

// apiGet wraps a GET request with a status code check, such that if the GET does
// not return 200, the error will be read and returned. The response body is
// not closed.
func apiGet(call string) (*http.Response, error) {
	if host, port, _ := net.SplitHostPort(addr); host == "" {
		addr = net.JoinHostPort("localhost", port)
	}
	resp, err := api.HttpGET("http://" + addr + call)
	if err != nil {
		return nil, errors.New("no response from daemon")
	}
	// check error code
	if resp.StatusCode == http.StatusNotFound {
		resp.Body.Close()
		err = errors.New("API call not recognized: " + call)
	} else if resp.StatusCode != http.StatusOK {
		errResp, _ := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		err = errors.New(strings.TrimSpace(string(errResp)))
	}
	return resp, err
}

// getAPI makes a GET API call and decodes the response.
func getAPI(call string, obj interface{}) error {
	resp, err := apiGet(call)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	err = json.NewDecoder(resp.Body).Decode(obj)
	if err != nil {
		return err
	}
	return nil
}

// get makes an API call and discards the response.
func get(call string) error {
	resp, err := apiGet(call)
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}

// apiPost wraps a POST request with a status code check, such that if the POST
// does not return 200, the error will be read and returned. The response body
// is not closed.
func apiPost(call, vals string) (*http.Response, error) {
	if host, port, _ := net.SplitHostPort(addr); host == "" {
		addr = net.JoinHostPort("localhost", port)
	}

	resp, err := api.HttpPOST("http://"+addr+call, vals)
	if err != nil {
		return nil, errors.New("no response from daemon")
	}
	// check error code
	if resp.StatusCode == http.StatusNotFound {
		resp.Body.Close()
		err = errors.New("API call not recognized: " + call)
	} else if resp.StatusCode != http.StatusOK {
		errResp, _ := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		err = errors.New(strings.TrimSpace(string(errResp)))
	}
	return resp, err
}

// postResp makes a POST API call and decodes the response.
func postResp(call, vals string, obj interface{}) error {
	resp, err := apiPost(call, vals)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	err = json.NewDecoder(resp.Body).Decode(obj)
	if err != nil {
		return err
	}
	return nil
}

func post(call, vals string) error {
	resp, err := apiPost(call, vals)
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}

// wrap wraps a generic command with a check that the command has been
// passed the correct number of arguments. The command must take only strings
// as arguments.
func wrap(fn interface{}) func(*cobra.Command, []string) {
	fnVal, fnType := reflect.ValueOf(fn), reflect.TypeOf(fn)
	if fnType.Kind() != reflect.Func {
		panic("wrapped function has wrong type signature")
	}
	for i := 0; i < fnType.NumIn(); i++ {
		if fnType.In(i).Kind() != reflect.String {
			panic("wrapped function has wrong type signature")
		}
	}

	return func(cmd *cobra.Command, args []string) {
		if len(args) != fnType.NumIn() {
			cmd.Usage()
			return
		}
		argVals := make([]reflect.Value, fnType.NumIn())
		for i := range args {
			argVals[i] = reflect.ValueOf(args[i])
		}
		fnVal.Call(argVals)
	}
}

func version(*cobra.Command, []string) {
	println("Sia Client v" + build.Version)
}

func main() {
	root := &cobra.Command{
		Use:   os.Args[0],
		Short: "Sia Client v" + build.Version,
		Long:  "Sia Client v" + build.Version,
		Run:   version,
	}

	// create command tree
	root.AddCommand(&cobra.Command{
		Use:   "version",
		Short: "Print version information",
		Long:  "Print version information.",
		Run:   version,
	})

	root.AddCommand(hostCmd)
	hostCmd.AddCommand(hostConfigCmd, hostAnnounceCmd, hostStatusCmd)

	root.AddCommand(hostdbCmd)
	hostCmd.AddCommand(hostdbCmd)

	root.AddCommand(minerCmd)
	minerCmd.AddCommand(minerStartCmd, minerStopCmd, minerStatusCmd)

	root.AddCommand(walletCmd)
	walletCmd.AddCommand(walletAddressCmd, walletAddressesCmd, walletInitCmd,
		walletLoadCmd, walletLockCmd, walletSeedsCmd, walletSendCmd,
		walletStatusCmd, walletUnlockCmd)
	walletInitCmd.Flags().BoolVarP(&initPassword, "password", "p", false, "Prompt for a custom password")
	walletLoadCmd.AddCommand(walletLoad033xCmd, walletLoadSeedCmd, walletLoadSiagCmd)

	root.AddCommand(renterCmd)
	renterCmd.AddCommand(renterDownloadQueueCmd, renterFilesDeleteCmd, renterFilesDownloadCmd,
		renterFilesListCmd, renterFilesLoadCmd, renterFilesLoadASCIICmd, renterFilesRenameCmd,
		renterFilesShareCmd, renterFilesShareASCIICmd, renterFilesUploadCmd)

	root.AddCommand(gatewayCmd)
	gatewayCmd.AddCommand(gatewayAddCmd, gatewayRemoveCmd, gatewayStatusCmd)

	root.AddCommand(updateCmd)
	updateCmd.AddCommand(updateCheckCmd, updateApplyCmd)

	// consensus cmds have no leading qualifier
	root.AddCommand(consensusStatusCmd)
	root.AddCommand(stopCmd)

	// parse flags
	root.PersistentFlags().StringVarP(&addr, "addr", "a", "localhost:9980", "which host/port to communicate with (i.e. the host/port siad is listening on)")
	root.PersistentFlags().BoolVarP(&force, "force", "f", false, "force certain commands")

	// run
	root.Execute()
}
<commit_msg>remove force flag<commit_after>package main

import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"reflect"
	"strings"

	"github.com/spf13/cobra"

	"github.com/NebulousLabs/Sia/api"
	"github.com/NebulousLabs/Sia/build"
)

var (
	addr         string
	initPassword bool
)

// apiGet wraps a GET request with a status code check, such that if the GET does
// not return 200, the error will be read and returned. The response body is
// not closed.
func apiGet(call string) (*http.Response, error) {
	if host, port, _ := net.SplitHostPort(addr); host == "" {
		addr = net.JoinHostPort("localhost", port)
	}
	resp, err := api.HttpGET("http://" + addr + call)
	if err != nil {
		return nil, errors.New("no response from daemon")
	}
	// check error code
	if resp.StatusCode == http.StatusNotFound {
		resp.Body.Close()
		err = errors.New("API call not recognized: " + call)
	} else if resp.StatusCode != http.StatusOK {
		errResp, _ := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		err = errors.New(strings.TrimSpace(string(errResp)))
	}
	return resp, err
}

// getAPI makes a GET API call and decodes the response.
func getAPI(call string, obj interface{}) error {
	resp, err := apiGet(call)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	err = json.NewDecoder(resp.Body).Decode(obj)
	if err != nil {
		return err
	}
	return nil
}

// get makes an API call and discards the response.
func get(call string) error {
	resp, err := apiGet(call)
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}

// apiPost wraps a POST request with a status code check, such that if the POST
// does not return 200, the error will be read and returned. The response body
// is not closed.
func apiPost(call, vals string) (*http.Response, error) {
	if host, port, _ := net.SplitHostPort(addr); host == "" {
		addr = net.JoinHostPort("localhost", port)
	}

	resp, err := api.HttpPOST("http://"+addr+call, vals)
	if err != nil {
		return nil, errors.New("no response from daemon")
	}
	// check error code
	if resp.StatusCode == http.StatusNotFound {
		resp.Body.Close()
		err = errors.New("API call not recognized: " + call)
	} else if resp.StatusCode != http.StatusOK {
		errResp, _ := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		err = errors.New(strings.TrimSpace(string(errResp)))
	}
	return resp, err
}

// postResp makes a POST API call and decodes the response.
func postResp(call, vals string, obj interface{}) error {
	resp, err := apiPost(call, vals)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	err = json.NewDecoder(resp.Body).Decode(obj)
	if err != nil {
		return err
	}
	return nil
}

func post(call, vals string) error {
	resp, err := apiPost(call, vals)
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}

// wrap wraps a generic command with a check that the command has been
// passed the correct number of arguments. The command must take only strings
// as arguments.
func wrap(fn interface{}) func(*cobra.Command, []string) {
	fnVal, fnType := reflect.ValueOf(fn), reflect.TypeOf(fn)
	if fnType.Kind() != reflect.Func {
		panic("wrapped function has wrong type signature")
	}
	for i := 0; i < fnType.NumIn(); i++ {
		if fnType.In(i).Kind() != reflect.String {
			panic("wrapped function has wrong type signature")
		}
	}

	return func(cmd *cobra.Command, args []string) {
		if len(args) != fnType.NumIn() {
			cmd.Usage()
			return
		}
		argVals := make([]reflect.Value, fnType.NumIn())
		for i := range args {
			argVals[i] = reflect.ValueOf(args[i])
		}
		fnVal.Call(argVals)
	}
}

func version(*cobra.Command, []string) {
	println("Sia Client v" + build.Version)
}

func main() {
	root := &cobra.Command{
		Use:   os.Args[0],
		Short: "Sia Client v" + build.Version,
		Long:  "Sia Client v" + build.Version,
		Run:   version,
	}

	// create command tree
	root.AddCommand(&cobra.Command{
		Use:   "version",
		Short: "Print version information",
		Long:  "Print version information.",
		Run:   version,
	})

	root.AddCommand(hostCmd)
	hostCmd.AddCommand(hostConfigCmd, hostAnnounceCmd, hostStatusCmd)

	root.AddCommand(hostdbCmd)
	hostCmd.AddCommand(hostdbCmd)

	root.AddCommand(minerCmd)
	minerCmd.AddCommand(minerStartCmd, minerStopCmd, minerStatusCmd)

	root.AddCommand(walletCmd)
	walletCmd.AddCommand(walletAddressCmd, walletAddressesCmd, walletInitCmd,
		walletLoadCmd, walletLockCmd, walletSeedsCmd, walletSendCmd,
		walletStatusCmd, walletUnlockCmd)
	walletInitCmd.Flags().BoolVarP(&initPassword, "password", "p", false, "Prompt for a custom password")
	walletLoadCmd.AddCommand(walletLoad033xCmd, walletLoadSeedCmd, walletLoadSiagCmd)

	root.AddCommand(renterCmd)
	renterCmd.AddCommand(renterDownloadQueueCmd, renterFilesDeleteCmd, renterFilesDownloadCmd,
		renterFilesListCmd, renterFilesLoadCmd, renterFilesLoadASCIICmd, renterFilesRenameCmd,
		renterFilesShareCmd, renterFilesShareASCIICmd, renterFilesUploadCmd)

	root.AddCommand(gatewayCmd)
	gatewayCmd.AddCommand(gatewayAddCmd, gatewayRemoveCmd, gatewayStatusCmd)

	root.AddCommand(updateCmd)
	updateCmd.AddCommand(updateCheckCmd, updateApplyCmd)

	// consensus cmds have no leading qualifier
	root.AddCommand(consensusStatusCmd)
	root.AddCommand(stopCmd)

	// parse flags
	root.PersistentFlags().StringVarP(&addr, "addr", "a", "localhost:9980", "which host/port to communicate with (i.e. the host/port siad is listening on)")

	// run
	root.Execute()
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"json"
	"os"
	"time"
	"./flunky"
)

var Usage = func() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	flag.PrintDefaults()
	os.Exit(0)
}

var server string
var verbose bool
var help bool
var image string
var wait bool
var minutesTimeout int64
var extra string

func init() {
	flag.BoolVar(&help, "h", false, "print usage")
	flag.BoolVar(&verbose, "v", false, "print debug information")
	flag.StringVar(&server, "S", "http://localhost:8080", "server base URL")
	flag.StringVar(&image, "i", "", "image")
	flag.BoolVar(&wait, "w", false, "Wait for build completion")
	flag.StringVar(&extra, "e", "", "Extradata for allocation")
	flag.Int64Var(&minutesTimeout, "t", 45, "Allocation timeout in minutes")
}

type ctlmsg struct {
	Addresses []string
	Image     string
	Extra     map[string]string
}

type sctlmsg struct {
	Address string
	Image   string
	Extra   map[string]string
}

type infoMsg struct {
	Time    int64
	Message string
	MsgType string
}

func (msg *infoMsg) Format (client string) (string) {
	strval := fmt.Sprintf("%s: %s: Node: %s: %s", msg.MsgType, time.SecondsToUTC(msg.Time).Format(time.UnixDate), client, msg.Message)
	return strval
}

type statusMessage struct {
	Status string
	Info   []infoMsg
}

type readyBailNode struct {
	Ready, Bail, Printed bool
}

func (status *readyBailNode) interpretPoll(status string) {
	if status == "Ready" {
		status.Ready = true
	} else if status == "Cancel" {
		status.Bail = true
	}
}

func determineDone(readyBail []readyBailNode) bool {
	done := true
	for i := 0; i < len(readyBail); i++ {
		done = done && (readyBail[i].Ready || readyBail[i].Bail)
	}
	return done
}

func pollForStatusMessage(pos int, node string, readyBail []readyBailNode, bs *flunky.BuildServer) {
	cm := new(sctlmsg)
	cm.Address = node
	js, _ := json.Marshal(cm)
	buf := bytes.NewBufferString(string(js))
	ret, _ := bs.Post("/status", buf)
	tmpStatusMessage := new(statusMessage)
	json.Unmarshal(ret, tmpStatusMessage)

	readyBail[pos].interpretPoll(tmpStatusMessage.Status)
	printStatusMessage(node, &readyBail[pos], tmpStatusMessage)
}

func pollForMessages(cancelTime int64, addresses []string, readyBail []readyBailNode, bs *flunky.BuildServer) {
	done := false
	for time.Seconds() < cancelTime && !done {
		time.Sleep(10000000000)
		for pos, value := range addresses {
			pollForStatusMessage(pos, value, readyBail, bs)
		}
		done = determineDone(readyBail)
	}
}

func printStatusMessage(node string, readyBail *readyBailNode, tmpStatusMessage *statusMessage) {
	for _, value := range tmpStatusMessage.Info {
		fmt.Fprintf(os.Stdout, "%s\n", value.Format(node))
	}

	if readyBail.Ready && !readyBail.Printed {
		fmt.Fprintf(os.Stdout, "NODE: %s TIME: %s STATUS: Ready \n", node, time.UTC().Format(time.UnixDate))
		readyBail.Printed = true
	} else if readyBail.Bail && !readyBail.Printed {
		fmt.Fprintf(os.Stdout, "NODE: %s TIME: %s STATUS: Failed \n", node, time.UTC().Format(time.UnixDate))
		readyBail.Printed = true
	} else {
		fmt.Fprintf(os.Stdout, "NODE: %s TIME: %s STATUS: Building \n", node, time.UTC().Format(time.UnixDate))
	}
}

func main() {
	flag.Parse()
	if help || minutesTimeout < 1 {
		Usage()
		os.Exit(0)
	}

	secondsTimeout := minutesTimeout * 60
	cancelTime := time.Seconds() + secondsTimeout
	addresses := flag.Args()
	readyBail := make([]readyBailNode, len(addresses))

	bs := flunky.NewBuildServer(server, verbose)

	bs.DebugLog(fmt.Sprintf("Server is %s", server))

	bs.DebugLog(fmt.Sprintf("Allocating hosts: %s", flag.Args()))

	if image == "" {
		fmt.Fprintf(os.Stderr, "-i option is required\n")
		Usage()
		os.Exit(1)
	}

	cm := new(ctlmsg)
	cm.Image = image
	cm.Addresses = addresses
	// FIXME: need to add in extradata
	js, _ := json.Marshal(cm)
	buf := bytes.NewBufferString(string(js))
	_, _ = bs.Post("/ctl", buf)

	pollForMessages(cancelTime, addresses, readyBail, bs)
	fmt.Fprintf(os.Stdout, "Done allocating your nodes. Report failed builds to your system administrator.\n")
}
<commit_msg>fctl: fix thinko<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"json"
	"os"
	"time"
	"./flunky"
)

var Usage = func() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	flag.PrintDefaults()
	os.Exit(0)
}

var server string
var verbose bool
var help bool
var image string
var wait bool
var minutesTimeout int64
var extra string

func init() {
	flag.BoolVar(&help, "h", false, "print usage")
	flag.BoolVar(&verbose, "v", false, "print debug information")
	flag.StringVar(&server, "S", "http://localhost:8080", "server base URL")
	flag.StringVar(&image, "i", "", "image")
	flag.BoolVar(&wait, "w", false, "Wait for build completion")
	flag.StringVar(&extra, "e", "", "Extradata for allocation")
	flag.Int64Var(&minutesTimeout, "t", 45, "Allocation timeout in minutes")
}

type ctlmsg struct {
	Addresses []string
	Image     string
	Extra     map[string]string
}

type sctlmsg struct {
	Address string
	Image   string
	Extra   map[string]string
}

type infoMsg struct {
	Time    int64
	Message string
	MsgType string
}

func (msg *infoMsg) Format (client string) (string) {
	strval := fmt.Sprintf("%s: %s: Node: %s: %s", msg.MsgType, time.SecondsToUTC(msg.Time).Format(time.UnixDate), client, msg.Message)
	return strval
}

type statusMessage struct {
	Status string
	Info   []infoMsg
}

type readyBailNode struct {
	Ready, Bail, Printed bool
}

func (rbn *readyBailNode) interpretPoll(status string) {
	if status == "Ready" {
		rbn.Ready = true
	} else if status == "Cancel" {
		rbn.Bail = true
	}
}

func determineDone(readyBail []readyBailNode) bool {
	done := true
	for i := 0; i < len(readyBail); i++ {
		done = done && (readyBail[i].Ready || readyBail[i].Bail)
	}
	return done
}

func pollForStatusMessage(pos int, node string, readyBail []readyBailNode, bs *flunky.BuildServer) {
	cm := new(sctlmsg)
	cm.Address = node
	js, _ := json.Marshal(cm)
	buf := bytes.NewBufferString(string(js))
	ret, _ := bs.Post("/status", buf)
	tmpStatusMessage := new(statusMessage)
	json.Unmarshal(ret, tmpStatusMessage)

	readyBail[pos].interpretPoll(tmpStatusMessage.Status)
	printStatusMessage(node, &readyBail[pos], tmpStatusMessage)
}

func pollForMessages(cancelTime int64, addresses []string, readyBail []readyBailNode, bs *flunky.BuildServer) {
	done := false
	for time.Seconds() < cancelTime && !done {
		time.Sleep(10000000000)
		for pos, value := range addresses {
			pollForStatusMessage(pos, value, readyBail, bs)
		}
		done = determineDone(readyBail)
	}
}

func printStatusMessage(node string, readyBail *readyBailNode, tmpStatusMessage *statusMessage) {
	for _, value := range tmpStatusMessage.Info {
		fmt.Fprintf(os.Stdout, "%s\n", value.Format(node))
	}

	if readyBail.Ready && !readyBail.Printed {
		fmt.Fprintf(os.Stdout, "NODE: %s TIME: %s STATUS: Ready \n", node, time.UTC().Format(time.UnixDate))
		readyBail.Printed = true
	} else if readyBail.Bail && !readyBail.Printed {
		fmt.Fprintf(os.Stdout, "NODE: %s TIME: %s STATUS: Failed \n", node, time.UTC().Format(time.UnixDate))
		readyBail.Printed = true
	} else {
		fmt.Fprintf(os.Stdout, "NODE: %s TIME: %s STATUS: Building \n", node, time.UTC().Format(time.UnixDate))
	}
}

func main() {
	flag.Parse()
	if help || minutesTimeout < 1 {
		Usage()
		os.Exit(0)
	}

	secondsTimeout := minutesTimeout * 60
	cancelTime := time.Seconds() + secondsTimeout
	addresses := flag.Args()
	readyBail := make([]readyBailNode, len(addresses))

	bs := flunky.NewBuildServer(server, verbose)

	bs.DebugLog(fmt.Sprintf("Server is %s", server))

	bs.DebugLog(fmt.Sprintf("Allocating hosts: %s", flag.Args()))

	if image == "" {
		fmt.Fprintf(os.Stderr, "-i option is required\n")
		Usage()
		os.Exit(1)
	}

	cm := new(ctlmsg)
	cm.Image = image
	cm.Addresses = addresses
	// FIXME: need to add in extradata
	js, _ := json.Marshal(cm)
	buf := bytes.NewBufferString(string(js))
	_, _ = bs.Post("/ctl", buf)

	pollForMessages(cancelTime, addresses, readyBail, bs)
	fmt.Fprintf(os.Stdout, "Done allocating your nodes. Report failed builds to your system administrator.\n")
}
<|endoftext|>


<commit_before>package client

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"

	"github.com/docker/distribution"
	"github.com/docker/distribution/digest"
)

type httpLayerUpload struct {
	repo   distribution.Repository
	client *http.Client

	uuid      string
	startedAt time.Time

	location string // always the last value of the location header.
	offset   int64
	closed   bool
}

func (hlu *httpLayerUpload) handleErrorResponse(resp *http.Response) error {
	if resp.StatusCode == http.StatusNotFound {
		return &BlobUploadNotFoundError{Location: hlu.location}
	}
	return handleErrorResponse(resp)
}

func (hlu *httpLayerUpload) ReadFrom(r io.Reader) (n int64, err error) {
	req, err := http.NewRequest("PATCH", hlu.location, r)
	if err != nil {
		return 0, err
	}
	defer req.Body.Close()

	resp, err := hlu.client.Do(req)
	if err != nil {
		return 0, err
	}

	if resp.StatusCode != http.StatusAccepted {
		return 0, hlu.handleErrorResponse(resp)
	}

	// TODO(dmcgowan): Validate headers
	hlu.uuid = resp.Header.Get("Docker-Upload-UUID")
	hlu.location, err = sanitizeLocation(resp.Header.Get("Location"), hlu.location)
	if err != nil {
		return 0, err
	}
	rng := resp.Header.Get("Range")
	var start, end int64
	if n, err := fmt.Sscanf(rng, "%d-%d", &start, &end); err != nil {
		return 0, err
	} else if n != 2 || end < start {
		return 0, fmt.Errorf("bad range format: %s", rng)
	}

	return (end - start + 1), nil

}

func (hlu *httpLayerUpload) Write(p []byte) (n int, err error) {
	req, err := http.NewRequest("PATCH", hlu.location, bytes.NewReader(p))
	if err != nil {
		return 0, err
	}
	req.Header.Set("Content-Range", fmt.Sprintf("%d-%d", hlu.offset, hlu.offset+int64(len(p)-1)))
	req.Header.Set("Content-Length", fmt.Sprintf("%d", len(p)))
	req.Header.Set("Content-Type", "application/octet-stream")

	resp, err := hlu.client.Do(req)
	if err != nil {
		return 0, err
	}

	if resp.StatusCode != http.StatusAccepted {
		return 0, hlu.handleErrorResponse(resp)
	}

	// TODO(dmcgowan): Validate headers
	hlu.uuid = resp.Header.Get("Docker-Upload-UUID")
	hlu.location, err = sanitizeLocation(resp.Header.Get("Location"), hlu.location)
	if err != nil {
		return 0, err
	}
	rng := resp.Header.Get("Range")
	var start, end int
	if n, err := fmt.Sscanf(rng, "%d-%d", &start, &end); err != nil {
		return 0, err
	} else if n != 2 || end < start {
		return 0, fmt.Errorf("bad range format: %s", rng)
	}

	return (end - start + 1), nil

}

func (hlu *httpLayerUpload) Seek(offset int64, whence int) (int64, error) {
	newOffset := hlu.offset

	switch whence {
	case os.SEEK_CUR:
		newOffset += int64(offset)
	case os.SEEK_END:
		return newOffset, errors.New("Cannot seek from end on incomplete upload")
	case os.SEEK_SET:
		newOffset = int64(offset)
	}

	hlu.offset = newOffset

	return hlu.offset, nil
}

func (hlu *httpLayerUpload) UUID() string {
	return hlu.uuid
}

func (hlu *httpLayerUpload) StartedAt() time.Time {
	return hlu.startedAt
}

func (hlu *httpLayerUpload) Finish(digest digest.Digest) (distribution.Layer, error) {
	// TODO(dmcgowan): Check if already finished, if so just fetch
	req, err := http.NewRequest("PUT", hlu.location, nil)
	if err != nil {
		return nil, err
	}

	values := req.URL.Query()
	values.Set("digest", digest.String())
	req.URL.RawQuery = values.Encode()

	resp, err := hlu.client.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusCreated {
		return nil, hlu.handleErrorResponse(resp)
	}

	return hlu.repo.Layers().Fetch(digest)
}

func (hlu *httpLayerUpload) Cancel() error {
	panic("not implemented")
}

func (hlu *httpLayerUpload) Close() error {
	hlu.closed = true
	return nil
}
<commit_msg>Update ReadFrom to wrap reader in NopCloser<commit_after>package client

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"time"

	"github.com/docker/distribution"
	"github.com/docker/distribution/digest"
)

type httpLayerUpload struct {
	repo   distribution.Repository
	client *http.Client

	uuid      string
	startedAt time.Time

	location string // always the last value of the location header.
	offset   int64
	closed   bool
}

func (hlu *httpLayerUpload) handleErrorResponse(resp *http.Response) error {
	if resp.StatusCode == http.StatusNotFound {
		return &BlobUploadNotFoundError{Location: hlu.location}
	}
	return handleErrorResponse(resp)
}

func (hlu *httpLayerUpload) ReadFrom(r io.Reader) (n int64, err error) {
	req, err := http.NewRequest("PATCH", hlu.location, ioutil.NopCloser(r))
	if err != nil {
		return 0, err
	}
	defer req.Body.Close()

	resp, err := hlu.client.Do(req)
	if err != nil {
		return 0, err
	}

	if resp.StatusCode != http.StatusAccepted {
		return 0, hlu.handleErrorResponse(resp)
	}

	// TODO(dmcgowan): Validate headers
	hlu.uuid = resp.Header.Get("Docker-Upload-UUID")
	hlu.location, err = sanitizeLocation(resp.Header.Get("Location"), hlu.location)
	if err != nil {
		return 0, err
	}
	rng := resp.Header.Get("Range")
	var start, end int64
	if n, err := fmt.Sscanf(rng, "%d-%d", &start, &end); err != nil {
		return 0, err
	} else if n != 2 || end < start {
		return 0, fmt.Errorf("bad range format: %s", rng)
	}

	return (end - start + 1), nil

}

func (hlu *httpLayerUpload) Write(p []byte) (n int, err error) {
	req, err := http.NewRequest("PATCH", hlu.location, bytes.NewReader(p))
	if err != nil {
		return 0, err
	}
	req.Header.Set("Content-Range", fmt.Sprintf("%d-%d", hlu.offset, hlu.offset+int64(len(p)-1)))
	req.Header.Set("Content-Length", fmt.Sprintf("%d", len(p)))
	req.Header.Set("Content-Type", "application/octet-stream")

	resp, err := hlu.client.Do(req)
	if err != nil {
		return 0, err
	}

	if resp.StatusCode != http.StatusAccepted {
		return 0, hlu.handleErrorResponse(resp)
	}

	// TODO(dmcgowan): Validate headers
	hlu.uuid = resp.Header.Get("Docker-Upload-UUID")
	hlu.location, err = sanitizeLocation(resp.Header.Get("Location"), hlu.location)
	if err != nil {
		return 0, err
	}
	rng := resp.Header.Get("Range")
	var start, end int
	if n, err := fmt.Sscanf(rng, "%d-%d", &start, &end); err != nil {
		return 0, err
	} else if n != 2 || end < start {
		return 0, fmt.Errorf("bad range format: %s", rng)
	}

	return (end - start + 1), nil

}

func (hlu *httpLayerUpload) Seek(offset int64, whence int) (int64, error) {
	newOffset := hlu.offset

	switch whence {
	case os.SEEK_CUR:
		newOffset += int64(offset)
	case os.SEEK_END:
		return newOffset, errors.New("Cannot seek from end on incomplete upload")
	case os.SEEK_SET:
		newOffset = int64(offset)
	}

	hlu.offset = newOffset

	return hlu.offset, nil
}

func (hlu *httpLayerUpload) UUID() string {
	return hlu.uuid
}

func (hlu *httpLayerUpload) StartedAt() time.Time {
	return hlu.startedAt
}

func (hlu *httpLayerUpload) Finish(digest digest.Digest) (distribution.Layer, error) {
	// TODO(dmcgowan): Check if already finished, if so just fetch
	req, err := http.NewRequest("PUT", hlu.location, nil)
	if err != nil {
		return nil, err
	}

	values := req.URL.Query()
	values.Set("digest", digest.String())
	req.URL.RawQuery = values.Encode()

	resp, err := hlu.client.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusCreated {
		return nil, hlu.handleErrorResponse(resp)
	}

	return hlu.repo.Layers().Fetch(digest)
}

func (hlu *httpLayerUpload) Cancel() error {
	panic("not implemented")
}

func (hlu *httpLayerUpload) Close() error {
	hlu.closed = true
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
)

var (
	setting Setting
)

type Setting struct {
	syaroDir   string
	wikiName   string
	wikiRoot   string
	port       int
	urlPrefix  string
	fcgi       bool
	mathjax    bool
	highlight  bool
	singleFile bool // TODO
	readonly   bool // TODO
	gitMode    bool
	verbose    bool
	quiet      bool
	color      bool
}

func init() {
	// setting up flags
	flag.StringVar(&setting.wikiName, "wikiname", "Syaro Wiki",
		"Name of wiki")
	flag.IntVar(&setting.port, "port", 8080,
		"Port number")
	flag.StringVar(&setting.urlPrefix, "url-prefix", "",
		"URL prefix (ex. if prefix is syarowiki, URL is localhost:PORT/syarowiki/)")
	flag.BoolVar(&setting.fcgi, "fcgi", false,
		"If true, syaro runs on fast cgi mode")
	flag.BoolVar(&setting.mathjax, "mathjax", true,
		"MathJax (Internet connection is required)")
	flag.BoolVar(&setting.highlight, "highlight", true,
		"Syntax highlighting in <code> (Internet connection is required)")
	flag.BoolVar(&setting.singleFile, "single", false,
		"Single file mode")
	flag.BoolVar(&setting.gitMode, "gitmode", false,
		"Enable git integration")
	flag.BoolVar(&setting.readonly, "readonly", false,
		"Readonly mode")
	flag.BoolVar(&setting.verbose, "verbose", false,
		"Verbose output")
	flag.BoolVar(&setting.quiet, "quiet", false,
		"Suppress output")
	flag.BoolVar(&setting.color, "color", true,
		"Colored output")

	// usage
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "syaro %s\n\n", version)
		fmt.Fprintf(os.Stderr, "Usage: %s [<flags>] [<wikiroot>]\n\nFlags:\n", os.Args[0])
		flag.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nArgs:\n  wikiroot=\"./\": Root folder of wiki\n")
	}
}

func parseFlags() {
	flag.Parse()

	if len(flag.Args()) > 0 {
		setting.wikiRoot = flag.Arg(0) // set wikiroot
	} else {
		setting.wikiRoot = "."
	}

	// TODO os.Getenv
}
<commit_msg>[REM] remove urlprefix support<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
)

var (
	setting Setting
)

type Setting struct {
	syaroDir   string
	wikiName   string
	wikiRoot   string
	port       int
	urlPrefix  string
	fcgi       bool
	mathjax    bool
	highlight  bool
	singleFile bool // TODO
	readonly   bool // TODO
	gitMode    bool
	verbose    bool
	quiet      bool
	color      bool
}

func init() {
	// setting up flags
	flag.StringVar(&setting.wikiName, "wikiname", "Syaro Wiki",
		"Name of wiki")
	flag.IntVar(&setting.port, "port", 8080,
		"Port number")
	// flag.StringVar(&setting.urlPrefix, "url-prefix", "",
	// 	"URL prefix (ex. if prefix is syarowiki, URL is localhost:PORT/syarowiki/)")
	flag.BoolVar(&setting.fcgi, "fcgi", false,
		"If true, syaro runs on fast cgi mode")
	flag.BoolVar(&setting.mathjax, "mathjax", true,
		"MathJax (Internet connection is required)")
	flag.BoolVar(&setting.highlight, "highlight", true,
		"Syntax highlighting in <code> (Internet connection is required)")
	flag.BoolVar(&setting.singleFile, "single", false,
		"Single file mode")
	flag.BoolVar(&setting.gitMode, "gitmode", false,
		"Enable git integration")
	flag.BoolVar(&setting.readonly, "readonly", false,
		"Readonly mode")
	flag.BoolVar(&setting.verbose, "verbose", false,
		"Verbose output")
	flag.BoolVar(&setting.quiet, "quiet", false,
		"Suppress output")
	flag.BoolVar(&setting.color, "color", true,
		"Colored output")

	// usage
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "syaro %s\n\n", version)
		fmt.Fprintf(os.Stderr, "Usage: %s [<flags>] [<wikiroot>]\n\nFlags:\n", os.Args[0])
		flag.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nArgs:\n  wikiroot=\"./\": Root folder of wiki\n")
	}
}

func parseFlags() {
	flag.Parse()

	if len(flag.Args()) > 0 {
		setting.wikiRoot = flag.Arg(0) // set wikiroot
	} else {
		setting.wikiRoot = "."
	}

	// TODO os.Getenv
}
<|endoftext|>


<commit_before>package simplessh

import (
	"code.google.com/p/go.crypto/ssh"
	"github.com/pkg/sftp"

	"io"
	"io/ioutil"
	"net"
	"os"
	"os/user"
	"path/filepath"
)

type Client struct {
	SSHClient *ssh.Client
}

func ConnectWithPassword(host, username, pass string) (*Client, error) {
	authMethod := ssh.Password(pass)

	return connect(username, host, authMethod)
}

// Connect with a private key. If privKeyPath is an empty string it will attempt
// to use $HOME/.ssh/id_rsa.
func ConnectWithPrivateKey(host, username, privKeyPath string) (*Client, error) {
	if privKeyPath == "" {
		currentUser, err := user.Current()
		if err == nil {
			privKeyPath = filepath.Join(currentUser.HomeDir, ".ssh", "id_rsa")
		}
	}

	privKey, err := ioutil.ReadFile(privKeyPath)
	if err != nil {
		return nil, err
	}

	signer, err := ssh.ParsePrivateKey(privKey)
	if err != nil {
		return nil, err
	}

	authMethod := ssh.PublicKeys(signer)

	return connect(username, host, authMethod)
}

func connect(username, host string, authMethod ssh.AuthMethod) (*Client, error) {
	config := &ssh.ClientConfig{
		User: username,
		Auth: []ssh.AuthMethod{authMethod},
	}

	host = addPortToHost(host)

	client, err := ssh.Dial("tcp", host, config)
	if err != nil {
		return nil, err
	}

	c := &Client{SSHClient: client}
	return c, nil
}

func (c *Client) Exec(cmd string) ([]byte, error) {
	session, err := c.SSHClient.NewSession()
	if err != nil {
		return nil, err
	}
	defer session.Close()

	return session.CombinedOutput(cmd)
}

func (c *Client) Download(remote, local string) error {
	client, err := sftp.NewClient(c.SSHClient)
	if err != nil {
		return err
	}
	defer client.Close()

	remoteFile, err := client.Open(remote)
	if err != nil {
		return err
	}
	defer remoteFile.Close()

	localFile, err := os.Create(local)
	if err != nil {
		return err
	}
	defer localFile.Close()

	_, err = io.Copy(localFile, remoteFile)
	return err
}

func (c *Client) Upload(local, remote string) error {
	client, err := sftp.NewClient(c.SSHClient)
	if err != nil {
		return err
	}
	defer client.Close()

	localFile, err := os.Open(local)
	if err != nil {
		return err
	}
	defer localFile.Close()

	remoteFile, err := client.Create(remote)
	if err != nil {
		return err
	}

	_, err = io.Copy(remoteFile, localFile)
	return err
}

func addPortToHost(host string) string {
	_, _, err := net.SplitHostPort(host)

	// We got an error so blindly try to add a port number
	if err != nil {
		return net.JoinHostPort(host, "22")
	}

	return host
}
<commit_msg>Allow connection with a private key as a string.<commit_after>package simplessh

import (
	"code.google.com/p/go.crypto/ssh"
	"github.com/pkg/sftp"

	"io"
	"io/ioutil"
	"net"
	"os"
	"os/user"
	"path/filepath"
)

type Client struct {
	SSHClient *ssh.Client
}

func ConnectWithPassword(host, username, pass string) (*Client, error) {
	authMethod := ssh.Password(pass)

	return connect(username, host, authMethod)
}

// Connect with a private key. If privKeyPath is an empty string it will attempt
// to use $HOME/.ssh/id_rsa.
func ConnectWithKeyFile(host, username, privKeyPath string) (*Client, error) {
	if privKeyPath == "" {
		currentUser, err := user.Current()
		if err == nil {
			privKeyPath = filepath.Join(currentUser.HomeDir, ".ssh", "id_rsa")
		}
	}

	privKey, err := ioutil.ReadFile(privKeyPath)
	if err != nil {
		return nil, err
	}

	return ConnectWithKey(host, username, string(privKey))
}

// Connect with a private key.
func ConnectWithKey(host, username, privKey string) (*Client, error) {
	signer, err := ssh.ParsePrivateKey([]byte(privKey))
	if err != nil {
		return nil, err
	}

	authMethod := ssh.PublicKeys(signer)

	return connect(username, host, authMethod)
}

func connect(username, host string, authMethod ssh.AuthMethod) (*Client, error) {
	config := &ssh.ClientConfig{
		User: username,
		Auth: []ssh.AuthMethod{authMethod},
	}

	host = addPortToHost(host)

	client, err := ssh.Dial("tcp", host, config)
	if err != nil {
		return nil, err
	}

	c := &Client{SSHClient: client}
	return c, nil
}

func (c *Client) Exec(cmd string) ([]byte, error) {
	session, err := c.SSHClient.NewSession()
	if err != nil {
		return nil, err
	}
	defer session.Close()

	return session.CombinedOutput(cmd)
}

func (c *Client) Download(remote, local string) error {
	client, err := sftp.NewClient(c.SSHClient)
	if err != nil {
		return err
	}
	defer client.Close()

	remoteFile, err := client.Open(remote)
	if err != nil {
		return err
	}
	defer remoteFile.Close()

	localFile, err := os.Create(local)
	if err != nil {
		return err
	}
	defer localFile.Close()

	_, err = io.Copy(localFile, remoteFile)
	return err
}

func (c *Client) Upload(local, remote string) error {
	client, err := sftp.NewClient(c.SSHClient)
	if err != nil {
		return err
	}
	defer client.Close()

	localFile, err := os.Open(local)
	if err != nil {
		return err
	}
	defer localFile.Close()

	remoteFile, err := client.Create(remote)
	if err != nil {
		return err
	}

	_, err = io.Copy(remoteFile, localFile)
	return err
}

func addPortToHost(host string) string {
	_, _, err := net.SplitHostPort(host)

	// We got an error so blindly try to add a port number
	if err != nil {
		return net.JoinHostPort(host, "22")
	}

	return host
}
<|endoftext|>


<commit_before>package frames

import (
	"bytes"
	"errors"
	"time"

	"github.com/lucas-clemente/quic-go/protocol"
	"github.com/lucas-clemente/quic-go/utils"
)

var errInvalidAckRanges = errors.New("AckFrame: ACK frame contains invalid ACK ranges")

// An AckFrameNew is a ACK frame in QUIC c34
type AckFrameNew struct {
	// TODO: rename to LargestAcked
	LargestObserved protocol.PacketNumber
	NackRanges      []NackRange // has to be ordered. The NACK range with the highest FirstPacketNumber goes first, the NACK range with the lowest FirstPacketNumber goes last
	LowestAcked     protocol.PacketNumber
	AckRanges       []AckRange

	DelayTime          time.Duration
	PacketReceivedTime time.Time // only for received packets. Will not be modified for received ACKs frames
}

// ParseAckFrameNew reads an ACK frame
func ParseAckFrameNew(r *bytes.Reader, version protocol.VersionNumber) (*AckFrameNew, error) {
	frame := &AckFrameNew{}

	typeByte, err := r.ReadByte()
	if err != nil {
		return nil, err
	}

	hasMissingRanges := false
	if typeByte&0x20 == 0x20 {
		hasMissingRanges = true
	}

	largestObservedLen := 2 * ((typeByte & 0x0C) >> 2)
	if largestObservedLen == 0 {
		largestObservedLen = 1
	}

	missingSequenceNumberDeltaLen := 2 * (typeByte & 0x03)
	if missingSequenceNumberDeltaLen == 0 {
		missingSequenceNumberDeltaLen = 1
	}

	largestObserved, err := utils.ReadUintN(r, largestObservedLen)
	if err != nil {
		return nil, err
	}
	frame.LargestObserved = protocol.PacketNumber(largestObserved)

	delay, err := utils.ReadUfloat16(r)
	if err != nil {
		return nil, err
	}
	frame.DelayTime = time.Duration(delay) * time.Microsecond

	var numAckBlocks uint8
	if hasMissingRanges {
		numAckBlocks, err = r.ReadByte()
		if err != nil {
			return nil, err
		}
	}

	ackBlockLength, err := utils.ReadUintN(r, missingSequenceNumberDeltaLen)
	if err != nil {
		return nil, err
	}

	if ackBlockLength > largestObserved {
		return nil, errInvalidAckRanges
	}

	if hasMissingRanges {
		ackRange := AckRange{
			FirstPacketNumber: protocol.PacketNumber(largestObserved-ackBlockLength) + 1,
			LastPacketNumber:  frame.LargestObserved,
		}
		frame.AckRanges = append(frame.AckRanges, ackRange)

		var inLongBlock bool
		for i := uint8(0); i < numAckBlocks; i++ {
			var gap uint8
			gap, err = r.ReadByte()
			if err != nil {
				return nil, err
			}

			ackBlockLength, err = utils.ReadUintN(r, missingSequenceNumberDeltaLen)
			if err != nil {
				return nil, err
			}

			length := protocol.PacketNumber(ackBlockLength)

			if inLongBlock {
				frame.AckRanges[len(frame.AckRanges)-1].FirstPacketNumber -= protocol.PacketNumber(gap) + length
				frame.AckRanges[len(frame.AckRanges)-1].LastPacketNumber -= protocol.PacketNumber(gap)
			} else {
				ackRange := AckRange{
					LastPacketNumber: frame.AckRanges[len(frame.AckRanges)-1].FirstPacketNumber - protocol.PacketNumber(gap) - 1,
				}
				ackRange.FirstPacketNumber = ackRange.LastPacketNumber - length + 1
				frame.AckRanges = append(frame.AckRanges, ackRange)
			}

			inLongBlock = (ackBlockLength == 0)
		}
		frame.LowestAcked = frame.AckRanges[len(frame.AckRanges)-1].FirstPacketNumber
	} else {
		// make sure that LowestAcked is not 0. 0 is not a valid PacketNumber
		// TODO: is this really the right behavior?
		if largestObserved == ackBlockLength {
			frame.LowestAcked = 1
		} else {
			frame.LowestAcked = protocol.PacketNumber(largestObserved - ackBlockLength)
		}
	}

	var numTimestampByte byte
	numTimestampByte, err = r.ReadByte()
	if err != nil {
		return nil, err
	}
	numTimestamp := uint8(numTimestampByte)

	if numTimestamp > 0 {
		// Delta Largest observed
		_, err = r.ReadByte()
		if err != nil {
			return nil, err
		}
		// First Timestamp
		_, err = utils.ReadUint32(r)
		if err != nil {
			return nil, err
		}

		for i := 0; i < int(numTimestamp)-1; i++ {
			// Delta Largest observed
			_, err = r.ReadByte()
			if err != nil {
				return nil, err
			}

			// Time Since Previous Timestamp
			_, err = utils.ReadUint16(r)
			if err != nil {
				return nil, err
			}
		}
	}

	return frame, nil
}

// Write writes an ACK frame.
func (f *AckFrameNew) Write(b *bytes.Buffer, version protocol.VersionNumber) error {
	largestObservedLen := protocol.GetPacketNumberLength(f.LargestObserved)

	typeByte := uint8(0x40)

	if largestObservedLen != protocol.PacketNumberLen1 {
		typeByte ^= (uint8(largestObservedLen / 2)) << 2
	}

	// TODO: send shorter values, if possible
	missingSequenceNumberDeltaLen := protocol.PacketNumberLen6
	if missingSequenceNumberDeltaLen != protocol.PacketNumberLen1 {
		typeByte ^= (uint8(missingSequenceNumberDeltaLen / 2))
	}

	if f.HasMissingRanges() {
		typeByte |= (0x20 | 0x03)
	}

	b.WriteByte(typeByte)

	switch largestObservedLen {
	case protocol.PacketNumberLen1:
		b.WriteByte(uint8(f.LargestObserved))
	case protocol.PacketNumberLen2:
		utils.WriteUint16(b, uint16(f.LargestObserved))
	case protocol.PacketNumberLen4:
		utils.WriteUint32(b, uint32(f.LargestObserved))
	case protocol.PacketNumberLen6:
		utils.WriteUint48(b, uint64(f.LargestObserved))
	}

	f.DelayTime = time.Now().Sub(f.PacketReceivedTime)
	utils.WriteUfloat16(b, uint64(f.DelayTime/time.Microsecond))

	var numRanges uint64
	var numRangesWritten uint64 // to check for internal consistency
	if f.HasMissingRanges() {
		numRanges = f.numWrittenNackRanges()
		if numRanges >= 0xFF {
			panic("AckFrame: Too many ACK ranges")
		}
		b.WriteByte(uint8(numRanges - 1))
	}

	if !f.HasMissingRanges() {
		utils.WriteUint48(b, uint64(f.LargestObserved-f.LowestAcked))
	} else {
		if f.LargestObserved != f.AckRanges[0].LastPacketNumber {
			return errors.New("internal inconsistency")
		}
		length := f.LargestObserved - f.AckRanges[0].FirstPacketNumber + 1
		utils.WriteUint48(b, uint64(length))
		numRangesWritten++
	}

	for i, ackRange := range f.AckRanges {
		if i == 0 {
			continue
		}

		length := ackRange.LastPacketNumber - ackRange.FirstPacketNumber + 1
		gap := f.AckRanges[i-1].FirstPacketNumber - ackRange.LastPacketNumber - 1

		num := gap/0xFF + 1
		if gap%0xFF == 0 {
			num--
		}

		if num == 1 {
			b.WriteByte(uint8(gap))
			utils.WriteUint48(b, uint64(length))
			numRangesWritten++
		} else {
			for i := 0; i < int(num); i++ {
				var lengthWritten uint64
				var gapWritten uint8

				if i == int(num)-1 { // last block
					lengthWritten = uint64(length)
					gapWritten = uint8(gap % 0xFF)
				} else {
					lengthWritten = 0
					gapWritten = 0xFF
				}

				b.WriteByte(uint8(gapWritten))
				utils.WriteUint48(b, lengthWritten)
				numRangesWritten++
			}
		}
	}

	if numRanges != numRangesWritten {
		return errors.New("BUG: Inconsistent number of ACK ranges written")
	}

	b.WriteByte(0x01)       // Just one timestamp
	b.WriteByte(0x00)       // Delta Largest observed
	utils.WriteUint32(b, 0) // First timestamp

	return nil
}

// MinLength of a written frame
func (f *AckFrameNew) MinLength(version protocol.VersionNumber) (protocol.ByteCount, error) {
	var length protocol.ByteCount
	length = 1 + 2 + 1 + 1 + 4 // 1 TypeByte, 2 ACK delay time, 1 Num Timestamp, 1 Delta Largest Observed, 4 FirstTimestamp
	length += protocol.ByteCount(protocol.GetPacketNumberLength(f.LargestObserved))

	missingSequenceNumberDeltaLen := protocol.ByteCount(protocol.PacketNumberLen6)

	if f.HasMissingRanges() {
		length += (1 + missingSequenceNumberDeltaLen) * protocol.ByteCount(f.numWrittenNackRanges())
	} else {
		length += missingSequenceNumberDeltaLen
	}

	length += (1 + 2) * 0 /* TODO: num_timestamps */

	return length, nil
}

// HasMissingRanges returns if this frame reports any missing packets
func (f *AckFrameNew) HasMissingRanges() bool {
	if len(f.AckRanges) > 0 {
		return true
	}
	return false
}

// GetHighestInOrderPacketNumber gets the highest in order packet number that is confirmed by this ACK
func (f *AckFrameNew) GetHighestInOrderPacketNumber() protocol.PacketNumber {
	if f.HasMissingRanges() {
		panic("NACKs not yet implemented")
	}
	return f.LargestObserved
}

// numWrittenNackRanges calculates the number of ACK blocks that are about to be written
// this number is different from len(f.AckRanges) for the case of long gaps (> 255 packets)
func (f *AckFrameNew) numWrittenNackRanges() uint64 {
	if len(f.AckRanges) == 0 {
		return 0
	}

	var numRanges uint64
	for i, ackRange := range f.AckRanges {
		if i == 0 {
			continue
		}

		lastAckRange := f.AckRanges[i-1]
		gap := lastAckRange.FirstPacketNumber - ackRange.LastPacketNumber
		numRanges += 1 + uint64(gap)/(0xFF+1)
		if uint64(gap)%(0xFF+1) == 0 {
			numRanges--
		}
	}

	return numRanges + 1
}
<commit_msg>don't write any timestamps in QUIC 34 ACK frames<commit_after>package frames

import (
	"bytes"
	"errors"
	"time"

	"github.com/lucas-clemente/quic-go/protocol"
	"github.com/lucas-clemente/quic-go/utils"
)

var errInvalidAckRanges = errors.New("AckFrame: ACK frame contains invalid ACK ranges")

// An AckFrameNew is a ACK frame in QUIC c34
type AckFrameNew struct {
	// TODO: rename to LargestAcked
	LargestObserved protocol.PacketNumber
	NackRanges      []NackRange // has to be ordered. The NACK range with the highest FirstPacketNumber goes first, the NACK range with the lowest FirstPacketNumber goes last
	LowestAcked     protocol.PacketNumber
	AckRanges       []AckRange

	DelayTime          time.Duration
	PacketReceivedTime time.Time // only for received packets. Will not be modified for received ACKs frames
}

// ParseAckFrameNew reads an ACK frame
func ParseAckFrameNew(r *bytes.Reader, version protocol.VersionNumber) (*AckFrameNew, error) {
	frame := &AckFrameNew{}

	typeByte, err := r.ReadByte()
	if err != nil {
		return nil, err
	}

	hasMissingRanges := false
	if typeByte&0x20 == 0x20 {
		hasMissingRanges = true
	}

	largestObservedLen := 2 * ((typeByte & 0x0C) >> 2)
	if largestObservedLen == 0 {
		largestObservedLen = 1
	}

	missingSequenceNumberDeltaLen := 2 * (typeByte & 0x03)
	if missingSequenceNumberDeltaLen == 0 {
		missingSequenceNumberDeltaLen = 1
	}

	largestObserved, err := utils.ReadUintN(r, largestObservedLen)
	if err != nil {
		return nil, err
	}
	frame.LargestObserved = protocol.PacketNumber(largestObserved)

	delay, err := utils.ReadUfloat16(r)
	if err != nil {
		return nil, err
	}
	frame.DelayTime = time.Duration(delay) * time.Microsecond

	var numAckBlocks uint8
	if hasMissingRanges {
		numAckBlocks, err = r.ReadByte()
		if err != nil {
			return nil, err
		}
	}

	ackBlockLength, err := utils.ReadUintN(r, missingSequenceNumberDeltaLen)
	if err != nil {
		return nil, err
	}

	if ackBlockLength > largestObserved {
		return nil, errInvalidAckRanges
	}

	if hasMissingRanges {
		ackRange := AckRange{
			FirstPacketNumber: protocol.PacketNumber(largestObserved-ackBlockLength) + 1,
			LastPacketNumber:  frame.LargestObserved,
		}
		frame.AckRanges = append(frame.AckRanges, ackRange)

		var inLongBlock bool
		for i := uint8(0); i < numAckBlocks; i++ {
			var gap uint8
			gap, err = r.ReadByte()
			if err != nil {
				return nil, err
			}

			ackBlockLength, err = utils.ReadUintN(r, missingSequenceNumberDeltaLen)
			if err != nil {
				return nil, err
			}

			length := protocol.PacketNumber(ackBlockLength)

			if inLongBlock {
				frame.AckRanges[len(frame.AckRanges)-1].FirstPacketNumber -= protocol.PacketNumber(gap) + length
				frame.AckRanges[len(frame.AckRanges)-1].LastPacketNumber -= protocol.PacketNumber(gap)
			} else {
				ackRange := AckRange{
					LastPacketNumber: frame.AckRanges[len(frame.AckRanges)-1].FirstPacketNumber - protocol.PacketNumber(gap) - 1,
				}
				ackRange.FirstPacketNumber = ackRange.LastPacketNumber - length + 1
				frame.AckRanges = append(frame.AckRanges, ackRange)
			}

			inLongBlock = (ackBlockLength == 0)
		}
		frame.LowestAcked = frame.AckRanges[len(frame.AckRanges)-1].FirstPacketNumber
	} else {
		// make sure that LowestAcked is not 0. 0 is not a valid PacketNumber
		// TODO: is this really the right behavior?
		if largestObserved == ackBlockLength {
			frame.LowestAcked = 1
		} else {
			frame.LowestAcked = protocol.PacketNumber(largestObserved - ackBlockLength)
		}
	}

	var numTimestampByte byte
	numTimestampByte, err = r.ReadByte()
	if err != nil {
		return nil, err
	}
	numTimestamp := uint8(numTimestampByte)

	if numTimestamp > 0 {
		// Delta Largest observed
		_, err = r.ReadByte()
		if err != nil {
			return nil, err
		}
		// First Timestamp
		_, err = utils.ReadUint32(r)
		if err != nil {
			return nil, err
		}

		for i := 0; i < int(numTimestamp)-1; i++ {
			// Delta Largest observed
			_, err = r.ReadByte()
			if err != nil {
				return nil, err
			}

			// Time Since Previous Timestamp
			_, err = utils.ReadUint16(r)
			if err != nil {
				return nil, err
			}
		}
	}

	return frame, nil
}

// Write writes an ACK frame.
func (f *AckFrameNew) Write(b *bytes.Buffer, version protocol.VersionNumber) error {
	largestObservedLen := protocol.GetPacketNumberLength(f.LargestObserved)

	typeByte := uint8(0x40)

	if largestObservedLen != protocol.PacketNumberLen1 {
		typeByte ^= (uint8(largestObservedLen / 2)) << 2
	}

	// TODO: send shorter values, if possible
	missingSequenceNumberDeltaLen := protocol.PacketNumberLen6
	if missingSequenceNumberDeltaLen != protocol.PacketNumberLen1 {
		typeByte ^= (uint8(missingSequenceNumberDeltaLen / 2))
	}

	if f.HasMissingRanges() {
		typeByte |= (0x20 | 0x03)
	}

	b.WriteByte(typeByte)

	switch largestObservedLen {
	case protocol.PacketNumberLen1:
		b.WriteByte(uint8(f.LargestObserved))
	case protocol.PacketNumberLen2:
		utils.WriteUint16(b, uint16(f.LargestObserved))
	case protocol.PacketNumberLen4:
		utils.WriteUint32(b, uint32(f.LargestObserved))
	case protocol.PacketNumberLen6:
		utils.WriteUint48(b, uint64(f.LargestObserved))
	}

	f.DelayTime = time.Now().Sub(f.PacketReceivedTime)
	utils.WriteUfloat16(b, uint64(f.DelayTime/time.Microsecond))

	var numRanges uint64
	var numRangesWritten uint64 // to check for internal consistency
	if f.HasMissingRanges() {
		numRanges = f.numWrittenNackRanges()
		if numRanges >= 0xFF {
			panic("AckFrame: Too many ACK ranges")
		}
		b.WriteByte(uint8(numRanges - 1))
	}

	if !f.HasMissingRanges() {
		utils.WriteUint48(b, uint64(f.LargestObserved-f.LowestAcked))
	} else {
		if f.LargestObserved != f.AckRanges[0].LastPacketNumber {
			return errors.New("internal inconsistency")
		}
		length := f.LargestObserved - f.AckRanges[0].FirstPacketNumber + 1
		utils.WriteUint48(b, uint64(length))
		numRangesWritten++
	}

	for i, ackRange := range f.AckRanges {
		if i == 0 {
			continue
		}

		length := ackRange.LastPacketNumber - ackRange.FirstPacketNumber + 1
		gap := f.AckRanges[i-1].FirstPacketNumber - ackRange.LastPacketNumber - 1

		num := gap/0xFF + 1
		if gap%0xFF == 0 {
			num--
		}

		if num == 1 {
			b.WriteByte(uint8(gap))
			utils.WriteUint48(b, uint64(length))
			numRangesWritten++
		} else {
			for i := 0; i < int(num); i++ {
				var lengthWritten uint64
				var gapWritten uint8

				if i == int(num)-1 { // last block
					lengthWritten = uint64(length)
					gapWritten = uint8(gap % 0xFF)
				} else {
					lengthWritten = 0
					gapWritten = 0xFF
				}

				b.WriteByte(uint8(gapWritten))
				utils.WriteUint48(b, lengthWritten)
				numRangesWritten++
			}
		}
	}

	if numRanges != numRangesWritten {
		return errors.New("BUG: Inconsistent number of ACK ranges written")
	}

	b.WriteByte(0) // no timestamps

	return nil
}

// MinLength of a written frame
func (f *AckFrameNew) MinLength(version protocol.VersionNumber) (protocol.ByteCount, error) {
	var length protocol.ByteCount
	length = 1 + 2 + 1 // 1 TypeByte, 2 ACK delay time, 1 Num Timestamp
	length += protocol.ByteCount(protocol.GetPacketNumberLength(f.LargestObserved))

	missingSequenceNumberDeltaLen := protocol.ByteCount(protocol.PacketNumberLen6)

	if f.HasMissingRanges() {
		length += (1 + missingSequenceNumberDeltaLen) * protocol.ByteCount(f.numWrittenNackRanges())
	} else {
		length += missingSequenceNumberDeltaLen
	}

	length += (1 + 2) * 0 /* TODO: num_timestamps */

	return length, nil
}

// HasMissingRanges returns if this frame reports any missing packets
func (f *AckFrameNew) HasMissingRanges() bool {
	if len(f.AckRanges) > 0 {
		return true
	}
	return false
}

// GetHighestInOrderPacketNumber gets the highest in order packet number that is confirmed by this ACK
func (f *AckFrameNew) GetHighestInOrderPacketNumber() protocol.PacketNumber {
	if f.HasMissingRanges() {
		panic("NACKs not yet implemented")
	}
	return f.LargestObserved
}

// numWrittenNackRanges calculates the number of ACK blocks that are about to be written
// this number is different from len(f.AckRanges) for the case of long gaps (> 255 packets)
func (f *AckFrameNew) numWrittenNackRanges() uint64 {
	if len(f.AckRanges) == 0 {
		return 0
	}

	var numRanges uint64
	for i, ackRange := range f.AckRanges {
		if i == 0 {
			continue
		}

		lastAckRange := f.AckRanges[i-1]
		gap := lastAckRange.FirstPacketNumber - ackRange.LastPacketNumber
		numRanges += 1 + uint64(gap)/(0xFF+1)
		if uint64(gap)%(0xFF+1) == 0 {
			numRanges--
		}
	}

	return numRanges + 1
}
<|endoftext|>


<commit_before>package main

import "flag"
import "golang.org/x/net/context"
import "google.golang.org/grpc"
import "log"
import "math/rand"
import "strconv"
import "strings"
import "time"
import "io/ioutil"

import "github.com/golang/protobuf/proto"

import pb "github.com/brotherlogic/discogssyncer/server"
import pbd "github.com/brotherlogic/godiscogs"
import pbdi "github.com/brotherlogic/discovery/proto"
import pbc "github.com/brotherlogic/cardserver/card"

func getIP(servername string, ip string, port int) (string, int) {
	conn, _ := grpc.Dial(ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	defer conn.Close()

	registry := pbdi.NewDiscoveryServiceClient(conn)
	entry := pbdi.RegistryEntry{Name: servername}
	r, _ := registry.Discover(context.Background(), &entry)
	return r.Ip, int(r.Port)
}

func getRelease(folderName []string, host string, port string) *pbd.Release {
	rand.Seed(time.Now().UTC().UnixNano())
	conn, err := grpc.Dial(host+":"+port, grpc.WithInsecure())
	defer conn.Close()
	client := pb.NewDiscogsServiceClient(conn)
	folderList := &pb.FolderList{}
	for _, name := range folderName {
		folder := &pbd.Folder{Name: name}
		folderList.Folders = append(folderList.Folders, folder)
	}
	r, err := client.GetReleasesInFolder(context.Background(), folderList)
	if err != nil {
		log.Fatal("Problem getting releases %v", err)
	}

	return r.Releases[rand.Intn(len(r.Releases))]
}

func main() {
	var folder = flag.String("foldername", "", "Folder to retrieve from.")
	var host = flag.String("host", "10.0.1.17", "Hostname of server.")
	var port = flag.String("port", "50055", "Port number of server")
	flag.Parse()
	portVal, _ := strconv.Atoi(*port)

	//Read the last written record
	data, _ := ioutil.ReadFile("last_written")
	lastWritten := &pbd.Release{}
	proto.Unmarshal(data, lastWritten)

	//Get the latest card from the cardserver
	cServer, cPort := getIP("cardserver", *host, portVal)
	conn, err := grpc.Dial(cServer+":"+strconv.Itoa(cPort), grpc.WithInsecure())
	defer conn.Close()
	client := pbc.NewCardServiceClient(conn)

	cardList, _ := client.GetCards(context.Background(), &pbc.Empty{})
	found := false
	for _, card := range cardList.Cards {
	    if card.Hash == "discogs" {
	       if pbd.GetReleaseArtist(*lastWritten) + " - " + lastWritten.Title == card.Text {
	       	  found = true
	       }
	    }
	}

	if !found {
		dServer, dPort := getIP("discogssyncer", *host, portVal)
		rel := getRelease(strings.Split(*folder, ","), dServer, strconv.Itoa(dPort))

	cards := pbc.CardList{}

	imageURL := ""
	backupURL := ""
	for _, image := range rel.Images {
		if image.Type == "primary" {
			imageURL = image.Uri
		}
		backupURL = image.Uri
	}
	if imageURL == "" {
		imageURL = backupURL
	}

	// Write out the chosen record
	data, _ := proto.Marshal(rel)
	ioutil.WriteFile("last_written", data, 0644)

	card := pbc.Card{Text: pbd.GetReleaseArtist(*rel) + " - " + rel.Title, Hash: "discogs", Image: imageURL, Action: pbc.Card_DISMISS}
	cards.Cards = append(cards.Cards, &card)
	_, err = client.AddCards(context.Background(), &cards)
	if err != nil {
		log.Printf("Problem adding cards %v", err)
	}
	}
}
<commit_msg>Fixed a bug in the record getter code<commit_after>package main

import "flag"
import "golang.org/x/net/context"
import "google.golang.org/grpc"
import "log"
import "math/rand"
import "strconv"
import "strings"
import "time"
import "io/ioutil"

import "github.com/golang/protobuf/proto"

import pb "github.com/brotherlogic/discogssyncer/server"
import pbd "github.com/brotherlogic/godiscogs"
import pbdi "github.com/brotherlogic/discovery/proto"
import pbc "github.com/brotherlogic/cardserver/card"

func getIP(servername string, ip string, port int) (string, int) {
	conn, _ := grpc.Dial(ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	defer conn.Close()

	registry := pbdi.NewDiscoveryServiceClient(conn)
	entry := pbdi.RegistryEntry{Name: servername}
	r, _ := registry.Discover(context.Background(), &entry)
	return r.Ip, int(r.Port)
}

func getRelease(folderName []string, host string, port string) *pbd.Release {
	rand.Seed(time.Now().UTC().UnixNano())
	conn, err := grpc.Dial(host+":"+port, grpc.WithInsecure())
	defer conn.Close()
	client := pb.NewDiscogsServiceClient(conn)
	folderList := &pb.FolderList{}
	for _, name := range folderName {
		folder := &pbd.Folder{Name: name}
		folderList.Folders = append(folderList.Folders, folder)
	}
	r, err := client.GetReleasesInFolder(context.Background(), folderList)
	if err != nil {
		log.Fatal("Problem getting releases %v", err)
	}

	return r.Releases[rand.Intn(len(r.Releases))]
}

func main() {
	var folder = flag.String("foldername", "", "Folder to retrieve from.")
	var host = flag.String("host", "10.0.1.17", "Hostname of server.")
	var port = flag.String("port", "50055", "Port number of server")
	flag.Parse()
	portVal, _ := strconv.Atoi(*port)

	//Read the last written record
	data, _ := ioutil.ReadFile("last_written")
	lastWritten := &pbd.Release{}
	proto.Unmarshal(data, lastWritten)

	//Get the latest card from the cardserver
	cServer, cPort := getIP("cardserver", *host, portVal)
	conn, err := grpc.Dial(cServer+":"+strconv.Itoa(cPort), grpc.WithInsecure())
	defer conn.Close()
	client := pbc.NewCardServiceClient(conn)

	cardList, _ := client.GetCards(context.Background(), &pbc.Empty{})
	found := false
	for _, card := range cardList.Cards {
	    if lastWritten.Title != "" && card.Hash == "discogs" {
	       if pbd.GetReleaseArtist(*lastWritten) + " - " + lastWritten.Title == card.Text {
	       	  found = true
	       }
	    }
	}

	log.Printf("Already found the record %v", found)
	if !found {
		dServer, dPort := getIP("discogssyncer", *host, portVal)
		rel := getRelease(strings.Split(*folder, ","), dServer, strconv.Itoa(dPort))

	cards := pbc.CardList{}

	imageURL := ""
	backupURL := ""
	for _, image := range rel.Images {
		if image.Type == "primary" {
			imageURL = image.Uri
		}
		backupURL = image.Uri
	}
	if imageURL == "" {
		imageURL = backupURL
	}

	// Write out the chosen record
	data, _ := proto.Marshal(rel)
	ioutil.WriteFile("last_written", data, 0644)

	card := pbc.Card{Text: pbd.GetReleaseArtist(*rel) + " - " + rel.Title, Hash: "discogs", Image: imageURL, Action: pbc.Card_DISMISS}
	cards.Cards = append(cards.Cards, &card)
	_, err = client.AddCards(context.Background(), &cards)
	if err != nil {
		log.Printf("Problem adding cards %v", err)
	}
	}
}
<|endoftext|>


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

package daemon

import (
	"os"
	"os/exec"
	"regexp"
	"strings"
	"text/template"
)

// upstartRecord - standard record (struct) for linux upstart version of daemon package
type upstartRecord struct {
	name         string
	description  string
	dependencies []string
}

// Standard service path for systemV daemons
func (linux *upstartRecord) servicePath() string {
	return "/etc/init/" + linux.name + ".conf"
}

// Is a service installed
func (linux *upstartRecord) isInstalled() bool {

	if _, err := os.Stat(linux.servicePath()); err == nil {
		return true
	}

	return false
}

// Check service is running
func (linux *upstartRecord) checkRunning() (string, bool) {
	output, err := exec.Command("status", linux.name).Output()
	if err == nil {
		if matched, err := regexp.MatchString(linux.name+" start/running", string(output)); err == nil && matched {
			reg := regexp.MustCompile("process ([0-9]+)")
			data := reg.FindStringSubmatch(string(output))
			if len(data) > 1 {
				return "Service (pid  " + data[1] + ") is running...", true
			}
			return "Service is running...", true
		}
	}

	return "Service is stopped", false
}

// Install the service
func (linux *upstartRecord) Install(args ...string) (string, error) {
	installAction := "Install " + linux.description + ":"

	if ok, err := checkPrivileges(); !ok {
		return installAction + failed, err
	}

	srvPath := linux.servicePath()

	if linux.isInstalled() {
		return installAction + failed, ErrAlreadyInstalled
	}

	file, err := os.Create(srvPath)
	if err != nil {
		return installAction + failed, err
	}
	defer file.Close()

	execPatch, err := executablePath(linux.name)
	if err != nil {
		return installAction + failed, err
	}

	templ, err := template.New("upstatConfig").Parse(upstatConfig)
	if err != nil {
		return installAction + failed, err
	}

	if err := templ.Execute(
		file,
		&struct {
			Name, Description, Path, Args string
		}{linux.name, linux.description, execPatch, strings.Join(args, " ")},
	); err != nil {
		return installAction + failed, err
	}

	if err := os.Chmod(srvPath, 0755); err != nil {
		return installAction + failed, err
	}

	return installAction + success, nil
}

// Remove the service
func (linux *upstartRecord) Remove() (string, error) {
	removeAction := "Removing " + linux.description + ":"

	if ok, err := checkPrivileges(); !ok {
		return removeAction + failed, err
	}

	if !linux.isInstalled() {
		return removeAction + failed, ErrNotInstalled
	}

	if err := os.Remove(linux.servicePath()); err != nil {
		return removeAction + failed, err
	}

	return removeAction + success, nil
}

// Start the service
func (linux *upstartRecord) Start() (string, error) {
	startAction := "Starting " + linux.description + ":"

	if ok, err := checkPrivileges(); !ok {
		return startAction + failed, err
	}

	if !linux.isInstalled() {
		return startAction + failed, ErrNotInstalled
	}

	if _, ok := linux.checkRunning(); ok {
		return startAction + failed, ErrAlreadyRunning
	}

	if err := exec.Command("start", linux.name).Run(); err != nil {
		return startAction + failed, err
	}

	return startAction + success, nil
}

// Stop the service
func (linux *upstartRecord) Stop() (string, error) {
	stopAction := "Stopping " + linux.description + ":"

	if ok, err := checkPrivileges(); !ok {
		return stopAction + failed, err
	}

	if !linux.isInstalled() {
		return stopAction + failed, ErrNotInstalled
	}

	if _, ok := linux.checkRunning(); !ok {
		return stopAction + failed, ErrAlreadyStopped
	}

	if err := exec.Command("stop", linux.name).Run(); err != nil {
		return stopAction + failed, err
	}

	return stopAction + success, nil
}

// Status - Get service status
func (linux *upstartRecord) Status() (string, error) {

	if ok, err := checkPrivileges(); !ok {
		return "", err
	}

	if !linux.isInstalled() {
		return "Status could not defined", ErrNotInstalled
	}

	statusAction, _ := linux.checkRunning()

	return statusAction, nil
}

var upstatConfig = `# {{.Name}} {{.Description}}

description     "{{.Description}}"
author          "Pichu Chen <pichu@tih.tw>"

start on runlevel [2345]
stop on runlevel [016]

#kill timeout 5

exec {{.Path} >> /var/log/{{.Name}}.log 2>> /var/log/{{.Name}}.err
`
<commit_msg>fix bug<commit_after>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by
// license that can be found in the LICENSE file.

package daemon

import (
	"os"
	"os/exec"
	"regexp"
	"strings"
	"text/template"
)

// upstartRecord - standard record (struct) for linux upstart version of daemon package
type upstartRecord struct {
	name         string
	description  string
	dependencies []string
}

// Standard service path for systemV daemons
func (linux *upstartRecord) servicePath() string {
	return "/etc/init/" + linux.name + ".conf"
}

// Is a service installed
func (linux *upstartRecord) isInstalled() bool {

	if _, err := os.Stat(linux.servicePath()); err == nil {
		return true
	}

	return false
}

// Check service is running
func (linux *upstartRecord) checkRunning() (string, bool) {
	output, err := exec.Command("status", linux.name).Output()
	if err == nil {
		if matched, err := regexp.MatchString(linux.name+" start/running", string(output)); err == nil && matched {
			reg := regexp.MustCompile("process ([0-9]+)")
			data := reg.FindStringSubmatch(string(output))
			if len(data) > 1 {
				return "Service (pid  " + data[1] + ") is running...", true
			}
			return "Service is running...", true
		}
	}

	return "Service is stopped", false
}

// Install the service
func (linux *upstartRecord) Install(args ...string) (string, error) {
	installAction := "Install " + linux.description + ":"

	if ok, err := checkPrivileges(); !ok {
		return installAction + failed, err
	}

	srvPath := linux.servicePath()

	if linux.isInstalled() {
		return installAction + failed, ErrAlreadyInstalled
	}

	file, err := os.Create(srvPath)
	if err != nil {
		return installAction + failed, err
	}
	defer file.Close()

	execPatch, err := executablePath(linux.name)
	if err != nil {
		return installAction + failed, err
	}

	templ, err := template.New("upstatConfig").Parse(upstatConfig)
	if err != nil {
		return installAction + failed, err
	}

	if err := templ.Execute(
		file,
		&struct {
			Name, Description, Path, Args string
		}{linux.name, linux.description, execPatch, strings.Join(args, " ")},
	); err != nil {
		return installAction + failed, err
	}

	if err := os.Chmod(srvPath, 0755); err != nil {
		return installAction + failed, err
	}

	return installAction + success, nil
}

// Remove the service
func (linux *upstartRecord) Remove() (string, error) {
	removeAction := "Removing " + linux.description + ":"

	if ok, err := checkPrivileges(); !ok {
		return removeAction + failed, err
	}

	if !linux.isInstalled() {
		return removeAction + failed, ErrNotInstalled
	}

	if err := os.Remove(linux.servicePath()); err != nil {
		return removeAction + failed, err
	}

	return removeAction + success, nil
}

// Start the service
func (linux *upstartRecord) Start() (string, error) {
	startAction := "Starting " + linux.description + ":"

	if ok, err := checkPrivileges(); !ok {
		return startAction + failed, err
	}

	if !linux.isInstalled() {
		return startAction + failed, ErrNotInstalled
	}

	if _, ok := linux.checkRunning(); ok {
		return startAction + failed, ErrAlreadyRunning
	}

	if err := exec.Command("start", linux.name).Run(); err != nil {
		return startAction + failed, err
	}

	return startAction + success, nil
}

// Stop the service
func (linux *upstartRecord) Stop() (string, error) {
	stopAction := "Stopping " + linux.description + ":"

	if ok, err := checkPrivileges(); !ok {
		return stopAction + failed, err
	}

	if !linux.isInstalled() {
		return stopAction + failed, ErrNotInstalled
	}

	if _, ok := linux.checkRunning(); !ok {
		return stopAction + failed, ErrAlreadyStopped
	}

	if err := exec.Command("stop", linux.name).Run(); err != nil {
		return stopAction + failed, err
	}

	return stopAction + success, nil
}

// Status - Get service status
func (linux *upstartRecord) Status() (string, error) {

	if ok, err := checkPrivileges(); !ok {
		return "", err
	}

	if !linux.isInstalled() {
		return "Status could not defined", ErrNotInstalled
	}

	statusAction, _ := linux.checkRunning()

	return statusAction, nil
}

var upstatConfig = `# {{.Name}} {{.Description}}

description     "{{.Description}}"
author          "Pichu Chen <pichu@tih.tw>"

start on runlevel [2345]
stop on runlevel [016]

#kill timeout 5

exec {{.Path}} >> /var/log/{{.Name}}.log 2>> /var/log/{{.Name}}.err
`
<|endoftext|>


<commit_before><commit_msg>Specify publicKeyKeyVersion as uint32.<commit_after><|endoftext|>


<commit_before>// +build windows

package systray

import (
	"fmt"
	"io/ioutil"
	"os"
	"sync/atomic"

	"github.com/lxn/walk"
)

var (
	tmpDir     string
	mainWindow *walk.MainWindow
	webView    *walk.WebView
	notifyIcon *walk.NotifyIcon

	actions      = make(map[int32]*walk.Action)
	nextActionId int32

	okayToClose int32
)

func nativeLoop(title string, width int, height int) {
	var err error
	mainWindow, err = walk.NewMainWindow()
	if err != nil {
		fail("Unable to create main window", err)
	}
	mainWindow.Closing().Attach(func(canceled *bool, reason walk.CloseReason) {
		fmt.Println(reason)
		// don't close app unless we're actually finished
		actuallyClose := atomic.LoadInt32(&okayToClose) == 1
		*canceled = !actuallyClose
		if !actuallyClose {
			mainWindow.SetVisible(false)
		}
	})
	layout := walk.NewVBoxLayout()
	if err := mainWindow.SetLayout(layout); err != nil {
		fail("Unable to set main layout", err)
	}
	notifyIcon, err = walk.NewNotifyIcon(mainWindow)
	if err != nil {
		fail("Unable to create notify icon", err)
	}
	if title != "" {
		webView, err = walk.NewWebView(mainWindow)
		if err != nil {
			fail("Unable to create web view", err)
		}
		if err := mainWindow.SetTitle(title); err != nil {
			fail("Unable to set main title", err)
		}
		if err := mainWindow.SetWidth(width); err != nil {
			fail("Unable to set width", err)
		}
		if err := mainWindow.SetHeight(height); err != nil {
			fail("Unable to set height", err)
		}
	}
	systrayReady()
	mainWindow.Run()
}

func quit() {
	atomic.StoreInt32(&okayToClose, 1)
	mainWindow.Close()
	notifyIcon.Dispose()
	systrayExit()
}

// SetIcon sets the systray icon.
// iconBytes should be the content of .ico for windows and .ico/.jpg/.png
// for other platforms.
func SetIcon(iconBytes []byte) {
	filename := "systray.ico"
	err := ioutil.WriteFile(filename, iconBytes, 0644)
	if err != nil {
		fail("Unable to save icon to disk", err)
	}
	defer os.Remove(filename)
	icon, err := walk.Resources.Icon(filename)
	if err != nil {
		fail("Unable to load icon", err)
	}
	err = notifyIcon.SetIcon(icon)
	if err != nil {
		fail("Unable to set systray icon", err)
	}
	err = notifyIcon.SetVisible(true)
	if err != nil {
		fail("Unable to make systray icon visible", err)
	}
}

// SetTitle sets the systray title, only available on Mac.
func SetTitle(title string) {
	// not supported on Windows
}

// SetTooltip sets the systray tooltip to display on mouse hover of the tray icon,
// only available on Mac and Windows.
func SetTooltip(tooltip string) {
	if err := notifyIcon.SetToolTip(tooltip); err != nil {
		fail("Unable to set tooltip", err)
	}
}

// ShowAppWindow shows the given URL in the application window. Only works if
// configureAppWindow has been called first.
func ShowAppWindow(url string) {
	if webView == nil {
		return
	}
	webView.SetURL(url)
	mainWindow.SetVisible(true)
}

func addOrUpdateMenuItem(item *MenuItem) {
	action := actions[item.id]
	if action == nil {
		item.id = nextActionId
		action = walk.NewAction()
		action.Triggered().Attach(func() {
			select {
			case item.ClickedCh <- struct{}{}:
				// okay
			default:
				// no listener, ignore
			}
		})
		if err := notifyIcon.ContextMenu().Actions().Add(action); err != nil {
			fail("Unable to add menu item to systray", err)
		}
		actions[item.id] = action
		atomic.AddInt32(&nextActionId, 1)
	}
	err := action.SetText(item.title)
	if err != nil {
		fail("Unable to set menu item text", err)
	}
	err = action.SetChecked(item.checked)
	if err != nil {
		fail("Unable to set menu item checked", err)
	}
	err = action.SetEnabled(!item.Disabled())
	if err != nil {
		fail("Unable to set menu item enabled", err)
	}
}

func (item *MenuItem) SetIcon(iconBytes []byte) {
	filename := fmt.Sprintf("systray.%d.ico", item.id)
	err := ioutil.WriteFile(filename, iconBytes, 0644)
	if err != nil {
		fail("Unable to save icon to disk", err)
	}
	defer os.Remove(filename)
	icon, err := walk.Resources.Image(filename)
	if err != nil {
		fail("Unable to load icon", err)
	}
	actions[item.id].SetImage(icon)
}

func addSeparator(id int32) {
	action := walk.NewSeparatorAction()
	if err := notifyIcon.ContextMenu().Actions().Add(action); err != nil {
		fail("Unable to add separator", err)
	}
}

func hideMenuItem(item *MenuItem) {
	actions[item.id].SetVisible(false)
}

func showMenuItem(item *MenuItem) {
	actions[item.id].SetVisible(true)
}

func fail(msg string, err error) {
	panic(fmt.Errorf("%v: %v", msg, err))
}
<commit_msg>Fix icon not changed after multiple SetIcon calls<commit_after>// +build windows

package systray

import (
	"crypto/md5"
	"fmt"
	"io/ioutil"
	"os"
	"sync/atomic"

	"github.com/lxn/walk"
)

var (
	tmpDir     string
	mainWindow *walk.MainWindow
	webView    *walk.WebView
	notifyIcon *walk.NotifyIcon

	actions      = make(map[int32]*walk.Action)
	nextActionId int32

	okayToClose int32
)

func nativeLoop(title string, width int, height int) {
	var err error
	mainWindow, err = walk.NewMainWindow()
	if err != nil {
		fail("Unable to create main window", err)
	}
	mainWindow.Closing().Attach(func(canceled *bool, reason walk.CloseReason) {
		fmt.Println(reason)
		// don't close app unless we're actually finished
		actuallyClose := atomic.LoadInt32(&okayToClose) == 1
		*canceled = !actuallyClose
		if !actuallyClose {
			mainWindow.SetVisible(false)
		}
	})
	layout := walk.NewVBoxLayout()
	if err := mainWindow.SetLayout(layout); err != nil {
		fail("Unable to set main layout", err)
	}
	notifyIcon, err = walk.NewNotifyIcon(mainWindow)
	if err != nil {
		fail("Unable to create notify icon", err)
	}
	if title != "" {
		webView, err = walk.NewWebView(mainWindow)
		if err != nil {
			fail("Unable to create web view", err)
		}
		if err := mainWindow.SetTitle(title); err != nil {
			fail("Unable to set main title", err)
		}
		if err := mainWindow.SetWidth(width); err != nil {
			fail("Unable to set width", err)
		}
		if err := mainWindow.SetHeight(height); err != nil {
			fail("Unable to set height", err)
		}
	}
	systrayReady()
	mainWindow.Run()
}

func quit() {
	atomic.StoreInt32(&okayToClose, 1)
	mainWindow.Close()
	notifyIcon.Dispose()
	systrayExit()
}

// SetIcon sets the systray icon.
// iconBytes should be the content of .ico for windows and .ico/.jpg/.png
// for other platforms.
func SetIcon(iconBytes []byte) {
	md5 := md5.Sum(iconBytes)
	filename := fmt.Sprintf("%x", md5) + ".ico"
	// First, try to find a previously loaded icon in walk cache
	icon, err := walk.Resources.Icon(filename)
	if err != nil {
		// Cache miss, load the icon
		err := ioutil.WriteFile(filename, iconBytes, 0644)
		if err != nil {
			fail("Unable to save icon to disk", err)
		}
		defer os.Remove(filename)
		icon, err = walk.Resources.Icon(filename)
		if err != nil {
			fail("Unable to load icon", err)
		}
	}
	err = notifyIcon.SetIcon(icon)
	if err != nil {
		fail("Unable to set systray icon", err)
	}
	err = notifyIcon.SetVisible(true)
	if err != nil {
		fail("Unable to make systray icon visible", err)
	}
}

// SetTitle sets the systray title, only available on Mac.
func SetTitle(title string) {
	// not supported on Windows
}

// SetTooltip sets the systray tooltip to display on mouse hover of the tray icon,
// only available on Mac and Windows.
func SetTooltip(tooltip string) {
	if err := notifyIcon.SetToolTip(tooltip); err != nil {
		fail("Unable to set tooltip", err)
	}
}

// ShowAppWindow shows the given URL in the application window. Only works if
// configureAppWindow has been called first.
func ShowAppWindow(url string) {
	if webView == nil {
		return
	}
	webView.SetURL(url)
	mainWindow.SetVisible(true)
}

func addOrUpdateMenuItem(item *MenuItem) {
	action := actions[item.id]
	if action == nil {
		item.id = nextActionId
		action = walk.NewAction()
		action.Triggered().Attach(func() {
			select {
			case item.ClickedCh <- struct{}{}:
				// okay
			default:
				// no listener, ignore
			}
		})
		if err := notifyIcon.ContextMenu().Actions().Add(action); err != nil {
			fail("Unable to add menu item to systray", err)
		}
		actions[item.id] = action
		atomic.AddInt32(&nextActionId, 1)
	}
	err := action.SetText(item.title)
	if err != nil {
		fail("Unable to set menu item text", err)
	}
	err = action.SetChecked(item.checked)
	if err != nil {
		fail("Unable to set menu item checked", err)
	}
	err = action.SetEnabled(!item.Disabled())
	if err != nil {
		fail("Unable to set menu item enabled", err)
	}
}

func (item *MenuItem) SetIcon(iconBytes []byte) {
	filename := fmt.Sprintf("systray.%d.ico", item.id)
	err := ioutil.WriteFile(filename, iconBytes, 0644)
	if err != nil {
		fail("Unable to save icon to disk", err)
	}
	defer os.Remove(filename)
	icon, err := walk.Resources.Image(filename)
	if err != nil {
		fail("Unable to load icon", err)
	}
	actions[item.id].SetImage(icon)
}

func addSeparator(id int32) {
	action := walk.NewSeparatorAction()
	if err := notifyIcon.ContextMenu().Actions().Add(action); err != nil {
		fail("Unable to add separator", err)
	}
}

func hideMenuItem(item *MenuItem) {
	actions[item.id].SetVisible(false)
}

func showMenuItem(item *MenuItem) {
	actions[item.id].SetVisible(true)
}

func fail(msg string, err error) {
	panic(fmt.Errorf("%v: %v", msg, err))
}
<|endoftext|>


<commit_before>package utils

import (
	"database/sql"

	e "github.com/techjanitor/pram-post/errors"
)

// user struct
type User struct {
	Id    uint   `json:"id"`
	Name  string `json:"name"`
	Group uint   `json:"group"`
}

// get the user info
func (u *User) Info() (err error) {

	err := db.QueryRow("SELECT usergroup_id,user_name FROM users WHERE user_id = ?", u.Id).Scan(&u.Group, &u.Name)
	if err == sql.ErrNoRows {
		return e.ErrNotFound
	} else if err != nil {
		return
	}

	return

}
<commit_msg>get user name and group from the database on jwt verification<commit_after>package utils

import (
	"database/sql"

	e "github.com/techjanitor/pram-post/errors"
)

// user struct
type User struct {
	Id    uint   `json:"id"`
	Name  string `json:"name"`
	Group uint   `json:"group"`
}

// get the user info
func (u *User) Info() (err error) {

	err = db.QueryRow("SELECT usergroup_id,user_name FROM users WHERE user_id = ?", u.Id).Scan(&u.Group, &u.Name)
	if err == sql.ErrNoRows {
		return e.ErrNotFound
	} else if err != nil {
		return
	}

	return

}
<|endoftext|>


<commit_before>package registry

import (
	"errors"
	"sync"

	"github.com/hashicorp/consul/api"
	"github.com/hashicorp/consul/watch"
)

type consulWatcher struct {
	r        *consulRegistry
	wp       *watch.WatchPlan
	watchers map[string]*watch.WatchPlan

	once sync.Once
	next chan *Result

	sync.RWMutex
	services map[string][]*Service
}

func newConsulWatcher(cr *consulRegistry) (Watcher, error) {
	var once sync.Once
	cw := &consulWatcher{
		r:        cr,
		once:     once,
		next:     make(chan *Result, 10),
		watchers: make(map[string]*watch.WatchPlan),
		services: make(map[string][]*Service),
	}

	wp, err := watch.Parse(map[string]interface{}{"type": "services"})
	if err != nil {
		return nil, err
	}

	wp.Handler = cw.handle
	go wp.Run(cr.Address)
	cw.wp = wp

	return cw, nil
}

func (cw *consulWatcher) serviceHandler(idx uint64, data interface{}) {
	entries, ok := data.([]*api.ServiceEntry)
	if !ok {
		return
	}

	serviceMap := map[string]*Service{}
	serviceName := ""

	for _, e := range entries {
		serviceName = e.Service.Service
		// version is now a tag
		version, found := decodeVersion(e.Service.Tags)
		// service ID is now the node id
		id := e.Service.ID
		// key is always the version
		key := version
		// address is service address
		address := e.Service.Address

		// if we can't get the version we bail
		if !found {
			continue
		}

		svc, ok := serviceMap[key]
		if !ok {
			svc = &Service{
				Endpoints: decodeEndpoints(e.Service.Tags),
				Name:      e.Service.Service,
				Version:   version,
			}
			serviceMap[key] = svc
		}

		svc.Nodes = append(svc.Nodes, &Node{
			Id:       id,
			Address:  address,
			Port:     e.Service.Port,
			Metadata: decodeMetadata(e.Service.Tags),
		})
	}

	cw.RLock()
	rservices := cw.services
	cw.RUnlock()

	var newServices []*Service

	// serviceMap is the new set of services keyed by name+version
	for _, newService := range serviceMap {
		// append to the new set of cached services
		newServices = append(newServices, newService)

		// check if the service exists in the existing cache
		oldServices, ok := rservices[serviceName]
		if !ok {
			// does not exist? then we're creating brand new entries
			cw.next <- &Result{Action: "create", Service: newService}
			continue
		}

		// service exists. ok let's figure out what to update and delete version wise
		action := "create"

		for _, oldService := range oldServices {
			// does this version exist?
			// no? then default to create
			if oldService.Version != newService.Version {
				continue
			}

			// yes? then it's an update
			action = "update"

			var nodes []*Node
			// check the old nodes to see if they've been deleted
			for _, oldNode := range oldService.Nodes {
				var seen bool
				for _, newNode := range newService.Nodes {
					if newNode.Id == oldNode.Id {
						seen = true
						break
					}
				}
				// does the old node exist in the new set of nodes
				// no? then delete that shit
				if !seen {
					nodes = append(nodes, oldNode)
				}
			}

			// it's an update rather than creation
			if len(nodes) > 0 {
				delService := oldService
				delService.Nodes = nodes
				cw.next <- &Result{Action: "delete", Service: delService}
			}
		}
		cw.next <- &Result{Action: action, Service: newService}
	}

	// Now check old versions that may not be in new services map
	for _, old := range rservices[serviceName] {
		// old version does not exist in new version map
		// kill it with fire!
		if _, ok := serviceMap[old.Version]; !ok {
			cw.next <- &Result{Action: "delete", Service: old}
		}
	}

	cw.Lock()
	cw.services[serviceName] = newServices
	cw.Unlock()
}

func (cw *consulWatcher) handle(idx uint64, data interface{}) {
	services, ok := data.(map[string][]string)
	if !ok {
		return
	}

	// add new watchers
	for service, _ := range services {
		if _, ok := cw.watchers[service]; ok {
			continue
		}
		wp, err := watch.Parse(map[string]interface{}{
			"type":    "service",
			"service": service,
		})
		if err == nil {
			wp.Handler = cw.serviceHandler
			go wp.Run(cw.r.Address)
			cw.watchers[service] = wp
			cw.next <- &Result{Action: "create", Service: &Service{Name: service}}
		}
	}

	cw.RLock()
	rservices := cw.services
	cw.RUnlock()

	// remove unknown services from registry
	for service, _ := range rservices {
		if _, ok := services[service]; !ok {
			cw.Lock()
			delete(cw.services, service)
			cw.Unlock()
		}
	}

	// remove unknown services from watchers
	for service, w := range cw.watchers {
		if _, ok := services[service]; !ok {
			w.Stop()
			delete(cw.watchers, service)
			cw.next <- &Result{Action: "delete", Service: &Service{Name: service}}
		}
	}
}

func (cw *consulWatcher) Next() (*Result, error) {
	r, ok := <-cw.next
	if !ok {
		return nil, errors.New("chan closed")
	}
	return r, nil
}

func (cw *consulWatcher) Stop() {
	if cw.wp == nil {
		return
	}
	cw.wp.Stop()

	cw.once.Do(func() {
		close(cw.next)
	})
}
<commit_msg>When the TTL flips to critical we should issue a delete event<commit_after>package registry

import (
	"errors"
	"sync"

	"github.com/hashicorp/consul/api"
	"github.com/hashicorp/consul/watch"
)

type consulWatcher struct {
	r        *consulRegistry
	wp       *watch.WatchPlan
	watchers map[string]*watch.WatchPlan

	once sync.Once
	next chan *Result

	sync.RWMutex
	services map[string][]*Service
}

func newConsulWatcher(cr *consulRegistry) (Watcher, error) {
	var once sync.Once
	cw := &consulWatcher{
		r:        cr,
		once:     once,
		next:     make(chan *Result, 10),
		watchers: make(map[string]*watch.WatchPlan),
		services: make(map[string][]*Service),
	}

	wp, err := watch.Parse(map[string]interface{}{"type": "services"})
	if err != nil {
		return nil, err
	}

	wp.Handler = cw.handle
	go wp.Run(cr.Address)
	cw.wp = wp

	return cw, nil
}

func (cw *consulWatcher) serviceHandler(idx uint64, data interface{}) {
	entries, ok := data.([]*api.ServiceEntry)
	if !ok {
		return
	}

	serviceMap := map[string]*Service{}
	serviceName := ""

	for _, e := range entries {
		serviceName = e.Service.Service
		// version is now a tag
		version, found := decodeVersion(e.Service.Tags)
		// service ID is now the node id
		id := e.Service.ID
		// key is always the version
		key := version
		// address is service address
		address := e.Service.Address

		// if we can't get the version we bail
		if !found {
			continue
		}

		svc, ok := serviceMap[key]
		if !ok {
			svc = &Service{
				Endpoints: decodeEndpoints(e.Service.Tags),
				Name:      e.Service.Service,
				Version:   version,
			}
			serviceMap[key] = svc
		}

		var del bool

		for _, check := range e.Checks {
			if check.ServiceName != serviceName {
				continue
			}

			if check.ServiceID != id {
				continue
			}

			// delete the node
			if check.Status == "critical" {
				del = true
				break
			}
		}

		// if delete then skip the node
		if del {
			continue
		}

		svc.Nodes = append(svc.Nodes, &Node{
			Id:       id,
			Address:  address,
			Port:     e.Service.Port,
			Metadata: decodeMetadata(e.Service.Tags),
		})
	}

	cw.RLock()
	rservices := cw.services
	cw.RUnlock()

	var newServices []*Service

	// serviceMap is the new set of services keyed by name+version
	for _, newService := range serviceMap {
		// append to the new set of cached services
		newServices = append(newServices, newService)

		// check if the service exists in the existing cache
		oldServices, ok := rservices[serviceName]
		if !ok {
			// does not exist? then we're creating brand new entries
			cw.next <- &Result{Action: "create", Service: newService}
			continue
		}

		// service exists. ok let's figure out what to update and delete version wise
		action := "create"

		for _, oldService := range oldServices {
			// does this version exist?
			// no? then default to create
			if oldService.Version != newService.Version {
				continue
			}

			// yes? then it's an update
			action = "update"

			var nodes []*Node
			// check the old nodes to see if they've been deleted
			for _, oldNode := range oldService.Nodes {
				var seen bool
				for _, newNode := range newService.Nodes {
					if newNode.Id == oldNode.Id {
						seen = true
						break
					}
				}
				// does the old node exist in the new set of nodes
				// no? then delete that shit
				if !seen {
					nodes = append(nodes, oldNode)
				}
			}

			// it's an update rather than creation
			if len(nodes) > 0 {
				delService := oldService
				delService.Nodes = nodes
				cw.next <- &Result{Action: "delete", Service: delService}
			}
		}

		cw.next <- &Result{Action: action, Service: newService}
	}

	// Now check old versions that may not be in new services map
	for _, old := range rservices[serviceName] {
		// old version does not exist in new version map
		// kill it with fire!
		if _, ok := serviceMap[old.Version]; !ok {
			cw.next <- &Result{Action: "delete", Service: old}
		}
	}

	cw.Lock()
	cw.services[serviceName] = newServices
	cw.Unlock()
}

func (cw *consulWatcher) handle(idx uint64, data interface{}) {
	services, ok := data.(map[string][]string)
	if !ok {
		return
	}

	// add new watchers
	for service, _ := range services {
		if _, ok := cw.watchers[service]; ok {
			continue
		}
		wp, err := watch.Parse(map[string]interface{}{
			"type":    "service",
			"service": service,
		})
		if err == nil {
			wp.Handler = cw.serviceHandler
			go wp.Run(cw.r.Address)
			cw.watchers[service] = wp
			cw.next <- &Result{Action: "create", Service: &Service{Name: service}}
		}
	}

	cw.RLock()
	rservices := cw.services
	cw.RUnlock()

	// remove unknown services from registry
	for service, _ := range rservices {
		if _, ok := services[service]; !ok {
			cw.Lock()
			delete(cw.services, service)
			cw.Unlock()
		}
	}

	// remove unknown services from watchers
	for service, w := range cw.watchers {
		if _, ok := services[service]; !ok {
			w.Stop()
			delete(cw.watchers, service)
			cw.next <- &Result{Action: "delete", Service: &Service{Name: service}}
		}
	}
}

func (cw *consulWatcher) Next() (*Result, error) {
	r, ok := <-cw.next
	if !ok {
		return nil, errors.New("chan closed")
	}
	return r, nil
}

func (cw *consulWatcher) Stop() {
	if cw.wp == nil {
		return
	}
	cw.wp.Stop()

	cw.once.Do(func() {
		close(cw.next)
	})
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"io"
)

// Result is returned from any JSON request.
type Result struct {
	Status     string `json:"status,omitempty"`
	StatusCode int    `json:"statuscode"`
	Token      string `json:"token,omitempty"`
}

// SetStatus fills in the status text from a code.
func (r *Result) SetStatus(code int) {
	s, ok := messages[code]
	if !ok {
		r.StatusCode = StatusOK
		r.Status = messages[StatusOK]
		return
	}
	r.StatusCode = code
	r.Status = s
}

func respond(w io.Writer, r interface{}) error {
	res, err := json.Marshal(r)
	if err != nil {
		return err
	}

	_, err = w.Write(res)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Phrasing.<commit_after>package main

import (
	"encoding/json"
	"io"
)

// Result is returned from many JSON requests.
type Result struct {
	Status     string `json:"status,omitempty"`
	StatusCode int    `json:"statuscode"`
	Token      string `json:"token,omitempty"`
}

// SetStatus fills in the status text from a code.
func (r *Result) SetStatus(code int) {
	s, ok := messages[code]
	if !ok {
		r.StatusCode = StatusOK
		r.Status = messages[StatusOK]
		return
	}
	r.StatusCode = code
	r.Status = s
}

func respond(w io.Writer, r interface{}) error {
	res, err := json.Marshal(r)
	if err != nil {
		return err
	}

	_, err = w.Write(res)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package gxutil

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"

	. "github.com/whyrusleeping/stump"
)

type ErrAlreadyInstalled struct {
	pkg string
}

func IsErrAlreadyInstalled(err error) bool {
	_, ok := err.(ErrAlreadyInstalled)
	return ok
}

func (eai ErrAlreadyInstalled) Error() string {
	return fmt.Sprintf("package %s already installed", eai.pkg)
}

func (pm *PM) GetPackageTo(hash, out string) (*Package, error) {
	var pkg Package
	_, err := os.Stat(out)
	if err == nil {
		err := FindPackageInDir(&pkg, out)
		if err == nil {
			return &pkg, nil
		} else if !os.IsNotExist(err) {
			return nil, err
		}
	}

	if err != nil && !os.IsNotExist(err) {
		return nil, err
	}

	begin := time.Now()
	VLog("  - fetching %s via ipfs api", hash)
	tries := 3
	for i := 0; i < tries; i++ {
		err = pm.Shell().Get(hash, out)
		if err != nil {
			Error("from shell.Get(): ", err)
			if i == tries-1 {
				return nil, err
			}
			Log("retrying fetch %s after a second...", hash)
			time.Sleep(time.Second)
		} else {
			break
		}
	}
	VLog("  - fetch finished in %s", time.Now().Sub(begin))

	err = FindPackageInDir(&pkg, out)
	if err != nil {
		return nil, err
	}

	return &pkg, nil
}

func FindPackageInDir(pkg interface{}, dir string) error {
	if err := LoadPackageFile(pkg, filepath.Join(dir, PkgFileName)); err == nil {
		return nil
	}

	name, err := PackageNameInDir(dir)
	if err != nil {
		return err
	}
	return LoadPackageFile(pkg, filepath.Join(dir, name, PkgFileName))
}

func PackageNameInDir(dir string) (string, error) {
	fs, err := ioutil.ReadDir(dir)
	if err != nil {
		return "", err
	}

	if len(fs) == 0 {
		return "", fmt.Errorf("no package found in hashdir: %s", dir)
	}

	if len(fs) > 1 {
		return "", fmt.Errorf("found multiple packages in hashdir: %s", dir)
	}

	return fs[0].Name(), nil
}
<commit_msg>don't leave partial downloads in place<commit_after>package gxutil

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"

	rname "github.com/jbenet/go-os-rename"
	. "github.com/whyrusleeping/stump"
)

type ErrAlreadyInstalled struct {
	pkg string
}

func IsErrAlreadyInstalled(err error) bool {
	_, ok := err.(ErrAlreadyInstalled)
	return ok
}

func (eai ErrAlreadyInstalled) Error() string {
	return fmt.Sprintf("package %s already installed", eai.pkg)
}

func (pm *PM) GetPackageTo(hash, out string) (*Package, error) {
	var pkg Package
	_, err := os.Stat(out)
	if err == nil {
		err := FindPackageInDir(&pkg, out)
		if err == nil {
			return &pkg, nil
		} else if !os.IsNotExist(err) {
			return nil, err
		}
	}

	if err != nil && !os.IsNotExist(err) {
		return nil, err
	}

	outtemp := out + ".part"

	// check if a fetch was previously started and failed, cleanup if found
	_, err = os.Stat(outtemp)
	if err == nil {
		VLog("Found previously failed fetch, cleaning up...")
		if err := os.RemoveAll(outtemp); err != nil {
			Error("cleaning up aborted transfer: %s", err)
		}
	}

	begin := time.Now()
	VLog("  - fetching %s via ipfs api", hash)
	tries := 3
	for i := 0; i < tries; i++ {
		if err := pm.Shell().Get(hash, outtemp); err != nil {
			Error("from shell.Get(): ", err)

			rmerr := os.RemoveAll(outtemp)
			if rmerr != nil {
				Error("cleaning up temp download directory: %s", rmerr)
			}

			if i == tries-1 {
				return nil, err
			}
			Log("retrying fetch %s after a second...", hash)
			time.Sleep(time.Second)
		} else {
			if err := rname.Rename(outtemp, out); err != nil {
				return nil, err
			}
			break
		}
	}
	VLog("  - fetch finished in %s", time.Now().Sub(begin))

	err = FindPackageInDir(&pkg, out)
	if err != nil {
		return nil, err
	}

	return &pkg, nil
}

func FindPackageInDir(pkg interface{}, dir string) error {
	if err := LoadPackageFile(pkg, filepath.Join(dir, PkgFileName)); err == nil {
		return nil
	}

	name, err := PackageNameInDir(dir)
	if err != nil {
		return err
	}
	return LoadPackageFile(pkg, filepath.Join(dir, name, PkgFileName))
}

func PackageNameInDir(dir string) (string, error) {
	fs, err := ioutil.ReadDir(dir)
	if err != nil {
		return "", err
	}

	if len(fs) == 0 {
		return "", fmt.Errorf("no package found in hashdir: %s", dir)
	}

	if len(fs) > 1 {
		return "", fmt.Errorf("found multiple packages in hashdir: %s", dir)
	}

	return fs[0].Name(), nil
}
<|endoftext|>


<commit_before>package fire

import (
	"testing"

	"github.com/Jeffail/gabs"
	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
	"gopkg.in/mgo.v2"
)

var session *mgo.Session

func init() {
	// set test mode
	gin.SetMode(gin.TestMode)

	// connect to local mongodb
	sess, err := mgo.Dial("mongodb://0.0.0.0:27017/fire")
	if err != nil {
		panic(err)
	}

	// store session globally
	session = sess
}

func getDB() *mgo.Database {
	// get db
	db := session.DB("")

	// clean database by removing all documents
	db.C("posts").RemoveAll(nil)
	db.C("comments").RemoveAll(nil)
	db.C("users").RemoveAll(nil)
	db.C("applications").RemoveAll(nil)
	db.C("access_tokens").RemoveAll(nil)

	return db
}

func buildServer(resources ...*Resource) (*gin.Engine, *mgo.Database) {
	// get db
	db := getDB()

	// create new router and endpoint
	router := gin.New()
	endpoint := NewEndpoint(db)

	// add all supplied resources
	for _, res := range resources {
		endpoint.AddResource(res)
	}

	// register routes
	endpoint.Register("", router)

	// return router
	return router, db
}

func saveModel(db *mgo.Database, model Model) Model {
	Init(model)

	err := db.C(model.Meta().Collection).Insert(model)
	if err != nil {
		panic(err)
	}

	return model
}

func countChildren(c *gabs.Container) int {
	list, _ := c.Children()
	return len(list)
}

// cheat to get more coverage

func TestAdapter(t *testing.T) {
	assert.Nil(t, (&adapter{}).Handler())
}
<commit_msg>cleanup<commit_after>package fire

import (
	"testing"

	"github.com/Jeffail/gabs"
	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
	"gopkg.in/mgo.v2"
)

var session *mgo.Session

func init() {
	// set test mode
	gin.SetMode(gin.TestMode)

	// connect to local mongodb
	sess, err := mgo.Dial("mongodb://0.0.0.0:27017/fire")
	if err != nil {
		panic(err)
	}

	// store session globally
	session = sess
}

func getDB() *mgo.Database {
	// get db
	db := session.DB("")

	// clean database by removing all documents
	db.C("posts").RemoveAll(nil)
	db.C("comments").RemoveAll(nil)

	return db
}

func buildServer(resources ...*Resource) (*gin.Engine, *mgo.Database) {
	// get db
	db := getDB()

	// create new router and endpoint
	router := gin.New()
	endpoint := NewEndpoint(db)

	// add all supplied resources
	for _, res := range resources {
		endpoint.AddResource(res)
	}

	// register routes
	endpoint.Register("", router)

	// return router
	return router, db
}

func saveModel(db *mgo.Database, model Model) Model {
	Init(model)

	err := db.C(model.Meta().Collection).Insert(model)
	if err != nil {
		panic(err)
	}

	return model
}

func countChildren(c *gabs.Container) int {
	list, _ := c.Children()
	return len(list)
}

// cheat to get more coverage

func TestAdapter(t *testing.T) {
	assert.Nil(t, (&adapter{}).Handler())
}
<|endoftext|>