<commit_before>package dsqueue

import (
	"firempq/common"
)

const (
	DEFAULT_TTL             = 10000 // In milliseconds
	DEFAULT_DELIVERY_DELAY  = 0
	DEFAULT_LOCK_TIMEOUT    = 1000 // In milliseconds
	DEFAULT_POP_COUNT_LIMIT = 0    // 0 means Unlimited.
)

type DSQueueSettings struct {
	MsgTTL         int64 // Default message TTL.
	DeliveryDelay  int64 // Default delivery delay.
	PopLockTimeout int64 // Timeout before message is getting released.
	PopCountLimit  int64 // Pop count limit. 0 - unlimited. >0 Will be removed after this number of attempts.
	MaxSize        int64 // Max queue size.
	MaxPriority    int64 // Max priority.
	CreateTs       int64 // Time when queue was created.
}

type DSQueueStats struct {
	CreateTs        int64 // Time when queue was created.
	LastPushTs      int64 // Last time item has been pushed into queue.
	LastPopTs       int64 // Last pop time.
	LastPushFrontTs int64 // Last time item has been pushed front into queue.
	LastPopFrontTs  int64 // Last front pop time.
	LastPushBackTs  int64 // Last time item has been pushed back into queue.
	LastPopBackTs   int64 // Last back pop time.
}

func NewDSQueueSettings(size int64) *DSQueueSettings {
	return &DSQueueSettings{
		MsgTTL:         int64(DEFAULT_TTL),
		DeliveryDelay:  int64(DEFAULT_DELIVERY_DELAY),
		PopLockTimeout: int64(DEFAULT_LOCK_TIMEOUT),
		PopCountLimit:  int64(DEFAULT_POP_COUNT_LIMIT),
		MaxSize:        size,
		CreateTs:       common.Uts(),
	}
}

func (p *DSQueueSettings) ToMap() map[string]interface{} {
	res := make(map[string]interface{})
	res["MaxPriority"] = p.MaxPriority
	res["MaxSize"] = p.MaxSize
	res["CreateTs"] = p.CreateTs
	res["PopTimeOut"] = p.PopLockTimeout
	res["DeliveryDelay"] = p.DeliveryDelay
	res["PopCountLimit"] = p.PopCountLimit
	res["MsgTTL"] = p.MsgTTL
	return res
}
<commit_msg>Removed MaxPriority from DSQueue stats.<commit_after>package dsqueue

import (
	"firempq/common"
)

const (
	DEFAULT_TTL             = 10000 // In milliseconds
	DEFAULT_DELIVERY_DELAY  = 0
	DEFAULT_LOCK_TIMEOUT    = 1000 // In milliseconds
	DEFAULT_POP_COUNT_LIMIT = 0    // 0 means Unlimited.
)

type DSQueueSettings struct {
	MsgTTL         int64 // Default message TTL.
	DeliveryDelay  int64 // Default delivery delay.
	PopLockTimeout int64 // Timeout before message is getting released.
	PopCountLimit  int64 // Pop count limit. 0 - unlimited. >0 Will be removed after this number of attempts.
	MaxSize        int64 // Max queue size.
	CreateTs       int64 // Time when queue was created.
}

type DSQueueStats struct {
	CreateTs        int64 // Time when queue was created.
	LastPushTs      int64 // Last time item has been pushed into queue.
	LastPopTs       int64 // Last pop time.
	LastPushFrontTs int64 // Last time item has been pushed front into queue.
	LastPopFrontTs  int64 // Last front pop time.
	LastPushBackTs  int64 // Last time item has been pushed back into queue.
	LastPopBackTs   int64 // Last back pop time.
}

func NewDSQueueSettings(size int64) *DSQueueSettings {
	return &DSQueueSettings{
		MsgTTL:         int64(DEFAULT_TTL),
		DeliveryDelay:  int64(DEFAULT_DELIVERY_DELAY),
		PopLockTimeout: int64(DEFAULT_LOCK_TIMEOUT),
		PopCountLimit:  int64(DEFAULT_POP_COUNT_LIMIT),
		MaxSize:        size,
		CreateTs:       common.Uts(),
	}
}

func (p *DSQueueSettings) ToMap() map[string]interface{} {
	res := make(map[string]interface{})
	res["MaxSize"] = p.MaxSize
	res["CreateTs"] = p.CreateTs
	res["PopTimeOut"] = p.PopLockTimeout
	res["DeliveryDelay"] = p.DeliveryDelay
	res["PopCountLimit"] = p.PopCountLimit
	res["MsgTTL"] = p.MsgTTL
	return res
}
<|endoftext|>


<commit_before>package filewritecache

import (
	"math"

	"github.com/nyaxt/otaru/blobstore"
	"github.com/nyaxt/otaru/logger"
	"github.com/nyaxt/otaru/util"
)

// Below may overwritten from tests
var MaxPatches = 32
var MaxPatchContentLen int64 = 256 * 1024

var wclog = logger.Registry().Category("filewritecache")

type FileWriteCache struct {
	ps Patches
}

func New() *FileWriteCache {
	return &FileWriteCache{ps: NewPatches()}
}

func (wc *FileWriteCache) PWrite(p []byte, offset int64) error {
	pcopy := make([]byte, len(p))
	copy(pcopy, p)

	newp := Patch{Offset: offset, P: pcopy}
	logger.Debugf(wclog, "PWrite: %v", newp)
	// logger.Debugf(wclog, "PWrite: p=%v", pcopy)

	wc.ps = wc.ps.Merge(newp)
	return nil
}

type ReadAter interface {
	ReadAt(p []byte, offset int64) (int, error)
}

func zerofill(p []byte) {
	for i := range p {
		p[i] = 0
	}
}

func (wc *FileWriteCache) ReadAtThrough(p []byte, offset int64, r ReadAter) (int, error) {
	nr := 0
	remo := offset
	remp := p

	for _, patch := range wc.ps {
		if len(remp) == 0 {
			return nr, nil
		}

		if patch.IsSentinel() {
			break
		}

		if remo > patch.Right() {
			continue
		}

		if remo < patch.Left() {
			fallbackLen64 := util.Int64Min(int64(len(remp)), patch.Left()-remo)
			if fallbackLen64 > math.MaxInt32 {
				panic("Logic error: fallbackLen should always be in int32 range")
			}
			fallbackLen := int(fallbackLen64)

			n, err := r.ReadAt(remp[:fallbackLen], remo)
			logger.Debugf(wclog, "BeforePatch: ReadAt issued offset %d, len %d bytes, read %d bytes", remo, fallbackLen, n)
			if err != nil {
				return nr + n, err
			}
			if n < fallbackLen {
				zerofill(remp[n:fallbackLen])
			}

			nr += fallbackLen
			remp = remp[fallbackLen:]
			remo += int64(fallbackLen)
		}

		if len(remp) == 0 {
			return nr, nil
		}

		applyOffset64 := remo - patch.Offset
		if applyOffset64 > math.MaxInt32 {
			panic("Logic error: applyOffset should always be in int32 range")
		}
		applyOffset := int(applyOffset64)
		applyLen := util.IntMin(len(patch.P)-applyOffset, len(remp))
		copy(remp[:applyLen], patch.P[applyOffset:])

		nr += applyLen
		remp = remp[applyLen:]
		remo += int64(applyLen)
	}

	n, err := r.ReadAt(remp, remo)
	logger.Debugf(wclog, "Last: ReadAt read %d bytes", n)
	if err != nil {
		return nr, err
	}
	nr += n

	return nr, nil
}

func (wc *FileWriteCache) ContentLen() int64 {
	l := int64(0)
	for _, p := range wc.ps {
		l += int64(len(p.P))
	}
	return l
}

func (wc *FileWriteCache) NeedsSync() bool {
	if len(wc.ps) > MaxPatches {
		return true
	}
	if wc.ContentLen() > MaxPatchContentLen {
		return true
	}

	return false
}

func (wc *FileWriteCache) Sync(bh blobstore.PWriter) error {
	for _, p := range wc.ps {
		if p.IsSentinel() {
			continue
		}

		logger.Debugf(wclog, "Sync: %v", p)
		// logger.Debugf(wclog, "Sync: p=%v", p.P)
		if err := bh.PWrite(p.P, p.Offset); err != nil {
			return err
		}
	}
	wc.ps = wc.ps.Reset()

	return nil
}

func (wc *FileWriteCache) Right() int64 {
	if len(wc.ps) == 0 {
		return 0
	}

	return wc.ps[0].Right()
}

func (wc *FileWriteCache) Truncate(size int64) {
	wc.ps = wc.ps.Truncate(size)
}
<commit_msg>Sync squash<commit_after>package filewritecache

import (
	"math"

	"github.com/nyaxt/otaru/blobstore"
	"github.com/nyaxt/otaru/logger"
	"github.com/nyaxt/otaru/util"
)

// Below may overwritten from tests
var MaxPatches = 32
var MaxPatchContentLen int64 = 256 * 1024

var wclog = logger.Registry().Category("filewritecache")

type FileWriteCache struct {
	ps Patches
}

func New() *FileWriteCache {
	return &FileWriteCache{ps: NewPatches()}
}

func (wc *FileWriteCache) PWrite(p []byte, offset int64) error {
	pcopy := make([]byte, len(p))
	copy(pcopy, p)

	newp := Patch{Offset: offset, P: pcopy}
	logger.Debugf(wclog, "PWrite: %v", newp)
	// logger.Debugf(wclog, "PWrite: p=%v", pcopy)

	wc.ps = wc.ps.Merge(newp)
	return nil
}

type ReadAter interface {
	ReadAt(p []byte, offset int64) (int, error)
}

func zerofill(p []byte) {
	for i := range p {
		p[i] = 0
	}
}

func (wc *FileWriteCache) ReadAtThrough(p []byte, offset int64, r ReadAter) (int, error) {
	nr := 0
	remo := offset
	remp := p

	for _, patch := range wc.ps {
		if len(remp) == 0 {
			return nr, nil
		}

		if patch.IsSentinel() {
			break
		}

		if remo > patch.Right() {
			continue
		}

		if remo < patch.Left() {
			fallbackLen64 := util.Int64Min(int64(len(remp)), patch.Left()-remo)
			if fallbackLen64 > math.MaxInt32 {
				panic("Logic error: fallbackLen should always be in int32 range")
			}
			fallbackLen := int(fallbackLen64)

			n, err := r.ReadAt(remp[:fallbackLen], remo)
			logger.Debugf(wclog, "BeforePatch: ReadAt issued offset %d, len %d bytes, read %d bytes", remo, fallbackLen, n)
			if err != nil {
				return nr + n, err
			}
			if n < fallbackLen {
				zerofill(remp[n:fallbackLen])
			}

			nr += fallbackLen
			remp = remp[fallbackLen:]
			remo += int64(fallbackLen)
		}

		if len(remp) == 0 {
			return nr, nil
		}

		applyOffset64 := remo - patch.Offset
		if applyOffset64 > math.MaxInt32 {
			panic("Logic error: applyOffset should always be in int32 range")
		}
		applyOffset := int(applyOffset64)
		applyLen := util.IntMin(len(patch.P)-applyOffset, len(remp))
		copy(remp[:applyLen], patch.P[applyOffset:])

		nr += applyLen
		remp = remp[applyLen:]
		remo += int64(applyLen)
	}

	n, err := r.ReadAt(remp, remo)
	logger.Debugf(wclog, "Last: ReadAt read %d bytes", n)
	if err != nil {
		return nr, err
	}
	nr += n

	return nr, nil
}

func (wc *FileWriteCache) ContentLen() int64 {
	l := int64(0)
	for _, p := range wc.ps {
		l += int64(len(p.P))
	}
	return l
}

func (wc *FileWriteCache) NeedsSync() bool {
	if len(wc.ps) > MaxPatches {
		return true
	}
	if wc.ContentLen() > MaxPatchContentLen {
		return true
	}

	return false
}

func (wc *FileWriteCache) Sync(bh blobstore.PWriter) error {
	var contP []byte
	offset := int64(-1)

	for _, p := range wc.ps {
		if p.IsSentinel() || contP == nil || p.Offset != offset+int64(len(p.P)) {
			if len(contP) != 0 {
				logger.Debugf(wclog, "PWrite offset: %d len(p): %d", offset, len(contP))
				if err := bh.PWrite(contP, offset); err != nil {
					return err
				}
			}

			contP = p.P
			offset = p.Offset
			continue
		}

		logger.Debugf(wclog, "Squash {offset: %d len(p): %d} <- %v", offset, len(contP), p)
		contP = append(contP, p.P...)
	}

	wc.ps = wc.ps.Reset()

	return nil
}

