<commit_before>package ethrpc

import (
	"bytes"
	"encoding/json"
	"math/big"
	"unsafe"
)

type Syncing struct {
	IsSyncing     bool
	StartingBlock int
	CurrentBlock  int
	HighestBlock  int
}

func (s *Syncing) UnmarshalJSON(data []byte) error {
	proxy := new(proxySyncing)
	if err := json.Unmarshal(data, proxy); err != nil {
		return err
	}

	proxy.IsSyncing = true
	*s = *(*Syncing)(unsafe.Pointer(proxy))

	return nil
}

// T - input transaction object
type T struct {
	From     string
	To       string
	Gas      int
	GasPrice *big.Int
	Value    *big.Int
	Data     string
	Nonce    int
}

func (t T) MarshalJSON() ([]byte, error) {
	params := map[string]interface{}{
		"from": t.From,
	}
	if t.To != "" {
		params["to"] = t.To
	}
	if t.Gas > 0 {
		params["gas"] = IntToHex(t.Gas)
	}
	if t.GasPrice != nil {
		params["gasPrice"] = BigToHex(*t.GasPrice)
	}
	if t.Value != nil {
		params["value"] = BigToHex(*t.Value)
	}
	if t.Data != "" {
		params["data"] = t.Data
	}
	if t.Nonce > 0 {
		params["nonce"] = IntToHex(t.Nonce)
	}

	return json.Marshal(params)
}

// Transaction - transaction object
type Transaction struct {
	Hash             string
	Nonce            int
	BlockHash        string
	BlockNumber      *int
	TransactionIndex *int
	From             string
	To               string
	Value            big.Int
	Gas              int
	GasPrice         big.Int
	Input            string
}

func (t *Transaction) UnmarshalJSON(data []byte) error {
	proxy := new(proxyTransaction)
	if err := json.Unmarshal(data, proxy); err != nil {
		return err
	}

	*t = *(*Transaction)(unsafe.Pointer(proxy))

	return nil
}

// Log - log object
type Log struct {
	Removed          bool
	LogIndex         int
	TransactionIndex int
	TransactionHash  string
	BlockNumber      int
	BlockHash        string
	Address          string
	Data             string
	Topics           []string
}

func (log *Log) UnmarshalJSON(data []byte) error {
	proxy := new(proxyLog)
	if err := json.Unmarshal(data, proxy); err != nil {
		return err
	}

	*log = *(*Log)(unsafe.Pointer(proxy))

	return nil
}

// TransactionReceipt - transaction receipt object
type TransactionReceipt struct {
	TransactionHash   string
	TransactionIndex  int
	BlockHash         string
	BlockNumber       int
	CumulativeGasUsed int
	GasUsed           int
	ContractAddress   string
	Logs              []Log
	LogsBloom         string
	Root              string
}

func (t *TransactionReceipt) UnmarshalJSON(data []byte) error {
	proxy := new(proxyTransactionReceipt)
	if err := json.Unmarshal(data, proxy); err != nil {
		return err
	}

	*t = *(*TransactionReceipt)(unsafe.Pointer(proxy))

	return nil
}

// Block - block object
type Block struct {
	Number           int
	Hash             string
	ParentHash       string
	Nonce            string
	Sha3Uncles       string
	LogsBloom        string
	TransactionsRoot string
	StateRoot        string
	Miner            string
	Difficulty       big.Int
	TotalDifficulty  big.Int
	ExtraData        string
	Size             int
	GasLimit         int
	GasUsed          int
	Timestamp        int
	Uncles           []string
	Transactions     []Transaction
}

type proxySyncing struct {
	IsSyncing     bool   `json:"-"`
	StartingBlock hexInt `json:"startingBlock"`
	CurrentBlock  hexInt `json:"currentBlock"`
	HighestBlock  hexInt `json:"highestBlock"`
}

type proxyTransaction struct {
	Hash             string  `json:"hash"`
	Nonce            hexInt  `json:"nonce"`
	BlockHash        string  `json:"blockHash"`
	BlockNumber      *hexInt `json:"blockNumber"`
	TransactionIndex *hexInt `json:"transactionIndex"`
	From             string  `json:"from"`
	To               string  `json:"to"`
	Value            hexBig  `json:"value"`
	Gas              hexInt  `json:"gas"`
	GasPrice         hexBig  `json:"gasPrice"`
	Input            string  `json:"input"`
}

type proxyLog struct {
	Removed          bool     `json:"removed"`
	LogIndex         hexInt   `json:"logIndex"`
	TransactionIndex hexInt   `json:"transactionIndex"`
	TransactionHash  string   `json:"transactionHash"`
	BlockNumber      hexInt   `json:"blockNumber"`
	BlockHash        string   `json:"blockHash"`
	Address          string   `json:"address"`
	Data             string   `json:"data"`
	Topics           []string `json:"topics"`
}

type proxyTransactionReceipt struct {
	TransactionHash   string `json:"transactionHash"`
	TransactionIndex  hexInt `json:"transactionIndex"`
	BlockHash         string `json:"blockHash"`
	BlockNumber       hexInt `json:"blockNumber"`
	CumulativeGasUsed hexInt `json:"cumulativeGasUsed"`
	GasUsed           hexInt `json:"gasUsed"`
	ContractAddress   string `json:"contractAddress,omitempty"`
	Logs              []Log  `json:"logs"`
	LogsBloom         string `json:"logsBloom"`
	Root              string `json:"root"`
}

type hexInt int

func (i *hexInt) UnmarshalJSON(data []byte) error {
	result, err := ParseInt(string(bytes.Trim(data, `"`)))
	*i = hexInt(result)

	return err
}

type hexBig big.Int

func (i *hexBig) UnmarshalJSON(data []byte) error {
	result, err := ParseBigInt(string(bytes.Trim(data, `"`)))
	*i = hexBig(result)

	return err
}

type proxyBlockWithTransactions struct {
	Number           hexInt             `json:"number"`
	Hash             string             `json:"hash"`
	ParentHash       string             `json:"parentHash"`
	Nonce            string             `json:"nonce"`
	Sha3Uncles       string             `json:"sha3Uncles"`
	LogsBloom        string             `json:"logsBloom"`
	TransactionsRoot string             `json:"transactionsRoot"`
	StateRoot        string             `json:"stateRoot"`
	Miner            string             `json:"miner"`
	Difficulty       hexBig             `json:"difficulty"`
	TotalDifficulty  hexBig             `json:"totalDifficulty"`
	ExtraData        string             `json:"extraData"`
	Size             hexInt             `json:"size"`
	GasLimit         hexInt             `json:"gasLimit"`
	GasUsed          hexInt             `json:"gasUsed"`
	Timestamp        hexInt             `json:"timestamp"`
	Uncles           []string           `json:"uncles"`
	Transactions     []proxyTransaction `json:"transactions"`
}

func (proxy *proxyBlockWithTransactions) toBlock() Block {
	return *(*Block)(unsafe.Pointer(proxy))
}

type proxyBlock interface {
	toBlock() Block
}

type proxyBlockWithoutTransactions struct {
	Number           hexInt   `json:"number"`
	Hash             string   `json:"hash"`
	ParentHash       string   `json:"parentHash"`
	Nonce            string   `json:"nonce"`
	Sha3Uncles       string   `json:"sha3Uncles"`
	LogsBloom        string   `json:"logsBloom"`
	TransactionsRoot string   `json:"transactionsRoot"`
	StateRoot        string   `json:"stateRoot"`
	Miner            string   `json:"miner"`
	Difficulty       hexBig   `json:"difficulty"`
	TotalDifficulty  hexBig   `json:"totalDifficulty"`
	ExtraData        string   `json:"extraData"`
	Size             hexInt   `json:"size"`
	GasLimit         hexInt   `json:"gasLimit"`
	GasUsed          hexInt   `json:"gasUsed"`
	Timestamp        hexInt   `json:"timestamp"`
	Uncles           []string `json:"uncles"`
	Transactions     []string `json:"transactions"`
}

func (proxy *proxyBlockWithoutTransactions) toBlock() Block {
	block := Block{
		Number:           int(proxy.Number),
		Hash:             proxy.Hash,
		ParentHash:       proxy.ParentHash,
		Nonce:            proxy.Nonce,
		Sha3Uncles:       proxy.Sha3Uncles,
		LogsBloom:        proxy.LogsBloom,
		TransactionsRoot: proxy.TransactionsRoot,
		StateRoot:        proxy.StateRoot,
		Miner:            proxy.Miner,
		Difficulty:       big.Int(proxy.Difficulty),
		TotalDifficulty:  big.Int(proxy.TotalDifficulty),
		ExtraData:        proxy.ExtraData,
		Size:             int(proxy.Size),
		GasLimit:         int(proxy.GasLimit),
		GasUsed:          int(proxy.GasUsed),
		Timestamp:        int(proxy.Timestamp),
		Uncles:           proxy.Uncles,
	}

	block.Transactions = make([]Transaction, len(proxy.Transactions))
	for i := range proxy.Transactions {
		block.Transactions[i] = Transaction{
			Hash: proxy.Transactions[i],
		}
	}

	return block
}
<commit_msg>Added missed comments.<commit_after>package ethrpc

import (
	"bytes"
	"encoding/json"
	"math/big"
	"unsafe"
)

