<commit_before>package parser

import (
	"fmt"
	"github.com/goby-lang/goby/compiler/ast"
	"github.com/goby-lang/goby/compiler/lexer"
	"github.com/goby-lang/goby/compiler/parser/errors"
	"github.com/goby-lang/goby/compiler/parser/events"
	"github.com/goby-lang/goby/compiler/parser/precedence"
	"github.com/goby-lang/goby/compiler/parser/states"
	"github.com/goby-lang/goby/compiler/token"
	"github.com/looplab/fsm"
)

// Parser represents lexical analyzer struct
type Parser struct {
	Lexer *lexer.Lexer
	error *errors.Error

	curToken  token.Token
	peekToken token.Token

	prefixParseFns map[token.Type]prefixParseFn
	infixParseFns  map[token.Type]infixParseFn

	// Determine if call expression should accept block argument,
	// currently only used when parsing while statement.
	// However, this is not a very good practice should change it in the future.
	acceptBlock bool
	fsm         *fsm.FSM
	Mode        int
}

// These are the enums for marking parser's mode, which decides whether it should pop unused values.
const (
	NormalMode int = iota
	REPLMode
	TestMode
)

// New initializes a parser and returns it
func New(l *lexer.Lexer) *Parser {
	p := &Parser{
		Lexer:       l,
		acceptBlock: true,
	}

	p.fsm = fsm.NewFSM(
		states.Normal,
		fsm.Events{
			{Name: events.ParseFuncCall, Src: []string{states.Normal}, Dst: states.ParsingFuncCall},
			{Name: events.ParseMethodParam, Src: []string{states.Normal, states.ParsingAssignment}, Dst: states.ParsingMethodParam},
			{Name: events.ParseAssignment, Src: []string{states.Normal, states.ParsingFuncCall}, Dst: states.ParsingAssignment},
			{Name: events.BackToNormal, Src: []string{states.ParsingFuncCall, states.ParsingMethodParam, states.ParsingAssignment}, Dst: states.Normal},
		},
		fsm.Callbacks{},
	)

	p.prefixParseFns = make(map[token.Type]prefixParseFn)
	p.registerPrefix(token.Ident, p.parseIdentifier)
	p.registerPrefix(token.Constant, p.parseConstant)
	p.registerPrefix(token.InstanceVariable, p.parseInstanceVariable)
	p.registerPrefix(token.Int, p.parseIntegerLiteral)
	p.registerPrefix(token.String, p.parseStringLiteral)
	p.registerPrefix(token.True, p.parseBooleanLiteral)
	p.registerPrefix(token.False, p.parseBooleanLiteral)
	p.registerPrefix(token.Null, p.parseNilExpression)
	p.registerPrefix(token.Minus, p.parsePrefixExpression)
	p.registerPrefix(token.Asterisk, p.parsePrefixExpression)
	p.registerPrefix(token.Bang, p.parsePrefixExpression)
	p.registerPrefix(token.LParen, p.parseGroupedExpression)
	p.registerPrefix(token.If, p.parseIfExpression)
	p.registerPrefix(token.Case, p.parseCaseExpression)
	p.registerPrefix(token.Self, p.parseSelfExpression)
	p.registerPrefix(token.LBracket, p.parseArrayExpression)
	p.registerPrefix(token.LBrace, p.parseHashExpression)
	p.registerPrefix(token.Semicolon, p.parseSemicolon)
	p.registerPrefix(token.Yield, p.parseYieldExpression)
	p.registerPrefix(token.GetBlock, p.parseGetBlockExpression)

	p.infixParseFns = make(map[token.Type]infixParseFn)
	p.registerInfix(token.Plus, p.parseInfixExpression)
	p.registerInfix(token.PlusEq, p.parseAssignExpression)
	p.registerInfix(token.Minus, p.parseInfixExpression)
	p.registerInfix(token.MinusEq, p.parseAssignExpression)
	p.registerInfix(token.Modulo, p.parseInfixExpression)
	p.registerInfix(token.Slash, p.parseInfixExpression)
	p.registerInfix(token.Pow, p.parseInfixExpression)
	p.registerInfix(token.Eq, p.parseInfixExpression)
	p.registerInfix(token.NotEq, p.parseInfixExpression)
	p.registerInfix(token.Match, p.parseInfixExpression)
	p.registerInfix(token.LT, p.parseInfixExpression)
	p.registerInfix(token.LTE, p.parseInfixExpression)
	p.registerInfix(token.GT, p.parseInfixExpression)
	p.registerInfix(token.GTE, p.parseInfixExpression)
	p.registerInfix(token.COMP, p.parseInfixExpression)
	p.registerInfix(token.And, p.parseInfixExpression)
	p.registerInfix(token.Or, p.parseInfixExpression)
	p.registerInfix(token.OrEq, p.parseAssignExpression)
	p.registerInfix(token.Comma, p.parseMultiVariables)
	p.registerInfix(token.ResolutionOperator, p.parseInfixExpression)
	p.registerInfix(token.Assign, p.parseAssignExpression)
	p.registerInfix(token.Range, p.parseRangeExpression)
	p.registerInfix(token.Dot, p.parseCallExpressionWithReceiver)
	p.registerInfix(token.LParen, p.parseCallExpressionWithoutReceiver)
	p.registerInfix(token.LBracket, p.parseIndexExpression)
	p.registerInfix(token.Colon, p.parseArgumentPairExpression)
	p.registerInfix(token.Asterisk, p.parseInfixExpression)

	return p
}

// ParseProgram update program statements and return program
func (p *Parser) ParseProgram() (*ast.Program, *errors.Error) {
	p.error = nil
	// Read two tokens, so curToken and peekToken are both set.
	p.nextToken()
	p.nextToken()
	program := &ast.Program{}
	program.Statements = []ast.Statement{}

	for !p.curTokenIs(token.EOF) {
		stmt := p.parseStatement()

		if p.error != nil {
			return nil, p.error
		}

		if stmt != nil {
			program.Statements = append(program.Statements, stmt)
		}

		p.nextToken()
	}

	if p.Mode == TestMode {
		stmt := program.Statements[len(program.Statements)-1]
		expStmt, ok := stmt.(*ast.ExpressionStatement)

		if ok {
			expStmt.Expression.MarkAsExp()
		}
	}

	return program, nil
}

func (p *Parser) parseSemicolon() ast.Expression {
	return nil
}

func (p *Parser) peekPrecedence() int {
	if p, ok := precedence.LookupTable[p.peekToken.Type]; ok {
		return p
	}

	return precedence.Normal
}

func (p *Parser) curPrecedence() int {
	if p, ok := precedence.LookupTable[p.curToken.Type]; ok {
		return p
	}

	return precedence.Normal
}

func (p *Parser) nextToken() {
	p.curToken = p.peekToken
	p.peekToken = p.Lexer.NextToken()
}

func (p *Parser) curTokenIs(t token.Type) bool {
	return p.curToken.Type == t
}

func (p *Parser) peekTokenIs(t token.Type) bool {
	return p.peekToken.Type == t
}

func (p *Parser) expectPeek(t token.Type) bool {
	if p.peekTokenIs(t) {
		p.nextToken()
		return true
	}
	p.peekError(t)
	return false
}

func (p *Parser) registerPrefix(tokenType token.Type, fn prefixParseFn) {
	p.prefixParseFns[tokenType] = fn
}

func (p *Parser) registerInfix(tokenType token.Type, fn infixParseFn) {
	p.infixParseFns[tokenType] = fn
}

func (p *Parser) peekTokenAtSameLine() bool {
	return p.curToken.Line == p.peekToken.Line && p.peekToken.Type != token.EOF
}

func (p *Parser) peekError(t token.Type) {
	msg := fmt.Sprintf("expected next token to be %s, got %s(%s) instead. Line: %d", t, p.peekToken.Type, p.peekToken.Literal, p.peekToken.Line)
	p.error = errors.InitError(msg, errors.UnexpectedTokenError)
}

func (p *Parser) noPrefixParseFnError(t token.Type) {
	msg := fmt.Sprintf("unexpected %s Line: %d", p.curToken.Literal, p.curToken.Line)

	if t == token.End {
		p.error = errors.InitError(msg, errors.UnexpectedEndError)
	} else {
		p.error = errors.InitError(msg, errors.UnexpectedTokenError)
	}
}

func (p *Parser) callConstantError(t token.Type) {
	msg := fmt.Sprintf("cannot call %s with %s. Line: %d", t, p.peekToken.Type, p.peekToken.Line)
	p.error = errors.InitError(msg, errors.UnexpectedTokenError)
}

func (p *Parser) IsNotDefMethodToken() bool {

	return p.curToken.Type != token.Ident && !(p.peekToken.Type == token.Dot && (p.curToken.Type == token.InstanceVariable || p.curToken.Type == token.Constant || p.curToken.Type == token.Self))
}
<commit_msg>recover mechanism<commit_after>package parser

import (
	"fmt"
	"github.com/goby-lang/goby/compiler/ast"
	"github.com/goby-lang/goby/compiler/lexer"
	"github.com/goby-lang/goby/compiler/parser/errors"
	"github.com/goby-lang/goby/compiler/parser/events"
	"github.com/goby-lang/goby/compiler/parser/precedence"
	"github.com/goby-lang/goby/compiler/parser/states"
	"github.com/goby-lang/goby/compiler/token"
	"github.com/looplab/fsm"
)

// Parser represents lexical analyzer struct
type Parser struct {
	Lexer *lexer.Lexer
	error *errors.Error

	curToken  token.Token
	peekToken token.Token

	prefixParseFns map[token.Type]prefixParseFn
	infixParseFns  map[token.Type]infixParseFn

	// Determine if call expression should accept block argument,
	// currently only used when parsing while statement.
	// However, this is not a very good practice should change it in the future.
	acceptBlock bool
	fsm         *fsm.FSM
	Mode        int
}

// These are the enums for marking parser's mode, which decides whether it should pop unused values.
const (
	NormalMode int = iota
	REPLMode
	TestMode
)

// New initializes a parser and returns it
func New(l *lexer.Lexer) *Parser {
	p := &Parser{
		Lexer:       l,
		acceptBlock: true,
	}

	p.fsm = fsm.NewFSM(
		states.Normal,
		fsm.Events{
			{Name: events.ParseFuncCall, Src: []string{states.Normal}, Dst: states.ParsingFuncCall},
			{Name: events.ParseMethodParam, Src: []string{states.Normal, states.ParsingAssignment}, Dst: states.ParsingMethodParam},
			{Name: events.ParseAssignment, Src: []string{states.Normal, states.ParsingFuncCall}, Dst: states.ParsingAssignment},
			{Name: events.BackToNormal, Src: []string{states.ParsingFuncCall, states.ParsingMethodParam, states.ParsingAssignment}, Dst: states.Normal},
		},
		fsm.Callbacks{},
	)

	p.prefixParseFns = make(map[token.Type]prefixParseFn)
	p.registerPrefix(token.Ident, p.parseIdentifier)
	p.registerPrefix(token.Constant, p.parseConstant)
	p.registerPrefix(token.InstanceVariable, p.parseInstanceVariable)
	p.registerPrefix(token.Int, p.parseIntegerLiteral)
	p.registerPrefix(token.String, p.parseStringLiteral)
	p.registerPrefix(token.True, p.parseBooleanLiteral)
	p.registerPrefix(token.False, p.parseBooleanLiteral)
	p.registerPrefix(token.Null, p.parseNilExpression)
	p.registerPrefix(token.Minus, p.parsePrefixExpression)
	p.registerPrefix(token.Asterisk, p.parsePrefixExpression)
	p.registerPrefix(token.Bang, p.parsePrefixExpression)
	p.registerPrefix(token.LParen, p.parseGroupedExpression)
	p.registerPrefix(token.If, p.parseIfExpression)
	p.registerPrefix(token.Case, p.parseCaseExpression)
	p.registerPrefix(token.Self, p.parseSelfExpression)
	p.registerPrefix(token.LBracket, p.parseArrayExpression)
	p.registerPrefix(token.LBrace, p.parseHashExpression)
	p.registerPrefix(token.Semicolon, p.parseSemicolon)
	p.registerPrefix(token.Yield, p.parseYieldExpression)
	p.registerPrefix(token.GetBlock, p.parseGetBlockExpression)

	p.infixParseFns = make(map[token.Type]infixParseFn)
	p.registerInfix(token.Plus, p.parseInfixExpression)
	p.registerInfix(token.PlusEq, p.parseAssignExpression)
	p.registerInfix(token.Minus, p.parseInfixExpression)
	p.registerInfix(token.MinusEq, p.parseAssignExpression)
	p.registerInfix(token.Modulo, p.parseInfixExpression)
	p.registerInfix(token.Slash, p.parseInfixExpression)
	p.registerInfix(token.Pow, p.parseInfixExpression)
	p.registerInfix(token.Eq, p.parseInfixExpression)
	p.registerInfix(token.NotEq, p.parseInfixExpression)
	p.registerInfix(token.Match, p.parseInfixExpression)
	p.registerInfix(token.LT, p.parseInfixExpression)
	p.registerInfix(token.LTE, p.parseInfixExpression)
	p.registerInfix(token.GT, p.parseInfixExpression)
	p.registerInfix(token.GTE, p.parseInfixExpression)
	p.registerInfix(token.COMP, p.parseInfixExpression)
	p.registerInfix(token.And, p.parseInfixExpression)
	p.registerInfix(token.Or, p.parseInfixExpression)
	p.registerInfix(token.OrEq, p.parseAssignExpression)
	p.registerInfix(token.Comma, p.parseMultiVariables)
	p.registerInfix(token.ResolutionOperator, p.parseInfixExpression)
	p.registerInfix(token.Assign, p.parseAssignExpression)
	p.registerInfix(token.Range, p.parseRangeExpression)
	p.registerInfix(token.Dot, p.parseCallExpressionWithReceiver)
	p.registerInfix(token.LParen, p.parseCallExpressionWithoutReceiver)
	p.registerInfix(token.LBracket, p.parseIndexExpression)
	p.registerInfix(token.Colon, p.parseArgumentPairExpression)
	p.registerInfix(token.Asterisk, p.parseInfixExpression)

	return p
}