func (wc *FileWriteCache) Right() int64 {
	if len(wc.ps) == 0 {
		return 0
	}

	return wc.ps[0].Right()
}

func (wc *FileWriteCache) Truncate(size int64) {
	wc.ps = wc.ps.Truncate(size)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ecs"
)

type Plugin struct {
	Key                     string
	Secret                  string
	Region                  string
	Family                  string
	TaskRoleArn             string
	Service                 string
	ContainerName           string
	DockerImage             string
	Tag                     string
	Cluster                 string
	LogDriver               string
	LogOptions              []string
	DeploymentConfiguration string
	PortMappings            []string
	Environment             []string
	SecretEnvironment       []string
	Labels                  []string
	DesiredCount            int64
	CPU                     int64
	Memory                  int64
	MemoryReservation       int64
	NetworkMode             string
	YamlVerified            bool
	TaskCPU                 string
	TaskMemory              string
	TaskExecutionRoleArn    string
	Compatibilities         string
	HealthCheckCommand      []string
	HealthCheckInterval     int64
	HealthCheckRetries      int64
	HealthCheckStartPeriod  int64
	HealthCheckTimeout      int64

	// ServiceNetworkSecurityGroups represents the VPC security groups to use
	// when running awsvpc network mode.
	ServiceNetworkSecurityGroups []string

	// ServiceNetworkSubnets represents the VPC security groups to use when
	// running awsvpc network mode.
	ServiceNetworkSubnets []string
}

const (
	hostPortBaseParseErr              = "error parsing port_mappings hostPort: "
	containerBaseParseErr             = "error parsing port_mappings containerPort: "
	minimumHealthyPercentBaseParseErr = "error parsing deployment_configuration minimumHealthyPercent: "
	maximumPercentBaseParseErr        = "error parsing deployment_configuration maximumPercent: "
)

func (p *Plugin) Exec() error {
	fmt.Println("Drone AWS ECS Plugin built")
	awsConfig := aws.Config{}

	if len(p.Key) != 0 && len(p.Secret) != 0 {
		awsConfig.Credentials = credentials.NewStaticCredentials(p.Key, p.Secret, "")
	}
	awsConfig.Region = aws.String(p.Region)
	svc := ecs.New(session.New(&awsConfig))

	Image := p.DockerImage + ":" + p.Tag
	if len(p.ContainerName) == 0 {
		p.ContainerName = p.Family + "-container"
	}

	definition := ecs.ContainerDefinition{
		Command: []*string{},

		DnsSearchDomains:      []*string{},
		DnsServers:            []*string{},
		DockerLabels:          map[string]*string{},
		DockerSecurityOptions: []*string{},
		EntryPoint:            []*string{},
		Environment:           []*ecs.KeyValuePair{},
		Essential:             aws.Bool(true),
		ExtraHosts:            []*ecs.HostEntry{},

		Image:        aws.String(Image),
		Links:        []*string{},
		MountPoints:  []*ecs.MountPoint{},
		Name:         aws.String(p.ContainerName),
		PortMappings: []*ecs.PortMapping{},

		Ulimits: []*ecs.Ulimit{},
		//User: aws.String("String"),
		VolumesFrom: []*ecs.VolumeFrom{},
		//WorkingDirectory: aws.String("String"),
	}

	if p.CPU != 0 {
		definition.Cpu = aws.Int64(p.CPU)
	}

	if p.Memory == 0 && p.MemoryReservation == 0 {
		definition.MemoryReservation = aws.Int64(128)
	} else {
		if p.Memory != 0 {
			definition.Memory = aws.Int64(p.Memory)
		}
		if p.MemoryReservation != 0 {
			definition.MemoryReservation = aws.Int64(p.MemoryReservation)
		}
	}

	// Port mappings
	for _, portMapping := range p.PortMappings {
		cleanedPortMapping := strings.Trim(portMapping, " ")
		parts := strings.SplitN(cleanedPortMapping, " ", 2)
		hostPort, hostPortErr := strconv.ParseInt(parts[0], 10, 64)
		if hostPortErr != nil {
			hostPortWrappedErr := errors.New(hostPortBaseParseErr + hostPortErr.Error())
			fmt.Println(hostPortWrappedErr.Error())
			return hostPortWrappedErr
		}
		containerPort, containerPortErr := strconv.ParseInt(parts[1], 10, 64)
		if containerPortErr != nil {
			containerPortWrappedErr := errors.New(containerBaseParseErr + containerPortErr.Error())
			fmt.Println(containerPortWrappedErr.Error())
			return containerPortWrappedErr
		}

		pair := ecs.PortMapping{
			ContainerPort: aws.Int64(containerPort),
			HostPort:      aws.Int64(hostPort),
			Protocol:      aws.String("TransportProtocol"),
		}

		definition.PortMappings = append(definition.PortMappings, &pair)
	}

	// Environment variables
	for _, envVar := range p.Environment {
		parts := strings.SplitN(envVar, "=", 2)
		pair := ecs.KeyValuePair{
			Name:  aws.String(strings.Trim(parts[0], " ")),
			Value: aws.String(strings.Trim(parts[1], " ")),
		}
		definition.Environment = append(definition.Environment, &pair)
	}

	// Secret Environment variables
	for _, envVar := range p.SecretEnvironment {
		parts := strings.SplitN(envVar, "=", 2)
		pair := ecs.KeyValuePair{}
		if len(parts) == 2 {
			// set to custom named variable
			pair.SetName(aws.StringValue(aws.String(strings.Trim(parts[0], " "))))
			pair.SetValue(aws.StringValue(aws.String(os.Getenv(strings.Trim(parts[1], " ")))))
		} else if len(parts) == 1 {
			// default to named var
			pair.SetName(aws.StringValue(aws.String(parts[0])))
			pair.SetValue(aws.StringValue(aws.String(os.Getenv(parts[0]))))
		} else {
			fmt.Println("invalid syntax in secret enironment var", envVar)
		}
		definition.Environment = append(definition.Environment, &pair)
	}

	// DockerLabels
	for _, label := range p.Labels {
		parts := strings.SplitN(label, "=", 2)
		definition.DockerLabels[strings.Trim(parts[0], " ")] = aws.String(strings.Trim(parts[1], " "))
	}

	// LogOptions
	if len(p.LogDriver) > 0 {
		definition.LogConfiguration = new(ecs.LogConfiguration)
		definition.LogConfiguration.LogDriver = &p.LogDriver
		if len(p.LogOptions) > 0 {
			definition.LogConfiguration.Options = make(map[string]*string)
			for _, logOption := range p.LogOptions {
				parts := strings.SplitN(logOption, "=", 2)
				logOptionKey := strings.Trim(parts[0], " ")
				logOptionValue := aws.String(strings.Trim(parts[1], " "))
				definition.LogConfiguration.Options[logOptionKey] = logOptionValue
			}
		}
	}

	if len(p.NetworkMode) == 0 {
		p.NetworkMode = "bridge"
	}

	if len(p.HealthCheckCommand) != 0 {
		healthcheck := ecs.HealthCheck{
			Command:  aws.StringSlice(p.HealthCheckCommand),
			Interval: &p.HealthCheckInterval,
			Retries:  &p.HealthCheckRetries,
			Timeout:  &p.HealthCheckTimeout,
		}
		if p.HealthCheckStartPeriod != 0 {
			healthcheck.StartPeriod = &p.HealthCheckStartPeriod
		}
		definition.HealthCheck = &healthcheck
	}

	params := &ecs.RegisterTaskDefinitionInput{
		ContainerDefinitions: []*ecs.ContainerDefinition{
			&definition,
		},
		Family:      aws.String(p.Family),
		Volumes:     []*ecs.Volume{},
		TaskRoleArn: aws.String(p.TaskRoleArn),
		NetworkMode: aws.String(p.NetworkMode),
	}

	cleanedCompatibilities := strings.Trim(p.Compatibilities, " ")
	compatibilitySlice := strings.Split(cleanedCompatibilities, " ")

	if cleanedCompatibilities != "" && len(compatibilitySlice) != 0 {
		params.RequiresCompatibilities = aws.StringSlice(compatibilitySlice)
	}

	if len(p.TaskCPU) != 0 {
		params.Cpu = aws.String(p.TaskCPU)
	}

	if len(p.TaskMemory) != 0 {
		params.Memory = aws.String(p.TaskMemory)
	}

	if len(p.TaskExecutionRoleArn) != 0 {
		params.ExecutionRoleArn = aws.String(p.TaskExecutionRoleArn)
	}

	resp, err := svc.RegisterTaskDefinition(params)
	if err != nil {
		return err
	}

	val := *(resp.TaskDefinition.TaskDefinitionArn)
	sparams := &ecs.UpdateServiceInput{
		Cluster:              aws.String(p.Cluster),
		Service:              aws.String(p.Service),
		TaskDefinition:       aws.String(val),
		NetworkConfiguration: p.setupServiceNetworkConfiguration(),
	}

	if p.DesiredCount >= 0 {
		sparams.DesiredCount = aws.Int64(p.DesiredCount)
	}

	cleanedDeploymentConfiguration := strings.Trim(p.DeploymentConfiguration, " ")
	parts := strings.SplitN(cleanedDeploymentConfiguration, " ", 2)
	minimumHealthyPercent, minimumHealthyPercentError := strconv.ParseInt(parts[0], 10, 64)
	if minimumHealthyPercentError != nil {
		minimumHealthyPercentWrappedErr := errors.New(minimumHealthyPercentBaseParseErr + minimumHealthyPercentError.Error())
		fmt.Println(minimumHealthyPercentWrappedErr.Error())
		return minimumHealthyPercentWrappedErr
	}
	maximumPercent, maximumPercentErr := strconv.ParseInt(parts[1], 10, 64)
	if maximumPercentErr != nil {
		maximumPercentWrappedErr := errors.New(maximumPercentBaseParseErr + maximumPercentErr.Error())
		fmt.Println(maximumPercentWrappedErr.Error())
		return maximumPercentWrappedErr
	}

	sparams.DeploymentConfiguration = &ecs.DeploymentConfiguration{
		MaximumPercent:        aws.Int64(maximumPercent),
		MinimumHealthyPercent: aws.Int64(minimumHealthyPercent),
	}

	sresp, serr := svc.UpdateService(sparams)
	if serr != nil {
		return serr
	}

	fmt.Println(sresp)
	fmt.Println(resp)
	return nil
}

// setupServiceNetworkConfiguration is used to setup the ECS service network
// configuration based on operator input.
func (p *Plugin) setupServiceNetworkConfiguration() *ecs.NetworkConfiguration {
	netConfig := ecs.NetworkConfiguration{AwsvpcConfiguration: &ecs.AwsVpcConfiguration{}}

	if p.NetworkMode != ecs.NetworkModeAwsvpc {
		return &netConfig
	}

	if len(p.ServiceNetworkSubnets) > 0 {
		netConfig.AwsvpcConfiguration.SetSubnets(p.stringSliceToPointerStringSlice(p.ServiceNetworkSubnets))
	}

	if len(p.ServiceNetworkSecurityGroups) > 0 {
		netConfig.AwsvpcConfiguration.SetSecurityGroups(p.stringSliceToPointerStringSlice(p.ServiceNetworkSecurityGroups))
	}

	return &netConfig
}

// stringSliceToPointerStringSlice converts and string slice to a slice of
// string pointers.
func (p *Plugin) stringSliceToPointerStringSlice(s []string) []*string {
	var output []*string
	for i := range s {
		output = append(output, &s[i])
	}
	return output
}
<commit_msg>Use AWS stringslice function rather than custom function.<commit_after>package main

import (
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ecs"
)

