<commit_before>// The MIT License (MIT)

// Copyright (c) 2016 Fabian Wenzelmann

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

package set

type SetValue interface{}

const maxBuffer = 10000

// Set is a unordered collection of unique values.
type Set struct {
	elements map[SetValue]struct{}
}

func EmptySet() *Set {
	return &Set{make(map[SetValue]struct{})}
}

func (this *Set) Length() int {
	return len(this.elements)
}

func (this *Set) Empty() bool {
	return this.Length() == 0
}

func (this *Set) Add(val SetValue) {
	this.elements[val] = struct{}{}
}

func (this *Set) Remove(val SetValue) {
	delete(this.elements, val)
}

func (this *Set) Contains(val SetValue) bool {
	_, res := this.elements[val]
	return res
}

func (this *Set) Subset(other *Set) bool {
	for val := range this.Iter() {
		if !other.Contains(val) {
			return false
		}
	}
	return true
}

func (this *Set) Equals(other *Set) bool {
	if this.Length() != other.Length() {
		return false
	}
	return this.Subset(other)
}

func (this *Set) Union(other *Set) *Set {
	res := EmptySet()
	for k, _ := range this.elements {
		res.Add(k)
	}
	for k, _ := range other.elements {
		res.Add(k)
	}
	return res
}

func (this *Set) Intersect(other *Set) *Set {
	s1, s2 := this, other
	if other.Length() < this.Length() {
		s1, s2 = other, this
	}
	res := EmptySet()
	for k, _ := range s1.elements {
		if s2.Contains(k) {
			res.Add(k)
		}
	}
	return res
}

func (this *Set) Extend(other *Set) {
	for k, _ := range other.elements {
		this.Add(k)
	}
}

// Return a chanel to iterate over all elements in the set.
// Important: Only use this iterator if you plan to iterate over *all* objects,
// so don't break the for loop with a break or something like that.
// If you plan to break the loop you can use Apply.
func (this *Set) Iter() <-chan SetValue {
	bufferSize := this.Length()
	if bufferSize > maxBuffer {
		bufferSize = maxBuffer
	}
	ch := make(chan SetValue, bufferSize)
	go func() {
		for k, _ := range this.elements {
			ch <- k
		}
		close(ch)
	}()
	return ch
}

// Applies a function to all values (acts like an iterator).
// The function argument is applied to all values in the set, if the function
// returns true the next element will be visited, otherwise the iteration
// will stop.
// See the example.
func (this *Set) Apply(f func(val SetValue) bool) {
	for k, _ := range this.elements {
		if !f(k) {
			break
		}
	}
}

func (this *Set) Pop() (SetValue, bool) {
	var val SetValue = nil
	succ := false
	for k, _ := range this.elements {
		val = k
		succ = true
		break
	}
	if succ {
		this.Remove(val)
	}
	return val, succ
}

func (this *Set) Copy() *Set {
	res := EmptySet()
	for k, _ := range this.elements {
		res.Add(k)
	}
	return res
}
<commit_msg>documentation for set<commit_after>// The MIT License (MIT)

// Copyright (c) 2016 Fabian Wenzelmann

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

package set

// An empty interface for elements stored in the set.
type SetValue interface{}

const maxBuffer = 10000

// Set is a unordered collection of unique values.
type Set struct {
	elements map[SetValue]struct{}
}

// EmptySet creates a set without any elements.
func EmptySet() *Set {
	return &Set{make(map[SetValue]struct{})}
}

// Length returns the number of elements in the set.
func (this *Set) Length() int {
	return len(this.elements)
}

// Empty returns true if the set does not contain any elements, and false
// otherwise.
func (this *Set) Empty() bool {
	return this.Length() == 0
}

// Add an element to the set.
func (this *Set) Add(val SetValue) {
	this.elements[val] = struct{}{}
}

// Remove an element from the set.
func (this *Set) Remove(val SetValue) {
	delete(this.elements, val)
}

// Contains returns true if val is contained in the set, false otherwise.
func (this *Set) Contains(val SetValue) bool {
	_, res := this.elements[val]
	return res
}

// Subset checks if this is a subset of the other set, i.e. this <= other.
func (this *Set) Subset(other *Set) bool {
	for val := range this.Iter() {
		if !other.Contains(val) {
			return false
		}
	}
	return true
}

// Equals returns true if both sets are equal.
func (this *Set) Equals(other *Set) bool {
	if this.Length() != other.Length() {
		return false
	}
	return this.Subset(other)
}

// Union returns a new set containing elements from both sets.
func (this *Set) Union(other *Set) *Set {
	res := EmptySet()
	for k, _ := range this.elements {
		res.Add(k)
	}
	for k, _ := range other.elements {
		res.Add(k)
	}
	return res
}

// Intersect returns a new set containing elements that are contained in both
// sets.
func (this *Set) Intersect(other *Set) *Set {
	s1, s2 := this, other
	if other.Length() < this.Length() {
		s1, s2 = other, this
	}
	res := EmptySet()
	for k, _ := range s1.elements {
		if s2.Contains(k) {
			res.Add(k)
		}
	}
	return res
}

// Extend adds all elements from another set to this set.
func (this *Set) Extend(other *Set) {
	for k, _ := range other.elements {
		this.Add(k)
	}
}

// Return a chanel to iterate over all elements in the set.
// Important: Only use this iterator if you plan to iterate over *all* objects,
// so don't break the for loop with a break or something like that.
// If you plan to break the loop you can use Apply.
func (this *Set) Iter() <-chan SetValue {
	bufferSize := this.Length()
	if bufferSize > maxBuffer {
		bufferSize = maxBuffer
	}
	ch := make(chan SetValue, bufferSize)
	go func() {
		for k, _ := range this.elements {
			ch <- k
		}
		close(ch)
	}()
	return ch
}

// Apply applies a function to all values (acts like an iterator).
// The function argument is applied to all values in the set, if the function
// returns true the next element will be visited, otherwise the iteration
// will stop.
// See the example.
func (this *Set) Apply(f func(val SetValue) bool) {
	for k, _ := range this.elements {
		if !f(k) {
			break
		}
	}
}

// Pop returns and removes a random element from the set, returns as second
// value true if there was an element. If there was no element nil is returned.
func (this *Set) Pop() (SetValue, bool) {
	var val SetValue = nil
	succ := false
	for k, _ := range this.elements {
		val = k
		succ = true
		break
	}
	if succ {
		this.Remove(val)
	}
	return val, succ
}

// Copy creates a new set containing the elements from the current set.
func (this *Set) Copy() *Set {
	res := EmptySet()
	for k, _ := range this.elements {
		res.Add(k)
	}
	return res
}
<|endoftext|>


<commit_before>package main

import "github.com/spf13/cobra"
import "fmt"
import "os"
import "net"
import "strconv"

// import "bufio"

func sendToTV(sharpCommand string, sharpParameter string) {

	debug := true
	cmdString := fmt.Sprintf("%4s%-4s\r", sharpCommand, sharpParameter)
	conn, err := net.Dial("tcp", "192.168.4.11:10002")

	if err != nil {
		fmt.Println("Error connecting to TV.")
		return
	}

	if debug {
		fmt.Printf("Sending command %v\n", cmdString)
	}

	fmt.Fprintf(conn, cmdString)
	if err != nil {
		fmt.Println("An error occured.")
		fmt.Println(err.Error())
	} else {
		if debug {
			fmt.Printf(">>>> Sent %v\n", cmdString)
		}
	}

	tmp := make([]byte, 256)
	result, err := conn.Read(tmp)
	if err != nil {
		fmt.Println(err.Error())
	} else {
		if debug {
			fmt.Printf(">>>> Received: %s %s\n", tmp, string(result))
		}

	}

}

func main() {

	var sharptvCmd = &cobra.Command{
		Use:   "sharptv",
		Short: "sharptv is your command line interface to your television set",
		Long: `sharptv is the main command, used to control your TV

GoSharpTV is a hobbist project by an owner of a Sharp brand TV for other owners
of Sharp brand TVs.  It is implemented in the the Go programming lanugage.

`,
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("SharpTV command line remote control.")
		},
	}

	var cmdVolume = &cobra.Command{
		Use:   "volume [integer volume level to set]",
		Short: "Set the volume level of the TV.",
		Long: `Adjust the sound volume for the television.

You may find that a lower volume is more pleasant at night.
    `,
		Run: func(cmd *cobra.Command, args []string) {

			if len(args) != 1 {
				cmd.Usage()
				os.Exit(1)
			}

			numerical_argument, err := strconv.Atoi(args[0])
			if err == nil {
				if (numerical_argument > -1 && numerical_argument < 61) {
					fmt.Printf("Setting volume to %v\n", args[0])
					sendToTV("VOLM", args[0])
				} else {
					fmt.Printf("Volume specificed is out of range 0 to 60")
					return
				}
				return
			}

			switch {

			case args[0] == "down":
				fmt.Println("Reducing the volume")
				sendToTV("RCKY", "32")

			case args[0] == "up":
				fmt.Println("Reducing the volume")
				sendToTV("RCKY", "33")

			default:
				cmd.Usage();
			}

		},
	}

	var cmdMute = &cobra.Command{
		Use:   "mute {on|off}",
		Short: "Turn the volume of the TV off or on",
		Long: `Mutes or unmutes the television.  If not subcommand of either "off" or "on" are
    specfified, then the mute will be toggled from it's current state.`,
		Run: func(cmd *cobra.Command, args []string) {
			switch {
			case len(args) > 1:
				cmd.Usage()
			case len(args) == 0:
				fmt.Println("Toggling mute.")
				sendToTV("MUTE", "0000")

			case args[0] == "on":
				fmt.Println("Turning on mute.  This will silence the TV.")
				sendToTV("MUTE", "0001")

			case args[0] == "off":
				fmt.Println("Turning off mute.  This will return TV to the previous volume.")
				sendToTV("MUTE", "0002")

			case args[0] == "status":
				sendToTV("MUTE", "?")

			}
		},
	}

	var cmdPower = &cobra.Command{
		Use:   "power {on|off}",
		Short: "Turn the TV off or on",
		Long: `Powers the TV off or on.  If neither subcommand of either "off" nor "on" are
    specfified, then the power will be toggled from it's current state.`,
		Run: func(cmd *cobra.Command, args []string) {
			switch {
			case len(args) == 0:
				fmt.Println("Toggling Power is not yet implemented.")
			case len(args) > 1:
				cmd.Usage()
			case args[0] == "on":
				fmt.Println("Turning on the TV.")
				sendToTV("POWR", "1")
			case args[0] == "off":
				fmt.Println("Turning off the TV.")
				sendToTV("POWR", "0")
			case args[0] == "status":
				sendToTV("POWR", "?")
			default:
				cmd.Usage()
			}
		},
	}

	var cmdInput = &cobra.Command{
		Use:   "input [TV source input number]",
		Short: "Set the input source",
		Long: `Adjust the input source to be displayed on the TV

    `,
		Run: func(cmd *cobra.Command, args []string) {
			switch {

			case len(args) == 1:
				fmt.Printf("Setting input source to %v\n", args[0])
				sendToTV("IAVD", args[0])

			case len(args) != 1:
				cmd.Usage()
			}
		},
	}
	sharptvCmd.AddCommand(cmdPower)
	sharptvCmd.AddCommand(cmdMute)
	sharptvCmd.AddCommand(cmdInput)
	sharptvCmd.AddCommand(cmdVolume)
	sharptvCmd.AddCommand(cmdVolumeDown)
	sharptvCmd.Execute()
}
<commit_msg>Fix typo and usage information.<commit_after>package main

import "github.com/spf13/cobra"
import "fmt"
import "os"
import "net"
import "strconv"

// import "bufio"

func sendToTV(sharpCommand string, sharpParameter string) {

	debug := true
	cmdString := fmt.Sprintf("%4s%-4s\r", sharpCommand, sharpParameter)
	conn, err := net.Dial("tcp", "192.168.4.11:10002")

	if err != nil {
		fmt.Println("Error connecting to TV.")
		return
	}

	if debug {
		fmt.Printf("Sending command %v\n", cmdString)
	}

	fmt.Fprintf(conn, cmdString)
	if err != nil {
		fmt.Println("An error occured.")
		fmt.Println(err.Error())
	} else {
		if debug {
			fmt.Printf(">>>> Sent %v\n", cmdString)
		}
	}

	tmp := make([]byte, 256)
	result, err := conn.Read(tmp)
	if err != nil {
		fmt.Println(err.Error())
	} else {
		if debug {
			fmt.Printf(">>>> Received: %s %s\n", tmp, string(result))
		}

	}

}

