<commit_before>package uaa_test

import (
	"net/http"
	"time"

	"golang.org/x/oauth2"

	"code.cloudfoundry.org/lager/lagertest"
	. "github.com/concourse/atc/auth/uaa"
	"github.com/concourse/atc/auth/verifier"
	"github.com/dgrijalva/jwt-go"

	"github.com/onsi/gomega/ghttp"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("SpaceVerifier", func() {
	var verifier verifier.Verifier
	var cfAPIServer *ghttp.Server
	var httpClient *http.Client
	var verified bool
	var verifyErr error
	var jwtToken *jwt.Token
	var nextPageCalled bool

	BeforeEach(func() {
		nextPageCalled = false
		cfAPIServer = ghttp.NewServer()

		verifier = NewSpaceVerifier(
			[]string{"myspace-guid-1", "myspace-guid-2"},
			cfAPIServer.URL(),
		)

		jwtToken = jwt.New(jwt.SigningMethodHS256)
		jwtToken.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()

		accessToken, err := jwtToken.SigningString()
		Expect(err).NotTo(HaveOccurred())

		oauthToken := &oauth2.Token{
			AccessToken: accessToken,
		}
		c := &oauth2.Config{}
		httpClient = c.Client(oauth2.NoContext, oauthToken)
	})

	JustBeforeEach(func() {
		verified, verifyErr = verifier.Verify(lagertest.NewTestLogger("test"), httpClient)
	})

	Context("when token does not contain 'user_id'", func() {
		It("user is not verified", func() {
			Expect(verified).To(BeFalse())
			Expect(verifyErr).To(HaveOccurred())
		})
	})

	Context("when token contains 'user_id'", func() {
		BeforeEach(func() {
			jwtToken.Claims["user_id"] = "my-user-id"

			accessToken, err := jwtToken.SigningString()
			Expect(err).NotTo(HaveOccurred())

			oauthToken := &oauth2.Token{
				AccessToken: accessToken,
			}
			c := &oauth2.Config{}
			httpClient = c.Client(oauth2.NoContext, oauthToken)
		})

		Context("when user is a space developer", func() {
			BeforeEach(func() {
				firstPageResponse := `{
				"next_url": "/next-url",
				"resources": [
						{
							"metadata": {
								"guid": "other-user-id-1"
							}
						},
						{
							"metadata": {
								"guid": "another-user-id"
							}
						}
					]
				}`
				spaceDevelopersResponse := `{
				"next_url": "null",
				"resources": [
						{
							"metadata": {
								"guid": "other-user-id-2"
							}
						},
						{
							"metadata": {
								"guid": "my-user-id"
							}
						}
					]
				}`
				cfAPIServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-1/developers", "results-per-page=100"),
						ghttp.RespondWith(http.StatusOK, `{}`),
					),
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-2/developers", "results-per-page=100"),
						ghttp.RespondWith(http.StatusOK, firstPageResponse),
					),
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/next-url"),
						func(w http.ResponseWriter, req *http.Request) {
							nextPageCalled = true
							w.Write([]byte(spaceDevelopersResponse))
						},
					),
				)
			})

			It("returns true", func() {
				Expect(verifyErr).NotTo(HaveOccurred())
				Expect(verified).To(BeTrue())
			})

			It("follows next page", func() {
				Expect(nextPageCalled).To(BeTrue())
			})
		})

		Context("when user is not a space developer", func() {
			BeforeEach(func() {
				spaceDevelopersResponse := `{
					"resources": [
						{
							"metadata": {
								"guid": "unknown-user-id"
							}
						}
					]
				}`
				cfAPIServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-1/developers", "results-per-page=100"),
						ghttp.RespondWith(http.StatusOK, spaceDevelopersResponse),
					),
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-2/developers", "results-per-page=100"),
						func(w http.ResponseWriter, req *http.Request) {
							nextPageCalled = true
							w.Write([]byte(spaceDevelopersResponse))
						},
					),
				)
			})

			It("returns false", func() {
				Expect(verifyErr).NotTo(HaveOccurred())
				Expect(verified).To(BeFalse())
				Expect(nextPageCalled).To(BeTrue())
			})
		})

		Context("when CF API responds with error code", func() {
			BeforeEach(func() {
				cfAPIServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-1/developers", "results-per-page=100"),
						ghttp.RespondWith(http.StatusUnauthorized, ""),
					),
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-2/developers", "results-per-page=100"),
						func(w http.ResponseWriter, req *http.Request) {
							nextPageCalled = true
						},
					),
				)
			})

			It("does not return error", func() {
				Expect(verifyErr).ToNot(HaveOccurred())
			})

			It("returns false", func() {
				Expect(verified).To(BeFalse())
			})

			It("makes requests to other spaces in the verifier", func() {
				Expect(nextPageCalled).To(BeTrue())
			})
		})
	})
})
<commit_msg>more claims interface updates<commit_after>package uaa_test

import (
	"net/http"
	"time"

	"golang.org/x/oauth2"

	"code.cloudfoundry.org/lager/lagertest"
	. "github.com/concourse/atc/auth/uaa"
	"github.com/concourse/atc/auth/verifier"
	"github.com/dgrijalva/jwt-go"

	"github.com/onsi/gomega/ghttp"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("SpaceVerifier", func() {
	var verifier verifier.Verifier
	var cfAPIServer *ghttp.Server
	var httpClient *http.Client
	var verified bool
	var verifyErr error
	var jwtToken *jwt.Token
	var nextPageCalled bool

	BeforeEach(func() {
		nextPageCalled = false
		cfAPIServer = ghttp.NewServer()

		verifier = NewSpaceVerifier(
			[]string{"myspace-guid-1", "myspace-guid-2"},
			cfAPIServer.URL(),
		)

		jwtToken = jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
			"exp": time.Now().Add(time.Hour * 72).Unix(),
		})

		accessToken, err := jwtToken.SigningString()
		Expect(err).NotTo(HaveOccurred())

		oauthToken := &oauth2.Token{
			AccessToken: accessToken,
		}
		c := &oauth2.Config{}
		httpClient = c.Client(oauth2.NoContext, oauthToken)
	})

	JustBeforeEach(func() {
		verified, verifyErr = verifier.Verify(lagertest.NewTestLogger("test"), httpClient)
	})

	Context("when token does not contain 'user_id'", func() {
		It("user is not verified", func() {
			Expect(verified).To(BeFalse())
			Expect(verifyErr).To(HaveOccurred())
		})
	})

	Context("when token contains 'user_id'", func() {
		BeforeEach(func() {
			jwtToken = jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
				"exp":     time.Now().Add(time.Hour * 72).Unix(),
				"user_id": "my-user-id",
			})

			accessToken, err := jwtToken.SigningString()
			Expect(err).NotTo(HaveOccurred())

			oauthToken := &oauth2.Token{
				AccessToken: accessToken,
			}
			c := &oauth2.Config{}
			httpClient = c.Client(oauth2.NoContext, oauthToken)
		})

		Context("when user is a space developer", func() {
			BeforeEach(func() {
				firstPageResponse := `{
				"next_url": "/next-url",
				"resources": [
						{
							"metadata": {
								"guid": "other-user-id-1"
							}
						},
						{
							"metadata": {
								"guid": "another-user-id"
							}
						}
					]
				}`
				spaceDevelopersResponse := `{
				"next_url": "null",
				"resources": [
						{
							"metadata": {
								"guid": "other-user-id-2"
							}
						},
						{
							"metadata": {
								"guid": "my-user-id"
							}
						}
					]
				}`
				cfAPIServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-1/developers", "results-per-page=100"),
						ghttp.RespondWith(http.StatusOK, `{}`),
					),
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-2/developers", "results-per-page=100"),
						ghttp.RespondWith(http.StatusOK, firstPageResponse),
					),
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/next-url"),
						func(w http.ResponseWriter, req *http.Request) {
							nextPageCalled = true
							w.Write([]byte(spaceDevelopersResponse))
						},
					),
				)
			})

			It("returns true", func() {
				Expect(verifyErr).NotTo(HaveOccurred())
				Expect(verified).To(BeTrue())
			})

			It("follows next page", func() {
				Expect(nextPageCalled).To(BeTrue())
			})
		})

		Context("when user is not a space developer", func() {
			BeforeEach(func() {
				spaceDevelopersResponse := `{
					"resources": [
						{
							"metadata": {
								"guid": "unknown-user-id"
							}
						}
					]
				}`
				cfAPIServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-1/developers", "results-per-page=100"),
						ghttp.RespondWith(http.StatusOK, spaceDevelopersResponse),
					),
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-2/developers", "results-per-page=100"),
						func(w http.ResponseWriter, req *http.Request) {
							nextPageCalled = true
							w.Write([]byte(spaceDevelopersResponse))
						},
					),
				)
			})

			It("returns false", func() {
				Expect(verifyErr).NotTo(HaveOccurred())
				Expect(verified).To(BeFalse())
				Expect(nextPageCalled).To(BeTrue())
			})
		})

		Context("when CF API responds with error code", func() {
			BeforeEach(func() {
				cfAPIServer.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-1/developers", "results-per-page=100"),
						ghttp.RespondWith(http.StatusUnauthorized, ""),
					),
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/v2/spaces/myspace-guid-2/developers", "results-per-page=100"),
						func(w http.ResponseWriter, req *http.Request) {
							nextPageCalled = true
						},
					),
				)
			})

			It("does not return error", func() {
				Expect(verifyErr).ToNot(HaveOccurred())
			})

			It("returns false", func() {
				Expect(verified).To(BeFalse())
			})

			It("makes requests to other spaces in the verifier", func() {
				Expect(nextPageCalled).To(BeTrue())
			})
		})
	})
})
<|endoftext|>


<commit_before>package contextio

import (
	"os"
	"testing"
)

func TestClient(t *testing.T) {
	key := os.Getenv("CONTEXTIOKEY")
	if len(key) == 0 {
		t.Fatal("CONTEXTIOKEY is not defined")
	}

	secret := os.Getenv("CONTEXTIOSECRET")
	if len(secret) == 0 {
		t.Fatal("CONTEXTIOSECRET is not defined")
	}

	client := New(key, secret)
	resp, err := client.Do("GET", nil, "accounts")
	if err != nil {
		t.Fatal(err)
	}

	var accounts []Account
	if err = client.Unmarshal(resp, &accounts); err != nil {
		t.Fatal(err)
	}
	for i, account := range accounts {
		t.Log("Account:", i, account.Username)
	}
}
<commit_msg>tests: Updated the tests<commit_after>package contextio

import (
	"log"
	"os"
	"testing"
)

var (
	testAccount Account
	testClient  *Client
	testKey     string
	testSecret  string
)

func init() {
	testKey = os.Getenv("CONTEXTIOKEY")
	if len(testKey) == 0 {
		log.Fatal("CONTEXTIOKEY is not defined")
	}

	testSecret = os.Getenv("CONTEXTIOSECRET")
	if len(testSecret) == 0 {
		log.Fatal("CONTEXTIOSECRET is not defined")
	}
}

func TestClient(t *testing.T) {
	testClient = New(testKey, testSecret)
	resp, err := testClient.Do("GET", nil, "accounts")
	if err != nil {
		t.Fatal(err)
	}

	var accounts []Account
	if err = testClient.Unmarshal(resp, &accounts); err != nil {
		t.Fatal(err)
	}
	for i, account := range accounts {
		t.Log("Account:", i, account.Username)
	}

	testAccount = accounts[0]
}

func TestMessages(t *testing.T) {
	resp, err := testClient.Do("GET", nil, "accounts", testAccount.Id, "messages")
	if err != nil {
		t.Fatal(err)
	}

	var messages []Message
	if err = testClient.Unmarshal(resp, &messages); err != nil {
		t.Fatal(err)
	}

	t.Log("Retrieved", len(messages), "messages")
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/schema"
)