// ParseProgram update program statements and return program
func (p *Parser) ParseProgram() (*ast.Program, *errors.Error) {

	defer func() {
		if recover() != nil {
			fmt.Println("Panic has been recover parser ")
		}
	}()

	p.error = nil
	// Read two tokens, so curToken and peekToken are both set.
	p.nextToken()
	p.nextToken()
	program := &ast.Program{}
	program.Statements = []ast.Statement{}

	for !p.curTokenIs(token.EOF) {
		stmt := p.parseStatement()

		if p.error != nil {
			return nil, p.error
		}

		if stmt != nil {
			program.Statements = append(program.Statements, stmt)
		}

		p.nextToken()
	}

	if p.Mode == TestMode {
		stmt := program.Statements[len(program.Statements)-1]
		expStmt, ok := stmt.(*ast.ExpressionStatement)

		if ok {
			expStmt.Expression.MarkAsExp()
		}
	}

	return program, nil
}

func (p *Parser) parseSemicolon() ast.Expression {
	return nil
}

func (p *Parser) peekPrecedence() int {
	if p, ok := precedence.LookupTable[p.peekToken.Type]; ok {
		return p
	}

	return precedence.Normal
}

func (p *Parser) curPrecedence() int {
	if p, ok := precedence.LookupTable[p.curToken.Type]; ok {
		return p
	}

	return precedence.Normal
}

func (p *Parser) nextToken() {
	p.curToken = p.peekToken
	p.peekToken = p.Lexer.NextToken()
}

func (p *Parser) curTokenIs(t token.Type) bool {
	return p.curToken.Type == t
}

func (p *Parser) peekTokenIs(t token.Type) bool {
	return p.peekToken.Type == t
}

func (p *Parser) expectPeek(t token.Type) bool {
	if p.peekTokenIs(t) {
		p.nextToken()
		return true
	}
	p.peekError(t)
	return false
}

func (p *Parser) registerPrefix(tokenType token.Type, fn prefixParseFn) {
	p.prefixParseFns[tokenType] = fn
}

func (p *Parser) registerInfix(tokenType token.Type, fn infixParseFn) {
	p.infixParseFns[tokenType] = fn
}

func (p *Parser) peekTokenAtSameLine() bool {
	return p.curToken.Line == p.peekToken.Line && p.peekToken.Type != token.EOF
}

func (p *Parser) peekError(t token.Type) {
	msg := fmt.Sprintf("expected next token to be %s, got %s(%s) instead. Line: %d", t, p.peekToken.Type, p.peekToken.Literal, p.peekToken.Line)
	p.error = errors.InitError(msg, errors.UnexpectedTokenError)
}

func (p *Parser) noPrefixParseFnError(t token.Type) {
	msg := fmt.Sprintf("unexpected %s Line: %d", p.curToken.Literal, p.curToken.Line)

	if t == token.End {
		p.error = errors.InitError(msg, errors.UnexpectedEndError)
	} else {
		p.error = errors.InitError(msg, errors.UnexpectedTokenError)
	}
}

func (p *Parser) callConstantError(t token.Type) {
	msg := fmt.Sprintf("cannot call %s with %s. Line: %d", t, p.peekToken.Type, p.peekToken.Line)
	p.error = errors.InitError(msg, errors.UnexpectedTokenError)
}

func (p *Parser) IsNotDefMethodToken() bool {

	return p.curToken.Type != token.Ident && !(p.peekToken.Type == token.Dot && (p.curToken.Type == token.InstanceVariable || p.curToken.Type == token.Constant || p.curToken.Type == token.Self))
}
<|endoftext|>


<commit_before>/*
Open Source Initiative OSI - The MIT License (MIT):Licensing
The MIT License (MIT)
Copyright (c) 2017 Ralph Caraveo (deckarep@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

package cmd

import (
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/boltdb/bolt"
)

const (
	// Stores your host lookups for a period of time.
	hostLookupBucket = "hostLookupCacheBucket"
	// Stores recipe caches so we don't have to regen every time. Speeds up Blade.
	recipeCacheBucket = "recipeCommandCacheBucket"
)

var db *bolt.DB

func openDB() {
	var err error
	db, err = bolt.Open("blade-boltdb.db", 0644, nil)
	if err != nil {
		log.Fatal(err)
	}
}

func storeBolt(bucket, key, value string) {
	err := db.Update(func(tx *bolt.Tx) error {
		bucket, err := tx.CreateBucketIfNotExists([]byte(bucket))
		if err != nil {
			return err
		}

		err = bucket.Put([]byte(key), []byte(value))
		if err != nil {
			return err
		}

		return nil
	})

	if err != nil {
		log.Fatal(err)
	}
}

func getBolt(bucket, key string) string {
	result := ""
	// retrieve the data
	err := db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte(bucket))
		if bucket == nil {
			// Bucket not created yet
			return nil
		}

		val := bucket.Get([]byte(key))
		result = string(val)

		return nil
	})

	if err != nil {
		log.Fatal(err)
	}

	return result
}

func endOnSignal() {
	sigs := make(chan os.Signal, 1)
	done := make(chan bool, 1)

	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		<-sigs
		done <- true
	}()

	<-done
}
<commit_msg>Removing boltdb stuff<commit_after><|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/bitly/go-nsq"
	"github.com/codegangsta/cli"
	. "github.com/gonet2/libs/nsq-logger"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
)

const (
	LAYOUT = "2006/1/2 15:04:05"
)

var (
	logTemplate = make(map[byte]string)
)

func init() {
	logTemplate[FINEST] = "\033[0;34m%v [FINEST] %v %v %v %v %v \033[0m"
	logTemplate[FINE] = "\033[0;34m%v [FINE] %v %v %v %v %v \033[0m"
	logTemplate[DEBUG] = "\033[1;32m%v [DEBUG] %v %v %v %v %v \033[0m"
	logTemplate[TRACE] = "\033[0;37m%v [TRACE] %v %v %v %v %v \033[0m"
	logTemplate[WARNING] = "\033[7;33m%v [WARNING] %v %v %v %v %v \033[0m"
	logTemplate[INFO] = "\033[0;32m%v [INFO] %v %v %v %v %v  \033[0m"
	logTemplate[ERROR] = "\033[7;31m%v [ERROR] %v %v %v %v %v \033[0m"
	logTemplate[CRITICAL] = "\033[0;31m%v [CRITICAL] %v %v %v %v %v \033[0m"
}

var (
	tailFlag = []cli.Flag{
		cli.StringFlag{
			Name:  "topic,t",
			Value: "LOG",
			Usage: "NSQ topic , defalut is LOG",
		},
		cli.StringFlag{
			Name:  "channel, c",
			Value: "tailn",
			Usage: "NSQ channel, defalut is tailn",
		},
		cli.StringFlag{
			Name:  "number, n",
			Value: "0",
			Usage: "Line to show, defalut no limit",
		},
		cli.StringFlag{
			Name:  "nsqd-tcp-address, a",
			Value: "localhost:4150",
			Usage: "nsqd TCP address",
		},
		cli.StringFlag{
			Name:  "lookupd-http-address, l",
			Value: "localhost:4160",
			Usage: "lookupd HTTP address",
		},
		cli.StringFlag{
			Name:  "timeout, o",
			Value: "5",
			Usage: "Dial timeout, default 5s",
		},
		cli.StringFlag{
			Name:  "type",
			Value: "NSQLOG",
			Usage: "Tail type , default NSQLOG (others print json )",
		},
		cli.StringFlag{
			Name:  "log",
			Value: "false",
			Usage: "whether open inner log",
		},
	}
)

type TailHandler struct {
	totalMessages int
	messagesShown int
	printMessage  func(m *nsq.Message) error
}

func NSQLog(m *nsq.Message) error {
	info := &LogFormat{}
	err := json.Unmarshal(m.Body, &info)
	if err != nil {
		fmt.Printf("err %v\n", err)
		return err
	}
	fmt.Println(fmt.Sprintf(logTemplate[info.Level], info.Time.Format(LAYOUT), info.Prefix, info.Host, info.Msg, info.Caller, info.LineNo))
	return nil
}

func Log(m *nsq.Message) error {
	_, err := os.Stdout.Write(m.Body)
	if err != nil {
		return err
	}
	_, err = os.Stdout.WriteString("\n")
	return err
}

func main() {
	myApp := cli.NewApp()
	myApp.Name = "tailn"
	myApp.Usage = "Tail log from nsq !"
	myApp.Version = "0.0.1"
	myApp.Flags = tailFlag
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	myApp.Action = func(c *cli.Context) {
		// TODO CheckFlag
		CheckFlag(c)
		cfg := nsq.NewConfig()
		// dail timeout
		cfg.DialTimeout = time.Duration(c.Int("timeout")) * time.Second
		cfg.UserAgent = fmt.Sprint("go-nsq version:%v", nsq.VERSION)
		consumer, err := nsq.NewConsumer(c.String("topic"), c.String("channel"), cfg)
		if err != nil {
			fmt.Printf("error %v\n", err)
			os.Exit(0)
		}

		f := NSQLog
		if c.String("type") != "NSQLOG" {
			f = Log
		}

		// 屏蔽内部日志
		if !c.Bool("log") {
			consumer.SetLogger(nil, 0)
		}

		consumer.AddHandler(&TailHandler{c.Int("number"), 0, f})
		err = consumer.ConnectToNSQDs(strings.Split(c.String("nsqd-tcp-address"), ","))
		if err != nil {
			fmt.Printf("error %v\n", err)
			os.Exit(0)

		}
		err = consumer.ConnectToNSQLookupds(strings.Split(c.String("lookupd-http-address"), ","))
		if err != nil {
			fmt.Printf("error %v\n", err)
			os.Exit(0)
		}
		for {
			select {
			case <-consumer.StopChan:
				return
			case <-sigChan:
				consumer.Stop()
			}
		}
	}
	myApp.Run(os.Args)
}

func CheckFlag(c *cli.Context) {
	if c.String("channel") == "" || c.String("topic") == "" {
		cli.ShowAppHelp(c)
		os.Exit(0)
	}
}

func (th *TailHandler) HandleMessage(m *nsq.Message) error {
	th.messagesShown++
	if err := th.printMessage(m); err != nil {
		fmt.Printf("err %v\n", err)
		return err
	}
	if th.totalMessages > 0 && th.totalMessages < th.messagesShown {
		os.Exit(0)
	}
	return nil
}
<commit_msg>update color<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/bitly/go-nsq"
	"github.com/codegangsta/cli"
	. "github.com/gonet2/libs/nsq-logger"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
)

const (
	LAYOUT = "2006/1/2 15:04:05"
)

var (
	logTemplate = make(map[byte]string)
)

func init() {
	logTemplate[FINEST] = "\033[1;34m%v [FINEST] %v %v %v %v %v \033[0m"
	logTemplate[FINE] = "\033[0;34m%v [FINE] %v %v %v %v %v \033[0m"
	logTemplate[DEBUG] = "\033[1;32m%v [DEBUG] %v %v %v %v %v \033[0m"
	logTemplate[TRACE] = "\033[0;37m%v [TRACE] %v %v %v %v %v \033[0m"
	logTemplate[WARNING] = "\033[0;33m%v [WARNING] %v %v %v %v %v \033[0m"
	logTemplate[INFO] = "\033[0;32m%v [INFO] %v %v %v %v %v  \033[0m"
	logTemplate[ERROR] = "\033[0;31m%v [ERROR] %v %v %v %v %v \033[0m"
	logTemplate[CRITICAL] = "\033[7;31m%v [CRITICAL] %v %v %v %v %v \033[0m"
}

var (
	tailFlag = []cli.Flag{
		cli.StringFlag{
			Name:  "topic,t",
			Value: "LOG",
			Usage: "NSQ topic , defalut is LOG",
		},
		cli.StringFlag{
			Name:  "channel, c",
			Value: "tailn",
			Usage: "NSQ channel, defalut is tailn",
		},
		cli.StringFlag{
			Name:  "number, n",
			Value: "0",
			Usage: "Line to show, defalut no limit",
		},
		cli.StringFlag{
			Name:  "nsqd-tcp-address, a",
			Value: "localhost:4150",
			Usage: "nsqd TCP address",
		},
		cli.StringFlag{
			Name:  "lookupd-http-address, l",
			Value: "localhost:4160",
			Usage: "lookupd HTTP address",
		},
		cli.StringFlag{
			Name:  "timeout, o",
			Value: "5",
			Usage: "Dial timeout, default 5s",
		},
		cli.StringFlag{
			Name:  "type",
			Value: "NSQLOG",
			Usage: "Tail type , default NSQLOG (others print json )",
		},
		cli.StringFlag{
			Name:  "log",
			Value: "false",
			Usage: "whether open inner log",
		},
	}
)

type TailHandler struct {
	totalMessages int
	messagesShown int
	printMessage  func(m *nsq.Message) error
}

func NSQLog(m *nsq.Message) error {
	info := &LogFormat{}
	err := json.Unmarshal(m.Body, &info)
	if err != nil {
		fmt.Printf("err %v\n", err)
		return err
	}
	fmt.Println(fmt.Sprintf(logTemplate[info.Level], info.Time.Format(LAYOUT), info.Prefix, info.Host, info.Msg, info.Caller, info.LineNo))
	return nil
}

func Log(m *nsq.Message) error {
	_, err := os.Stdout.Write(m.Body)
	if err != nil {
		return err
	}
	_, err = os.Stdout.WriteString("\n")
	return err
}

func main() {
	myApp := cli.NewApp()
	myApp.Name = "tailn"
	myApp.Usage = "Tail log from nsq !"
	myApp.Version = "0.0.1"
	myApp.Flags = tailFlag
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	myApp.Action = func(c *cli.Context) {
		// TODO CheckFlag
		CheckFlag(c)
		cfg := nsq.NewConfig()
		// dail timeout
		cfg.DialTimeout = time.Duration(c.Int("timeout")) * time.Second
		cfg.UserAgent = fmt.Sprint("go-nsq version:%v", nsq.VERSION)
		consumer, err := nsq.NewConsumer(c.String("topic"), c.String("channel"), cfg)
		if err != nil {
			fmt.Printf("error %v\n", err)
			os.Exit(0)
		}

		f := NSQLog
		if c.String("type") != "NSQLOG" {
			f = Log
		}

		// 屏蔽内部日志
		if !c.Bool("log") {
			consumer.SetLogger(nil, 0)
		}

		consumer.AddHandler(&TailHandler{c.Int("number"), 0, f})
		err = consumer.ConnectToNSQDs(strings.Split(c.String("nsqd-tcp-address"), ","))
		if err != nil {
			fmt.Printf("error %v\n", err)
			os.Exit(0)

		}
		err = consumer.ConnectToNSQLookupds(strings.Split(c.String("lookupd-http-address"), ","))
		if err != nil {
			fmt.Printf("error %v\n", err)
			os.Exit(0)
		}
		for {
			select {
			case <-consumer.StopChan:
				return
			case <-sigChan:
				consumer.Stop()
			}
		}
	}
	myApp.Run(os.Args)
}

func CheckFlag(c *cli.Context) {
	if c.String("channel") == "" || c.String("topic") == "" {
		cli.ShowAppHelp(c)
		os.Exit(0)
	}
}

func (th *TailHandler) HandleMessage(m *nsq.Message) error {
	th.messagesShown++
	if err := th.printMessage(m); err != nil {
		fmt.Printf("err %v\n", err)
		return err
	}
	if th.totalMessages > 0 && th.totalMessages < th.messagesShown {
		os.Exit(0)
	}
	return nil
}
<|endoftext|>


<commit_before>package tally

import (
	"fmt"
	"github.com/qmsk/e2/client"
	"github.com/qmsk/e2/discovery"
	//	"github.com/wujiang/embd"
	//	_ "github.com/wujiang/embd/host/rpi" // This loads the RPi drive
	"log"
)

type Options struct {
	clientOptions    client.Options
	discoveryOptions discovery.Options
}

func (options Options) Tally(clientOptions client.Options, discoveryOptions discovery.Options) (*Tally, error) {
	options.clientOptions = clientOptions
	options.discoveryOptions = discoveryOptions

	var tally Tally

	return &tally, tally.start(options)
}

// Concurrent tally support for multiple sources and destinations
type Tally struct {
	options Options

	discovery     *discovery.Discovery
	discoveryChan chan discovery.Packet

	/* run() state */
	// active systems
	sources map[string]Source

	// updates to sources
	sourceChan chan Source
}

