<commit_before>package goac

type CommentFeature struct {
	Comments map[string]string `json:"comments,omitempty"`
}

func (c *CommentFeature) GetAllComments() map[string]string {
	return c.Comments
}
func (c *CommentFeature) SetAllComments(cs map[string]string) {
	c.Comments = cs
}

type Vertex struct {
	Name            string           `json:"name,omitempty"`
	FullAssignments []FullAssignment `json:"fullAssignments,omitempty"`
}

type FullAssignment struct {
	CommentFeature
	Elevate string `json:"elevate,omitempty"`
	Over    string `json:"over,omitempty"`
}
<commit_msg>add encode/decode json helper founctions<commit_after>package goac

import (
	"encoding/json"
	"io"
)

type CommentFeature struct {
	Comments map[string]string `json:"comments,omitempty"`
}

func (c *CommentFeature) GetAllComments() map[string]string {
	return c.Comments
}
func (c *CommentFeature) SetAllComments(cs map[string]string) {
	c.Comments = cs
}

type Vertex struct {
	Name            string           `json:"name,omitempty"`
	FullAssignments []FullAssignment `json:"fullAssignments,omitempty"`
}

type FullAssignment struct {
	CommentFeature
	Elevate string `json:"elevate,omitempty"`
	Over    string `json:"over,omitempty"`
}

func (v Vertex) EncodeJson(w io.Writer) error {
	bs, err := json.MarshalIndent(v, "", "/t")
	if err != nil {
		return err
	}
	_, err = w.Write(bs)
	return err
}

func DecodeJsonToVertex(r io.Reader) (Vertex, error) {
	v := Vertex{}
	dec := json.NewDecoder(r)
	err := dec.Decode(&v)
	return v, err
}
<|endoftext|>


<commit_before>// Package command implements functions for responding to user
// input and dispatching to appropriate backend commands.
package command

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"

	"github.com/derekparker/delve/proctl"
)

type cmdfunc func(proc *proctl.DebuggedProcess, args ...string) error

type command struct {
	aliases []string
	helpMsg string
	cmdFn   cmdfunc
}

// Returns true if the command string matches one of the aliases for this command
func (c command) match(cmdstr string) bool {
	for _, v := range c.aliases {
		if v == cmdstr {
			return true
		}
	}
	return false
}

type Commands struct {
	cmds    []command
	lastCmd cmdfunc
}

// Returns a Commands struct with default commands defined.
func DebugCommands() *Commands {
	c := &Commands{}

	c.cmds = []command{
		command{aliases: []string{"help"}, cmdFn: c.help, helpMsg: "Prints the help message."},
		command{aliases: []string{"break", "b"}, cmdFn: breakpoint, helpMsg: "Set break point at the entry point of a function, or at a specific file/line. Example: break foo.go:13"},
		command{aliases: []string{"continue", "c"}, cmdFn: cont, helpMsg: "Run until breakpoint or program termination."},
		command{aliases: []string{"step", "si"}, cmdFn: step, helpMsg: "Single step through program."},
		command{aliases: []string{"next", "n"}, cmdFn: next, helpMsg: "Step over to next source line."},
		command{aliases: []string{"threads"}, cmdFn: threads, helpMsg: "Print out info for every traced thread."},
		command{aliases: []string{"thread", "t"}, cmdFn: thread, helpMsg: "Switch to the specified thread."},
		command{aliases: []string{"clear"}, cmdFn: clear, helpMsg: "Deletes breakpoint."},
		command{aliases: []string{"goroutines"}, cmdFn: goroutines, helpMsg: "Print out info for every goroutine."},
		command{aliases: []string{"breakpoints", "bp"}, cmdFn: breakpoints, helpMsg: "Print out info for active breakpoints."},
		command{aliases: []string{"print", "p"}, cmdFn: printVar, helpMsg: "Evaluate a variable."},
		command{aliases: []string{"info"}, cmdFn: info, helpMsg: "Provides info about args, funcs, locals, sources, or vars."},
		command{aliases: []string{"exit"}, cmdFn: nullCommand, helpMsg: "Exit the debugger."},
	}

	return c
}

// Register custom commands. Expects cf to be a func of type cmdfunc,
// returning only an error.
func (c *Commands) Register(cmdstr string, cf cmdfunc, helpMsg string) {
	for _, v := range c.cmds {
		if v.match(cmdstr) {
			v.cmdFn = cf
			return
		}
	}

	c.cmds = append(c.cmds, command{aliases: []string{cmdstr}, cmdFn: cf, helpMsg: helpMsg})
}

// Find will look up the command function for the given command input.
// If it cannot find the command it will defualt to noCmdAvailable().
// If the command is an empty string it will replay the last command.
func (c *Commands) Find(cmdstr string) cmdfunc {
	// If <enter> use last command, if there was one.
	if cmdstr == "" {
		if c.lastCmd != nil {
			return c.lastCmd
		}
		return nullCommand
	}

	for _, v := range c.cmds {
		if v.match(cmdstr) {
			c.lastCmd = v.cmdFn
			return v.cmdFn
		}
	}

	return noCmdAvailable
}

func CommandFunc(fn func() error) cmdfunc {
	return func(p *proctl.DebuggedProcess, args ...string) error {
		return fn()
	}
}

func noCmdAvailable(p *proctl.DebuggedProcess, ars ...string) error {
	return fmt.Errorf("command not available")
}

func nullCommand(p *proctl.DebuggedProcess, ars ...string) error {
	return nil
}

func (c *Commands) help(p *proctl.DebuggedProcess, ars ...string) error {
	fmt.Println("The following commands are available:")
	for _, cmd := range c.cmds {
		fmt.Printf("\t%s - %s\n", strings.Join(cmd.aliases, "|"), cmd.helpMsg)
	}
	return nil
}

func threads(p *proctl.DebuggedProcess, ars ...string) error {
	for _, th := range p.Threads {
		prefix := "  "
		if th == p.CurrentThread {
			prefix = "* "
		}
		pc, err := th.CurrentPC()
		if err != nil {
			return err
		}
		f, l, fn := th.Process.GoSymTable.PCToLine(pc)
		if fn != nil {
			fmt.Printf("%sThread %d at %#v %s:%d %s\n", prefix, th.Id, pc, f, l, fn.Name)
		} else {
			fmt.Printf("%sThread %d at %#v\n", prefix, th.Id, pc)
		}
	}
	return nil
}

func thread(p *proctl.DebuggedProcess, ars ...string) error {
	if len(ars) == 0 {
		return fmt.Errorf("you must specify a thread")
	}
	oldTid := p.CurrentThread.Id
	tid, err := strconv.Atoi(ars[0])
	if err != nil {
		return err
	}

	err = p.SwitchThread(tid)
	if err != nil {
		return err
	}

	fmt.Printf("Switched from %d to %d\n", oldTid, tid)
	return nil
}

func goroutines(p *proctl.DebuggedProcess, ars ...string) error {
	return p.PrintGoroutinesInfo()
}

func cont(p *proctl.DebuggedProcess, ars ...string) error {
	err := p.Continue()
	if err != nil {
		return err
	}

	return printcontext(p)
}

func step(p *proctl.DebuggedProcess, args ...string) error {
	err := p.Step()
	if err != nil {
		return err
	}

	return printcontext(p)
}

func next(p *proctl.DebuggedProcess, args ...string) error {
	err := p.Next()
	if err != nil {
		return err
	}

	return printcontext(p)
}

func clear(p *proctl.DebuggedProcess, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("not enough arguments")
	}

	bp, err := p.ClearByLocation(args[0])
	if err != nil {
		return err
	}

	fmt.Printf("Breakpoint %d cleared at %#v for %s %s:%d\n", bp.ID, bp.Addr, bp.FunctionName, bp.File, bp.Line)

	return nil
}

type ById []*proctl.BreakPoint

func (a ById) Len() int           { return len(a) }
func (a ById) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ById) Less(i, j int) bool { return a[i].ID < a[j].ID }

func breakpoints(p *proctl.DebuggedProcess, args ...string) error {
	bps := make([]*proctl.BreakPoint, 0, len(p.BreakPoints)+4)

	for _, bp := range p.HWBreakPoints {
		if bp == nil {
			continue
		}
		bps = append(bps, bp)
	}

	for _, bp := range p.BreakPoints {
		if bp.Temp {
			continue
		}
		bps = append(bps, bp)
	}

	sort.Sort(ById(bps))
	for _, bp := range bps {
		fmt.Println(bp)
	}

	return nil
}

func breakpoint(p *proctl.DebuggedProcess, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("not enough arguments")
	}

	bp, err := p.BreakByLocation(args[0])
	if err != nil {
		return err
	}

	fmt.Printf("Breakpoint %d set at %#v for %s %s:%d\n", bp.ID, bp.Addr, bp.FunctionName, bp.File, bp.Line)

	return nil
}

func printVar(p *proctl.DebuggedProcess, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("not enough arguments")
	}

	val, err := p.EvalSymbol(args[0])
	if err != nil {
		return err
	}

	fmt.Println(val.Value)
	return nil
}

func filterVariables(vars []*proctl.Variable, filter *regexp.Regexp) []string {
	data := make([]string, 0, len(vars))
	for _, v := range vars {
		if v == nil {
			continue
		}
		if filter == nil || filter.Match([]byte(v.Name)) {
			data = append(data, fmt.Sprintf("%s = %s", v.Name, v.Value))
		}
	}
	return data
}

func info(p *proctl.DebuggedProcess, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("not enough arguments. expected info type [regex].")
	}

	// Allow for optional regex
	var filter *regexp.Regexp
	if len(args) >= 2 {
		var err error
		if filter, err = regexp.Compile(args[1]); err != nil {
			return fmt.Errorf("invalid filter argument: %s", err.Error())
		}
	}

	var data []string

	switch args[0] {
	case "sources":
		data = make([]string, 0, len(p.GoSymTable.Files))
		for f := range p.GoSymTable.Files {
			if filter == nil || filter.Match([]byte(f)) {
				data = append(data, f)
			}
		}

	case "funcs":
		data = make([]string, 0, len(p.GoSymTable.Funcs))
		for _, f := range p.GoSymTable.Funcs {
			if f.Sym != nil && (filter == nil || filter.Match([]byte(f.Name))) {
				data = append(data, f.Name)
			}
		}

	case "args":
		vars, err := p.CurrentThread.FunctionArguments()
		if err != nil {
			return nil
		}
		data = filterVariables(vars, filter)

	case "locals":
		vars, err := p.CurrentThread.LocalVariables()
		if err != nil {
			return nil
		}
		data = filterVariables(vars, filter)

	case "vars":
		vars, err := p.CurrentThread.PackageVariables()
		if err != nil {
			return nil
		}
		data = filterVariables(vars, filter)

	default:
		return fmt.Errorf("unsupported info type, must be args, funcs, locals, sources, or vars")
	}

	// sort and output data
	sort.Sort(sort.StringSlice(data))

	for _, d := range data {
		fmt.Println(d)
	}

	return nil
}

func printcontext(p *proctl.DebuggedProcess) error {
	var context []string

	regs, err := p.Registers()
	if err != nil {
		return err
	}

	f, l, fn := p.GoSymTable.PCToLine(regs.PC())

	if fn != nil {
		fmt.Printf("current loc: %s %s:%d\n", fn.Name, f, l)
		file, err := os.Open(f)
		if err != nil {
			return err
		}
		defer file.Close()

		buf := bufio.NewReader(file)
		for i := 1; i < l-5; i++ {
			_, err := buf.ReadString('\n')
			if err != nil && err != io.EOF {
				return err
			}
		}

		for i := l - 5; i <= l+5; i++ {
			line, err := buf.ReadString('\n')
			if err != nil {
				if err != io.EOF {
					return err
				}

				if err == io.EOF {
					break
				}
			}

			arrow := "  "
			if i == l {
				arrow = "=>"
			}

			context = append(context, fmt.Sprintf("\033[34m%s %d\033[0m: %s", arrow, i, line))
		}
	} else {
		fmt.Printf("Stopped at: 0x%x\n", regs.PC())
		context = append(context, "\033[34m=>\033[0m    no source available")
	}

	fmt.Println(strings.Join(context, ""))

	return nil
}
<commit_msg>Fix argument typos<commit_after>// Package command implements functions for responding to user
// input and dispatching to appropriate backend commands.
package command

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"

	"github.com/derekparker/delve/proctl"
)

type cmdfunc func(proc *proctl.DebuggedProcess, args ...string) error

type command struct {
	aliases []string
	helpMsg string
	cmdFn   cmdfunc
}

// Returns true if the command string matches one of the aliases for this command
func (c command) match(cmdstr string) bool {
	for _, v := range c.aliases {
		if v == cmdstr {
			return true
		}
	}
	return false
}

type Commands struct {
	cmds    []command
	lastCmd cmdfunc
}