func dataSourceAwsInstance() *schema.Resource {
	return &schema.Resource{
		Read: dataSourceAwsInstanceRead,

		Schema: map[string]*schema.Schema{
			"filter":        dataSourceFiltersSchema(),
			"tags":          tagsSchemaComputed(),
			"instance_tags": tagsSchemaComputed(),
			"instance_id": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"ami": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"instance_type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"instance_state": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"availability_zone": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"placement_group": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"tenancy": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"key_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"get_password_data": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"password_data": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"public_dns": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"public_ip": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"private_dns": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"private_ip": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"iam_instance_profile": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"subnet_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"network_interface_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"associate_public_ip_address": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"ebs_optimized": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"source_dest_check": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"monitoring": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"user_data": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"security_groups": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem: &schema.Schema{
					Type: schema.TypeString,
				},
			},
			"vpc_security_group_ids": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem: &schema.Schema{
					Type: schema.TypeString,
				},
			},
			"ephemeral_block_device": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"device_name": {
							Type:     schema.TypeString,
							Required: true,
						},

						"virtual_name": {
							Type:     schema.TypeString,
							Optional: true,
						},

						"no_device": {
							Type:     schema.TypeBool,
							Optional: true,
						},
					},
				},
			},
			"ebs_block_device": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"delete_on_termination": {
							Type:     schema.TypeBool,
							Computed: true,
						},

						"device_name": {
							Type:     schema.TypeString,
							Computed: true,
						},

						"encrypted": {
							Type:     schema.TypeBool,
							Computed: true,
						},

						"iops": {
							Type:     schema.TypeInt,
							Computed: true,
						},

						"snapshot_id": {
							Type:     schema.TypeString,
							Computed: true,
						},

						"volume_size": {
							Type:     schema.TypeInt,
							Computed: true,
						},

						"volume_type": {
							Type:     schema.TypeString,
							Computed: true,
						},

						"volume_id": {
							Type:     schema.TypeString,
							Computed: true,
						},
					},
				},
			},
			"root_block_device": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"delete_on_termination": {
							Type:     schema.TypeBool,
							Computed: true,
						},

						"iops": {
							Type:     schema.TypeInt,
							Computed: true,
						},

						"volume_size": {
							Type:     schema.TypeInt,
							Computed: true,
						},

						"volume_type": {
							Type:     schema.TypeString,
							Computed: true,
						},

						"volume_id": {
							Type:     schema.TypeString,
							Computed: true,
						},
					},
				},
			},
			"credit_specification": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"cpu_credits": {
							Type:     schema.TypeString,
							Computed: true,
						},
					},
				},
			},
		},
	}
}

// dataSourceAwsInstanceRead performs the instanceID lookup
func dataSourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	filters, filtersOk := d.GetOk("filter")
	instanceID, instanceIDOk := d.GetOk("instance_id")
	tags, tagsOk := d.GetOk("instance_tags")

	if filtersOk == false && instanceIDOk == false && tagsOk == false {
		return fmt.Errorf("One of filters, instance_tags, or instance_id must be assigned")
	}

	// Build up search parameters
	params := &ec2.DescribeInstancesInput{}
	if filtersOk {
		params.Filters = buildAwsDataSourceFilters(filters.(*schema.Set))
	}
	if instanceIDOk {
		params.InstanceIds = []*string{aws.String(instanceID.(string))}
	}
	if tagsOk {
		params.Filters = append(params.Filters, buildEC2TagFilterList(
			tagsFromMap(tags.(map[string]interface{})),
		)...)
	}

	log.Printf("[DEBUG] Reading IAM Instance: %s", params)
	resp, err := conn.DescribeInstances(params)
	if err != nil {
		return err
	}

	// If no instances were returned, return
	if len(resp.Reservations) == 0 {
		return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.")
	}

	var filteredInstances []*ec2.Instance

	// loop through reservations, and remove terminated instances, populate instance slice
	for _, res := range resp.Reservations {
		for _, instance := range res.Instances {
			if instance.State != nil && *instance.State.Name != "terminated" {
				filteredInstances = append(filteredInstances, instance)
			}
		}
	}

	var instance *ec2.Instance
	if len(filteredInstances) < 1 {
		return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.")
	}

	// (TODO: Support a list of instances to be returned)
	// Possibly with a different data source that returns a list of individual instance data sources
	if len(filteredInstances) > 1 {
		return fmt.Errorf("Your query returned more than one result. Please try a more " +
			"specific search criteria.")
	} else {
		instance = filteredInstances[0]
	}

	log.Printf("[DEBUG] aws_instance - Single Instance ID found: %s", *instance.InstanceId)
	if err := instanceDescriptionAttributes(d, instance, conn); err != nil {
		return err
	}

	if d.Get("get_password_data").(bool) {
		passwordData, err := getAwsEc2InstancePasswordData(*instance.InstanceId, conn)
		if err != nil {
			return err
		}
		d.Set("password_data", passwordData)
	}

	return nil
}

// Populate instance attribute fields with the returned instance
func instanceDescriptionAttributes(d *schema.ResourceData, instance *ec2.Instance, conn *ec2.EC2) error {
	d.SetId(*instance.InstanceId)
	// Set the easy attributes
	d.Set("instance_state", instance.State.Name)
	if instance.Placement != nil {
		d.Set("availability_zone", instance.Placement.AvailabilityZone)
	}
	if instance.Placement.GroupName != nil {
		d.Set("placement_group", instance.Placement.GroupName)
	}
	if instance.Placement.Tenancy != nil {
		d.Set("tenancy", instance.Placement.Tenancy)
	}
	d.Set("ami", instance.ImageId)
	d.Set("instance_type", instance.InstanceType)
	d.Set("key_name", instance.KeyName)
	d.Set("public_dns", instance.PublicDnsName)
	d.Set("public_ip", instance.PublicIpAddress)
	d.Set("private_dns", instance.PrivateDnsName)
	d.Set("private_ip", instance.PrivateIpAddress)
	d.Set("iam_instance_profile", iamInstanceProfileArnToName(instance.IamInstanceProfile))

	// iterate through network interfaces, and set subnet, network_interface, public_addr
	if len(instance.NetworkInterfaces) > 0 {
		for _, ni := range instance.NetworkInterfaces {
			if *ni.Attachment.DeviceIndex == 0 {
				d.Set("subnet_id", ni.SubnetId)
				d.Set("network_interface_id", ni.NetworkInterfaceId)
				d.Set("associate_public_ip_address", ni.Association != nil)
			}
		}
	} else {
		d.Set("subnet_id", instance.SubnetId)
		d.Set("network_interface_id", "")
	}

	d.Set("ebs_optimized", instance.EbsOptimized)
	if instance.SubnetId != nil && *instance.SubnetId != "" {
		d.Set("source_dest_check", instance.SourceDestCheck)
	}

	if instance.Monitoring != nil && instance.Monitoring.State != nil {
		monitoringState := *instance.Monitoring.State
		d.Set("monitoring", monitoringState == "enabled" || monitoringState == "pending")
	}

	d.Set("tags", tagsToMap(instance.Tags))

	// Security Groups
	if err := readSecurityGroups(d, instance, conn); err != nil {
		return err
	}

	// Block devices
	if err := readBlockDevices(d, instance, conn); err != nil {
		return err
	}
	if _, ok := d.GetOk("ephemeral_block_device"); !ok {
		d.Set("ephemeral_block_device", []interface{}{})
	}

	// Lookup and Set Instance Attributes
	{
		attr, err := conn.DescribeInstanceAttribute(&ec2.DescribeInstanceAttributeInput{
			Attribute:  aws.String("disableApiTermination"),
			InstanceId: aws.String(d.Id()),
		})
		if err != nil {
			return err
		}
		d.Set("disable_api_termination", attr.DisableApiTermination.Value)
	}
	{
		attr, err := conn.DescribeInstanceAttribute(&ec2.DescribeInstanceAttributeInput{
			Attribute:  aws.String(ec2.InstanceAttributeNameUserData),
			InstanceId: aws.String(d.Id()),
		})
		if err != nil {
			return err
		}
		if attr.UserData.Value != nil {
			d.Set("user_data", userDataHashSum(*attr.UserData.Value))
		}
	}
	{
		creditSpecifications, err := getCreditSpecifications(conn, d.Id())
		if err != nil {
			return err
		}
		if err := d.Set("credit_specification", creditSpecifications); err != nil {
			return fmt.Errorf("error setting credit_specification: %s", err)
		}
	}

	return nil
}
<commit_msg>add missing disable_api_termination attribute<commit_after>package aws

import (
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/schema"
)

func dataSourceAwsInstance() *schema.Resource {
	return &schema.Resource{
		Read: dataSourceAwsInstanceRead,

		Schema: map[string]*schema.Schema{
			"filter":        dataSourceFiltersSchema(),
			"tags":          tagsSchemaComputed(),
			"instance_tags": tagsSchemaComputed(),
			"instance_id": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"ami": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"instance_type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"instance_state": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"availability_zone": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"placement_group": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"tenancy": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"key_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"get_password_data": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"password_data": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"public_dns": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"public_ip": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"private_dns": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"private_ip": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"iam_instance_profile": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"subnet_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"network_interface_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"associate_public_ip_address": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"ebs_optimized": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"source_dest_check": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"monitoring": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"user_data": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"security_groups": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem: &schema.Schema{
					Type: schema.TypeString,
				},
			},
			"vpc_security_group_ids": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem: &schema.Schema{
					Type: schema.TypeString,
				},
			},
			"ephemeral_block_device": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"device_name": {
							Type:     schema.TypeString,
							Required: true,
						},

						"virtual_name": {
							Type:     schema.TypeString,
							Optional: true,
						},

						"no_device": {
							Type:     schema.TypeBool,
							Optional: true,
						},
					},
				},
			},
			"ebs_block_device": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"delete_on_termination": {
							Type:     schema.TypeBool,
							Computed: true,
						},

						"device_name": {
							Type:     schema.TypeString,
							Computed: true,
						},

						"encrypted": {
							Type:     schema.TypeBool,
							Computed: true,
						},

						"iops": {
							Type:     schema.TypeInt,
							Computed: true,
						},

						"snapshot_id": {
							Type:     schema.TypeString,
							Computed: true,
						},

						"volume_size": {
							Type:     schema.TypeInt,
							Computed: true,
						},

						"volume_type": {
							Type:     schema.TypeString,
							Computed: true,
						},

						"volume_id": {
							Type:     schema.TypeString,
							Computed: true,
						},
					},
				},
			},
			"root_block_device": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"delete_on_termination": {
							Type:     schema.TypeBool,
							Computed: true,
						},

						"iops": {
							Type:     schema.TypeInt,
							Computed: true,
						},

						"volume_size": {
							Type:     schema.TypeInt,
							Computed: true,
						},

						"volume_type": {
							Type:     schema.TypeString,
							Computed: true,
						},

						"volume_id": {
							Type:     schema.TypeString,
							Computed: true,
						},
					},
				},
			},
			"credit_specification": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"cpu_credits": {
							Type:     schema.TypeString,
							Computed: true,
						},
					},
				},
			},
			"disable_api_termination": {
				Type:     schema.TypeBool,
				Computed: true,
			},
		},
	}
}

// dataSourceAwsInstanceRead performs the instanceID lookup
func dataSourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	filters, filtersOk := d.GetOk("filter")
	instanceID, instanceIDOk := d.GetOk("instance_id")
	tags, tagsOk := d.GetOk("instance_tags")

	if filtersOk == false && instanceIDOk == false && tagsOk == false {
		return fmt.Errorf("One of filters, instance_tags, or instance_id must be assigned")
	}

	// Build up search parameters
	params := &ec2.DescribeInstancesInput{}
	if filtersOk {
		params.Filters = buildAwsDataSourceFilters(filters.(*schema.Set))
	}
	if instanceIDOk {
		params.InstanceIds = []*string{aws.String(instanceID.(string))}
	}
	if tagsOk {
		params.Filters = append(params.Filters, buildEC2TagFilterList(
			tagsFromMap(tags.(map[string]interface{})),
		)...)
	}

	log.Printf("[DEBUG] Reading IAM Instance: %s", params)
	resp, err := conn.DescribeInstances(params)
	if err != nil {
		return err
	}

	// If no instances were returned, return
	if len(resp.Reservations) == 0 {
		return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.")
	}

	var filteredInstances []*ec2.Instance

	// loop through reservations, and remove terminated instances, populate instance slice
	for _, res := range resp.Reservations {
		for _, instance := range res.Instances {
			if instance.State != nil && *instance.State.Name != "terminated" {
				filteredInstances = append(filteredInstances, instance)
			}
		}
	}

	var instance *ec2.Instance
	if len(filteredInstances) < 1 {
		return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.")
	}

	// (TODO: Support a list of instances to be returned)
	// Possibly with a different data source that returns a list of individual instance data sources
	if len(filteredInstances) > 1 {
		return fmt.Errorf("Your query returned more than one result. Please try a more " +
			"specific search criteria.")
	} else {
		instance = filteredInstances[0]
	}

	log.Printf("[DEBUG] aws_instance - Single Instance ID found: %s", *instance.InstanceId)
	if err := instanceDescriptionAttributes(d, instance, conn); err != nil {
		return err
	}

	if d.Get("get_password_data").(bool) {
		passwordData, err := getAwsEc2InstancePasswordData(*instance.InstanceId, conn)
		if err != nil {
			return err
		}
		d.Set("password_data", passwordData)
	}

	return nil
}

