<commit_before>package main

import (
	"fmt"
	"net"
	"os"
	"bytes"
)

func die(msg string, err os.Error) {
	fmt.Fprintf(os.Stderr, "fatal error : %s%v\n", msg, err)
	os.Exit(1)
}
func error(msg string, err os.Error) {
	fmt.Fprintf(os.Stderr, "error : %s%v\n", msg, err)
}

func readUntilCrLf(con *net.TCPConn) (line []byte, err os.Error) {

	buf := make([]byte, 1)
	var data []byte
	crSeen := false

	for {
		_, err := con.Read(buf)
		if err != nil {
			if err == os.EOF {
				break
			} else {
				return nil, err
			}
		}
		if crSeen {
			if buf[0] == 10 {
				break
			} else {
				crSeen = false
				data = bytes.Add(data, buf)
			}
		} else {
			if buf[0] == 13 {
				crSeen = true
			} else {
				data = bytes.Add(data, buf)
			}
		}
	}

	return data, nil
}

func serve(con *net.TCPConn) {

	defer con.Close()

	line, _ := readUntilCrLf(con)

	fmt.Printf(string(line))
}

func listen() {

	addr, err := net.ResolveTCPAddr("127.0.0.1:5555")
	if err != nil {
		die("failed to resolve TCP address", err)
	}

	listener, err := net.ListenTCP("tcp", addr)
	if err != nil {
		die("failed to listen on TCP address", err)
	}

	for {
		con, err := listener.AcceptTCP()
		if err != nil {
			error("problem with new connection", err)
		} else {
			go serve(con)
		}
	}
}

func main() {
	listen()
}
<commit_msg>con.RemoteAddr()<commit_after>package main

import (
	"fmt"
	"net"
	"os"
	"bytes"
)

func die(msg string, err os.Error) {
	fmt.Fprintf(os.Stderr, "fatal error : %s%v\n", msg, err)
	os.Exit(1)
}
func error(msg string, err os.Error) {
	fmt.Fprintf(os.Stderr, "error : %s%v\n", msg, err)
}

func readUntilCrLf(con *net.TCPConn) (line []byte, err os.Error) {

	buf := make([]byte, 1)
	var data []byte
	crSeen := false

	for {
		_, err := con.Read(buf)
		if err != nil {
			if err == os.EOF {
				break
			} else {
				return nil, err
			}
		}
		if crSeen {
			if buf[0] == 10 {
				break
			} else {
				crSeen = false
				data = bytes.Add(data, buf)
			}
		} else {
			if buf[0] == 13 {
				crSeen = true
			} else {
				data = bytes.Add(data, buf)
			}
		}
	}

	return data, nil
}

func serve(con *net.TCPConn) {

	defer con.Close()

	fmt.Fprintf(os.Stdout, "serving %s\n", con.RemoteAddr().String())

	line, _ := readUntilCrLf(con)

	fmt.Printf(string(line))
}

func listen() {

	addr, err := net.ResolveTCPAddr("127.0.0.1:5555")
	if err != nil {
		die("failed to resolve TCP address", err)
	}

	listener, err := net.ListenTCP("tcp", addr)
	if err != nil {
		die("failed to listen on TCP address", err)
	}

	for {
		con, err := listener.AcceptTCP()
		if err != nil {
			error("problem with new connection", err)
		} else {
			go serve(con)
		}
	}
}

func main() {
	listen()
}
<|endoftext|>


<commit_before>package build

import (
	"errors"
	"fmt"
)

var (
	// ErrSkip is used as a return value when container execution should be
	// skipped at runtime. It is not returned as an error by any function.
	ErrSkip = errors.New("Skip")

	// ErrTerm is used as a return value when the runner should terminate
	// execution and exit. It is not returned as an error by any function.
	ErrTerm = errors.New("Terminate")
)

// An ExitError reports an unsuccessful exit.
type ExitError struct {
	Name string
	Code int
}

// Error reteurns the error message in string format.
func (e *ExitError) Error() string {
	return fmt.Sprintf("%s : exit code %d", e.Name, e.Code)
}

// An OomError reports the process received an OOMKill from the kernel.
type OomError struct {
	Name string
}

// Error reteurns the error message in string format.
func (e *OomError) Error() string {
	return fmt.Sprintf("%s : received oom kill", e.Name)
}
<commit_msg>Fix docs typos<commit_after>package build

import (
	"errors"
	"fmt"
)

var (
	// ErrSkip is used as a return value when container execution should be
	// skipped at runtime. It is not returned as an error by any function.
	ErrSkip = errors.New("Skip")

	// ErrTerm is used as a return value when the runner should terminate
	// execution and exit. It is not returned as an error by any function.
	ErrTerm = errors.New("Terminate")
)

// An ExitError reports an unsuccessful exit.
type ExitError struct {
	Name string
	Code int
}

// Error returns the error message in string format.
func (e *ExitError) Error() string {
	return fmt.Sprintf("%s : exit code %d", e.Name, e.Code)
}

// An OomError reports the process received an OOMKill from the kernel.
type OomError struct {
	Name string
}

// Error returns the error message in string format.
func (e *OomError) Error() string {
	return fmt.Sprintf("%s : received oom kill", e.Name)
}
<|endoftext|>


<commit_before>package main

import (
	"container/list"
	"encoding/json"
	"entity"
	"fmt"
	"io/ioutil"
	"os/exec"
	"runtime"
	"time"
	"util"
)

const (
	BROWSER_PATH = "/usr/local/firefox/firefox"
	FMT          = "%s-%d"
)

var (
	LAST_MODIFIED time.Time
	IS_WORKER     bool
	CURRENT_TASK  map[string]*entity.User = map[string]*entity.User{}
	RANGE_TIME    int64                   = 600
	QUEUE                                 = list.New()
)

func Load(url string) *entity.Task {
	response, err_con := util.GetUrlInUserAgent(url)
	task := &entity.Task{}
	if err_con != nil {
		util.ERROR("connect ERROR, %s", err_con)
		util.Connect()
	} else {
		defer response.Body.Close()
		body, _ := ioutil.ReadAll(response.Body)
		json.Unmarshal(body, &task)
		task.Size = len(task.Users)
		las_modify, err_parse := time.Parse(time.RFC1123, response.Header.Get("Last-Modified"))
		if err_parse != nil {
			util.ERROR("Parse time is ERROR: %s", err_parse)
		} else {
			if las_modify.After(LAST_MODIFIED) {
				if LAST_MODIFIED.IsZero() {
					util.INFO("Last-Modified is NULL, program is first run, Last-Modifyed: %s", las_modify)
				} else {
					util.INFO("file is change, Last-Modifyed: %s", las_modify)
				}
				LAST_MODIFIED = las_modify
				if task.Start {
					IS_WORKER = true
					util.INFO("start worker!")
				} else {
					IS_WORKER = false
					util.INFO("worker is not start!")
				}
			}
		}
	}
	return task
}

func Jobs(task *entity.Task) {
	for _, user := range task.Users {
		user.Date = time.Unix(user.Trigger, user.Trigger)
		if user.Start && time.Now().Unix()-user.Trigger < RANGE_TIME {
			if value, ok := CURRENT_TASK[fmt.Sprintf(FMT, user.UserName, user.Trigger)]; ok {
				util.INFO("task is exits, username: %s, trigger: %d", value.UserName, value.Trigger)
			} else {
				CURRENT_TASK[fmt.Sprintf(FMT, user.UserName, user.Trigger)] = user
				go Task(user)
			}
		}
	}
	for _, cancel := range task.Cancel {
		if _, ok := CURRENT_TASK[cancel]; ok {
			delete(CURRENT_TASK, cancel)
		}
	}
	util.INFO("shutdown worker!")
	IS_WORKER = false
}

func Task(user *entity.User) {
	runtime.Gosched()
	util.DEBUG("add job username: %s", user.UserName)
	for {
		if _, ok := CURRENT_TASK[fmt.Sprintf(FMT, user.UserName, user.Trigger)]; ok {
			util.DEBUG("loop task username: %s, trigger: %d, current: %d", user.UserName, user.Trigger, time.Now().Unix())
			if time.Now().After(user.Date) && time.Now().Unix()-user.Trigger < RANGE_TIME {
				util.DEBUG("jobs username: %s, password: %s, start: %t, trigger: %d, date: %s",
					user.UserName, user.PassWord, user.Start, user.Trigger, user.Date)
				QUEUE.PushBack(user)
				break
			} else {
				time.Sleep(time.Duration(10) * time.Second)
			}
		} else {
			break
		}
	}
}

func OpenBrowser(filename string) {
	runtime.Gosched()
	cmd := exec.Command(BROWSER_PATH, filename)
	err_run := cmd.Run()
	if err_run != nil {
		util.ERROR("start browser file [%s] ERROR: %s", filename, err_run)
	}
}

func start() {
	runtime.Gosched()
	util.INFO("start ....")
	var user *entity.User
	for {
		if QUEUE.Len() > 0 {
			task := QUEUE.Back()
			user = task.Value.(*entity.User)
			if _, ok := CURRENT_TASK[fmt.Sprintf(FMT, user.UserName, user.Trigger)]; ok {
				filename := fmt.Sprintf("%s", util.HtmlFile(user))
				util.INFO("open browser file: %s", filename)
				go OpenBrowser(filename)
			} else {
				util.ERROR("task is removed, username: %s, trigger: %d", user.UserName, user.Trigger)
			}
			QUEUE.Remove(task)
			delete(CURRENT_TASK, fmt.Sprintf(FMT, user.UserName, user.Trigger))
		} else {
			time.Sleep(time.Duration(10) * time.Second)
		}
		time.Sleep(time.Duration(5) * time.Second)
	}
}

func heartbeat() {
	runtime.Gosched()
	for {
		keys := []string{}
		for key, _ := range CURRENT_TASK {
			keys = append(keys, key)
		}
		util.DEBUG("hearbeat %s", keys)
		time.Sleep(time.Duration(5) * time.Second)
	}
}

func main() {
	runtime.GOMAXPROCS(8)
	go start()
	go heartbeat()
	for {
		task := Load("http://task.open-ns.org/task.json")
		if IS_WORKER {
			util.DEBUG("load user [%d] size", task.Size)
			util.INFO("worker is true, go jobs")
			Jobs(task)
		}
		util.DEBUG("task size: %d, queue size: %d", len(CURRENT_TASK), QUEUE.Len())
		time.Sleep(time.Duration(3) * time.Second)
	}
}
<commit_msg>heartbeat to http json<commit_after>package main

import (
	"container/list"
	"encoding/json"
	"entity"
	"fmt"
	"io/ioutil"
	"os/exec"
	"runtime"
	"time"
	"util"
)

const (
	BROWSER_PATH = "/usr/local/firefox/firefox"
	FMT          = "%s-%d"
)

var (
	LAST_MODIFIED time.Time
	IS_WORKER     bool
	CURRENT_TASK  map[string]*entity.User = map[string]*entity.User{}
	RANGE_TIME    int64                   = 600
	QUEUE                                 = list.New()
)

func Load(url string) *entity.Task {
	response, err_con := util.GetUrlInUserAgent(url)
	task := &entity.Task{}
	if err_con != nil {
		util.ERROR("connect ERROR, %s", err_con)
		util.Connect()
	} else {
		defer response.Body.Close()
		body, _ := ioutil.ReadAll(response.Body)
		json.Unmarshal(body, &task)
		task.Size = len(task.Users)
		las_modify, err_parse := time.Parse(time.RFC1123, response.Header.Get("Last-Modified"))
		if err_parse != nil {
			util.ERROR("Parse time is ERROR: %s", err_parse)
		} else {
			if las_modify.After(LAST_MODIFIED) {
				if LAST_MODIFIED.IsZero() {
					util.INFO("Last-Modified is NULL, program is first run, Last-Modifyed: %s", las_modify)
				} else {
					util.INFO("file is change, Last-Modifyed: %s", las_modify)
				}
				LAST_MODIFIED = las_modify
				if task.Start {
					IS_WORKER = true
					util.INFO("start worker!")
				} else {
					IS_WORKER = false
					util.INFO("worker is not start!")
				}
			}
		}
	}
	return task
}

