<commit_before>package osutil

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	fp "path/filepath"
	"strings"
	"syscall"

	"github.com/hashicorp/errwrap"
	"github.com/docker/docker/pkg/mount"

	"github.com/yuuki1/droot/log"
)

func ExistsFile(file string) bool {
	f, err := os.Stat(file)
	return err == nil && !f.IsDir()
}

func ExistsDir(dir string) bool {
	if f, err := os.Stat(dir); os.IsNotExist(err) || !f.IsDir() {
		return false
	}
	return true
}

func IsDirEmpty(dir string) (bool, error) {
	f, err := os.Open(dir)
	if err != nil {
		return false, errwrap.Wrapf(fmt.Sprintf("Failed to open %s: {{err}}", dir), err)
	}
	defer f.Close()

	_, err = f.Readdirnames(1)
	if err == io.EOF {
		return true, nil
	}
	return false, err // Either not empty or error, suits both cases
}

func RunCmd(name string, arg ...string) error {
	log.Debug("runcmd: ", name, arg)
	out, err := exec.Command(name, arg...).CombinedOutput()
	if len(out) > 0 {
		log.Debug(string(out))
	}
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to exec %s %s: {{err}}", name, arg), err)
	}
	return nil
}

func Cp(from, to string) error {
	if err := RunCmd("cp", "-p", from, to); err != nil {
		return err
	}
	return nil
}

func GetMountsByRoot(rootDir string) ([]*mount.Info, error) {
	mounts, err := mount.GetMounts()
	if err != nil {
		return nil, err
	}

	targets := make([]*mount.Info, 0)
	for _, m := range mounts {
		if strings.HasPrefix(m.Mountpoint, fp.Clean(rootDir)) {
			targets = append(targets, m)
		}
	}

	return targets, nil
}

func UmountRoot(rootDir string) error {
	mounts, err := GetMountsByRoot(rootDir)
	if err != nil {
		return err
	}

	for _, m := range mounts {
		if err := mount.Unmount(m.Mountpoint); err != nil {
			return err
		}
		log.Debug("umount:", m.Mountpoint)
	}

	return nil
}

func BindMount(src, dest string) error {
	return mount.Mount(src, dest, "bind", "")
}

func RObindMount(src, dest string) error {
	return mount.Mount(src, dest, "bind", "remount,ro,bind")
}

// Mknod unless path does not exists.
func Mknod(path string, mode uint32, dev int) error {
	if ExistsFile(path) {
		return nil
	}
	if err := syscall.Mknod(path, mode, dev); err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to mknod %s: {{err}}", path), err)
	}
	return nil
}

// Symlink, but ignore already exists file.
func Symlink(oldname, newname string) error {
	if err := os.Symlink(oldname, newname); err != nil {
		// Ignore already created symlink
		if _, ok := err.(*os.LinkError); !ok {
			return errwrap.Wrapf(fmt.Sprintf("Failed to symlink %s %s: {{err}}", oldname, newname), err)
		}
	}
	return nil
}

func Execv(cmd string, args []string, env []string) error {
	name, err := exec.LookPath(cmd)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Not found %s: {{err}}", cmd), err)
	}

	log.Debug("exec: ", name, args)

	return syscall.Exec(name, args, env)
}
<commit_msg>Ignore Readdirnames err<commit_after>package osutil

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	fp "path/filepath"
	"strings"
	"syscall"

	"github.com/hashicorp/errwrap"
	"github.com/docker/docker/pkg/mount"

	"github.com/yuuki1/droot/log"
)

func ExistsFile(file string) bool {
	f, err := os.Stat(file)
	return err == nil && !f.IsDir()
}

func ExistsDir(dir string) bool {
	if f, err := os.Stat(dir); os.IsNotExist(err) || !f.IsDir() {
		return false
	}
	return true
}

func IsDirEmpty(dir string) (bool, error) {
	f, err := os.Open(dir)
	if err != nil {
		return false, errwrap.Wrapf(fmt.Sprintf("Failed to open %s: {{err}}", dir), err)
	}
	defer f.Close()

	_, err = f.Readdirnames(1)
	if err == io.EOF {
		return true, nil
	}
	return false, nil
}

func RunCmd(name string, arg ...string) error {
	log.Debug("runcmd: ", name, arg)
	out, err := exec.Command(name, arg...).CombinedOutput()
	if len(out) > 0 {
		log.Debug(string(out))
	}
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to exec %s %s: {{err}}", name, arg), err)
	}
	return nil
}

func Cp(from, to string) error {
	if err := RunCmd("cp", "-p", from, to); err != nil {
		return err
	}
	return nil
}

func GetMountsByRoot(rootDir string) ([]*mount.Info, error) {
	mounts, err := mount.GetMounts()
	if err != nil {
		return nil, err
	}

	targets := make([]*mount.Info, 0)
	for _, m := range mounts {
		if strings.HasPrefix(m.Mountpoint, fp.Clean(rootDir)) {
			targets = append(targets, m)
		}
	}

	return targets, nil
}

func UmountRoot(rootDir string) error {
	mounts, err := GetMountsByRoot(rootDir)
	if err != nil {
		return err
	}

	for _, m := range mounts {
		if err := mount.Unmount(m.Mountpoint); err != nil {
			return err
		}
		log.Debug("umount:", m.Mountpoint)
	}

	return nil
}

func BindMount(src, dest string) error {
	return mount.Mount(src, dest, "bind", "")
}

func RObindMount(src, dest string) error {
	return mount.Mount(src, dest, "bind", "remount,ro,bind")
}

// Mknod unless path does not exists.
func Mknod(path string, mode uint32, dev int) error {
	if ExistsFile(path) {
		return nil
	}
	if err := syscall.Mknod(path, mode, dev); err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to mknod %s: {{err}}", path), err)
	}
	return nil
}

// Symlink, but ignore already exists file.
func Symlink(oldname, newname string) error {
	if err := os.Symlink(oldname, newname); err != nil {
		// Ignore already created symlink
		if _, ok := err.(*os.LinkError); !ok {
			return errwrap.Wrapf(fmt.Sprintf("Failed to symlink %s %s: {{err}}", oldname, newname), err)
		}
	}
	return nil
}

func Execv(cmd string, args []string, env []string) error {
	name, err := exec.LookPath(cmd)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Not found %s: {{err}}", cmd), err)
	}

	log.Debug("exec: ", name, args)

	return syscall.Exec(name, args, env)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"time"

	"srcd.works/go-git.v4"
	"srcd.works/go-git.v4/plumbing"
	"srcd.works/go-git.v4/plumbing/object"
	"srcd.works/go-git.v4/storage/memory"

	"bytes"

	"regexp"

	"github.com/BurntSushi/toml"
)

type gitConfig struct {
	uri string
}
type salesforceConfig struct {
	username    string
	password    string
	endpoint    string
	packagePath string
	apiVersion  string
}

type Downloader interface {
	Download() ([]*File, error)
}

type MetaPackageFile struct {
	Version float64 `toml:"version"`
	Types   []*Type `toml:"types"`
}

type Type struct {
	Name    string   `toml:"name"`
	Members []string `toml:"members"`
}

type SalesforceDownloader struct {
	config *salesforceConfig
	client *ForceClient
	logger Logger
}

func NewSalesforceDownloader(logger Logger, config *salesforceConfig) (*SalesforceDownloader, error) {
	d := &SalesforceDownloader{
		logger: logger,
		config: config,
	}
	err := d.init()
	return d, err
}

func (i *SalesforceDownloader) init() (err error) {
	if i.config.username == "" {
		return errors.New("Username is required")
	}
	if i.config.password == "" {
		return errors.New("Password is required")
	}

	err = i.setClient()
	if err != nil {
		return err
	}
	return nil
}

func (i *SalesforceDownloader) setClient() error {
	i.client = NewForceClient(i.config.endpoint, i.config.apiVersion)
	err := i.client.Login(i.config.username, i.config.password)
	if err != nil {
		return err
	}
	return nil
}

func (i *SalesforceDownloader) Download() ([]*File, error) {
	buf, err := ioutil.ReadFile(i.config.packagePath)
	if err != nil {
		return nil, err
	}
	packages := &MetaPackageFile{}
	err = toml.Unmarshal(buf, packages)
	if err != nil {
		return nil, err
	}
	i.logger.Info("Start Retrieve Request...")
	r, err := i.client.Retrieve(createRetrieveRequest(packages))
	if err != nil {
		return nil, err
	}
	for {
		time.Sleep(2 * time.Second)
		i.logger.Info("Check Retrieve Status...")
		ret_res, err := i.client.CheckRetrieveStatus(r.Result.Id)
		if err != nil {
			return nil, err
		}
		if ret_res.Result.Done {
			zb := make([]byte, len(ret_res.Result.ZipFile))
			_, err = base64.StdEncoding.Decode(zb, ret_res.Result.ZipFile)
			return []*File{&File{Body: zb}}, err
		}
	}
	return nil, nil // Todo: error handling
}

type GitDownloader struct {
	logger Logger
	config *gitConfig
}

func NewGitDownloader(logger Logger, config *gitConfig) (*GitDownloader, error) {
	return &GitDownloader{
		logger: logger,
		config: config,
	}, nil
}

func (d *GitDownloader) Download() ([]*File, error) {
	uri, _, _, branch := extractInstallParameter(d.config.uri)
	d.logger.Infof("Clone repository from %s (branch: %s)", uri, branch)

	r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
		ReferenceName: plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", branch)),
		SingleBranch:  true,
		URL:           uri,
	})
	if err != nil {
		return nil, err
	}

	ref, _ := r.Head()
	commit, _ := r.Commit(ref.Hash())

	gfiles, err := commit.Files()
	files := make([]*File, 0)
	err = gfiles.ForEach(func(f *object.File) error {
		reader, err := f.Reader()
		if err != nil {
			return err
		}

		b := new(bytes.Buffer)
		if _, err := b.ReadFrom(reader); err != nil {
			return err
		}
		files = append(files, &File{Name: f.Name, Body: b.Bytes()})
		return nil
	})
	if err != nil {
		return nil, err
	}
	return files, nil
}

func dispatchDownloader(logger Logger, uri string) (Downloader, error) {
	r := regexp.MustCompile(`^https://([^/]+?)/([^/]+?)/([^/@]+?)(/([^@]+))?(\?([^/]+))?$`)
	if r.MatchString(uri) {
		return NewGitDownloader(logger, &gitConfig{uri: uri})
	}
	r = regexp.MustCompile(`^sf://([^/]+?):([^/]+)@([^/]+?)\?path=(.+)$`)
	fmt.Println(uri)
	if r.MatchString(uri) {
		group := r.FindAllStringSubmatch(uri, -1)
		return NewSalesforceDownloader(logger, &salesforceConfig{
			username:    group[0][1],
			password:    group[0][2],
			endpoint:    group[0][3],
			packagePath: group[0][4],
			apiVersion:  "38.0",
		})
	}
	return nil, errors.New("Invalid downloader")
}
<commit_msg>Mod regexp<commit_after>package main

import (
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"time"

	"srcd.works/go-git.v4"
	"srcd.works/go-git.v4/plumbing"
	"srcd.works/go-git.v4/plumbing/object"
	"srcd.works/go-git.v4/storage/memory"

	"bytes"

	"regexp"

	"github.com/BurntSushi/toml"
)

type gitConfig struct {
	uri string
}
type salesforceConfig struct {
	username    string
	password    string
	endpoint    string
	packagePath string
	apiVersion  string
}

type Downloader interface {
	Download() ([]*File, error)
}

type MetaPackageFile struct {
	Version float64 `toml:"version"`
	Types   []*Type `toml:"types"`
}

type Type struct {
	Name    string   `toml:"name"`
	Members []string `toml:"members"`
}

type SalesforceDownloader struct {
	config *salesforceConfig
	client *ForceClient
	logger Logger
}

func NewSalesforceDownloader(logger Logger, config *salesforceConfig) (*SalesforceDownloader, error) {
	d := &SalesforceDownloader{
		logger: logger,
		config: config,
	}
	err := d.init()
	return d, err
}

func (i *SalesforceDownloader) init() (err error) {
	if i.config.username == "" {
		return errors.New("Username is required")
	}
	if i.config.password == "" {
		return errors.New("Password is required")
	}

	err = i.setClient()
	if err != nil {
		return err
	}
	return nil
}

func (i *SalesforceDownloader) setClient() error {
	i.client = NewForceClient(i.config.endpoint, i.config.apiVersion)
	err := i.client.Login(i.config.username, i.config.password)
	if err != nil {
		return err
	}
	return nil
}

func (i *SalesforceDownloader) Download() ([]*File, error) {
	buf, err := ioutil.ReadFile(i.config.packagePath)
	if err != nil {
		return nil, err
	}
	packages := &MetaPackageFile{}
	err = toml.Unmarshal(buf, packages)
	if err != nil {
		return nil, err
	}
	i.logger.Info("Start Retrieve Request...")
	r, err := i.client.Retrieve(createRetrieveRequest(packages))
	if err != nil {
		return nil, err
	}
	for {
		time.Sleep(2 * time.Second)
		i.logger.Info("Check Retrieve Status...")
		ret_res, err := i.client.CheckRetrieveStatus(r.Result.Id)
		if err != nil {
			return nil, err
		}
		if ret_res.Result.Done {
			zb := make([]byte, len(ret_res.Result.ZipFile))
			_, err = base64.StdEncoding.Decode(zb, ret_res.Result.ZipFile)
			return []*File{&File{Body: zb}}, err
		}
	}
	return nil, nil // Todo: error handling
}