type Plugin struct {
	Key                     string
	Secret                  string
	Region                  string
	Family                  string
	TaskRoleArn             string
	Service                 string
	ContainerName           string
	DockerImage             string
	Tag                     string
	Cluster                 string
	LogDriver               string
	LogOptions              []string
	DeploymentConfiguration string
	PortMappings            []string
	Environment             []string
	SecretEnvironment       []string
	Labels                  []string
	DesiredCount            int64
	CPU                     int64
	Memory                  int64
	MemoryReservation       int64
	NetworkMode             string
	YamlVerified            bool
	TaskCPU                 string
	TaskMemory              string
	TaskExecutionRoleArn    string
	Compatibilities         string
	HealthCheckCommand      []string
	HealthCheckInterval     int64
	HealthCheckRetries      int64
	HealthCheckStartPeriod  int64
	HealthCheckTimeout      int64

	// ServiceNetworkSecurityGroups represents the VPC security groups to use
	// when running awsvpc network mode.
	ServiceNetworkSecurityGroups []string

	// ServiceNetworkSubnets represents the VPC security groups to use when
	// running awsvpc network mode.
	ServiceNetworkSubnets []string
}

const (
	hostPortBaseParseErr              = "error parsing port_mappings hostPort: "
	containerBaseParseErr             = "error parsing port_mappings containerPort: "
	minimumHealthyPercentBaseParseErr = "error parsing deployment_configuration minimumHealthyPercent: "
	maximumPercentBaseParseErr        = "error parsing deployment_configuration maximumPercent: "
)

func (p *Plugin) Exec() error {
	fmt.Println("Drone AWS ECS Plugin built")
	awsConfig := aws.Config{}

	if len(p.Key) != 0 && len(p.Secret) != 0 {
		awsConfig.Credentials = credentials.NewStaticCredentials(p.Key, p.Secret, "")
	}
	awsConfig.Region = aws.String(p.Region)
	svc := ecs.New(session.New(&awsConfig))

	Image := p.DockerImage + ":" + p.Tag
	if len(p.ContainerName) == 0 {
		p.ContainerName = p.Family + "-container"
	}

	definition := ecs.ContainerDefinition{
		Command: []*string{},

		DnsSearchDomains:      []*string{},
		DnsServers:            []*string{},
		DockerLabels:          map[string]*string{},
		DockerSecurityOptions: []*string{},
		EntryPoint:            []*string{},
		Environment:           []*ecs.KeyValuePair{},
		Essential:             aws.Bool(true),
		ExtraHosts:            []*ecs.HostEntry{},

		Image:        aws.String(Image),
		Links:        []*string{},
		MountPoints:  []*ecs.MountPoint{},
		Name:         aws.String(p.ContainerName),
		PortMappings: []*ecs.PortMapping{},

		Ulimits: []*ecs.Ulimit{},
		//User: aws.String("String"),
		VolumesFrom: []*ecs.VolumeFrom{},
		//WorkingDirectory: aws.String("String"),
	}

	if p.CPU != 0 {
		definition.Cpu = aws.Int64(p.CPU)
	}

	if p.Memory == 0 && p.MemoryReservation == 0 {
		definition.MemoryReservation = aws.Int64(128)
	} else {
		if p.Memory != 0 {
			definition.Memory = aws.Int64(p.Memory)
		}
		if p.MemoryReservation != 0 {
			definition.MemoryReservation = aws.Int64(p.MemoryReservation)
		}
	}

	// Port mappings
	for _, portMapping := range p.PortMappings {
		cleanedPortMapping := strings.Trim(portMapping, " ")
		parts := strings.SplitN(cleanedPortMapping, " ", 2)
		hostPort, hostPortErr := strconv.ParseInt(parts[0], 10, 64)
		if hostPortErr != nil {
			hostPortWrappedErr := errors.New(hostPortBaseParseErr + hostPortErr.Error())
			fmt.Println(hostPortWrappedErr.Error())
			return hostPortWrappedErr
		}
		containerPort, containerPortErr := strconv.ParseInt(parts[1], 10, 64)
		if containerPortErr != nil {
			containerPortWrappedErr := errors.New(containerBaseParseErr + containerPortErr.Error())
			fmt.Println(containerPortWrappedErr.Error())
			return containerPortWrappedErr
		}

		pair := ecs.PortMapping{
			ContainerPort: aws.Int64(containerPort),
			HostPort:      aws.Int64(hostPort),
			Protocol:      aws.String("TransportProtocol"),
		}

		definition.PortMappings = append(definition.PortMappings, &pair)
	}

	// Environment variables
	for _, envVar := range p.Environment {
		parts := strings.SplitN(envVar, "=", 2)
		pair := ecs.KeyValuePair{
			Name:  aws.String(strings.Trim(parts[0], " ")),
			Value: aws.String(strings.Trim(parts[1], " ")),
		}
		definition.Environment = append(definition.Environment, &pair)
	}

	// Secret Environment variables
	for _, envVar := range p.SecretEnvironment {
		parts := strings.SplitN(envVar, "=", 2)
		pair := ecs.KeyValuePair{}
		if len(parts) == 2 {
			// set to custom named variable
			pair.SetName(aws.StringValue(aws.String(strings.Trim(parts[0], " "))))
			pair.SetValue(aws.StringValue(aws.String(os.Getenv(strings.Trim(parts[1], " ")))))
		} else if len(parts) == 1 {
			// default to named var
			pair.SetName(aws.StringValue(aws.String(parts[0])))
			pair.SetValue(aws.StringValue(aws.String(os.Getenv(parts[0]))))
		} else {
			fmt.Println("invalid syntax in secret enironment var", envVar)
		}
		definition.Environment = append(definition.Environment, &pair)
	}

	// DockerLabels
	for _, label := range p.Labels {
		parts := strings.SplitN(label, "=", 2)
		definition.DockerLabels[strings.Trim(parts[0], " ")] = aws.String(strings.Trim(parts[1], " "))
	}

	// LogOptions
	if len(p.LogDriver) > 0 {
		definition.LogConfiguration = new(ecs.LogConfiguration)
		definition.LogConfiguration.LogDriver = &p.LogDriver
		if len(p.LogOptions) > 0 {
			definition.LogConfiguration.Options = make(map[string]*string)
			for _, logOption := range p.LogOptions {
				parts := strings.SplitN(logOption, "=", 2)
				logOptionKey := strings.Trim(parts[0], " ")
				logOptionValue := aws.String(strings.Trim(parts[1], " "))
				definition.LogConfiguration.Options[logOptionKey] = logOptionValue
			}
		}
	}

	if len(p.NetworkMode) == 0 {
		p.NetworkMode = "bridge"
	}

	if len(p.HealthCheckCommand) != 0 {
		healthcheck := ecs.HealthCheck{
			Command:  aws.StringSlice(p.HealthCheckCommand),
			Interval: &p.HealthCheckInterval,
			Retries:  &p.HealthCheckRetries,
			Timeout:  &p.HealthCheckTimeout,
		}
		if p.HealthCheckStartPeriod != 0 {
			healthcheck.StartPeriod = &p.HealthCheckStartPeriod
		}
		definition.HealthCheck = &healthcheck
	}

	params := &ecs.RegisterTaskDefinitionInput{
		ContainerDefinitions: []*ecs.ContainerDefinition{
			&definition,
		},
		Family:      aws.String(p.Family),
		Volumes:     []*ecs.Volume{},
		TaskRoleArn: aws.String(p.TaskRoleArn),
		NetworkMode: aws.String(p.NetworkMode),
	}

	cleanedCompatibilities := strings.Trim(p.Compatibilities, " ")
	compatibilitySlice := strings.Split(cleanedCompatibilities, " ")

	if cleanedCompatibilities != "" && len(compatibilitySlice) != 0 {
		params.RequiresCompatibilities = aws.StringSlice(compatibilitySlice)
	}

	if len(p.TaskCPU) != 0 {
		params.Cpu = aws.String(p.TaskCPU)
	}

	if len(p.TaskMemory) != 0 {
		params.Memory = aws.String(p.TaskMemory)
	}

	if len(p.TaskExecutionRoleArn) != 0 {
		params.ExecutionRoleArn = aws.String(p.TaskExecutionRoleArn)
	}

	resp, err := svc.RegisterTaskDefinition(params)
	if err != nil {
		return err
	}

	val := *(resp.TaskDefinition.TaskDefinitionArn)
	sparams := &ecs.UpdateServiceInput{
		Cluster:              aws.String(p.Cluster),
		Service:              aws.String(p.Service),
		TaskDefinition:       aws.String(val),
		NetworkConfiguration: p.setupServiceNetworkConfiguration(),
	}

	if p.DesiredCount >= 0 {
		sparams.DesiredCount = aws.Int64(p.DesiredCount)
	}

	cleanedDeploymentConfiguration := strings.Trim(p.DeploymentConfiguration, " ")
	parts := strings.SplitN(cleanedDeploymentConfiguration, " ", 2)
	minimumHealthyPercent, minimumHealthyPercentError := strconv.ParseInt(parts[0], 10, 64)
	if minimumHealthyPercentError != nil {
		minimumHealthyPercentWrappedErr := errors.New(minimumHealthyPercentBaseParseErr + minimumHealthyPercentError.Error())
		fmt.Println(minimumHealthyPercentWrappedErr.Error())
		return minimumHealthyPercentWrappedErr
	}
	maximumPercent, maximumPercentErr := strconv.ParseInt(parts[1], 10, 64)
	if maximumPercentErr != nil {
		maximumPercentWrappedErr := errors.New(maximumPercentBaseParseErr + maximumPercentErr.Error())
		fmt.Println(maximumPercentWrappedErr.Error())
		return maximumPercentWrappedErr
	}

	sparams.DeploymentConfiguration = &ecs.DeploymentConfiguration{
		MaximumPercent:        aws.Int64(maximumPercent),
		MinimumHealthyPercent: aws.Int64(minimumHealthyPercent),
	}

	sresp, serr := svc.UpdateService(sparams)
	if serr != nil {
		return serr
	}

	fmt.Println(sresp)
	fmt.Println(resp)
	return nil
}

// setupServiceNetworkConfiguration is used to setup the ECS service network
// configuration based on operator input.
func (p *Plugin) setupServiceNetworkConfiguration() *ecs.NetworkConfiguration {
	netConfig := ecs.NetworkConfiguration{AwsvpcConfiguration: &ecs.AwsVpcConfiguration{}}

	if p.NetworkMode != ecs.NetworkModeAwsvpc {
		return &netConfig
	}

	if len(p.ServiceNetworkSubnets) > 0 {
		netConfig.AwsvpcConfiguration.SetSubnets(aws.StringSlice(p.ServiceNetworkSubnets))
	}

	if len(p.ServiceNetworkSecurityGroups) > 0 {
		netConfig.AwsvpcConfiguration.SetSecurityGroups(aws.StringSlice(p.ServiceNetworkSecurityGroups))
	}

	return &netConfig
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"

	"os"
	"os/exec"

	"path/filepath"

	"github.com/drone-plugins/drone-git-push/repo"
)

type (
	Repo struct {
		Clone string
	}

	Build struct {
		Path string
	}

	Author struct {
		Name  string
		Email string
	}

	Commit struct {
		Author Author
	}

	Netrc struct {
		Machine  string
		Login    string
		Password string
	}

	Config struct {
		Key            string
		UpstreamName   string
		TargetBranch   string
		TemporaryBase  string
		PagesDirectory string
	}

	Plugin struct {
		Repo   Repo
		Build  Build
		Commit Commit
		Netrc  Netrc
		Config Config
	}
)

func (p Plugin) Exec() error {
	cloneUrl := p.Repo.Clone

	upstreamName := p.Config.UpstreamName
	targetBranch := p.Config.TargetBranch
	temporaryBase := p.Config.TemporaryBase
	pagesDirectory := p.Config.PagesDirectory
	buildPath := p.Build.Path

	netrcMachine := p.Netrc.Machine
	netrcLogin := p.Netrc.Login
	netrcPassword := p.Netrc.Password
	sshKey := p.Config.Key

	userName := p.Commit.Author.Name
	userEmail := p.Commit.Author.Email

	temporaryBaseDirectory := ""

	if filepath.IsAbs(temporaryBase) {
		temporaryBaseDirectory = temporaryBase
	} else {
		temporaryBaseDirectory = filepath.Join(buildPath, temporaryBase)
	}

	temporaryPagesDirectory := filepath.Join(temporaryBaseDirectory, pagesDirectory)
	fullPagesDirectory := filepath.Join(buildPath, pagesDirectory)

	// generate the .netrc file
	if err := repo.WriteNetrc(netrcMachine, netrcLogin, netrcPassword); err != nil {
		return err
	}

	// write the rsa private key if provided
	if err := repo.WriteKey(sshKey); err != nil {
		return err
	}

	if err := repo.GlobalUser(userEmail).Run(); err != nil {
		return err
	}

	if err := repo.GlobalName(userName).Run(); err != nil {
		return err
	}

	if err := os.MkdirAll(temporaryPagesDirectory, 0777); err != nil {
		return err
	}

	defer os.RemoveAll(temporaryPagesDirectory)

	return runPublishSteps(
		buildPath,
		temporaryBaseDirectory,
		temporaryPagesDirectory,
		fullPagesDirectory,
		targetBranch,
		upstreamName,
		cloneUrl,
	)
}

