<commit_before>/*
Copyright IBM Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package container

import (
	"io"
	"sync"

	"github.com/hyperledger/fabric/common/flogging"
	"github.com/hyperledger/fabric/core/chaincode/persistence"
	"github.com/hyperledger/fabric/core/container/ccintf"

	"github.com/pkg/errors"
)

var vmLogger = flogging.MustGetLogger("container")

//go:generate counterfeiter -o mock/vm.go --fake-name VM . VM

//VM is an abstract virtual image for supporting arbitrary virual machines
type VM interface {
	Build(ccid string, metadata *persistence.ChaincodePackageMetadata, codePackageStream io.Reader) (Instance, error)
}

//go:generate counterfeiter -o mock/instance.go --fake-name Instance . Instance

// Instance represents a built chaincode instance, because of the docker legacy, calling this a
// built 'container' would be very misleading, and going forward with the external launcher
// 'image' also seemed inappropriate.  So, the vague 'Instance' is used here.
type Instance interface {
	Start(peerConnection *ccintf.PeerConnection) error
	Stop() error
	Wait() (int, error)
}

type UninitializedInstance struct{}

func (UninitializedInstance) Start(peerConnection *ccintf.PeerConnection) error {
	return errors.Errorf("instance has not yet been built, cannot be started")
}

func (UninitializedInstance) Stop() error {
	return errors.Errorf("instance has not yet been built, cannot be stopped")
}

func (UninitializedInstance) Wait() (int, error) {
	return 0, errors.Errorf("instance has not yet been built, cannot wait")
}

//go:generate counterfeiter -o mock/package_provider.go --fake-name PackageProvider . PackageProvider

// PackageProvider gets chaincode packages from the filesystem.
type PackageProvider interface {
	GetChaincodePackage(packageID string) (*persistence.ChaincodePackageMetadata, io.ReadCloser, error)
}

type Router struct {
	ExternalVM      VM
	DockerVM        VM
	containers      map[string]Instance
	PackageProvider PackageProvider
	mutex           sync.Mutex
}

func (r *Router) getInstance(ccid string) Instance {
	r.mutex.Lock()
	defer r.mutex.Unlock()
	// Note, to resolve the locking problem which existed in the previous code, we never delete
	// references from the map.  In this way, it is safe to release the lock and operate
	// on the returned reference

	if r.containers == nil {
		r.containers = map[string]Instance{}
	}

	vm, ok := r.containers[ccid]
	if !ok {
		return UninitializedInstance{}
	}

	return vm
}

func (r *Router) Build(ccid string) error {
	// for now, the package ID we retrieve from the FS is always the ccid
	// the chaincode uses for registration
	packageID := ccid

	metadata, codeStream, err := r.PackageProvider.GetChaincodePackage(packageID)
	if err != nil {
		return errors.WithMessage(err, "get chaincode package for external build failed")
	}

	var instance Instance
	var externalErr error
	if r.ExternalVM != nil {
		instance, externalErr = r.ExternalVM.Build(ccid, metadata, codeStream)
		codeStream.Close()
	}

	if r.ExternalVM == nil || externalErr != nil {
		_, codeStream, err = r.PackageProvider.GetChaincodePackage(ccid)
		if err != nil {
			return errors.WithMessage(err, "get chaincode package for docker build failed")
		}
		instance, err = r.DockerVM.Build(ccid, metadata, codeStream)
		codeStream.Close()
	}

	if err != nil {
		return errors.WithMessagef(err, "failed external (%s) and docker build", externalErr)
	}

	r.mutex.Lock()
	defer r.mutex.Unlock()

	if r.containers == nil {
		r.containers = map[string]Instance{}
	}

	r.containers[ccid] = instance

	return nil
}

func (r *Router) Start(ccid string, peerConnection *ccintf.PeerConnection) error {
	return r.getInstance(ccid).Start(peerConnection)
}

func (r *Router) Stop(ccid string) error {
	return r.getInstance(ccid).Stop()
}

func (r *Router) Wait(ccid string) (int, error) {
	return r.getInstance(ccid).Wait()
}
<commit_msg>FAB-13528 Fix potential container file-handle leak<commit_after>/*
Copyright IBM Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package container

import (
	"io"
	"sync"

	"github.com/hyperledger/fabric/common/flogging"
	"github.com/hyperledger/fabric/core/chaincode/persistence"
	"github.com/hyperledger/fabric/core/container/ccintf"

	"github.com/pkg/errors"
)

var vmLogger = flogging.MustGetLogger("container")

//go:generate counterfeiter -o mock/vm.go --fake-name VM . VM

//VM is an abstract virtual image for supporting arbitrary virual machines
type VM interface {
	Build(ccid string, metadata *persistence.ChaincodePackageMetadata, codePackageStream io.Reader) (Instance, error)
}

//go:generate counterfeiter -o mock/instance.go --fake-name Instance . Instance

// Instance represents a built chaincode instance, because of the docker legacy, calling this a
// built 'container' would be very misleading, and going forward with the external launcher
// 'image' also seemed inappropriate.  So, the vague 'Instance' is used here.
type Instance interface {
	Start(peerConnection *ccintf.PeerConnection) error
	Stop() error
	Wait() (int, error)
}

type UninitializedInstance struct{}

func (UninitializedInstance) Start(peerConnection *ccintf.PeerConnection) error {
	return errors.Errorf("instance has not yet been built, cannot be started")
}

func (UninitializedInstance) Stop() error {
	return errors.Errorf("instance has not yet been built, cannot be stopped")
}

func (UninitializedInstance) Wait() (int, error) {
	return 0, errors.Errorf("instance has not yet been built, cannot wait")
}

//go:generate counterfeiter -o mock/package_provider.go --fake-name PackageProvider . PackageProvider

// PackageProvider gets chaincode packages from the filesystem.
type PackageProvider interface {
	GetChaincodePackage(packageID string) (*persistence.ChaincodePackageMetadata, io.ReadCloser, error)
}

type Router struct {
	ExternalVM      VM
	DockerVM        VM
	containers      map[string]Instance
	PackageProvider PackageProvider
	mutex           sync.Mutex
}

func (r *Router) getInstance(ccid string) Instance {
	r.mutex.Lock()
	defer r.mutex.Unlock()
	// Note, to resolve the locking problem which existed in the previous code, we never delete
	// references from the map.  In this way, it is safe to release the lock and operate
	// on the returned reference

	if r.containers == nil {
		r.containers = map[string]Instance{}
	}

	vm, ok := r.containers[ccid]
	if !ok {
		return UninitializedInstance{}
	}

	return vm
}

func (r *Router) Build(ccid string) error {
	// for now, the package ID we retrieve from the FS is always the ccid
	// the chaincode uses for registration
	packageID := ccid

	var instance Instance

	var externalErr error
	if r.ExternalVM != nil {
		metadata, codeStream, err := r.PackageProvider.GetChaincodePackage(packageID)
		if err != nil {
			return errors.WithMessage(err, "get chaincode package for external build failed")
		}
		instance, externalErr = r.ExternalVM.Build(ccid, metadata, codeStream)
		codeStream.Close()
	}

	var dockerErr error
	if r.ExternalVM == nil || externalErr != nil {
		metadata, codeStream, err := r.PackageProvider.GetChaincodePackage(ccid)
		if err != nil {
			return errors.WithMessage(err, "get chaincode package for docker build failed")
		}
		instance, dockerErr = r.DockerVM.Build(ccid, metadata, codeStream)
		codeStream.Close()
	}

	if dockerErr != nil {
		return errors.WithMessagef(dockerErr, "failed external (%s) and docker build", externalErr)
	}

	r.mutex.Lock()
	defer r.mutex.Unlock()

	if r.containers == nil {
		r.containers = map[string]Instance{}
	}

	r.containers[ccid] = instance

	return nil
}

func (r *Router) Start(ccid string, peerConnection *ccintf.PeerConnection) error {
	return r.getInstance(ccid).Start(peerConnection)
}

func (r *Router) Stop(ccid string) error {
	return r.getInstance(ccid).Stop()
}

func (r *Router) Wait(ccid string) (int, error) {
	return r.getInstance(ccid).Wait()
}
<|endoftext|>


<commit_before>package aws

import (
	"crypto/sha256"
	"fmt"
	"io/ioutil"
	"log"
	"strings"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/lambda"
	"github.com/mitchellh/go-homedir"

	"errors"

	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsLambdaFunction() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsLambdaFunctionCreate,
		Read:   resourceAwsLambdaFunctionRead,
		Update: resourceAwsLambdaFunctionUpdate,
		Delete: resourceAwsLambdaFunctionDelete,

		Schema: map[string]*schema.Schema{
			"filename": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"s3_bucket", "s3_key", "s3_object_version"},
			},
			"s3_bucket": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"filename"},
			},
			"s3_key": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"filename"},
			},
			"s3_object_version": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"filename"},
			},
			"description": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"function_name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"handler": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true, // TODO make this editable
			},
			"memory_size": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  128,
				ForceNew: true, // TODO make this editable
			},
			"role": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true, // TODO make this editable
			},
			"runtime": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Default:  "nodejs",
			},
			"timeout": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  3,
				ForceNew: true, // TODO make this editable
			},
			"arn": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
			"last_modified": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
			"source_code_hash": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
				ForceNew: true,
			},
		},
	}
}

// resourceAwsLambdaFunction maps to:
// CreateFunction in the API / SDK
func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).lambdaconn

	functionName := d.Get("function_name").(string)
	iamRole := d.Get("role").(string)

	log.Printf("[DEBUG] Creating Lambda Function %s with role %s", functionName, iamRole)

	var functionCode *lambda.FunctionCode
	if v, ok := d.GetOk("filename"); ok {
		filename, err := homedir.Expand(v.(string))
		if err != nil {
			return err
		}
		zipfile, err := ioutil.ReadFile(filename)
		if err != nil {
			return err
		}
		d.Set("source_code_hash", sha256.Sum256(zipfile))
		functionCode = &lambda.FunctionCode{
			ZipFile: zipfile,
		}
	} else {
		s3Bucket, bucketOk := d.GetOk("s3_bucket")
		s3Key, keyOk := d.GetOk("s3_key")
		s3ObjectVersion, versionOk := d.GetOk("s3_object_version")
		if !bucketOk || !keyOk || !versionOk {
			return errors.New("s3_bucket, s3_key and s3_object_version must all be set while using S3 code source")
		}
		functionCode = &lambda.FunctionCode{
			S3Bucket:        aws.String(s3Bucket.(string)),
			S3Key:           aws.String(s3Key.(string)),
			S3ObjectVersion: aws.String(s3ObjectVersion.(string)),
		}
	}

	params := &lambda.CreateFunctionInput{
		Code:         functionCode,
		Description:  aws.String(d.Get("description").(string)),
		FunctionName: aws.String(functionName),
		Handler:      aws.String(d.Get("handler").(string)),
		MemorySize:   aws.Int64(int64(d.Get("memory_size").(int))),
		Role:         aws.String(iamRole),
		Runtime:      aws.String(d.Get("runtime").(string)),
		Timeout:      aws.Int64(int64(d.Get("timeout").(int))),
	}

	var err error
	for i := 0; i < 5; i++ {
		_, err = conn.CreateFunction(params)
		if awsErr, ok := err.(awserr.Error); ok {

			// IAM profiles can take ~10 seconds to propagate in AWS:
			//  http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console
			// Error creating Lambda function: InvalidParameterValueException: The role defined for the task cannot be assumed by Lambda.
			if awsErr.Code() == "InvalidParameterValueException" && strings.Contains(awsErr.Message(), "The role defined for the task cannot be assumed by Lambda.") {
				log.Printf("[DEBUG] Invalid IAM Instance Profile referenced, retrying...")
				time.Sleep(2 * time.Second)
				continue
			}
		}
		break
	}
	if err != nil {
		return fmt.Errorf("Error creating Lambda function: %s", err)
	}

	d.SetId(d.Get("function_name").(string))

	return resourceAwsLambdaFunctionRead(d, meta)
}

// resourceAwsLambdaFunctionRead maps to:
// GetFunction in the API / SDK
func resourceAwsLambdaFunctionRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).lambdaconn

	log.Printf("[DEBUG] Fetching Lambda Function: %s", d.Id())

	params := &lambda.GetFunctionInput{
		FunctionName: aws.String(d.Get("function_name").(string)),
	}

	getFunctionOutput, err := conn.GetFunction(params)
	if err != nil {
		return err
	}

	// getFunctionOutput.Code.Location is a pre-signed URL pointing at the zip
	// file that we uploaded when we created the resource. You can use it to
	// download the code from AWS. The other part is
	// getFunctionOutput.Configuration which holds metadata.

	function := getFunctionOutput.Configuration
	// TODO error checking / handling on the Set() calls.
	d.Set("arn", function.FunctionArn)
	d.Set("description", function.Description)
	d.Set("handler", function.Handler)
	d.Set("memory_size", function.MemorySize)
	d.Set("last_modified", function.LastModified)
	d.Set("role", function.Role)
	d.Set("runtime", function.Runtime)
	d.Set("timeout", function.Timeout)

	return nil
}

// resourceAwsLambdaFunction maps to:
// DeleteFunction in the API / SDK
func resourceAwsLambdaFunctionDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).lambdaconn

	log.Printf("[INFO] Deleting Lambda Function: %s", d.Id())

	params := &lambda.DeleteFunctionInput{
		FunctionName: aws.String(d.Get("function_name").(string)),
	}

	_, err := conn.DeleteFunction(params)
	if err != nil {
		return fmt.Errorf("Error deleting Lambda Function: %s", err)
	}

	d.SetId("")

	return nil
}

// resourceAwsLambdaFunctionUpdate maps to:
// UpdateFunctionCode in the API / SDK
func resourceAwsLambdaFunctionUpdate(d *schema.ResourceData, meta interface{}) error {
	// conn := meta.(*AWSClient).lambdaconn

	return nil
}
<commit_msg>provider/aws: Update Lambda create error handling to be more flexible<commit_after>package aws

import (
	"crypto/sha256"
	"fmt"
	"io/ioutil"
	"log"
	"strings"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/lambda"
	"github.com/mitchellh/go-homedir"

	"errors"

	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsLambdaFunction() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsLambdaFunctionCreate,
		Read:   resourceAwsLambdaFunctionRead,
		Update: resourceAwsLambdaFunctionUpdate,
		Delete: resourceAwsLambdaFunctionDelete,

		Schema: map[string]*schema.Schema{
			"filename": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"s3_bucket", "s3_key", "s3_object_version"},
			},
			"s3_bucket": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"filename"},
			},
			"s3_key": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"filename"},
			},
			"s3_object_version": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"filename"},
			},
			"description": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"function_name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"handler": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true, // TODO make this editable
			},
			"memory_size": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  128,
				ForceNew: true, // TODO make this editable
			},
			"role": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true, // TODO make this editable
			},
			"runtime": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Default:  "nodejs",
			},
			"timeout": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  3,
				ForceNew: true, // TODO make this editable
			},
			"arn": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
			"last_modified": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},
			"source_code_hash": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
				ForceNew: true,
			},
		},
	}
}

// resourceAwsLambdaFunction maps to:
// CreateFunction in the API / SDK
func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).lambdaconn

	functionName := d.Get("function_name").(string)
	iamRole := d.Get("role").(string)

	log.Printf("[DEBUG] Creating Lambda Function %s with role %s", functionName, iamRole)

	var functionCode *lambda.FunctionCode
	if v, ok := d.GetOk("filename"); ok {
		filename, err := homedir.Expand(v.(string))
		if err != nil {
			return err
		}
		zipfile, err := ioutil.ReadFile(filename)
		if err != nil {
			return err
		}
		d.Set("source_code_hash", sha256.Sum256(zipfile))
		functionCode = &lambda.FunctionCode{
			ZipFile: zipfile,
		}
	} else {
		s3Bucket, bucketOk := d.GetOk("s3_bucket")
		s3Key, keyOk := d.GetOk("s3_key")
		s3ObjectVersion, versionOk := d.GetOk("s3_object_version")
		if !bucketOk || !keyOk || !versionOk {
			return errors.New("s3_bucket, s3_key and s3_object_version must all be set while using S3 code source")
		}
		functionCode = &lambda.FunctionCode{
			S3Bucket:        aws.String(s3Bucket.(string)),
			S3Key:           aws.String(s3Key.(string)),
			S3ObjectVersion: aws.String(s3ObjectVersion.(string)),
		}
	}

	params := &lambda.CreateFunctionInput{
		Code:         functionCode,
		Description:  aws.String(d.Get("description").(string)),
		FunctionName: aws.String(functionName),
		Handler:      aws.String(d.Get("handler").(string)),
		MemorySize:   aws.Int64(int64(d.Get("memory_size").(int))),
		Role:         aws.String(iamRole),
		Runtime:      aws.String(d.Get("runtime").(string)),
		Timeout:      aws.Int64(int64(d.Get("timeout").(int))),
	}

	var err error
	for i := 0; i < 5; i++ {
		_, err = conn.CreateFunction(params)
		if awsErr, ok := err.(awserr.Error); ok {

			// IAM profiles can take ~10 seconds to propagate in AWS:
			//  http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console
			// Error creating Lambda function: InvalidParameterValueException: The role defined for the task cannot be assumed by Lambda.
			if awsErr.Code() == "InvalidParameterValueException" && strings.Contains(awsErr.Message(), "cannot be assumed by Lambda.") {
				log.Printf("[DEBUG] Invalid IAM Instance Profile referenced, retrying...")
				time.Sleep(2 * time.Second)
				continue
			}
		}
		break
	}
	if err != nil {
		return fmt.Errorf("Error creating Lambda function: %s", err)
	}

	d.SetId(d.Get("function_name").(string))

	return resourceAwsLambdaFunctionRead(d, meta)
}

// resourceAwsLambdaFunctionRead maps to:
// GetFunction in the API / SDK
func resourceAwsLambdaFunctionRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).lambdaconn

	log.Printf("[DEBUG] Fetching Lambda Function: %s", d.Id())

	params := &lambda.GetFunctionInput{
		FunctionName: aws.String(d.Get("function_name").(string)),
	}

	getFunctionOutput, err := conn.GetFunction(params)
	if err != nil {
		return err
	}

	// getFunctionOutput.Code.Location is a pre-signed URL pointing at the zip
	// file that we uploaded when we created the resource. You can use it to
	// download the code from AWS. The other part is
	// getFunctionOutput.Configuration which holds metadata.

	function := getFunctionOutput.Configuration
	// TODO error checking / handling on the Set() calls.
	d.Set("arn", function.FunctionArn)
	d.Set("description", function.Description)
	d.Set("handler", function.Handler)
	d.Set("memory_size", function.MemorySize)
	d.Set("last_modified", function.LastModified)
	d.Set("role", function.Role)
	d.Set("runtime", function.Runtime)
	d.Set("timeout", function.Timeout)

	return nil
}

// resourceAwsLambdaFunction maps to:
// DeleteFunction in the API / SDK
func resourceAwsLambdaFunctionDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).lambdaconn

	log.Printf("[INFO] Deleting Lambda Function: %s", d.Id())

	params := &lambda.DeleteFunctionInput{
		FunctionName: aws.String(d.Get("function_name").(string)),
	}

	_, err := conn.DeleteFunction(params)
	if err != nil {
		return fmt.Errorf("Error deleting Lambda Function: %s", err)
	}

	d.SetId("")

	return nil
}

// resourceAwsLambdaFunctionUpdate maps to:
// UpdateFunctionCode in the API / SDK
func resourceAwsLambdaFunctionUpdate(d *schema.ResourceData, meta interface{}) error {
	// conn := meta.(*AWSClient).lambdaconn

	return nil
}
<|endoftext|>


<commit_before>package compact

import (
	"fmt"
	"strconv"

	"github.com/bcicen/ctop/cwidgets"
	ui "github.com/gizak/termui"
)

func (row *Compact) SetNet(rx int64, tx int64) {
	label := fmt.Sprintf("%s / %s", cwidgets.ByteFormat(rx), cwidgets.ByteFormat(tx))
	row.Net.Set(label)
}

func (row *Compact) SetIO(read int64, write int64) {
	label := fmt.Sprintf("%s / %s", cwidgets.ByteFormat(read), cwidgets.ByteFormat(write))
	row.IO.Set(label)
}

func (row *Compact) SetPids(val int) {
	label := fmt.Sprintf("%s", strconv.Itoa(val))
	row.Pids.Set(label)
}

func (row *Compact) SetCPU(val int) {
	row.Cpu.BarColor = colorScale(val)
	row.Cpu.Label = fmt.Sprintf("%s%%", strconv.Itoa(val))
	if val < 5 {
		val = 5
		row.Cpu.BarColor = ui.ThemeAttr("gauge.bar.bg")
	}
	if val > 100 {
		val = 100
	}
	row.Cpu.Percent = val
}

func (row *Compact) SetMem(val int64, limit int64, percent int) {
	row.Mem.Label = fmt.Sprintf("%s / %s", cwidgets.ByteFormat(val), cwidgets.ByteFormat(limit))
	if percent < 5 {
		percent = 5
		row.Mem.BarColor = ui.ColorBlack
	} else {
		row.Mem.BarColor = ui.ThemeAttr("gauge.bar.bg")
	}
	row.Mem.Percent = percent
}
<commit_msg>remove unneeded `fmt.Sprintf`<commit_after>package compact

import (
	"fmt"
	"strconv"

	"github.com/bcicen/ctop/cwidgets"
	ui "github.com/gizak/termui"
)

func (row *Compact) SetNet(rx int64, tx int64) {
	label := fmt.Sprintf("%s / %s", cwidgets.ByteFormat(rx), cwidgets.ByteFormat(tx))
	row.Net.Set(label)
}

func (row *Compact) SetIO(read int64, write int64) {
	label := fmt.Sprintf("%s / %s", cwidgets.ByteFormat(read), cwidgets.ByteFormat(write))
	row.IO.Set(label)
}

func (row *Compact) SetPids(val int) {
	label := strconv.Itoa(val)
	row.Pids.Set(label)
}

func (row *Compact) SetCPU(val int) {
	row.Cpu.BarColor = colorScale(val)
	row.Cpu.Label = fmt.Sprintf("%s%%", strconv.Itoa(val))
	if val < 5 {
		val = 5
		row.Cpu.BarColor = ui.ThemeAttr("gauge.bar.bg")
	}
	if val > 100 {
		val = 100
	}
	row.Cpu.Percent = val
}

func (row *Compact) SetMem(val int64, limit int64, percent int) {
	row.Mem.Label = fmt.Sprintf("%s / %s", cwidgets.ByteFormat(val), cwidgets.ByteFormat(limit))
	if percent < 5 {
		percent = 5
		row.Mem.BarColor = ui.ColorBlack
	} else {
		row.Mem.BarColor = ui.ThemeAttr("gauge.bar.bg")
	}
	row.Mem.Percent = percent
}
<|endoftext|>


<commit_before>// Copyright 2018-2020 Authors of Cilium
//
// 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.

// +build !privileged_tests

package cmd

import (
	"context"
	"net"
	"runtime"
	"time"

	"github.com/cilium/cilium/api/v1/models"
	apiEndpoint "github.com/cilium/cilium/api/v1/server/restapi/endpoint"
	"github.com/cilium/cilium/pkg/checker"
	endpointid "github.com/cilium/cilium/pkg/endpoint/id"
	"github.com/cilium/cilium/pkg/identity"
	"github.com/cilium/cilium/pkg/labels"
	"github.com/cilium/cilium/pkg/metrics"

	. "gopkg.in/check.v1"
)

func getEPTemplate(c *C, d *Daemon) *models.EndpointChangeRequest {
	ip4, ip6, err := d.ipam.AllocateNext("", "test")
	c.Assert(err, Equals, nil)
	c.Assert(ip4, Not(IsNil))
	c.Assert(ip6, Not(IsNil))

	return &models.EndpointChangeRequest{
		ContainerName: "foo",
		State:         models.EndpointStateWaitingForIdentity,
		Addressing: &models.AddressPair{
			IPV6: ip6.IP.String(),
			IPV4: ip4.IP.String(),
		},
	}
}

func (ds *DaemonSuite) TestEndpointAddReservedLabel(c *C) {
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)

	epTemplate := getEPTemplate(c, ds.d)
	epTemplate.Labels = []string{"reserved:world"}
	_, code, err := ds.d.createEndpoint(context.TODO(), epTemplate)
	c.Assert(err, Not(IsNil))
	c.Assert(code, Equals, apiEndpoint.PutEndpointIDInvalidCode)

	// Endpoint was created with invalid data; should transition from
	// WaitForIdentity -> Invalid.
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)
	assertOnMetric(c, string(models.EndpointStateInvalid), 0)

	// Endpoint is created with inital label as well as disallowed
	// reserved:world label.
	epTemplate.Labels = append(epTemplate.Labels, "reserved:init")
	_, code, err = ds.d.createEndpoint(context.TODO(), epTemplate)
	c.Assert(err, ErrorMatches, "not allowed to add reserved labels:.+")
	c.Assert(code, Equals, apiEndpoint.PutEndpointIDInvalidCode)

	// Endpoint was created with invalid data; should transition from
	// WaitForIdentity -> Invalid.
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)
	assertOnMetric(c, string(models.EndpointStateInvalid), 0)
}

func (ds *DaemonSuite) TestEndpointAddInvalidLabel(c *C) {
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)

	epTemplate := getEPTemplate(c, ds.d)
	epTemplate.Labels = []string{"reserved:foo"}
	_, code, err := ds.d.createEndpoint(context.TODO(), epTemplate)
	c.Assert(err, Not(IsNil))
	c.Assert(code, Equals, apiEndpoint.PutEndpointIDInvalidCode)

	// Endpoint was created with invalid data; should transition from
	// WaitForIdentity -> Invalid.
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)
	assertOnMetric(c, string(models.EndpointStateInvalid), 0)
}

func (ds *DaemonSuite) TestEndpointAddNoLabels(c *C) {
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)

	// Create the endpoint without any labels.
	epTemplate := getEPTemplate(c, ds.d)
	_, _, err := ds.d.createEndpoint(context.TODO(), epTemplate)
	c.Assert(err, IsNil)

	// Endpoint enters WaitingToRegenerate as it has its labels updated during
	// creation.
	assertOnMetric(c, string(models.EndpointStateWaitingToRegenerate), 1)

	expectedLabels := labels.Labels{
		labels.IDNameInit: labels.NewLabel(labels.IDNameInit, "", labels.LabelSourceReserved),
	}
	// Check that the endpoint has the reserved:init label.
	ep, err := ds.d.endpointManager.Lookup(endpointid.NewIPPrefixID(net.ParseIP(epTemplate.Addressing.IPV4)))
	c.Assert(err, IsNil)
	c.Assert(ep.OpLabels.IdentityLabels(), checker.DeepEquals, expectedLabels)

	secID := ep.WaitForIdentity(3 * time.Second)
	c.Assert(secID, Not(IsNil))
	c.Assert(secID.ID, Equals, identity.ReservedIdentityInit)

	// Endpoint should transition from WaitingToRegenerate -> Ready.
	assertOnMetric(c, string(models.EndpointStateWaitingToRegenerate), 0)
	assertOnMetric(c, string(models.EndpointStateReady), 1)
}

func (ds *DaemonSuite) TestUpdateSecLabels(c *C) {
	lbls := labels.NewLabelsFromModel([]string{"reserved:world"})
	code, err := ds.d.modifyEndpointIdentityLabelsFromAPI("1", lbls, nil)
	c.Assert(err, Not(IsNil))
	c.Assert(code, Equals, apiEndpoint.PatchEndpointIDLabelsUpdateFailedCode)
}

func (ds *DaemonSuite) TestUpdateLabelsFailed(c *C) {
	cancelledContext, cancelFunc := context.WithTimeout(context.Background(), 1*time.Second)
	cancelFunc() // Cancel immediatly to trigger the codepath to test.

	// Create the endpoint without any labels.
	epTemplate := getEPTemplate(c, ds.d)
	_, _, err := ds.d.createEndpoint(cancelledContext, epTemplate)
	c.Assert(err, ErrorMatches, "request cancelled while resolving identity")

	assertOnMetric(c, string(models.EndpointStateReady), 0)
}

func getMetricValue(state string) int64 {
	return int64(metrics.GetGaugeValue(metrics.EndpointStateCount.WithLabelValues(state)))
}

func assertOnMetric(c *C, state string, expected int64) {
	obtained := getMetricValue(state)
	if obtained != expected {
		_, _, line, _ := runtime.Caller(1)
		c.Errorf("Metrics assertion failed on line %d for Endpoint state %s: obtained %d, expected %d",
			line, state, obtained, expected)
	}
}
<commit_msg>daemon: Fix waiting on metrics in endpoint_test.go<commit_after>// Copyright 2018-2020 Authors of Cilium
//
// 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.

// +build !privileged_tests

package cmd

import (
	"context"
	"net"
	"runtime"
	"time"

	"github.com/cilium/cilium/api/v1/models"
	apiEndpoint "github.com/cilium/cilium/api/v1/server/restapi/endpoint"
	"github.com/cilium/cilium/pkg/checker"
	endpointid "github.com/cilium/cilium/pkg/endpoint/id"
	"github.com/cilium/cilium/pkg/identity"
	"github.com/cilium/cilium/pkg/labels"
	"github.com/cilium/cilium/pkg/metrics"
	"github.com/cilium/cilium/pkg/testutils"

	. "gopkg.in/check.v1"
)

func getEPTemplate(c *C, d *Daemon) *models.EndpointChangeRequest {
	ip4, ip6, err := d.ipam.AllocateNext("", "test")
	c.Assert(err, Equals, nil)
	c.Assert(ip4, Not(IsNil))
	c.Assert(ip6, Not(IsNil))

	return &models.EndpointChangeRequest{
		ContainerName: "foo",
		State:         models.EndpointStateWaitingForIdentity,
		Addressing: &models.AddressPair{
			IPV6: ip6.IP.String(),
			IPV4: ip4.IP.String(),
		},
	}
}

func (ds *DaemonSuite) TestEndpointAddReservedLabel(c *C) {
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)

	epTemplate := getEPTemplate(c, ds.d)
	epTemplate.Labels = []string{"reserved:world"}
	_, code, err := ds.d.createEndpoint(context.TODO(), epTemplate)
	c.Assert(err, Not(IsNil))
	c.Assert(code, Equals, apiEndpoint.PutEndpointIDInvalidCode)

	// Endpoint was created with invalid data; should transition from
	// WaitForIdentity -> Invalid.
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)
	assertOnMetric(c, string(models.EndpointStateInvalid), 0)

	// Endpoint is created with inital label as well as disallowed
	// reserved:world label.
	epTemplate.Labels = append(epTemplate.Labels, "reserved:init")
	_, code, err = ds.d.createEndpoint(context.TODO(), epTemplate)
	c.Assert(err, ErrorMatches, "not allowed to add reserved labels:.+")
	c.Assert(code, Equals, apiEndpoint.PutEndpointIDInvalidCode)

	// Endpoint was created with invalid data; should transition from
	// WaitForIdentity -> Invalid.
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)
	assertOnMetric(c, string(models.EndpointStateInvalid), 0)
}

func (ds *DaemonSuite) TestEndpointAddInvalidLabel(c *C) {
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)

	epTemplate := getEPTemplate(c, ds.d)
	epTemplate.Labels = []string{"reserved:foo"}
	_, code, err := ds.d.createEndpoint(context.TODO(), epTemplate)
	c.Assert(err, Not(IsNil))
	c.Assert(code, Equals, apiEndpoint.PutEndpointIDInvalidCode)

	// Endpoint was created with invalid data; should transition from
	// WaitForIdentity -> Invalid.
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)
	assertOnMetric(c, string(models.EndpointStateInvalid), 0)
}

func (ds *DaemonSuite) TestEndpointAddNoLabels(c *C) {
	assertOnMetric(c, string(models.EndpointStateWaitingForIdentity), 0)

	// Create the endpoint without any labels.
	epTemplate := getEPTemplate(c, ds.d)
	_, _, err := ds.d.createEndpoint(context.TODO(), epTemplate)
	c.Assert(err, IsNil)

	// Endpoint enters WaitingToRegenerate as it has its labels updated during
	// creation.
	assertOnMetric(c, string(models.EndpointStateWaitingToRegenerate), 1)

	expectedLabels := labels.Labels{
		labels.IDNameInit: labels.NewLabel(labels.IDNameInit, "", labels.LabelSourceReserved),
	}
	// Check that the endpoint has the reserved:init label.
	ep, err := ds.d.endpointManager.Lookup(endpointid.NewIPPrefixID(net.ParseIP(epTemplate.Addressing.IPV4)))
	c.Assert(err, IsNil)
	c.Assert(ep.OpLabels.IdentityLabels(), checker.DeepEquals, expectedLabels)

	secID := ep.WaitForIdentity(3 * time.Second)
	c.Assert(secID, Not(IsNil))
	c.Assert(secID.ID, Equals, identity.ReservedIdentityInit)

	// Endpoint should transition from WaitingToRegenerate -> Ready.
	assertOnMetric(c, string(models.EndpointStateWaitingToRegenerate), 0)
	assertOnMetric(c, string(models.EndpointStateReady), 1)
}

func (ds *DaemonSuite) TestUpdateSecLabels(c *C) {
	lbls := labels.NewLabelsFromModel([]string{"reserved:world"})
	code, err := ds.d.modifyEndpointIdentityLabelsFromAPI("1", lbls, nil)
	c.Assert(err, Not(IsNil))
	c.Assert(code, Equals, apiEndpoint.PatchEndpointIDLabelsUpdateFailedCode)
}

func (ds *DaemonSuite) TestUpdateLabelsFailed(c *C) {
	cancelledContext, cancelFunc := context.WithTimeout(context.Background(), 1*time.Second)
	cancelFunc() // Cancel immediatly to trigger the codepath to test.

	// Create the endpoint without any labels.
	epTemplate := getEPTemplate(c, ds.d)
	_, _, err := ds.d.createEndpoint(cancelledContext, epTemplate)
	c.Assert(err, ErrorMatches, "request cancelled while resolving identity")

	assertOnMetric(c, string(models.EndpointStateReady), 0)
}

func getMetricValue(state string) int64 {
	return int64(metrics.GetGaugeValue(metrics.EndpointStateCount.WithLabelValues(state)))
}

func assertOnMetric(c *C, state string, expected int64) {
	_, _, line, _ := runtime.Caller(1)

	obtainedValues := make(map[int64]struct{}, 0)
	err := testutils.WaitUntil(func() bool {
		obtained := getMetricValue(state)
		obtainedValues[obtained] = struct{}{}
		return obtained == expected
	}, 10*time.Second)
	if err != nil {
		// We are printing the map here to show every unique obtained metrics
		// value because these values change rapidly and it may be misleading
		// to only show the last obtained value.
		c.Errorf("Metrics assertion failed on line %d for Endpoint state %s: obtained %v, expected %d",
			line, state, obtainedValues, expected)
	}
}
<|endoftext|>


<commit_before>/*
   Copyright The containerd 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 containerd

import (
	"bytes"
	"context"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"testing"
	"time"

	"github.com/containerd/containerd/oci"
	"github.com/containerd/containerd/pkg/testutil"
	"github.com/containerd/containerd/runtime/v2/runc/options"
	"github.com/containerd/containerd/services/server"
)

// the following nolint is for shutting up gometalinter on non-linux.
// nolint: unused
func newDaemonWithConfig(t *testing.T, configTOML string) (*Client, *daemon, func()) {
	if testing.Short() {
		t.Skip()
	}
	testutil.RequiresRoot(t)
	var (
		ctrd              = daemon{}
		configTOMLDecoded server.Config
		buf               = bytes.NewBuffer(nil)
	)

	tempDir, err := ioutil.TempDir("", "containerd-test-new-daemon-with-config")
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err != nil {
			os.RemoveAll(tempDir)
		}
	}()

	configTOMLFile := filepath.Join(tempDir, "config.toml")
	if err = ioutil.WriteFile(configTOMLFile, []byte(configTOML), 0600); err != nil {
		t.Fatal(err)
	}

	if err = server.LoadConfig(configTOMLFile, &configTOMLDecoded); err != nil {
		t.Fatal(err)
	}

	address := configTOMLDecoded.GRPC.Address
	if address == "" {
		address = filepath.Join(tempDir, "containerd.sock")
	}
	args := []string{"-c", configTOMLFile}
	if configTOMLDecoded.Root == "" {
		args = append(args, "--root", filepath.Join(tempDir, "root"))
	}
	if configTOMLDecoded.State == "" {
		args = append(args, "--state", filepath.Join(tempDir, "state"))
	}
	if err = ctrd.start("containerd", address, args, buf, buf); err != nil {
		t.Fatalf("%v: %s", err, buf.String())
	}

	waitCtx, waitCancel := context.WithTimeout(context.TODO(), 2*time.Second)
	client, err := ctrd.waitForStart(waitCtx)
	waitCancel()
	if err != nil {
		ctrd.Kill()
		ctrd.Wait()
		t.Fatalf("%v: %s", err, buf.String())
	}

	cleanup := func() {
		if err := client.Close(); err != nil {
			t.Fatalf("failed to close client: %v", err)
		}
		if err := ctrd.Stop(); err != nil {
			if err := ctrd.Kill(); err != nil {
				t.Fatalf("failed to signal containerd: %v", err)
			}
		}
		if err := ctrd.Wait(); err != nil {
			if _, ok := err.(*exec.ExitError); !ok {
				t.Fatalf("failed to wait for: %v", err)
			}
		}
		if err := os.RemoveAll(tempDir); err != nil {
			t.Fatalf("failed to remove %s: %v", tempDir, err)
		}
		// cleaning config-specific resources is up to the caller
	}
	return client, &ctrd, cleanup

}

func testDaemonRuntimeRoot(t *testing.T, noShim bool) {
	runtimeRoot, err := ioutil.TempDir("", "containerd-test-runtime-root")
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err != nil {
			os.RemoveAll(runtimeRoot)
		}
	}()
	configTOML := `
[plugins]
 [plugins.cri]
   stream_server_port = "0"
`

	client, _, cleanup := newDaemonWithConfig(t, configTOML)
	defer cleanup()

	ctx, cancel := testContext()
	defer cancel()
	// FIXME(AkihiroSuda): import locally frozen image?
	image, err := client.Pull(ctx, testImage, WithPullUnpack)
	if err != nil {
		t.Fatal(err)
	}

	id := t.Name()
	container, err := client.NewContainer(ctx, id, WithNewSpec(oci.WithImageConfig(image), withProcessArgs("top")), WithNewSnapshot(id, image), WithRuntime("io.containerd.runc.v1", &options.Options{
		Root: runtimeRoot,
	}))
	if err != nil {
		t.Fatal(err)
	}
	defer container.Delete(ctx, WithSnapshotCleanup)

	task, err := container.NewTask(ctx, empty())
	if err != nil {
		t.Fatal(err)
	}
	defer task.Delete(ctx)

	if err = task.Start(ctx); err != nil {
		t.Fatal(err)
	}

	stateJSONPath := filepath.Join(runtimeRoot, testNamespace, id, "state.json")
	if _, err = os.Stat(stateJSONPath); err != nil {
		t.Errorf("error while getting stat for %s: %v", stateJSONPath, err)
	}

	finishedC, err := task.Wait(ctx)
	if err != nil {
		t.Fatal(err)
	}
	if err = task.Kill(ctx, syscall.SIGKILL); err != nil {
		t.Error(err)
	}
	<-finishedC
}

// TestDaemonRuntimeRoot ensures plugin.linux.runtime_root is not ignored
func TestDaemonRuntimeRoot(t *testing.T) {
	testDaemonRuntimeRoot(t, false)
}

// TestDaemonRuntimeRootNoShim ensures plugin.linux.runtime_root is not ignored when no_shim is true
func TestDaemonRuntimeRootNoShim(t *testing.T) {
	t.Skip("no_shim is not functional now: https://github.com/containerd/containerd/issues/2181")
	testDaemonRuntimeRoot(t, true)
}
<commit_msg>Wait before start with runtime root test<commit_after>/*
   Copyright The containerd 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 containerd

import (
	"bytes"
	"context"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"testing"
	"time"

	"github.com/containerd/containerd/oci"
	"github.com/containerd/containerd/pkg/testutil"
	"github.com/containerd/containerd/runtime/v2/runc/options"
	"github.com/containerd/containerd/services/server"
)

// the following nolint is for shutting up gometalinter on non-linux.
// nolint: unused
func newDaemonWithConfig(t *testing.T, configTOML string) (*Client, *daemon, func()) {
	if testing.Short() {
		t.Skip()
	}
	testutil.RequiresRoot(t)
	var (
		ctrd              = daemon{}
		configTOMLDecoded server.Config
		buf               = bytes.NewBuffer(nil)
	)

	tempDir, err := ioutil.TempDir("", "containerd-test-new-daemon-with-config")
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err != nil {
			os.RemoveAll(tempDir)
		}
	}()

	configTOMLFile := filepath.Join(tempDir, "config.toml")
	if err = ioutil.WriteFile(configTOMLFile, []byte(configTOML), 0600); err != nil {
		t.Fatal(err)
	}

	if err = server.LoadConfig(configTOMLFile, &configTOMLDecoded); err != nil {
		t.Fatal(err)
	}

	address := configTOMLDecoded.GRPC.Address
	if address == "" {
		address = filepath.Join(tempDir, "containerd.sock")
	}
	args := []string{"-c", configTOMLFile}
	if configTOMLDecoded.Root == "" {
		args = append(args, "--root", filepath.Join(tempDir, "root"))
	}
	if configTOMLDecoded.State == "" {
		args = append(args, "--state", filepath.Join(tempDir, "state"))
	}
	if err = ctrd.start("containerd", address, args, buf, buf); err != nil {
		t.Fatalf("%v: %s", err, buf.String())
	}

	waitCtx, waitCancel := context.WithTimeout(context.TODO(), 2*time.Second)
	client, err := ctrd.waitForStart(waitCtx)
	waitCancel()
	if err != nil {
		ctrd.Kill()
		ctrd.Wait()
		t.Fatalf("%v: %s", err, buf.String())
	}

	cleanup := func() {
		if err := client.Close(); err != nil {
			t.Fatalf("failed to close client: %v", err)
		}
		if err := ctrd.Stop(); err != nil {
			if err := ctrd.Kill(); err != nil {
				t.Fatalf("failed to signal containerd: %v", err)
			}
		}
		if err := ctrd.Wait(); err != nil {
			if _, ok := err.(*exec.ExitError); !ok {
				t.Fatalf("failed to wait for: %v", err)
			}
		}
		if err := os.RemoveAll(tempDir); err != nil {
			t.Fatalf("failed to remove %s: %v", tempDir, err)
		}
		// cleaning config-specific resources is up to the caller
	}
	return client, &ctrd, cleanup
}

// TestDaemonRuntimeRoot ensures plugin.linux.runtime_root is not ignored
func TestDaemonRuntimeRoot(t *testing.T) {
	runtimeRoot, err := ioutil.TempDir("", "containerd-test-runtime-root")
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err != nil {
			os.RemoveAll(runtimeRoot)
		}
	}()
	configTOML := `
[plugins]
 [plugins.cri]
   stream_server_port = "0"
`

	client, _, cleanup := newDaemonWithConfig(t, configTOML)
	defer cleanup()

	ctx, cancel := testContext()
	defer cancel()
	// FIXME(AkihiroSuda): import locally frozen image?
	image, err := client.Pull(ctx, testImage, WithPullUnpack)
	if err != nil {
		t.Fatal(err)
	}

	id := t.Name()
	container, err := client.NewContainer(ctx, id, WithNewSpec(oci.WithImageConfig(image), withProcessArgs("top")), WithNewSnapshot(id, image), WithRuntime("io.containerd.runc.v1", &options.Options{
		Root: runtimeRoot,
	}))
	if err != nil {
		t.Fatal(err)
	}
	defer container.Delete(ctx, WithSnapshotCleanup)

	task, err := container.NewTask(ctx, empty())
	if err != nil {
		t.Fatal(err)
	}
	defer task.Delete(ctx)

	status, err := task.Wait(ctx)
	if err != nil {
		t.Fatal(err)
	}

	if err = task.Start(ctx); err != nil {
		t.Fatal(err)
	}

	stateJSONPath := filepath.Join(runtimeRoot, testNamespace, id, "state.json")
	if _, err = os.Stat(stateJSONPath); err != nil {
		t.Errorf("error while getting stat for %s: %v", stateJSONPath, err)
	}

	if err = task.Kill(ctx, syscall.SIGKILL); err != nil {
		t.Error(err)
	}
	<-status
}
<|endoftext|>


<commit_before>package sdk

/*
   Copyright 2016 Alexander I.Grafov <grafov@gmail.com>

   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.

   ॐ तारे तुत्तारे तुरे स्व
*/

