<commit_before>// This program creates an SDL window and renderer and pushes events with PushEvent to be read by PollEvents
package main

import (
	"fmt"
	"github.com/jackyb/go-sdl2/sdl"
	"os"
)

var winTitle string = "Go-SDL2 TestWaitEvent"
var winWidth, winHeight int = 800, 600
const pushTime uint32 = 1000 // number of milliseconds between event pushes

func main() {
	var window *sdl.Window
	var renderer *sdl.Renderer
	var event sdl.Event
	var running bool

	window = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
		winWidth, winHeight, sdl.WINDOW_SHOWN)
	if window == nil {
		fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", sdl.GetError())
		os.Exit(1)
	}

	renderer = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
	if renderer == nil {
		fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", sdl.GetError())
		os.Exit(2)
	}

	running = true
	lastPushTime := sdl.GetTicks()
	for running {

		// Push a UserEvent every second
		if lastPushTime + pushTime > sdl.GetTicks() {
			lastPushTime = sdl.GetTicks()
			pEvent := sdl.UserEvent{sdl.USEREVENT, sdl.GetTicks(), window.GetID(), 1331, nil, nil}

			retVal := sdl.PushEvent(pEvent) // Here's where the event is actually pushed

			switch retVal {
				case 1:
					fmt.Println("PushEvent returned success")
				case 0:
					fmt.Println("PushEvent returned filtered")
				case -1:
					fmt.Printf("PushEvent returned error: %s", sdl.GetError)
			}
		}

		for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
			switch t := event.(type) {
			case *sdl.QuitEvent:
				running = false
			case *sdl.MouseMotionEvent:
				fmt.Printf("[%d ms] MouseMotion\ttype:%d\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n",
					t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel)
			case *sdl.MouseButtonEvent:
				fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n",
					t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State)
			case *sdl.MouseWheelEvent:
				fmt.Printf("[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n",
					t.Timestamp, t.Type, t.Which, t.X, t.Y)
			case *sdl.KeyUpEvent:
				fmt.Printf("[%d ms] Keyboard\ttype:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n",
					t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat)
			case *sdl.UserEvent:
				fmt.Printf("[%d ms] UserEvent\tcode:%d\n", t.Timestamp, t.Code)
			}
		}
	}

	renderer.Destroy()
	window.Destroy()
}
<commit_msg>Fix timing for pushing 1 event per second<commit_after>// This program creates an SDL window and renderer and pushes events with PushEvent to be read by PollEvents
package main

import (
	"fmt"
	"github.com/jackyb/go-sdl2/sdl"
	"os"
)

var winTitle string = "Go-SDL2 TestWaitEvent"
var winWidth, winHeight int = 800, 600
const pushTime uint32 = 1000 // number of milliseconds between event pushes

func main() {
	var window *sdl.Window
	var renderer *sdl.Renderer
	var event sdl.Event
	var running bool

	window = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
		winWidth, winHeight, sdl.WINDOW_SHOWN)
	if window == nil {
		fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", sdl.GetError())
		os.Exit(1)
	}

	renderer = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
	if renderer == nil {
		fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", sdl.GetError())
		os.Exit(2)
	}

	running = true
	lastPushTime := sdl.GetTicks()
	for running {

		// Push a UserEvent every second
		if lastPushTime + pushTime < sdl.GetTicks() {
			lastPushTime = sdl.GetTicks()
			pEvent := sdl.UserEvent{sdl.USEREVENT, sdl.GetTicks(), window.GetID(), 1331, nil, nil}

			retVal := sdl.PushEvent(pEvent) // Here's where the event is actually pushed

			switch retVal {
				case 1:
					fmt.Println("PushEvent returned success")
				case 0:
					fmt.Println("PushEvent returned filtered")
				case -1:
					fmt.Printf("PushEvent returned error: %s\n", sdl.GetError)
			}
		}

		for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
			switch t := event.(type) {
			case *sdl.QuitEvent:
				running = false
			case *sdl.MouseMotionEvent:
				fmt.Printf("[%d ms] MouseMotion\ttype:%d\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n",
					t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel)
			case *sdl.MouseButtonEvent:
				fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n",
					t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State)
			case *sdl.MouseWheelEvent:
				fmt.Printf("[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n",
					t.Timestamp, t.Type, t.Which, t.X, t.Y)
			case *sdl.KeyUpEvent:
				fmt.Printf("[%d ms] Keyboard\ttype:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n",
					t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat)
			case *sdl.UserEvent:
				fmt.Printf("[%d ms] UserEvent\tcode:%d\n", t.Timestamp, t.Code)
			}
		}
		sdl.Delay(1000/30)
	}

	renderer.Destroy()
	window.Destroy()
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"net"
	"strconv"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ec2"
)

func expandNetworkAclEntries(configured []interface{}, entryType string) ([]*ec2.NetworkAclEntry, error) {
	entries := make([]*ec2.NetworkAclEntry, 0, len(configured))
	for _, eRaw := range configured {
		data := eRaw.(map[string]interface{})
		protocol := data["protocol"].(string)
		p, err := strconv.Atoi(protocol)
		if err != nil {
			var ok bool
			p, ok = protocolIntegers()[protocol]
			if !ok {
				return nil, fmt.Errorf("Invalid Protocol %s for rule %#v", protocol, data)
			}
		}

		e := &ec2.NetworkAclEntry{
			Protocol: aws.String(strconv.Itoa(p)),
			PortRange: &ec2.PortRange{
				From: aws.Int64(int64(data["from_port"].(int))),
				To:   aws.Int64(int64(data["to_port"].(int))),
			},
			Egress:     aws.Bool(entryType == "egress"),
			RuleAction: aws.String(data["action"].(string)),
			RuleNumber: aws.Int64(int64(data["rule_no"].(int))),
			CidrBlock:  aws.String(data["cidr_block"].(string)),
		}

		// Specify additional required fields for ICMP
		if p == 1 {
			e.IcmpTypeCode = &ec2.IcmpTypeCode{}
			if v, ok := data["icmp_code"]; ok {
				e.IcmpTypeCode.Code = aws.Int64(int64(v.(int)))
			}
			if v, ok := data["icmp_type"]; ok {
				e.IcmpTypeCode.Type = aws.Int64(int64(v.(int)))
			}
		}

		entries = append(entries, e)
	}
	return entries, nil
}

func flattenNetworkAclEntries(list []*ec2.NetworkAclEntry) []map[string]interface{} {
	entries := make([]map[string]interface{}, 0, len(list))

	for _, entry := range list {
		entries = append(entries, map[string]interface{}{
			"from_port":  *entry.PortRange.From,
			"to_port":    *entry.PortRange.To,
			"action":     *entry.RuleAction,
			"rule_no":    *entry.RuleNumber,
			"protocol":   *entry.Protocol,
			"cidr_block": *entry.CidrBlock,
		})
	}

	return entries

}

func protocolStrings(protocolIntegers map[string]int) map[int]string {
	protocolStrings := make(map[int]string, len(protocolIntegers))
	for k, v := range protocolIntegers {
		protocolStrings[v] = k
	}

	return protocolStrings
}

func protocolIntegers() map[string]int {
	var protocolIntegers = make(map[string]int)
	protocolIntegers = map[string]int{
		// defined at https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
		"ah":   51,
		"esp":  50,
		"udp":  17,
		"tcp":  6,
		"icmp": 1,
		"all":  -1,
	}
	return protocolIntegers
}

// expectedPortPair stores a pair of ports we expect to see together.
type expectedPortPair struct {
	to_port   int64
	from_port int64
}

// validatePorts ensures the ports and protocol match expected
// values.
func validatePorts(to int64, from int64, expected expectedPortPair) bool {
	if to != expected.to_port || from != expected.from_port {
		return false
	}

	return true
}