func runCommand(cmd *exec.Cmd, out *bytes.Buffer) error {
	if out == nil {
		if cmd.Stdout == nil {
			cmd.Stdout = os.Stdout
		}
	} else {
		cmd.Stdout = out
	}

	cmd.Stderr = os.Stderr

	if err := cmd.Run(); err != nil {
		fmt.Printf("Error: %+v %s\n", cmd, err)
		return err
	}

	return nil
}

func runPublishSteps(
	workspacePath string,
	temporaryBaseDirectory string,
	temporaryPagesDirectory string,
	fullPagesDirectory string,
	vargsTargetBranch string,
	vargsUpstreamName string,
	cloneUrl string) error {

	// Get the commit message
	msgRaw, err := commitMessage(workspacePath).Output()

	if err != nil {
		return err
	}

	msg := string(msgRaw)

	// Set up git config (rsa, etc)
	fmt.Println("about to clone")
	err = runCommand(cloneTarget(workspacePath, vargsTargetBranch, cloneUrl, temporaryPagesDirectory), nil)
	if err != nil {
		return err
	}

	fmt.Println("about to rsync")
	err = runCommand(rsyncPages(workspacePath, fullPagesDirectory, temporaryBaseDirectory), nil)
	if err != nil {
		return err
	}

	fmt.Println("about to add to clone")
	var addResult bytes.Buffer
	err = runCommand(addTemporaryFilesToClone(temporaryPagesDirectory), &addResult)
	if err != nil {
		fmt.Printf("Error on add: %s", addResult.String())
		return err
	}

	// For now, if the add resulted in a success, with output, we are assuming that there are
	// changes to commit and push
	if addResult.Len() > 0 {
		fmt.Println("about to commit")
		err = runCommand(commitTemporaryFilesToClone(temporaryPagesDirectory, msg), nil)
		if err != nil {
			return err
		}

		fmt.Println("about to push")
		err = runCommand(pushTemporaryClone(temporaryPagesDirectory, vargsUpstreamName, vargsTargetBranch), nil)
		if err != nil {
			return err
		}
	}

	return nil
}

// Returns command to get the commit message for the gh-pages
// commit based on the last commit in the build
func commitMessage(workspacePath string) *exec.Cmd {
	cmd := exec.Command(
		"git",
		"show",
		"-q",
	)
	cmd.Dir = workspacePath
	return cmd
}

// Returns command to clone gh-pages into our temporary location.
// git clone -b gh-pages --single-branch repo .tmp/[pages directory]
func cloneTarget(workspacePath string, targetBranch string, repo string, temporaryPagesDirectory string) *exec.Cmd {
	cmd := exec.Command(
		"git",
		"clone",
		"-b",
		targetBranch,
		"--single-branch",
		repo,
		temporaryPagesDirectory,
	)
	cmd.Dir = workspacePath
	return cmd
}

// Copy the pages content to the temporary location
// rsync --delete --exclude .git -r docs .tmp
func rsyncPages(workspacePath string, pagesDirectory string, temporaryBaseDirectory string) *exec.Cmd {
	cmd := exec.Command(
		"rsync",
		"--delete",
		"--exclude",
		".git",
		"-r",
		pagesDirectory,
		temporaryBaseDirectory,
	)
	cmd.Dir = workspacePath
	return cmd
}

// Add the files in the temporary directory to the commit
// we want to make in the clone.
func addTemporaryFilesToClone(temporaryPagesDirectory string) *exec.Cmd {
	cmd := exec.Command(
		"git",
		"add",
		"--verbose",
		".",
	)
	cmd.Dir = temporaryPagesDirectory
	return cmd
}

// Commit the working version of the pages content to
// our clone
func commitTemporaryFilesToClone(temporaryPagesDirectory string, message string) *exec.Cmd {
	cmd := exec.Command(
		"git",
		"commit",
		"-m",
		message,
	)
	cmd.Dir = temporaryPagesDirectory
	return cmd
}

// Push our clone to the upstream
func pushTemporaryClone(temporaryPagesDirectory string, upstreamName string, targetBranch string) *exec.Cmd {
	cmd := repo.RemotePush(upstreamName, targetBranch, false)
	cmd.Dir = temporaryPagesDirectory
	return cmd
}
<commit_msg>fix not excluded cname<commit_after>package main

import (
	"bytes"
	"fmt"

	"os"
	"os/exec"

	"path/filepath"

	"github.com/drone-plugins/drone-git-push/repo"
)

type (
	Repo struct {
		Clone string
	}

	Build struct {
		Path string
	}

	Author struct {
		Name  string
		Email string
	}

	Commit struct {
		Author Author
	}

	Netrc struct {
		Machine  string
		Login    string
		Password string
	}

	Config struct {
		Key            string
		UpstreamName   string
		TargetBranch   string
		TemporaryBase  string
		PagesDirectory string
	}

	Plugin struct {
		Repo   Repo
		Build  Build
		Commit Commit
		Netrc  Netrc
		Config Config
	}
)

func (p Plugin) Exec() error {
	cloneUrl := p.Repo.Clone

	upstreamName := p.Config.UpstreamName
	targetBranch := p.Config.TargetBranch
	temporaryBase := p.Config.TemporaryBase
	pagesDirectory := p.Config.PagesDirectory
	buildPath := p.Build.Path

	netrcMachine := p.Netrc.Machine
	netrcLogin := p.Netrc.Login
	netrcPassword := p.Netrc.Password
	sshKey := p.Config.Key

	userName := p.Commit.Author.Name
	userEmail := p.Commit.Author.Email

	temporaryBaseDirectory := ""

	if filepath.IsAbs(temporaryBase) {
		temporaryBaseDirectory = temporaryBase
	} else {
		temporaryBaseDirectory = filepath.Join(buildPath, temporaryBase)
	}

	temporaryPagesDirectory := filepath.Join(temporaryBaseDirectory, pagesDirectory)
	fullPagesDirectory := filepath.Join(buildPath, pagesDirectory)

	// generate the .netrc file
	if err := repo.WriteNetrc(netrcMachine, netrcLogin, netrcPassword); err != nil {
		return err
	}

	// write the rsa private key if provided
	if err := repo.WriteKey(sshKey); err != nil {
		return err
	}

	if err := repo.GlobalUser(userEmail).Run(); err != nil {
		return err
	}

	if err := repo.GlobalName(userName).Run(); err != nil {
		return err
	}

	if err := os.MkdirAll(temporaryPagesDirectory, 0777); err != nil {
		return err
	}

	defer os.RemoveAll(temporaryPagesDirectory)

	return runPublishSteps(
		buildPath,
		temporaryBaseDirectory,
		temporaryPagesDirectory,
		fullPagesDirectory,
		targetBranch,
		upstreamName,
		cloneUrl,
	)
}

func runCommand(cmd *exec.Cmd, out *bytes.Buffer) error {
	if out == nil {
		if cmd.Stdout == nil {
			cmd.Stdout = os.Stdout
		}
	} else {
		cmd.Stdout = out
	}

	cmd.Stderr = os.Stderr

	if err := cmd.Run(); err != nil {
		fmt.Printf("Error: %+v %s\n", cmd, err)
		return err
	}

	return nil
}

func runPublishSteps(
	workspacePath string,
	temporaryBaseDirectory string,
	temporaryPagesDirectory string,
	fullPagesDirectory string,
	vargsTargetBranch string,
	vargsUpstreamName string,
	cloneUrl string) error {

	// Get the commit message
	msgRaw, err := commitMessage(workspacePath).Output()

	if err != nil {
		return err
	}

	msg := string(msgRaw)

	// Set up git config (rsa, etc)
	fmt.Println("about to clone")
	err = runCommand(cloneTarget(workspacePath, vargsTargetBranch, cloneUrl, temporaryPagesDirectory), nil)
	if err != nil {
		return err
	}

	fmt.Println("about to rsync")
	err = runCommand(rsyncPages(workspacePath, fullPagesDirectory, temporaryBaseDirectory), nil)
	if err != nil {
		return err
	}

	fmt.Println("about to add to clone")
	var addResult bytes.Buffer
	err = runCommand(addTemporaryFilesToClone(temporaryPagesDirectory), &addResult)
	if err != nil {
		fmt.Printf("Error on add: %s", addResult.String())
		return err
	}

	// For now, if the add resulted in a success, with output, we are assuming that there are
	// changes to commit and push
	if addResult.Len() > 0 {
		fmt.Println("about to commit")
		err = runCommand(commitTemporaryFilesToClone(temporaryPagesDirectory, msg), nil)
		if err != nil {
			return err
		}

		fmt.Println("about to push")
		err = runCommand(pushTemporaryClone(temporaryPagesDirectory, vargsUpstreamName, vargsTargetBranch), nil)
		if err != nil {
			return err
		}
	}

	return nil
}

// Returns command to get the commit message for the gh-pages
// commit based on the last commit in the build
func commitMessage(workspacePath string) *exec.Cmd {
	cmd := exec.Command(
		"git",
		"show",
		"-q",
	)
	cmd.Dir = workspacePath
	return cmd
}

// Returns command to clone gh-pages into our temporary location.
// git clone -b gh-pages --single-branch repo .tmp/[pages directory]
func cloneTarget(workspacePath string, targetBranch string, repo string, temporaryPagesDirectory string) *exec.Cmd {
	cmd := exec.Command(
		"git",
		"clone",
		"-b",
		targetBranch,
		"--single-branch",
		repo,
		temporaryPagesDirectory,
	)
	cmd.Dir = workspacePath
	return cmd
}

// Copy the pages content to the temporary location
// rsync --delete --exclude .git -r docs .tmp
func rsyncPages(workspacePath string, pagesDirectory string, temporaryBaseDirectory string) *exec.Cmd {
	cmd := exec.Command(
		"rsync",
		"--delete",
		"--exclude",
		".git",
		"--exclude",
		"CNAME",
		"-r",
		pagesDirectory,
		temporaryBaseDirectory,
	)
	cmd.Dir = workspacePath
	return cmd
}

// Add the files in the temporary directory to the commit
// we want to make in the clone.
func addTemporaryFilesToClone(temporaryPagesDirectory string) *exec.Cmd {
	cmd := exec.Command(
		"git",
		"add",
		"--verbose",
		".",
	)
	cmd.Dir = temporaryPagesDirectory
	return cmd
}

// Commit the working version of the pages content to
// our clone
func commitTemporaryFilesToClone(temporaryPagesDirectory string, message string) *exec.Cmd {
	cmd := exec.Command(
		"git",
		"commit",
		"-m",
		message,
	)
	cmd.Dir = temporaryPagesDirectory
	return cmd
}

// Push our clone to the upstream
func pushTemporaryClone(temporaryPagesDirectory string, upstreamName string, targetBranch string) *exec.Cmd {
	cmd := repo.RemotePush(upstreamName, targetBranch, false)
	cmd.Dir = temporaryPagesDirectory
	return cmd
}
<|endoftext|>


<commit_before>package test

import (
	"testing"
	"github.com/coderoamer/docker-go/api"
)

func TestListImages(t *testing.T) {
	client, err := api.NewDClient("http://222.26.224.50:4213")
	if err != nil {
		t.Error(err)
		return
	}
	err = client.ListImages(false)
	if err != nil {
		t.Error(err)
		return
	}
}