func Jobs(task *entity.Task) {
	for _, user := range task.Users {
		user.Date = time.Unix(user.Trigger, user.Trigger)
		if user.Start && time.Now().Unix()-user.Trigger < RANGE_TIME {
			if value, ok := CURRENT_TASK[fmt.Sprintf(FMT, user.UserName, user.Trigger)]; ok {
				util.INFO("task is exits, username: %s, trigger: %d", value.UserName, value.Trigger)
			} else {
				CURRENT_TASK[fmt.Sprintf(FMT, user.UserName, user.Trigger)] = user
				go Task(user)
			}
		}
	}
	for _, cancel := range task.Cancel {
		if _, ok := CURRENT_TASK[cancel]; ok {
			delete(CURRENT_TASK, cancel)
		}
	}
	util.INFO("shutdown worker!")
	IS_WORKER = false
}

func Task(user *entity.User) {
	runtime.Gosched()
	util.DEBUG("add job username: %s", user.UserName)
	for {
		if _, ok := CURRENT_TASK[fmt.Sprintf(FMT, user.UserName, user.Trigger)]; ok {
			util.DEBUG("loop task username: %s, trigger: %d, current: %d", user.UserName, user.Trigger, time.Now().Unix())
			if time.Now().After(user.Date) && time.Now().Unix()-user.Trigger < RANGE_TIME {
				util.DEBUG("jobs username: %s, password: %s, start: %t, trigger: %d, date: %s",
					user.UserName, user.PassWord, user.Start, user.Trigger, user.Date)
				QUEUE.PushBack(user)
				break
			} else {
				time.Sleep(time.Duration(10) * time.Second)
			}
		} else {
			break
		}
	}
}

func OpenBrowser(filename string) {
	runtime.Gosched()
	cmd := exec.Command(BROWSER_PATH, filename)
	err_run := cmd.Run()
	if err_run != nil {
		util.ERROR("start browser file [%s] ERROR: %s", filename, err_run)
	}
}

func start() {
	runtime.Gosched()
	util.INFO("start ....")
	var user *entity.User
	for {
		if QUEUE.Len() > 0 {
			task := QUEUE.Back()
			user = task.Value.(*entity.User)
			if _, ok := CURRENT_TASK[fmt.Sprintf(FMT, user.UserName, user.Trigger)]; ok {
				filename := fmt.Sprintf("%s", util.HtmlFile(user))
				util.INFO("open browser file: %s", filename)
				go OpenBrowser(filename)
			} else {
				util.ERROR("task is removed, username: %s, trigger: %d", user.UserName, user.Trigger)
			}
			QUEUE.Remove(task)
			delete(CURRENT_TASK, fmt.Sprintf(FMT, user.UserName, user.Trigger))
		} else {
			time.Sleep(time.Duration(10) * time.Second)
		}
		time.Sleep(time.Duration(5) * time.Second)
	}
}

func heartbeat() {
	runtime.Gosched()
	for {
		keys := []string{}
		for key, _ := range CURRENT_TASK {
			keys = append(keys, key)
		}
		data, _ := json.Marshal(keys)
		response, err := util.Client().Get(fmt.Sprintf("http://task.open-ns.org/hearbeat.json?%s", string(data)))
		if err != nil {
		} else {
			defer response.Body.Close()
		}
		time.Sleep(time.Duration(5) * time.Second)
	}
}

func main() {
	runtime.GOMAXPROCS(8)
	go start()
	go heartbeat()
	for {
		task := Load("http://task.open-ns.org/task.json")
		if IS_WORKER {
			util.DEBUG("load user [%d] size", task.Size)
			util.INFO("worker is true, go jobs")
			Jobs(task)
		}
		util.DEBUG("task size: %d, queue size: %d", len(CURRENT_TASK), QUEUE.Len())
		time.Sleep(time.Duration(3) * time.Second)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"strings"
)

func main() {
	flagSet := flag.NewFlagSet("sel", flag.ExitOnError)

	splitExpr := flagSet.String("split", "\\s+", "Regex to split fields")
	joinExpr := flagSet.String("join", " ", "String to join selected fields")
	help := flagSet.Bool("help", false, "Show help")

	// Before we call `flagSet.Parse`, we need to separate selectors from flags ourselves. This is because negative
	// selectors (such as "-1") look like invalid flags to the implementation, and there's no option to avoid that:
	flags, selectorExprs := classifyArgs(os.Args[1:])
	flagSet.Parse(flags)

	if *help {
		flagSet.PrintDefaults()
		os.Exit(0)
	}

	splitter, err := ParseSplitter(*splitExpr)
	check(err, "Invalid regex to split fields: %s", *splitExpr)

	joiner, err := ParseJoiner(*joinExpr)
	check(err, "Invalid string to join fields: %s", *joinExpr)

	var selectors []*Selector

	for _, selectorExpr := range selectorExprs {
		selector, err := ParseSelector(selectorExpr)
		check(err, "Invalid selector: '%s'", selectorExpr)

		selectors = append(selectors, selector)
	}

	doTheThing(splitter, joiner, selectors)
}

// classifyArgs separates flags and positional arguments, because negative selectors (eg "-1") look like invalid flags
func classifyArgs(args []string) ([]string, []string) {
	var flags []string
	var selectorExprs []string

	for _, arg := range args {
		// If this argument is obviously not a flag, just add it to the selector expression list:
		if !strings.HasPrefix(arg, "-") {
			selectorExprs = append(selectorExprs, arg)
			continue
		}

		// Now this could be a flag or a negative selector. Try to parse it, see what happens:
		_, err := ParseSelector(arg)

		if err != nil {
			flags = append(flags, arg)
		} else {
			selectorExprs = append(selectorExprs, arg)
		}

		// NOTE:
		// For the negative selector vs flag case, we're running `ParseSelector` twice (will also happe in `main`). Not
		// ideal, but not a problem that merits additional complexity. I blame the `flags` module for forcing me into this
		// position. Yeah, that's it. Not my fault.
	}

	return flags, selectorExprs
}

func doTheThing(splitter *Splitter, joiner *Joiner, selectors []*Selector) {
	scanner := bufio.NewScanner(os.Stdin)

	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		fields := splitter.Split(line)

		var selectedFields []string

		for _, selector := range selectors {
			selectedFields = append(selectedFields, selector.Select(fields)...)
		}

		fmt.Println(joiner.Join(selectedFields))
	}
}

func check(err error, message string, params ...interface{}) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %s\n", fmt.Sprintf(message, params...))
		os.Exit(1)
	}
}
<commit_msg>Fix typo in comment<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"strings"
)

func main() {
	flagSet := flag.NewFlagSet("sel", flag.ExitOnError)

	splitExpr := flagSet.String("split", "\\s+", "Regex to split fields")
	joinExpr := flagSet.String("join", " ", "String to join selected fields")
	help := flagSet.Bool("help", false, "Show help")

	// Before we call `flagSet.Parse`, we need to separate selectors from flags ourselves. This is because negative
	// selectors (such as "-1") look like invalid flags to the implementation, and there's no option to avoid that:
	flags, selectorExprs := classifyArgs(os.Args[1:])
	flagSet.Parse(flags)

	if *help {
		flagSet.PrintDefaults()
		os.Exit(0)
	}

	splitter, err := ParseSplitter(*splitExpr)
	check(err, "Invalid regex to split fields: %s", *splitExpr)

	joiner, err := ParseJoiner(*joinExpr)
	check(err, "Invalid string to join fields: %s", *joinExpr)

	var selectors []*Selector

	for _, selectorExpr := range selectorExprs {
		selector, err := ParseSelector(selectorExpr)
		check(err, "Invalid selector: '%s'", selectorExpr)

		selectors = append(selectors, selector)
	}

	doTheThing(splitter, joiner, selectors)
}

// classifyArgs separates flags and positional arguments, because negative selectors (eg "-1") look like invalid flags
func classifyArgs(args []string) ([]string, []string) {
	var flags []string
	var selectorExprs []string

	for _, arg := range args {
		// If this argument is obviously not a flag, just add it to the selector expression list:
		if !strings.HasPrefix(arg, "-") {
			selectorExprs = append(selectorExprs, arg)
			continue
		}

		// Now this could be a flag or a negative selector. Try to parse it, see what happens:
		_, err := ParseSelector(arg)

		if err != nil {
			flags = append(flags, arg)
		} else {
			selectorExprs = append(selectorExprs, arg)
		}

		// NOTE:
		// For the negative selector vs flag case, we're running `ParseSelector` twice (will also happen in `main`). Not
		// ideal, but not a problem that merits additional complexity. I blame the `flags` module for forcing me into this
		// position. Yeah, that's it. Not my fault.
	}

	return flags, selectorExprs
}

func doTheThing(splitter *Splitter, joiner *Joiner, selectors []*Selector) {
	scanner := bufio.NewScanner(os.Stdin)

	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		fields := splitter.Split(line)

		var selectedFields []string

		for _, selector := range selectors {
			selectedFields = append(selectedFields, selector.Select(fields)...)
		}

		fmt.Println(joiner.Join(selectedFields))
	}
}

func check(err error, message string, params ...interface{}) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %s\n", fmt.Sprintf(message, params...))
		os.Exit(1)
	}
}
<|endoftext|>


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

package main

import (
	"bytes"
	"encoding/xml"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"

	"code.google.com/p/go.tools/go/vcs"
)

// Repo represents a mercurial repository.
type Repo struct {
	Path   string
	Master *vcs.RepoRoot
	sync.Mutex
}

// RemoteRepo constructs a *Repo representing a remote repository.
func RemoteRepo(url, path string) (*Repo, error) {
	rr, err := vcs.RepoRootForImportPath(url, *verbose)
	if err != nil {
		return nil, err
	}
	return &Repo{
		Path:   path,
		Master: rr,
	}, nil
}

// Clone clones the current Repo to a new destination
// returning a new *Repo if successful.
func (r *Repo) Clone(path, rev string) (*Repo, error) {
	r.Lock()
	defer r.Unlock()

	err := timeout(*cmdTimeout, func() error {
		downloadPath := r.Path
		if !r.Exists() {
			downloadPath = r.Master.Repo
		}

		err := r.Master.VCS.CreateAtRev(path, downloadPath, rev)
		if err != nil {
			return err
		}
		return r.Master.VCS.TagSync(path, "")
	})
	if err != nil {
		return nil, err
	}
	return &Repo{
		Path:   path,
		Master: r.Master,
	}, nil
}

// Export exports the current Repo at revision rev to a new destination.
func (r *Repo) Export(path, rev string) error {
	r.Lock()
	defer r.Unlock()

	downloadPath := r.Path
	if !r.Exists() {
		_, err := r.Clone(path, rev)
		return err
	}

	cmd := exec.Command(r.Master.VCS.Cmd, "archive", "-t", "files", "-r", rev, path)
	cmd.Dir = downloadPath
	if err := run(cmd); err != nil {
		return fmt.Errorf("executing %v: %v", cmd.Args, err)
	}
	return nil
}

// UpdateTo updates the working copy of this Repo to the
// supplied revision.
func (r *Repo) UpdateTo(hash string) error {
	r.Lock()
	defer r.Unlock()

	return timeout(*cmdTimeout, func() error {
		return r.Master.VCS.TagSync(r.Path, hash)
	})
}

// Exists reports whether this Repo represents a valid Mecurial repository.
func (r *Repo) Exists() bool {
	fi, err := os.Stat(filepath.Join(r.Path, "."+r.Master.VCS.Cmd))
	if err != nil {
		return false
	}
	return fi.IsDir()
}

// Pull pulls changes from the default path, that is, the path
// this Repo was cloned from.
func (r *Repo) Pull() error {
	r.Lock()
	defer r.Unlock()

	return timeout(*cmdTimeout, func() error {
		return r.Master.VCS.Download(r.Path)
	})
}