func (tally *Tally) start(options Options) error {
	tally.options = options
	tally.sources = make(map[string]Source)
	tally.sourceChan = make(chan Source)

	if discovery, err := options.discoveryOptions.Discovery(); err != nil {
		return fmt.Errorf("discovery:DiscoveryOptions.Discovery: %v", err)
	} else {
		tally.discovery = discovery
		tally.discoveryChan = discovery.Run()
	}

	return nil
}

// mainloop, owns Tally state
func (tally *Tally) Run() error {
	for {
		select {
		case discoveryPacket := <-tally.discoveryChan:
			if clientOptions, err := tally.options.clientOptions.DiscoverOptions(discoveryPacket); err != nil {
				log.Printf("Tally: invalid discovery client options: %v\n", err)
			} else if _, exists := tally.sources[clientOptions.String()]; exists {
				// already known
			} else if source, err := newSource(tally, clientOptions); err != nil {
				log.Printf("Tally: unable to connect to discovered system: %v\n", err)
			} else {
				log.Printf("Tally: connected to new source: %v\n", source)

				tally.sources[clientOptions.String()] = source
			}

		case source := <-tally.sourceChan:
			if err := source.err; err != nil {
				log.Printf("Tally: Source %v Error: %v\n", source, err)

				delete(tally.sources, source.String())
			} else {
				log.Printf("Tally: Source %v: Update\n", source)

				tally.sources[source.String()] = source
			}

			if err := tally.update(); err != nil {
				return fmt.Errorf("Tally.update: %v\n", err)
			}
		}
	}
}

// Compute new output state from sources
func (tally *Tally) update() error {
	var state = State{
		Inputs: make(map[Input]ID),
		Tally:  make(map[ID]Status),
	}

	for _, source := range tally.sources {
		if err := state.updateSystem(source.system, source.String()); err != nil {
			return err
		}
	}

	if err := state.update(); err != nil {
		return err
	}

	log.Printf("Tally.update: state:\n")
	state.Print()
	log.Printf("Set relays\n")
	relay_states := [8]bool{false, false, false, false, false, false, false, false}
	for i, status := range state.Tally {
		if i < 9 && i > 0 {
			relay_states[i-1] = status.Program
		}
	}

	for i, enable := range relay_states {
		fmt.Printf("relay %d: ", i+1)
		if enable {
			//			if err := relays[i].Write(embd.High); err != nil {
			//				panic(err)
			//			}
			fmt.Printf("ON, ")
		} else {
			//			if err := relays[i].Write(embd.Low); err != nil {
			//				panic(err)
			//			}
			fmt.Printf("off, ")
		}
	}
	fmt.Printf("\n")

	return nil
}
<commit_msg>Highlight tallies in ON state in prints<commit_after>package tally

import (
	"fmt"
	"github.com/qmsk/e2/client"
	"github.com/qmsk/e2/discovery"
	//	"github.com/wujiang/embd"
	//	_ "github.com/wujiang/embd/host/rpi" // This loads the RPi drive
	"log"
)

type Options struct {
	clientOptions    client.Options
	discoveryOptions discovery.Options
}

func (options Options) Tally(clientOptions client.Options, discoveryOptions discovery.Options) (*Tally, error) {
	options.clientOptions = clientOptions
	options.discoveryOptions = discoveryOptions

	var tally Tally

	return &tally, tally.start(options)
}

// Concurrent tally support for multiple sources and destinations
type Tally struct {
	options Options

	discovery     *discovery.Discovery
	discoveryChan chan discovery.Packet

	/* run() state */
	// active systems
	sources map[string]Source

	// updates to sources
	sourceChan chan Source
}

func (tally *Tally) start(options Options) error {
	tally.options = options
	tally.sources = make(map[string]Source)
	tally.sourceChan = make(chan Source)

	if discovery, err := options.discoveryOptions.Discovery(); err != nil {
		return fmt.Errorf("discovery:DiscoveryOptions.Discovery: %v", err)
	} else {
		tally.discovery = discovery
		tally.discoveryChan = discovery.Run()
	}

	return nil
}

// mainloop, owns Tally state
func (tally *Tally) Run() error {
	for {
		select {
		case discoveryPacket := <-tally.discoveryChan:
			if clientOptions, err := tally.options.clientOptions.DiscoverOptions(discoveryPacket); err != nil {
				log.Printf("Tally: invalid discovery client options: %v\n", err)
			} else if _, exists := tally.sources[clientOptions.String()]; exists {
				// already known
			} else if source, err := newSource(tally, clientOptions); err != nil {
				log.Printf("Tally: unable to connect to discovered system: %v\n", err)
			} else {
				log.Printf("Tally: connected to new source: %v\n", source)

				tally.sources[clientOptions.String()] = source
			}

		case source := <-tally.sourceChan:
			if err := source.err; err != nil {
				log.Printf("Tally: Source %v Error: %v\n", source, err)

				delete(tally.sources, source.String())
			} else {
				log.Printf("Tally: Source %v: Update\n", source)

				tally.sources[source.String()] = source
			}

			if err := tally.update(); err != nil {
				return fmt.Errorf("Tally.update: %v\n", err)
			}
		}
	}
}

// Compute new output state from sources
func (tally *Tally) update() error {
	var state = State{
		Inputs: make(map[Input]ID),
		Tally:  make(map[ID]Status),
	}

	for _, source := range tally.sources {
		if err := state.updateSystem(source.system, source.String()); err != nil {
			return err
		}
	}

	if err := state.update(); err != nil {
		return err
	}

	log.Printf("Tally.update: state:\n")
	state.Print()
	log.Printf("Set relays\n")
	relay_states := [8]bool{false, false, false, false, false, false, false, false}
	for i, status := range state.Tally {
		if i < 9 && i > 0 {
			relay_states[i-1] = status.Program
		}
	}

	for i, enable := range relay_states {
		fmt.Printf("\t%d: ", i+1)
		if enable {
			//			if err := relays[i].Write(embd.High); err != nil {
			//				panic(err)
			//			}
			fmt.Printf("\033[7m\033[1mON\033[21m\033[27m ")
		} else {
			//			if err := relays[i].Write(embd.Low); err != nil {
			//				panic(err)
			//			}
			fmt.Printf("off ")
		}
	}
	fmt.Printf("\n")

	return nil
}
<|endoftext|>


<commit_before>package task

import (
	"errors"
	"fmt"
	"gopkg.in/yaml.v2"
)

type TaskDefinition struct {
	Name                 string
	ContainerDefinitions map[string]*ContainerDefinition
}

type ContainerDefinition struct {
	Name                  string
	Image                 string            `yaml:"image"`
	Ports                 []string          `yaml:"ports"`
	Environment           map[string]string `yaml:"environment"`
	Links                 []string          `yaml:"links"`
	Volumes               []string          `yaml:"volumes"`
	VolumesFrom           []string          `yaml:"volumes_from"`
	Memory                int64             `yaml:"memory"`
	CpuUnits              int64             `yaml:"cpu_units"`
	Essential             bool              `yaml:"essential"`
	EntryPoint            string            `yaml:"entry_point"`
	Command               string            `yaml:"command"`
	DisableNetworking     bool              `yaml:"disable_networking"`
	DnsSearchDomains      []string          `yaml:"dns_search_domains"`
	DnsServers            []string          `yaml:"dns_servers"`
	DockerLabels          map[string]string `yaml:"docker_labels"`
	DockerSecurityOptions []string          `yaml:"docker_security_options"`
	ExtraHosts            []string          `yaml:"extra_hosts"`
	Hostname              string            `yaml:"hostname"`
}

func CreateTaskDefinition(taskDefName string, data string) (*TaskDefinition, error) {

	containerMap := map[string]ContainerDefinition{}
	if err := yaml.Unmarshal([]byte(data), &containerMap); err != nil {
		return nil, errors.New(fmt.Sprintf("%v\n\n%v", err.Error(), data))
	}

	containers := map[string]*ContainerDefinition{}
	for name, container := range containerMap {
		con := container
		con.Name = name
		containers[name] = &con
	}

	taskDef := TaskDefinition{
		Name:                 taskDefName,
		ContainerDefinitions: containers,
	}

	return &taskDef, nil
}
<commit_msg>keep the compatibility with docker-compose<commit_after>package task

import (
	"errors"
	"fmt"
	"gopkg.in/yaml.v2"
)

type TaskDefinition struct {
	Name                 string
	ContainerDefinitions map[string]*ContainerDefinition
}

type ContainerDefinition struct {
	Name                  string
	Image                 string            `yaml:"image"`
	Ports                 []string          `yaml:"ports"`
	Environment           map[string]string `yaml:"environment"`
	Links                 []string          `yaml:"links"`
	Volumes               []string          `yaml:"volumes"`
	VolumesFrom           []string          `yaml:"volumes_from"`
	Memory                int64             `yaml:"memory"`
	CpuUnits              int64             `yaml:"cpu_units"`
	Essential             bool              `yaml:"essential"`
	EntryPoint            string            `yaml:"entry_point"`
	Command               string            `yaml:"command"`
	DisableNetworking     bool              `yaml:"disable_networking"`
	DnsSearchDomains      []string          `yaml:"dns_search"`
	DnsServers            []string          `yaml:"dns"`
	DockerLabels          map[string]string `yaml:"labels"`
	DockerSecurityOptions []string          `yaml:"security_opt"`
	ExtraHosts            []string          `yaml:"extra_hosts"`
	Hostname              string            `yaml:"hostname"`
}

func CreateTaskDefinition(taskDefName string, data string) (*TaskDefinition, error) {

	containerMap := map[string]ContainerDefinition{}
	if err := yaml.Unmarshal([]byte(data), &containerMap); err != nil {
		return nil, errors.New(fmt.Sprintf("%v\n\n%v", err.Error(), data))
	}

	containers := map[string]*ContainerDefinition{}
	for name, container := range containerMap {
		con := container
		con.Name = name
		containers[name] = &con
	}

	taskDef := TaskDefinition{
		Name:                 taskDefName,
		ContainerDefinitions: containers,
	}

	return &taskDef, nil
}
<|endoftext|>


<commit_before>package term // import "github.com/amalog/go/term"