func TestPing(t *testing.T) {
	client, err := api.NewDClient("http://222.26.224.50:4213")
	if err != nil {
		t.Error(err)
		return
	}
	err = client.Ping()
	if err != nil {
		t.Error("ping error")
		return
	}

	client, err = api.NewDClient("http://222.26.224.51:4213")
	if err != nil {
		t.Error(err)
		return
	}
	err = client.Ping()
	if err != nil {
		return
	}else {
		t.Error("error ")
	}
}
<commit_msg>fix test error<commit_after>package test

import (
	"testing"
	"github.com/coderoamer/docker-go/api"
)

func TestListImages(t *testing.T) {
	client, err := api.NewDClient("http://222.26.224.50:4213")
	if err != nil {
		t.Error(err)
		return
	}
	images, err := client.ListImages(false)
	if err != nil {
		t.Error(err)
		return
	}
	if images == nil {
		t.Error("images not fetch")
	}
}

func TestPing(t *testing.T) {
	client, err := api.NewDClient("http://222.26.224.50:4213")
	if err != nil {
		t.Error(err)
		return
	}
	err = client.Ping()
	if err != nil {
		t.Error("ping error")
		return
	}

	client, err = api.NewDClient("http://222.26.224.51:4213")
	if err != nil {
		t.Error(err)
		return
	}
	err = client.Ping()
	if err != nil {
		return
	}else {
		t.Error("error ")
	}
}
<|endoftext|>


<commit_before>package azure

import (
	"encoding/xml"
	"fmt"
	"github.com/loldesign/azure/core"
	"io"
	"mime"
	"net/http"
	"path"
	"strings"
	"time"
)

var client = &http.Client{}

type Azure struct {
	Account string
	Key     string
}

type Blobs struct {
	XMLName xml.Name `xml:"EnumerationResults"`
	Itens   []Blob   `xml:"Blobs>Blob"`
}

type Blob struct {
	Name     string   `xml:"Name"`
	Property Property `xml:"Properties"`
}

type Property struct {
	LastModified  string `xml:"Last-Modified"`
	Etag          string `xml:"Etag"`
	ContentLength string `xml:"Content-Length"`
	ContentType   string `xml:"Content-Type"`
	BlobType      string `xml:"BlobType"`
	LeaseStatus   string `xml:"LeaseStatus"`
}

func (a Azure) doRequest(azureRequest core.AzureRequest) (*http.Response, error) {
	client, req := a.clientAndRequest(azureRequest)
	return client.Do(req)
}

func (a Azure) clientAndRequest(azureRequest core.AzureRequest) (*http.Client, *http.Request) {
	req := a.prepareRequest(azureRequest)

	return client, req
}

func (a Azure) prepareRequest(azureRequest core.AzureRequest) *http.Request {
	credentials := core.Credentials{
		Account:   a.Account,
		AccessKey: a.Key}

	return core.New(credentials, azureRequest).PrepareRequest()
}

func prepareMetadata(keys map[string]string) map[string]string {
	header := make(map[string]string)

	for k, v := range keys {
		key := fmt.Sprintf("x-ms-meta-%s", k)
		header[key] = v
	}

	return header
}

func New(account, accessKey string) Azure {
	return Azure{account, accessKey}
}

func (a Azure) CreateContainer(container string, meta map[string]string) (*http.Response, error) {
	azureRequest := core.AzureRequest{
		Method:      "put",
		Container:   container,
		Resource:    "?restype=container",
		Header:      prepareMetadata(meta),
		RequestTime: time.Now().UTC()}

	return a.doRequest(azureRequest)
}

func (a Azure) DeleteContainer(container string) (*http.Response, error) {
	azureRequest := core.AzureRequest{
		Method:      "delete",
		Container:   container,
		Resource:    "?restype=container",
		RequestTime: time.Now().UTC()}

	return a.doRequest(azureRequest)
}

func (a Azure) FileUpload(container, name string, body io.Reader) (*http.Response, error) {
	extension := strings.ToLower(path.Ext(name))
	contentType := mime.TypeByExtension(extension)

	azureRequest := core.AzureRequest{
		Method:      "put",
		Container:   container,
		Blob:        name,
		Body:        body,
		Header:      map[string]string{"x-ms-blob-type": "BlockBlob", "Accept-Charset": "UTF-8", "Content-Type": contentType},
		RequestTime: time.Now().UTC()}

	return a.doRequest(azureRequest)
}

func (a Azure) ListBlobs(container string) (Blobs, error) {
	var blobs Blobs

	azureRequest := core.AzureRequest{
		Method:      "get",
		Container:   container,
		Resource:    "?restype=container&comp=list",
		RequestTime: time.Now().UTC()}

	res, err := a.doRequest(azureRequest)

	if err != nil {
		return blobs, err
	}

	decoder := xml.NewDecoder(res.Body)
	decoder.Decode(&blobs)

	return blobs, nil
}

func (a Azure) DeleteBlob(container, name string) (bool, error) {
	azureRequest := core.AzureRequest{
		Method:      "delete",
		Container:   container,
		Blob:        name,
		RequestTime: time.Now().UTC()}

	res, err := a.doRequest(azureRequest)

	if err != nil {
		return false, err
	}

	if res.StatusCode != 202 {
		return false, fmt.Errorf("deleteBlob: %s", res.Status)
	}

	return true, nil
}

func (a Azure) FileDownload(container, name string) (*http.Response, error) {
	azureRequest := core.AzureRequest{
		Method:      "get",
		Container:   container,
		Blob:        name,
		RequestTime: time.Now().UTC()}

	return a.doRequest(azureRequest)
}
<commit_msg>removing func prepareMetadata and pass the meta forward<commit_after>package azure

import (
	"encoding/xml"
	"fmt"
	"github.com/loldesign/azure/core"
	"io"
	"mime"
	"net/http"
	"path"
	"strings"
	"time"
)

var client = &http.Client{}

type Azure struct {
	Account string
	Key     string
}

type Blobs struct {
	XMLName xml.Name `xml:"EnumerationResults"`
	Itens   []Blob   `xml:"Blobs>Blob"`
}

type Blob struct {
	Name     string   `xml:"Name"`
	Property Property `xml:"Properties"`
}

type Property struct {
	LastModified  string `xml:"Last-Modified"`
	Etag          string `xml:"Etag"`
	ContentLength string `xml:"Content-Length"`
	ContentType   string `xml:"Content-Type"`
	BlobType      string `xml:"BlobType"`
	LeaseStatus   string `xml:"LeaseStatus"`
}

func (a Azure) doRequest(azureRequest core.AzureRequest) (*http.Response, error) {
	client, req := a.clientAndRequest(azureRequest)
	return client.Do(req)
}

func (a Azure) clientAndRequest(azureRequest core.AzureRequest) (*http.Client, *http.Request) {
	req := a.prepareRequest(azureRequest)

	return client, req
}

func (a Azure) prepareRequest(azureRequest core.AzureRequest) *http.Request {
	credentials := core.Credentials{
		Account:   a.Account,
		AccessKey: a.Key}

	return core.New(credentials, azureRequest).PrepareRequest()
}

func New(account, accessKey string) Azure {
	return Azure{account, accessKey}
}

func (a Azure) CreateContainer(container string, meta map[string]string) (*http.Response, error) {
	azureRequest := core.AzureRequest{
		Method:      "put",
		Container:   container,
		Resource:    "?restype=container",
		Header:      meta,
		RequestTime: time.Now().UTC()}

	return a.doRequest(azureRequest)
}

func (a Azure) DeleteContainer(container string) (*http.Response, error) {
	azureRequest := core.AzureRequest{
		Method:      "delete",
		Container:   container,
		Resource:    "?restype=container",
		RequestTime: time.Now().UTC()}

	return a.doRequest(azureRequest)
}

func (a Azure) FileUpload(container, name string, body io.Reader) (*http.Response, error) {
	extension := strings.ToLower(path.Ext(name))
	contentType := mime.TypeByExtension(extension)

	azureRequest := core.AzureRequest{
		Method:      "put",
		Container:   container,
		Blob:        name,
		Body:        body,
		Header:      map[string]string{"x-ms-blob-type": "BlockBlob", "Accept-Charset": "UTF-8", "Content-Type": contentType},
		RequestTime: time.Now().UTC()}

	return a.doRequest(azureRequest)
}

func (a Azure) ListBlobs(container string) (Blobs, error) {
	var blobs Blobs

	azureRequest := core.AzureRequest{
		Method:      "get",
		Container:   container,
		Resource:    "?restype=container&comp=list",
		RequestTime: time.Now().UTC()}

	res, err := a.doRequest(azureRequest)

	if err != nil {
		return blobs, err
	}

	decoder := xml.NewDecoder(res.Body)
	decoder.Decode(&blobs)

	return blobs, nil
}

func (a Azure) DeleteBlob(container, name string) (bool, error) {
	azureRequest := core.AzureRequest{
		Method:      "delete",
		Container:   container,
		Blob:        name,
		RequestTime: time.Now().UTC()}

	res, err := a.doRequest(azureRequest)

	if err != nil {
		return false, err
	}

	if res.StatusCode != 202 {
		return false, fmt.Errorf("deleteBlob: %s", res.Status)
	}

	return true, nil
}

func (a Azure) FileDownload(container, name string) (*http.Response, error) {
	azureRequest := core.AzureRequest{
		Method:      "get",
		Container:   container,
		Blob:        name,
		RequestTime: time.Now().UTC()}

	return a.doRequest(azureRequest)
}
<|endoftext|>


<commit_before>package chipmunk

import (
	"github.com/vova616/chipmunk/vect"
	//. "github.com/vova616/chipmunk/transform"
	"math"
)

type ComponentNode struct {
	Root     *Body
	Next     *Body
	IdleTime vect.Float
}

type BodyType uint8
type UpdatePositionFunction func(body *Body, dt vect.Float)
type UpdateVelocityFunction func(body *Body, gravity vect.Vect, damping, dt vect.Float)

const (
	BodyType_Static  = BodyType(0)
	BodyType_Dynamic = BodyType(1)
)

var Inf = vect.Float(math.Inf(1))

type CollisionCallback interface {
	CollisionEnter(arbiter *Arbiter) bool
	CollisionPreSolve(arbiter *Arbiter) bool
	CollisionPostSolve(arbiter *Arbiter)
	CollisionExit(arbiter *Arbiter)
}

type Body struct {
	/// Mass of the body.
	/// Must agree with cpBody.m_inv! Use cpBodySetMass() when changing the mass for this reason.
	m vect.Float

	/// Mass inverse.
	m_inv vect.Float

	/// Moment of inertia of the body.
	/// Must agree with cpBody.i_inv! Use cpBodySetMoment() when changing the moment for this reason.
	i vect.Float
	/// Moment of inertia inverse.
	i_inv vect.Float

	/// Position of the rigid body's center of gravity.
	p vect.Vect
	/// Velocity of the rigid body's center of gravity.
	v vect.Vect
	/// Force acting on the rigid body's center of gravity.
	f vect.Vect

	//Transform Transform

	/// Rotation of the body around it's center of gravity in radians.
	/// Must agree with cpBody.rot! Use cpBodySetAngle() when changing the angle for this reason.
	a vect.Float
	/// Angular velocity of the body around it's center of gravity in radians/second.
	w vect.Float
	/// Torque applied to the body around it's center of gravity.
	t vect.Float

	/// Cached unit length vector representing the angle of the body.
	/// Used for fast rotations using cpvrotate().
	rot vect.Vect

	v_bias vect.Vect
	w_bias vect.Float

	/// User definable data pointer.
	/// Generally this points to your the game object class so you can access it
	/// when given a cpBody reference in a callback.
	UserData           interface{}
	CallbackHandler    CollisionCallback
	UpdatePositionFunc UpdatePositionFunction
	UpdateVelocityFunc UpdateVelocityFunction

	/// Maximum velocity allowed when updating the velocity.
	v_limit vect.Float
	/// Maximum rotational rate (in radians/second) allowed when updating the angular velocity.
	w_limit vect.Float

	space *Space

	Shapes []*Shape

	node ComponentNode

	hash HashValue

	deleted bool

	idleTime vect.Float

	IgnoreGravity bool
}

func NewBodyStatic() (body *Body) {

	body = &Body{}
	body.Shapes = make([]*Shape, 0)
	body.SetMass(Inf)
	body.SetMoment(Inf)
	body.IgnoreGravity = true
	body.node.IdleTime = Inf
	body.SetAngle(0)

	return
}