func main() {

	var sharptvCmd = &cobra.Command{
		Use:   "sharptv",
		Short: "sharptv is your command line interface to your television set",
		Long: `sharptv is the main command, used to control your TV

GoSharpTV is a hobbist project by an owner of a Sharp brand TV for other owners
of Sharp brand TVs.  It is implemented in the the Go programming lanugage.

`,
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("SharpTV command line remote control.")
		},
	}

	var cmdVolume = &cobra.Command{
		Use:   "volume {0..60|up|down}",
		Short: "Set the volume level of the TV.",
		Long: `Adjust the sound volume for the television.

You may find that a lower volume is more pleasant at night.
    `,
		Run: func(cmd *cobra.Command, args []string) {

			if len(args) != 1 {
				cmd.Usage()
				os.Exit(1)
			}

			numerical_argument, err := strconv.Atoi(args[0])
			if err == nil {
				if (numerical_argument > -1 && numerical_argument < 61) {
					fmt.Printf("Setting volume to %v\n", args[0])
					sendToTV("VOLM", args[0])
				} else {
					fmt.Printf("Volume specificed is out of range 0 to 60")
					return
				}
				return
			}

			switch args[0] {

			case "down":
				fmt.Println("Reducing the volume")
				sendToTV("RCKY", "32")

			case "up":
				fmt.Println("Increasing the volume")
				sendToTV("RCKY", "33")

			default:
				cmd.Usage();
			}

		},
	}

	var cmdMute = &cobra.Command{
		Use:   "mute {on|off}",
		Short: "Turn the volume of the TV off or on",
		Long: `Mutes or unmutes the television.  If not subcommand of either "off" or "on" are
    specfified, then the mute will be toggled from it's current state.`,
		Run: func(cmd *cobra.Command, args []string) {
			switch {
			case len(args) > 1:
				cmd.Usage()
			case len(args) == 0:
				fmt.Println("Toggling mute.")
				sendToTV("MUTE", "0000")

			case args[0] == "on":
				fmt.Println("Turning on mute.  This will silence the TV.")
				sendToTV("MUTE", "0001")

			case args[0] == "off":
				fmt.Println("Turning off mute.  This will return TV to the previous volume.")
				sendToTV("MUTE", "0002")

			case args[0] == "status":
				sendToTV("MUTE", "?")

			}
		},
	}

	var cmdPower = &cobra.Command{
		Use:   "power {on|off}",
		Short: "Turn the TV off or on",
		Long: `Powers the TV off or on.  If neither subcommand of either "off" nor "on" are
    specfified, then the power will be toggled from it's current state.`,
		Run: func(cmd *cobra.Command, args []string) {
			switch {
			case len(args) == 0:
				fmt.Println("Toggling Power is not yet implemented.")
			case len(args) > 1:
				cmd.Usage()
			case args[0] == "on":
				fmt.Println("Turning on the TV.")
				sendToTV("POWR", "1")
			case args[0] == "off":
				fmt.Println("Turning off the TV.")
				sendToTV("POWR", "0")
			case args[0] == "status":
				sendToTV("POWR", "?")
			default:
				cmd.Usage()
			}
		},
	}

	var cmdInput = &cobra.Command{
		Use:   "input [TV source input number]",
		Short: "Set the input source",
		Long: `Adjust the input source to be displayed on the TV

    `,
		Run: func(cmd *cobra.Command, args []string) {
			switch {

			case len(args) == 1:
				fmt.Printf("Setting input source to %v\n", args[0])
				sendToTV("IAVD", args[0])

			case len(args) != 1:
				cmd.Usage()
			}
		},
	}
	sharptvCmd.AddCommand(cmdPower)
	sharptvCmd.AddCommand(cmdMute)
	sharptvCmd.AddCommand(cmdInput)
	sharptvCmd.AddCommand(cmdVolume)
		sharptvCmd.Execute()
}
<|endoftext|>


<commit_before>package vault

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/url"
	"time"

	"code.cloudfoundry.org/lager"

	"github.com/cloudfoundry/bosh-cli/director/template"
	"github.com/concourse/atc/creds"
	vaultapi "github.com/hashicorp/vault/api"
)

type VaultManager struct {
	URL string `long:"url" description:"Vault server address used to access secrets."`

	PathPrefix string `long:"path-prefix" default:"/concourse" description:"Path under which to namespace credential lookup."`

	Cache    bool          `long:"cache" description:"Cache returned secrets for their lease duration in memory"`
	MaxLease time.Duration `long:"max-lease" description:"If the cache is enabled, and this is set, override secrets lease duration with a maximum value"`

	TLS    TLS
	Auth   AuthConfig
	Client *APIClient
}

type TLS struct {
	CACert     string `long:"ca-cert"              description:"Path to a PEM-encoded CA cert file to use to verify the vault server SSL cert."`
	CAPath     string `long:"ca-path"              description:"Path to a directory of PEM-encoded CA cert files to verify the vault server SSL cert."`
	ClientCert string `long:"client-cert"          description:"Path to the client certificate for Vault authorization."`
	ClientKey  string `long:"client-key"           description:"Path to the client private key for Vault authorization."`
	ServerName string `long:"server-name"          description:"If set, is used to set the SNI host when connecting via TLS."`
	Insecure   bool   `long:"insecure-skip-verify" description:"Enable insecure SSL verification."`
}

type AuthConfig struct {
	ClientToken string `long:"client-token" description:"Client token for accessing secrets within the Vault server."`

	Backend       string        `long:"auth-backend"               description:"Auth backend to use for logging in to Vault."`
	BackendMaxTTL time.Duration `long:"auth-backend-max-ttl"       description:"Time after which to force a re-login. If not set, the token will just be continuously renewed."`
	RetryMax      time.Duration `long:"retry-max"     default:"5m" description:"The maximum time between retries when logging in or re-authing a secret."`
	RetryInitial  time.Duration `long:"retry-initial" default:"1s" description:"The initial time between retries when logging in or re-authing a secret."`

	Params []template.VarKV `long:"auth-param"  description:"Paramter to pass when logging in via the backend. Can be specified multiple times." value-name:"NAME=VALUE"`
}

func (manager *VaultManager) Init(log lager.Logger) error {
	var err error

	tlsConfig := &vaultapi.TLSConfig{
		CACert:        manager.TLS.CACert,
		CAPath:        manager.TLS.CAPath,
		TLSServerName: manager.TLS.ServerName,
		Insecure:      manager.TLS.Insecure,

		ClientCert: manager.TLS.ClientCert,
		ClientKey:  manager.TLS.ClientKey,
	}

	manager.Client, err = NewAPIClient(nil, manager.URL, tlsConfig, manager.Auth)
	if err != nil {
		return err
	}

	return nil
}

func (manager *VaultManager) MarshalJSON() ([]byte, error) {
	health, err := manager.Health()
	if err != nil {
		return nil, err
	}

	return json.Marshal(&map[string]interface{}{
		"url":                manager.URL,
		"path_prefix":        manager.PathPrefix,
		"cache":              manager.Cache,
		"max_lease":          manager.MaxLease,
		"ca_cert":            manager.TLS.CACert,
		"server_name":        manager.TLS.ServerName,
		"auth_backend":       manager.Auth.Backend,
		"auth_max_ttl":       manager.Auth.BackendMaxTTL,
		"auth_retry_max":     manager.Auth.RetryMax,
		"auth_retry_initial": manager.Auth.RetryInitial,
		"health":             health,
	})
}

func (manager VaultManager) IsConfigured() bool {
	return manager.URL != ""
}

func (manager VaultManager) Validate() error {
	_, err := url.Parse(manager.URL)
	if err != nil {
		return fmt.Errorf("invalid URL: %s", err)
	}

	if manager.Auth.ClientToken != "" {
		return nil
	}

	if manager.Auth.Backend != "" {
		return nil
	}

	return errors.New("must configure client token or auth backend")
}

func (manager VaultManager) Health() (*creds.HealthResponse, error) {
	health := &creds.HealthResponse{
		Method: "/v1/sys/health",
	}

	response, err := manager.Client.health()
	if err != nil {
		health.Error = err.Error()
		return health, nil
	}

	health.Response = response
	return health, nil
}

func (manager VaultManager) NewVariablesFactory(logger lager.Logger) (creds.VariablesFactory, error) {
	ra := NewReAuther(manager.Client, manager.Auth.BackendMaxTTL, manager.Auth.RetryInitial, manager.Auth.RetryMax)
	var sr SecretReader = manager.Client
	if manager.Cache {
		sr = NewCache(manager.Client, manager.MaxLease)
	}

	return NewVaultFactory(sr, ra.LoggedIn(), manager.PathPrefix), nil
}
<commit_msg>Fix topgun job by fixing nil pointer to logger<commit_after>package vault

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/url"
	"time"

	"code.cloudfoundry.org/lager"

	"github.com/cloudfoundry/bosh-cli/director/template"
	"github.com/concourse/atc/creds"
	vaultapi "github.com/hashicorp/vault/api"
)

type VaultManager struct {
	URL string `long:"url" description:"Vault server address used to access secrets."`

	PathPrefix string `long:"path-prefix" default:"/concourse" description:"Path under which to namespace credential lookup."`

	Cache    bool          `long:"cache" description:"Cache returned secrets for their lease duration in memory"`
	MaxLease time.Duration `long:"max-lease" description:"If the cache is enabled, and this is set, override secrets lease duration with a maximum value"`

	TLS    TLS
	Auth   AuthConfig
	Client *APIClient
}

type TLS struct {
	CACert     string `long:"ca-cert"              description:"Path to a PEM-encoded CA cert file to use to verify the vault server SSL cert."`
	CAPath     string `long:"ca-path"              description:"Path to a directory of PEM-encoded CA cert files to verify the vault server SSL cert."`
	ClientCert string `long:"client-cert"          description:"Path to the client certificate for Vault authorization."`
	ClientKey  string `long:"client-key"           description:"Path to the client private key for Vault authorization."`
	ServerName string `long:"server-name"          description:"If set, is used to set the SNI host when connecting via TLS."`
	Insecure   bool   `long:"insecure-skip-verify" description:"Enable insecure SSL verification."`
}

type AuthConfig struct {
	ClientToken string `long:"client-token" description:"Client token for accessing secrets within the Vault server."`

	Backend       string        `long:"auth-backend"               description:"Auth backend to use for logging in to Vault."`
	BackendMaxTTL time.Duration `long:"auth-backend-max-ttl"       description:"Time after which to force a re-login. If not set, the token will just be continuously renewed."`
	RetryMax      time.Duration `long:"retry-max"     default:"5m" description:"The maximum time between retries when logging in or re-authing a secret."`
	RetryInitial  time.Duration `long:"retry-initial" default:"1s" description:"The initial time between retries when logging in or re-authing a secret."`

	Params []template.VarKV `long:"auth-param"  description:"Paramter to pass when logging in via the backend. Can be specified multiple times." value-name:"NAME=VALUE"`
}

func (manager *VaultManager) Init(log lager.Logger) error {
	var err error

	tlsConfig := &vaultapi.TLSConfig{
		CACert:        manager.TLS.CACert,
		CAPath:        manager.TLS.CAPath,
		TLSServerName: manager.TLS.ServerName,
		Insecure:      manager.TLS.Insecure,

		ClientCert: manager.TLS.ClientCert,
		ClientKey:  manager.TLS.ClientKey,
	}

	manager.Client, err = NewAPIClient(log, manager.URL, tlsConfig, manager.Auth)
	if err != nil {
		return err
	}

	return nil
}

func (manager *VaultManager) MarshalJSON() ([]byte, error) {
	health, err := manager.Health()
	if err != nil {
		return nil, err
	}

	return json.Marshal(&map[string]interface{}{
		"url":                manager.URL,
		"path_prefix":        manager.PathPrefix,
		"cache":              manager.Cache,
		"max_lease":          manager.MaxLease,
		"ca_cert":            manager.TLS.CACert,
		"server_name":        manager.TLS.ServerName,
		"auth_backend":       manager.Auth.Backend,
		"auth_max_ttl":       manager.Auth.BackendMaxTTL,
		"auth_retry_max":     manager.Auth.RetryMax,
		"auth_retry_initial": manager.Auth.RetryInitial,
		"health":             health,
	})
}

func (manager VaultManager) IsConfigured() bool {
	return manager.URL != ""
}

func (manager VaultManager) Validate() error {
	_, err := url.Parse(manager.URL)
	if err != nil {
		return fmt.Errorf("invalid URL: %s", err)
	}

	if manager.Auth.ClientToken != "" {
		return nil
	}

	if manager.Auth.Backend != "" {
		return nil
	}

	return errors.New("must configure client token or auth backend")
}

