<commit_before>// +build windows

package collector

import (
	"github.com/Microsoft/hcsshim"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
)

func init() {
	Factories["container"] = NewContainerMetricsCollector
}

// A ContainerMetricsCollector is a Prometheus collector for containers metrics
type ContainerMetricsCollector struct {
	// Presence
	ContainerAvailable *prometheus.Desc

	// Number of containers
	ContainersCount *prometheus.Desc
	// memory
	UsageCommitBytes            *prometheus.Desc
	UsageCommitPeakBytes        *prometheus.Desc
	UsagePrivateWorkingSetBytes *prometheus.Desc

	// CPU
	RuntimeTotal  *prometheus.Desc
	RuntimeUser   *prometheus.Desc
	RuntimeKernel *prometheus.Desc

	// Network
	BytesReceived          *prometheus.Desc
	BytesSent              *prometheus.Desc
	PacketsReceived        *prometheus.Desc
	PacketsSent            *prometheus.Desc
	DroppedPacketsIncoming *prometheus.Desc
	DroppedPacketsOutgoing *prometheus.Desc
}

// NewContainerMetricsCollector constructs a new ContainerMetricsCollector
func NewContainerMetricsCollector() (Collector, error) {
	const subsystem = "container"
	return &ContainerMetricsCollector{
		ContainerAvailable: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "available"),
			"Available",
			[]string{"container_id"},
			nil,
		),
		ContainersCount: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "count"),
			"Number of containers",
			nil,
			nil,
		),
		UsageCommitBytes: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "memory_usage_commit_bytes"),
			"Memory Usage Commit Bytes",
			[]string{"container_id"},
			nil,
		),
		UsageCommitPeakBytes: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "memory_usage_commit_peak_bytes"),
			"Memory Usage Commit Peak Bytes",
			[]string{"container_id"},
			nil,
		),
		UsagePrivateWorkingSetBytes: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "memory_usage_private_working_set_bytes"),
			"Memory Usage Private Working Set Bytes",
			[]string{"container_id"},
			nil,
		),
		RuntimeTotal: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "cpu_usage_seconds_total"),
			"Total Run time in Seconds",
			[]string{"container_id"},
			nil,
		),
		RuntimeUser: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "cpu_usage_seconds_usermode"),
			"Run Time in User mode in Seconds",
			[]string{"container_id"},
			nil,
		),
		RuntimeKernel: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "cpu_usage_seconds_kernelmode"),
			"Run time in Kernel mode in Seconds",
			[]string{"container_id"},
			nil,
		),
		BytesReceived: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_receive_bytes_total"),
			"Bytes Received on Interface",
			[]string{"container_id", "interface"},
			nil,
		),
		BytesSent: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_transmit_bytes_total"),
			"Bytes Sent on Interface",
			[]string{"container_id", "interface"},
			nil,
		),
		PacketsReceived: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_receive_packets_total"),
			"Packets Received on Interface",
			[]string{"container_id", "interface"},
			nil,
		),
		PacketsSent: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_transmit_packets_total"),
			"Packets Sent on Interface",
			[]string{"container_id", "interface"},
			nil,
		),
		DroppedPacketsIncoming: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_receive_packets_dropped_total"),
			"Dropped Incoming Packets on Interface",
			[]string{"container_id", "interface"},
			nil,
		),
		DroppedPacketsOutgoing: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_transmit_packets_dropped_total"),
			"Dropped Outgoing Packets on Interface",
			[]string{"container_id", "interface"},
			nil,
		),
	}, nil
}

// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *ContainerMetricsCollector) Collect(ch chan<- prometheus.Metric) error {
	if desc, err := c.collect(ch); err != nil {
		log.Error("failed collecting ContainerMetricsCollector metrics:", desc, err)
		return err
	}
	return nil
}

// containerClose closes the container resource
func containerClose(c hcsshim.Container) {
	err := c.Close()
	if err != nil {
		log.Error(err)
	}
}

func (c *ContainerMetricsCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {

	// Types Container is passed to get the containers compute systems only
	containers, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{Types: []string{"Container"}})
	if err != nil {
		log.Error("Err in Getting containers:", err)
		return nil, err
	}

	count := len(containers)

	ch <- prometheus.MustNewConstMetric(
		c.ContainersCount,
		prometheus.GaugeValue,
		float64(count),
	)
	if count == 0 {
		return nil, nil
	}

	for _, containerDetails := range containers {
		containerId := containerDetails.ID

		container, err := hcsshim.OpenContainer(containerId)
		if container != nil {
			defer containerClose(container)
		}
		if err != nil {
			log.Error("err in opening container: ", containerId, err)
			continue
		}

		cstats, err := container.Statistics()
		if err != nil {
			log.Error("err in fetching container Statistics: ", containerId, err)
			continue
		}
		// HCS V1 is for docker runtime. Add the docker:// prefix on container_id
		containerId = "docker://" + containerId

		ch <- prometheus.MustNewConstMetric(
			c.ContainerAvailable,
			prometheus.CounterValue,
			1,
			containerId,
		)
		ch <- prometheus.MustNewConstMetric(
			c.UsageCommitBytes,
			prometheus.GaugeValue,
			float64(cstats.Memory.UsageCommitBytes),
			containerId,
		)
		ch <- prometheus.MustNewConstMetric(
			c.UsageCommitPeakBytes,
			prometheus.GaugeValue,
			float64(cstats.Memory.UsageCommitPeakBytes),
			containerId,
		)
		ch <- prometheus.MustNewConstMetric(
			c.UsagePrivateWorkingSetBytes,
			prometheus.GaugeValue,
			float64(cstats.Memory.UsagePrivateWorkingSetBytes),
			containerId,
		)
		ch <- prometheus.MustNewConstMetric(
			c.RuntimeTotal,
			prometheus.CounterValue,
			float64(cstats.Processor.TotalRuntime100ns)*ticksToSecondsScaleFactor,
			containerId,
		)
		ch <- prometheus.MustNewConstMetric(
			c.RuntimeUser,
			prometheus.CounterValue,
			float64(cstats.Processor.RuntimeUser100ns)*ticksToSecondsScaleFactor,
			containerId,
		)
		ch <- prometheus.MustNewConstMetric(
			c.RuntimeKernel,
			prometheus.CounterValue,
			float64(cstats.Processor.RuntimeKernel100ns)*ticksToSecondsScaleFactor,
			containerId,
		)

		if len(cstats.Network) == 0 {
			log.Info("No Network Stats for container: ", containerId)
			continue
		}

		networkStats := cstats.Network

		for _, networkInterface := range networkStats {
			ch <- prometheus.MustNewConstMetric(
				c.BytesReceived,
				prometheus.CounterValue,
				float64(networkInterface.BytesReceived),
				containerId, networkInterface.EndpointId,
			)
			ch <- prometheus.MustNewConstMetric(
				c.BytesSent,
				prometheus.CounterValue,
				float64(networkInterface.BytesSent),
				containerId, networkInterface.EndpointId,
			)
			ch <- prometheus.MustNewConstMetric(
				c.PacketsReceived,
				prometheus.CounterValue,
				float64(networkInterface.PacketsReceived),
				containerId, networkInterface.EndpointId,
			)
			ch <- prometheus.MustNewConstMetric(
				c.PacketsSent,
				prometheus.CounterValue,
				float64(networkInterface.PacketsSent),
				containerId, networkInterface.EndpointId,
			)
			ch <- prometheus.MustNewConstMetric(
				c.DroppedPacketsIncoming,
				prometheus.CounterValue,
				float64(networkInterface.DroppedPacketsIncoming),
				containerId, networkInterface.EndpointId,
			)
			ch <- prometheus.MustNewConstMetric(
				c.DroppedPacketsOutgoing,
				prometheus.CounterValue,
				float64(networkInterface.DroppedPacketsOutgoing),
				containerId, networkInterface.EndpointId,
			)
			break
		}
	}

	return nil, nil
}
<commit_msg>add container name<commit_after>// +build windows

package collector

import (
	"github.com/Microsoft/hcsshim"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
)

func init() {
	Factories["container"] = NewContainerMetricsCollector
}

// A ContainerMetricsCollector is a Prometheus collector for containers metrics
type ContainerMetricsCollector struct {
	// Presence
	ContainerAvailable *prometheus.Desc

	// Number of containers
	ContainersCount *prometheus.Desc
	// memory
	UsageCommitBytes            *prometheus.Desc
	UsageCommitPeakBytes        *prometheus.Desc
	UsagePrivateWorkingSetBytes *prometheus.Desc

	// CPU
	RuntimeTotal  *prometheus.Desc
	RuntimeUser   *prometheus.Desc
	RuntimeKernel *prometheus.Desc

	// Network
	BytesReceived          *prometheus.Desc
	BytesSent              *prometheus.Desc
	PacketsReceived        *prometheus.Desc
	PacketsSent            *prometheus.Desc
	DroppedPacketsIncoming *prometheus.Desc
	DroppedPacketsOutgoing *prometheus.Desc
}

// NewContainerMetricsCollector constructs a new ContainerMetricsCollector
func NewContainerMetricsCollector() (Collector, error) {
	const subsystem = "container"
	return &ContainerMetricsCollector{
		ContainerAvailable: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "available"),
			"Available",
			[]string{"container_id", "container_name"},
			nil,
		),
		ContainersCount: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "count"),
			"Number of containers",
			nil,
			nil,
		),
		UsageCommitBytes: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "memory_usage_commit_bytes"),
			"Memory Usage Commit Bytes",
			[]string{"container_id", "container_name"},
			nil,
		),
		UsageCommitPeakBytes: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "memory_usage_commit_peak_bytes"),
			"Memory Usage Commit Peak Bytes",
			[]string{"container_id", "container_name"},
			nil,
		),
		UsagePrivateWorkingSetBytes: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "memory_usage_private_working_set_bytes"),
			"Memory Usage Private Working Set Bytes",
			[]string{"container_id", "container_name"},
			nil,
		),
		RuntimeTotal: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "cpu_usage_seconds_total"),
			"Total Run time in Seconds",
			[]string{"container_id", "container_name"},
			nil,
		),
		RuntimeUser: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "cpu_usage_seconds_usermode"),
			"Run Time in User mode in Seconds",
			[]string{"container_id", "container_name"},
			nil,
		),
		RuntimeKernel: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "cpu_usage_seconds_kernelmode"),
			"Run time in Kernel mode in Seconds",
			[]string{"container_id", "container_name"},
			nil,
		),
		BytesReceived: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_receive_bytes_total"),
			"Bytes Received on Interface",
			[]string{"container_id", "container_name", "interface"},
			nil,
		),
		BytesSent: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_transmit_bytes_total"),
			"Bytes Sent on Interface",
			[]string{"container_id", "container_name", "interface"},
			nil,
		),
		PacketsReceived: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_receive_packets_total"),
			"Packets Received on Interface",
			[]string{"container_id", "container_name", "interface"},
			nil,
		),
		PacketsSent: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_transmit_packets_total"),
			"Packets Sent on Interface",
			[]string{"container_id", "container_name", "interface"},
			nil,
		),
		DroppedPacketsIncoming: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_receive_packets_dropped_total"),
			"Dropped Incoming Packets on Interface",
			[]string{"container_id", "container_name", "interface"},
			nil,
		),
		DroppedPacketsOutgoing: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "network_transmit_packets_dropped_total"),
			"Dropped Outgoing Packets on Interface",
			[]string{"container_id", "container_name", "interface"},
			nil,
		),
	}, nil
}

// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *ContainerMetricsCollector) Collect(ch chan<- prometheus.Metric) error {
	if desc, err := c.collect(ch); err != nil {
		log.Error("failed collecting ContainerMetricsCollector metrics:", desc, err)
		return err
	}
	return nil
}

// containerClose closes the container resource
func containerClose(c hcsshim.Container) {
	err := c.Close()
	if err != nil {
		log.Error(err)
	}
}