import (
	"io"

	"github.com/amalog/go/scanner"
)

type Reader struct {
	s *scanner.Scanner
}

func NewReader(r io.RuneScanner) *Reader {
	self := new(Reader)
	self.s = scanner.New(r)
	return self
}

func (r *Reader) Read() (Term, error) {
	x, err := r.s.Scan()
	if err != nil {
		return nil, err
	}

	switch x.Class {
	case scanner.Atom:
		y, err := r.s.Scan()
		if err != nil {
			return nil, err
		}

		switch y.Class {
		case scanner.Punct:
			switch y.Text {
			case ";":
				return NewAtom(x.Text), nil
			case "(":
				args, err := r.readSeq() // consumes closing ')'
				if err != nil {
					return nil, err
				}

				z, err := r.s.Scan()
				if err != nil {
					return nil, err
				}

				switch z.Class {
				case scanner.Punct:
					switch z.Text {
					case ";":
						t := &Struct{
							Name: NewAtom(x.Text),
							Args: NewSeq(args),
						}
						return t, nil
					}
				}
				return nil, &ErrUnexpectedToken{z}
			}
		}
		return nil, &ErrUnexpectedToken{y}
	case scanner.String:
		if len(x.Text) < 2 {
			return nil, &Err{x, "string token too short"}
		}
		if x.Text[0] != '"' {
			return nil, &Err{x, "string missing opening quote"}
		}
		if x.Text[len(x.Text)-1] != '"' {
			return nil, &Err{x, "string missing closing quote"}
		}
		text := x.Text[1 : len(x.Text)-1]

		y, err := r.s.Scan()
		if err != nil {
			return nil, err
		}

		switch y.Class {
		case scanner.Punct:
			if y.Text == ";" {
				return NewString(text), nil
			}
		}
		return nil, &ErrUnexpectedToken{y}
	case scanner.Var:
		y, err := r.s.Scan()
		if err != nil {
			return nil, err
		}

		switch y.Class {
		case scanner.Punct:
			if y.Text == ";" {
				term := &Var{
					Name:  x.Text,
					Value: nil,
				}
				return term, nil
			}
		}
		return nil, &ErrUnexpectedToken{y}
	default:
		return nil, &ErrUnexpectedToken{x}
	}

	return nil, nil
}

// reads a sequence of terms. should be called immediately after the '('
// term is consumed.  consumes the closing ')' term.
func (r *Reader) readSeq() ([]Term, error) {
	args := make([]Term, 0)

ARGS:
	for {
		t, err := r.Read()
		switch e := err.(type) {
		case nil:
			args = append(args, t)
		case *ErrUnexpectedToken:
			if e.Token.Class == scanner.Punct && e.Token.Text == ")" {
				break ARGS
			}
			return nil, err
		default:
			return nil, err
		}
	}

	return args, nil
}
<commit_msg>Factor out the term terminator<commit_after>package term // import "github.com/amalog/go/term"

import (
	"io"

	"github.com/amalog/go/scanner"
)

// central definition of the term terminator
const terminator = ";"

type Reader struct {
	s *scanner.Scanner
}

func NewReader(r io.RuneScanner) *Reader {
	self := new(Reader)
	self.s = scanner.New(r)
	return self
}

func (r *Reader) Read() (Term, error) {
	x, err := r.s.Scan()
	if err != nil {
		return nil, err
	}

	switch x.Class {
	case scanner.Atom:
		y, err := r.s.Scan()
		if err != nil {
			return nil, err
		}

		switch y.Class {
		case scanner.Punct:
			switch y.Text {
			case terminator:
				return NewAtom(x.Text), nil
			case "(":
				args, err := r.readSeq() // consumes closing ')'
				if err != nil {
					return nil, err
				}

				z, err := r.s.Scan()
				if err != nil {
					return nil, err
				}

				switch z.Class {
				case scanner.Punct:
					switch z.Text {
					case terminator:
						t := &Struct{
							Name: NewAtom(x.Text),
							Args: NewSeq(args),
						}
						return t, nil
					}
				}
				return nil, &ErrUnexpectedToken{z}
			}
		}
		return nil, &ErrUnexpectedToken{y}
	case scanner.String:
		if len(x.Text) < 2 {
			return nil, &Err{x, "string token too short"}
		}
		if x.Text[0] != '"' {
			return nil, &Err{x, "string missing opening quote"}
		}
		if x.Text[len(x.Text)-1] != '"' {
			return nil, &Err{x, "string missing closing quote"}
		}
		text := x.Text[1 : len(x.Text)-1]

		y, err := r.s.Scan()
		if err != nil {
			return nil, err
		}

		switch y.Class {
		case scanner.Punct:
			if y.Text == terminator {
				return NewString(text), nil
			}
		}
		return nil, &ErrUnexpectedToken{y}
	case scanner.Var:
		y, err := r.s.Scan()
		if err != nil {
			return nil, err
		}

		switch y.Class {
		case scanner.Punct:
			if y.Text == terminator {
				term := &Var{
					Name:  x.Text,
					Value: nil,
				}
				return term, nil
			}
		}
		return nil, &ErrUnexpectedToken{y}
	default:
		return nil, &ErrUnexpectedToken{x}
	}

	return nil, nil
}

// reads a sequence of terms. should be called immediately after the '('
// term is consumed.  consumes the closing ')' term.
func (r *Reader) readSeq() ([]Term, error) {
	args := make([]Term, 0)

ARGS:
	for {
		t, err := r.Read()
		switch e := err.(type) {
		case nil:
			args = append(args, t)
		case *ErrUnexpectedToken:
			if e.Token.Class == scanner.Punct && e.Token.Text == ")" {
				break ARGS
			}
			return nil, err
		default:
			return nil, err
		}
	}

	return args, nil
}
<|endoftext|>


<commit_before>package driver

import (
	log "github.com/Sirupsen/logrus"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netlink/nl"
	"net"
	"sync"
	"syscall"
)

type neighCheck struct {
	ip *net.IP
	ch chan<- bool
}

type neighUseNotifier struct {
	ip *net.IP
	ch chan<- struct{}
}

type neighState struct {
	state int
	cbs   []chan<- bool     // callbacks to notify on address in use or not
	ncbs  []chan<- struct{} //channel to be closed if address comes in use
}

func (n *neighState) isKnown() bool {
	return n.state == netlink.NUD_FAILED || n.state == netlink.NUD_REACHABLE
}

func (n *neighState) isReachable() bool {
	return n.state != netlink.NUD_FAILED
}

func checkNeigh(ncCh <-chan *neighCheck, ncUCh <-chan *neighUseNotifier, quit <-chan struct{}, wg sync.WaitGroup) {
	nch := make(chan *netlink.Neigh)

	neighSubscribe(nch, quit, wg)
	neighs := make(map[string]neighState)

	for {
		select {
		case _ = <-quit:
			return
		case n := <-nch:
			ns := neighs[n.IP.String()]
			ns.state = n.State
			if !ns.isKnown() {
				if len(ns.cbs) == 0 && len(ns.ncbs) == 0 {
					delete(neighs, n.IP.String())
				}
				if len(ns.cbs) > 0 {
					log.Debugf("Callbacks waiting on unknown neigh update. Probing %v", n.IP)
					probe(&n.IP)
				}
				break
			}
			if ns.isReachable() {
				for _, cb := range ns.ncbs {
					log.Debugf("Closing in use callback for %v", n.IP)
					close(cb)
				}
			}
			for _, cb := range ns.cbs {
				log.Debugf("Returning answer to callback for %v", n.IP)
				cb <- ns.isReachable()
			}
			ns.cbs = []chan<- bool{}
			neighs[n.IP.String()] = ns
		case n := <-ncCh:
			ns := neighs[n.ip.String()]
			if ns.isKnown() {
				log.Debugf("Already have answer for requested callback on %v", n.ip)
				n.ch <- ns.isReachable()
				break
			}
			log.Debugf("Registering callback on %v", n.ip)
			ns.cbs = append(ns.cbs, n.ch)
			neighs[n.ip.String()] = ns
			probe(n.ip)
		case n := <-ncUCh:
			ns := neighs[n.ip.String()]
			if ns.isKnown() && ns.isReachable() {
				log.Debugf("Already in use, closing callback on %v", n.ip)
				close(n.ch)
			}
			log.Debugf("Registering in use callback for %v", n.ip)
			ns.ncbs = append(ns.ncbs, n.ch)
			neighs[n.ip.String()] = ns
		}
	}
}

func probe(ip *net.IP) {
	conn, err := net.Dial("udp", ip.String()+":8765")
	if err != nil {
		log.Error(err)
		return
	}
	defer conn.Close()
	conn.Write([]byte("probe"))
	return
}

func neighSubscribe(ch chan<- *netlink.Neigh, done <-chan struct{}, wg sync.WaitGroup) error {
	s, err := nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_NEIGH)
	if err != nil {
		return err
	}
	if done != nil {
		wg.Add(1)
		go func() {
			defer wg.Done()
			<-done
			s.Close()
		}()
	}

	wg.Add(1)
	go func() {
		defer wg.Done()
		defer close(ch)
		for {
			msgs, err := s.Receive()
			if err != nil {
				panic(err)
			}
			for _, m := range msgs {
				n, err := netlink.NeighDeserialize(m.Data)
				if err != nil {
					log.Errorf("Error deserializing neighbor message %v", m.Data)
				}
				ch <- n
			}
		}
	}()

	return nil
}
<commit_msg>recover from closing closed channel panics<commit_after>package driver

import (
	log "github.com/Sirupsen/logrus"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netlink/nl"
	"net"
	"sync"
	"syscall"
)

type neighCheck struct {
	ip *net.IP
	ch chan<- bool
}

type neighUseNotifier struct {
	ip *net.IP
	ch chan<- struct{}
}

type neighState struct {
	state int
	cbs   []chan<- bool     // callbacks to notify on address in use or not
	ncbs  []chan<- struct{} //channel to be closed if address comes in use
}

func (n *neighState) isKnown() bool {
	return n.state == netlink.NUD_FAILED || n.state == netlink.NUD_REACHABLE
}

func (n *neighState) isReachable() bool {
	return n.state != netlink.NUD_FAILED
}

func checkNeigh(ncCh <-chan *neighCheck, ncUCh <-chan *neighUseNotifier, quit <-chan struct{}, wg sync.WaitGroup) {
	nch := make(chan *netlink.Neigh)

	neighSubscribe(nch, quit, wg)
	neighs := make(map[string]neighState)

	for {
		select {
		case _ = <-quit:
			return
		case n := <-nch:
			ns := neighs[n.IP.String()]
			ns.state = n.State
			if !ns.isKnown() {
				if len(ns.cbs) == 0 && len(ns.ncbs) == 0 {
					delete(neighs, n.IP.String())
				}
				if len(ns.cbs) > 0 {
					log.Debugf("Callbacks waiting on unknown neigh update. Probing %v", n.IP)
					probe(&n.IP)
				}
				break
			}
			if ns.isReachable() {
				for _, cb := range ns.ncbs {
					log.Debugf("Closing in use callback for %v", n.IP)
					// Catch panics closing closed channel. This can happen if
					// we get 2 updates very quickly
					func() {
						defer func() { recover() }()
						close(cb)
					}()
				}
			}
			for _, cb := range ns.cbs {
				log.Debugf("Returning answer to callback for %v", n.IP)
				cb <- ns.isReachable()
			}
			ns.cbs = []chan<- bool{}
			neighs[n.IP.String()] = ns
		case n := <-ncCh:
			ns := neighs[n.ip.String()]
			if ns.isKnown() {
				log.Debugf("Already have answer for requested callback on %v", n.ip)
				n.ch <- ns.isReachable()
				break
			}
			log.Debugf("Registering callback on %v", n.ip)
			ns.cbs = append(ns.cbs, n.ch)
			neighs[n.ip.String()] = ns
			probe(n.ip)
		case n := <-ncUCh:
			ns := neighs[n.ip.String()]
			if ns.isKnown() && ns.isReachable() {
				log.Debugf("Already in use, closing callback on %v", n.ip)
				close(n.ch)
			}
			log.Debugf("Registering in use callback for %v", n.ip)
			ns.ncbs = append(ns.ncbs, n.ch)
			neighs[n.ip.String()] = ns
		}
	}
}

func probe(ip *net.IP) {
	conn, err := net.Dial("udp", ip.String()+":8765")
	if err != nil {
		log.Error(err)
		return
	}
	defer conn.Close()
	conn.Write([]byte("probe"))
	return
}

func neighSubscribe(ch chan<- *netlink.Neigh, done <-chan struct{}, wg sync.WaitGroup) error {
	s, err := nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_NEIGH)
	if err != nil {
		return err
	}
	if done != nil {
		wg.Add(1)
		go func() {
			defer wg.Done()
			<-done
			s.Close()
		}()
	}

	wg.Add(1)
	go func() {
		defer wg.Done()
		defer close(ch)
		for {
			msgs, err := s.Receive()
			if err != nil {
				panic(err)
			}
			for _, m := range msgs {
				n, err := netlink.NeighDeserialize(m.Data)
				if err != nil {
					log.Errorf("Error deserializing neighbor message %v", m.Data)
				}
				ch <- n
			}
		}
	}()

	return nil
}
<|endoftext|>


<commit_before>// +build !windows

package graphdriver

import (
	"fmt"
	"os"
	"syscall"

	"github.com/containers/storage/pkg/idtools"
	"github.com/containers/storage/pkg/system"
)