// validateCIDRBlock ensures the passed CIDR block represents an implied
// network, and not an overly-specified IP address.
func validateCIDRBlock(cidr string) error {
	_, ipnet, err := net.ParseCIDR(cidr)
	if err != nil {
		return err
	}
	if ipnet.String() != cidr {
		return fmt.Errorf("%s is not a valid mask; did you mean %s?", cidr, ipnet)
	}

	return nil
}
<commit_msg>Add VRRP to allowed protocols in network ACL rules (#12107)<commit_after>package aws

import (
	"fmt"
	"net"
	"strconv"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ec2"
)

func expandNetworkAclEntries(configured []interface{}, entryType string) ([]*ec2.NetworkAclEntry, error) {
	entries := make([]*ec2.NetworkAclEntry, 0, len(configured))
	for _, eRaw := range configured {
		data := eRaw.(map[string]interface{})
		protocol := data["protocol"].(string)
		p, err := strconv.Atoi(protocol)
		if err != nil {
			var ok bool
			p, ok = protocolIntegers()[protocol]
			if !ok {
				return nil, fmt.Errorf("Invalid Protocol %s for rule %#v", protocol, data)
			}
		}

		e := &ec2.NetworkAclEntry{
			Protocol: aws.String(strconv.Itoa(p)),
			PortRange: &ec2.PortRange{
				From: aws.Int64(int64(data["from_port"].(int))),
				To:   aws.Int64(int64(data["to_port"].(int))),
			},
			Egress:     aws.Bool(entryType == "egress"),
			RuleAction: aws.String(data["action"].(string)),
			RuleNumber: aws.Int64(int64(data["rule_no"].(int))),
			CidrBlock:  aws.String(data["cidr_block"].(string)),
		}

		// Specify additional required fields for ICMP
		if p == 1 {
			e.IcmpTypeCode = &ec2.IcmpTypeCode{}
			if v, ok := data["icmp_code"]; ok {
				e.IcmpTypeCode.Code = aws.Int64(int64(v.(int)))
			}
			if v, ok := data["icmp_type"]; ok {
				e.IcmpTypeCode.Type = aws.Int64(int64(v.(int)))
			}
		}

		entries = append(entries, e)
	}
	return entries, nil
}

func flattenNetworkAclEntries(list []*ec2.NetworkAclEntry) []map[string]interface{} {
	entries := make([]map[string]interface{}, 0, len(list))

	for _, entry := range list {
		entries = append(entries, map[string]interface{}{
			"from_port":  *entry.PortRange.From,
			"to_port":    *entry.PortRange.To,
			"action":     *entry.RuleAction,
			"rule_no":    *entry.RuleNumber,
			"protocol":   *entry.Protocol,
			"cidr_block": *entry.CidrBlock,
		})
	}

	return entries

}

func protocolStrings(protocolIntegers map[string]int) map[int]string {
	protocolStrings := make(map[int]string, len(protocolIntegers))
	for k, v := range protocolIntegers {
		protocolStrings[v] = k
	}

	return protocolStrings
}

func protocolIntegers() map[string]int {
	var protocolIntegers = make(map[string]int)
	protocolIntegers = map[string]int{
		// defined at https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
		"ah":   51,
		"esp":  50,
		"udp":  17,
		"tcp":  6,
		"icmp": 1,
		"all":  -1,
		"vrrp": 112,
	}
	return protocolIntegers
}

// expectedPortPair stores a pair of ports we expect to see together.
type expectedPortPair struct {
	to_port   int64
	from_port int64
}

// validatePorts ensures the ports and protocol match expected
// values.
func validatePorts(to int64, from int64, expected expectedPortPair) bool {
	if to != expected.to_port || from != expected.from_port {
		return false
	}

	return true
}

// validateCIDRBlock ensures the passed CIDR block represents an implied
// network, and not an overly-specified IP address.
func validateCIDRBlock(cidr string) error {
	_, ipnet, err := net.ParseCIDR(cidr)
	if err != nil {
		return err
	}
	if ipnet.String() != cidr {
		return fmt.Errorf("%s is not a valid mask; did you mean %s?", cidr, ipnet)
	}

	return nil
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"

	"github.com/hashicorp/terraform/helper/diff"
	"github.com/hashicorp/terraform/terraform"
	"github.com/hashicorp/terraform/flatmap"
	"github.com/mitchellh/goamz/ec2"
)

func resource_aws_security_group_create(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	// Merge the diff into the state so that we have all the attributes
	// properly.
	rs := s.MergeDiff(d)

	securityGroupOpts := ec2.SecurityGroup{
		Name:        rs.Attributes["name"],
		Description: rs.Attributes["description"],
		VpcId:       rs.Attributes["vpc_id"],
	}

	log.Printf("[DEBUG] Security Group create configuration: %#v", securityGroupOpts)
	createResp, err := ec2conn.CreateSecurityGroup(securityGroupOpts)
	if err != nil {
		return nil, fmt.Errorf("Error creating Security Group: %s", err)
	}

	rs.ID = createResp.Id
	group := createResp.SecurityGroup

	log.Printf("[INFO] Security Group ID: %s", rs.ID)
	ingressRules := []ec2.IPPerm{}
	egressRules := []ec2.IPPerm{}

	// Expand the "ingress" array to goamz compat []ec2.IPPerm
	v, ok := flatmap.Expand(rs.Attributes, "ingress").([]interface{})
	if ok {
		ingressRules = expandIPPerms(v)
	}

	// Expand the "egress" array to goamz compat []ec2.IPPerm
	v, ok = flatmap.Expand(rs.Attributes, "egress").([]interface{})
	if ok {
		egressRules = expandIPPerms(v)
	}

	if len(egressRules) > 0 {
		_, err = ec2conn.AuthorizeSecurityGroupEgress(group, egressRules)
		if err != nil {
			return rs, fmt.Errorf("Error authorizing security group egress rules: %s", err)
		}
	}

	if len(ingressRules) > 0 {
		_, err = ec2conn.AuthorizeSecurityGroup(group, ingressRules)
		if err != nil {
			return rs, fmt.Errorf("Error authorizing security group ingress rules: %s", err)
		}
	}

	sg, err := resource_aws_security_group_retrieve(rs.ID, ec2conn)
	if err != nil {
		return rs, err
	}

	return resource_aws_security_group_update_state(rs, sg)
}

func resource_aws_security_group_update(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {

	rs := s.MergeDiff(d)
	log.Printf("ResourceDiff: %s", d)
	log.Printf("ResourceState: %s", s)
	log.Printf("Merged: %s", rs)

	return nil, fmt.Errorf("Did not update")
}

func resource_aws_security_group_destroy(
	s *terraform.ResourceState,
	meta interface{}) error {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	log.Printf("[DEBUG] Security Group destroy: %v", s.ID)

	_, err := ec2conn.DeleteSecurityGroup(ec2.SecurityGroup{Id: s.ID})

	if err != nil {
		ec2err, ok := err.(*ec2.Error)
		if ok && ec2err.Code == "InvalidGroup.NotFound" {
			return nil
		}
	}

	return err
}

func resource_aws_security_group_refresh(
	s *terraform.ResourceState,
	meta interface{}) (*terraform.ResourceState, error) {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	sg, err := resource_aws_security_group_retrieve(s.ID, ec2conn)

	if err != nil {
		return s, err
	}

	return resource_aws_security_group_update_state(s, sg)
}

func resource_aws_security_group_diff(
	s *terraform.ResourceState,
	c *terraform.ResourceConfig,
	meta interface{}) (*terraform.ResourceDiff, error) {

	b := &diff.ResourceBuilder{
		Attrs: map[string]diff.AttrType{
			"name":        diff.AttrTypeCreate,
			"description": diff.AttrTypeCreate,
			"vpc_id":      diff.AttrTypeUpdate,
			"ingress":      diff.AttrTypeUpdate,
			"egress":      diff.AttrTypeUpdate,
		},

		ComputedAttrs: []string{
			"owner_id",
		},
	}

	return b.Diff(s, c)
}

func resource_aws_security_group_update_state(
	s *terraform.ResourceState,
	sg *ec2.SecurityGroupInfo) (*terraform.ResourceState, error) {

	s.Attributes["description"] = sg.Description
	s.Attributes["name"] = sg.Name
	s.Attributes["vpc_id"] = sg.VpcId
	s.Attributes["owner_id"] = sg.OwnerId

	return s, nil
}

// Returns a single sg by it's ID
func resource_aws_security_group_retrieve(id string, ec2conn *ec2.EC2) (*ec2.SecurityGroupInfo, error) {
	sgs := []ec2.SecurityGroup{
		ec2.SecurityGroup{
			Id: id,
		},
	}

	log.Printf("[DEBUG] Security Group describe configuration: %#v", sgs)

	describeGroups, err := ec2conn.SecurityGroups(sgs, nil)

	if err != nil {
		return nil, fmt.Errorf("Error retrieving security groups: %s", err)
	}

	// Verify AWS returned our sg
	if len(describeGroups.Groups) != 1 ||
		describeGroups.Groups[0].Id != id {
		if err != nil {
			return nil, fmt.Errorf("Unable to find security group: %#v", describeGroups.Groups)
		}
	}

	sg := describeGroups.Groups[0]

	return &sg, nil
}
<commit_msg>terraform: add ID to diff implicitly<commit_after>package aws

import (
	"fmt"
	"log"

	"github.com/hashicorp/terraform/flatmap"
	"github.com/hashicorp/terraform/helper/diff"
	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/goamz/ec2"
)

func resource_aws_security_group_create(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	// Merge the diff into the state so that we have all the attributes
	// properly.
	rs := s.MergeDiff(d)

	securityGroupOpts := ec2.SecurityGroup{
		Name:        rs.Attributes["name"],
		Description: rs.Attributes["description"],
		VpcId:       rs.Attributes["vpc_id"],
	}

	log.Printf("[DEBUG] Security Group create configuration: %#v", securityGroupOpts)
	createResp, err := ec2conn.CreateSecurityGroup(securityGroupOpts)
	if err != nil {
		return nil, fmt.Errorf("Error creating Security Group: %s", err)
	}

	rs.ID = createResp.Id
	group := createResp.SecurityGroup

	log.Printf("[INFO] Security Group ID: %s", rs.ID)
	ingressRules := []ec2.IPPerm{}
	egressRules := []ec2.IPPerm{}

	// Expand the "ingress" array to goamz compat []ec2.IPPerm
	v, ok := flatmap.Expand(rs.Attributes, "ingress").([]interface{})
	if ok {
		ingressRules = expandIPPerms(v)
	}

	// Expand the "egress" array to goamz compat []ec2.IPPerm
	v, ok = flatmap.Expand(rs.Attributes, "egress").([]interface{})
	if ok {
		egressRules = expandIPPerms(v)
	}

	if len(egressRules) > 0 {
		_, err = ec2conn.AuthorizeSecurityGroupEgress(group, egressRules)
		if err != nil {
			return rs, fmt.Errorf("Error authorizing security group egress rules: %s", err)
		}
	}

	if len(ingressRules) > 0 {
		_, err = ec2conn.AuthorizeSecurityGroup(group, ingressRules)
		if err != nil {
			return rs, fmt.Errorf("Error authorizing security group ingress rules: %s", err)
		}
	}

	sg, err := resource_aws_security_group_retrieve(rs.ID, ec2conn)
	if err != nil {
		return rs, err
	}

	return resource_aws_security_group_update_state(rs, sg)
}

func resource_aws_security_group_update(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {

	rs := s.MergeDiff(d)
	log.Printf("ResourceDiff: %s", d)
	log.Printf("ResourceState: %s", s)
	log.Printf("Merged: %s", rs)

	return nil, fmt.Errorf("Did not update")
}

func resource_aws_security_group_destroy(
	s *terraform.ResourceState,
	meta interface{}) error {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	log.Printf("[DEBUG] Security Group destroy: %v", s.ID)

	_, err := ec2conn.DeleteSecurityGroup(ec2.SecurityGroup{Id: s.ID})

	if err != nil {
		ec2err, ok := err.(*ec2.Error)
		if ok && ec2err.Code == "InvalidGroup.NotFound" {
			return nil
		}
	}

	return err
}

func resource_aws_security_group_refresh(
	s *terraform.ResourceState,
	meta interface{}) (*terraform.ResourceState, error) {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	sg, err := resource_aws_security_group_retrieve(s.ID, ec2conn)

	if err != nil {
		return s, err
	}

	return resource_aws_security_group_update_state(s, sg)
}

func resource_aws_security_group_diff(
	s *terraform.ResourceState,
	c *terraform.ResourceConfig,
	meta interface{}) (*terraform.ResourceDiff, error) {

	b := &diff.ResourceBuilder{
		Attrs: map[string]diff.AttrType{
			"name":        diff.AttrTypeCreate,
			"description": diff.AttrTypeCreate,
			"vpc_id":      diff.AttrTypeUpdate,
			"ingress":     diff.AttrTypeUpdate,
			"egress":      diff.AttrTypeUpdate,
		},

		ComputedAttrs: []string{
			"owner_id",
		},
	}

	return b.Diff(s, c)
}

func resource_aws_security_group_update_state(
	s *terraform.ResourceState,
	sg *ec2.SecurityGroupInfo) (*terraform.ResourceState, error) {

	s.Attributes["description"] = sg.Description
	s.Attributes["name"] = sg.Name
	s.Attributes["vpc_id"] = sg.VpcId
	s.Attributes["owner_id"] = sg.OwnerId

	return s, nil
}

// Returns a single sg by it's ID
func resource_aws_security_group_retrieve(id string, ec2conn *ec2.EC2) (*ec2.SecurityGroupInfo, error) {
	sgs := []ec2.SecurityGroup{
		ec2.SecurityGroup{
			Id: id,
		},
	}

	log.Printf("[DEBUG] Security Group describe configuration: %#v", sgs)

	describeGroups, err := ec2conn.SecurityGroups(sgs, nil)

	if err != nil {
		return nil, fmt.Errorf("Error retrieving security groups: %s", err)
	}

	// Verify AWS returned our sg
	if len(describeGroups.Groups) != 1 ||
		describeGroups.Groups[0].Id != id {
		if err != nil {
			return nil, fmt.Errorf("Unable to find security group: %#v", describeGroups.Groups)
		}
	}

	sg := describeGroups.Groups[0]

	return &sg, nil
}
<|endoftext|>


<commit_before>package whetstone_test

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

	"github.com/cloudfoundry-incubator/runtime-schema/models"
	"github.com/cloudfoundry-incubator/runtime-schema/models/factories"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/gorilla/websocket"
	"github.com/onsi/gomega/gbytes"

	"code.google.com/p/gogoprotobuf/proto"
	"github.com/cloudfoundry-incubator/receptor"
	"github.com/cloudfoundry/loggregatorlib/logmessage"
)

const (
	spyDownloadUrl string = "http://file_server.service.dc1.consul:8080/v1/static/docker-circus/docker-circus.tgz"
)

var _ = Describe("Diego Edge", func() {
	Context("when desiring a docker-based LRP", func() {

		var (
			processGuid string
			appName     string
			route       string
		)

		BeforeEach(func() {
			processGuid = factories.GenerateGuid()
			appName = fmt.Sprintf("whetstone-%s", factories.GenerateGuid())
			route = fmt.Sprintf("%s.%s", appName, domain)
		})

		AfterEach(func() {
			err := receptorClient.DeleteDesiredLRP(processGuid)
			Expect(err).To(BeNil())

			Eventually(errorCheckForRoute(route), timeout, 1).Should(HaveOccurred())
		})

		It("eventually runs on an executor", func() {
			err := desireLongRunningProcess(processGuid, route, 1)
			Expect(err).To(BeNil())

			Eventually(errorCheckForRoute(route), timeout, 1).ShouldNot(HaveOccurred())

			outBuf := gbytes.NewBuffer()
			go streamAppLogsIntoGbytes(processGuid, outBuf)
			Eventually(outBuf, 4).Should(gbytes.Say("Diego Edge Docker App. Says Hello"))

			err = desireLongRunningProcess(processGuid, route, 3)
			Expect(err).To(BeNil())

			instanceCountChan := make(chan int, numCpu)
			go countInstances(route, instanceCountChan)

			Eventually(instanceCountChan, timeout).Should(Receive(Equal(3)))
		})
	})

})

func errorCheckForRoute(route string) func() error {
	return func() error {
		resp, err := makeGetRequestToRoute(route)
		if err != nil {
			return err
		}

		io.Copy(ioutil.Discard, resp.Body)
		defer resp.Body.Close()

		if resp.StatusCode != 200 {
			return fmt.Errorf("Status code %d should be 200", resp.StatusCode)
		}

		return nil
	}
}

func streamAppLogsIntoGbytes(logGuid string, outBuf *gbytes.Buffer) {
	defer GinkgoRecover()

	ws, _, err := websocket.DefaultDialer.Dial(
		fmt.Sprintf("ws://%s/tail/?app=%s", loggregatorAddress, logGuid),
		http.Header{},
	)
	Expect(err).To(BeNil())

	for {
		_, data, err := ws.ReadMessage()
		if err != nil {
			return
		}

		receivedMessage := &logmessage.LogMessage{}
		err = proto.Unmarshal(data, receivedMessage)
		Expect(err).To(BeNil())

		outBuf.Write(receivedMessage.GetMessage())
	}

}

func countInstances(route string, instanceCountChan chan<- int) {
	defer GinkgoRecover()
	instanceIndexRoute := fmt.Sprintf("%s/instance-index", route)
	instancesSeen := make(map[int]bool)
	instanceIndexChan := make(chan int, numCpu)

	for i := 0; i < numCpu; i++ {
		go pollForInstanceIndices(instanceIndexRoute, instanceIndexChan)
	}

	for {
		instanceIndex := <-instanceIndexChan
		instancesSeen[instanceIndex] = true
		instanceCountChan <- len(instancesSeen)
	}
}

func pollForInstanceIndices(route string, instanceIndexChan chan<- int) {
	defer GinkgoRecover()
	for {
		resp, err := makeGetRequestToRoute(route)
		Expect(err).To(BeNil())

		responseBody, err := ioutil.ReadAll(resp.Body)
		defer resp.Body.Close()
		Expect(err).To(BeNil())

		instanceIndex, err := strconv.Atoi(string(responseBody))
		if err != nil {
			continue
		}
		instanceIndexChan <- instanceIndex
	}
}

func makeGetRequestToRoute(route string) (*http.Response, error) {
	routeWithScheme := fmt.Sprintf("http://%s", route)
	resp, err := http.DefaultClient.Get(routeWithScheme)
	if err != nil {
		return nil, err
	}

	return resp, nil
}

func desireLongRunningProcess(processGuid, route string, instanceCount int) error {
	return receptorClient.CreateDesiredLRP(receptor.DesiredLRPCreateRequest{
		ProcessGuid: processGuid,
		Domain:      "whetstone",
		RootFSPath:  "docker:///diegoedge/diego-edge-docker-app",
		Instances:   instanceCount,
		Stack:       "lucid64",
		Routes:      []string{route},
		MemoryMB:    128,
		DiskMB:      1024,
		CPUWeight:   1,
		Ports:       []uint32{8080},
		LogGuid:     processGuid,
		LogSource:   "APP",
		Setup: &models.DownloadAction{
			From: spyDownloadUrl,
			To:   "/tmp",
		},
		Action: &models.RunAction{
			Path: "/dockerapp",
		},
		Monitor: &models.RunAction{
			Path: "/tmp/spy",
			Args: []string{"-addr", ":8080"},
		},
	})
}
<commit_msg>Reinstate "use the diego edge cli in tests""<commit_after>package whetstone_test

import (
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os/exec"
	"strconv"

	"github.com/cloudfoundry-incubator/runtime-schema/models/factories"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
)

var (
	diegoEdgeCli string
)

var _ = BeforeSuite(func() {
	var err error
	diegoEdgeCli, err = gexec.Build("github.com/pivotal-cf-experimental/diego-edge-cli")
	Expect(err).ToNot(HaveOccurred())
})

var _ = AfterSuite(func() {
	gexec.CleanupBuildArtifacts()
})

var _ = Describe("Diego Edge", func() {
	Context("when desiring a docker-based LRP", func() {

		var (
			appName string
			route   string
		)

		BeforeEach(func() {
			appName = fmt.Sprintf("whetstone-%s", factories.GenerateGuid())
			route = fmt.Sprintf("%s.%s", appName, domain)
		})

		AfterEach(func() {
			stopApp(appName)

			Eventually(errorCheckForRoute(route), timeout, 1).Should(HaveOccurred())
		})

		It("eventually runs a docker app", func() {
			startDockerApp(appName)
			Eventually(errorCheckForRoute(route), timeout, 1).ShouldNot(HaveOccurred())

			logsStream := streamLogs(appName)
			Eventually(logsStream.Out, timeout).Should(gbytes.Say("Diego Edge Docker App. Says Hello"))

			scaleApp(appName)

			instanceCountChan := make(chan int, numCpu)
			go countInstances(route, instanceCountChan)
			Eventually(instanceCountChan, timeout).Should(Receive(Equal(3)))

			logsStream.Terminate().Wait()
		})
	})

})

func startDockerApp(appName string) {
	command := exec.Command(diegoEdgeCli, "start", appName, "-i", "docker:///diegoedge/diego-edge-docker-app", "-c", "/dockerapp")
	session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)

	Expect(err).ToNot(HaveOccurred())
	Eventually(session).Should(gexec.Exit(0))
}

func streamLogs(appName string) *gexec.Session {
	command := exec.Command(diegoEdgeCli, "logs", appName)
	session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
	Expect(err).ToNot(HaveOccurred())

	return session
}

func scaleApp(appName string) {
	command := exec.Command(diegoEdgeCli, "scale", appName, "--instances", "3")
	session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)

	Expect(err).ToNot(HaveOccurred())
	Eventually(session).Should(gexec.Exit(0))
}