// Populate instance attribute fields with the returned instance
func instanceDescriptionAttributes(d *schema.ResourceData, instance *ec2.Instance, conn *ec2.EC2) error {
	d.SetId(*instance.InstanceId)
	// Set the easy attributes
	d.Set("instance_state", instance.State.Name)
	if instance.Placement != nil {
		d.Set("availability_zone", instance.Placement.AvailabilityZone)
	}
	if instance.Placement.GroupName != nil {
		d.Set("placement_group", instance.Placement.GroupName)
	}
	if instance.Placement.Tenancy != nil {
		d.Set("tenancy", instance.Placement.Tenancy)
	}
	d.Set("ami", instance.ImageId)
	d.Set("instance_type", instance.InstanceType)
	d.Set("key_name", instance.KeyName)
	d.Set("public_dns", instance.PublicDnsName)
	d.Set("public_ip", instance.PublicIpAddress)
	d.Set("private_dns", instance.PrivateDnsName)
	d.Set("private_ip", instance.PrivateIpAddress)
	d.Set("iam_instance_profile", iamInstanceProfileArnToName(instance.IamInstanceProfile))

	// iterate through network interfaces, and set subnet, network_interface, public_addr
	if len(instance.NetworkInterfaces) > 0 {
		for _, ni := range instance.NetworkInterfaces {
			if *ni.Attachment.DeviceIndex == 0 {
				d.Set("subnet_id", ni.SubnetId)
				d.Set("network_interface_id", ni.NetworkInterfaceId)
				d.Set("associate_public_ip_address", ni.Association != nil)
			}
		}
	} else {
		d.Set("subnet_id", instance.SubnetId)
		d.Set("network_interface_id", "")
	}

	d.Set("ebs_optimized", instance.EbsOptimized)
	if instance.SubnetId != nil && *instance.SubnetId != "" {
		d.Set("source_dest_check", instance.SourceDestCheck)
	}

	if instance.Monitoring != nil && instance.Monitoring.State != nil {
		monitoringState := *instance.Monitoring.State
		d.Set("monitoring", monitoringState == "enabled" || monitoringState == "pending")
	}

	d.Set("tags", tagsToMap(instance.Tags))

	// Security Groups
	if err := readSecurityGroups(d, instance, conn); err != nil {
		return err
	}

	// Block devices
	if err := readBlockDevices(d, instance, conn); err != nil {
		return err
	}
	if _, ok := d.GetOk("ephemeral_block_device"); !ok {
		d.Set("ephemeral_block_device", []interface{}{})
	}

	// Lookup and Set Instance Attributes
	{
		attr, err := conn.DescribeInstanceAttribute(&ec2.DescribeInstanceAttributeInput{
			Attribute:  aws.String("disableApiTermination"),
			InstanceId: aws.String(d.Id()),
		})
		if err != nil {
			return err
		}
		d.Set("disable_api_termination", attr.DisableApiTermination.Value)
	}
	{
		attr, err := conn.DescribeInstanceAttribute(&ec2.DescribeInstanceAttributeInput{
			Attribute:  aws.String(ec2.InstanceAttributeNameUserData),
			InstanceId: aws.String(d.Id()),
		})
		if err != nil {
			return err
		}
		if attr.UserData.Value != nil {
			d.Set("user_data", userDataHashSum(*attr.UserData.Value))
		}
	}
	{
		creditSpecifications, err := getCreditSpecifications(conn, d.Id())
		if err != nil {
			return err
		}
		if err := d.Set("credit_specification", creditSpecifications); err != nil {
			return fmt.Errorf("error setting credit_specification: %s", err)
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package consul

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

	"github.com/codegangsta/cli"
	"github.com/fatih/color"
	"github.com/hashicorp/consul/api"

	"github.com/InnovaCo/serve/utils"
)

func RouteCommand() cli.Command {
	return cli.Command{
		Name:  "route",
		Usage: "Save app route to consul",
		Flags: []cli.Flag{
			cli.StringFlag{Name: "service"},
			cli.StringFlag{Name: "host"},
			cli.StringFlag{Name: "location", Value: "/"},
			cli.StringFlag{Name: "route"},
		},
		Action: func(c *cli.Context) error {
			consul, _ := api.NewClient(api.DefaultConfig())

			name := c.String("service")
			services, _, err := consul.Health().Service(name, "", true, nil)
			if err != nil {
				return err
			}

			if len(services) == 0 {
				return fmt.Errorf("Service `%s` not started!", name)
			} else {
				log.Printf("Service `%s` started with %v instances.", name, len(services))
			}

			routeFlags := make(map[string]string, 0)
			if c.IsSet("route") {
				if err := json.Unmarshal([]byte(c.String("route")), &routeFlags); err != nil {
					return err
				}
			}

			route := utils.MergeMaps(map[string]string{
				"host":     c.String("host"),
				"location": c.String("location"),
			}, routeFlags)

			routesJson, err := json.MarshalIndent([]map[string]string{route}, "", "  ")
			if err != nil {
				return err
			}

			// write routes to consul kv
			if _, err := consul.KV().Put(&api.KVPair{
				Key:   fmt.Sprintf("services/routes/%s", name),
				Value: routesJson,
			}, nil); err != nil {
				return err
			}

			log.Println(color.GreenString("Updated routes for `%s`: %s", name, string(routesJson)))

			return nil
		},
	}
}
<commit_msg>= consule route: retry check services<commit_after>package consul

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

	"github.com/codegangsta/cli"
	"github.com/fatih/color"
	"github.com/hashicorp/consul/api"
	"github.com/cenk/backoff"

	"github.com/InnovaCo/serve/utils"
)

func RouteCommand() cli.Command {
	return cli.Command{
		Name:  "route",
		Usage: "Save app route to consul",
		Flags: []cli.Flag{
			cli.StringFlag{Name: "service"},
			cli.StringFlag{Name: "host"},
			cli.StringFlag{Name: "location", Value: "/"},
			cli.StringFlag{Name: "route"},
		},
		Action: func(c *cli.Context) error {
			consul, _ := api.NewClient(api.DefaultConfig())

			name := c.String("service")

			err := backoff.Retry(func() error {
				services, _, err := consul.Health().Service(name, "", true, nil)
				if err != nil {
					log.Println(color.RedString("Error in check health in consul: %v", err))
					return err
				}

				if len(services) == 0 {
					log.Printf("Service `%s` not started yet! Retry...", name)
					return fmt.Errorf("Service `%s` not started!", name)
				} else {
					log.Printf("Service `%s` started with %v instances.", name, len(services))
					return nil
				}
			}, backoff.NewExponentialBackOff())

			if err != nil {
				return err
			}

			routeFlags := make(map[string]string, 0)
			if c.IsSet("route") {
				if err := json.Unmarshal([]byte(c.String("route")), &routeFlags); err != nil {
					return err
				}
			}

			route := utils.MergeMaps(map[string]string{
				"host":     c.String("host"),
				"location": c.String("location"),
			}, routeFlags)

			routesJson, err := json.MarshalIndent([]map[string]string{route}, "", "  ")
			if err != nil {
				return err
			}

			// write routes to consul kv
			if _, err := consul.KV().Put(&api.KVPair{
				Key:   fmt.Sprintf("services/routes/%s", name),
				Value: routesJson,
			}, nil); err != nil {
				return err
			}

			log.Println(color.GreenString("Updated routes for `%s`: %s", name, string(routesJson)))

			return nil
		},
	}
}
<|endoftext|>


<commit_before>package main

import (
	"testing"
	"io/ioutil"
	"os"
	"fmt"
)

func TestTokenizePath(t *testing.T) {
	m := map[string][]string{
		"/a/b/c":   []string{"a", "b", "c"},
		"./foo":    []string{"foo"},
		"x_y/z_a/": []string{"x_y", "z_a"},
	}
	for path, expected := range m {
		if got := TokenizePath(path); !equal(got, expected) {
			t.Errorf("%s: expected '%s', got '%s'", path, expected, got)
		}
	}
}

func TestSubpath(t *testing.T) {
	type pair struct {
		rootDir string
		file    string
	}
	m := map[pair]string{
		pair{"sub", "sub/dir"}:                         "dir",
		pair{"sub", "sub/dir/foo/"}:                    "dir/foo",
		pair{"sub", "sub/dir/foo/bar"}:                 "dir/foo/bar",
		pair{"sub/dir", "sub/dir/foo/bar"}:             "foo/bar",
		pair{"sub/dir/foo", "sub/dir/foo/bar"}:         "bar",
		pair{"sub/dir/foo/", "sub/dir/foo/bar"}:        "bar",
		pair{"/var/log", "/var/log/daemon.log"}:        "daemon.log",
		pair{"/usr///share/", "/usr/share/dict/words"}: "dict/words",
	}
	for pair, expected := range m {
		if got := Subpath(pair.rootDir, pair.file); got != expected {
			t.Errorf("%s: expected '%s', got '%s'", pair.file, expected, got)
		}
	}
}

func TestStripExtension(t *testing.T) {
	m := map[string]string{
		"foo.bar":             "foo",
		"A.long-extension":    "A",
		"beep":                "beep",
		"/some/path/file.txt": "/some/path/file",
		"./foo.x":             "./foo",
	}
	for file, expected := range m {
		if got := StripExtension(file); got != expected {
			t.Errorf("%s: expected '%s', got '%s'", file, expected, got)
		}
	}
}

func writeToTempFile(t *testing.T, contents string) string {
	f, err := ioutil.TempFile(os.TempDir(), "grender-context-test")
	if err != nil {
		t.Fatalf("%s", err)
	}
	defer f.Close()
	if _, err := f.WriteString(contents); err != nil {
		t.Fatalf("%s", err)
	}
	return f.Name()
}

func TestMergeJSON(t *testing.T) {
	m := map[string]Context{
		`{}`: Context{},
		`{"a": "b"}`: Context{
			"a": "b",
		},
		`{"array": [1,2,3]}`: Context{
			"array": []int{1, 2, 3},
		},
		`{"map": {"a":1.23}}`: Context{
			"map": map[string]float64{
				"a": 1.23,
			},
		},
		`{"x": ["a", {"b":1}, "c"]}`: Context{
			"x": []interface{}{
				"a",
				map[string]int{
					"b": 1,
				},
				"c",
			},
		},
	}
	for body, expected := range m {
		filename := writeToTempFile(t, body)
		got := Context{}
		mergeJSON(filename, got)
		if len(expected) != len(got) {
			t.Errorf("%s: expected %d, got %d", body, len(expected), len(got))
		}
		expectedStr := fmt.Sprintf("%v", expected)
		gotStr := fmt.Sprintf("%v", got)
		t.Logf("%s: expected '%s', got '%s'", body, expectedStr, gotStr)
		if expectedStr != gotStr {
			t.Errorf("%s: expected '%s', got '%s'", body, expectedStr, gotStr)
		}
	}
}

func TestMergeMarkdown(t *testing.T) {
	m := map[string]Context{
		// https://github.com/knieriem/markdown/issues/5
		// ``:  Context{MarkdownKey: ""}, // TODO ^^^
		md1: Context{MarkdownKey: html1},
	}
	for body, expected := range m {
		filename := writeToTempFile(t, body)
		got := Context{}
		mergeMarkdown(filename, got)
		if len(expected) != len(got) {
			t.Errorf("%s: expected %d, got %d", body, len(expected), len(got))
		}
		expectedStr := fmt.Sprintf("%v", expected)
		gotStr := fmt.Sprintf("%v", got)
		t.Logf("%s: expected '%s', got '%s'", body, expectedStr, gotStr)
		if expectedStr != gotStr {
			t.Errorf("%s: expected '%s', got '%s'", body, expectedStr, gotStr)
		}
	}
}

//
//
//

const md1 = `# A
Lorem _ipsum_ **dolor** sit.

Herpa derp—a derp.

## B

AT&T.
`

const html1 = `
A

Lorem ipsum dolor sit.

Herpa derp—a derp.

B

AT&T.

`
<commit_msg>Fix for Markdown issue 5<commit_after>package main

import (
	"testing"
	"io/ioutil"
	"os"
	"fmt"
)

func TestTokenizePath(t *testing.T) {
	m := map[string][]string{
		"/a/b/c":   []string{"a", "b", "c"},
		"./foo":    []string{"foo"},
		"x_y/z_a/": []string{"x_y", "z_a"},
	}
	for path, expected := range m {
		if got := TokenizePath(path); !equal(got, expected) {
			t.Errorf("%s: expected '%s', got '%s'", path, expected, got)
		}
	}
}

func TestSubpath(t *testing.T) {
	type pair struct {
		rootDir string
		file    string
	}
	m := map[pair]string{
		pair{"sub", "sub/dir"}:                         "dir",
		pair{"sub", "sub/dir/foo/"}:                    "dir/foo",
		pair{"sub", "sub/dir/foo/bar"}:                 "dir/foo/bar",
		pair{"sub/dir", "sub/dir/foo/bar"}:             "foo/bar",
		pair{"sub/dir/foo", "sub/dir/foo/bar"}:         "bar",
		pair{"sub/dir/foo/", "sub/dir/foo/bar"}:        "bar",
		pair{"/var/log", "/var/log/daemon.log"}:        "daemon.log",
		pair{"/usr///share/", "/usr/share/dict/words"}: "dict/words",
	}
	for pair, expected := range m {
		if got := Subpath(pair.rootDir, pair.file); got != expected {
			t.Errorf("%s: expected '%s', got '%s'", pair.file, expected, got)
		}
	}
}

func TestStripExtension(t *testing.T) {
	m := map[string]string{
		"foo.bar":             "foo",
		"A.long-extension":    "A",
		"beep":                "beep",
		"/some/path/file.txt": "/some/path/file",
		"./foo.x":             "./foo",
	}
	for file, expected := range m {
		if got := StripExtension(file); got != expected {
			t.Errorf("%s: expected '%s', got '%s'", file, expected, got)
		}
	}
}

func writeToTempFile(t *testing.T, contents string) string {
	f, err := ioutil.TempFile(os.TempDir(), "grender-context-test")
	if err != nil {
		t.Fatalf("%s", err)
	}
	defer f.Close()
	if _, err := f.WriteString(contents); err != nil {
		t.Fatalf("%s", err)
	}
	return f.Name()
}

func TestMergeJSON(t *testing.T) {
	m := map[string]Context{
		`{}`: Context{},
		`{"a": "b"}`: Context{
			"a": "b",
		},
		`{"array": [1,2,3]}`: Context{
			"array": []int{1, 2, 3},
		},
		`{"map": {"a":1.23}}`: Context{
			"map": map[string]float64{
				"a": 1.23,
			},
		},
		`{"x": ["a", {"b":1}, "c"]}`: Context{
			"x": []interface{}{
				"a",
				map[string]int{
					"b": 1,
				},
				"c",
			},
		},
	}
	for body, expected := range m {
		filename := writeToTempFile(t, body)
		got := Context{}
		mergeJSON(filename, got)
		if len(expected) != len(got) {
			t.Errorf("%s: expected %d, got %d", body, len(expected), len(got))
		}
		expectedStr := fmt.Sprintf("%v", expected)
		gotStr := fmt.Sprintf("%v", got)
		t.Logf("%s: expected '%s', got '%s'", body, expectedStr, gotStr)
		if expectedStr != gotStr {
			t.Errorf("%s: expected '%s', got '%s'", body, expectedStr, gotStr)
		}
	}
}

func TestMergeMarkdown(t *testing.T) {
	m := map[string]Context{
		``:  Context{MarkdownKey: "\n"},
		md1: Context{MarkdownKey: html1},
	}
	for body, expected := range m {
		filename := writeToTempFile(t, body)
		got := Context{}
		mergeMarkdown(filename, got)
		if len(expected) != len(got) {
			t.Errorf("%s: expected %d, got %d", body, len(expected), len(got))
		}
		expectedStr := fmt.Sprintf("%v", expected)
		gotStr := fmt.Sprintf("%v", got)
		if expectedStr != gotStr {
			t.Errorf("%s: expected '%s', got '%s'", body, expectedStr, gotStr)
		}
	}
}

//
//
//

const md1 = `# A
Lorem _ipsum_ **dolor** sit.

Herpa derp—a derp.

## B

AT&T.
`

const html1 = `
A

Lorem ipsum dolor sit.

Herpa derp—a derp.

B

AT&T.

`
<|endoftext|>


<commit_before>// +build linux

/*
 * Copyright (C) 2017 Red Hat, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

package socketinfo

import (
	"bufio"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/skydive-project/skydive/config"
	"github.com/skydive-project/skydive/flow"
	"github.com/skydive-project/skydive/logging"
	"github.com/skydive-project/skydive/topology/graph"
)

var tcpStates = []string{
	"UNKNOWN",
	"ESTABLISHED",
	"SYN_SENT",
	"SYN_RECV",
	"FIN_WAIT1",
	"FIN_WAIT2",
	"TIME_WAIT",
	"CLOSE",
	"CLOSE_WAIT",
	"LAST_ACK",
	"LISTEN",
	"CLOSING",
}

// ProcSocketInfoProbe describes a probe that collects active connections
type ProcSocketInfoProbe struct {
	connCache *ConnectionCache
	quit      chan bool
	graph     *graph.Graph
	host      *graph.Node
	procGlob  string
}

func getProcessInfo(pid int) (*ProcessInfo, error) {
	processPath := fmt.Sprintf("/proc/%d", pid)
	exe, err := os.Readlink(processPath + "/exe")
	if err != nil {
		return nil, err
	}

	stat, err := ioutil.ReadFile(processPath + "/stat")
	if err != nil {
		return nil, err
	}

	var name string
	fmt.Sscanf(string(stat), "%d %s", &pid, &name)

	return &ProcessInfo{
		Process: exe,
		Name:    name[1 : len(name)-1],
		Pid:     int64(pid),
	}, nil
}

func (s *ProcSocketInfoProbe) scanProc() error {
	s.connCache.Flush()

	inodePids := make(map[int]int)
	namespaces := make(map[uint64]bool)
	processes := make(map[int]*ProcessInfo)

	buildInodePidMap := func() error {
		// Loop through all fd dirs of process on /proc to compare the inode and
		// get the pid. Shamelessly taken from github.com/drael/GOnetstat
		d, err := filepath.Glob("/proc/[0-9]*/fd/[0-9]*")
		if err != nil {
			return err
		}

		var inode int
		for _, item := range d {
			path, _ := os.Readlink(item)
			if _, err := fmt.Sscanf(path, "socket:[%d]", &inode); err == nil {
				pid, _ := strconv.Atoi(strings.Split(item, "/")[2])
				inodePids[inode] = pid
			}
		}

		return nil
	}

	parseProcAddr := func(hexIPPort string) (ip net.IP, port uint16) {
		splitted := strings.SplitN(hexIPPort, ":", 2)
		hexIP, hexPort := splitted[0], splitted[1]
		ipString, _ := hex.DecodeString(hexIP)
		portString, _ := hex.DecodeString(hexPort)
		port = binary.BigEndian.Uint16(portString)

		if len(hexIP) > 8 {
			ip = make(net.IP, 16)
			n := binary.LittleEndian.Uint32(ipString[0:4])
			binary.BigEndian.PutUint32(ip[0:], n)
			n = binary.LittleEndian.Uint32(ipString[4:8])
			binary.BigEndian.PutUint32(ip[4:], n)
			n = binary.LittleEndian.Uint32(ipString[8:12])
			binary.BigEndian.PutUint32(ip[8:], n)
			n = binary.LittleEndian.Uint32(ipString[12:16])
			binary.BigEndian.PutUint32(ip[12:], n)
		} else {
			ip = make(net.IP, 4)
			n := binary.LittleEndian.Uint32(ipString)
			binary.BigEndian.PutUint32(ip, n)
		}
		return
	}

	parseNetEntry := func(line string) (*ConnectionInfo, error) {
		var localIPPort, remoteIPPort string
		var inode, ignore, state int

		_, err := fmt.Sscanf(line, "%d: %s %s %x %x:%x %x:%x %x %d %d %d",
			&ignore, &localIPPort, &remoteIPPort,
			&state, &ignore, &ignore, &ignore, &ignore, &ignore, &ignore, &ignore,
			&inode)
		if err != nil {
			return nil, err
		}

		localIP, localPort := parseProcAddr(localIPPort)
		remoteIP, remotePort := parseProcAddr(remoteIPPort)

		pid, found := inodePids[inode]
		if !found {
			return nil, fmt.Errorf("Could not find process for inode %d", inode)
		}

		processInfo, found := processes[pid]
		if !found {
			processInfo, err = getProcessInfo(pid)
			if err != nil {
				return nil, fmt.Errorf("Failed to get stats for process %d", pid)
			}
			processes[pid] = processInfo
		}

		return &ConnectionInfo{
			ProcessInfo:   *processInfo,
			LocalAddress:  localIP.String(),
			LocalPort:     int64(localPort),
			RemoteAddress: remoteIP.String(),
			RemotePort:    int64(remotePort),
			State:         ConnectionState(tcpStates[state]),
		}, nil
	}

	parseNet := func(protocol flow.FlowProtocol, path string) {
		u, err := os.Open(path)
		if err != nil {
			return
		}
		defer u.Close()

		var stats syscall.Stat_t
		if err := syscall.Fstat(int(u.Fd()), &stats); err != nil {
			return
		}

		if _, found := namespaces[stats.Ino]; found {
			// Already parsed
			return
		}
		namespaces[stats.Ino] = true

		r := bufio.NewReader(u)
		r.ReadLine()

		for {
			line, err := r.ReadString('\n')
			if err != nil {
				return
			}

			conn, err := parseNetEntry(line)
			if err != nil {
				logging.GetLogger().Debugf("Failed to parse entry: %s", err.Error())
				continue
			}
			conn.Protocol = protocol

			logging.GetLogger().Debugf("Adding connection %+v", conn)
			s.connCache.Set(conn.Hash(), conn)
		}
	}

	parseNetTCP := func(path string) {
		parseNet(flow.FlowProtocol_TCP, path)
	}

	parseNetUDP := func(path string) {
		parseNet(flow.FlowProtocol_UDP, path)
	}

	if err := buildInodePidMap(); err != nil {
		return err
	}

	d, err := filepath.Glob(s.procGlob)
	if err != nil {
		return err
	}

	for _, item := range d {
		parseNetTCP(item + "/tcp")
		parseNetTCP(item + "/tcp6")
		parseNetUDP(item + "/udp")
		parseNetUDP(item + "/udp6")
	}

	return nil
}