func (c *ContainerMetricsCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {

	// Types Container is passed to get the containers compute systems only
	containers, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{Types: []string{"Container"}})
	if err != nil {
		log.Error("Err in Getting containers:", err)
		return nil, err
	}

	count := len(containers)

	ch <- prometheus.MustNewConstMetric(
		c.ContainersCount,
		prometheus.GaugeValue,
		float64(count),
	)
	if count == 0 {
		return nil, nil
	}

	for _, containerDetails := range containers {
		containerId := containerDetails.ID
		containerName := containerDetails.Name

		container, err := hcsshim.OpenContainer(containerId)
		if container != nil {
			defer containerClose(container)
		}
		if err != nil {
			log.Error("err in opening container: ", containerId, err)
			continue
		}

		cstats, err := container.Statistics()
		if err != nil {
			log.Error("err in fetching container Statistics: ", containerId, err)
			continue
		}
		// HCS V1 is for docker runtime. Add the docker:// prefix on container_id
		containerId = "docker://" + containerId

		ch <- prometheus.MustNewConstMetric(
			c.ContainerAvailable,
			prometheus.CounterValue,
			1,
			containerId, containerName,
		)
		ch <- prometheus.MustNewConstMetric(
			c.UsageCommitBytes,
			prometheus.GaugeValue,
			float64(cstats.Memory.UsageCommitBytes),
			containerId, containerName,
		)
		ch <- prometheus.MustNewConstMetric(
			c.UsageCommitPeakBytes,
			prometheus.GaugeValue,
			float64(cstats.Memory.UsageCommitPeakBytes),
			containerId, containerName,
		)
		ch <- prometheus.MustNewConstMetric(
			c.UsagePrivateWorkingSetBytes,
			prometheus.GaugeValue,
			float64(cstats.Memory.UsagePrivateWorkingSetBytes),
			containerId, containerName,
		)
		ch <- prometheus.MustNewConstMetric(
			c.RuntimeTotal,
			prometheus.CounterValue,
			float64(cstats.Processor.TotalRuntime100ns)*ticksToSecondsScaleFactor,
			containerId, containerName,
		)
		ch <- prometheus.MustNewConstMetric(
			c.RuntimeUser,
			prometheus.CounterValue,
			float64(cstats.Processor.RuntimeUser100ns)*ticksToSecondsScaleFactor,
			containerId, containerName,
		)
		ch <- prometheus.MustNewConstMetric(
			c.RuntimeKernel,
			prometheus.CounterValue,
			float64(cstats.Processor.RuntimeKernel100ns)*ticksToSecondsScaleFactor,
			containerId, containerName,
		)

		if len(cstats.Network) == 0 {
			log.Info("No Network Stats for container: ", containerId)
			continue
		}

		networkStats := cstats.Network

		for _, networkInterface := range networkStats {
			ch <- prometheus.MustNewConstMetric(
				c.BytesReceived,
				prometheus.CounterValue,
				float64(networkInterface.BytesReceived),
				containerId, containerName, networkInterface.EndpointId,
			)
			ch <- prometheus.MustNewConstMetric(
				c.BytesSent,
				prometheus.CounterValue,
				float64(networkInterface.BytesSent),
				containerId, containerName, networkInterface.EndpointId,
			)
			ch <- prometheus.MustNewConstMetric(
				c.PacketsReceived,
				prometheus.CounterValue,
				float64(networkInterface.PacketsReceived),
				containerId, containerName, networkInterface.EndpointId,
			)
			ch <- prometheus.MustNewConstMetric(
				c.PacketsSent,
				prometheus.CounterValue,
				float64(networkInterface.PacketsSent),
				containerId, containerName, networkInterface.EndpointId,
			)
			ch <- prometheus.MustNewConstMetric(
				c.DroppedPacketsIncoming,
				prometheus.CounterValue,
				float64(networkInterface.DroppedPacketsIncoming),
				containerId, containerName, networkInterface.EndpointId,
			)
			ch <- prometheus.MustNewConstMetric(
				c.DroppedPacketsOutgoing,
				prometheus.CounterValue,
				float64(networkInterface.DroppedPacketsOutgoing),
				containerId, containerName, networkInterface.EndpointId,
			)
			break
		}
	}

	return nil, nil
}
<|endoftext|>


<commit_before>// Package client is a simple library for http.Client to sign Akamai OPEN Edgegrid API requests
package client

import (
	"bytes"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"runtime"
	"strings"

	"github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
	"github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1"
)

var (
	libraryVersion = "0.6.2"
	// UserAgent is the User-Agent value sent for all requests
	UserAgent = "Akamai-Open-Edgegrid-golang/" + libraryVersion + " golang/" + strings.TrimPrefix(runtime.Version(), "go")
	// Client is the *http.Client to use
	Client = http.DefaultClient
)

// NewRequest creates an HTTP request that can be sent to Akamai APIs. A relative URL can be provided in path, which will be resolved to the
// Host specified in Config. If body is specified, it will be sent as the request body.
func NewRequest(config edgegrid.Config, method, path string, body io.Reader) (*http.Request, error) {
	var (
		baseURL *url.URL
		err     error
	)

	if strings.HasPrefix(config.Host, "https://") {
		baseURL, err = url.Parse(config.Host)
	} else {
		baseURL, err = url.Parse("https://" + config.Host)
	}

	if err != nil {
		return nil, err
	}

	rel, err := url.Parse(strings.TrimPrefix(path, "/"))
	if err != nil {
		return nil, err
	}

	u := baseURL.ResolveReference(rel)

	req, err := http.NewRequest(method, u.String(), body)
	if err != nil {
		return nil, err
	}

	req.Header.Add("User-Agent", UserAgent)

	return req, nil
}

// NewJSONRequest creates an HTTP request that can be sent to the Akamai APIs with a JSON body
// The JSON body is encoded and the Content-Type/Accept headers are set automatically.
func NewJSONRequest(config edgegrid.Config, method, path string, body interface{}) (*http.Request, error) {
	jsonBody, err := jsonhooks.Marshal(body)
	if err != nil {
		return nil, err
	}

	buf := bytes.NewReader(jsonBody)
	req, err := NewRequest(config, method, path, buf)
	if err != nil {
		return nil, err
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", "application/json,*/*")

	return req, nil
}

// Do performs a given HTTP Request, signed with the Akamai OPEN Edgegrid
// Authorization header. An edgegrid.Response or an error is returned.
func Do(config edgegrid.Config, req *http.Request) (*http.Response, error) {
	Client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		req = edgegrid.AddRequestHeader(config, req)
		return nil
	}

	req = edgegrid.AddRequestHeader(config, req)
	res, err := Client.Do(req)
	if err != nil {
		return nil, err
	}

	return res, nil
}

// BodyJSON unmarshals the Response.Body into a given data structure
func BodyJSON(r *http.Response, data interface{}) error {
	if data == nil {
		return errors.New("You must pass in an interface{}")
	}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}
	err = jsonhooks.Unmarshal(body, data)

	return err
}
<commit_msg>Add a multipart form data request<commit_after>// Package client is a simple library for http.Client to sign Akamai OPEN Edgegrid API requests
package client

import (
	"bytes"
	"errors"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
	"github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1"
)

var (
	libraryVersion = "0.6.2"
	// UserAgent is the User-Agent value sent for all requests
	UserAgent = "Akamai-Open-Edgegrid-golang/" + libraryVersion + " golang/" + strings.TrimPrefix(runtime.Version(), "go")
	// Client is the *http.Client to use
	Client = http.DefaultClient
)

// NewRequest creates an HTTP request that can be sent to Akamai APIs. A relative URL can be provided in path, which will be resolved to the
// Host specified in Config. If body is specified, it will be sent as the request body.
func NewRequest(config edgegrid.Config, method, path string, body io.Reader) (*http.Request, error) {
	var (
		baseURL *url.URL
		err     error
	)

	if strings.HasPrefix(config.Host, "https://") {
		baseURL, err = url.Parse(config.Host)
	} else {
		baseURL, err = url.Parse("https://" + config.Host)
	}

	if err != nil {
		return nil, err
	}

	rel, err := url.Parse(strings.TrimPrefix(path, "/"))
	if err != nil {
		return nil, err
	}

	u := baseURL.ResolveReference(rel)

	req, err := http.NewRequest(method, u.String(), body)
	if err != nil {
		return nil, err
	}

	req.Header.Add("User-Agent", UserAgent)

	return req, nil
}

// NewJSONRequest creates an HTTP request that can be sent to the Akamai APIs with a JSON body
// The JSON body is encoded and the Content-Type/Accept headers are set automatically.
func NewJSONRequest(config edgegrid.Config, method, path string, body interface{}) (*http.Request, error) {
	jsonBody, err := jsonhooks.Marshal(body)
	if err != nil {
		return nil, err
	}

	buf := bytes.NewReader(jsonBody)
	req, err := NewRequest(config, method, path, buf)
	if err != nil {
		return nil, err
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", "application/json,*/*")

	return req, nil
}

// NewMultiPartFormDataRequest creates an HTTP request that uploads a file to the Akamai API
func NewMultiPartFormDataRequest(config edgegrid.Config, uriPath, filePath string, otherFormParams map[string]string) (*http.Request, error) {
	file, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	// TODO: make this field name configurable
	part, err := writer.CreateFormFile("importFile", filepath.Base(filePath))
	if err != nil {
		return nil, err
	}
	_, err = io.Copy(part, file)

	for key, val := range otherFormParams {
		_ = writer.WriteField(key, val)
	}
	err = writer.Close()
	if err != nil {
		return nil, err
	}

	req, err := NewRequest(config, "POST", uriPath, body)
	req.Header.Set("Content-Type", writer.FormDataContentType())
	return req, err
}

// Do performs a given HTTP Request, signed with the Akamai OPEN Edgegrid
// Authorization header. An edgegrid.Response or an error is returned.
func Do(config edgegrid.Config, req *http.Request) (*http.Response, error) {
	Client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		req = edgegrid.AddRequestHeader(config, req)
		return nil
	}

	req = edgegrid.AddRequestHeader(config, req)
	res, err := Client.Do(req)
	if err != nil {
		return nil, err
	}

	return res, nil
}

// BodyJSON unmarshals the Response.Body into a given data structure
func BodyJSON(r *http.Response, data interface{}) error {
	if data == nil {
		return errors.New("You must pass in an interface{}")
	}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}
	err = jsonhooks.Unmarshal(body, data)

	return err
}
<|endoftext|>


<commit_before>//go:build linux
// +build linux

