<commit_before>/*
Copyright 2014 The Kubernetes Authors.

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

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

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

package cmd

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"os/signal"

	"github.com/spf13/cobra"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	restclient "k8s.io/client-go/rest"
	"k8s.io/client-go/tools/portforward"
	"k8s.io/client-go/transport/spdy"
	"k8s.io/kubernetes/pkg/api"
	coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
	"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
	"k8s.io/kubernetes/pkg/util/i18n"
)

// PortForwardOptions contains all the options for running the port-forward cli command.
type PortForwardOptions struct {
	Namespace     string
	PodName       string
	RESTClient    *restclient.RESTClient
	Config        *restclient.Config
	PodClient     coreclient.PodsGetter
	Ports         []string
	PortForwarder portForwarder
	StopChannel   chan struct{}
	ReadyChannel  chan struct{}
}

var (
	portforwardExample = templates.Examples(i18n.T(`
		# Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod
		kubectl port-forward mypod 5000 6000

		# Listen on port 8888 locally, forwarding to 5000 in the pod
		kubectl port-forward mypod 8888:5000

		# Listen on a random port locally, forwarding to 5000 in the pod
		kubectl port-forward mypod :5000

		# Listen on a random port locally, forwarding to 5000 in the pod
		kubectl port-forward mypod 0:5000`))
)

func NewCmdPortForward(f cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra.Command {
	opts := &PortForwardOptions{
		PortForwarder: &defaultPortForwarder{
			cmdOut: cmdOut,
			cmdErr: cmdErr,
		},
	}
	cmd := &cobra.Command{
		Use:     "port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]",
		Short:   i18n.T("Forward one or more local ports to a pod"),
		Long:    "Forward one or more local ports to a pod.",
		Example: portforwardExample,
		Run: func(cmd *cobra.Command, args []string) {
			if err := opts.Complete(f, cmd, args); err != nil {
				cmdutil.CheckErr(err)
			}
			if err := opts.Validate(); err != nil {
				cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err.Error()))
			}
			if err := opts.RunPortForward(); err != nil {
				cmdutil.CheckErr(err)
			}
		},
	}
	cmd.Flags().StringP("pod", "p", "", "Pod name")
	// TODO support UID
	return cmd
}

type portForwarder interface {
	ForwardPorts(method string, url *url.URL, opts PortForwardOptions) error
}

type defaultPortForwarder struct {
	cmdOut, cmdErr io.Writer
}

func (f *defaultPortForwarder) ForwardPorts(method string, url *url.URL, opts PortForwardOptions) error {
	transport, upgrader, err := spdy.RoundTripperFor(opts.Config)
	if err != nil {
		return err
	}
	dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, method, url)
	fw, err := portforward.New(dialer, opts.Ports, opts.StopChannel, opts.ReadyChannel, f.cmdOut, f.cmdErr)
	if err != nil {
		return err
	}
	return fw.ForwardPorts()
}

// Complete completes all the required options for port-forward cmd.
func (o *PortForwardOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
	var err error
	o.PodName = cmdutil.GetFlagString(cmd, "pod")
	if len(o.PodName) == 0 && len(args) == 0 {
		return cmdutil.UsageErrorf(cmd, "POD is required for port-forward")
	}

	if len(o.PodName) != 0 {
		printDeprecationWarning("port-forward POD", "-p POD")
		o.Ports = args
	} else {
		o.PodName = args[0]
		o.Ports = args[1:]
	}

	o.Namespace, _, err = f.DefaultNamespace()
	if err != nil {
		return err
	}

	clientset, err := f.ClientSet()
	if err != nil {
		return err
	}
	o.PodClient = clientset.Core()

	o.Config, err = f.ClientConfig()
	if err != nil {
		return err
	}
	o.RESTClient, err = f.RESTClient()
	if err != nil {
		return err
	}

	o.StopChannel = make(chan struct{}, 1)
	o.ReadyChannel = make(chan struct{})
	return nil
}

// Validate validates all the required options for port-forward cmd.
func (o PortForwardOptions) Validate() error {
	if len(o.PodName) == 0 {
		return fmt.Errorf("pod name must be specified")
	}

	if len(o.Ports) < 1 {
		return fmt.Errorf("at least 1 PORT is required for port-forward")
	}

	if o.PortForwarder == nil || o.PodClient == nil || o.RESTClient == nil || o.Config == nil {
		return fmt.Errorf("client, client config, restClient, and portforwarder must be provided")
	}
	return nil
}

// RunPortForward implements all the necessary functionality for port-forward cmd.
func (o PortForwardOptions) RunPortForward() error {
	pod, err := o.PodClient.Pods(o.Namespace).Get(o.PodName, metav1.GetOptions{})
	if err != nil {
		return err
	}

	if pod.Status.Phase != api.PodRunning {
		return fmt.Errorf("unable to forward port because pod is not running. Current status=%v", pod.Status.Phase)
	}

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, os.Interrupt)
	defer signal.Stop(signals)

	go func() {
		<-signals
		if o.StopChannel != nil {
			close(o.StopChannel)
		}
	}()

	req := o.RESTClient.Post().
		Resource("pods").
		Namespace(o.Namespace).
		Name(pod.Name).
		SubResource("portforward")

	return o.PortForwarder.ForwardPorts("POST", req.URL(), o)
}
<commit_msg>Remove duplicate command example<commit_after>/*
Copyright 2014 The Kubernetes Authors.

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

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

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

package cmd

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"os/signal"

	"github.com/spf13/cobra"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	restclient "k8s.io/client-go/rest"
	"k8s.io/client-go/tools/portforward"
	"k8s.io/client-go/transport/spdy"
	"k8s.io/kubernetes/pkg/api"
	coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
	"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
	"k8s.io/kubernetes/pkg/util/i18n"
)

// PortForwardOptions contains all the options for running the port-forward cli command.
type PortForwardOptions struct {
	Namespace     string
	PodName       string
	RESTClient    *restclient.RESTClient
	Config        *restclient.Config
	PodClient     coreclient.PodsGetter
	Ports         []string
	PortForwarder portForwarder
	StopChannel   chan struct{}
	ReadyChannel  chan struct{}
}

var (
	portforwardExample = templates.Examples(i18n.T(`
		# Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod
		kubectl port-forward mypod 5000 6000

		# Listen on port 8888 locally, forwarding to 5000 in the pod
		kubectl port-forward mypod 8888:5000

		# Listen on a random port locally, forwarding to 5000 in the pod
		kubectl port-forward mypod :5000`))
)

func NewCmdPortForward(f cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra.Command {
	opts := &PortForwardOptions{
		PortForwarder: &defaultPortForwarder{
			cmdOut: cmdOut,
			cmdErr: cmdErr,
		},
	}
	cmd := &cobra.Command{
		Use:     "port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]",
		Short:   i18n.T("Forward one or more local ports to a pod"),
		Long:    "Forward one or more local ports to a pod.",
		Example: portforwardExample,
		Run: func(cmd *cobra.Command, args []string) {
			if err := opts.Complete(f, cmd, args); err != nil {
				cmdutil.CheckErr(err)
			}
			if err := opts.Validate(); err != nil {
				cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err.Error()))
			}
			if err := opts.RunPortForward(); err != nil {
				cmdutil.CheckErr(err)
			}
		},
	}
	cmd.Flags().StringP("pod", "p", "", "Pod name")
	// TODO support UID
	return cmd
}

type portForwarder interface {
	ForwardPorts(method string, url *url.URL, opts PortForwardOptions) error
}

type defaultPortForwarder struct {
	cmdOut, cmdErr io.Writer
}

func (f *defaultPortForwarder) ForwardPorts(method string, url *url.URL, opts PortForwardOptions) error {
	transport, upgrader, err := spdy.RoundTripperFor(opts.Config)
	if err != nil {
		return err
	}
	dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, method, url)
	fw, err := portforward.New(dialer, opts.Ports, opts.StopChannel, opts.ReadyChannel, f.cmdOut, f.cmdErr)
	if err != nil {
		return err
	}
	return fw.ForwardPorts()
}

// Complete completes all the required options for port-forward cmd.
func (o *PortForwardOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
	var err error
	o.PodName = cmdutil.GetFlagString(cmd, "pod")
	if len(o.PodName) == 0 && len(args) == 0 {
		return cmdutil.UsageErrorf(cmd, "POD is required for port-forward")
	}

	if len(o.PodName) != 0 {
		printDeprecationWarning("port-forward POD", "-p POD")
		o.Ports = args
	} else {
		o.PodName = args[0]
		o.Ports = args[1:]
	}

	o.Namespace, _, err = f.DefaultNamespace()
	if err != nil {
		return err
	}

	clientset, err := f.ClientSet()
	if err != nil {
		return err
	}
	o.PodClient = clientset.Core()

	o.Config, err = f.ClientConfig()
	if err != nil {
		return err
	}
	o.RESTClient, err = f.RESTClient()
	if err != nil {
		return err
	}

	o.StopChannel = make(chan struct{}, 1)
	o.ReadyChannel = make(chan struct{})
	return nil
}

// Validate validates all the required options for port-forward cmd.
func (o PortForwardOptions) Validate() error {
	if len(o.PodName) == 0 {
		return fmt.Errorf("pod name must be specified")
	}

	if len(o.Ports) < 1 {
		return fmt.Errorf("at least 1 PORT is required for port-forward")
	}

	if o.PortForwarder == nil || o.PodClient == nil || o.RESTClient == nil || o.Config == nil {
		return fmt.Errorf("client, client config, restClient, and portforwarder must be provided")
	}
	return nil
}

// RunPortForward implements all the necessary functionality for port-forward cmd.
func (o PortForwardOptions) RunPortForward() error {
	pod, err := o.PodClient.Pods(o.Namespace).Get(o.PodName, metav1.GetOptions{})
	if err != nil {
		return err
	}

	if pod.Status.Phase != api.PodRunning {
		return fmt.Errorf("unable to forward port because pod is not running. Current status=%v", pod.Status.Phase)
	}

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, os.Interrupt)
	defer signal.Stop(signals)

	go func() {
		<-signals
		if o.StopChannel != nil {
			close(o.StopChannel)
		}
	}()

	req := o.RESTClient.Post().
		Resource("pods").
		Namespace(o.Namespace).
		Name(pod.Name).
		SubResource("portforward")

	return o.PortForwarder.ForwardPorts("POST", req.URL(), o)
}
<|endoftext|>


<commit_before>package mount // import "github.com/docker/docker/pkg/mount"

/*
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
*/
import "C"

import (
	"fmt"
	"reflect"
	"unsafe"
)

//parseMountTable returns information about mounted filesystems
func parseMountTable(filter FilterFunc) ([]*Info, error) {
	var rawEntries *C.struct_statfs

	count := int(C.getmntinfo(&rawEntries, C.MNT_WAIT))
	if count == 0 {
		return nil, fmt.Errorf("Failed to call getmntinfo")
	}

	var entries []C.struct_statfs
	header := (*reflect.SliceHeader)(unsafe.Pointer(&entries))
	header.Cap = count
	header.Len = count
	header.Data = uintptr(unsafe.Pointer(rawEntries))

	var out []*Info
	for _, entry := range entries {
		var mountinfo Info
		var skip, stop bool
		mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0])

		if filter != nil {
			// filter out entries we're not interested in
			skip, stop = filter(&mountinfo)
			if skip {
				continue
			}
		}

		mountinfo.Source = C.GoString(&entry.f_mntfromname[0])
		mountinfo.Fstype = C.GoString(&entry.f_fstypename[0])

		out = append(out, &mountinfo)
		if stop {
			break
		}
	}
	return out, nil
}
<commit_msg>Fix to gofmt/goimports errors<commit_after>package mount // import "github.com/docker/docker/pkg/mount"

/*
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
*/
import "C"

import (
	"fmt"
	"reflect"
	"unsafe"
)