func platformLChown(path string, info os.FileInfo, toHost, toContainer *idtools.IDMappings) error {
	st, ok := info.Sys().(*syscall.Stat_t)
	if !ok {
		return nil
	}
	// Map an on-disk UID/GID pair from host to container
	// using the first map, then back to the host using the
	// second map.  Skip that first step if they're 0, to
	// compensate for cases where a parent layer should
	// have had a mapped value, but didn't.
	uid, gid := int(st.Uid), int(st.Gid)
	if toContainer != nil {
		pair := idtools.IDPair{
			UID: uid,
			GID: gid,
		}
		mappedUID, mappedGID, err := toContainer.ToContainer(pair)
		if err != nil {
			if (uid != 0) || (gid != 0) {
				return fmt.Errorf("error mapping host ID pair %#v for %q to container: %v", pair, path, err)
			}
			mappedUID, mappedGID = uid, gid
		}
		uid, gid = mappedUID, mappedGID
	}
	if toHost != nil {
		pair := idtools.IDPair{
			UID: uid,
			GID: gid,
		}
		mappedPair, err := toHost.ToHost(pair)
		if err != nil {
			return fmt.Errorf("error mapping container ID pair %#v for %q to host: %v", pair, path, err)
		}
		uid, gid = mappedPair.UID, mappedPair.GID
	}
	if uid != int(st.Uid) || gid != int(st.Gid) {
		cap, err := system.Lgetxattr(path, "security.capability")
		if err != nil && err != system.ErrNotSupportedPlatform {
			return fmt.Errorf("%s: %v", os.Args[0], err)
		}

		// Make the change.
		if err := system.Lchown(path, uid, gid); err != nil {
			return fmt.Errorf("%s: %v", os.Args[0], err)
		}
		// Restore the SUID and SGID bits if they were originally set.
		if (info.Mode()&os.ModeSymlink == 0) && info.Mode()&(os.ModeSetuid|os.ModeSetgid) != 0 {
			if err := system.Chmod(path, info.Mode()); err != nil {
				return fmt.Errorf("%s: %v", os.Args[0], err)
			}
		}
		if cap != nil {
			if err := system.Lsetxattr(path, "security.capability", cap, 0); err != nil {
				return fmt.Errorf("%s: %v", os.Args[0], err)
			}
		}

	}
	return nil
}
<commit_msg>chown: ignore both pkg/system.EOPNOTSUPP and pkg/system.ErrNotSupportedPlatform<commit_after>// +build !windows

package graphdriver

import (
	"errors"
	"fmt"
	"os"
	"syscall"

	"github.com/containers/storage/pkg/idtools"
	"github.com/containers/storage/pkg/system"
)

func platformLChown(path string, info os.FileInfo, toHost, toContainer *idtools.IDMappings) error {
	st, ok := info.Sys().(*syscall.Stat_t)
	if !ok {
		return nil
	}
	// Map an on-disk UID/GID pair from host to container
	// using the first map, then back to the host using the
	// second map.  Skip that first step if they're 0, to
	// compensate for cases where a parent layer should
	// have had a mapped value, but didn't.
	uid, gid := int(st.Uid), int(st.Gid)
	if toContainer != nil {
		pair := idtools.IDPair{
			UID: uid,
			GID: gid,
		}
		mappedUID, mappedGID, err := toContainer.ToContainer(pair)
		if err != nil {
			if (uid != 0) || (gid != 0) {
				return fmt.Errorf("error mapping host ID pair %#v for %q to container: %v", pair, path, err)
			}
			mappedUID, mappedGID = uid, gid
		}
		uid, gid = mappedUID, mappedGID
	}
	if toHost != nil {
		pair := idtools.IDPair{
			UID: uid,
			GID: gid,
		}
		mappedPair, err := toHost.ToHost(pair)
		if err != nil {
			return fmt.Errorf("error mapping container ID pair %#v for %q to host: %v", pair, path, err)
		}
		uid, gid = mappedPair.UID, mappedPair.GID
	}
	if uid != int(st.Uid) || gid != int(st.Gid) {
		cap, err := system.Lgetxattr(path, "security.capability")
		if err != nil && !errors.Is(err, system.EOPNOTSUPP) && err != system.ErrNotSupportedPlatform {
			return fmt.Errorf("%s: %v", os.Args[0], err)
		}

		// Make the change.
		if err := system.Lchown(path, uid, gid); err != nil {
			return fmt.Errorf("%s: %v", os.Args[0], err)
		}
		// Restore the SUID and SGID bits if they were originally set.
		if (info.Mode()&os.ModeSymlink == 0) && info.Mode()&(os.ModeSetuid|os.ModeSetgid) != 0 {
			if err := system.Chmod(path, info.Mode()); err != nil {
				return fmt.Errorf("%s: %v", os.Args[0], err)
			}
		}
		if cap != nil {
			if err := system.Lsetxattr(path, "security.capability", cap, 0); err != nil {
				return fmt.Errorf("%s: %v", os.Args[0], err)
			}
		}

	}
	return nil
}
<|endoftext|>


<commit_before>package editor

import (
	"fmt"
	"strings"

	"github.com/elpinal/coco3/screen"
)

type exCommand struct {
	name string
	fn   func(*commandline, []string) continuity
}

// exComands represents a table of Ex commands and corresponding functions.
// The order is important. Precede commands have higher precedence.
var exCommands = []exCommand{
	{"help", (*commandline).help},
	{"delete", (*commandline).delete},
	{"quit", (*commandline).quit},
}

type commandline struct {
	streamSet
	*editor

	basic *basic
}

func newCommandline(s streamSet, e *editor) *commandline {
	return &commandline{
		streamSet: s,
		editor:    e,
		basic:     &basic{},
	}
}

func (e *commandline) Mode() mode {
	return modeCommandline
}

func (e *commandline) Position() int {
	return e.basic.pos + 1
}

func (e *commandline) Runes() []rune {
	return e.buf
}

func (e *commandline) Message() []rune {
	return append([]rune{':'}, e.basic.buf...)
}

func (e *commandline) Highlight() *screen.Hi {
	return nil
}

func (e *commandline) Run() (end continuity, next modeChanger, err error) {
	r, _, err := e.streamSet.in.ReadRune()
	if err != nil {
		return end, next, err
	}
	switch r {
	case CharCtrlM, CharCtrlJ:
	case CharEscape, CharCtrlC:
		next = norm()
		return end, next, err
	case CharBackspace, CharCtrlH:
		if len(e.basic.buf) == 0 {
			next = norm()
			return
		}
		e.basic.delete(e.basic.pos-1, e.basic.pos)
	case CharCtrlB:
		e.basic.move(0)
	case CharCtrlE:
		e.basic.move(len(e.basic.buf))
	case CharCtrlU:
		e.basic.delete(0, e.basic.pos)
	case CharCtrlW:
		// FIXME: It's redundant.
		ed := newEditor()
		ed.pos = e.basic.pos
		ed.buf = e.basic.buf
		pos := ed.pos
		ed.wordBackward()
		e.basic.delete(pos, ed.pos)
		return
	default:
		e.basic.insert([]rune{r}, e.basic.pos)
	}
	if r != CharCtrlM && r != CharCtrlJ {
		return
	}
	next = norm()
	var candidate exCommand
	s := string(e.basic.buf)
	if s == "" {
		return
	}
	for _, cmd := range exCommands {
		if !strings.HasPrefix(cmd.name, s) {
			continue
		}
		if cmd.name == s {
			end = cmd.fn(e, nil)
			return
		}
		if candidate.name == "" {
			candidate = cmd
		}
	}
	if candidate.name != "" {
		end = candidate.fn(e, nil)
		return
	}
	err = fmt.Errorf("not a command: %q", s)
	return
}

func (e *commandline) quit(args []string) continuity {
	return exit
}

func (e *commandline) delete(args []string) (_ continuity) {
	e.editor.delete(0, len(e.editor.buf))
	return
}

func (e *commandline) help(args []string) continuity {
	e.buf = []rune("help")
	e.pos = 4
	return execute
}

func (e *commandline) substitute(args []string) (_ continuity) {
	return
}
<commit_msg>Bind :substitute<commit_after>package editor

import (
	"fmt"
	"strings"

	"github.com/elpinal/coco3/screen"
)

type exCommand struct {
	name string
	fn   func(*commandline, []string) continuity
}

// exComands represents a table of Ex commands and corresponding functions.
// The order is important. Precede commands have higher precedence.
var exCommands = []exCommand{
	{"help", (*commandline).help},
	{"delete", (*commandline).delete},
	{"quit", (*commandline).quit},
	{"substitute", (*commandline).substitute},
}

type commandline struct {
	streamSet
	*editor

	basic *basic
}

func newCommandline(s streamSet, e *editor) *commandline {
	return &commandline{
		streamSet: s,
		editor:    e,
		basic:     &basic{},
	}
}

func (e *commandline) Mode() mode {
	return modeCommandline
}

func (e *commandline) Position() int {
	return e.basic.pos + 1
}

func (e *commandline) Runes() []rune {
	return e.buf
}

func (e *commandline) Message() []rune {
	return append([]rune{':'}, e.basic.buf...)
}

func (e *commandline) Highlight() *screen.Hi {
	return nil
}

func (e *commandline) Run() (end continuity, next modeChanger, err error) {
	r, _, err := e.streamSet.in.ReadRune()
	if err != nil {
		return end, next, err
	}
	switch r {
	case CharCtrlM, CharCtrlJ:
	case CharEscape, CharCtrlC:
		next = norm()
		return end, next, err
	case CharBackspace, CharCtrlH:
		if len(e.basic.buf) == 0 {
			next = norm()
			return
		}
		e.basic.delete(e.basic.pos-1, e.basic.pos)
	case CharCtrlB:
		e.basic.move(0)
	case CharCtrlE:
		e.basic.move(len(e.basic.buf))
	case CharCtrlU:
		e.basic.delete(0, e.basic.pos)
	case CharCtrlW:
		// FIXME: It's redundant.
		ed := newEditor()
		ed.pos = e.basic.pos
		ed.buf = e.basic.buf
		pos := ed.pos
		ed.wordBackward()
		e.basic.delete(pos, ed.pos)
		return
	default:
		e.basic.insert([]rune{r}, e.basic.pos)
	}
	if r != CharCtrlM && r != CharCtrlJ {
		return
	}
	next = norm()
	var candidate exCommand
	s := string(e.basic.buf)
	if s == "" {
		return
	}
	for _, cmd := range exCommands {
		if !strings.HasPrefix(cmd.name, s) {
			continue
		}
		if cmd.name == s {
			end = cmd.fn(e, nil)
			return
		}
		if candidate.name == "" {
			candidate = cmd
		}
	}
	if candidate.name != "" {
		end = candidate.fn(e, nil)
		return
	}
	err = fmt.Errorf("not a command: %q", s)
	return
}

func (e *commandline) quit(args []string) continuity {
	return exit
}

func (e *commandline) delete(args []string) (_ continuity) {
	e.editor.delete(0, len(e.editor.buf))
	return
}

func (e *commandline) help(args []string) continuity {
	e.buf = []rune("help")
	e.pos = 4
	return execute
}

func (e *commandline) substitute(args []string) (_ continuity) {
	return
}
<|endoftext|>


<commit_before>package edward_test

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"strings"
	"testing"

	"github.com/pkg/errors"
	"github.com/theothertomelliott/gopsutil-nocgo/process"
	"github.com/yext/edward/edward"
	"github.com/yext/edward/home"
	"github.com/yext/edward/tracker"
)

// Path to the Edward executable as built
var edwardExecutable string

func TestMain(m *testing.M) {
	buildDir, err := ioutil.TempDir("", "edwardTest")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(buildDir)

	edwardExecutable = path.Join(buildDir, "edward")

	cmd := exec.Command("go", "build", "-o", edwardExecutable, "github.com/yext/edward")
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		log.Fatal(err)
	}

	// Set up edward home directory
	if err := home.EdwardConfig.Initialize(); err != nil {
		log.Fatal(err)
	}

	os.Exit(m.Run())
}

type testFollower struct {
	states     map[string]string
	stateOrder []string
	messages   []string
}

func newTestFollower() *testFollower {
	return &testFollower{
		states: make(map[string]string),
	}
}

func (f *testFollower) Handle(update tracker.Task) {
	var names []string
	for _, task := range update.Lineage() {
		if task.Name() != "" {
			names = append(names, task.Name())
		}
	}

	fullName := strings.Join(names, " > ")
	f.states[fullName] = update.State().String()
	if len(f.stateOrder) == 0 || f.stateOrder[len(f.stateOrder)-1] != fullName {
		f.stateOrder = append(f.stateOrder, fullName)
	}
	f.messages = append(f.messages, update.Messages()...)
}
func (f *testFollower) Done() {}

// getRunnerAndServiceProcesses returns all processes and children spawned by this test
func getRunnerAndServiceProcesses(t *testing.T) []*process.Process {
	var processes []*process.Process
	testProcess, err := process.NewProcess(int32(os.Getpid()))
	if err != nil {
		t.Fatal(err)
	}
	runners, err := testProcess.Children()
	if err != nil {
		t.Fatalf("No processes found")
	}
	processes = append(processes, runners...)
	for _, runner := range runners {
		services, err := runner.Children()
		if err != nil {
			t.Fatalf("No processes found")
		}
		processes = append(processes, services...)
	}
	return processes
}