// Returns a Commands struct with default commands defined.
func DebugCommands() *Commands {
	c := &Commands{}

	c.cmds = []command{
		command{aliases: []string{"help"}, cmdFn: c.help, helpMsg: "Prints the help message."},
		command{aliases: []string{"break", "b"}, cmdFn: breakpoint, helpMsg: "Set break point at the entry point of a function, or at a specific file/line. Example: break foo.go:13"},
		command{aliases: []string{"continue", "c"}, cmdFn: cont, helpMsg: "Run until breakpoint or program termination."},
		command{aliases: []string{"step", "si"}, cmdFn: step, helpMsg: "Single step through program."},
		command{aliases: []string{"next", "n"}, cmdFn: next, helpMsg: "Step over to next source line."},
		command{aliases: []string{"threads"}, cmdFn: threads, helpMsg: "Print out info for every traced thread."},
		command{aliases: []string{"thread", "t"}, cmdFn: thread, helpMsg: "Switch to the specified thread."},
		command{aliases: []string{"clear"}, cmdFn: clear, helpMsg: "Deletes breakpoint."},
		command{aliases: []string{"goroutines"}, cmdFn: goroutines, helpMsg: "Print out info for every goroutine."},
		command{aliases: []string{"breakpoints", "bp"}, cmdFn: breakpoints, helpMsg: "Print out info for active breakpoints."},
		command{aliases: []string{"print", "p"}, cmdFn: printVar, helpMsg: "Evaluate a variable."},
		command{aliases: []string{"info"}, cmdFn: info, helpMsg: "Provides info about args, funcs, locals, sources, or vars."},
		command{aliases: []string{"exit"}, cmdFn: nullCommand, helpMsg: "Exit the debugger."},
	}

	return c
}

// Register custom commands. Expects cf to be a func of type cmdfunc,
// returning only an error.
func (c *Commands) Register(cmdstr string, cf cmdfunc, helpMsg string) {
	for _, v := range c.cmds {
		if v.match(cmdstr) {
			v.cmdFn = cf
			return
		}
	}

	c.cmds = append(c.cmds, command{aliases: []string{cmdstr}, cmdFn: cf, helpMsg: helpMsg})
}

// Find will look up the command function for the given command input.
// If it cannot find the command it will defualt to noCmdAvailable().
// If the command is an empty string it will replay the last command.
func (c *Commands) Find(cmdstr string) cmdfunc {
	// If <enter> use last command, if there was one.
	if cmdstr == "" {
		if c.lastCmd != nil {
			return c.lastCmd
		}
		return nullCommand
	}

	for _, v := range c.cmds {
		if v.match(cmdstr) {
			c.lastCmd = v.cmdFn
			return v.cmdFn
		}
	}

	return noCmdAvailable
}

func CommandFunc(fn func() error) cmdfunc {
	return func(p *proctl.DebuggedProcess, args ...string) error {
		return fn()
	}
}

func noCmdAvailable(p *proctl.DebuggedProcess, args ...string) error {
	return fmt.Errorf("command not available")
}

func nullCommand(p *proctl.DebuggedProcess, args ...string) error {
	return nil
}

func (c *Commands) help(p *proctl.DebuggedProcess, args ...string) error {
	fmt.Println("The following commands are available:")
	for _, cmd := range c.cmds {
		fmt.Printf("\t%s - %s\n", strings.Join(cmd.aliases, "|"), cmd.helpMsg)
	}
	return nil
}

func threads(p *proctl.DebuggedProcess, args ...string) error {
	for _, th := range p.Threads {
		prefix := "  "
		if th == p.CurrentThread {
			prefix = "* "
		}
		pc, err := th.CurrentPC()
		if err != nil {
			return err
		}
		f, l, fn := th.Process.GoSymTable.PCToLine(pc)
		if fn != nil {
			fmt.Printf("%sThread %d at %#v %s:%d %s\n", prefix, th.Id, pc, f, l, fn.Name)
		} else {
			fmt.Printf("%sThread %d at %#v\n", prefix, th.Id, pc)
		}
	}
	return nil
}

func thread(p *proctl.DebuggedProcess, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("you must specify a thread")
	}
	oldTid := p.CurrentThread.Id
	tid, err := strconv.Atoi(args[0])
	if err != nil {
		return err
	}

	err = p.SwitchThread(tid)
	if err != nil {
		return err
	}

	fmt.Printf("Switched from %d to %d\n", oldTid, tid)
	return nil
}

func goroutines(p *proctl.DebuggedProcess, args ...string) error {
	return p.PrintGoroutinesInfo()
}

func cont(p *proctl.DebuggedProcess, args ...string) error {
	err := p.Continue()
	if err != nil {
		return err
	}

	return printcontext(p)
}

func step(p *proctl.DebuggedProcess, args ...string) error {
	err := p.Step()
	if err != nil {
		return err
	}

	return printcontext(p)
}

func next(p *proctl.DebuggedProcess, args ...string) error {
	err := p.Next()
	if err != nil {
		return err
	}

	return printcontext(p)
}

func clear(p *proctl.DebuggedProcess, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("not enough arguments")
	}

	bp, err := p.ClearByLocation(args[0])
	if err != nil {
		return err
	}

	fmt.Printf("Breakpoint %d cleared at %#v for %s %s:%d\n", bp.ID, bp.Addr, bp.FunctionName, bp.File, bp.Line)

	return nil
}

type ById []*proctl.BreakPoint

func (a ById) Len() int           { return len(a) }
func (a ById) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ById) Less(i, j int) bool { return a[i].ID < a[j].ID }

func breakpoints(p *proctl.DebuggedProcess, args ...string) error {
	bps := make([]*proctl.BreakPoint, 0, len(p.BreakPoints)+4)

	for _, bp := range p.HWBreakPoints {
		if bp == nil {
			continue
		}
		bps = append(bps, bp)
	}

	for _, bp := range p.BreakPoints {
		if bp.Temp {
			continue
		}
		bps = append(bps, bp)
	}

	sort.Sort(ById(bps))
	for _, bp := range bps {
		fmt.Println(bp)
	}

	return nil
}

func breakpoint(p *proctl.DebuggedProcess, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("not enough arguments")
	}

	bp, err := p.BreakByLocation(args[0])
	if err != nil {
		return err
	}

	fmt.Printf("Breakpoint %d set at %#v for %s %s:%d\n", bp.ID, bp.Addr, bp.FunctionName, bp.File, bp.Line)

	return nil
}

func printVar(p *proctl.DebuggedProcess, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("not enough arguments")
	}

	val, err := p.EvalSymbol(args[0])
	if err != nil {
		return err
	}

	fmt.Println(val.Value)
	return nil
}

func filterVariables(vars []*proctl.Variable, filter *regexp.Regexp) []string {
	data := make([]string, 0, len(vars))
	for _, v := range vars {
		if v == nil {
			continue
		}
		if filter == nil || filter.Match([]byte(v.Name)) {
			data = append(data, fmt.Sprintf("%s = %s", v.Name, v.Value))
		}
	}
	return data
}

func info(p *proctl.DebuggedProcess, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("not enough arguments. expected info type [regex].")
	}

	// Allow for optional regex
	var filter *regexp.Regexp
	if len(args) >= 2 {
		var err error
		if filter, err = regexp.Compile(args[1]); err != nil {
			return fmt.Errorf("invalid filter argument: %s", err.Error())
		}
	}

	var data []string

	switch args[0] {
	case "sources":
		data = make([]string, 0, len(p.GoSymTable.Files))
		for f := range p.GoSymTable.Files {
			if filter == nil || filter.Match([]byte(f)) {
				data = append(data, f)
			}
		}

	case "funcs":
		data = make([]string, 0, len(p.GoSymTable.Funcs))
		for _, f := range p.GoSymTable.Funcs {
			if f.Sym != nil && (filter == nil || filter.Match([]byte(f.Name))) {
				data = append(data, f.Name)
			}
		}

	case "args":
		vars, err := p.CurrentThread.FunctionArguments()
		if err != nil {
			return nil
		}
		data = filterVariables(vars, filter)

	case "locals":
		vars, err := p.CurrentThread.LocalVariables()
		if err != nil {
			return nil
		}
		data = filterVariables(vars, filter)

	case "vars":
		vars, err := p.CurrentThread.PackageVariables()
		if err != nil {
			return nil
		}
		data = filterVariables(vars, filter)

	default:
		return fmt.Errorf("unsupported info type, must be args, funcs, locals, sources, or vars")
	}

	// sort and output data
	sort.Sort(sort.StringSlice(data))

	for _, d := range data {
		fmt.Println(d)
	}

	return nil
}

func printcontext(p *proctl.DebuggedProcess) error {
	var context []string

	regs, err := p.Registers()
	if err != nil {
		return err
	}

	f, l, fn := p.GoSymTable.PCToLine(regs.PC())

	if fn != nil {
		fmt.Printf("current loc: %s %s:%d\n", fn.Name, f, l)
		file, err := os.Open(f)
		if err != nil {
			return err
		}
		defer file.Close()

		buf := bufio.NewReader(file)
		for i := 1; i < l-5; i++ {
			_, err := buf.ReadString('\n')
			if err != nil && err != io.EOF {
				return err
			}
		}

		for i := l - 5; i <= l+5; i++ {
			line, err := buf.ReadString('\n')
			if err != nil {
				if err != io.EOF {
					return err
				}

				if err == io.EOF {
					break
				}
			}

			arrow := "  "
			if i == l {
				arrow = "=>"
			}

			context = append(context, fmt.Sprintf("\033[34m%s %d\033[0m: %s", arrow, i, line))
		}
	} else {
		fmt.Printf("Stopped at: 0x%x\n", regs.PC())
		context = append(context, "\033[34m=>\033[0m    no source available")
	}

	fmt.Println(strings.Join(context, ""))

	return nil
}
<|endoftext|>


<commit_before>// Copyright (c) Alex Ellis 2017. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package commands

import (
	"fmt"
	"os"

	"github.com/openfaas/faas-cli/proxy"
	"github.com/openfaas/faas-cli/stack"
	"github.com/spf13/cobra"
)

func init() {
	// Setup flags that are used by multiple commands (variables defined in faas.go)
	removeCmd.Flags().StringVarP(&gateway, "gateway", "g", defaultGateway, "Gateway URL starting with http(s)://")

	faasCmd.AddCommand(removeCmd)
}

// removeCmd deletes/removes OpenFaaS function containers
var removeCmd = &cobra.Command{
	Use: `remove FUNCTION_NAME [--gateway GATEWAY_URL]
  faas-cli remove -f YAML_FILE [--regex "REGEX"] [--filter "WILDCARD"]`,
	Aliases: []string{"rm"},
	Short:   "Remove deployed OpenFaaS functions",
	Long: `Removes/deletes deployed OpenFaaS functions either via the supplied YAML config
using the "--yaml" flag (which may contain multiple function definitions), or by
explicitly specifying a function name.`,
	Example: `  faas-cli remove -f https://domain/path/myfunctions.yml
  faas-cli remove -f ./stack.yml
  faas-cli remove -f ./stack.yml --filter "*gif*"
  faas-cli remove -f ./stack.yml --regex "fn[0-9]_.*"
  faas-cli remove url-ping
  faas-cli remove img2ansi --gateway==http://remote-site.com:8080`,
	RunE: runDelete,
}

func runDelete(cmd *cobra.Command, args []string) error {
	var services stack.Services
	var gatewayAddress string
	var yamlGateway string
	if len(yamlFile) > 0 {
		parsedServices, err := stack.ParseYAMLFile(yamlFile, regex, filter)
		if err != nil {
			return err
		}

		if parsedServices != nil {
			services = *parsedServices
			yamlGateway = services.Provider.GatewayURL
		}
	}

	gatewayAddress = getGatewayURL(gateway, defaultGateway, yamlGateway, os.Getenv(openFaaSURLEnvironment))

	if len(services.Functions) > 0 {
		if len(services.Provider.Network) == 0 {
			services.Provider.Network = defaultNetwork
		}

		for k, function := range services.Functions {
			function.Name = k
			fmt.Printf("Deleting: %s.\n", function.Name)

			proxy.DeleteFunction(gatewayAddress, function.Name)
		}
	} else {
		if len(args) < 1 {
			return fmt.Errorf("please provide the name of a function to delete")
		}

		functionName = args[0]
		fmt.Printf("Deleting: %s.\n", functionName)
		proxy.DeleteFunction(gateway, functionName)
	}

	return nil
}
<commit_msg>Remove command to honor OPENFAAS_URL env variable<commit_after>// Copyright (c) Alex Ellis 2017. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package commands

import (
	"fmt"
	"os"

	"github.com/openfaas/faas-cli/proxy"
	"github.com/openfaas/faas-cli/stack"
	"github.com/spf13/cobra"
)

func init() {
	// Setup flags that are used by multiple commands (variables defined in faas.go)
	removeCmd.Flags().StringVarP(&gateway, "gateway", "g", defaultGateway, "Gateway URL starting with http(s)://")

	faasCmd.AddCommand(removeCmd)
}