func (manager VaultManager) Health() (*creds.HealthResponse, error) {
	health := &creds.HealthResponse{
		Method: "/v1/sys/health",
	}

	response, err := manager.Client.health()
	if err != nil {
		health.Error = err.Error()
		return health, nil
	}

	health.Response = response
	return health, nil
}

func (manager VaultManager) NewVariablesFactory(logger lager.Logger) (creds.VariablesFactory, error) {
	ra := NewReAuther(manager.Client, manager.Auth.BackendMaxTTL, manager.Auth.RetryInitial, manager.Auth.RetryMax)
	var sr SecretReader = manager.Client
	if manager.Cache {
		sr = NewCache(manager.Client, manager.MaxLease)
	}

	return NewVaultFactory(sr, ra.LoggedIn(), manager.PathPrefix), nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"strings"
	"path"
	"regexp"
	"net/http"
	"net/url"
	"encoding/base64"
	"encoding/binary"
	"github.com/simonz05/godis"
)

const HELP string = `cdrvws(1)                          CDRV.WS                          cdrvws(1)

NAME
    cdrvws: command line url shortener

SYNOPSIS
    <command> | curl -F 'rvw=<-' http://cdrv.ws

EXAMPLE
    ~$ echo "http://ebushpilot.com/images/polarbear_1.jpg" | curl -F 'rvw=<-' http://cdrv.ws
    http://cdrv.ws/2
    ~$ open http://cdrv.ws/2

AUTHOR
    Justin Tulloss <justin.tulloss at gmail>

SEE ALSO
    http://github.com/JustinTulloss/cdrvws

CREDITS
    Inspired by sprunge: http://github.com/rupa/sprunge`

var redis *godis.Client
var trimmer *regexp.Regexp

func main() {
	connectToRedis()
	http.HandleFunc("/", route)
	trimmer, _ = regexp.Compile("A+=$")
	startServer()
}

func encode(id uint64) string {
	bytes := make([]byte, 8)
	binary.PutUvarint(bytes, id)
	encoded := base64.URLEncoding.EncodeToString([]byte(bytes))
	return trimmer.ReplaceAllLiteralString(encoded, "")
}

func createShortUrl(longurl string) (error, string) {
	shortid, err := redis.Incr("urlId")
	if err != nil {
		return err, ""
	}
	shorturl := encode(uint64(shortid))
	if err := redis.Set(shorturl, longurl); err != nil {
		return err, ""
	}
	return nil, shorturl
}

func expand(shorturl string) (error, string) {
	longurl, err := redis.Get(shorturl)
	if err != nil && err.Error() == "Nonexisting key" {
		return nil, ""
	} else if err != nil {
		return err, ""
	}
	return nil, longurl.String()
}

func connectToRedis() {
	rawurl := os.Getenv("REDISTOGO_URL")
	log.Printf("Redis to go url: %s\n", rawurl)
	redisurl := url.URL{
		Host: "localhost:6379",
		User: url.UserPassword("", ""),
	}
	parsedurl := &redisurl
	if rawurl != "" {
		var err error
		parsedurl, err = parsedurl.Parse(rawurl)
		if err != nil {
			log.Fatal("Could not parse redis url", err)
		}
	}
	password, _ := parsedurl.User.Password()
	log.Printf("Connecting to redis: '%s' with password '%s'\n", parsedurl.Host, password)
	redis = godis.New("tcp:" + parsedurl.Host, 0, password)
}

func startServer() {
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	log.Printf("Starting on %s\n", port)
	err := http.ListenAndServe(":" + port, nil)
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}

func route(w http.ResponseWriter, req *http.Request) {
	if req.Method == "GET" {
		if req.URL.String() == "/" {
			handleHome(w, req)
		} else {
			handleExpand(w, req)
		}
	} else if req.Method == "POST" {
		handleShorten(w, req)
	}
}

func handleHome(w http.ResponseWriter, req *http.Request) {
	w.Header().Set("Content-Type", "text/plain")
	fmt.Fprintln(w, HELP)
}