// Syncing - object with syncing data info
type Syncing struct {
	IsSyncing     bool
	StartingBlock int
	CurrentBlock  int
	HighestBlock  int
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (s *Syncing) UnmarshalJSON(data []byte) error {
	proxy := new(proxySyncing)
	if err := json.Unmarshal(data, proxy); err != nil {
		return err
	}

	proxy.IsSyncing = true
	*s = *(*Syncing)(unsafe.Pointer(proxy))

	return nil
}

// T - input transaction object
type T struct {
	From     string
	To       string
	Gas      int
	GasPrice *big.Int
	Value    *big.Int
	Data     string
	Nonce    int
}

// MarshalJSON implements the json.Unmarshaler interface.
func (t T) MarshalJSON() ([]byte, error) {
	params := map[string]interface{}{
		"from": t.From,
	}
	if t.To != "" {
		params["to"] = t.To
	}
	if t.Gas > 0 {
		params["gas"] = IntToHex(t.Gas)
	}
	if t.GasPrice != nil {
		params["gasPrice"] = BigToHex(*t.GasPrice)
	}
	if t.Value != nil {
		params["value"] = BigToHex(*t.Value)
	}
	if t.Data != "" {
		params["data"] = t.Data
	}
	if t.Nonce > 0 {
		params["nonce"] = IntToHex(t.Nonce)
	}

	return json.Marshal(params)
}

// Transaction - transaction object
type Transaction struct {
	Hash             string
	Nonce            int
	BlockHash        string
	BlockNumber      *int
	TransactionIndex *int
	From             string
	To               string
	Value            big.Int
	Gas              int
	GasPrice         big.Int
	Input            string
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (t *Transaction) UnmarshalJSON(data []byte) error {
	proxy := new(proxyTransaction)
	if err := json.Unmarshal(data, proxy); err != nil {
		return err
	}

	*t = *(*Transaction)(unsafe.Pointer(proxy))

	return nil
}

// Log - log object
type Log struct {
	Removed          bool
	LogIndex         int
	TransactionIndex int
	TransactionHash  string
	BlockNumber      int
	BlockHash        string
	Address          string
	Data             string
	Topics           []string
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (log *Log) UnmarshalJSON(data []byte) error {
	proxy := new(proxyLog)
	if err := json.Unmarshal(data, proxy); err != nil {
		return err
	}

	*log = *(*Log)(unsafe.Pointer(proxy))

	return nil
}

// TransactionReceipt - transaction receipt object
type TransactionReceipt struct {
	TransactionHash   string
	TransactionIndex  int
	BlockHash         string
	BlockNumber       int
	CumulativeGasUsed int
	GasUsed           int
	ContractAddress   string
	Logs              []Log
	LogsBloom         string
	Root              string
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (t *TransactionReceipt) UnmarshalJSON(data []byte) error {
	proxy := new(proxyTransactionReceipt)
	if err := json.Unmarshal(data, proxy); err != nil {
		return err
	}

	*t = *(*TransactionReceipt)(unsafe.Pointer(proxy))

	return nil
}

// Block - block object
type Block struct {
	Number           int
	Hash             string
	ParentHash       string
	Nonce            string
	Sha3Uncles       string
	LogsBloom        string
	TransactionsRoot string
	StateRoot        string
	Miner            string
	Difficulty       big.Int
	TotalDifficulty  big.Int
	ExtraData        string
	Size             int
	GasLimit         int
	GasUsed          int
	Timestamp        int
	Uncles           []string
	Transactions     []Transaction
}

type proxySyncing struct {
	IsSyncing     bool   `json:"-"`
	StartingBlock hexInt `json:"startingBlock"`
	CurrentBlock  hexInt `json:"currentBlock"`
	HighestBlock  hexInt `json:"highestBlock"`
}

type proxyTransaction struct {
	Hash             string  `json:"hash"`
	Nonce            hexInt  `json:"nonce"`
	BlockHash        string  `json:"blockHash"`
	BlockNumber      *hexInt `json:"blockNumber"`
	TransactionIndex *hexInt `json:"transactionIndex"`
	From             string  `json:"from"`
	To               string  `json:"to"`
	Value            hexBig  `json:"value"`
	Gas              hexInt  `json:"gas"`
	GasPrice         hexBig  `json:"gasPrice"`
	Input            string  `json:"input"`
}

type proxyLog struct {
	Removed          bool     `json:"removed"`
	LogIndex         hexInt   `json:"logIndex"`
	TransactionIndex hexInt   `json:"transactionIndex"`
	TransactionHash  string   `json:"transactionHash"`
	BlockNumber      hexInt   `json:"blockNumber"`
	BlockHash        string   `json:"blockHash"`
	Address          string   `json:"address"`
	Data             string   `json:"data"`
	Topics           []string `json:"topics"`
}

type proxyTransactionReceipt struct {
	TransactionHash   string `json:"transactionHash"`
	TransactionIndex  hexInt `json:"transactionIndex"`
	BlockHash         string `json:"blockHash"`
	BlockNumber       hexInt `json:"blockNumber"`
	CumulativeGasUsed hexInt `json:"cumulativeGasUsed"`
	GasUsed           hexInt `json:"gasUsed"`
	ContractAddress   string `json:"contractAddress,omitempty"`
	Logs              []Log  `json:"logs"`
	LogsBloom         string `json:"logsBloom"`
	Root              string `json:"root"`
}

type hexInt int

func (i *hexInt) UnmarshalJSON(data []byte) error {
	result, err := ParseInt(string(bytes.Trim(data, `"`)))
	*i = hexInt(result)

	return err
}

type hexBig big.Int

func (i *hexBig) UnmarshalJSON(data []byte) error {
	result, err := ParseBigInt(string(bytes.Trim(data, `"`)))
	*i = hexBig(result)

	return err
}

type proxyBlockWithTransactions struct {
	Number           hexInt             `json:"number"`
	Hash             string             `json:"hash"`
	ParentHash       string             `json:"parentHash"`
	Nonce            string             `json:"nonce"`
	Sha3Uncles       string             `json:"sha3Uncles"`
	LogsBloom        string             `json:"logsBloom"`
	TransactionsRoot string             `json:"transactionsRoot"`
	StateRoot        string             `json:"stateRoot"`
	Miner            string             `json:"miner"`
	Difficulty       hexBig             `json:"difficulty"`
	TotalDifficulty  hexBig             `json:"totalDifficulty"`
	ExtraData        string             `json:"extraData"`
	Size             hexInt             `json:"size"`
	GasLimit         hexInt             `json:"gasLimit"`
	GasUsed          hexInt             `json:"gasUsed"`
	Timestamp        hexInt             `json:"timestamp"`
	Uncles           []string           `json:"uncles"`
	Transactions     []proxyTransaction `json:"transactions"`
}

func (proxy *proxyBlockWithTransactions) toBlock() Block {
	return *(*Block)(unsafe.Pointer(proxy))
}

type proxyBlock interface {
	toBlock() Block
}

type proxyBlockWithoutTransactions struct {
	Number           hexInt   `json:"number"`
	Hash             string   `json:"hash"`
	ParentHash       string   `json:"parentHash"`
	Nonce            string   `json:"nonce"`
	Sha3Uncles       string   `json:"sha3Uncles"`
	LogsBloom        string   `json:"logsBloom"`
	TransactionsRoot string   `json:"transactionsRoot"`
	StateRoot        string   `json:"stateRoot"`
	Miner            string   `json:"miner"`
	Difficulty       hexBig   `json:"difficulty"`
	TotalDifficulty  hexBig   `json:"totalDifficulty"`
	ExtraData        string   `json:"extraData"`
	Size             hexInt   `json:"size"`
	GasLimit         hexInt   `json:"gasLimit"`
	GasUsed          hexInt   `json:"gasUsed"`
	Timestamp        hexInt   `json:"timestamp"`
	Uncles           []string `json:"uncles"`
	Transactions     []string `json:"transactions"`
}

func (proxy *proxyBlockWithoutTransactions) toBlock() Block {
	block := Block{
		Number:           int(proxy.Number),
		Hash:             proxy.Hash,
		ParentHash:       proxy.ParentHash,
		Nonce:            proxy.Nonce,
		Sha3Uncles:       proxy.Sha3Uncles,
		LogsBloom:        proxy.LogsBloom,
		TransactionsRoot: proxy.TransactionsRoot,
		StateRoot:        proxy.StateRoot,
		Miner:            proxy.Miner,
		Difficulty:       big.Int(proxy.Difficulty),
		TotalDifficulty:  big.Int(proxy.TotalDifficulty),
		ExtraData:        proxy.ExtraData,
		Size:             int(proxy.Size),
		GasLimit:         int(proxy.GasLimit),
		GasUsed:          int(proxy.GasUsed),
		Timestamp:        int(proxy.Timestamp),
		Uncles:           proxy.Uncles,
	}

	block.Transactions = make([]Transaction, len(proxy.Transactions))
	for i := range proxy.Transactions {
		block.Transactions[i] = Transaction{
			Hash: proxy.Transactions[i],
		}
	}

	return block
}
<|endoftext|>


<commit_before>package mmm

import (
	"fmt"
	"reflect"
)

// -----------------------------------------------------------------------------

// Type represents the underlying type of an interface.
type Type int

const (
	// TypeInvalid is an illegal type.
	TypeInvalid Type = iota
	// TypeNumeric is any of bool/int/uint/float/complex and their variants.
	TypeNumeric Type = iota
	// TypeArray is an array of any underlying type.
	TypeArray Type = iota
	// TypeStruct is any struct.
	TypeStruct Type = iota
)

// TypeOf returns the underlying type of an interface.
func TypeOf(v interface{}) (Type, error) {
	t := reflect.TypeOf(v)
	if t == nil {
		return TypeInvalid, Error(fmt.Sprintf("unsuppported type: %#v", v))
	}
	k := t.Kind()

	switch k {
	case reflect.Bool:
		return TypeNumeric, nil
	case reflect.Int:
		return TypeNumeric, nil
	case reflect.Int8:
		return TypeNumeric, nil
	case reflect.Int16:
		return TypeNumeric, nil
	case reflect.Int32:
		return TypeNumeric, nil
	case reflect.Int64:
		return TypeNumeric, nil
	case reflect.Uint:
		return TypeNumeric, nil
	case reflect.Uint8:
		return TypeNumeric, nil
	case reflect.Uint16:
		return TypeNumeric, nil
	case reflect.Uint32:
		return TypeNumeric, nil
	case reflect.Uint64:
		return TypeNumeric, nil
	case reflect.Uintptr:
		return TypeNumeric, nil
	case reflect.Float32:
		return TypeNumeric, nil
	case reflect.Float64:
		return TypeNumeric, nil
	case reflect.Complex64:
		return TypeNumeric, nil
	case reflect.Complex128:
		return TypeNumeric, nil
	case reflect.Array:
		return TypeArray, nil
	case reflect.Struct:
		return TypeStruct, nil
	default:
		return TypeInvalid, Error(fmt.Sprintf("unsuppported type: %#v", k.String()))
	}
}
<commit_msg>added TypeCheck()<commit_after>package mmm

import (
	"fmt"
	"reflect"
)

// -----------------------------------------------------------------------------

// Type represents the underlying type of an interface.
type Type int

const (
	// TypeInvalid is an illegal type.
	TypeInvalid Type = iota
	// TypeNumeric is any of bool/int/uint/float/complex and their variants.
	TypeNumeric Type = iota
	// TypeArray is an array of any underlying type.
	TypeArray Type = iota
	// TypeStruct is any struct.
	TypeStruct Type = iota
)

// TypeOf returns the underlying type of an interface.
func TypeOf(v interface{}) (Type, error) {
	t := reflect.TypeOf(v)
	if t == nil {
		return TypeInvalid, Error(fmt.Sprintf("unsuppported type: %#v", v))
	}
	k := t.Kind()

	switch k {
	case reflect.Bool:
		return TypeNumeric, nil
	case reflect.Int:
		return TypeNumeric, nil
	case reflect.Int8:
		return TypeNumeric, nil
	case reflect.Int16:
		return TypeNumeric, nil
	case reflect.Int32:
		return TypeNumeric, nil
	case reflect.Int64:
		return TypeNumeric, nil
	case reflect.Uint:
		return TypeNumeric, nil
	case reflect.Uint8:
		return TypeNumeric, nil
	case reflect.Uint16:
		return TypeNumeric, nil
	case reflect.Uint32:
		return TypeNumeric, nil
	case reflect.Uint64:
		return TypeNumeric, nil
	case reflect.Uintptr:
		return TypeNumeric, nil
	case reflect.Float32:
		return TypeNumeric, nil
	case reflect.Float64:
		return TypeNumeric, nil
	case reflect.Complex64:
		return TypeNumeric, nil
	case reflect.Complex128:
		return TypeNumeric, nil
	case reflect.Array:
		return TypeArray, nil
	case reflect.Struct:
		return TypeStruct, nil
	default:
		return TypeInvalid, Error(fmt.Sprintf("unsuppported type: %#v", k.String()))
	}
}

// TypeCheck recursively checks the underlying types of `v` and returns an error
// if one or more of those types are illegal.
func TypeCheck(v interface{}) error {
	t, err := TypeOf(v)
	if err != nil {
		return nil
	}

	rv := reflect.ValueOf(v)

	if t == TypeArray && rv.Len() > 0 {
		return TypeCheck(rv.Index(0).Interface())
	}

	if t == TypeStruct {
		fields := rv.NumField()
		for i := 0; i < fields; i++ {
			if err := TypeCheck(rv.Field(i).Interface()); err != nil {
				return err
			}
		}
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package azure

import (
	. "launchpad.net/gocheck"
	"launchpad.net/juju-core/environs/config"
	"launchpad.net/juju-core/testing"
	"sync"
)

type EnvironSuite struct {
	ProviderSuite
}

var _ = Suite(new(EnvironSuite))

func makeEnviron(c *C) *azureEnviron {
	attrs := makeAzureConfigMap(c)
	cfg, err := config.New(attrs)
	c.Assert(err, IsNil)
	ecfg, err := azureEnvironProvider{}.newConfig(cfg)
	c.Assert(err, IsNil)
	return &azureEnviron{
		name: "env",
		ecfg: ecfg,
	}
}

func (EnvironSuite) TestGetSnapshot(c *C) {
	original := azureEnviron{name: "this-env", ecfg: new(azureEnvironConfig)}
	snapshot := original.getSnapshot()

	// The snapshot is identical to the original.
	c.Check(*snapshot, DeepEquals, original)

	// However, they are distinct objects.
	c.Check(snapshot, Not(Equals), &original)

	// It's a shallow copy; they still share pointers.
	c.Check(snapshot.ecfg, Equals, original.ecfg)

	// Neither object is locked at the end of the copy.
	c.Check(original.Mutex, Equals, sync.Mutex{})
	c.Check(snapshot.Mutex, Equals, sync.Mutex{})
}

func (EnvironSuite) TestGetSnapshotLocksEnviron(c *C) {
	original := azureEnviron{}
	testing.TestLockingFunction(&original.Mutex, func() { original.getSnapshot() })
}

func (EnvironSuite) TestName(c *C) {
	env := azureEnviron{name: "foo"}
	c.Check(env.Name(), Equals, env.name)
}

func (EnvironSuite) TestConfigReturnsConfig(c *C) {
	cfg := new(config.Config)
	ecfg := azureEnvironConfig{Config: cfg}
	env := azureEnviron{ecfg: &ecfg}
	c.Check(env.Config(), Equals, cfg)
}

func (EnvironSuite) TestConfigLocksEnviron(c *C) {
	env := azureEnviron{name: "env", ecfg: new(azureEnvironConfig)}
	testing.TestLockingFunction(&env.Mutex, func() { env.Config() })
}

// TODO: Temporarily deactivating this code.  Passing certificate in-memory
// may require gwacl change.
/*
func (EnvironSuite) TestGetManagementAPI(c *C) {
	env := makeEnviron(c)
	management, err := env.getManagementAPI()
	c.Assert(err, IsNil)
	c.Check(management, NotNil)
}
*/

func (EnvironSuite) TestGetStorageContext(c *C) {
	env := makeEnviron(c)
	storage, err := env.getStorageContext()
	c.Assert(err, IsNil)
	c.Assert(storage, NotNil)
	c.Check(storage.Account, Equals, env.ecfg.StorageAccountName())
	c.Check(storage.Key, Equals, env.ecfg.StorageAccountKey())
}

func (EnvironSuite) TestSetConfigValidates(c *C) {
	env := makeEnviron(c)
	originalCfg := env.ecfg
	attrs := makeAzureConfigMap(c)
	// This config is not valid.  It lacks essential information.
	delete(attrs, "management-subscription-id")
	badCfg, err := config.New(attrs)
	c.Assert(err, IsNil)

	err = env.SetConfig(badCfg)

	// Since the config was not valid, SetConfig returns an error.  It
	// does not update the environment's config either.
	c.Check(err, NotNil)
	c.Check(env.ecfg, Equals, originalCfg)
}

func (EnvironSuite) TestSetConfigUpdatesConfig(c *C) {
	env := makeEnviron(c)
	// We're going to set a new config.  It can be recognized by its
	// unusual default Ubuntu release series: 7.04 Feisty Fawn.
	attrs := makeAzureConfigMap(c)
	attrs["default-series"] = "feisty"
	cfg, err := config.New(attrs)
	c.Assert(err, IsNil)

	err = env.SetConfig(cfg)
	c.Assert(err, IsNil)

	c.Check(env.ecfg.Config.DefaultSeries(), Equals, "feisty")
}

func (EnvironSuite) TestSetConfigLocksEnviron(c *C) {
	env := makeEnviron(c)
	cfg, err := config.New(makeAzureConfigMap(c))
	c.Assert(err, IsNil)

	testing.TestLockingFunction(&env.Mutex, func() { env.SetConfig(cfg) })
}

func (EnvironSuite) TestSetConfigInitialisesName(c *C) {
	env := azureEnviron{}
	attrs := makeAzureConfigMap(c)
	attrs["name"] = "my-shiny-new-env"
	cfg, err := config.New(attrs)
	c.Assert(err, IsNil)

	err = env.SetConfig(cfg)
	c.Assert(err, IsNil)

	c.Check(env.Name(), Equals, attrs["name"])
}

func (EnvironSuite) TestSetConfigWillNotUpdateName(c *C) {
	// Once the environment's name has been set, it cannot be updated.
	// Global validation rejects such a change.
	// This matters because the attribute is not protected by a lock.
	env := makeEnviron(c)
	originalName := env.Name()
	attrs := makeAzureConfigMap(c)
	attrs["name"] = "new-name"
	cfg, err := config.New(attrs)
	c.Assert(err, IsNil)

	err = env.SetConfig(cfg)

	c.Assert(err, NotNil)
	c.Check(env.Name(), Equals, originalName)
}
<commit_msg>Review change: test for exact error strings.  The juju-core people prefer it.<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package azure

import (
	. "launchpad.net/gocheck"
	"launchpad.net/juju-core/environs/config"
	"launchpad.net/juju-core/testing"
	"sync"
)

type EnvironSuite struct {
	ProviderSuite
}

var _ = Suite(new(EnvironSuite))

func makeEnviron(c *C) *azureEnviron {
	attrs := makeAzureConfigMap(c)
	cfg, err := config.New(attrs)
	c.Assert(err, IsNil)
	ecfg, err := azureEnvironProvider{}.newConfig(cfg)
	c.Assert(err, IsNil)
	return &azureEnviron{
		name: "env",
		ecfg: ecfg,
	}
}

func (EnvironSuite) TestGetSnapshot(c *C) {
	original := azureEnviron{name: "this-env", ecfg: new(azureEnvironConfig)}
	snapshot := original.getSnapshot()

	// The snapshot is identical to the original.
	c.Check(*snapshot, DeepEquals, original)

	// However, they are distinct objects.
	c.Check(snapshot, Not(Equals), &original)

	// It's a shallow copy; they still share pointers.
	c.Check(snapshot.ecfg, Equals, original.ecfg)

	// Neither object is locked at the end of the copy.
	c.Check(original.Mutex, Equals, sync.Mutex{})
	c.Check(snapshot.Mutex, Equals, sync.Mutex{})
}

func (EnvironSuite) TestGetSnapshotLocksEnviron(c *C) {
	original := azureEnviron{}
	testing.TestLockingFunction(&original.Mutex, func() { original.getSnapshot() })
}

func (EnvironSuite) TestName(c *C) {
	env := azureEnviron{name: "foo"}
	c.Check(env.Name(), Equals, env.name)
}

func (EnvironSuite) TestConfigReturnsConfig(c *C) {
	cfg := new(config.Config)
	ecfg := azureEnvironConfig{Config: cfg}
	env := azureEnviron{ecfg: &ecfg}
	c.Check(env.Config(), Equals, cfg)
}

func (EnvironSuite) TestConfigLocksEnviron(c *C) {
	env := azureEnviron{name: "env", ecfg: new(azureEnvironConfig)}
	testing.TestLockingFunction(&env.Mutex, func() { env.Config() })
}

// TODO: Temporarily deactivating this code.  Passing certificate in-memory
// may require gwacl change.
/*
func (EnvironSuite) TestGetManagementAPI(c *C) {
	env := makeEnviron(c)
	management, err := env.getManagementAPI()
	c.Assert(err, IsNil)
	c.Check(management, NotNil)
}
*/

func (EnvironSuite) TestGetStorageContext(c *C) {
	env := makeEnviron(c)
	storage, err := env.getStorageContext()
	c.Assert(err, IsNil)
	c.Assert(storage, NotNil)
	c.Check(storage.Account, Equals, env.ecfg.StorageAccountName())
	c.Check(storage.Key, Equals, env.ecfg.StorageAccountKey())
}

func (EnvironSuite) TestSetConfigValidates(c *C) {
	env := makeEnviron(c)
	originalCfg := env.ecfg
	attrs := makeAzureConfigMap(c)
	// This config is not valid.  It lacks essential information.
	delete(attrs, "management-subscription-id")
	badCfg, err := config.New(attrs)
	c.Assert(err, IsNil)

	err = env.SetConfig(badCfg)

	// Since the config was not valid, SetConfig returns an error.  It
	// does not update the environment's config either.
	c.Check(err, NotNil)
	c.Check(
		err,
		ErrorMatches,
		"management-subscription-id: expected string, got nothing")
	c.Check(env.ecfg, Equals, originalCfg)
}

func (EnvironSuite) TestSetConfigUpdatesConfig(c *C) {
	env := makeEnviron(c)
	// We're going to set a new config.  It can be recognized by its
	// unusual default Ubuntu release series: 7.04 Feisty Fawn.
	attrs := makeAzureConfigMap(c)
	attrs["default-series"] = "feisty"
	cfg, err := config.New(attrs)
	c.Assert(err, IsNil)

	err = env.SetConfig(cfg)
	c.Assert(err, IsNil)

	c.Check(env.ecfg.Config.DefaultSeries(), Equals, "feisty")
}

func (EnvironSuite) TestSetConfigLocksEnviron(c *C) {
	env := makeEnviron(c)
	cfg, err := config.New(makeAzureConfigMap(c))
	c.Assert(err, IsNil)

	testing.TestLockingFunction(&env.Mutex, func() { env.SetConfig(cfg) })
}

func (EnvironSuite) TestSetConfigInitialisesName(c *C) {
	env := azureEnviron{}
	attrs := makeAzureConfigMap(c)
	attrs["name"] = "my-shiny-new-env"
	cfg, err := config.New(attrs)
	c.Assert(err, IsNil)

	err = env.SetConfig(cfg)
	c.Assert(err, IsNil)

	c.Check(env.Name(), Equals, attrs["name"])
}

func (EnvironSuite) TestSetConfigWillNotUpdateName(c *C) {
	// Once the environment's name has been set, it cannot be updated.
	// Global validation rejects such a change.
	// This matters because the attribute is not protected by a lock.
	env := makeEnviron(c)
	originalName := env.Name()
	attrs := makeAzureConfigMap(c)
	attrs["name"] = "new-name"
	cfg, err := config.New(attrs)
	c.Assert(err, IsNil)

	err = env.SetConfig(cfg)

	c.Assert(err, NotNil)
	c.Check(
		err,
		ErrorMatches,
		`cannot change name from ".*" to "new-name"`)
	c.Check(env.Name(), Equals, originalName)
}
<|endoftext|>


<commit_before>package dockerclient

import (
	"fmt"
	"io"
	"time"

	"github.com/docker/go-units"
)

type ContainerConfig struct {
	Hostname        string
	Domainname      string
	User            string
	AttachStdin     bool
	AttachStdout    bool
	AttachStderr    bool
	ExposedPorts    map[string]struct{}
	Tty             bool
	OpenStdin       bool
	StdinOnce       bool
	Env             []string
	Cmd             []string
	Image           string
	Volumes         map[string]struct{}
	WorkingDir      string
	Entrypoint      []string
	NetworkDisabled bool
	MacAddress      string
	OnBuild         []string
	Labels          map[string]string
	StopSignal      string

	// FIXME: VolumeDriver have been removed since docker 1.9
	VolumeDriver string

	// FIXME: The following fields have been removed since API v1.18
	Memory     int64
	MemorySwap int64
	CpuShares  int64
	Cpuset     string
	PortSpecs  []string

	// This is used only by the create command
	HostConfig HostConfig
}

type HostConfig struct {
	Binds             []string
	ContainerIDFile   string
	LxcConf           []map[string]string
	Memory            int64
	MemoryReservation int64
	MemorySwap        int64
	KernelMemory      int64
	CpuShares         int64
	CpuPeriod         int64
	CpusetCpus        string
	CpusetMems        string
	CpuQuota          int64
	BlkioWeight       int64
	OomKillDisable    bool
	MemorySwappiness  int64
	Privileged        bool
	PortBindings      map[string][]PortBinding
	Links             []string
	PublishAllPorts   bool
	Dns               []string
	DNSOptions        []string
	DnsSearch         []string
	ExtraHosts        []string
	VolumesFrom       []string
	Devices           []DeviceMapping
	NetworkMode       string
	IpcMode           string
	PidMode           string
	UTSMode           string
	CapAdd            []string
	CapDrop           []string
	GroupAdd          []string
	RestartPolicy     RestartPolicy
	SecurityOpt       []string
	ReadonlyRootfs    bool
	Ulimits           []Ulimit
	LogConfig         LogConfig
	CgroupParent      string
	ConsoleSize       [2]int
	VolumeDriver      string
}

type DeviceMapping struct {
	PathOnHost        string `json:"PathOnHost"`
	PathInContainer   string `json:"PathInContainer"`
	CgroupPermissions string `json:"CgroupPermissions"`
}

type ExecConfig struct {
	AttachStdin  bool
	AttachStdout bool
	AttachStderr bool
	Tty          bool
	Cmd          []string
	Container    string
	Detach       bool
}

type LogOptions struct {
	Follow     bool
	Stdout     bool
	Stderr     bool
	Timestamps bool
	Tail       int64
}

type AttachOptions struct {
	Logs   bool
	Stream bool
	Stdin  bool
	Stdout bool
	Stderr bool
}

type MonitorEventsFilters struct {
	Event     string `json:",omitempty"`
	Image     string `json:",omitempty"`
	Container string `json:",omitempty"`
}

type MonitorEventsOptions struct {
	Since   int
	Until   int
	Filters *MonitorEventsFilters `json:",omitempty"`
}

type RestartPolicy struct {
	Name              string
	MaximumRetryCount int64
}

type PortBinding struct {
	HostIp   string
	HostPort string
}

type State struct {
	Running    bool
	Paused     bool
	Restarting bool
	OOMKilled  bool
	Dead       bool
	Pid        int
	ExitCode   int
	Error      string // contains last known error when starting the container
	StartedAt  time.Time
	FinishedAt time.Time
	Ghost      bool
}

// String returns a human-readable description of the state
// Stoken from docker/docker/daemon/state.go
func (s *State) String() string {
	if s.Running {
		if s.Paused {
			return fmt.Sprintf("Up %s (Paused)", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))
		}
		if s.Restarting {
			return fmt.Sprintf("Restarting (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
		}

		return fmt.Sprintf("Up %s", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))
	}

	if s.Dead {
		return "Dead"
	}

	if s.FinishedAt.IsZero() {
		return ""
	}

	return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
}

// StateString returns a single string to describe state
// Stoken from docker/docker/daemon/state.go
func (s *State) StateString() string {
	if s.Running {
		if s.Paused {
			return "paused"
		}
		if s.Restarting {
			return "restarting"
		}
		return "running"
	}

	if s.Dead {
		return "dead"
	}

	return "exited"
}

type ImageInfo struct {
	Architecture    string
	Author          string
	Comment         string
	Config          *ContainerConfig
	Container       string
	ContainerConfig *ContainerConfig
	Created         time.Time
	DockerVersion   string
	Id              string
	Os              string
	Parent          string
	Size            int64
	VirtualSize     int64
}

type ContainerInfo struct {
	Id              string
	Created         string
	Path            string
	Name            string
	Args            []string
	ExecIDs         []string
	Config          *ContainerConfig
	State           *State
	Image           string
	NetworkSettings struct {
		IPAddress   string `json:"IpAddress"`
		IPPrefixLen int    `json:"IpPrefixLen"`
		Gateway     string
		Bridge      string
		Ports       map[string][]PortBinding
	}
	SysInitPath    string
	ResolvConfPath string
	Volumes        map[string]string
	HostConfig     *HostConfig
}

type ContainerChanges struct {
	Path string
	Kind int
}

type Port struct {
	IP          string
	PrivatePort int
	PublicPort  int
	Type        string
}

type EndpointSettings struct {
	EndpointID          string
	Gateway             string
	IPAddress           string
	IPPrefixLen         int
	IPv6Gateway         string
	GlobalIPv6Address   string
	GlobalIPv6PrefixLen int
	MacAddress          string
}

type Container struct {
	Id              string
	Names           []string
	Image           string
	Command         string
	Created         int64
	Status          string
	Ports           []Port
	SizeRw          int64
	SizeRootFs      int64
	Labels          map[string]string
	NetworkSettings struct {
		Networks map[string]EndpointSettings
	}
}

type Actor struct {
	ID         string
	Attributes map[string]string
}

type Event struct {
	Status string `json:"status,omitempty"`
	ID     string `json:"id,omitempty"`
	From   string `json:"from,omitempty"`

	Type   string
	Action string
	Actor  Actor

	Time     int64 `json:"time,omitempty"`
	TimeNano int64 `json:"timeNano,omitempty"`
}

type Version struct {
	ApiVersion    string
	Arch          string
	GitCommit     string
	GoVersion     string
	KernelVersion string
	Os            string
	Version       string
}

type RespContainersCreate struct {
	Id       string
	Warnings []string
}

type Image struct {
	Created     int64
	Id          string
	Labels      map[string]string
	ParentId    string
	RepoDigests []string
	RepoTags    []string
	Size        int64
	VirtualSize int64
}

// Info is the struct returned by /info
// The API is currently in flux, so Debug, MemoryLimit, SwapLimit, and
// IPv4Forwarding are interfaces because in docker 1.6.1 they are 0 or 1 but in
// master they are bools.
type Info struct {
	ID                 string
	Containers         int64
	Driver             string
	DriverStatus       [][]string
	ExecutionDriver    string
	Images             int64
	KernelVersion      string
	OperatingSystem    string
	NCPU               int64
	MemTotal           int64
	Name               string
	Labels             []string
	Debug              interface{}
	NFd                int64
	NGoroutines        int64
	SystemTime         string
	NEventsListener    int64
	InitPath           string
	InitSha1           string
	IndexServerAddress string
	MemoryLimit        interface{}
	SwapLimit          interface{}
	IPv4Forwarding     interface{}
	BridgeNfIptables   bool
	BridgeNfIp6tables  bool
	DockerRootDir      string
	HttpProxy          string
	HttpsProxy         string
	NoProxy            string
}

type ImageDelete struct {
	Deleted  string
	Untagged string
}

type EventOrError struct {
	Event
	Error error
}

type WaitResult struct {
	ExitCode int
	Error    error
}

type decodingResult struct {
	result interface{}
	err    error
}

// The following are types for the API stats endpoint
type ThrottlingData struct {
	// Number of periods with throttling active
	Periods uint64 `json:"periods"`
	// Number of periods when the container hit its throttling limit.
	ThrottledPeriods uint64 `json:"throttled_periods"`
	// Aggregate time the container was throttled for in nanoseconds.
	ThrottledTime uint64 `json:"throttled_time"`
}

type CpuUsage struct {
	// Total CPU time consumed.
	// Units: nanoseconds.
	TotalUsage uint64 `json:"total_usage"`
	// Total CPU time consumed per core.
	// Units: nanoseconds.
	PercpuUsage []uint64 `json:"percpu_usage"`
	// Time spent by tasks of the cgroup in kernel mode.
	// Units: nanoseconds.
	UsageInKernelmode uint64 `json:"usage_in_kernelmode"`
	// Time spent by tasks of the cgroup in user mode.
	// Units: nanoseconds.
	UsageInUsermode uint64 `json:"usage_in_usermode"`
}

type CpuStats struct {
	CpuUsage       CpuUsage       `json:"cpu_usage"`
	SystemUsage    uint64         `json:"system_cpu_usage"`
	ThrottlingData ThrottlingData `json:"throttling_data,omitempty"`
}

type NetworkStats struct {
	RxBytes   uint64 `json:"rx_bytes"`
	RxPackets uint64 `json:"rx_packets"`
	RxErrors  uint64 `json:"rx_errors"`
	RxDropped uint64 `json:"rx_dropped"`
	TxBytes   uint64 `json:"tx_bytes"`
	TxPackets uint64 `json:"tx_packets"`
	TxErrors  uint64 `json:"tx_errors"`
	TxDropped uint64 `json:"tx_dropped"`
}

type MemoryStats struct {
	Usage    uint64            `json:"usage"`
	MaxUsage uint64            `json:"max_usage"`
	Stats    map[string]uint64 `json:"stats"`
	Failcnt  uint64            `json:"failcnt"`
	Limit    uint64            `json:"limit"`
}

type BlkioStatEntry struct {
	Major uint64 `json:"major"`
	Minor uint64 `json:"minor"`
	Op    string `json:"op"`
	Value uint64 `json:"value"`
}

type BlkioStats struct {
	// number of bytes tranferred to and from the block device
	IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive"`
	IoServicedRecursive     []BlkioStatEntry `json:"io_serviced_recursive"`
	IoQueuedRecursive       []BlkioStatEntry `json:"io_queue_recursive"`
	IoServiceTimeRecursive  []BlkioStatEntry `json:"io_service_time_recursive"`
	IoWaitTimeRecursive     []BlkioStatEntry `json:"io_wait_time_recursive"`
	IoMergedRecursive       []BlkioStatEntry `json:"io_merged_recursive"`
	IoTimeRecursive         []BlkioStatEntry `json:"io_time_recursive"`
	SectorsRecursive        []BlkioStatEntry `json:"sectors_recursive"`
}

type Stats struct {
	Read         time.Time    `json:"read"`
	NetworkStats NetworkStats `json:"network,omitempty"`
	CpuStats     CpuStats     `json:"cpu_stats,omitempty"`
	MemoryStats  MemoryStats  `json:"memory_stats,omitempty"`
	BlkioStats   BlkioStats   `json:"blkio_stats,omitempty"`
}

type Ulimit struct {
	Name string `json:"name"`
	Soft uint64 `json:"soft"`
	Hard uint64 `json:"hard"`
}

type LogConfig struct {
	Type   string            `json:"type"`
	Config map[string]string `json:"config"`
}

type BuildImage struct {
	Config         *ConfigFile
	DockerfileName string
	Context        io.Reader
	RemoteURL      string
	RepoName       string
	SuppressOutput bool
	NoCache        bool
	Remove         bool
	ForceRemove    bool
	Pull           bool
	Memory         int64
	MemorySwap     int64
	CpuShares      int64
	CpuPeriod      int64
	CpuQuota       int64
	CpuSetCpus     string
	CpuSetMems     string
	CgroupParent   string
	BuildArgs      map[string]string
}

type Volume struct {
	Name       string // Name is the name of the volume
	Driver     string // Driver is the Driver name used to create the volume
	Mountpoint string // Mountpoint is the location on disk of the volume
}

type VolumesListResponse struct {
	Volumes []*Volume // Volumes is the list of volumes being returned
}

type VolumeCreateRequest struct {
	Name       string            // Name is the requested name of the volume
	Driver     string            // Driver is the name of the driver that should be used to create the volume
	DriverOpts map[string]string // DriverOpts holds the driver specific options to use for when creating the volume.
}

// IPAM represents IP Address Management
type IPAM struct {
	Driver string
	Config []IPAMConfig
}

// IPAMConfig represents IPAM configurations
type IPAMConfig struct {
	Subnet     string            `json:",omitempty"`
	IPRange    string            `json:",omitempty"`
	Gateway    string            `json:",omitempty"`
	AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"`
}

// NetworkResource is the body of the "get network" http response message
type NetworkResource struct {
	Name       string
	ID         string `json:"Id"`
	Scope      string
	Driver     string
	IPAM       IPAM
	Containers map[string]EndpointResource
	Options    map[string]string
}

// EndpointResource contains network resources allocated and used for a container in a network
type EndpointResource struct {
	Name        string
	EndpointID  string
	MacAddress  string
	IPv4Address string
	IPv6Address string
}

// NetworkCreate is the expected body of the "create network" http request message
type NetworkCreate struct {
	Name           string
	CheckDuplicate bool
	Driver         string
	IPAM           IPAM
	Options        map[string]string
}

// NetworkCreateResponse is the response message sent by the server for network create call
type NetworkCreateResponse struct {
	ID      string `json:"Id"`
	Warning string
}

// NetworkConnect represents the data to be used to connect a container to the network
type NetworkConnect struct {
	Container string
}

// NetworkDisconnect represents the data to be used to disconnect a container from the network
type NetworkDisconnect struct {
	Container string
	Force     bool
}
<commit_msg>add Networks for ContainerInfo<commit_after>package dockerclient

import (
	"fmt"
	"io"
	"time"

	"github.com/docker/go-units"
)

type ContainerConfig struct {
	Hostname        string
	Domainname      string
	User            string
	AttachStdin     bool
	AttachStdout    bool
	AttachStderr    bool
	ExposedPorts    map[string]struct{}
	Tty             bool
	OpenStdin       bool
	StdinOnce       bool
	Env             []string
	Cmd             []string
	Image           string
	Volumes         map[string]struct{}
	WorkingDir      string
	Entrypoint      []string
	NetworkDisabled bool
	MacAddress      string
	OnBuild         []string
	Labels          map[string]string
	StopSignal      string

	// FIXME: VolumeDriver have been removed since docker 1.9
	VolumeDriver string

	// FIXME: The following fields have been removed since API v1.18
	Memory     int64
	MemorySwap int64
	CpuShares  int64
	Cpuset     string
	PortSpecs  []string

	// This is used only by the create command
	HostConfig HostConfig
}

type HostConfig struct {
	Binds             []string
	ContainerIDFile   string
	LxcConf           []map[string]string
	Memory            int64
	MemoryReservation int64
	MemorySwap        int64
	KernelMemory      int64
	CpuShares         int64
	CpuPeriod         int64
	CpusetCpus        string
	CpusetMems        string
	CpuQuota          int64
	BlkioWeight       int64
	OomKillDisable    bool
	MemorySwappiness  int64
	Privileged        bool
	PortBindings      map[string][]PortBinding
	Links             []string
	PublishAllPorts   bool
	Dns               []string
	DNSOptions        []string
	DnsSearch         []string
	ExtraHosts        []string
	VolumesFrom       []string
	Devices           []DeviceMapping
	NetworkMode       string
	IpcMode           string
	PidMode           string
	UTSMode           string
	CapAdd            []string
	CapDrop           []string
	GroupAdd          []string
	RestartPolicy     RestartPolicy
	SecurityOpt       []string
	ReadonlyRootfs    bool
	Ulimits           []Ulimit
	LogConfig         LogConfig
	CgroupParent      string
	ConsoleSize       [2]int
	VolumeDriver      string
}

type DeviceMapping struct {
	PathOnHost        string `json:"PathOnHost"`
	PathInContainer   string `json:"PathInContainer"`
	CgroupPermissions string `json:"CgroupPermissions"`
}

type ExecConfig struct {
	AttachStdin  bool
	AttachStdout bool
	AttachStderr bool
	Tty          bool
	Cmd          []string
	Container    string
	Detach       bool
}

type LogOptions struct {
	Follow     bool
	Stdout     bool
	Stderr     bool
	Timestamps bool
	Tail       int64
}

type AttachOptions struct {
	Logs   bool
	Stream bool
	Stdin  bool
	Stdout bool
	Stderr bool
}

type MonitorEventsFilters struct {
	Event     string `json:",omitempty"`
	Image     string `json:",omitempty"`
	Container string `json:",omitempty"`
}

type MonitorEventsOptions struct {
	Since   int
	Until   int
	Filters *MonitorEventsFilters `json:",omitempty"`
}

type RestartPolicy struct {
	Name              string
	MaximumRetryCount int64
}

type PortBinding struct {
	HostIp   string
	HostPort string
}

type State struct {
	Running    bool
	Paused     bool
	Restarting bool
	OOMKilled  bool
	Dead       bool
	Pid        int
	ExitCode   int
	Error      string // contains last known error when starting the container
	StartedAt  time.Time
	FinishedAt time.Time
	Ghost      bool
}

// String returns a human-readable description of the state
// Stoken from docker/docker/daemon/state.go
func (s *State) String() string {
	if s.Running {
		if s.Paused {
			return fmt.Sprintf("Up %s (Paused)", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))
		}
		if s.Restarting {
			return fmt.Sprintf("Restarting (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
		}

		return fmt.Sprintf("Up %s", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))
	}

	if s.Dead {
		return "Dead"
	}

	if s.FinishedAt.IsZero() {
		return ""
	}

	return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
}

// StateString returns a single string to describe state
// Stoken from docker/docker/daemon/state.go
func (s *State) StateString() string {
	if s.Running {
		if s.Paused {
			return "paused"
		}
		if s.Restarting {
			return "restarting"
		}
		return "running"
	}

	if s.Dead {
		return "dead"
	}

	return "exited"
}

type ImageInfo struct {
	Architecture    string
	Author          string
	Comment         string
	Config          *ContainerConfig
	Container       string
	ContainerConfig *ContainerConfig
	Created         time.Time
	DockerVersion   string
	Id              string
	Os              string
	Parent          string
	Size            int64
	VirtualSize     int64
}

type ContainerInfo struct {
	Id              string
	Created         string
	Path            string
	Name            string
	Args            []string
	ExecIDs         []string
	Config          *ContainerConfig
	State           *State
	Image           string
	NetworkSettings struct {
		IPAddress   string `json:"IpAddress"`
		IPPrefixLen int    `json:"IpPrefixLen"`
		Gateway     string
		Bridge      string
		Ports       map[string][]PortBinding
		Networks    map[string]*EndpointSettings

	}
	SysInitPath    string
	ResolvConfPath string
	Volumes        map[string]string
	HostConfig     *HostConfig
}

type ContainerChanges struct {
	Path string
	Kind int
}

type Port struct {
	IP          string
	PrivatePort int
	PublicPort  int
	Type        string
}

type EndpointSettings struct {
	EndpointID          string
	Gateway             string
	IPAddress           string
	IPPrefixLen         int
	IPv6Gateway         string
	GlobalIPv6Address   string
	GlobalIPv6PrefixLen int
	MacAddress          string
}

type Container struct {
	Id              string
	Names           []string
	Image           string
	Command         string
	Created         int64
	Status          string
	Ports           []Port
	SizeRw          int64
	SizeRootFs      int64
	Labels          map[string]string
	NetworkSettings struct {
		Networks map[string]EndpointSettings
	}
}

type Actor struct {
	ID         string
	Attributes map[string]string
}

type Event struct {
	Status string `json:"status,omitempty"`
	ID     string `json:"id,omitempty"`
	From   string `json:"from,omitempty"`

	Type   string
	Action string
	Actor  Actor

	Time     int64 `json:"time,omitempty"`
	TimeNano int64 `json:"timeNano,omitempty"`
}

type Version struct {
	ApiVersion    string
	Arch          string
	GitCommit     string
	GoVersion     string
	KernelVersion string
	Os            string
	Version       string
}

type RespContainersCreate struct {
	Id       string
	Warnings []string
}

type Image struct {
	Created     int64
	Id          string
	Labels      map[string]string
	ParentId    string
	RepoDigests []string
	RepoTags    []string
	Size        int64
	VirtualSize int64
}

// Info is the struct returned by /info
// The API is currently in flux, so Debug, MemoryLimit, SwapLimit, and
// IPv4Forwarding are interfaces because in docker 1.6.1 they are 0 or 1 but in
// master they are bools.
type Info struct {
	ID                 string
	Containers         int64
	Driver             string
	DriverStatus       [][]string
	ExecutionDriver    string
	Images             int64
	KernelVersion      string
	OperatingSystem    string
	NCPU               int64
	MemTotal           int64
	Name               string
	Labels             []string
	Debug              interface{}
	NFd                int64
	NGoroutines        int64
	SystemTime         string
	NEventsListener    int64
	InitPath           string
	InitSha1           string
	IndexServerAddress string
	MemoryLimit        interface{}
	SwapLimit          interface{}
	IPv4Forwarding     interface{}
	BridgeNfIptables   bool
	BridgeNfIp6tables  bool
	DockerRootDir      string
	HttpProxy          string
	HttpsProxy         string
	NoProxy            string
}

type ImageDelete struct {
	Deleted  string
	Untagged string
}

type EventOrError struct {
	Event
	Error error
}

type WaitResult struct {
	ExitCode int
	Error    error
}

type decodingResult struct {
	result interface{}
	err    error
}

// The following are types for the API stats endpoint
type ThrottlingData struct {
	// Number of periods with throttling active
	Periods uint64 `json:"periods"`
	// Number of periods when the container hit its throttling limit.
	ThrottledPeriods uint64 `json:"throttled_periods"`
	// Aggregate time the container was throttled for in nanoseconds.
	ThrottledTime uint64 `json:"throttled_time"`
}

type CpuUsage struct {
	// Total CPU time consumed.
	// Units: nanoseconds.
	TotalUsage uint64 `json:"total_usage"`
	// Total CPU time consumed per core.
	// Units: nanoseconds.
	PercpuUsage []uint64 `json:"percpu_usage"`
	// Time spent by tasks of the cgroup in kernel mode.
	// Units: nanoseconds.
	UsageInKernelmode uint64 `json:"usage_in_kernelmode"`
	// Time spent by tasks of the cgroup in user mode.
	// Units: nanoseconds.
	UsageInUsermode uint64 `json:"usage_in_usermode"`
}

type CpuStats struct {
	CpuUsage       CpuUsage       `json:"cpu_usage"`
	SystemUsage    uint64         `json:"system_cpu_usage"`
	ThrottlingData ThrottlingData `json:"throttling_data,omitempty"`
}

type NetworkStats struct {
	RxBytes   uint64 `json:"rx_bytes"`
	RxPackets uint64 `json:"rx_packets"`
	RxErrors  uint64 `json:"rx_errors"`
	RxDropped uint64 `json:"rx_dropped"`
	TxBytes   uint64 `json:"tx_bytes"`
	TxPackets uint64 `json:"tx_packets"`
	TxErrors  uint64 `json:"tx_errors"`
	TxDropped uint64 `json:"tx_dropped"`
}

type MemoryStats struct {
	Usage    uint64            `json:"usage"`
	MaxUsage uint64            `json:"max_usage"`
	Stats    map[string]uint64 `json:"stats"`
	Failcnt  uint64            `json:"failcnt"`
	Limit    uint64            `json:"limit"`
}

type BlkioStatEntry struct {
	Major uint64 `json:"major"`
	Minor uint64 `json:"minor"`
	Op    string `json:"op"`
	Value uint64 `json:"value"`
}

type BlkioStats struct {
	// number of bytes tranferred to and from the block device
	IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive"`
	IoServicedRecursive     []BlkioStatEntry `json:"io_serviced_recursive"`
	IoQueuedRecursive       []BlkioStatEntry `json:"io_queue_recursive"`
	IoServiceTimeRecursive  []BlkioStatEntry `json:"io_service_time_recursive"`
	IoWaitTimeRecursive     []BlkioStatEntry `json:"io_wait_time_recursive"`
	IoMergedRecursive       []BlkioStatEntry `json:"io_merged_recursive"`
	IoTimeRecursive         []BlkioStatEntry `json:"io_time_recursive"`
	SectorsRecursive        []BlkioStatEntry `json:"sectors_recursive"`
}

type Stats struct {
	Read         time.Time    `json:"read"`
	NetworkStats NetworkStats `json:"network,omitempty"`
	CpuStats     CpuStats     `json:"cpu_stats,omitempty"`
	MemoryStats  MemoryStats  `json:"memory_stats,omitempty"`
	BlkioStats   BlkioStats   `json:"blkio_stats,omitempty"`
}

type Ulimit struct {
	Name string `json:"name"`
	Soft uint64 `json:"soft"`
	Hard uint64 `json:"hard"`
}

type LogConfig struct {
	Type   string            `json:"type"`
	Config map[string]string `json:"config"`
}

type BuildImage struct {
	Config         *ConfigFile
	DockerfileName string
	Context        io.Reader
	RemoteURL      string
	RepoName       string
	SuppressOutput bool
	NoCache        bool
	Remove         bool
	ForceRemove    bool
	Pull           bool
	Memory         int64
	MemorySwap     int64
	CpuShares      int64
	CpuPeriod      int64
	CpuQuota       int64
	CpuSetCpus     string
	CpuSetMems     string
	CgroupParent   string
	BuildArgs      map[string]string
}

type Volume struct {
	Name       string // Name is the name of the volume
	Driver     string // Driver is the Driver name used to create the volume
	Mountpoint string // Mountpoint is the location on disk of the volume
}

type VolumesListResponse struct {
	Volumes []*Volume // Volumes is the list of volumes being returned
}

type VolumeCreateRequest struct {
	Name       string            // Name is the requested name of the volume
	Driver     string            // Driver is the name of the driver that should be used to create the volume
	DriverOpts map[string]string // DriverOpts holds the driver specific options to use for when creating the volume.
}

// IPAM represents IP Address Management
type IPAM struct {
	Driver string
	Config []IPAMConfig
}

// IPAMConfig represents IPAM configurations
type IPAMConfig struct {
	Subnet     string            `json:",omitempty"`
	IPRange    string            `json:",omitempty"`
	Gateway    string            `json:",omitempty"`
	AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"`
}

// NetworkResource is the body of the "get network" http response message
type NetworkResource struct {
	Name       string
	ID         string `json:"Id"`
	Scope      string
	Driver     string
	IPAM       IPAM
	Containers map[string]EndpointResource
	Options    map[string]string
}

// EndpointResource contains network resources allocated and used for a container in a network
type EndpointResource struct {
	Name        string
	EndpointID  string
	MacAddress  string
	IPv4Address string
	IPv6Address string
}

// NetworkCreate is the expected body of the "create network" http request message
type NetworkCreate struct {
	Name           string
	CheckDuplicate bool
	Driver         string
	IPAM           IPAM
	Options        map[string]string
}

// NetworkCreateResponse is the response message sent by the server for network create call
type NetworkCreateResponse struct {
	ID      string `json:"Id"`
	Warning string
}

// NetworkConnect represents the data to be used to connect a container to the network
type NetworkConnect struct {
	Container string
}

// NetworkDisconnect represents the data to be used to disconnect a container from the network
type NetworkDisconnect struct {
	Container string
	Force     bool
}
<|endoftext|>


<commit_before>package form

import (
	"regexp"
	"strconv"
	"strings"
	"time"
)

// Bool is a bool that implements Parser
type Bool struct {
	Data *bool
}

// Parse is an implementation of Parser
func (b Bool) Parse(d []string) error {
	switch strings.ToLower(d[0]) {
	case "on", "yes", "y":
		*b.Data = true
	case "off", "no", "n":
		*b.Data = false
	default:
		c, err := strconv.ParseBool(d[0])
		*b.Data = c
		return err
	}
	return nil
}

// Int is an int that implements Parser
type Int struct {
	Data *int
}

// Parse is an implementation of Parser
func (i Int) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 0)
	*i.Data = int(n)
	return err
}

// Int8 is an int8 that implements Parser
type Int8 struct {
	Data *int8
}

// Parse is an implementation of Parser
func (i Int8) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 8)
	*i.Data = int8(n)
	return err
}