import (
	"encoding/json"
	"io/ioutil"
	"testing"
)

func TestUnmarshal_NewEmptyDashboard26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("../testdata/new-empty-dashboard-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}

func TestUnmarshal_EmptyDashboardWithTemplating26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("../testdata/empty-dashboard-with-templating-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}

func TestUnmarshal_EmptyDashboardWithAnnotation26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("../testdata/empty-dashboard-with-annotation-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}

func TestUnmarshal_EmptyDashboardWithLinks26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("../testdata/empty-dashboard-with-links-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}

func TestUnmarshal_DashboardWithDefaultPanelsIn2Rows26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("../testdata/default-panels-all-types-2-rows-dashboard-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}

func TestUnmarshal_DashboardWithGraphWithTargets26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("../testdata/default-panels-graph-with-targets-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
	if len(board.Rows) != 1 {
		t.Errorf("there are 1 row defined but got %d", len(board.Rows))
	}
	if len(board.Rows[0].Panels) != 1 {
		t.Errorf("there are 1 panel defined but got %d", len(board.Rows[0].Panels))
	}
	panel := board.Rows[0].Panels[0]
	if panel.OfType != GraphType {
		t.Errorf("panel type should be %d (\"graph\") type but got %d", GraphType, panel.OfType)
	}
	if *panel.Datasource != MixedSource {
		t.Errorf("panel Datasource should be \"%s\" but got \"%s\"", MixedSource, *panel.Datasource)
	}
	if len(panel.GraphPanel.Targets) != 2 {
		t.Errorf("panel has 2 targets but got %s", len(panel.GraphPanel.Targets))
	}
}

func TestUnmarshal_DashboardWithEmptyPanels30(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("../testdata/dashboard-with-default-panels-grafana-3.0.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}
<commit_msg>Fix paths in unit tests.<commit_after>package sdk

/*
   Copyright 2016 Alexander I.Grafov <grafov@gmail.com>

   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.

   ॐ तारे तुत्तारे तुरे स्व
*/

import (
	"encoding/json"
	"io/ioutil"
	"testing"
)

func TestUnmarshal_NewEmptyDashboard26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("testdata/new-empty-dashboard-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}

func TestUnmarshal_EmptyDashboardWithTemplating26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("testdata/empty-dashboard-with-templating-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}

func TestUnmarshal_EmptyDashboardWithAnnotation26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("testdata/empty-dashboard-with-annotation-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}

func TestUnmarshal_EmptyDashboardWithLinks26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("testdata/empty-dashboard-with-links-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}

func TestUnmarshal_DashboardWithDefaultPanelsIn2Rows26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("testdata/default-panels-all-types-2-rows-dashboard-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}

func TestUnmarshal_DashboardWithGraphWithTargets26(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("testdata/default-panels-graph-with-targets-2.6.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
	if len(board.Rows) != 1 {
		t.Errorf("there are 1 row defined but got %d", len(board.Rows))
	}
	if len(board.Rows[0].Panels) != 1 {
		t.Errorf("there are 1 panel defined but got %d", len(board.Rows[0].Panels))
	}
	panel := board.Rows[0].Panels[0]
	if panel.OfType != GraphType {
		t.Errorf("panel type should be %d (\"graph\") type but got %d", GraphType, panel.OfType)
	}
	if *panel.Datasource != MixedSource {
		t.Errorf("panel Datasource should be \"%s\" but got \"%s\"", MixedSource, *panel.Datasource)
	}
	if len(panel.GraphPanel.Targets) != 2 {
		t.Errorf("panel has 2 targets but got %s", len(panel.GraphPanel.Targets))
	}
}

func TestUnmarshal_DashboardWithEmptyPanels30(t *testing.T) {
	var board Board
	raw, _ := ioutil.ReadFile("testdata/dashboard-with-default-panels-grafana-3.0.json")

	err := json.Unmarshal(raw, &board)

	if err != nil {
		t.Error(err)
	}
}
<|endoftext|>


<commit_before>// Copyright © 2012, Greg Ward. All rights reserved.
// Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE.txt file.

package runtime

import (
	"testing"
	//"reflect"

	"github.com/stretchrcom/testify/assert"

	"fubsy/dsl"
	"fubsy/testutils"
	"fubsy/types"
)

func Test_Runtime_assign(t *testing.T) {
	// AST for a = "foo"
	node := dsl.NewASTAssignment("a", stringnode("foo"))
	rt := &Runtime{}
	ns := types.NewValueMap()

	rt.assign(node, ns)
	expect := types.FuString("foo")
	assertIn(t, ns, "a", expect)
}

// evaluate simple expressions (no operators)
func Test_Runtime_evaluate_simple(t *testing.T) {
	// the expression "meep" evaluates to the string "meep"
	var expect types.FuObject
	snode := stringnode("meep")
	rt := NewRuntime("", nil)
	expect = types.FuString("meep")
	assertEvaluateOK(t, rt, expect, snode)

	// the expression foo evaluates to the string "meep" if foo is set
	// to that string in the global ValueMap
	rt.globals.Assign("foo", expect)
	nnode := dsl.NewASTName("foo")
	assertEvaluateOK(t, rt, expect, nnode)

	// ... and to an error if the variable is not defined
	nnode = dsl.NewASTName("boo")
	assertEvaluateFail(t, rt, "undefined variable 'boo'", nnode)

	// expression <*.c blah> evaluates to a FileFinder with two
	// include patterns
	patterns := []string{"*.c", "blah"}
	flnode := dsl.NewASTFileList(patterns)
	expect = types.NewFileFinder([]string{"*.c", "blah"})
	assertEvaluateOK(t, rt, expect, flnode)
}

func stringnode(value string) *dsl.ASTString {
	// NewASTString takes a token, which comes quoted
	value = "\"" + value + "\""
	return dsl.NewASTString(value)
}

func assertIn(t *testing.T, ns types.ValueMap, name string, expect types.FuObject) {
	if actual, ok := ns[name]; ok {
		if actual != expect {
			t.Errorf("expected %#v, but got %#v", expect, actual)
		}
	} else {
		t.Errorf("expected to find name '%s' in namespace", name)
	}
}

func assertEvaluateOK(
	t *testing.T,
	rt *Runtime,
	expect types.FuObject,
	input dsl.ASTExpression) {

	obj, err := rt.evaluate(input)
	assert.Nil(t, err)

	// need to use DeepEqual() to handle (e.g.) slices inside structs
	//if !reflect.DeepEqual(expect, obj) {
	if !expect.Equal(obj) {
		t.Errorf("expected\n%#v\nbut got\n%#v", expect, obj)
	}
}

func assertEvaluateFail(
	t *testing.T,
	rt *Runtime,
	expecterr string,
	input dsl.ASTExpression) {

	obj, err := rt.evaluate(input)
	testutils.AssertError(t, expecterr, err)
	if obj != nil {
		t.Errorf("expected obj == nil, but got %#v", obj)
	}
}
<commit_msg>runtime: start adding unit tests for runMainPhase()<commit_after>// Copyright © 2012, Greg Ward. All rights reserved.
// Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE.txt file.

package runtime

import (
	"bytes"
	"os"
	"testing"
	//"fmt"
	//"reflect"

	"github.com/stretchrcom/testify/assert"

	"fubsy/dsl"
	"fubsy/testutils"
	"fubsy/types"
)

func Test_Runtime_runMainPhase_missing(t *testing.T) {
	// invalid: a script with no main phase
	filename := "test.fubsy"
	script := "" +
		"import meep\n" +
		"plunk {\n" +
		"}\n"
	// ast, err := dsl.ParseString(filename, script)
	// assert.Equal(t, 0, len(err)) // syntax is fine
	// rt := NewRuntime(filename, ast)
	rt := parseScript(t, filename, script)
	errors := rt.runMainPhase()
	assert.Equal(t, 1, len(errors))
	assert.Equal(t, "test.fubsy:1-3: no main phase defined", errors[0].Error())
}

func Test_Runtime_runMainPhase_valid(t *testing.T) {
	script := "" +
		"main {\n" +
		"  src = \"foo.c\"\n" +
		"  \"foo\": src {\n" +
		"    \"cc -o $TARGET $src\"\n" +
		"  }\n" +
		"}\n"
	rt := parseScript(t, "test.fubsy", script)
	errors := rt.runMainPhase()
	assert.Equal(t, 0, len(errors))
	val, ok := rt.stack.Lookup("src")
	assert.True(t, ok)
	assert.Equal(t, types.FuString("foo.c"), val)
	assert.NotNil(t, rt.dag)
	rt.dag.Dump(os.Stdout)

	// this seems *awfully* detailed and brittle, but DAG doesn't
	// provide a good way to query what's in it (yet...)
	expect := "" +
		"0000: foo (*dag.FileNode, UNKNOWN)\n" +
		"  action: cc -o $TARGET $src\n" +
		"  parents:\n" +
		"    0001: foo.c\n" +
		"0001: foo.c (*dag.FileNode, UNKNOWN)\n"
	var buf bytes.Buffer
	rt.dag.Dump(&buf)
	assert.Equal(t, expect, buf.String())
}

func parseScript(t *testing.T, filename string, content string) *Runtime {
	ast, errors := dsl.ParseString(filename, content)
	assert.Equal(t, 0, len(errors)) // syntax must be good
	return NewRuntime(filename, ast)
}

func Test_Runtime_assign(t *testing.T) {
	// AST for a = "foo"
	node := dsl.NewASTAssignment("a", stringnode("foo"))
	rt := &Runtime{}
	ns := types.NewValueMap()

	rt.assign(node, ns)
	expect := types.FuString("foo")
	assertIn(t, ns, "a", expect)
}

// evaluate simple expressions (no operators)
func Test_Runtime_evaluate_simple(t *testing.T) {
	// the expression "meep" evaluates to the string "meep"
	var expect types.FuObject
	snode := stringnode("meep")
	rt := NewRuntime("", nil)
	expect = types.FuString("meep")
	assertEvaluateOK(t, rt, expect, snode)

	// the expression foo evaluates to the string "meep" if foo is set
	// to that string in the global ValueMap
	rt.globals.Assign("foo", expect)
	nnode := dsl.NewASTName("foo")
	assertEvaluateOK(t, rt, expect, nnode)

	// ... and to an error if the variable is not defined
	nnode = dsl.NewASTName("boo")
	assertEvaluateFail(t, rt, "undefined variable 'boo'", nnode)

	// expression <*.c blah> evaluates to a FileFinder with two
	// include patterns
	patterns := []string{"*.c", "blah"}
	flnode := dsl.NewASTFileList(patterns)
	expect = types.NewFileFinder([]string{"*.c", "blah"})
	assertEvaluateOK(t, rt, expect, flnode)
}

func stringnode(value string) *dsl.ASTString {
	// NewASTString takes a token, which comes quoted
	value = "\"" + value + "\""
	return dsl.NewASTString(value)
}

func assertIn(t *testing.T, ns types.ValueMap, name string, expect types.FuObject) {
	if actual, ok := ns[name]; ok {
		if actual != expect {
			t.Errorf("expected %#v, but got %#v", expect, actual)
		}
	} else {
		t.Errorf("expected to find name '%s' in namespace", name)
	}
}

func assertEvaluateOK(
	t *testing.T,
	rt *Runtime,
	expect types.FuObject,
	input dsl.ASTExpression) {

	obj, err := rt.evaluate(input)
	assert.Nil(t, err)

	// need to use DeepEqual() to handle (e.g.) slices inside structs
	//if !reflect.DeepEqual(expect, obj) {
	if !expect.Equal(obj) {
		t.Errorf("expected\n%#v\nbut got\n%#v", expect, obj)
	}
}

func assertEvaluateFail(
	t *testing.T,
	rt *Runtime,
	expecterr string,
	input dsl.ASTExpression) {

	obj, err := rt.evaluate(input)
	testutils.AssertError(t, expecterr, err)
	if obj != nil {
		t.Errorf("expected obj == nil, but got %#v", obj)
	}
}
<|endoftext|>


<commit_before>package handler

import (
	"bytes"
	"fullerite/metric"
	"github.com/golang/protobuf/proto"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

// SignalFx Handler
type SignalFx struct {
	BaseHandler
	endpoint  string
	authToken string
}

// NewSignalFx returns a new SignalFx handler.
func NewSignalFx() *SignalFx {
	s := new(SignalFx)
	s.name = "SignalFx"
	s.maxBufferSize = DefaultBufferSize
	s.channel = make(chan metric.Metric)
	return s
}

// Configure : accepts the different configuration options for the signalfx handler
func (s *SignalFx) Configure(config *map[string]string) {
	asmap := *config
	var exists bool
	s.authToken, exists = asmap["authToken"]
	if !exists {
		log.Println("There was no auth key specified for the SignalFx Handler, there won't be any emissions")
	}
	s.endpoint, exists = asmap["endpoint"]
	if !exists {
		log.Println("There was no endpoint specified for the SignalFx Handler, there won't be any emissions")
	}
}

// Run send metrics in the channel to SignalFx.
func (s *SignalFx) Run() {
	log.Println("Starting signalfx handler...")
	lastEmission := time.Now()

	datapoints := make([]*DataPoint, 0, s.maxBufferSize)

	for incomingMetric := range s.Channel() {
		datapoint := s.convertToProto(&incomingMetric)
		datapoints = append(datapoints, datapoint)
		if time.Since(lastEmission).Seconds() >= float64(s.interval) || len(datapoints) >= s.maxBufferSize {
			s.emitMetrics(&datapoints)
			datapoints = make([]*DataPoint, 0, s.maxBufferSize)
		}
	}
}

func (s *SignalFx) convertToProto(incomingMetric *metric.Metric) *DataPoint {
	outname := s.Prefix() + (*incomingMetric).Name

	datapoint := new(DataPoint)
	datapoint.Metric = &outname
	datapoint.Value = &Datum{
		DoubleValue: &(*incomingMetric).Value,
	}
	datapoint.Source = new(string)
	*datapoint.Source = "fullerite"

	switch incomingMetric.MetricType {
	case metric.Gauge:
		datapoint.MetricType = MetricType_GAUGE.Enum()
	case metric.Counter:
		datapoint.MetricType = MetricType_COUNTER.Enum()
	case metric.CumulativeCounter:
		datapoint.MetricType = MetricType_CUMULATIVE_COUNTER.Enum()
	}

	dimensions := incomingMetric.GetDimensions(s.DefaultDimensions())
	for key, value := range dimensions {
		dim := Dimension{
			Key:   &key,
			Value: &value,
		}
		datapoint.Dimensions = append(datapoint.Dimensions, &dim)
	}

	return datapoint
}

func (s *SignalFx) emitMetrics(datapoints *[]*DataPoint) {
	log.Println("Starting to emit", len(*datapoints), "datapoints")

	if len(*datapoints) == 0 {
		log.Println("Skipping send because of an empty payload")
		return
	}

	payload := new(DataPointUploadMessage)
	payload.Datapoints = *datapoints

	if s.authToken == "" || s.endpoint == "" {
		log.Println("Skipping emission because we're missing the auth token ",
			"or the endpoint, payload would have been", payload.String())
		return
	}
	serialized, err := proto.Marshal(payload)
	if err != nil {
		log.Println("Failed to serailize payload", *payload)
		return
	}

	req, err := http.NewRequest("POST", s.endpoint, bytes.NewBuffer(serialized))
	if err != nil {
		log.Println("Failed to create a request to endpoint", s.endpoint)
		return
	}
	req.Header.Set("X-SF-TOKEN", s.authToken)
	req.Header.Set("Content-Type", "application/x-protobuf")

	client := &http.Client{}
	rsp, err := client.Do(req)
	if err != nil {
		log.Println("Failed to complete POST", err)
		return
	}

	defer rsp.Body.Close()
	if rsp.Status != "200 OK" {
		body, _ := ioutil.ReadAll(rsp.Body)
		log.Println("Failed to post to signalfx @", s.endpoint,
			"status was", rsp.Status,
			"rsp body was", string(body),
			"payload was", payload)
		return
	}

	log.Println("Successfully sent", len(*datapoints), "datapoints to signalfx")
}
<commit_msg>reset last emission time<commit_after>package handler

import (
	"bytes"
	"fullerite/metric"
	"github.com/golang/protobuf/proto"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

// SignalFx Handler
type SignalFx struct {
	BaseHandler
	endpoint  string
	authToken string
}

// NewSignalFx returns a new SignalFx handler.
func NewSignalFx() *SignalFx {
	s := new(SignalFx)
	s.name = "SignalFx"
	s.maxBufferSize = DefaultBufferSize
	s.channel = make(chan metric.Metric)
	return s
}

// Configure : accepts the different configuration options for the signalfx handler
func (s *SignalFx) Configure(config *map[string]string) {
	asmap := *config
	var exists bool
	s.authToken, exists = asmap["authToken"]
	if !exists {
		log.Println("There was no auth key specified for the SignalFx Handler, there won't be any emissions")
	}
	s.endpoint, exists = asmap["endpoint"]
	if !exists {
		log.Println("There was no endpoint specified for the SignalFx Handler, there won't be any emissions")
	}
}

// Run send metrics in the channel to SignalFx.
func (s *SignalFx) Run() {
	log.Println("Starting signalfx handler...")
	datapoints := make([]*DataPoint, 0, s.maxBufferSize)

	lastEmission := time.Now()
	for incomingMetric := range s.Channel() {
		datapoint := s.convertToProto(&incomingMetric)
		datapoints = append(datapoints, datapoint)
		if time.Since(lastEmission).Seconds() >= float64(s.interval) || len(datapoints) >= s.maxBufferSize {
			s.emitMetrics(&datapoints)
			lastEmission = time.Now()
			datapoints = make([]*DataPoint, 0, s.maxBufferSize)
		}
	}
}

func (s *SignalFx) convertToProto(incomingMetric *metric.Metric) *DataPoint {
	outname := s.Prefix() + (*incomingMetric).Name

	datapoint := new(DataPoint)
	datapoint.Metric = &outname
	datapoint.Value = &Datum{
		DoubleValue: &(*incomingMetric).Value,
	}
	datapoint.Source = new(string)
	*datapoint.Source = "fullerite"

	switch incomingMetric.MetricType {
	case metric.Gauge:
		datapoint.MetricType = MetricType_GAUGE.Enum()
	case metric.Counter:
		datapoint.MetricType = MetricType_COUNTER.Enum()
	case metric.CumulativeCounter:
		datapoint.MetricType = MetricType_CUMULATIVE_COUNTER.Enum()
	}

	dimensions := incomingMetric.GetDimensions(s.DefaultDimensions())
	for key, value := range dimensions {
		dim := Dimension{
			Key:   &key,
			Value: &value,
		}
		datapoint.Dimensions = append(datapoint.Dimensions, &dim)
	}

	return datapoint
}

func (s *SignalFx) emitMetrics(datapoints *[]*DataPoint) {
	log.Println("Starting to emit", len(*datapoints), "datapoints")

	if len(*datapoints) == 0 {
		log.Println("Skipping send because of an empty payload")
		return
	}

	payload := new(DataPointUploadMessage)
	payload.Datapoints = *datapoints

	if s.authToken == "" || s.endpoint == "" {
		log.Println("Skipping emission because we're missing the auth token ",
			"or the endpoint, payload would have been", payload.String())
		return
	}
	serialized, err := proto.Marshal(payload)
	if err != nil {
		log.Println("Failed to serailize payload", *payload)
		return
	}

	req, err := http.NewRequest("POST", s.endpoint, bytes.NewBuffer(serialized))
	if err != nil {
		log.Println("Failed to create a request to endpoint", s.endpoint)
		return
	}
	req.Header.Set("X-SF-TOKEN", s.authToken)
	req.Header.Set("Content-Type", "application/x-protobuf")

	client := &http.Client{}
	rsp, err := client.Do(req)
	if err != nil {
		log.Println("Failed to complete POST", err)
		return
	}

	defer rsp.Body.Close()
	if rsp.Status != "200 OK" {
		body, _ := ioutil.ReadAll(rsp.Body)
		log.Println("Failed to post to signalfx @", s.endpoint,
			"status was", rsp.Status,
			"rsp body was", string(body),
			"payload was", payload)
		return
	}

	log.Println("Successfully sent", len(*datapoints), "datapoints to signalfx")
}
<|endoftext|>


<commit_before>// Package realos defines the actual interface into operating system
// functionality.
package realos

import (
	"bufio"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"syscall"

	"github.com/Microsoft/opengcs/service/gcs/oslayer"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

// realProcessExitState represents an oslayer.ProcessExitState which uses an
// os.ProcessState for its information.
type realProcessExitState struct {
	state *os.ProcessState
}

// NewProcessExitState returns an oslayer.ProcessExitState wrapping the given
// *os.ProcessState.
func NewProcessExitState(state *os.ProcessState) oslayer.ProcessExitState {
	return &realProcessExitState{state: state}
}
func (s *realProcessExitState) ExitCode() int {
	return s.state.Sys().(syscall.WaitStatus).ExitStatus()
}

type realFile struct {
	file *os.File
}

type realProcess struct {
	process *os.Process
}

func newProcess(process *os.Process) *realProcess {
	return &realProcess{process: process}
}
func (p *realProcess) Pid() int {
	return p.process.Pid
}

type realCmd struct {
	cmd *exec.Cmd
}

func newCmd(cmd *exec.Cmd) *realCmd {
	return &realCmd{cmd: cmd}
}
func (c *realCmd) SetDir(dir string) {
	c.cmd.Dir = dir
}
func (c *realCmd) SetEnv(env []string) {
	c.cmd.Env = env
}
func (c *realCmd) StdinPipe() (io.WriteCloser, error) {
	pipe, err := c.cmd.StdinPipe()
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return pipe, nil
}
func (c *realCmd) StdoutPipe() (io.ReadCloser, error) {
	pipe, err := c.cmd.StdoutPipe()
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return pipe, nil
}
func (c *realCmd) StderrPipe() (io.ReadCloser, error) {
	pipe, err := c.cmd.StderrPipe()
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return pipe, nil
}
func (c *realCmd) SetStdin(stdin io.Reader) {
	c.cmd.Stdin = stdin
}
func (c *realCmd) SetStdout(stdout io.Writer) {
	c.cmd.Stdout = stdout
}
func (c *realCmd) SetStderr(stderr io.Writer) {
	c.cmd.Stderr = stderr
}
func (c *realCmd) ExitState() oslayer.ProcessExitState {
	return NewProcessExitState(c.cmd.ProcessState)
}
func (c *realCmd) Process() oslayer.Process {
	return newProcess(c.cmd.Process)
}
func (c *realCmd) Start() error {
	if err := c.cmd.Start(); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (c *realCmd) Wait() error {
	if err := c.cmd.Wait(); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (c *realCmd) Run() error {
	if err := c.cmd.Run(); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (c *realCmd) Output() ([]byte, error) {
	out, err := c.cmd.Output()
	if err != nil {
		return out, errors.WithStack(err)
	}
	return out, nil
}
func (c *realCmd) CombinedOutput() ([]byte, error) {
	out, err := c.cmd.CombinedOutput()
	if err != nil {
		return out, errors.WithStack(err)
	}
	return out, nil
}

type realOS struct{}

// NewOS returns an oslayer.OS implementation which calls into actual system OS
// functionality.
func NewOS() oslayer.OS {
	return &realOS{}
}

// Filesystem
func (o *realOS) OpenFile(name string, flag int, perm os.FileMode) (oslayer.File, error) {
	file, err := os.OpenFile(name, flag, perm)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return file, nil
}
func (o *realOS) Command(name string, arg ...string) oslayer.Cmd {
	return newCmd(exec.Command(name, arg...))
}
func (o *realOS) MkdirAll(path string, perm os.FileMode) error {
	if err := os.MkdirAll(path, perm); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) RemoveAll(path string) error {
	if err := os.RemoveAll(path); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) Create(name string) (oslayer.File, error) {
	file, err := os.Create(name)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return file, nil
}
func (o *realOS) ReadDir(dirname string) ([]os.FileInfo, error) {
	dirs, err := ioutil.ReadDir(dirname)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return dirs, nil
}
func (o *realOS) Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
	if err := syscall.Mount(source, target, fstype, flags, data); err != nil {
		logrus.Debugf("Mount failed: source: %s, target: %s, fstype: %s, flags: %d, data: %s", source, target, fstype, flags, data)
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) Unmount(target string, flags int) (err error) {
	if err := syscall.Unmount(target, flags); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) UnplugSCSIDisk(scsiID string) (err error) {
	f, err := os.OpenFile(filepath.Join("/sys/bus/scsi/devices", scsiID, "delete"), os.O_WRONLY, 0644)
	if err != nil {
		return errors.WithStack(err)
	}
	defer f.Close()

	if _, err := f.Write([]byte("1\n")); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) PathExists(name string) (bool, error) {
	_, err := os.Stat(name)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, errors.WithStack(err)
	}
	return true, nil
}
func (o *realOS) PathIsMounted(name string) (bool, error) {
	mountinfoFile, err := os.Open("/proc/self/mountinfo")
	if err != nil {
		return false, errors.WithStack(err)
	}
	defer mountinfoFile.Close()

	scanner := bufio.NewScanner(mountinfoFile)
	for scanner.Scan() {
		tokens := strings.Fields(scanner.Text())
		dir1 := tokens[3]
		dir2 := tokens[4]
		if name == dir1 || name == dir2 {
			return true, nil
		}
	}
	return false, nil
}
func (o *realOS) Link(oldname, newname string) error {
	if err := os.Link(oldname, newname); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) Shutdown() error {
	return syscall.Reboot(syscall.LINUX_REBOOT_CMD_POWER_OFF)
}

// Processes
func (o *realOS) Kill(pid int, sig syscall.Signal) error {
	if err := syscall.Kill(pid, sig); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
<commit_msg>Support OS with sysvinit in PathIsMounted<commit_after>// Package realos defines the actual interface into operating system
// functionality.
package realos

import (
	"bufio"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"syscall"

	"github.com/Microsoft/opengcs/service/gcs/oslayer"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

// realProcessExitState represents an oslayer.ProcessExitState which uses an
// os.ProcessState for its information.
type realProcessExitState struct {
	state *os.ProcessState
}

// NewProcessExitState returns an oslayer.ProcessExitState wrapping the given
// *os.ProcessState.
func NewProcessExitState(state *os.ProcessState) oslayer.ProcessExitState {
	return &realProcessExitState{state: state}
}
func (s *realProcessExitState) ExitCode() int {
	return s.state.Sys().(syscall.WaitStatus).ExitStatus()
}

type realFile struct {
	file *os.File
}

type realProcess struct {
	process *os.Process
}

func newProcess(process *os.Process) *realProcess {
	return &realProcess{process: process}
}
func (p *realProcess) Pid() int {
	return p.process.Pid
}

type realCmd struct {
	cmd *exec.Cmd
}

func newCmd(cmd *exec.Cmd) *realCmd {
	return &realCmd{cmd: cmd}
}
func (c *realCmd) SetDir(dir string) {
	c.cmd.Dir = dir
}
func (c *realCmd) SetEnv(env []string) {
	c.cmd.Env = env
}
func (c *realCmd) StdinPipe() (io.WriteCloser, error) {
	pipe, err := c.cmd.StdinPipe()
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return pipe, nil
}
func (c *realCmd) StdoutPipe() (io.ReadCloser, error) {
	pipe, err := c.cmd.StdoutPipe()
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return pipe, nil
}
func (c *realCmd) StderrPipe() (io.ReadCloser, error) {
	pipe, err := c.cmd.StderrPipe()
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return pipe, nil
}
func (c *realCmd) SetStdin(stdin io.Reader) {
	c.cmd.Stdin = stdin
}
func (c *realCmd) SetStdout(stdout io.Writer) {
	c.cmd.Stdout = stdout
}
func (c *realCmd) SetStderr(stderr io.Writer) {
	c.cmd.Stderr = stderr
}
func (c *realCmd) ExitState() oslayer.ProcessExitState {
	return NewProcessExitState(c.cmd.ProcessState)
}
func (c *realCmd) Process() oslayer.Process {
	return newProcess(c.cmd.Process)
}
func (c *realCmd) Start() error {
	if err := c.cmd.Start(); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (c *realCmd) Wait() error {
	if err := c.cmd.Wait(); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (c *realCmd) Run() error {
	if err := c.cmd.Run(); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (c *realCmd) Output() ([]byte, error) {
	out, err := c.cmd.Output()
	if err != nil {
		return out, errors.WithStack(err)
	}
	return out, nil
}
func (c *realCmd) CombinedOutput() ([]byte, error) {
	out, err := c.cmd.CombinedOutput()
	if err != nil {
		return out, errors.WithStack(err)
	}
	return out, nil
}

type realOS struct{}

// NewOS returns an oslayer.OS implementation which calls into actual system OS
// functionality.
func NewOS() oslayer.OS {
	return &realOS{}
}

// Filesystem
func (o *realOS) OpenFile(name string, flag int, perm os.FileMode) (oslayer.File, error) {
	file, err := os.OpenFile(name, flag, perm)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return file, nil
}
func (o *realOS) Command(name string, arg ...string) oslayer.Cmd {
	return newCmd(exec.Command(name, arg...))
}
func (o *realOS) MkdirAll(path string, perm os.FileMode) error {
	if err := os.MkdirAll(path, perm); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) RemoveAll(path string) error {
	if err := os.RemoveAll(path); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) Create(name string) (oslayer.File, error) {
	file, err := os.Create(name)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return file, nil
}
func (o *realOS) ReadDir(dirname string) ([]os.FileInfo, error) {
	dirs, err := ioutil.ReadDir(dirname)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return dirs, nil
}
func (o *realOS) Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
	if err := syscall.Mount(source, target, fstype, flags, data); err != nil {
		logrus.Debugf("Mount failed: source: %s, target: %s, fstype: %s, flags: %d, data: %s", source, target, fstype, flags, data)
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) Unmount(target string, flags int) (err error) {
	if err := syscall.Unmount(target, flags); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) UnplugSCSIDisk(scsiID string) (err error) {
	f, err := os.OpenFile(filepath.Join("/sys/bus/scsi/devices", scsiID, "delete"), os.O_WRONLY, 0644)
	if err != nil {
		return errors.WithStack(err)
	}
	defer f.Close()

	if _, err := f.Write([]byte("1\n")); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) PathExists(name string) (bool, error) {
	_, err := os.Stat(name)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, errors.WithStack(err)
	}
	return true, nil
}
func (o *realOS) PathIsMounted(name string) (bool, error) {
	mountinfoFile, err := os.Open("/proc/self/mountinfo")
	if err != nil {
		return false, errors.WithStack(err)
	}
	defer mountinfoFile.Close()

	scanner := bufio.NewScanner(mountinfoFile)
	for scanner.Scan() {
		tokens := strings.Fields(scanner.Text())
		dir1 := tokens[3]
		dir2 := tokens[4]
		if name == dir1 || name == dir2 {
			return true, nil
		}
		if ("/var/volatile" + name) == dir1 || ("/var/volatile" + name) == dir2 {
			return true, nil
		}
	}
	return false, nil
}
func (o *realOS) Link(oldname, newname string) error {
	if err := os.Link(oldname, newname); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (o *realOS) Shutdown() error {
	return syscall.Reboot(syscall.LINUX_REBOOT_CMD_POWER_OFF)
}

// Processes
func (o *realOS) Kill(pid int, sig syscall.Signal) error {
	if err := syscall.Kill(pid, sig); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
<|endoftext|>


<commit_before>package models

import (
	"fmt"
	"log"
	"os"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

var (
	database      *sqlx.DB
	SQLTimeFormat = "2006-01-02 15:04:05"
)

// Set Database handle
func SetDatabase(DB *sqlx.DB) {
	database = DB
}

func SetupDatabase(driver string, spec string) (*sqlx.DB, error) {
	var err error

	// Build Connection Pool
	if database, err = sqlx.Connect(driver, spec); err != nil {
		return nil, err
	}

	// Check we can connect
	if err = database.Ping(); err != nil {
		return nil, err
	}

	// Put some finite limits to prevent opening too many connections
	database.SetConnMaxLifetime(time.Minute * 2)
	database.SetMaxIdleConns(100)

	SetDatabase(database)
	return database, nil
}

func DumpDatabase(file string, db string) (err error) {
	f, err := os.Create(file)
	if err != nil {
		log.Panicln(err)
	}
	defer f.Close()

	f.WriteString(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s;\n\n", db))

	f.WriteString(fmt.Sprintf("USE %s;\n\n", db))

	tables, err := database.Query(`SELECT table_name
			FROM information_schema.TABLES WHERE table_schema = ?;`, db)
	if err != nil {
		log.Panicln(err)
	}
	defer tables.Close()

	for tables.Next() {
		var table, create string
		err = tables.Scan(&table)
		if err != nil {
			log.Panicln(err)
		}
		row := database.QueryRow(fmt.Sprintf(`SHOW CREATE TABLE %s.%s;`, db, table))
		err = row.Scan(&table, &create)
		if err != nil {
			log.Panicln(err)
		}
		f.WriteString(fmt.Sprintf("%s;\n\n", create))
	}

	f.WriteString(`
		DELIMITER $$
		CREATE PROCEDURE atWarWith(IN entity INT)
		BEGIN
			SELECT DISTINCT IF (aggressorID = entity, defenderID, aggressorID) AS id, timeStarted, timeFinished
				FROM evedata.wars W
				LEFT OUTER JOIN evedata.warAllies A ON A.id = W.id
				WHERE (aggressorID = entity OR defenderID = entity OR allyID = entity) AND
					(timeFinished > UTC_TIMESTAMP() OR
					timeFinished = "0001-01-01 00:00:00")
			UNION
				SELECT DISTINCT allyID AS id, timeStarted, timeFinished
				FROM evedata.wars W
				INNER JOIN evedata.warAllies A ON A.id = W.id
				WHERE (aggressorID = entity) AND
					(timeFinished > UTC_TIMESTAMP() OR
					timeFinished = "0001-01-01 00:00:00");
			END$$
			DELIMITER ;
		`)

	f.WriteString(`
			DELIMITER $$
			CREATE FUNCTION alliedMilita(factionID INT UNSIGNED) RETURNS int(11)
			DETERMINISTIC
			BEGIN
			IF factionID = 500001 THEN
				RETURN 500003;
			ELSEIF factionID = 500003 THEN
				RETURN 500001;
			ELSEIF factionID = 500002 THEN
				RETURN 500004;
			ELSEIF factionID = 500004 THEN
				RETURN 500002;
			END IF;
			RETURN 0;
			END$$
			DELIMITER ;
			`)

	f.WriteString(`
		DELIMITER $$
		CREATE FUNCTION constellationIDBySolarSystem(system INT UNSIGNED) RETURNS int(10) unsigned
			DETERMINISTIC
		BEGIN
			DECLARE constellation int(10) unsigned;
			SELECT constellationID INTO constellation
				FROM eve.mapSolarSystems
				WHERE solarSystemID = system
				LIMIT 1;

		RETURN constellation;
		END$$
		DELIMITER ;
		`)

	f.WriteString(`
		DELIMITER $$
		CREATE FUNCTION closestCelestial(s INT UNSIGNED, x1 FLOAT, y1 FLOAT, z1 FLOAT) RETURNS int(10) unsigned
			DETERMINISTIC
		BEGIN
			DECLARE celestialID int(10) unsigned;
			SELECT itemID INTO celestialID
				FROM eve.mapDenormalize
				WHERE orbitID IS NOT NULL AND solarSystemID = s
				ORDER BY POW(( x1 - x), 2) + POW(( y1 - y), 2) + POW(( z1 - z), 2)
				LIMIT 1;

		RETURN celestialID;
		END$$
		DELIMITER ;
		`)

	f.WriteString(`DELIMITER $$
		CREATE FUNCTION regionIDBySolarSystem(system INT UNSIGNED) RETURNS int(10) unsigned
			DETERMINISTIC
		BEGIN
			DECLARE region int(10) unsigned;
			SELECT regionID INTO region
				FROM eve.mapSolarSystems
				WHERE solarSystemID = system
				LIMIT 1;

		RETURN region;
		END$$
		DELIMITER ;
		`)

	f.WriteString(`DELIMITER $$
		CREATE FUNCTION regionIDByStructureID(structure BIGINT UNSIGNED) RETURNS int(10) unsigned
			DETERMINISTIC
		BEGIN
			DECLARE region int(10) unsigned;
			SELECT regionID INTO region
				FROM eve.mapSolarSystems M
				INNER JOIN evedata.structures S ON S.solarSystemID = M.solarSystemID
				WHERE stationID = structure
				LIMIT 1;

		RETURN region;
		END$$
		DELIMITER ;
		`)

	f.WriteString(`DELIMITER $$
		CREATE FUNCTION raceByID(inRaceID int UNSIGNED) RETURNS VARCHAR(20)
			DETERMINISTIC
		BEGIN
			DECLARE race VARCHAR(20) ;
			SELECT raceName INTO race
				FROM eve.chrRaces
				WHERE raceID = inRaceID
				LIMIT 1;

		RETURN race;
		END$$
		DELIMITER ;
		`)

	return err
}
<commit_msg>swap to staStations<commit_after>package models

import (
	"fmt"
	"log"
	"os"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

var (
	database      *sqlx.DB
	SQLTimeFormat = "2006-01-02 15:04:05"
)

// Set Database handle
func SetDatabase(DB *sqlx.DB) {
	database = DB
}

func SetupDatabase(driver string, spec string) (*sqlx.DB, error) {
	var err error

	// Build Connection Pool
	if database, err = sqlx.Connect(driver, spec); err != nil {
		return nil, err
	}

	// Check we can connect
	if err = database.Ping(); err != nil {
		return nil, err
	}

	// Put some finite limits to prevent opening too many connections
	database.SetConnMaxLifetime(time.Minute * 2)
	database.SetMaxIdleConns(100)

	SetDatabase(database)
	return database, nil
}

func DumpDatabase(file string, db string) (err error) {
	f, err := os.Create(file)
	if err != nil {
		log.Panicln(err)
	}
	defer f.Close()

	f.WriteString(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s;\n\n", db))

	f.WriteString(fmt.Sprintf("USE %s;\n\n", db))

	tables, err := database.Query(`SELECT table_name
			FROM information_schema.TABLES WHERE table_schema = ?;`, db)
	if err != nil {
		log.Panicln(err)
	}
	defer tables.Close()

	for tables.Next() {
		var table, create string
		err = tables.Scan(&table)
		if err != nil {
			log.Panicln(err)
		}
		row := database.QueryRow(fmt.Sprintf(`SHOW CREATE TABLE %s.%s;`, db, table))
		err = row.Scan(&table, &create)
		if err != nil {
			log.Panicln(err)
		}
		f.WriteString(fmt.Sprintf("%s;\n\n", create))
	}

	f.WriteString(`
		DELIMITER $$
		CREATE PROCEDURE atWarWith(IN entity INT)
		BEGIN
			SELECT DISTINCT IF (aggressorID = entity, defenderID, aggressorID) AS id, timeStarted, timeFinished
				FROM evedata.wars W
				LEFT OUTER JOIN evedata.warAllies A ON A.id = W.id
				WHERE (aggressorID = entity OR defenderID = entity OR allyID = entity) AND
					(timeFinished > UTC_TIMESTAMP() OR
					timeFinished = "0001-01-01 00:00:00")
			UNION
				SELECT DISTINCT allyID AS id, timeStarted, timeFinished
				FROM evedata.wars W
				INNER JOIN evedata.warAllies A ON A.id = W.id
				WHERE (aggressorID = entity) AND
					(timeFinished > UTC_TIMESTAMP() OR
					timeFinished = "0001-01-01 00:00:00");
			END$$
			DELIMITER ;
		`)

	f.WriteString(`
			DELIMITER $$
			CREATE FUNCTION alliedMilita(factionID INT UNSIGNED) RETURNS int(11)
			DETERMINISTIC
			BEGIN
			IF factionID = 500001 THEN
				RETURN 500003;
			ELSEIF factionID = 500003 THEN
				RETURN 500001;
			ELSEIF factionID = 500002 THEN
				RETURN 500004;
			ELSEIF factionID = 500004 THEN
				RETURN 500002;
			END IF;
			RETURN 0;
			END$$
			DELIMITER ;
			`)

	f.WriteString(`
		DELIMITER $$
		CREATE FUNCTION constellationIDBySolarSystem(system INT UNSIGNED) RETURNS int(10) unsigned
			DETERMINISTIC
		BEGIN
			DECLARE constellation int(10) unsigned;
			SELECT constellationID INTO constellation
				FROM eve.mapSolarSystems
				WHERE solarSystemID = system
				LIMIT 1;

		RETURN constellation;
		END$$
		DELIMITER ;
		`)

	f.WriteString(`
		DELIMITER $$
		CREATE FUNCTION closestCelestial(s INT UNSIGNED, x1 FLOAT, y1 FLOAT, z1 FLOAT) RETURNS int(10) unsigned
			DETERMINISTIC
		BEGIN
			DECLARE celestialID int(10) unsigned;
			SELECT itemID INTO celestialID
				FROM eve.mapDenormalize
				WHERE orbitID IS NOT NULL AND solarSystemID = s
				ORDER BY POW(( x1 - x), 2) + POW(( y1 - y), 2) + POW(( z1 - z), 2)
				LIMIT 1;

		RETURN celestialID;
		END$$
		DELIMITER ;
		`)

	f.WriteString(`DELIMITER $$
		CREATE FUNCTION regionIDBySolarSystem(system INT UNSIGNED) RETURNS int(10) unsigned
			DETERMINISTIC
		BEGIN
			DECLARE region int(10) unsigned;
			SELECT regionID INTO region
				FROM eve.mapSolarSystems
				WHERE solarSystemID = system
				LIMIT 1;

		RETURN region;
		END$$
		DELIMITER ;
		`)

	f.WriteString(`DELIMITER $$
		CREATE FUNCTION regionIDByStructureID(structure BIGINT UNSIGNED) RETURNS int(10) unsigned
			DETERMINISTIC
		BEGIN
			DECLARE region int(10) unsigned;
			SELECT regionID INTO region
				FROM eve.staStations
				WHERE stationID = structure
				LIMIT 1;
			IF region IS NULL THEN
				SET region = 0;
			END IF;
		RETURN region;
		END$$
		DELIMITER ;
		`)

	f.WriteString(`DELIMITER $$
		CREATE FUNCTION raceByID(inRaceID int UNSIGNED) RETURNS VARCHAR(20)
			DETERMINISTIC
		BEGIN
			DECLARE race VARCHAR(20) ;
			SELECT raceName INTO race
				FROM eve.chrRaces
				WHERE raceID = inRaceID
				LIMIT 1;

		RETURN race;
		END$$
		DELIMITER ;
		`)

	return err
}
<|endoftext|>