// Log returns the changelog for this repository.
func (r *Repo) Log() ([]HgLog, error) {
	if err := r.Pull(); err != nil {
		return nil, err
	}
	r.Lock()
	defer r.Unlock()

	var logStruct struct {
		Log []HgLog
	}
	err := timeout(*cmdTimeout, func() error {
		data, err := r.Master.VCS.Log(r.Path, xmlLogTemplate)
		if err != nil {
			return err
		}

		// We have a commit with description that contains 0x1b byte.
		// Mercurial does not escape it, but xml.Unmarshal does not accept it.
		data = bytes.Replace(data, []byte{0x1b}, []byte{'?'}, -1)

		err = xml.Unmarshal([]byte("<Top>"+string(data)+"</Top>"), &logStruct)
		if err != nil {
			return fmt.Errorf("unmarshal %s log: %v", r.Master.VCS, err)
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	for i, log := range logStruct.Log {
		// Let's pretend there can be only one parent.
		if log.Parent != "" && strings.Contains(log.Parent, " ") {
			logStruct.Log[i].Parent = strings.Split(log.Parent, " ")[0]
		}
	}
	return logStruct.Log, nil
}

// FullHash returns the full hash for the given Mercurial revision.
func (r *Repo) FullHash(rev string) (string, error) {
	r.Lock()
	defer r.Unlock()

	var hash string
	err := timeout(*cmdTimeout, func() error {
		data, err := r.Master.VCS.LogAtRev(r.Path, rev, "{node}")
		if err != nil {
			return err
		}

		s := strings.TrimSpace(string(data))
		if s == "" {
			return fmt.Errorf("cannot find revision")
		}
		if len(s) != 40 {
			return fmt.Errorf("%s returned invalid hash: %s", r.Master.VCS, s)
		}
		hash = s
		return nil
	})
	if err != nil {
		return "", err
	}
	return hash, nil
}

// HgLog represents a single Mercurial revision.
type HgLog struct {
	Hash   string
	Author string
	Date   string
	Desc   string
	Parent string
	Branch string
	Files  string

	// Internal metadata
	added bool
	bench bool // needs to be benchmarked?
}

// xmlLogTemplate is a template to pass to Mercurial to make
// hg log print the log in valid XML for parsing with xml.Unmarshal.
// Can not escape branches and files, because it crashes python with:
// AttributeError: 'NoneType' object has no attribute 'replace'
const xmlLogTemplate = `
        <Log>
        <Hash>{node|escape}</Hash>
        <Parent>{parents}</Parent>
        <Author>{author|escape}</Author>
        <Date>{date|rfc3339date}</Date>
        <Desc>{desc|escape}</Desc>
        <Branch>{branches}</Branch>
        <Files>{files}</Files>
        </Log>
`
<commit_msg>dashboard: use correct hg template for parents<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"encoding/xml"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"

	"code.google.com/p/go.tools/go/vcs"
)

// Repo represents a mercurial repository.
type Repo struct {
	Path   string
	Master *vcs.RepoRoot
	sync.Mutex
}

// RemoteRepo constructs a *Repo representing a remote repository.
func RemoteRepo(url, path string) (*Repo, error) {
	rr, err := vcs.RepoRootForImportPath(url, *verbose)
	if err != nil {
		return nil, err
	}
	return &Repo{
		Path:   path,
		Master: rr,
	}, nil
}

// Clone clones the current Repo to a new destination
// returning a new *Repo if successful.
func (r *Repo) Clone(path, rev string) (*Repo, error) {
	r.Lock()
	defer r.Unlock()

	err := timeout(*cmdTimeout, func() error {
		downloadPath := r.Path
		if !r.Exists() {
			downloadPath = r.Master.Repo
		}

		err := r.Master.VCS.CreateAtRev(path, downloadPath, rev)
		if err != nil {
			return err
		}
		return r.Master.VCS.TagSync(path, "")
	})
	if err != nil {
		return nil, err
	}
	return &Repo{
		Path:   path,
		Master: r.Master,
	}, nil
}

// Export exports the current Repo at revision rev to a new destination.
func (r *Repo) Export(path, rev string) error {
	r.Lock()
	defer r.Unlock()

	downloadPath := r.Path
	if !r.Exists() {
		_, err := r.Clone(path, rev)
		return err
	}

	cmd := exec.Command(r.Master.VCS.Cmd, "archive", "-t", "files", "-r", rev, path)
	cmd.Dir = downloadPath
	if err := run(cmd); err != nil {
		return fmt.Errorf("executing %v: %v", cmd.Args, err)
	}
	return nil
}

// UpdateTo updates the working copy of this Repo to the
// supplied revision.
func (r *Repo) UpdateTo(hash string) error {
	r.Lock()
	defer r.Unlock()

	return timeout(*cmdTimeout, func() error {
		return r.Master.VCS.TagSync(r.Path, hash)
	})
}

// Exists reports whether this Repo represents a valid Mecurial repository.
func (r *Repo) Exists() bool {
	fi, err := os.Stat(filepath.Join(r.Path, "."+r.Master.VCS.Cmd))
	if err != nil {
		return false
	}
	return fi.IsDir()
}

// Pull pulls changes from the default path, that is, the path
// this Repo was cloned from.
func (r *Repo) Pull() error {
	r.Lock()
	defer r.Unlock()

	return timeout(*cmdTimeout, func() error {
		return r.Master.VCS.Download(r.Path)
	})
}

// Log returns the changelog for this repository.
func (r *Repo) Log() ([]HgLog, error) {
	if err := r.Pull(); err != nil {
		return nil, err
	}
	r.Lock()
	defer r.Unlock()

	var logStruct struct {
		Log []HgLog
	}
	err := timeout(*cmdTimeout, func() error {
		data, err := r.Master.VCS.Log(r.Path, xmlLogTemplate)
		if err != nil {
			return err
		}

		// We have a commit with description that contains 0x1b byte.
		// Mercurial does not escape it, but xml.Unmarshal does not accept it.
		data = bytes.Replace(data, []byte{0x1b}, []byte{'?'}, -1)

		err = xml.Unmarshal([]byte("<Top>"+string(data)+"</Top>"), &logStruct)
		if err != nil {
			return fmt.Errorf("unmarshal %s log: %v", r.Master.VCS, err)
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	for i, log := range logStruct.Log {
		// Let's pretend there can be only one parent.
		if log.Parent != "" && strings.Contains(log.Parent, " ") {
			logStruct.Log[i].Parent = strings.Split(log.Parent, " ")[0]
		}
	}
	return logStruct.Log, nil
}

// FullHash returns the full hash for the given Mercurial revision.
func (r *Repo) FullHash(rev string) (string, error) {
	r.Lock()
	defer r.Unlock()

	var hash string
	err := timeout(*cmdTimeout, func() error {
		data, err := r.Master.VCS.LogAtRev(r.Path, rev, "{node}")
		if err != nil {
			return err
		}

		s := strings.TrimSpace(string(data))
		if s == "" {
			return fmt.Errorf("cannot find revision")
		}
		if len(s) != 40 {
			return fmt.Errorf("%s returned invalid hash: %s", r.Master.VCS, s)
		}
		hash = s
		return nil
	})
	if err != nil {
		return "", err
	}
	return hash, nil
}

// HgLog represents a single Mercurial revision.
type HgLog struct {
	Hash   string
	Author string
	Date   string
	Desc   string
	Parent string
	Branch string
	Files  string

	// Internal metadata
	added bool
	bench bool // needs to be benchmarked?
}

// xmlLogTemplate is a template to pass to Mercurial to make
// hg log print the log in valid XML for parsing with xml.Unmarshal.
// Can not escape branches and files, because it crashes python with:
// AttributeError: 'NoneType' object has no attribute 'replace'
const xmlLogTemplate = `
        <Log>
        <Hash>{node|escape}</Hash>
        <Parent>{p1node}</Parent>
        <Author>{author|escape}</Author>
        <Date>{date|rfc3339date}</Date>
        <Desc>{desc|escape}</Desc>
        <Branch>{branches}</Branch>
        <Files>{files}</Files>
        </Log>
`
<|endoftext|>


<commit_before>package siesta

import "time"

type RecordAccumulatorConfig struct {
	batchSize         int
	totalMemorySize   int
	compressionType   string
	linger            time.Duration
	retryBackoff      time.Duration
	blockOnBufferFull bool
	metrics           map[string]Metric
	time              time.Time
	metricTags        map[string]string
	networkClient     *NetworkClient
}

type RecordAccumulator struct {
	config        *RecordAccumulatorConfig
	networkClient *NetworkClient
	batchSize     int
	batches       map[string]map[int32][]*ProducerRecord

	addChan chan *ProducerRecord
	flushed map[string]map[int32]chan bool
}

func NewRecordAccumulator(config *RecordAccumulatorConfig) *RecordAccumulator {
	accumulator := &RecordAccumulator{}
	accumulator.config = config
	accumulator.batchSize = config.batchSize
	accumulator.addChan = make(chan *ProducerRecord, 100)
	accumulator.batches = make(map[string]map[int32][]*ProducerRecord)
	accumulator.flushed = make(map[string]map[int32]chan bool)
	accumulator.networkClient = config.networkClient

	go accumulator.sender()

	return accumulator
}

func (ra *RecordAccumulator) sender() {
	for record := range ra.addChan {
		if ra.batches[record.Topic] == nil {
			ra.batches[record.Topic] = make(map[int32][]*ProducerRecord)
		}
		if ra.batches[record.Topic][record.partition] == nil {
			ra.createBatch(record.Topic, record.partition)
		}

		partitionBatch := ra.batches[record.Topic][record.partition]
		partitionBatch = append(partitionBatch, record)

		if len(partitionBatch) == 1 {
			go ra.watcher(record.Topic, record.partition)
		}

		ra.batches[record.Topic][record.partition] = partitionBatch
		if len(partitionBatch) == ra.batchSize {
			go ra.flushAndNotify(record.Topic, record.partition)
		}
	}
}

func (ra *RecordAccumulator) createBatch(topic string, partition int32) {
	ra.batches[topic][partition] = make([]*ProducerRecord, 0, ra.batchSize)
}

func (ra *RecordAccumulator) watcher(topic string, partition int32) {
	select {
	case <-ra.flushed[topic][partition]:
	case <-time.After(ra.config.linger):
		ra.flush(topic, partition)
	}
}

func (ra *RecordAccumulator) flushAndNotify(topic string, partition int32) {
	ra.flush(topic, partition)
	ra.flushed[topic][partition] <- true
}

func (ra *RecordAccumulator) flush(topic string, partition int32) {
	ra.networkClient.send(topic, partition, ra.batches[topic][partition])
	ra.createBatch(topic, partition)
}

func (ra *RecordAccumulator) close() {
	close(ra.addChan)
	ra.networkClient.close()
}
<commit_msg>Fix race condition.<commit_after>package siesta

import "time"

type RecordAccumulatorConfig struct {
	batchSize         int
	totalMemorySize   int
	compressionType   string
	linger            time.Duration
	retryBackoff      time.Duration
	blockOnBufferFull bool
	metrics           map[string]Metric
	time              time.Time
	metricTags        map[string]string
	networkClient     *NetworkClient
}

type RecordAccumulator struct {
	config        *RecordAccumulatorConfig
	networkClient *NetworkClient
	batchSize     int
	batches       map[string]map[int32][]*ProducerRecord

	addChan chan *ProducerRecord
	flushed map[string]map[int32]chan bool
}

func NewRecordAccumulator(config *RecordAccumulatorConfig) *RecordAccumulator {
	accumulator := &RecordAccumulator{}
	accumulator.config = config
	accumulator.batchSize = config.batchSize
	accumulator.addChan = make(chan *ProducerRecord, 100)
	accumulator.batches = make(map[string]map[int32][]*ProducerRecord)
	accumulator.flushed = make(map[string]map[int32]chan bool)
	accumulator.networkClient = config.networkClient

	go accumulator.sender()

	return accumulator
}

func (ra *RecordAccumulator) sender() {
	for record := range ra.addChan {
		if ra.batches[record.Topic] == nil {
			ra.batches[record.Topic] = make(map[int32][]*ProducerRecord)
		}
		if ra.batches[record.Topic][record.partition] == nil {
			ra.createBatch(record.Topic, record.partition)
		}

		partitionBatch := ra.batches[record.Topic][record.partition]
		partitionBatch = append(partitionBatch, record)

		if len(partitionBatch) == 1 {
			go ra.watcher(record.Topic, record.partition)
		}

		ra.batches[record.Topic][record.partition] = partitionBatch
		if len(partitionBatch) == ra.batchSize {
			go ra.toFlush(record.Topic, record.partition)
		}
	}
}

func (ra *RecordAccumulator) createBatch(topic string, partition int32) {
	ra.batches[topic][partition] = make([]*ProducerRecord, 0, ra.batchSize)
}

func (ra *RecordAccumulator) watcher(topic string, partition int32) {
	select {
	case <-ra.flushed[topic][partition]:
		ra.flush(topic, partition)
	case <-time.After(ra.config.linger):
		ra.flush(topic, partition)
	}
}

func (ra *RecordAccumulator) toFlush(topic string, partition int32) {
	ra.flushed[topic][partition] <- true
}

func (ra *RecordAccumulator) flush(topic string, partition int32) {
	ra.networkClient.send(topic, partition, ra.batches[topic][partition])
	ra.createBatch(topic, partition)
}

func (ra *RecordAccumulator) close() {
	close(ra.addChan)
	ra.networkClient.close()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/BytemarkHosting/row"
	"github.com/olekukonko/tablewriter"
	"github.com/urfave/cli"
	"reflect"
	"strings"
)

// OutputJSON is an OutputFn which outputs a nicely-indented JSON object that represents obj
func (c *Context) OutputJSON(obj interface{}) error {
	js, err := json.MarshalIndent(obj, "", "    ")
	if err != nil {
		return err
	}
	fmt.Fprintf(global.App.Writer, string(js))
	return nil
}

func trimAllSpace(strs []string) {
	for i, s := range strs {
		strs[i] = strings.TrimSpace(s)
	}
}

func (c *Context) determineTableFields(obj interface{}) []string {
	chosenFields := strings.Split(c.String("table-fields"), ",")
	trimAllSpace(chosenFields)

	fieldsList := row.FieldsFrom(obj)
	if len(chosenFields) > 0 && chosenFields[0] == "help" {
		fmt.Fprintf(global.App.Writer, "Table fields available for this command: \r\n  %s\r\n\r\n", strings.Join(fieldsList, "\r\n  "))
		return nil
	} else if len(chosenFields) > 0 && chosenFields[0] != "" {
		return chosenFields
	} else {
		return fieldsList
	}
}

// OutputTable is an OutputFn which outputs the object in table form, using github.com/BytemarkHosting/row and github.com/olekukonko/tablewriter
func (c *Context) OutputTable(obj interface{}) error {
	fields := c.determineTableFields(obj)
	return RenderTable(obj, fields)
}

// RenderTable creates a table for the given object. This makes
// most sense when it's an array, but a regular struct-y object works fine too.
func RenderTable(obj interface{}, fields []string) error {
	table := tablewriter.NewWriter(global.App.Writer)
	// don't autowrap because fields that are slices output one element per line
	// and autowrap
	table.SetAutoWrapText(false)
	// lines between rows!
	table.SetRowLine(true)
	// don't autoformat the headers - autoformat makes them ALLCAPS which makes
	// it hard to figure out what to set --table-fields to.
	// with autoformat off, --table-fields can be set by copying and pasting
	// from the table header.
	table.SetAutoFormatHeaders(false)

	table.SetHeader(fields)
	v := reflect.ValueOf(obj)

	// indirect pointers so we can switch on Kind()
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	// output a single table row for a struct, or several for a slice / array
	switch v.Kind() {
	case reflect.Struct:
		r, err := row.From(obj, fields)
		if err != nil {
			return err
		}
		table.Append(r)
	case reflect.Slice, reflect.Array:
		length := v.Len()
		for i := 0; i < length; i++ {
			el := v.Index(i)
			r, err := row.From(el.Interface(), fields)
			if err != nil {
				return err
			}
			table.Append(r)
		}
	default:
		return fmt.Errorf("%T is not a struct or slice type - please file a bug report", obj)
	}

	table.Render()
	return nil
}

const (
	// DefaultAccountTableFields is the default for --table-fields for lib.Account
	DefaultAccountTableFields = "BillingID, Name, Suspended, Groups"
	// DefaultBackupTableFields is the default for --table-fields for brain.Backup
	DefaultBackupTableFields = "ID, Manual, Label, StorageGrade, Size, BackupCount, BackupSchedules"
	// DefaultBackupScheduleTableFields is the default for --table-fields for brain.BackupSchedule
	DefaultBackupScheduleTableFields = "ID, StartDate, Interval"
	// DefaultDiscTableFields is the default for --table-fields for brain.Disc
	DefaultDiscTableFields = "ID, Label, StorageGrade, Size, BackupCount, BackupSchedules"
	// DefaultGroupTableFields is the default for --table-fields for brain.Group
	DefaultGroupTableFields = "ID, Name, VirtualMachines"
	// DefaultPrivilegeTableFields is the default for --table-fields for brain.Privilege
	DefaultPrivilegeTableFields = "ID, Username, Level, Target, YubikeyRequired"
	// DefaultServerTableFields is the default for --table-fields for brain.VirtualMachine
	DefaultServerTableFields = "ID, Hostname, ManagementAddress, Memory, Cores, Discs, CdromURL, Autoreboot, PowerOn, Deleted"

	// DefaultHeadTableFields is the default for --table-fields for brain.Head
	DefaultHeadTableFields = "ID, Label, IsOnline, UsageStrategy, UUID, CCAddress, VirtualMachineCount, MemoryFree, UsedCores, Memory, Note, Architecture, Models, ZoneName"
	// DefaultTailTableFields is the default for --table-fields for brain.Tail
	DefaultTailTableFields = "ID, Label, IsOnline, UUID, CCAddress, StoragePools, ZoneName"
	// DefaultStoragePoolTableFields is the default for --table-fields for brain.StoragePool
	DefaultStoragePoolTableFields = "Label, Discs, Name, Size, FreeSpace, StorageGrade"
	// DefaultIPRangeTableFields is the default for --table-fields for brain.IPRange
	DefaultIPRangeTableFields = "ID, Spec, VLANNum, Available, Zones"
	// DefaultVLANTableFields is the default for --table-fields for brain.VLAN
	DefaultVLANTableFields = "ID, Num, UsageType, IPRanges"

	// DefaultDefinitionTableFields is the default for --table-fields for the *Definition types, because they're all the same at the moment.
	DefaultDefinitionTableFields = "Name, Description"
)

// OutputFlags creates some cli.Flags for when you wanna use OutputInDesiredForm
// thing should be like "server", "servers", "group", "groups"
// jsonType should be "array" or "object"
func OutputFlags(thing string, jsonType string, defaultTableFields string) []cli.Flag {
	return []cli.Flag{
		cli.BoolFlag{
			Name:  "json",
			Usage: fmt.Sprintf("Output the %s as a JSON %s", thing, jsonType),
		},
		cli.BoolFlag{
			Name:  "table",
			Usage: fmt.Sprintf("Output the %s as a table", thing),
		},
		cli.StringFlag{
			Name:  "table-fields",
			Usage: fmt.Sprintf("The fields of the %s to output in the table, comma separated. set to 'help' for a list of fields for this command", thing),
			Value: defaultTableFields,
		},
	}
}

// OutputFn is a function for outputting an object to the terminal in some way
// See the OutputFormatFns map to see examples
type OutputFn func(context *Context, obj interface{}) error

// OutputFormatFns is a map which contains all the supported output format functions -- except 'human' because that's implemented in the OutputInDesiredForm method, by necessity.
var OutputFormatFns = map[string]OutputFn{
	"debug": func(c *Context, obj interface{}) error {
		fmt.Fprintf(global.App.Writer, "%#v", obj)
		return nil
	},
	"json":  (*Context).OutputJSON,
	"table": (*Context).OutputTable,
}

// SupportedOutputTypes returns a list of all suppported output forms, including 'human'
func SupportedOutputTypes() (outputTypes []string) {
	outputTypes = make([]string, 0, len(OutputFormatFns)+1)
	for k := range OutputFormatFns {
		outputTypes = append(outputTypes, k)
	}
	outputTypes = append(outputTypes, "human")
	return
}

// OutputInDesiredForm outputs obj as a JSON object if --json is set,
// or as a table / table row if --table is set
// otherwise calls humanOutputFn (which should output it in a very human form - PrettyPrint or such
// defaultFormat is an optional string stating that the default format should be
func (c *Context) OutputInDesiredForm(obj interface{}, humanOutputFn func() error, defaultFormat ...string) error {
	format, err := global.Config.GetV("output-format")
	if err != nil {
		return err
	}
	if len(defaultFormat) > 0 && format.Source == "CODE" {
		format.Value = defaultFormat[0]
	}

	if c.Bool("json") {
		format.Value = "json"
	} else if c.Bool("table") || c.Context.IsSet("table-fields") {
		format.Value = "table"
	}

	if format.Value == "" || format.Value == "human" {
		return humanOutputFn()
	}

	if fn, ok := OutputFormatFns[format.Value]; ok {
		return fn(c, obj)
	}

	return fmt.Errorf("%s isn't a supported output type. Use one of the following instead:\r\n%s", format.Value, strings.Join(SupportedOutputTypes(), "\r\n"))
}
<commit_msg>Fix --table-fields help outputting +\n+ at the end<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/BytemarkHosting/row"
	"github.com/olekukonko/tablewriter"
	"github.com/urfave/cli"
	"reflect"
	"strings"
)

// OutputJSON is an OutputFn which outputs a nicely-indented JSON object that represents obj
func (c *Context) OutputJSON(obj interface{}) error {
	js, err := json.MarshalIndent(obj, "", "    ")
	if err != nil {
		return err
	}
	fmt.Fprintf(global.App.Writer, string(js))
	return nil
}

func trimAllSpace(strs []string) {
	for i, s := range strs {
		strs[i] = strings.TrimSpace(s)
	}
}

func (c *Context) determineTableFields(obj interface{}) []string {
	chosenFields := strings.Split(c.String("table-fields"), ",")
	trimAllSpace(chosenFields)

	fieldsList := row.FieldsFrom(obj)
	if len(chosenFields) > 0 && chosenFields[0] != "" {
		return chosenFields
	} else {
		return fieldsList
	}
}

// OutputTable is an OutputFn which outputs the object in table form, using github.com/BytemarkHosting/row and github.com/olekukonko/tablewriter
func (c *Context) OutputTable(obj interface{}) error {
	if c.String("table-fields") == "help" {
		fieldsList := row.FieldsFrom(obj)
		fmt.Fprintf(global.App.Writer, "Table fields available for this command: \r\n  %s\r\n\r\n", strings.Join(fieldsList, "\r\n  "))
		return nil
	}
	fields := c.determineTableFields(obj)
	return RenderTable(obj, fields)
}

// RenderTable creates a table for the given object. This makes
// most sense when it's an array, but a regular struct-y object works fine too.
func RenderTable(obj interface{}, fields []string) error {
	table := tablewriter.NewWriter(global.App.Writer)
	// don't autowrap because fields that are slices output one element per line
	// and autowrap
	table.SetAutoWrapText(false)
	// lines between rows!
	table.SetRowLine(true)
	// don't autoformat the headers - autoformat makes them ALLCAPS which makes
	// it hard to figure out what to set --table-fields to.
	// with autoformat off, --table-fields can be set by copying and pasting
	// from the table header.
	table.SetAutoFormatHeaders(false)

	table.SetHeader(fields)
	v := reflect.ValueOf(obj)

	// indirect pointers so we can switch on Kind()
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	// output a single table row for a struct, or several for a slice / array
	switch v.Kind() {
	case reflect.Struct:
		r, err := row.From(obj, fields)
		if err != nil {
			return err
		}
		table.Append(r)
	case reflect.Slice, reflect.Array:
		length := v.Len()
		for i := 0; i < length; i++ {
			el := v.Index(i)
			r, err := row.From(el.Interface(), fields)
			if err != nil {
				return err
			}
			table.Append(r)
		}
	default:
		return fmt.Errorf("%T is not a struct or slice type - please file a bug report", obj)
	}

	table.Render()
	return nil
}

const (
	// DefaultAccountTableFields is the default for --table-fields for lib.Account
	DefaultAccountTableFields = "BillingID, Name, Suspended, Groups"
	// DefaultBackupTableFields is the default for --table-fields for brain.Backup
	DefaultBackupTableFields = "ID, Manual, Label, StorageGrade, Size, BackupCount, BackupSchedules"
	// DefaultBackupScheduleTableFields is the default for --table-fields for brain.BackupSchedule
	DefaultBackupScheduleTableFields = "ID, StartDate, Interval"
	// DefaultDiscTableFields is the default for --table-fields for brain.Disc
	DefaultDiscTableFields = "ID, Label, StorageGrade, Size, BackupCount, BackupSchedules"
	// DefaultGroupTableFields is the default for --table-fields for brain.Group
	DefaultGroupTableFields = "ID, Name, VirtualMachines"
	// DefaultPrivilegeTableFields is the default for --table-fields for brain.Privilege
	DefaultPrivilegeTableFields = "ID, Username, Level, Target, YubikeyRequired"
	// DefaultServerTableFields is the default for --table-fields for brain.VirtualMachine
	DefaultServerTableFields = "ID, Hostname, ManagementAddress, Memory, Cores, Discs, CdromURL, Autoreboot, PowerOn, Deleted"

	// DefaultHeadTableFields is the default for --table-fields for brain.Head
	DefaultHeadTableFields = "ID, Label, IsOnline, UsageStrategy, UUID, CCAddress, VirtualMachineCount, MemoryFree, UsedCores, Memory, Note, Architecture, Models, ZoneName"
	// DefaultTailTableFields is the default for --table-fields for brain.Tail
	DefaultTailTableFields = "ID, Label, IsOnline, UUID, CCAddress, StoragePools, ZoneName"
	// DefaultStoragePoolTableFields is the default for --table-fields for brain.StoragePool
	DefaultStoragePoolTableFields = "Label, Discs, Name, Size, FreeSpace, StorageGrade"
	// DefaultIPRangeTableFields is the default for --table-fields for brain.IPRange
	DefaultIPRangeTableFields = "ID, Spec, VLANNum, Available, Zones"
	// DefaultVLANTableFields is the default for --table-fields for brain.VLAN
	DefaultVLANTableFields = "ID, Num, UsageType, IPRanges"

	// DefaultDefinitionTableFields is the default for --table-fields for the *Definition types, because they're all the same at the moment.
	DefaultDefinitionTableFields = "Name, Description"
)

// OutputFlags creates some cli.Flags for when you wanna use OutputInDesiredForm
// thing should be like "server", "servers", "group", "groups"
// jsonType should be "array" or "object"
func OutputFlags(thing string, jsonType string, defaultTableFields string) []cli.Flag {
	return []cli.Flag{
		cli.BoolFlag{
			Name:  "json",
			Usage: fmt.Sprintf("Output the %s as a JSON %s", thing, jsonType),
		},
		cli.BoolFlag{
			Name:  "table",
			Usage: fmt.Sprintf("Output the %s as a table", thing),
		},
		cli.StringFlag{
			Name:  "table-fields",
			Usage: fmt.Sprintf("The fields of the %s to output in the table, comma separated. set to 'help' for a list of fields for this command", thing),
			Value: defaultTableFields,
		},
	}
}

// OutputFn is a function for outputting an object to the terminal in some way
// See the OutputFormatFns map to see examples
type OutputFn func(context *Context, obj interface{}) error

// OutputFormatFns is a map which contains all the supported output format functions -- except 'human' because that's implemented in the OutputInDesiredForm method, by necessity.
var OutputFormatFns = map[string]OutputFn{
	"debug": func(c *Context, obj interface{}) error {
		fmt.Fprintf(global.App.Writer, "%#v", obj)
		return nil
	},
	"json":  (*Context).OutputJSON,
	"table": (*Context).OutputTable,
}

// SupportedOutputTypes returns a list of all suppported output forms, including 'human'
func SupportedOutputTypes() (outputTypes []string) {
	outputTypes = make([]string, 0, len(OutputFormatFns)+1)
	for k := range OutputFormatFns {
		outputTypes = append(outputTypes, k)
	}
	outputTypes = append(outputTypes, "human")
	return
}

// OutputInDesiredForm outputs obj as a JSON object if --json is set,
// or as a table / table row if --table is set
// otherwise calls humanOutputFn (which should output it in a very human form - PrettyPrint or such
// defaultFormat is an optional string stating that the default format should be
func (c *Context) OutputInDesiredForm(obj interface{}, humanOutputFn func() error, defaultFormat ...string) error {
	format, err := global.Config.GetV("output-format")
	if err != nil {
		return err
	}
	if len(defaultFormat) > 0 && format.Source == "CODE" {
		format.Value = defaultFormat[0]
	}

	if c.Bool("json") {
		format.Value = "json"
	} else if c.Bool("table") || c.Context.IsSet("table-fields") {
		format.Value = "table"
	}

	if format.Value == "" || format.Value == "human" {
		return humanOutputFn()
	}

	if fn, ok := OutputFormatFns[format.Value]; ok {
		return fn(c, obj)
	}

	return fmt.Errorf("%s isn't a supported output type. Use one of the following instead:\r\n%s", format.Value, strings.Join(SupportedOutputTypes(), "\r\n"))
}
<|endoftext|>


<commit_before>/*
Copyright 2017 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 cmd

import (
	"fmt"
	"os"
	"text/template"

	"github.com/golang/glog"
	"github.com/spf13/cobra"
	cmdConfig "k8s.io/minikube/cmd/minikube/cmd/config"
	"k8s.io/minikube/pkg/minikube/constants"
)

const cacheListFormat = "- {{.CacheImageName}}\n"

type CacheListTemplate struct {
	CacheImageName   string
}

// listCacheCmd represents the cache list command
var listCacheCmd = &cobra.Command{
	Use:   "list",
	Short: "List all available images from the local cache.",
	Long:  "List all available images from the local cache.",
	Run: func(cmd *cobra.Command, args []string) {
		// list images from config file
		images, err := cmdConfig.ListConfigMap(constants.Cache)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error listing images: %s\n", err)
			os.Exit(1)
		}
		if err := cacheList(images); err != nil {
			fmt.Fprintf(os.Stderr, "Error listing images: %s\n", err)
			os.Exit(1)
		}
	},
}

func init() {
	cacheCmd.AddCommand(listCacheCmd)
	RootCmd.AddCommand(cacheCmd)
}

func cacheList(images map[string]interface{}) error {
	for imageName := range images {
		tmpl, err := template.New("list").Parse(cacheListFormat)
		if err != nil {
			glog.Errorln("Error creating list template:", err)
			os.Exit(1)
		}
		listTmplt := CacheListTemplate{imageName}
		err = tmpl.Execute(os.Stdout, listTmplt)
		if err != nil {
			glog.Errorln("Error executing list template:", err)
			os.Exit(1)
		}
	}
	return nil
}
<commit_msg>Fix gofmt check errors<commit_after>/*
Copyright 2017 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 cmd

import (
	"fmt"
	"os"
	"text/template"

	"github.com/spf13/cobra"
	cmdConfig "k8s.io/minikube/cmd/minikube/cmd/config"
	"k8s.io/minikube/pkg/minikube/constants"
)

const cacheListFormat = "- {{.CacheImageName}}\n"

type CacheListTemplate struct {
	CacheImageName string
}

// listCacheCmd represents the cache list command
var listCacheCmd = &cobra.Command{
	Use:   "list",
	Short: "List all available images from the local cache.",
	Long:  "List all available images from the local cache.",
	Run: func(cmd *cobra.Command, args []string) {
		// list images from config file
		images, err := cmdConfig.ListConfigMap(constants.Cache)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error listing image entries from config: %s\n", err)
			os.Exit(1)
		}
		if err := cacheList(images); err != nil {
			fmt.Fprintf(os.Stderr, "Error listing images: %s\n", err)
			os.Exit(1)
		}
	},
}

func init() {
	cacheCmd.AddCommand(listCacheCmd)
	RootCmd.AddCommand(cacheCmd)
}

func cacheList(images map[string]interface{}) error {
	for imageName := range images {
		tmpl, err := template.New("list").Parse(cacheListFormat)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error creating list template: %s\n", err)
			os.Exit(1)
		}
		listTmplt := CacheListTemplate{imageName}
		err = tmpl.Execute(os.Stdout, listTmplt)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error executing list template: %s\n", err)
			os.Exit(1)
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/spf13/cobra"
)

var autocompleteTarget string

var cmdAutocomplete = &cobra.Command{
	Use:   "autocomplete",
	Short: "Generate shell autocompletion script",
	Long: `The "autocomplete" command generates a shell autocompletion script.

NOTE: The current version supports Bash only.
      This should work for *nix systems with Bash installed.

By default, the file is written directly to /etc/bash_completion.d
for convenience, and the command may need superuser rights, e.g.:

$ sudo restic autocomplete`,

	DisableAutoGenTag: true,
	RunE: func(cmd *cobra.Command, args []string) error {
		if err := cmdRoot.GenBashCompletionFile(autocompleteTarget); err != nil {
			return err
		}
		return nil
	},
}

func init() {
	cmdRoot.AddCommand(cmdAutocomplete)

	cmdAutocomplete.Flags().StringVarP(&autocompleteTarget, "completionfile", "", "/etc/bash_completion.d/restic.sh", "autocompletion file")
	// For bash-completion
	cmdAutocomplete.Flags().SetAnnotation("completionfile", cobra.BashCompFilenameExt, []string{})
}
<commit_msg>Correct bash completion file path<commit_after>package main

import (
	"github.com/spf13/cobra"
)

var cmdAutocomplete = &cobra.Command{
	Use:   "autocomplete",
	Short: "Generate shell autocompletion script",
	Long: `The "autocomplete" command generates a shell autocompletion script.

NOTE: The current version supports Bash only.
      This should work for *nix systems with Bash installed.

By default, the file is written directly to /etc/bash_completion.d
for convenience, and the command may need superuser rights, e.g.:

$ sudo restic autocomplete`,

	DisableAutoGenTag: true,
	RunE: func(cmd *cobra.Command, args []string) error {
		if err := cmdRoot.GenBashCompletionFile(autocompleteTarget); err != nil {
			return err
		}
		return nil
	},
}

var autocompleteTarget string

func init() {
	cmdRoot.AddCommand(cmdAutocomplete)

	cmdAutocomplete.Flags().StringVarP(&autocompleteTarget, "completionfile", "", "/usr/share/bash-completion/completions/restic", "autocompletion file")
	// For bash-completion
	cmdAutocomplete.Flags().SetAnnotation("completionfile", cobra.BashCompFilenameExt, []string{})
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2016 Intel Corporation
//
// 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

import (
	"errors"
	"flag"
	"fmt"
	"io"
	"os"
	"text/template"

	"github.com/01org/ciao/templateutils"
	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/openstack"
	"github.com/rackspace/gophercloud/openstack/imageservice/v2/images"
	"github.com/rackspace/gophercloud/pagination"
	"strings"
)

var imageCommand = &command{
	SubCommands: map[string]subCommand{
		"add":    new(imageAddCommand),
		"show":   new(imageShowCommand),
		"list":   new(imageListCommand),
		"delete": new(imageDeleteCommand),
	},
}

type imageAddCommand struct {
	Flag       flag.FlagSet
	name       string
	id         string
	file       string
	template   string
	tags       string
	visibility string
}

const (
	internalImage images.ImageVisibility = "internal"
)

func (cmd *imageAddCommand) usage(...string) {
	fmt.Fprintf(os.Stderr, `usage: ciao-cli [options] image add [flags]

Creates a new image

The add flags are:

`)
	cmd.Flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, "\n%s", templateutils.GenerateUsageDecorated("f", images.Image{}, nil))
	os.Exit(2)
}

func (cmd *imageAddCommand) parseArgs(args []string) []string {
	cmd.Flag.StringVar(&cmd.name, "name", "", "Image Name")
	cmd.Flag.StringVar(&cmd.id, "id", "", "Image UUID")
	cmd.Flag.StringVar(&cmd.file, "file", "", "Image file to upload")
	cmd.Flag.StringVar(&cmd.template, "f", "", "Template used to format output")
	cmd.Flag.StringVar(&cmd.visibility, "visibility", string(images.ImageVisibilityPrivate),
		"Image visibility (internal,public,private)")
	cmd.Flag.StringVar(&cmd.tags, "tag", "", "Image tags (comma separated)")
	cmd.Flag.Usage = func() { cmd.usage() }
	cmd.Flag.Parse(args)
	return cmd.Flag.Args()
}

func (cmd *imageAddCommand) run(args []string) error {
	if cmd.name == "" {
		return errors.New("Missing required -name parameter")
	}

	if cmd.file == "" {
		return errors.New("Missing required -file parameter")
	}

	_, err := os.Stat(cmd.file)
	if err != nil {
		fatalf("Could not open %s [%s]\n", cmd.file, err)
	}

	client, err := imageServiceClient(*identityUser, *identityPassword, *tenantID)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	imageVisibility := images.ImageVisibilityPrivate
	if cmd.visibility != "" {
		imageVisibility = images.ImageVisibility(cmd.visibility)
		switch imageVisibility {
		case images.ImageVisibilityPublic, images.ImageVisibilityPrivate, internalImage:
		default:
			fatalf("Invalid image visibility [%v]", imageVisibility)
		}
	}

	tags := strings.Split(cmd.tags, ",")

	opts := images.CreateOpts{
		Name:       cmd.name,
		ID:         cmd.id,
		Visibility: &imageVisibility,
		Tags:       tags,
	}

	image, err := images.Create(client, opts).Extract()
	if err != nil {
		fatalf("Could not create image [%s]\n", err)
	}

	uploadTenantImage(*identityUser, *identityPassword, *tenantID, image.ID, cmd.file)
	image, err = images.Get(client, image.ID).Extract()
	if err != nil {
		fatalf("Could not retrieve new created image [%s]\n", err)
	}

	if cmd.template != "" {
		return templateutils.OutputToTemplate(os.Stdout, "image-add", cmd.template, image, nil)
	}

	fmt.Printf("Created image:\n")
	dumpImage(image)
	return nil
}

type imageShowCommand struct {
	Flag     flag.FlagSet
	image    string
	template string
}

func (cmd *imageShowCommand) usage(...string) {
	fmt.Fprintf(os.Stderr, `usage: ciao-cli [options] image show

Show images
`)
	cmd.Flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, "\n%s", templateutils.GenerateUsageDecorated("f", images.Image{}, nil))
	os.Exit(2)
}

func (cmd *imageShowCommand) parseArgs(args []string) []string {
	cmd.Flag.StringVar(&cmd.template, "f", "", "Template used to format output")
	cmd.Flag.StringVar(&cmd.image, "image", "", "Image UUID")
	cmd.Flag.Usage = func() { cmd.usage() }
	cmd.Flag.Parse(args)
	return cmd.Flag.Args()
}

func (cmd *imageShowCommand) run(args []string) error {
	if cmd.image == "" {
		return errors.New("Missing required -image parameter")
	}

	client, err := imageServiceClient(*identityUser, *identityPassword, *tenantID)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	i, err := images.Get(client, cmd.image).Extract()
	if err != nil {
		fatalf("Could not retrieve image %s [%s]\n", cmd.image, err)
	}

	if cmd.template != "" {
		return templateutils.OutputToTemplate(os.Stdout, "image-show", cmd.template, i, nil)
	}

	dumpImage(i)

	return nil
}

type imageListCommand struct {
	Flag     flag.FlagSet
	template string
}

func (cmd *imageListCommand) usage(...string) {
	fmt.Fprintf(os.Stderr, `usage: ciao-cli [options] image list

List images
`)
	cmd.Flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, `
The template passed to the -f option operates on a

%s

As images are retrieved in pages, the template may be applied multiple
times.  You can not therefore rely on the length of the slice passed
to the template to determine the total number of images.
`, templateutils.GenerateUsageUndecorated([]images.Image{}))
	fmt.Fprintln(os.Stderr, templateutils.TemplateFunctionHelp(nil))
	os.Exit(2)
}

func (cmd *imageListCommand) parseArgs(args []string) []string {
	cmd.Flag.StringVar(&cmd.template, "f", "", "Template used to format output")
	cmd.Flag.Usage = func() { cmd.usage() }
	cmd.Flag.Parse(args)
	return cmd.Flag.Args()
}

func (cmd *imageListCommand) run(args []string) error {
	client, err := imageServiceClient(*identityUser, *identityPassword, *tenantID)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	var t *template.Template
	if cmd.template != "" {
		t, err = templateutils.CreateTemplate("image-list", cmd.template, nil)
		if err != nil {
			fatalf(err.Error())
		}
	}

	pager := images.List(client, images.ListOpts{})

	var allImages []images.Image
	err = pager.EachPage(func(page pagination.Page) (bool, error) {
		imageList, err := images.ExtractImages(page)
		if err != nil {
			errorf("Could not extract image [%s]\n", err)
		}
		allImages = append(allImages, imageList...)

		return false, nil
	})

	if t != nil {
		if err = t.Execute(os.Stdout, &allImages); err != nil {
			fatalf(err.Error())
		}
		return nil
	}

	for k, i := range allImages {
		fmt.Printf("Image #%d\n", k+1)
		dumpImage(&i)
		fmt.Printf("\n")
	}

	return err
}

type imageDownloadCommand struct {
	Flag  flag.FlagSet
	image string
	file  string
}

func (cmd *imageDownloadCommand) usage(...string) {
	fmt.Fprintf(os.Stderr, `usage: ciao-cli [options] image download [flags]

Fetch an image

The download flags are:

`)
	cmd.Flag.PrintDefaults()
	os.Exit(2)
}

func (cmd *imageDownloadCommand) parseArgs(args []string) []string {
	cmd.Flag.StringVar(&cmd.image, "image", "", "Image UUID")
	cmd.Flag.StringVar(&cmd.file, "file", "", "Filename to save the image (default will print to stdout)")
	cmd.Flag.Usage = func() { cmd.usage() }
	cmd.Flag.Parse(args)
	return cmd.Flag.Args()
}

func (cmd *imageDownloadCommand) run(args []string) (err error) {
	client, err := imageServiceClient(*identityUser, *identityPassword, *tenantID)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	r, err := images.Download(client, cmd.image).Extract()
	if err != nil {
		fatalf("Could not download image [%s]\n", err)
	}

	dest := os.Stdout
	if cmd.file != "" {
		dest, err = os.Create(cmd.file)
		defer func() {
			closeErr := dest.Close()
			if err == nil {
				err = closeErr
			}
		}()
		if err != nil {
			fatalf("Could not create destination file: %s: %v", cmd.file, err)
		}
	}

	_, err = io.Copy(dest, r)
	if err != nil {
		fatalf("Error copying to destination: %v", err)
	}

	return nil
}

type imageDeleteCommand struct {
	Flag  flag.FlagSet
	image string
}

func (cmd *imageDeleteCommand) usage(...string) {
	fmt.Fprintf(os.Stderr, `usage: ciao-cli [options] image delete [flags]

Deletes an image

The delete flags are:

`)
	cmd.Flag.PrintDefaults()
	os.Exit(2)
}

func (cmd *imageDeleteCommand) parseArgs(args []string) []string {
	cmd.Flag.StringVar(&cmd.image, "image", "", "Image UUID")
	cmd.Flag.Usage = func() { cmd.usage() }
	cmd.Flag.Parse(args)
	return cmd.Flag.Args()
}

func (cmd *imageDeleteCommand) run(args []string) error {
	client, err := imageServiceClient(*identityUser, *identityPassword, *tenantID)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	res := images.Delete(client, cmd.image)
	if res.Err != nil {
		fatalf("Could not delete Image [%s]\n", res.Err)
	}
	fmt.Printf("Deleted image %s\n", cmd.image)
	return res.Err
}

func uploadTenantImage(username, password, tenant, image, filename string) error {
	client, err := imageServiceClient(username, password, tenant)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	file, err := os.Open(filename)
	if err != nil {
		fatalf("Could not open %s [%s]", filename, err)
	}
	defer file.Close()

	res := images.Upload(client, image, file)
	if res.Err != nil {
		fatalf("Could not upload %s [%s]", filename, res.Err)
	}
	return res.Err
}

type imageModifyCommand struct {
	Flag  flag.FlagSet
	name  string
	image string
}

func (cmd *imageModifyCommand) usage(...string) {
	fmt.Fprintf(os.Stderr, `usage: ciao-cli [options] image modify [flags]

Modify an image

The modify flags are:

`)
	cmd.Flag.PrintDefaults()
	os.Exit(2)
}

func (cmd *imageModifyCommand) parseArgs(args []string) []string {
	cmd.Flag.StringVar(&cmd.name, "name", "", "Image Name")
	cmd.Flag.StringVar(&cmd.image, "image", "", "Image UUID")
	cmd.Flag.Usage = func() { cmd.usage() }
	cmd.Flag.Parse(args)
	return cmd.Flag.Args()
}

func (cmd *imageModifyCommand) run(args []string) error {
	if cmd.image == "" {
		return errors.New("Missing required -image parameter")
	}

	client, err := imageServiceClient(*identityUser, *identityPassword, *tenantID)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	var opts images.UpdateOpts
	if cmd.name != "" {
		n := images.ReplaceImageName{
			NewName: cmd.name,
		}
		opts = append(opts, n)
	}

	image, err := images.Update(client, cmd.image, opts).Extract()
	if err != nil {
		fatalf("Could not update image's properties [%s]\n", err)
	}

	fmt.Printf("Updated image:\n")
	dumpImage(image)
	return nil
}

func dumpImage(i *images.Image) {
	fmt.Printf("\tName             [%s]\n", i.Name)
	fmt.Printf("\tSize             [%d bytes]\n", i.SizeBytes)
	fmt.Printf("\tUUID             [%s]\n", i.ID)
	fmt.Printf("\tStatus           [%s]\n", i.Status)
	fmt.Printf("\tVisibility       [%s]\n", i.Visibility)
	fmt.Printf("\tTags             %v\n", i.Tags)
	fmt.Printf("\tCreatedDate      [%s]\n", i.CreatedDate)
}

func imageServiceClient(username, password, tenant string) (*gophercloud.ServiceClient, error) {
	opt := gophercloud.AuthOptions{
		IdentityEndpoint: *identityURL + "/v3/",
		Username:         username,
		Password:         password,
		DomainID:         "default",
		TenantID:         tenant,
		AllowReauth:      true,
	}

	provider, err := newAuthenticatedClient(opt)
	if err != nil {
		errorf("Could not get AuthenticatedClient %s\n", err)
		return nil, err
	}

	return openstack.NewImageServiceV2(provider, gophercloud.EndpointOpts{
		Name:   "glance",
		Region: "RegionOne",
	})
}
<commit_msg>ciao-cli: deadcode: remove image modify and download functionality<commit_after>//
// Copyright (c) 2016 Intel Corporation
//
// 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

import (
	"errors"
	"flag"
	"fmt"
	"os"
	"text/template"

	"strings"

	"github.com/01org/ciao/templateutils"
	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/openstack"
	"github.com/rackspace/gophercloud/openstack/imageservice/v2/images"
	"github.com/rackspace/gophercloud/pagination"
)

var imageCommand = &command{
	SubCommands: map[string]subCommand{
		"add":    new(imageAddCommand),
		"show":   new(imageShowCommand),
		"list":   new(imageListCommand),
		"delete": new(imageDeleteCommand),
	},
}

type imageAddCommand struct {
	Flag       flag.FlagSet
	name       string
	id         string
	file       string
	template   string
	tags       string
	visibility string
}

const (
	internalImage images.ImageVisibility = "internal"
)

func (cmd *imageAddCommand) usage(...string) {
	fmt.Fprintf(os.Stderr, `usage: ciao-cli [options] image add [flags]

Creates a new image

The add flags are:

`)
	cmd.Flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, "\n%s", templateutils.GenerateUsageDecorated("f", images.Image{}, nil))
	os.Exit(2)
}

func (cmd *imageAddCommand) parseArgs(args []string) []string {
	cmd.Flag.StringVar(&cmd.name, "name", "", "Image Name")
	cmd.Flag.StringVar(&cmd.id, "id", "", "Image UUID")
	cmd.Flag.StringVar(&cmd.file, "file", "", "Image file to upload")
	cmd.Flag.StringVar(&cmd.template, "f", "", "Template used to format output")
	cmd.Flag.StringVar(&cmd.visibility, "visibility", string(images.ImageVisibilityPrivate),
		"Image visibility (internal,public,private)")
	cmd.Flag.StringVar(&cmd.tags, "tag", "", "Image tags (comma separated)")
	cmd.Flag.Usage = func() { cmd.usage() }
	cmd.Flag.Parse(args)
	return cmd.Flag.Args()
}

func (cmd *imageAddCommand) run(args []string) error {
	if cmd.name == "" {
		return errors.New("Missing required -name parameter")
	}

	if cmd.file == "" {
		return errors.New("Missing required -file parameter")
	}

	_, err := os.Stat(cmd.file)
	if err != nil {
		fatalf("Could not open %s [%s]\n", cmd.file, err)
	}

	client, err := imageServiceClient(*identityUser, *identityPassword, *tenantID)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	imageVisibility := images.ImageVisibilityPrivate
	if cmd.visibility != "" {
		imageVisibility = images.ImageVisibility(cmd.visibility)
		switch imageVisibility {
		case images.ImageVisibilityPublic, images.ImageVisibilityPrivate, internalImage:
		default:
			fatalf("Invalid image visibility [%v]", imageVisibility)
		}
	}

	tags := strings.Split(cmd.tags, ",")

	opts := images.CreateOpts{
		Name:       cmd.name,
		ID:         cmd.id,
		Visibility: &imageVisibility,
		Tags:       tags,
	}

	image, err := images.Create(client, opts).Extract()
	if err != nil {
		fatalf("Could not create image [%s]\n", err)
	}

	uploadTenantImage(*identityUser, *identityPassword, *tenantID, image.ID, cmd.file)
	image, err = images.Get(client, image.ID).Extract()
	if err != nil {
		fatalf("Could not retrieve new created image [%s]\n", err)
	}

	if cmd.template != "" {
		return templateutils.OutputToTemplate(os.Stdout, "image-add", cmd.template, image, nil)
	}

	fmt.Printf("Created image:\n")
	dumpImage(image)
	return nil
}

type imageShowCommand struct {
	Flag     flag.FlagSet
	image    string
	template string
}

func (cmd *imageShowCommand) usage(...string) {
	fmt.Fprintf(os.Stderr, `usage: ciao-cli [options] image show

Show images
`)
	cmd.Flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, "\n%s", templateutils.GenerateUsageDecorated("f", images.Image{}, nil))
	os.Exit(2)
}

func (cmd *imageShowCommand) parseArgs(args []string) []string {
	cmd.Flag.StringVar(&cmd.template, "f", "", "Template used to format output")
	cmd.Flag.StringVar(&cmd.image, "image", "", "Image UUID")
	cmd.Flag.Usage = func() { cmd.usage() }
	cmd.Flag.Parse(args)
	return cmd.Flag.Args()
}

func (cmd *imageShowCommand) run(args []string) error {
	if cmd.image == "" {
		return errors.New("Missing required -image parameter")
	}

	client, err := imageServiceClient(*identityUser, *identityPassword, *tenantID)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	i, err := images.Get(client, cmd.image).Extract()
	if err != nil {
		fatalf("Could not retrieve image %s [%s]\n", cmd.image, err)
	}

	if cmd.template != "" {
		return templateutils.OutputToTemplate(os.Stdout, "image-show", cmd.template, i, nil)
	}

	dumpImage(i)

	return nil
}

type imageListCommand struct {
	Flag     flag.FlagSet
	template string
}

func (cmd *imageListCommand) usage(...string) {
	fmt.Fprintf(os.Stderr, `usage: ciao-cli [options] image list

List images
`)
	cmd.Flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, `
The template passed to the -f option operates on a

%s

As images are retrieved in pages, the template may be applied multiple
times.  You can not therefore rely on the length of the slice passed
to the template to determine the total number of images.
`, templateutils.GenerateUsageUndecorated([]images.Image{}))
	fmt.Fprintln(os.Stderr, templateutils.TemplateFunctionHelp(nil))
	os.Exit(2)
}

func (cmd *imageListCommand) parseArgs(args []string) []string {
	cmd.Flag.StringVar(&cmd.template, "f", "", "Template used to format output")
	cmd.Flag.Usage = func() { cmd.usage() }
	cmd.Flag.Parse(args)
	return cmd.Flag.Args()
}

func (cmd *imageListCommand) run(args []string) error {
	client, err := imageServiceClient(*identityUser, *identityPassword, *tenantID)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	var t *template.Template
	if cmd.template != "" {
		t, err = templateutils.CreateTemplate("image-list", cmd.template, nil)
		if err != nil {
			fatalf(err.Error())
		}
	}

	pager := images.List(client, images.ListOpts{})

	var allImages []images.Image
	err = pager.EachPage(func(page pagination.Page) (bool, error) {
		imageList, err := images.ExtractImages(page)
		if err != nil {
			errorf("Could not extract image [%s]\n", err)
		}
		allImages = append(allImages, imageList...)

		return false, nil
	})

	if t != nil {
		if err = t.Execute(os.Stdout, &allImages); err != nil {
			fatalf(err.Error())
		}
		return nil
	}

	for k, i := range allImages {
		fmt.Printf("Image #%d\n", k+1)
		dumpImage(&i)
		fmt.Printf("\n")
	}

	return err
}

type imageDeleteCommand struct {
	Flag  flag.FlagSet
	image string
}

func (cmd *imageDeleteCommand) usage(...string) {
	fmt.Fprintf(os.Stderr, `usage: ciao-cli [options] image delete [flags]

Deletes an image

The delete flags are:

`)
	cmd.Flag.PrintDefaults()
	os.Exit(2)
}

func (cmd *imageDeleteCommand) parseArgs(args []string) []string {
	cmd.Flag.StringVar(&cmd.image, "image", "", "Image UUID")
	cmd.Flag.Usage = func() { cmd.usage() }
	cmd.Flag.Parse(args)
	return cmd.Flag.Args()
}

func (cmd *imageDeleteCommand) run(args []string) error {
	client, err := imageServiceClient(*identityUser, *identityPassword, *tenantID)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	res := images.Delete(client, cmd.image)
	if res.Err != nil {
		fatalf("Could not delete Image [%s]\n", res.Err)
	}
	fmt.Printf("Deleted image %s\n", cmd.image)
	return res.Err
}

func uploadTenantImage(username, password, tenant, image, filename string) error {
	client, err := imageServiceClient(username, password, tenant)
	if err != nil {
		fatalf("Could not get Image service client [%s]\n", err)
	}

	file, err := os.Open(filename)
	if err != nil {
		fatalf("Could not open %s [%s]", filename, err)
	}
	defer file.Close()

	res := images.Upload(client, image, file)
	if res.Err != nil {
		fatalf("Could not upload %s [%s]", filename, res.Err)
	}
	return res.Err
}

func dumpImage(i *images.Image) {
	fmt.Printf("\tName             [%s]\n", i.Name)
	fmt.Printf("\tSize             [%d bytes]\n", i.SizeBytes)
	fmt.Printf("\tUUID             [%s]\n", i.ID)
	fmt.Printf("\tStatus           [%s]\n", i.Status)
	fmt.Printf("\tVisibility       [%s]\n", i.Visibility)
	fmt.Printf("\tTags             %v\n", i.Tags)
	fmt.Printf("\tCreatedDate      [%s]\n", i.CreatedDate)
}

func imageServiceClient(username, password, tenant string) (*gophercloud.ServiceClient, error) {
	opt := gophercloud.AuthOptions{
		IdentityEndpoint: *identityURL + "/v3/",
		Username:         username,
		Password:         password,
		DomainID:         "default",
		TenantID:         tenant,
		AllowReauth:      true,
	}

	provider, err := newAuthenticatedClient(opt)
	if err != nil {
		errorf("Could not get AuthenticatedClient %s\n", err)
		return nil, err
	}

	return openstack.NewImageServiceV2(provider, gophercloud.EndpointOpts{
		Name:   "glance",
		Region: "RegionOne",
	})
}
<|endoftext|>


<commit_before>package kontrolclient

import (
	"container/list"
	"errors"
	"net/url"
	"sync"

	"github.com/dgrijalva/jwt-go"
	"github.com/koding/kite"
	"github.com/koding/kite/protocol"
)

// Returned from GetKites when query matches no kites.
var ErrNoKitesAvailable = errors.New("no kites availabile")

// Kontrol is a client for registering and querying Kontrol Kite.
type Kontrol struct {
	*kite.RemoteKite

	LocalKite *kite.Kite

	// used for synchronizing methods that needs to be called after
	// successful connection.
	ready chan bool

	// Watchers are saved here to re-watch on reconnect.
	watchers      *list.List
	watchersMutex sync.RWMutex
}

// NewKontrol returns a pointer to new Kontrol instance.
func New(k *kite.Kite) *Kontrol {
	if k.Config.KontrolURL == nil {
		panic("no kontrol URL given in config")
	}

	// Only the address is required to connect Kontrol
	auth := &kite.Authentication{
		Type: "kiteKey",
		Key:  k.Config.KiteKey,
	}

	remoteKite := k.NewRemoteKite(k.Config.KontrolURL)
	remoteKite.Kite = protocol.Kite{Name: "kontrol"} // for logging purposes
	remoteKite.Authentication = auth
	// remoteKite.client.Reconnect = true

	kontrol := &Kontrol{
		RemoteKite: remoteKite,
		LocalKite:  k,
		ready:      make(chan bool),
		watchers:   list.New(),
	}

	var once sync.Once

	kontrol.OnConnect(func() {
		k.Log.Info("Connected to Kontrol ")

		// signal all other methods that are listening on this channel, that we
		// are ready.
		once.Do(func() { close(kontrol.ready) })

		// Re-register existing watchers.
		kontrol.watchersMutex.RLock()
		for e := kontrol.watchers.Front(); e != nil; e = e.Next() {
			watcher := e.Value.(*Watcher)
			if err := watcher.rewatch(); err != nil {
				kontrol.Log.Error("Cannot rewatch query: %+v", watcher)
			}
		}
		kontrol.watchersMutex.RUnlock()
	})

	return kontrol
}

type registerResult struct {
	URL *url.URL
}

// Register registers current Kite to Kontrol. After registration other Kites
// can find it via GetKites() method.
func (k *Kontrol) Register(kiteURL *url.URL) (*registerResult, error) {
	<-k.ready

	args := protocol.RegsiterArgs{
		URL: kiteURL.String(),
	}

	response, err := k.RemoteKite.Tell("register", args)
	if err != nil {
		return nil, err
	}

	var rr protocol.RegisterResult
	err = response.Unmarshal(&rr)
	if err != nil {
		return nil, err
	}

	k.Log.Info("Registered to kontrol with URL: %s", rr.URL)

	parsed, err := url.Parse(rr.URL)
	if err != nil {
		k.Log.Error("Cannot parse registered URL: %s", err.Error())
	}

	return &registerResult{parsed}, nil
}

// WatchKites watches for Kites that matches the query. The onEvent functions
// is called for current kites and every new kite event.
func (k *Kontrol) WatchKites(query protocol.KontrolQuery, onEvent EventHandler) (*Watcher, error) {
	<-k.ready

	watcherID, err := k.watchKites(query, onEvent)
	if err != nil {
		return nil, err
	}

	return k.newWatcher(watcherID, &query, onEvent), nil
}

func (k *Kontrol) eventCallbackHandler(onEvent EventHandler) kite.Callback {
	return func(r *kite.Request) {
		var returnEvent *Event
		var returnError error

		args := r.Args.MustSliceOfLength(2)

		// Unmarshal event argument
		if args[0] != nil {
			var event = Event{localKite: k.LocalKite}
			err := args[0].Unmarshal(&event)
			if err != nil {
				k.Log.Error(err.Error())
				return
			}
			returnEvent = &event
		}

		// Unmarshal error argument
		if args[1] != nil {
			var kiteErr kite.Error
			err := args[1].Unmarshal(&kiteErr)
			if err != nil {
				k.Log.Error(err.Error())
				return
			}
			returnError = &kiteErr
		}

		onEvent(returnEvent, returnError)
	}
}

func (k *Kontrol) watchKites(query protocol.KontrolQuery, onEvent EventHandler) (watcherID string, err error) {
	remoteKites, watcherID, err := k.getKites(query, k.eventCallbackHandler(onEvent))
	if err != nil && err != ErrNoKitesAvailable {
		return "", err // return only when something really happened
	}

	// also put the current kites to the eventChan.
	for _, remoteKite := range remoteKites {
		event := Event{
			KiteEvent: protocol.KiteEvent{
				Action: protocol.Register,
				Kite:   remoteKite.Kite,
				Token:  remoteKite.Authentication.Key,
			},
			localKite: k.LocalKite,
		}

		onEvent(&event, nil)
	}

	return watcherID, nil
}

// GetKites returns the list of Kites matching the query. The returned list
// contains ready to connect RemoteKite instances. The caller must connect
// with RemoteKite.Dial() before using each Kite. An error is returned when no
// kites are available.
func (k *Kontrol) GetKites(query protocol.KontrolQuery) ([]*kite.RemoteKite, error) {
	remoteKites, _, err := k.getKites(query)
	if err != nil {
		return nil, err
	}

	if len(remoteKites) == 0 {
		return nil, ErrNoKitesAvailable
	}

	return remoteKites, nil
}

// used internally for GetKites() and WatchKites()
func (k *Kontrol) getKites(args ...interface{}) (kites []*kite.RemoteKite, watcherID string, err error) {
	<-k.ready

	response, err := k.RemoteKite.Tell("getKites", args...)
	if err != nil {
		return nil, "", err
	}

	var result = new(protocol.GetKitesResult)
	err = response.Unmarshal(&result)
	if err != nil {
		return nil, "", err
	}

	remoteKites := make([]*kite.RemoteKite, len(result.Kites))
	for i, currentKite := range result.Kites {
		_, err := jwt.Parse(currentKite.Token, k.LocalKite.RSAKey)
		if err != nil {
			return nil, result.WatcherID, err
		}

		// exp := time.Unix(int64(token.Claims["exp"].(float64)), 0).UTC()
		auth := &kite.Authentication{
			Type: "token",
			Key:  currentKite.Token,
			// validUntil: &exp,
		}

		parsed, err := url.Parse(currentKite.URL)
		if err != nil {
			k.Log.Error("invalid url came from kontrol", currentKite.URL)
		}

		remoteKites[i] = k.LocalKite.NewRemoteKiteString(currentKite.URL)
		remoteKites[i].Kite = currentKite.Kite
		remoteKites[i].URL = parsed
		remoteKites[i].Authentication = auth
	}

	return remoteKites, result.WatcherID, nil
}

// GetToken is used to get a new token for a single Kite.
func (k *Kontrol) GetToken(kite *protocol.Kite) (string, error) {
	<-k.ready

	result, err := k.RemoteKite.Tell("getToken", kite)
	if err != nil {
		return "", err
	}

	var tkn string
	err = result.Unmarshal(&tkn)
	if err != nil {
		return "", err
	}

	return tkn, nil
}
<commit_msg>remove unused code<commit_after>package kontrolclient

import (
	"container/list"
	"errors"
	"net/url"
	"sync"

	"github.com/dgrijalva/jwt-go"
	"github.com/koding/kite"
	"github.com/koding/kite/protocol"
)

// Returned from GetKites when query matches no kites.
var ErrNoKitesAvailable = errors.New("no kites availabile")

// Kontrol is a client for registering and querying Kontrol Kite.
type Kontrol struct {
	*kite.RemoteKite

	LocalKite *kite.Kite

	// used for synchronizing methods that needs to be called after
	// successful connection.
	ready chan bool

	// Watchers are saved here to re-watch on reconnect.
	watchers      *list.List
	watchersMutex sync.RWMutex
}

// NewKontrol returns a pointer to new Kontrol instance.
func New(k *kite.Kite) *Kontrol {
	if k.Config.KontrolURL == nil {
		panic("no kontrol URL given in config")
	}

	// Only the address is required to connect Kontrol
	auth := &kite.Authentication{
		Type: "kiteKey",
		Key:  k.Config.KiteKey,
	}

	remoteKite := k.NewRemoteKite(k.Config.KontrolURL)
	remoteKite.Kite = protocol.Kite{Name: "kontrol"} // for logging purposes
	remoteKite.Authentication = auth

	kontrol := &Kontrol{
		RemoteKite: remoteKite,
		LocalKite:  k,
		ready:      make(chan bool),
		watchers:   list.New(),
	}

	var once sync.Once

	kontrol.OnConnect(func() {
		k.Log.Info("Connected to Kontrol ")

		// signal all other methods that are listening on this channel, that we
		// are ready.
		once.Do(func() { close(kontrol.ready) })

		// Re-register existing watchers.
		kontrol.watchersMutex.RLock()
		for e := kontrol.watchers.Front(); e != nil; e = e.Next() {
			watcher := e.Value.(*Watcher)
			if err := watcher.rewatch(); err != nil {
				kontrol.Log.Error("Cannot rewatch query: %+v", watcher)
			}
		}
		kontrol.watchersMutex.RUnlock()
	})

	return kontrol
}

type registerResult struct {
	URL *url.URL
}

// Register registers current Kite to Kontrol. After registration other Kites
// can find it via GetKites() method.
func (k *Kontrol) Register(kiteURL *url.URL) (*registerResult, error) {
	<-k.ready

	args := protocol.RegsiterArgs{
		URL: kiteURL.String(),
	}

	response, err := k.RemoteKite.Tell("register", args)
	if err != nil {
		return nil, err
	}

	var rr protocol.RegisterResult
	err = response.Unmarshal(&rr)
	if err != nil {
		return nil, err
	}

	k.Log.Info("Registered to kontrol with URL: %s", rr.URL)

	parsed, err := url.Parse(rr.URL)
	if err != nil {
		k.Log.Error("Cannot parse registered URL: %s", err.Error())
	}

	return &registerResult{parsed}, nil
}

// WatchKites watches for Kites that matches the query. The onEvent functions
// is called for current kites and every new kite event.
func (k *Kontrol) WatchKites(query protocol.KontrolQuery, onEvent EventHandler) (*Watcher, error) {
	<-k.ready

	watcherID, err := k.watchKites(query, onEvent)
	if err != nil {
		return nil, err
	}

	return k.newWatcher(watcherID, &query, onEvent), nil
}

func (k *Kontrol) eventCallbackHandler(onEvent EventHandler) kite.Callback {
	return func(r *kite.Request) {
		var returnEvent *Event
		var returnError error

		args := r.Args.MustSliceOfLength(2)

		// Unmarshal event argument
		if args[0] != nil {
			var event = Event{localKite: k.LocalKite}
			err := args[0].Unmarshal(&event)
			if err != nil {
				k.Log.Error(err.Error())
				return
			}
			returnEvent = &event
		}

		// Unmarshal error argument
		if args[1] != nil {
			var kiteErr kite.Error
			err := args[1].Unmarshal(&kiteErr)
			if err != nil {
				k.Log.Error(err.Error())
				return
			}
			returnError = &kiteErr
		}

		onEvent(returnEvent, returnError)
	}
}

func (k *Kontrol) watchKites(query protocol.KontrolQuery, onEvent EventHandler) (watcherID string, err error) {
	remoteKites, watcherID, err := k.getKites(query, k.eventCallbackHandler(onEvent))
	if err != nil && err != ErrNoKitesAvailable {
		return "", err // return only when something really happened
	}

	// also put the current kites to the eventChan.
	for _, remoteKite := range remoteKites {
		event := Event{
			KiteEvent: protocol.KiteEvent{
				Action: protocol.Register,
				Kite:   remoteKite.Kite,
				Token:  remoteKite.Authentication.Key,
			},
			localKite: k.LocalKite,
		}

		onEvent(&event, nil)
	}

	return watcherID, nil
}

// GetKites returns the list of Kites matching the query. The returned list
// contains ready to connect RemoteKite instances. The caller must connect
// with RemoteKite.Dial() before using each Kite. An error is returned when no
// kites are available.
func (k *Kontrol) GetKites(query protocol.KontrolQuery) ([]*kite.RemoteKite, error) {
	remoteKites, _, err := k.getKites(query)
	if err != nil {
		return nil, err
	}

	if len(remoteKites) == 0 {
		return nil, ErrNoKitesAvailable
	}

	return remoteKites, nil
}

// used internally for GetKites() and WatchKites()
func (k *Kontrol) getKites(args ...interface{}) (kites []*kite.RemoteKite, watcherID string, err error) {
	<-k.ready

	response, err := k.RemoteKite.Tell("getKites", args...)
	if err != nil {
		return nil, "", err
	}

	var result = new(protocol.GetKitesResult)
	err = response.Unmarshal(&result)
	if err != nil {
		return nil, "", err
	}

	remoteKites := make([]*kite.RemoteKite, len(result.Kites))
	for i, currentKite := range result.Kites {
		_, err := jwt.Parse(currentKite.Token, k.LocalKite.RSAKey)
		if err != nil {
			return nil, result.WatcherID, err
		}

		// exp := time.Unix(int64(token.Claims["exp"].(float64)), 0).UTC()
		auth := &kite.Authentication{
			Type: "token",
			Key:  currentKite.Token,
			// validUntil: &exp,
		}

		parsed, err := url.Parse(currentKite.URL)
		if err != nil {
			k.Log.Error("invalid url came from kontrol", currentKite.URL)
		}

		remoteKites[i] = k.LocalKite.NewRemoteKiteString(currentKite.URL)
		remoteKites[i].Kite = currentKite.Kite
		remoteKites[i].URL = parsed
		remoteKites[i].Authentication = auth
	}

	return remoteKites, result.WatcherID, nil
}

// GetToken is used to get a new token for a single Kite.
func (k *Kontrol) GetToken(kite *protocol.Kite) (string, error) {
	<-k.ready

	result, err := k.RemoteKite.Tell("getToken", kite)
	if err != nil {
		return "", err
	}

	var tkn string
	err = result.Unmarshal(&tkn)
	if err != nil {
		return "", err
	}

	return tkn, nil
}
<|endoftext|>