func stopApp(appName string) {
	command := exec.Command(diegoEdgeCli, "stop", appName)
	session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)

	Expect(err).ToNot(HaveOccurred())
	Eventually(session).Should(gexec.Exit(0))
}

func errorCheckForRoute(route string) func() error {
	return func() error {
		response, err := makeGetRequestToRoute(route)
		if err != nil {
			return err
		}

		io.Copy(ioutil.Discard, response.Body)
		defer response.Body.Close()

		if response.StatusCode != 200 {
			return fmt.Errorf("Status code %d should be 200", response.StatusCode)
		}

		return nil
	}
}

func countInstances(route string, instanceCountChan chan<- int) {
	defer GinkgoRecover()
	instanceIndexRoute := fmt.Sprintf("%s/instance-index", route)
	instancesSeen := make(map[int]bool)

	instanceIndexChan := make(chan int, numCpu)

	for i := 0; i < numCpu; i++ {
		go pollForInstanceIndices(instanceIndexRoute, instanceIndexChan)
	}

	for {
		instanceIndex := <-instanceIndexChan
		instancesSeen[instanceIndex] = true
		instanceCountChan <- len(instancesSeen)
	}
}

func pollForInstanceIndices(route string, instanceIndexChan chan<- int) {
	defer GinkgoRecover()
	for {
		response, err := makeGetRequestToRoute(route)
		Expect(err).To(BeNil())

		responseBody, err := ioutil.ReadAll(response.Body)
		defer response.Body.Close()
		Expect(err).To(BeNil())

		instanceIndex, err := strconv.Atoi(string(responseBody))
		if err != nil {
			continue
		}
		instanceIndexChan <- instanceIndex
	}
}

func makeGetRequestToRoute(route string) (*http.Response, error) {
	routeWithScheme := fmt.Sprintf("http://%s", route)
	resp, err := http.DefaultClient.Get(routeWithScheme)
	if err != nil {
		return nil, err
	}

	return resp, nil
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/network"
	"github.com/docker/docker/client"
	manifest "github.com/estafette/estafette-ci-manifest"

	"github.com/rs/zerolog/log"
)

// DockerRunner pulls and runs docker containers
type DockerRunner interface {
	isDockerImagePulled(manifest.EstafettePipeline) bool
	runDockerPull(manifest.EstafettePipeline) error
	getDockerImageSize(manifest.EstafettePipeline) (int64, error)
	runDockerRun(string, map[string]string, manifest.EstafettePipeline) ([]buildJobLogLine, int64, error)
	startDockerDaemon() error
	waitForDockerDaemon()
}

type dockerRunnerImpl struct {
	envvarHelper EnvvarHelper
}

// NewDockerRunner returns a new DockerRunner
func NewDockerRunner(envvarHelper EnvvarHelper) DockerRunner {
	return &dockerRunnerImpl{
		envvarHelper: envvarHelper,
	}
}

func (dr *dockerRunnerImpl) isDockerImagePulled(p manifest.EstafettePipeline) bool {

	log.Info().Msgf("[%v] Checking if docker image '%v' exists locally...", p.Name, p.ContainerImage)

	cli, err := client.NewEnvClient()
	if err != nil {
		return false
	}

	imageSummaries, err := cli.ImageList(context.Background(), types.ImageListOptions{})

	for _, summary := range imageSummaries {
		if contains(summary.RepoTags, p.ContainerImage) {
			return true
		}
	}

	return false
}

func (dr *dockerRunnerImpl) runDockerPull(p manifest.EstafettePipeline) (err error) {

	log.Info().Msgf("[%v] Pulling docker image '%v'", p.Name, p.ContainerImage)

	cli, err := client.NewEnvClient()
	if err != nil {
		return err
	}

	rc, err := cli.ImagePull(context.Background(), p.ContainerImage, types.ImagePullOptions{})
	if err != nil {
		return err
	}
	defer rc.Close()

	// wait for image pull to finish
	_, err = ioutil.ReadAll(rc)
	if err != nil {
		return err
	}

	return
}

func (dr *dockerRunnerImpl) getDockerImageSize(p manifest.EstafettePipeline) (totalSize int64, err error) {

	cli, err := client.NewEnvClient()
	if err != nil {
		return totalSize, err
	}

	items, err := cli.ImageHistory(context.Background(), p.ContainerImage)
	if err != nil {
		return totalSize, err
	}

	for _, item := range items {
		totalSize += item.Size
	}

	return totalSize, nil
}

func (dr *dockerRunnerImpl) runDockerRun(dir string, envvars map[string]string, p manifest.EstafettePipeline) (logLines []buildJobLogLine, exitCode int64, err error) {

	logLines = make([]buildJobLogLine, 0)
	exitCode = -1

	// run docker with image and commands from yaml
	ctx := context.Background()
	cli, err := client.NewEnvClient()
	if err != nil {
		return
	}

	// define commands
	cmdSlice := make([]string, 0)
	cmdSlice = append(cmdSlice, "set -e;"+strings.Join(p.Commands, ";"))

	// add custom properties as ESTAFETTE_EXTENSION_... envvar
	extensionEnvVars := map[string]string{}
	if p.CustomProperties != nil && len(p.CustomProperties) > 0 {
		for k, v := range p.CustomProperties {
			extensionkey := dr.envvarHelper.getEstafetteEnvvarName(fmt.Sprintf("ESTAFETTE_EXTENSION_%v", dr.envvarHelper.toUpperSnake(k)))

			if s, isString := v.(string); isString {
				// if custom property is of type string add the envvar
				extensionEnvVars[extensionkey] = os.Expand(s, dr.envvarHelper.getEstafetteEnv)
			} else if s, isBool := v.(bool); isBool {
				// if custom property is of type bool add the envvar
				extensionEnvVars[extensionkey] = os.Expand(strconv.FormatBool(s), dr.envvarHelper.getEstafetteEnv)
			} else if s, isInt := v.(int); isInt {
				// if custom property is of type bool add the envvar
				extensionEnvVars[extensionkey] = os.Expand(strconv.FormatInt(int64(s), 10), dr.envvarHelper.getEstafetteEnv)
			} else if i, isInterfaceArray := v.([]interface{}); isInterfaceArray {
				// check whether all array items are of type string
				valid := true
				stringValues := []string{}
				for _, iv := range i {
					if s, isString := iv.(string); isString {
						stringValues = append(stringValues, s)
					} else {
						valid = false
						break
					}
				}

				if valid {
					// if all array items are string, pass as comma-separated list to extension
					extensionEnvVars[extensionkey] = os.Expand(strings.Join(stringValues, ","), dr.envvarHelper.getEstafetteEnv)
				} else {
					log.Warn().Interface("customProperty", v).Msgf("Cannot turn custom property %v into extension envvar", k)
				}
			} else {
				log.Warn().Interface("customProperty", v).Msgf("Cannot turn custom property %v into extension envvar", k)
			}
		}
	}

	// combine and override estafette and global envvars with pipeline envvars
	combinedEnvVars := dr.envvarHelper.overrideEnvvars(envvars, p.EnvVars, extensionEnvVars)

	// decrypt secrets
	combinedEnvVars = dr.envvarHelper.decryptSecrets(combinedEnvVars)

	// define docker envvars
	dockerEnvVars := make([]string, 0)
	if combinedEnvVars != nil && len(combinedEnvVars) > 0 {
		for k, v := range combinedEnvVars {
			dockerEnvVars = append(dockerEnvVars, fmt.Sprintf("%v=%v", k, v))
		}
	}

	// define entrypoint
	entrypoint := make([]string, 0)
	entrypoint = append(entrypoint, p.Shell)
	entrypoint = append(entrypoint, "-c")

	// define binds
	binds := make([]string, 0)
	if runtime.GOOS != "windows" {
		binds = append(binds, fmt.Sprintf("%v:%v", dir, os.Expand(p.WorkingDirectory, dr.envvarHelper.getEstafetteEnv)))
	}
	if ok, _ := pathExists("/var/run/docker.sock"); ok {
		binds = append(binds, "/var/run/docker.sock:/var/run/docker.sock")
	}
	if ok, _ := pathExists("/var/run/secrets/kubernetes.io/serviceaccount"); ok {
		binds = append(binds, "/var/run/secrets/kubernetes.io/serviceaccount:/var/run/secrets/kubernetes.io/serviceaccount")
	}

	// define config
	config := container.Config{
		AttachStdout: true,
		AttachStderr: true,
		Env:          dockerEnvVars,
		Image:        p.ContainerImage,
		WorkingDir:   os.Expand(p.WorkingDirectory, dr.envvarHelper.getEstafetteEnv),
	}
	if len(p.Commands) > 0 {
		// only pass commands when they are set, so extensions can work without
		config.Cmd = cmdSlice
		// only override entrypoint when commands are set, so extensions can work without commands
		config.Entrypoint = entrypoint
	}

	// create container
	resp, err := cli.ContainerCreate(ctx, &config, &container.HostConfig{
		Binds:      binds,
		AutoRemove: true,
		Privileged: true,
	}, &network.NetworkingConfig{}, "")
	if err != nil {
		return
	}

	// start container
	if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
		return logLines, exitCode, err
	}

	// follow logs
	rc, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{
		ShowStdout: true,
		ShowStderr: true,
		Follow:     true,
	})
	defer rc.Close()
	if err != nil {
		return
	}

	// stream logs to stdout with buffering
	in := bufio.NewReader(rc)
	var readError error
	for {

		// strip first 8 bytes, they contain docker control characters (https://github.com/docker/docker/issues/7375)
		logLine, readError := in.ReadBytes('\n')

		if readError != nil {
			break
		}

		logType := "stdout"
		if len(logLine) > 8 {

			headers := []byte(logLine[0:8])

			// first byte contains the streamType
			// -   0: stdin (will be written on stdout)
			// -   1: stdout
			// -   2: stderr
			streamType := headers[0]

			if streamType == 2 {
				logType = "stderr"
			}

			logLine = logLine[8:]
		}

		if logType == "stderr" {
			log.Info().Msgf("[%v] %v", p.Name, logLine)
		} else {
			log.Info().Msgf("[%v] %v", p.Name, logLine)
		}

		logLines = append(logLines, buildJobLogLine{
			timestamp: time.Now().UTC(),
			logLevel:  logType,
			logText:   string(logLine),
		})
	}

	if readError != nil && readError != io.EOF {
		log.Error().Msgf("[%v] Error: %v", p.Name, readError)
		return logLines, exitCode, readError
	}

	// wait for container to stop run
	exitCode, err = cli.ContainerWait(ctx, resp.ID)
	if err != nil {
		return
	}

	if exitCode != 0 {
		return logLines, exitCode, fmt.Errorf("Failed with exit code: %v", exitCode)
	}

	return
}