// Int16 is an int16 that implements Parser
type Int16 struct {
	Data *int16
}

// Parse is an implementation of Parser
func (i Int16) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 16)
	*i.Data = int16(n)
	return err
}

// Int32 is an int32 that implements Parser
type Int32 struct {
	Data *int32
}

// Parse is an implementation of Parser
func (i Int32) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 32)
	*i.Data = int32(n)
	return err
}

// Int64 is an int64 that implements Parser
type Int64 struct {
	Data *int64
}

// Parse is an implementation of Parser
func (i Int64) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 64)
	*i.Data = n
	return err
}

// IntBetween is an implementation of Parser that allows a signed integer
// between the Min and Max (inclusively)
type IntBetween struct {
	Parser
	Min, Max int64
}

// Parse is an implementation of Parser
func (i IntBetween) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 64)
	if err != nil {
		return err
	}
	if n >= i.Min && n <= i.Max {
		return i.Parser.Parse(d)
	}
	return OutsideBounds(d[0])
}

// Uint is a uint that implements Parser
type Uint struct {
	Data *uint
}

// Parse is an implementation of Parser
func (u Uint) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 0)
	*u.Data = uint(n)
	return err
}

// Uint8 is a uint8 that implements Parser
type Uint8 struct {
	Data *uint8
}