type GitDownloader struct {
	logger Logger
	config *gitConfig
}

func NewGitDownloader(logger Logger, config *gitConfig) (*GitDownloader, error) {
	return &GitDownloader{
		logger: logger,
		config: config,
	}, nil
}

func (d *GitDownloader) Download() ([]*File, error) {
	uri, _, _, branch := extractInstallParameter(d.config.uri)
	d.logger.Infof("Clone repository from %s (branch: %s)", uri, branch)

	r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
		ReferenceName: plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", branch)),
		SingleBranch:  true,
		URL:           uri,
	})
	if err != nil {
		return nil, err
	}

	ref, _ := r.Head()
	commit, _ := r.Commit(ref.Hash())

	gfiles, err := commit.Files()
	files := make([]*File, 0)
	err = gfiles.ForEach(func(f *object.File) error {
		reader, err := f.Reader()
		if err != nil {
			return err
		}

		b := new(bytes.Buffer)
		if _, err := b.ReadFrom(reader); err != nil {
			return err
		}
		files = append(files, &File{Name: f.Name, Body: b.Bytes()})
		return nil
	})
	if err != nil {
		return nil, err
	}
	return files, nil
}

func dispatchDownloader(logger Logger, uri string) (Downloader, error) {
	r := regexp.MustCompile(`^https://([^/]+?)/([^/]+?)/([^/@]+?)(/([^@]+))?(\?([^/]+))?$`)
	if r.MatchString(uri) {
		return NewGitDownloader(logger, &gitConfig{uri: uri})
	}
	r = regexp.MustCompile(`^sf://([^/]*?):([^/]*)@([^/]+?)\?path=(.+)$`)
	fmt.Println(uri)
	if r.MatchString(uri) {
		group := r.FindAllStringSubmatch(uri, -1)
		return NewSalesforceDownloader(logger, &salesforceConfig{
			username:    group[0][1],
			password:    group[0][2],
			endpoint:    group[0][3],
			packagePath: group[0][4],
			apiVersion:  "38.0",
		})
	}
	return nil, errors.New("Invalid downloader")
}
<|endoftext|>


<commit_before>package packet

import (
	"testing"

	"github.com/yosssi/gmq/mqtt"
)

func TestPUBLISH_setFixedHeader(t *testing.T) {
	p := &PUBLISH{
		DUP:    true,
		retain: true,
	}

	p.variableHeader = []byte{0x00}

	p.payload = []byte{0x00, 0x00}

	p.setFixedHeader()

	want := []byte{0x39, 0x03}

	if len(p.fixedHeader) != len(want) || p.fixedHeader[0] != want[0] || p.fixedHeader[1] != want[1] {
		t.Errorf("p.fixedHeader => %v, want => %v", p.fixedHeader, want)
	}
}

func TestPUBLISH_setVariableHeader(t *testing.T) {
	p := &PUBLISH{
		QoS:       mqtt.QoS1,
		TopicName: []byte("topicName"),
		PacketID:  1,
	}

	p.setVariableHeader()

	want := []byte{0x00, 0x09, 0x74, 0x6F, 0x70, 0x69, 0x63, 0x4E, 0x061, 0x6D, 0x65, 0x00, 0x01}

	if len(p.variableHeader) != len(want) {
		t.Errorf("p.variableHeader => %v, want => %v", p.variableHeader, want)
		return
	}

	for i, b := range p.variableHeader {
		if b != want[i] {
			t.Errorf("p.variableHeader => %v, want => %v", p.variableHeader, want)
			return
		}
	}
}

func TestPUBLISH_setPayload(t *testing.T) {
	p := &PUBLISH{
		Message: []byte{0x00, 0x01},
	}

	p.setPayload()

	if len(p.payload) != len(p.Message) || p.payload[0] != p.Message[0] || p.payload[1] != p.Message[1] {
		t.Errorf("p.payload => %v, want => %v", p.payload, p.Message)
	}
}

func TestNewPUBLISH_optsNil(t *testing.T) {
	if _, err := NewPUBLISH(nil); err != nil {
		nilErrorExpected(t, err)
	}
}

func TestNewPUBLISH_validateErr(t *testing.T) {
	_, err := NewPUBLISH(&PUBLISHOptions{
		QoS: 0x03,
	})

	if err != ErrInvalidQoS {
		invalidError(t, err, ErrInvalidQoS)
	}
}

func Test_validatePUBLISHBytes_fixedHeaderErrInvalidFixedHeaderLen(t *testing.T) {
	if err := validatePUBLISHBytes(nil, nil); err != ErrInvalidFixedHeaderLen {
		invalidError(t, err, ErrInvalidFixedHeaderLen)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidFixedHeaderLen(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH << 4}, nil); err != ErrInvalidFixedHeaderLen {
		invalidError(t, err, ErrInvalidFixedHeaderLen)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidPacketType(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypeCONNECT << 4, 0x00}, nil); err != ErrInvalidPacketType {
		invalidError(t, err, ErrInvalidPacketType)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidQoS(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH<<4 | 0x06, 0x00}, nil); err != ErrInvalidQoS {
		invalidError(t, err, ErrInvalidQoS)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidRemainingLen(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH << 4, 0x00}, nil); err != ErrInvalidRemainingLen {
		invalidError(t, err, ErrInvalidRemainingLen)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidRemainingLength(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH<<4 | 0x02, 0x02}, []byte{0x00, 0x00}); err != ErrInvalidRemainingLength {
		invalidError(t, err, ErrInvalidRemainingLength)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidPacketID(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH<<4 | 0x02, 0x07}, []byte{0x00, 0x03, 0x61, 0x2F, 0x62, 0x00, 0x00}); err != ErrInvalidPacketID {
		invalidError(t, err, ErrInvalidPacketID)
	}
}
<commit_msg>Update mqtt/packet/publish_test.go<commit_after>package packet

import (
	"testing"

	"github.com/yosssi/gmq/mqtt"
)

func TestPUBLISH_setFixedHeader(t *testing.T) {
	p := &PUBLISH{
		DUP:    true,
		retain: true,
	}

	p.variableHeader = []byte{0x00}

	p.payload = []byte{0x00, 0x00}

	p.setFixedHeader()

	want := []byte{0x39, 0x03}

	if len(p.fixedHeader) != len(want) || p.fixedHeader[0] != want[0] || p.fixedHeader[1] != want[1] {
		t.Errorf("p.fixedHeader => %v, want => %v", p.fixedHeader, want)
	}
}

func TestPUBLISH_setVariableHeader(t *testing.T) {
	p := &PUBLISH{
		QoS:       mqtt.QoS1,
		TopicName: []byte("topicName"),
		PacketID:  1,
	}

	p.setVariableHeader()

	want := []byte{0x00, 0x09, 0x74, 0x6F, 0x70, 0x69, 0x63, 0x4E, 0x061, 0x6D, 0x65, 0x00, 0x01}

	if len(p.variableHeader) != len(want) {
		t.Errorf("p.variableHeader => %v, want => %v", p.variableHeader, want)
		return
	}

	for i, b := range p.variableHeader {
		if b != want[i] {
			t.Errorf("p.variableHeader => %v, want => %v", p.variableHeader, want)
			return
		}
	}
}

func TestPUBLISH_setPayload(t *testing.T) {
	p := &PUBLISH{
		Message: []byte{0x00, 0x01},
	}

	p.setPayload()

	if len(p.payload) != len(p.Message) || p.payload[0] != p.Message[0] || p.payload[1] != p.Message[1] {
		t.Errorf("p.payload => %v, want => %v", p.payload, p.Message)
	}
}

func TestNewPUBLISH_optsNil(t *testing.T) {
	if _, err := NewPUBLISH(nil); err != nil {
		nilErrorExpected(t, err)
	}
}

func TestNewPUBLISH_validateErr(t *testing.T) {
	_, err := NewPUBLISH(&PUBLISHOptions{
		QoS: 0x03,
	})

	if err != ErrInvalidQoS {
		invalidError(t, err, ErrInvalidQoS)
	}
}

func TestNewPUBLISHFromBytes_ErrInvalidFixedHeaderLen(t *testing.T) {
	if _, err := NewPUBLISHFromBytes(nil, nil); err != ErrInvalidFixedHeaderLen {
		invalidError(t, err, ErrInvalidFixedHeaderLen)
	}
}

func TestNewPUBLISHFromBytes(t *testing.T) {
	if _, err := NewPUBLISHFromBytes([]byte{TypePUBLISH<<4 | 0x02, 0x07}, []byte{0x00, 0x03, 0x61, 0x2F, 0x62, 0x00, 0x01}); err != nil {
		nilErrorExpected(t, err)
	}
}

func Test_validatePUBLISHBytes_fixedHeaderErrInvalidFixedHeaderLen(t *testing.T) {
	if err := validatePUBLISHBytes(nil, nil); err != ErrInvalidFixedHeaderLen {
		invalidError(t, err, ErrInvalidFixedHeaderLen)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidFixedHeaderLen(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH << 4}, nil); err != ErrInvalidFixedHeaderLen {
		invalidError(t, err, ErrInvalidFixedHeaderLen)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidPacketType(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypeCONNECT << 4, 0x00}, nil); err != ErrInvalidPacketType {
		invalidError(t, err, ErrInvalidPacketType)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidQoS(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH<<4 | 0x06, 0x00}, nil); err != ErrInvalidQoS {
		invalidError(t, err, ErrInvalidQoS)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidRemainingLen(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH << 4, 0x00}, nil); err != ErrInvalidRemainingLen {
		invalidError(t, err, ErrInvalidRemainingLen)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidRemainingLength(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH<<4 | 0x02, 0x02}, []byte{0x00, 0x00}); err != ErrInvalidRemainingLength {
		invalidError(t, err, ErrInvalidRemainingLength)
	}
}

func Test_validatePUBLISHBytes_ErrInvalidPacketID(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH<<4 | 0x02, 0x07}, []byte{0x00, 0x03, 0x61, 0x2F, 0x62, 0x00, 0x00}); err != ErrInvalidPacketID {
		invalidError(t, err, ErrInvalidPacketID)
	}
}