func (dr *dockerRunnerImpl) startDockerDaemon() error {

	// dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 --storage-driver=$STORAGE_DRIVER &
	log.Debug().Msg("Starting docker daemon...")
	args := []string{"--host=unix:///var/run/docker.sock", "--host=tcp://0.0.0.0:2375", "--storage-driver=overlay2"}
	dockerDaemonCommand := exec.Command("dockerd", args...)
	dockerDaemonCommand.Stdout = log.Logger
	dockerDaemonCommand.Stderr = log.Logger
	err := dockerDaemonCommand.Start()
	if err != nil {
		return err
	}

	return nil
}

func (dr *dockerRunnerImpl) waitForDockerDaemon() {

	// wait until /var/run/docker.sock exists
	log.Debug().Msg("Waiting for docker daemon to be ready for use...")
	for {
		if _, err := os.Stat("/var/run/docker.sock"); os.IsNotExist(err) {
			// does not exist
			time.Sleep(1000 * time.Millisecond)
		} else {
			// file exists, break out of for loop
			break
		}
	}
	log.Debug().Msg("Docker daemon is ready for use")
}
<commit_msg>log string instead of bytes<commit_after>package main

import (
	"bufio"
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/network"
	"github.com/docker/docker/client"
	manifest "github.com/estafette/estafette-ci-manifest"

	"github.com/rs/zerolog/log"
)

// DockerRunner pulls and runs docker containers
type DockerRunner interface {
	isDockerImagePulled(manifest.EstafettePipeline) bool
	runDockerPull(manifest.EstafettePipeline) error
	getDockerImageSize(manifest.EstafettePipeline) (int64, error)
	runDockerRun(string, map[string]string, manifest.EstafettePipeline) ([]buildJobLogLine, int64, error)
	startDockerDaemon() error
	waitForDockerDaemon()
}

type dockerRunnerImpl struct {
	envvarHelper EnvvarHelper
}

// NewDockerRunner returns a new DockerRunner
func NewDockerRunner(envvarHelper EnvvarHelper) DockerRunner {
	return &dockerRunnerImpl{
		envvarHelper: envvarHelper,
	}
}

func (dr *dockerRunnerImpl) isDockerImagePulled(p manifest.EstafettePipeline) bool {

	log.Info().Msgf("[%v] Checking if docker image '%v' exists locally...", p.Name, p.ContainerImage)

	cli, err := client.NewEnvClient()
	if err != nil {
		return false
	}

	imageSummaries, err := cli.ImageList(context.Background(), types.ImageListOptions{})

	for _, summary := range imageSummaries {
		if contains(summary.RepoTags, p.ContainerImage) {
			return true
		}
	}

	return false
}

func (dr *dockerRunnerImpl) runDockerPull(p manifest.EstafettePipeline) (err error) {

	log.Info().Msgf("[%v] Pulling docker image '%v'", p.Name, p.ContainerImage)

	cli, err := client.NewEnvClient()
	if err != nil {
		return err
	}

	rc, err := cli.ImagePull(context.Background(), p.ContainerImage, types.ImagePullOptions{})
	if err != nil {
		return err
	}
	defer rc.Close()

	// wait for image pull to finish
	_, err = ioutil.ReadAll(rc)
	if err != nil {
		return err
	}

	return
}

func (dr *dockerRunnerImpl) getDockerImageSize(p manifest.EstafettePipeline) (totalSize int64, err error) {

	cli, err := client.NewEnvClient()
	if err != nil {
		return totalSize, err
	}

	items, err := cli.ImageHistory(context.Background(), p.ContainerImage)
	if err != nil {
		return totalSize, err
	}

	for _, item := range items {
		totalSize += item.Size
	}

	return totalSize, nil
}

func (dr *dockerRunnerImpl) runDockerRun(dir string, envvars map[string]string, p manifest.EstafettePipeline) (logLines []buildJobLogLine, exitCode int64, err error) {

	logLines = make([]buildJobLogLine, 0)
	exitCode = -1

	// run docker with image and commands from yaml
	ctx := context.Background()
	cli, err := client.NewEnvClient()
	if err != nil {
		return
	}

	// define commands
	cmdSlice := make([]string, 0)
	cmdSlice = append(cmdSlice, "set -e;"+strings.Join(p.Commands, ";"))

	// add custom properties as ESTAFETTE_EXTENSION_... envvar
	extensionEnvVars := map[string]string{}
	if p.CustomProperties != nil && len(p.CustomProperties) > 0 {
		for k, v := range p.CustomProperties {
			extensionkey := dr.envvarHelper.getEstafetteEnvvarName(fmt.Sprintf("ESTAFETTE_EXTENSION_%v", dr.envvarHelper.toUpperSnake(k)))

			if s, isString := v.(string); isString {
				// if custom property is of type string add the envvar
				extensionEnvVars[extensionkey] = os.Expand(s, dr.envvarHelper.getEstafetteEnv)
			} else if s, isBool := v.(bool); isBool {
				// if custom property is of type bool add the envvar
				extensionEnvVars[extensionkey] = os.Expand(strconv.FormatBool(s), dr.envvarHelper.getEstafetteEnv)
			} else if s, isInt := v.(int); isInt {
				// if custom property is of type bool add the envvar
				extensionEnvVars[extensionkey] = os.Expand(strconv.FormatInt(int64(s), 10), dr.envvarHelper.getEstafetteEnv)
			} else if i, isInterfaceArray := v.([]interface{}); isInterfaceArray {
				// check whether all array items are of type string
				valid := true
				stringValues := []string{}
				for _, iv := range i {
					if s, isString := iv.(string); isString {
						stringValues = append(stringValues, s)
					} else {
						valid = false
						break
					}
				}

				if valid {
					// if all array items are string, pass as comma-separated list to extension
					extensionEnvVars[extensionkey] = os.Expand(strings.Join(stringValues, ","), dr.envvarHelper.getEstafetteEnv)
				} else {
					log.Warn().Interface("customProperty", v).Msgf("Cannot turn custom property %v into extension envvar", k)
				}
			} else {
				log.Warn().Interface("customProperty", v).Msgf("Cannot turn custom property %v into extension envvar", k)
			}
		}
	}

	// combine and override estafette and global envvars with pipeline envvars
	combinedEnvVars := dr.envvarHelper.overrideEnvvars(envvars, p.EnvVars, extensionEnvVars)

	// decrypt secrets
	combinedEnvVars = dr.envvarHelper.decryptSecrets(combinedEnvVars)

	// define docker envvars
	dockerEnvVars := make([]string, 0)
	if combinedEnvVars != nil && len(combinedEnvVars) > 0 {
		for k, v := range combinedEnvVars {
			dockerEnvVars = append(dockerEnvVars, fmt.Sprintf("%v=%v", k, v))
		}
	}

	// define entrypoint
	entrypoint := make([]string, 0)
	entrypoint = append(entrypoint, p.Shell)
	entrypoint = append(entrypoint, "-c")

	// define binds
	binds := make([]string, 0)
	if runtime.GOOS != "windows" {
		binds = append(binds, fmt.Sprintf("%v:%v", dir, os.Expand(p.WorkingDirectory, dr.envvarHelper.getEstafetteEnv)))
	}
	if ok, _ := pathExists("/var/run/docker.sock"); ok {
		binds = append(binds, "/var/run/docker.sock:/var/run/docker.sock")
	}
	if ok, _ := pathExists("/var/run/secrets/kubernetes.io/serviceaccount"); ok {
		binds = append(binds, "/var/run/secrets/kubernetes.io/serviceaccount:/var/run/secrets/kubernetes.io/serviceaccount")
	}

	// define config
	config := container.Config{
		AttachStdout: true,
		AttachStderr: true,
		Env:          dockerEnvVars,
		Image:        p.ContainerImage,
		WorkingDir:   os.Expand(p.WorkingDirectory, dr.envvarHelper.getEstafetteEnv),
	}
	if len(p.Commands) > 0 {
		// only pass commands when they are set, so extensions can work without
		config.Cmd = cmdSlice
		// only override entrypoint when commands are set, so extensions can work without commands
		config.Entrypoint = entrypoint
	}

	// create container
	resp, err := cli.ContainerCreate(ctx, &config, &container.HostConfig{
		Binds:      binds,
		AutoRemove: true,
		Privileged: true,
	}, &network.NetworkingConfig{}, "")
	if err != nil {
		return
	}

	// start container
	if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
		return logLines, exitCode, err
	}

	// follow logs
	rc, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{
		ShowStdout: true,
		ShowStderr: true,
		Follow:     true,
	})
	defer rc.Close()
	if err != nil {
		return
	}

	// stream logs to stdout with buffering
	in := bufio.NewReader(rc)
	var readError error
	for {

		// strip first 8 bytes, they contain docker control characters (https://github.com/docker/docker/issues/7375)
		logLine, readError := in.ReadBytes('\n')

		if readError != nil {
			break
		}

		logType := "stdout"
		if len(logLine) > 8 {

			headers := []byte(logLine[0:8])

			// first byte contains the streamType
			// -   0: stdin (will be written on stdout)
			// -   1: stdout
			// -   2: stderr
			streamType := headers[0]

			if streamType == 2 {
				logType = "stderr"
			}

			logLine = logLine[8:]
		}

		if logType == "stderr" {
			log.Info().Msgf("[%v] %v", p.Name, string(logLine))
		} else {
			log.Info().Msgf("[%v] %v", p.Name, string(logLine))
		}

		logLines = append(logLines, buildJobLogLine{
			timestamp: time.Now().UTC(),
			logLevel:  logType,
			logText:   string(logLine),
		})
	}

	if readError != nil && readError != io.EOF {
		log.Error().Msgf("[%v] Error: %v", p.Name, readError)
		return logLines, exitCode, readError
	}

	// wait for container to stop run
	exitCode, err = cli.ContainerWait(ctx, resp.ID)
	if err != nil {
		return
	}

	if exitCode != 0 {
		return logLines, exitCode, fmt.Errorf("Failed with exit code: %v", exitCode)
	}

	return
}

func (dr *dockerRunnerImpl) startDockerDaemon() error {

	// dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 --storage-driver=$STORAGE_DRIVER &
	log.Debug().Msg("Starting docker daemon...")
	args := []string{"--host=unix:///var/run/docker.sock", "--host=tcp://0.0.0.0:2375", "--storage-driver=overlay2"}
	dockerDaemonCommand := exec.Command("dockerd", args...)
	dockerDaemonCommand.Stdout = log.Logger
	dockerDaemonCommand.Stderr = log.Logger
	err := dockerDaemonCommand.Start()
	if err != nil {
		return err
	}

	return nil
}

func (dr *dockerRunnerImpl) waitForDockerDaemon() {

	// wait until /var/run/docker.sock exists
	log.Debug().Msg("Waiting for docker daemon to be ready for use...")
	for {
		if _, err := os.Stat("/var/run/docker.sock"); os.IsNotExist(err) {
			// does not exist
			time.Sleep(1000 * time.Millisecond)
		} else {
			// file exists, break out of for loop
			break
		}
	}
	log.Debug().Msg("Docker daemon is ready for use")
}
<|endoftext|>


<commit_before>//+build !windows

package daemon // import "github.com/docker/docker/daemon"

import (
	"context"
	"fmt"
	"os/exec"
	"regexp"
	"strconv"
	"strings"

	"github.com/docker/docker/api/types/container"
)

func validatePSArgs(psArgs string) error {
	// NOTE: \\s does not detect unicode whitespaces.
	// So we use fieldsASCII instead of strings.Fields in parsePSOutput.
	// See https://github.com/docker/docker/pull/24358
	// nolint: gosimple
	re := regexp.MustCompile("\\s+([^\\s]*)=\\s*(PID[^\\s]*)")
	for _, group := range re.FindAllStringSubmatch(psArgs, -1) {
		if len(group) >= 3 {
			k := group[1]
			v := group[2]
			if k != "pid" {
				return fmt.Errorf("specifying \"%s=%s\" is not allowed", k, v)
			}
		}
	}
	return nil
}

// fieldsASCII is similar to strings.Fields but only allows ASCII whitespaces
func fieldsASCII(s string) []string {
	fn := func(r rune) bool {
		switch r {
		case '\t', '\n', '\f', '\r', ' ':
			return true
		}
		return false
	}
	return strings.FieldsFunc(s, fn)
}

func appendProcess2ProcList(procList *container.ContainerTopOKBody, fields []string) {
	// Make sure number of fields equals number of header titles
	// merging "overhanging" fields
	process := fields[:len(procList.Titles)-1]
	process = append(process, strings.Join(fields[len(procList.Titles)-1:], " "))
	procList.Processes = append(procList.Processes, process)
}

func hasPid(procs []uint32, pid int) bool {
	for _, p := range procs {
		if int(p) == pid {
			return true
		}
	}
	return false
}

func parsePSOutput(output []byte, procs []uint32) (*container.ContainerTopOKBody, error) {
	procList := &container.ContainerTopOKBody{}

	lines := strings.Split(string(output), "\n")
	procList.Titles = fieldsASCII(lines[0])

	pidIndex := -1
	for i, name := range procList.Titles {
		if name == "PID" {
			pidIndex = i
			break
		}
	}
	if pidIndex == -1 {
		return nil, fmt.Errorf("Couldn't find PID field in ps output")
	}

	// loop through the output and extract the PID from each line
	// fixing #30580, be able to display thread line also when "m" option used
	// in "docker top" client command
	preContainedPidFlag := false
	for _, line := range lines[1:] {
		if len(line) == 0 {
			continue
		}
		fields := fieldsASCII(line)

		var (
			p   int
			err error
		)

		if fields[pidIndex] == "-" {
			if preContainedPidFlag {
				appendProcess2ProcList(procList, fields)
			}
			continue
		}
		p, err = strconv.Atoi(fields[pidIndex])
		if err != nil {
			return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
		}

		if hasPid(procs, p) {
			preContainedPidFlag = true
			appendProcess2ProcList(procList, fields)
			continue
		}
		preContainedPidFlag = false
	}
	return procList, nil
}