func NewBody(mass, i vect.Float) (body *Body) {

	body = &Body{}
	body.Shapes = make([]*Shape, 0)
	body.SetMass(mass)
	body.SetMoment(i)
	body.SetAngle(0)

	return
}

func (body *Body) AddShape(shape *Shape) {
	body.Shapes = append(body.Shapes, shape)
	shape.Body = body
}

func (body *Body) Clone() *Body {
	clone := *body
	clone.Shapes = make([]*Shape, 0)
	for _, shape := range body.Shapes {
		clone.AddShape(shape.Clone())
	}
	clone.space = nil
	clone.hash = 0
	return &clone
}

func (body *Body) KineticEnergy() vect.Float {
	vsq := vect.Dot(body.v, body.v)
	wsq := body.w * body.w
	if vsq != 0 {
		vsq = vsq * body.m
	}
	if wsq != 0 {
		wsq = wsq * body.i
	}
	return vsq + wsq
}

func (body *Body) SetMass(mass vect.Float) {
	if mass <= 0 {
		panic("Mass must be positive and non-zero.")
	}

	body.BodyActivate()
	body.m = mass
	body.m_inv = 1 / mass
}

func (body *Body) SetMoment(moment vect.Float) {
	if moment <= 0 {
		panic("Moment of Inertia must be positive and non-zero.")
	}

	body.BodyActivate()
	body.i = moment
	body.i_inv = 1 / moment
}

func (body *Body) Moment() float32 {
	return float32(body.i)
}

func (body *Body) MomentIsInf() bool {
	return math.IsInf(float64(body.i), 0)
}

func (body *Body) SetAngle(angle vect.Float) {
	body.BodyActivate()
	body.setAngle(angle)
}

func (body *Body) AddAngle(angle float32) {
	body.SetAngle(vect.Float(angle) + body.Angle())
}

func (body *Body) Mass() vect.Float {
	return body.m
}

func (body *Body) setAngle(angle vect.Float) {
	body.a = angle
	body.rot = vect.FromAngle(angle)
}

func (body *Body) BodyActivate() {
	//TODO: make it work with sleeping
	if body.IsStatic() {
		return
	}

	if !body.IsRogue() {
		body.node.IdleTime = 0
	}
}

func (body *Body) ComponentRoot() *Body {
	if body != nil {
		return body.node.Root
	}
	return nil
}

func (body *Body) ComponentActive() {
	if body.IsSleeping() || body.IsRogue() {
		return
	}
	return

	space := body.space
	b := body
	for b != nil {
		next := b.node.Next

		b.node.IdleTime = 0
		b.node.Root = nil
		b.node.Next = nil
		space.ActiveBody(body)

		b = next
	}

	//for i,sleeping
	//cpArrayDeleteObj(space->sleepingComponents, root);
}

func (body *Body) IsRogue() bool {
	return body.space == nil
}

func (body *Body) IsSleeping() bool {
	return body.node.Root != nil
}

func (body *Body) IsStatic() bool {
	return math.IsInf(float64(body.node.IdleTime), 0)
}

func (body *Body) UpdateShapes() {
	for _, shape := range body.Shapes {
		shape.Update()
	}
}

func (body *Body) SetPosition(pos vect.Vect) {
	body.p = pos
}

func (body *Body) AddForce(x, y float32) {
	body.f.X += vect.Float(x)
	body.f.Y += vect.Float(y)
}

func (body *Body) SetForce(x, y float32) {
	body.f.X = vect.Float(x)
	body.f.Y = vect.Float(y)
}

func (body *Body) AddVelocity(x, y float32) {
	body.v.X += vect.Float(x)
	body.v.Y += vect.Float(y)
}

func (body *Body) SetVelocity(x, y float32) {
	body.v.X = vect.Float(x)
	body.v.Y = vect.Float(y)
}

func (body *Body) AddTorque(t float32) {
	body.t += vect.Float(t)
}

func (body *Body) Torque() float32 {
	return float32(body.t)
}

func (body *Body) AngularVelocity() float32 {
	return float32(body.w)
}

func (body *Body) SetTorque(t float32) {
	body.t = vect.Float(t)
}

func (body *Body) AddAngularVelocity(w float32) {
	body.w += vect.Float(w)
}

func (body *Body) SetAngularVelocity(w float32) {
	body.w = vect.Float(w)
}

func (body *Body) Velocity() vect.Vect {
	return body.v
}

func (body *Body) Position() vect.Vect {
	return body.p
}

func (body *Body) Angle() vect.Float {
	return body.a
}

func (body *Body) Rot() (rx, ry float32) {
	return float32(body.rot.X), float32(body.rot.Y)
}

func (body *Body) UpdatePosition(dt vect.Float) {
	if body.UpdatePositionFunc != nil {
		body.UpdatePositionFunc(body, dt)
		return
	}
	body.p = vect.Add(body.p, vect.Mult(vect.Add(body.v, body.v_bias), dt))
	body.setAngle(body.a + (body.w+body.w_bias)*dt)

	body.v_bias = vect.Vector_Zero
	body.w_bias = 0.0
}

func (body *Body) UpdateVelocity(gravity vect.Vect, damping, dt vect.Float) {
	if body.UpdateVelocityFunc != nil {
		body.UpdateVelocityFunc(body, gravity, damping, dt)
		return
	}
	body.v = vect.Add(vect.Mult(body.v, damping), vect.Mult(vect.Add(gravity, vect.Mult(body.f, body.m_inv)), dt))

	body.w = (body.w * damping) + (body.t * body.i_inv * dt)

	body.f = vect.Vector_Zero

}
<commit_msg>Added some functions to Body.<commit_after>package chipmunk

import (
	"github.com/vova616/chipmunk/vect"
	//. "github.com/vova616/chipmunk/transform"
	"math"
)

type ComponentNode struct {
	Root     *Body
	Next     *Body
	IdleTime vect.Float
}

type BodyType uint8
type UpdatePositionFunction func(body *Body, dt vect.Float)
type UpdateVelocityFunction func(body *Body, gravity vect.Vect, damping, dt vect.Float)

const (
	BodyType_Static  = BodyType(0)
	BodyType_Dynamic = BodyType(1)
)

var Inf = vect.Float(math.Inf(1))

type CollisionCallback interface {
	CollisionEnter(arbiter *Arbiter) bool
	CollisionPreSolve(arbiter *Arbiter) bool
	CollisionPostSolve(arbiter *Arbiter)
	CollisionExit(arbiter *Arbiter)
}

type Body struct {
	/// Mass of the body.
	/// Must agree with cpBody.m_inv! Use cpBodySetMass() when changing the mass for this reason.
	m vect.Float

	/// Mass inverse.
	m_inv vect.Float

	/// Moment of inertia of the body.
	/// Must agree with cpBody.i_inv! Use cpBodySetMoment() when changing the moment for this reason.
	i vect.Float
	/// Moment of inertia inverse.
	i_inv vect.Float

	/// Position of the rigid body's center of gravity.
	p vect.Vect
	/// Velocity of the rigid body's center of gravity.
	v vect.Vect
	/// Force acting on the rigid body's center of gravity.
	f vect.Vect

	//Transform Transform

	/// Rotation of the body around it's center of gravity in radians.
	/// Must agree with cpBody.rot! Use cpBodySetAngle() when changing the angle for this reason.
	a vect.Float
	/// Angular velocity of the body around it's center of gravity in radians/second.
	w vect.Float
	/// Torque applied to the body around it's center of gravity.
	t vect.Float

	/// Cached unit length vector representing the angle of the body.
	/// Used for fast rotations using cpvrotate().
	rot vect.Vect

	v_bias vect.Vect
	w_bias vect.Float

	/// User definable data pointer.
	/// Generally this points to your the game object class so you can access it
	/// when given a cpBody reference in a callback.
	UserData           interface{}
	CallbackHandler    CollisionCallback
	UpdatePositionFunc UpdatePositionFunction
	UpdateVelocityFunc UpdateVelocityFunction

	/// Maximum velocity allowed when updating the velocity.
	v_limit vect.Float
	/// Maximum rotational rate (in radians/second) allowed when updating the angular velocity.
	w_limit vect.Float

	space *Space

	Shapes []*Shape

	node ComponentNode

	hash HashValue

	deleted bool

	idleTime vect.Float

	IgnoreGravity bool
}

func NewBodyStatic() (body *Body) {

	body = &Body{}
	body.Shapes = make([]*Shape, 0)
	body.SetMass(Inf)
	body.SetMoment(Inf)
	body.IgnoreGravity = true
	body.node.IdleTime = Inf
	body.SetAngle(0)

	return
}

func NewBody(mass, i vect.Float) (body *Body) {

	body = &Body{}
	body.Shapes = make([]*Shape, 0)
	body.SetMass(mass)
	body.SetMoment(i)
	body.SetAngle(0)

	return
}

func (body *Body) AddShape(shape *Shape) {
	body.Shapes = append(body.Shapes, shape)
	shape.Body = body
}

func (body *Body) Clone() *Body {
	clone := *body
	clone.Shapes = make([]*Shape, 0)
	for _, shape := range body.Shapes {
		clone.AddShape(shape.Clone())
	}
	clone.space = nil
	clone.hash = 0
	return &clone
}

func (body *Body) KineticEnergy() vect.Float {
	vsq := vect.Dot(body.v, body.v)
	wsq := body.w * body.w
	if vsq != 0 {
		vsq = vsq * body.m
	}
	if wsq != 0 {
		wsq = wsq * body.i
	}
	return vsq + wsq
}

func (body *Body) SetMass(mass vect.Float) {
	if mass <= 0 {
		panic("Mass must be positive and non-zero.")
	}

	body.BodyActivate()
	body.m = mass
	body.m_inv = 1 / mass
}

func (body *Body) SetMoment(moment vect.Float) {
	if moment <= 0 {
		panic("Moment of Inertia must be positive and non-zero.")
	}

	body.BodyActivate()
	body.i = moment
	body.i_inv = 1 / moment
}

func (body *Body) Moment() float32 {
	return float32(body.i)
}

func (body *Body) MomentIsInf() bool {
	return math.IsInf(float64(body.i), 0)
}

func (body *Body) SetAngle(angle vect.Float) {
	body.BodyActivate()
	body.setAngle(angle)
}

func (body *Body) AddAngle(angle float32) {
	body.SetAngle(vect.Float(angle) + body.Angle())
}

func (body *Body) Mass() vect.Float {
	return body.m
}

func (body *Body) setAngle(angle vect.Float) {
	body.a = angle
	body.rot = vect.FromAngle(angle)
}

func (body *Body) BodyActivate() {
	//TODO: make it work with sleeping
	if body.IsStatic() {
		return
	}

	if !body.IsRogue() {
		body.node.IdleTime = 0
	}
}

func (body *Body) ComponentRoot() *Body {
	if body != nil {
		return body.node.Root
	}
	return nil
}

func (body *Body) ComponentActive() {
	if body.IsSleeping() || body.IsRogue() {
		return
	}
	return

	space := body.space
	b := body
	for b != nil {
		next := b.node.Next

		b.node.IdleTime = 0
		b.node.Root = nil
		b.node.Next = nil
		space.ActiveBody(body)

		b = next
	}

	//for i,sleeping
	//cpArrayDeleteObj(space->sleepingComponents, root);
}

func (body *Body) IsRogue() bool {
	return body.space == nil
}

func (body *Body) IsSleeping() bool {
	return body.node.Root != nil
}

func (body *Body) IsStatic() bool {
	return math.IsInf(float64(body.node.IdleTime), 0)
}

func (body *Body) UpdateShapes() {
	for _, shape := range body.Shapes {
		shape.Update()
	}
}

func (body *Body) SetPosition(pos vect.Vect) {
	body.p = pos
}

func (body *Body) AddForce(x, y float32) {
	body.f.X += vect.Float(x)
	body.f.Y += vect.Float(y)
}

func (body *Body) SetForce(x, y float32) {
	body.f.X = vect.Float(x)
	body.f.Y = vect.Float(y)
}

func (body *Body) AddVelocity(x, y float32) {
	body.v.X += vect.Float(x)
	body.v.Y += vect.Float(y)
}

func (body *Body) SetVelocity(x, y float32) {
	body.v.X = vect.Float(x)
	body.v.Y = vect.Float(y)
}