// removeCmd deletes/removes OpenFaaS function containers
var removeCmd = &cobra.Command{
	Use: `remove FUNCTION_NAME [--gateway GATEWAY_URL]
  faas-cli remove -f YAML_FILE [--regex "REGEX"] [--filter "WILDCARD"]`,
	Aliases: []string{"rm"},
	Short:   "Remove deployed OpenFaaS functions",
	Long: `Removes/deletes deployed OpenFaaS functions either via the supplied YAML config
using the "--yaml" flag (which may contain multiple function definitions), or by
explicitly specifying a function name.`,
	Example: `  faas-cli remove -f https://domain/path/myfunctions.yml
  faas-cli remove -f ./stack.yml
  faas-cli remove -f ./stack.yml --filter "*gif*"
  faas-cli remove -f ./stack.yml --regex "fn[0-9]_.*"
  faas-cli remove url-ping
  faas-cli remove img2ansi --gateway==http://remote-site.com:8080`,
	RunE: runDelete,
}

func runDelete(cmd *cobra.Command, args []string) error {
	var services stack.Services
	var gatewayAddress string
	var yamlGateway string
	if len(yamlFile) > 0 {
		parsedServices, err := stack.ParseYAMLFile(yamlFile, regex, filter)
		if err != nil {
			return err
		}

		if parsedServices != nil {
			services = *parsedServices
			yamlGateway = services.Provider.GatewayURL
		}
	}

	gatewayAddress = getGatewayURL(gateway, defaultGateway, yamlGateway, os.Getenv(openFaaSURLEnvironment))

	if len(services.Functions) > 0 {
		if len(services.Provider.Network) == 0 {
			services.Provider.Network = defaultNetwork
		}

		for k, function := range services.Functions {
			function.Name = k
			fmt.Printf("Deleting: %s.\n", function.Name)

			proxy.DeleteFunction(gatewayAddress, function.Name)
		}
	} else {
		if len(args) < 1 {
			return fmt.Errorf("please provide the name of a function to delete")
		}

		functionName = args[0]
		fmt.Printf("Deleting: %s.\n", functionName)
		proxy.DeleteFunction(gatewayAddress, functionName)
	}

	return nil
}
<|endoftext|>


<commit_before>package messages

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"gondola/astutil"
	"gondola/log"
	"gondola/pkg"
	"os"
	"path/filepath"
	"strings"
)

func DefaultFunctions() []*Function {
	return []*Function{
		// Singular functions without context
		{Name: "gondola/i18n.T"},
		{Name: "gondola/i18n.Errorf"},
		{Name: "gondola/i18n.Sprintf"},
		{Name: "gondola/i18n.NewError"},
		{Name: "gondola/mux.Context.T"},
		{Name: "T", Template: true},
		// Singular functions with context
		{Name: "gondola/i18n.Tc", Context: true},
		{Name: "gondola/i18n.Sprintfc", Context: true},
		{Name: "gondola/i18n.Errorfc", Context: true},
		{Name: "gondola/i18n.NewErrorc", Context: true},
		{Name: "gondola/mux.Context.Tc", Context: true},
		{Name: "Tc", Template: true, Context: true},
		// Plural functions without context
		{Name: "gondola/i18n.Tn", Plural: true},
		{Name: "gondola/i18n.Sprintfn", Plural: true},
		{Name: "gondola/i18n.Errorfn", Plural: true},
		{Name: "gondola/i18n.NewErrorn", Plural: true},
		{Name: "gondola/mux.Context.Tn", Plural: true},
		{Name: "Tn", Template: true, Plural: true},
		// Plural functions with context
		{Name: "gondola/i18n.Tnc", Context: true, Plural: true},
		{Name: "gondola/i18n.Errorfnc", Context: true, Plural: true},
		{Name: "gondola/i18n.Sprintfnc", Context: true, Plural: true},
		{Name: "gondola/i18n.NewErrornc", Context: true, Plural: true},
		{Name: "gondola/mux.Context.Tnc", Context: true, Plural: true},
		{Name: "Tnc", Template: true, Context: true, Plural: true},
	}
}

func DefaultTypes() []string {
	return []string{
		"gondola/i18n.String",
	}
}

func DefaultTagFields() []string {
	return []string{
		"help",
		"label",
		"placeholder",
	}
}

func Extract(dir string, functions []*Function, types []string, tagFields []string) ([]*Message, error) {
	messages := make(messageMap)
	err := extract(messages, dir, functions, types, tagFields)
	if err != nil {
		return nil, err
	}
	return messages.Messages(), nil
}

func extract(messages messageMap, dir string, functions []*Function, types []string, tagFields []string) error {
	f, err := os.Open(dir)
	if err != nil {
		return err
	}
	defer f.Close()
	infos, err := f.Readdir(-1)
	if err != nil {
		return err
	}
	for _, v := range infos {
		name := v.Name()
		p := filepath.Join(dir, name)
		if v.IsDir() {
			if !pkg.IsPackage(p) {
				if err := extract(messages, p, functions, types, tagFields); err != nil {
					return err
				}
			}
			continue
		}
		switch strings.ToLower(filepath.Ext(name)) {
		// TODO: templates, strings files
		case ".go":
			if err := extractGoMessages(messages, p, functions, types, tagFields); err != nil {
				return err
			}
		}
	}
	return nil
}

func extractGoMessages(messages messageMap, path string, functions []*Function, types []string, tagFields []string) error {
	log.Debugf("Extracting messages from Go file %s", path)
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
	if err != nil {
		return fmt.Errorf("error parsing go file %s: %s", path, err)
	}
	for _, v := range functions {
		if v.Template {
			continue
		}
		if err := extractGoFunc(messages, fset, f, v); err != nil {
			return err
		}
	}
	for _, v := range types {
		if err := extractGoType(messages, fset, f, v); err != nil {
			return err
		}
	}
	for _, v := range tagFields {
		if err := extractGoTagField(messages, fset, f, v); err != nil {
			return err
		}
	}
	return nil
}

func extractGoFunc(messages messageMap, fset *token.FileSet, f *ast.File, fn *Function) error {
	calls, err := astutil.Calls(fset, f, fn.Name)
	if err != nil {
		return err
	}
	n := 0
	if fn.Context {
		n++
	}
	var message *Message
	var position *token.Position
	for _, c := range calls {
		if fn.Plural {
			if len(c.Args) < n+3 {
				log.Debugf("Skipping plural function %s (%v) - not enough arguments", astutil.Ident(c.Fun), fset.Position(c.Pos()))
				continue
			}
			slit, spos := astutil.StringLiteral(fset, c.Args[n])
			if slit == "" || spos == nil {
				log.Debugf("Skipping first argument to plural function %s (%v) - not a literal", astutil.Ident(c.Fun), fset.Position(c.Pos()))
				continue
			}
			plit, ppos := astutil.StringLiteral(fset, c.Args[n+1])
			if plit == "" || ppos == nil {
				log.Debugf("Skipping second argument to plural function %s (%v) - not a literal", astutil.Ident(c.Fun), fset.Position(c.Pos()))
				continue
			}
			message = &Message{
				Singular: slit,
				Plural:   plit,
			}
			position = spos
		} else {
			if len(c.Args) < n+1 {
				log.Debugf("Skipping singular function %s (%v) - not enough arguments", astutil.Ident(c.Fun), fset.Position(c.Pos()))
				continue
			}
			lit, pos := astutil.StringLiteral(fset, c.Args[n])
			if lit == "" || pos == nil {
				log.Debugf("Skipping argument to singular function %s (%v) - not a literal", astutil.Ident(c.Fun), fset.Position(c.Pos()))
				continue
			}
			message = &Message{
				Singular: lit,
			}
			position = pos
		}
		if message != nil && position != nil {
			if fn.Context {
				ctx, cpos := astutil.StringLiteral(fset, c.Args[0])
				if ctx == "" || cpos == nil {
					log.Debugf("Skipping argument to context function %s (%v) - empty context", astutil.Ident(c.Fun), fset.Position(c.Pos()))
					continue
				}
				message.Context = ctx
			}
			if err := messages.Add(message, position, comments(fset, f, position)); err != nil {
				return err
			}
		}
	}
	return nil
}

func extractGoType(messages messageMap, fset *token.FileSet, f *ast.File, typ string) error {
	// for castings
	tf := &Function{Name: typ}
	if err := extractGoFunc(messages, fset, f, tf); err != nil {
		return err
	}
	strings, err := astutil.Strings(fset, f, typ)
	if err != nil {
		return err
	}
	for _, s := range strings {
		comment := comments(fset, f, s.Position)
		if err := messages.AddString(s, comment); err != nil {
			return err
		}
	}
	return nil
}