// ContainerTop lists the processes running inside of the given
// container by calling ps with the given args, or with the flags
// "-ef" if no args are given.  An error is returned if the container
// is not found, or is not running, or if there are any problems
// running ps, or parsing the output.
func (daemon *Daemon) ContainerTop(name string, psArgs string) (*container.ContainerTopOKBody, error) {
	if psArgs == "" {
		psArgs = "-ef"
	}

	if err := validatePSArgs(psArgs); err != nil {
		return nil, err
	}

	container, err := daemon.GetContainer(name)
	if err != nil {
		return nil, err
	}

	if !container.IsRunning() {
		return nil, errNotRunning(container.ID)
	}

	if container.IsRestarting() {
		return nil, errContainerIsRestarting(container.ID)
	}

	procs, err := daemon.containerd.ListPids(context.Background(), container.ID)
	if err != nil {
		return nil, err
	}

	output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output()
	if err != nil {
		return nil, fmt.Errorf("Error running ps: %v", err)
	}
	procList, err := parsePSOutput(output, procs)
	if err != nil {
		return nil, err
	}
	daemon.LogContainerEvent(container, "top")
	return procList, nil
}
<commit_msg>ContainerTop: speed up<commit_after>//+build !windows

package daemon // import "github.com/docker/docker/daemon"

import (
	"context"
	"fmt"
	"os/exec"
	"regexp"
	"strconv"
	"strings"

	"github.com/docker/docker/api/types/container"
)

func validatePSArgs(psArgs string) error {
	// NOTE: \\s does not detect unicode whitespaces.
	// So we use fieldsASCII instead of strings.Fields in parsePSOutput.
	// See https://github.com/docker/docker/pull/24358
	// nolint: gosimple
	re := regexp.MustCompile("\\s+([^\\s]*)=\\s*(PID[^\\s]*)")
	for _, group := range re.FindAllStringSubmatch(psArgs, -1) {
		if len(group) >= 3 {
			k := group[1]
			v := group[2]
			if k != "pid" {
				return fmt.Errorf("specifying \"%s=%s\" is not allowed", k, v)
			}
		}
	}
	return nil
}

// fieldsASCII is similar to strings.Fields but only allows ASCII whitespaces
func fieldsASCII(s string) []string {
	fn := func(r rune) bool {
		switch r {
		case '\t', '\n', '\f', '\r', ' ':
			return true
		}
		return false
	}
	return strings.FieldsFunc(s, fn)
}

func appendProcess2ProcList(procList *container.ContainerTopOKBody, fields []string) {
	// Make sure number of fields equals number of header titles
	// merging "overhanging" fields
	process := fields[:len(procList.Titles)-1]
	process = append(process, strings.Join(fields[len(procList.Titles)-1:], " "))
	procList.Processes = append(procList.Processes, process)
}

func hasPid(procs []uint32, pid int) bool {
	for _, p := range procs {
		if int(p) == pid {
			return true
		}
	}
	return false
}

func parsePSOutput(output []byte, procs []uint32) (*container.ContainerTopOKBody, error) {
	procList := &container.ContainerTopOKBody{}

	lines := strings.Split(string(output), "\n")
	procList.Titles = fieldsASCII(lines[0])

	pidIndex := -1
	for i, name := range procList.Titles {
		if name == "PID" {
			pidIndex = i
			break
		}
	}
	if pidIndex == -1 {
		return nil, fmt.Errorf("Couldn't find PID field in ps output")
	}

	// loop through the output and extract the PID from each line
	// fixing #30580, be able to display thread line also when "m" option used
	// in "docker top" client command
	preContainedPidFlag := false
	for _, line := range lines[1:] {
		if len(line) == 0 {
			continue
		}
		fields := fieldsASCII(line)

		var (
			p   int
			err error
		)

		if fields[pidIndex] == "-" {
			if preContainedPidFlag {
				appendProcess2ProcList(procList, fields)
			}
			continue
		}
		p, err = strconv.Atoi(fields[pidIndex])
		if err != nil {
			return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
		}

		if hasPid(procs, p) {
			preContainedPidFlag = true
			appendProcess2ProcList(procList, fields)
			continue
		}
		preContainedPidFlag = false
	}
	return procList, nil
}

// psPidsArg converts a slice of PIDs to a string consisting
// of comma-separated list of PIDs prepended by "-q".
// For example, psPidsArg([]uint32{1,2,3}) returns "-q1,2,3".
func psPidsArg(pids []uint32) string {
	b := []byte{'-', 'q'}
	for i, p := range pids {
		b = strconv.AppendUint(b, uint64(p), 10)
		if i < len(pids)-1 {
			b = append(b, ',')
		}
	}
	return string(b)
}

// ContainerTop lists the processes running inside of the given
// container by calling ps with the given args, or with the flags
// "-ef" if no args are given.  An error is returned if the container
// is not found, or is not running, or if there are any problems
// running ps, or parsing the output.
func (daemon *Daemon) ContainerTop(name string, psArgs string) (*container.ContainerTopOKBody, error) {
	if psArgs == "" {
		psArgs = "-ef"
	}

	if err := validatePSArgs(psArgs); err != nil {
		return nil, err
	}

	container, err := daemon.GetContainer(name)
	if err != nil {
		return nil, err
	}

	if !container.IsRunning() {
		return nil, errNotRunning(container.ID)
	}

	if container.IsRestarting() {
		return nil, errContainerIsRestarting(container.ID)
	}

	procs, err := daemon.containerd.ListPids(context.Background(), container.ID)
	if err != nil {
		return nil, err
	}

	args := strings.Split(psArgs, " ")
	pids := psPidsArg(procs)
	output, err := exec.Command("ps", append(args, pids)...).Output()
	if err != nil {
		// some ps options (such as f) can't be used together with q,
		// so retry without it
		output, err = exec.Command("ps", args...).Output()
		if err != nil {
			return nil, fmt.Errorf("Error running ps: %v", err)
		}
	}
	procList, err := parsePSOutput(output, procs)
	if err != nil {
		return nil, err
	}
	daemon.LogContainerEvent(container, "top")
	return procList, nil
}
<|endoftext|>


<commit_before>package main // import "github.com/boivie/lovebeat"

import (
	"flag"
	"fmt"
	"github.com/boivie/lovebeat/alert"
	"github.com/boivie/lovebeat/backend"
	"github.com/boivie/lovebeat/config"
	"github.com/boivie/lovebeat/dashboard"
	"github.com/boivie/lovebeat/eventbus"
	"github.com/boivie/lovebeat/httpapi"
	"github.com/boivie/lovebeat/metrics"
	"github.com/boivie/lovebeat/service"
	"github.com/boivie/lovebeat/tcpapi"
	"github.com/boivie/lovebeat/udpapi"
	"github.com/gorilla/mux"
	"github.com/op/go-logging"
	"log/syslog"
	"net/http"
	"os"
	"os/signal"
	"runtime"
	"strings"
	"syscall"
)

var log = logging.MustGetLogger("lovebeat")

const (
	VERSION = "0.8.0"
)

var (
	debug       = flag.Bool("debug", false, "Enable debug logs")
	showVersion = flag.Bool("version", false, "Print version string")
	cfgFile     = flag.String("config", "/etc/lovebeat.cfg", "Configuration file")
	cfgDir      = flag.String("config-dir", "", "Configuration directory")
	useSyslog   = flag.Bool("syslog", false, "Log to syslog instead of stderr")
)

var (
	signalchan = make(chan os.Signal, 1)
)

func signalHandler(be backend.Backend) {
	for {
		select {
		case sig := <-signalchan:
			fmt.Printf("!! Caught signal %d... shutting down\n", sig)
			be.Sync()
			return
		}
	}
}

func httpServer(cfg *config.ConfigBind, svcs *service.Services) {
	rtr := mux.NewRouter()
	httpapi.Register(rtr, svcs.GetClient())
	dashboard.Register(rtr, svcs.GetClient())
	http.Handle("/", rtr)
	log.Info("HTTP listening on %s\n", cfg.Listen)
	http.ListenAndServe(cfg.Listen, nil)
}

func getHostname() string {
	var hostname, err = os.Hostname()
	if err != nil {
		return fmt.Sprintf("unknown_%d", os.Getpid())
	}
	return strings.Split(hostname, ".")[0]
}

func main() {
	flag.Parse()

	if *debug {
		logging.SetLevel(logging.DEBUG, "lovebeat")
	} else {
		logging.SetLevel(logging.INFO, "lovebeat")
	}
	if *useSyslog {
		var backend, err = logging.NewSyslogBackendPriority("lovebeat", syslog.LOG_DAEMON)
		if err != nil {
			panic(err)
		}
		logging.SetBackend(logging.AddModuleLevel(backend))
	} else {
		var format = logging.MustStringFormatter("%{level} %{message}")
		logging.SetFormatter(format)
	}
	log.Debug("Debug logs enabled")

	if *showVersion {
		fmt.Printf("lovebeats v%s (built w/%s)\n", VERSION, runtime.Version())
		return
	}

	var hostname = getHostname()
	wd, _ := os.Getwd()
	log.Info("Lovebeat v%s started as host %s, PID %d, running from %s", VERSION, hostname, os.Getpid(), wd)

	var cfg = config.ReadConfig(*cfgFile, *cfgDir)
	bus := eventbus.New()

	m := metrics.New(&cfg.Metrics)

	service.RegisterMetrics(bus, m)
	var be = backend.NewFileBackend(&cfg.Database, m)
	var svcs = service.NewServices(be, bus)

	alert.RegisterAlerters(bus, cfg)

	signal.Notify(signalchan, syscall.SIGTERM)
	signal.Notify(signalchan, os.Interrupt)

	go svcs.Monitor(cfg)
	go httpServer(&cfg.Http, svcs)
	go udpapi.Listener(&cfg.Udp, svcs.GetClient())
	go tcpapi.Listener(&cfg.Tcp, svcs.GetClient())

	m.IncCounter("started.count")

	signalHandler(be)
}
<commit_msg>Setting default config directory value<commit_after>package main // import "github.com/boivie/lovebeat"

import (
	"flag"
	"fmt"
	"github.com/boivie/lovebeat/alert"
	"github.com/boivie/lovebeat/backend"
	"github.com/boivie/lovebeat/config"
	"github.com/boivie/lovebeat/dashboard"
	"github.com/boivie/lovebeat/eventbus"
	"github.com/boivie/lovebeat/httpapi"
	"github.com/boivie/lovebeat/metrics"
	"github.com/boivie/lovebeat/service"
	"github.com/boivie/lovebeat/tcpapi"
	"github.com/boivie/lovebeat/udpapi"
	"github.com/gorilla/mux"
	"github.com/op/go-logging"
	"log/syslog"
	"net/http"
	"os"
	"os/signal"
	"runtime"
	"strings"
	"syscall"
)

var log = logging.MustGetLogger("lovebeat")

const (
	VERSION = "0.8.0"
)

var (
	debug       = flag.Bool("debug", false, "Enable debug logs")
	showVersion = flag.Bool("version", false, "Print version string")
	cfgFile     = flag.String("config", "/etc/lovebeat.cfg", "Configuration file")
	cfgDir      = flag.String("config-dir", "/etc/lovebeat.conf.d", "Configuration directory")
	useSyslog   = flag.Bool("syslog", false, "Log to syslog instead of stderr")
)

var (
	signalchan = make(chan os.Signal, 1)
)

func signalHandler(be backend.Backend) {
	for {
		select {
		case sig := <-signalchan:
			fmt.Printf("!! Caught signal %d... shutting down\n", sig)
			be.Sync()
			return
		}
	}
}

func httpServer(cfg *config.ConfigBind, svcs *service.Services) {
	rtr := mux.NewRouter()
	httpapi.Register(rtr, svcs.GetClient())
	dashboard.Register(rtr, svcs.GetClient())
	http.Handle("/", rtr)
	log.Info("HTTP listening on %s\n", cfg.Listen)
	http.ListenAndServe(cfg.Listen, nil)
}

func getHostname() string {
	var hostname, err = os.Hostname()
	if err != nil {
		return fmt.Sprintf("unknown_%d", os.Getpid())
	}
	return strings.Split(hostname, ".")[0]
}

func main() {
	flag.Parse()

	if *debug {
		logging.SetLevel(logging.DEBUG, "lovebeat")
	} else {
		logging.SetLevel(logging.INFO, "lovebeat")
	}
	if *useSyslog {
		var backend, err = logging.NewSyslogBackendPriority("lovebeat", syslog.LOG_DAEMON)
		if err != nil {
			panic(err)
		}
		logging.SetBackend(logging.AddModuleLevel(backend))
	} else {
		var format = logging.MustStringFormatter("%{level} %{message}")
		logging.SetFormatter(format)
	}
	log.Debug("Debug logs enabled")

	if *showVersion {
		fmt.Printf("lovebeats v%s (built w/%s)\n", VERSION, runtime.Version())
		return
	}

	var hostname = getHostname()
	wd, _ := os.Getwd()
	log.Info("Lovebeat v%s started as host %s, PID %d, running from %s", VERSION, hostname, os.Getpid(), wd)

	var cfg = config.ReadConfig(*cfgFile, *cfgDir)
	bus := eventbus.New()

	m := metrics.New(&cfg.Metrics)

	service.RegisterMetrics(bus, m)
	var be = backend.NewFileBackend(&cfg.Database, m)
	var svcs = service.NewServices(be, bus)

	alert.RegisterAlerters(bus, cfg)

	signal.Notify(signalchan, syscall.SIGTERM)
	signal.Notify(signalchan, os.Interrupt)

	go svcs.Monitor(cfg)
	go httpServer(&cfg.Http, svcs)
	go udpapi.Listener(&cfg.Udp, svcs.GetClient())
	go tcpapi.Listener(&cfg.Tcp, svcs.GetClient())

	m.IncCounter("started.count")

	signalHandler(be)
}
<|endoftext|>