//parseMountTable returns information about mounted filesystems
func parseMountTable(filter FilterFunc) ([]*Info, error) {
	var rawEntries *C.struct_statfs

	count := int(C.getmntinfo(&rawEntries, C.MNT_WAIT))
	if count == 0 {
		return nil, fmt.Errorf("Failed to call getmntinfo")
	}

	var entries []C.struct_statfs
	header := (*reflect.SliceHeader)(unsafe.Pointer(&entries))
	header.Cap = count
	header.Len = count
	header.Data = uintptr(unsafe.Pointer(rawEntries))

	var out []*Info
	for _, entry := range entries {
		var mountinfo Info
		var skip, stop bool
		mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0])

		if filter != nil {
			// filter out entries we're not interested in
			skip, stop = filter(&mountinfo)
			if skip {
				continue
			}
		}

		mountinfo.Source = C.GoString(&entry.f_mntfromname[0])
		mountinfo.Fstype = C.GoString(&entry.f_fstypename[0])

		out = append(out, &mountinfo)
		if stop {
			break
		}
	}
	return out, nil
}
<|endoftext|>


<commit_before>package rtcp

import (
	"encoding/binary"

	"github.com/pkg/errors"
)

// RTP SDES item types registered with IANA. See: https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-5
const (
	SDESEnd      = iota // end of SDES list                RFC 3550, 6.5
	SDESCNAME           // canonical name                  RFC 3550, 6.5.1
	SDESName            // user name                       RFC 3550, 6.5.2
	SDESEmail           // user's electronic mail address  RFC 3550, 6.5.3
	SDESPhone           // user's phone number             RFC 3550, 6.5.4
	SDESLocation        // geographic user location        RFC 3550, 6.5.5
	SDESTool            // name of application or tool     RFC 3550, 6.5.6
	SDESNote            // notice about the source         RFC 3550, 6.5.7
	SDESPrivate         // private extensions              RFC 3550, 6.5.8  (not implemented)
)

var (
	errSDESTextTooLong = errors.New("session description must be < 255 octets long")
	errSDESMissingType = errors.New("session description item missing type")
)

const (
	sdesSourceLen        = 4
	sdesTypeLen          = 1
	sdesTypeOffset       = 0
	sdesOctetCountLen    = 1
	sdesOctetCountOffset = 1
	sdesMaxOctetCount    = (1 << 8) - 1
	sdesTextOffset       = 2
)

// A SourceDescription (SDES) packet describes the sources in an RTP stream.
type SourceDescription struct {
	Chunks []SourceDescriptionChunk
}

// Marshal encodes the SourceDescription in binary
func (s SourceDescription) Marshal() ([]byte, error) {
	/*
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 * chunk  |                          SSRC/CSRC_1                          |
	 *   1    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *        |                           SDES items                          |
	 *        |                              ...                              |
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 * chunk  |                          SSRC/CSRC_2                          |
	 *   2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *        |                           SDES items                          |
	 *        |                              ...                              |
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 */

	rawPacket := make([]byte, 0)
	for _, c := range s.Chunks {
		data, err := c.Marshal()
		if err != nil {
			return nil, err
		}
		rawPacket = append(rawPacket, data...)
	}

	return rawPacket, nil
}

// Unmarshal decodes the SourceDescription from binary
func (s *SourceDescription) Unmarshal(rawPacket []byte) error {
	/*
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 * chunk  |                          SSRC/CSRC_1                          |
	 *   1    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *        |                           SDES items                          |
	 *        |                              ...                              |
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 * chunk  |                          SSRC/CSRC_2                          |
	 *   2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *        |                           SDES items                          |
	 *        |                              ...                              |
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 */

	for i := 0; i < len(rawPacket); {
		var chunk SourceDescriptionChunk
		if err := chunk.Unmarshal(rawPacket[i:]); err != nil {
			return err
		}
		s.Chunks = append(s.Chunks, chunk)

		i += chunk.len()
	}

	return nil
}

// A SourceDescriptionChunk contains items describing a single RTP source
type SourceDescriptionChunk struct {
	// The source (ssrc) or contributing source (csrc) identifier this packet describes
	Source uint32
	Items  []SourceDescriptionItem
}

// Marshal encodes the SourceDescriptionChunk in binary
func (s SourceDescriptionChunk) Marshal() ([]byte, error) {
	/*
	 *  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 *  |                          SSRC/CSRC_1                          |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                           SDES items                          |
	 *  |                              ...                              |
	 *  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 */

	rawPacket := make([]byte, sdesSourceLen)
	binary.BigEndian.PutUint32(rawPacket, s.Source)

	for _, it := range s.Items {
		data, err := it.Marshal()
		if err != nil {
			return nil, err
		}
		rawPacket = append(rawPacket, data...)
	}

	// The list of items in each chunk MUST be terminated by one or more null octets
	rawPacket = append(rawPacket, SDESEnd)

	// additional null octets MUST be included if needed to pad until the next 32-bit boundary
	if size := len(rawPacket); size%4 != 0 {
		padding := make([]byte, 4-size%4)
		rawPacket = append(rawPacket, padding...)
	}

	return rawPacket, nil
}

// Unmarshal decodes the SourceDescriptionChunk from binary
func (s *SourceDescriptionChunk) Unmarshal(rawPacket []byte) error {
	/*
	 *  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 *  |                          SSRC/CSRC_1                          |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                           SDES items                          |
	 *  |                              ...                              |
	 *  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 */

	if len(rawPacket) < (sdesSourceLen + sdesTypeLen) {
		return errPacketTooShort
	}

	s.Source = binary.BigEndian.Uint32(rawPacket)

	for i := 4; i < len(rawPacket); {
		if pktType := rawPacket[i]; pktType == SDESEnd {
			return nil
		}

		var it SourceDescriptionItem
		if err := it.Unmarshal(rawPacket[i:]); err != nil {
			return err
		}
		s.Items = append(s.Items, it)
		i += it.len()
	}

	return errPacketTooShort
}

func (s SourceDescriptionChunk) len() int {
	len := sdesSourceLen
	for _, it := range s.Items {
		len += it.len()
	}
	len += sdesTypeLen // for terminating null octet

	// align to 32-bit boundary
	if len%4 != 0 {
		len += 4 - (len % 4)
	}

	return len
}

// A SourceDescriptionItem is a part of a SourceDescription that describes a stream.
type SourceDescriptionItem struct {
	// The type identifier for this item. eg, SDESCNAME for canonical name description.
	//
	// Type zero or SDESEnd is interpreted as the end of an item list and cannot be used.
	Type uint8
	// Text is a unicode text blob associated with the item. Its meaning varies based on the item's Type.
	Text string
}

func (s SourceDescriptionItem) len() int {
	/*
	 *   0                   1                   2                   3
	 *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |    CNAME=1    |     length    | user and domain name        ...
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 */
	return sdesTypeLen + sdesOctetCountLen + len([]byte(s.Text))
}

// Marshal encodes the SourceDescriptionItem in binary
func (s SourceDescriptionItem) Marshal() ([]byte, error) {
	/*
	 *   0                   1                   2                   3
	 *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |    CNAME=1    |     length    | user and domain name        ...
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 */

	if s.Type == SDESEnd {
		return nil, errSDESMissingType
	}

	rawPacket := make([]byte, sdesTypeLen+sdesOctetCountLen)

	rawPacket[sdesTypeOffset] = s.Type

	txtBytes := []byte(s.Text)
	octetCount := len(txtBytes)
	if octetCount > sdesMaxOctetCount {
		return nil, errSDESTextTooLong
	}
	rawPacket[sdesOctetCountOffset] = uint8(octetCount)

	rawPacket = append(rawPacket, txtBytes...)

	return rawPacket, nil
}

// Unmarshal decodes the SourceDescriptionItem from binary
func (s *SourceDescriptionItem) Unmarshal(rawPacket []byte) error {
	/*
	 *   0                   1                   2                   3
	 *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |    CNAME=1    |     length    | user and domain name        ...
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 */

	if len(rawPacket) < (sdesTypeLen + sdesOctetCountLen) {
		return errPacketTooShort
	}

	s.Type = rawPacket[sdesTypeOffset]

	octetCount := int(rawPacket[sdesOctetCountOffset])
	if sdesTextOffset+octetCount > len(rawPacket) {
		return errPacketTooShort
	}

	txtBytes := rawPacket[sdesTextOffset : sdesTextOffset+octetCount]
	s.Text = string(txtBytes)

	return nil
}
<commit_msg>Add String() to SDES item type<commit_after>package rtcp

import (
	"encoding/binary"

	"github.com/pkg/errors"
)

// SDESType is the item type used in the RTCP SDES control packet.
type SDESType uint8

// RTP SDES item types registered with IANA. See: https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-5
const (
	SDESEnd      SDESType = iota // end of SDES list                RFC 3550, 6.5
	SDESCNAME                    // canonical name                  RFC 3550, 6.5.1
	SDESName                     // user name                       RFC 3550, 6.5.2
	SDESEmail                    // user's electronic mail address  RFC 3550, 6.5.3
	SDESPhone                    // user's phone number             RFC 3550, 6.5.4
	SDESLocation                 // geographic user location        RFC 3550, 6.5.5
	SDESTool                     // name of application or tool     RFC 3550, 6.5.6
	SDESNote                     // notice about the source         RFC 3550, 6.5.7
	SDESPrivate                  // private extensions              RFC 3550, 6.5.8  (not implemented)
)

func (s SDESType) String() string {
	switch s {
	case SDESEnd:
		return "END"
	case SDESCNAME:
		return "CNAME"
	case SDESName:
		return "NAME"
	case SDESEmail:
		return "EMAIL"
	case SDESPhone:
		return "PHONE"
	case SDESLocation:
		return "LOC"
	case SDESTool:
		return "TOOL"
	case SDESNote:
		return "NOTE"
	case SDESPrivate:
		return "PRIV"
	default:
		return string(s)
	}
}

var (
	errSDESTextTooLong = errors.New("session description must be < 255 octets long")
	errSDESMissingType = errors.New("session description item missing type")
)

const (
	sdesSourceLen        = 4
	sdesTypeLen          = 1
	sdesTypeOffset       = 0
	sdesOctetCountLen    = 1
	sdesOctetCountOffset = 1
	sdesMaxOctetCount    = (1 << 8) - 1
	sdesTextOffset       = 2
)

// A SourceDescription (SDES) packet describes the sources in an RTP stream.
type SourceDescription struct {
	Chunks []SourceDescriptionChunk
}

// Marshal encodes the SourceDescription in binary
func (s SourceDescription) Marshal() ([]byte, error) {
	/*
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 * chunk  |                          SSRC/CSRC_1                          |
	 *   1    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *        |                           SDES items                          |
	 *        |                              ...                              |
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 * chunk  |                          SSRC/CSRC_2                          |
	 *   2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *        |                           SDES items                          |
	 *        |                              ...                              |
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 */

	rawPacket := make([]byte, 0)
	for _, c := range s.Chunks {
		data, err := c.Marshal()
		if err != nil {
			return nil, err
		}
		rawPacket = append(rawPacket, data...)
	}

	return rawPacket, nil
}

// Unmarshal decodes the SourceDescription from binary
func (s *SourceDescription) Unmarshal(rawPacket []byte) error {
	/*
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 * chunk  |                          SSRC/CSRC_1                          |
	 *   1    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *        |                           SDES items                          |
	 *        |                              ...                              |
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 * chunk  |                          SSRC/CSRC_2                          |
	 *   2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *        |                           SDES items                          |
	 *        |                              ...                              |
	 *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 */

	for i := 0; i < len(rawPacket); {
		var chunk SourceDescriptionChunk
		if err := chunk.Unmarshal(rawPacket[i:]); err != nil {
			return err
		}
		s.Chunks = append(s.Chunks, chunk)

		i += chunk.len()
	}

	return nil
}