func handleShorten(w http.ResponseWriter, req *http.Request) {
	err, shorturl := createShortUrl(req.FormValue("rvw"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fullurl := url.URL{
		Scheme: "http",
		Host:   req.Host,
		Path:   "/" + shorturl,
	}
	fmt.Fprintln(w, fullurl.String())
}

func handleExpand(w http.ResponseWriter, req *http.Request) {
	shorturl := strings.Trim(req.URL.String(), "/")
	suffix := ""
	if strings.ContainsRune(shorturl, '/') {
		shorturl, suffix = path.Split(shorturl)
		if shorturl == "" {
			shorturl = suffix
			suffix = ""
		}
	}
	shorturl = strings.Trim(shorturl, "/")
	err, longurl := expand(shorturl)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	} else if longurl == "" {
		http.NotFound(w, req)
	} else {
		if !strings.HasSuffix(longurl, "/") {
			longurl += "/"
		}
		http.Redirect(w, req, longurl + suffix, http.StatusMovedPermanently)
	}
}
<commit_msg>run through gofmt<commit_after>package main

import (
	"encoding/base64"
	"encoding/binary"
	"fmt"
	"github.com/simonz05/godis"
	"log"
	"net/http"
	"net/url"
	"os"
	"path"
	"regexp"
	"strings"
)

const HELP string = `cdrvws(1)                          CDRV.WS                          cdrvws(1)

NAME
    cdrvws: command line url shortener

SYNOPSIS
    <command> | curl -F 'rvw=<-' http://cdrv.ws

EXAMPLE
    ~$ echo "http://ebushpilot.com/images/polarbear_1.jpg" | curl -F 'rvw=<-' http://cdrv.ws
    http://cdrv.ws/2
    ~$ open http://cdrv.ws/2

AUTHOR
    Justin Tulloss <justin.tulloss at gmail>

SEE ALSO
    http://github.com/JustinTulloss/cdrvws

CREDITS
    Inspired by sprunge: http://github.com/rupa/sprunge`

var redis *godis.Client
var trimmer *regexp.Regexp

func main() {
	connectToRedis()
	http.HandleFunc("/", route)
	trimmer, _ = regexp.Compile("A+=$")
	startServer()
}

func encode(id uint64) string {
	bytes := make([]byte, 8)
	binary.PutUvarint(bytes, id)
	encoded := base64.URLEncoding.EncodeToString([]byte(bytes))
	return trimmer.ReplaceAllLiteralString(encoded, "")
}

func createShortUrl(longurl string) (error, string) {
	shortid, err := redis.Incr("urlId")
	if err != nil {
		return err, ""
	}
	shorturl := encode(uint64(shortid))
	if err := redis.Set(shorturl, longurl); err != nil {
		return err, ""
	}
	return nil, shorturl
}

func expand(shorturl string) (error, string) {
	longurl, err := redis.Get(shorturl)
	if err != nil && err.Error() == "Nonexisting key" {
		return nil, ""
	} else if err != nil {
		return err, ""
	}
	return nil, longurl.String()
}

func connectToRedis() {
	rawurl := os.Getenv("REDISTOGO_URL")
	log.Printf("Redis to go url: %s\n", rawurl)
	redisurl := url.URL{
		Host: "localhost:6379",
		User: url.UserPassword("", ""),
	}
	parsedurl := &redisurl
	if rawurl != "" {
		var err error
		parsedurl, err = parsedurl.Parse(rawurl)
		if err != nil {
			log.Fatal("Could not parse redis url", err)
		}
	}
	password, _ := parsedurl.User.Password()
	log.Printf("Connecting to redis: '%s' with password '%s'\n", parsedurl.Host, password)
	redis = godis.New("tcp:"+parsedurl.Host, 0, password)
}

func startServer() {
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	log.Printf("Starting on %s\n", port)
	err := http.ListenAndServe(":"+port, nil)
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}

func route(w http.ResponseWriter, req *http.Request) {
	if req.Method == "GET" {
		if req.URL.String() == "/" {
			handleHome(w, req)
		} else {
			handleExpand(w, req)
		}
	} else if req.Method == "POST" {
		handleShorten(w, req)
	}
}

func handleHome(w http.ResponseWriter, req *http.Request) {
	w.Header().Set("Content-Type", "text/plain")
	fmt.Fprintln(w, HELP)
}

func handleShorten(w http.ResponseWriter, req *http.Request) {
	err, shorturl := createShortUrl(req.FormValue("rvw"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fullurl := url.URL{
		Scheme: "http",
		Host:   req.Host,
		Path:   "/" + shorturl,
	}
	fmt.Fprintln(w, fullurl.String())
}

func handleExpand(w http.ResponseWriter, req *http.Request) {
	shorturl := strings.Trim(req.URL.String(), "/")
	suffix := ""
	if strings.ContainsRune(shorturl, '/') {
		shorturl, suffix = path.Split(shorturl)
		if shorturl == "" {
			shorturl = suffix
			suffix = ""
		}
	}
	shorturl = strings.Trim(shorturl, "/")
	err, longurl := expand(shorturl)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	} else if longurl == "" {
		http.NotFound(w, req)
	} else {
		if !strings.HasSuffix(longurl, "/") {
			longurl += "/"
		}
		http.Redirect(w, req, longurl+suffix, http.StatusMovedPermanently)
	}
}
<|endoftext|>


<commit_before>package ebs

import (
	"fmt"

	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/mitchellh/multistep"
	awscommon "github.com/mitchellh/packer/builder/amazon/common"
	"github.com/mitchellh/packer/packer"
)

type stepCreateAMI struct {
	image *ec2.Image
}

func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction {
	config := state.Get("config").(Config)
	ec2conn := state.Get("ec2").(*ec2.EC2)
	instance := state.Get("instance").(*ec2.Instance)
	ui := state.Get("ui").(packer.Ui)

	// Create the image
	ui.Say(fmt.Sprintf("Creating the AMI: %s", config.AMIName))
	createOpts := &ec2.CreateImageInput{
		InstanceId:          instance.InstanceId,
		Name:                &config.AMIName,
		BlockDeviceMappings: config.BlockDevices.BuildAMIDevices(),
	}

	createResp, err := ec2conn.CreateImage(createOpts)
	if err != nil {
		err := fmt.Errorf("Error creating AMI: %s", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	// Set the AMI ID in the state
	ui.Message(fmt.Sprintf("AMI: %s", *createResp.ImageId))
	amis := make(map[string]string)
	amis[*ec2conn.Config.Region] = *createResp.ImageId
	state.Put("amis", amis)

	// Wait for the image to become ready
	stateChange := awscommon.StateChangeConf{
		Pending:   []string{"pending"},
		Target:    "available",
		Refresh:   awscommon.AMIStateRefreshFunc(ec2conn, *createResp.ImageId),
		StepState: state,
	}

	ui.Say("Waiting for AMI to become ready...")
	if _, err := awscommon.WaitForState(&stateChange); err != nil {
		err := fmt.Errorf("Error waiting for AMI: %s", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	imagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{createResp.ImageId}})
	if err != nil {
		err := fmt.Errorf("Error searching for AMI: %s", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}
	s.image = imagesResp.Images[0]

	snapshots := make(map[string][]string)
	for _, blockDeviceMapping := range imagesResp.Images[0].BlockDeviceMappings {
		if blockDeviceMapping.Ebs != nil {
			snapshots[*ec2conn.Config.Region] = append(snapshots[*ec2conn.Config.Region], *blockDeviceMapping.Ebs.SnapshotId)
		}
	}
	state.Put("snapshots", snapshots)

	return multistep.ActionContinue
}

func (s *stepCreateAMI) Cleanup(state multistep.StateBag) {
	if s.image == nil {
		return
	}

	_, cancelled := state.GetOk(multistep.StateCancelled)
	_, halted := state.GetOk(multistep.StateHalted)
	if !cancelled && !halted {
		return
	}

	ec2conn := state.Get("ec2").(*ec2.EC2)
	ui := state.Get("ui").(packer.Ui)

	ui.Say("Deregistering the AMI because cancelation or error...")
	deregisterOpts := &ec2.DeregisterImageInput{ImageId: s.image.ImageId}
	if _, err := ec2conn.DeregisterImage(deregisterOpts); err != nil {
		ui.Error(fmt.Sprintf("Error deregistering AMI, may still be around: %s", err))
		return
	}
}
<commit_msg>builder/amazon: Crashes when multiple EBS vols are used<commit_after>package ebs

import (
	"fmt"

	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/mitchellh/multistep"
	awscommon "github.com/mitchellh/packer/builder/amazon/common"
	"github.com/mitchellh/packer/packer"
)

type stepCreateAMI struct {
	image *ec2.Image
}

func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction {
	config := state.Get("config").(Config)
	ec2conn := state.Get("ec2").(*ec2.EC2)
	instance := state.Get("instance").(*ec2.Instance)
	ui := state.Get("ui").(packer.Ui)

	// Create the image
	ui.Say(fmt.Sprintf("Creating the AMI: %s", config.AMIName))
	createOpts := &ec2.CreateImageInput{
		InstanceId:          instance.InstanceId,
		Name:                &config.AMIName,
		BlockDeviceMappings: config.BlockDevices.BuildAMIDevices(),
	}

	createResp, err := ec2conn.CreateImage(createOpts)
	if err != nil {
		err := fmt.Errorf("Error creating AMI: %s", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	// Set the AMI ID in the state
	ui.Message(fmt.Sprintf("AMI: %s", *createResp.ImageId))
	amis := make(map[string]string)
	amis[*ec2conn.Config.Region] = *createResp.ImageId
	state.Put("amis", amis)

	// Wait for the image to become ready
	stateChange := awscommon.StateChangeConf{
		Pending:   []string{"pending"},
		Target:    "available",
		Refresh:   awscommon.AMIStateRefreshFunc(ec2conn, *createResp.ImageId),
		StepState: state,
	}

	ui.Say("Waiting for AMI to become ready...")
	if _, err := awscommon.WaitForState(&stateChange); err != nil {
		err := fmt.Errorf("Error waiting for AMI: %s", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	imagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{createResp.ImageId}})
	if err != nil {
		err := fmt.Errorf("Error searching for AMI: %s", err)
		state.Put("error", err)
		ui.Error(err.Error())
		return multistep.ActionHalt
	}
	s.image = imagesResp.Images[0]

	snapshots := make(map[string][]string)
	for _, blockDeviceMapping := range imagesResp.Images[0].BlockDeviceMappings {
		if blockDeviceMapping.Ebs != nil && blockDeviceMapping.Ebs.SnapshotId != nil {

			snapshots[*ec2conn.Config.Region] = append(snapshots[*ec2conn.Config.Region], *blockDeviceMapping.Ebs.SnapshotId)
		}
	}
	state.Put("snapshots", snapshots)

	return multistep.ActionContinue
}

func (s *stepCreateAMI) Cleanup(state multistep.StateBag) {
	if s.image == nil {
		return
	}

	_, cancelled := state.GetOk(multistep.StateCancelled)
	_, halted := state.GetOk(multistep.StateHalted)
	if !cancelled && !halted {
		return
	}

	ec2conn := state.Get("ec2").(*ec2.EC2)
	ui := state.Get("ui").(packer.Ui)

	ui.Say("Deregistering the AMI because cancelation or error...")
	deregisterOpts := &ec2.DeregisterImageInput{ImageId: s.image.ImageId}
	if _, err := ec2conn.DeregisterImage(deregisterOpts); err != nil {
		ui.Error(fmt.Sprintf("Error deregistering AMI, may still be around: %s", err))
		return
	}
}
<|endoftext|>


<commit_before><commit_msg>Fixed some data race and optimize lookup code<commit_after><|endoftext|>


<commit_before>package peco

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/nsf/termbox-go"
)

func TestReadRC(t *testing.T) {
	txt := `
{
	"Keymap": {
		"C-j": "peco.Finish",
		"C-x,C-c": "peco.Finish"
	},
	"Style": {
		"Basic": ["on_default", "default"],
		"Selected": ["underline", "on_cyan", "black"],
		"Query": ["yellow", "bold"],
		"Matched": ["cyan", "bold", "on_red"]
	},
	"Prompt": "[peco]"
}
`
	cfg := NewConfig()
	if err := json.Unmarshal([]byte(txt), cfg); err != nil {
		t.Fatalf("Error unmarshaling json: %s", err)
	}
	t.Logf("%#v", cfg)
}

type stringsToStyleTest struct {
	strings []string
	style   *Style
}

func TestStringsToStyle(t *testing.T) {
	tests := []stringsToStyleTest{
		stringsToStyleTest{
			strings: []string{"on_default", "default"},
			style:   &Style{fg: termbox.ColorDefault, bg: termbox.ColorDefault},
		},
		stringsToStyleTest{
			strings: []string{"bold", "on_blue", "yellow"},
			style:   &Style{fg: termbox.ColorYellow | termbox.AttrBold, bg: termbox.ColorBlue},
		},
		stringsToStyleTest{
			strings: []string{"underline", "on_cyan", "black"},
			style:   &Style{fg: termbox.ColorBlack | termbox.AttrUnderline, bg: termbox.ColorCyan},
		},
		stringsToStyleTest{
			strings: []string{"reverse", "on_red", "white"},
			style:   &Style{fg: termbox.ColorWhite | termbox.AttrReverse, bg: termbox.ColorRed},
		},
		stringsToStyleTest{
			strings: []string{"on_bold", "on_magenta", "green"},
			style:   &Style{fg: termbox.ColorGreen, bg: termbox.ColorMagenta | termbox.AttrBold},
		},
	}

	t.Logf("Checking strings -> color mapping...")
	for _, test := range tests {
		t.Logf("    checking %s...", test.strings)
		if a := stringsToStyle(test.strings); *a != *test.style {
			t.Errorf("Expected '%s' to be '%#v', but got '%#v'", test.strings, test.style, a)
		}
	}
}

func TestLocateRcfile(t *testing.T) {
	dir, err := ioutil.TempDir("", "peco-")
	if err != nil {
		t.Fatalf("Failed to create temporary directory: %s", err)
	}

	homedirFunc = func() (string, error) {
		return dir, nil
	}

	expected := []string{
		filepath.Join(dir, "peco"),
		filepath.Join(dir, "1", "peco"),
		filepath.Join(dir, "2", "peco"),
		filepath.Join(dir, "3", "peco"),
		filepath.Join(dir, ".peco"),
	}

	i := 0
	locateRcfileInFunc = func(dir string) (string, error) {
		t.Logf("looking for file in %s", dir)
		if i > len(expected)-1 {
			t.Fatalf("Got %d directories, only have %d", i+1, len(expected))
		}

		if expected[i] != dir {
			t.Errorf("Expected %s, got %s", expected[i], dir)
		}
		i++
		return "", fmt.Errorf("error: Not found")
	}

	os.Setenv("XDG_CONFIG_HOME", dir)
	os.Setenv("XDG_CONFIG_DIRS", strings.Join(
		[]string{
			filepath.Join(dir, "1"),
			filepath.Join(dir, "2"),
			filepath.Join(dir, "3"),
		},
		fmt.Sprintf("%c", filepath.ListSeparator),
	))

	LocateRcfile()
	expected[0] = filepath.Join(dir, ".config", "peco")
	os.Setenv("XDG_CONFIG_HOME", "")
	i = 0
	LocateRcfile()

}
<commit_msg>use Config{}/Init<commit_after>package peco

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/nsf/termbox-go"
)

func TestReadRC(t *testing.T) {
	txt := `
{
	"Keymap": {
		"C-j": "peco.Finish",
		"C-x,C-c": "peco.Finish"
	},
	"Style": {
		"Basic": ["on_default", "default"],
		"Selected": ["underline", "on_cyan", "black"],
		"Query": ["yellow", "bold"],
		"Matched": ["cyan", "bold", "on_red"]
	},
	"Prompt": "[peco]"
}
`
	cfg := Config{}
	cfg.Init()
	if err := json.Unmarshal([]byte(txt), cfg); err != nil {
		t.Fatalf("Error unmarshaling json: %s", err)
	}
	t.Logf("%#v", cfg)
}

type stringsToStyleTest struct {
	strings []string
	style   *Style
}

func TestStringsToStyle(t *testing.T) {
	tests := []stringsToStyleTest{
		stringsToStyleTest{
			strings: []string{"on_default", "default"},
			style:   &Style{fg: termbox.ColorDefault, bg: termbox.ColorDefault},
		},
		stringsToStyleTest{
			strings: []string{"bold", "on_blue", "yellow"},
			style:   &Style{fg: termbox.ColorYellow | termbox.AttrBold, bg: termbox.ColorBlue},
		},
		stringsToStyleTest{
			strings: []string{"underline", "on_cyan", "black"},
			style:   &Style{fg: termbox.ColorBlack | termbox.AttrUnderline, bg: termbox.ColorCyan},
		},
		stringsToStyleTest{
			strings: []string{"reverse", "on_red", "white"},
			style:   &Style{fg: termbox.ColorWhite | termbox.AttrReverse, bg: termbox.ColorRed},
		},
		stringsToStyleTest{
			strings: []string{"on_bold", "on_magenta", "green"},
			style:   &Style{fg: termbox.ColorGreen, bg: termbox.ColorMagenta | termbox.AttrBold},
		},
	}

	t.Logf("Checking strings -> color mapping...")
	for _, test := range tests {
		t.Logf("    checking %s...", test.strings)
		if a := stringsToStyle(test.strings); *a != *test.style {
			t.Errorf("Expected '%s' to be '%#v', but got '%#v'", test.strings, test.style, a)
		}
	}
}

func TestLocateRcfile(t *testing.T) {
	dir, err := ioutil.TempDir("", "peco-")
	if err != nil {
		t.Fatalf("Failed to create temporary directory: %s", err)
	}

	homedirFunc = func() (string, error) {
		return dir, nil
	}

	expected := []string{
		filepath.Join(dir, "peco"),
		filepath.Join(dir, "1", "peco"),
		filepath.Join(dir, "2", "peco"),
		filepath.Join(dir, "3", "peco"),
		filepath.Join(dir, ".peco"),
	}

	i := 0
	locateRcfileInFunc = func(dir string) (string, error) {
		t.Logf("looking for file in %s", dir)
		if i > len(expected)-1 {
			t.Fatalf("Got %d directories, only have %d", i+1, len(expected))
		}

		if expected[i] != dir {
			t.Errorf("Expected %s, got %s", expected[i], dir)
		}
		i++
		return "", fmt.Errorf("error: Not found")
	}

	os.Setenv("XDG_CONFIG_HOME", dir)
	os.Setenv("XDG_CONFIG_DIRS", strings.Join(
		[]string{
			filepath.Join(dir, "1"),
			filepath.Join(dir, "2"),
			filepath.Join(dir, "3"),
		},
		fmt.Sprintf("%c", filepath.ListSeparator),
	))

	LocateRcfile()
	expected[0] = filepath.Join(dir, ".config", "peco")
	os.Setenv("XDG_CONFIG_HOME", "")
	i = 0
	LocateRcfile()

}
<|endoftext|>


<commit_before>package blarg

import (
    "io"
    "net/http"
    "pat"
)

// hello world, the web server
func HelloServer(w http.ResponseWriter, req *http.Request) {
    io.WriteString(w, "hello, "+req.URL.Query().Get(":name")+"!\n")
}

func init() {
    m := pat.New()
    m.Get("/hello/:name", http.HandlerFunc(HelloServer))

    // Register this pat with the default serve mux so that other packages
    // may also be exported. (i.e. /debug/pprof/*)
    http.Handle("/", m)
}
<commit_msg>compiles but doesn't work<commit_after>package blarg

import (
    "net/http"
    "pat"
    "mustache"
    "bytes"
)

// hello world, the web server
func HelloServer(w http.ResponseWriter, req *http.Request, tmpl *mustache.Template) {
    var buf bytes.Buffer;
    tmpl.Render (map[string]string { "c": req.URL.Query().Get(":name")}, &buf)
    buf.WriteTo(w)
}

func init() {
    tmpl,_ := mustache.ParseString("hello {{c}}!\n")
    tmplhdlr:= func(w http.ResponseWriter, req *http.Request) {
      HelloServer(w, req, tmpl)
    }

    m := pat.New()
    m.Get("/hello/:name", http.HandlerFunc(tmplhdlr))

    // Register this pat with the default serve mux so that other packages
    // may also be exported. (i.e. /debug/pprof/*)
    http.Handle("/", m)
}
<|endoftext|>


<commit_before>package main

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

	"labix.org/v2/mgo/bson"

	"github.com/gorilla/mux"
)

var r *mux.Router

func init() {
	r = mux.NewRouter()
	r.HandleFunc("/contacts", getContactsHandler).Methods("GET")
	r.HandleFunc("/contacts/{id}", getContactHandler).Methods("GET")
}

// getContactsHandler returns a json response containing all
// the contacts.
//
// URL: GET /contacts
//
// For example, If there were only two contacts in total,
// GET /contacts and
// would yield the following response.
//
// Response:
// [
//  {
//    "id": "53a14760e3bdea4286000003",
//    "company": "Encom Inc.",
//    "person": "Sam Flynni !",
//    "email": "samflynn@encom.com",
//    "phone": "103-345-456",
//    "skypeid": "sam_flynn",
//    "country": "USA"
//    "slug": "sam-flynn"
//  },
//  {
//    "id": "53a14760e3bdea4286000004",
//    "company": "Encom Inc.",
//    "person": "Kevin Flynn",
//    "email": "kevinflynn@encom.com",
//    "phone": "234-877-988",
//    "skypeid": "kevin_flynn",
//    "country": "USA"
//  }
// ]
func getContactsHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	c, err := GetAllContacts()
	if err != nil {
		log.Fatalf("%s", err)
	}
	enc := json.NewEncoder(w)
	if err = enc.Encode(c); err != nil {
		log.Println(err)
	}
}

// getContactHandler returns json data pertaining to a specific contact.
//
// URL: GET /contacts/{id}
//
// For example,
// GET /contacts/53a15a07e3bdea53d0000002
// Response:
// {
//   "id": "53a15a07e3bdea53d0000002",
//   "company": "Encom Inc.",
//   "person": "Flynn",
//   "email": "flynn@encom.com",
//   "country": "USA"
// }
func getContactHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	vars := mux.Vars(r)
	i := vars["id"]
	id := bson.ObjectIdHex(i)
	c, err := GetContact(id)
	if err != nil {
		log.Fatalf("%s", err)
	}
	enc := json.NewEncoder(w)
	if err = enc.Encode(c); err != nil {
		log.Println(err)
	}
}
<commit_msg>Add POST /contacts handler<commit_after>package main

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

	"labix.org/v2/mgo/bson"

	"github.com/gorilla/mux"
)

var r *mux.Router

func init() {
	r = mux.NewRouter()
	r.HandleFunc("/contacts", getContactsHandler).Methods("GET")
	r.HandleFunc("/contacts", postContactsHandler).Methods("POST")
	r.HandleFunc("/contacts/{id}", getContactHandler).Methods("GET")
}

// getContactsHandler returns a json response containing all
// the contacts.
//
// URL: GET /contacts
//
// For example, If there were only two contacts in total,
// GET /contacts and
// would yield the following response.
//
// Response:
// [
//  {
//    "id": "53a14760e3bdea4286000003",
//    "company": "Encom Inc.",
//    "person": "Sam Flynni !",
//    "email": "samflynn@encom.com",
//    "phone": "103-345-456",
//    "skypeid": "sam_flynn",
//    "country": "USA"
//    "slug": "sam-flynn"
//  },
//  {
//    "id": "53a14760e3bdea4286000004",
//    "company": "Encom Inc.",
//    "person": "Kevin Flynn",
//    "email": "kevinflynn@encom.com",
//    "phone": "234-877-988",
//    "skypeid": "kevin_flynn",
//    "country": "USA"
//  }
// ]
func getContactsHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	c, err := GetAllContacts()
	if err != nil {
		log.Fatalf("%s", err)
	}
	enc := json.NewEncoder(w)
	if err = enc.Encode(c); err != nil {
		log.Println(err)
	}
}