<commit_before>package wireup

import (
	"fmt"
	"net/http"
	"net/url"
	"time"

	sdk "github.com/smartystreets/smartystreets-go-sdk"
	internal "github.com/smartystreets/smartystreets-go-sdk/internal/sdk"
	"github.com/smartystreets/smartystreets-go-sdk/us-street-api"
	"github.com/smartystreets/smartystreets-go-sdk/us-zipcode-api"
)

// ClientBuilder is responsible for accepting credentials and other configuration options to combine
// all components necessary to assemble a fully functional Client for use in an application.
type ClientBuilder struct {
	credential sdk.Credential
	baseURL    *url.URL
	retries    int
	timeout    time.Duration
	debug      bool
	headers    http.Header
}

// NewClientBuilder creates a new client builder, ready to receive calls to its chain-able methods.
func NewClientBuilder() *ClientBuilder {
	return &ClientBuilder{
		credential: &internal.NopCredential{},
		retries:    4,
		timeout:    time.Second * 10,
		headers:    initializeHeadersWithUserAgent(),
	}
}

func initializeHeadersWithUserAgent() http.Header {
	headers := make(http.Header)
	headers.Add("User-Agent", fmt.Sprintf("smartystreets (sdk:go@%s)", sdk.VERSION))
	return headers
}

// WithSecretKeyCredential allows the caller to set the authID and authToken for use with the client.
// In all but very few cases calling this method with a valid authID and authToken is required.
func (b *ClientBuilder) WithSecretKeyCredential(authID, authToken string) *ClientBuilder {
	b.credential = &sdk.SecretKeyCredential{AuthID: authID, AuthToken: authToken}
	return b
}

// WithSecretKeyCredential allows the caller to specify the url that the client will use.
// In all but very few use cases the default value is sufficient and this method should not be called.
// The address provided should be a url that consists of only the scheme and host. Any other elements
// (such as a path, query string, or fragment) will be ignored.
func (b *ClientBuilder) WithCustomBaseURL(address string) *ClientBuilder {
	parsed, err := url.Parse(address)
	if err != nil {
		panic(fmt.Sprint("Could not parse provided address:", err.Error()))
	}
	b.baseURL = parsed
	return b
}

// WithMaxRetry allows the caller to specify the number of times an API request will be resent in the
// case of network errors or unexpected results.
func (b *ClientBuilder) WithMaxRetry(retries int) *ClientBuilder {
	if retries < 0 {
		panic(fmt.Sprintf("Please provide a non-negative number of retry attempts (you supplied %d).", retries))
	}
	b.retries = retries
	return b
}

// WithTimeout allows the caller to specify the timeout for all API requests.
func (b *ClientBuilder) WithTimeout(duration time.Duration) *ClientBuilder {
	if duration < 0 {
		panic(fmt.Sprintf("Please provide a non-negative duration (you supplied %s).", duration.String()))
	}
	b.timeout = duration
	return b
}

// WithDebugHTTPOutput enables detailed HTTP request/response logging using functions from net/http/httputil.
func (b *ClientBuilder) WithDebugHTTPOutput() *ClientBuilder {
	b.debug = true
	return b
}

// WithCustomHeader ensures the provided header is added to every API request made with the resulting client.
func (b *ClientBuilder) WithCustomHeader(key, value string) *ClientBuilder {
	b.headers.Add(key, value)
	return b
}

// BuildUSStreetAPIClient builds the us-street-api client using the provided
// configuration details provided by other methods on the ClientBuilder.
func (b *ClientBuilder) BuildUSStreetAPIClient() *street.Client {
	b.ensureBaseURLNotNil(defaultBaseURL_USStreetAPI)
	return street.NewClient(b.buildHTTPSender())
}

// BuildUSZIPCodeAPIClient builds the us-zipcode-api client using the provided
// configuration details provided by other methods on the ClientBuilder.
func (b *ClientBuilder) BuildUSZIPCodeAPIClient() *zipcode.Client {
	b.ensureBaseURLNotNil(defaultBaseURL_USZIPCodeAPI)
	return zipcode.NewClient(b.buildHTTPSender())
}

func (b *ClientBuilder) ensureBaseURLNotNil(u *url.URL) {
	if b.baseURL == nil {
		b.baseURL = u
	}
}

func (b *ClientBuilder) buildHTTPSender() *internal.HTTPSender {
	client := b.buildHTTPClient()
	return internal.NewHTTPSender(client)
}

func (b *ClientBuilder) buildHTTPClient() (wrapped internal.HTTPClient) {
	wrapped = &http.Client{Timeout: b.timeout}
	wrapped = internal.NewDebugOutputClient(wrapped, b.debug)
	wrapped = internal.NewRetryClient(wrapped, b.retries)
	wrapped = internal.NewSigningClient(wrapped, b.credential)
	wrapped = internal.NewBaseURLClient(wrapped, b.baseURL)
	wrapped = internal.NewCustomHeadersClient(wrapped, b.headers)
	return wrapped
}

var (
	defaultBaseURL_USStreetAPI, _  = url.Parse("https://api.smartystreets.com")
	defaultBaseURL_USZIPCodeAPI, _ = url.Parse("https://us-zipcode.api.smartystreets.com")
)
<commit_msg>Now using updated hostname for us-street-api.<commit_after>package wireup

import (
	"fmt"
	"net/http"
	"net/url"
	"time"

	sdk "github.com/smartystreets/smartystreets-go-sdk"
	internal "github.com/smartystreets/smartystreets-go-sdk/internal/sdk"
	"github.com/smartystreets/smartystreets-go-sdk/us-street-api"
	"github.com/smartystreets/smartystreets-go-sdk/us-zipcode-api"
)

// ClientBuilder is responsible for accepting credentials and other configuration options to combine
// all components necessary to assemble a fully functional Client for use in an application.
type ClientBuilder struct {
	credential sdk.Credential
	baseURL    *url.URL
	retries    int
	timeout    time.Duration
	debug      bool
	headers    http.Header
}

// NewClientBuilder creates a new client builder, ready to receive calls to its chain-able methods.
func NewClientBuilder() *ClientBuilder {
	return &ClientBuilder{
		credential: &internal.NopCredential{},
		retries:    4,
		timeout:    time.Second * 10,
		headers:    initializeHeadersWithUserAgent(),
	}
}

func initializeHeadersWithUserAgent() http.Header {
	headers := make(http.Header)
	headers.Add("User-Agent", fmt.Sprintf("smartystreets (sdk:go@%s)", sdk.VERSION))
	return headers
}

// WithSecretKeyCredential allows the caller to set the authID and authToken for use with the client.
// In all but very few cases calling this method with a valid authID and authToken is required.
func (b *ClientBuilder) WithSecretKeyCredential(authID, authToken string) *ClientBuilder {
	b.credential = &sdk.SecretKeyCredential{AuthID: authID, AuthToken: authToken}
	return b
}

// WithSecretKeyCredential allows the caller to specify the url that the client will use.
// In all but very few use cases the default value is sufficient and this method should not be called.
// The address provided should be a url that consists of only the scheme and host. Any other elements
// (such as a path, query string, or fragment) will be ignored.
func (b *ClientBuilder) WithCustomBaseURL(address string) *ClientBuilder {
	parsed, err := url.Parse(address)
	if err != nil {
		panic(fmt.Sprint("Could not parse provided address:", err.Error()))
	}
	b.baseURL = parsed
	return b
}

// WithMaxRetry allows the caller to specify the number of times an API request will be resent in the
// case of network errors or unexpected results.
func (b *ClientBuilder) WithMaxRetry(retries int) *ClientBuilder {
	if retries < 0 {
		panic(fmt.Sprintf("Please provide a non-negative number of retry attempts (you supplied %d).", retries))
	}
	b.retries = retries
	return b
}

// WithTimeout allows the caller to specify the timeout for all API requests.
func (b *ClientBuilder) WithTimeout(duration time.Duration) *ClientBuilder {
	if duration < 0 {
		panic(fmt.Sprintf("Please provide a non-negative duration (you supplied %s).", duration.String()))
	}
	b.timeout = duration
	return b
}

// WithDebugHTTPOutput enables detailed HTTP request/response logging using functions from net/http/httputil.
func (b *ClientBuilder) WithDebugHTTPOutput() *ClientBuilder {
	b.debug = true
	return b
}

// WithCustomHeader ensures the provided header is added to every API request made with the resulting client.
func (b *ClientBuilder) WithCustomHeader(key, value string) *ClientBuilder {
	b.headers.Add(key, value)
	return b
}

// BuildUSStreetAPIClient builds the us-street-api client using the provided
// configuration details provided by other methods on the ClientBuilder.
func (b *ClientBuilder) BuildUSStreetAPIClient() *street.Client {
	b.ensureBaseURLNotNil(defaultBaseURL_USStreetAPI)
	return street.NewClient(b.buildHTTPSender())
}

// BuildUSZIPCodeAPIClient builds the us-zipcode-api client using the provided
// configuration details provided by other methods on the ClientBuilder.
func (b *ClientBuilder) BuildUSZIPCodeAPIClient() *zipcode.Client {
	b.ensureBaseURLNotNil(defaultBaseURL_USZIPCodeAPI)
	return zipcode.NewClient(b.buildHTTPSender())
}

func (b *ClientBuilder) ensureBaseURLNotNil(u *url.URL) {
	if b.baseURL == nil {
		b.baseURL = u
	}
}

func (b *ClientBuilder) buildHTTPSender() *internal.HTTPSender {
	client := b.buildHTTPClient()
	return internal.NewHTTPSender(client)
}

func (b *ClientBuilder) buildHTTPClient() (wrapped internal.HTTPClient) {
	wrapped = &http.Client{Timeout: b.timeout}
	wrapped = internal.NewDebugOutputClient(wrapped, b.debug)
	wrapped = internal.NewRetryClient(wrapped, b.retries)
	wrapped = internal.NewSigningClient(wrapped, b.credential)
	wrapped = internal.NewBaseURLClient(wrapped, b.baseURL)
	wrapped = internal.NewCustomHeadersClient(wrapped, b.headers)
	return wrapped
}

var (
	defaultBaseURL_USStreetAPI, _  = url.Parse("https://us-street.api.smartystreets.com")
	defaultBaseURL_USZIPCodeAPI, _ = url.Parse("https://us-zipcode.api.smartystreets.com")
)
<|endoftext|>


<commit_before>package ivy

import (
	"bytes"
	"github.com/stretchr/testify/assert"
	"image"
	"image/png"
	"testing"
)

func TestGMProcess(t *testing.T) {
	buffer := new(bytes.Buffer)
	png.Encode(buffer, image.NewRGBA(image.Rect(0, 0, 200, 200)))

	gm := NewGMProcessor()
	params, _ := ParseParams("r_100x100,c_50x50,g_c,q_50")
	img, err := gm.Process(params, "text.png", buffer)
	assert.NoError(t, err)
	assert.NotNil(t, img)
	assert.True(t, img.Len() > 0)

	params, _ = ParseParams("r_100x0,c_50x50,g_c,q_50")
	img, err = gm.Process(params, "text.png", buffer)
	assert.NoError(t, err)
	assert.NotNil(t, img)
	assert.True(t, img.Len() > 0)

	params, _ = ParseParams("r_0x100,c_50x50,g_c,q_50")
	img, err = gm.Process(params, "text.png", buffer)
	assert.NoError(t, err)
	assert.NotNil(t, img)
	assert.True(t, img.Len() > 0)
}

func TestGMGetGravity(t *testing.T) {
	gm := NewGMProcessor()
	assert.Equal(t, "NorthWest", gm.getGravity("nw"))
	assert.Equal(t, "North", gm.getGravity("n"))
	assert.Equal(t, "NorthEast", gm.getGravity("ne"))
	assert.Equal(t, "West", gm.getGravity("w"))
	assert.Equal(t, "Center", gm.getGravity("c"))
	assert.Equal(t, "East", gm.getGravity("e"))
	assert.Equal(t, "SouthWest", gm.getGravity("sw"))
	assert.Equal(t, "South", gm.getGravity("s"))
	assert.Equal(t, "SouthEast", gm.getGravity("se"))
	assert.Equal(t, "NorthWest", gm.getGravity("xx"))
}
<commit_msg>fix test<commit_after>package ivy

import (
	"bytes"
	"github.com/stretchr/testify/assert"
	"image"
	"image/png"
	"testing"
)