/*
Copyright 2021 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2enode

import (
	"time"

	"golang.org/x/sys/unix"

	"github.com/onsi/ginkgo"
	"github.com/onsi/gomega"
	"k8s.io/kubernetes/test/e2e/framework"
)

const contentionLockFile = "/var/run/kubelet.lock"

// Kubelet Lock contention tests the lock contention feature.
// Disruptive because the kubelet is restarted in the test.
// NodeSpecialFeature:LockContention because we don't want the test to be picked up by any other
// test suite, hence the unique name "LockContention".
var _ = SIGDescribe("Lock contention [Slow] [Disruptive] [NodeSpecialFeature:LockContention]", func() {

	// Requires `--lock-file` & `--exit-on-lock-contention` flags to be set on the Kubelet.
	ginkgo.It("Kubelet should stop when the test acquires the lock on lock file and restart once the lock is released", func() {

		ginkgo.By("perform kubelet health check to check if kubelet is healthy and running.")
		// Precautionary check that kubelet is healthy before running the test.
		gomega.Expect(kubeletHealthCheck(kubeletHealthCheckURL)).To(gomega.BeTrue())

		ginkgo.By("acquiring the lock on lock file i.e /var/run/kubelet.lock")
		// Open the file with the intention to acquire the lock, this would imitate the behaviour
		// of the another kubelet(self-hosted) trying to start. When this lock contention happens
		// it is expected that the running kubelet must terminate and wait until the lock on the
		// lock file is released.
		// Kubelet uses the same approach to acquire the lock on lock file as shown here:
		// https://github.com/kubernetes/kubernetes/blob/9d2b361ebc7ef28f7cb75596ef40b7c239732d37/cmd/kubelet/app/server.go#L512-#L523
		// and the function definition of Acquire is here:
		// https://github.com/kubernetes/kubernetes/blob/9d2b361ebc7ef28f7cb75596ef40b7c239732d37/pkg/util/flock/flock_unix.go#L26
		fd, err := unix.Open(contentionLockFile, unix.O_CREAT|unix.O_RDWR|unix.O_CLOEXEC, 0600)
		framework.ExpectNoError(err)
		// Defer the lock release in case test fails and we don't reach the step of the release
		// lock. This ensures that we release the lock for sure.
		defer func() {
			err = unix.Flock(fd, unix.LOCK_UN)
			framework.ExpectNoError(err)
		}()
		// Acquire lock.
		err = unix.Flock(fd, unix.LOCK_EX)
		framework.ExpectNoError(err)

		ginkgo.By("verifying the kubelet is not healthy as there was a lock contention.")
		// Once the lock is acquired, check if the kubelet is in healthy state or not.
		// It should not be.
		gomega.Eventually(func() bool {
			return kubeletHealthCheck(kubeletHealthCheckURL)
		}, 10*time.Second, time.Second).Should(gomega.BeFalse())

		ginkgo.By("releasing the lock on lock file i.e /var/run/kubelet.lock, triggering kubelet restart.")
		// Release the lock.
		err = unix.Flock(fd, unix.LOCK_UN)
		framework.ExpectNoError(err)

		// Releasing the lock triggers kubelet to re-acquire the lock and restart.
		ginkgo.By("verifying the kubelet is healthy after restart.")
		// Kubelet should report healthy state.
		gomega.Eventually(func() bool {
			return kubeletHealthCheck(kubeletHealthCheckURL)
		}, 10*time.Second, time.Second).Should(gomega.BeTrue())
	})
})
<commit_msg>Remove the restart kubelet check from the test.<commit_after>//go:build linux
// +build linux

/*
Copyright 2021 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2enode

import (
	"time"

	"golang.org/x/sys/unix"

	"github.com/onsi/ginkgo"
	"github.com/onsi/gomega"
	"k8s.io/kubernetes/test/e2e/framework"
)

const contentionLockFile = "/var/run/kubelet.lock"

// Kubelet Lock contention tests the lock contention feature.
// Disruptive because the kubelet is restarted in the test.
// NodeSpecialFeature:LockContention because we don't want the test to be picked up by any other
// test suite, hence the unique name "LockContention".
var _ = SIGDescribe("Lock contention [Slow] [Disruptive] [NodeSpecialFeature:LockContention]", func() {

	// Requires `--lock-file` & `--exit-on-lock-contention` flags to be set on the Kubelet.
	ginkgo.It("Kubelet should stop when the test acquires the lock on lock file and restart once the lock is released", func() {

		ginkgo.By("perform kubelet health check to check if kubelet is healthy and running.")
		// Precautionary check that kubelet is healthy before running the test.
		gomega.Expect(kubeletHealthCheck(kubeletHealthCheckURL)).To(gomega.BeTrue())

		ginkgo.By("acquiring the lock on lock file i.e /var/run/kubelet.lock")
		// Open the file with the intention to acquire the lock, this would imitate the behaviour
		// of the another kubelet(self-hosted) trying to start. When this lock contention happens
		// it is expected that the running kubelet must terminate and wait until the lock on the
		// lock file is released.
		// Kubelet uses the same approach to acquire the lock on lock file as shown here:
		// https://github.com/kubernetes/kubernetes/blob/9d2b361ebc7ef28f7cb75596ef40b7c239732d37/cmd/kubelet/app/server.go#L512-#L523
		// and the function definition of Acquire is here:
		// https://github.com/kubernetes/kubernetes/blob/9d2b361ebc7ef28f7cb75596ef40b7c239732d37/pkg/util/flock/flock_unix.go#L26
		fd, err := unix.Open(contentionLockFile, unix.O_CREAT|unix.O_RDWR|unix.O_CLOEXEC, 0600)
		framework.ExpectNoError(err)
		// Defer the lock release in case test fails and we don't reach the step of the release
		// lock. This ensures that we release the lock for sure.
		defer func() {
			err = unix.Flock(fd, unix.LOCK_UN)
			framework.ExpectNoError(err)
		}()
		// Acquire lock.
		err = unix.Flock(fd, unix.LOCK_EX)
		framework.ExpectNoError(err)

		ginkgo.By("verifying the kubelet is not healthy as there was a lock contention.")
		// Once the lock is acquired, check if the kubelet is in healthy state or not.
		// It should not be as the lock contention forces the kubelet to stop.
		gomega.Eventually(func() bool {
			return kubeletHealthCheck(kubeletHealthCheckURL)
		}, 10*time.Second, time.Second).Should(gomega.BeFalse())
	})
})
<|endoftext|>


<commit_before>/*
Copyright (C) 2013 Lucy

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

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

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

package main

import (
	"encoding/binary"
	"flag"
	"fmt"
	"os"

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

var dbuf [][]bool

var (
	step  = flag.Int("s", 2, "number of samples to average in each column")
	dim   = flag.Bool("d", false, "don't use bold")
	color = flag.String("c", "blue", "which color to use")
	file  = flag.String("f", "/tmp/mpd.fifo",
		"where to read fifo output from")
)

var colors = map[string]termbox.Attribute{
	"default": termbox.ColorDefault,
	"black":   termbox.ColorBlack,
	"red":     termbox.ColorRed,
	"green":   termbox.ColorGreen,
	"yellow":  termbox.ColorYellow,
	"blue":    termbox.ColorBlue,
	"magenta": termbox.ColorMagenta,
	"cyan":    termbox.ColorCyan,
	"white":   termbox.ColorWhite,
}

var on termbox.Attribute
var off = termbox.ColorBlack

func main() {
	flag.Parse()
	var ok bool
	on, ok = colors[*color]
	if !ok {
		die("unknown color " + *color)
	}
	if !*dim {
		on = on | termbox.AttrBold
	}

	file, err := os.Open(*file)
	if err != nil {
		die(err)
	}

	err = termbox.Init()
	if err != nil {
		die(err)
	}
	defer termbox.Close()

	clear()

	// input handler
	go func() {
		for {
			ev := termbox.PollEvent()
			if ev.Ch == 0 && ev.Key == termbox.KeyCtrlC {
				termbox.Close()
				os.Exit(0)
			}
		}
	}()

	ch := make(chan int16, 128)
	go draw(ch)
	for {
		var i int16
		binary.Read(file, binary.LittleEndian, &i)
		ch <- i
	}
}

func flush() {
	w, h := len(dbuf[0]), len(dbuf)
	for x := 0; x < h; x++ {
		for y := 0; y < w; y++ {
			if y%2 != 0 {
				continue
			}

			up, down := dbuf[x][y], dbuf[x][y+1]
			switch {
			case up:
				termbox.SetCell(x, y/2, '▀', on, off)
			case down:
				termbox.SetCell(x, y/2, '▄', on, off)
			}
		}
	}
	termbox.Flush()
}

func clear() {
	termbox.Clear(0, 0)
	w, h := termbox.Size()
	h *= 2
	dbuf = make([][]bool, w)
	for i := 0; i < w; i++ {
		dbuf[i] = make([]bool, h)
		for j := 0; j < h; j++ {
			dbuf[i][j] = false
		}
	}
}

func draw(c chan int16) {
	for pos := 0; ; pos++ {
		w, h := len(dbuf), len(dbuf[0])
		if pos >= w {
			flush()
			clear()
			pos = 0
		}

		var v float64
		for i := 0; i < *step; i++ {
			v += float64(<-c)
		}

		half_h := float64(h / 2)
		v = (v/float64(*step))/(32768/half_h) + half_h
		dbuf[pos][int(v)] = true
	}
}

func die(args ...interface{}) {
	fmt.Fprintf(os.Stderr, "mpdviz: %s\n", fmt.Sprint(args...))
	os.Exit(1)
}
<commit_msg>add sectrum visualization<commit_after>/*
Copyright (C) 2013 Lucy

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

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

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

package main

import (
	"encoding/binary"
	"flag"
	"fmt"
	"math"
	"math/cmplx"
	"os"

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

var (
	color = flag.String("c", "blue", "which color to use")
	dim   = flag.Bool("d", false, "don't use bold")

	step = flag.Int("step", 2,
		"number of samples to average in each column (for wave)")
	scale = flag.Float64("scale", 3,
		"scale divisor (for spectrum)")

	file = flag.String("f", "/tmp/mpd.fifo",
		"where to read fifo output from")
	vis = flag.String("v", "wave",
		"choose visualization (spectrum or wave)")
)

var colors = map[string]termbox.Attribute{
	"default": termbox.ColorDefault,
	"black":   termbox.ColorBlack,
	"red":     termbox.ColorRed,
	"green":   termbox.ColorGreen,
	"yellow":  termbox.ColorYellow,
	"blue":    termbox.ColorBlue,
	"magenta": termbox.ColorMagenta,
	"cyan":    termbox.ColorCyan,
	"white":   termbox.ColorWhite,
}

var on termbox.Attribute
var off = termbox.ColorDefault

var dbuf [][]bool

func main() {
	flag.Parse()
	var ok bool
	on, ok = colors[*color]
	if !ok {
		die("unknown color " + *color)
	}
	if !*dim {
		on = on | termbox.AttrBold
	}

	file, err := os.Open(*file)
	if err != nil {
		die(err)
	}

	err = termbox.Init()
	if err != nil {
		die(err)
	}
	defer termbox.Close()

	clear()

	ch := make(chan int16, 128)
	switch *vis {
	case "spectrum":
		go drawSpectrum(ch)
	case "wave":
		go drawWave(ch)
	default:
		fmt.Fprintf(os.Stderr, "mpdviz: unknown visualization %s\n"+
			"supported visualizations: spectrum, wave", *vis)
		os.Exit(1)
	}

	go func() {
		for {
			var i int16
			binary.Read(file, binary.LittleEndian, &i)
			ch <- i
		}
	}()

	// input handler
	for {
		ev := termbox.PollEvent()
		if ev.Ch == 0 && ev.Key == termbox.KeyCtrlC {
			termbox.Close()
			os.Exit(0)
		}
	}

}

func flush(both, upc, downc rune) {
	w, h := len(dbuf[0]), len(dbuf)
	for x := 0; x < h; x++ {
		for y := 0; y < w; y++ {
			if y%2 != 0 {
				continue
			}

			up, down := dbuf[x][y], dbuf[x][y+1]
			switch {
			case up && down:
				termbox.SetCell(x, y/2, both, on, off)
			case up:
				termbox.SetCell(x, y/2, upc, on, off)
			case down:
				termbox.SetCell(x, y/2, downc, on, off)
			}
		}
	}
	termbox.Flush()
}

func clear() {
	termbox.Clear(0, 0)
	w, h := termbox.Size()
	h *= 2
	dbuf = make([][]bool, w)
	for i := 0; i < w; i++ {
		dbuf[i] = make([]bool, h)
		for j := 0; j < h; j++ {
			dbuf[i][j] = false
		}
	}
}

func drawWave(c chan int16) {
	for pos := 0; ; pos++ {
		w, h := len(dbuf), len(dbuf[0])
		if pos >= w {
			flush('█', '▀', '▄')
			clear()
			pos = 0
		}

		var v float64
		for i := 0; i < *step; i++ {
			v += float64(<-c)
		}

		half_h := float64(h / 2)
		v = (v/float64(*step))/(32768/half_h) + half_h
		dbuf[pos][int(v)] = true
	}
}

func drawSpectrum(c chan int16) {
	var (
		samples = 2048
		resn    = samples/2 + 1
		mag     = make([]float64, resn)
		in      = make([]float64, samples)
		out     = fftw.Alloc1d(resn)
		plan    = fftw.PlanDftR2C1d(in, out, fftw.Estimate)
	)

	// TODO: improve efficiency, possibly dither more frames
	for {
		w, h := len(dbuf), len(dbuf[0])
		for i := 0; i < samples; i++ {
			in[i] = float64(<-c)
		}

		plan.Execute()
		for i := 0; i < resn; i++ {
			mag[i] = cmplx.Abs(out[i]) / 1e5 * float64(h) / *scale
		}

		mlen := resn / w
		for i := 0; i < w; i++ {
			v := 0.0
			for _, m := range mag[mlen*i:][:mlen] {
				v += m
			}
			v /= float64(mlen)
			v = math.Min(float64(h), v)
			for j := h - 1; j > h-int(v); j-- {
				dbuf[i][j] = true
			}
		}

		flush('┃', '╹', '╻')
		clear()
	}
}

func die(args ...interface{}) {
	fmt.Fprintf(os.Stderr, "mpdviz: %s\n", fmt.Sprint(args...))
	os.Exit(1)
}
<|endoftext|>


<commit_before>package htlcswitch

import (
	"fmt"
	"sync"

	"github.com/go-errors/errors"
	"github.com/lightningnetwork/lnd/lnwire"
)

// PaymentCircuit is used by the HTLC switch subsystem to determine the
// backwards path for the settle/fail HTLC messages. A payment circuit
// will be created once a channel link forwards the HTLC add request and
// removed when we receive a settle/fail HTLC message.
type PaymentCircuit struct {
	// PaymentHash used as unique identifier of payment.
	PaymentHash [32]byte

	// IncomingChanID identifies the channel from which add HTLC request
	// came and to which settle/fail HTLC request will be returned back.
	// Once the switch forwards the settle/fail message to the src the
	// circuit is considered to be completed.
	IncomingChanID lnwire.ShortChannelID

	// IncomingHTLCID is the ID in the update_add_htlc message we received
	// from the incoming channel, which will be included in any settle/fail
	// messages we send back.
	IncomingHTLCID uint64

	// IncomingAmt is the value of the incoming HTLC. If we take this and
	// subtract it from the OutgoingAmt, then we'll compute the total fee
	// attached to this payment circuit.
	IncomingAmt lnwire.MilliSatoshi

	// OutgoingChanID identifies the channel to which we propagate the HTLC
	// add update and from which we are expecting to receive HTLC
	// settle/fail request back.
	OutgoingChanID lnwire.ShortChannelID

	// OutgoingHTLCID is the ID in the update_add_htlc message we sent to
	// the outgoing channel.
	OutgoingHTLCID uint64

	// OutgoingAmt is the value of the outgoing HTLC. If we subtract this
	// from the IncomingAmt, then we'll compute the total fee attached to
	// this payment circuit.
	OutgoingAmt lnwire.MilliSatoshi

	// ErrorEncrypter is used to re-encrypt the onion failure before
	// sending it back to the originator of the payment.
	ErrorEncrypter ErrorEncrypter
}

// circuitKey is a channel ID, HTLC ID tuple used as an identifying key for a
// payment circuit. The circuit map is keyed with the identifier for the
// outgoing HTLC
type circuitKey struct {
	chanID lnwire.ShortChannelID
	htlcID uint64
}

// String returns a string representation of the circuitKey.
func (k *circuitKey) String() string {
	return fmt.Sprintf("(Chan ID=%s, HTLC ID=%d)", k.chanID, k.htlcID)
}

// CircuitMap is a data structure that implements thread safe storage of
// circuit routing information. The switch consults a circuit map to determine
// where to forward HTLC update messages. Each circuit is stored with its
// outgoing HTLC as the primary key because, each offered HTLC has at most one
// received HTLC, but there may be multiple offered or received HTLCs with the
// same payment hash. Circuits are also indexed to provide fast lookups by
// payment hash.
//
// TODO(andrew.shvv) make it persistent
type CircuitMap struct {
	mtx       sync.RWMutex
	circuits  map[circuitKey]*PaymentCircuit
	hashIndex map[[32]byte]map[PaymentCircuit]struct{}
}

// NewCircuitMap creates a new instance of the CircuitMap.
func NewCircuitMap() *CircuitMap {
	return &CircuitMap{
		circuits:  make(map[circuitKey]*PaymentCircuit),
		hashIndex: make(map[[32]byte]map[PaymentCircuit]struct{}),
	}
}

// LookupByHTLC looks up the payment circuit by the outgoing channel and HTLC
// IDs. Returns nil if there is no such circuit.
func (cm *CircuitMap) LookupByHTLC(chanID lnwire.ShortChannelID, htlcID uint64) *PaymentCircuit {
	cm.mtx.RLock()

	key := circuitKey{
		chanID: chanID,
		htlcID: htlcID,
	}
	circuit := cm.circuits[key]

	cm.mtx.RUnlock()
	return circuit
}

// LookupByPaymentHash looks up and returns any payment circuits with a given
// payment hash.
func (cm *CircuitMap) LookupByPaymentHash(hash [32]byte) []*PaymentCircuit {
	cm.mtx.RLock()

	var circuits []*PaymentCircuit
	if circuitSet, ok := cm.hashIndex[hash]; ok {
		circuits = make([]*PaymentCircuit, 0, len(circuitSet))
		for circuit := range circuitSet {
			circuits = append(circuits, &circuit)
		}
	}

	cm.mtx.RUnlock()
	return circuits
}

// Add adds a new active payment circuit to the CircuitMap.
func (cm *CircuitMap) Add(circuit *PaymentCircuit) error {
	cm.mtx.Lock()

	key := circuitKey{
		chanID: circuit.OutgoingChanID,
		htlcID: circuit.OutgoingHTLCID,
	}
	cm.circuits[key] = circuit

	// Add circuit to the hash index.
	if _, ok := cm.hashIndex[circuit.PaymentHash]; !ok {
		cm.hashIndex[circuit.PaymentHash] = make(map[PaymentCircuit]struct{})
	}
	cm.hashIndex[circuit.PaymentHash][*circuit] = struct{}{}

	cm.mtx.Unlock()
	return nil
}

// Remove destroys the target circuit by removing it from the circuit map.
func (cm *CircuitMap) Remove(chanID lnwire.ShortChannelID, htlcID uint64) error {
	cm.mtx.Lock()
	defer cm.mtx.Unlock()

	// Look up circuit so that pointer can be matched in the hash index.
	key := circuitKey{
		chanID: chanID,
		htlcID: htlcID,
	}
	circuit, found := cm.circuits[key]
	if !found {
		return errors.Errorf("Can't find circuit for HTLC %v", key)
	}
	delete(cm.circuits, key)

	// Remove circuit from hash index.
	circuitsWithHash, ok := cm.hashIndex[circuit.PaymentHash]
	if !ok {
		return errors.Errorf("Can't find circuit in hash index for HTLC %v",
			key)
	}

	if _, ok = circuitsWithHash[*circuit]; !ok {
		return errors.Errorf("Can't find circuit in hash index for HTLC %v",
			key)
	}

	delete(circuitsWithHash, *circuit)
	if len(circuitsWithHash) == 0 {
		delete(cm.hashIndex, circuit.PaymentHash)
	}
	return nil
}

// pending returns number of circuits which are waiting for to be completed
// (settle/fail responses to be received).
func (cm *CircuitMap) pending() int {
	cm.mtx.RLock()
	count := len(cm.circuits)
	cm.mtx.RUnlock()
	return count
}
<commit_msg>htlcswitch/circuit: add half adds to circuit map<commit_after>package htlcswitch

import (
	"encoding/binary"
	"io"

	"github.com/lightningnetwork/lnd/channeldb"
	"github.com/lightningnetwork/lnd/lnwire"
)

// EmptyCircuitKey is a default value for an outgoing circuit key returned when
// a circuit's keystone has not been set. Note that this value is invalid for
// use as a keystone, since the outgoing channel id can never be equal to
// sourceHop.
var EmptyCircuitKey CircuitKey

// CircuitKey is a tuple of channel ID and HTLC ID, used to uniquely identify
// HTLCs in a circuit. Circuits are identified primarily by the circuit key of
// the incoming HTLC. However, a circuit may also be referenced by its outgoing
// circuit key after the HTLC has been forwarded via the outgoing link.
type CircuitKey = channeldb.CircuitKey

// PaymentCircuit is used by the switch as placeholder between when the
// switch makes a forwarding decision and the outgoing link determines the
// proper HTLC ID for the local log. After the outgoing HTLC ID has been
// determined, the half circuit will be converted into a full PaymentCircuit.
type PaymentCircuit struct {
	// AddRef is the forward reference of the Add update in the incoming
	// link's forwarding package. This value is set on the htlcPacket of the
	// returned settle/fail so that it can be removed from disk.
	AddRef channeldb.AddRef

	// Incoming is the circuit key identifying the incoming channel and htlc
	// index from which this ADD originates.
	Incoming CircuitKey

	// Outgoing is the circuit key identifying the outgoing channel, and the
	// HTLC index that was used to forward the ADD. It will be nil if this
	// circuit's keystone has not been set.
	Outgoing *CircuitKey

	// PaymentHash used as unique identifier of payment.
	PaymentHash [32]byte

	// IncomingAmount is the value of the HTLC from the incoming link.
	IncomingAmount lnwire.MilliSatoshi

	// OutgoingAmount specifies the value of the HTLC leaving the switch,
	// either as a payment or forwarded amount.
	OutgoingAmount lnwire.MilliSatoshi

	// ErrorEncrypter is used to re-encrypt the onion failure before
	// sending it back to the originator of the payment.
	ErrorEncrypter ErrorEncrypter

	// LoadedFromDisk is set true for any circuits loaded after the circuit
	// map is reloaded from disk.
	//
	// NOTE: This value is determined implicitly during a restart. It is not
	// persisted, and should never be set outside the circuit map.
	LoadedFromDisk bool
}

// HasKeystone returns true if an outgoing link has assigned this circuit's
// outgoing circuit key.
func (c *PaymentCircuit) HasKeystone() bool {
	return c.Outgoing != nil
}

// newPaymentCircuit initializes a payment circuit on the heap using the payment
// hash and an in-memory htlc packet.
func newPaymentCircuit(hash *[32]byte, pkt *htlcPacket) *PaymentCircuit {
	var addRef channeldb.AddRef
	if pkt.sourceRef != nil {
		addRef = *pkt.sourceRef
	}

	return &PaymentCircuit{
		AddRef: addRef,
		Incoming: CircuitKey{
			ChanID: pkt.incomingChanID,
			HtlcID: pkt.incomingHTLCID,
		},
		PaymentHash:    *hash,
		IncomingAmount: pkt.incomingAmount,
		OutgoingAmount: pkt.amount,
		ErrorEncrypter: pkt.obfuscator,
	}
}

// makePaymentCircuit initalizes a payment circuit on the stack using the
// payment hash and an in-memory htlc packet.
func makePaymentCircuit(hash *[32]byte, pkt *htlcPacket) PaymentCircuit {
	var addRef channeldb.AddRef
	if pkt.sourceRef != nil {
		addRef = *pkt.sourceRef
	}

	return PaymentCircuit{
		AddRef: addRef,
		Incoming: CircuitKey{
			ChanID: pkt.incomingChanID,
			HtlcID: pkt.incomingHTLCID,
		},
		PaymentHash:    *hash,
		IncomingAmount: pkt.incomingAmount,
		OutgoingAmount: pkt.amount,
		ErrorEncrypter: pkt.obfuscator,
	}
}

// Encode writes a PaymentCircuit to the provided io.Writer.
func (c *PaymentCircuit) Encode(w io.Writer) error {
	if err := c.AddRef.Encode(w); err != nil {
		return err
	}

	if err := c.Incoming.Encode(w); err != nil {
		return err
	}

	if _, err := w.Write(c.PaymentHash[:]); err != nil {
		return err
	}

	var scratch [8]byte

	binary.BigEndian.PutUint64(scratch[:], uint64(c.IncomingAmount))
	if _, err := w.Write(scratch[:]); err != nil {
		return err
	}

	binary.BigEndian.PutUint64(scratch[:], uint64(c.OutgoingAmount))
	if _, err := w.Write(scratch[:]); err != nil {
		return err
	}

	// Defaults to EncrypterTypeNone.
	var encrypterType EncrypterType
	if c.ErrorEncrypter != nil {
		encrypterType = c.ErrorEncrypter.Type()
	}

	err := binary.Write(w, binary.BigEndian, encrypterType)
	if err != nil {
		return err
	}

	// Skip encoding of error encrypter if this half add does not have one.
	if encrypterType == EncrypterTypeNone {
		return nil
	}

	return c.ErrorEncrypter.Encode(w)
}

// Decode reads a PaymentCircuit from the provided io.Reader.
func (c *PaymentCircuit) Decode(r io.Reader) error {
	if err := c.AddRef.Decode(r); err != nil {
		return err
	}

	if err := c.Incoming.Decode(r); err != nil {
		return err
	}

	if _, err := io.ReadFull(r, c.PaymentHash[:]); err != nil {
		return err
	}

	var scratch [8]byte

	if _, err := io.ReadFull(r, scratch[:]); err != nil {
		return err
	}
	c.IncomingAmount = lnwire.MilliSatoshi(
		binary.BigEndian.Uint64(scratch[:]))

	if _, err := io.ReadFull(r, scratch[:]); err != nil {
		return err
	}
	c.OutgoingAmount = lnwire.MilliSatoshi(
		binary.BigEndian.Uint64(scratch[:]))

	// Read the encrypter type used for this circuit.
	var encrypterType EncrypterType
	err := binary.Read(r, binary.BigEndian, &encrypterType)
	if err != nil {
		return err
	}

	switch encrypterType {
	case EncrypterTypeNone:
		// No encrypter was provided, such as when the payment is
		// locally initiated.
		return nil

	case EncrypterTypeSphinx:
		// Sphinx encrypter was used as this is a forwarded HTLC.
		c.ErrorEncrypter = NewSphinxErrorEncrypter()

	case EncrypterTypeMock:
		// Test encrypter.
		c.ErrorEncrypter = NewMockObfuscator()

	default:
		return UnknownEncrypterType(encrypterType)
	}

	return c.ErrorEncrypter.Decode(r)
}

// InKey returns the primary identifier for the circuit corresponding to the
// incoming HTLC.
func (c *PaymentCircuit) InKey() CircuitKey {
	return c.Incoming
}

// OutKey returns the keystone identifying the outgoing link and HTLC ID. If the
// circuit hasn't been completed, this method returns an EmptyKeystone, which is
// an invalid outgoing circuit key. Only call this method if HasKeystone returns
// true.
func (c *PaymentCircuit) OutKey() CircuitKey {
	if c.Outgoing != nil {
		return *c.Outgoing
	}

	return EmptyCircuitKey
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/mehrdadrad/myping/cli"
	"github.com/mehrdadrad/myping/icmp"
	"github.com/mehrdadrad/myping/icmp/telia"
	"net"
	"regexp"
	"strings"
)

type Provider interface {
	Init(host, version string)
	GetDefaultNode() string
	GetNodes() map[string]string
	Ping() (string, error)
}

var providers = map[string]Provider{"telia": new(telia.Provider)}

func validateProvider(p string) (string, error) {
	p = strings.ToLower(p)
	return p, nil
}

func main() {
	var (
		err    error
		cPName string = "local"
	)

	rep := make(chan string, 1)
	cmd := make(chan string, 1)
	nxt := make(chan struct{}, 1)

	c := cli.Init("local")
	go c.Run(cmd, nxt)

	r, _ := regexp.Compile("(ping|connect) (.*)")

	for {
		select {
		case req := <-cmd:
			subReq := r.FindStringSubmatch(req)
			if len(subReq) == 0 {
				println("syntax error")
				nxt <- struct{}{}
				continue
			}
			switch {
			case subReq[1] == "ping" && cPName == "local":
				p := icmp.NewPing()
				ra, err := net.ResolveIPAddr("ip", subReq[2])
				if err != nil {
					println("cannot resolve", subReq[2], ": Unknown host")
					nxt <- struct{}{}
					continue
				}
				p.IP(ra.String())
				for n := 0; n < 4; n++ {
					p.Ping(rep)
					println(<-rep)
				}
				nxt <- struct{}{}
			case subReq[1] == "ping":
				providers[cPName].Init(subReq[2], "ipv4")
				m, _ := providers[cPName].Ping()
				println(m)
				nxt <- struct{}{}
			case subReq[1] == "connect":
				var pName string
				if pName, err = validateProvider(subReq[2]); err != nil {
					println("provider not available")
					nxt <- struct{}{}
					continue
				}
				cPName = pName
				c.SetPrompt(cPName + "/" + providers[cPName].GetDefaultNode())
				nxt <- struct{}{}
			}
		}
	}
}
<commit_msg>add change node<commit_after>package main

import (
	"github.com/mehrdadrad/myping/cli"
	"github.com/mehrdadrad/myping/icmp"
	"github.com/mehrdadrad/myping/icmp/telia"
	"net"
	"regexp"
	"strings"
)

type Provider interface {
	Set(host, version string)
	GetDefaultNode() string
	GetNodes() map[string]string
	ChangeNode(node string)
	Ping() (string, error)
}

var providers = map[string]Provider{"telia": new(telia.Provider)}

func validateProvider(p string) (string, error) {
	p = strings.ToLower(p)
	return p, nil
}

func main() {
	var (
		err    error
		cPName string = "local"
	)

	rep := make(chan string, 1)
	cmd := make(chan string, 1)
	nxt := make(chan struct{}, 1)

	c := cli.Init("local")
	go c.Run(cmd, nxt)

	r, _ := regexp.Compile("(ping|connect|node) (.*)")

	for {
		select {
		case req := <-cmd:
			subReq := r.FindStringSubmatch(req)
			if len(subReq) == 0 {
				println("syntax error")
				nxt <- struct{}{}
				continue
			}
			switch {
			case subReq[1] == "ping" && cPName == "local":
				p := icmp.NewPing()
				ra, err := net.ResolveIPAddr("ip", subReq[2])
				if err != nil {
					println("cannot resolve", subReq[2], ": Unknown host")
					nxt <- struct{}{}
					continue
				}
				p.IP(ra.String())
				for n := 0; n < 4; n++ {
					p.Ping(rep)
					println(<-rep)
				}
				nxt <- struct{}{}
			case subReq[1] == "ping":
				providers[cPName].Set(subReq[2], "ipv4")
				m, _ := providers[cPName].Ping()
				println(m)
				nxt <- struct{}{}
			case subReq[1] == "node":
				providers[cPName].ChangeNode(subReq[2])
				c.SetPrompt(cPName + "/" + subReq[2])
				nxt <- struct{}{}
			case subReq[1] == "connect":
				var pName string
				if pName, err = validateProvider(subReq[2]); err != nil {
					println("provider not available")
					nxt <- struct{}{}
					continue
				}
				cPName = pName
				c.SetPrompt(cPName + "/" + providers[cPName].GetDefaultNode())
				nxt <- struct{}{}
			}
		}
	}
}
<|endoftext|>


<commit_before>package go_simple_sql

import (
	"database/sql"
	"fmt"
)

type CONN struct {
	DB  sql.DB
	err error
}

func (c *CONN) InitDB(ip, port, user, pwd, dbname, charset string) {
	url := user + ":" + pwd + "@" + "tcp(" + ip + ":" + port + ")/" + dbname + "?charset=" + charset
	&c.DB, c.err = sql.Open("mysql", url)
	if c.err != nil {
		fmt.Println("mysql init fail")
	} else {
		fmt.Println("mysql init success")
	}
}

func (c *CONN) Query(text string) ([]map[string]string, error) {
	rows, err := c.DB.Query(text)
	result := make([]map[string]string, 0)
	if err != nil {
		return result, err
	}
	columns, _ := rows.Columns()
	scanArgs := make([]interface{}, len(columns))
	values := make([]interface{}, len(columns))
	for i := range values {
		scanArgs[i] = &values[i]
	}

	for rows.Next() {
		err = rows.Scan(scanArgs...)
		record := make(map[string]string)
		for i, col := range values {
			if col != nil {
				record[columns[i]] = string(col.([]byte))
			}
		}
		result = append(result, record)
	}
	return result, err
}

func (c *CONN) Update(text string) (int64, error) {
	tx, err := c.DB.Begin()
	if err != nil {
		return 0, err
	}
	result, err := tx.Exec(text)
	if err != nil {
		return 0, err
	}
	tx.Commit()
	rows, err := result.RowsAffected()
	return rows, err
}

func (c *CONN) Insert(text string) (int64, error) {
	tx, err := c.DB.Begin()
	if err != nil {
		return 0, err
	}
	result, err := tx.Exec(text)
	if err != nil {
		return 0, err
	}
	tx.Commit()
	id, err := result.LastInsertId()
	return id, err
}

func (c *CONN) Delete(text string) (int64, error) {
	tx, err := c.DB.Begin()
	if err != nil {
		return 0, err
	}
	result, err := tx.Exec(text)
	if err != nil {
		return 0, err
	}
	tx.Commit()
	rows, err := result.RowsAffected()
	return rows, err
}
<commit_msg>fix bug<commit_after>package go_simple_sql

import (
	"database/sql"
	"fmt"
)

type CONN struct {
	DB  sql.DB
	err error
}

func (c *CONN) InitDB(ip, port, user, pwd, dbname, charset string) {
	url := user + ":" + pwd + "@" + "tcp(" + ip + ":" + port + ")/" + dbname + "?charset=" + charset
	db, err := sql.Open("mysql", url)
	if c.err != nil {
		fmt.Println("mysql init fail")
	} else {
		c.DB = *db
		c.err = err
		fmt.Println("mysql init success")
	}
}

func (c *CONN) Query(text string) ([]map[string]string, error) {
	rows, err := c.DB.Query(text)
	result := make([]map[string]string, 0)
	if err != nil {
		return result, err
	}
	columns, _ := rows.Columns()
	scanArgs := make([]interface{}, len(columns))
	values := make([]interface{}, len(columns))
	for i := range values {
		scanArgs[i] = &values[i]
	}

	for rows.Next() {
		err = rows.Scan(scanArgs...)
		record := make(map[string]string)
		for i, col := range values {
			if col != nil {
				record[columns[i]] = string(col.([]byte))
			}
		}
		result = append(result, record)
	}
	return result, err
}

func (c *CONN) Update(text string) (int64, error) {
	tx, err := c.DB.Begin()
	if err != nil {
		return 0, err
	}
	result, err := tx.Exec(text)
	if err != nil {
		return 0, err
	}
	tx.Commit()
	rows, err := result.RowsAffected()
	return rows, err
}

func (c *CONN) Insert(text string) (int64, error) {
	tx, err := c.DB.Begin()
	if err != nil {
		return 0, err
	}
	result, err := tx.Exec(text)
	if err != nil {
		return 0, err
	}
	tx.Commit()
	id, err := result.LastInsertId()
	return id, err
}

func (c *CONN) Delete(text string) (int64, error) {
	tx, err := c.DB.Begin()
	if err != nil {
		return 0, err
	}
	result, err := tx.Exec(text)
	if err != nil {
		return 0, err
	}
	tx.Commit()
	rows, err := result.RowsAffected()
	return rows, err
}
<|endoftext|>


<commit_before>// +build integration,!no-etcd

/*
Copyright 2014 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package integration

import (
	"testing"
	"time"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/resource"
	"k8s.io/kubernetes/pkg/api/testapi"
	client "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/controller/persistentvolume"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/volume"
	"k8s.io/kubernetes/pkg/watch"
)

func init() {
	requireEtcd()
}

func TestPersistentVolumeClaimBinder(t *testing.T) {
	_, s := runAMaster(t)
	defer s.Close()

	deleteAllEtcdKeys()
	client := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})

	binder := volumeclaimbinder.NewPersistentVolumeClaimBinder(client, 1*time.Second)
	binder.Run()
	defer binder.Stop()

	for _, volume := range createTestVolumes() {
		_, err := client.PersistentVolumes().Create(volume)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}
	}

	volumes, err := client.PersistentVolumes().List(labels.Everything(), fields.Everything())
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if len(volumes.Items) != 2 {
		t.Errorf("expected 2 PVs, got %#v", len(volumes.Items))
	}

	for _, claim := range createTestClaims() {
		_, err := client.PersistentVolumeClaims(api.NamespaceDefault).Create(claim)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}
	}

	claims, err := client.PersistentVolumeClaims(api.NamespaceDefault).List(labels.Everything(), fields.Everything())
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if len(claims.Items) != 3 {
		t.Errorf("expected 3 PVCs, got %#v", len(claims.Items))
	}

	// the binder will eventually catch up and set status on Claims
	watch, err := client.PersistentVolumeClaims(api.NamespaceDefault).Watch(labels.Everything(), fields.Everything(), "0")
	if err != nil {
		t.Fatalf("Couldn't subscribe to PersistentVolumeClaims: %v", err)
	}
	defer watch.Stop()

	boundCount := 0
	expectedBoundCount := 2
	for {
		event := <-watch.ResultChan()
		claim := event.Object.(*api.PersistentVolumeClaim)
		if claim.Spec.VolumeName != "" {
			boundCount++
		}
		if boundCount == expectedBoundCount {
			break
		}
	}

	for _, claim := range createTestClaims() {
		claim, err := client.PersistentVolumeClaims(api.NamespaceDefault).Get(claim.Name)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		if (claim.Name == "claim01" || claim.Name == "claim02") && claim.Spec.VolumeName == "" {
			t.Errorf("Expected claim to be bound: %+v", claim)
		}
		if claim.Name == "claim03" && claim.Spec.VolumeName != "" {
			t.Errorf("Expected claim03 to be unbound: %v", claim)
		}
	}
}

func createTestClaims() []*api.PersistentVolumeClaim {
	return []*api.PersistentVolumeClaim{
		{
			ObjectMeta: api.ObjectMeta{
				Name:      "claim03",
				Namespace: api.NamespaceDefault,
			},
			Spec: api.PersistentVolumeClaimSpec{
				AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
				Resources: api.ResourceRequirements{
					Requests: api.ResourceList{
						api.ResourceName(api.ResourceStorage): resource.MustParse("500G"),
					},
				},
			},
		},
		{
			ObjectMeta: api.ObjectMeta{
				Name:      "claim01",
				Namespace: api.NamespaceDefault,
			},
			Spec: api.PersistentVolumeClaimSpec{
				AccessModes: []api.PersistentVolumeAccessMode{api.ReadOnlyMany, api.ReadWriteOnce},
				Resources: api.ResourceRequirements{
					Requests: api.ResourceList{
						api.ResourceName(api.ResourceStorage): resource.MustParse("8G"),
					},
				},
			},
		},
		{
			ObjectMeta: api.ObjectMeta{
				Name:      "claim02",
				Namespace: api.NamespaceDefault,
			},
			Spec: api.PersistentVolumeClaimSpec{
				AccessModes: []api.PersistentVolumeAccessMode{api.ReadOnlyMany, api.ReadWriteOnce, api.ReadWriteMany},
				Resources: api.ResourceRequirements{
					Requests: api.ResourceList{
						api.ResourceName(api.ResourceStorage): resource.MustParse("5G"),
					},
				},
			},
		},
	}
}

func createTestVolumes() []*api.PersistentVolume {
	return []*api.PersistentVolume{
		{
			ObjectMeta: api.ObjectMeta{
				UID:  "gce-pd-10",
				Name: "gce003",
			},
			Spec: api.PersistentVolumeSpec{
				Capacity: api.ResourceList{
					api.ResourceName(api.ResourceStorage): resource.MustParse("10G"),
				},
				PersistentVolumeSource: api.PersistentVolumeSource{
					GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{
						PDName: "gce123123123",
						FSType: "foo",
					},
				},
				AccessModes: []api.PersistentVolumeAccessMode{
					api.ReadWriteOnce,
					api.ReadOnlyMany,
				},
			},
		},
		{
			ObjectMeta: api.ObjectMeta{
				UID:  "nfs-5",
				Name: "nfs002",
			},
			Spec: api.PersistentVolumeSpec{
				Capacity: api.ResourceList{
					api.ResourceName(api.ResourceStorage): resource.MustParse("5G"),
				},
				PersistentVolumeSource: api.PersistentVolumeSource{
					Glusterfs: &api.GlusterfsVolumeSource{
						EndpointsName: "andintheend",
						Path:          "theloveyoutakeisequaltotheloveyoumake",
					},
				},
				AccessModes: []api.PersistentVolumeAccessMode{
					api.ReadWriteOnce,
					api.ReadOnlyMany,
					api.ReadWriteMany,
				},
			},
		},
	}
}

func TestPersistentVolumeRecycler(t *testing.T) {
	_, s := runAMaster(t)
	defer s.Close()

	deleteAllEtcdKeys()
	client := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})

	binder := volumeclaimbinder.NewPersistentVolumeClaimBinder(client, 1*time.Second)
	binder.Run()
	defer binder.Stop()

	recycler, _ := volumeclaimbinder.NewPersistentVolumeRecycler(client, 1*time.Second, []volume.VolumePlugin{&volume.FakeVolumePlugin{"plugin-name", volume.NewFakeVolumeHost("/tmp/fake", nil, nil)}})
	recycler.Run()
	defer recycler.Stop()

	// This PV will be claimed, released, and recycled.
	pv := &api.PersistentVolume{
		ObjectMeta: api.ObjectMeta{Name: "fake-pv"},
		Spec: api.PersistentVolumeSpec{
			PersistentVolumeSource:        api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: "foo"}},
			Capacity:                      api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("10G")},
			AccessModes:                   []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
			PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimRecycle,
		},
	}

	pvc := &api.PersistentVolumeClaim{
		ObjectMeta: api.ObjectMeta{Name: "fake-pvc"},
		Spec: api.PersistentVolumeClaimSpec{
			Resources:   api.ResourceRequirements{Requests: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("5G")}},
			AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
		},
	}

	watch, _ := client.PersistentVolumes().Watch(labels.Everything(), fields.Everything(), "0")
	defer watch.Stop()

	_, _ = client.PersistentVolumes().Create(pv)
	_, _ = client.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc)

	// wait until the binder pairs the volume and claim
	waitForPersistentVolumePhase(watch, api.VolumeBound)

	// deleting a claim releases the volume, after which it can be recycled
	if err := client.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name); err != nil {
		t.Errorf("error deleting claim %s", pvc.Name)
	}

	waitForPersistentVolumePhase(watch, api.VolumeReleased)
	waitForPersistentVolumePhase(watch, api.VolumeAvailable)
}

func waitForPersistentVolumePhase(w watch.Interface, phase api.PersistentVolumePhase) {
	for {
		event := <-w.ResultChan()
		volume := event.Object.(*api.PersistentVolume)
		if volume.Status.Phase == phase {
			break
		}
	}
}

func TestPersistentVolumeDeleter(t *testing.T) {
	_, s := runAMaster(t)
	defer s.Close()

	deleteAllEtcdKeys()
	client := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})

	binder := volumeclaimbinder.NewPersistentVolumeClaimBinder(client, 1*time.Second)
	binder.Run()
	defer binder.Stop()

	recycler, _ := volumeclaimbinder.NewPersistentVolumeRecycler(client, 1*time.Second, []volume.VolumePlugin{&volume.FakeVolumePlugin{"plugin-name", volume.NewFakeVolumeHost("/tmp/fake", nil, nil)}})
	recycler.Run()
	defer recycler.Stop()

	// This PV will be claimed, released, and recycled.
	pv := &api.PersistentVolume{
		ObjectMeta: api.ObjectMeta{Name: "fake-pv"},
		Spec: api.PersistentVolumeSpec{
			PersistentVolumeSource:        api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/tmp/foo"}},
			Capacity:                      api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("10G")},
			AccessModes:                   []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
			PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimDelete,
		},
	}

	pvc := &api.PersistentVolumeClaim{
		ObjectMeta: api.ObjectMeta{Name: "fake-pvc"},
		Spec: api.PersistentVolumeClaimSpec{
			Resources:   api.ResourceRequirements{Requests: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("5G")}},
			AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
		},
	}

	w, _ := client.PersistentVolumes().Watch(labels.Everything(), fields.Everything(), "0")
	defer w.Stop()

	_, _ = client.PersistentVolumes().Create(pv)
	_, _ = client.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc)

	// wait until the binder pairs the volume and claim
	waitForPersistentVolumePhase(w, api.VolumeBound)

	// deleting a claim releases the volume, after which it can be recycled
	if err := client.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name); err != nil {
		t.Errorf("error deleting claim %s", pvc.Name)
	}

	waitForPersistentVolumePhase(w, api.VolumeReleased)

	for {
		event := <-w.ResultChan()
		if event.Type == watch.Deleted {
			break
		}
	}
}
<commit_msg>added separate clients per caller in integration tests<commit_after>// +build integration,!no-etcd

/*
Copyright 2014 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package integration

import (
	"testing"
	"time"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/resource"
	"k8s.io/kubernetes/pkg/api/testapi"
	client "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/controller/persistentvolume"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/volume"
	"k8s.io/kubernetes/pkg/watch"
)

func init() {
	requireEtcd()
}

func TestPersistentVolumeClaimBinder(t *testing.T) {
	_, s := runAMaster(t)
	defer s.Close()

	deleteAllEtcdKeys()
	binderClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})
	testClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})

	binder := volumeclaimbinder.NewPersistentVolumeClaimBinder(binderClient, 1*time.Second)
	binder.Run()
	defer binder.Stop()

	for _, volume := range createTestVolumes() {
		_, err := testClient.PersistentVolumes().Create(volume)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}
	}

	volumes, err := testClient.PersistentVolumes().List(labels.Everything(), fields.Everything())
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if len(volumes.Items) != 2 {
		t.Errorf("expected 2 PVs, got %#v", len(volumes.Items))
	}

	for _, claim := range createTestClaims() {
		_, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(claim)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}
	}

	claims, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).List(labels.Everything(), fields.Everything())
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if len(claims.Items) != 3 {
		t.Errorf("expected 3 PVCs, got %#v", len(claims.Items))
	}

	// the binder will eventually catch up and set status on Claims
	watch, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Watch(labels.Everything(), fields.Everything(), "0")
	if err != nil {
		t.Fatalf("Couldn't subscribe to PersistentVolumeClaims: %v", err)
	}
	defer watch.Stop()

	boundCount := 0
	expectedBoundCount := 2
	for {
		event := <-watch.ResultChan()
		claim := event.Object.(*api.PersistentVolumeClaim)
		if claim.Spec.VolumeName != "" {
			boundCount++
		}
		if boundCount == expectedBoundCount {
			break
		}
	}

	for _, claim := range createTestClaims() {
		claim, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Get(claim.Name)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		if (claim.Name == "claim01" || claim.Name == "claim02") && claim.Spec.VolumeName == "" {
			t.Errorf("Expected claim to be bound: %+v", claim)
		}
		if claim.Name == "claim03" && claim.Spec.VolumeName != "" {
			t.Errorf("Expected claim03 to be unbound: %v", claim)
		}
	}
}

func createTestClaims() []*api.PersistentVolumeClaim {
	return []*api.PersistentVolumeClaim{
		{
			ObjectMeta: api.ObjectMeta{
				Name:      "claim03",
				Namespace: api.NamespaceDefault,
			},
			Spec: api.PersistentVolumeClaimSpec{
				AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
				Resources: api.ResourceRequirements{
					Requests: api.ResourceList{
						api.ResourceName(api.ResourceStorage): resource.MustParse("500G"),
					},
				},
			},
		},
		{
			ObjectMeta: api.ObjectMeta{
				Name:      "claim01",
				Namespace: api.NamespaceDefault,
			},
			Spec: api.PersistentVolumeClaimSpec{
				AccessModes: []api.PersistentVolumeAccessMode{api.ReadOnlyMany, api.ReadWriteOnce},
				Resources: api.ResourceRequirements{
					Requests: api.ResourceList{
						api.ResourceName(api.ResourceStorage): resource.MustParse("8G"),
					},
				},
			},
		},
		{
			ObjectMeta: api.ObjectMeta{
				Name:      "claim02",
				Namespace: api.NamespaceDefault,
			},
			Spec: api.PersistentVolumeClaimSpec{
				AccessModes: []api.PersistentVolumeAccessMode{api.ReadOnlyMany, api.ReadWriteOnce, api.ReadWriteMany},
				Resources: api.ResourceRequirements{
					Requests: api.ResourceList{
						api.ResourceName(api.ResourceStorage): resource.MustParse("5G"),
					},
				},
			},
		},
	}
}

func createTestVolumes() []*api.PersistentVolume {
	return []*api.PersistentVolume{
		{
			ObjectMeta: api.ObjectMeta{
				UID:  "gce-pd-10",
				Name: "gce003",
			},
			Spec: api.PersistentVolumeSpec{
				Capacity: api.ResourceList{
					api.ResourceName(api.ResourceStorage): resource.MustParse("10G"),
				},
				PersistentVolumeSource: api.PersistentVolumeSource{
					GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{
						PDName: "gce123123123",
						FSType: "foo",
					},
				},
				AccessModes: []api.PersistentVolumeAccessMode{
					api.ReadWriteOnce,
					api.ReadOnlyMany,
				},
			},
		},
		{
			ObjectMeta: api.ObjectMeta{
				UID:  "nfs-5",
				Name: "nfs002",
			},
			Spec: api.PersistentVolumeSpec{
				Capacity: api.ResourceList{
					api.ResourceName(api.ResourceStorage): resource.MustParse("5G"),
				},
				PersistentVolumeSource: api.PersistentVolumeSource{
					Glusterfs: &api.GlusterfsVolumeSource{
						EndpointsName: "andintheend",
						Path:          "theloveyoutakeisequaltotheloveyoumake",
					},
				},
				AccessModes: []api.PersistentVolumeAccessMode{
					api.ReadWriteOnce,
					api.ReadOnlyMany,
					api.ReadWriteMany,
				},
			},
		},
	}
}

func TestPersistentVolumeRecycler(t *testing.T) {
	_, s := runAMaster(t)
	defer s.Close()

	deleteAllEtcdKeys()
	binderClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})
	recyclerClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})
	testClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})

	binder := volumeclaimbinder.NewPersistentVolumeClaimBinder(binderClient, 1*time.Second)
	binder.Run()
	defer binder.Stop()

	recycler, _ := volumeclaimbinder.NewPersistentVolumeRecycler(recyclerClient, 1*time.Second, []volume.VolumePlugin{&volume.FakeVolumePlugin{"plugin-name", volume.NewFakeVolumeHost("/tmp/fake", nil, nil)}})
	recycler.Run()
	defer recycler.Stop()

	// This PV will be claimed, released, and recycled.
	pv := &api.PersistentVolume{
		ObjectMeta: api.ObjectMeta{Name: "fake-pv"},
		Spec: api.PersistentVolumeSpec{
			PersistentVolumeSource:        api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: "foo"}},
			Capacity:                      api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("10G")},
			AccessModes:                   []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
			PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimRecycle,
		},
	}

	pvc := &api.PersistentVolumeClaim{
		ObjectMeta: api.ObjectMeta{Name: "fake-pvc"},
		Spec: api.PersistentVolumeClaimSpec{
			Resources:   api.ResourceRequirements{Requests: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("5G")}},
			AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
		},
	}

	watch, _ := testClient.PersistentVolumes().Watch(labels.Everything(), fields.Everything(), "0")
	defer watch.Stop()

	_, _ = testClient.PersistentVolumes().Create(pv)
	_, _ = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc)

	// wait until the binder pairs the volume and claim
	waitForPersistentVolumePhase(watch, api.VolumeBound)

	// deleting a claim releases the volume, after which it can be recycled
	if err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name); err != nil {
		t.Errorf("error deleting claim %s", pvc.Name)
	}

	waitForPersistentVolumePhase(watch, api.VolumeReleased)
	waitForPersistentVolumePhase(watch, api.VolumeAvailable)
}

func waitForPersistentVolumePhase(w watch.Interface, phase api.PersistentVolumePhase) {
	for {
		event := <-w.ResultChan()
		volume := event.Object.(*api.PersistentVolume)
		if volume.Status.Phase == phase {
			break
		}
	}
}

func TestPersistentVolumeDeleter(t *testing.T) {
	_, s := runAMaster(t)
	defer s.Close()

	deleteAllEtcdKeys()
	binderClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})
	recyclerClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})
	testClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()})

	binder := volumeclaimbinder.NewPersistentVolumeClaimBinder(binderClient, 1*time.Second)
	binder.Run()
	defer binder.Stop()

	recycler, _ := volumeclaimbinder.NewPersistentVolumeRecycler(recyclerClient, 1*time.Second, []volume.VolumePlugin{&volume.FakeVolumePlugin{"plugin-name", volume.NewFakeVolumeHost("/tmp/fake", nil, nil)}})
	recycler.Run()
	defer recycler.Stop()

	// This PV will be claimed, released, and recycled.
	pv := &api.PersistentVolume{
		ObjectMeta: api.ObjectMeta{Name: "fake-pv"},
		Spec: api.PersistentVolumeSpec{
			PersistentVolumeSource:        api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/tmp/foo"}},
			Capacity:                      api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("10G")},
			AccessModes:                   []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
			PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimDelete,
		},
	}

	pvc := &api.PersistentVolumeClaim{
		ObjectMeta: api.ObjectMeta{Name: "fake-pvc"},
		Spec: api.PersistentVolumeClaimSpec{
			Resources:   api.ResourceRequirements{Requests: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("5G")}},
			AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
		},
	}

	w, _ := testClient.PersistentVolumes().Watch(labels.Everything(), fields.Everything(), "0")
	defer w.Stop()

	_, _ = testClient.PersistentVolumes().Create(pv)
	_, _ = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc)

	// wait until the binder pairs the volume and claim
	waitForPersistentVolumePhase(w, api.VolumeBound)

	// deleting a claim releases the volume, after which it can be recycled
	if err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name); err != nil {
		t.Errorf("error deleting claim %s", pvc.Name)
	}

	waitForPersistentVolumePhase(w, api.VolumeReleased)

	for {
		event := <-w.ResultChan()
		if event.Type == watch.Deleted {
			break
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"net"
	"log"
	"io"
	"os"
	"flag"
)

func handle(r io.Reader, w io.Writer) <-chan bool {
	buf := make([]byte, 1024)
	c := make(chan bool)
	go func() {
		defer func() {
			if con, ok := w.(net.Conn); ok {
				con.Close();
				log.Printf("Connection from %v is closed\n", con.RemoteAddr())
			}
			c <- true
		}()

		for {
			n, err := r.Read(buf)
			if err != nil {
				if err != io.EOF {
					log.Printf("Read error: %s\n", err)
				}
				break
			}
			w.Write(buf[0:n])
		}
	}()
	return c
}

func transferStreams(con net.Conn) {
	c1 := handle(os.Stdin, con)
	c2 := handle(con, os.Stdout)
	select {
	case <-c1:
		log.Println("Local program is terminated")
	case <-c2:
		log.Println("Remote connection is closed")
	}
}

func handleUdpIn(r net.PacketConn, w io.Writer) <-chan net.Addr {
	buf := make([]byte, 1024)
	c := make(chan net.Addr)
	go func() {
		var remoteAddr net.Addr = nil
		defer func() {
			if con, ok := w.(net.PacketConn); ok {
				con.Close();
				log.Printf("Connection is closed\n")
			}
			c <- remoteAddr
		}()

		for {
			n, addr, err := r.ReadFrom(buf)
			if err != nil {
				if err != io.EOF {
					log.Printf("Read error: %s\n", err)
				}
				break
			}
			if remoteAddr == nil {
				remoteAddr = addr
				c <- remoteAddr
			}
			w.Write(buf[0:n])
		}
	}()
	return c
}

func handleUdpOut(r io.Reader, w net.PacketConn, addr net.Addr) <-chan bool {
	buf := make([]byte, 1024)
	c := make(chan bool)
	go func() {
		defer func() {
			if con, ok := w.(net.PacketConn); ok {
				con.Close();
				log.Printf("Connection is closed\n")
			}
			c <- true
		}()

		for {
			n, err := r.Read(buf)
			if err != nil {
				if err != io.EOF {
					log.Printf("Read error: %s\n", err)
				}
				break
			}
			w.WriteTo(buf[0:n], addr)
		}
	}()
	return c
}

func transferPackets(con net.PacketConn) {
	c1 := handleUdpIn(con, os.Stdout)
	remoteAddr := <-c1
	c2 := handleUdpOut(os.Stdin, con, remoteAddr)
	select {
		case <-c1:
			log.Println("Remote connection is closed")
		case <-c2:
			log.Println("Local program is terminated")
	}
}

func main() {
	var host, port, proto string
	var listen bool
	flag.StringVar(&host, "host", "", "Remote host to connect, i.e. 127.0.0.1")
	flag.StringVar(&proto, "proto", "tcp", "TCP/UDP mode")
	flag.BoolVar(&listen, "listen", false, "Listen mode")
	flag.StringVar(&port, "port", "", "Port to listen on or connect to (prepended by colon), i.e. :9999")
	flag.Parse()

	if listen {
		if proto == "tcp" {
			ln, err := net.Listen(proto, port)
			if err != nil {
				log.Fatalln(err)
			}
			log.Println("Listening on", port)
			con, err := ln.Accept()
			if err != nil {
				log.Fatalln(err)
			}
			log.Println("Connect from", con.RemoteAddr())
			transferStreams(con)
		} else if proto == "udp" {
			con, err := net.ListenPacket(proto, port)
			if err != nil {
				log.Fatalln(err)
			}
			log.Println("Listening on", port)
			transferPackets(con)
		}
	} else if host != "" {
		con, err := net.Dial(proto, host+port)
		if err != nil {
			log.Fatalln(err)
		}
		log.Println("Connected to", host+port)
		transferStreams(con)
	} else {
		flag.Usage()
	}
}
<commit_msg>Clarify code<commit_after>package main

import (
	"net"
	"log"
	"io"
	"os"
	"flag"
)

func readAndWrite(r io.Reader, w io.Writer) <-chan bool {
	buf := make([]byte, 1024)
	c := make(chan bool)
	go func() {
		defer func() {
			if con, ok := w.(net.Conn); ok {
				con.Close();
				log.Printf("Connection from %v is closed\n", con.RemoteAddr())
			}
			c <- true
		}()

		for {
			n, err := r.Read(buf)
			if err != nil {
				if err != io.EOF {
					log.Printf("Read error: %s\n", err)
				}
				break
			}
			w.Write(buf[0:n])
		}
	}()
	return c
}

func transferStreams(con net.Conn) {
	c1 := readAndWrite(os.Stdin, con)
	c2 := readAndWrite(con, os.Stdout)
	select {
	case <-c1:
		log.Println("Local program is terminated")
	case <-c2:
		log.Println("Remote connection is closed")
	}
}

func receivePackets(r net.PacketConn, w io.Writer) <-chan net.Addr {
	buf := make([]byte, 1024)
	c := make(chan net.Addr)
	go func() {
		var remoteAddr net.Addr = nil
		defer func() {
			c <- remoteAddr
		}()

		for {
			n, addr, err := r.ReadFrom(buf)
			if err != nil {
				if err != io.EOF {
					log.Printf("Read error: %s\n", err)
				}
				break
			}
			if remoteAddr == nil {
				remoteAddr = addr
				c <- remoteAddr
			}
			w.Write(buf[0:n])
		}
	}()
	return c
}

func sendPackets(r io.Reader, w net.PacketConn, addr net.Addr) <-chan bool {
	buf := make([]byte, 1024)
	c := make(chan bool)
	go func() {
		defer func() {
			w.Close();
			c <- true
		}()

		for {
			n, err := r.Read(buf)
			if err != nil {
				if err != io.EOF {
					log.Printf("Read error: %s\n", err)
				}
				break
			}
			w.WriteTo(buf[0:n], addr)
		}
	}()
	return c
}

func transferPackets(con net.PacketConn) {
	c1 := receivePackets(con, os.Stdout)
	remoteAddr := <-c1
	c2 := sendPackets(os.Stdin, con, remoteAddr)
	select {
		case <-c1:
			log.Println("Remote connection is closed")
		case <-c2:
			log.Println("Local program is terminated")
	}
}

func main() {
	var host, port, proto string
	var listen bool
	flag.StringVar(&host, "host", "", "Remote host to connect, i.e. 127.0.0.1")
	flag.StringVar(&proto, "proto", "tcp", "TCP/UDP mode")
	flag.BoolVar(&listen, "listen", false, "Listen mode")
	flag.StringVar(&port, "port", "", "Port to listen on or connect to (prepended by colon), i.e. :9999")
	flag.Parse()

	if listen {
		if proto == "tcp" {
			ln, err := net.Listen(proto, port)
			if err != nil {
				log.Fatalln(err)
			}
			log.Println("Listening on", port)
			con, err := ln.Accept()
			if err != nil {
				log.Fatalln(err)
			}
			log.Println("Connect from", con.RemoteAddr())
			transferStreams(con)
		} else if proto == "udp" {
			con, err := net.ListenPacket(proto, port)
			if err != nil {
				log.Fatalln(err)
			}
			log.Println("Listening on", port)
			transferPackets(con)
		}
	} else if host != "" {
		con, err := net.Dial(proto, host+port)
		if err != nil {
			log.Fatalln(err)
		}
		log.Println("Connected to", host+port)
		transferStreams(con)
	} else {
		flag.Usage()
	}
}
<|endoftext|>


<commit_before>package receiver

import (
	"fmt"
	"testing"
	"time"
)

func BenchmarkPlainParseBuffer(b *testing.B) {
	days := &DaysFrom1970{}
	buf := GetBuffer()
	out := make(chan *WriteBuffer, 1)

	c1 := uint32(0)
	c2 := uint32(0)

	msg := fmt.Sprintf("carbon.agents.localhost.cache.size 1412351 %d\n", time.Now().Unix())

	for i := 0; i < 50; i++ {
		buf.Write([]byte(msg))
	}

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		PlainParseBuffer(nil, buf, out, days, &c1, &c2)
		wb := <-out
		wb.Release()
	}
}
<commit_msg>fix date in benchmark to today<commit_after>package receiver

import (
	"fmt"
	"testing"
	"time"
)

func BenchmarkPlainParseBuffer(b *testing.B) {
	days := &DaysFrom1970{}
	buf := GetBuffer()
	out := make(chan *WriteBuffer, 1)

	c1 := uint32(0)
	c2 := uint32(0)

	now := time.Now().Unix()
	msg := fmt.Sprintf("carbon.agents.localhost.cache.size 1412351 %d\n", now)
	buf.Time = uint32(now)

	for i := 0; i < 50; i++ {
		buf.Write([]byte(msg))
	}

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		PlainParseBuffer(nil, buf, out, days, &c1, &c2)
		wb := <-out
		wb.Release()
	}
}
<|endoftext|>


<commit_before>package tree

// Interface: Receiver
func (ter *Repository) Receive(r ReceiveRequest) {
	if receiveRequestCheck(r, ter) {
		switch r.ChildType {
		case "bucket":
			ter.receiveBucket(r)
		case "fault":
			ter.receiveFault(r)
		default:
			panic(`Repository.Receive`)
		}
		return
	}
	for child, _ := range ter.Children {
		ter.Children[child].(Receiver).Receive(r)
	}
}

// Interface: BucketReceiver
func (ter *Repository) receiveBucket(r ReceiveRequest) {
	if receiveRequestCheck(r, ter) {
		switch r.ChildType {
		case "bucket":
			ter.Children[r.Bucket.GetID()] = r.Bucket
			r.Bucket.setParent(ter)
			r.Bucket.setAction(ter.Action)
		default:
			panic(`Repository.receiveBucket`)
		}
	}
}

// Interface: FaultReceiver
func (ter *Repository) receiveFault(r ReceiveRequest) {
	if receiveRequestCheck(r, ter) {
		switch r.ChildType {
		case "fault":
			ter.setFault(r.Fault)
			ter.Fault.setParent(ter)
			ter.updateFaultRecursive(ter.Fault)
		default:
			panic(`Repository.receiveFault`)
		}
		return
	}
	panic(`Repository.receiveFault`)
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<commit_msg>FIX: add missing setFault() call<commit_after>package tree

// Interface: Receiver
func (ter *Repository) Receive(r ReceiveRequest) {
	if receiveRequestCheck(r, ter) {
		switch r.ChildType {
		case "bucket":
			ter.receiveBucket(r)
		case "fault":
			ter.receiveFault(r)
		default:
			panic(`Repository.Receive`)
		}
		return
	}
	for child, _ := range ter.Children {
		ter.Children[child].(Receiver).Receive(r)
	}
}

// Interface: BucketReceiver
func (ter *Repository) receiveBucket(r ReceiveRequest) {
	if receiveRequestCheck(r, ter) {
		switch r.ChildType {
		case "bucket":
			ter.Children[r.Bucket.GetID()] = r.Bucket
			r.Bucket.setParent(ter)
			r.Bucket.setAction(ter.Action)
			r.Bucket.setFault(ter.Fault)
		default:
			panic(`Repository.receiveBucket`)
		}
	}
}

// Interface: FaultReceiver
func (ter *Repository) receiveFault(r ReceiveRequest) {
	if receiveRequestCheck(r, ter) {
		switch r.ChildType {
		case "fault":
			ter.setFault(r.Fault)
			ter.Fault.setParent(ter)
			ter.updateFaultRecursive(ter.Fault)
		default:
			panic(`Repository.receiveFault`)
		}
		return
	}
	panic(`Repository.receiveFault`)
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<|endoftext|>


<commit_before>package compose

import (
	"errors"
	"fmt"
	"github.com/docker/libcompose/docker"
	"github.com/docker/libcompose/project"
	"github.com/gondor/depcon/pkg/envsubst"
	"io/ioutil"
	"os"
	"strings"
)

const (
	DOCKER_TLS_VERIFY string = "DOCKER_TLS_VERIFY"
)

var (
	ErrorParamsMissing = errors.New("One or more ${PARAMS} that were defined in the compose file could not be resolved.")
)

type ComposeWrapper struct {
	context *Context
	project *project.Project
}

func NewCompose(context *Context) Compose {
	c := new(ComposeWrapper)
	c.context = context
	project, err := c.createDockerContext()
	if err != nil {
		log.Fatal(err)
	}
	c.project = project
	return c
}

func (c *ComposeWrapper) Up(services ...string) error {
	return c.project.Up(services...)
}

func (c *ComposeWrapper) Kill(services ...string) error {
	return c.project.Kill(services...)
}

func (c *ComposeWrapper) Build(services ...string) error {
	return c.project.Build(services...)
}

func (c *ComposeWrapper) Restart(services ...string) error {
	return c.project.Restart(services...)
}

func (c *ComposeWrapper) Pull(services ...string) error {
	return c.project.Pull(services...)
}

func (c *ComposeWrapper) Delete(services ...string) error {
	return c.project.Delete(services...)
}

func (c *ComposeWrapper) Logs(services ...string) error {
	return c.project.Log(services...)
}

func (c *ComposeWrapper) Start(services ...string) error {
	return c.execStartStop(true, services...)
}

func (c *ComposeWrapper) Stop(services ...string) error {
	return c.execStartStop(false, services...)
}

func (c *ComposeWrapper) execStartStop(start bool, services ...string) error {
	if start {
		return c.project.Start(services...)
	}
	return c.project.Down(services...)
}

func (c *ComposeWrapper) Port(index int, proto, service, port string) error {

	s, err := c.project.CreateService(service)
	if err != nil {
		return err
	}

	containers, err := s.Containers()
	if err != nil {
		return err
	}

	if index < 1 || index > len(containers) {
		fmt.Errorf("Invalid index %d", index)
	}

	output, err := containers[index-1].Port(fmt.Sprintf("%s/%s", port, proto))
	if err != nil {
		return err
	}
	fmt.Println(output)
	return nil
}

func (c *ComposeWrapper) PS(quiet bool) error {
	allInfo := project.InfoSet{}

	for name := range c.project.Configs {
		service, err := c.project.CreateService(name)
		if err != nil {
			return err
		}

		info, err := service.Info(quiet)
		if err != nil {
			return err
		}

		allInfo = append(allInfo, info...)
	}
	os.Stdout.WriteString(allInfo.String(!quiet))
	return nil
}

func (c *ComposeWrapper) createDockerContext() (*project.Project, error) {

	clientFactory, err := docker.NewDefaultClientFactory(docker.ClientOpts{})
	if err != nil {
		log.Fatal(err)
	}

	tlsVerify := os.Getenv(DOCKER_TLS_VERIFY)

	if tlsVerify == "1" {
		clientFactory, err = docker.NewDefaultClientFactory(docker.ClientOpts{
			TLS:       true,
			TLSVerify: true,
		})
		if err != nil {
			log.Fatal(err)
		}
	}

	if c.context.EnvParams != nil && len(c.context.EnvParams) > 0 {
		file, err := os.Open(c.context.ComposeFile)
		if err != nil {
			return nil, fmt.Errorf("Error opening filename %s, %s", c.context.ComposeFile, err.Error())
		}
		parsed, missing := envsubst.SubstFileTokens(file, c.context.ComposeFile, c.context.EnvParams)
		log.Debug("Map: %v\nParsed: %s\n", c.context.EnvParams, parsed)

		if c.context.ErrorOnMissingParams && missing {
			return nil, ErrorParamsMissing
		}
		file, err = ioutil.TempFile("", "depcon")
		if err != nil {
			return nil, err
		}
		err = ioutil.WriteFile(file.Name(), []byte(parsed), os.ModeTemporary)
		if err != nil {
			return nil, err
		}
		c.context.ComposeFile = file.Name()
	}
	return docker.NewProject(&docker.Context{
		Context: project.Context{
			ComposeFiles: strings.Split(c.context.ComposeFile, ","),
			ProjectName:  c.context.ProjectName,
		},
		ClientFactory: clientFactory,
	})
}
<commit_msg>fix build due to upstream compose changes<commit_after>package compose

import (
	"errors"
	"fmt"
	"github.com/docker/libcompose/docker"
	"github.com/docker/libcompose/project"
	"github.com/gondor/depcon/pkg/envsubst"
	"io/ioutil"
	"os"
	"strings"
)

const (
	DOCKER_TLS_VERIFY string = "DOCKER_TLS_VERIFY"
)

var (
	ErrorParamsMissing = errors.New("One or more ${PARAMS} that were defined in the compose file could not be resolved.")
)

type ComposeWrapper struct {
	context *Context
	project *project.Project
}

func NewCompose(context *Context) Compose {
	c := new(ComposeWrapper)
	c.context = context
	project, err := c.createDockerContext()
	if err != nil {
		log.Fatal(err)
	}
	c.project = project
	return c
}

func (c *ComposeWrapper) Up(services ...string) error {
	return c.project.Up(services...)
}

func (c *ComposeWrapper) Kill(services ...string) error {
	return c.project.Kill(services...)
}

func (c *ComposeWrapper) Build(services ...string) error {
	return c.project.Build(services...)
}

func (c *ComposeWrapper) Restart(services ...string) error {
	return c.project.Restart(services...)
}

func (c *ComposeWrapper) Pull(services ...string) error {
	return c.project.Pull(services...)
}

func (c *ComposeWrapper) Delete(services ...string) error {
	return c.project.Delete(services...)
}

func (c *ComposeWrapper) Logs(services ...string) error {
	return c.project.Log(services...)
}

func (c *ComposeWrapper) Start(services ...string) error {
	return c.execStartStop(true, services...)
}

func (c *ComposeWrapper) Stop(services ...string) error {
	return c.execStartStop(false, services...)
}

func (c *ComposeWrapper) execStartStop(start bool, services ...string) error {
	if start {
		return c.project.Start(services...)
	}
	return c.project.Down(services...)
}

func (c *ComposeWrapper) Port(index int, proto, service, port string) error {

	s, err := c.project.CreateService(service)
	if err != nil {
		return err
	}

	containers, err := s.Containers()
	if err != nil {
		return err
	}

	if index < 1 || index > len(containers) {
		fmt.Errorf("Invalid index %d", index)
	}

	output, err := containers[index-1].Port(fmt.Sprintf("%s/%s", port, proto))
	if err != nil {
		return err
	}
	fmt.Println(output)
	return nil
}

func (c *ComposeWrapper) PS(quiet bool) error {
	allInfo := project.InfoSet{}

	for _, name := range c.project.Configs.Keys() {
		service, err := c.project.CreateService(name)
		if err != nil {
			return err
		}

		info, err := service.Info(quiet)
		if err != nil {
			return err
		}

		allInfo = append(allInfo, info...)
	}
	os.Stdout.WriteString(allInfo.String(!quiet))
	return nil
}

func (c *ComposeWrapper) createDockerContext() (*project.Project, error) {

	clientFactory, err := docker.NewDefaultClientFactory(docker.ClientOpts{})
	if err != nil {
		log.Fatal(err)
	}

	tlsVerify := os.Getenv(DOCKER_TLS_VERIFY)

	if tlsVerify == "1" {
		clientFactory, err = docker.NewDefaultClientFactory(docker.ClientOpts{
			TLS:       true,
			TLSVerify: true,
		})
		if err != nil {
			log.Fatal(err)
		}
	}

	if c.context.EnvParams != nil && len(c.context.EnvParams) > 0 {
		file, err := os.Open(c.context.ComposeFile)
		if err != nil {
			return nil, fmt.Errorf("Error opening filename %s, %s", c.context.ComposeFile, err.Error())
		}
		parsed, missing := envsubst.SubstFileTokens(file, c.context.ComposeFile, c.context.EnvParams)
		log.Debug("Map: %v\nParsed: %s\n", c.context.EnvParams, parsed)

		if c.context.ErrorOnMissingParams && missing {
			return nil, ErrorParamsMissing
		}
		file, err = ioutil.TempFile("", "depcon")
		if err != nil {
			return nil, err
		}
		err = ioutil.WriteFile(file.Name(), []byte(parsed), os.ModeTemporary)
		if err != nil {
			return nil, err
		}
		c.context.ComposeFile = file.Name()
	}
	return docker.NewProject(&docker.Context{
		Context: project.Context{
			ComposeFiles: strings.Split(c.context.ComposeFile, ","),
			ProjectName:  c.context.ProjectName,
		},
		ClientFactory: clientFactory,
	})
}
<|endoftext|>