// postContactsHandler creates a new contact in the database.
// URL: POST /contacts
// Request:
// {
//   "company": "Encom Inc.",
//   "person": "Sam Flynn",
//   "email": "samflynn@encom.com",
//   "phone": "103-345-456",
//   "skypeid": "sam_flynn",
//   "country": "USA"
// }
// Response: HTTP 200
func postContactsHandler(w http.ResponseWriter, r *http.Request) {
	decoder := json.NewDecoder(r.Body)
	var c contact
	err := decoder.Decode(&c)
	if err != nil {
		log.Fatalf("%s", err)
	}
	_, err = NewContact(c.Company, c.Person, c.Email, c.Phone, c.SkypeId, c.Country)
	if err != nil {
		log.Fatalf("%s", err)
	}
}

// getContactHandler returns json data pertaining to a specific contact.
//
// URL: GET /contacts/{id}
//
// For example,
// GET /contacts/53a15a07e3bdea53d0000002
// Response:
// {
//   "id": "53a15a07e3bdea53d0000002",
//   "company": "Encom Inc.",
//   "person": "Flynn",
//   "email": "flynn@encom.com",
//   "country": "USA"
// }
func getContactHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	vars := mux.Vars(r)
	i := vars["id"]
	id := bson.ObjectIdHex(i)
	c, err := GetContact(id)
	if err != nil {
		log.Fatalf("%s", err)
	}
	enc := json.NewEncoder(w)
	if err = enc.Encode(c); err != nil {
		log.Println(err)
	}
}
<|endoftext|>


<commit_before>package golog

import (
	"fmt"
	"time"
)

const (
	INFO = iota
	WARNING
	ERROR
	FATAL
)

type LevelLogger interface {
	Log(level int, vals ...interface{})
	Logf(level int, f string, vals ...interface{})
	Logc(level int, closure func() string)
}

type levelLoggerImpl struct {
	FailLogger
}

func NewLevelLogger(f FailLogger) LevelLogger {
	return &levelLoggerImpl{f}
}

func NewDefaultLevelLogger() LevelLogger {
	return &levelLoggerImpl{NewDefaultFailLogger()}
}

// Formats the message with metadata. The format is:
// LEVEL HH:MM:SS:NANOSC LOC] MESSAGE
func makeLogClosure(level int, msg func() string) func() *LogMessage {
	// Evaluate this early.
	ns := time.Nanoseconds()

	return func() *LogMessage {
		return &LogMessage{
			Level:       level,
			Message:     msg(),
			Nanoseconds: ns,
		}
	}
}

func (l *levelLoggerImpl) logCommon(level int, closure func() string) {
	l.Log(level, makeLogClosure(level, closure))
}

func (l *levelLoggerImpl) Log(level int, msg ...interface{}) {
	l.logCommon(level, func() string { return fmt.Sprint(msg...) })
}

func (l *levelLoggerImpl) Logf(level int, f string, msg ...interface{}) {
	l.logCommon(level, func() string { return fmt.Sprintf(f, msg...) })
}

func (l *levelLoggerImpl) Logc(level int, closure func() string) {
	l.logCommon(level, closure)
}
<commit_msg>Remove incorrect comment<commit_after>package golog

import (
	"fmt"
	"time"
)

const (
	INFO = iota
	WARNING
	ERROR
	FATAL
)

type LevelLogger interface {
	Log(level int, vals ...interface{})
	Logf(level int, f string, vals ...interface{})
	Logc(level int, closure func() string)
}

type levelLoggerImpl struct {
	FailLogger
}

func NewLevelLogger(f FailLogger) LevelLogger {
	return &levelLoggerImpl{f}
}

func NewDefaultLevelLogger() LevelLogger {
	return &levelLoggerImpl{NewDefaultFailLogger()}
}

func makeLogClosure(level int, msg func() string) func() *LogMessage {
	// Evaluate this early.
	ns := time.Nanoseconds()

	return func() *LogMessage {
		return &LogMessage{
			Level:       level,
			Message:     msg(),
			Nanoseconds: ns,
		}
	}
}

func (l *levelLoggerImpl) logCommon(level int, closure func() string) {
	l.Log(level, makeLogClosure(level, closure))
}

func (l *levelLoggerImpl) Log(level int, msg ...interface{}) {
	l.logCommon(level, func() string { return fmt.Sprint(msg...) })
}

func (l *levelLoggerImpl) Logf(level int, f string, msg ...interface{}) {
	l.logCommon(level, func() string { return fmt.Sprintf(f, msg...) })
}

func (l *levelLoggerImpl) Logc(level int, closure func() string) {
	l.logCommon(level, closure)
}
<|endoftext|>


<commit_before>package board

import (
    "math/rand"
)

// Board size
const (
    X = 4
    Y = 4
)

// Direction
type Direction int32

// Direction
const (
    LEFT  = iota
    UP    = iota
    RIGHT = iota
    DOWN  = iota
)

var (
    DIRECTIONS = map[int]int{
        LEFT:  -1,
        UP:    -1,
        RIGHT: 1,
        DOWN:  1,
    }
)

type Board struct {
    Cells [Y][X]int

    goal   int
    points int
}

func New() Board {
    return Board{
        Cells: [Y][X]int {
            {0, 3, 0, 0},
            {1, 0, 2, 0},
            {2, 1, 1, 0},
            {0, 6, 5, 0},
        },
        goal:   2048,
        points: 0,
    }
}

func (b* Board) emptyRow(n int) []int {
    row := []int{0, 0, 0, 0}
    return row[0:n]
}

func (b* Board) moveLine(row [4]int, direction int) [4]int {
    var empty []int
    var nonEmpty []int
    var result [4]int

    for i := 0; i < len(row); i++ {
        if row[i] == 0 { continue }

        nonEmpty = append(nonEmpty, row[i])
    }

    empty = b.emptyRow(X-len(nonEmpty))

    // Copy merges to result array
    if direction == -1 {
        copy(result[:], append(nonEmpty, empty...)[0:4])
    } else {
        copy(result[:], append(empty, nonEmpty...)[0:4])
    }

    return result
}

// Is a given line mergeable
func canMergeLine(row [4]int) bool {
    for i := 0; i < len(row); i++ {
        // Previous
        if i > 0 && row[i] == row[i-1] {
            return true
        }

        // Next
        if i+1 < len(row) && row[i] == row[i+1] {
            return true
        }
    }

    return false
}

func (b* Board) mergeLine(row [4]int, direction int) [4]int {
    var newRow [4]int
    var start, end, pos, nextpos int

    if direction == -1 {
        end = 0
        start = len(row) - 1
    } else {
        start = 0
        end = len(row) - 1
    }

    pos = start
    for i := 0; i < len(row); i++  {
        nextpos = pos + direction

        // Don't merge empty cells
        // or already merged cells
        if row[pos] == 0 || newRow[pos] != 0 {
            pos = nextpos
            continue
        }

        // Next cell is identical
        if pos != end && row[pos] == row[nextpos] {
            var value = row[pos] + 1
            newRow[pos] = 0
            newRow[nextpos] = value
        } else {
            newRow[pos] = row[pos]
        }

        // Update position
        pos = nextpos
    }

    return newRow
}

func (b* Board) setRow(y int, row [4]int) {
    for x := 0; x < X; x++ {
        b.Cells[y][x] = row[x]
    }
}

func (b* Board) getRow(y int) [4]int {
    return b.Cells[y]
}

func (b* Board) setCol(x int, row [4]int) {
    for y := 0; y < Y; y++ {
        b.Cells[y][x] = row[y]
    }
}

func (b* Board) getCol(x int) [4]int {
    var a [4]int

    for y := 0; y < Y; y++ {
        a[y] = b.Cells[y][x]
    }

    return a
}

func (b* Board) moveRows(d int) {
    for y := 0; y < Y; y++ {
        // Get new row by moving and merging previous row
        var newRow = b.moveLine(
            b.mergeLine(
                b.moveLine(
                    b.getRow(y),
                    d,
                ),
                d,
            ),
            d,
        )

        // Set new row
        b.setRow(y, newRow)
    }
}

func (b* Board) moveCols(d int) {
    for x := 0; x < X; x++ {
        // Get new col by moving and merging previous col
        var newCol = b.moveLine(
            b.mergeLine(
                b.moveLine(
                    b.getCol(x),
                    d,
                ),
                d,
            ),
            d,
        )

        // Set new col
        b.setCol(x, newCol)
    }
}

func (b *Board) emptyCells() [][2]int {
    var arr [][2]int;

    for y := 0; y < Y; y++ {
    for x := 0; x < X; x++ {
        if b.Cells[y][x] == 0 {
            var cell = [2]int {x, y};
            arr = append(arr, cell);
        }
    }}

    return arr;
}

func (b *Board) IsFull() bool {
    return len(b.emptyCells()) == 0;
}

func (b *Board) AddTile() {
    cells := b.emptyCells()
    cell := cells[rand.Int() % len(cells)]
    x := cell[0]
    y := cell[1]

    // Set cell randomly to 1 or 2
    b.Cells[y][x] = (rand.Int() % 2) + 1
}

func (b *Board) Playable() bool {
    if !b.IsFull() {
        return true
    }

    for y := 0; y < Y; y++ {
        if canMergeLine(b.getRow(y)) {
            return true
        }
    }

    for x := 0; x < X; x++ {
        if canMergeLine(b.getCol(x)) {
            return true
        }
    }

    return false
}

func (b *Board) Values() []int {
    var arr []int

    for y := 0; y < Y; y++ {
    for x := 0; x < X; x++ {
        if b.Cells[y][x] != 0 {
            arr = append(arr, b.Cells[y][x])
        }
    }}
    return arr
}