func TestGMProcess(t *testing.T) {
	buffer := new(bytes.Buffer)
	png.Encode(buffer, image.NewRGBA(image.Rect(0, 0, 200, 200)))

	gm := NewGMProcessor()
	params, _ := ParseParams("r_100x100,c_50x50,g_c,q_50")
	img, err := gm.Process(params, "text.png", buffer)
	assert.NoError(t, err)
	assert.NotNil(t, img)
	assert.True(t, img.Len() > 0)

	buffer = new(bytes.Buffer)
	png.Encode(buffer, image.NewRGBA(image.Rect(0, 0, 200, 200)))
	params, _ = ParseParams("r_100x0,c_50x50,g_c,q_50")
	img, err = gm.Process(params, "text.png", buffer)
	assert.NoError(t, err)
	assert.NotNil(t, img)
	assert.True(t, img.Len() > 0)

	buffer = new(bytes.Buffer)
	png.Encode(buffer, image.NewRGBA(image.Rect(0, 0, 200, 200)))
	params, _ = ParseParams("r_0x100,c_50x50,g_c,q_50")
	img, err = gm.Process(params, "text.png", buffer)
	assert.NoError(t, err)
	assert.NotNil(t, img)
	assert.True(t, img.Len() > 0)
}

func TestGMGetGravity(t *testing.T) {
	gm := NewGMProcessor()
	assert.Equal(t, "NorthWest", gm.getGravity("nw"))
	assert.Equal(t, "North", gm.getGravity("n"))
	assert.Equal(t, "NorthEast", gm.getGravity("ne"))
	assert.Equal(t, "West", gm.getGravity("w"))
	assert.Equal(t, "Center", gm.getGravity("c"))
	assert.Equal(t, "East", gm.getGravity("e"))
	assert.Equal(t, "SouthWest", gm.getGravity("sw"))
	assert.Equal(t, "South", gm.getGravity("s"))
	assert.Equal(t, "SouthEast", gm.getGravity("se"))
	assert.Equal(t, "NorthWest", gm.getGravity("xx"))
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/fzzy/radix/redis"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
)

type ConfigStruct struct {
	RedisNetwork  string
	RedisAddress  string
	RedisQueueKey string
	Tasks         []TaskStruct
	ErrorCmd      string
}

type TaskStruct struct {
	Type    string
	Script  string
	Workers int
}

type QueueTaskStruct struct {
	Args []string
}

var verbose bool

func init() {
	flag.BoolVar(&verbose, "v", false, "enable verbose/debugging output")
	flag.Parse()
}

func main() {
	basepath := Basepath{}
	err := basepath.Update()
	if err != nil {
		log.Fatal("basepath.Update(): ", err)
	}

	config, err := getConfig(basepath.GetAbsWith("./goophry.config.json"))
	if err != nil {
		log.Fatal("getConfig(): ", err)
	}

	var wg sync.WaitGroup

	for _, task := range config.Tasks {
		debugOutput(fmt.Sprintf("Creating %d workers for type %s", task.Workers, task.Type))
		queue := make(chan QueueTaskStruct)

		task.Script = basepath.GetAbsWith(task.Script)

		for i := 0; i < task.Workers; i++ {
			wg.Add(1)
			go taskWorker(config, task, queue)
			debugOutput("Created worker for type " + task.Type)
		}

		go taskQueueWorker(config, task, queue)
		debugOutput("Created queue worker for type " + task.Type)
	}

	wg.Wait()
}

func debugOutput(msg string) {
	if verbose == true {
		log.Println(msg)
	}
}

func getBasePath() (path string, err error) {
	path, err = filepath.Abs(filepath.Dir(os.Args[0]))
	return
}

func getConfig(path string) (c ConfigStruct, err error) {
	file, err := os.Open(path)
	if err != nil {
		return
	}
	defer file.Close()

	parser := json.NewDecoder(file)
	err = parser.Decode(&c)
	return
}

func taskWorker(config ConfigStruct, task TaskStruct, queue chan QueueTaskStruct) {
	for t := range queue {
		debugOutput("Executing task for type " + task.Type)
		err := executeTask(task.Script, t.Args)
		if err != nil {
			errorCmdTask(config.ErrorCmd, task.Script, t.Args, err)
		}
	}
}

func taskQueueWorker(config ConfigStruct, task TaskStruct, queue chan QueueTaskStruct) {
	rc, err := redis.Dial(config.RedisNetwork, config.RedisAddress)
	if err != nil {
		log.Fatal("redis.Dial(): ", err)
	}
	defer rc.Close()

	queueKey := config.RedisQueueKey + ":" + task.Type

	for {
		values, err := rc.Cmd("BLPOP", queueKey, 0).List()
		if err != nil {
			errorCmdRedis(config.ErrorCmd, err)
			continue
		}
		if len(values) == 0 {
			continue
		}

		for _, value := range values {
			if value == queueKey {
				continue
			}

			debugOutput("Task from redis: " + value)

			t, err := parseQueueTask(value)
			if err != nil {
				errorCmd(config.ErrorCmd, fmt.Sprintf("parseQueueTask(): ", err))
				continue
			}

			debugOutput("Sending task for type " + task.Type)
			queue <- t
		}
	}
}

func parseQueueTask(value string) (task QueueTaskStruct, err error) {
	reader := strings.NewReader(value)
	parser := json.NewDecoder(reader)
	err = parser.Decode(&task)
	return
}

func executeTask(script string, args []string) error {
	out, err := exec.Command(script, args...).Output()

	if len(out) != 0 && err == nil {
		err = fmt.Errorf("%s", out)
	}

	return err
}

func errorCmdTask(cmd string, script string, args []string, err error) {
	msg := fmt.Sprintf("%s %s\n\n%s", script, strings.Join(args, " "), err)
	errorCmd(cmd, msg)
}

func errorCmdRedis(cmd string, err error) {
	msg := fmt.Sprintf("Redis Error:\n%s", err)
	errorCmd(cmd, msg)
}

func errorCmd(cmd string, msg string) {
	debugOutput(fmt.Sprintf("Calling ErrorCmd with: %s", msg))

	cmdExec := fmt.Sprintf(cmd, strconv.Quote(msg))
	out, err := exec.Command("sh", "-c", cmdExec).Output()

	if len(out) != 0 && err == nil {
		log.Println(fmt.Sprintf("Error calling ErrorCmd:\n%s\n\nOutput:\n%s", cmdExec, out))
	}

	if err != nil {
		log.Println(fmt.Sprintf("Error calling ErrorCmd:\n%s", err))
	}
}

type Basepath struct {
	Path string
}

func (b *Basepath) Update() (err error) {
	b.Path, err = filepath.Abs(filepath.Dir(os.Args[0]))
	return
}

func (b Basepath) GetAbsWith(file string) (string) {
	if !filepath.IsAbs(file) {
		file = b.Path + "/" + file
	}
	return file
}
<commit_msg>improved handling of redis-errors<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/fzzy/radix/redis"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
)

type ConfigStruct struct {
	RedisNetwork  string
	RedisAddress  string
	RedisQueueKey string
	Tasks         []TaskStruct
	ErrorCmd      string
}

type TaskStruct struct {
	Type    string
	Script  string
	Workers int
}

type QueueTaskStruct struct {
	Args []string
}

var verbose bool

func init() {
	flag.BoolVar(&verbose, "v", false, "enable verbose/debugging output")
	flag.Parse()
}

func main() {
	basepath := Basepath{}
	err := basepath.Update()
	if err != nil {
		log.Fatal("basepath.Update(): ", err)
	}

	config, err := getConfig(basepath.GetAbsWith("./goophry.config.json"))
	if err != nil {
		log.Fatal("getConfig(): ", err)
	}

	var wg sync.WaitGroup

	for _, task := range config.Tasks {
		debugOutput(fmt.Sprintf("Creating %d workers for type %s", task.Workers, task.Type))
		queue := make(chan QueueTaskStruct)

		task.Script = basepath.GetAbsWith(task.Script)

		for i := 0; i < task.Workers; i++ {
			wg.Add(1)
			go taskWorker(config, task, queue, &wg)
			debugOutput("Created worker for type " + task.Type)
		}

		wg.Add(1)
		go taskQueueWorker(config, task, queue, &wg)
		debugOutput("Created queue worker for type " + task.Type)
	}

	wg.Wait()
}

func debugOutput(msg string) {
	if verbose == true {
		log.Println(msg)
	}
}

func getBasePath() (path string, err error) {
	path, err = filepath.Abs(filepath.Dir(os.Args[0]))
	return
}

func getConfig(path string) (c ConfigStruct, err error) {
	file, err := os.Open(path)
	if err != nil {
		return
	}
	defer file.Close()

	parser := json.NewDecoder(file)
	err = parser.Decode(&c)
	return
}

func taskWorker(config ConfigStruct, task TaskStruct, queue chan QueueTaskStruct, wg *sync.WaitGroup) {
	for t := range queue {
		debugOutput("Executing task for type " + task.Type)
		err := executeTask(task.Script, t.Args)
		if err != nil {
			errorCmdTask(config.ErrorCmd, task.Script, t.Args, err)
		}
	}

	wg.Done()
}

func taskQueueWorker(config ConfigStruct, task TaskStruct, queue chan QueueTaskStruct, wg *sync.WaitGroup) {
	rc, err := redis.Dial(config.RedisNetwork, config.RedisAddress)
	if err != nil {
		log.Fatal("redis.Dial(): ", err)
	}
	defer rc.Close()

	queueKey := config.RedisQueueKey + ":" + task.Type

	for {
		values, err := rc.Cmd("BLPOP", queueKey, 0).List()
		if err != nil {
			errorCmdRedis(config.ErrorCmd, task.Type, err)
			break
		}
		if len(values) == 0 {
			continue
		}

		for _, value := range values {
			if value == queueKey {
				continue
			}

			debugOutput("Task from redis: " + value)

			t, err := parseQueueTask(value)
			if err != nil {
				errorCmd(config.ErrorCmd, fmt.Sprintf("parseQueueTask(): ", err))
				continue
			}

			debugOutput("Sending task for type " + task.Type)
			queue <- t
		}
	}

	close(queue)
	wg.Done()
}

func parseQueueTask(value string) (task QueueTaskStruct, err error) {
	reader := strings.NewReader(value)
	parser := json.NewDecoder(reader)
	err = parser.Decode(&task)
	return
}

func executeTask(script string, args []string) error {
	out, err := exec.Command(script, args...).Output()

	if len(out) != 0 && err == nil {
		err = fmt.Errorf("%s", out)
	}

	return err
}

func errorCmdTask(cmd string, script string, args []string, err error) {
	msg := fmt.Sprintf("%s %s\n\n%s", script, strings.Join(args, " "), err)
	errorCmd(cmd, msg)
}

func errorCmdRedis(cmd string, tt string, err error) {
	msg := fmt.Sprintf("Redis Error:\n%s\nStopping task %s.", err, tt)
	errorCmd(cmd, msg)
}

func errorCmd(cmd string, msg string) {
	debugOutput(fmt.Sprintf("Calling ErrorCmd with: %s", msg))

	cmdExec := fmt.Sprintf(cmd, strconv.Quote(msg))
	out, err := exec.Command("sh", "-c", cmdExec).Output()

	if len(out) != 0 && err == nil {
		log.Println(fmt.Sprintf("Error calling ErrorCmd:\n%s\n\nOutput:\n%s", cmdExec, out))
	}

	if err != nil {
		log.Println(fmt.Sprintf("Error calling ErrorCmd:\n%s", err))
	}
}

type Basepath struct {
	Path string
}

func (b *Basepath) Update() (err error) {
	b.Path, err = filepath.Abs(filepath.Dir(os.Args[0]))
	return
}

func (b Basepath) GetAbsWith(file string) (string) {
	if !filepath.IsAbs(file) {
		file = b.Path + "/" + file
	}
	return file
}
<|endoftext|>


<commit_before>package main

import (
	"math/rand"
	"os"
	"time"

	"github.com/canonical/go-dqlite"
	"github.com/spf13/cobra"

	"github.com/lxc/lxd/lxd/daemon"
	"github.com/lxc/lxd/lxd/events"
	"github.com/lxc/lxd/lxd/operations"
	"github.com/lxc/lxd/lxd/response"
	"github.com/lxc/lxd/lxd/rsync"
	"github.com/lxc/lxd/shared/logger"
	"github.com/lxc/lxd/shared/logging"
	"github.com/lxc/lxd/shared/version"
)

// Initialize the random number generator
func init() {
	rand.Seed(time.Now().UTC().UnixNano())
}

type cmdGlobal struct {
	cmd *cobra.Command

	flagHelp    bool
	flagVersion bool

	flagLogFile    string
	flagLogDebug   bool
	flagLogSyslog  bool
	flagLogTrace   []string
	flagLogVerbose bool
}

func (c *cmdGlobal) Run(cmd *cobra.Command, args []string) error {
	// Configure dqlite to *not* disable internal SQLite locking, since we
	// use SQLite both through dqlite and through go-dqlite, potentially
	// from different threads at the same time. We need to call this
	// function as early as possible since this is a global setting in
	// SQLite, which can't be changed afterwise.
	err := dqlite.ConfigMultiThread()
	if err != nil {
		return err
	}

	// Set logging global variables
	daemon.Debug = c.flagLogDebug
	rsync.Debug = c.flagLogDebug
	daemon.Verbose = c.flagLogVerbose

	// Set debug for the operations package
	operations.Init(daemon.Debug)

	// Set debug for the response package
	response.Init(daemon.Verbose)

	// Setup logger
	syslog := ""
	if c.flagLogSyslog {
		syslog = "lxd"
	}

	log, err := logging.GetLogger(syslog, c.flagLogFile, c.flagLogVerbose, c.flagLogDebug, events.NewEventHandler())
	if err != nil {
		return err
	}
	logger.Log = log

	return nil
}