func (s *ProcSocketInfoProbe) updateMetadata() {
	var sockets []*ConnectionInfo
	for _, item := range s.connCache.Items() {
		conn := item.Object.(*ConnectionInfo)
		sockets = append(sockets, conn)
	}

	s.graph.Lock()
	s.graph.AddMetadata(s.host, "Sockets", sockets)
	s.graph.Unlock()
}

// MapTCP returns the sending and receiving processes for a pair of TCP addresses
// When using /proc, if the connection was not found at the first try, we scan
// /proc again
func (s *ProcSocketInfoProbe) MapTCP(srcAddr, dstAddr *net.TCPAddr) (src *ProcessInfo, dst *ProcessInfo) {
	if src, dst = s.connCache.MapTCP(srcAddr, dstAddr); src == nil && dst == nil {
		s.scanProc()
		src, dst = s.connCache.MapTCP(srcAddr, dstAddr)
	}
	return
}

// Start the socket info probe
func (s *ProcSocketInfoProbe) Start() {
	s.scanProc()
	s.updateMetadata()

	go func() {
		seconds := config.GetInt("agent.topology.socketinfo.host_update")
		ticker := time.NewTicker(time.Duration(seconds) * time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-s.quit:
				return
			case <-ticker.C:
				s.scanProc()
				s.updateMetadata()
			}
		}
	}()
}