// Move board in a given direction
func (b* Board) Move(d Direction) {
    switch d {
    case UP:
        b.moveCols(DIRECTIONS[UP])
    case DOWN:
        b.moveCols(DIRECTIONS[DOWN])

    case LEFT:
        b.moveRows(DIRECTIONS[LEFT])
    case RIGHT:
        b.moveRows(DIRECTIONS[RIGHT])
    }

    // Add new tile if not empty
    if !b.IsFull() {
        b.AddTile()
    }
}
<commit_msg>Start Cells with only two random tiles<commit_after>package board

import (
    "time"
    "math/rand"
)

// Board size
const (
    X = 4
    Y = 4
)

// Direction
type Direction int32

// Direction
const (
    LEFT  = iota
    UP    = iota
    RIGHT = iota
    DOWN  = iota
)

var (
    DIRECTIONS = map[int]int{
        LEFT:  -1,
        UP:    -1,
        RIGHT: 1,
        DOWN:  1,
    }
)

type Board struct {
    Cells [Y][X]int

    goal   int
    points int
}

func New() Board {
    board := Board{
        /*
        Cells: [Y][X]int {
            {0, 3, 0, 0},
            {1, 0, 2, 0},
            {2, 1, 1, 0},
            {0, 6, 5, 0},
        },
        */
        Cells: [Y][X]int {
            {0, 0, 0, 0},
            {0, 0, 0, 0},
            {0, 0, 0, 0},
            {0, 0, 0, 0},
        },
        goal:   2048,
        points: 0,
    }

    // Seed rng
    rand.Seed(time.Now().Unix())

    // Add two random tiles
    board.AddTile()
    board.AddTile()

    return board
}

func (b* Board) emptyRow(n int) []int {
    row := []int{0, 0, 0, 0}
    return row[0:n]
}

func (b* Board) moveLine(row [4]int, direction int) [4]int {
    var empty []int
    var nonEmpty []int
    var result [4]int

    for i := 0; i < len(row); i++ {
        if row[i] == 0 { continue }

        nonEmpty = append(nonEmpty, row[i])
    }

    empty = b.emptyRow(X-len(nonEmpty))

    // Copy merges to result array
    if direction == -1 {
        copy(result[:], append(nonEmpty, empty...)[0:4])
    } else {
        copy(result[:], append(empty, nonEmpty...)[0:4])
    }

    return result
}

// Is a given line mergeable
func canMergeLine(row [4]int) bool {
    for i := 0; i < len(row); i++ {
        // Previous
        if i > 0 && row[i] == row[i-1] {
            return true
        }

        // Next
        if i+1 < len(row) && row[i] == row[i+1] {
            return true
        }
    }

    return false
}

func (b* Board) mergeLine(row [4]int, direction int) [4]int {
    var newRow [4]int
    var start, end, pos, nextpos int

    if direction == -1 {
        end = 0
        start = len(row) - 1
    } else {
        start = 0
        end = len(row) - 1
    }

    pos = start
    for i := 0; i < len(row); i++  {
        nextpos = pos + direction

        // Don't merge empty cells
        // or already merged cells
        if row[pos] == 0 || newRow[pos] != 0 {
            pos = nextpos
            continue
        }

        // Next cell is identical
        if pos != end && row[pos] == row[nextpos] {
            var value = row[pos] + 1
            newRow[pos] = 0
            newRow[nextpos] = value
        } else {
            newRow[pos] = row[pos]
        }

        // Update position
        pos = nextpos
    }

    return newRow
}

func (b* Board) setRow(y int, row [4]int) {
    for x := 0; x < X; x++ {
        b.Cells[y][x] = row[x]
    }
}

func (b* Board) getRow(y int) [4]int {
    return b.Cells[y]
}

func (b* Board) setCol(x int, row [4]int) {
    for y := 0; y < Y; y++ {
        b.Cells[y][x] = row[y]
    }
}

func (b* Board) getCol(x int) [4]int {
    var a [4]int

    for y := 0; y < Y; y++ {
        a[y] = b.Cells[y][x]
    }

    return a
}

func (b* Board) moveRows(d int) {
    for y := 0; y < Y; y++ {
        // Get new row by moving and merging previous row
        var newRow = b.moveLine(
            b.mergeLine(
                b.moveLine(
                    b.getRow(y),
                    d,
                ),
                d,
            ),
            d,
        )

        // Set new row
        b.setRow(y, newRow)
    }
}

func (b* Board) moveCols(d int) {
    for x := 0; x < X; x++ {
        // Get new col by moving and merging previous col
        var newCol = b.moveLine(
            b.mergeLine(
                b.moveLine(
                    b.getCol(x),
                    d,
                ),
                d,
            ),
            d,
        )

        // Set new col
        b.setCol(x, newCol)
    }
}

func (b *Board) emptyCells() [][2]int {
    var arr [][2]int;

    for y := 0; y < Y; y++ {
    for x := 0; x < X; x++ {
        if b.Cells[y][x] == 0 {
            var cell = [2]int {x, y};
            arr = append(arr, cell);
        }
    }}

    return arr;
}

func (b *Board) IsFull() bool {
    return len(b.emptyCells()) == 0;
}

func (b *Board) AddTile() {
    cells := b.emptyCells()
    cell := cells[rand.Int() % len(cells)]
    x := cell[0]
    y := cell[1]

    // Set cell randomly to 1 or 2
    b.Cells[y][x] = (rand.Int() % 2) + 1
}

func (b *Board) Playable() bool {
    if !b.IsFull() {
        return true
    }

    for y := 0; y < Y; y++ {
        if canMergeLine(b.getRow(y)) {
            return true
        }
    }

    for x := 0; x < X; x++ {
        if canMergeLine(b.getCol(x)) {
            return true
        }
    }

    return false
}

func (b *Board) Values() []int {
    var arr []int

    for y := 0; y < Y; y++ {
    for x := 0; x < X; x++ {
        if b.Cells[y][x] != 0 {
            arr = append(arr, b.Cells[y][x])
        }
    }}
    return arr
}

// Move board in a given direction
func (b* Board) Move(d Direction) {
    switch d {
    case UP:
        b.moveCols(DIRECTIONS[UP])
    case DOWN:
        b.moveCols(DIRECTIONS[DOWN])

    case LEFT:
        b.moveRows(DIRECTIONS[LEFT])
    case RIGHT:
        b.moveRows(DIRECTIONS[RIGHT])
    }

    // Add new tile if not empty
    if !b.IsFull() {
        b.AddTile()
    }
}
<|endoftext|>


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

package daemonset

import (
	"context"
	"log"

	"github.com/kubernetes/dashboard/src/app/backend/errors"
	metricapi "github.com/kubernetes/dashboard/src/app/backend/integration/metric/api"
	"github.com/kubernetes/dashboard/src/app/backend/resource/common"
	"github.com/kubernetes/dashboard/src/app/backend/resource/dataselect"
	"github.com/kubernetes/dashboard/src/app/backend/resource/event"
	"github.com/kubernetes/dashboard/src/app/backend/resource/pod"
	api "k8s.io/api/core/v1"
	metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	k8sClient "k8s.io/client-go/kubernetes"
)

// GetDaemonSetPods return list of pods targeting daemon set.
func GetDaemonSetPods(client k8sClient.Interface, metricClient metricapi.MetricClient,
	dsQuery *dataselect.DataSelectQuery, daemonSetName, namespace string) (*pod.PodList, error) {
	log.Printf("Getting replication controller %s pods in namespace %s", daemonSetName, namespace)

	pods, err := getRawDaemonSetPods(client, daemonSetName, namespace)
	if err != nil {
		return pod.EmptyPodList, err
	}

	events, err := event.GetPodsEvents(client, namespace, pods)
	nonCriticalErrors, criticalError := errors.HandleError(err)
	if criticalError != nil {
		return nil, criticalError
	}

	podList := pod.ToPodList(pods, events, nonCriticalErrors, dsQuery, metricClient)
	return &podList, nil
}

// Returns array of api pods targeting daemon set with given name.
func getRawDaemonSetPods(client k8sClient.Interface, daemonSetName, namespace string) ([]api.Pod, error) {
	daemonSet, err := client.AppsV1().DaemonSets(namespace).Get(context.TODO(), daemonSetName, metaV1.GetOptions{})
	if err != nil {
		return nil, err
	}

	channels := &common.ResourceChannels{
		PodList: common.GetPodListChannel(client, common.NewSameNamespaceQuery(namespace), 1),
	}

	podList := <-channels.PodList.List
	if err := <-channels.PodList.Error; err != nil {
		return nil, err
	}

	matchingPods := common.FilterPodsByControllerRef(daemonSet, podList.Items)
	return matchingPods, nil
}
<commit_msg>Bring the daemonset label when querying to reduce the pressure on the api server caused by daemonset related pod queries (#5761)<commit_after>// Copyright 2017 The Kubernetes Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package daemonset

import (
	"context"
	"log"

	"github.com/kubernetes/dashboard/src/app/backend/errors"
	metricapi "github.com/kubernetes/dashboard/src/app/backend/integration/metric/api"
	"github.com/kubernetes/dashboard/src/app/backend/resource/common"
	"github.com/kubernetes/dashboard/src/app/backend/resource/dataselect"
	"github.com/kubernetes/dashboard/src/app/backend/resource/event"
	"github.com/kubernetes/dashboard/src/app/backend/resource/pod"
	api "k8s.io/api/core/v1"
	metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	k8sClient "k8s.io/client-go/kubernetes"
)

// GetDaemonSetPods return list of pods targeting daemon set.
func GetDaemonSetPods(client k8sClient.Interface, metricClient metricapi.MetricClient,
	dsQuery *dataselect.DataSelectQuery, daemonSetName, namespace string) (*pod.PodList, error) {
	log.Printf("Getting replication controller %s pods in namespace %s", daemonSetName, namespace)

	pods, err := getRawDaemonSetPods(client, daemonSetName, namespace)
	if err != nil {
		return pod.EmptyPodList, err
	}

	events, err := event.GetPodsEvents(client, namespace, pods)
	nonCriticalErrors, criticalError := errors.HandleError(err)
	if criticalError != nil {
		return nil, criticalError
	}

	podList := pod.ToPodList(pods, events, nonCriticalErrors, dsQuery, metricClient)
	return &podList, nil
}

// Returns array of api pods targeting daemon set with given name.
func getRawDaemonSetPods(client k8sClient.Interface, daemonSetName, namespace string) ([]api.Pod, error) {
	daemonSet, err := client.AppsV1().DaemonSets(namespace).Get(context.TODO(), daemonSetName, metaV1.GetOptions{})
	if err != nil {
		return nil, err
	}

	selector, err := metaV1.LabelSelectorAsSelector(daemonSet.Spec.Selector)
	if err != nil {
		return nil, err
	}
	options := metaV1.ListOptions{LabelSelector: selector.String()}

	channels := &common.ResourceChannels{
		PodList: common.GetPodListChannelWithOptions(client, common.NewSameNamespaceQuery(namespace), options, 1),
	}

	podList := <-channels.PodList.List
	if err := <-channels.PodList.Error; err != nil {
		return nil, err
	}

	matchingPods := common.FilterPodsByControllerRef(daemonSet, podList.Items)
	return matchingPods, nil
}
<|endoftext|>


<commit_before>/*
Testing out boltdb for the following use case:

* Load several million key/value pairs in as quickly as possible
* Data forms a graph, that will be searched using A*
* Load once, search many times
* Data is too big to be all be in memory

Issues so far:

* Writing to boltdb involves 2 writes to disk, so performance is terrible if writes aren't batched

Ideas to try out:

* Built test suite with a regular map  [DONE]
* Swap in boltdb backend and compare.  [DONE]
* Try out boltdb transaction coalescer [DONE]
  https://github.com/boltdb/coalescer
* Rerun on SSD                         [DONE]
* Separate test to measure how long it takes to read all the values back.

Findings:

* Overhead of db.Update for single key/value write is massive.
  At 1 million keys per db.Update overhead  still 5x slower

coalescer -- Not working well even on an SSD, but works. Go back to home built solution.
 (Found issue with coalescer logic)

*/

package main

import (
	"fmt"
	"github.com/boltdb/bolt"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

// Interface used for testing
type db interface {
	Writer(key, value string)
	Flush()
}

type mapType struct {
	db map[string]string
}

func (m *mapType) Writer(key, value string) {
	m.db[key] = value
}

func (m *mapType) Flush() {
}

func NewMapType() *mapType {
	m := mapType{
		db: make(map[string]string),
	}
	return &m
}

type boltType struct {
	Db        *bolt.DB
	buffer    map[string]string
	batchSize int
}

func NewBoltType(limit int) *boltType {
	db := prepBolt(limit)
	b := boltType{
		Db:     db,
		buffer: make(map[string]string),
		// If batch is too things slow down
		batchSize: 10000,
	}
	return &b
}

func (mybolt *boltType) Writer(key, value string) {
	mybolt.buffer[key] = value
	if len(mybolt.buffer) > mybolt.batchSize {
		mybolt.Flush()
	}
}

func (mybolt *boltType) Flush() {
	err := mybolt.Db.Update(func(tx *bolt.Tx) error {
		//var err error
		b := tx.Bucket(bucket)
		for key, value := range mybolt.buffer {
			err := b.Put([]byte(key), []byte(value))
			delete(mybolt.buffer, key)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}
	mybolt.Db.NoSync = true
}

var bucket = []byte("MyBucket")

func prepBolt(limit int) *bolt.DB {
	path := "my.db"
	// make sure we start from a fresh file every time
	os.Remove(path)
	db, err := bolt.Open(path, 0600, nil)
	if err != nil {
		log.Fatal(err)
	}

	// create bucket
	err = db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists(bucket)
		if err != nil {
			return fmt.Errorf("create bucket: %s", err)
		}
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}

	return db
}

func hellobolt() {
	db := prepBolt(1)
	defer db.Close()

	err := db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket(bucket)
		err := b.Put([]byte("answer"), []byte("42"))
		return err
	})
	if err != nil {
		log.Fatal(err)
	}

	err = db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(bucket)
		v := b.Get([]byte("answer"))
		fmt.Printf("value: %s\n", v)
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}
}