// A SourceDescriptionChunk contains items describing a single RTP source
type SourceDescriptionChunk struct {
	// The source (ssrc) or contributing source (csrc) identifier this packet describes
	Source uint32
	Items  []SourceDescriptionItem
}

// Marshal encodes the SourceDescriptionChunk in binary
func (s SourceDescriptionChunk) Marshal() ([]byte, error) {
	/*
	 *  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 *  |                          SSRC/CSRC_1                          |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                           SDES items                          |
	 *  |                              ...                              |
	 *  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 */

	rawPacket := make([]byte, sdesSourceLen)
	binary.BigEndian.PutUint32(rawPacket, s.Source)

	for _, it := range s.Items {
		data, err := it.Marshal()
		if err != nil {
			return nil, err
		}
		rawPacket = append(rawPacket, data...)
	}

	// The list of items in each chunk MUST be terminated by one or more null octets
	rawPacket = append(rawPacket, uint8(SDESEnd))

	// additional null octets MUST be included if needed to pad until the next 32-bit boundary
	if size := len(rawPacket); size%4 != 0 {
		padding := make([]byte, 4-size%4)
		rawPacket = append(rawPacket, padding...)
	}

	return rawPacket, nil
}

// Unmarshal decodes the SourceDescriptionChunk from binary
func (s *SourceDescriptionChunk) Unmarshal(rawPacket []byte) error {
	/*
	 *  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 *  |                          SSRC/CSRC_1                          |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                           SDES items                          |
	 *  |                              ...                              |
	 *  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
	 */

	if len(rawPacket) < (sdesSourceLen + sdesTypeLen) {
		return errPacketTooShort
	}

	s.Source = binary.BigEndian.Uint32(rawPacket)

	for i := 4; i < len(rawPacket); {
		if pktType := SDESType(rawPacket[i]); pktType == SDESEnd {
			return nil
		}

		var it SourceDescriptionItem
		if err := it.Unmarshal(rawPacket[i:]); err != nil {
			return err
		}
		s.Items = append(s.Items, it)
		i += it.len()
	}

	return errPacketTooShort
}

func (s SourceDescriptionChunk) len() int {
	len := sdesSourceLen
	for _, it := range s.Items {
		len += it.len()
	}
	len += sdesTypeLen // for terminating null octet

	// align to 32-bit boundary
	if len%4 != 0 {
		len += 4 - (len % 4)
	}

	return len
}

// A SourceDescriptionItem is a part of a SourceDescription that describes a stream.
type SourceDescriptionItem struct {
	// The type identifier for this item. eg, SDESCNAME for canonical name description.
	//
	// Type zero or SDESEnd is interpreted as the end of an item list and cannot be used.
	Type SDESType
	// Text is a unicode text blob associated with the item. Its meaning varies based on the item's Type.
	Text string
}

func (s SourceDescriptionItem) len() int {
	/*
	 *   0                   1                   2                   3
	 *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |    CNAME=1    |     length    | user and domain name        ...
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 */
	return sdesTypeLen + sdesOctetCountLen + len([]byte(s.Text))
}

// Marshal encodes the SourceDescriptionItem in binary
func (s SourceDescriptionItem) Marshal() ([]byte, error) {
	/*
	 *   0                   1                   2                   3
	 *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |    CNAME=1    |     length    | user and domain name        ...
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 */

	if s.Type == SDESEnd {
		return nil, errSDESMissingType
	}

	rawPacket := make([]byte, sdesTypeLen+sdesOctetCountLen)

	rawPacket[sdesTypeOffset] = uint8(s.Type)

	txtBytes := []byte(s.Text)
	octetCount := len(txtBytes)
	if octetCount > sdesMaxOctetCount {
		return nil, errSDESTextTooLong
	}
	rawPacket[sdesOctetCountOffset] = uint8(octetCount)

	rawPacket = append(rawPacket, txtBytes...)

	return rawPacket, nil
}

// Unmarshal decodes the SourceDescriptionItem from binary
func (s *SourceDescriptionItem) Unmarshal(rawPacket []byte) error {
	/*
	 *   0                   1                   2                   3
	 *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |    CNAME=1    |     length    | user and domain name        ...
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 */

	if len(rawPacket) < (sdesTypeLen + sdesOctetCountLen) {
		return errPacketTooShort
	}

	s.Type = SDESType(rawPacket[sdesTypeOffset])

	octetCount := int(rawPacket[sdesOctetCountOffset])
	if sdesTextOffset+octetCount > len(rawPacket) {
		return errPacketTooShort
	}

	txtBytes := rawPacket[sdesTextOffset : sdesTextOffset+octetCount]
	s.Text = string(txtBytes)

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"koding/db/models"
	"koding/db/mongodb/modelhelper"
)

// pops username from set in db and gets metrics for machines belonging
// to that user; it uses pop instead of find so multiple workers can
// work in parallel
func getAndSaveQueueMachineMetrics() error {
	var index = 0
	defer func() {
		Log.Info("Fetched: %d entries for queued usernames", index)
	}()

	for {
		for _, metric := range metricsToSave {
			machines, err := popMachinesForMetricGet(metric.GetName())
			if err != nil {
				// ran out of usernames in queue, so return
				if isRedisRecordNil(err) {
					return nil
				}
			}

			if len(machines) == 0 {
				Log.Error(err.Error())
				continue
			}

			for _, machine := range machines {
				err := metric.GetAndSaveData(machine.Credential)
				if err != nil {
					Log.Error(err.Error())
				}
			}
		}

		index += 1
	}

	return nil
}

func stopMachinesOverLimit() error {
	for _, metric := range metricsToSave {
		machines, err := metric.GetMachinesOverLimit()
		if err != nil {
			Log.Error(err.Error())
			continue
		}

		Log.Info(
			"Fetched: %d machines that are overlimit for metric: %s",
			len(machines), metric.GetName(),
		)

		if len(machines) == 0 {
			continue
		}

		var stopSuccess = 0

		for _, machine := range machines {
			err = stopVm(machine.ObjectId.Hex())
			if err != nil {
				Log.Error(err.Error())
				continue
			}

			stopSuccess += 1

			err := metric.RemoveUsername(machine.Credential)
			if err != nil {
				Log.Error(err.Error())
				continue
			}
		}

		Log.Info(
			"Successfully stopped: %d overlimit machines for metric: %s",
			len(machines), metric.GetName(),
		)
	}

	return nil
}

func queueUsernamesForMetricGet() error {
	machines, err := getRunningVms()
	if err != nil {
		return err
	}

	if len(machines) == 0 {
		return nil
	}

	usernames := []interface{}{}
	for _, machine := range machines {
		usernames = append(usernames, machine.Credential)
	}

	for _, metric := range metricsToSave {
		Log.Info("Queued: %d usernames for metric: %s", len(usernames), metric.GetName())

		err := storage.Queue(metric.GetName(), usernames)
		if err != nil {
			return err
		}
	}

	return nil
}

func popMachinesForMetricGet(metricName string) ([]*models.Machine, error) {
	username, err := storage.Pop(metricName)
	if err != nil {
		return nil, err
	}

	machines, err := modelhelper.GetMachinesForUsername(username)
	if err != nil {
		return nil, err
	}

	return machines, nil
}

func getRunningVms() ([]*models.Machine, error) {
	return modelhelper.GetRunningVms()
}
<commit_msg>vmwatcher: minor fix<commit_after>package main

import (
	"koding/db/models"
	"koding/db/mongodb/modelhelper"
)

// pops username from set in db and gets metrics for machines belonging
// to that user; it uses pop instead of find so multiple workers can
// work in parallel
func getAndSaveQueueMachineMetrics() error {
	var index = 0
	defer func() {
		Log.Info("Fetched: %d entries for queued usernames", index)
	}()

	for {
		for _, metric := range metricsToSave {
			machines, err := popMachinesForMetricGet(metric.GetName())
			if err != nil {
				// ran out of usernames in queue, so return
				if isRedisRecordNil(err) {
					return nil
				}
			}

			if len(machines) == 0 {
				continue
			}

			for _, machine := range machines {
				err := metric.GetAndSaveData(machine.Credential)
				if err != nil {
					Log.Error(err.Error())
				}
			}
		}

		index += 1
	}

	return nil
}

func stopMachinesOverLimit() error {
	for _, metric := range metricsToSave {
		machines, err := metric.GetMachinesOverLimit()
		if err != nil {
			Log.Error(err.Error())
			continue
		}

		Log.Info(
			"Fetched: %d machines that are overlimit for metric: %s",
			len(machines), metric.GetName(),
		)

		if len(machines) == 0 {
			continue
		}

		var stopSuccess = 0

		for _, machine := range machines {
			err = stopVm(machine.ObjectId.Hex())
			if err != nil {
				Log.Error(err.Error())
				continue
			}

			stopSuccess += 1

			err := metric.RemoveUsername(machine.Credential)
			if err != nil {
				Log.Error(err.Error())
				continue
			}
		}

		Log.Info(
			"Successfully stopped: %d overlimit machines for metric: %s",
			len(machines), metric.GetName(),
		)
	}

	return nil
}

func queueUsernamesForMetricGet() error {
	machines, err := getRunningVms()
	if err != nil {
		return err
	}

	if len(machines) == 0 {
		return nil
	}

	usernames := []interface{}{}
	for _, machine := range machines {
		usernames = append(usernames, machine.Credential)
	}

	for _, metric := range metricsToSave {
		Log.Info("Queued: %d usernames for metric: %s", len(usernames), metric.GetName())

		err := storage.Queue(metric.GetName(), usernames)
		if err != nil {
			return err
		}
	}

	return nil
}

func popMachinesForMetricGet(metricName string) ([]*models.Machine, error) {
	username, err := storage.Pop(metricName)
	if err != nil {
		return nil, err
	}

	machines, err := modelhelper.GetMachinesForUsername(username)
	if err != nil {
		return nil, err
	}

	return machines, nil
}

func getRunningVms() ([]*models.Machine, error) {
	return modelhelper.GetRunningVms()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/streadway/amqp"
	"koding/databases/neo4j"
	"koding/tools/amqputil"
	"log"
)

var (
	EXCHANGE_NAME     = "a-relationshipExchange"
	WORKER_QUEUE_NAME = "relationshipEventWorker"
)

type Consumer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
}

type Message struct {
	Event   string `json:"event"`
	Payload []EventData
}

type EventData struct {
	SourceName string
	SourceId   string
	TargetName string
	TargetId   string
	As         string
}

func main() {
	log.Println("Neo4J Feeder worker started")
	startConsuming()
	//looooop forever
	select {}
}

//here, mapping of decoded json
func jsonDecode(data string) (*Message, error) {
	source := &Message{}
	err := json.Unmarshal([]byte(data), &source)
	if err != nil {
		fmt.Println("Marshalling error:", err)
		return source, err
	}

	return source, nil
}

func startConsuming() {

	c := &Consumer{
		conn:    nil,
		channel: nil,
	}

	c.conn = amqputil.CreateConnection("neo4jFeeding")
	c.channel = amqputil.CreateChannel(c.conn)

	err := c.channel.ExchangeDeclare(EXCHANGE_NAME, "fanout", false, false, false, false, nil)
	if err != nil {
		log.Fatal("exchange.declare: %s", err)
	}

	//name, durable, autoDelete, exclusive, noWait, args Table
	if _, err := c.channel.QueueDeclare(WORKER_QUEUE_NAME, true, false, false, false, nil); err != nil {
		log.Fatal("queue.declare: %s", err)
	}

	if err := c.channel.QueueBind(WORKER_QUEUE_NAME, "" /* binding key */, EXCHANGE_NAME, false, nil); err != nil {
		log.Fatal("queue.bind: %s", err)
	}

	//(queue, consumer string, autoAck, exclusive, noLocal, noWait bool, args Table) (<-chan Delivery, error) {
	relationshipEvent, err := c.channel.Consume("relationshipEventWorker", "neo4jFeeding", true, false, false, false, nil)
	if err != nil {
		log.Fatal("basic.consume: %s", err)
	}

	go func() {
		for msg := range relationshipEvent {
			body := fmt.Sprintf("%s", msg.Body)

			message, err := jsonDecode(body)
			if err != nil {
				log.Fatal(err)
			}
			//there will be only one array in data
			data := message.Payload[0]
			fmt.Println(message.Event)
			if message.Event == "RelationshipSaved" {
				createNode(data)
			} else if message.Event == "RelationshipRemoved" {
				deleteNode(data)
			}
		}
	}()
}