// verifyAndStopRunners expects that there will be the specified number of runners in progress,
// and that the runners are behaving as expected (exactly one child service, etc).
// Once verified, it will kill the runners and their child services.
func verifyAndStopRunners(t *testing.T, client *edward.Client, serviceCount int) {
	testProcess, err := process.NewProcess(int32(os.Getpid()))
	if err != nil {
		t.Fatal(err)
	}
	children, err := testProcess.Children()
	if err != nil {
		if serviceCount != 0 {
			t.Fatalf("No processes found, expected %d", serviceCount)
		}
	}
	var verifiedCount int
	for _, child := range children {
		verified, err := verifyAndStopRunner(t, client, child)
		if err != nil {
			t.Fatal(err)
		}
		if verified {
			verifiedCount++
		}
	}
	if verifiedCount != serviceCount {
		t.Errorf("Expected %d tagged runners, got %d", serviceCount, verifiedCount)
	}
}

// verifyAndStopRunner will check that a runner process has exactly one child service,
// and then kill the service, expecting the runner to die.
func verifyAndStopRunner(t *testing.T, client *edward.Client, runner *process.Process) (bool, error) {
	cmdline, err := runner.CmdlineSlice()
	if err != nil {
		t.Logf("error getting command line, ignoring: %v", err)
		return false, nil
	}
	if len(cmdline) > 2 && strings.HasSuffix(cmdline[0], "edward") && cmdline[1] == "run" {
		services, err := runner.Children()
		if err != nil {
			t.Logf("error getting children, ignoring: %v", err)
			return false, nil
		}
		if len(services) != 1 {
			t.Errorf("Expected 1 child of runner (%s), got %v", cmdline, len(services))
		}
		fullCmd := strings.Join(cmdline, " ")
		for _, tag := range client.Tags {
			if !strings.Contains(fullCmd, fmt.Sprintf("--tag %s", tag)) {
				return false, nil
			}
		}
		for _, service := range services {
			err = service.Kill()
			if err != nil {
				return false, errors.WithStack(err)
			}
		}
		if running, _ := runner.IsRunning(); running {
			return true, nil
		}
		t.Error("Expected stopping children to kill runner process")
		err = runner.Kill()
		if err != nil {
			t.Fatal("Could not kill runner:", err)
		}
		return true, nil
	}
	return false, nil
}
<commit_msg>Perform tag verification of runners before getting children and performing related tests.<commit_after>package edward_test

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"strings"
	"testing"

	"github.com/pkg/errors"
	"github.com/theothertomelliott/gopsutil-nocgo/process"
	"github.com/yext/edward/edward"
	"github.com/yext/edward/home"
	"github.com/yext/edward/tracker"
)

// Path to the Edward executable as built
var edwardExecutable string

func TestMain(m *testing.M) {
	buildDir, err := ioutil.TempDir("", "edwardTest")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(buildDir)

	edwardExecutable = path.Join(buildDir, "edward")

	cmd := exec.Command("go", "build", "-o", edwardExecutable, "github.com/yext/edward")
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		log.Fatal(err)
	}

	// Set up edward home directory
	if err := home.EdwardConfig.Initialize(); err != nil {
		log.Fatal(err)
	}

	os.Exit(m.Run())
}

type testFollower struct {
	states     map[string]string
	stateOrder []string
	messages   []string
}

func newTestFollower() *testFollower {
	return &testFollower{
		states: make(map[string]string),
	}
}

func (f *testFollower) Handle(update tracker.Task) {
	var names []string
	for _, task := range update.Lineage() {
		if task.Name() != "" {
			names = append(names, task.Name())
		}
	}

	fullName := strings.Join(names, " > ")
	f.states[fullName] = update.State().String()
	if len(f.stateOrder) == 0 || f.stateOrder[len(f.stateOrder)-1] != fullName {
		f.stateOrder = append(f.stateOrder, fullName)
	}
	f.messages = append(f.messages, update.Messages()...)
}
func (f *testFollower) Done() {}

// getRunnerAndServiceProcesses returns all processes and children spawned by this test
func getRunnerAndServiceProcesses(t *testing.T) []*process.Process {
	var processes []*process.Process
	testProcess, err := process.NewProcess(int32(os.Getpid()))
	if err != nil {
		t.Fatal(err)
	}
	runners, err := testProcess.Children()
	if err != nil {
		t.Fatalf("No processes found")
	}
	processes = append(processes, runners...)
	for _, runner := range runners {
		services, err := runner.Children()
		if err != nil {
			t.Fatalf("No processes found")
		}
		processes = append(processes, services...)
	}
	return processes
}

// verifyAndStopRunners expects that there will be the specified number of runners in progress,
// and that the runners are behaving as expected (exactly one child service, etc).
// Once verified, it will kill the runners and their child services.
func verifyAndStopRunners(t *testing.T, client *edward.Client, serviceCount int) {
	testProcess, err := process.NewProcess(int32(os.Getpid()))
	if err != nil {
		t.Fatal(err)
	}
	children, err := testProcess.Children()
	if err != nil {
		if serviceCount != 0 {
			t.Fatalf("No processes found, expected %d", serviceCount)
		}
	}
	var verifiedCount int
	for _, child := range children {
		verified, err := verifyAndStopRunner(t, client, child)
		if err != nil {
			t.Fatal(err)
		}
		if verified {
			verifiedCount++
		}
	}
	if verifiedCount != serviceCount {
		t.Errorf("Expected %d tagged runners, got %d", serviceCount, verifiedCount)
	}
}

// verifyAndStopRunner will check that a runner process has exactly one child service,
// and then kill the service, expecting the runner to die.
func verifyAndStopRunner(t *testing.T, client *edward.Client, runner *process.Process) (bool, error) {
	cmdline, err := runner.CmdlineSlice()
	if err != nil {
		t.Logf("error getting command line, ignoring: %v", err)
		return false, nil
	}
	if len(cmdline) > 2 && strings.HasSuffix(cmdline[0], "edward") && cmdline[1] == "run" {
		fullCmd := strings.Join(cmdline, " ")
		for _, tag := range client.Tags {
			if !strings.Contains(fullCmd, fmt.Sprintf("--tag %s", tag)) {
				return false, nil
			}
		}
		services, err := runner.Children()
		if err != nil {
			t.Logf("error getting children, ignoring: %v", err)
			return false, nil
		}
		if len(services) != 1 {
			t.Errorf("Expected 1 child of runner (%s), got %v", cmdline, len(services))
		}
		for _, service := range services {
			if running, _ := service.IsRunning(); running {
				err = service.Kill()
				if err != nil {
					return false, errors.WithMessage(err, "killing service")
				}
			}
		}
		if running, _ := runner.IsRunning(); running {
			return true, nil
		}
		t.Error("Expected stopping children to kill runner process")
		err = runner.Kill()
		if err != nil {
			t.Fatal("Could not kill runner:", err)
		}
		return true, nil
	}
	return false, nil
}
<|endoftext|>


<commit_before>package main

import "encoding/json"
import "net/http"
import log "github.com/Sirupsen/logrus"

type ElasticsearchHook struct{}

func (hook *ElasticsearchHook) Fire(entry *log.Entry) error {
    data := MarshalData(entry)

    serialized, err := json.Marshal(data)
    if err != nil {
        log.Error("Failed to marshal fields to JSON, %v", err)
        return nil
    }

    status := ElasticsearchPost("/logstash-data/metricsd", serialized)
    if status != http.StatusCreated {
        log.Warning("Indexing serialized data failed, %s", err)
    }

    return nil
}

func (hook *ElasticsearchHook) Levels() []log.Level {
  return []log.Level{
    log.InfoLevel,
  }
}
<commit_msg>Make elasticsearch shipping configurable<commit_after>package main

import "encoding/json"
import "fmt"
import "net/http"
import log "github.com/Sirupsen/logrus"

type ElasticsearchHook struct{}

func (hook *ElasticsearchHook) Fire(entry *log.Entry) error {
    data := MarshalData(entry)

    serialized, err := json.Marshal(data)
    if err != nil {
        log.Error("Failed to marshal fields to JSON, %v", err)
        return nil
    }

    entry_index := Getenv("ELASTICSEARCH_INDEX", "logstash-data")
    entry_type := Getenv("METRIC_TYPE", "metricsd")
    status := ElasticsearchPost(fmt.Sprintf("/%s/%s", entry_index, entry_type), serialized)
    if status != http.StatusCreated {
        log.Warning("Indexing serialized data failed, %s", err)
    }

    return nil
}

func (hook *ElasticsearchHook) Levels() []log.Level {
  return []log.Level{
    log.InfoLevel,
  }
}
<|endoftext|>


<commit_before>package net

import (
	"fmt"
	"io/ioutil"
	"net"

	log "github.com/Sirupsen/logrus"
	"github.com/vishvananda/netlink"
)

//AddIp it receives a CIDR Address and add it to the given interface
func AddIp(ip, iface string) error {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return err
	}

	addr, err := netlink.ParseAddr(ip)
	if err != nil {
		return err
	}

	return netlink.AddrAdd(link, addr)
}

func DelIp(ip, iface string) error {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return err
	}

	addr, err := netlink.ParseAddr(ip)
	if err != nil {
		return err
	}

	return netlink.AddrDel(link, addr)
}

func DelVips(iface string) error {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return err
	}

	addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
	if err != nil {
		return err
	}

	for _, a := range addrs[1:] {
		if err := netlink.AddrDel(link, &a); err != nil {
			return err
		}
	}

	return nil
}

func GetVips(iface string) ([]netlink.Addr, error) {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return []netlink.Addr{}, err
	}

	return netlink.AddrList(link, netlink.FAMILY_V4)
}

func GetFusisVipsIps(iface string) ([]string, error) {
	addrs, err := GetVips(iface)
	if err != nil {
		return nil, err
	}
	addrs = addrs[1:]
	ips := make([]string, len(addrs))
	for i, addr := range addrs {
		ips[i] = addr.IP.String()
	}
	return ips, nil
}

func GetIpByInterface(iface string) (string, error) {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return "", err
	}

	addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
	if err != nil {
		return "", err
	}

	return addrs[0].IP.String(), nil
}

func SetIpForwarding() error {
	return ioutil.WriteFile("/proc/sys/net/ipv4/ip_forward", []byte("1"), 0644)
}

func AddDefaultGateway(ip string) error {
	err := netlink.RouteAdd(&netlink.Route{
		Scope: netlink.SCOPE_UNIVERSE,
		Gw:    net.ParseIP(ip),
	})
	if err != nil {
		log.Errorf("Adding Default Gateway: %s", ip)
		return err
	}
	return nil
}

func GetDefaultGateway() (*netlink.Route, error) {
	routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
	if err != nil {
		return nil, err
	}

	var route netlink.Route
	for _, v := range routes {
		if v.Gw != nil {
			route = v
		}
	}

	if route.Gw == nil {
		return nil, fmt.Errorf("default gateway not found")
	}

	return &route, nil
}

func DeleteDefaultGateway(route *netlink.Route) error {
	err := netlink.RouteDel(route)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>net: small refactor<commit_after>package net

import (
	"fmt"
	"io/ioutil"
	"net"

	log "github.com/Sirupsen/logrus"
	"github.com/vishvananda/netlink"
)

//AddIp it receives a CIDR Address and add it to the given interface
func AddIp(ip, iface string) error {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return err
	}

	addr, err := netlink.ParseAddr(ip)
	if err != nil {
		return err
	}

	return netlink.AddrAdd(link, addr)
}

func DelIp(ip, iface string) error {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return err
	}

	addr, err := netlink.ParseAddr(ip)
	if err != nil {
		return err
	}

	return netlink.AddrDel(link, addr)
}

func DelVips(iface string) error {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return err
	}

	addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
	if err != nil {
		return err
	}

	for _, a := range addrs[1:] {
		if err := netlink.AddrDel(link, &a); err != nil {
			return err
		}
	}

	return nil
}

func GetVips(iface string) ([]netlink.Addr, error) {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return []netlink.Addr{}, err
	}

	return netlink.AddrList(link, netlink.FAMILY_V4)
}

func GetFusisVipsIps(iface string) ([]string, error) {
	addrs, err := GetVips(iface)
	if err != nil {
		return nil, err
	}
	addrs = addrs[1:]
	ips := make([]string, len(addrs))
	for i, addr := range addrs {
		ips[i] = addr.IP.String()
	}
	return ips, nil
}

func GetIpByInterface(iface string) (string, error) {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return "", err
	}

	addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
	if err != nil {
		return "", err
	}

	return addrs[0].IP.String(), nil
}

func SetIpForwarding() error {
	return ioutil.WriteFile("/proc/sys/net/ipv4/ip_forward", []byte("1"), 0644)
}

func AddDefaultGateway(ip string) error {
	err := netlink.RouteAdd(&netlink.Route{
		Scope: netlink.SCOPE_UNIVERSE,
		Gw:    net.ParseIP(ip),
	})
	if err != nil {
		log.Errorf("Adding Default Gateway: %s", ip)
		return err
	}
	return nil
}

func GetDefaultGateway() (*netlink.Route, error) {
	routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
	if err != nil {
		return nil, err
	}

	var route netlink.Route
	for _, v := range routes {
		if v.Gw != nil {
			route = v
		}
	}

	if route.Gw == nil {
		return nil, fmt.Errorf("default gateway not found")
	}

	return &route, nil
}