// Parse is an implementation of Parser
func (u Uint8) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 8)
	*u.Data = uint8(n)
	return err
}

// Uint16 is a uint16 that implements Parser
type Uint16 struct {
	Data *uint16
}

// Parse is an implementation of Parser
func (u Uint16) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 16)
	*u.Data = uint16(n)
	return err
}

// Uint32 is a uint32 that implements Parser
type Uint32 struct {
	Data *uint32
}

// Parse is an implementation of Parser
func (u Uint32) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 32)
	*u.Data = uint32(n)
	return err
}

// Uint64 is a uint64 that implements Parser
type Uint64 struct {
	Data *uint64
}

// Parse is an implementation of Parser
func (u Uint64) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 64)
	*u.Data = n
	return err
}

// UintBetween is an implementation of Parser that allows an unsigned integer
// between the Min and Max (inclusively)
type UintBetween struct {
	Parser
	Min, Max uint64
}

// Parse is an implementation of Parser
func (u UintBetween) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 64)
	if err != nil {
		return err
	}
	if n >= u.Min && n <= u.Max {
		return u.Parser.Parse(d)
	}
	return OutsideBounds(d[0])
}

// Float32 is a float32 that implements Parser
type Float32 struct {
	Data *float32
}

// Parse is an implementation of Parser
func (f Float32) Parse(d []string) error {
	n, err := strconv.ParseFloat(d[0], 32)
	*f.Data = float32(n)
	return err
}