func Test_validatePUBLISHBytes(t *testing.T) {
	if err := validatePUBLISHBytes([]byte{TypePUBLISH<<4 | 0x02, 0x07}, []byte{0x00, 0x03, 0x61, 0x2F, 0x62, 0x00, 0x01}); err != nil {
		nilErrorExpected(t, err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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 container

import (
	"fmt"
	"sync"
	"time"

	"github.com/google/cadvisor/info"
	"github.com/google/cadvisor/sampling"
)

type percentilesContainerHandlerWrapper struct {
	handler              ContainerHandler
	containerPercentiles *info.ContainerStatsPercentiles
	prevStats            *info.ContainerStats
	numStats             uint64
	sampler              sampling.Sampler
	lock                 sync.Mutex
}

func (self *percentilesContainerHandlerWrapper) GetSpec() (*info.ContainerSpec, error) {
	return self.handler.GetSpec()
}

func (self *percentilesContainerHandlerWrapper) updatePrevStats(stats *info.ContainerStats) {
	if stats == nil || stats.Cpu == nil || stats.Memory == nil {
		// discard incomplete stats
		self.prevStats = nil
		return
	}
	if self.prevStats == nil {
		self.prevStats = &info.ContainerStats{
			Cpu:    &info.CpuStats{},
			Memory: &info.MemoryStats{},
		}
	}
	// make a deep copy.
	self.prevStats.Timestamp = stats.Timestamp
	*self.prevStats.Cpu = *stats.Cpu
	self.prevStats.Cpu.Usage.PerCpu = make([]uint64, len(stats.Cpu.Usage.PerCpu))
	for i, perCpu := range stats.Cpu.Usage.PerCpu {
		self.prevStats.Cpu.Usage.PerCpu[i] = perCpu
	}
	*self.prevStats.Memory = *stats.Memory
}

func (self *percentilesContainerHandlerWrapper) GetStats() (*info.ContainerStats, error) {
	stats, err := self.handler.GetStats()
	if err != nil {
		return nil, err
	}
	// nil stats and nil error is possible for /docker container.
	if stats == nil {
		// return nil, fmt.Errorf("container handler returns a nil error and a nil stats")
		return nil, nil
	}
	if stats.Timestamp.IsZero() {
		return nil, fmt.Errorf("container handler did not set timestamp")
	}
	self.lock.Lock()
	defer self.lock.Unlock()

	if self.prevStats != nil {
		sample, err := info.NewSample(self.prevStats, stats)
		if err != nil {
			return nil, fmt.Errorf("wrong stats: %v", err)
		}
		if sample != nil {
			self.sampler.Update(sample)
		}
	}
	self.updatePrevStats(stats)
	if self.containerPercentiles == nil {
		self.containerPercentiles = new(info.ContainerStatsPercentiles)
	}
	self.numStats++
	if stats.Memory != nil {
		if stats.Memory.Usage > self.containerPercentiles.MaxMemoryUsage {
			self.containerPercentiles.MaxMemoryUsage = stats.Memory.Usage
		}
	}
	return stats, nil
}

func (self *percentilesContainerHandlerWrapper) ListContainers(listType ListType) ([]info.ContainerReference, error) {
	return self.handler.ListContainers(listType)
}

func (self *percentilesContainerHandlerWrapper) ListThreads(listType ListType) ([]int, error) {
	return self.handler.ListThreads(listType)
}

func (self *percentilesContainerHandlerWrapper) ListProcesses(listType ListType) ([]int, error) {
	return self.handler.ListProcesses(listType)
}

func (self *percentilesContainerHandlerWrapper) StatsSummary() (*info.ContainerStatsPercentiles, error) {
	self.lock.Lock()
	defer self.lock.Unlock()
	samples := make([]*info.ContainerStatsSample, 0, self.sampler.Len())
	self.sampler.Map(func(d interface{}) {
		stats := d.(*info.ContainerStatsSample)
		samples = append(samples, stats)
	})
	self.containerPercentiles.Samples = samples
	// XXX(dengnan): probably add to StatsParameter?
	self.containerPercentiles.FillPercentiles(
		[]int{50, 80, 90, 95, 99},
		[]int{50, 80, 90, 95, 99},
	)
	return self.containerPercentiles, nil
}

type StatsParameter struct {
	Sampler     string
	NumSamples  int
	WindowSize  int
	ResetPeriod time.Duration
}

func AddStatsSummary(handler ContainerHandler, parameter *StatsParameter) (ContainerHandler, error) {
	sampler, err := NewSampler(parameter)
	if err != nil {
		return nil, err
	}
	return &percentilesContainerHandlerWrapper{
		handler:              handler,
		containerPercentiles: &info.ContainerStatsPercentiles{},
		sampler:              sampler,
	}, nil
}
<commit_msg>error when GetStats() return nil, nil<commit_after>// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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 container

import (
	"fmt"
	"sync"
	"time"

	"github.com/google/cadvisor/info"
	"github.com/google/cadvisor/sampling"
)

type percentilesContainerHandlerWrapper struct {
	handler              ContainerHandler
	containerPercentiles *info.ContainerStatsPercentiles
	prevStats            *info.ContainerStats
	numStats             uint64
	sampler              sampling.Sampler
	lock                 sync.Mutex
}

func (self *percentilesContainerHandlerWrapper) GetSpec() (*info.ContainerSpec, error) {
	return self.handler.GetSpec()
}

func (self *percentilesContainerHandlerWrapper) updatePrevStats(stats *info.ContainerStats) {
	if stats == nil || stats.Cpu == nil || stats.Memory == nil {
		// discard incomplete stats
		self.prevStats = nil
		return
	}
	if self.prevStats == nil {
		self.prevStats = &info.ContainerStats{
			Cpu:    &info.CpuStats{},
			Memory: &info.MemoryStats{},
		}
	}
	// make a deep copy.
	self.prevStats.Timestamp = stats.Timestamp
	*self.prevStats.Cpu = *stats.Cpu
	self.prevStats.Cpu.Usage.PerCpu = make([]uint64, len(stats.Cpu.Usage.PerCpu))
	for i, perCpu := range stats.Cpu.Usage.PerCpu {
		self.prevStats.Cpu.Usage.PerCpu[i] = perCpu
	}
	*self.prevStats.Memory = *stats.Memory
}

func (self *percentilesContainerHandlerWrapper) GetStats() (*info.ContainerStats, error) {
	stats, err := self.handler.GetStats()
	if err != nil {
		return nil, err
	}
	if stats == nil {
		return nil, fmt.Errorf("container handler returns a nil error and a nil stats")
	}
	if stats.Timestamp.IsZero() {
		return nil, fmt.Errorf("container handler did not set timestamp")
	}
	self.lock.Lock()
	defer self.lock.Unlock()

	if self.prevStats != nil {
		sample, err := info.NewSample(self.prevStats, stats)
		if err != nil {
			return nil, fmt.Errorf("wrong stats: %v", err)
		}
		if sample != nil {
			self.sampler.Update(sample)
		}
	}
	self.updatePrevStats(stats)
	if self.containerPercentiles == nil {
		self.containerPercentiles = new(info.ContainerStatsPercentiles)
	}
	self.numStats++
	if stats.Memory != nil {
		if stats.Memory.Usage > self.containerPercentiles.MaxMemoryUsage {
			self.containerPercentiles.MaxMemoryUsage = stats.Memory.Usage
		}
	}
	return stats, nil
}

func (self *percentilesContainerHandlerWrapper) ListContainers(listType ListType) ([]info.ContainerReference, error) {
	return self.handler.ListContainers(listType)
}

func (self *percentilesContainerHandlerWrapper) ListThreads(listType ListType) ([]int, error) {
	return self.handler.ListThreads(listType)
}

func (self *percentilesContainerHandlerWrapper) ListProcesses(listType ListType) ([]int, error) {
	return self.handler.ListProcesses(listType)
}

func (self *percentilesContainerHandlerWrapper) StatsSummary() (*info.ContainerStatsPercentiles, error) {
	self.lock.Lock()
	defer self.lock.Unlock()
	samples := make([]*info.ContainerStatsSample, 0, self.sampler.Len())
	self.sampler.Map(func(d interface{}) {
		stats := d.(*info.ContainerStatsSample)
		samples = append(samples, stats)
	})
	self.containerPercentiles.Samples = samples
	// XXX(dengnan): probably add to StatsParameter?
	self.containerPercentiles.FillPercentiles(
		[]int{50, 80, 90, 95, 99},
		[]int{50, 80, 90, 95, 99},
	)
	return self.containerPercentiles, nil
}

type StatsParameter struct {
	Sampler     string
	NumSamples  int
	WindowSize  int
	ResetPeriod time.Duration
}

func AddStatsSummary(handler ContainerHandler, parameter *StatsParameter) (ContainerHandler, error) {
	sampler, err := NewSampler(parameter)
	if err != nil {
		return nil, err
	}
	return &percentilesContainerHandlerWrapper{
		handler:              handler,
		containerPercentiles: &info.ContainerStatsPercentiles{},
		sampler:              sampler,
	}, nil
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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 unversioned

import (
	"fmt"

	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/util/sets"
)

// LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements
// labels.Selector
func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) {
	if ps == nil {
		return labels.Nothing(), nil
	}
	if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 {
		return labels.Everything(), nil
	}
	selector := labels.NewSelector()
	for k, v := range ps.MatchLabels {
		r, err := labels.NewRequirement(k, labels.InOperator, sets.NewString(v))
		if err != nil {
			return nil, err
		}
		selector = selector.Add(*r)
	}
	for _, expr := range ps.MatchExpressions {
		var op labels.Operator
		switch expr.Operator {
		case LabelSelectorOpIn:
			op = labels.InOperator
		case LabelSelectorOpNotIn:
			op = labels.NotInOperator
		case LabelSelectorOpExists:
			op = labels.ExistsOperator
		case LabelSelectorOpDoesNotExist:
			op = labels.DoesNotExistOperator
		default:
			return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator)
		}
		r, err := labels.NewRequirement(expr.Key, op, sets.NewString(expr.Values...))
		if err != nil {
			return nil, err
		}
		selector = selector.Add(*r)
	}
	return selector, nil
}

// SetAsLabelSelector converts the labels.Set object into a LabelSelector api object.
func SetAsLabelSelector(ls labels.Set) *LabelSelector {
	if ls == nil {
		return nil
	}

	selector := &LabelSelector{
		MatchLabels: make(map[string]string),
	}
	for label, value := range ls {
		selector.MatchLabels[label] = value
	}

	return selector
}
<commit_msg>implement kubectl get/describe for ReplicaSet<commit_after>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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 unversioned

import (
	"fmt"

	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/util/sets"
)

// LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements
// labels.Selector
func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) {
	if ps == nil {
		return labels.Nothing(), nil
	}
	if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 {
		return labels.Everything(), nil
	}
	selector := labels.NewSelector()
	for k, v := range ps.MatchLabels {
		r, err := labels.NewRequirement(k, labels.InOperator, sets.NewString(v))
		if err != nil {
			return nil, err
		}
		selector = selector.Add(*r)
	}
	for _, expr := range ps.MatchExpressions {
		var op labels.Operator
		switch expr.Operator {
		case LabelSelectorOpIn:
			op = labels.InOperator
		case LabelSelectorOpNotIn:
			op = labels.NotInOperator
		case LabelSelectorOpExists:
			op = labels.ExistsOperator
		case LabelSelectorOpDoesNotExist:
			op = labels.DoesNotExistOperator
		default:
			return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator)
		}
		r, err := labels.NewRequirement(expr.Key, op, sets.NewString(expr.Values...))
		if err != nil {
			return nil, err
		}
		selector = selector.Add(*r)
	}
	return selector, nil
}

// SetAsLabelSelector converts the labels.Set object into a LabelSelector api object.
func SetAsLabelSelector(ls labels.Set) *LabelSelector {
	if ls == nil {
		return nil
	}

	selector := &LabelSelector{
		MatchLabels: make(map[string]string),
	}
	for label, value := range ls {
		selector.MatchLabels[label] = value
	}

	return selector
}

// FormatLabelSelector convert labelSelector into plain string
func FormatLabelSelector(labelSelector *LabelSelector) string {
	var l string
	if selector, err := LabelSelectorAsSelector(labelSelector); err != nil {
		l = selector.String()
	} else {
		l = "<error>"
	}
	if l == "" {
		l = "<none>"
	}
	return l
}
<|endoftext|>