func createNode(data EventData) {

	sourceNode := neo4j.CreateUniqueNode(data.SourceId, data.SourceName)
	targetNode := neo4j.CreateUniqueNode(data.TargetId, data.TargetName)

	source := fmt.Sprintf("%s", sourceNode["create_relationship"])
	target := fmt.Sprintf("%s", targetNode["self"])
	neo4j.CreateRelationship(data.As, source, target)

}

func deleteNode(data EventData) {
	result := neo4j.DeleteRelationship(data.SourceId, data.TargetId, data.As)
	if result {
		fmt.Println("Relationship deleted")
	} else {
		fmt.Println("Relationship couldnt be deleted")
	}
}
<commit_msg>[go][koding][workers] added node property updater methods<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/streadway/amqp"
	"koding/databases/mongo"
	"koding/databases/neo4j"
	"koding/tools/amqputil"
	"labix.org/v2/mgo/bson"
	"log"
)

var (
	EXCHANGE_NAME     = "a-relationshipExchange"
	WORKER_QUEUE_NAME = "relationshipEventWorker"
)

type Consumer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
}

type Message struct {
	Event   string `json:"event"`
	Payload []EventData
}

type EventData struct {
	SourceName string
	SourceId   string
	TargetName string
	TargetId   string
	As         string
}

func main() {
	log.Println("Neo4J Feeder worker started")
	startConsuming()
	//looooop forever
	select {}
}

//here, mapping of decoded json
func jsonDecode(data string) (*Message, error) {
	source := &Message{}
	err := json.Unmarshal([]byte(data), &source)
	if err != nil {
		fmt.Println("Marshalling error:", err)
		return source, err
	}

	return source, nil
}

func startConsuming() {

	c := &Consumer{
		conn:    nil,
		channel: nil,
	}

	c.conn = amqputil.CreateConnection("neo4jFeeding")
	c.channel = amqputil.CreateChannel(c.conn)

	err := c.channel.ExchangeDeclare(EXCHANGE_NAME, "fanout", false, false, false, false, nil)
	if err != nil {
		log.Fatal("exchange.declare: %s", err)
	}

	//name, durable, autoDelete, exclusive, noWait, args Table
	if _, err := c.channel.QueueDeclare(WORKER_QUEUE_NAME, true, false, false, false, nil); err != nil {
		log.Fatal("queue.declare: %s", err)
	}

	if err := c.channel.QueueBind(WORKER_QUEUE_NAME, "" /* binding key */, EXCHANGE_NAME, false, nil); err != nil {
		log.Fatal("queue.bind: %s", err)
	}

	//(queue, consumer string, autoAck, exclusive, noLocal, noWait bool, args Table) (<-chan Delivery, error) {
	relationshipEvent, err := c.channel.Consume(WORKER_QUEUE_NAME, "neo4jFeeding", true, false, false, false, nil)
	if err != nil {
		log.Fatal("basic.consume: %s", err)
	}

	go func() {
		for msg := range relationshipEvent {
			body := fmt.Sprintf("%s", msg.Body)

			message, err := jsonDecode(body)
			if err != nil {
				log.Fatal(err)
			}
			//there will be only one array in data
			data := message.Payload[0]
			fmt.Println(message.Event)
			if message.Event == "RelationshipSaved" {
				createNode(data)
			} else if message.Event == "RelationshipRemoved" {
				deleteNode(data)
			}
		}
	}()
}

func createNode(data EventData) {

	sourceNode := neo4j.CreateUniqueNode(data.SourceId, data.SourceName)
	fmt.Println(data)
	sourceContent, err := mongo.FetchContent(bson.ObjectIdHex(data.SourceId), data.SourceName)
	if err != nil {
		fmt.Println(err)
	} else {
		neo4j.UpdateNode(data.SourceId, sourceContent)
	}

	targetNode := neo4j.CreateUniqueNode(data.TargetId, data.TargetName)
	targetContent, err := mongo.FetchContent(bson.ObjectIdHex(data.TargetId), data.TargetName)
	if err != nil {
		fmt.Println(err)
	} else {
		neo4j.UpdateNode(data.TargetId, targetContent)
	}

	source := fmt.Sprintf("%s", sourceNode["create_relationship"])
	target := fmt.Sprintf("%s", targetNode["self"])
	neo4j.CreateRelationship(data.As, source, target)

}