func extractGoTagField(messages messageMap, fset *token.FileSet, f *ast.File, tagField string) error {
	strings, err := astutil.TagFields(fset, f, tagField)
	if err != nil {
		return err
	}
	for _, s := range strings {
		comment := comments(fset, f, s.Position)
		if err := messages.AddString(s, comment); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Skip .po and .pot files when extracting strings<commit_after>package messages

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"gondola/astutil"
	"gondola/log"
	"gondola/pkg"
	"os"
	"path/filepath"
	"strings"
)

func DefaultFunctions() []*Function {
	return []*Function{
		// Singular functions without context
		{Name: "gondola/i18n.T"},
		{Name: "gondola/i18n.Errorf"},
		{Name: "gondola/i18n.Sprintf"},
		{Name: "gondola/i18n.NewError"},
		{Name: "gondola/mux.Context.T"},
		{Name: "T", Template: true},
		// Singular functions with context
		{Name: "gondola/i18n.Tc", Context: true},
		{Name: "gondola/i18n.Sprintfc", Context: true},
		{Name: "gondola/i18n.Errorfc", Context: true},
		{Name: "gondola/i18n.NewErrorc", Context: true},
		{Name: "gondola/mux.Context.Tc", Context: true},
		{Name: "Tc", Template: true, Context: true},
		// Plural functions without context
		{Name: "gondola/i18n.Tn", Plural: true},
		{Name: "gondola/i18n.Sprintfn", Plural: true},
		{Name: "gondola/i18n.Errorfn", Plural: true},
		{Name: "gondola/i18n.NewErrorn", Plural: true},
		{Name: "gondola/mux.Context.Tn", Plural: true},
		{Name: "Tn", Template: true, Plural: true},
		// Plural functions with context
		{Name: "gondola/i18n.Tnc", Context: true, Plural: true},
		{Name: "gondola/i18n.Errorfnc", Context: true, Plural: true},
		{Name: "gondola/i18n.Sprintfnc", Context: true, Plural: true},
		{Name: "gondola/i18n.NewErrornc", Context: true, Plural: true},
		{Name: "gondola/mux.Context.Tnc", Context: true, Plural: true},
		{Name: "Tnc", Template: true, Context: true, Plural: true},
	}
}

func DefaultTypes() []string {
	return []string{
		"gondola/i18n.String",
	}
}

func DefaultTagFields() []string {
	return []string{
		"help",
		"label",
		"placeholder",
	}
}

func Extract(dir string, functions []*Function, types []string, tagFields []string) ([]*Message, error) {
	messages := make(messageMap)
	err := extract(messages, dir, functions, types, tagFields)
	if err != nil {
		return nil, err
	}
	return messages.Messages(), nil
}

func extract(messages messageMap, dir string, functions []*Function, types []string, tagFields []string) error {
	f, err := os.Open(dir)
	if err != nil {
		return err
	}
	defer f.Close()
	infos, err := f.Readdir(-1)
	if err != nil {
		return err
	}
	for _, v := range infos {
		name := v.Name()
		p := filepath.Join(dir, name)
		if v.IsDir() {
			if !pkg.IsPackage(p) {
				if err := extract(messages, p, functions, types, tagFields); err != nil {
					return err
				}
			}
			continue
		}
		switch strings.ToLower(filepath.Ext(name)) {
		// TODO: templates, strings files
		case ".go":
			if err := extractGoMessages(messages, p, functions, types, tagFields); err != nil {
				return err
			}
		case ".po", ".pot":
			// Do nothing
		}
	}
	return nil
}

func extractGoMessages(messages messageMap, path string, functions []*Function, types []string, tagFields []string) error {
	log.Debugf("Extracting messages from Go file %s", path)
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
	if err != nil {
		return fmt.Errorf("error parsing go file %s: %s", path, err)
	}
	for _, v := range functions {
		if v.Template {
			continue
		}
		if err := extractGoFunc(messages, fset, f, v); err != nil {
			return err
		}
	}
	for _, v := range types {
		if err := extractGoType(messages, fset, f, v); err != nil {
			return err
		}
	}
	for _, v := range tagFields {
		if err := extractGoTagField(messages, fset, f, v); err != nil {
			return err
		}
	}
	return nil
}

func extractGoFunc(messages messageMap, fset *token.FileSet, f *ast.File, fn *Function) error {
	calls, err := astutil.Calls(fset, f, fn.Name)
	if err != nil {
		return err
	}
	n := 0
	if fn.Context {
		n++
	}
	var message *Message
	var position *token.Position
	for _, c := range calls {
		if fn.Plural {
			if len(c.Args) < n+3 {
				log.Debugf("Skipping plural function %s (%v) - not enough arguments", astutil.Ident(c.Fun), fset.Position(c.Pos()))
				continue
			}
			slit, spos := astutil.StringLiteral(fset, c.Args[n])
			if slit == "" || spos == nil {
				log.Debugf("Skipping first argument to plural function %s (%v) - not a literal", astutil.Ident(c.Fun), fset.Position(c.Pos()))
				continue
			}
			plit, ppos := astutil.StringLiteral(fset, c.Args[n+1])
			if plit == "" || ppos == nil {
				log.Debugf("Skipping second argument to plural function %s (%v) - not a literal", astutil.Ident(c.Fun), fset.Position(c.Pos()))
				continue
			}
			message = &Message{
				Singular: slit,
				Plural:   plit,
			}
			position = spos
		} else {
			if len(c.Args) < n+1 {
				log.Debugf("Skipping singular function %s (%v) - not enough arguments", astutil.Ident(c.Fun), fset.Position(c.Pos()))
				continue
			}
			lit, pos := astutil.StringLiteral(fset, c.Args[n])
			if lit == "" || pos == nil {
				log.Debugf("Skipping argument to singular function %s (%v) - not a literal", astutil.Ident(c.Fun), fset.Position(c.Pos()))
				continue
			}
			message = &Message{
				Singular: lit,
			}
			position = pos
		}
		if message != nil && position != nil {
			if fn.Context {
				ctx, cpos := astutil.StringLiteral(fset, c.Args[0])
				if ctx == "" || cpos == nil {
					log.Debugf("Skipping argument to context function %s (%v) - empty context", astutil.Ident(c.Fun), fset.Position(c.Pos()))
					continue
				}
				message.Context = ctx
			}
			if err := messages.Add(message, position, comments(fset, f, position)); err != nil {
				return err
			}
		}
	}
	return nil
}

func extractGoType(messages messageMap, fset *token.FileSet, f *ast.File, typ string) error {
	// for castings
	tf := &Function{Name: typ}
	if err := extractGoFunc(messages, fset, f, tf); err != nil {
		return err
	}
	strings, err := astutil.Strings(fset, f, typ)
	if err != nil {
		return err
	}
	for _, s := range strings {
		comment := comments(fset, f, s.Position)
		if err := messages.AddString(s, comment); err != nil {
			return err
		}
	}
	return nil
}

func extractGoTagField(messages messageMap, fset *token.FileSet, f *ast.File, tagField string) error {
	strings, err := astutil.TagFields(fset, f, tagField)
	if err != nil {
		return err
	}
	for _, s := range strings {
		comment := comments(fset, f, s.Position)
		if err := messages.AddString(s, comment); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package compose

import (
	"fmt"

	"golang.org/x/net/context"

	yaml "github.com/cloudfoundry-incubator/candiedyaml"
	dockerClient "github.com/docker/engine-api/client"
	"github.com/docker/libcompose/cli/logger"
	composeConfig "github.com/docker/libcompose/config"
	"github.com/docker/libcompose/docker"
	composeClient "github.com/docker/libcompose/docker/client"

	"github.com/docker/libcompose/project"
	"github.com/docker/libcompose/project/events"
	"github.com/docker/libcompose/project/options"
	"github.com/rancher/os/config"
	rosDocker "github.com/rancher/os/docker"
	"github.com/rancher/os/log"
	"github.com/rancher/os/util"
	"github.com/rancher/os/util/network"
)

func CreateService(cfg *config.CloudConfig, name string, serviceConfig *composeConfig.ServiceConfigV1) (project.Service, error) {
	if cfg == nil {
		cfg = config.LoadConfig()
	}

	p, err := CreateServiceSet("once", cfg, map[string]*composeConfig.ServiceConfigV1{
		name: serviceConfig,
	})
	if err != nil {
		return nil, err
	}

	return p.CreateService(name)
}

func CreateServiceSet(name string, cfg *config.CloudConfig, configs map[string]*composeConfig.ServiceConfigV1) (*project.Project, error) {
	p, err := newProject(name, cfg, nil, nil)
	if err != nil {
		return nil, err
	}

	addServices(p, map[interface{}]interface{}{}, configs)

	return p, nil
}

func RunServiceSet(name string, cfg *config.CloudConfig, configs map[string]*composeConfig.ServiceConfigV1) (*project.Project, error) {
	p, err := CreateServiceSet(name, cfg, configs)
	if err != nil {
		return nil, err
	}
	return p, p.Up(context.Background(), options.Up{
		Log: cfg.Rancher.Log,
	})
}

func GetProject(cfg *config.CloudConfig, networkingAvailable, loadConsole bool) (*project.Project, error) {
	return newCoreServiceProject(cfg, networkingAvailable, loadConsole)
}

func newProject(name string, cfg *config.CloudConfig, environmentLookup composeConfig.EnvironmentLookup, authLookup *rosDocker.ConfigAuthLookup) (*project.Project, error) {
	clientFactory, err := rosDocker.NewClientFactory(composeClient.Options{})
	if err != nil {
		return nil, err
	}

	if environmentLookup == nil {
		environmentLookup = rosDocker.NewConfigEnvironment(cfg)
	}
	if authLookup == nil {
		authLookup = rosDocker.NewConfigAuthLookup(cfg)
	}

	serviceFactory := &rosDocker.ServiceFactory{
		Deps: map[string][]string{},
	}
	context := &docker.Context{
		ClientFactory: clientFactory,
		AuthLookup:    authLookup,
		Context: project.Context{
			ProjectName:       name,
			EnvironmentLookup: environmentLookup,
			ServiceFactory:    serviceFactory,
			LoggerFactory:     logger.NewColorLoggerFactory(),
		},
	}
	serviceFactory.Context = context

	authLookup.SetContext(context)

	return docker.NewProject(context, &composeConfig.ParseOptions{
		Interpolate: true,
		Validate:    false,
		Preprocess:  preprocessServiceMap,
	})
}

func preprocessServiceMap(serviceMap composeConfig.RawServiceMap) (composeConfig.RawServiceMap, error) {
	newServiceMap := make(composeConfig.RawServiceMap)

	for k, v := range serviceMap {
		newServiceMap[k] = make(composeConfig.RawService)

		for k2, v2 := range v {
			if k2 == "environment" || k2 == "labels" {
				newServiceMap[k][k2] = preprocess(v2, true)
			} else {
				newServiceMap[k][k2] = preprocess(v2, false)
			}

		}
	}

	return newServiceMap, nil
}

func preprocess(item interface{}, replaceTypes bool) interface{} {
	switch typedDatas := item.(type) {

	case map[interface{}]interface{}:
		newMap := make(map[interface{}]interface{})

		for key, value := range typedDatas {
			newMap[key] = preprocess(value, replaceTypes)
		}
		return newMap

	case []interface{}:
		// newArray := make([]interface{}, 0) will cause golint to complain
		var newArray []interface{}
		newArray = make([]interface{}, 0)

		for _, value := range typedDatas {
			newArray = append(newArray, preprocess(value, replaceTypes))
		}
		return newArray

	default:
		if replaceTypes {
			return fmt.Sprint(item)
		}
		return item
	}
}

func addServices(p *project.Project, enabled map[interface{}]interface{}, configs map[string]*composeConfig.ServiceConfigV1) map[interface{}]interface{} {
	serviceConfigsV2, _ := composeConfig.ConvertServices(configs)

	// Note: we ignore errors while loading services
	unchanged := true
	for name, serviceConfig := range serviceConfigsV2 {
		hash := composeConfig.GetServiceHash(name, serviceConfig)

		if enabled[name] == hash {
			continue
		}

		if err := p.AddConfig(name, serviceConfig); err != nil {
			log.Infof("Failed loading service %s", name)
			continue
		}

		if unchanged {
			enabled = util.MapCopy(enabled)
			unchanged = false
		}
		enabled[name] = hash
	}
	return enabled
}

func adjustContainerNames(m map[interface{}]interface{}) map[interface{}]interface{} {
	for k, v := range m {
		if k, ok := k.(string); ok {
			if v, ok := v.(map[interface{}]interface{}); ok {
				if _, ok := v["container_name"]; !ok {
					v["container_name"] = k
				}
			}
		}
	}
	return m
}

func newCoreServiceProject(cfg *config.CloudConfig, useNetwork, loadConsole bool) (*project.Project, error) {
	environmentLookup := rosDocker.NewConfigEnvironment(cfg)
	authLookup := rosDocker.NewConfigAuthLookup(cfg)

	p, err := newProject("os", cfg, environmentLookup, authLookup)
	if err != nil {
		return nil, err
	}

	projectEvents := make(chan events.Event)
	p.AddListener(project.NewDefaultListener(p))
	p.AddListener(projectEvents)

	p.ReloadCallback = projectReload(p, &useNetwork, loadConsole, environmentLookup, authLookup)

	go func() {
		for event := range projectEvents {
			if event.EventType == events.ContainerStarted && event.ServiceName == "network" {
				useNetwork = true
			}
		}
	}()

	err = p.ReloadCallback()
	if err != nil {
		log.Errorf("Failed to reload os: %v", err)
		return nil, err
	}

	return p, nil
}

func StageServices(cfg *config.CloudConfig, services ...string) error {
	p, err := newProject("stage-services", cfg, nil, nil)
	if err != nil {
		return err
	}

	for _, service := range services {
		bytes, err := network.LoadServiceResource(service, true, cfg)
		if err != nil {
			return fmt.Errorf("Failed to load %s : %v", service, err)
		}

		m := map[interface{}]interface{}{}
		if err := yaml.Unmarshal(bytes, &m); err != nil {
			return fmt.Errorf("Failed to parse YAML configuration: %s : %v", service, err)
		}

		bytes, err = yaml.Marshal(m)
		if err != nil {
			return fmt.Errorf("Failed to marshal YAML configuration: %s : %v", service, err)
		}

		err = p.Load(bytes)
		if err != nil {
			return fmt.Errorf("Failed to load %s : %v", service, err)
		}
	}

	// Reduce service configurations to just image and labels
	needToPull := false
	for _, serviceName := range p.ServiceConfigs.Keys() {
		serviceConfig, _ := p.ServiceConfigs.Get(serviceName)

		// test to see if we need to Pull
		var client dockerClient.APIClient
		if serviceConfig.Labels[config.ScopeLabel] != config.System {
			client, err = rosDocker.NewDefaultClient()
			if err != nil {
				log.Error(err)
			}
		} else {
			client, err = rosDocker.NewSystemClient()
			if err != nil {
				log.Error(err)
			}
		}
		if client != nil {
			_, _, err := client.ImageInspectWithRaw(context.Background(), serviceConfig.Image, false)
			if err == nil {
				log.Infof("Service %s using local image %s", serviceName, serviceConfig.Image)
				continue
			}
		}
		needToPull = true

		p.ServiceConfigs.Add(serviceName, &composeConfig.ServiceConfig{
			Image:  serviceConfig.Image,
			Labels: serviceConfig.Labels,
		})
	}

	if needToPull {
		return p.Pull(context.Background())
	}
	return nil
}
<commit_msg>cache the user/system client if its created<commit_after>package compose

import (
	"fmt"

	"golang.org/x/net/context"

	yaml "github.com/cloudfoundry-incubator/candiedyaml"
	dockerClient "github.com/docker/engine-api/client"
	"github.com/docker/libcompose/cli/logger"
	composeConfig "github.com/docker/libcompose/config"
	"github.com/docker/libcompose/docker"
	composeClient "github.com/docker/libcompose/docker/client"

	"github.com/docker/libcompose/project"
	"github.com/docker/libcompose/project/events"
	"github.com/docker/libcompose/project/options"
	"github.com/rancher/os/config"
	rosDocker "github.com/rancher/os/docker"
	"github.com/rancher/os/log"
	"github.com/rancher/os/util"
	"github.com/rancher/os/util/network"
)

func CreateService(cfg *config.CloudConfig, name string, serviceConfig *composeConfig.ServiceConfigV1) (project.Service, error) {
	if cfg == nil {
		cfg = config.LoadConfig()
	}

	p, err := CreateServiceSet("once", cfg, map[string]*composeConfig.ServiceConfigV1{
		name: serviceConfig,
	})
	if err != nil {
		return nil, err
	}

	return p.CreateService(name)
}

func CreateServiceSet(name string, cfg *config.CloudConfig, configs map[string]*composeConfig.ServiceConfigV1) (*project.Project, error) {
	p, err := newProject(name, cfg, nil, nil)
	if err != nil {
		return nil, err
	}

	addServices(p, map[interface{}]interface{}{}, configs)

	return p, nil
}

func RunServiceSet(name string, cfg *config.CloudConfig, configs map[string]*composeConfig.ServiceConfigV1) (*project.Project, error) {
	p, err := CreateServiceSet(name, cfg, configs)
	if err != nil {
		return nil, err
	}
	return p, p.Up(context.Background(), options.Up{
		Log: cfg.Rancher.Log,
	})
}

func GetProject(cfg *config.CloudConfig, networkingAvailable, loadConsole bool) (*project.Project, error) {
	return newCoreServiceProject(cfg, networkingAvailable, loadConsole)
}

func newProject(name string, cfg *config.CloudConfig, environmentLookup composeConfig.EnvironmentLookup, authLookup *rosDocker.ConfigAuthLookup) (*project.Project, error) {
	clientFactory, err := rosDocker.NewClientFactory(composeClient.Options{})
	if err != nil {
		return nil, err
	}

	if environmentLookup == nil {
		environmentLookup = rosDocker.NewConfigEnvironment(cfg)
	}
	if authLookup == nil {
		authLookup = rosDocker.NewConfigAuthLookup(cfg)
	}

	serviceFactory := &rosDocker.ServiceFactory{
		Deps: map[string][]string{},
	}
	context := &docker.Context{
		ClientFactory: clientFactory,
		AuthLookup:    authLookup,
		Context: project.Context{
			ProjectName:       name,
			EnvironmentLookup: environmentLookup,
			ServiceFactory:    serviceFactory,
			LoggerFactory:     logger.NewColorLoggerFactory(),
		},
	}
	serviceFactory.Context = context

	authLookup.SetContext(context)

	return docker.NewProject(context, &composeConfig.ParseOptions{
		Interpolate: true,
		Validate:    false,
		Preprocess:  preprocessServiceMap,
	})
}

func preprocessServiceMap(serviceMap composeConfig.RawServiceMap) (composeConfig.RawServiceMap, error) {
	newServiceMap := make(composeConfig.RawServiceMap)

	for k, v := range serviceMap {
		newServiceMap[k] = make(composeConfig.RawService)

		for k2, v2 := range v {
			if k2 == "environment" || k2 == "labels" {
				newServiceMap[k][k2] = preprocess(v2, true)
			} else {
				newServiceMap[k][k2] = preprocess(v2, false)
			}

		}
	}

	return newServiceMap, nil
}

func preprocess(item interface{}, replaceTypes bool) interface{} {
	switch typedDatas := item.(type) {

	case map[interface{}]interface{}:
		newMap := make(map[interface{}]interface{})

		for key, value := range typedDatas {
			newMap[key] = preprocess(value, replaceTypes)
		}
		return newMap

	case []interface{}:
		// newArray := make([]interface{}, 0) will cause golint to complain
		var newArray []interface{}
		newArray = make([]interface{}, 0)

		for _, value := range typedDatas {
			newArray = append(newArray, preprocess(value, replaceTypes))
		}
		return newArray

	default:
		if replaceTypes {
			return fmt.Sprint(item)
		}
		return item
	}
}

func addServices(p *project.Project, enabled map[interface{}]interface{}, configs map[string]*composeConfig.ServiceConfigV1) map[interface{}]interface{} {
	serviceConfigsV2, _ := composeConfig.ConvertServices(configs)

	// Note: we ignore errors while loading services
	unchanged := true
	for name, serviceConfig := range serviceConfigsV2 {
		hash := composeConfig.GetServiceHash(name, serviceConfig)

		if enabled[name] == hash {
			continue
		}

		if err := p.AddConfig(name, serviceConfig); err != nil {
			log.Infof("Failed loading service %s", name)
			continue
		}

		if unchanged {
			enabled = util.MapCopy(enabled)
			unchanged = false
		}
		enabled[name] = hash
	}
	return enabled
}

func adjustContainerNames(m map[interface{}]interface{}) map[interface{}]interface{} {
	for k, v := range m {
		if k, ok := k.(string); ok {
			if v, ok := v.(map[interface{}]interface{}); ok {
				if _, ok := v["container_name"]; !ok {
					v["container_name"] = k
				}
			}
		}
	}
	return m
}

func newCoreServiceProject(cfg *config.CloudConfig, useNetwork, loadConsole bool) (*project.Project, error) {
	environmentLookup := rosDocker.NewConfigEnvironment(cfg)
	authLookup := rosDocker.NewConfigAuthLookup(cfg)

	p, err := newProject("os", cfg, environmentLookup, authLookup)
	if err != nil {
		return nil, err
	}

	projectEvents := make(chan events.Event)
	p.AddListener(project.NewDefaultListener(p))
	p.AddListener(projectEvents)

	p.ReloadCallback = projectReload(p, &useNetwork, loadConsole, environmentLookup, authLookup)

	go func() {
		for event := range projectEvents {
			if event.EventType == events.ContainerStarted && event.ServiceName == "network" {
				useNetwork = true
			}
		}
	}()

	err = p.ReloadCallback()
	if err != nil {
		log.Errorf("Failed to reload os: %v", err)
		return nil, err
	}

	return p, nil
}

func StageServices(cfg *config.CloudConfig, services ...string) error {
	p, err := newProject("stage-services", cfg, nil, nil)
	if err != nil {
		return err
	}

	for _, service := range services {
		bytes, err := network.LoadServiceResource(service, true, cfg)
		if err != nil {
			return fmt.Errorf("Failed to load %s : %v", service, err)
		}

		m := map[interface{}]interface{}{}
		if err := yaml.Unmarshal(bytes, &m); err != nil {
			return fmt.Errorf("Failed to parse YAML configuration: %s : %v", service, err)
		}

		bytes, err = yaml.Marshal(m)
		if err != nil {
			return fmt.Errorf("Failed to marshal YAML configuration: %s : %v", service, err)
		}

		err = p.Load(bytes)
		if err != nil {
			return fmt.Errorf("Failed to load %s : %v", service, err)
		}
	}

	// Reduce service configurations to just image and labels
	needToPull := false
	var client, userClient, systemClient dockerClient.APIClient
	for _, serviceName := range p.ServiceConfigs.Keys() {
		serviceConfig, _ := p.ServiceConfigs.Get(serviceName)

		// test to see if we need to Pull
		if serviceConfig.Labels[config.ScopeLabel] != config.System {
			if userClient == nil {
				userClient, err = rosDocker.NewDefaultClient()
				if err != nil {
					log.Error(err)
				}

			}
			client = userClient
		} else {
			if systemClient == nil {
				systemClient, err = rosDocker.NewSystemClient()
				if err != nil {
					log.Error(err)
				}
				client = systemClient
			}
		}
		if client != nil {
			_, _, err := client.ImageInspectWithRaw(context.Background(), serviceConfig.Image, false)
			if err == nil {
				log.Infof("Service %s using local image %s", serviceName, serviceConfig.Image)
				continue
			}
		}
		needToPull = true

		p.ServiceConfigs.Add(serviceName, &composeConfig.ServiceConfig{
			Image:  serviceConfig.Image,
			Labels: serviceConfig.Labels,
		})
	}

	if needToPull {
		return p.Pull(context.Background())
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Tigera, 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 constants

const (
	DatastoreIntro = `Set the Calico datastore access information in the environment variables or
or supply details in a config file.

`
	DefaultConfigPath = "/etc/calico/calicoctl.cfg"
)
<commit_msg>remove redundant “or” in `calicoctl help text`<commit_after>// Copyright (c) 2016 Tigera, 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 constants

const (
	DatastoreIntro = `Set the Calico datastore access information in the environment variables or
supply details in a config file.

`
	DefaultConfigPath = "/etc/calico/calicoctl.cfg"
)
<|endoftext|>


<commit_before><commit_msg>Remove file aseq.go<commit_after><|endoftext|>


<commit_before>package testutil

import (
	"os/exec"
	"runtime"
	"syscall"
	"testing"
)

func ExecCompatible(t *testing.T) {
	if runtime.GOOS != "windows" && syscall.Geteuid() != 0 {
		t.Skip("Must be root on non-windows environments to run test")
	}
}

func QemuCompatible(t *testing.T) {
	if runtime.GOOS == "windows"  {
		t.Skip("Must be on non-windows environments to run test")
	}
	// else see if qemu exists
	_, err := exec.Command("qemu-system-x86_64", "-version").CombinedOutput()
	if err != nil {
		t.Skip("Must have Qemu installed for Qemu specific tests to run")
	}
}

func RktCompatible(t *testing.T) {
	if runtime.GOOS == "windows" || syscall.Geteuid() != 0 {
		t.Skip("Must be root on non-windows environments to run test")
	}
	// else see if rkt exists
	_, err := exec.Command("rkt", "version").CombinedOutput()
	if err != nil {
		t.Skip("Must have rkt installed for rkt specific tests to run")
	}
}

func MountCompatible(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip("Windows does not support mount")
	}

	if syscall.Geteuid() != 0 {
		t.Skip("Must be root to run test")
	}
}
<commit_msg>Run gofmt<commit_after>package testutil

import (
	"os/exec"
	"runtime"
	"syscall"
	"testing"
)

func ExecCompatible(t *testing.T) {
	if runtime.GOOS != "windows" && syscall.Geteuid() != 0 {
		t.Skip("Must be root on non-windows environments to run test")
	}
}

func QemuCompatible(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip("Must be on non-windows environments to run test")
	}
	// else see if qemu exists
	_, err := exec.Command("qemu-system-x86_64", "-version").CombinedOutput()
	if err != nil {
		t.Skip("Must have Qemu installed for Qemu specific tests to run")
	}
}

func RktCompatible(t *testing.T) {
	if runtime.GOOS == "windows" || syscall.Geteuid() != 0 {
		t.Skip("Must be root on non-windows environments to run test")
	}
	// else see if rkt exists
	_, err := exec.Command("rkt", "version").CombinedOutput()
	if err != nil {
		t.Skip("Must have rkt installed for rkt specific tests to run")
	}
}

func MountCompatible(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip("Windows does not support mount")
	}

	if syscall.Geteuid() != 0 {
		t.Skip("Must be root to run test")
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The mccdaq developers. All rights reserved.
// Project site: https://github.com/gotmc/mccdaq
// Use of this source code is governed by a MIT-style license that
// can be found in the LICENSE.txt file for the project.

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/gotmc/libusb"
	"github.com/gotmc/mccdaq/usb1608fsplus"
)

func main() {
	ctx, err := libusb.Init()
	if err != nil {
		log.Fatal("Couldn't create USB context. Ending now.")
	}
	defer ctx.Exit()

	// Create the USB-1608FS-Plus DAQ device
	daq, err := usb1608fsplus.NewViaSN(ctx, "01ACD31D")
	if err != nil {
		log.Fatalf("Something bad getting S/N happened: %s", err)
	}
	// If you just want to grab the first USB-1608FS-Plus that's attached, you
	// can use:
	// daq, err := usb1608fsplus.GetFirstDevice(ctx)

	// Print some info about the device
	log.Printf("Vendor ID = 0x%x / Product ID = 0x%x\n", daq.DeviceDescriptor.VendorID,
		daq.DeviceDescriptor.ProductID)
	serialNumber, err := daq.SerialNumber()
	log.Printf("Serial number via control transfer = %s", serialNumber)
	log.Printf("USB ConfigurationIndex = %d\n", daq.ConfigDescriptor.ConfigurationIndex)
	log.Printf("Bulk endpoint address = 0x%x (%b)\n",
		daq.BulkEndpoint.EndpointAddress, daq.BulkEndpoint.EndpointAddress)

	// Test blinking the LED
	numBlinks := 5
	actualBlinks, err := daq.BlinkLED(numBlinks)
	if err != nil {
		fmt.Errorf("Error blinking LED %s", err)
	}
	log.Printf("Sent %d byte of data to blink LED %d times.", actualBlinks, numBlinks)

	// Get status
	status, err := daq.Status()
	log.Printf("Status = %v", status)

	// Read the calibration memory to setup the gain table
	gainTable, _ := daq.BuildGainTable()
	log.Printf("Slope = %v\n", gainTable.Slope)
	log.Printf("Intercept = %v\n", gainTable.Intercept)

	/**************************
	* Start the Analog Scan   *
	**************************/

	// Setup stuff
	const millisecondDelay = 100
	splitScansIn := 4
	totalScans := 512
	scansPerRead := totalScans / splitScansIn
	var frequency float64 = 20000.0

	// Create new analog input and ensure the scan is stopped and buffer cleared
	ai := daq.NewAnalogInput(frequency)
	ai.StopScan()
	time.Sleep(millisecondDelay * time.Millisecond)
	ai.ClearScanBuffer()
	// Setup the analog input scan
	ai.TransferMode = usb1608fsplus.BlockTransfer
	ai.DebugMode = true
	ai.ConfigureChannel(0, true, 5, "Vin1")
	ai.SetScanRanges()
	// Read the scan ranges
	time.Sleep(millisecondDelay * time.Millisecond)
	scanRanges, err := ai.ScanRanges()
	log.Printf("Ranges = %v\n", scanRanges)

	// Start the scan
	ai.StartScan(totalScans)
	for j := 0; j < splitScansIn; j++ {
		time.Sleep(millisecondDelay * time.Millisecond)
		data, err := ai.ReadScan(scansPerRead)
		if err != nil {
			log.Fatalf("Error reading scan: %s", err)
		}
		// FIXME(mdr): Are we receiving the correct values when reading multiple
		// times????
		for i := 0; i < 8; i += 2 {
			log.Printf("data[%d:%d] = %d %d\n", i, i+1, data[i+1], data[i])
		}
		for i := scansPerRead - 8; i < scansPerRead; i += 2 {
			log.Printf("data[%d:%d] = %d %d\n", i, i+1, data[i+1], data[i])
		}
		log.Printf("data is %d bytes\n", len(data))
	}
	ai.StopScan()
	time.Sleep(millisecondDelay * time.Millisecond)
	daq.Close()

}
<commit_msg>Correct the printing of the analog data in example<commit_after>// Copyright (c) 2016 The mccdaq developers. All rights reserved.
// Project site: https://github.com/gotmc/mccdaq
// Use of this source code is governed by a MIT-style license that
// can be found in the LICENSE.txt file for the project.

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/gotmc/libusb"
	"github.com/gotmc/mccdaq/usb1608fsplus"
)

const millisecondDelay = 100

func main() {
	ctx, err := libusb.Init()
	if err != nil {
		log.Fatal("Couldn't create USB context. Ending now.")
	}
	defer ctx.Exit()

	// Create the USB-1608FS-Plus DAQ device
	daq, err := usb1608fsplus.NewViaSN(ctx, "01ACD31D")
	if err != nil {
		log.Fatalf("Something bad getting S/N happened: %s", err)
	}
	// If you just want to grab the first USB-1608FS-Plus that's attached, you
	// can use:
	// daq, err := usb1608fsplus.GetFirstDevice(ctx)

	// Print some info about the device
	log.Printf("Vendor ID = 0x%x / Product ID = 0x%x\n", daq.DeviceDescriptor.VendorID,
		daq.DeviceDescriptor.ProductID)
	serialNumber, err := daq.SerialNumber()
	log.Printf("Serial number via control transfer = %s", serialNumber)
	log.Printf("USB ConfigurationIndex = %d\n", daq.ConfigDescriptor.ConfigurationIndex)
	log.Printf("Bulk endpoint address = 0x%x (%b)\n",
		daq.BulkEndpoint.EndpointAddress, daq.BulkEndpoint.EndpointAddress)

	// Test blinking the LED
	numBlinks := 5
	actualBlinks, err := daq.BlinkLED(numBlinks)
	if err != nil {
		fmt.Errorf("Error blinking LED %s", err)
	}
	log.Printf("Sent %d byte of data to blink LED %d times.", actualBlinks, numBlinks)

	// Get status
	status, err := daq.Status()
	log.Printf("Status = %v", status)

	// Read the calibration memory to setup the gain table
	gainTable, _ := daq.BuildGainTable()
	log.Printf("Slope = %v\n", gainTable.Slope)
	log.Printf("Intercept = %v\n", gainTable.Intercept)

	/**************************
	* Start the Analog Scan   *
	**************************/

	// Create new analog input and ensure the scan is stopped and buffer cleared
	var frequency float64 = 20000.0
	ai := daq.NewAnalogInput(frequency)
	ai.StopScan()
	time.Sleep(millisecondDelay * time.Millisecond)
	ai.ClearScanBuffer()

	// Setup the analog input scan
	ai.TransferMode = usb1608fsplus.BlockTransfer
	ai.DebugMode = true
	ai.ConfigureChannel(0, true, 5, "Vin1")
	ai.SetScanRanges()

	// Read the scan ranges
	time.Sleep(millisecondDelay * time.Millisecond)
	scanRanges, err := ai.ScanRanges()
	log.Printf("Ranges = %v\n", scanRanges)

	// Read the totalScans using splitScansIn number of scans
	splitScansIn := 2
	totalScans := 1024
	scansPerRead := totalScans / splitScansIn
	ai.StartScan(totalScans)
	for j := 0; j < splitScansIn; j++ {
		time.Sleep(millisecondDelay * time.Millisecond)
		data, err := ai.ReadScan(scansPerRead)
		if err != nil {
			log.Fatalf("Error reading scan: %s", err)
		}
		// Print the first 8 bytes and the last 8 bytes of each read
		bytesToShow := 8
		for i := 0; i < bytesToShow; i += 2 {
			log.Printf("data[%d:%d] = 0x%02x%02x\n", i, i+1, data[i+1], data[i])
		}
		for i := len(data) - bytesToShow; i < len(data); i += 2 {
			log.Printf("data[%d:%d] = 0x%02x%02x\n", i, i+1, data[i+1], data[i])
		}
		log.Printf("data is %d bytes\n", len(data))
	}
	// Stop the analog scan and close the DAQ
	ai.StopScan()
	time.Sleep(millisecondDelay * time.Millisecond)
	daq.Close()
}
<|endoftext|>


<commit_before>/*
Copyright 2017 Mirantis

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 network

import (
	"encoding/json"
	"fmt"
	"log"
	"net"

	"github.com/containernetworking/cni/pkg/ns"
	cnicurrent "github.com/containernetworking/cni/pkg/types/current"
	"github.com/vishvananda/netlink"

	"github.com/Mirantis/virtlet/pkg/cni"
	"github.com/Mirantis/virtlet/pkg/nettools"
	"github.com/Mirantis/virtlet/pkg/utils"
)

// FakeCNIVethPair represents a veth pair created by the fake CNI
type FakeCNIVethPair struct {
	HostSide netlink.Link
	ContSide netlink.Link
}

type fakeCNIEntry struct {
	podId, podName, podNS   string
	info, infoAfterTeardown *cnicurrent.Result
	extraRoutes             map[int][]netlink.Route
	hostNS, contNS          ns.NetNS
	veths                   []FakeCNIVethPair
	added                   bool
	removed                 bool
	useBadResult            bool
}

func (e *fakeCNIEntry) addSandboxToNetwork(ifaceIndex int) error {
	iface := e.info.Interfaces[ifaceIndex]
	iface.Sandbox = cni.PodNetNSPath(e.podId)

	var err error
	e.contNS, err = ns.GetNS(iface.Sandbox)
	if err != nil {
		return fmt.Errorf("can't get pod netns (path %q): %v", iface.Sandbox, err)
	}

	var vp FakeCNIVethPair
	if err := e.hostNS.Do(func(ns.NetNS) error {
		var err error
		vp.HostSide, vp.ContSide, err = nettools.CreateEscapeVethPair(e.contNS, iface.Name, 1500)
		return err
	}); err != nil {
		return fmt.Errorf("failed to create escape veth pair: %v", err)
	}

	return e.contNS.Do(func(ns.NetNS) error {
		hwAddr, err := net.ParseMAC(iface.Mac)
		if err != nil {
			return fmt.Errorf("error parsing hwaddr %q: %v", iface.Mac, err)
		}
		if err := nettools.SetHardwareAddr(vp.ContSide, hwAddr); err != nil {
			return fmt.Errorf("SetHardwareAddr(): %v", err)
		}
		// mac address changed, reload the link
		vp.ContSide, err = netlink.LinkByIndex(vp.ContSide.Attrs().Index)
		if err != nil {
			return fmt.Errorf("can't reload container veth info: %v", err)
		}
		if err := nettools.ConfigureLink(vp.ContSide, e.info); err != nil {
			return fmt.Errorf("error configuring link %q: %v", iface.Name, err)
		}
		if e.extraRoutes != nil {
			for _, r := range e.extraRoutes[ifaceIndex] {
				if r.Scope == nettools.SCOPE_LINK {
					r.LinkIndex = vp.ContSide.Attrs().Index
				}
				if err := netlink.RouteAdd(&r); err != nil {
					return fmt.Errorf("Failed to add route %#v: %v", r, err)
				}
			}
		}
		e.veths = append(e.veths, vp)
		e.added = true
		return nil
	})
}

func (c *fakeCNIEntry) captureNetworkConfigAfterTeardown(podId string) error {
	return c.contNS.Do(func(ns.NetNS) error {
		for _, ipConfig := range c.info.IPs {
			ifaceIndex := ipConfig.Interface
			if ifaceIndex > len(c.info.Interfaces) {
				return fmt.Errorf("bad interface index %d", ifaceIndex)
			}
			iface := c.info.Interfaces[ifaceIndex]
			link, err := netlink.LinkByName(iface.Name)
			if err != nil {
				return fmt.Errorf("can't find link %q: %v", iface.Name, err)
			}
			linkInfo, err := nettools.ExtractLinkInfo(link, cni.PodNetNSPath(podId))
			if err != nil {
				return fmt.Errorf("error extracting link info: %v", err)
			}
			if c.infoAfterTeardown == nil {
				c.infoAfterTeardown = linkInfo
			} else {
				if len(linkInfo.Interfaces) != 1 {
					return fmt.Errorf("more than one interface extracted")
				}
				if len(linkInfo.IPs) != 1 {
					return fmt.Errorf("more than one ip config extracted")
				}
				linkInfo.IPs[0].Interface = len(c.infoAfterTeardown.Interfaces)
				c.infoAfterTeardown.IPs = append(c.infoAfterTeardown.IPs, linkInfo.IPs[0])
				c.infoAfterTeardown.Interfaces = append(c.infoAfterTeardown.Interfaces, linkInfo.Interfaces[0])
			}
		}
		return nil
	})
}

func (e *fakeCNIEntry) cleanup() {
	if e.contNS != nil {
		e.contNS.Close()
	}
}

func podKey(podId, podName, podNS string) string {
	return fmt.Sprintf("%s:%s:%s", podId, podName, podNS)
}

// FakeCNIClient fakes a CNI client. It's only good for one-time
// network setup for a single pod network namespace
type FakeCNIClient struct {
	// DummyPodId is an id of dummy pod which is used by the
	// Calico workaround
	DummyPodId string
	entries    map[string]*fakeCNIEntry
}

var _ cni.CNIClient = &FakeCNIClient{}

func NewFakeCNIClient() *FakeCNIClient {
	return &FakeCNIClient{
		DummyPodId: utils.NewUuid(),
		entries:    make(map[string]*fakeCNIEntry),
	}
}

func (c *FakeCNIClient) ExpectPod(podId, podName, podNS string, info *cnicurrent.Result, hostNS ns.NetNS, extraRoutes map[int][]netlink.Route) {
	c.entries[podKey(podId, podName, podNS)] = &fakeCNIEntry{
		podId:       podId,
		podName:     podName,
		podNS:       podNS,
		info:        info,
		hostNS:      hostNS,
		extraRoutes: extraRoutes,
	}
}

func (c *FakeCNIClient) ExpectDummyPod(info *cnicurrent.Result, hostNS ns.NetNS, extraRoutes map[int][]netlink.Route) {
	c.ExpectPod(c.DummyPodId, "", "", info, hostNS, extraRoutes)
}

func (c *FakeCNIClient) GetDummyNetwork() (*cnicurrent.Result, string, error) {
	if err := cni.CreateNetNS(c.DummyPodId); err != nil {
		return nil, "", fmt.Errorf("couldn't create netns for dummy pod %q: %v", c.DummyPodId, err)
	}
	result, err := c.AddSandboxToNetwork(c.DummyPodId, "", "")
	if err != nil {
		return nil, "", err
	}
	return result, cni.PodNetNSPath(c.DummyPodId), nil
}

func (c *FakeCNIClient) getEntry(podId, podName, podNS string) *fakeCNIEntry {
	if entry, found := c.entries[podKey(podId, podName, podNS)]; found {
		return entry
	}
	log.Panicf("Unexpected pod id = %q name = %q ns = %q", podId, podName, podNS)
	return nil
}

func (c *FakeCNIClient) AddSandboxToNetwork(podId, podName, podNS string) (*cnicurrent.Result, error) {
	entry := c.getEntry(podId, podName, podNS)
	if entry.added {
		panic("AddSandboxToNetwork() was already called")
	}

	replaceSandboxPlaceholders(entry.info, podId)
	for n, iface := range entry.info.Interfaces {
		if iface.Sandbox == "" {
			continue
		}

		if err := entry.addSandboxToNetwork(n); err != nil {
			return nil, err
		}
	}

	r := copyCNIResult(entry.info)
	if entry.useBadResult {
		r.Interfaces = nil
		r.Routes = nil
	}
	return r, nil
}

func (c *FakeCNIClient) RemoveSandboxFromNetwork(podId, podName, podNS string) error {
	entry := c.getEntry(podId, podName, podNS)
	if !entry.added {
		panic("RemoveSandboxFromNetwork() was called without prior AddSandboxToNetwork()")
	}
	if entry.removed {
		panic("RemoveSandboxFromNetwork() was already called")
	}

	if err := entry.captureNetworkConfigAfterTeardown(podId); err != nil {
		panic(err)
	}
	entry.removed = true
	return nil
}

func (c *FakeCNIClient) VerifyAdded(podId, podName, podNS string) {
	entry := c.getEntry(podId, podName, podNS)
	if !entry.added {
		panic("Pod sandbox not added to the network")
	}
	if entry.removed {
		panic("Pod sandbox is already removed")
	}
}

func (c *FakeCNIClient) VerifyRemoved(podId, podName, podNS string) {
	entry := c.getEntry(podId, podName, podNS)
	if !entry.added {
		panic("Pod sandbox not added to the network")
	}
	if !entry.removed {
		panic("Pod sandbox not removed from the network")
	}
}

func (c *FakeCNIClient) Cleanup() {
	for _, entry := range c.entries {
		entry.cleanup()
	}
	if _, found := c.entries[podKey(c.DummyPodId, "", "")]; found {
		cni.DestroyNetNS(c.DummyPodId)
		// XXXX
		// if err := cni.DestroyNetNS(c.DummyPodId); err != nil {
		// 	log.Panicf("Error destroying dummy pod network ns: %v", err)
		// }
	}
}

func (c *FakeCNIClient) Veths(podId, podName, podNS string) []FakeCNIVethPair {
	c.VerifyAdded(podId, podName, podNS)
	return c.getEntry(podId, podName, podNS).veths
}

func (c *FakeCNIClient) NetworkInfoAfterTeardown(podId, podName, podNS string) *cnicurrent.Result {
	c.VerifyRemoved(podId, podName, podNS)
	return c.getEntry(podId, podName, podNS).infoAfterTeardown
}

func (c *FakeCNIClient) UseBadResult(podId, podName, podNS string, useBadResult bool) {
	c.getEntry(podId, podName, podNS).useBadResult = useBadResult
}

func copyCNIResult(result *cnicurrent.Result) *cnicurrent.Result {
	bs, err := json.Marshal(result)
	if err != nil {
		log.Panicf("Error marshalling CNI result: %v", err)
	}
	var newResult *cnicurrent.Result
	if err := json.Unmarshal(bs, &newResult); err != nil {
		log.Panicf("Error unmarshalling CNI result: %v", err)
	}
	return newResult
}

func replaceSandboxPlaceholders(result *cnicurrent.Result, podId string) {
	for _, iface := range result.Interfaces {
		if iface.Sandbox == "placeholder" {
			iface.Sandbox = cni.PodNetNSPath(podId)
		}
	}
}
<commit_msg>Fix dummy netns teardown in vm network tests<commit_after>/*
Copyright 2017 Mirantis

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 network

import (
	"encoding/json"
	"fmt"
	"log"
	"net"

	"github.com/containernetworking/cni/pkg/ns"
	cnicurrent "github.com/containernetworking/cni/pkg/types/current"
	"github.com/vishvananda/netlink"

	"github.com/Mirantis/virtlet/pkg/cni"
	"github.com/Mirantis/virtlet/pkg/nettools"
	"github.com/Mirantis/virtlet/pkg/utils"
)

// FakeCNIVethPair represents a veth pair created by the fake CNI
type FakeCNIVethPair struct {
	HostSide netlink.Link
	ContSide netlink.Link
}

type fakeCNIEntry struct {
	podId, podName, podNS   string
	info, infoAfterTeardown *cnicurrent.Result
	extraRoutes             map[int][]netlink.Route
	hostNS, contNS          ns.NetNS
	veths                   []FakeCNIVethPair
	added                   bool
	removed                 bool
	useBadResult            bool
}

func (e *fakeCNIEntry) addSandboxToNetwork(ifaceIndex int) error {
	iface := e.info.Interfaces[ifaceIndex]
	iface.Sandbox = cni.PodNetNSPath(e.podId)

	var err error
	e.contNS, err = ns.GetNS(iface.Sandbox)
	if err != nil {
		return fmt.Errorf("can't get pod netns (path %q): %v", iface.Sandbox, err)
	}

	var vp FakeCNIVethPair
	if err := e.hostNS.Do(func(ns.NetNS) error {
		var err error
		vp.HostSide, vp.ContSide, err = nettools.CreateEscapeVethPair(e.contNS, iface.Name, 1500)
		return err
	}); err != nil {
		return fmt.Errorf("failed to create escape veth pair: %v", err)
	}

	return e.contNS.Do(func(ns.NetNS) error {
		hwAddr, err := net.ParseMAC(iface.Mac)
		if err != nil {
			return fmt.Errorf("error parsing hwaddr %q: %v", iface.Mac, err)
		}
		if err := nettools.SetHardwareAddr(vp.ContSide, hwAddr); err != nil {
			return fmt.Errorf("SetHardwareAddr(): %v", err)
		}
		// mac address changed, reload the link
		vp.ContSide, err = netlink.LinkByIndex(vp.ContSide.Attrs().Index)
		if err != nil {
			return fmt.Errorf("can't reload container veth info: %v", err)
		}
		if err := nettools.ConfigureLink(vp.ContSide, e.info); err != nil {
			return fmt.Errorf("error configuring link %q: %v", iface.Name, err)
		}
		if e.extraRoutes != nil {
			for _, r := range e.extraRoutes[ifaceIndex] {
				if r.Scope == nettools.SCOPE_LINK {
					r.LinkIndex = vp.ContSide.Attrs().Index
				}
				if err := netlink.RouteAdd(&r); err != nil {
					return fmt.Errorf("Failed to add route %#v: %v", r, err)
				}
			}
		}
		e.veths = append(e.veths, vp)
		e.added = true
		return nil
	})
}

func (c *fakeCNIEntry) captureNetworkConfigAfterTeardown(podId string) error {
	return c.contNS.Do(func(ns.NetNS) error {
		for _, ipConfig := range c.info.IPs {
			ifaceIndex := ipConfig.Interface
			if ifaceIndex > len(c.info.Interfaces) {
				return fmt.Errorf("bad interface index %d", ifaceIndex)
			}
			iface := c.info.Interfaces[ifaceIndex]
			link, err := netlink.LinkByName(iface.Name)
			if err != nil {
				return fmt.Errorf("can't find link %q: %v", iface.Name, err)
			}
			linkInfo, err := nettools.ExtractLinkInfo(link, cni.PodNetNSPath(podId))
			if err != nil {
				return fmt.Errorf("error extracting link info: %v", err)
			}
			if c.infoAfterTeardown == nil {
				c.infoAfterTeardown = linkInfo
			} else {
				if len(linkInfo.Interfaces) != 1 {
					return fmt.Errorf("more than one interface extracted")
				}
				if len(linkInfo.IPs) != 1 {
					return fmt.Errorf("more than one ip config extracted")
				}
				linkInfo.IPs[0].Interface = len(c.infoAfterTeardown.Interfaces)
				c.infoAfterTeardown.IPs = append(c.infoAfterTeardown.IPs, linkInfo.IPs[0])
				c.infoAfterTeardown.Interfaces = append(c.infoAfterTeardown.Interfaces, linkInfo.Interfaces[0])
			}
		}
		return nil
	})
}

func (e *fakeCNIEntry) cleanup() {
	if e.contNS != nil {
		e.contNS.Close()
	}
}

func podKey(podId, podName, podNS string) string {
	return fmt.Sprintf("%s:%s:%s", podId, podName, podNS)
}

// FakeCNIClient fakes a CNI client. It's only good for one-time
// network setup for a single pod network namespace
type FakeCNIClient struct {
	// DummyPodId is an id of dummy pod which is used by the
	// Calico workaround
	DummyPodId string
	entries    map[string]*fakeCNIEntry
}

var _ cni.CNIClient = &FakeCNIClient{}

func NewFakeCNIClient() *FakeCNIClient {
	return &FakeCNIClient{
		DummyPodId: utils.NewUuid(),
		entries:    make(map[string]*fakeCNIEntry),
	}
}

func (c *FakeCNIClient) ExpectPod(podId, podName, podNS string, info *cnicurrent.Result, hostNS ns.NetNS, extraRoutes map[int][]netlink.Route) {
	c.entries[podKey(podId, podName, podNS)] = &fakeCNIEntry{
		podId:       podId,
		podName:     podName,
		podNS:       podNS,
		info:        info,
		hostNS:      hostNS,
		extraRoutes: extraRoutes,
	}
}

func (c *FakeCNIClient) ExpectDummyPod(info *cnicurrent.Result, hostNS ns.NetNS, extraRoutes map[int][]netlink.Route) {
	c.ExpectPod(c.DummyPodId, "", "", info, hostNS, extraRoutes)
}

func (c *FakeCNIClient) GetDummyNetwork() (*cnicurrent.Result, string, error) {
	if err := cni.CreateNetNS(c.DummyPodId); err != nil {
		return nil, "", fmt.Errorf("couldn't create netns for dummy pod %q: %v", c.DummyPodId, err)
	}
	result, err := c.AddSandboxToNetwork(c.DummyPodId, "", "")
	if err != nil {
		return nil, "", err
	}
	return result, cni.PodNetNSPath(c.DummyPodId), nil
}

func (c *FakeCNIClient) getEntry(podId, podName, podNS string) *fakeCNIEntry {
	if entry, found := c.entries[podKey(podId, podName, podNS)]; found {
		return entry
	}
	log.Panicf("Unexpected pod id = %q name = %q ns = %q", podId, podName, podNS)
	return nil
}

func (c *FakeCNIClient) AddSandboxToNetwork(podId, podName, podNS string) (*cnicurrent.Result, error) {
	entry := c.getEntry(podId, podName, podNS)
	if entry.added {
		panic("AddSandboxToNetwork() was already called")
	}

	replaceSandboxPlaceholders(entry.info, podId)
	for n, iface := range entry.info.Interfaces {
		if iface.Sandbox == "" {
			continue
		}

		if err := entry.addSandboxToNetwork(n); err != nil {
			return nil, err
		}
	}

	r := copyCNIResult(entry.info)
	if entry.useBadResult {
		r.Interfaces = nil
		r.Routes = nil
	}
	return r, nil
}

func (c *FakeCNIClient) RemoveSandboxFromNetwork(podId, podName, podNS string) error {
	entry := c.getEntry(podId, podName, podNS)
	if !entry.added {
		panic("RemoveSandboxFromNetwork() was called without prior AddSandboxToNetwork()")
	}
	if entry.removed {
		panic("RemoveSandboxFromNetwork() was already called")
	}

	if err := entry.captureNetworkConfigAfterTeardown(podId); err != nil {
		panic(err)
	}
	entry.removed = true
	return nil
}

func (c *FakeCNIClient) VerifyAdded(podId, podName, podNS string) {
	entry := c.getEntry(podId, podName, podNS)
	if !entry.added {
		panic("Pod sandbox not added to the network")
	}
	if entry.removed {
		panic("Pod sandbox is already removed")
	}
}

func (c *FakeCNIClient) VerifyRemoved(podId, podName, podNS string) {
	entry := c.getEntry(podId, podName, podNS)
	if !entry.added {
		panic("Pod sandbox not added to the network")
	}
	if !entry.removed {
		panic("Pod sandbox not removed from the network")
	}
}

func (c *FakeCNIClient) Cleanup() {
	for _, entry := range c.entries {
		entry.cleanup()
	}
	if _, found := c.entries[podKey(c.DummyPodId, "", "")]; found {
		if err := cni.DestroyNetNS(c.DummyPodId); err != nil {
			log.Panicf("Error destroying dummy pod network ns: %v", err)
		}
	}
}

func (c *FakeCNIClient) Veths(podId, podName, podNS string) []FakeCNIVethPair {
	c.VerifyAdded(podId, podName, podNS)
	return c.getEntry(podId, podName, podNS).veths
}

func (c *FakeCNIClient) NetworkInfoAfterTeardown(podId, podName, podNS string) *cnicurrent.Result {
	c.VerifyRemoved(podId, podName, podNS)
	return c.getEntry(podId, podName, podNS).infoAfterTeardown
}

func (c *FakeCNIClient) UseBadResult(podId, podName, podNS string, useBadResult bool) {
	c.getEntry(podId, podName, podNS).useBadResult = useBadResult
}

func copyCNIResult(result *cnicurrent.Result) *cnicurrent.Result {
	bs, err := json.Marshal(result)
	if err != nil {
		log.Panicf("Error marshalling CNI result: %v", err)
	}
	var newResult *cnicurrent.Result
	if err := json.Unmarshal(bs, &newResult); err != nil {
		log.Panicf("Error unmarshalling CNI result: %v", err)
	}
	return newResult
}

func replaceSandboxPlaceholders(result *cnicurrent.Result, podId string) {
	for _, iface := range result.Interfaces {
		if iface.Sandbox == "placeholder" {
			iface.Sandbox = cni.PodNetNSPath(podId)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"io/ioutil"
	"log"
	"strconv"
	"time"

	"github.com/brotherlogic/goserver"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	pbd "github.com/brotherlogic/discovery/proto"
	pb "github.com/brotherlogic/gobuildmaster/proto"
	pbs "github.com/brotherlogic/gobuildslave/proto"
	pbg "github.com/brotherlogic/goserver/proto"
)

const (
	intentWait = time.Second
)

// Server the main server type
type Server struct {
	*goserver.GoServer
	config  *pb.Config
	serving bool
}

type mainChecker struct {
	prev []string
}

func getIP(servertype, servername string) (string, int) {
	conn, _ := grpc.Dial("192.168.86.64:50055", grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	if err != nil {
		return "", -1
	}
	for _, s := range r.Services {
		if s.Name == servertype && s.Identifier == servername {
			return s.Ip, int(s.Port)
		}
	}

	return "", -1
}

func (t *mainChecker) getprev() []string {
	return t.prev
}
func (t *mainChecker) setprev(v []string) {
	t.prev = v
}

func (t *mainChecker) assess(server string) (*pbs.JobList, *pbs.Config) {
	list := &pbs.JobList{}
	conf := &pbs.Config{}

	ip, port := getIP("gobuildslave", server)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	defer conn.Close()

	slave := pbs.NewGoBuildSlaveClient(conn)
	r, err := slave.List(context.Background(), &pbs.Empty{})
	if err != nil {
		return list, conf
	}

	r2, err := slave.GetConfig(context.Background(), &pbs.Empty{})
	if err != nil {
		return list, conf
	}

	return r, r2
}

func (t *mainChecker) master(entry *pbd.RegistryEntry) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, _ := grpc.DialContext(ctx, entry.GetIp()+":"+strconv.Itoa(int(entry.GetPort())), grpc.WithInsecure())
	defer conn.Close()

	server := pbg.NewGoserverServiceClient(conn)
	log.Printf("SETTING MASTER: %v", entry)
	_, err := server.Mote(context.Background(), &pbg.MoteRequest{Master: entry.GetMaster()})
	log.Printf("RESPONSE: %v", err)
}

func runJob(job *pbs.JobSpec, server string) {
	log.Printf("Run %v on %v", job.Name, server)
	if server != "" {
		ip, port := getIP("gobuildslave", server)
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
		defer conn.Close()

		slave := pbs.NewGoBuildSlaveClient(conn)
		job.Server = server
		slave.Run(context.Background(), job)
	}
}

func (t *mainChecker) discover() *pbd.ServiceList {
	ret := &pbd.ServiceList{}

	conn, _ := grpc.Dial("192.168.86.64:50055", grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	if err == nil {
		for _, s := range r.Services {
			ret.Services = append(ret.Services, s)
		}
	}

	return ret
}

// DoRegister Registers this server
func (s Server) DoRegister(server *grpc.Server) {
	pb.RegisterGoBuildMasterServer(server, &s)
}

// ReportHealth determines if the server is healthy
func (s Server) ReportHealth() bool {
	return true
}

// Mote promotes/demotes this server
func (s Server) Mote(master bool) error {
	return nil
}

//Compare compares current state to desired state
func (s Server) Compare(ctx context.Context, in *pb.Empty) (*pb.CompareResponse, error) {
	resp := &pb.CompareResponse{}
	list, _ := getFleetStatus(&mainChecker{})
	cc := &pb.Config{}
	for _, jlist := range list {
		for _, job := range jlist.GetDetails() {
			cc.Intents = append(cc.Intents, &pb.Intent{Spec: job.GetSpec()})
		}
	}
	resp.Current = cc
	resp.Desired = s.config

	return resp, nil
}

func getConfig(c checker) *pb.Config {
	list, _ := getFleetStatus(c)
	config := &pb.Config{}

	for _, jlist := range list {
		for _, job := range jlist.Details {
			found := false
			for _, ij := range config.Intents {
				if job.Spec.Name == ij.Spec.Name {
					ij.Count++
					found = true
				}
			}

			if !found {
				config.Intents = append(config.Intents, &pb.Intent{Spec: &pbs.JobSpec{Name: job.Spec.Name}, Count: 1})
			}
		}
	}

	return config
}

// MatchIntent tries to match the intent with the state of production
func (s Server) MatchIntent() {
	checker := &mainChecker{}
	for s.serving {
		time.Sleep(intentWait)

		state := getConfig(checker)
		diff := configDiff(s.config, state)
		joblist := runJobs(diff)
		for _, job := range joblist {
			runJob(job, chooseServer(job, checker))
		}
	}
}

// SetMaster sets up the master settings
func (s Server) SetMaster() {
	checker := &mainChecker{}
	for s.serving {
		time.Sleep(intentWait)

		fleet := checker.discover()
		matcher := make(map[string]*pbd.RegistryEntry)
		for _, entry := range fleet.GetServices() {
			if _, ok := matcher[entry.GetName()]; !ok {
				matcher[entry.GetName()] = entry
			} else {
				if entry.GetMaster() {
					matcher[entry.GetName()] = entry
				}
			}
		}

		log.Printf("Resolved Master: %v", matcher)
		for _, entry := range matcher {
			if !entry.GetMaster() {
				entry.Master = true
				checker.master(entry)
			}
		}
	}
}

func main() {
	config, err := loadConfig("config.pb")
	if err != nil {
		log.Fatalf("Fatal loading of config: %v", err)
	}

	var sync = flag.Bool("once", false, "One pass intent match")
	s := Server{&goserver.GoServer{}, config, true}

	var quiet = flag.Bool("quiet", true, "Show all output")
	flag.Parse()

	if *quiet {
		log.SetFlags(0)
		log.SetOutput(ioutil.Discard)
	}

	if *sync {
		s.MatchIntent()
	} else {
		s.Register = s
		s.PrepServer()
		s.GoServer.Killme = false
		s.RegisterServer("gobuildmaster", false)
		s.RegisterServingTask(s.MatchIntent)
		s.RegisterServingTask(s.SetMaster)
		s.Serve()
	}
}
<commit_msg>Cleared the logs<commit_after>package main

import (
	"flag"
	"io/ioutil"
	"log"
	"strconv"
	"time"

	"github.com/brotherlogic/goserver"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	pbd "github.com/brotherlogic/discovery/proto"
	pb "github.com/brotherlogic/gobuildmaster/proto"
	pbs "github.com/brotherlogic/gobuildslave/proto"
	pbg "github.com/brotherlogic/goserver/proto"
)

const (
	intentWait = time.Second
)

// Server the main server type
type Server struct {
	*goserver.GoServer
	config  *pb.Config
	serving bool
}

type mainChecker struct {
	prev []string
}

func getIP(servertype, servername string) (string, int) {
	conn, _ := grpc.Dial("192.168.86.64:50055", grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	if err != nil {
		return "", -1
	}
	for _, s := range r.Services {
		if s.Name == servertype && s.Identifier == servername {
			return s.Ip, int(s.Port)
		}
	}

	return "", -1
}

func (t *mainChecker) getprev() []string {
	return t.prev
}
func (t *mainChecker) setprev(v []string) {
	t.prev = v
}

func (t *mainChecker) assess(server string) (*pbs.JobList, *pbs.Config) {
	list := &pbs.JobList{}
	conf := &pbs.Config{}

	ip, port := getIP("gobuildslave", server)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	defer conn.Close()

	slave := pbs.NewGoBuildSlaveClient(conn)
	r, err := slave.List(context.Background(), &pbs.Empty{})
	if err != nil {
		return list, conf
	}

	r2, err := slave.GetConfig(context.Background(), &pbs.Empty{})
	if err != nil {
		return list, conf
	}

	return r, r2
}

func (t *mainChecker) master(entry *pbd.RegistryEntry) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, _ := grpc.DialContext(ctx, entry.GetIp()+":"+strconv.Itoa(int(entry.GetPort())), grpc.WithInsecure())
	defer conn.Close()

	server := pbg.NewGoserverServiceClient(conn)
	log.Printf("SETTING MASTER: %v", entry)
	_, err := server.Mote(context.Background(), &pbg.MoteRequest{Master: entry.GetMaster()})
	if err != nil {
		log.Printf("RESPONSE: %v", err)
	}
}

func runJob(job *pbs.JobSpec, server string) {
	log.Printf("Run %v on %v", job.Name, server)
	if server != "" {
		ip, port := getIP("gobuildslave", server)
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
		defer conn.Close()

		slave := pbs.NewGoBuildSlaveClient(conn)
		job.Server = server
		slave.Run(context.Background(), job)
	}
}

func (t *mainChecker) discover() *pbd.ServiceList {
	ret := &pbd.ServiceList{}

	conn, _ := grpc.Dial("192.168.86.64:50055", grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	if err == nil {
		for _, s := range r.Services {
			ret.Services = append(ret.Services, s)
		}
	}

	return ret
}

// DoRegister Registers this server
func (s Server) DoRegister(server *grpc.Server) {
	pb.RegisterGoBuildMasterServer(server, &s)
}

// ReportHealth determines if the server is healthy
func (s Server) ReportHealth() bool {
	return true
}

// Mote promotes/demotes this server
func (s Server) Mote(master bool) error {
	return nil
}

//Compare compares current state to desired state
func (s Server) Compare(ctx context.Context, in *pb.Empty) (*pb.CompareResponse, error) {
	resp := &pb.CompareResponse{}
	list, _ := getFleetStatus(&mainChecker{})
	cc := &pb.Config{}
	for _, jlist := range list {
		for _, job := range jlist.GetDetails() {
			cc.Intents = append(cc.Intents, &pb.Intent{Spec: job.GetSpec()})
		}
	}
	resp.Current = cc
	resp.Desired = s.config

	return resp, nil
}

func getConfig(c checker) *pb.Config {
	list, _ := getFleetStatus(c)
	config := &pb.Config{}

	for _, jlist := range list {
		for _, job := range jlist.Details {
			found := false
			for _, ij := range config.Intents {
				if job.Spec.Name == ij.Spec.Name {
					ij.Count++
					found = true
				}
			}

			if !found {
				config.Intents = append(config.Intents, &pb.Intent{Spec: &pbs.JobSpec{Name: job.Spec.Name}, Count: 1})
			}
		}
	}

	return config
}

// MatchIntent tries to match the intent with the state of production
func (s Server) MatchIntent() {
	checker := &mainChecker{}
	for s.serving {
		time.Sleep(intentWait)

		state := getConfig(checker)
		diff := configDiff(s.config, state)
		joblist := runJobs(diff)
		for _, job := range joblist {
			runJob(job, chooseServer(job, checker))
		}
	}
}

// SetMaster sets up the master settings
func (s Server) SetMaster() {
	checker := &mainChecker{}
	for s.serving {
		time.Sleep(intentWait)

		fleet := checker.discover()
		matcher := make(map[string]*pbd.RegistryEntry)
		for _, entry := range fleet.GetServices() {
			if _, ok := matcher[entry.GetName()]; !ok {
				matcher[entry.GetName()] = entry
			} else {
				if entry.GetMaster() {
					matcher[entry.GetName()] = entry
				}
			}
		}

		for _, entry := range matcher {
			if !entry.GetMaster() {
				entry.Master = true
				checker.master(entry)
			}
		}
	}
}

func main() {
	config, err := loadConfig("config.pb")
	if err != nil {
		log.Fatalf("Fatal loading of config: %v", err)
	}

	var sync = flag.Bool("once", false, "One pass intent match")
	s := Server{&goserver.GoServer{}, config, true}

	var quiet = flag.Bool("quiet", true, "Show all output")
	flag.Parse()

	if *quiet {
		log.SetFlags(0)
		log.SetOutput(ioutil.Discard)
	}

	if *sync {
		s.MatchIntent()
	} else {
		s.Register = s
		s.PrepServer()
		s.GoServer.Killme = false
		s.RegisterServer("gobuildmaster", false)
		s.RegisterServingTask(s.MatchIntent)
		s.RegisterServingTask(s.SetMaster)
		s.Serve()
	}
}
<|endoftext|>


<commit_before>package gocostmodel

import (
	"math"
	"math/rand"
	"testing"
)

var (
	neg    float64 = -3.456
	mathv1 float64 = 6.4
	mathv2 float64 = 1.2
	out    float64
	outi   int
)

func BenchmarkAbs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Abs(neg)
	}
}

func BenchmarkCos(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Cos(mathv1)
	}
}

func BenchmarkSin(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Sin(mathv1)
	}
}

func BenchmarkPow(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Pow(mathv1, mathv2)
	}
}

func BenchmarkLog(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Log(mathv1)
	}
}

func BenchmarkExp(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Exp(mathv1)
	}
}

func BenchmarkSqrt(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Sqrt(mathv1)
	}
}

func BenchmarkMax(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Max(mathv1, mathv2)
	}
}

func BenchmarkMin(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Min(mathv1, mathv2)
	}
}

func BenchmarkRand(b *testing.B) {
	for i := 0; i < b.N; i++ {
		outi = rand.Int()
	}
}
<commit_msg>make math benchmarks easier to grep<commit_after>package gocostmodel

import (
	"math"
	"math/rand"
	"testing"
)

var (
	neg    float64 = -3.456
	mathv1 float64 = 6.4
	mathv2 float64 = 1.2
	out    float64
	outi   int
)

func BenchmarkMathAbs(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Abs(neg)
	}
}

func BenchmarkMathCos(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Cos(mathv1)
	}
}

func BenchmarkMathSin(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Sin(mathv1)
	}
}

func BenchmarkMathPow(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Pow(mathv1, mathv2)
	}
}

func BenchmarkMathLog(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Log(mathv1)
	}
}

func BenchmarkMathExp(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Exp(mathv1)
	}
}

func BenchmarkMathSqrt(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Sqrt(mathv1)
	}
}

func BenchmarkMathMax(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Max(mathv1, mathv2)
	}
}

func BenchmarkMathMin(b *testing.B) {
	for i := 0; i < b.N; i++ {
		out = math.Min(mathv1, mathv2)
	}
}

func BenchmarkMathRand(b *testing.B) {
	for i := 0; i < b.N; i++ {
		outi = rand.Int()
	}
}
<|endoftext|>