// Float64 is a float64 that implements Parser
type Float64 struct {
	Data *float64
}

// Parse is an implementation of Parser
func (f Float64) Parse(d []string) error {
	n, err := strconv.ParseFloat(d[0], 64)
	*f.Data = n
	return err
}

// FloatBetween is an implementation of Parser that allows a float between the
// Min and Max (inclusively)
type FloatBetween struct {
	Parser
	Min, Max float64
}

// Parse is an implementation of Parser
func (f FloatBetween) Parse(d []string) error {
	n, err := strconv.ParseFloat(d[0], 64)
	if err != nil {
		return err
	}
	if n >= f.Min && n <= f.Max {
		return f.Parser.Parse(d)
	}
	return OutsideBounds(d[0])
}

// String is a string that implements Parser
type String struct {
	Data *string
}

// Parse is an implementation of Parser
func (s String) Parse(d []string) error {
	*s.Data = d[0]
	return nil
}

// RegexString is an implementation of Parser that matches a string again the
// given regular expression
type RegexString struct {
	Data  *string
	Regex *regexp.Regexp
}

// Parse is an implementation of Parser
func (r RegexString) Parse(d []string) error {
	if r.Regex.MatchString(d[0]) {
		*r.Data = d[0]
		return nil
	}
	return NoRegexMatch(d[0])
}