<commit_before>/*
Copyright 2015 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"
	"os"
	"strconv"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
	"k8s.io/kubernetes/pkg/kubectl/resource"
	"k8s.io/kubernetes/pkg/util/i18n"

	"github.com/daviddengcn/go-colortext"
	"github.com/spf13/cobra"
)

var (
	longDescr = templates.LongDesc(`
  Display addresses of the master and services with label kubernetes.io/cluster-service=true
  To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.`)

	clusterinfo_example = templates.Examples(`
		# Print the address of the master and cluster services
		kubectl cluster-info`)
)

func NewCmdClusterInfo(f cmdutil.Factory, out io.Writer) *cobra.Command {
	cmd := &cobra.Command{
		Use: "cluster-info",
		// clusterinfo is deprecated.
		Aliases: []string{"clusterinfo"},
		Short:   i18n.T("Display cluster info"),
		Long:    longDescr,
		Example: clusterinfo_example,
		Run: func(cmd *cobra.Command, args []string) {
			err := RunClusterInfo(f, out, cmd)
			cmdutil.CheckErr(err)
		},
	}
	cmdutil.AddInclude3rdPartyFlags(cmd)
	cmd.AddCommand(NewCmdClusterInfoDump(f, out))
	return cmd
}

func RunClusterInfo(f cmdutil.Factory, out io.Writer, cmd *cobra.Command) error {
	if len(os.Args) > 1 && os.Args[1] == "clusterinfo" {
		printDeprecationWarning("cluster-info", "clusterinfo")
	}

	client, err := f.ClientConfig()
	if err != nil {
		return err
	}
	printService(out, "Kubernetes master", client.Host)

	mapper, typer := f.Object()
	cmdNamespace := cmdutil.GetFlagString(cmd, "namespace")
	if cmdNamespace == "" {
		cmdNamespace = metav1.NamespaceSystem
	}

	// TODO use generalized labels once they are implemented (#341)
	b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
		NamespaceParam(cmdNamespace).DefaultNamespace().
		SelectorParam("kubernetes.io/cluster-service=true").
		ResourceTypeOrNameArgs(false, []string{"services"}...).
		Latest()
	b.Do().Visit(func(r *resource.Info, err error) error {
		if err != nil {
			return err
		}
		services := r.Object.(*api.ServiceList).Items
		for _, service := range services {
			var link string
			if len(service.Status.LoadBalancer.Ingress) > 0 {
				ingress := service.Status.LoadBalancer.Ingress[0]
				ip := ingress.IP
				if ip == "" {
					ip = ingress.Hostname
				}
				for _, port := range service.Spec.Ports {
					link += "http://" + ip + ":" + strconv.Itoa(int(port.Port)) + " "
				}
			} else {
				if len(client.GroupVersion.Group) == 0 {
					link = client.Host + "/api/" + client.GroupVersion.Version + "/proxy/namespaces/" + service.ObjectMeta.Namespace + "/services/" + service.ObjectMeta.Name
				} else {
					link = client.Host + "/api/" + client.GroupVersion.Group + "/" + client.GroupVersion.Version + "/proxy/namespaces/" + service.ObjectMeta.Namespace + "/services/" + service.ObjectMeta.Name

				}
			}
			name := service.ObjectMeta.Labels["kubernetes.io/name"]
			if len(name) == 0 {
				name = service.ObjectMeta.Name
			}
			printService(out, name, link)
		}
		return nil
	})
	out.Write([]byte("\nTo further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.\n"))
	return nil

	// TODO consider printing more information about cluster
}

func printService(out io.Writer, name, link string) {
	ct.ChangeColor(ct.Green, false, ct.None, false)
	fmt.Fprint(out, name)
	ct.ResetColor()
	fmt.Fprintf(out, " is running at ")
	ct.ChangeColor(ct.Yellow, false, ct.None, false)
	fmt.Fprint(out, link)
	ct.ResetColor()
	fmt.Fprintln(out, "")
}
<commit_msg>Switch clusterinfo to print recommended proxy endpoints<commit_after>/*
Copyright 2015 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"
	"os"
	"strconv"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
	"k8s.io/kubernetes/pkg/kubectl/resource"
	"k8s.io/kubernetes/pkg/util/i18n"

	"github.com/daviddengcn/go-colortext"
	"github.com/spf13/cobra"
)

var (
	longDescr = templates.LongDesc(`
  Display addresses of the master and services with label kubernetes.io/cluster-service=true
  To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.`)

	clusterinfo_example = templates.Examples(`
		# Print the address of the master and cluster services
		kubectl cluster-info`)
)

func NewCmdClusterInfo(f cmdutil.Factory, out io.Writer) *cobra.Command {
	cmd := &cobra.Command{
		Use: "cluster-info",
		// clusterinfo is deprecated.
		Aliases: []string{"clusterinfo"},
		Short:   i18n.T("Display cluster info"),
		Long:    longDescr,
		Example: clusterinfo_example,
		Run: func(cmd *cobra.Command, args []string) {
			err := RunClusterInfo(f, out, cmd)
			cmdutil.CheckErr(err)
		},
	}
	cmdutil.AddInclude3rdPartyFlags(cmd)
	cmd.AddCommand(NewCmdClusterInfoDump(f, out))
	return cmd
}

func RunClusterInfo(f cmdutil.Factory, out io.Writer, cmd *cobra.Command) error {
	if len(os.Args) > 1 && os.Args[1] == "clusterinfo" {
		printDeprecationWarning("cluster-info", "clusterinfo")
	}

	client, err := f.ClientConfig()
	if err != nil {
		return err
	}
	printService(out, "Kubernetes master", client.Host)

	mapper, typer := f.Object()
	cmdNamespace := cmdutil.GetFlagString(cmd, "namespace")
	if cmdNamespace == "" {
		cmdNamespace = metav1.NamespaceSystem
	}

	// TODO use generalized labels once they are implemented (#341)
	b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
		NamespaceParam(cmdNamespace).DefaultNamespace().
		SelectorParam("kubernetes.io/cluster-service=true").
		ResourceTypeOrNameArgs(false, []string{"services"}...).
		Latest()
	b.Do().Visit(func(r *resource.Info, err error) error {
		if err != nil {
			return err
		}
		services := r.Object.(*api.ServiceList).Items
		for _, service := range services {
			var link string
			if len(service.Status.LoadBalancer.Ingress) > 0 {
				ingress := service.Status.LoadBalancer.Ingress[0]
				ip := ingress.IP
				if ip == "" {
					ip = ingress.Hostname
				}
				for _, port := range service.Spec.Ports {
					link += "http://" + ip + ":" + strconv.Itoa(int(port.Port)) + " "
				}
			} else {
				if len(client.GroupVersion.Group) == 0 {
					link = client.Host + "/api/" + client.GroupVersion.Version + "/namespaces/" + service.ObjectMeta.Namespace + "/services/" + service.ObjectMeta.Name + "/proxy"
				} else {
					link = client.Host + "/api/" + client.GroupVersion.Group + "/" + client.GroupVersion.Version + "/namespaces/" + service.ObjectMeta.Namespace + "/services/" + service.ObjectMeta.Name + "/proxy"

				}
			}
			name := service.ObjectMeta.Labels["kubernetes.io/name"]
			if len(name) == 0 {
				name = service.ObjectMeta.Name
			}
			printService(out, name, link)
		}
		return nil
	})
	out.Write([]byte("\nTo further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.\n"))
	return nil

	// TODO consider printing more information about cluster
}

func printService(out io.Writer, name, link string) {
	ct.ChangeColor(ct.Green, false, ct.None, false)
	fmt.Fprint(out, name)
	ct.ResetColor()
	fmt.Fprintf(out, " is running at ")
	ct.ChangeColor(ct.Yellow, false, ct.None, false)
	fmt.Fprint(out, link)
	ct.ResetColor()
	fmt.Fprintln(out, "")
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"net"
	"strings"
	"time"
)

type User struct {
	nick       string
	user       string
	ident      string
	dead       bool
	nickset    bool
	connection net.Conn
	id         int
	realname   string
	userset    bool
	registered bool
	ip         string
	host       string
	epoch      time.Time
	chanlist   map[string]*Channel
}

func (user *User) QuitCommandHandler(args []string) {
	var reason string
	if len(args) > 1 {
		args[1] = StripLeading(args[1], ":")
		var buffer bytes.Buffer
		for i := 1; i < len(args); i++ {
			buffer.WriteString(args[i])
			buffer.WriteString(" ")
		}
		reason = strings.TrimSpace(buffer.String())
	} else {
		reason = "Leaving"
	}
	user.Quit(reason)
}

func (user *User) Quit(reason string) {
	targets := []*User{user}
	for _, k := range user.chanlist {
		targets = append(targets, k.GetUserList()...)
		delete(k.userlist, user.id)
		delete(user.chanlist, k.name)
		k.ShouldIDie()
	}
	SendToMany(fmt.Sprintf(":%s QUIT :%s", user.GetHostMask(), reason), targets)
	user.SendLine(fmt.Sprintf("ERROR :Closing Link: %s (%s)", user.host, reason))
	user.dead = true
	if user.connection != nil {
		user.connection.Close()
	}
	delete(userlist, user.id)
}

func (user *User) FireNumeric(numeric int, args ...interface{}) {
	msg := strcat(fmt.Sprintf(":%s %.3d %s ", sname, numeric, user.nick), fmt.Sprintf(NUM[numeric], args...))
	user.SendLine(msg)
}

func NewUser(conn net.Conn) *User {
	userip := GetIpFromConn(conn)
	log.Println("New connection from", userip)
	counter = counter + 1
	user := &User{id: counter, connection: conn, ip: userip, nick: "*"}
	user.chanlist = make(map[string]*Channel)
	user.host = user.ip
	user.epoch = time.Now()
	userlist[user.id] = user
	go user.UserHostLookup()
	return user
}

func (user *User) SendLine(msg string) {
	msg = fmt.Sprintf("%s\n", msg)
	if user.dead {
		return
	}
	_, err := user.connection.Write([]byte(msg))
	if err != nil {
		user.dead = true
		user.Quit("Error")
		log.Printf("Error sending message to %s, disconnecting\n", user.nick)
	}
	log.Printf("Send to %s: %s", user.nick, msg)
}

func (user *User) HandleRequests() {
	b := bufio.NewReader(user.connection)
	for {
		if user.dead {
			break
		}
		line, err := b.ReadString('\n')
		if err != nil {
			log.Println("Error reading:", err.Error())
			user.dead = true
			user.Quit("Error")
		}
		if line == "" {
			user.dead = true
			user.Quit("Error")
			break
		}
		line = strings.TrimSpace(line)
		log.Println("Receive from", fmt.Sprintf("%s:", user.nick), line)
		go ProcessLine(user, line)
	}
}
func (user *User) NickHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NONICKNAMEGIVEN)
		return
	}
	if GetUserByNick(args[1]) != nil {
		user.FireNumeric(ERR_NICKNAMEINUSE, args[1])
		return
	}
	if !user.nickset {
		user.nickset = true
	} else if user.registered {
		targets := []*User{}
		targets = append(targets, user)
		for _, k := range user.chanlist {
			targets = append(targets, k.GetUserList()...)
		}
		SendToMany(fmt.Sprintf(":%s NICK %s", user.GetHostMask(), args[1]), targets)
	}
	user.nick = args[1]
	if !user.registered && user.userset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserHandler(args []string) {
	if len(args) < 5 {
		//ERR_NEEDMOREPARAMS
		return
	}
	user.ident = args[1]
	args[4] = StripLeading(args[4], ":")
	var buffer bytes.Buffer
	for i := 4; i < len(args); i++ {
		buffer.WriteString(args[i])
		buffer.WriteString(" ")
	}
	user.realname = strings.TrimSpace(buffer.String())
	user.userset = true
	if !user.registered && user.nickset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserRegistrationFinished() {
	user.registered = true
	log.Printf("User %d finished registration\n", user.id)
	user.FireNumeric(RPL_WELCOME, user.nick, user.ident, user.host)
	user.FireNumeric(RPL_YOURHOST, sname, software, softwarev)
	user.FireNumeric(RPL_CREATED, epoch)
	//TODO fire RPL_MYINFO when we actually have enough stuff to do it
}

func (user *User) UserHostLookup() {
	user.SendLine(fmt.Sprintf(":%s NOTICE %s :*** Looking up your hostname...", sname, user.nick))
	adds, err := net.LookupAddr(user.ip)
	if err != nil {
		user.SendLine(fmt.Sprintf("%s NOTICE %s :*** Unable to resolve your hostname", sname, user.nick))
		return
	}
	addstring := adds[0]
	adds, err = net.LookupHost(addstring)
	if err != nil {
		user.SendLine(fmt.Sprintf("%s NOTICE %s :*** Unable to resolve your hostname", sname, user.nick))
		return
	}
	for _, k := range adds {
		if user.ip == k {
			user.host = addstring
			user.SendLine(fmt.Sprintf(":%s NOTICE %s :*** Found your hostname", sname, user.nick))
			return
		}
	}
	user.SendLine(fmt.Sprintf(":%s NOTICE %s :*** Your forward and reverse DNS do not match, ignoring hostname", sname, user.nick))
}

func (user *User) CommandNotFound(args []string) {
	user.FireNumeric(ERR_UNKNOWNCOMMAND, args[0])
}

func (user *User) GetHostMask() string {
	return fmt.Sprintf("%s!%s@%s", user.nick, user.ident, user.host)
}

func (user *User) JoinHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "JOIN")
		return
	}
	if !ValidChanName(args[1]) {
		user.FireNumeric(ERR_NOSUCHCHANNEL, args[1])
		return
	}
	_, channel := GetChannelByName(args[1])
	channel.JoinUser(user)
	user.chanlist[channel.name] = channel
}

func (user *User) PrivmsgHandler(args []string) {
	if len(args) < 3 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "PRIVMSG")
		return
	}
	if ValidChanName(args[1]) { //TODO part of this should be sent to the channel "object"
		//presumably a channel
		k, j := GetChannelByName(args[1])
		if k {
			//channel exists, send the message
			msg := FormatMessageArgs(args)
			list := j.GetUserList()
			for _, l := range list {
				if l != user {
					l.SendLine(fmt.Sprintf(":%s PRIVMSG %s :%s", user.GetHostMask(), j.name, msg))
				}
			}
			return
		} else {
			//channel didnt exist but get channel by name makes one anyways, lets kill it...
			user.FireNumeric(ERR_NOSUCHCHANNEL, args[1])
			j.ShouldIDie()
			return
		}
	} else {
		//maybe its a user
		target := GetUserByNick(args[1])
		if target != nil {
			msg := FormatMessageArgs(args)
			target.SendLine(fmt.Sprint(":%s PRIVMSG %s :%s", user.GetHostMask(), target.nick, msg))
		}
	}
}
<commit_msg>fire ERR_NEEDMOREPARAMS when USER doesn't have enough commands<commit_after>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"net"
	"strings"
	"time"
)

type User struct {
	nick       string
	user       string
	ident      string
	dead       bool
	nickset    bool
	connection net.Conn
	id         int
	realname   string
	userset    bool
	registered bool
	ip         string
	host       string
	epoch      time.Time
	chanlist   map[string]*Channel
}

func (user *User) QuitCommandHandler(args []string) {
	var reason string
	if len(args) > 1 {
		args[1] = StripLeading(args[1], ":")
		var buffer bytes.Buffer
		for i := 1; i < len(args); i++ {
			buffer.WriteString(args[i])
			buffer.WriteString(" ")
		}
		reason = strings.TrimSpace(buffer.String())
	} else {
		reason = "Leaving"
	}
	user.Quit(reason)
}

func (user *User) Quit(reason string) {
	targets := []*User{user}
	for _, k := range user.chanlist {
		targets = append(targets, k.GetUserList()...)
		delete(k.userlist, user.id)
		delete(user.chanlist, k.name)
		k.ShouldIDie()
	}
	SendToMany(fmt.Sprintf(":%s QUIT :%s", user.GetHostMask(), reason), targets)
	user.SendLine(fmt.Sprintf("ERROR :Closing Link: %s (%s)", user.host, reason))
	user.dead = true
	if user.connection != nil {
		user.connection.Close()
	}
	delete(userlist, user.id)
}

func (user *User) FireNumeric(numeric int, args ...interface{}) {
	msg := strcat(fmt.Sprintf(":%s %.3d %s ", sname, numeric, user.nick), fmt.Sprintf(NUM[numeric], args...))
	user.SendLine(msg)
}

func NewUser(conn net.Conn) *User {
	userip := GetIpFromConn(conn)
	log.Println("New connection from", userip)
	counter = counter + 1
	user := &User{id: counter, connection: conn, ip: userip, nick: "*"}
	user.chanlist = make(map[string]*Channel)
	user.host = user.ip
	user.epoch = time.Now()
	userlist[user.id] = user
	go user.UserHostLookup()
	return user
}

func (user *User) SendLine(msg string) {
	msg = fmt.Sprintf("%s\n", msg)
	if user.dead {
		return
	}
	_, err := user.connection.Write([]byte(msg))
	if err != nil {
		user.dead = true
		user.Quit("Error")
		log.Printf("Error sending message to %s, disconnecting\n", user.nick)
	}
	log.Printf("Send to %s: %s", user.nick, msg)
}

func (user *User) HandleRequests() {
	b := bufio.NewReader(user.connection)
	for {
		if user.dead {
			break
		}
		line, err := b.ReadString('\n')
		if err != nil {
			log.Println("Error reading:", err.Error())
			user.dead = true
			user.Quit("Error")
		}
		if line == "" {
			user.dead = true
			user.Quit("Error")
			break
		}
		line = strings.TrimSpace(line)
		log.Println("Receive from", fmt.Sprintf("%s:", user.nick), line)
		go ProcessLine(user, line)
	}
}
func (user *User) NickHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NONICKNAMEGIVEN)
		return
	}
	if GetUserByNick(args[1]) != nil {
		user.FireNumeric(ERR_NICKNAMEINUSE, args[1])
		return
	}
	if !user.nickset {
		user.nickset = true
	} else if user.registered {
		targets := []*User{}
		targets = append(targets, user)
		for _, k := range user.chanlist {
			targets = append(targets, k.GetUserList()...)
		}
		SendToMany(fmt.Sprintf(":%s NICK %s", user.GetHostMask(), args[1]), targets)
	}
	user.nick = args[1]
	if !user.registered && user.userset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserHandler(args []string) {
	if len(args) < 5 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "USER")
		return
	}
	user.ident = args[1]
	args[4] = StripLeading(args[4], ":")
	var buffer bytes.Buffer
	for i := 4; i < len(args); i++ {
		buffer.WriteString(args[i])
		buffer.WriteString(" ")
	}
	user.realname = strings.TrimSpace(buffer.String())
	user.userset = true
	if !user.registered && user.nickset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserRegistrationFinished() {
	user.registered = true
	log.Printf("User %d finished registration\n", user.id)
	user.FireNumeric(RPL_WELCOME, user.nick, user.ident, user.host)
	user.FireNumeric(RPL_YOURHOST, sname, software, softwarev)
	user.FireNumeric(RPL_CREATED, epoch)
	//TODO fire RPL_MYINFO when we actually have enough stuff to do it
}

func (user *User) UserHostLookup() {
	user.SendLine(fmt.Sprintf(":%s NOTICE %s :*** Looking up your hostname...", sname, user.nick))
	adds, err := net.LookupAddr(user.ip)
	if err != nil {
		user.SendLine(fmt.Sprintf("%s NOTICE %s :*** Unable to resolve your hostname", sname, user.nick))
		return
	}
	addstring := adds[0]
	adds, err = net.LookupHost(addstring)
	if err != nil {
		user.SendLine(fmt.Sprintf("%s NOTICE %s :*** Unable to resolve your hostname", sname, user.nick))
		return
	}
	for _, k := range adds {
		if user.ip == k {
			user.host = addstring
			user.SendLine(fmt.Sprintf(":%s NOTICE %s :*** Found your hostname", sname, user.nick))
			return
		}
	}
	user.SendLine(fmt.Sprintf(":%s NOTICE %s :*** Your forward and reverse DNS do not match, ignoring hostname", sname, user.nick))
}

func (user *User) CommandNotFound(args []string) {
	user.FireNumeric(ERR_UNKNOWNCOMMAND, args[0])
}

func (user *User) GetHostMask() string {
	return fmt.Sprintf("%s!%s@%s", user.nick, user.ident, user.host)
}

func (user *User) JoinHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "JOIN")
		return
	}
	if !ValidChanName(args[1]) {
		user.FireNumeric(ERR_NOSUCHCHANNEL, args[1])
		return
	}
	_, channel := GetChannelByName(args[1])
	channel.JoinUser(user)
	user.chanlist[channel.name] = channel
}

func (user *User) PrivmsgHandler(args []string) {
	if len(args) < 3 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "PRIVMSG")
		return
	}
	if ValidChanName(args[1]) { //TODO part of this should be sent to the channel "object"
		//presumably a channel
		k, j := GetChannelByName(args[1])
		if k {
			//channel exists, send the message
			msg := FormatMessageArgs(args)
			list := j.GetUserList()
			for _, l := range list {
				if l != user {
					l.SendLine(fmt.Sprintf(":%s PRIVMSG %s :%s", user.GetHostMask(), j.name, msg))
				}
			}
			return
		} else {
			//channel didnt exist but get channel by name makes one anyways, lets kill it...
			user.FireNumeric(ERR_NOSUCHCHANNEL, args[1])
			j.ShouldIDie()
			return
		}
	} else {
		//maybe its a user
		target := GetUserByNick(args[1])
		if target != nil {
			msg := FormatMessageArgs(args)
			target.SendLine(fmt.Sprint(":%s PRIVMSG %s :%s", user.GetHostMask(), target.nick, msg))
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"net"
	"strings"
)

type User struct {
	nick       string
	user       string
	ident      string
	ip         string
	dead       bool
	nickset    bool
	connection net.Conn
	id         int
	realname   string
	userset    bool
	registered bool
	host       string
}

func (user *User) Quit() {
	user.dead = true
	if user.connection != nil {
		user.connection.Close()
	}
	delete(userlist, user.id)
}

func (user *User) FireNumeric(numeric int, args ...interface{}) {
	msg := strcat(fmt.Sprintf(":%s %.3d ", "test.net.local", numeric), fmt.Sprintf(NUM[numeric], args...))
	user.SendLine(msg)
}

func NewUser(conn net.Conn) User {
	counter = counter + 1
	user := User{id: counter, connection: conn}
	user.host = "lol"
	AddUserToList(user)
	return user
}

func (user *User) SendLine(msg string) {
	msg = fmt.Sprintf("%s\n", msg)
	user.connection.Write([]byte(msg))
}

func (user *User) HandleRequests() {
	b := bufio.NewReader(user.connection)
	for {
		if user.dead {
			break
		}
		line, err := b.ReadString('\n')
		if err != nil {
			fmt.Println("Error reading:", err.Error())
			user.Quit()
		}
		line = strings.TrimSpace(line)
		fmt.Println("Received Line: ", line)
		// Send a response back to person contacting us.
		go ProcessLine(user, line)
	}
}
func (user *User) NickHandler(args []string) {
	if CheckNickCollision(args[1]) != false {
		return //TODO handle properly
	}
	if !user.nickset {
		user.nickset = true
	}
	user.nick = args[1]
	fmt.Println("User changed name to", args[1])
	if !user.registered && user.userset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserHandler(args []string) {
	if len(args) < 5 {
		//ERR_NEEDMOREPARAMS
		return
	}
	user.ident = args[1]
	if strings.HasPrefix(args[4], ":") {
		args[4] = strings.Replace(args[4], ":", "", 1)
	}
	var buffer bytes.Buffer
	for i := 4; i < len(args); i++ {
		buffer.WriteString(args[i])
		buffer.WriteString(" ")
	}
	user.realname = strings.TrimSpace(buffer.String())
	user.userset = true
	if !user.registered && user.nickset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserRegistrationFinished() {
	user.registered = true
	fmt.Printf("User %d finished registration\n", user.id)
	user.FireNumeric(RPL_WELCOME, user.nick, user.ident, user.host)
}
<commit_msg>remove unecessary threading<commit_after>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"net"
	"strings"
)

type User struct {
	nick       string
	user       string
	ident      string
	ip         string
	dead       bool
	nickset    bool
	connection net.Conn
	id         int
	realname   string
	userset    bool
	registered bool
	host       string
}

func (user *User) Quit() {
	user.dead = true
	if user.connection != nil {
		user.connection.Close()
	}
	delete(userlist, user.id)
}

func (user *User) FireNumeric(numeric int, args ...interface{}) {
	msg := strcat(fmt.Sprintf(":%s %.3d ", "test.net.local", numeric), fmt.Sprintf(NUM[numeric], args...))
	user.SendLine(msg)
}

func NewUser(conn net.Conn) User {
	counter = counter + 1
	user := User{id: counter, connection: conn}
	user.host = "lol"
	AddUserToList(user)
	return user
}

func (user *User) SendLine(msg string) {
	msg = fmt.Sprintf("%s\n", msg)
	user.connection.Write([]byte(msg))
}

func (user *User) HandleRequests() {
	b := bufio.NewReader(user.connection)
	for {
		if user.dead {
			break
		}
		line, err := b.ReadString('\n')
		if err != nil {
			fmt.Println("Error reading:", err.Error())
			user.Quit()
		}
		line = strings.TrimSpace(line)
		fmt.Println("Received Line: ", line)
		ProcessLine(user, line)
	}
}
func (user *User) NickHandler(args []string) {
	if CheckNickCollision(args[1]) != false {
		return //TODO handle properly
	}
	if !user.nickset {
		user.nickset = true
	}
	user.nick = args[1]
	fmt.Println("User changed name to", args[1])
	if !user.registered && user.userset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserHandler(args []string) {
	if len(args) < 5 {
		//ERR_NEEDMOREPARAMS
		return
	}
	user.ident = args[1]
	if strings.HasPrefix(args[4], ":") {
		args[4] = strings.Replace(args[4], ":", "", 1)
	}
	var buffer bytes.Buffer
	for i := 4; i < len(args); i++ {
		buffer.WriteString(args[i])
		buffer.WriteString(" ")
	}
	user.realname = strings.TrimSpace(buffer.String())
	user.userset = true
	if !user.registered && user.nickset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserRegistrationFinished() {
	user.registered = true
	fmt.Printf("User %d finished registration\n", user.id)
	user.FireNumeric(RPL_WELCOME, user.nick, user.ident, user.host)
}
<|endoftext|>


<commit_before>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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 event

import (
	"fmt"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/errors"
	"k8s.io/kubernetes/pkg/api/validation"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/registry/generic"
	"k8s.io/kubernetes/pkg/runtime"
	utilvalidation "k8s.io/kubernetes/pkg/util/validation"
)

type eventStrategy struct {
	runtime.ObjectTyper
	api.NameGenerator
}

// Strategy is the default logic that pplies when creating and updating
// Event objects via the REST API.
var Strategy = eventStrategy{api.Scheme, api.SimpleNameGenerator}

func (eventStrategy) NamespaceScoped() bool {
	return true
}

func (eventStrategy) PrepareForCreate(obj runtime.Object) {
}

func (eventStrategy) PrepareForUpdate(obj, old runtime.Object) {
}

func (eventStrategy) Validate(ctx api.Context, obj runtime.Object) utilvalidation.ErrorList {
	event := obj.(*api.Event)
	return validation.ValidateEvent(event)
}

// Canonicalize normalizes the object after validation.
func (eventStrategy) Canonicalize(obj runtime.Object) {
}

func (eventStrategy) AllowCreateOnUpdate() bool {
	return true
}

func (eventStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) utilvalidation.ErrorList {
	event := obj.(*api.Event)
	return validation.ValidateEvent(event)
}

func (eventStrategy) AllowUnconditionalUpdate() bool {
	return true
}

func MatchEvent(label labels.Selector, field fields.Selector) generic.Matcher {
	return &generic.SelectionPredicate{Label: label, Field: field, GetAttrs: getAttrs}
}

func getAttrs(obj runtime.Object) (objLabels labels.Set, objFields fields.Set, err error) {
	event, ok := obj.(*api.Event)
	if !ok {
		return nil, nil, errors.NewInternalError(fmt.Errorf("object is not of type event: %#v", obj))
	}
	l := event.Labels
	if l == nil {
		l = labels.Set{}
	}

	objectMetaFieldsSet := generic.ObjectMetaFieldsSet(event.ObjectMeta, true)
	specificFieldsSet := fields.Set{
		"involvedObject.kind":            event.InvolvedObject.Kind,
		"involvedObject.namespace":       event.InvolvedObject.Namespace,
		"involvedObject.name":            event.InvolvedObject.Name,
		"involvedObject.uid":             string(event.InvolvedObject.UID),
		"involvedObject.apiVersion":      event.InvolvedObject.APIVersion,
		"involvedObject.resourceVersion": fmt.Sprintf("%s", event.InvolvedObject.ResourceVersion),
		"involvedObject.fieldPath":       event.InvolvedObject.FieldPath,
		"reason":                         event.Reason,
		"source":                         event.Source.Component,
	}
	return l, generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet), nil
}
<commit_msg>remove unnecessary fmt.Printf()<commit_after>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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 event

import (
	"fmt"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/errors"
	"k8s.io/kubernetes/pkg/api/validation"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/registry/generic"
	"k8s.io/kubernetes/pkg/runtime"
	utilvalidation "k8s.io/kubernetes/pkg/util/validation"
)

type eventStrategy struct {
	runtime.ObjectTyper
	api.NameGenerator
}

// Strategy is the default logic that pplies when creating and updating
// Event objects via the REST API.
var Strategy = eventStrategy{api.Scheme, api.SimpleNameGenerator}

func (eventStrategy) NamespaceScoped() bool {
	return true
}

func (eventStrategy) PrepareForCreate(obj runtime.Object) {
}

func (eventStrategy) PrepareForUpdate(obj, old runtime.Object) {
}

func (eventStrategy) Validate(ctx api.Context, obj runtime.Object) utilvalidation.ErrorList {
	event := obj.(*api.Event)
	return validation.ValidateEvent(event)
}

// Canonicalize normalizes the object after validation.
func (eventStrategy) Canonicalize(obj runtime.Object) {
}

func (eventStrategy) AllowCreateOnUpdate() bool {
	return true
}

func (eventStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) utilvalidation.ErrorList {
	event := obj.(*api.Event)
	return validation.ValidateEvent(event)
}

func (eventStrategy) AllowUnconditionalUpdate() bool {
	return true
}

func MatchEvent(label labels.Selector, field fields.Selector) generic.Matcher {
	return &generic.SelectionPredicate{Label: label, Field: field, GetAttrs: getAttrs}
}

func getAttrs(obj runtime.Object) (objLabels labels.Set, objFields fields.Set, err error) {
	event, ok := obj.(*api.Event)
	if !ok {
		return nil, nil, errors.NewInternalError(fmt.Errorf("object is not of type event: %#v", obj))
	}
	l := event.Labels
	if l == nil {
		l = labels.Set{}
	}

	objectMetaFieldsSet := generic.ObjectMetaFieldsSet(event.ObjectMeta, true)
	specificFieldsSet := fields.Set{
		"involvedObject.kind":            event.InvolvedObject.Kind,
		"involvedObject.namespace":       event.InvolvedObject.Namespace,
		"involvedObject.name":            event.InvolvedObject.Name,
		"involvedObject.uid":             string(event.InvolvedObject.UID),
		"involvedObject.apiVersion":      event.InvolvedObject.APIVersion,
		"involvedObject.resourceVersion": event.InvolvedObject.ResourceVersion,
		"involvedObject.fieldPath":       event.InvolvedObject.FieldPath,
		"reason":                         event.Reason,
		"source":                         event.Source.Component,
	}
	return l, generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet), nil
}
<|endoftext|>


<commit_before>package cluster

import (
	"io/ioutil"
	"os"
	"reflect"
	"testing"
)

const (
	testPath = "/dev/shm/info.json"
)

func newInfo() *Info {
	return NewInfo(testPath)
}

func rmInfo() {
	os.Remove(testPath)
}

func TestInfoSave(t *testing.T) {
	info := newInfo()
	defer rmInfo()

	err := info.Save()
	if err != nil {
		t.Fatalf("Save() failed")
	}

	st, err := os.Stat(testPath)
	if err != nil {
		t.Fatalf("Could not stat saved file")
	}

	if st == nil {
		t.Fatalf("Save() failed to write a file")
	}

	permissions := st.Mode().Perm()
	if permissions&077 != 0 {
		t.Fatalf("File mode is too permissive, got %#o", st.Mode())
	}
}

func TestInfoSaveFail(t *testing.T) {
	i := NewInfo("/nonexisting/path/something.json")
	err := i.Save()
	if err == nil {
		t.Fatalf("Save() failed to detect error")
	}
}

func TestInfoLoadFail(t *testing.T) {
	defer rmInfo()

	i := &Info{
		path: testPath,
	}

	err := i.Load()
	if err == nil {
		t.Fatalf("Load() failed to detect file read error")
	}

	// Write some broken JSON.
	ioutil.WriteFile(testPath, []byte("NOT JSON"), 0600)
	err = i.Load()
	if err == nil {
		t.Fatalf("Load() failed to detect broken JSON")
	}
}

func TestInfoPeers(t *testing.T) {
	i := newInfo()
	defer rmInfo()

	cases := [][]string{
		nil,
		{},
		{"a"},
		{"a", "b"},
	}

	for _, c := range cases {
		err := i.SetPeers(c)
		if err != nil {
			t.Fatalf("SetPeers() failed: %s", err.Error())
		}

		// Let's have a roundtrip to disk.
		i.Save()
		i.PeerList = nil
		i.Load()

		peers, err := i.Peers()
		if err != nil {
			t.Fatalf("Peers() failed: %s", err.Error())
		}

		if !reflect.DeepEqual(c, peers) {
			t.Fatalf("Peers() did not return what we gave SetPeers()")
		}
	}
}

func TestInfoSelf(t *testing.T) {
	i := newInfo()
	defer rmInfo()

	cases := []string{
		"a",
		"",
		"\n",
	}

	for _, c := range cases {
		err := i.SetSelf(c)
		if err != nil {
			t.Fatalf("SetSelf() failed: %s", err.Error())
		}

		// Let's have a roundtrip to disk.
		i.Save()
		i.SelfName = "NOT THIS"
		i.Load()

		self := i.Self()
		if err != nil {
			t.Fatalf("Self() failed: %s", err.Error())
		}

		if c != self {
			t.Fatalf("Self() failed to return what we gave SetSelf()")
		}
	}
}

func TestInfoIP(t *testing.T) {
	i := newInfo()
	defer rmInfo()

	i.SetSelf("go-test-target-v4.gansoi-dev.com")
	ip := i.IP()
	if ip == nil {
		t.Fatalf("Failed to resolve IPv4 , got %s", ip)
	}

	if ip.String() != "198.51.100.1" {
		t.Fatalf("Failed to resolve self to IP, got %s", ip.String())
	}

	i.SetSelf("go-test-target-v6.gansoi-dev.com")
	ip = i.IP()
	if ip == nil {
		t.Fatalf("Failed to resolve IPv6 self, got %s", ip)
	}

	if ip.String() != "2001:db8::2" {
		t.Fatalf("Failed to resolve self to IP, got %s", ip.String())
	}

	i.SetSelf("go-test-nonexisting.gansoi-dev.com:4934")
	ip = i.IP()
	if ip != nil {
		t.Fatalf("Returned something for failing host in Self(), got %s", ip)
	}
}
<commit_msg>Use os.TempDir() instead of hardcoded /dev/shm.<commit_after>package cluster

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"os"
	"path"
	"reflect"
	"testing"
)

var (
	testPath = path.Join(os.TempDir(), fmt.Sprintf(".info-%d.json", rand.Int63()))
)

func newInfo() *Info {
	return NewInfo(testPath)
}

func rmInfo() {
	os.Remove(testPath)
}

func TestInfoSave(t *testing.T) {
	info := newInfo()
	defer rmInfo()

	err := info.Save()
	if err != nil {
		t.Fatalf("Save() failed")
	}

	st, err := os.Stat(testPath)
	if err != nil {
		t.Fatalf("Could not stat saved file")
	}

	if st == nil {
		t.Fatalf("Save() failed to write a file")
	}

	permissions := st.Mode().Perm()
	if permissions&077 != 0 {
		t.Fatalf("File mode is too permissive, got %#o", st.Mode())
	}
}

func TestInfoSaveFail(t *testing.T) {
	i := NewInfo("/nonexisting/path/something.json")
	err := i.Save()
	if err == nil {
		t.Fatalf("Save() failed to detect error")
	}
}

func TestInfoLoadFail(t *testing.T) {
	defer rmInfo()

	i := &Info{
		path: testPath,
	}

	err := i.Load()
	if err == nil {
		t.Fatalf("Load() failed to detect file read error")
	}

	// Write some broken JSON.
	ioutil.WriteFile(testPath, []byte("NOT JSON"), 0600)
	err = i.Load()
	if err == nil {
		t.Fatalf("Load() failed to detect broken JSON")
	}
}

func TestInfoPeers(t *testing.T) {
	i := newInfo()
	defer rmInfo()

	cases := [][]string{
		nil,
		{},
		{"a"},
		{"a", "b"},
	}

	for _, c := range cases {
		err := i.SetPeers(c)
		if err != nil {
			t.Fatalf("SetPeers() failed: %s", err.Error())
		}

		// Let's have a roundtrip to disk.
		i.Save()
		i.PeerList = nil
		i.Load()

		peers, err := i.Peers()
		if err != nil {
			t.Fatalf("Peers() failed: %s", err.Error())
		}

		if !reflect.DeepEqual(c, peers) {
			t.Fatalf("Peers() did not return what we gave SetPeers()")
		}
	}
}

func TestInfoSelf(t *testing.T) {
	i := newInfo()
	defer rmInfo()

	cases := []string{
		"a",
		"",
		"\n",
	}

	for _, c := range cases {
		err := i.SetSelf(c)
		if err != nil {
			t.Fatalf("SetSelf() failed: %s", err.Error())
		}

		// Let's have a roundtrip to disk.
		i.Save()
		i.SelfName = "NOT THIS"
		i.Load()

		self := i.Self()
		if err != nil {
			t.Fatalf("Self() failed: %s", err.Error())
		}

		if c != self {
			t.Fatalf("Self() failed to return what we gave SetSelf()")
		}
	}
}

func TestInfoIP(t *testing.T) {
	i := newInfo()
	defer rmInfo()

	i.SetSelf("go-test-target-v4.gansoi-dev.com")
	ip := i.IP()
	if ip == nil {
		t.Fatalf("Failed to resolve IPv4 , got %s", ip)
	}

	if ip.String() != "198.51.100.1" {
		t.Fatalf("Failed to resolve self to IP, got %s", ip.String())
	}

	i.SetSelf("go-test-target-v6.gansoi-dev.com")
	ip = i.IP()
	if ip == nil {
		t.Fatalf("Failed to resolve IPv6 self, got %s", ip)
	}

	if ip.String() != "2001:db8::2" {
		t.Fatalf("Failed to resolve self to IP, got %s", ip.String())
	}

	i.SetSelf("go-test-nonexisting.gansoi-dev.com:4934")
	ip = i.IP()
	if ip != nil {
		t.Fatalf("Returned something for failing host in Self(), got %s", ip)
	}
}
<|endoftext|>


<commit_before>package facts

import (
	"bufio"
	"bytes"
	"io"
	"os"
	"reflect"
	"strings"

	"golang.org/x/tools/go/analysis"
)

type Generator int

// A list of known generators we can detect
const (
	Unknown Generator = iota
	Goyacc
	Cgo
	Stringer
)

var (
	// used by cgo before Go 1.11
	oldCgo = []byte("// Created by cgo - DO NOT EDIT")
	prefix = []byte("// Code generated ")
	suffix = []byte(" DO NOT EDIT.")
	nl     = []byte("\n")
	crnl   = []byte("\r\n")
)

func isGenerated(path string) (Generator, bool) {
	f, err := os.Open(path)
	if err != nil {
		return 0, false
	}
	defer f.Close()
	br := bufio.NewReader(f)
	for {
		s, err := br.ReadBytes('\n')
		if err != nil && err != io.EOF {
			return 0, false
		}
		s = bytes.TrimSuffix(s, crnl)
		s = bytes.TrimSuffix(s, nl)
		if bytes.HasPrefix(s, prefix) && bytes.HasSuffix(s, suffix) {
			text := string(s[len(prefix) : len(s)-len(suffix)])
			switch text {
			case "by goyacc.":
				return Goyacc, true
			case "by cmd/cgo;":
				return Cgo, true
			}
			if strings.HasPrefix(text, `by "stringer `) {
				return Stringer, true
			}
			return Unknown, true
		}
		if bytes.Equal(s, oldCgo) {
			return Cgo, true
		}
		if err == io.EOF {
			break
		}
	}
	return 0, false
}

var Generated = &analysis.Analyzer{
	Name: "isgenerated",
	Doc:  "annotate file names that have been code generated",
	Run: func(pass *analysis.Pass) (interface{}, error) {
		m := map[string]Generator{}
		for _, f := range pass.Files {
			path := pass.Fset.PositionFor(f.Pos(), false).Filename
			g, ok := isGenerated(path)
			if ok {
				m[path] = g
			}
		}
		return m, nil
	},
	RunDespiteErrors: true,
	ResultType:       reflect.TypeOf(map[string]Generator{}),
}
<commit_msg>facts: fix detection of goyacc generated files<commit_after>package facts

import (
	"bufio"
	"bytes"
	"io"
	"os"
	"reflect"
	"strings"

	"golang.org/x/tools/go/analysis"
)

type Generator int

// A list of known generators we can detect
const (
	Unknown Generator = iota
	Goyacc
	Cgo
	Stringer
)

var (
	// used by cgo before Go 1.11
	oldCgo = []byte("// Created by cgo - DO NOT EDIT")
	prefix = []byte("// Code generated ")
	suffix = []byte(" DO NOT EDIT.")
	nl     = []byte("\n")
	crnl   = []byte("\r\n")
)

func isGenerated(path string) (Generator, bool) {
	f, err := os.Open(path)
	if err != nil {
		return 0, false
	}
	defer f.Close()
	br := bufio.NewReader(f)
	for {
		s, err := br.ReadBytes('\n')
		if err != nil && err != io.EOF {
			return 0, false
		}
		s = bytes.TrimSuffix(s, crnl)
		s = bytes.TrimSuffix(s, nl)
		if bytes.HasPrefix(s, prefix) && bytes.HasSuffix(s, suffix) {
			text := string(s[len(prefix) : len(s)-len(suffix)])
			switch text {
			case "by goyacc.":
				return Goyacc, true
			case "by cmd/cgo;":
				return Cgo, true
			}
			if strings.HasPrefix(text, `by "stringer `) {
				return Stringer, true
			}
			if strings.HasPrefix(text, `by goyacc `) {
				return Goyacc, true
			}

			return Unknown, true
		}
		if bytes.Equal(s, oldCgo) {
			return Cgo, true
		}
		if err == io.EOF {
			break
		}
	}
	return 0, false
}

var Generated = &analysis.Analyzer{
	Name: "isgenerated",
	Doc:  "annotate file names that have been code generated",
	Run: func(pass *analysis.Pass) (interface{}, error) {
		m := map[string]Generator{}
		for _, f := range pass.Files {
			path := pass.Fset.PositionFor(f.Pos(), false).Filename
			g, ok := isGenerated(path)
			if ok {
				m[path] = g
			}
		}
		return m, nil
	},
	RunDespiteErrors: true,
	ResultType:       reflect.TypeOf(map[string]Generator{}),
}
<|endoftext|>


<commit_before>package cssminify

import (
	"fmt"
)

func Minify(blocks []Block) {
	for _, block := range blocks {
		fmt.Printf("%s\n", block.selector)
	}
}
<commit_msg>Preparing the field for minifying<commit_after>package cssminify

import (
	"fmt"
)

func Minify(blocks []Block) {
	for _, block := range blocks {
		showSelectors(string(block.selector))
		fmt.Print("{")
		showPropVals(block.pairs)
		fmt.Print("}")
	}
}

func showSelectors(selector string) {
}

func showPropVals(pairs []Pair) {
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
// 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 main contains a Go mobile app that tweaks the
// cmd/blinker server's blink rate.
package main

import (
	"encoding/binary"
	"log"

	"golang.org/x/mobile/app"
	"golang.org/x/mobile/event/config"
	"golang.org/x/mobile/event/lifecycle"
	"golang.org/x/mobile/event/paint"
	"golang.org/x/mobile/event/touch"
	"golang.org/x/mobile/exp/f32"
	"golang.org/x/mobile/exp/gl/glutil"
	"golang.org/x/mobile/geom"
	"golang.org/x/mobile/gl"
)

var (
	program  gl.Program
	position gl.Attrib
	offset   gl.Uniform
	color    gl.Uniform
	buf      gl.Buffer

	touchLoc geom.Point
)

func main() {
	app.Main(func(a app.App) {
		var c config.Event
		for e := range a.Events() {
			switch e := app.Filter(e).(type) {
			case lifecycle.Event:
				switch e.Crosses(lifecycle.StageVisible) {
				case lifecycle.CrossOn:
					onStart()
				case lifecycle.CrossOff:
					onStop()
				}
			case config.Event:
				c = e
				touchLoc = geom.Point{c.Width / 2, c.Height / 2}
			case paint.Event:
				onPaint(c)
				a.EndPaint()
			case touch.Event:
				touchLoc = e.Loc
			}
		}
	})
}

func onStart() {
	var err error
	program, err = glutil.CreateProgram(vertexShader, fragmentShader)
	if err != nil {
		log.Printf("error creating GL program: %v", err)
		return
	}

	buf = gl.CreateBuffer()
	gl.BindBuffer(gl.ARRAY_BUFFER, buf)
	gl.BufferData(gl.ARRAY_BUFFER, rectData, gl.STATIC_DRAW)

	position = gl.GetAttribLocation(program, "position")
	color = gl.GetUniformLocation(program, "color")
	offset = gl.GetUniformLocation(program, "offset")
}

func onStop() {
	gl.DeleteProgram(program)
	gl.DeleteBuffer(buf)
}

func onPaint(c config.Event) {
	gl.ClearColor(1, 1, 1, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)

	gl.UseProgram(program)

	gl.Uniform4f(color, 0.3, 0.3, 0.3, 1) // color
	// position
	x := float32(touchLoc.X / c.Width)
	y := float32(touchLoc.Y / c.Height)
	gl.Uniform2f(offset, x, y)

	gl.BindBuffer(gl.ARRAY_BUFFER, buf)
	gl.EnableVertexAttribArray(position)
	gl.VertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0)
	gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
	gl.DisableVertexAttribArray(position)
}

var rectData = f32.Bytes(binary.LittleEndian,
	0, 0,
	0, 0.2,
	0.2, 0,
	0.2, 0.2,
)

const vertexShader = `#version 100
uniform vec2 offset;

attribute vec4 position;
void main() {
  // offset comes in with x/y values between 0 and 1.
  // position bounds are -1 to 1.
  vec4 offset4 = vec4(2.0*offset.x-1.0, 1.0-2.0*offset.y, 0, 0);
  gl_Position = position + offset4;
}`

const fragmentShader = `#version 100
precision mediump float;
uniform vec4 color;
void main() {
  gl_FragColor = color;
}`
<commit_msg>on touch update blink rate<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
// 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 main contains a Go mobile app that tweaks the
// cmd/blinker server's blink rate.
package main

import (
	"encoding/binary"
	"fmt"
	"log"
	"net/http"

	"golang.org/x/mobile/app"
	"golang.org/x/mobile/event/config"
	"golang.org/x/mobile/event/lifecycle"
	"golang.org/x/mobile/event/paint"
	"golang.org/x/mobile/event/touch"
	"golang.org/x/mobile/exp/f32"
	"golang.org/x/mobile/exp/gl/glutil"
	"golang.org/x/mobile/geom"
	"golang.org/x/mobile/gl"
)

var (
	program  gl.Program
	position gl.Attrib
	offset   gl.Uniform
	color    gl.Uniform
	buf      gl.Buffer

	c        config.Event
	touchLoc geom.Point
)

func main() {
	app.Main(func(a app.App) {
		for e := range a.Events() {
			switch e := app.Filter(e).(type) {
			case lifecycle.Event:
				switch e.Crosses(lifecycle.StageVisible) {
				case lifecycle.CrossOn:
					onStart()
				case lifecycle.CrossOff:
					onStop()
				}
			case config.Event:
				c = e
				touchLoc = geom.Point{c.Width / 2, c.Height / 2}
			case paint.Event:
				onPaint(c)
				a.EndPaint()
			case touch.Event:
				touchLoc = e.Loc
				go updateBlinker()
			}
		}
	})
}

func onStart() {
	var err error
	program, err = glutil.CreateProgram(vertexShader, fragmentShader)
	if err != nil {
		log.Printf("error creating GL program: %v", err)
		return
	}

	buf = gl.CreateBuffer()
	gl.BindBuffer(gl.ARRAY_BUFFER, buf)
	gl.BufferData(gl.ARRAY_BUFFER, rectData, gl.STATIC_DRAW)

	position = gl.GetAttribLocation(program, "position")
	color = gl.GetUniformLocation(program, "color")
	offset = gl.GetUniformLocation(program, "offset")
}

func onStop() {
	gl.DeleteProgram(program)
	gl.DeleteBuffer(buf)
}

func onPaint(c config.Event) {
	gl.ClearColor(1, 1, 1, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)

	gl.UseProgram(program)

	gl.Uniform4f(color, 0.3, 0.3, 0.3, 1) // color
	// position
	x := float32(touchLoc.X / c.Width)
	y := float32(touchLoc.Y / c.Height)
	gl.Uniform2f(offset, x, y)

	gl.BindBuffer(gl.ARRAY_BUFFER, buf)
	gl.EnableVertexAttribArray(position)
	gl.VertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0)
	gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
	gl.DisableVertexAttribArray(position)
}

func updateBlinker() {
	r := float32(touchLoc.Y/c.Height) * 200
	// TODO(jbd): Don't hardcode the server.
	// TODO(jbd): Switch to mdns or another p2p protocol
	_, err := http.Get(fmt.Sprintf("http://10.0.1.9:8080?t=%d", int(r)))
	if err != nil {
		fmt.Println(err)
	}
}

var rectData = f32.Bytes(binary.LittleEndian,
	0, 0,
	0, 0.2,
	0.2, 0,
	0.2, 0.2,
)

const vertexShader = `#version 100
uniform vec2 offset;

attribute vec4 position;
void main() {
  // offset comes in with x/y values between 0 and 1.
  // position bounds are -1 to 1.
  vec4 offset4 = vec4(2.0*offset.x-1.0, 1.0-2.0*offset.y, 0, 0);
  gl_Position = position + offset4;
}`

const fragmentShader = `#version 100
precision mediump float;
uniform vec4 color;
void main() {
  gl_FragColor = color;
}`
<|endoftext|>


<commit_before>package main // import "go.zeta.pm/disguard/cmd/disguard"

import (
	"io/ioutil"
	"log"
	"net/http"

	"github.com/pressly/chi"
	"go.zeta.pm/disguard"
	"gopkg.in/yaml.v2"
)

func main() {
	in, err := ioutil.ReadFile("config.yaml")
	if err != nil {
		log.Fatal(err)
	}
	var conf disguard.Config
	err = yaml.Unmarshal(in, &conf)
	if err != nil {
		log.Fatal(err)
	}

	if conf.AuthRoot == "" {
		conf.AuthRoot = "/oauth"
	}

	sess := disguard.NewSessionRouter(&conf)

	root := chi.NewRouter()
	root.Route(conf.AuthRoot, sess.Route)
	root.Mount("/", sess.ReverseHandler())

	http.ListenAndServe(conf.ListenAddress, root)
}
<commit_msg>Adds a config file flag<commit_after>package main // import "go.zeta.pm/disguard/cmd/disguard"

import (
	"io/ioutil"
	"log"
	"net/http"

	"flag"

	"github.com/pressly/chi"
	"go.zeta.pm/disguard"
	"gopkg.in/yaml.v2"
)

var (
	configPath string
)

func init() {
	flag.StringVar(&configPath, "c", "config.yaml", "The path to the configuration file.")
	flag.Parse()
}

func main() {
	in, err := ioutil.ReadFile(configPath)
	if err != nil {
		log.Fatal(err)
	}
	var conf disguard.Config
	err = yaml.Unmarshal(in, &conf)
	if err != nil {
		log.Fatal(err)
	}

	if conf.AuthRoot == "" {
		conf.AuthRoot = "/oauth"
	}

	sess := disguard.NewSessionRouter(&conf)

	root := chi.NewRouter()
	root.Route(conf.AuthRoot, sess.Route)
	root.Mount("/", sess.ReverseHandler())

	http.ListenAndServe(conf.ListenAddress, root)
}
<|endoftext|>


<commit_before>package cmd

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"strconv"
	"testing"

	"github.com/exercism/cli/config"
	"github.com/exercism/cli/workspace"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
	"github.com/stretchr/testify/assert"
)

func TestDownloadWithoutToken(t *testing.T) {
	cfg := config.Config{
		UserViperConfig: viper.New(),
	}

	err := runDownload(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{})
	if assert.Error(t, err) {
		assert.Regexp(t, "Welcome to Exercism", err.Error())
		// It uses the default base API url to infer the host
		assert.Regexp(t, "exercism.io/my/settings", err.Error())
	}
}

func TestDownloadWithoutWorkspace(t *testing.T) {
	v := viper.New()
	v.Set("token", "abc123")
	cfg := config.Config{
		UserViperConfig: v,
	}

	err := runDownload(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{})
	if assert.Error(t, err) {
		assert.Regexp(t, "re-run the configure", err.Error())
	}
}

func TestDownloadWithoutBaseURL(t *testing.T) {
	v := viper.New()
	v.Set("token", "abc123")
	v.Set("workspace", "/home/whatever")
	cfg := config.Config{
		UserViperConfig: v,
	}

	err := runDownload(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{})
	if assert.Error(t, err) {
		assert.Regexp(t, "re-run the configure", err.Error())
	}
}

func TestDownloadWithoutFlags(t *testing.T) {
	v := viper.New()
	v.Set("token", "abc123")
	v.Set("workspace", "/home/username")
	v.Set("apibaseurl", "http://example.com")

	cfg := config.Config{
		UserViperConfig: v,
	}

	flags := pflag.NewFlagSet("fake", pflag.PanicOnError)
	setupDownloadFlags(flags)

	err := runDownload(cfg, flags, []string{})
	if assert.Error(t, err) {
		assert.Regexp(t, "need an --exercise name or a solution --uuid", err.Error())
	}
}

func TestDownload(t *testing.T) {
	oldOut := Out
	oldErr := Err
	Out = ioutil.Discard
	Err = ioutil.Discard
	defer func() {
		Out = oldOut
		Err = oldErr
	}()

	testCases := []struct {
		requester   bool
		expectedDir string
		flags       map[string]string
	}{
		{
			requester:   true,
			expectedDir: "",
			flags:       map[string]string{"exercise": "bogus-exercise"},
		},
		{
			requester:   true,
			expectedDir: "",
			flags:       map[string]string{"uuid": "bogus-id"},
		},
		{
			requester:   false,
			expectedDir: filepath.Join("users", "alice"),
			flags:       map[string]string{"uuid": "bogus-id"},
		},
		{
			requester:   true,
			expectedDir: filepath.Join("teams", "bogus-team"),
			flags:       map[string]string{"exercise": "bogus-exercise", "track": "bogus-track", "team": "bogus-team"},
		},
	}

	for _, tc := range testCases {
		tmpDir, err := ioutil.TempDir("", "download-cmd")
		defer os.RemoveAll(tmpDir)
		assert.NoError(t, err)

		ts := fakeDownloadServer(strconv.FormatBool(tc.requester), tc.flags["team"])
		defer ts.Close()

		v := viper.New()
		v.Set("workspace", tmpDir)
		v.Set("apibaseurl", ts.URL)
		v.Set("token", "abc123")

		cfg := config.Config{
			UserViperConfig: v,
		}
		flags := pflag.NewFlagSet("fake", pflag.PanicOnError)
		setupDownloadFlags(flags)
		for name, value := range tc.flags {
			flags.Set(name, value)
		}

		err = runDownload(cfg, flags, []string{})
		assert.NoError(t, err)

		targetDir := filepath.Join(tmpDir, tc.expectedDir)
		assertDownloadedCorrectFiles(t, targetDir)

		path := filepath.Join(targetDir, "bogus-track", "bogus-exercise")
		b, err := ioutil.ReadFile(workspace.NewExerciseFromDir(path).MetadataFilepath())
		var s workspace.Solution
		err = json.Unmarshal(b, &s)
		assert.NoError(t, err)

		assert.Equal(t, "bogus-track", s.Track)
		assert.Equal(t, "bogus-exercise", s.Exercise)
		assert.Equal(t, tc.requester, s.IsRequester)
	}
}

func fakeDownloadServer(requestor, teamSlug string) *httptest.Server {
	mux := http.NewServeMux()
	server := httptest.NewServer(mux)

	mux.HandleFunc("/file-1.txt", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "this is file 1")
	})

	mux.HandleFunc("/subdir/file-2.txt", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "this is file 2")
	})

	mux.HandleFunc("/special-char-filename#.txt", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "this is a special file")
	})

	mux.HandleFunc("/with-leading-slash.txt", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "this has a slash")
	})

	mux.HandleFunc("/file-3.txt", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "")
	})

	mux.HandleFunc("/solutions/latest", func(w http.ResponseWriter, r *http.Request) {
		team := "null"
		if teamSlug := r.FormValue("team_id"); teamSlug != "" {
			team = fmt.Sprintf(`{"name": "Bogus Team", "slug": "%s"}`, teamSlug)
		}
		payloadBody := fmt.Sprintf(payloadTemplate, requestor, team, server.URL+"/")
		fmt.Fprint(w, payloadBody)
	})
	mux.HandleFunc("/solutions/bogus-id", func(w http.ResponseWriter, r *http.Request) {
		payloadBody := fmt.Sprintf(payloadTemplate, requestor, "null", server.URL+"/")
		fmt.Fprint(w, payloadBody)
	})

	return server
}

func assertDownloadedCorrectFiles(t *testing.T, targetDir string) {
	expectedFiles := []struct {
		desc     string
		path     string
		contents string
	}{
		{
			desc:     "a file in the exercise root directory",
			path:     filepath.Join(targetDir, "bogus-track", "bogus-exercise", "file-1.txt"),
			contents: "this is file 1",
		},
		{
			desc:     "a file in a subdirectory",
			path:     filepath.Join(targetDir, "bogus-track", "bogus-exercise", "subdir", "file-2.txt"),
			contents: "this is file 2",
		},
		{
			desc:     "a file that requires URL encoding",
			path:     filepath.Join(targetDir, "bogus-track", "bogus-exercise", "special-char-filename#.txt"),
			contents: "this is a special file",
		},
		{
			desc:     "a file that has a leading slash",
			path:     filepath.Join(targetDir, "bogus-track", "bogus-exercise", "with-leading-slash.txt"),
			contents: "this has a slash",
		},
	}

	for _, file := range expectedFiles {
		t.Run(file.desc, func(t *testing.T) {
			b, err := ioutil.ReadFile(file.path)
			assert.NoError(t, err)
			assert.Equal(t, file.contents, string(b))
		})
	}

	path := filepath.Join(targetDir, "bogus-track", "bogus-exercise", "file-3.txt")
	_, err := os.Lstat(path)
	assert.True(t, os.IsNotExist(err), "It should not write the file if empty.")
}

const payloadTemplate = `
{
	"solution": {
		"id": "bogus-id",
		"user": {
			"handle": "alice",
			"is_requester": %s
		},
		"team": %s,
		"exercise": {
			"id": "bogus-exercise",
			"instructions_url": "http://example.com/bogus-exercise",
			"auto_approve": false,
			"track": {
				"id": "bogus-track",
				"language": "Bogus Language"
			}
		},
		"file_download_base_url": "%s",
		"files": [
			"file-1.txt",
			"subdir/file-2.txt",
			"special-char-filename#.txt",
			"/with-leading-slash.txt",
			"file-3.txt"
		],
		"iteration": {
			"submitted_at": "2017-08-21t10:11:12.130z"
		}
	}
}
`
<commit_msg>Refactor improve var name<commit_after>package cmd

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"strconv"
	"testing"

	"github.com/exercism/cli/config"
	"github.com/exercism/cli/workspace"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
	"github.com/stretchr/testify/assert"
)

func TestDownloadWithoutToken(t *testing.T) {
	cfg := config.Config{
		UserViperConfig: viper.New(),
	}

	err := runDownload(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{})
	if assert.Error(t, err) {
		assert.Regexp(t, "Welcome to Exercism", err.Error())
		// It uses the default base API url to infer the host
		assert.Regexp(t, "exercism.io/my/settings", err.Error())
	}
}

func TestDownloadWithoutWorkspace(t *testing.T) {
	v := viper.New()
	v.Set("token", "abc123")
	cfg := config.Config{
		UserViperConfig: v,
	}

	err := runDownload(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{})
	if assert.Error(t, err) {
		assert.Regexp(t, "re-run the configure", err.Error())
	}
}

func TestDownloadWithoutBaseURL(t *testing.T) {
	v := viper.New()
	v.Set("token", "abc123")
	v.Set("workspace", "/home/whatever")
	cfg := config.Config{
		UserViperConfig: v,
	}

	err := runDownload(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{})
	if assert.Error(t, err) {
		assert.Regexp(t, "re-run the configure", err.Error())
	}
}

func TestDownloadWithoutFlags(t *testing.T) {
	v := viper.New()
	v.Set("token", "abc123")
	v.Set("workspace", "/home/username")
	v.Set("apibaseurl", "http://example.com")

	cfg := config.Config{
		UserViperConfig: v,
	}

	flags := pflag.NewFlagSet("fake", pflag.PanicOnError)
	setupDownloadFlags(flags)

	err := runDownload(cfg, flags, []string{})
	if assert.Error(t, err) {
		assert.Regexp(t, "need an --exercise name or a solution --uuid", err.Error())
	}
}

func TestDownload(t *testing.T) {
	oldOut := Out
	oldErr := Err
	Out = ioutil.Discard
	Err = ioutil.Discard
	defer func() {
		Out = oldOut
		Err = oldErr
	}()

	testCases := []struct {
		requester   bool
		expectedDir string
		flags       map[string]string
	}{
		{
			requester:   true,
			expectedDir: "",
			flags:       map[string]string{"exercise": "bogus-exercise"},
		},
		{
			requester:   true,
			expectedDir: "",
			flags:       map[string]string{"uuid": "bogus-id"},
		},
		{
			requester:   false,
			expectedDir: filepath.Join("users", "alice"),
			flags:       map[string]string{"uuid": "bogus-id"},
		},
		{
			requester:   true,
			expectedDir: filepath.Join("teams", "bogus-team"),
			flags:       map[string]string{"exercise": "bogus-exercise", "track": "bogus-track", "team": "bogus-team"},
		},
	}

	for _, tc := range testCases {
		tmpDir, err := ioutil.TempDir("", "download-cmd")
		defer os.RemoveAll(tmpDir)
		assert.NoError(t, err)

		ts := fakeDownloadServer(strconv.FormatBool(tc.requester), tc.flags["team"])
		defer ts.Close()

		v := viper.New()
		v.Set("workspace", tmpDir)
		v.Set("apibaseurl", ts.URL)
		v.Set("token", "abc123")

		cfg := config.Config{
			UserViperConfig: v,
		}
		flags := pflag.NewFlagSet("fake", pflag.PanicOnError)
		setupDownloadFlags(flags)
		for name, value := range tc.flags {
			flags.Set(name, value)
		}

		err = runDownload(cfg, flags, []string{})
		assert.NoError(t, err)

		targetDir := filepath.Join(tmpDir, tc.expectedDir)
		assertDownloadedCorrectFiles(t, targetDir)

		dir := filepath.Join(targetDir, "bogus-track", "bogus-exercise")
		b, err := ioutil.ReadFile(workspace.NewExerciseFromDir(dir).MetadataFilepath())
		var s workspace.Solution
		err = json.Unmarshal(b, &s)
		assert.NoError(t, err)

		assert.Equal(t, "bogus-track", s.Track)
		assert.Equal(t, "bogus-exercise", s.Exercise)
		assert.Equal(t, tc.requester, s.IsRequester)
	}
}

func fakeDownloadServer(requestor, teamSlug string) *httptest.Server {
	mux := http.NewServeMux()
	server := httptest.NewServer(mux)

	mux.HandleFunc("/file-1.txt", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "this is file 1")
	})

	mux.HandleFunc("/subdir/file-2.txt", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "this is file 2")
	})

	mux.HandleFunc("/special-char-filename#.txt", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "this is a special file")
	})

	mux.HandleFunc("/with-leading-slash.txt", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "this has a slash")
	})

	mux.HandleFunc("/file-3.txt", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "")
	})

	mux.HandleFunc("/solutions/latest", func(w http.ResponseWriter, r *http.Request) {
		team := "null"
		if teamSlug := r.FormValue("team_id"); teamSlug != "" {
			team = fmt.Sprintf(`{"name": "Bogus Team", "slug": "%s"}`, teamSlug)
		}
		payloadBody := fmt.Sprintf(payloadTemplate, requestor, team, server.URL+"/")
		fmt.Fprint(w, payloadBody)
	})
	mux.HandleFunc("/solutions/bogus-id", func(w http.ResponseWriter, r *http.Request) {
		payloadBody := fmt.Sprintf(payloadTemplate, requestor, "null", server.URL+"/")
		fmt.Fprint(w, payloadBody)
	})

	return server
}

func assertDownloadedCorrectFiles(t *testing.T, targetDir string) {
	expectedFiles := []struct {
		desc     string
		path     string
		contents string
	}{
		{
			desc:     "a file in the exercise root directory",
			path:     filepath.Join(targetDir, "bogus-track", "bogus-exercise", "file-1.txt"),
			contents: "this is file 1",
		},
		{
			desc:     "a file in a subdirectory",
			path:     filepath.Join(targetDir, "bogus-track", "bogus-exercise", "subdir", "file-2.txt"),
			contents: "this is file 2",
		},
		{
			desc:     "a file that requires URL encoding",
			path:     filepath.Join(targetDir, "bogus-track", "bogus-exercise", "special-char-filename#.txt"),
			contents: "this is a special file",
		},
		{
			desc:     "a file that has a leading slash",
			path:     filepath.Join(targetDir, "bogus-track", "bogus-exercise", "with-leading-slash.txt"),
			contents: "this has a slash",
		},
	}

	for _, file := range expectedFiles {
		t.Run(file.desc, func(t *testing.T) {
			b, err := ioutil.ReadFile(file.path)
			assert.NoError(t, err)
			assert.Equal(t, file.contents, string(b))
		})
	}

	path := filepath.Join(targetDir, "bogus-track", "bogus-exercise", "file-3.txt")
	_, err := os.Lstat(path)
	assert.True(t, os.IsNotExist(err), "It should not write the file if empty.")
}

const payloadTemplate = `
{
	"solution": {
		"id": "bogus-id",
		"user": {
			"handle": "alice",
			"is_requester": %s
		},
		"team": %s,
		"exercise": {
			"id": "bogus-exercise",
			"instructions_url": "http://example.com/bogus-exercise",
			"auto_approve": false,
			"track": {
				"id": "bogus-track",
				"language": "Bogus Language"
			}
		},
		"file_download_base_url": "%s",
		"files": [
			"file-1.txt",
			"subdir/file-2.txt",
			"special-char-filename#.txt",
			"/with-leading-slash.txt",
			"file-3.txt"
		],
		"iteration": {
			"submitted_at": "2017-08-21t10:11:12.130z"
		}
	}
}
`
<|endoftext|>