func (body *Body) AddTorque(t float32) {
	body.t += vect.Float(t)
}

func (body *Body) Torque() float32 {
	return float32(body.t)
}

func (body *Body) VBias() vect.Vect {
	return body.v_bias
}

func (body *Body) WBias() float32 {
	return float32(body.w_bias)
}

func (body *Body) SetVBias(v vect.Vect) {
	body.v_bias = v
}

func (body *Body) SetWBias(w float32) {
	body.w_bias = vect.Float(w)
}

func (body *Body) AngularVelocity() float32 {
	return float32(body.w)
}

func (body *Body) SetTorque(t float32) {
	body.t = vect.Float(t)
}

func (body *Body) AddAngularVelocity(w float32) {
	body.w += vect.Float(w)
}

func (body *Body) SetAngularVelocity(w float32) {
	body.w = vect.Float(w)
}

func (body *Body) Velocity() vect.Vect {
	return body.v
}

func (body *Body) Position() vect.Vect {
	return body.p
}

func (body *Body) Angle() vect.Float {
	return body.a
}

func (body *Body) Rot() (rx, ry float32) {
	return float32(body.rot.X), float32(body.rot.Y)
}

func (body *Body) UpdatePosition(dt vect.Float) {
	if body.UpdatePositionFunc != nil {
		body.UpdatePositionFunc(body, dt)
		return
	}
	body.p = vect.Add(body.p, vect.Mult(vect.Add(body.v, body.v_bias), dt))
	body.setAngle(body.a + (body.w+body.w_bias)*dt)

	body.v_bias = vect.Vector_Zero
	body.w_bias = 0.0
}

func (body *Body) UpdateVelocity(gravity vect.Vect, damping, dt vect.Float) {
	if body.UpdateVelocityFunc != nil {
		body.UpdateVelocityFunc(body, gravity, damping, dt)
		return
	}
	body.v = vect.Add(vect.Mult(body.v, damping), vect.Mult(vect.Add(gravity, vect.Mult(body.f, body.m_inv)), dt))

	body.w = (body.w * damping) + (body.t * body.i_inv * dt)

	body.f = vect.Vector_Zero

}
<|endoftext|>


<commit_before>package luddite

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"mime"
	"net/http"
	"reflect"
	"time"

	"github.com/gorilla/schema"
)

const (
	ContentTypeMultipartFormData = "multipart/form-data"
	ContentTypeWwwFormUrlencoded = "application/x-www-form-urlencoded"
	ContentTypeGif               = "image/gif"
	ContentTypePng               = "image/png"
	ContentTypeCss               = "text/css"
	ContentTypeHtml              = "text/html"
	ContentTypePlain             = "text/plain"
	ContentTypeJson              = "application/json"
	ContentTypeOctetStream       = "application/octet-stream"
	ContentTypeXml               = "application/xml"

	maxFormDataMemoryUsage = 10 * 1024 * 1024
)

var formDecoder = schema.NewDecoder()

func init() {
	t := time.Time{}
	formDecoder.RegisterConverter(t, ConvertTime)
}

func ConvertTime(value string) reflect.Value {
	if t, err := time.Parse(time.RFC3339, value); err == nil {
		return reflect.ValueOf(t)
	}
	return reflect.Value{}
}

func ReadRequest(req *http.Request, v interface{}) error {
	ct := req.Header.Get(HeaderContentType)
	switch mt, _, _ := mime.ParseMediaType(ct); mt {
	case ContentTypeMultipartFormData:
		if err := req.ParseMultipartForm(maxFormDataMemoryUsage); err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		if err := formDecoder.Decode(v, req.PostForm); err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		return nil
	case ContentTypeWwwFormUrlencoded:
		if err := req.ParseForm(); err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		if err := formDecoder.Decode(v, req.PostForm); err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		return nil
	case ContentTypeJson:
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(v)
		if err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		return nil
	case ContentTypeXml:
		decoder := xml.NewDecoder(req.Body)
		err := decoder.Decode(v)
		if err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		return nil
	case "":
		return nil
	default:
		return NewError(nil, EcodeUnsupportedMediaType, ct)
	}
}

func WriteResponse(rw http.ResponseWriter, status int, v interface{}) (err error) {
	var b []byte
	if v != nil {
		switch v.(type) {
		case *Error:
		case error:
			v = NewError(nil, EcodeInternal, v)
		}
		switch rw.Header().Get(HeaderContentType) {
		case ContentTypeJson:
			b, err = json.Marshal(v)
			if err != nil {
				rw.WriteHeader(http.StatusInternalServerError)
				b, err = json.Marshal(NewError(nil, EcodeSerializationFailed, err))
				if err != nil {
					rw.Write(b)
				}
				return
			}
		case ContentTypeXml:
			b, err = xml.Marshal(v)
			if err != nil {
				rw.WriteHeader(http.StatusInternalServerError)
				b, err = xml.Marshal(NewError(nil, EcodeSerializationFailed, err))
				if err != nil {
					rw.Write(b)
				}
				return
			}
		case ContentTypeHtml:
			switch v.(type) {
			case []byte:
				b = v.([]byte)
			case string:
				b = []byte(v.(string))
			default:
				b, err = json.Marshal(v)
				if err != nil {
					rw.WriteHeader(http.StatusInternalServerError)
					b, err = json.Marshal(NewError(nil, EcodeSerializationFailed, err))
					if err != nil {
						rw.Write(b)
					}
					return
				}
				esc := new(bytes.Buffer)
				json.HTMLEscape(esc, b)
				b = esc.Bytes()
			}
		case ContentTypeOctetStream:
			switch v.(type) {
			case []byte:
				b = v.([]byte)
			case string:
				b = []byte(v.(string))
			default:
				rw.WriteHeader(http.StatusInternalServerError)
				return
			}
		}
	}
	rw.WriteHeader(status)
	if b != nil {
		_, err = rw.Write(b)
	}
	return
}
<commit_msg>Add msgpack and protobuf content types<commit_after>package luddite

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"mime"
	"net/http"
	"reflect"
	"time"

	"github.com/gorilla/schema"
)

const (
	ContentTypeCss               = "text/css"
	ContentTypeGif               = "image/gif"
	ContentTypeHtml              = "text/html"
	ContentTypeJson              = "application/json"
	ContentTypeMsgpack           = "application/msgpack"
	ContentTypeMultipartFormData = "multipart/form-data"
	ContentTypeOctetStream       = "application/octet-stream"
	ContentTypePlain             = "text/plain"
	ContentTypePng               = "image/png"
	ContentTypeProtobuf          = "application/protobuf"
	ContentTypeWwwFormUrlencoded = "application/x-www-form-urlencoded"
	ContentTypeXml               = "application/xml"

	maxFormDataMemoryUsage = 10 * 1024 * 1024
)

var formDecoder = schema.NewDecoder()

func init() {
	t := time.Time{}
	formDecoder.RegisterConverter(t, ConvertTime)
}

func ConvertTime(value string) reflect.Value {
	if t, err := time.Parse(time.RFC3339, value); err == nil {
		return reflect.ValueOf(t)
	}
	return reflect.Value{}
}

func ReadRequest(req *http.Request, v interface{}) error {
	ct := req.Header.Get(HeaderContentType)
	switch mt, _, _ := mime.ParseMediaType(ct); mt {
	case ContentTypeMultipartFormData:
		if err := req.ParseMultipartForm(maxFormDataMemoryUsage); err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		if err := formDecoder.Decode(v, req.PostForm); err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		return nil
	case ContentTypeWwwFormUrlencoded:
		if err := req.ParseForm(); err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		if err := formDecoder.Decode(v, req.PostForm); err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		return nil
	case ContentTypeJson:
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(v)
		if err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		return nil
	case ContentTypeXml:
		decoder := xml.NewDecoder(req.Body)
		err := decoder.Decode(v)
		if err != nil {
			return NewError(nil, EcodeDeserializationFailed, err)
		}
		return nil
	case "":
		return nil
	default:
		return NewError(nil, EcodeUnsupportedMediaType, ct)
	}
}

func WriteResponse(rw http.ResponseWriter, status int, v interface{}) (err error) {
	var b []byte
	if v != nil {
		switch v.(type) {
		case *Error:
		case error:
			v = NewError(nil, EcodeInternal, v)
		}
		switch rw.Header().Get(HeaderContentType) {
		case ContentTypeJson:
			b, err = json.Marshal(v)
			if err != nil {
				rw.WriteHeader(http.StatusInternalServerError)
				b, err = json.Marshal(NewError(nil, EcodeSerializationFailed, err))
				if err != nil {
					rw.Write(b)
				}
				return
			}
		case ContentTypeXml:
			b, err = xml.Marshal(v)
			if err != nil {
				rw.WriteHeader(http.StatusInternalServerError)
				b, err = xml.Marshal(NewError(nil, EcodeSerializationFailed, err))
				if err != nil {
					rw.Write(b)
				}
				return
			}
		case ContentTypeHtml:
			switch v.(type) {
			case []byte:
				b = v.([]byte)
			case string:
				b = []byte(v.(string))
			default:
				b, err = json.Marshal(v)
				if err != nil {
					rw.WriteHeader(http.StatusInternalServerError)
					b, err = json.Marshal(NewError(nil, EcodeSerializationFailed, err))
					if err != nil {
						rw.Write(b)
					}
					return
				}
				esc := new(bytes.Buffer)
				json.HTMLEscape(esc, b)
				b = esc.Bytes()
			}
		case ContentTypeOctetStream:
			switch v.(type) {
			case []byte:
				b = v.([]byte)
			case string:
				b = []byte(v.(string))
			default:
				rw.WriteHeader(http.StatusInternalServerError)
				return
			}
		}
	}
	rw.WriteHeader(status)
	if b != nil {
		_, err = rw.Write(b)
	}
	return
}
<|endoftext|>


<commit_before>// With many thanks to http://www.kfish.org/boids/pseudocode.html

package main

import (
	rtree "github.com/patrick-higgins/rtreego"
	"math"
)

type Boid struct {
	ID       int         `json:"id"`
	Point    rtree.Point `json:"position"`
	Velocity rtree.Point `json:"-"`
}

func NewBoid(id int) *Boid {
	return &Boid{
		ID:       id,
		Point:    rtree.Point{0.0, 0.0, 0.0},
		Velocity: rtree.Point{0.0, 0.0, 0.0},
	}
}

func (b *Boid) RandomizePosition(area *Area) {
	b.Point[0] = area.X.Rand()
	b.Point[1] = area.Y.Rand()
	b.Point[2] = area.Z.Rand()
}

func (b *Boid) Bounds() *rtree.Rect {
	return b.Point.ToRect(0.01)
}

func (b *Boid) UpdateVelocity(area *Area) {
	v1 := b.Rule1(area)
	v2 := b.Rule2(area)
	v3 := b.Rule3(area)

	velocities := AddPoints(b.Velocity, v1, v2, v3)
	b.Velocity = LimitVelocity(velocities)
}

func (b *Boid) UpdatePosition() {
	b.Point = AddPoints(b.Point, b.Velocity)
}

// Rule1
//
// 	PROCEDURE Rule1(boid bJ)
//
//		Vector pcJ
//
//    FOR EACH BOID b
//    	IF b != bJ THEN
//    		pcJ = pcJ + b.position
//    	END IF
//    END
//
//    pcJ = pcJ / N-1
//
//    RETURN (pcJ - bJ.position) / 100
//
// 	END PROCEDURE
func (b *Boid) Rule1(area *Area) rtree.Point {
	pcJ := rtree.Point{0.0, 0.0, 0.0}

	nearest := area.Tree.NearestNeighbors(5, b.Point)
	boids := SpatialsToBoids(nearest)

	for _, boid := range boids {
		if boid.ID != b.ID {
			for i := 0; i < 3; i++ {
				pcJ[i] = pcJ[i] + boid.Point[i]
			}
		}
	}

	for i := 0; i < 3; i++ {
		pcJ[i] = pcJ[i] / float64(len(boids)-1)
	}

	subbed := SubPoints(pcJ, b.Point)
	divved := DivPoint(subbed, 100.0)
	return divved
}