// Stop the socket info probe
func (s *ProcSocketInfoProbe) Stop() {
	s.quit <- true
}

// NewProcSocketInfoProbe create a new socket info probe
func NewProcSocketInfoProbe(g *graph.Graph, host *graph.Node) *ProcSocketInfoProbe {
	procGlob := "/proc/[0-9]*/task/[0-9]*/net"
	pid := os.Getpid()
	if _, err := os.Stat(fmt.Sprintf("/proc/%d/tasks/%d/net", pid, pid)); os.IsNotExist(err) {
		procGlob = "/proc/[0-9]*/net"
	}

	return &ProcSocketInfoProbe{
		procGlob:  procGlob,
		connCache: NewConnectionCache(),
		quit:      make(chan bool),
		graph:     g,
		host:      host,
	}
}
<commit_msg>socketinfo: be less verbose<commit_after>// +build linux

/*
 * Copyright (C) 2017 Red Hat, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

package socketinfo

import (
	"bufio"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/skydive-project/skydive/config"
	"github.com/skydive-project/skydive/flow"
	"github.com/skydive-project/skydive/logging"
	"github.com/skydive-project/skydive/topology/graph"
)

var tcpStates = []string{
	"UNKNOWN",
	"ESTABLISHED",
	"SYN_SENT",
	"SYN_RECV",
	"FIN_WAIT1",
	"FIN_WAIT2",
	"TIME_WAIT",
	"CLOSE",
	"CLOSE_WAIT",
	"LAST_ACK",
	"LISTEN",
	"CLOSING",
}

// ProcSocketInfoProbe describes a probe that collects active connections
type ProcSocketInfoProbe struct {
	connCache *ConnectionCache
	quit      chan bool
	graph     *graph.Graph
	host      *graph.Node
	procGlob  string
}

func getProcessInfo(pid int) (*ProcessInfo, error) {
	processPath := fmt.Sprintf("/proc/%d", pid)
	exe, err := os.Readlink(processPath + "/exe")
	if err != nil {
		return nil, err
	}

	stat, err := ioutil.ReadFile(processPath + "/stat")
	if err != nil {
		return nil, err
	}

	var name string
	fmt.Sscanf(string(stat), "%d %s", &pid, &name)

	return &ProcessInfo{
		Process: exe,
		Name:    name[1 : len(name)-1],
		Pid:     int64(pid),
	}, nil
}

func (s *ProcSocketInfoProbe) scanProc() error {
	s.connCache.Flush()

	inodePids := make(map[int]int)
	namespaces := make(map[uint64]bool)
	processes := make(map[int]*ProcessInfo)

	buildInodePidMap := func() error {
		// Loop through all fd dirs of process on /proc to compare the inode and
		// get the pid. Shamelessly taken from github.com/drael/GOnetstat
		d, err := filepath.Glob("/proc/[0-9]*/fd/[0-9]*")
		if err != nil {
			return err
		}

		var inode int
		for _, item := range d {
			path, _ := os.Readlink(item)
			if _, err := fmt.Sscanf(path, "socket:[%d]", &inode); err == nil {
				pid, _ := strconv.Atoi(strings.Split(item, "/")[2])
				inodePids[inode] = pid
			}
		}

		return nil
	}

	parseProcAddr := func(hexIPPort string) (ip net.IP, port uint16) {
		splitted := strings.SplitN(hexIPPort, ":", 2)
		hexIP, hexPort := splitted[0], splitted[1]
		ipString, _ := hex.DecodeString(hexIP)
		portString, _ := hex.DecodeString(hexPort)
		port = binary.BigEndian.Uint16(portString)

		if len(hexIP) > 8 {
			ip = make(net.IP, 16)
			n := binary.LittleEndian.Uint32(ipString[0:4])
			binary.BigEndian.PutUint32(ip[0:], n)
			n = binary.LittleEndian.Uint32(ipString[4:8])
			binary.BigEndian.PutUint32(ip[4:], n)
			n = binary.LittleEndian.Uint32(ipString[8:12])
			binary.BigEndian.PutUint32(ip[8:], n)
			n = binary.LittleEndian.Uint32(ipString[12:16])
			binary.BigEndian.PutUint32(ip[12:], n)
		} else {
			ip = make(net.IP, 4)
			n := binary.LittleEndian.Uint32(ipString)
			binary.BigEndian.PutUint32(ip, n)
		}
		return
	}

	parseNetEntry := func(line string) (*ConnectionInfo, error) {
		var localIPPort, remoteIPPort string
		var inode, ignore, state int

		_, err := fmt.Sscanf(line, "%d: %s %s %x %x:%x %x:%x %x %d %d %d",
			&ignore, &localIPPort, &remoteIPPort,
			&state, &ignore, &ignore, &ignore, &ignore, &ignore, &ignore, &ignore,
			&inode)
		if err != nil {
			return nil, err
		}

		localIP, localPort := parseProcAddr(localIPPort)
		remoteIP, remotePort := parseProcAddr(remoteIPPort)

		pid, found := inodePids[inode]
		if !found {
			return nil, fmt.Errorf("Could not find process for inode %d", inode)
		}

		processInfo, found := processes[pid]
		if !found {
			processInfo, err = getProcessInfo(pid)
			if err != nil {
				return nil, fmt.Errorf("Failed to get stats for process %d", pid)
			}
			processes[pid] = processInfo
		}

		return &ConnectionInfo{
			ProcessInfo:   *processInfo,
			LocalAddress:  localIP.String(),
			LocalPort:     int64(localPort),
			RemoteAddress: remoteIP.String(),
			RemotePort:    int64(remotePort),
			State:         ConnectionState(tcpStates[state]),
		}, nil
	}

	parseNet := func(protocol flow.FlowProtocol, path string) {
		u, err := os.Open(path)
		if err != nil {
			return
		}
		defer u.Close()

		var stats syscall.Stat_t
		if err := syscall.Fstat(int(u.Fd()), &stats); err != nil {
			return
		}

		if _, found := namespaces[stats.Ino]; found {
			// Already parsed
			return
		}
		namespaces[stats.Ino] = true

		r := bufio.NewReader(u)
		r.ReadLine()

		for {
			line, err := r.ReadString('\n')
			if err != nil {
				return
			}

			conn, err := parseNetEntry(line)
			if err != nil {
				logging.GetLogger().Debugf("Failed to parse entry: %s", err.Error())
				continue
			}
			conn.Protocol = protocol

			s.connCache.Set(conn.Hash(), conn)
		}
	}

	parseNetTCP := func(path string) {
		parseNet(flow.FlowProtocol_TCP, path)
	}

	parseNetUDP := func(path string) {
		parseNet(flow.FlowProtocol_UDP, path)
	}

	if err := buildInodePidMap(); err != nil {
		return err
	}

	d, err := filepath.Glob(s.procGlob)
	if err != nil {
		return err
	}

	for _, item := range d {
		parseNetTCP(item + "/tcp")
		parseNetTCP(item + "/tcp6")
		parseNetUDP(item + "/udp")
		parseNetUDP(item + "/udp6")
	}

	return nil
}

func (s *ProcSocketInfoProbe) updateMetadata() {
	var sockets []*ConnectionInfo
	for _, item := range s.connCache.Items() {
		conn := item.Object.(*ConnectionInfo)
		sockets = append(sockets, conn)
	}

	s.graph.Lock()
	s.graph.AddMetadata(s.host, "Sockets", sockets)
	s.graph.Unlock()
}

// MapTCP returns the sending and receiving processes for a pair of TCP addresses
// When using /proc, if the connection was not found at the first try, we scan
// /proc again
func (s *ProcSocketInfoProbe) MapTCP(srcAddr, dstAddr *net.TCPAddr) (src *ProcessInfo, dst *ProcessInfo) {
	if src, dst = s.connCache.MapTCP(srcAddr, dstAddr); src == nil && dst == nil {
		s.scanProc()
		src, dst = s.connCache.MapTCP(srcAddr, dstAddr)
	}
	return
}

// Start the socket info probe
func (s *ProcSocketInfoProbe) Start() {
	s.scanProc()
	s.updateMetadata()

	go func() {
		seconds := config.GetInt("agent.topology.socketinfo.host_update")
		ticker := time.NewTicker(time.Duration(seconds) * time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-s.quit:
				return
			case <-ticker.C:
				s.scanProc()
				s.updateMetadata()
			}
		}
	}()
}

// Stop the socket info probe
func (s *ProcSocketInfoProbe) Stop() {
	s.quit <- true
}

// NewProcSocketInfoProbe create a new socket info probe
func NewProcSocketInfoProbe(g *graph.Graph, host *graph.Node) *ProcSocketInfoProbe {
	procGlob := "/proc/[0-9]*/task/[0-9]*/net"
	pid := os.Getpid()
	if _, err := os.Stat(fmt.Sprintf("/proc/%d/tasks/%d/net", pid, pid)); os.IsNotExist(err) {
		procGlob = "/proc/[0-9]*/net"
	}

	return &ProcSocketInfoProbe{
		procGlob:  procGlob,
		connCache: NewConnectionCache(),
		quit:      make(chan bool),
		graph:     g,
		host:      host,
	}
}
<|endoftext|>


<commit_before>// Container provides a Writer which is capable of serializing gogen-avro structs and writing them in the Avro Object Container File (OCF) format
package container

import (
	"bytes"
	"compress/flate"
	"github.com/alanctgardner/gogen-avro/container/avro"
	"io"
)

/*
  A Codec specifies how the blocks within a container file should be compressed.
*/
type Codec string

const (
	// No compression
	Null Codec = "null"
	// Deflate compression
	Deflate Codec = "deflate"
	// Snappy compression
	Snappy Codec = "snappy"
)

type CloseableResettableWriter interface {
	Close() error
	Reset(io.Writer)
}

/*
  Writer wraps an io.Writer and writes the file and block-level framing required for an OCF file
*/
type Writer struct {
	writer           io.Writer
	syncMarker       [16]byte
	codec            Codec
	recordsPerBlock  int64
	blockBuffer      *bytes.Buffer
	compressedWriter io.Writer
	nextBlockRecords int64
}

/*
  Create a new Writer wrapping the provided io.Writer with the given Codec and number of records per block.
  The Writer will lazily write the container file header when WriteRecord is called the first time.
  You must call Flush on the Writer before closing the underlying io.Writer, to ensure the final block is written.
  A schema string must be passed to ensure that a correct header is written even if no records are written. This
  is required to produce valid empty Avro container files.
*/
func NewWriter(writer io.Writer, codec Codec, recordsPerBlock int64, schema string) (*Writer, error) {
	blockBytes := make([]byte, 0)
	blockBuffer := bytes.NewBuffer(blockBytes)

	avroWriter := &Writer{
		writer:          writer,
		syncMarker:      [16]byte{'g', 'o', 'g', 'e', 'n', 'a', 'v', 'r', 'o', 'm', 'a', 'g', 'i', 'c', '1', '0'},
		codec:           codec,
		recordsPerBlock: recordsPerBlock,
		blockBuffer:     blockBuffer,
	}
	var err error
	if codec == Deflate {
		avroWriter.compressedWriter, err = flate.NewWriter(avroWriter.blockBuffer, flate.DefaultCompression)
		if err != nil {
			return nil, err
		}
	} else if codec == Snappy {
		avroWriter.compressedWriter = newSnappyWriter(avroWriter.blockBuffer)
	} else if codec == Null {
		avroWriter.compressedWriter = avroWriter.blockBuffer
	}

	err = avroWriter.writeHeader(schema)
	if err != nil {
		return nil, err
	}

	return avroWriter, nil
}