func DeleteDefaultGateway(route *netlink.Route) error {
	return netlink.RouteDel(route)
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2017 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package main

import (
	"fmt"
	"net"

	hyper "github.com/clearcontainers/agent/api"
	"github.com/vishvananda/netlink"
)

func findLinkFromHwAddr(netHandle *netlink.Handle, hwAddr string) (netlink.Link, error) {
	links, err := netHandle.LinkList()
	if err != nil {
		return nil, err
	}

	for _, link := range links {
		lAttrs := link.Attrs()
		if lAttrs == nil {
			continue
		}

		if lAttrs.HardwareAddr.String() == hwAddr {
			return link, nil
		}
	}

	return nil, fmt.Errorf("Could not find the link corresponding to HwAddr %q", hwAddr)
}

func setupInterface(netHandle *netlink.Handle, iface hyper.NetIface, link netlink.Link) error {
	lAttrs := link.Attrs()
	if lAttrs != nil && (lAttrs.Flags&net.FlagUp) == net.FlagUp {
		// The link is up, makes sure we get it down before
		// doing any modification.
		if err := netHandle.LinkSetDown(link); err != nil {
			return err
		}
	}

	// Rename the link
	if iface.Name != "" {
		if err := netHandle.LinkSetName(link, iface.Name); err != nil {
			return err
		}
	}

	// Set MTU
	if iface.MTU > 0 {
		if err := netHandle.LinkSetMTU(link, iface.MTU); err != nil {
			return err
		}
	}

	for _, ipAddress := range iface.IPAddresses {
		// Add an IP address
		addr, err := netlink.ParseAddr(fmt.Sprintf("%s/%s", ipAddress.IPAddr, ipAddress.NetMask))
		if err != nil {
			return fmt.Errorf("Could not parse the IP address %s: %v", ipAddress.IPAddr, err)
		}
		if err := netHandle.AddrAdd(link, addr); err != nil {
			return err
		}
	}

	// Set the link up
	return netHandle.LinkSetUp(link)
}

func setupInterfaces(netHandle *netlink.Handle, ifaces []hyper.NetIface) error {
	for _, iface := range ifaces {
		var link netlink.Link
		if iface.HwAddr != "" {
			agentLog.Infof("Get the interface from its MAC address %q", iface.HwAddr)

			// Find the interface link from its hardware address
			var err error
			link, err = findLinkFromHwAddr(netHandle, iface.HwAddr)
			if err != nil {
				return err
			}
		} else if iface.Name != "" {
			agentLog.Infof("Get the interface from its name %s", iface.Name)

			// Find the interface link from its name
			var err error
			link, err = netHandle.LinkByName(iface.Name)
			if err != nil {
				return err
			}
		} else {
			return fmt.Errorf("Interface HwAddr and Name are both empty")
		}

		agentLog.Infof("Link found %+v", link)

		if err := setupInterface(netHandle, iface, link); err != nil {
			return err
		}
	}

	return nil
}

func setupRoutes(netHandle *netlink.Handle, routes []hyper.Route) error {
	for _, route := range routes {
		var dst *net.IPNet
		var err error

		if route.Dest != "" && route.Dest != "default" {
			_, dst, err = net.ParseCIDR(route.Dest)
			if err != nil {
				return fmt.Errorf("Could not parse route destination %s: %v", route.Dest, err)
			}
		}

		// Find link index from route's device name
		link, err := netHandle.LinkByName(route.Device)
		if err != nil {
			return fmt.Errorf("Could not find link from device name %s: %v", route.Device, err)
		}

		linkAttrs := link.Attrs()
		if linkAttrs == nil {
			return fmt.Errorf("Could not find link index for device %v", route.Device)
		}

		netRoute := &netlink.Route{
			LinkIndex: linkAttrs.Index,
			Dst:       dst,
			Src:       net.ParseIP(route.Src),
			Gw:        net.ParseIP(route.Gateway),
		}

		if err := netHandle.RouteReplace(netRoute); err != nil {
			return fmt.Errorf("Could not add/replace route dest(%s)/src(%s)/gw(%s)/dev(%s): %v", route.Dest, route.Src, route.Gateway, route.Device, err)
		}
	}

	return nil
}

func setupDNS(netHandle *netlink.Handle, dns []string) error {
	return nil
}

func (p *pod) setupNetwork() error {
	netHandle, err := netlink.NewHandle()
	if err != nil {
		return err
	}
	defer netHandle.Delete()

	if err := setupInterfaces(netHandle, p.network.Interfaces); err != nil {
		return fmt.Errorf("Could not setup network interfaces: %v", err)
	}

	if err := setupRoutes(netHandle, p.network.Routes); err != nil {
		return fmt.Errorf("Could not setup network routes: %v", err)
	}

	if err := setupDNS(netHandle, p.network.DNS); err != nil {
		return fmt.Errorf("Could not setup network DNS: %v", err)
	}

	return nil
}

func removeInterfaces(netHandle *netlink.Handle, ifaces []hyper.NetIface) error {
	for _, iface := range ifaces {
		// Find the interface by name
		link, err := netHandle.LinkByName(iface.Name)
		if err != nil {
			return err
		}

		// Set the link down
		if err := netHandle.LinkSetDown(link); err != nil {
			return err
		}

		for _, ipAddress := range iface.IPAddresses {
			// Remove the IP address
			addr, err := netlink.ParseAddr(fmt.Sprintf("%s/%s", ipAddress.IPAddr, ipAddress.NetMask))
			if err != nil {
				return fmt.Errorf("Could not parse the IP address %s: %v", ipAddress.IPAddr, err)
			}
			if err := netHandle.AddrDel(link, addr); err != nil {
				return err
			}
		}
	}

	return nil
}

func removeRoutes(netHandle *netlink.Handle, routes []hyper.Route) error {
	for _, route := range routes {
		_, dst, err := net.ParseCIDR(route.Dest)
		if err != nil {
			return fmt.Errorf("Could not parse route destination %s: %v", route.Dest, err)
		}

		netRoute := &netlink.Route{
			Dst: dst,
			Src: net.ParseIP(route.Src),
			Gw:  net.ParseIP(route.Gateway),
		}

		if err := netHandle.RouteDel(netRoute); err != nil {
			return fmt.Errorf("Could not remove route dest(%s)/src(%s)/gw(%s)/dev(%s): %v", route.Dest, route.Src, route.Gateway, route.Device, err)
		}
	}

	return nil
}

func removeDNS(netHandle *netlink.Handle, dns []string) error {
	return nil
}

func (p *pod) removeNetwork() error {
	netHandle, err := netlink.NewHandle()
	if err != nil {
		return err
	}
	defer netHandle.Delete()

	if err := removeInterfaces(netHandle, p.network.Interfaces); err != nil {
		return fmt.Errorf("Could not remove network interfaces: %v", err)
	}

	if err := removeRoutes(netHandle, p.network.Routes); err != nil {
		return fmt.Errorf("Could not remove network routes: %v", err)
	}

	if err := removeDNS(netHandle, p.network.DNS); err != nil {
		return fmt.Errorf("Could not remove network DNS: %v", err)
	}

	return nil
}
<commit_msg>network: Support more IP and netmast formats<commit_after>//
// Copyright (c) 2017 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package main

import (
	"fmt"
	"net"

	hyper "github.com/clearcontainers/agent/api"
	"github.com/vishvananda/netlink"
)

func findLinkFromHwAddr(netHandle *netlink.Handle, hwAddr string) (netlink.Link, error) {
	links, err := netHandle.LinkList()
	if err != nil {
		return nil, err
	}

	for _, link := range links {
		lAttrs := link.Attrs()
		if lAttrs == nil {
			continue
		}

		if lAttrs.HardwareAddr.String() == hwAddr {
			return link, nil
		}
	}

	return nil, fmt.Errorf("Could not find the link corresponding to HwAddr %q", hwAddr)
}

func getStrNetMaskFromIPv4(ip net.IP) (string, error) {
	ipMask := ip.DefaultMask()
	if ipMask == nil {
		return "", fmt.Errorf("Could not deduce IP network mask from %v", ip)
	}

	ipMaskInt, _ := ipMask.Size()

	return fmt.Sprintf("%d", ipMaskInt), nil
}

func setupInterface(netHandle *netlink.Handle, iface hyper.NetIface, link netlink.Link) error {
	lAttrs := link.Attrs()
	if lAttrs != nil && (lAttrs.Flags&net.FlagUp) == net.FlagUp {
		// The link is up, makes sure we get it down before
		// doing any modification.
		if err := netHandle.LinkSetDown(link); err != nil {
			return err
		}
	}

	// Rename the link
	if iface.Name != "" {
		if err := netHandle.LinkSetName(link, iface.Name); err != nil {
			return err
		}
	}

	// Set MTU
	if iface.MTU > 0 {
		if err := netHandle.LinkSetMTU(link, iface.MTU); err != nil {
			return err
		}
	}

	for _, ipAddress := range iface.IPAddresses {
		netMask := ipAddress.NetMask

		// Determine the network mask if not provided in the expected format
		netMaskIP := net.ParseIP(netMask)
		if netMaskIP != nil {
			ip := net.ParseIP(ipAddress.IPAddr)
			if ip == nil {
				return fmt.Errorf("Invalid IP address %q", ipAddress.IPAddr)
			}

			tmpNetMask, err := getStrNetMaskFromIPv4(ip)
			if err != nil {
				return err
			}

			netMask = tmpNetMask
		}

		// Add an IP address
		addr, err := netlink.ParseAddr(fmt.Sprintf("%s/%s", ipAddress.IPAddr, netMask))
		if err != nil {
			return fmt.Errorf("Could not parse the IP address %s: %v", ipAddress.IPAddr, err)
		}
		if err := netHandle.AddrAdd(link, addr); err != nil {
			return err
		}
	}

	// Set the link up
	return netHandle.LinkSetUp(link)
}

func setupInterfaces(netHandle *netlink.Handle, ifaces []hyper.NetIface) error {
	for _, iface := range ifaces {
		var link netlink.Link
		if iface.HwAddr != "" {
			agentLog.Infof("Get the interface from its MAC address %q", iface.HwAddr)

			// Find the interface link from its hardware address
			var err error
			link, err = findLinkFromHwAddr(netHandle, iface.HwAddr)
			if err != nil {
				return err
			}
		} else if iface.Name != "" {
			agentLog.Infof("Get the interface from its name %s", iface.Name)

			// Find the interface link from its name
			var err error
			link, err = netHandle.LinkByName(iface.Name)
			if err != nil {
				return err
			}
		} else {
			return fmt.Errorf("Interface HwAddr and Name are both empty")
		}

		agentLog.Infof("Link found %+v", link)

		if err := setupInterface(netHandle, iface, link); err != nil {
			return err
		}
	}

	return nil
}

func setupRoutes(netHandle *netlink.Handle, routes []hyper.Route) error {
	for _, route := range routes {
		var dst *net.IPNet
		var err error

		if route.Dest != "" && route.Dest != "default" {
			destIP := net.ParseIP(route.Dest)
			if destIP != nil {
				// Add the missing network mask
				netMask, err := getStrNetMaskFromIPv4(destIP)
				if err != nil {
					return err
				}

				route.Dest += "/" + netMask
			}

			_, dst, err = net.ParseCIDR(route.Dest)
			if err != nil {
				return fmt.Errorf("Could not parse route destination %s: %v", route.Dest, err)
			}
		}

		// Find link index from route's device name
		link, err := netHandle.LinkByName(route.Device)
		if err != nil {
			return fmt.Errorf("Could not find link from device name %s: %v", route.Device, err)
		}

		linkAttrs := link.Attrs()
		if linkAttrs == nil {
			return fmt.Errorf("Could not find link index for device %v", route.Device)
		}

		netRoute := &netlink.Route{
			LinkIndex: linkAttrs.Index,
			Dst:       dst,
			Src:       net.ParseIP(route.Src),
			Gw:        net.ParseIP(route.Gateway),
		}

		if err := netHandle.RouteReplace(netRoute); err != nil {
			return fmt.Errorf("Could not add/replace route dest(%s)/src(%s)/gw(%s)/dev(%s): %v", route.Dest, route.Src, route.Gateway, route.Device, err)
		}
	}

	return nil
}

func setupDNS(netHandle *netlink.Handle, dns []string) error {
	return nil
}

func (p *pod) setupNetwork() error {
	netHandle, err := netlink.NewHandle()
	if err != nil {
		return err
	}
	defer netHandle.Delete()

	if err := setupInterfaces(netHandle, p.network.Interfaces); err != nil {
		return fmt.Errorf("Could not setup network interfaces: %v", err)
	}

	if err := setupRoutes(netHandle, p.network.Routes); err != nil {
		return fmt.Errorf("Could not setup network routes: %v", err)
	}

	if err := setupDNS(netHandle, p.network.DNS); err != nil {
		return fmt.Errorf("Could not setup network DNS: %v", err)
	}

	return nil
}

func removeInterfaces(netHandle *netlink.Handle, ifaces []hyper.NetIface) error {
	for _, iface := range ifaces {
		// Find the interface by name
		link, err := netHandle.LinkByName(iface.Name)
		if err != nil {
			return err
		}

		// Set the link down
		if err := netHandle.LinkSetDown(link); err != nil {
			return err
		}

		for _, ipAddress := range iface.IPAddresses {
			// Remove the IP address
			addr, err := netlink.ParseAddr(fmt.Sprintf("%s/%s", ipAddress.IPAddr, ipAddress.NetMask))
			if err != nil {
				return fmt.Errorf("Could not parse the IP address %s: %v", ipAddress.IPAddr, err)
			}
			if err := netHandle.AddrDel(link, addr); err != nil {
				return err
			}
		}
	}

	return nil
}

func removeRoutes(netHandle *netlink.Handle, routes []hyper.Route) error {
	for _, route := range routes {
		_, dst, err := net.ParseCIDR(route.Dest)
		if err != nil {
			return fmt.Errorf("Could not parse route destination %s: %v", route.Dest, err)
		}

		netRoute := &netlink.Route{
			Dst: dst,
			Src: net.ParseIP(route.Src),
			Gw:  net.ParseIP(route.Gateway),
		}

		if err := netHandle.RouteDel(netRoute); err != nil {
			return fmt.Errorf("Could not remove route dest(%s)/src(%s)/gw(%s)/dev(%s): %v", route.Dest, route.Src, route.Gateway, route.Device, err)
		}
	}

	return nil
}

func removeDNS(netHandle *netlink.Handle, dns []string) error {
	return nil
}

func (p *pod) removeNetwork() error {
	netHandle, err := netlink.NewHandle()
	if err != nil {
		return err
	}
	defer netHandle.Delete()

	if err := removeInterfaces(netHandle, p.network.Interfaces); err != nil {
		return fmt.Errorf("Could not remove network interfaces: %v", err)
	}

	if err := removeRoutes(netHandle, p.network.Routes); err != nil {
		return fmt.Errorf("Could not remove network routes: %v", err)
	}

	if err := removeDNS(netHandle, p.network.DNS); err != nil {
		return fmt.Errorf("Could not remove network DNS: %v", err)
	}

	return nil
}
<|endoftext|>


<commit_before>package goupnp

import (
	"io"
	"net"

	"github.com/huin/goupnp/httpu"
)

// httpuClient creates a HTTPU client that multiplexes to all multicast-capable
// IPv4 addresses on the host. Returns a function to clean up once the client is
// no longer required.
func httpuClient() (httpu.ClientInterface, func(), error) {
	addrs, err := localIPv4MCastAddrs()
	if err != nil {
		return nil, nil, ctxError(err, "requesting host IPv4 addresses")
	}

	closers := make([]io.Closer, 0, len(addrs))
	delegates := make([]httpu.ClientInterface, 0, len(addrs))
	for _, addr := range addrs {
		c, err := httpu.NewHTTPUClientAddr(addr)
		if err != nil {
			return nil, nil, ctxErrorf(err,
				"creating HTTPU client for address %s", addr)
		}
		closers = append(closers, c)
		delegates = append(delegates, c)
	}

	closer := func() {
		for _, c := range closers {
			c.Close()
		}
	}

	return httpu.NewMultiClient(delegates), closer, nil
}

// localIPv2MCastAddrs returns the set of IPv4 addresses on multicast-able
// network interfaces.
func localIPv4MCastAddrs() ([]string, error) {
	ifaces, err := net.Interfaces()
	if err != nil {
		return nil, ctxError(err, "requesting host interfaces")
	}

	// Find the set of addresses to listen on.
	var addrs []string
	for _, iface := range ifaces {
		if iface.Flags&net.FlagMulticast == 0 || iface.Flags&net.FlagLoopback != 0 {
			// Does not support multicast or is a loopback address.
			continue
		}
		ifaceAddrs, err := iface.Addrs()
		if err != nil {
			return nil, ctxErrorf(err,
				"finding addresses on interface %s", iface.Name)
		}
		for _, netAddr := range ifaceAddrs {
			addr, ok := netAddr.(*net.IPNet)
			if !ok {
				// Not an IPNet address.
				continue
			}
			if addr.IP.To4() == nil {
				// Not IPv4.
				continue
			}
			addrs = append(addrs, addr.IP.String())
		}
	}

	return addrs, nil
}
<commit_msg>localIPv4MCastAddrs if（net.FlagUp == 0 ）continue<commit_after>package goupnp

import (
	"io"
	"net"

	"github.com/huin/goupnp/httpu"
)

// httpuClient creates a HTTPU client that multiplexes to all multicast-capable
// IPv4 addresses on the host. Returns a function to clean up once the client is
// no longer required.
func httpuClient() (httpu.ClientInterface, func(), error) {
	addrs, err := localIPv4MCastAddrs()
	if err != nil {
		return nil, nil, ctxError(err, "requesting host IPv4 addresses")
	}

	closers := make([]io.Closer, 0, len(addrs))
	delegates := make([]httpu.ClientInterface, 0, len(addrs))
	for _, addr := range addrs {
		c, err := httpu.NewHTTPUClientAddr(addr)
		if err != nil {
			return nil, nil, ctxErrorf(err,
				"creating HTTPU client for address %s", addr)
		}
		closers = append(closers, c)
		delegates = append(delegates, c)
	}

	closer := func() {
		for _, c := range closers {
			c.Close()
		}
	}

	return httpu.NewMultiClient(delegates), closer, nil
}

// localIPv2MCastAddrs returns the set of IPv4 addresses on multicast-able
// network interfaces.
func localIPv4MCastAddrs() ([]string, error) {
	ifaces, err := net.Interfaces()
	if err != nil {
		return nil, ctxError(err, "requesting host interfaces")
	}

	// Find the set of addresses to listen on.
	var addrs []string
	for _, iface := range ifaces {
		if iface.Flags&net.FlagMulticast == 0 || iface.Flags&net.FlagLoopback != 0 || iface.Flags&net.FlagUp == 0 {
			// Does not support multicast or is a loopback address.
			continue
		}
		ifaceAddrs, err := iface.Addrs()
		if err != nil {
			return nil, ctxErrorf(err,
				"finding addresses on interface %s", iface.Name)
		}
		for _, netAddr := range ifaceAddrs {
			addr, ok := netAddr.(*net.IPNet)
			if !ok {
				// Not an IPNet address.
				continue
			}
			if addr.IP.To4() == nil {
				// Not IPv4.
				continue
			}
			addrs = append(addrs, addr.IP.String())
		}
	}

	return addrs, nil
}
<|endoftext|>


<commit_before>package docker

import (
	"fmt"
	"net"
)

const (
	networkBridgeIface = "lxcbr0"
)

type NetworkInterface struct {
	IpAddress   string
	IpPrefixLen int
	Gateway     net.IP
}

func allocateIPAddress() string {
	return "10.0.3.2"
}

func getBridgeAddr(name string) (net.Addr, error) {
	iface, err := net.InterfaceByName(name)
	if err != nil {
		return nil, err
	}
	addrs, err := iface.Addrs()
	if err != nil {
		return nil, err
	}
	var addrs4 []net.Addr
	for _, addr := range addrs {
		ip := (addr.(*net.IPNet)).IP
		if ip4 := ip.To4(); len(ip4) == net.IPv4len {
			addrs4 = append(addrs4, addr)
		}
	}
	switch {
	case len(addrs4) == 0:
		return nil, fmt.Errorf("Bridge %v has no IP addresses", name)
	case len(addrs4) > 1:
		return nil, fmt.Errorf("Bridge %v has more than 1 IPv4 address", name)
	}
	return addrs4[0], nil
}

func allocateNetwork() (*NetworkInterface, error) {
	bridgeAddr, err := getBridgeAddr(networkBridgeIface)
	if err != nil {
		return nil, err
	}
	bridge := bridgeAddr.(*net.IPNet)
	ipPrefixLen, _ := bridge.Mask.Size()
	iface := &NetworkInterface{
		IpAddress:   allocateIPAddress(),
		IpPrefixLen: ipPrefixLen,
		Gateway:     bridge.IP,
	}
	return iface, nil
}
<commit_msg>Network: Simple random IP allocation on the bridge network.<commit_after>package docker

import (
	"fmt"
	"math/rand"
	"net"
)

const (
	networkBridgeIface = "lxcbr0"
)

type NetworkInterface struct {
	IpAddress   string
	IpPrefixLen int
	Gateway     net.IP
}

func allocateIPAddress(network *net.IPNet) net.IP {
	ip := network.IP.Mask(network.Mask)
	ip[3] = byte(rand.Intn(254))
	return ip
}

func getBridgeAddr(name string) (net.Addr, error) {
	iface, err := net.InterfaceByName(name)
	if err != nil {
		return nil, err
	}
	addrs, err := iface.Addrs()
	if err != nil {
		return nil, err
	}
	var addrs4 []net.Addr
	for _, addr := range addrs {
		ip := (addr.(*net.IPNet)).IP
		if ip4 := ip.To4(); len(ip4) == net.IPv4len {
			addrs4 = append(addrs4, addr)
		}
	}
	switch {
	case len(addrs4) == 0:
		return nil, fmt.Errorf("Bridge %v has no IP addresses", name)
	case len(addrs4) > 1:
		return nil, fmt.Errorf("Bridge %v has more than 1 IPv4 address", name)
	}
	return addrs4[0], nil
}

func allocateNetwork() (*NetworkInterface, error) {
	bridgeAddr, err := getBridgeAddr(networkBridgeIface)
	if err != nil {
		return nil, err
	}
	bridge := bridgeAddr.(*net.IPNet)
	ipPrefixLen, _ := bridge.Mask.Size()
	iface := &NetworkInterface{
		IpAddress:   allocateIPAddress(bridge).String(),
		IpPrefixLen: ipPrefixLen,
		Gateway:     bridge.IP,
	}
	return iface, nil
}
<|endoftext|>


<commit_before>package main

import (
	"container/list";
	"net";
	"log";
	"irc";
)

type Network struct {
	name	string;
	server	*irc.Conn;
	listen	net.Listener;
	clients	*list.List;
}

func NewNetwork(name string, server net.Conn, listen net.Listener) *Network {
	if listen == nil {
		return nil
	}
	network := &Network{name, irc.NewConn(server, nil), listen, list.New()};
	go network.run();
	return network;
}

func (network *Network) acceptor(accepted chan net.Conn) {
	for {
		conn, err := network.listen.Accept();
		if err != nil {
			log.Stderrf("accept failed\n");
			// TODO handle error
			return
		}
		accepted <- conn;
	}
}

func (network *Network) run() {
	accepted := make(chan net.Conn, 0);
	go network.acceptor(accepted);
	log.Stderrf("network %s listening on %s\n", network.name, network.listen.Addr());
	for {
		select {
		case client := <-accepted:
			network.addClient(client)
		}
	}
}

func (network *Network) addClient(conn net.Conn) {
	client := irc.NewConn(conn, nil);
	network.clients.PushBack(client);
	log.Stderrf("client connected from %s\n", conn.RemoteAddr());
}
<commit_msg>Improve Network accept error message<commit_after>package main

import (
	"container/list";
	"net";
	"log";
	"irc";
)

type Network struct {
	name	string;
	server	*irc.Conn;
	listen	net.Listener;
	clients	*list.List;
}

func NewNetwork(name string, server net.Conn, listen net.Listener) *Network {
	if listen == nil {
		return nil
	}
	network := &Network{name, irc.NewConn(server, nil), listen, list.New()};
	go network.run();
	return network;
}

func (network *Network) acceptor(accepted chan net.Conn) {
	for {
		conn, err := network.listen.Accept();
		if err != nil {
			log.Stderrf("accept failed: %s\n", err);
			// TODO handle error
			return
		}
		accepted <- conn;
	}
}

func (network *Network) run() {
	accepted := make(chan net.Conn, 0);
	go network.acceptor(accepted);
	log.Stderrf("network %s listening on %s\n", network.name, network.listen.Addr());
	for {
		select {
		case client := <-accepted:
			network.addClient(client)
		}
	}
}

func (network *Network) addClient(conn net.Conn) {
	client := irc.NewConn(conn, nil);
	network.clients.PushBack(client);
	log.Stderrf("client connected from %s\n", conn.RemoteAddr());
}
<|endoftext|>


<commit_before>package echo

import (
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestResponse(t *testing.T) {
	w := httptest.NewRecorder()
	r := NewResponse(w)

	// SetWriter
	r.SetWriter(w)

	// Writer
	assert.Equal(t, w, r.Writer())

	// Header
	assert.NotNil(t, r.Header())

	// WriteHeader
	r.WriteHeader(http.StatusOK)
	assert.Equal(t, http.StatusOK, r.status)

	// Committed
	assert.True(t, r.committed)

	// Already committed
	r.WriteHeader(http.StatusTeapot)
	assert.NotEqual(t, http.StatusTeapot, r.Status())

	// Status
	r.status = http.StatusOK
	assert.Equal(t, http.StatusOK, r.Status())

	// Write
	s := "echo"
	_, err := r.Write([]byte(s))
	assert.NoError(t, err)

	// Flush
	r.Flush()

	// Size
	assert.EqualValues(t, len(s), r.Size())

	// Hijack
	assert.Panics(t, func() {
		r.Hijack()
	})

	// CloseNotify
	assert.Panics(t, func() {
		r.CloseNotify()
	})

	// reset
	r.reset(httptest.NewRecorder())
}
<commit_msg>adding code coverage<commit_after>package echo

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestResponse(t *testing.T) {
	w := httptest.NewRecorder()
	r := NewResponse(w)

	// SetWriter
	r.SetWriter(w)

	// Writer
	assert.Equal(t, w, r.Writer())

	// Header
	assert.NotNil(t, r.Header())

	// WriteHeader
	r.WriteHeader(http.StatusOK)
	assert.Equal(t, http.StatusOK, r.status)

	// Committed
	assert.True(t, r.committed)

	// Already committed
	r.WriteHeader(http.StatusTeapot)
	assert.NotEqual(t, http.StatusTeapot, r.Status())

	// Status
	r.status = http.StatusOK
	assert.Equal(t, http.StatusOK, r.Status())

	// Write
	s := "echo"
	_, err := r.Write([]byte(s))
	assert.NoError(t, err)

	// Flush
	r.Flush()

	// Size
	assert.EqualValues(t, len(s), r.Size())

	// Committed
	assert.Equal(t, true, r.Committed())

	// Hijack
	assert.Panics(t, func() {
		r.Hijack()
	})

	// CloseNotify
	assert.Panics(t, func() {
		r.CloseNotify()
	})

	// reset
	r.reset(httptest.NewRecorder())
}
<|endoftext|>