// Rule2
//
// PROCEDURE rule2(boid bJ)
//
// 	Vector c = 0;
//
// 	FOR EACH BOID b
// 		IF b != bJ THEN
// 			IF |b.position - bJ.position| < 100 THEN
// 				c = c - (b.position - bJ.position)
// 			END IF
// 		END IF
// 	END
//
// 	RETURN c
//
// END PROCEDURE
func (b *Boid) Rule2(area *Area) rtree.Point {
	vector := rtree.Point{0.0, 0.0, 0.0}

	nearest := area.Tree.NearestNeighbors(5, b.Point)
	boids := SpatialsToBoids(nearest)

	for _, boid := range boids {
		if boid.ID != b.ID {
			for i := 0; i < 3; i++ {
				if math.Abs(boid.Point[i]-b.Point[i]) < 10 {
					vector[i] = vector[i] - (boid.Point[i] - b.Point[i])
				}
			}
		}
	}

	return vector
}

// Rule3
//
// PROCEDURE rule3(boid bJ)
//
// 	Vector pvJ
//
// 	FOR EACH BOID b
// 		IF b != bJ THEN
// 			pvJ = pvJ + b.velocity
// 		END IF
// 	END
//
// 	pvJ = pvJ / N-1
//
// 	RETURN (pvJ - bJ.velocity) / 8
//
// END PROCEDURE
func (b *Boid) Rule3(area *Area) rtree.Point {
	pvJ := rtree.Point{0.0, 0.0, 0.0}

	nearest := area.Tree.NearestNeighbors(5, b.Point)
	boids := SpatialsToBoids(nearest)

	for _, boid := range boids {
		if boid.ID != b.ID {
			for i := 0; i < 3; i++ {
				pvJ[i] = pvJ[i] + boid.Velocity[i]
			}
		}
	}

	for i := 0; i < 3; i++ {
		pvJ[i] = pvJ[i] / float64(len(boids)-1)
	}

	subbed := SubPoints(pvJ, b.Velocity)
	divved := DivPoint(subbed, 8.0)
	return divved
}

// LimitVelocity
//
//  PROCEDURE limit_velocity(Boid b)
//          Integer vlim
//          Vector v
//
//          IF |b.velocity| > vlim THEN
//                  b.velocity = (b.velocity / |b.velocity|) * vlim
//          END IF
//  END PROCEDURE
func LimitVelocity(velocities rtree.Point) rtree.Point {
	vlim := 25.0
	var absVel float64

	for i := 0; i < 3; i++ {
		absVel = math.Abs(velocities[i])
		if absVel > vlim {
			velocities[i] = (velocities[i] / absVel) * vlim
		}
	}

	return velocities
}

func SpatialsToBoids(spatials []rtree.Spatial) []*Boid {
	var boids []*Boid

	for _, spatial := range spatials {
		if spatial != nil {
			boids = append(boids, spatial.(*Boid))
		}
	}
	return boids
}

func (b *Boid) ToBoidPosition() *BoidPosition {
	return &BoidPosition{
		Id:       int32(b.ID),
		Position: []float64{b.Point[0], b.Point[1], b.Point[2]},
	}
}
<commit_msg>look for 10 nearest neighbors instead of 5<commit_after>// With many thanks to http://www.kfish.org/boids/pseudocode.html

package main

import (
	rtree "github.com/patrick-higgins/rtreego"
	"math"
)

type Boid struct {
	ID       int         `json:"id"`
	Point    rtree.Point `json:"position"`
	Velocity rtree.Point `json:"-"`
}

func NewBoid(id int) *Boid {
	return &Boid{
		ID:       id,
		Point:    rtree.Point{0.0, 0.0, 0.0},
		Velocity: rtree.Point{0.0, 0.0, 0.0},
	}
}

func (b *Boid) RandomizePosition(area *Area) {
	b.Point[0] = area.X.Rand()
	b.Point[1] = area.Y.Rand()
	b.Point[2] = area.Z.Rand()
}

func (b *Boid) Bounds() *rtree.Rect {
	return b.Point.ToRect(0.01)
}

func (b *Boid) UpdateVelocity(area *Area) {
	v1 := b.Rule1(area)
	v2 := b.Rule2(area)
	v3 := b.Rule3(area)

	velocities := AddPoints(b.Velocity, v1, v2, v3)
	b.Velocity = LimitVelocity(velocities)
}

func (b *Boid) UpdatePosition() {
	b.Point = AddPoints(b.Point, b.Velocity)
}

// Rule1
//
// 	PROCEDURE Rule1(boid bJ)
//
//		Vector pcJ
//
//    FOR EACH BOID b
//    	IF b != bJ THEN
//    		pcJ = pcJ + b.position
//    	END IF
//    END
//
//    pcJ = pcJ / N-1
//
//    RETURN (pcJ - bJ.position) / 100
//
// 	END PROCEDURE
func (b *Boid) Rule1(area *Area) rtree.Point {
	pcJ := rtree.Point{0.0, 0.0, 0.0}

	nearest := area.Tree.NearestNeighbors(10, b.Point)
	boids := SpatialsToBoids(nearest)

	for _, boid := range boids {
		if boid.ID != b.ID {
			for i := 0; i < 3; i++ {
				pcJ[i] = pcJ[i] + boid.Point[i]
			}
		}
	}

	for i := 0; i < 3; i++ {
		pcJ[i] = pcJ[i] / float64(len(boids)-1)
	}

	subbed := SubPoints(pcJ, b.Point)
	divved := DivPoint(subbed, 100.0)
	return divved
}

// Rule2
//
// PROCEDURE rule2(boid bJ)
//
// 	Vector c = 0;
//
// 	FOR EACH BOID b
// 		IF b != bJ THEN
// 			IF |b.position - bJ.position| < 100 THEN
// 				c = c - (b.position - bJ.position)
// 			END IF
// 		END IF
// 	END
//
// 	RETURN c
//
// END PROCEDURE
func (b *Boid) Rule2(area *Area) rtree.Point {
	vector := rtree.Point{0.0, 0.0, 0.0}

	nearest := area.Tree.NearestNeighbors(10, b.Point)
	boids := SpatialsToBoids(nearest)

	for _, boid := range boids {
		if boid.ID != b.ID {
			for i := 0; i < 3; i++ {
				if math.Abs(boid.Point[i]-b.Point[i]) < 10 {
					vector[i] = vector[i] - (boid.Point[i] - b.Point[i])
				}
			}
		}
	}

	return vector
}

// Rule3
//
// PROCEDURE rule3(boid bJ)
//
// 	Vector pvJ
//
// 	FOR EACH BOID b
// 		IF b != bJ THEN
// 			pvJ = pvJ + b.velocity
// 		END IF
// 	END
//
// 	pvJ = pvJ / N-1
//
// 	RETURN (pvJ - bJ.velocity) / 8
//
// END PROCEDURE
func (b *Boid) Rule3(area *Area) rtree.Point {
	pvJ := rtree.Point{0.0, 0.0, 0.0}

	nearest := area.Tree.NearestNeighbors(10, b.Point)
	boids := SpatialsToBoids(nearest)

	for _, boid := range boids {
		if boid.ID != b.ID {
			for i := 0; i < 3; i++ {
				pvJ[i] = pvJ[i] + boid.Velocity[i]
			}
		}
	}

	for i := 0; i < 3; i++ {
		pvJ[i] = pvJ[i] / float64(len(boids)-1)
	}

	subbed := SubPoints(pvJ, b.Velocity)
	divved := DivPoint(subbed, 8.0)
	return divved
}

// LimitVelocity
//
//  PROCEDURE limit_velocity(Boid b)
//          Integer vlim
//          Vector v
//
//          IF |b.velocity| > vlim THEN
//                  b.velocity = (b.velocity / |b.velocity|) * vlim
//          END IF
//  END PROCEDURE
func LimitVelocity(velocities rtree.Point) rtree.Point {
	vlim := 25.0
	var absVel float64

	for i := 0; i < 3; i++ {
		absVel = math.Abs(velocities[i])
		if absVel > vlim {
			velocities[i] = (velocities[i] / absVel) * vlim
		}
	}

	return velocities
}

func SpatialsToBoids(spatials []rtree.Spatial) []*Boid {
	var boids []*Boid

	for _, spatial := range spatials {
		if spatial != nil {
			boids = append(boids, spatial.(*Boid))
		}
	}
	return boids
}

func (b *Boid) ToBoidPosition() *BoidPosition {
	return &BoidPosition{
		Id:       int32(b.ID),
		Position: []float64{b.Point[0], b.Point[1], b.Point[2]},
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	"github.com/coreos/fleet/job"
	"github.com/coreos/fleet/log"
)

var (
	cmdUnloadUnit = &Command{
		Name:    "unload",
		Summary: "Unschedule one or more units in the cluster.",
		Usage:   "UNIT...",
		Run:     runUnloadUnit,
	}
)

func init() {
	cmdUnloadUnit.Flags.IntVar(&sharedFlags.BlockAttempts, "block-attempts", 0, "Wait until the units are inactive, performing up to N attempts before giving up. A value of 0 indicates no limit.")
	cmdUnloadUnit.Flags.BoolVar(&sharedFlags.NoBlock, "no-block", false, "Do not wait until the units have become inactive before exiting.")
}

func runUnloadUnit(args []string) (exit int) {
	units, err := findUnits(args)
	if err != nil {
		stderr("%v", err)
		return 1
	}

	wait := make([]string, 0)
	for _, s := range units {
		if !suToGlobal(s) {
			if job.JobState(s.CurrentState) == job.JobStateInactive {
				log.V(1).Infof("Target state of Unit(%s) already %s, skipping.", s.Name, job.JobStateInactive)
				continue
			}
		}

		log.V(1).Infof("Setting target state of Unit(%s) to %s", s.Name, job.JobStateInactive)
		cAPI.SetUnitTargetState(s.Name, string(job.JobStateInactive))
		if suToGlobal(s) {
			stdout("Triggered global unit %s unload", s.Name)
		} else {
			wait = append(wait, s.Name)
		}
	}

	if !sharedFlags.NoBlock {
		errchan := waitForUnitStates(wait, job.JobStateInactive, sharedFlags.BlockAttempts, os.Stderr)
		for err := range errchan {
			stderr("Error waiting for units: %v", err)
			exit = 1
		}
	} else {
		for _, name := range wait {
			stdout("Triggered unit %s unload", name)
		}
	}

	return
}
<commit_msg>fleetctl: unload should print to stdout<commit_after>package main

import (
	"os"

	"github.com/coreos/fleet/job"
	"github.com/coreos/fleet/log"
)

var (
	cmdUnloadUnit = &Command{
		Name:    "unload",
		Summary: "Unschedule one or more units in the cluster.",
		Usage:   "UNIT...",
		Run:     runUnloadUnit,
	}
)

func init() {
	cmdUnloadUnit.Flags.IntVar(&sharedFlags.BlockAttempts, "block-attempts", 0, "Wait until the units are inactive, performing up to N attempts before giving up. A value of 0 indicates no limit.")
	cmdUnloadUnit.Flags.BoolVar(&sharedFlags.NoBlock, "no-block", false, "Do not wait until the units have become inactive before exiting.")
}

func runUnloadUnit(args []string) (exit int) {
	units, err := findUnits(args)
	if err != nil {
		stderr("%v", err)
		return 1
	}

	wait := make([]string, 0)
	for _, s := range units {
		if !suToGlobal(s) {
			if job.JobState(s.CurrentState) == job.JobStateInactive {
				log.V(1).Infof("Target state of Unit(%s) already %s, skipping.", s.Name, job.JobStateInactive)
				continue
			}
		}

		log.V(1).Infof("Setting target state of Unit(%s) to %s", s.Name, job.JobStateInactive)
		cAPI.SetUnitTargetState(s.Name, string(job.JobStateInactive))
		if suToGlobal(s) {
			stdout("Triggered global unit %s unload", s.Name)
		} else {
			wait = append(wait, s.Name)
		}
	}

	if !sharedFlags.NoBlock {
		errchan := waitForUnitStates(wait, job.JobStateInactive, sharedFlags.BlockAttempts, os.Stdout)
		for err := range errchan {
			stderr("Error waiting for units: %v", err)
			exit = 1
		}
	} else {
		for _, name := range wait {
			stdout("Triggered unit %s unload", name)
		}
	}

	return
}
<|endoftext|>