func (avroWriter *Writer) writeHeader(schema string) error {
	header := &avro.AvroContainerHeader{
		Magic: [4]byte{'O', 'b', 'j', 1},
		Meta: map[string][]byte{
			"avro.schema": []byte(schema),
			"avro.codec":  []byte(avroWriter.codec),
		},
		Sync: avroWriter.syncMarker,
	}
	return header.Serialize(avroWriter.writer)
}

/*
  Write an AvroRecord to the container file. All gogen-avro generated structs
  fulfill the AvroRecord interface. Note that all records in a given container file
  must be of the same Avro type.
*/
func (avroWriter *Writer) WriteRecord(record AvroRecord) error {
	var err error
	// Serialize the new record into the compressed writer
	err = record.Serialize(avroWriter.compressedWriter)
	if err != nil {
		return err
	}
	avroWriter.nextBlockRecords += 1

	// If the block if full, flush and reset the compressed writer,
	// write the header and the block contents
	if avroWriter.nextBlockRecords >= avroWriter.recordsPerBlock {
		return avroWriter.Flush()
	}

	return nil
}

/*
  Write the current block to the file if it has been filled.  It is
  best-practise to always call this before the underlying io.Writer is closed.
*/
func (avroWriter *Writer) Flush() error {
	if avroWriter.nextBlockRecords == 0 {
		return nil
	}

	// Write out all of the buffered records as a new block
	// Must be called before closing to ensure the last block is written
	if fwWriter, ok := avroWriter.compressedWriter.(CloseableResettableWriter); ok {
		fwWriter.Close()
		fwWriter.Reset(avroWriter.blockBuffer)
	}

	if avroWriter.nextBlockRecords > 0 {
		block := &avro.AvroContainerBlock{
			NumRecords:  avroWriter.nextBlockRecords,
			RecordBytes: avroWriter.blockBuffer.Bytes(),
			Sync:        avroWriter.syncMarker,
		}
		err := block.Serialize(avroWriter.writer)
		if err != nil {
			return err
		}
	}

	avroWriter.blockBuffer.Reset()
	avroWriter.nextBlockRecords = 0

	return nil
}
<commit_msg>ref(container): reorder imports<commit_after>// Container provides a Writer which is capable of serializing gogen-avro structs and writing them in the Avro Object Container File (OCF) format
package container

import (
	"bytes"
	"compress/flate"
	"io"

	"github.com/alanctgardner/gogen-avro/container/avro"
)

/*
  A Codec specifies how the blocks within a container file should be compressed.
*/
type Codec string

const (
	// No compression
	Null Codec = "null"
	// Deflate compression
	Deflate Codec = "deflate"
	// Snappy compression
	Snappy Codec = "snappy"
)

type CloseableResettableWriter interface {
	Close() error
	Reset(io.Writer)
}

/*
  Writer wraps an io.Writer and writes the file and block-level framing required for an OCF file
*/
type Writer struct {
	writer           io.Writer
	syncMarker       [16]byte
	codec            Codec
	recordsPerBlock  int64
	blockBuffer      *bytes.Buffer
	compressedWriter io.Writer
	nextBlockRecords int64
}

/*
  Create a new Writer wrapping the provided io.Writer with the given Codec and number of records per block.
  The Writer will lazily write the container file header when WriteRecord is called the first time.
  You must call Flush on the Writer before closing the underlying io.Writer, to ensure the final block is written.
  A schema string must be passed to ensure that a correct header is written even if no records are written. This
  is required to produce valid empty Avro container files.
*/
func NewWriter(writer io.Writer, codec Codec, recordsPerBlock int64, schema string) (*Writer, error) {
	blockBytes := make([]byte, 0)
	blockBuffer := bytes.NewBuffer(blockBytes)

	avroWriter := &Writer{
		writer:          writer,
		syncMarker:      [16]byte{'g', 'o', 'g', 'e', 'n', 'a', 'v', 'r', 'o', 'm', 'a', 'g', 'i', 'c', '1', '0'},
		codec:           codec,
		recordsPerBlock: recordsPerBlock,
		blockBuffer:     blockBuffer,
	}
	var err error
	if codec == Deflate {
		avroWriter.compressedWriter, err = flate.NewWriter(avroWriter.blockBuffer, flate.DefaultCompression)
		if err != nil {
			return nil, err
		}
	} else if codec == Snappy {
		avroWriter.compressedWriter = newSnappyWriter(avroWriter.blockBuffer)
	} else if codec == Null {
		avroWriter.compressedWriter = avroWriter.blockBuffer
	}

	err = avroWriter.writeHeader(schema)
	if err != nil {
		return nil, err
	}

	return avroWriter, nil
}

func (avroWriter *Writer) writeHeader(schema string) error {
	header := &avro.AvroContainerHeader{
		Magic: [4]byte{'O', 'b', 'j', 1},
		Meta: map[string][]byte{
			"avro.schema": []byte(schema),
			"avro.codec":  []byte(avroWriter.codec),
		},
		Sync: avroWriter.syncMarker,
	}
	return header.Serialize(avroWriter.writer)
}

/*
  Write an AvroRecord to the container file. All gogen-avro generated structs
  fulfill the AvroRecord interface. Note that all records in a given container file
  must be of the same Avro type.
*/
func (avroWriter *Writer) WriteRecord(record AvroRecord) error {
	var err error
	// Serialize the new record into the compressed writer
	err = record.Serialize(avroWriter.compressedWriter)
	if err != nil {
		return err
	}
	avroWriter.nextBlockRecords += 1

	// If the block if full, flush and reset the compressed writer,
	// write the header and the block contents
	if avroWriter.nextBlockRecords >= avroWriter.recordsPerBlock {
		return avroWriter.Flush()
	}

	return nil
}

/*
  Write the current block to the file if it has been filled.  It is
  best-practise to always call this before the underlying io.Writer is closed.
*/
func (avroWriter *Writer) Flush() error {
	if avroWriter.nextBlockRecords == 0 {
		return nil
	}

	// Write out all of the buffered records as a new block
	// Must be called before closing to ensure the last block is written
	if fwWriter, ok := avroWriter.compressedWriter.(CloseableResettableWriter); ok {
		fwWriter.Close()
		fwWriter.Reset(avroWriter.blockBuffer)
	}

	if avroWriter.nextBlockRecords > 0 {
		block := &avro.AvroContainerBlock{
			NumRecords:  avroWriter.nextBlockRecords,
			RecordBytes: avroWriter.blockBuffer.Bytes(),
			Sync:        avroWriter.syncMarker,
		}
		err := block.Serialize(avroWriter.writer)
		if err != nil {
			return err
		}
	}

	avroWriter.blockBuffer.Reset()
	avroWriter.nextBlockRecords = 0

	return nil
}
<|endoftext|>


<commit_before>package kcp

import (
	"container/heap"
	"sync"
	"time"
)

var updater updateHeap

func init() {
	updater.init()
	go updater.updateTask()
}

// entry contains a session update info
type entry struct {
	ts time.Time
	s  *UDPSession
}

// a global heap managed kcp.flush() caller
type updateHeap struct {
	entries  []entry
	mu       sync.Mutex
	chWakeUp chan struct{}
}

func (h *updateHeap) Len() int           { return len(h.entries) }
func (h *updateHeap) Less(i, j int) bool { return h.entries[i].ts.Before(h.entries[j].ts) }
func (h *updateHeap) Swap(i, j int) {
	h.entries[i], h.entries[j] = h.entries[j], h.entries[i]
	h.entries[i].s.updaterIdx = i
	h.entries[j].s.updaterIdx = j
}

func (h *updateHeap) Push(x interface{}) {
	h.entries = append(h.entries, x.(entry))
	n := len(h.entries)
	h.entries[n-1].s.updaterIdx = n - 1
}

func (h *updateHeap) Pop() interface{} {
	n := len(h.entries)
	x := h.entries[n-1]
	h.entries[n-1].s.updaterIdx = -1
	h.entries[n-1] = entry{} // manual set nil for GC
	h.entries = h.entries[0 : n-1]
	return x
}

func (h *updateHeap) init() {
	h.chWakeUp = make(chan struct{}, 1)
}

func (h *updateHeap) addSession(s *UDPSession) {
	h.mu.Lock()
	heap.Push(h, entry{time.Now(), s})
	h.mu.Unlock()
	h.wakeup()
}

func (h *updateHeap) removeSession(s *UDPSession) {
	h.mu.Lock()
	if s.updaterIdx != -1 {
		heap.Remove(h, s.updaterIdx)
	}
	h.mu.Unlock()
}

func (h *updateHeap) wakeup() {
	select {
	case h.chWakeUp <- struct{}{}:
	default:
	}
}

func (h *updateHeap) updateTask() {
	timer := time.NewTimer(0)
	for {
		select {
		case <-timer.C:
		case <-h.chWakeUp:
		}

		h.mu.Lock()
		hlen := h.Len()
		for i := 0; i < hlen; i++ {
			entry := &h.entries[0]
			if time.Now().After(entry.ts) {
				interval := entry.s.update()
				entry.ts = time.Now().Add(interval)
				heap.Fix(h, 0)
			} else {
				break
			}
		}

		if hlen > 0 {
			timer.Reset(h.entries[0].ts.Sub(time.Now()))
		}
		h.mu.Unlock()
	}
}
<commit_msg>fix time comparsion on edge<commit_after>package kcp

import (
	"container/heap"
	"sync"
	"time"
)

var updater updateHeap

func init() {
	updater.init()
	go updater.updateTask()
}

// entry contains a session update info
type entry struct {
	ts time.Time
	s  *UDPSession
}

// a global heap managed kcp.flush() caller
type updateHeap struct {
	entries  []entry
	mu       sync.Mutex
	chWakeUp chan struct{}
}

func (h *updateHeap) Len() int           { return len(h.entries) }
func (h *updateHeap) Less(i, j int) bool { return h.entries[i].ts.Before(h.entries[j].ts) }
func (h *updateHeap) Swap(i, j int) {
	h.entries[i], h.entries[j] = h.entries[j], h.entries[i]
	h.entries[i].s.updaterIdx = i
	h.entries[j].s.updaterIdx = j
}

func (h *updateHeap) Push(x interface{}) {
	h.entries = append(h.entries, x.(entry))
	n := len(h.entries)
	h.entries[n-1].s.updaterIdx = n - 1
}

func (h *updateHeap) Pop() interface{} {
	n := len(h.entries)
	x := h.entries[n-1]
	h.entries[n-1].s.updaterIdx = -1
	h.entries[n-1] = entry{} // manual set nil for GC
	h.entries = h.entries[0 : n-1]
	return x
}

func (h *updateHeap) init() {
	h.chWakeUp = make(chan struct{}, 1)
}

func (h *updateHeap) addSession(s *UDPSession) {
	h.mu.Lock()
	heap.Push(h, entry{time.Now(), s})
	h.mu.Unlock()
	h.wakeup()
}

func (h *updateHeap) removeSession(s *UDPSession) {
	h.mu.Lock()
	if s.updaterIdx != -1 {
		heap.Remove(h, s.updaterIdx)
	}
	h.mu.Unlock()
}

func (h *updateHeap) wakeup() {
	select {
	case h.chWakeUp <- struct{}{}:
	default:
	}
}