func keyValue(i int) (key, value string) {
	key = strconv.Itoa(i)
	value = strings.Repeat(key, 5)
	return key, value
}

func writeTest(myDb db, size int) (duration time.Duration) {
	start := time.Now()
	var key string
	var value string
	for i := 0; i < size; i++ {
		key, value = keyValue(i)
		myDb.Writer(key, value)
	}
	myDb.Flush()
	return time.Since(start)
}

func main() {
	hellobolt()

	size := 500000
	fmt.Printf("number of entries: %d\n", size)

	mapDb := NewMapType()
	mapTime := writeTest(mapDb, size)
	fmt.Printf("Map Test took: %s\n", mapTime)

	mapBolt := NewBoltType(size / 5)
	defer mapBolt.Db.Close()

	boltTime := writeTest(mapBolt, size)
	fmt.Printf("Bolt Test took: %s\n", boltTime)

	// sanity check
	mapBolt.Db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(bucket)
		key, value := keyValue(size - 1)
		storedValue := b.Get([]byte(key))
		if value != string(storedValue) {
			fmt.Printf("something went wrong, with the stored value: %s\n", storedValue)
		}
		return nil
	})

	fmt.Printf("bolt/map: %1.1fX\n",
		float64(boltTime.Nanoseconds())/float64(mapTime.Nanoseconds()))

}
<commit_msg>Add crude read test<commit_after>/*
Testing out boltdb for the following use case:

* Load several million key/value pairs in as quickly as possible
* Data forms a graph, that will be searched using A*
* Load once, search many times
* Data is too big to be all be in memory

Issues so far:

* Writing to boltdb involves 2 writes to disk, so performance is terrible if writes aren't batched

Ideas to try out:

* Built test suite with a regular map  [DONE]
* Swap in boltdb backend and compare.  [DONE]
* Try out boltdb transaction coalescer [DONE]
  https://github.com/boltdb/coalescer
* Rerun on SSD                         [DONE]
* Separate test to measure how long it takes to read all the values back. [DONE]

Findings:

* Overhead of db.Update for single key/value write is massive.
  At 1 million keys per db.Update overhead  still 5x slower

coalescer -- Not working well even on an SSD, but works. Go back to home built solution.
 (Found issue with coalescer logic)

* Reading back, as expected is faster then writing.

number of entries: 5 Million
Write map test took: 5.528 s
Write bolt test took: 38.55 s
Write bolt/map: 7.0X
Read bolt test took: 15.99 s

bolt db file size: ~1GB

*/

package main

import (
	"fmt"
	"github.com/boltdb/bolt"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

// Interface used for testing
type db interface {
	Writer(key, value string)
	Flush()
}

type mapType struct {
	db map[string]string
}

func (m *mapType) Writer(key, value string) {
	m.db[key] = value
}

func (m *mapType) Flush() {
}

func NewMapType() *mapType {
	m := mapType{
		db: make(map[string]string),
	}
	return &m
}

type boltType struct {
	Db        *bolt.DB
	buffer    map[string]string
	batchSize int
}

func NewBoltType(limit int) *boltType {
	db := prepBolt(limit)
	b := boltType{
		Db:     db,
		buffer: make(map[string]string),
		// If batch is too things slow down
		batchSize: 10000,
	}
	return &b
}

func (mybolt *boltType) Writer(key, value string) {
	mybolt.buffer[key] = value
	if len(mybolt.buffer) > mybolt.batchSize {
		mybolt.Flush()
	}
}

func (mybolt *boltType) Flush() {
	err := mybolt.Db.Update(func(tx *bolt.Tx) error {
		//var err error
		b := tx.Bucket(bucket)
		for key, value := range mybolt.buffer {
			err := b.Put([]byte(key), []byte(value))
			delete(mybolt.buffer, key)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}
	mybolt.Db.NoSync = true
}

var bucket = []byte("MyBucket")

func prepBolt(limit int) *bolt.DB {
	path := "my.db"
	// make sure we start from a fresh file every time
	os.Remove(path)
	db, err := bolt.Open(path, 0600, nil)
	if err != nil {
		log.Fatal(err)
	}

	// create bucket
	err = db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists(bucket)
		if err != nil {
			return fmt.Errorf("create bucket: %s", err)
		}
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}

	return db
}

func hellobolt() {
	db := prepBolt(1)
	defer db.Close()

	err := db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket(bucket)
		err := b.Put([]byte("answer"), []byte("42"))
		return err
	})
	if err != nil {
		log.Fatal(err)
	}

	err = db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(bucket)
		v := b.Get([]byte("answer"))
		fmt.Printf("value: %s\n", v)
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}
}

func keyValue(i int) (key, value string) {
	key = strconv.Itoa(i)
	value = strings.Repeat(key, 5)
	return key, value
}

func writeTest(myDb db, size int) (duration time.Duration) {
	start := time.Now()
	var key string
	var value string
	for i := 0; i < size; i++ {
		key, value = keyValue(i)
		myDb.Writer(key, value)
	}
	myDb.Flush()
	return time.Since(start)
}

func main() {
	hellobolt()

	size := 5000000
	fmt.Printf("number of entries: %d\n", size)

	mapDb := NewMapType()
	mapTime := writeTest(mapDb, size)
	fmt.Printf("Write map test took: %s\n", mapTime)

	mapBolt := NewBoltType(size / 5)
	defer mapBolt.Db.Close()
	boltTime := writeTest(mapBolt, size)
	fmt.Printf("Write bolt test took: %s\n", boltTime)

	fmt.Printf("Write bolt/map: %1.1fX\n",
		float64(boltTime.Nanoseconds())/float64(mapTime.Nanoseconds()))

	// sanity check, read everything
	start := time.Now()
	mapBolt.Db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(bucket)
		for i := 0; i < size; i++ {
			key, value := keyValue(i)
			storedValue := b.Get([]byte(key))
			if value != string(storedValue) {
				fmt.Printf("something went wrong, with the stored value: %s\n", storedValue)
				return nil
			}
		}
		return nil
	})
	fmt.Printf("Read bolt test took: %s\n", time.Since(start))

}
<|endoftext|>


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

package ec2

import (
	"launchpad.net/goamz/aws"

	"launchpad.net/juju-core/environs/instances"
)

// Type of virtualisation used.
var (
	paravirtual = "pv"
	hvm         = "hvm"
)

// all instance types can run amd64 images, and some can also run i386 ones.
var (
	amd64 = []string{"amd64"}
	both  = []string{"amd64", "i386"}
)

// allRegions is defined here to allow tests to override the content.
var allRegions = aws.Regions

// TODO(bug 1212688): the RootDisk defaults to 8G currently until the
// referenced bug is fixed, at which point RootDisk can be set to nil and the
// specified constraint can be passed through via block device mapping to
// request an appropriate resize of the root disk.