// RequiredString is like String except that it returns an error when it gets
// an empty string
type RequiredString String

// Parse is an implementation of Parser
func (r RequiredString) Parse(d []string) error {
	if d[0] == "" {
		return Empty{}
	}
	*r.Data = d[0]
	return nil
}

var formats = [...]string{
	time.ANSIC,
	time.Kitchen,
	time.RFC1123,
	time.RFC1123Z,
	time.RFC3339,
	time.RFC3339Nano,
	time.RFC822,
	time.RFC822Z,
	time.RFC850,
	time.RubyDate,
	time.Stamp,
	time.StampNano,
	time.StampMicro,
	time.StampMilli,
	time.UnixDate,
	"2/1/06 15:04:05",
	"2/1/2006 15:04:05",
	"02/01/06 15:04:05",
	"02/01/2006 15:04:05",
	"2/1/06 15:04",
	"2/1/2006 15:04",
	"02/01/06 15:04",
	"02/01/2006 15:04",
	"15:04:05 2/1/06",
	"15:04:05 2/1/2006",
	"15:04:05 02/01/06",
	"15:04:05 02/01/2006",
	"15:04 2/1/06",
	"15:04 2/1/2006",
	"15:04 02/01/06",
	"15:04 02/01/2006",
	"2-1-06 15:04:05",
	"2-1-2006 15:04:05",
	"02-01-06 15:04:05",
	"02-01-2006 15:04:05",
	"2-1-06 15:04",
	"2-1-2006 15:04",
	"02-01-06 15:04",
	"02-01-2006 15:04",
	"15:04:05 2-1-06",
	"15:04:05 2-1-2006",
	"15:04:05 02-01-06",
	"15:04:05 02-01-2006",
	"15:04 2-1-06",
	"15:04 2-1-2006",
	"15:04 02-01-06",
	"15:04 02-01-2006",
}

// Time is a time.Time that implements Parser
type Time struct {
	Data *time.Time
}

// Parse is an implementation of Parser
func (t Time) Parse(d []string) error {
	for _, format := range formats {
		pt, err := time.Parse(format, d[0])
		if err == nil {
			*t.Data = pt
			return nil
		}
	}
	return UnknownFormat(d[0])
}

// UnixTime is like time except that it expects the time to be a Unix timestamp
type UnixTime struct {
	Data *time.Time
}

// Parse is an implementation of Parser
func (u UnixTime) Parse(d []string) error {
	i, err := strconv.ParseInt(d[0], 10, 64)
	if err != nil {
		return err
	}
	*u.Data = time.Unix(i, 0)
	return nil
}

// TimeFormat is like a Time except that it allows a specific format to be
// specified
type TimeFormat struct {
	Data   *time.Time
	Format string
}

// Parse is an implementation of Parser
func (t TimeFormat) Parse(d []string) error {
	pt, err := time.Parse(t.Format, d[0])
	if err != nil {
		return err
	}
	*t.Data = pt
	return nil
}

// Errors

// OutsideBounds is an error returned from a Parser when the parsed value falls
// outside of the range given as an acceptable value
type OutsideBounds string

func (OutsideBounds) Error() string {
	return "value received was outside of specified bounds"
}

// NoRegexMatch is an error returned from RegexString.Parse when the given
// string does not match the given regular expression
type NoRegexMatch string

func (NoRegexMatch) Error() string {
	return "string did not match given regular expression"
}

// Empty is returned when a field contains only an empty string and that is not
// allowed
type Empty struct{}

func (Empty) Error() string {
	return "field is empty"
}

// UnknownFormat is an error returned from Time.Parse when it cannot determine
// the time format of the given string
type UnknownFormat string

func (UnknownFormat) Error() string {
	return "unknown time format"
}
<commit_msg>Removed custom date formats (too region specific)<commit_after>package form

import (
	"regexp"
	"strconv"
	"strings"
	"time"
)

// Bool is a bool that implements Parser
type Bool struct {
	Data *bool
}

// Parse is an implementation of Parser
func (b Bool) Parse(d []string) error {
	switch strings.ToLower(d[0]) {
	case "on", "yes", "y":
		*b.Data = true
	case "off", "no", "n":
		*b.Data = false
	default:
		c, err := strconv.ParseBool(d[0])
		*b.Data = c
		return err
	}
	return nil
}

// Int is an int that implements Parser
type Int struct {
	Data *int
}

// Parse is an implementation of Parser
func (i Int) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 0)
	*i.Data = int(n)
	return err
}

// Int8 is an int8 that implements Parser
type Int8 struct {
	Data *int8
}

// Parse is an implementation of Parser
func (i Int8) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 8)
	*i.Data = int8(n)
	return err
}

// Int16 is an int16 that implements Parser
type Int16 struct {
	Data *int16
}

// Parse is an implementation of Parser
func (i Int16) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 16)
	*i.Data = int16(n)
	return err
}

// Int32 is an int32 that implements Parser
type Int32 struct {
	Data *int32
}

// Parse is an implementation of Parser
func (i Int32) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 32)
	*i.Data = int32(n)
	return err
}

// Int64 is an int64 that implements Parser
type Int64 struct {
	Data *int64
}

// Parse is an implementation of Parser
func (i Int64) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 64)
	*i.Data = n
	return err
}

// IntBetween is an implementation of Parser that allows a signed integer
// between the Min and Max (inclusively)
type IntBetween struct {
	Parser
	Min, Max int64
}

// Parse is an implementation of Parser
func (i IntBetween) Parse(d []string) error {
	n, err := strconv.ParseInt(d[0], 10, 64)
	if err != nil {
		return err
	}
	if n >= i.Min && n <= i.Max {
		return i.Parser.Parse(d)
	}
	return OutsideBounds(d[0])
}

// Uint is a uint that implements Parser
type Uint struct {
	Data *uint
}

// Parse is an implementation of Parser
func (u Uint) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 0)
	*u.Data = uint(n)
	return err
}

// Uint8 is a uint8 that implements Parser
type Uint8 struct {
	Data *uint8
}

// Parse is an implementation of Parser
func (u Uint8) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 8)
	*u.Data = uint8(n)
	return err
}

// Uint16 is a uint16 that implements Parser
type Uint16 struct {
	Data *uint16
}

// Parse is an implementation of Parser
func (u Uint16) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 16)
	*u.Data = uint16(n)
	return err
}

// Uint32 is a uint32 that implements Parser
type Uint32 struct {
	Data *uint32
}

// Parse is an implementation of Parser
func (u Uint32) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 32)
	*u.Data = uint32(n)
	return err
}

// Uint64 is a uint64 that implements Parser
type Uint64 struct {
	Data *uint64
}

// Parse is an implementation of Parser
func (u Uint64) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 64)
	*u.Data = n
	return err
}

// UintBetween is an implementation of Parser that allows an unsigned integer
// between the Min and Max (inclusively)
type UintBetween struct {
	Parser
	Min, Max uint64
}

// Parse is an implementation of Parser
func (u UintBetween) Parse(d []string) error {
	n, err := strconv.ParseUint(d[0], 10, 64)
	if err != nil {
		return err
	}
	if n >= u.Min && n <= u.Max {
		return u.Parser.Parse(d)
	}
	return OutsideBounds(d[0])
}

// Float32 is a float32 that implements Parser
type Float32 struct {
	Data *float32
}

// Parse is an implementation of Parser
func (f Float32) Parse(d []string) error {
	n, err := strconv.ParseFloat(d[0], 32)
	*f.Data = float32(n)
	return err
}

// Float64 is a float64 that implements Parser
type Float64 struct {
	Data *float64
}

// Parse is an implementation of Parser
func (f Float64) Parse(d []string) error {
	n, err := strconv.ParseFloat(d[0], 64)
	*f.Data = n
	return err
}

// FloatBetween is an implementation of Parser that allows a float between the
// Min and Max (inclusively)
type FloatBetween struct {
	Parser
	Min, Max float64
}

// Parse is an implementation of Parser
func (f FloatBetween) Parse(d []string) error {
	n, err := strconv.ParseFloat(d[0], 64)
	if err != nil {
		return err
	}
	if n >= f.Min && n <= f.Max {
		return f.Parser.Parse(d)
	}
	return OutsideBounds(d[0])
}

// String is a string that implements Parser
type String struct {
	Data *string
}

// Parse is an implementation of Parser
func (s String) Parse(d []string) error {
	*s.Data = d[0]
	return nil
}

// RegexString is an implementation of Parser that matches a string again the
// given regular expression
type RegexString struct {
	Data  *string
	Regex *regexp.Regexp
}

// Parse is an implementation of Parser
func (r RegexString) Parse(d []string) error {
	if r.Regex.MatchString(d[0]) {
		*r.Data = d[0]
		return nil
	}
	return NoRegexMatch(d[0])
}

// RequiredString is like String except that it returns an error when it gets
// an empty string
type RequiredString String

// Parse is an implementation of Parser
func (r RequiredString) Parse(d []string) error {
	if d[0] == "" {
		return Empty{}
	}
	*r.Data = d[0]
	return nil
}

var formats = [...]string{
	time.ANSIC,
	time.Kitchen,
	time.RFC1123,
	time.RFC1123Z,
	time.RFC3339,
	time.RFC3339Nano,
	time.RFC822,
	time.RFC822Z,
	time.RFC850,
	time.RubyDate,
	time.Stamp,
	time.StampNano,
	time.StampMicro,
	time.StampMilli,
	time.UnixDate,
}

// Time is a time.Time that implements Parser
type Time struct {
	Data *time.Time
}

// Parse is an implementation of Parser
func (t Time) Parse(d []string) error {
	for _, format := range formats {
		pt, err := time.Parse(format, d[0])
		if err == nil {
			*t.Data = pt
			return nil
		}
	}
	return UnknownFormat(d[0])
}

// UnixTime is like time except that it expects the time to be a Unix timestamp
type UnixTime struct {
	Data *time.Time
}

// Parse is an implementation of Parser
func (u UnixTime) Parse(d []string) error {
	i, err := strconv.ParseInt(d[0], 10, 64)
	if err != nil {
		return err
	}
	*u.Data = time.Unix(i, 0)
	return nil
}

// TimeFormat is like a Time except that it allows a specific format to be
// specified
type TimeFormat struct {
	Data   *time.Time
	Format string
}

// Parse is an implementation of Parser
func (t TimeFormat) Parse(d []string) error {
	pt, err := time.Parse(t.Format, d[0])
	if err != nil {
		return err
	}
	*t.Data = pt
	return nil
}

// Errors

// OutsideBounds is an error returned from a Parser when the parsed value falls
// outside of the range given as an acceptable value
type OutsideBounds string

func (OutsideBounds) Error() string {
	return "value received was outside of specified bounds"
}

// NoRegexMatch is an error returned from RegexString.Parse when the given
// string does not match the given regular expression
type NoRegexMatch string

func (NoRegexMatch) Error() string {
	return "string did not match given regular expression"
}

// Empty is returned when a field contains only an empty string and that is not
// allowed
type Empty struct{}

func (Empty) Error() string {
	return "field is empty"
}

// UnknownFormat is an error returned from Time.Parse when it cannot determine
// the time format of the given string
type UnknownFormat string

func (UnknownFormat) Error() string {
	return "unknown time format"
}
<|endoftext|>


<commit_before>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package sshstorage

import (
	"bufio"
	"bytes"
	"encoding/base64"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"sort"
	"strconv"
	"strings"

	coreerrors "launchpad.net/juju-core/errors"
	"launchpad.net/juju-core/utils"
)

const (
	// tmpdir is the name of the subdirectory
	// inside the remote storage directory where
	// temporary files are created.
	tmpdir = "tmp"

	// contentdir is the name of the subdirectory
	// inside the remote storage directory where
	// files are stored.
	contentdir = "content"
)

// SSHStorage implements environs.Storage.
//
// The storage is created under sudo, and ownership given over to the
// login uid/gid. This is done so that we don't require sudo, and by
// consequence, don't require a pty, so we can interact with a script
// via stdin.
type SSHStorage struct {
	host       string
	remotepath string

	cmd     *exec.Cmd
	stdin   io.WriteCloser
	stdout  io.ReadCloser
	scanner *bufio.Scanner
}

var sshCommand = func(host string, tty bool, command string) *exec.Cmd {
	sshArgs := []string{host}
	if tty {
		sshArgs = append(sshArgs, "-t")
	}
	sshArgs = append(sshArgs, "--", command)
	return exec.Command("ssh", sshArgs...)
}

type flockmode string

const (
	flockShared    flockmode = "-s"
	flockExclusive flockmode = "-x"
)