func (h *updateHeap) updateTask() {
	timer := time.NewTimer(0)
	for {
		select {
		case <-timer.C:
		case <-h.chWakeUp:
		}

		h.mu.Lock()
		hlen := h.Len()
		for i := 0; i < hlen; i++ {
			entry := &h.entries[0]
			if !time.Now().Before(entry.ts) {
				interval := entry.s.update()
				entry.ts = time.Now().Add(interval)
				heap.Fix(h, 0)
			} else {
				break
			}
		}

		if hlen > 0 {
			timer.Reset(h.entries[0].ts.Sub(time.Now()))
		}
		h.mu.Unlock()
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The following enables go generate to generate the doc.go file.
//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go .

package main

import (
	"fmt"
	"runtime"

	"v.io/x/devtools/internal/tool"
	"v.io/x/lib/cmdline"
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	tool.InitializeRunFlags(&cmdRoot.Flags)
}

func main() {
	cmdline.Main(cmdRoot)
}

// cmdRoot represents the root of the v23 tool.
var cmdRoot = &cmdline.Command{
	Name:  "v23",
	Short: "Multi-purpose tool for Vanadium development",
	Long: `
Command v23 is a multi-purpose tool for Vanadium development.
`,
	LookPath: true,
	// TODO(nlacasse): Remove LookPathPrefixes once v23->jiri transition is
	// complete.
	LookPathPrefixes: []string{"jiri", "v23"},
	Children: []*cmdline.Command{
		cmdCL,
		cmdContributors,
		cmdProject,
		cmdSnapshot,
		cmdUpdate,
		cmdVersion,
	},
}

// cmdVersion represents the "v23 version" command.
var cmdVersion = &cmdline.Command{
	Runner: cmdline.RunnerFunc(runVersion),
	Name:   "version",
	Short:  "Print version",
	Long:   "Print version of the v23 tool.",
}

func runVersion(env *cmdline.Env, _ []string) error {
	fmt.Fprintf(env.Stdout, "v23 tool version %v\n", tool.Version)
	return nil
}
<commit_msg>TBR: v23 tool should only look for subcommands of the form jiri-cmd.<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The following enables go generate to generate the doc.go file.
//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go .

package main

import (
	"fmt"
	"runtime"

	"v.io/x/devtools/internal/tool"
	"v.io/x/lib/cmdline"
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	tool.InitializeRunFlags(&cmdRoot.Flags)
}

func main() {
	cmdline.Main(cmdRoot)
}

// cmdRoot represents the root of the v23 tool.
var cmdRoot = &cmdline.Command{
	Name:  "v23",
	Short: "Multi-purpose tool for Vanadium development",
	Long: `
Command v23 is a multi-purpose tool for Vanadium development.
`,
	LookPath: true,
	// TODO(nlacasse): Remove LookPathPrefixes once v23->jiri transition is
	// complete.
	LookPathPrefixes: []string{"jiri"},
	Children: []*cmdline.Command{
		cmdCL,
		cmdContributors,
		cmdProject,
		cmdSnapshot,
		cmdUpdate,
		cmdVersion,
	},
}

// cmdVersion represents the "v23 version" command.
var cmdVersion = &cmdline.Command{
	Runner: cmdline.RunnerFunc(runVersion),
	Name:   "version",
	Short:  "Print version",
	Long:   "Print version of the v23 tool.",
}

func runVersion(env *cmdline.Env, _ []string) error {
	fmt.Fprintf(env.Stdout, "v23 tool version %v\n", tool.Version)
	return nil
}
<|endoftext|>


<commit_before>package vcs

import (
	"fmt"
	"os"
	"path/filepath"
	"text/template"

	"github.com/hashicorp/errwrap"
)

var PostCheckoutTmpl = template.Must(template.New("name").Parse(`#!/bin/sh
# when checkout is a branch, start timer
if [ $3 -eq 1 ]; then
   sourceclock start;
fi
`))

var PrepCommitTmpl = template.Must(template.New("name").Parse(`#!/bin/sh

# only add time to template and message sources
# @see http://git-scm.com/docs/githooks#_prepare_commit_msg
case "$2" in
message|template) echo normal
	printf "$(cat $1) [$(sourceclock split)]" > "$1" ;;
esac

`))

var PostCommitTmpl = template.Must(template.New("name").Parse(`#!/bin/sh
# @todo handle merge/rebase kind of commits

sourceclock lap
`))

type Git struct {
	dir string
}

func NewGit(dir string) *Git {
	return &Git{
		dir: filepath.Join(dir, ".git"),
	}
}

func (g *Git) Name() string { return "git" }
func (g *Git) Supported() bool {
	fi, err := os.Stat(g.dir)
	if err != nil || !fi.IsDir() {
		return false
	}

	return true
}

func (g *Git) Hook() error {
	hpath := filepath.Join(g.dir, "hooks")

	//post checkout: start()
	postchf, err := os.Create(filepath.Join(hpath, "post-checkout"))
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to create post-checkout '%s': {{err}}", postchf.Name()), err)
	}

	err = postchf.Chmod(0766)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to make post-checkout file '%s' executable: {{err}}", hpath), err)
	}

	err = PostCheckoutTmpl.Execute(postchf, struct{}{})
	if err != nil {
		return errwrap.Wrapf("Failed to run post-checkout template: {{err}}", err)
	}

	//prepare commit msg: split()
	prepcof, err := os.Create(filepath.Join(hpath, "prepare-commit-msg"))
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to create prepare-commit-msg  '%s': {{err}}", postchf.Name()), err)
	}

	err = prepcof.Chmod(0766)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to make prepare-commit-msg file '%s' executable: {{err}}", hpath), err)
	}

	err = PrepCommitTmpl.Execute(prepcof, struct{}{})
	if err != nil {
		return errwrap.Wrapf("Failed to run post-commit template: {{err}}", err)
	}

	//post commit: lap()
	postcof, err := os.Create(filepath.Join(hpath, "post-commit"))
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to create post-commit  '%s': {{err}}", postchf.Name()), err)
	}

	err = postcof.Chmod(0766)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to make post-commit file '%s' executable: {{err}}", hpath), err)
	}

	err = PostCommitTmpl.Execute(postcof, struct{}{})
	if err != nil {
		return errwrap.Wrapf("Failed to run post-commit template: {{err}}", err)
	}

	return nil
}
<commit_msg>post commit always resets timer [3m10s]<commit_after>package vcs

import (
	"fmt"
	"os"
	"path/filepath"
	"text/template"

	"github.com/hashicorp/errwrap"
)

var PostCheckoutTmpl = template.Must(template.New("name").Parse(`#!/bin/sh
# when checkout is a branch, start timer
if [ $3 -eq 1 ]; then
   sourceclock start;
fi
`))

var PrepCommitTmpl = template.Must(template.New("name").Parse(`#!/bin/sh
# only add time to template and message sources
# @see http://git-scm.com/docs/githooks#_prepare_commit_msg
case "$2" in
message|template)
	printf "$(cat $1) [$(sourceclock split)]" > "$1" ;;
esac
`))

var PostCommitTmpl = template.Must(template.New("name").Parse(`#!/bin/sh
#always reset after commit
sourceclock lap
`))

type Git struct {
	dir string
}

func NewGit(dir string) *Git {
	return &Git{
		dir: filepath.Join(dir, ".git"),
	}
}

func (g *Git) Name() string { return "git" }
func (g *Git) Supported() bool {
	fi, err := os.Stat(g.dir)
	if err != nil || !fi.IsDir() {
		return false
	}

	return true
}

func (g *Git) Hook() error {
	hpath := filepath.Join(g.dir, "hooks")

	//post checkout: start()
	postchf, err := os.Create(filepath.Join(hpath, "post-checkout"))
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to create post-checkout '%s': {{err}}", postchf.Name()), err)
	}

	err = postchf.Chmod(0766)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to make post-checkout file '%s' executable: {{err}}", hpath), err)
	}

	err = PostCheckoutTmpl.Execute(postchf, struct{}{})
	if err != nil {
		return errwrap.Wrapf("Failed to run post-checkout template: {{err}}", err)
	}

	//prepare commit msg: split()
	prepcof, err := os.Create(filepath.Join(hpath, "prepare-commit-msg"))
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to create prepare-commit-msg  '%s': {{err}}", postchf.Name()), err)
	}

	err = prepcof.Chmod(0766)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to make prepare-commit-msg file '%s' executable: {{err}}", hpath), err)
	}

	err = PrepCommitTmpl.Execute(prepcof, struct{}{})
	if err != nil {
		return errwrap.Wrapf("Failed to run post-commit template: {{err}}", err)
	}

	//post commit: lap()
	postcof, err := os.Create(filepath.Join(hpath, "post-commit"))
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to create post-commit  '%s': {{err}}", postchf.Name()), err)
	}

	err = postcof.Chmod(0766)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to make post-commit file '%s' executable: {{err}}", hpath), err)
	}

	err = PostCommitTmpl.Execute(postcof, struct{}{})
	if err != nil {
		return errwrap.Wrapf("Failed to run post-commit template: {{err}}", err)
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 The btcsuite developers
// Copyright (c) 2015 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"strings"
)

// semanticAlphabet
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"

// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
	appMajor uint = 0
	appMinor uint = 8
	appPatch uint = 0

	// appPreRelease MUST only contain characters from semanticAlphabet
	// per the semantic versioning spec.
	appPreRelease = "beta"
)

// appBuild is defined as a variable so it can be overridden during the build
// process with '-ldflags "-X main.appBuild foo' if needed.  It MUST only
// contain characters from semanticAlphabet per the semantic versioning spec.
var appBuild string

// version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func version() string {
	// Start with the major, minor, and path versions.
	version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)

	// Append pre-release version if there is one.  The hyphen called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the pre-release string.  The pre-release version
	// is not appended if it contains invalid characters.
	preRelease := normalizeVerString(appPreRelease)
	if preRelease != "" {
		version = fmt.Sprintf("%s-%s", version, preRelease)
	}

	// Append build metadata if there is any.  The plus called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the build metadata string.  The build metadata
	// string is not appended if it contains invalid characters.
	build := normalizeVerString(appBuild)
	if build != "" {
		version = fmt.Sprintf("%s+%s", version, build)
	}

	return version
}

// normalizeVerString returns the passed string stripped of all characters which
// are not valid according to the semantic versioning guidelines for pre-release
// version and build metadata strings.  In particular they MUST only contain
// characters in semanticAlphabet.
func normalizeVerString(str string) string {
	result := bytes.Buffer{}
	for _, r := range str {
		if strings.ContainsRune(semanticAlphabet, r) {
			_, err := result.WriteRune(r)
			// Writing to a bytes.Buffer panics on OOM, and all
			// errors are unexpected.
			if err != nil {
				panic(err)
			}
		}
	}
	return result.String()
}
<commit_msg>Bump for v0.8.2<commit_after>// Copyright (c) 2013-2014 The btcsuite developers
// Copyright (c) 2015 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"strings"
)

// semanticAlphabet
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"

// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
	appMajor uint = 0
	appMinor uint = 8
	appPatch uint = 2

	// appPreRelease MUST only contain characters from semanticAlphabet
	// per the semantic versioning spec.
	appPreRelease = "beta"
)

// appBuild is defined as a variable so it can be overridden during the build
// process with '-ldflags "-X main.appBuild foo' if needed.  It MUST only
// contain characters from semanticAlphabet per the semantic versioning spec.
var appBuild string

// version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func version() string {
	// Start with the major, minor, and path versions.
	version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)

	// Append pre-release version if there is one.  The hyphen called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the pre-release string.  The pre-release version
	// is not appended if it contains invalid characters.
	preRelease := normalizeVerString(appPreRelease)
	if preRelease != "" {
		version = fmt.Sprintf("%s-%s", version, preRelease)
	}

	// Append build metadata if there is any.  The plus called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the build metadata string.  The build metadata
	// string is not appended if it contains invalid characters.
	build := normalizeVerString(appBuild)
	if build != "" {
		version = fmt.Sprintf("%s+%s", version, build)
	}

	return version
}

// normalizeVerString returns the passed string stripped of all characters which
// are not valid according to the semantic versioning guidelines for pre-release
// version and build metadata strings.  In particular they MUST only contain
// characters in semanticAlphabet.
func normalizeVerString(str string) string {
	result := bytes.Buffer{}
	for _, r := range str {
		if strings.ContainsRune(semanticAlphabet, r) {
			_, err := result.WriteRune(r)
			// Writing to a bytes.Buffer panics on OOM, and all
			// errors are unexpected.
			if err != nil {
				panic(err)
			}
		}
	}
	return result.String()
}
<|endoftext|>


<commit_before>package main

const VERSION = "0.5.1-alpha1"
<commit_msg>:tada: Bump up the version<commit_after>package main