// allInstanceTypes holds the relevant attributes of every known
// instance type.
var allInstanceTypes = []instances.InstanceType{
	{ // First generation.
		Name:     "m1.small",
		Arches:   both,
		CpuCores: 1,
		CpuPower: instances.CpuPower(100),
		Mem:      1740,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m1.medium",
		Arches:   both,
		CpuCores: 1,
		CpuPower: instances.CpuPower(200),
		Mem:      3840,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m1.large",
		Arches:   amd64,
		CpuCores: 2,
		CpuPower: instances.CpuPower(400),
		Mem:      7680,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m1.xlarge",
		Arches:   amd64,
		CpuCores: 4,
		CpuPower: instances.CpuPower(800),
		Mem:      15360,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // Second generation.
		Name:     "m3.xlarge",
		Arches:   amd64,
		CpuCores: 4,
		CpuPower: instances.CpuPower(1300),
		Mem:      15360,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m3.2xlarge",
		Arches:   amd64,
		CpuCores: 8,
		CpuPower: instances.CpuPower(2600),
		Mem:      30720,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // Micro.
		Name:     "t1.micro",
		Arches:   both,
		CpuCores: 1,
		CpuPower: instances.CpuPower(20),
		Mem:      613,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // High-Memory.
		Name:     "m2.xlarge",
		Arches:   amd64,
		CpuCores: 2,
		CpuPower: instances.CpuPower(650),
		Mem:      17408,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m2.2xlarge",
		Arches:   amd64,
		CpuCores: 4,
		CpuPower: instances.CpuPower(1300),
		Mem:      34816,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m2.4xlarge",
		Arches:   amd64,
		CpuCores: 8,
		CpuPower: instances.CpuPower(2600),
		Mem:      69632,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // High-CPU.
		Name:     "c1.medium",
		Arches:   both,
		CpuCores: 2,
		CpuPower: instances.CpuPower(500),
		Mem:      1740,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "c1.xlarge",
		Arches:   amd64,
		CpuCores: 8,
		CpuPower: instances.CpuPower(2000),
		Mem:      7168,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // Cluster compute.
		Name:     "cc1.4xlarge",
		Arches:   amd64,
		CpuCores: 8,
		CpuPower: instances.CpuPower(3350),
		Mem:      23552,
		RootDisk: 8192,
		VType:    &hvm,
	}, {
		Name:     "cc2.8xlarge",
		Arches:   amd64,
		CpuCores: 16,
		CpuPower: instances.CpuPower(8800),
		Mem:      61952,
		RootDisk: 8192,
		VType:    &hvm,
	},
	{ // High Memory cluster.
		Name:     "cr1.8xlarge",
		Arches:   amd64,
		CpuCores: 16,
		CpuPower: instances.CpuPower(8800),
		Mem:      249856,
		RootDisk: 8192,
		VType:    &hvm,
	},
	{ // Cluster GPU.
		Name:     "cg1.4xlarge",
		Arches:   amd64,
		CpuCores: 8,
		CpuPower: instances.CpuPower(3350),
		Mem:      22528,
		RootDisk: 8192,
		VType:    &hvm,
	},
	{ // High I/O.
		Name:     "hi1.4xlarge",
		Arches:   amd64,
		CpuCores: 16,
		CpuPower: instances.CpuPower(3500),
		Mem:      61952,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // High storage.
		Name:     "hs1.8xlarge",
		Arches:   amd64,
		CpuCores: 16,
		CpuPower: instances.CpuPower(3500),
		Mem:      119808,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
}

type instanceTypeCost map[string]uint64
type regionCosts map[string]instanceTypeCost

// allRegionCosts holds the cost in USDe-3/hour for each available instance
// type in each region.
var allRegionCosts = regionCosts{
	"ap-northeast-1": { // Tokyo.
		"m1.small":   88,
		"m1.medium":  175,
		"m1.large":   350,
		"m1.xlarge":  700,
		"m3.xlarge":  760,
		"m3.2xlarge": 1520,
		"t1.micro":   27,
		"m2.xlarge":  505,
		"m2.2xlarge": 1010,
		"m2.4xlarge": 2020,
		"c1.medium":  185,
		"c1.xlarge":  740,
	},
	"ap-southeast-1": { // Singapore.
		"m1.small":   80,
		"m1.medium":  160,
		"m1.large":   320,
		"m1.xlarge":  640,
		"m3.xlarge":  700,
		"m3.2xlarge": 1400,
		"t1.micro":   20,
		"m2.xlarge":  495,
		"m2.2xlarge": 990,
		"m2.4xlarge": 1980,
		"c1.medium":  183,
		"c1.xlarge":  730,
	},
	"ap-southeast-2": { // Sydney.
		"m1.small":   80,
		"m1.medium":  160,
		"m1.large":   320,
		"m1.xlarge":  640,
		"m3.xlarge":  700,
		"m3.2xlarge": 1400,
		"t1.micro":   20,
		"m2.xlarge":  495,
		"m2.2xlarge": 990,
		"m2.4xlarge": 1980,
		"c1.medium":  183,
		"c1.xlarge":  730,
	},
	"eu-west-1": { // Ireland.
		"m1.small":    65,
		"m1.medium":   130,
		"m1.large":    260,
		"m1.xlarge":   520,
		"m3.xlarge":   550,
		"m3.2xlarge":  1100,
		"t1.micro":    20,
		"m2.xlarge":   460,
		"m2.2xlarge":  920,
		"m2.4xlarge":  1840,
		"c1.medium":   165,
		"c1.xlarge":   660,
		"cc2.8xlarge": 2700,
		"cg1.4xlarge": 2360,
		"hi1.4xlarge": 3410,
	},
	"sa-east-1": { // Sao Paulo.
		"m1.small":   80,
		"m1.medium":  160,
		"m1.large":   320,
		"m1.xlarge":  640,
		"t1.micro":   27,
		"m2.xlarge":  540,
		"m2.2xlarge": 1080,
		"m2.4xlarge": 2160,
		"c1.medium":  200,
		"c1.xlarge":  800,
	},
	"us-east-1": { // Northern Virginia.
		"m1.small":    60,
		"m1.medium":   120,
		"m1.large":    240,
		"m1.xlarge":   480,
		"m3.xlarge":   500,
		"m3.2xlarge":  1000,
		"t1.micro":    20,
		"m2.xlarge":   410,
		"m2.2xlarge":  820,
		"m2.4xlarge":  1640,
		"c1.medium":   145,
		"c1.xlarge":   580,
		"cc1.4xlarge": 1300,
		"cc2.8xlarge": 2400,
		"cr1.8xlarge": 3500,
		"cg1.4xlarge": 2100,
		"hi1.4xlarge": 3100,
		"hs1.8xlarge": 4600,
	},
	"us-west-1": { // Northern California.
		"m1.small":   65,
		"m1.medium":  130,
		"m1.large":   260,
		"m1.xlarge":  520,
		"m3.xlarge":  550,
		"m3.2xlarge": 1100,
		"t1.micro":   25,
		"m2.xlarge":  460,
		"m2.2xlarge": 920,
		"m2.4xlarge": 1840,
		"c1.medium":  165,
		"c1.xlarge":  660,
	},
	"us-west-2": { // Oregon.
		"m1.small":    60,
		"m1.medium":   120,
		"m1.large":    240,
		"m1.xlarge":   480,
		"m3.xlarge":   500,
		"m3.2xlarge":  1000,
		"t1.micro":    20,
		"m2.xlarge":   410,
		"m2.2xlarge":  820,
		"m2.4xlarge":  1640,
		"c1.medium":   145,
		"c1.xlarge":   580,
		"cc2.8xlarge": 2400,
		"cr1.8xlarge": 3500,
		"hi1.4xlarge": 3100,
	},
}
<commit_msg>Ec2 m3.* pricing seems to be different (cheaper) than we had recorded. There also seem to be a couple smaller m3 types (medium and large). We should be using them.<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package ec2

import (
	"launchpad.net/goamz/aws"

	"launchpad.net/juju-core/environs/instances"
)

// Type of virtualisation used.
var (
	paravirtual = "pv"
	hvm         = "hvm"
)

// all instance types can run amd64 images, and some can also run i386 ones.
var (
	amd64 = []string{"amd64"}
	both  = []string{"amd64", "i386"}
)

// allRegions is defined here to allow tests to override the content.
var allRegions = aws.Regions

// TODO(bug 1212688): the RootDisk defaults to 8G currently until the
// referenced bug is fixed, at which point RootDisk can be set to nil and the
// specified constraint can be passed through via block device mapping to
// request an appropriate resize of the root disk.

// allInstanceTypes holds the relevant attributes of every known
// instance type.
var allInstanceTypes = []instances.InstanceType{
	{ // First generation.
		Name:     "m1.small",
		Arches:   both,
		CpuCores: 1,
		CpuPower: instances.CpuPower(100),
		Mem:      1740,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m1.medium",
		Arches:   both,
		CpuCores: 1,
		CpuPower: instances.CpuPower(200),
		Mem:      3840,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m1.large",
		Arches:   amd64,
		CpuCores: 2,
		CpuPower: instances.CpuPower(400),
		Mem:      7680,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m1.xlarge",
		Arches:   amd64,
		CpuCores: 4,
		CpuPower: instances.CpuPower(800),
		Mem:      15360,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // Second generation.
		Name:     "m3.medium",
		Arches:   amd64,
		CpuCores: 1,
		CpuPower: instances.CpuPower(300),
		Mem:      3840,
		VType:    &paravirtual,
	}, {
		Name:     "m3.large",
		Arches:   amd64,
		CpuCores: 2,
		CpuPower: instances.CpuPower(6500),
		Mem:      7680,
		VType:    &paravirtual,
	}, {
		Name:     "m3.xlarge",
		Arches:   amd64,
		CpuCores: 4,
		CpuPower: instances.CpuPower(1300),
		Mem:      15360,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m3.2xlarge",
		Arches:   amd64,
		CpuCores: 8,
		CpuPower: instances.CpuPower(2600),
		Mem:      30720,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // Micro.
		Name:     "t1.micro",
		Arches:   both,
		CpuCores: 1,
		CpuPower: instances.CpuPower(20),
		Mem:      613,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // High-Memory.
		Name:     "m2.xlarge",
		Arches:   amd64,
		CpuCores: 2,
		CpuPower: instances.CpuPower(650),
		Mem:      17408,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m2.2xlarge",
		Arches:   amd64,
		CpuCores: 4,
		CpuPower: instances.CpuPower(1300),
		Mem:      34816,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "m2.4xlarge",
		Arches:   amd64,
		CpuCores: 8,
		CpuPower: instances.CpuPower(2600),
		Mem:      69632,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // High-CPU.
		Name:     "c1.medium",
		Arches:   both,
		CpuCores: 2,
		CpuPower: instances.CpuPower(500),
		Mem:      1740,
		RootDisk: 8192,
		VType:    &paravirtual,
	}, {
		Name:     "c1.xlarge",
		Arches:   amd64,
		CpuCores: 8,
		CpuPower: instances.CpuPower(2000),
		Mem:      7168,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // Cluster compute.
		Name:     "cc1.4xlarge",
		Arches:   amd64,
		CpuCores: 8,
		CpuPower: instances.CpuPower(3350),
		Mem:      23552,
		RootDisk: 8192,
		VType:    &hvm,
	}, {
		Name:     "cc2.8xlarge",
		Arches:   amd64,
		CpuCores: 16,
		CpuPower: instances.CpuPower(8800),
		Mem:      61952,
		RootDisk: 8192,
		VType:    &hvm,
	},
	{ // High Memory cluster.
		Name:     "cr1.8xlarge",
		Arches:   amd64,
		CpuCores: 16,
		CpuPower: instances.CpuPower(8800),
		Mem:      249856,
		RootDisk: 8192,
		VType:    &hvm,
	},
	{ // Cluster GPU.
		Name:     "cg1.4xlarge",
		Arches:   amd64,
		CpuCores: 8,
		CpuPower: instances.CpuPower(3350),
		Mem:      22528,
		RootDisk: 8192,
		VType:    &hvm,
	},
	{ // High I/O.
		Name:     "hi1.4xlarge",
		Arches:   amd64,
		CpuCores: 16,
		CpuPower: instances.CpuPower(3500),
		Mem:      61952,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
	{ // High storage.
		Name:     "hs1.8xlarge",
		Arches:   amd64,
		CpuCores: 16,
		CpuPower: instances.CpuPower(3500),
		Mem:      119808,
		RootDisk: 8192,
		VType:    &paravirtual,
	},
}

type instanceTypeCost map[string]uint64
type regionCosts map[string]instanceTypeCost

// allRegionCosts holds the cost in USDe-3/hour for each available instance
// type in each region.
var allRegionCosts = regionCosts{
	"ap-northeast-1": { // Tokyo.
		"m1.small":   88,
		"m1.medium":  175,
		"m1.large":   350,
		"m1.xlarge":  700,
		"m3.medium":  171,
		"m3.large":   342,
		"m3.xlarge":  684,
		"m3.2xlarge": 1368,
		"t1.micro":   27,
		"m2.xlarge":  505,
		"m2.2xlarge": 1010,
		"m2.4xlarge": 2020,
		"c1.medium":  185,
		"c1.xlarge":  740,
	},
	"ap-southeast-1": { // Singapore.
		"m1.small":   80,
		"m1.medium":  160,
		"m1.large":   320,
		"m1.xlarge":  640,
		"m3.medium":  158,
		"m3.large":   315,
		"m3.xlarge":  730,
		"m3.2xlarge": 1260,
		"t1.micro":   20,
		"m2.xlarge":  495,
		"m2.2xlarge": 990,
		"m2.4xlarge": 1980,
		"c1.medium":  183,
		"c1.xlarge":  730,
	},
	"ap-southeast-2": { // Sydney.
		"m1.small":   80,
		"m1.medium":  160,
		"m1.large":   320,
		"m1.xlarge":  640,
		"m3.medium":  158,
		"m3.large":   315,
		"m3.xlarge":  730,
		"m3.2xlarge": 1260,
		"t1.micro":   20,
		"m2.xlarge":  495,
		"m2.2xlarge": 990,
		"m2.4xlarge": 1980,
		"c1.medium":  183,
		"c1.xlarge":  730,
	},
	"eu-west-1": { // Ireland.
		"m1.small":    65,
		"m1.medium":   130,
		"m1.large":    260,
		"m1.xlarge":   520,
		"m3.medium":   124,
		"m3.large":    248,
		"m3.xlarge":   495,
		"m3.2xlarge":  990,
		"t1.micro":    20,
		"m2.xlarge":   460,
		"m2.2xlarge":  920,
		"m2.4xlarge":  1840,
		"c1.medium":   165,
		"c1.xlarge":   660,
		"cc2.8xlarge": 2700,
		"cg1.4xlarge": 2360,
		"hi1.4xlarge": 3410,
	},
	"sa-east-1": { // Sao Paulo.
		"m1.small":   80,
		"m1.medium":  160,
		"m1.large":   320,
		"m1.xlarge":  640,
		"t1.micro":   27,
		"m3.medium":  153,
		"m3.large":   306,
		"m3.xlarge":  612,
		"m3.2xlarge": 1224,
		"m2.xlarge":  540,
		"m2.2xlarge": 1080,
		"m2.4xlarge": 2160,
		"c1.medium":  200,
		"c1.xlarge":  800,
	},
	"us-east-1": { // Northern Virginia.
		"m1.small":    60,
		"m1.medium":   120,
		"m1.large":    240,
		"m1.xlarge":   480,
		"m3.medium":   113,
		"m3.large":    225,
		"m3.xlarge":   450,
		"m3.2xlarge":  900,
		"t1.micro":    20,
		"m2.xlarge":   410,
		"m2.2xlarge":  820,
		"m2.4xlarge":  1640,
		"c1.medium":   145,
		"c1.xlarge":   580,
		"cc1.4xlarge": 1300,
		"cc2.8xlarge": 2400,
		"cr1.8xlarge": 3500,
		"cg1.4xlarge": 2100,
		"hi1.4xlarge": 3100,
		"hs1.8xlarge": 4600,
	},
	"us-west-1": { // Northern California.
		"m1.small":   65,
		"m1.medium":  130,
		"m1.large":   260,
		"m1.xlarge":  520,
		"m3.medium":  124,
		"m3.large":   248,
		"m3.xlarge":  495,
		"m3.2xlarge": 990,
		"t1.micro":   25,
		"m2.xlarge":  460,
		"m2.2xlarge": 920,
		"m2.4xlarge": 1840,
		"c1.medium":  165,
		"c1.xlarge":  660,
	},
	"us-west-2": { // Oregon.
		"m1.small":    60,
		"m1.medium":   120,
		"m1.large":    240,
		"m1.xlarge":   480,
		"m3.medium":   113,
		"m3.large":    225,
		"m3.xlarge":   450,
		"m3.2xlarge":  900,
		"t1.micro":    20,
		"m2.xlarge":   410,
		"m2.2xlarge":  820,
		"m2.4xlarge":  1640,
		"c1.medium":   145,
		"c1.xlarge":   580,
		"cc2.8xlarge": 2400,
		"cr1.8xlarge": 3500,
		"hi1.4xlarge": 3100,
	},
}
<|endoftext|>