// rawArgs returns the raw unprocessed arguments from os.Args after the command name arg is found.
func (c *cmdGlobal) rawArgs(cmd *cobra.Command) []string {
	for i, arg := range os.Args {
		if arg == cmd.Name() && len(os.Args)-1 > i {
			return os.Args[i+1:]
		}
	}

	return []string{}
}

func main() {
	// daemon command (main)
	daemonCmd := cmdDaemon{}
	app := daemonCmd.Command()
	app.SilenceUsage = true
	app.CompletionOptions = cobra.CompletionOptions{DisableDefaultCmd: true}

	// Workaround for main command
	app.Args = cobra.ArbitraryArgs

	// Global flags
	globalCmd := cmdGlobal{cmd: app}
	daemonCmd.global = &globalCmd
	app.PersistentPreRunE = globalCmd.Run
	app.PersistentFlags().BoolVar(&globalCmd.flagVersion, "version", false, "Print version number")
	app.PersistentFlags().BoolVarP(&globalCmd.flagHelp, "help", "h", false, "Print help")
	app.PersistentFlags().StringVar(&globalCmd.flagLogFile, "logfile", "", "Path to the log file"+"``")
	app.PersistentFlags().BoolVar(&globalCmd.flagLogSyslog, "syslog", false, "Log to syslog")
	app.PersistentFlags().StringArrayVar(&globalCmd.flagLogTrace, "trace", []string{}, "Log tracing targets"+"``")
	app.PersistentFlags().BoolVarP(&globalCmd.flagLogDebug, "debug", "d", false, "Show all debug messages")
	app.PersistentFlags().BoolVarP(&globalCmd.flagLogVerbose, "verbose", "v", false, "Show all information messages")

	// Version handling
	app.SetVersionTemplate("{{.Version}}\n")
	app.Version = version.Version

	// activateifneeded sub-command
	activateifneededCmd := cmdActivateifneeded{global: &globalCmd}
	app.AddCommand(activateifneededCmd.Command())

	// callhook sub-command
	callhookCmd := cmdCallhook{global: &globalCmd}
	app.AddCommand(callhookCmd.Command())

	// forkconsole sub-command
	forkconsoleCmd := cmdForkconsole{global: &globalCmd}
	app.AddCommand(forkconsoleCmd.Command())

	// forkdns sub-command
	forkDNSCmd := cmdForkDNS{global: &globalCmd}
	app.AddCommand(forkDNSCmd.Command())

	// forkexec sub-command
	forkexecCmd := cmdForkexec{global: &globalCmd}
	app.AddCommand(forkexecCmd.Command())

	// forkfile sub-command
	forkfileCmd := cmdForkfile{global: &globalCmd}
	app.AddCommand(forkfileCmd.Command())

	// forklimits sub-command
	forklimitsCmd := cmdForklimits{global: &globalCmd}
	app.AddCommand(forklimitsCmd.Command())

	// forkmigrate sub-command
	forkmigrateCmd := cmdForkmigrate{global: &globalCmd}
	app.AddCommand(forkmigrateCmd.Command())

	// forksyscall sub-command
	forksyscallCmd := cmdForksyscall{global: &globalCmd}
	app.AddCommand(forksyscallCmd.Command())

	// forkmount sub-command
	forkmountCmd := cmdForkmount{global: &globalCmd}
	app.AddCommand(forkmountCmd.Command())

	// forknet sub-command
	forknetCmd := cmdForknet{global: &globalCmd}
	app.AddCommand(forknetCmd.Command())

	// forkproxy sub-command
	forkproxyCmd := cmdForkproxy{global: &globalCmd}
	app.AddCommand(forkproxyCmd.Command())

	// forkstart sub-command
	forkstartCmd := cmdForkstart{global: &globalCmd}
	app.AddCommand(forkstartCmd.Command())

	// forkuevent sub-command
	forkueventCmd := cmdForkuevent{global: &globalCmd}
	app.AddCommand(forkueventCmd.Command())

	// forkzfs sub-command
	forkzfsCmd := cmdForkZFS{global: &globalCmd}
	app.AddCommand(forkzfsCmd.Command())

	// import sub-command
	importCmd := cmdImport{global: &globalCmd}
	app.AddCommand(importCmd.Command())

	// init sub-command
	initCmd := cmdInit{global: &globalCmd}
	app.AddCommand(initCmd.Command())

	// manpage sub-command
	manpageCmd := cmdManpage{global: &globalCmd}
	app.AddCommand(manpageCmd.Command())

	// migratedumpsuccess sub-command
	migratedumpsuccessCmd := cmdMigratedumpsuccess{global: &globalCmd}
	app.AddCommand(migratedumpsuccessCmd.Command())

	// netcat sub-command
	netcatCmd := cmdNetcat{global: &globalCmd}
	app.AddCommand(netcatCmd.Command())

	// recover sub-command
	recoverCmd := cmdRecover{global: &globalCmd}
	app.AddCommand(recoverCmd.Command())

	// shutdown sub-command
	shutdownCmd := cmdShutdown{global: &globalCmd}
	app.AddCommand(shutdownCmd.Command())

	// sql sub-command
	sqlCmd := cmdSql{global: &globalCmd}
	app.AddCommand(sqlCmd.Command())

	// version sub-command
	versionCmd := cmdVersion{global: &globalCmd}
	app.AddCommand(versionCmd.Command())

	// waitready sub-command
	waitreadyCmd := cmdWaitready{global: &globalCmd}
	app.AddCommand(waitreadyCmd.Command())

	// cluster sub-command
	clusterCmd := cmdCluster{global: &globalCmd}
	app.AddCommand(clusterCmd.Command())

	// Run the main command and handle errors
	err := app.Execute()
	if err != nil {
		os.Exit(1)
	}
}
<commit_msg>lxd/main: Set response debug mode based on --debug flag<commit_after>package main

import (
	"math/rand"
	"os"
	"time"

	"github.com/canonical/go-dqlite"
	"github.com/spf13/cobra"

	"github.com/lxc/lxd/lxd/daemon"
	"github.com/lxc/lxd/lxd/events"
	"github.com/lxc/lxd/lxd/operations"
	"github.com/lxc/lxd/lxd/response"
	"github.com/lxc/lxd/lxd/rsync"
	"github.com/lxc/lxd/shared/logger"
	"github.com/lxc/lxd/shared/logging"
	"github.com/lxc/lxd/shared/version"
)

// Initialize the random number generator
func init() {
	rand.Seed(time.Now().UTC().UnixNano())
}

type cmdGlobal struct {
	cmd *cobra.Command

	flagHelp    bool
	flagVersion bool

	flagLogFile    string
	flagLogDebug   bool
	flagLogSyslog  bool
	flagLogTrace   []string
	flagLogVerbose bool
}

func (c *cmdGlobal) Run(cmd *cobra.Command, args []string) error {
	// Configure dqlite to *not* disable internal SQLite locking, since we
	// use SQLite both through dqlite and through go-dqlite, potentially
	// from different threads at the same time. We need to call this
	// function as early as possible since this is a global setting in
	// SQLite, which can't be changed afterwise.
	err := dqlite.ConfigMultiThread()
	if err != nil {
		return err
	}

	// Set logging global variables
	daemon.Debug = c.flagLogDebug
	rsync.Debug = c.flagLogDebug
	daemon.Verbose = c.flagLogVerbose

	// Set debug for the operations package
	operations.Init(daemon.Debug)

	// Set debug for the response package
	response.Init(daemon.Debug)

	// Setup logger
	syslog := ""
	if c.flagLogSyslog {
		syslog = "lxd"
	}

	log, err := logging.GetLogger(syslog, c.flagLogFile, c.flagLogVerbose, c.flagLogDebug, events.NewEventHandler())
	if err != nil {
		return err
	}
	logger.Log = log

	return nil
}

// rawArgs returns the raw unprocessed arguments from os.Args after the command name arg is found.
func (c *cmdGlobal) rawArgs(cmd *cobra.Command) []string {
	for i, arg := range os.Args {
		if arg == cmd.Name() && len(os.Args)-1 > i {
			return os.Args[i+1:]
		}
	}

	return []string{}
}

func main() {
	// daemon command (main)
	daemonCmd := cmdDaemon{}
	app := daemonCmd.Command()
	app.SilenceUsage = true
	app.CompletionOptions = cobra.CompletionOptions{DisableDefaultCmd: true}

	// Workaround for main command
	app.Args = cobra.ArbitraryArgs

	// Global flags
	globalCmd := cmdGlobal{cmd: app}
	daemonCmd.global = &globalCmd
	app.PersistentPreRunE = globalCmd.Run
	app.PersistentFlags().BoolVar(&globalCmd.flagVersion, "version", false, "Print version number")
	app.PersistentFlags().BoolVarP(&globalCmd.flagHelp, "help", "h", false, "Print help")
	app.PersistentFlags().StringVar(&globalCmd.flagLogFile, "logfile", "", "Path to the log file"+"``")
	app.PersistentFlags().BoolVar(&globalCmd.flagLogSyslog, "syslog", false, "Log to syslog")
	app.PersistentFlags().StringArrayVar(&globalCmd.flagLogTrace, "trace", []string{}, "Log tracing targets"+"``")
	app.PersistentFlags().BoolVarP(&globalCmd.flagLogDebug, "debug", "d", false, "Show all debug messages")
	app.PersistentFlags().BoolVarP(&globalCmd.flagLogVerbose, "verbose", "v", false, "Show all information messages")

	// Version handling
	app.SetVersionTemplate("{{.Version}}\n")
	app.Version = version.Version

	// activateifneeded sub-command
	activateifneededCmd := cmdActivateifneeded{global: &globalCmd}
	app.AddCommand(activateifneededCmd.Command())

	// callhook sub-command
	callhookCmd := cmdCallhook{global: &globalCmd}
	app.AddCommand(callhookCmd.Command())

	// forkconsole sub-command
	forkconsoleCmd := cmdForkconsole{global: &globalCmd}
	app.AddCommand(forkconsoleCmd.Command())

	// forkdns sub-command
	forkDNSCmd := cmdForkDNS{global: &globalCmd}
	app.AddCommand(forkDNSCmd.Command())

	// forkexec sub-command
	forkexecCmd := cmdForkexec{global: &globalCmd}
	app.AddCommand(forkexecCmd.Command())

	// forkfile sub-command
	forkfileCmd := cmdForkfile{global: &globalCmd}
	app.AddCommand(forkfileCmd.Command())

	// forklimits sub-command
	forklimitsCmd := cmdForklimits{global: &globalCmd}
	app.AddCommand(forklimitsCmd.Command())

	// forkmigrate sub-command
	forkmigrateCmd := cmdForkmigrate{global: &globalCmd}
	app.AddCommand(forkmigrateCmd.Command())

	// forksyscall sub-command
	forksyscallCmd := cmdForksyscall{global: &globalCmd}
	app.AddCommand(forksyscallCmd.Command())

	// forkmount sub-command
	forkmountCmd := cmdForkmount{global: &globalCmd}
	app.AddCommand(forkmountCmd.Command())

	// forknet sub-command
	forknetCmd := cmdForknet{global: &globalCmd}
	app.AddCommand(forknetCmd.Command())

	// forkproxy sub-command
	forkproxyCmd := cmdForkproxy{global: &globalCmd}
	app.AddCommand(forkproxyCmd.Command())

	// forkstart sub-command
	forkstartCmd := cmdForkstart{global: &globalCmd}
	app.AddCommand(forkstartCmd.Command())

	// forkuevent sub-command
	forkueventCmd := cmdForkuevent{global: &globalCmd}
	app.AddCommand(forkueventCmd.Command())

	// forkzfs sub-command
	forkzfsCmd := cmdForkZFS{global: &globalCmd}
	app.AddCommand(forkzfsCmd.Command())

	// import sub-command
	importCmd := cmdImport{global: &globalCmd}
	app.AddCommand(importCmd.Command())

	// init sub-command
	initCmd := cmdInit{global: &globalCmd}
	app.AddCommand(initCmd.Command())

	// manpage sub-command
	manpageCmd := cmdManpage{global: &globalCmd}
	app.AddCommand(manpageCmd.Command())

	// migratedumpsuccess sub-command
	migratedumpsuccessCmd := cmdMigratedumpsuccess{global: &globalCmd}
	app.AddCommand(migratedumpsuccessCmd.Command())

	// netcat sub-command
	netcatCmd := cmdNetcat{global: &globalCmd}
	app.AddCommand(netcatCmd.Command())

	// recover sub-command
	recoverCmd := cmdRecover{global: &globalCmd}
	app.AddCommand(recoverCmd.Command())

	// shutdown sub-command
	shutdownCmd := cmdShutdown{global: &globalCmd}
	app.AddCommand(shutdownCmd.Command())

	// sql sub-command
	sqlCmd := cmdSql{global: &globalCmd}
	app.AddCommand(sqlCmd.Command())

	// version sub-command
	versionCmd := cmdVersion{global: &globalCmd}
	app.AddCommand(versionCmd.Command())

	// waitready sub-command
	waitreadyCmd := cmdWaitready{global: &globalCmd}
	app.AddCommand(waitreadyCmd.Command())

	// cluster sub-command
	clusterCmd := cmdCluster{global: &globalCmd}
	app.AddCommand(clusterCmd.Command())

	// Run the main command and handle errors
	err := app.Execute()
	if err != nil {
		os.Exit(1)
	}
}
<|endoftext|>