const VERSION = "0.5.1"
<|endoftext|>


<commit_before>package bimg

// Version represents the current package semantic version.
const Version = "1.0.10"
<commit_msg>feat(version): bump to v1.0.11<commit_after>package bimg

// Version represents the current package semantic version.
const Version = "1.0.11"
<|endoftext|>


<commit_before>package gf

const VERSION  = "v1.3.1"
const AUTHORS  = "john<john@johng.cn>"

<commit_msg>VERSION updates<commit_after>package gf

const VERSION  = "v1.2.11"
const AUTHORS  = "john<john@johng.cn>"

<|endoftext|>


<commit_before>package main

const VERSION = "0.9.2"
<commit_msg>updater version to v0.9.3<commit_after>package main

const VERSION = "0.9.3"
<|endoftext|>


<commit_before>package main

/*
Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.
*/
const VersionMajor = 4
const VersionMinor = 4
const VersionPatch = 7
<commit_msg>bump version<commit_after>package main

/*
Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.
*/
const VersionMajor = 4
const VersionMinor = 4
const VersionPatch = 8
<|endoftext|>


<commit_before>// Copyright (c) Mainflux
// SPDX-License-Identifier: Apache-2.0

package mainflux

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

const version string = "0.11.0"

// VersionInfo contains version endpoint response.
type VersionInfo struct {
	// Service contains service name.
	Service string `json:"service"`

	// Version contains service current version value.
	Version string `json:"version"`
}

// Version exposes an HTTP handler for retrieving service version.
func Version(service string) http.HandlerFunc {
	return http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
		res := VersionInfo{service, version}

		data, _ := json.Marshal(res)

		rw.Write(data)
	})
}
<commit_msg>Bump Mainflux version to 0.12.0 (#1399)<commit_after>// Copyright (c) Mainflux
// SPDX-License-Identifier: Apache-2.0

package mainflux

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

const version string = "0.12.0"

// VersionInfo contains version endpoint response.
type VersionInfo struct {
	// Service contains service name.
	Service string `json:"service"`

	// Version contains service current version value.
	Version string `json:"version"`
}

// Version exposes an HTTP handler for retrieving service version.
func Version(service string) http.HandlerFunc {
	return http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
		res := VersionInfo{service, version}

		data, _ := json.Marshal(res)

		rw.Write(data)
	})
}
<|endoftext|>


<commit_before>package dns

import "fmt"

// Version is current version of this library.
var Version = v{1, 1, 45}

// v holds the version of this library.
type v struct {
	Major, Minor, Patch int
}

func (v v) String() string {
	return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
}
<commit_msg>Release 1.1.46<commit_after>package dns

import "fmt"

// Version is current version of this library.
var Version = v{1, 1, 46}

// v holds the version of this library.
type v struct {
	Major, Minor, Patch int
}

func (v v) String() string {
	return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
}
<|endoftext|>


<commit_before>package main

/*
Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.
*/
const VersionMajor = 4
const VersionMinor = 14
const VersionPatch = 0
<commit_msg>Version bump<commit_after>package main

/*
Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.
*/
const VersionMajor = 4
const VersionMinor = 14
const VersionPatch = 1
<|endoftext|>


<commit_before>
package main

import (
	"fmt"
	"strings"
)

// The git commit that was compiled. This will be filled in by the compiler.
var (
	GitCommit   string
	GitDescribe string
)

// The main version number that is being run at the moment.
const Version = "0.3"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = ""

// GetHumanVersion composes the parts of the version in a way that's suitable
// for displaying to humans.
func GetHumanVersion() string {

	version := GetVersion()

	release := VersionPrerelease
	if GitDescribe == "" && release == "" {
		release = "dev"
	}
	if release != "" {
		version += fmt.Sprintf("-%s", release)
		if GitCommit != "" {
			version += fmt.Sprintf(" (%s)", GitCommit)
		}
	}

	// Strip off any single quotes added by the git information.
	return strings.Replace(version, "'", "", -1)
}

func GetVersion() string {
	version := Version
	if GitDescribe != "" {
		version = GitDescribe
	}
	return strings.Replace(version, "'", "", -1)
}<commit_msg>Puts tree back in dev mode.<commit_after>
package main

import (
	"fmt"
	"strings"
)

// The git commit that was compiled. This will be filled in by the compiler.
var (
	GitCommit   string
	GitDescribe string
)

// The main version number that is being run at the moment.
const Version = "0.4"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = "dev"

// GetHumanVersion composes the parts of the version in a way that's suitable
// for displaying to humans.
func GetHumanVersion() string {

	version := GetVersion()

	release := VersionPrerelease
	if GitDescribe == "" && release == "" {
		release = "dev"
	}
	if release != "" {
		version += fmt.Sprintf("-%s", release)
		if GitCommit != "" {
			version += fmt.Sprintf(" (%s)", GitCommit)
		}
	}

	// Strip off any single quotes added by the git information.
	return strings.Replace(version, "'", "", -1)
}

func GetVersion() string {
	version := Version
	if GitDescribe != "" {
		version = GitDescribe
	}
	return strings.Replace(version, "'", "", -1)
}<|endoftext|>


<commit_before>package mqant

const version = "1.4.4"
<commit_msg>=移除ip地址端口号<commit_after>package mqant

const version = "1.4.5"
<|endoftext|>


<commit_before>package main

const Name = "ghr"
const Version string = "v0.3.0"

// Describe latest commit hash.
// This is automatically extracted by git describe --always.
var GitCommit string = ""
<commit_msg>v0.4.0-pre<commit_after>package main

const Name = "ghr"
const Version string = "v0.4.0-pre"

// Describe latest commit hash.
// This is automatically extracted by git describe --always.
var GitCommit string = ""
<|endoftext|>


<commit_before>package main

const Version = "0.0.1"
<commit_msg>Bump to 0.1.0<commit_after>package main

const Version = "0.1.0"
<|endoftext|>


<commit_before>package main

import (
  "github.com/schmich/ward/store"
  "github.com/fatih/color"
  "golang.org/x/crypto/ssh/terminal"
  "strings"
  "strconv"
  "bufio"
  "fmt"
  "os"
)

var scanner = bufio.NewScanner(os.Stdin)

func printSuccess(format string, args ...interface {}) {
  fmt.Printf(color.GreenString("✓ ") + format, args...)
}

func printError(format string, args ...interface {}) {
  fmt.Printf(color.RedString("✗ ") + format, args...)
}

func readInput(prompt string) string {
  fmt.Fprint(os.Stderr, prompt)
  color.Set(color.FgHiBlack)
  defer color.Unset()
  scanner.Scan()
  return scanner.Text()
}

func readPassword(prompt string) string {
  fmt.Fprint(os.Stderr, prompt)
  password, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
  println()
  return string(password)
}

func readPasswordConfirm(prompt string) string {
  for {
    password := readPassword(prompt + ": ")
    confirm := readPassword(prompt + " (confirm): ")

    if password != confirm {
      printError("Passwords do not match.\n")
    } else {
      return password
    }
  }
}

func readChar(prompt string, allowedRunes string) byte {
  for {
    response := strings.ToLower(readInput(prompt))

    if len(response) == 0 || !strings.Contains(allowedRunes, string(response[0])) {
      printError("Invalid response.\n")
    } else {
      return response[0]
    }
  }
}

func readYesNo(prompt string) bool {
  response := readChar(prompt + " (y/n)? ", "yn")
  return response == 'y'
}

func readIndex(low, high int, prompt string) int {
  for {
    input := readInput(prompt)
    index, err := strconv.Atoi(input)
    if (err != nil) || (index < low) || (index > high) {
      printError("Invalid choice.\n")
    } else {
      return index
    }
  }
}

func selectCredential(credentials []*store.Credential) *store.Credential {
  for i, credential := range credentials {
    fmt.Fprintf(os.Stderr, "%d. %s\n", i + 1, formatCredential(credential))
  }

  index := readIndex(1, len(credentials), "> ")
  return credentials[index - 1]
}

func findCredential(db *store.Store, query []string) *store.Credential {
  credentials := db.FindCredentials(query)
  if len(credentials) == 0 {
    queryString := strings.Join(query, " ")
    printError("No credentials match \"%s\".\n", queryString)
    return nil
  } else if len(credentials) == 1 {
    return credentials[0]
  } else {
    queryString := strings.Join(query, " ")
    fmt.Fprintf(os.Stderr, "Found multiple credentials matching \"%s\":\n", queryString)
    return selectCredential(credentials)
  }
}

func formatCredential(credential *store.Credential) string {
  loginRealm := ""
  if len(credential.Login) > 0 && len(credential.Realm) > 0 {
    loginRealm = credential.Login + "@" + credential.Realm
  } else {
    loginRealm = credential.Login + credential.Realm
  }

  if len(credential.Note) == 0 {
    return loginRealm
  }

  if len(loginRealm) == 0 {
    return credential.Note
  } else {
    return loginRealm + " (" + credential.Note + ")"
  }
}
<commit_msg>Trim space when reading index or single characters.<commit_after>package main

import (
  "github.com/schmich/ward/store"
  "github.com/fatih/color"
  "golang.org/x/crypto/ssh/terminal"
  "strings"
  "strconv"
  "bufio"
  "fmt"
  "os"
)

var scanner = bufio.NewScanner(os.Stdin)

func printSuccess(format string, args ...interface {}) {
  fmt.Printf(color.GreenString("✓ ") + format, args...)
}

func printError(format string, args ...interface {}) {
  fmt.Printf(color.RedString("✗ ") + format, args...)
}

func readInput(prompt string) string {
  fmt.Fprint(os.Stderr, prompt)
  color.Set(color.FgHiBlack)
  defer color.Unset()
  scanner.Scan()
  return scanner.Text()
}

func readPassword(prompt string) string {
  fmt.Fprint(os.Stderr, prompt)
  password, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
  println()
  return string(password)
}

func readPasswordConfirm(prompt string) string {
  for {
    password := readPassword(prompt + ": ")
    confirm := readPassword(prompt + " (confirm): ")

    if password != confirm {
      printError("Passwords do not match.\n")
    } else {
      return password
    }
  }
}

func readChar(prompt string, allowedRunes string) byte {
  for {
    response := strings.ToLower(strings.TrimSpace(readInput(prompt)))

    if len(response) == 0 || !strings.Contains(allowedRunes, string(response[0])) {
      printError("Invalid response.\n")
    } else {
      return response[0]
    }
  }
}

func readYesNo(prompt string) bool {
  response := readChar(prompt + " (y/n)? ", "yn")
  return response == 'y'
}

func readIndex(low, high int, prompt string) int {
  for {
    input := strings.TrimSpace(readInput(prompt))
    index, err := strconv.Atoi(input)
    if (err != nil) || (index < low) || (index > high) {
      printError("Invalid choice.\n")
    } else {
      return index
    }
  }
}

func selectCredential(credentials []*store.Credential) *store.Credential {
  for i, credential := range credentials {
    fmt.Fprintf(os.Stderr, "%d. %s\n", i + 1, formatCredential(credential))
  }

  index := readIndex(1, len(credentials), "> ")
  return credentials[index - 1]
}

func findCredential(db *store.Store, query []string) *store.Credential {
  credentials := db.FindCredentials(query)
  if len(credentials) == 0 {
    queryString := strings.Join(query, " ")
    printError("No credentials match \"%s\".\n", queryString)
    return nil
  } else if len(credentials) == 1 {
    return credentials[0]
  } else {
    queryString := strings.Join(query, " ")
    fmt.Fprintf(os.Stderr, "Found multiple credentials matching \"%s\":\n", queryString)
    return selectCredential(credentials)
  }
}

func formatCredential(credential *store.Credential) string {
  loginRealm := ""
  if len(credential.Login) > 0 && len(credential.Realm) > 0 {
    loginRealm = credential.Login + "@" + credential.Realm
  } else {
    loginRealm = credential.Login + credential.Realm
  }

  if len(credential.Note) == 0 {
    return loginRealm
  }

  if len(loginRealm) == 0 {
    return credential.Note
  } else {
    return loginRealm + " (" + credential.Note + ")"
  }
}
<|endoftext|>