// NewSSHStorage creates a new SSHStorage, connected to the
// specified host, managing state under the specified remote path.
func NewSSHStorage(host string, remotepath string) (*SSHStorage, error) {
	contentdir := path.Join(remotepath, contentdir)
	tmpdir := path.Join(remotepath, tmpdir)
	script := fmt.Sprintf("install -d -g $SUDO_GID -o $SUDO_UID %s %s", contentdir, tmpdir)
	cmd := sshCommand(host, true, fmt.Sprintf("sudo bash -c '%s'", script))
	cmd.Stdin = os.Stdin
	if out, err := cmd.CombinedOutput(); err != nil {
		err = fmt.Errorf("failed to create storage dir: %v (%v)", err, strings.TrimSpace(string(out)))
		return nil, err
	}

	// We could use sftp, but then we'd be at the mercy of
	// sftp's output messages for checking errors. Instead,
	// we execute an interactive bash shell.
	cmd = sshCommand(host, false, "bash")
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		stdin.Close()
		return nil, err
	}
	storage := &SSHStorage{
		host:       host,
		remotepath: remotepath,
		cmd:        cmd,
		stdin:      stdin,
		stdout:     stdout,
		scanner:    bufio.NewScanner(stdout),
	}
	cmd.Start()

	// Verify we have write permissions, and set the temporary directory.
	_, err = storage.runf(
		flockExclusive,
		"touch %s && export TMPDIR=%s",
		utils.ShQuote(remotepath),
		utils.ShQuote(tmpdir),
	)
	if err != nil {
		stdin.Close()
		stdout.Close()
		cmd.Wait()
		return nil, err
	}
	return storage, nil
}

// Close cleanly terminates the underlying SSH connection.
func (s *SSHStorage) Close() error {
	s.stdin.Close()
	s.stdout.Close()
	return s.cmd.Wait()
}

func (s *SSHStorage) runf(flockmode flockmode, command string, args ...interface{}) (string, error) {
	command = fmt.Sprintf(command, args...)
	return s.run(flockmode, command)
}

func (s *SSHStorage) run(flockmode flockmode, command string) (string, error) {
	const rcPrefix = "JUJU-RC: "
	command = fmt.Sprintf(
		"(flock %s %s -c %s) 2>&1; echo %s$?",
		flockmode,
		s.remotepath,
		utils.ShQuote(command),
		rcPrefix,
	)
	if _, err := s.stdin.Write([]byte(command + "\r\n")); err != nil {
		return "", fmt.Errorf("failed to write command: %v", err)
	}
	var output []string
	for s.scanner.Scan() {
		line := s.scanner.Text()
		if strings.HasPrefix(line, rcPrefix) {
			line := line[len(rcPrefix):]
			rc, err := strconv.Atoi(line)
			if err != nil {
				return "", fmt.Errorf("failed to parse exit code %q: %v", line, err)
			}
			outputJoined := strings.Join(output, "\n")
			if rc == 0 {
				return outputJoined, nil
			}
			return "", SSHStorageError{outputJoined, rc}
		} else {
			output = append(output, line)
		}
	}
	return "", s.scanner.Err()
}

// path returns a remote absolute path for a storage object name.
func (s *SSHStorage) path(name string) (string, error) {
	contentdir := path.Join(s.remotepath, contentdir)
	remotepath := path.Clean(path.Join(contentdir, name))
	if !strings.HasPrefix(remotepath, contentdir) {
		return "", fmt.Errorf("%q escapes storage directory", name)
	}
	return remotepath, nil
}

// Get implements environs.StorageReader.Get.
func (s *SSHStorage) Get(name string) (io.ReadCloser, error) {
	path, err := s.path(name)
	if err != nil {
		return nil, err
	}
	out, err := s.runf(flockShared, "base64 < %s", utils.ShQuote(path))
	if err != nil {
		err := err.(SSHStorageError)
		if strings.Contains(err.Output, "No such file or directory") {
			return nil, coreerrors.NewNotFoundError(err, "")
		}
		return nil, err
	}
	decoded, err := base64.StdEncoding.DecodeString(out)
	if err != nil {
		return nil, err
	}
	return ioutil.NopCloser(bytes.NewBuffer(decoded)), nil
}

// List implements environs.StorageReader.List.
func (s *SSHStorage) List(prefix string) ([]string, error) {
	remotepath, err := s.path(prefix)
	if err != nil {
		return nil, err
	}
	dir, prefix := path.Split(remotepath)
	quotedDir := utils.ShQuote(dir)
	out, err := s.runf(flockShared, "(test -d %s && find %s -type f) || true", quotedDir, quotedDir)
	if err != nil {
		return nil, err
	}
	if out == "" {
		return nil, nil
	}
	var names []string
	contentdir := path.Join(s.remotepath, contentdir)
	for _, name := range strings.Split(out, "\n") {
		if strings.HasPrefix(name[len(dir):], prefix) {
			names = append(names, name[len(contentdir)+1:])
		}
	}
	sort.Strings(names)
	return names, nil
}

// URL implements environs.StorageReader.URL.
func (s *SSHStorage) URL(name string) (string, error) {
	path, err := s.path(name)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("sftp://%s/%s", s.host, path), nil
}

// ConsistencyStrategy implements environs.StorageReader.ConsistencyStrategy.
func (s *SSHStorage) ConsistencyStrategy() utils.AttemptStrategy {
	return utils.AttemptStrategy{}
}

// Put implements environs.StorageWriter.Put
func (s *SSHStorage) Put(name string, r io.Reader, length int64) error {
	path, err := s.path(name)
	if err != nil {
		return err
	}
	buf := make([]byte, length)
	if _, err := r.Read(buf); err != nil {
		return err
	}
	encoded := base64.StdEncoding.EncodeToString(buf)
	path = utils.ShQuote(path)
	// Write to a temporary file ($TMPFILE), then mv atomically.
	command := fmt.Sprintf("mkdir -p `dirname %s` && base64 -d > $TMPFILE", path)
	command = fmt.Sprintf("TMPFILE=`mktemp` && ((%s && mv $TMPFILE %s) || rm -f $TMPFILE)", command, path)
	command = fmt.Sprintf("(%s) << EOF\n%s\nEOF", command, encoded)
	_, err = s.runf(flockExclusive, command+"\n")
	return err
}

// Remove implements environs.StorageWriter.Remove
func (s *SSHStorage) Remove(name string) error {
	path, err := s.path(name)
	if err != nil {
		return err
	}
	path = utils.ShQuote(path)
	_, err = s.runf(flockExclusive, "rm -f %s", path)
	return err
}

// RemoveAll implements environs.StorageWriter.RemoveAll
func (s *SSHStorage) RemoveAll() error {
	contentdir := path.Join(s.remotepath, contentdir)
	_, err := s.runf(flockExclusive, "rm -fr %s/*", utils.ShQuote(contentdir))
	return err
}
<commit_msg>environs/sshstorage: adjust error message<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package sshstorage

import (
	"bufio"
	"bytes"
	"encoding/base64"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"sort"
	"strconv"
	"strings"

	coreerrors "launchpad.net/juju-core/errors"
	"launchpad.net/juju-core/utils"
)

const (
	// tmpdir is the name of the subdirectory
	// inside the remote storage directory where
	// temporary files are created.
	tmpdir = "tmp"

	// contentdir is the name of the subdirectory
	// inside the remote storage directory where
	// files are stored.
	contentdir = "content"
)

// SSHStorage implements environs.Storage.
//
// The storage is created under sudo, and ownership given over to the
// login uid/gid. This is done so that we don't require sudo, and by
// consequence, don't require a pty, so we can interact with a script
// via stdin.
type SSHStorage struct {
	host       string
	remotepath string

	cmd     *exec.Cmd
	stdin   io.WriteCloser
	stdout  io.ReadCloser
	scanner *bufio.Scanner
}

var sshCommand = func(host string, tty bool, command string) *exec.Cmd {
	sshArgs := []string{host}
	if tty {
		sshArgs = append(sshArgs, "-t")
	}
	sshArgs = append(sshArgs, "--", command)
	return exec.Command("ssh", sshArgs...)
}

type flockmode string

const (
	flockShared    flockmode = "-s"
	flockExclusive flockmode = "-x"
)

// NewSSHStorage creates a new SSHStorage, connected to the
// specified host, managing state under the specified remote path.
func NewSSHStorage(host string, remotepath string) (*SSHStorage, error) {
	contentdir := path.Join(remotepath, contentdir)
	tmpdir := path.Join(remotepath, tmpdir)
	script := fmt.Sprintf("install -d -g $SUDO_GID -o $SUDO_UID %s %s", contentdir, tmpdir)
	cmd := sshCommand(host, true, fmt.Sprintf("sudo bash -c '%s'", script))
	cmd.Stdin = os.Stdin
	if out, err := cmd.CombinedOutput(); err != nil {
		err = fmt.Errorf("failed to create storage dir: %v (%v)", err, strings.TrimSpace(string(out)))
		return nil, err
	}

	// We could use sftp, but then we'd be at the mercy of
	// sftp's output messages for checking errors. Instead,
	// we execute an interactive bash shell.
	cmd = sshCommand(host, false, "bash")
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		stdin.Close()
		return nil, err
	}
	storage := &SSHStorage{
		host:       host,
		remotepath: remotepath,
		cmd:        cmd,
		stdin:      stdin,
		stdout:     stdout,
		scanner:    bufio.NewScanner(stdout),
	}
	cmd.Start()

	// Verify we have write permissions, and set the temporary directory.
	_, err = storage.runf(
		flockExclusive,
		"touch %s && export TMPDIR=%s",
		utils.ShQuote(remotepath),
		utils.ShQuote(tmpdir),
	)
	if err != nil {
		stdin.Close()
		stdout.Close()
		cmd.Wait()
		return nil, err
	}
	return storage, nil
}

// Close cleanly terminates the underlying SSH connection.
func (s *SSHStorage) Close() error {
	s.stdin.Close()
	s.stdout.Close()
	return s.cmd.Wait()
}

func (s *SSHStorage) runf(flockmode flockmode, command string, args ...interface{}) (string, error) {
	command = fmt.Sprintf(command, args...)
	return s.run(flockmode, command)
}

func (s *SSHStorage) run(flockmode flockmode, command string) (string, error) {
	const rcPrefix = "JUJU-RC: "
	command = fmt.Sprintf(
		"(flock %s %s -c %s) 2>&1; echo %s$?",
		flockmode,
		s.remotepath,
		utils.ShQuote(command),
		rcPrefix,
	)
	if _, err := s.stdin.Write([]byte(command + "\r\n")); err != nil {
		return "", fmt.Errorf("failed to write command: %v", err)
	}
	var output []string
	for s.scanner.Scan() {
		line := s.scanner.Text()
		if strings.HasPrefix(line, rcPrefix) {
			line := line[len(rcPrefix):]
			rc, err := strconv.Atoi(line)
			if err != nil {
				return "", fmt.Errorf("failed to parse exit code %q: %v", line, err)
			}
			outputJoined := strings.Join(output, "\n")
			if rc == 0 {
				return outputJoined, nil
			}
			return "", SSHStorageError{outputJoined, rc}
		} else {
			output = append(output, line)
		}
	}
	return "", s.scanner.Err()
}

// path returns a remote absolute path for a storage object name.
func (s *SSHStorage) path(name string) (string, error) {
	contentdir := path.Join(s.remotepath, contentdir)
	remotepath := path.Clean(path.Join(contentdir, name))
	if !strings.HasPrefix(remotepath, contentdir) {
		return "", fmt.Errorf("%q escapes storage directory", name)
	}
	return remotepath, nil
}

// Get implements environs.StorageReader.Get.
func (s *SSHStorage) Get(name string) (io.ReadCloser, error) {
	path, err := s.path(name)
	if err != nil {
		return nil, err
	}
	out, err := s.runf(flockShared, "base64 < %s", utils.ShQuote(path))
	if err != nil {
		err := err.(SSHStorageError)
		if strings.Contains(err.Output, "No such file") {
			return nil, coreerrors.NewNotFoundError(err, "")
		}
		return nil, err
	}
	decoded, err := base64.StdEncoding.DecodeString(out)
	if err != nil {
		return nil, err
	}
	return ioutil.NopCloser(bytes.NewBuffer(decoded)), nil
}

// List implements environs.StorageReader.List.
func (s *SSHStorage) List(prefix string) ([]string, error) {
	remotepath, err := s.path(prefix)
	if err != nil {
		return nil, err
	}
	dir, prefix := path.Split(remotepath)
	quotedDir := utils.ShQuote(dir)
	out, err := s.runf(flockShared, "(test -d %s && find %s -type f) || true", quotedDir, quotedDir)
	if err != nil {
		return nil, err
	}
	if out == "" {
		return nil, nil
	}
	var names []string
	contentdir := path.Join(s.remotepath, contentdir)
	for _, name := range strings.Split(out, "\n") {
		if strings.HasPrefix(name[len(dir):], prefix) {
			names = append(names, name[len(contentdir)+1:])
		}
	}
	sort.Strings(names)
	return names, nil
}

// URL implements environs.StorageReader.URL.
func (s *SSHStorage) URL(name string) (string, error) {
	path, err := s.path(name)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("sftp://%s/%s", s.host, path), nil
}

// ConsistencyStrategy implements environs.StorageReader.ConsistencyStrategy.
func (s *SSHStorage) ConsistencyStrategy() utils.AttemptStrategy {
	return utils.AttemptStrategy{}
}