func deleteNode(data EventData) {
	result := neo4j.DeleteRelationship(data.SourceId, data.TargetId, data.As)
	if result {
		fmt.Println("Relationship deleted")
	} else {
		fmt.Println("Relationship couldnt be deleted")
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2020 The Vitess Authors.

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

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

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

package vindexes

import (
	"bytes"
	"encoding/binary"
	"encoding/json"
	"io/ioutil"

	"vitess.io/vitess/go/sqltypes"
	"vitess.io/vitess/go/vt/key"
	"vitess.io/vitess/go/vt/log"
)

var (
	_ MultiColumn = (*RegionJson)(nil)
)

func init() {
	Register("region_json", NewRegionJson)
}

// RegionMap is used to store mapping of country to region
type RegionMap map[string]uint64

// RegionJson is a multi-column unique vindex
// The first column is used to lookup the prefix part of the keyspace id, the second column is hashed,
// and the two values are combined to produce the keyspace id.
// RegionJson can be used for geo-partitioning because the first column can denote a region,
// and it will dictate the shard range for that region.
type RegionJson struct {
	name        string
	regionMap   RegionMap
	regionBytes int
}

// NewRegionJson creates a RegionJson vindex.
// The supplied map requires all the fields of "RegionExperimental".
// Additionally, it requires a region_map argument representing the path to a json file
// containing a map of country to region.
func NewRegionJson(name string, m map[string]string) (Vindex, error) {
	rmPath := m["region_map"]
	rmap := make(map[string]uint64)
	data, err := ioutil.ReadFile(rmPath)
	if err != nil {
		return nil, err
	}
	log.Infof("Loaded Region map from: %s", rmPath)
	err = json.Unmarshal(data, &rmap)
	if err != nil {
		return nil, err
	}

	return &RegionJson{
		name:      name,
		regionMap: rmap,
	}, nil
}

// String returns the name of the vindex.
func (rv *RegionJson) String() string {
	return rv.name
}

// Cost returns the cost of this index as 1.
func (rv *RegionJson) Cost() int {
	return 1
}

// IsUnique returns true since the Vindex is unique.
func (rv *RegionJson) IsUnique() bool {
	return true
}

// Map satisfies MultiColumn.
func (rv *RegionJson) Map(vcursor VCursor, rowsColValues [][]sqltypes.Value) ([]key.Destination, error) {
	destinations := make([]key.Destination, 0, len(rowsColValues))
	for _, row := range rowsColValues {
		if len(row) != 2 {
			destinations = append(destinations, key.DestinationNone{})
			continue
		}
		// Compute hash.
		hn, err := sqltypes.ToUint64(row[0])
		if err != nil {
			destinations = append(destinations, key.DestinationNone{})
			continue
		}
		h := vhash(hn)

		rn, ok := rv.regionMap[row[1].ToString()]
		if !ok {
			destinations = append(destinations, key.DestinationNone{})
			continue
		}
		r := make([]byte, 2)
		binary.BigEndian.PutUint16(r, uint16(rn))

		// Concatenate and add to destinations.
		if rv.regionBytes == 1 {
			r = r[1:]
		}
		dest := append(r, h...)
		destinations = append(destinations, key.DestinationKeyspaceID(dest))
	}
	return destinations, nil
}

// Verify satisfies MultiColumn
func (rv *RegionJson) Verify(vcursor VCursor, rowsColValues [][]sqltypes.Value, ksids [][]byte) ([]bool, error) {
	result := make([]bool, len(rowsColValues))
	destinations, _ := rv.Map(vcursor, rowsColValues)
	for i, dest := range destinations {
		destksid, ok := dest.(key.DestinationKeyspaceID)
		if !ok {
			continue
		}
		result[i] = bytes.Equal([]byte(destksid), ksids[i])
	}
	return result, nil
}

// NeedVCursor satisfies the Vindex interface.
func (rv *RegionJson) NeedsVCursor() bool {
	return false
}
<commit_msg>region_json bug fix 1.region_bytes value when create region_json vindex 2.rename function name according golint hint<commit_after>/*
Copyright 2020 The Vitess Authors.

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

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

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

package vindexes

import (
	"bytes"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"strconv"

	"vitess.io/vitess/go/sqltypes"
	"vitess.io/vitess/go/vt/key"
	"vitess.io/vitess/go/vt/log"
)

var (
	_ MultiColumn = (*RegionJSON)(nil)
)

func init() {
	Register("region_json", NewRegionJSON)
}

// RegionMap is used to store mapping of country to region
type RegionMap map[string]uint64

// RegionJSON is a multi-column unique vindex
// The first column is used to lookup the prefix part of the keyspace id, the second column is hashed,
// and the two values are combined to produce the keyspace id.
// RegionJson can be used for geo-partitioning because the first column can denote a region,
// and it will dictate the shard range for that region.
type RegionJSON struct {
	name        string
	regionMap   RegionMap
	regionBytes int
}

// NewRegionJSON creates a RegionJson vindex.
// The supplied map requires all the fields of "RegionExperimental".
// Additionally, it requires a region_map argument representing the path to a json file
// containing a map of country to region.
func NewRegionJSON(name string, m map[string]string) (Vindex, error) {
	rmPath := m["region_map"]
	rmap := make(map[string]uint64)
	data, err := ioutil.ReadFile(rmPath)
	if err != nil {
		return nil, err
	}
	log.Infof("Loaded Region map from: %s", rmPath)
	err = json.Unmarshal(data, &rmap)
	if err != nil {
		return nil, err
	}
	rb, err := strconv.Atoi(m["region_bytes"])
	if err != nil {
		return nil, err
	}
	switch rb {
	case 1, 2:
	default:
		return nil, fmt.Errorf("region_bytes must be 1 or 2: %v", rb)
	}

	return &RegionJSON{
		name:        name,
		regionMap:   rmap,
		regionBytes: rb,
	}, nil
}

// String returns the name of the vindex.
func (rv *RegionJSON) String() string {
	return rv.name
}

// Cost returns the cost of this index as 1.
func (rv *RegionJSON) Cost() int {
	return 1
}

// IsUnique returns true since the Vindex is unique.
func (rv *RegionJSON) IsUnique() bool {
	return true
}

// Map satisfies MultiColumn.
func (rv *RegionJSON) Map(vcursor VCursor, rowsColValues [][]sqltypes.Value) ([]key.Destination, error) {
	destinations := make([]key.Destination, 0, len(rowsColValues))
	for _, row := range rowsColValues {
		if len(row) != 2 {
			destinations = append(destinations, key.DestinationNone{})
			continue
		}
		// Compute hash.
		hn, err := sqltypes.ToUint64(row[0])
		if err != nil {
			destinations = append(destinations, key.DestinationNone{})
			continue
		}
		h := vhash(hn)

		rn, ok := rv.regionMap[row[1].ToString()]
		if !ok {
			destinations = append(destinations, key.DestinationNone{})
			continue
		}
		r := make([]byte, 2)
		binary.BigEndian.PutUint16(r, uint16(rn))

		// Concatenate and add to destinations.
		if rv.regionBytes == 1 {
			r = r[1:]
		}
		dest := append(r, h...)
		destinations = append(destinations, key.DestinationKeyspaceID(dest))
	}
	return destinations, nil
}

// Verify satisfies MultiColumn
func (rv *RegionJSON) Verify(vcursor VCursor, rowsColValues [][]sqltypes.Value, ksids [][]byte) ([]bool, error) {
	result := make([]bool, len(rowsColValues))
	destinations, _ := rv.Map(vcursor, rowsColValues)
	for i, dest := range destinations {
		destksid, ok := dest.(key.DestinationKeyspaceID)
		if !ok {
			continue
		}
		result[i] = bytes.Equal([]byte(destksid), ksids[i])
	}
	return result, nil
}

// NeedsVCursor satisfies the Vindex interface.
func (rv *RegionJSON) NeedsVCursor() bool {
	return false
}
<|endoftext|>


<commit_before>package debug

import (
	"fmt"
	. "github.com/antonmedv/expr/vm"
	"github.com/gdamore/tcell"
	"github.com/rivo/tview"
	"os"
	"sort"
	"strconv"
	"strings"
	"time"
)

func StartDebugger(program *Program, env interface{}) {
	vm := Debug()
	app := tview.NewApplication()
	table := tview.NewTable()
	stack := tview.NewTable()
	stack.
		SetBorder(true).
		SetTitle("Stack")
	scope := tview.NewTable()
	scope.
		SetBorder(true).
		SetTitle("Scope")
	sub := tview.NewFlex().
		SetDirection(tview.FlexRow).
		AddItem(stack, 0, 3, false).
		AddItem(scope, 0, 1, false)
	flex := tview.NewFlex().
		AddItem(table, 0, 1, true).
		AddItem(sub, 0, 1, false)
	app.SetRoot(flex, true)

	go func() {
		out, err := vm.Run(program, env)
		app.QueueUpdateDraw(func() {
			sub.RemoveItem(stack)
			sub.RemoveItem(scope)
			result := tview.NewTextView()
			result.
				SetBorder(true).
				SetTitle("Output")
			result.SetText(fmt.Sprintf("%#v", out))
			sub.AddItem(result, 0, 1, false)
			if err != nil {
				errorView := tview.NewTextView()
				errorView.
					SetBorder(true).
					SetTitle("Error")
				errorView.SetText(err.Error())
				sub.AddItem(errorView, 0, 1, false)
			}
		})
	}()

	index := make(map[int]int)
	for row, line := range strings.Split(program.Disassemble(), "\n") {
		if line == "" {
			continue
		}
		parts := strings.Split(line, "\t")

		ip, err := strconv.Atoi(parts[0])
		check(err)
		index[ip] = row
		table.SetCellSimple(row, 0, fmt.Sprintf("% *d", 5, ip))

		for col := 1; col < len(parts); col++ {
			table.SetCellSimple(row, col, parts[col])
		}
		for col := len(parts); col < 4; col++ {
			table.SetCellSimple(row, col, "")
		}
		table.SetCell(row, 4, tview.NewTableCell("").SetExpansion(1))
	}

	draw := func(ip int) {
		app.QueueUpdateDraw(func() {
			for row := 0; row < table.GetRowCount(); row++ {
				for col := 0; col < table.GetColumnCount(); col++ {
					table.GetCell(row, col).SetBackgroundColor(tcell.ColorDefault)
				}
			}

			if row, ok := index[ip]; ok {
				table.Select(row, 0)
				for col := 0; col < 5; col++ {
					table.GetCell(row, col).SetBackgroundColor(tcell.ColorMediumBlue)
				}
				table.SetOffset(row-10, 0)

				opcode := table.GetCell(row, 1).Text
				if strings.HasPrefix(opcode, "OpJump") {
					jump := table.GetCell(row, 3).Text
					jump = strings.Trim(jump, "()")
					ip, err := strconv.Atoi(jump)
					if err == nil {
						if row, ok := index[ip]; ok {
							for col := 0; col < 5; col++ {
								table.GetCell(row, col).SetBackgroundColor(tcell.ColorDimGrey)
							}
						}
					}
				}
			}

			stack.Clear()
			for i, value := range vm.Stack() {
				stack.SetCellSimple(i, 0, fmt.Sprintf("% *d: ", 2, i))
				stack.SetCellSimple(i, 1, fmt.Sprintf("%+v", value))
			}
			stack.ScrollToEnd()

			scope.Clear()
			var keys []string
			for k := range vm.Scope() {
				keys = append(keys, k)
			}
			sort.Strings(keys)
			row := 0
			for _, name := range keys {
				scope.SetCellSimple(row, 0, fmt.Sprintf("%v: ", name))
				scope.SetCellSimple(row, 1, fmt.Sprintf("%v", vm.Scope()[name]))
				row++
			}
		})
	}

	getSelectedPosition := func() int {
		row, _ := table.GetSelection()
		ip, err := strconv.Atoi(strings.TrimSpace(table.GetCell(row, 0).Text))
		check(err)
		return ip
	}

	autostep := false
	var breakpoint int

	go func() {
		draw(0)
		for ip := range vm.Position() {
			draw(ip)

			if autostep {
				if breakpoint != ip {
					time.Sleep(20 * time.Millisecond)
					vm.Step()
				} else {
					autostep = false
				}
			}
		}
	}()

	app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
		if event.Key() == tcell.KeyDown || event.Key() == tcell.KeyUp {
			table.SetSelectable(true, false)
		}
		if event.Key() == tcell.KeyEnter {
			selectable, _ := table.GetSelectable()
			if selectable {
				table.SetSelectable(false, false)
				breakpoint = getSelectedPosition()
				autostep = true
			}
			vm.Step()
		}
		return event
	})

	err := app.Run()
	check(err)
}

func check(err error) {
	if err != nil {
		_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
		os.Exit(1)
	}
}
<commit_msg>Better debugger<commit_after>package debug

import (
	"fmt"
	. "github.com/antonmedv/expr/vm"
	"github.com/gdamore/tcell"
	"github.com/rivo/tview"
	"os"
	"sort"
	"strconv"
	"strings"
	"time"
)

func StartDebugger(program *Program, env interface{}) {
	vm := Debug()
	app := tview.NewApplication()
	table := tview.NewTable()
	stack := tview.NewTable()
	stack.
		SetBorder(true).
		SetTitle("Stack")
	scope := tview.NewTable()
	scope.
		SetBorder(true).
		SetTitle("Scope")
	sub := tview.NewFlex().
		SetDirection(tview.FlexRow).
		AddItem(stack, 0, 3, false).
		AddItem(scope, 0, 1, false)
	flex := tview.NewFlex().
		AddItem(table, 0, 1, true).
		AddItem(sub, 0, 1, false)
	app.SetRoot(flex, true)

	go func() {
		out, err := vm.Run(program, env)
		app.QueueUpdateDraw(func() {
			sub.RemoveItem(stack)
			sub.RemoveItem(scope)
			result := tview.NewTextView()
			result.
				SetBorder(true).
				SetTitle("Output")
			result.SetText(fmt.Sprintf("%#v", out))
			sub.AddItem(result, 0, 1, false)
			if err != nil {
				errorView := tview.NewTextView()
				errorView.
					SetBorder(true).
					SetTitle("Error")
				errorView.SetText(err.Error())
				sub.AddItem(errorView, 0, 1, false)
			}
		})
	}()

	index := make(map[int]int)
	for row, line := range strings.Split(program.Disassemble(), "\n") {
		if line == "" {
			continue
		}
		parts := strings.Split(line, "\t")

		ip, err := strconv.Atoi(parts[0])
		check(err)
		index[ip] = row
		table.SetCellSimple(row, 0, fmt.Sprintf("% *d", 5, ip))

		for col := 1; col < len(parts); col++ {
			table.SetCellSimple(row, col, parts[col])
		}
		for col := len(parts); col < 4; col++ {
			table.SetCellSimple(row, col, "")
		}
		table.SetCell(row, 4, tview.NewTableCell("").SetExpansion(1))
	}

	draw := func(ip int) {
		app.QueueUpdateDraw(func() {
			for row := 0; row < table.GetRowCount(); row++ {
				for col := 0; col < table.GetColumnCount(); col++ {
					table.GetCell(row, col).SetBackgroundColor(tcell.ColorDefault)
				}
			}

			if row, ok := index[ip]; ok {
				table.Select(row, 0)
				for col := 0; col < 5; col++ {
					table.GetCell(row, col).SetBackgroundColor(tcell.ColorMediumBlue)
				}
				table.SetOffset(row-10, 0)

				opcode := table.GetCell(row, 1).Text
				if strings.HasPrefix(opcode, "OpJump") {
					jump := table.GetCell(row, 3).Text
					jump = strings.Trim(jump, "()")
					ip, err := strconv.Atoi(jump)
					if err == nil {
						if row, ok := index[ip]; ok {
							for col := 0; col < 5; col++ {
								table.GetCell(row, col).SetBackgroundColor(tcell.ColorDimGrey)
							}
						}
					}
				}
			}

			stack.Clear()
			for i, value := range vm.Stack() {
				stack.SetCellSimple(i, 0, fmt.Sprintf("% *d: ", 2, i))
				stack.SetCellSimple(i, 1, fmt.Sprintf("%#v", value))
			}
			stack.ScrollToEnd()

			scope.Clear()
			var keys []string
			for k := range vm.Scope() {
				keys = append(keys, k)
			}
			sort.Strings(keys)
			row := 0
			for _, name := range keys {
				scope.SetCellSimple(row, 0, fmt.Sprintf("%v: ", name))
				scope.SetCellSimple(row, 1, fmt.Sprintf("%v", vm.Scope()[name]))
				row++
			}
		})
	}

	getSelectedPosition := func() int {
		row, _ := table.GetSelection()
		ip, err := strconv.Atoi(strings.TrimSpace(table.GetCell(row, 0).Text))
		check(err)
		return ip
	}

	autostep := false
	var breakpoint int

	go func() {
		draw(0)
		for ip := range vm.Position() {
			draw(ip)

			if autostep {
				if breakpoint != ip {
					time.Sleep(20 * time.Millisecond)
					vm.Step()
				} else {
					autostep = false
				}
			}
		}
	}()

	app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
		if event.Key() == tcell.KeyDown || event.Key() == tcell.KeyUp {
			table.SetSelectable(true, false)
		}
		if event.Key() == tcell.KeyEnter {
			selectable, _ := table.GetSelectable()
			if selectable {
				table.SetSelectable(false, false)
				breakpoint = getSelectedPosition()
				autostep = true
			}
			vm.Step()
		}
		return event
	})

	err := app.Run()
	check(err)
}

func check(err error) {
	if err != nil {
		_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package entrapped

import (
	"github.com/SKatiyar/entrapped/Godeps/_workspace/src/github.com/julienschmidt/httprouter"
	"net/http"
)

const (
	size     int = 7
	numBombs int = 10
	lifes    int = 5
)

func Start(addr string) {
	if len(addr) == 0 {
		addr = ":7000"
	}

	// initialize hunt
	go ch.run()

	// initialize router
	router := httprouter.New()

	// file routes
	router.GET("/", home)
	router.ServeFiles("/statics/*filepath", http.Dir("../../../client/dist/statics"))

	// socket route
	router.GET("/players/:id", addPlayer)

	// start listening to incoming connections
	listenErr := http.ListenAndServe(addr, router)
	if listenErr != nil {
		logger.Println(listenErr)
		return
	}
}

func addPlayer(rw http.ResponseWriter, req *http.Request, params httprouter.Params) {
	id := params.ByName("id")

	ws, wsErr := upgrader.Upgrade(rw, req, nil)
	if wsErr != nil {
		logger.Println(wsErr)
		return
	}

	trap := makeTrap(size, numBombs, lifes)

	ch.add(&trooper{id, trap, ws, make(chan []byte, 512)})
}

func home(rw http.ResponseWriter, req *http.Request, _ httprouter.Params) {
	rw.Header().Set("Content-Type", "text/html; charset=utf-8")
	http.ServeFile(rw, req, "client/dist/index.html")
}
<commit_msg>small fix<commit_after>package entrapped

import (
	"github.com/SKatiyar/entrapped/Godeps/_workspace/src/github.com/julienschmidt/httprouter"
	"net/http"
)

const (
	size     int = 7
	numBombs int = 10
	lifes    int = 5
)

func Start(addr string) {
	if len(addr) == 0 {
		addr = ":7000"
	}

	// initialize hunt
	go ch.run()

	// initialize router
	router := httprouter.New()

	// file routes
	router.GET("/", home)
	router.ServeFiles("/statics/*filepath", http.Dir("client/dist/statics"))

	// socket route
	router.GET("/players/:id", addPlayer)

	// start listening to incoming connections
	listenErr := http.ListenAndServe(addr, router)
	if listenErr != nil {
		logger.Println(listenErr)
		return
	}
}

func addPlayer(rw http.ResponseWriter, req *http.Request, params httprouter.Params) {
	id := params.ByName("id")

	ws, wsErr := upgrader.Upgrade(rw, req, nil)
	if wsErr != nil {
		logger.Println(wsErr)
		return
	}

	trap := makeTrap(size, numBombs, lifes)

	ch.add(&trooper{id, trap, ws, make(chan []byte, 512)})
}

func home(rw http.ResponseWriter, req *http.Request, _ httprouter.Params) {
	rw.Header().Set("Content-Type", "text/html; charset=utf-8")
	http.ServeFile(rw, req, "client/dist/index.html")
}
<|endoftext|>


<commit_before>package server

import (
	"fmt"
	"net"
	"reflect"

	"github.com/micro/go-micro/registry"
)

var (
	privateBlocks []*net.IPNet
)

func init() {
	for _, b := range []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"} {
		if _, block, err := net.ParseCIDR(b); err == nil {
			privateBlocks = append(privateBlocks, block)
		}
	}
}

func extractValue(v reflect.Type) *registry.Value {
	if v == nil {
		return nil
	}

	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	arg := &registry.Value{
		Name: v.Name(),
		Type: v.Name(),
	}

	if v.Kind() == reflect.Struct {
		for i := 0; i < v.NumField(); i++ {
			val := extractValue(v.Field(i).Type)
			val.Name = v.Field(i).Name
			arg.Values = append(arg.Values, val)
		}
	}

	return arg
}

func extractEndpoint(method reflect.Method) *registry.Endpoint {
	if method.PkgPath != "" {
		return nil
	}

	var rspType, reqType reflect.Type
	var stream bool
	mt := method.Type

	switch mt.NumIn() {
	case 3:
		reqType = mt.In(1)
		rspType = mt.In(2)
	case 4:
		reqType = mt.In(2)
		rspType = mt.In(3)
	default:
		return nil
	}

	if rspType.Kind() == reflect.Func {
		stream = true
	}

	request := extractValue(reqType)
	response := extractValue(rspType)

	return &registry.Endpoint{
		Name:     method.Name,
		Request:  request,
		Response: response,
		Metadata: map[string]string{
			"stream": fmt.Sprintf("%v", stream),
		},
	}
}

func extractSubValue(typ reflect.Type) *registry.Value {
	var reqType reflect.Type
	switch typ.NumIn() {
	case 1:
		reqType = typ.In(0)
	case 2:
		reqType = typ.In(1)
	case 3:
		reqType = typ.In(2)
	default:
		return nil
	}
	return extractValue(reqType)
}

func extractAddress(addr string) (string, error) {
	if len(addr) > 0 && (addr != "0.0.0.0" && addr != "[::]") {
		return addr, nil
	}

	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return "", fmt.Errorf("Failed to get interface addresses! Err: %v", err)
	}

	var ipAddr []byte

	for _, rawAddr := range addrs {
		var ip net.IP
		switch addr := rawAddr.(type) {
		case *net.IPAddr:
			ip = addr.IP
		case *net.IPNet:
			ip = addr.IP
		default:
			continue
		}

		if ip.To4() == nil {
			continue
		}

		if !isPrivateIP(ip.String()) {
			continue
		}

		ipAddr = ip
		break
	}

	if ipAddr == nil {
		return "", fmt.Errorf("No private IP address found, and explicit IP not provided")
	}

	return net.IP(ipAddr).String(), nil
}

func isPrivateIP(ipAddr string) bool {
	ip := net.ParseIP(ipAddr)
	for _, priv := range privateBlocks {
		if priv.Contains(ip) {
			return true
		}
	}
	return false
}
<commit_msg>support slices in extractor, longer term need to look at all types<commit_after>package server

import (
	"fmt"
	"net"
	"reflect"

	"github.com/micro/go-micro/registry"
)

var (
	privateBlocks []*net.IPNet
)

func init() {
	for _, b := range []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"} {
		if _, block, err := net.ParseCIDR(b); err == nil {
			privateBlocks = append(privateBlocks, block)
		}
	}
}

func extractValue(v reflect.Type) *registry.Value {
	if v == nil {
		return nil
	}

	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	arg := &registry.Value{
		Name: v.Name(),
		Type: v.Name(),
	}

	switch v.Kind() {
	case reflect.Struct:
		for i := 0; i < v.NumField(); i++ {
			val := extractValue(v.Field(i).Type)
			val.Name = v.Field(i).Name
			arg.Values = append(arg.Values, val)
		}
	case reflect.Slice:
		p := v.Elem()
		if p.Kind() == reflect.Ptr {
			p = p.Elem()
		}
		arg.Type = "[]" + p.Name()
		arg.Values = append(arg.Values, extractValue(v.Elem()))
	}

	return arg
}

func extractEndpoint(method reflect.Method) *registry.Endpoint {
	if method.PkgPath != "" {
		return nil
	}

	var rspType, reqType reflect.Type
	var stream bool
	mt := method.Type

	switch mt.NumIn() {
	case 3:
		reqType = mt.In(1)
		rspType = mt.In(2)
	case 4:
		reqType = mt.In(2)
		rspType = mt.In(3)
	default:
		return nil
	}

	if rspType.Kind() == reflect.Func {
		stream = true
	}

	request := extractValue(reqType)
	response := extractValue(rspType)

	return &registry.Endpoint{
		Name:     method.Name,
		Request:  request,
		Response: response,
		Metadata: map[string]string{
			"stream": fmt.Sprintf("%v", stream),
		},
	}
}

func extractSubValue(typ reflect.Type) *registry.Value {
	var reqType reflect.Type
	switch typ.NumIn() {
	case 1:
		reqType = typ.In(0)
	case 2:
		reqType = typ.In(1)
	case 3:
		reqType = typ.In(2)
	default:
		return nil
	}
	return extractValue(reqType)
}

func extractAddress(addr string) (string, error) {
	if len(addr) > 0 && (addr != "0.0.0.0" && addr != "[::]") {
		return addr, nil
	}

	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return "", fmt.Errorf("Failed to get interface addresses! Err: %v", err)
	}

	var ipAddr []byte

	for _, rawAddr := range addrs {
		var ip net.IP
		switch addr := rawAddr.(type) {
		case *net.IPAddr:
			ip = addr.IP
		case *net.IPNet:
			ip = addr.IP
		default:
			continue
		}

		if ip.To4() == nil {
			continue
		}

		if !isPrivateIP(ip.String()) {
			continue
		}

		ipAddr = ip
		break
	}

	if ipAddr == nil {
		return "", fmt.Errorf("No private IP address found, and explicit IP not provided")
	}

	return net.IP(ipAddr).String(), nil
}

func isPrivateIP(ipAddr string) bool {
	ip := net.ParseIP(ipAddr)
	for _, priv := range privateBlocks {
		if priv.Contains(ip) {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package keyboard

import (
	"os"
	"os/exec"
)

type bytes [3]byte

type KeyEvent struct {
	Bytes bytes
	Key   int
	Char  string
}

const (
	Tilde = iota + 96
	A
	B
	C
	D
	E
	F
	G
	H
	I
	J
	K
	L
	M
	N
	O
	P
	Q
	R
	S
	T
	U
	V
	W
	X
	Y
	Z
)

const (
	Escape   = 27
	Spacebar = 32
)

const (
	Zero = iota + 48
	One
	Two
	Three
	Four
	Five
	Six
	Seven
	Eight
	Nine
)

const (
	ArrowUp = iota + 65
	ArrowDown
	ArrowRight
	ArrowLeft
)

// used to hold the original stty state
var originalState string

func Parse(input bytes) KeyEvent {
	var event = KeyEvent{Bytes: input, Char: string(input[:])}

	var code byte

	// basic input codes
	if input[1] == 0 && input[2] == 0 {
		code = input[0]

		// space bar
		if code == Spacebar {
			event.Key = Spacebar
		}

		// vanilla escape
		if code == Escape {
			event.Key = Escape
		}

		// number keys
		if code >= 48 && code <= 57 {
			event.Key = int(code)
		}

		// alphabet
		if code >= 97 && code <= 122 {
			event.Key = int(code)
		}

		return event
	}

	// arrow keys
	if input[0] == Escape && input[1] == 91 {
		code = input[2]

		if code >= 65 && code <= 68 {
			event.Key = int(code)
			return event
		}
	}

	return event
}

// fetches original state, sets up TTY for raw (unbuffered) input
func configure() (err error) {
	state, err := stty("-g")
	if err != nil {
		return err
	}

	originalState = state

	// -echo: terminal doesn't echo typed characters back to the terminal
	// -icanon: terminal doesn't interpret special characters (like backspace)
	if _, err := stty("-echo", "-icanon"); err != nil {
		return err
	}

	return
}

// restores the TTY to the original state
func restore() (errs []error) {
	if _, err := stty(originalState); err != nil {
		return []error{err}
	}

	return
}

func stty(args ...string) (string, error) {
	cmd := exec.Command("stty", args...)
	cmd.Stdin = os.Stdin

	out, err := cmd.Output()
	if err != nil {
		return "", err
	}

	return string(out), nil
}
<commit_msg>Re-enable echo when restoring<commit_after>package keyboard

import (
	"os"
	"os/exec"
)

type bytes [3]byte

type KeyEvent struct {
	Bytes bytes
	Key   int
	Char  string
}

const (
	Tilde = iota + 96
	A
	B
	C
	D
	E
	F
	G
	H
	I
	J
	K
	L
	M
	N
	O
	P
	Q
	R
	S
	T
	U
	V
	W
	X
	Y
	Z
)

const (
	Escape   = 27
	Spacebar = 32
)

const (
	Zero = iota + 48
	One
	Two
	Three
	Four
	Five
	Six
	Seven
	Eight
	Nine
)

const (
	ArrowUp = iota + 65
	ArrowDown
	ArrowRight
	ArrowLeft
)

// used to hold the original stty state
var originalState string

func Parse(input bytes) KeyEvent {
	var event = KeyEvent{Bytes: input, Char: string(input[:])}

	var code byte

	// basic input codes
	if input[1] == 0 && input[2] == 0 {
		code = input[0]

		// space bar
		if code == Spacebar {
			event.Key = Spacebar
		}

		// vanilla escape
		if code == Escape {
			event.Key = Escape
		}

		// number keys
		if code >= 48 && code <= 57 {
			event.Key = int(code)
		}

		// alphabet
		if code >= 97 && code <= 122 {
			event.Key = int(code)
		}

		return event
	}

	// arrow keys
	if input[0] == Escape && input[1] == 91 {
		code = input[2]

		if code >= 65 && code <= 68 {
			event.Key = int(code)
			return event
		}
	}

	return event
}

// fetches original state, sets up TTY for raw (unbuffered) input
func configure() (err error) {
	state, err := stty("-g")
	if err != nil {
		return err
	}

	originalState = state

	// -echo: terminal doesn't echo typed characters back to the terminal
	// -icanon: terminal doesn't interpret special characters (like backspace)
	if _, err := stty("-echo", "-icanon"); err != nil {
		return err
	}

	return
}

// restores the TTY to the original state
func restore() (errs []error) {
	if _, err := stty("echo"); err != nil {
		return []error{err}
	}

	if _, err := stty(originalState); err != nil {
		return []error{err}
	}

	return
}

func stty(args ...string) (string, error) {
	cmd := exec.Command("stty", args...)
	cmd.Stdin = os.Stdin

	out, err := cmd.Output()
	if err != nil {
		return "", err
	}

	return string(out), nil
}
<|endoftext|>


<commit_before>package espsdk

import (
	"encoding/json"
)

type Contribution struct {
	CameraShotDate       string   `json:"camera_shot_date"`
	CollectionCode       string   `json:"collection_code"`
	ContentProviderName  string   `json:"content_provider_name"`
	ContentProviderTitle string   `json:"content_provider_title"`
	CountryOfShoot       string   `json:"country_of_shoot"`
	CreditLine           string   `json:"credit_line"`
	ExternalFileLocation string   `json:"external_file_location"`
	FileName             string   `json:"file_name"`
	FilePath             string   `json:"file_path"`
	Headline             string   `json:"headline"`
	IptcCategory         string   `json:"iptc_category"`
	IptcSubjects         []string `json:"iptc_subjects"`
	MimeType             string   `json:"mime_type"`
	ParentSource         string   `json:"parent_source"`
	RecordedDate         string   `json:"recorded_date"`
	RiskCategory         string   `json:"risk_category"`
	ShotSpeed            string   `json:"shot_speed"`
	SiteDestination      []string `json:"site_destination"`
	Source               string   `json:"source"`
	SubmittedToReviewAt  string   `json:"submitted_to_review_at"`
	UploadBucket         string   `json:"upload_bucket"`
	UploadId             string   `json:"upload_id"`
}

func (c Contribution) Marshal() ([]byte, error) {
	return json.MarshalIndent(c, "", "  ")
}
<commit_msg>alpha sort<commit_after>package espsdk

import (
	"encoding/json"
)

type Contribution struct {
	CameraShotDate       string   `json:"camera_shot_date,omitempty"`
	CollectionCode       string   `json:"collection_code,omitempty"`
	ContentProviderName  string   `json:"content_provider_name,omitempty"`
	ContentProviderTitle string   `json:"content_provider_title,omitempty"`
	CountryOfShoot       string   `json:"country_of_shoot,omitempty"`
	CreditLine           string   `json:"credit_line,omitempty"`
	ExternalFileLocation string   `json:"external_file_location,omitempty"`
	FileName             string   `json:"file_name,omitempty"`
	FilePath             string   `json:"file_path,omitempty"`
	Headline             string   `json:"headline,omitempty"`
	Id                   string   `json:"id,omitempty"`
	IptcCategory         string   `json:"iptc_category,omitempty"`
	IptcSubjects         []string `json:"iptc_subjects,omitempty"`
	MimeType             string   `json:"mime_type,omitempty"`
	ParentSource         string   `json:"parent_source,omitempty"`
	RecordedDate         string   `json:"recorded_date,omitempty"`
	RiskCategory         string   `json:"risk_category,omitempty"`
	ShotSpeed            string   `json:"shot_speed,omitempty"`
	SiteDestination      []string `json:"site_destination,omitempty"`
	Source               string   `json:"source,omitempty"`
	SubmittedToReviewAt  string   `json:"submitted_to_review_at,omitempty"`
	UploadBucket         string   `json:"upload_bucket,omitempty"`
	UploadId             string   `json:"upload_id,omitempty"`
}

func (c Contribution) Marshal() ([]byte, error) {
	return json.MarshalIndent(c, "", "  ")
}
<|endoftext|>


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

package ssdp

import (
	"bytes"
	"errors"
	"log"
	"net"
	"net/http"
	"runtime"
	"sync"
	"time"
)

// A ControlPoint represents a SSDP control point.
type ControlPoint struct {
	// ErrorLog specified an optional logger for errors. If it is
	// nil, logging goes to os.Stderr via the log package's
	// standard logger.
	ErrorLog *log.Logger

	conn                      // network connection endpoint
	group   *net.UDPAddr      // group address
	unicast func(net.IP) bool // unicast address filter
	mifs    []net.Interface   // multicast network interfaces

	muxmu sync.RWMutex
	mux   map[*http.Request]chan *http.Response // unicast message mux
}

// ListenControlPoint listens on the UDP network Listener.Group and
// Listener.Port, and returns a control point. If mifs is nil, it
// tries to listen on all available multicast network interfaces.
func (ln *Listener) ListenControlPoint(mifs []net.Interface) (*ControlPoint, error) {
	var err error
	cp := &ControlPoint{mux: make(map[*http.Request]chan *http.Response)}
	if cp.conn, cp.group, err = ln.listen(); err != nil {
		return nil, err
	}
	if cp.group.IP.To4() != nil {
		cp.unicast = ipv4Unicast
	} else {
		cp.unicast = ipv6Unicast
	}
	if cp.mifs, err = joinGroup(cp.conn, cp.group, mifs, cp.unicast); err != nil {
		cp.Close()
		return nil, err
	}
	return cp, nil
}

// Serve starts to handle incoming SSDP messages from SSDP
// devices. The handler must not be nil.
func (cp *ControlPoint) Serve(hdlr http.Handler) error {
	if hdlr == nil {
		return errors.New("invalid http handler")
	}
	b := make([]byte, 1280)
	for {
		n, path, err := cp.readFrom(b)
		if err != nil {
			if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
				cp.logf("read failed: %v", err)
				continue
			}
			return err
		}
		if !path.dst.IP.IsMulticast() {
			resp, err := parseResponse(b[:n])
			if err != nil {
				cp.logf("parse response failed: %v", err)
				continue
			}
			cp.muxmu.RLock()
			for _, ch := range cp.mux {
				ch <- resp
			}
			cp.muxmu.RUnlock()
			continue
		}
		if !path.dst.IP.Equal(cp.group.IP) {
			cp.logf("unknown destination address: %v on %v", path.dst, interfaceByIndex(cp.mifs, path.ifIndex).Name)
			continue
		}
		req, err := parseAdvert(b[:n])
		if err != nil {
			cp.logf("parse advert failed: %v", err)
			continue
		}
		if req.Method != notifyMethod {
			continue
		}
		resp := newResponseWriter(cp.conn, cp.mifs, cp.group, path, req)
		go func() {
			defer func() {
				if err := recover(); err != nil {
					const size = 64 << 10
					b := make([]byte, size)
					b = b[:runtime.Stack(b, false)]
					cp.logf("panic serving %v: %v\n%s", resp.path.src, err, b)
				}
			}()
			hdlr.ServeHTTP(resp, req)
		}()
	}
}

// GroupAddr returns the joined group network address.
func (cp *ControlPoint) GroupAddr() *net.UDPAddr {
	return cp.group
}

// Close closes the control point.
func (cp *ControlPoint) Close() error {
	for _, ifi := range cp.mifs {
		cp.LeaveGroup(&ifi, cp.group)
	}
	return cp.conn.Close()
}

// Interfaces returns a list of the joined multicast network
// interfaces.
func (cp *ControlPoint) Interfaces() []net.Interface {
	return cp.mifs
}

// MSearch issues a M-SEARCH SSDP message, takes a timeout and returns
// a list of responses. Callers should close each http.Response.Body
// when done reading from it. If mifs is nil, it tries to use all
// available multicast network interfaces.
func (cp *ControlPoint) MSearch(hdr http.Header, mifs []net.Interface, tmo time.Duration) ([]*http.Response, error) {
	req := newAdvert(msearchMethod, cp.group.String(), hdr)
	var buf bytes.Buffer
	if err := marshalAdvert(&buf, req); err != nil {
		return nil, err
	}
	mifs, err := interfaces(mifs, cp.unicast)
	if err != nil {
		return nil, err
	}
	if _, err := cp.writeToMulti(buf.Bytes(), cp.group, mifs); err != nil {
		return nil, err
	}
	respCh := cp.register(req)
	defer cp.deregister(req)
	t := time.NewTimer(tmo)
	defer t.Stop()
	var resps []*http.Response
loop:
	for {
		select {
		case <-t.C:
			break loop
		case resp := <-respCh:
			resps = append(resps, resp)
		}
	}
	return resps, nil
}

func (cp *ControlPoint) register(req *http.Request) chan *http.Response {
	cp.muxmu.Lock()
	defer cp.muxmu.Unlock()
	if ch, ok := cp.mux[req]; ok {
		return ch
	}
	ch := make(chan *http.Response, 1)
	cp.mux[req] = ch
	return ch
}

func (cp *ControlPoint) deregister(req *http.Request) {
	cp.muxmu.Lock()
	if ch, ok := cp.mux[req]; ok {
		close(ch)
	}
	delete(cp.mux, req)
	cp.muxmu.Unlock()
}

func (cp ControlPoint) logf(format string, args ...interface{}) {
	if cp.ErrorLog != nil {
		cp.ErrorLog.Printf(format, args...)
	} else {
		log.Printf(format, args...)
	}
}
<commit_msg>ssdp: vet<commit_after>// Copyright 2014 Mikio Hara. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ssdp

import (
	"bytes"
	"errors"
	"log"
	"net"
	"net/http"
	"runtime"
	"sync"
	"time"
)

// A ControlPoint represents a SSDP control point.
type ControlPoint struct {
	// ErrorLog specified an optional logger for errors. If it is
	// nil, logging goes to os.Stderr via the log package's
	// standard logger.
	ErrorLog *log.Logger

	conn                      // network connection endpoint
	group   *net.UDPAddr      // group address
	unicast func(net.IP) bool // unicast address filter
	mifs    []net.Interface   // multicast network interfaces

	muxmu sync.RWMutex
	mux   map[*http.Request]chan *http.Response // unicast message mux
}

// ListenControlPoint listens on the UDP network Listener.Group and
// Listener.Port, and returns a control point. If mifs is nil, it
// tries to listen on all available multicast network interfaces.
func (ln *Listener) ListenControlPoint(mifs []net.Interface) (*ControlPoint, error) {
	var err error
	cp := &ControlPoint{mux: make(map[*http.Request]chan *http.Response)}
	if cp.conn, cp.group, err = ln.listen(); err != nil {
		return nil, err
	}
	if cp.group.IP.To4() != nil {
		cp.unicast = ipv4Unicast
	} else {
		cp.unicast = ipv6Unicast
	}
	if cp.mifs, err = joinGroup(cp.conn, cp.group, mifs, cp.unicast); err != nil {
		cp.Close()
		return nil, err
	}
	return cp, nil
}

// Serve starts to handle incoming SSDP messages from SSDP
// devices. The handler must not be nil.
func (cp *ControlPoint) Serve(hdlr http.Handler) error {
	if hdlr == nil {
		return errors.New("invalid http handler")
	}
	b := make([]byte, 1280)
	for {
		n, path, err := cp.readFrom(b)
		if err != nil {
			if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
				cp.logf("read failed: %v", err)
				continue
			}
			return err
		}
		if !path.dst.IP.IsMulticast() {
			resp, err := parseResponse(b[:n])
			if err != nil {
				cp.logf("parse response failed: %v", err)
				continue
			}
			cp.muxmu.RLock()
			for _, ch := range cp.mux {
				ch <- resp
			}
			cp.muxmu.RUnlock()
			continue
		}
		if !path.dst.IP.Equal(cp.group.IP) {
			cp.logf("unknown destination address: %v on %v", path.dst, interfaceByIndex(cp.mifs, path.ifIndex).Name)
			continue
		}
		req, err := parseAdvert(b[:n])
		if err != nil {
			cp.logf("parse advert failed: %v", err)
			continue
		}
		if req.Method != notifyMethod {
			continue
		}
		resp := newResponseWriter(cp.conn, cp.mifs, cp.group, path, req)
		go func() {
			defer func() {
				if err := recover(); err != nil {
					const size = 64 << 10
					b := make([]byte, size)
					b = b[:runtime.Stack(b, false)]
					cp.logf("panic serving %v: %v\n%s", resp.path.src, err, b)
				}
			}()
			hdlr.ServeHTTP(resp, req)
		}()
	}
}

// GroupAddr returns the joined group network address.
func (cp *ControlPoint) GroupAddr() *net.UDPAddr {
	return cp.group
}

// Close closes the control point.
func (cp *ControlPoint) Close() error {
	for _, ifi := range cp.mifs {
		cp.LeaveGroup(&ifi, cp.group)
	}
	return cp.conn.Close()
}

// Interfaces returns a list of the joined multicast network
// interfaces.
func (cp *ControlPoint) Interfaces() []net.Interface {
	return cp.mifs
}

// MSearch issues a M-SEARCH SSDP message, takes a timeout and returns
// a list of responses. Callers should close each http.Response.Body
// when done reading from it. If mifs is nil, it tries to use all
// available multicast network interfaces.
func (cp *ControlPoint) MSearch(hdr http.Header, mifs []net.Interface, tmo time.Duration) ([]*http.Response, error) {
	req := newAdvert(msearchMethod, cp.group.String(), hdr)
	var buf bytes.Buffer
	if err := marshalAdvert(&buf, req); err != nil {
		return nil, err
	}
	mifs, err := interfaces(mifs, cp.unicast)
	if err != nil {
		return nil, err
	}
	if _, err := cp.writeToMulti(buf.Bytes(), cp.group, mifs); err != nil {
		return nil, err
	}
	respCh := cp.register(req)
	defer cp.deregister(req)
	t := time.NewTimer(tmo)
	defer t.Stop()
	var resps []*http.Response
loop:
	for {
		select {
		case <-t.C:
			break loop
		case resp := <-respCh:
			resps = append(resps, resp)
		}
	}
	return resps, nil
}

func (cp *ControlPoint) register(req *http.Request) chan *http.Response {
	cp.muxmu.Lock()
	defer cp.muxmu.Unlock()
	if ch, ok := cp.mux[req]; ok {
		return ch
	}
	ch := make(chan *http.Response, 1)
	cp.mux[req] = ch
	return ch
}

func (cp *ControlPoint) deregister(req *http.Request) {
	cp.muxmu.Lock()
	if ch, ok := cp.mux[req]; ok {
		close(ch)
	}
	delete(cp.mux, req)
	cp.muxmu.Unlock()
}

func (cp *ControlPoint) logf(format string, args ...interface{}) {
	if cp.ErrorLog != nil {
		cp.ErrorLog.Printf(format, args...)
	} else {
		log.Printf(format, args...)
	}
}
<|endoftext|>


<commit_before>package cli

import (
	"fmt"
	"strings"

	"github.com/docker/docker/pkg/term"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

// SetupRootCommand sets default usage, help, and error handling for the
// root command.
func SetupRootCommand(rootCmd *cobra.Command) {
	cobra.AddTemplateFunc("hasSubCommands", hasSubCommands)
	cobra.AddTemplateFunc("hasManagementSubCommands", hasManagementSubCommands)
	cobra.AddTemplateFunc("operationSubCommands", operationSubCommands)
	cobra.AddTemplateFunc("managementSubCommands", managementSubCommands)
	cobra.AddTemplateFunc("wrappedFlagUsages", wrappedFlagUsages)
	cobra.AddTemplateFunc("useLine", UseLine)

	rootCmd.SetUsageTemplate(usageTemplate)
	rootCmd.SetHelpTemplate(helpTemplate)
	rootCmd.SetFlagErrorFunc(FlagErrorFunc)
	rootCmd.SetHelpCommand(helpCommand)

	rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage")
	rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help")
}

// FlagErrorFunc prints an error message which matches the format of the
// docker/cli/cli error messages
func FlagErrorFunc(cmd *cobra.Command, err error) error {
	if err == nil {
		return nil
	}

	usage := ""
	if cmd.HasSubCommands() {
		usage = "\n\n" + cmd.UsageString()
	}
	return StatusError{
		Status:     fmt.Sprintf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage),
		StatusCode: 125,
	}
}

var helpCommand = &cobra.Command{
	Use:               "help [command]",
	Short:             "Help about the command",
	PersistentPreRun:  func(cmd *cobra.Command, args []string) {},
	PersistentPostRun: func(cmd *cobra.Command, args []string) {},
	RunE: func(c *cobra.Command, args []string) error {
		cmd, args, e := c.Root().Find(args)
		if cmd == nil || e != nil || len(args) > 0 {
			return errors.Errorf("unknown help topic: %v", strings.Join(args, " "))
		}

		helpFunc := cmd.HelpFunc()
		helpFunc(cmd, args)
		return nil
	},
}

func hasSubCommands(cmd *cobra.Command) bool {
	return len(operationSubCommands(cmd)) > 0
}

func hasManagementSubCommands(cmd *cobra.Command) bool {
	return len(managementSubCommands(cmd)) > 0
}

func operationSubCommands(cmd *cobra.Command) []*cobra.Command {
	cmds := []*cobra.Command{}
	for _, sub := range cmd.Commands() {
		if sub.IsAvailableCommand() && !sub.HasSubCommands() {
			cmds = append(cmds, sub)
		}
	}
	return cmds
}

func wrappedFlagUsages(cmd *cobra.Command) string {
	width := 80
	if ws, err := term.GetWinsize(0); err == nil {
		width = int(ws.Width)
	}
	return cmd.Flags().FlagUsagesWrapped(width - 1)
}

func managementSubCommands(cmd *cobra.Command) []*cobra.Command {
	cmds := []*cobra.Command{}
	for _, sub := range cmd.Commands() {
		if sub.IsAvailableCommand() && sub.HasSubCommands() {
			cmds = append(cmds, sub)
		}
	}
	return cmds
}

// UseLine returns the usage line for a command. This implementation is different
// from the default Command.UseLine in that it does not add a `[flags]` to the
// of the line.
func UseLine(cmd *cobra.Command) string {
	if cmd.HasParent() {
		return cmd.Parent().CommandPath() + " " + cmd.Use
	}
	return cmd.Use
}

var usageTemplate = `Usage:

{{- if not .HasSubCommands}}	{{ useLine . }}{{end}}
{{- if .HasSubCommands}}	{{ .CommandPath}} COMMAND{{end}}

{{ .Short | trim }}

{{- if gt .Aliases 0}}

Aliases:
  {{.NameAndAliases}}

{{- end}}
{{- if .HasExample}}

Examples:
{{ .Example }}

{{- end}}
{{- if .HasFlags}}

Options:
{{ wrappedFlagUsages . | trimRightSpace}}

{{- end}}
{{- if hasManagementSubCommands . }}

Management Commands:

{{- range managementSubCommands . }}
  {{rpad .Name .NamePadding }} {{.Short}}
{{- end}}

{{- end}}
{{- if hasSubCommands .}}

Commands:

{{- range operationSubCommands . }}
  {{rpad .Name .NamePadding }} {{.Short}}
{{- end}}
{{- end}}

{{- if .HasSubCommands }}

Run '{{.CommandPath}} COMMAND --help' for more information on a command.
{{- end}}
`

var helpTemplate = `
{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
<commit_msg>Hide help flag from help output.<commit_after>package cli

import (
	"fmt"
	"strings"

	"github.com/docker/docker/pkg/term"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

// SetupRootCommand sets default usage, help, and error handling for the
// root command.
func SetupRootCommand(rootCmd *cobra.Command) {
	cobra.AddTemplateFunc("hasSubCommands", hasSubCommands)
	cobra.AddTemplateFunc("hasManagementSubCommands", hasManagementSubCommands)
	cobra.AddTemplateFunc("operationSubCommands", operationSubCommands)
	cobra.AddTemplateFunc("managementSubCommands", managementSubCommands)
	cobra.AddTemplateFunc("wrappedFlagUsages", wrappedFlagUsages)
	cobra.AddTemplateFunc("useLine", UseLine)

	rootCmd.SetUsageTemplate(usageTemplate)
	rootCmd.SetHelpTemplate(helpTemplate)
	rootCmd.SetFlagErrorFunc(FlagErrorFunc)
	rootCmd.SetHelpCommand(helpCommand)

	rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage")
	rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help")
	rootCmd.PersistentFlags().Lookup("help").Hidden = true
}

// FlagErrorFunc prints an error message which matches the format of the
// docker/cli/cli error messages
func FlagErrorFunc(cmd *cobra.Command, err error) error {
	if err == nil {
		return nil
	}

	usage := ""
	if cmd.HasSubCommands() {
		usage = "\n\n" + cmd.UsageString()
	}
	return StatusError{
		Status:     fmt.Sprintf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage),
		StatusCode: 125,
	}
}

var helpCommand = &cobra.Command{
	Use:               "help [command]",
	Short:             "Help about the command",
	PersistentPreRun:  func(cmd *cobra.Command, args []string) {},
	PersistentPostRun: func(cmd *cobra.Command, args []string) {},
	RunE: func(c *cobra.Command, args []string) error {
		cmd, args, e := c.Root().Find(args)
		if cmd == nil || e != nil || len(args) > 0 {
			return errors.Errorf("unknown help topic: %v", strings.Join(args, " "))
		}

		helpFunc := cmd.HelpFunc()
		helpFunc(cmd, args)
		return nil
	},
}

func hasSubCommands(cmd *cobra.Command) bool {
	return len(operationSubCommands(cmd)) > 0
}

func hasManagementSubCommands(cmd *cobra.Command) bool {
	return len(managementSubCommands(cmd)) > 0
}

func operationSubCommands(cmd *cobra.Command) []*cobra.Command {
	cmds := []*cobra.Command{}
	for _, sub := range cmd.Commands() {
		if sub.IsAvailableCommand() && !sub.HasSubCommands() {
			cmds = append(cmds, sub)
		}
	}
	return cmds
}

func wrappedFlagUsages(cmd *cobra.Command) string {
	width := 80
	if ws, err := term.GetWinsize(0); err == nil {
		width = int(ws.Width)
	}
	return cmd.Flags().FlagUsagesWrapped(width - 1)
}

func managementSubCommands(cmd *cobra.Command) []*cobra.Command {
	cmds := []*cobra.Command{}
	for _, sub := range cmd.Commands() {
		if sub.IsAvailableCommand() && sub.HasSubCommands() {
			cmds = append(cmds, sub)
		}
	}
	return cmds
}

// UseLine returns the usage line for a command. This implementation is different
// from the default Command.UseLine in that it does not add a `[flags]` to the
// end of the line.
func UseLine(cmd *cobra.Command) string {
	if cmd.HasParent() {
		return cmd.Parent().CommandPath() + " " + cmd.Use
	}
	return cmd.Use
}

var usageTemplate = `Usage:

{{- if not .HasSubCommands}}	{{ useLine . }}{{end}}
{{- if .HasSubCommands}}	{{ .CommandPath}} COMMAND{{end}}

{{ .Short | trim }}

{{- if gt .Aliases 0}}

Aliases:
  {{.NameAndAliases}}

{{- end}}
{{- if .HasExample}}

Examples:
{{ .Example }}

{{- end}}
{{- if .HasFlags}}

Options:
{{ wrappedFlagUsages . | trimRightSpace}}

{{- end}}
{{- if hasManagementSubCommands . }}

Management Commands:

{{- range managementSubCommands . }}
  {{rpad .Name .NamePadding }} {{.Short}}
{{- end}}

{{- end}}
{{- if hasSubCommands .}}

Commands:

{{- range operationSubCommands . }}
  {{rpad .Name .NamePadding }} {{.Short}}
{{- end}}
{{- end}}

{{- if .HasSubCommands }}

Run '{{.CommandPath}} COMMAND --help' for more information on a command.
{{- end}}
`

var helpTemplate = `
{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
<|endoftext|>