// Put implements environs.StorageWriter.Put
func (s *SSHStorage) Put(name string, r io.Reader, length int64) error {
	path, err := s.path(name)
	if err != nil {
		return err
	}
	buf := make([]byte, length)
	if _, err := r.Read(buf); err != nil {
		return err
	}
	encoded := base64.StdEncoding.EncodeToString(buf)
	path = utils.ShQuote(path)
	// Write to a temporary file ($TMPFILE), then mv atomically.
	command := fmt.Sprintf("mkdir -p `dirname %s` && base64 -d > $TMPFILE", path)
	command = fmt.Sprintf("TMPFILE=`mktemp` && ((%s && mv $TMPFILE %s) || rm -f $TMPFILE)", command, path)
	command = fmt.Sprintf("(%s) << EOF\n%s\nEOF", command, encoded)
	_, err = s.runf(flockExclusive, command+"\n")
	return err
}

// Remove implements environs.StorageWriter.Remove
func (s *SSHStorage) Remove(name string) error {
	path, err := s.path(name)
	if err != nil {
		return err
	}
	path = utils.ShQuote(path)
	_, err = s.runf(flockExclusive, "rm -f %s", path)
	return err
}

// RemoveAll implements environs.StorageWriter.RemoveAll
func (s *SSHStorage) RemoveAll() error {
	contentdir := path.Join(s.remotepath, contentdir)
	_, err := s.runf(flockExclusive, "rm -fr %s/*", utils.ShQuote(contentdir))
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"nli-go/lib/common"
	"nli-go/lib/global"
	"os"
)

type Result struct {
	Error      bool
	ErrorLines []string
	Value      []string
}

// This application takes a sentence as its parameter and executes a given command.
func main() {

	if len(os.Args) != 4 {
		fmt.Println("Usage: nli <command> </path/to/config.json> <full sentence>")
		fmt.Println("")
		fmt.Println("Example:")
		fmt.Println("    nli answer fox/config.json \"Did the quick brown jump over the lazy dog?\"")
		fmt.Println("")
		fmt.Println("Commands:")
		fmt.Println("    answer     Return an answer to <full sentence>")
		fmt.Println("    suggest    Returns next word suggestions")
		return
	}

	command := os.Args[1]
	configPath := os.Args[2]
	sentence := os.Args[3]

	path := configPath
	if len(path) > 0 && path[0] != os.PathSeparator {
		path = common.Dir() + string(os.PathSeparator) + configPath
	}

	log := global.NewSystemLog()
	system := global.NewSystem(path, log)

	ok := log.IsOk()
	value := []string{}
	errorLines := []string{}

	if ok {
		switch command {
		case "answer":
			value = []string{system.Answer(sentence)}
		case "suggest":
			value = system.Suggest(sentence)
		default:
			errorLines = []string{fmt.Sprintf("%s is not valid command.\n", os.Args[1])}
			ok = false
		}
	}

	if !log.IsOk() {
		errorLines = append(errorLines, log.GetLogLines()...)
	}

	result := Result{
		Error:      !ok,
		ErrorLines: errorLines,
		Value:      value,
	}

	jsonString, _ := json.Marshal(result)
	fmt.Printf(string(jsonString))

	if !ok {
		os.Exit(1)
	}
}
<commit_msg>Fix nli command<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"nli-go/lib/common"
	"nli-go/lib/global"
	"os"
)

type Result struct {
	Error      bool
	ErrorLines []string
	Value      []string
}

// This application takes a sentence as its parameter and executes a given command.
func main() {

	if len(os.Args) != 4 {
		fmt.Println("Usage: nli <command> </path/to/config.json> <full sentence>")
		fmt.Println("")
		fmt.Println("Example:")
		fmt.Println("    nli answer fox/config.json \"Did the quick brown jump over the lazy dog?\"")
		fmt.Println("")
		fmt.Println("Commands:")
		fmt.Println("    answer     Return an answer to <full sentence>")
		fmt.Println("    suggest    Returns next word suggestions")
		return
	}

	command := os.Args[1]
	configPath := os.Args[2]
	sentence := os.Args[3]

	path := configPath
	if len(path) > 0 && path[0] != os.PathSeparator {
		path = common.Dir() + string(os.PathSeparator) + configPath
	}

	log := common.NewSystemLog(false)
	system := global.NewSystem(path, log)

	value := []string{}
	errorLines := []string{}

	if log.IsOk() {
		switch command {
		case "answer":
			value = []string{system.Answer(sentence)}
		case "suggest":
			value = system.Suggest(sentence)
		default:
			errorLines = []string{fmt.Sprintf("%s is not valid command.\n", os.Args[1])}
		}
	}

	if !log.IsOk() {
		errorLines = append(errorLines, log.GetDebugLines()...)
	}

	result := Result{
		Error:      !log.IsOk(),
		ErrorLines: errorLines,
		Value:      value,
	}

	jsonString, _ := json.Marshal(result)
	fmt.Printf(string(jsonString))

	if !log.IsOk() {
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"io"
	"os"
	"regexp"
	"strings"

	"github.com/Financial-Times/coco-logfilter"
)

var (
	blacklistedProperties = []string{
		"_GID",
		"_CAP_EFFECTIVE",
		"SYSLOG_FACILITY",
		"PRIORITY",
		"SYSLOG_IDENTIFIER",
		"_BOOT_ID",
		"_CMDLINE",
		"_COMM",
		"_EXE",
		"_SYSTEMD_CGROUP",
		"_SYSTEMD_SLICE",
		"_TRANSPORT",
		"_UID",
		"__CURSOR",
		"__MONOTONIC_TIMESTAMP",
		"_SELINUX_CONTEXT",
		"__REALTIME_TIMESTAMP",
		"_PID",
	}

	blacklistedUnits = map[string]bool{
		"splunk-forwarder.service":   true,
		"docker.service":             true,
		"diamond.service":            true,
		"logstash-forwarder.service": true,
	}

	blacklistedStrings = []string{
		"transaction_id=SYNTHETIC-REQ",
	}

	propertyMapping = map[string]string{
		"_SYSTEMD_UNIT": "SYSTEMD_UNIT",
		"_MACHINE_ID":   "MACHINE_ID",
		"_HOSTNAME":     "HOSTNAME",
	}
)

var environmentTag *string = new(string)

func main() {
	*environmentTag = os.Getenv("ENV")

	dec := json.NewDecoder(os.Stdin)
	enc := json.NewEncoder(os.Stdout)
	for {
		m := make(map[string]interface{})
		err := dec.Decode(&m)
		if err != nil {
			if err == io.EOF {
				return
			}
			panic(err)
		}
		unit := m["_SYSTEMD_UNIT"]
		if unitString, ok := unit.(string); ok {
			if blacklistedUnits[unitString] {
				continue
			}
		}

		message := fixBytesToString(m["MESSAGE"]).(string)

		if containsBlacklistedString(message) {
			continue
		}

		munge(m, message)
		removeBlacklistedProperties(m)
		renameProperties(m)
		enc.Encode(m)
	}
}

func containsBlacklistedString(message string) bool {
	for _, blacklistedString := range blacklistedStrings {
		if strings.Contains(message, blacklistedString) {
			return true
		}
	}
	return false
}

func munge(m map[string]interface{}, message string) {

	m["platform"] = "up-coco"
	if *environmentTag != "" {
		m["environment"] = *environmentTag
	}

	message = fixNewLines(message)
	m["MESSAGE"] = message

	trans_id := extractTransactionId(message)
	if trans_id != "" {
		m["transaction_id"] = trans_id
	}

	ent, ok := logfilter.Extract(message)
	if !ok {
		return
	}

	// hackity
	j, err := json.Marshal(ent)
	if err != nil {
		panic(err)
	}
	entMap := make(map[string]interface{})
	err = json.Unmarshal(j, &entMap)
	if err != nil {
		panic(err)
	}
	for k, v := range entMap {
		m[k] = v
	}
}

var trans_regex = regexp.MustCompile(`\btransaction_id=([\w-]*)`)

func extractTransactionId(message string) string {
	matches := trans_regex.FindAllStringSubmatch(message, -1)
	if len(matches) != 0 {
		return matches[0][1]
	}

	return ""
}

// workaround for cases where a string has been turned into a
// byte array, or more accurately an array of float64, since
// we've been via json.
// TODO: remove this hack once the underlying cause is found
func fixBytesToString(message interface{}) interface{} {
	intArray, ok := message.([]interface{})
	if !ok {
		return message
	}

	data := make([]byte, len(intArray))
	for i, v := range intArray {
		f64, ok := v.(float64)
		if !ok {
			return message
		}
		data[i] = byte(f64)
	}
	return string(data)
}

func fixNewLines(message string) string {
	return strings.Replace(message, "|", "\n", -1)
}

func removeBlacklistedProperties(m map[string]interface{}) {
	for _, p := range blacklistedProperties {
		delete(m, p)
	}
}

func renameProperties(m map[string]interface{}) {
	for p, r := range propertyMapping {
		value := m[p]
		if value != nil {
			delete(m, p)
			m[r] = value
		}
	}

}
<commit_msg>Added kubernetes services to be ignored.<commit_after>package main

import (
	"encoding/json"
	"io"
	"os"
	"regexp"
	"strings"

	"github.com/Financial-Times/coco-logfilter"
)

var (
	blacklistedProperties = []string{
		"_GID",
		"_CAP_EFFECTIVE",
		"SYSLOG_FACILITY",
		"PRIORITY",
		"SYSLOG_IDENTIFIER",
		"_BOOT_ID",
		"_CMDLINE",
		"_COMM",
		"_EXE",
		"_SYSTEMD_CGROUP",
		"_SYSTEMD_SLICE",
		"_TRANSPORT",
		"_UID",
		"__CURSOR",
		"__MONOTONIC_TIMESTAMP",
		"_SELINUX_CONTEXT",
		"__REALTIME_TIMESTAMP",
		"_PID",
	}

	blacklistedUnits = map[string]bool{
		"splunk-forwarder.service":   true,
		"docker.service":             true,
		"diamond.service":            true,
		"logstash-forwarder.service": true,
		"kubelet.service": true,
		"flanneld.service": true,

	}

	blacklistedStrings = []string{
		"transaction_id=SYNTHETIC-REQ",
	}

	propertyMapping = map[string]string{
		"_SYSTEMD_UNIT": "SYSTEMD_UNIT",
		"_MACHINE_ID":   "MACHINE_ID",
		"_HOSTNAME":     "HOSTNAME",
	}
)

var environmentTag *string = new(string)

func main() {
	*environmentTag = os.Getenv("ENV")

	dec := json.NewDecoder(os.Stdin)
	enc := json.NewEncoder(os.Stdout)
	for {
		m := make(map[string]interface{})
		err := dec.Decode(&m)
		if err != nil {
			if err == io.EOF {
				return
			}
			panic(err)
		}
		unit := m["_SYSTEMD_UNIT"]
		if unitString, ok := unit.(string); ok {
			if blacklistedUnits[unitString] {
				continue
			}
		}

		message := fixBytesToString(m["MESSAGE"]).(string)

		if containsBlacklistedString(message) {
			continue
		}

		munge(m, message)
		removeBlacklistedProperties(m)
		renameProperties(m)
		enc.Encode(m)
	}
}

func containsBlacklistedString(message string) bool {
	for _, blacklistedString := range blacklistedStrings {
		if strings.Contains(message, blacklistedString) {
			return true
		}
	}
	return false
}

func munge(m map[string]interface{}, message string) {

	m["platform"] = "up-coco"
	if *environmentTag != "" {
		m["environment"] = *environmentTag
	}

	message = fixNewLines(message)
	m["MESSAGE"] = message

	trans_id := extractTransactionId(message)
	if trans_id != "" {
		m["transaction_id"] = trans_id
	}

	ent, ok := logfilter.Extract(message)
	if !ok {
		return
	}

	// hackity
	j, err := json.Marshal(ent)
	if err != nil {
		panic(err)
	}
	entMap := make(map[string]interface{})
	err = json.Unmarshal(j, &entMap)
	if err != nil {
		panic(err)
	}
	for k, v := range entMap {
		m[k] = v
	}
}

var trans_regex = regexp.MustCompile(`\btransaction_id=([\w-]*)`)

func extractTransactionId(message string) string {
	matches := trans_regex.FindAllStringSubmatch(message, -1)
	if len(matches) != 0 {
		return matches[0][1]
	}

	return ""
}

// workaround for cases where a string has been turned into a
// byte array, or more accurately an array of float64, since
// we've been via json.
// TODO: remove this hack once the underlying cause is found
func fixBytesToString(message interface{}) interface{} {
	intArray, ok := message.([]interface{})
	if !ok {
		return message
	}

	data := make([]byte, len(intArray))
	for i, v := range intArray {
		f64, ok := v.(float64)
		if !ok {
			return message
		}
		data[i] = byte(f64)
	}
	return string(data)
}

func fixNewLines(message string) string {
	return strings.Replace(message, "|", "\n", -1)
}

func removeBlacklistedProperties(m map[string]interface{}) {
	for _, p := range blacklistedProperties {
		delete(m, p)
	}
}

func renameProperties(m map[string]interface{}) {
	for p, r := range propertyMapping {
		value := m[p]
		if value != nil {
			delete(m, p)
			m[r] = value
		}
	}

}
<|endoftext|>


<commit_before>package seq

//  Some utilities supporting seq.PersistentVector implementations
<commit_msg>Remove file avec.go<commit_after><|endoftext|>