<commit_before>package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/gin-gonic/gin"
	"github.com/hashicorp/vault/api"
	"github.com/hashicorp/vault/helper/uuid"
	"net/http"
)

type user struct {
	Email string `form:"email" json:"email" binding:"required"`
}

type awsSec struct {
	AccessKeyID string `form:"access_key_id" json:"access_key_id" binding:"required"`
	SecretKeyID string `form:"secret_key_id" json:"secret_key_id" binding:"required"`
}

// GET /private/user endpoint
// This function returns the user object of the user
// making the request
func getUser(c *gin.Context) {
	if SwTokenInterface, exists := c.Get("SwToken"); exists {
		SwToken := SwTokenInterface.(StopwatchToken)
		c.JSON(http.StatusOK, gin.H{
			"email": SwToken.Email})
	} else {
		c.JSON(http.StatusInternalServerError, gin.H{
			"status":     "problem verifying api token",
			"suggestion": "server load might be high right now, please try later"})
	}
}

// POST /register endpoint
// the register function takes an email as the only input parameter and generates
// a UUID that it returns to the user
func register(c *gin.Context) {
	var json user

	if c.BindJSON(&json) == nil {
		redisConn := pool.Get()
		defer redisConn.Close()

		redisReply, redisError := redis.Bool(redisConn.Do("EXISTS", json.Email))
		if redisError != nil {
			fmt.Sprintf("Error reading redis data '%s'", redisError)
		}
		if redisReply == true {
			c.JSON(http.StatusConflict, gin.H{
				"status": "user already exists",
				"email":  json.Email})
			return
		}

		verificationToken := uuid.GenerateUUID()
		verificationTokenHash := generateSha256String(verificationToken)

		_, redisError = redisConn.Do("HMSET", verificationTokenHash,
			"email", json.Email,
			"tokenType", "verification")
		if redisError != nil {
			fmt.Sprintf("Error inserting redis data '%s'", redisError)
			return
		}

		_, redisError = redisConn.Do("HMSET", json.Email,
			"verified", false)
		if redisError != nil {
			fmt.Sprintf("Error inserting redis data '%s'", redisError)
			return
		}

		go sendVerificationEmail(json.Email, verificationToken)

		c.JSON(http.StatusOK, gin.H{
			"status":                    "user registered",
			"email":                     json.Email,
			"email_verification_status": "pending verification",
			"verified":                  false})
	} else {
		c.JSON(http.StatusBadRequest, gin.H{
			"status": "invalid request json"})
	}
}

// GET /verify endpoint
// This function is used for email verification
// Where the clickable link provided to the user via email
// is handled
func verifyToken(c *gin.Context) {
	var st StopwatchToken
	token := c.Param("token")
	verToken, verTokenError := verifyRegistrationToken(token, &st)
	if verTokenError == nil {
		redisConn := pool.Get()
		defer redisConn.Close()
		apiToken, tokenErr := createVaultToken(vaultclient, verToken.Email)
		if tokenErr != nil {
			fmt.Sprintf("Error creating vault token '%s'", tokenErr)
			return
		}
		apiTokenHash := generateSha256String(apiToken)

		_, redisError := redisConn.Do("HMSET", apiTokenHash,
			"email", verToken.Email,
			"tokenType", "api")
		if redisError != nil {
			fmt.Sprintf("Error inserting redis data '%s'", redisError)
			return
		}
		_, redisError = redisConn.Do("HMSET", verToken.Email,
			"verified", true)
		if redisError != nil {
			fmt.Sprintf("Error inserting redis data '%s'", redisError)
			return
		}

		go sendTokenEmail(verToken.Email, apiToken)
		c.JSON(http.StatusOK, gin.H{
			"status":           "email verified",
			"verified":         true,
			"api_token_status": fmt.Sprintf("email sent to %s", verToken.Email)})
	} else {
		c.JSON(http.StatusUnauthorized, gin.H{
			"status": "error verifying email",
			"error":  fmt.Sprintf("%s", verTokenError)})
	}
}

// POST /private/aws/secrets
func awsSecrets(c *gin.Context) {
	var json awsSec

	if c.BindJSON(&json) == nil {

		if SwTokenInterface, exists := c.Get("SwToken"); exists {
			SwToken := SwTokenInterface.(StopwatchToken)
			APIToken := GetStopwatchAPIToken(c)

			vconfig := api.DefaultConfig()
			vclient, verr := api.NewClient(vconfig)
			if verr != nil {
				fmt.Sprintf("Problem creating vault client, '%s'", verr)
			}

			vclient.SetToken(APIToken)

			// Check Vault Connection
			_, authError := vclient.Logical().Read("auth/token/lookup-self")
			if authError != nil {
				fmt.Sprintf("Something went wrong connecting to Vault! Error is '%s'", authError)
			}

			path := fmt.Sprintf("secret/%s/aws/%s", SwToken.Email, json.AccessKeyID)

			_, err := vclient.Logical().Write(path, map[string]interface{}{"secret_key": json.SecretKeyID})
			if err != nil {
				fmt.Sprintf("error writing %s: %s", path, err)
			} else {
				c.JSON(http.StatusOK, gin.H{
					"status": "secrets written"})
				fmt.Printf("wrote %s successfully", path)
			}

		} else {
			c.JSON(http.StatusInternalServerError, gin.H{
				"status":     "problem verifying api token",
				"suggestion": "server load might be high right now, please try later"})
		}

	} else {
		c.JSON(http.StatusBadRequest, gin.H{
			"status": "invalid request json"})
	}
}

// POST /private/aws/schedule
// This takes the start, end, and expiration (optional)
// times of an ec2 instance, lots of TODO here
func awsSchedule(c *gin.Context) {
}
<commit_msg>added some structs to be used for schedule creation<commit_after>package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/gin-gonic/gin"
	"github.com/hashicorp/vault/api"
	"github.com/hashicorp/vault/helper/uuid"
	"net/http"
)

type user struct {
	Email string `json:"email" binding:"required"`
}

type awsSec struct {
	AccessKeyID string `json:"access_key_id" binding:"required"`
	SecretKeyID string `json:"secret_key_id" binding:"required"`
}

type ScheduleRequest struct {
	InstanceID     string   `json:"instance_id" binding:"required"`
	StartSchedule  schedule `json:"start" binding:"required"`
	EndSchedule    schedule `json:"end"`
	ExpirationDate int      `json:"expiration"`
}

type schedule struct {
	Minute     string `json:"minute" binding:"required"`
	Hour       string `json:"hour" binding:"required"`
	DayOfMonth string `json:"day_of_month" binding:"required"`
	Month      string `json:"month" binding:"required"`
	DayOfWeek  string `json:"day_of_week" binding:"required"`
}

// GET /private/user endpoint
// This function returns the user object of the user
// making the request
func getUser(c *gin.Context) {
	if SwTokenInterface, exists := c.Get("SwToken"); exists {
		SwToken := SwTokenInterface.(StopwatchToken)
		c.JSON(http.StatusOK, gin.H{
			"email": SwToken.Email})
	} else {
		c.JSON(http.StatusInternalServerError, gin.H{
			"status":     "problem verifying api token",
			"suggestion": "server load might be high right now, please try later"})
	}
}

// POST /register endpoint
// the register function takes an email as the only input parameter and generates
// a UUID that it returns to the user
func register(c *gin.Context) {
	var json user

	if c.BindJSON(&json) == nil {
		redisConn := pool.Get()
		defer redisConn.Close()

		redisReply, redisError := redis.Bool(redisConn.Do("EXISTS", json.Email))
		if redisError != nil {
			fmt.Sprintf("Error reading redis data '%s'", redisError)
		}
		if redisReply == true {
			c.JSON(http.StatusConflict, gin.H{
				"status": "user already exists",
				"email":  json.Email})
			return
		}

		verificationToken := uuid.GenerateUUID()
		verificationTokenHash := generateSha256String(verificationToken)

		_, redisError = redisConn.Do("HMSET", verificationTokenHash,
			"email", json.Email,
			"tokenType", "verification")
		if redisError != nil {
			fmt.Sprintf("Error inserting redis data '%s'", redisError)
			return
		}

		_, redisError = redisConn.Do("HMSET", json.Email,
			"verified", false)
		if redisError != nil {
			fmt.Sprintf("Error inserting redis data '%s'", redisError)
			return
		}

		go sendVerificationEmail(json.Email, verificationToken)

		c.JSON(http.StatusOK, gin.H{
			"status":                    "user registered",
			"email":                     json.Email,
			"email_verification_status": "pending verification",
			"verified":                  false})
	} else {
		c.JSON(http.StatusBadRequest, gin.H{
			"status": "invalid request json"})
	}
}

// GET /verify endpoint
// This function is used for email verification
// Where the clickable link provided to the user via email
// is handled
func verifyToken(c *gin.Context) {
	var st StopwatchToken
	token := c.Param("token")
	verToken, verTokenError := verifyRegistrationToken(token, &st)
	if verTokenError == nil {
		redisConn := pool.Get()
		defer redisConn.Close()
		apiToken, tokenErr := createVaultToken(vaultclient, verToken.Email)
		if tokenErr != nil {
			fmt.Sprintf("Error creating vault token '%s'", tokenErr)
			return
		}
		apiTokenHash := generateSha256String(apiToken)

		_, redisError := redisConn.Do("HMSET", apiTokenHash,
			"email", verToken.Email,
			"tokenType", "api")
		if redisError != nil {
			fmt.Sprintf("Error inserting redis data '%s'", redisError)
			return
		}
		_, redisError = redisConn.Do("HMSET", verToken.Email,
			"verified", true)
		if redisError != nil {
			fmt.Sprintf("Error inserting redis data '%s'", redisError)
			return
		}

		go sendTokenEmail(verToken.Email, apiToken)
		c.JSON(http.StatusOK, gin.H{
			"status":           "email verified",
			"verified":         true,
			"api_token_status": fmt.Sprintf("email sent to %s", verToken.Email)})
	} else {
		c.JSON(http.StatusUnauthorized, gin.H{
			"status": "error verifying email",
			"error":  fmt.Sprintf("%s", verTokenError)})
	}
}

// POST /private/aws/secrets
func awsSecrets(c *gin.Context) {
	var json awsSec

	if c.BindJSON(&json) == nil {

		if SwTokenInterface, exists := c.Get("SwToken"); exists {
			SwToken := SwTokenInterface.(StopwatchToken)
			APIToken := GetStopwatchAPIToken(c)

			vconfig := api.DefaultConfig()
			vclient, verr := api.NewClient(vconfig)
			if verr != nil {
				fmt.Sprintf("Problem creating vault client, '%s'", verr)
			}

			vclient.SetToken(APIToken)

			// Check Vault Connection
			_, authError := vclient.Logical().Read("auth/token/lookup-self")
			if authError != nil {
				fmt.Sprintf("Something went wrong connecting to Vault! Error is '%s'", authError)
			}

			path := fmt.Sprintf("secret/%s/aws/%s", SwToken.Email, json.AccessKeyID)

			_, err := vclient.Logical().Write(path, map[string]interface{}{"secret_key": json.SecretKeyID})
			if err != nil {
				fmt.Sprintf("error writing %s: %s", path, err)
			} else {
				c.JSON(http.StatusOK, gin.H{
					"status": "secrets written"})
				fmt.Printf("wrote %s successfully", path)
			}

		} else {
			c.JSON(http.StatusInternalServerError, gin.H{
				"status":     "problem verifying api token",
				"suggestion": "server load might be high right now, please try later"})
		}

	} else {
		c.JSON(http.StatusBadRequest, gin.H{
			"status": "invalid request json"})
	}
}

// POST /private/aws/schedule
// This takes the start, end, and expiration (optional)
// times of an ec2 instance, lots of TODO here
func awsSchedule(c *gin.Context) {
}
<|endoftext|>


<commit_before>package workers

import (
	"bytes"
	"encoding/json"
	"log"

	"github.com/NaySoftware/go-fcm"
	nsq "github.com/bitly/go-nsq"
	"github.com/boltdb/bolt"
)

var (
	pub         *nsq.Producer
	useNSQ      = false
	useFirebase = false
	nsqPort     string
	nsqHost     string
)

// A buffered channel that we can send work requests on.
var WorkQueue = make(chan WorkRequest, 100)

func AddJob(message WorkRequest) {
	//Add message to the work queue
	WorkQueue <- message
}

func SetQueueType(queue string) {
	if queue == "nsq" {
		useNSQ = true
	} else if queue == "firebase" {
		useFirebase = true
	} else if queue == "both" {
		useNSQ = true
		useFirebase = true
	}
}

func SetupNSQ(host, port string) {
	nsqHost = host
	nsqPort = port
	config := nsq.NewConfig()
	pub, _ = nsq.NewProducer(host+":"+port, config)
}

type Topic struct {
	TopicString string `json:"topic,omitempty"`
}

type WorkRequest struct {
	//Sensor `json:"sensor"`
	Token string          `json:"token"`
	Data  json.RawMessage `json:"data"`
}

type Payload struct {
	Device *string          `json:"device"`
	Name   *string          `json:"name"`
	Data   *json.RawMessage `json:"payload"`
}

func (work *WorkRequest) PublishToFirebase() error {
	log.Println("Received firebase publish request")
	if useFirebase && work.verifyAPIKey() {
		log.Println("Publishing to Firebase")
		fcmClient := fcm.NewFcmClient(key)
		//log.Println("Data: ", string(work.Data))
		//Use a buffer to concat strings, it's much faster
		buffer := bytes.NewBuffer(make([]byte, 0, 32))
		buffer.WriteString("/topics/")
		buffer.WriteString(work.Token)
		topic := buffer.String()

		//payload := work.transformToPayload()
		data, err := json.Marshal(work.Data)
		log.Println("Payload: ", string(data))
		fcmClient.NewFcmMsgTo(topic, work.Data)
		fcmClient.SetTimeToLive(0)
		status, err := fcmClient.Send()
		if err != nil {
			status.PrintResults()
			log.Println(err)
			//status.PrintResults()
		}
		return err
	}
	return nil
}

func (work *WorkRequest) PublishToNSQ() error {
	if useNSQ {
		//err := pub.Publish(work.Topic.TopicString, []byte(work.Data))
		//return err
	}
	return nil
}

func (work *WorkRequest) transformToPayload() *Payload {
	//payload := Payload{Device: &work.Sensor.Device, Name: &work.Sensor.Name, Data: &work.Data}
	//return &payload
	return nil
}

func (work *WorkRequest) verifyAPIKey() bool {
	valid := false
	boltDB.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(apiBucket))
		data := b.Get([]byte(work.Token))
		if string(data) == "valid" {
			log.Println("Valid API Key Accepted")
			valid = true
		}
		return nil
	})
	return valid
}
<commit_msg>removed firebase conditional<commit_after>package workers

import (
	"bytes"
	"encoding/json"
	"log"

	"github.com/NaySoftware/go-fcm"
	nsq "github.com/bitly/go-nsq"
	"github.com/boltdb/bolt"
)

var (
	pub         *nsq.Producer
	useNSQ      = false
	useFirebase = false
	nsqPort     string
	nsqHost     string
)

// A buffered channel that we can send work requests on.
var WorkQueue = make(chan WorkRequest, 100)

func AddJob(message WorkRequest) {
	//Add message to the work queue
	WorkQueue <- message
}

func SetQueueType(queue string) {
	if queue == "nsq" {
		useNSQ = true
	} else if queue == "firebase" {
		useFirebase = true
	} else if queue == "both" {
		useNSQ = true
		useFirebase = true
	}
}

func SetupNSQ(host, port string) {
	nsqHost = host
	nsqPort = port
	config := nsq.NewConfig()
	pub, _ = nsq.NewProducer(host+":"+port, config)
}

type Topic struct {
	TopicString string `json:"topic,omitempty"`
}

type WorkRequest struct {
	//Sensor `json:"sensor"`
	Token string          `json:"token"`
	Data  json.RawMessage `json:"data"`
}

type Payload struct {
	Device *string          `json:"device"`
	Name   *string          `json:"name"`
	Data   *json.RawMessage `json:"payload"`
}

func (work *WorkRequest) PublishToFirebase() error {
	log.Println("Received firebase publish request")
	if work.verifyAPIKey() {
		log.Println("Publishing to Firebase")
		fcmClient := fcm.NewFcmClient(key)
		//log.Println("Data: ", string(work.Data))
		//Use a buffer to concat strings, it's much faster
		buffer := bytes.NewBuffer(make([]byte, 0, 32))
		buffer.WriteString("/topics/")
		buffer.WriteString(work.Token)
		topic := buffer.String()

		//payload := work.transformToPayload()
		data, err := json.Marshal(work.Data)
		log.Println("Payload: ", string(data))
		fcmClient.NewFcmMsgTo(topic, work.Data)
		fcmClient.SetTimeToLive(0)
		status, err := fcmClient.Send()
		if err != nil {
			status.PrintResults()
			log.Println(err)
			//status.PrintResults()
		}
		return err
	}
	return nil
}

func (work *WorkRequest) PublishToNSQ() error {
	if useNSQ {
		//err := pub.Publish(work.Topic.TopicString, []byte(work.Data))
		//return err
	}
	return nil
}

func (work *WorkRequest) transformToPayload() *Payload {
	//payload := Payload{Device: &work.Sensor.Device, Name: &work.Sensor.Name, Data: &work.Data}
	//return &payload
	return nil
}

func (work *WorkRequest) verifyAPIKey() bool {
	valid := false
	boltDB.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(apiBucket))
		data := b.Get([]byte(work.Token))
		if string(data) == "valid" {
			log.Println("Valid API Key Accepted")
			valid = true
		}
		return nil
	})
	return valid
}
<|endoftext|>


<commit_before>package droplet

import (
  digioceanauth "github.com/cloudlibz/gocloud/digioceanauth"
  "bytes"
  "fmt"
  "io/ioutil"
	"net/http"
  "encoding/json"
  "strconv"
  "errors"
)

// dropletBasePath is the endpoint URL for digitalocean API.
const dropletBasePath = "https://api.digitalocean.com/v2/droplets"

// Createnode function creates a new droplet.
func (droplet *Droplet) Createnode(request interface{}) (resp interface{}, err error) {

  var DropletInstance Droplet // Initialize Droplet struct
  DigiOceanAccessToken := digioceanauth.Token.DigiOceanAccessToken  // Fetch the DigiOceanAccessToken

  param := make(map[string]interface{})
  param = request.(map[string]interface{})

  for key, value := range param {

    switch key {

    case "Name":
      name, _ := value.(string)
      DropletInstance.Name = name

    case "Region":
      region, _ := value.(string)
      DropletInstance.Region = region

    case "Size":
      size, _ := value.(string)
      DropletInstance.Size = size

    case "Image":
    imageparam, _ := value.(map[string]interface{})
    for key, value := range imageparam {
      switch key {
        case "ID":
          id, _ := value.(int)
          DropletInstance.Image.ID = id
          break
    		case "Slug":
          slug, _ := value.(string)
          DropletInstance.Image.Slug = slug
          break
        }
      }

    case "SSHKeys":
      sshkeyparam, _ := value.([]map[string]string)
      for i := 0; i < len(sshkeyparam); i++ {
        var dropletCreateSSHKey CreateSSHKey
        dropletCreateSSHKey.ID = sshkeyparam[i]["ID"]
        dropletCreateSSHKey.Fingerprint = sshkeyparam[i]["Fingerprint"]
        DropletInstance.SSHKeys = append(DropletInstance.SSHKeys, dropletCreateSSHKey)
      }

    case "Volumes":
      volumeparam, _ := value.([]map[string]string)
      for i := 0; i < len(volumeparam); i++ {
        var dropletCreateVolume CreateVolume
        dropletCreateVolume.ID = volumeparam[i]["ID"]
        dropletCreateVolume.Name = volumeparam[i]["Name"]
        DropletInstance.Volumes = append(DropletInstance.Volumes, dropletCreateVolume)
      }

    case "Backups":
      backups, _ := value.(bool)
      DropletInstance.Backups = backups

    case "IPv6":
      ipv6, _ := value.(bool)
      DropletInstance.IPv6 = ipv6

    case "PrivateNetworking":
      privateNetworking, _ := value.(bool)
      DropletInstance.PrivateNetworking = privateNetworking

    case "Monitoring":
      monitoring, _ := value.(bool)
      DropletInstance.Monitoring = monitoring

    case "UserData":
      userData, _ := value.(string)
      DropletInstance.UserData = userData

    case "Tags":
      tags, _ := value.([]string)
      DropletInstance.Tags = tags

    } // Closes switch-case

  } // Closes for loop

  dropletInstanceJSON, _ := json.Marshal(DropletInstance)
  dropletInstanceJSONString := string(dropletInstanceJSON)
  var dropletInstanceJSONStringbyte = []byte(dropletInstanceJSONString)

  Createnodereq, err := http.NewRequest("POST", dropletBasePath, bytes.NewBuffer(dropletInstanceJSONStringbyte))
  if err != nil {
    fmt.Println(err)
  }
  Createnodereq.Header.Set("Content-Type", "application/json")
  Createnodereq.Header.Set("Authorization", "Bearer " + DigiOceanAccessToken)

	Createnoderesp, err := http.DefaultClient.Do(Createnodereq)
	if err != nil {
		fmt.Println(err)
	}

	defer Createnoderesp.Body.Close()

	responseBody, err := ioutil.ReadAll(Createnoderesp.Body)
  Createnoderesponse := make(map[string]interface{})
	Createnoderesponse["status"] = Createnoderesp.StatusCode
	Createnoderesponse["body"] = string(responseBody)
	resp = Createnoderesponse

	return resp, err

}

// Startnode function starts a droplet.
func (droplet *Droplet) Startnode(request interface{}) (resp interface{}, err error) {

	options := request.(map[string]string)
  inputID, err := strconv.Atoi(options["ID"])
  if err != nil {
    fmt.Println(err)
  }
  if inputID < 1 {
		return nil, errors.New("dropletID cannot be less than 1")
	}
	url := dropletBasePath + "/" + options["ID"] + "/actions"
	DigiOceanAccessToken := digioceanauth.Token.DigiOceanAccessToken  // Fetch the DigiOceanAccessToken

	startRequest := &ActionRequest{"type": "power_on"}
	startRequestJSON, _ := json.Marshal(startRequest)
  startRequestJSONString := string(startRequestJSON)
  var startRequestJSONStringbyte = []byte(startRequestJSONString)

	Startnodereq, err := http.NewRequest("POST", url, bytes.NewBuffer(startRequestJSONStringbyte))
	if err != nil {
		fmt.Println(err)
	}
	Startnodereq.Header.Set("Content-Type", "application/json")
	Startnodereq.Header.Set("Authorization", "Bearer " + DigiOceanAccessToken)

	Startnoderesp, err := http.DefaultClient.Do(Startnodereq)
	if err != nil {
		fmt.Println(err)
	}
	defer Startnoderesp.Body.Close()

	responseBody, err := ioutil.ReadAll(Startnoderesp.Body)
	Startnoderesponse := make(map[string]interface{})
	Startnoderesponse["body"] = string(responseBody)
	resp = Startnoderesponse

	return resp, err

}

// Stopnode function stops a droplet.
func (droplet *Droplet) Stopnode(request interface{}) (resp interface{}, err error) {

	options := request.(map[string]string)
  inputID, err := strconv.Atoi(options["ID"])
  if err != nil {
    fmt.Println(err)
  }
  if inputID < 1 {
		return nil, errors.New("dropletID cannot be less than 1")
	}
	url := dropletBasePath + "/" + options["ID"] + "/actions"
	DigiOceanAccessToken := digioceanauth.Token.DigiOceanAccessToken  // Fetch the DigiOceanAccessToken

	stopRequest := &ActionRequest{"type": "power_off"}
	stopRequestJSON, _ := json.Marshal(stopRequest)
  stopRequestJSONString := string(stopRequestJSON)
  var stopRequestJSONStringbyte = []byte(stopRequestJSONString)

	Stopnodereq, err := http.NewRequest("POST", url, bytes.NewBuffer(stopRequestJSONStringbyte))
	if err != nil {
		fmt.Println(err)
	}
	Stopnodereq.Header.Set("Content-Type", "application/json")
	Stopnodereq.Header.Set("Authorization", "Bearer " + DigiOceanAccessToken)

	Stopnoderesp, err := http.DefaultClient.Do(Stopnodereq)
	if err != nil {
		fmt.Println(err)
	}
	defer Stopnoderesp.Body.Close()

	responseBody, err := ioutil.ReadAll(Stopnoderesp.Body)
	Stopnoderesponse := make(map[string]interface{})
	Stopnoderesponse["body"] = string(responseBody)
	resp = Stopnoderesponse

	return resp, err

}

// Rebootnode function reboots a droplet.
func (droplet *Droplet) Rebootnode(request interface{}) (resp interface{}, err error) {

	options := request.(map[string]string)
  inputID, err := strconv.Atoi(options["ID"])
  if err != nil {
    fmt.Println(err)
  }
  if inputID < 1 {
		return nil, errors.New("dropletID cannot be less than 1")
	}
	url := dropletBasePath + "/" + options["ID"] + "/actions"
	DigiOceanAccessToken := digioceanauth.Token.DigiOceanAccessToken  // Fetch the DigiOceanAccessToken

	rebootRequest := &ActionRequest{"type": "reboot"}
	rebootRequestJSON, _ := json.Marshal(rebootRequest)
  rebootRequestJSONString := string(rebootRequestJSON)
  var rebootRequestJSONStringbyte = []byte(rebootRequestJSONString)

	Rebootnodereq, err := http.NewRequest("POST", url, bytes.NewBuffer(rebootRequestJSONStringbyte))
	if err != nil {
		fmt.Println(err)
	}
	Rebootnodereq.Header.Set("Content-Type", "application/json")
	Rebootnodereq.Header.Set("Authorization", "Bearer " + DigiOceanAccessToken)

	Rebootnoderesp, err := http.DefaultClient.Do(Rebootnodereq)
	if err != nil {
		fmt.Println(err)
	}
	defer Rebootnoderesp.Body.Close()

	responseBody, err := ioutil.ReadAll(Rebootnoderesp.Body)
	Rebootnoderesponse := make(map[string]interface{})
	Rebootnoderesponse["status"] = Rebootnoderesp.StatusCode
	Rebootnoderesponse["body"] = string(responseBody)
	resp = Rebootnoderesponse

	return resp, err

}

// Deletenode function deletes a droplet.
func (droplet *Droplet) Deletenode(request interface{}) (resp interface{}, err error) {

	options := request.(map[string]string)
  inputID, err := strconv.Atoi(options["ID"])
  if err != nil {
    fmt.Println(err)
  }
  if inputID < 1 {
		return nil, errors.New("dropletID cannot be less than 1")
	}

	url := dropletBasePath + "/" + options["ID"]
	DigiOceanAccessToken := digioceanauth.Token.DigiOceanAccessToken  // Fetch the DigiOceanAccessToken

	Deletenoderequest, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		fmt.Println(err)
	}
	Deletenoderequest.Header.Set("Content-Type", "application/json")
	Deletenoderequest.Header.Set("Authorization", "Bearer " + DigiOceanAccessToken)

	Deletenoderesp, err := http.DefaultClient.Do(Deletenoderequest)
	if err != nil {
		fmt.Println(err)
	}

	defer Deletenoderesp.Body.Close()

	responseBody, err := ioutil.ReadAll(Deletenoderesp.Body)
	Deletenoderesponse := make(map[string]interface{})
	Deletenoderesponse["status"] = Deletenoderesp.StatusCode
	Deletenoderesponse["body"] = string(responseBody)
	resp = Deletenoderesponse

	return resp, err
}
<commit_msg>Spacing edits<commit_after>package droplet

import (
  digioceanAuth "github.com/cloudlibz/gocloud/digioceanauth"
  "bytes"
  "fmt"
  "io/ioutil"
	"net/http"
  "encoding/json"
  "strconv"
  "errors"
)

// dropletBasePath is the endpoint URL for digitalocean API.
const dropletBasePath = "https://api.digitalocean.com/v2/droplets"

// Createnode function creates a new droplet.
func (droplet *Droplet) Createnode(request interface{}) (resp interface{}, err error) {

  var DropletInstance Droplet // Initialize Droplet struct
  DigiOceanAccessToken := digioceanAuth.Token.DigiOceanAccessToken  // Fetch the DigiOceanAccessToken

  param := make(map[string]interface{})
  param = request.(map[string]interface{})

  for key, value := range param {

    switch key {

      case "Name":
        name, _ := value.(string)
        DropletInstance.Name = name

      case "Region":
        region, _ := value.(string)
        DropletInstance.Region = region

      case "Size":
        size, _ := value.(string)
        DropletInstance.Size = size

      case "Image":
      imageparam, _ := value.(map[string]interface{})
      for key, value := range imageparam {
        switch key {
          case "ID":
            id, _ := value.(int)
            DropletInstance.Image.ID = id
            break
      		case "Slug":
            slug, _ := value.(string)
            DropletInstance.Image.Slug = slug
            break
          }
        }

      case "SSHKeys":
        sshkeyparam, _ := value.([]map[string]string)
        for i := 0; i < len(sshkeyparam); i++ {
          var dropletCreateSSHKey CreateSSHKey
          dropletCreateSSHKey.ID = sshkeyparam[i]["ID"]
          dropletCreateSSHKey.Fingerprint = sshkeyparam[i]["Fingerprint"]
          DropletInstance.SSHKeys = append(DropletInstance.SSHKeys, dropletCreateSSHKey)
        }

      case "Volumes":
        volumeparam, _ := value.([]map[string]string)
        for i := 0; i < len(volumeparam); i++ {
          var dropletCreateVolume CreateVolume
          dropletCreateVolume.ID = volumeparam[i]["ID"]
          dropletCreateVolume.Name = volumeparam[i]["Name"]
          DropletInstance.Volumes = append(DropletInstance.Volumes, dropletCreateVolume)
        }

      case "Backups":
        backups, _ := value.(bool)
        DropletInstance.Backups = backups

      case "IPv6":
        ipv6, _ := value.(bool)
        DropletInstance.IPv6 = ipv6

      case "PrivateNetworking":
        privateNetworking, _ := value.(bool)
        DropletInstance.PrivateNetworking = privateNetworking

      case "Monitoring":
        monitoring, _ := value.(bool)
        DropletInstance.Monitoring = monitoring

      case "UserData":
        userData, _ := value.(string)
        DropletInstance.UserData = userData

      case "Tags":
        tags, _ := value.([]string)
        DropletInstance.Tags = tags

    } // Closes switch-case

  } // Closes for loop

  dropletInstanceJSON, _ := json.Marshal(DropletInstance)
  dropletInstanceJSONString := string(dropletInstanceJSON)
  var dropletInstanceJSONStringbyte = []byte(dropletInstanceJSONString)

  Createnodereq, err := http.NewRequest("POST", dropletBasePath, bytes.NewBuffer(dropletInstanceJSONStringbyte))
  if err != nil {
    fmt.Println(err)
  }
  Createnodereq.Header.Set("Content-Type", "application/json")
  Createnodereq.Header.Set("Authorization", "Bearer " + DigiOceanAccessToken)

	Createnoderesp, err := http.DefaultClient.Do(Createnodereq)
	if err != nil {
		fmt.Println(err)
	}

	defer Createnoderesp.Body.Close()

	responseBody, err := ioutil.ReadAll(Createnoderesp.Body)
  Createnoderesponse := make(map[string]interface{})
	Createnoderesponse["status"] = Createnoderesp.StatusCode
	Createnoderesponse["body"] = string(responseBody)
	resp = Createnoderesponse

	return resp, err

}

// Startnode function starts a droplet.
func (droplet *Droplet) Startnode(request interface{}) (resp interface{}, err error) {

	options := request.(map[string]string)
  inputID, err := strconv.Atoi(options["ID"])
  if err != nil {
    fmt.Println(err)
  }
  if inputID < 1 {
		return nil, errors.New("dropletID cannot be less than 1")
	}
	url := dropletBasePath + "/" + options["ID"] + "/actions"
	DigiOceanAccessToken := digioceanAuth.Token.DigiOceanAccessToken  // Fetch the DigiOceanAccessToken

	startRequest := &ActionRequest{"type": "power_on"}
	startRequestJSON, _ := json.Marshal(startRequest)
  startRequestJSONString := string(startRequestJSON)
  var startRequestJSONStringbyte = []byte(startRequestJSONString)

	Startnodereq, err := http.NewRequest("POST", url, bytes.NewBuffer(startRequestJSONStringbyte))
	if err != nil {
		fmt.Println(err)
	}
	Startnodereq.Header.Set("Content-Type", "application/json")
	Startnodereq.Header.Set("Authorization", "Bearer " + DigiOceanAccessToken)

	Startnoderesp, err := http.DefaultClient.Do(Startnodereq)
	if err != nil {
		fmt.Println(err)
	}
	defer Startnoderesp.Body.Close()

	responseBody, err := ioutil.ReadAll(Startnoderesp.Body)
	Startnoderesponse := make(map[string]interface{})
	Startnoderesponse["body"] = string(responseBody)
	resp = Startnoderesponse

	return resp, err

}

// Stopnode function stops a droplet.
func (droplet *Droplet) Stopnode(request interface{}) (resp interface{}, err error) {

	options := request.(map[string]string)
  inputID, err := strconv.Atoi(options["ID"])
  if err != nil {
    fmt.Println(err)
  }
  if inputID < 1 {
		return nil, errors.New("dropletID cannot be less than 1")
	}
	url := dropletBasePath + "/" + options["ID"] + "/actions"
	DigiOceanAccessToken := digioceanAuth.Token.DigiOceanAccessToken  // Fetch the DigiOceanAccessToken

	stopRequest := &ActionRequest{"type": "power_off"}
	stopRequestJSON, _ := json.Marshal(stopRequest)
  stopRequestJSONString := string(stopRequestJSON)
  var stopRequestJSONStringbyte = []byte(stopRequestJSONString)

	Stopnodereq, err := http.NewRequest("POST", url, bytes.NewBuffer(stopRequestJSONStringbyte))
	if err != nil {
		fmt.Println(err)
	}
	Stopnodereq.Header.Set("Content-Type", "application/json")
	Stopnodereq.Header.Set("Authorization", "Bearer " + DigiOceanAccessToken)

	Stopnoderesp, err := http.DefaultClient.Do(Stopnodereq)
	if err != nil {
		fmt.Println(err)
	}
	defer Stopnoderesp.Body.Close()

	responseBody, err := ioutil.ReadAll(Stopnoderesp.Body)
	Stopnoderesponse := make(map[string]interface{})
	Stopnoderesponse["body"] = string(responseBody)
	resp = Stopnoderesponse

	return resp, err

}

// Rebootnode function reboots a droplet.
func (droplet *Droplet) Rebootnode(request interface{}) (resp interface{}, err error) {

	options := request.(map[string]string)
  inputID, err := strconv.Atoi(options["ID"])
  if err != nil {
    fmt.Println(err)
  }
  if inputID < 1 {
		return nil, errors.New("dropletID cannot be less than 1")
	}
	url := dropletBasePath + "/" + options["ID"] + "/actions"
	DigiOceanAccessToken := digioceanAuth.Token.DigiOceanAccessToken  // Fetch the DigiOceanAccessToken

	rebootRequest := &ActionRequest{"type": "reboot"}
	rebootRequestJSON, _ := json.Marshal(rebootRequest)
  rebootRequestJSONString := string(rebootRequestJSON)
  var rebootRequestJSONStringbyte = []byte(rebootRequestJSONString)

	Rebootnodereq, err := http.NewRequest("POST", url, bytes.NewBuffer(rebootRequestJSONStringbyte))
	if err != nil {
		fmt.Println(err)
	}
	Rebootnodereq.Header.Set("Content-Type", "application/json")
	Rebootnodereq.Header.Set("Authorization", "Bearer " + DigiOceanAccessToken)

	Rebootnoderesp, err := http.DefaultClient.Do(Rebootnodereq)
	if err != nil {
		fmt.Println(err)
	}
	defer Rebootnoderesp.Body.Close()

	responseBody, err := ioutil.ReadAll(Rebootnoderesp.Body)
	Rebootnoderesponse := make(map[string]interface{})
	Rebootnoderesponse["status"] = Rebootnoderesp.StatusCode
	Rebootnoderesponse["body"] = string(responseBody)
	resp = Rebootnoderesponse

	return resp, err

}

// Deletenode function deletes a droplet.
func (droplet *Droplet) Deletenode(request interface{}) (resp interface{}, err error) {

	options := request.(map[string]string)
  inputID, err := strconv.Atoi(options["ID"])
  if err != nil {
    fmt.Println(err)
  }
  if inputID < 1 {
		return nil, errors.New("dropletID cannot be less than 1")
	}

	url := dropletBasePath + "/" + options["ID"]
	DigiOceanAccessToken := digioceanAuth.Token.DigiOceanAccessToken  // Fetch the DigiOceanAccessToken

	Deletenoderequest, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		fmt.Println(err)
	}
	Deletenoderequest.Header.Set("Content-Type", "application/json")
	Deletenoderequest.Header.Set("Authorization", "Bearer " + DigiOceanAccessToken)

	Deletenoderesp, err := http.DefaultClient.Do(Deletenoderequest)
	if err != nil {
		fmt.Println(err)
	}

	defer Deletenoderesp.Body.Close()

	responseBody, err := ioutil.ReadAll(Deletenoderesp.Body)
	Deletenoderesponse := make(map[string]interface{})
	Deletenoderesponse["status"] = Deletenoderesp.StatusCode
	Deletenoderesponse["body"] = string(responseBody)
	resp = Deletenoderesponse

	return resp, err
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strconv"
	"strings"

	"image"
	"image/draw"
	"image/png"
)

type Size struct {
	X, Y int
}

type sprite struct {
	Name   string
	Offset image.Point
	Size   Size
	img    image.Image
	area   int
}

type ByArea []sprite

func (a ByArea) Len() int           { return len(a) }
func (a ByArea) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByArea) Less(i, j int) bool { return a[i].area < a[j].area }

type Node struct {
	child [2]*Node
	rect  image.Rectangle
	img   *sprite
}

func (n *Node) size() Size {
	return Size{n.rect.Dx(), n.rect.Dy()}
}

func (n *Node) print() {
	fmt.Println(n)
	if n.child[0] != nil {
		n.child[0].print()
	}
	if n.child[1] != nil {
		n.child[1].print()
	}
}

func (n *Node) isLeaf() bool {
	return n.child[0] == nil || n.child[1] == nil
}

func (n *Node) insert(img *sprite) *Node {
	if !n.isLeaf() {
		node := n.child[0].insert(img)

		if node != nil {
			return node
		} else {
			return n.child[1].insert(img)
		}
	}

	// there is already an image in this node
	if n.img != nil {
		return nil
	}

	// space too small
	if n.rect.Dx() < img.Size.X || n.rect.Dy() < img.Size.Y {
		return nil
	}

	// just right
	if n.rect.Dx() == img.Size.X && n.rect.Dy() == img.Size.Y {
		img.Offset = n.rect.Min
		n.img = img
		return n
	}

	// the space that is left will be large enough to split
	n.split(img)

	return n.child[0].insert(img)
}

func (n *Node) split(img *sprite) {
	dx := n.rect.Dx() - img.Size.X
	dy := n.rect.Dy() - img.Size.Y

	if dx > dy {
		n.child[0] = &Node{rect: image.Rect(
			n.rect.Min.X,
			n.rect.Min.Y,
			n.rect.Min.X+img.Size.X,
			n.rect.Max.Y)}
		n.child[1] = &Node{rect: image.Rect(
			n.rect.Min.X+img.Size.X,
			n.rect.Min.Y,
			n.rect.Max.X,
			n.rect.Max.Y)}
	} else {
		n.child[0] = &Node{rect: image.Rect(
			n.rect.Min.X,
			n.rect.Min.Y,
			n.rect.Max.X,
			n.rect.Min.Y+img.Size.Y)}
		n.child[1] = &Node{rect: image.Rect(
			n.rect.Min.X,
			n.rect.Min.Y+img.Size.Y,
			n.rect.Max.X,
			n.rect.Max.Y)}
	}

}

func main() {
	var space int
	var dim string

	flag.IntVar(&space, "space", 1, "space added between images")
	flag.StringVar(&dim, "dimensions", "1024x1024", "atlas size")

	flag.Parse()

	args := flag.Args()

	inputDir := args[0]
	outputName := args[1]

	dimX, dimY, err := parseDimensions(dim)
	if err != nil {
		log.Fatal(err)
	}

	files, _ := ioutil.ReadDir(inputDir)
	sprites := make([]sprite, len(files))

	totalArea := 0

	for i := range sprites {
		s, err := readSprite(inputDir, files[i].Name(), space)
		if err != nil {
			log.Fatal(err)
		}
		totalArea += s.area
		sprites[i] = s
	}

	if totalArea > dimX*dimY {
		log.Fatal("atlas to small")
	}

	// we want to place the largest sprite first
	sort.Sort(sort.Reverse(ByArea(sprites)))

	// the final image
	dst := image.NewRGBA(image.Rect(0, 0, dimX, dimY))

	n := Node{rect: image.Rect(0, 0, dimX, dimY)}

	for i := range sprites {
		s := &sprites[i]
		node := n.insert(s)
		if node != nil {
			draw.Draw(dst, node.rect, s.img, image.ZP, draw.Src)
		} else {
			log.Fatalf("could not place %s\n", s.Name)
		}

	}

	writer, err := os.Create(outputName)
	err = png.Encode(writer, dst)
	if err != nil {
		log.Fatal(err)
	}
}

func parseDimensions(dim string) (dimX, dimY int, err error) {
	dims := strings.Split(dim, "x")
	if len(dims) != 2 {
		err = fmt.Errorf("couldn't parse dimension %s\n", dims)
		return
	}

	dimX, err = strconv.Atoi(dims[0])
	if err != nil {
		return
	}

	dimY, err = strconv.Atoi(dims[1])
	if err != nil {
		return
	}

	return
}

func readSprite(dir, name string, space int) (s sprite, err error) {
	path := path.Join(dir, name)
	reader, err := os.Open(path)
	if err != nil {
		return
	}
	defer reader.Close()

	img, _, err := image.Decode(reader)
	if err != nil {
		return
	}

	s.Name = strings.TrimSuffix(name, filepath.Ext(name))
	s.img = img
	rect := img.Bounds()
	s.Size = Size{rect.Dx() + space, rect.Dy() + space}
	s.area = s.Size.X * s.Size.Y
	return
}
<commit_msg>Add error handling to the Writer and defer close<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strconv"
	"strings"

	"image"
	"image/draw"
	"image/png"
)

type Size struct {
	X, Y int
}

type sprite struct {
	Name   string
	Offset image.Point
	Size   Size
	img    image.Image
	area   int
}

type ByArea []sprite

func (a ByArea) Len() int           { return len(a) }
func (a ByArea) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByArea) Less(i, j int) bool { return a[i].area < a[j].area }

type Node struct {
	child [2]*Node
	rect  image.Rectangle
	img   *sprite
}

func (n *Node) size() Size {
	return Size{n.rect.Dx(), n.rect.Dy()}
}

func (n *Node) print() {
	fmt.Println(n)
	if n.child[0] != nil {
		n.child[0].print()
	}
	if n.child[1] != nil {
		n.child[1].print()
	}
}

func (n *Node) isLeaf() bool {
	return n.child[0] == nil || n.child[1] == nil
}

func (n *Node) insert(img *sprite) *Node {
	if !n.isLeaf() {
		node := n.child[0].insert(img)

		if node != nil {
			return node
		} else {
			return n.child[1].insert(img)
		}
	}

	// there is already an image in this node
	if n.img != nil {
		return nil
	}

	// space too small
	if n.rect.Dx() < img.Size.X || n.rect.Dy() < img.Size.Y {
		return nil
	}

	// just right
	if n.rect.Dx() == img.Size.X && n.rect.Dy() == img.Size.Y {
		img.Offset = n.rect.Min
		n.img = img
		return n
	}

	// the space that is left will be large enough to split
	n.split(img)

	return n.child[0].insert(img)
}

func (n *Node) split(img *sprite) {
	dx := n.rect.Dx() - img.Size.X
	dy := n.rect.Dy() - img.Size.Y

	if dx > dy {
		n.child[0] = &Node{rect: image.Rect(
			n.rect.Min.X,
			n.rect.Min.Y,
			n.rect.Min.X+img.Size.X,
			n.rect.Max.Y)}
		n.child[1] = &Node{rect: image.Rect(
			n.rect.Min.X+img.Size.X,
			n.rect.Min.Y,
			n.rect.Max.X,
			n.rect.Max.Y)}
	} else {
		n.child[0] = &Node{rect: image.Rect(
			n.rect.Min.X,
			n.rect.Min.Y,
			n.rect.Max.X,
			n.rect.Min.Y+img.Size.Y)}
		n.child[1] = &Node{rect: image.Rect(
			n.rect.Min.X,
			n.rect.Min.Y+img.Size.Y,
			n.rect.Max.X,
			n.rect.Max.Y)}
	}

}

func main() {
	var space int
	var dim string

	flag.IntVar(&space, "space", 1, "space added between images")
	flag.StringVar(&dim, "dimensions", "1024x1024", "atlas size")

	flag.Parse()

	args := flag.Args()

	inputDir := args[0]
	outputName := args[1]

	dimX, dimY, err := parseDimensions(dim)
	if err != nil {
		log.Fatal(err)
	}

	files, _ := ioutil.ReadDir(inputDir)
	sprites := make([]sprite, len(files))

	totalArea := 0

	for i := range sprites {
		s, err := readSprite(inputDir, files[i].Name(), space)
		if err != nil {
			log.Fatal(err)
		}
		totalArea += s.area
		sprites[i] = s
	}

	if totalArea > dimX*dimY {
		log.Fatal("atlas to small")
	}

	// we want to place the largest sprite first
	sort.Sort(sort.Reverse(ByArea(sprites)))

	// the final image
	dst := image.NewRGBA(image.Rect(0, 0, dimX, dimY))

	n := Node{rect: image.Rect(0, 0, dimX, dimY)}

	for i := range sprites {
		s := &sprites[i]
		node := n.insert(s)
		if node != nil {
			draw.Draw(dst, node.rect, s.img, image.ZP, draw.Src)
		} else {
			log.Fatalf("could not place %s\n", s.Name)
		}

	}

	writer, err := os.Create(outputName)
	if err != nil {
		log.Fatal(err)
	}
	defer writer.Close()

	err = png.Encode(writer, dst)
	if err != nil {
		log.Fatal(err)
	}
}

func parseDimensions(dim string) (dimX, dimY int, err error) {
	dims := strings.Split(dim, "x")
	if len(dims) != 2 {
		err = fmt.Errorf("couldn't parse dimension %s\n", dims)
		return
	}

	dimX, err = strconv.Atoi(dims[0])
	if err != nil {
		return
	}

	dimY, err = strconv.Atoi(dims[1])
	if err != nil {
		return
	}

	return
}

func readSprite(dir, name string, space int) (s sprite, err error) {
	path := path.Join(dir, name)
	reader, err := os.Open(path)
	if err != nil {
		return
	}
	defer reader.Close()

	img, _, err := image.Decode(reader)
	if err != nil {
		return
	}

	s.Name = strings.TrimSuffix(name, filepath.Ext(name))
	s.img = img
	rect := img.Bounds()
	s.Size = Size{rect.Dx() + space, rect.Dy() + space}
	s.area = s.Size.X * s.Size.Y
	return
}
<|endoftext|>


<commit_before>package waldo

// PairedComparison tests whether two Bernoulli samples are drawn from
// the same underlying distribution, utilizing a Wald test.  If X is the
// number of successes in the first sample (of size m) and Y the same
// value for the second sample (of size n),
// then X ~ Binomial(m, p1) and Y ~ Binomial(n,p1)
// for unkown parameter's p1 and p2.
type PairedComparison struct {
	X BernoulliSample
	Y BernoulliSample
}

// MLE estimate of the comparison estimator hat(p) := X.MLE() - Y.MLE()
func (s PairedComparison) MLE() float64 {
	return s.X.MLE() - s.Y.MLE()
}

// StandardError estimates the standard deviation of the distribution
// to which the MLE belongs.
func (s PairedComparison) Variance() float64 {
	// V(X - Y) = V(X) + V(-Y) = V(X) + (-1)^2*V(Y)
	return s.X.Variance() + s.Y.Variance()
}

// FIXME can probably delete this.
// WaldStatistic associated to the comparison sample, using a Wald
// test of size alpha.
// func (s PairedComparison) WaldStatistic(alpha float64) *Statistic {
// 	p := s.MLE()
// 	se := StandardError(s)
// 	t := Test{Alpha: alpha}
// 	return t.Statistic(p, se)
// }
<commit_msg>PairedComparison uses interfaces.<commit_after>package waldo

// PairedComparison tests whether two parameter estimates are equal.
// A typical use-case is to determine whether two Bernoulli samples
// are drawn from the same distribution.
type PairedComparison struct {
	X Sample
	Y Sample
}

// MLE estimate of the comparison estimator hat(p) := X.MLE() - Y.MLE()
func (s PairedComparison) MLE() float64 {
	return s.X.MLE() - s.Y.MLE()
}

// StandardError estimates the standard deviation of the distribution
// to which the MLE belongs.
func (s PairedComparison) Variance() float64 {
	// V(X - Y) = V(X) + V(-Y) = V(X) + (-1)^2*V(Y)
	return s.X.Variance() + s.Y.Variance()
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcd

import (
	"github.com/FactomProject/btcd/chaincfg"
	"github.com/FactomProject/btcd/wire"
)

// activeNetParams is a pointer to the parameters specific to the
// currently active bitcoin network.
var activeNetParams = &mainNetParams

// params is used to group parameters for various networks such as the main
// network and test networks.
type params struct {
	*chaincfg.Params
	rpcPort  string
	dnsSeeds []string
}

// mainNetParams contains parameters specific to the main network
// (wire.MainNet).  NOTE: The RPC port is intentionally different than the
// reference implementation because btcd does not handle wallet requests.  The
// separate wallet process listens on the well-known port and forwards requests
// it does not handle on to btcd.  This approach allows the wallet process
// to emulate the full reference implementation RPC API.
var mainNetParams = params{
	Params:  &chaincfg.MainNetParams,
	rpcPort: "8384",
	dnsSeeds: []string{
		"seed.bitcoin.sipa.be",
		"dnsseed.bluematt.me",
		"dnsseed.bitcoin.dashjr.org",
		"seed.bitcoinstats.com",
		"seed.bitnodes.io",
		"bitseed.xf2.org",
		"seeds.bitcoin.open-nodes.org",
	},
}

// regressionNetParams contains parameters specific to the regression test
// network (wire.TestNet).  NOTE: The RPC port is intentionally different
// than the reference implementation - see the mainNetParams comment for
// details.
var regressionNetParams = params{
	Params:   &chaincfg.RegressionNetParams,
	rpcPort:  "18334",
	dnsSeeds: []string{},
}

/*
// testNet3Params contains parameters specific to the test network (version 3)
// (wire.TestNet3).  NOTE: The RPC port is intentionally different than the
// reference implementation - see the mainNetParams comment for details.
var testNet3Params = params{
	Params:  &chaincfg.TestNet3Params,
	rpcPort: "18334",
	dnsSeeds: []string{
		"testnet-seed.alexykot.me",
		"testnet-seed.bitcoin.schildbach.de",
		"testnet-seed.bitcoin.petertodd.org",
		"testnet-seed.bluematt.me",
	},
}
*/

// simNetParams contains parameters specific to the simulation test network
// (wire.SimNet).
var simNetParams = params{
	Params:   &chaincfg.SimNetParams,
	rpcPort:  "18556",
	dnsSeeds: []string{}, // NOTE: There must NOT be any seeds.
}

// netName returns the name used when referring to a bitcoin network.  At the
// time of writing, btcd currently places blocks for testnet version 3 in the
// data and log directory "testnet", which does not match the Name field of the
// chaincfg parameters.  This function can be used to override this directory
// name as "testnet" when the passed active network matches wire.TestNet3.
//
// A proper upgrade to move the data and log directories for this network to
// "testnet3" is planned for the future, at which point this function can be
// removed and the network parameter's name used instead.
func netName(chainParams *params) string {
	switch chainParams.Net {
	case wire.TestNet3:
		return "testnet"
	default:
		return chainParams.Name
	}
}
<commit_msg>remove old btc nodes<commit_after>// Copyright (c) 2013-2014 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcd

import (
	"github.com/FactomProject/btcd/chaincfg"
	"github.com/FactomProject/btcd/wire"
)

// activeNetParams is a pointer to the parameters specific to the
// currently active bitcoin network.
var activeNetParams = &mainNetParams

// params is used to group parameters for various networks such as the main
// network and test networks.
type params struct {
	*chaincfg.Params
	rpcPort  string
	dnsSeeds []string
}

// mainNetParams contains parameters specific to the main network
// (wire.MainNet).  NOTE: The RPC port is intentionally different than the
// reference implementation because btcd does not handle wallet requests.  The
// separate wallet process listens on the well-known port and forwards requests
// it does not handle on to btcd.  This approach allows the wallet process
// to emulate the full reference implementation RPC API.
var mainNetParams = params{
	Params:   &chaincfg.MainNetParams,
	rpcPort:  "8384",
	dnsSeeds: []string{
	/*
		"seed.bitcoin.sipa.be",
		"dnsseed.bluematt.me",
		"dnsseed.bitcoin.dashjr.org",
		"seed.bitcoinstats.com",
		"seed.bitnodes.io",
		"bitseed.xf2.org",
		"seeds.bitcoin.open-nodes.org",
	*/
	},
}

// regressionNetParams contains parameters specific to the regression test
// network (wire.TestNet).  NOTE: The RPC port is intentionally different
// than the reference implementation - see the mainNetParams comment for
// details.
var regressionNetParams = params{
	Params:   &chaincfg.RegressionNetParams,
	rpcPort:  "18334",
	dnsSeeds: []string{},
}

/*
// testNet3Params contains parameters specific to the test network (version 3)
// (wire.TestNet3).  NOTE: The RPC port is intentionally different than the
// reference implementation - see the mainNetParams comment for details.
var testNet3Params = params{
	Params:  &chaincfg.TestNet3Params,
	rpcPort: "18334",
	dnsSeeds: []string{
		"testnet-seed.alexykot.me",
		"testnet-seed.bitcoin.schildbach.de",
		"testnet-seed.bitcoin.petertodd.org",
		"testnet-seed.bluematt.me",
	},
}
*/

// simNetParams contains parameters specific to the simulation test network
// (wire.SimNet).
var simNetParams = params{
	Params:   &chaincfg.SimNetParams,
	rpcPort:  "18556",
	dnsSeeds: []string{}, // NOTE: There must NOT be any seeds.
}

// netName returns the name used when referring to a bitcoin network.  At the
// time of writing, btcd currently places blocks for testnet version 3 in the
// data and log directory "testnet", which does not match the Name field of the
// chaincfg parameters.  This function can be used to override this directory
// name as "testnet" when the passed active network matches wire.TestNet3.
//
// A proper upgrade to move the data and log directories for this network to
// "testnet3" is planned for the future, at which point this function can be
// removed and the network parameter's name used instead.
func netName(chainParams *params) string {
	switch chainParams.Net {
	case wire.TestNet3:
		return "testnet"
	default:
		return chainParams.Name
	}
}
<|endoftext|>


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

// This file contains tests of the GobEncoder/GobDecoder support.

package gob

import (
	"bytes"
	"fmt"
	"os"
	"strings"
	"testing"
)

// Types that implement the GobEncoder/Decoder interfaces.

type ByteStruct struct {
	a byte // not an exported field
}

type StringStruct struct {
	s string // not an exported field
}

type Gobber int

type ValueGobber string // encodes with a value, decodes with a pointer.

// The relevant methods

func (g *ByteStruct) GobEncode() ([]byte, os.Error) {
	b := make([]byte, 3)
	b[0] = g.a
	b[1] = g.a + 1
	b[2] = g.a + 2
	return b, nil
}

func (g *ByteStruct) GobDecode(data []byte) os.Error {
	if g == nil {
		return os.ErrorString("NIL RECEIVER")
	}
	// Expect N sequential-valued bytes.
	if len(data) == 0 {
		return os.EOF
	}
	g.a = data[0]
	for i, c := range data {
		if c != g.a+byte(i) {
			return os.ErrorString("invalid data sequence")
		}
	}
	return nil
}

func (g *StringStruct) GobEncode() ([]byte, os.Error) {
	return []byte(g.s), nil
}

func (g *StringStruct) GobDecode(data []byte) os.Error {
	// Expect N sequential-valued bytes.
	if len(data) == 0 {
		return os.EOF
	}
	a := data[0]
	for i, c := range data {
		if c != a+byte(i) {
			return os.ErrorString("invalid data sequence")
		}
	}
	g.s = string(data)
	return nil
}

func (g *Gobber) GobEncode() ([]byte, os.Error) {
	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
}

func (g *Gobber) GobDecode(data []byte) os.Error {
	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
	return err
}

func (v ValueGobber) GobEncode() ([]byte, os.Error) {
	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
}

func (v *ValueGobber) GobDecode(data []byte) os.Error {
	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
	return err
}

// Structs that include GobEncodable fields.

type GobTest0 struct {
	X int // guarantee we have  something in common with GobTest*
	G *ByteStruct
}

type GobTest1 struct {
	X int // guarantee we have  something in common with GobTest*
	G *StringStruct
}

type GobTest2 struct {
	X int    // guarantee we have  something in common with GobTest*
	G string // not a GobEncoder - should give us errors
}

type GobTest3 struct {
	X int // guarantee we have  something in common with GobTest*
	G *Gobber
}

type GobTest4 struct {
	X int // guarantee we have  something in common with GobTest*
	V ValueGobber
}

type GobTest5 struct {
	X int // guarantee we have  something in common with GobTest*
	V *ValueGobber
}

type GobTestIgnoreEncoder struct {
	X int // guarantee we have  something in common with GobTest*
}

type GobTestValueEncDec struct {
	X int          // guarantee we have  something in common with GobTest*
	G StringStruct // not a pointer.
}

type GobTestIndirectEncDec struct {
	X int             // guarantee we have  something in common with GobTest*
	G ***StringStruct // indirections to the receiver.
}

func TestGobEncoderField(t *testing.T) {
	b := new(bytes.Buffer)
	// First a field that's a structure.
	enc := NewEncoder(b)
	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTest0)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.G.a != 'A' {
		t.Errorf("expected 'A' got %c", x.G.a)
	}
	// Now a field that's not a structure.
	b.Reset()
	gobber := Gobber(23)
	err = enc.Encode(GobTest3{17, &gobber})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	y := new(GobTest3)
	err = dec.Decode(y)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if *y.G != 23 {
		t.Errorf("expected '23 got %d", *y.G)
	}
}

// Even though the field is a value, we can still take its address
// and should be able to call the methods.
func TestGobEncoderValueField(t *testing.T) {
	b := new(bytes.Buffer)
	// First a field that's a structure.
	enc := NewEncoder(b)
	err := enc.Encode(GobTestValueEncDec{17, StringStruct{"HIJKL"}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTestValueEncDec)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.G.s != "HIJKL" {
		t.Errorf("expected `HIJKL` got %s", x.G.s)
	}
}

// GobEncode/Decode should work even if the value is
// more indirect than the receiver.
func TestGobEncoderIndirectField(t *testing.T) {
	b := new(bytes.Buffer)
	// First a field that's a structure.
	enc := NewEncoder(b)
	s := &StringStruct{"HIJKL"}
	sp := &s
	err := enc.Encode(GobTestIndirectEncDec{17, &sp})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTestIndirectEncDec)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if (***x.G).s != "HIJKL" {
		t.Errorf("expected `HIJKL` got %s", (***x.G).s)
	}
}

// As long as the fields have the same name and implement the
// interface, we can cross-connect them.  Not sure it's useful
// and may even be bad but it works and it's hard to prevent
// without exposing the contents of the object, which would
// defeat the purpose.
func TestGobEncoderFieldsOfDifferentType(t *testing.T) {
	// first, string in field to byte in field
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTest0)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.G.a != 'A' {
		t.Errorf("expected 'A' got %c", x.G.a)
	}
	// now the other direction, byte in field to string in field
	b.Reset()
	err = enc.Encode(GobTest0{17, &ByteStruct{'X'}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	y := new(GobTest1)
	err = dec.Decode(y)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if y.G.s != "XYZ" {
		t.Fatalf("expected `XYZ` got %c", y.G.s)
	}
}

// Test that we can encode a value and decode into a pointer.
func TestGobEncoderValueEncoder(t *testing.T) {
	// first, string in field to byte in field
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	err := enc.Encode(GobTest4{17, ValueGobber("hello")})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTest5)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if *x.V != "hello" {
		t.Errorf("expected `hello` got %s", x.V)
	}
}

func TestGobEncoderFieldTypeError(t *testing.T) {
	// GobEncoder to non-decoder: error
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := &GobTest2{}
	err = dec.Decode(x)
	if err == nil {
		t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
	}
	if strings.Index(err.String(), "type") < 0 {
		t.Fatal("expected type error; got", err)
	}
	// Non-encoder to GobDecoder: error
	b.Reset()
	err = enc.Encode(GobTest2{17, "ABC"})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	y := &GobTest1{}
	err = dec.Decode(y)
	if err == nil {
		t.Fatal("expected decode error for mistmatched fields (non-encoder to decoder)")
	}
	if strings.Index(err.String(), "type") < 0 {
		t.Fatal("expected type error; got", err)
	}
}

// Even though ByteStruct is a struct, it's treated as a singleton at the top level.
func TestGobEncoderStructSingleton(t *testing.T) {
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	err := enc.Encode(&ByteStruct{'A'})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(ByteStruct)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.a != 'A' {
		t.Errorf("expected 'A' got %c", x.a)
	}
}

func TestGobEncoderNonStructSingleton(t *testing.T) {
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	err := enc.Encode(Gobber(1234))
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	var x Gobber
	err = dec.Decode(&x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x != 1234 {
		t.Errorf("expected 1234 got %c", x)
	}
}

func TestGobEncoderIgnoreStructField(t *testing.T) {
	b := new(bytes.Buffer)
	// First a field that's a structure.
	enc := NewEncoder(b)
	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTestIgnoreEncoder)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.X != 17 {
		t.Errorf("expected 17 got %c", x.X)
	}
}

func TestGobEncoderIgnoreNonStructField(t *testing.T) {
	b := new(bytes.Buffer)
	// First a field that's a structure.
	enc := NewEncoder(b)
	gobber := Gobber(23)
	err := enc.Encode(GobTest3{17, &gobber})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTestIgnoreEncoder)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.X != 17 {
		t.Errorf("expected 17 got %c", x.X)
	}
}
<commit_msg>gob: test case for indirection to large field.<commit_after>// Copyright 20011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains tests of the GobEncoder/GobDecoder support.

package gob

import (
	"bytes"
	"fmt"
	"os"
	"strings"
	"testing"
)

// Types that implement the GobEncoder/Decoder interfaces.

type ByteStruct struct {
	a byte // not an exported field
}

type StringStruct struct {
	s string // not an exported field
}

type ArrayStruct struct {
	a [8192]byte // not an exported field
}

type Gobber int

type ValueGobber string // encodes with a value, decodes with a pointer.

// The relevant methods

func (g *ByteStruct) GobEncode() ([]byte, os.Error) {
	b := make([]byte, 3)
	b[0] = g.a
	b[1] = g.a + 1
	b[2] = g.a + 2
	return b, nil
}

func (g *ByteStruct) GobDecode(data []byte) os.Error {
	if g == nil {
		return os.ErrorString("NIL RECEIVER")
	}
	// Expect N sequential-valued bytes.
	if len(data) == 0 {
		return os.EOF
	}
	g.a = data[0]
	for i, c := range data {
		if c != g.a+byte(i) {
			return os.ErrorString("invalid data sequence")
		}
	}
	return nil
}

func (g *StringStruct) GobEncode() ([]byte, os.Error) {
	return []byte(g.s), nil
}

func (g *StringStruct) GobDecode(data []byte) os.Error {
	// Expect N sequential-valued bytes.
	if len(data) == 0 {
		return os.EOF
	}
	a := data[0]
	for i, c := range data {
		if c != a+byte(i) {
			return os.ErrorString("invalid data sequence")
		}
	}
	g.s = string(data)
	return nil
}

func (a *ArrayStruct) GobEncode() ([]byte, os.Error) {
	return a.a[:], nil
}

func (a *ArrayStruct) GobDecode(data []byte) os.Error {
	if len(data) != len(a.a) {
		return os.ErrorString("wrong length in array decode")
	}
	copy(a.a[:], data)
	return nil
}

func (g *Gobber) GobEncode() ([]byte, os.Error) {
	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
}

func (g *Gobber) GobDecode(data []byte) os.Error {
	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
	return err
}

func (v ValueGobber) GobEncode() ([]byte, os.Error) {
	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
}

func (v *ValueGobber) GobDecode(data []byte) os.Error {
	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
	return err
}

// Structs that include GobEncodable fields.

type GobTest0 struct {
	X int // guarantee we have  something in common with GobTest*
	G *ByteStruct
}

type GobTest1 struct {
	X int // guarantee we have  something in common with GobTest*
	G *StringStruct
}

type GobTest2 struct {
	X int    // guarantee we have  something in common with GobTest*
	G string // not a GobEncoder - should give us errors
}

type GobTest3 struct {
	X int // guarantee we have  something in common with GobTest*
	G *Gobber
}

type GobTest4 struct {
	X int // guarantee we have  something in common with GobTest*
	V ValueGobber
}

type GobTest5 struct {
	X int // guarantee we have  something in common with GobTest*
	V *ValueGobber
}

type GobTestIgnoreEncoder struct {
	X int // guarantee we have  something in common with GobTest*
}

type GobTestValueEncDec struct {
	X int          // guarantee we have  something in common with GobTest*
	G StringStruct // not a pointer.
}

type GobTestIndirectEncDec struct {
	X int             // guarantee we have  something in common with GobTest*
	G ***StringStruct // indirections to the receiver.
}

type GobTestArrayEncDec struct {
	X int         // guarantee we have  something in common with GobTest*
	A ArrayStruct // not a pointer.
}

type GobTestIndirectArrayEncDec struct {
	X int            // guarantee we have  something in common with GobTest*
	A ***ArrayStruct // indirections to a large receiver.
}

func TestGobEncoderField(t *testing.T) {
	b := new(bytes.Buffer)
	// First a field that's a structure.
	enc := NewEncoder(b)
	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTest0)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.G.a != 'A' {
		t.Errorf("expected 'A' got %c", x.G.a)
	}
	// Now a field that's not a structure.
	b.Reset()
	gobber := Gobber(23)
	err = enc.Encode(GobTest3{17, &gobber})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	y := new(GobTest3)
	err = dec.Decode(y)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if *y.G != 23 {
		t.Errorf("expected '23 got %d", *y.G)
	}
}

// Even though the field is a value, we can still take its address
// and should be able to call the methods.
func TestGobEncoderValueField(t *testing.T) {
	b := new(bytes.Buffer)
	// First a field that's a structure.
	enc := NewEncoder(b)
	err := enc.Encode(GobTestValueEncDec{17, StringStruct{"HIJKL"}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTestValueEncDec)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.G.s != "HIJKL" {
		t.Errorf("expected `HIJKL` got %s", x.G.s)
	}
}

// GobEncode/Decode should work even if the value is
// more indirect than the receiver.
func TestGobEncoderIndirectField(t *testing.T) {
	b := new(bytes.Buffer)
	// First a field that's a structure.
	enc := NewEncoder(b)
	s := &StringStruct{"HIJKL"}
	sp := &s
	err := enc.Encode(GobTestIndirectEncDec{17, &sp})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTestIndirectEncDec)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if (***x.G).s != "HIJKL" {
		t.Errorf("expected `HIJKL` got %s", (***x.G).s)
	}
}

// Test with a large field with methods.
func TestGobEncoderArrayField(t *testing.T) {
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	var a GobTestArrayEncDec
	a.X = 17
	for i := range a.A.a {
		a.A.a[i] = byte(i)
	}
	err := enc.Encode(a)
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTestArrayEncDec)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	for i, v := range x.A.a {
		if v != byte(i) {
			t.Errorf("expected %x got %x", byte(i), v)
			break
		}
	}
}

// Test an indirection to a large field with methods.
func TestGobEncoderIndirectArrayField(t *testing.T) {
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	var a GobTestIndirectArrayEncDec
	a.X = 17
	var array ArrayStruct
	ap := &array
	app := &ap
	a.A = &app
	for i := range array.a {
		array.a[i] = byte(i)
	}
	err := enc.Encode(a)
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTestIndirectArrayEncDec)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	for i, v := range (***x.A).a {
		if v != byte(i) {
			t.Errorf("expected %x got %x", byte(i), v)
			break
		}
	}
}

// As long as the fields have the same name and implement the
// interface, we can cross-connect them.  Not sure it's useful
// and may even be bad but it works and it's hard to prevent
// without exposing the contents of the object, which would
// defeat the purpose.
func TestGobEncoderFieldsOfDifferentType(t *testing.T) {
	// first, string in field to byte in field
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTest0)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.G.a != 'A' {
		t.Errorf("expected 'A' got %c", x.G.a)
	}
	// now the other direction, byte in field to string in field
	b.Reset()
	err = enc.Encode(GobTest0{17, &ByteStruct{'X'}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	y := new(GobTest1)
	err = dec.Decode(y)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if y.G.s != "XYZ" {
		t.Fatalf("expected `XYZ` got %c", y.G.s)
	}
}

// Test that we can encode a value and decode into a pointer.
func TestGobEncoderValueEncoder(t *testing.T) {
	// first, string in field to byte in field
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	err := enc.Encode(GobTest4{17, ValueGobber("hello")})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTest5)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if *x.V != "hello" {
		t.Errorf("expected `hello` got %s", x.V)
	}
}

func TestGobEncoderFieldTypeError(t *testing.T) {
	// GobEncoder to non-decoder: error
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := &GobTest2{}
	err = dec.Decode(x)
	if err == nil {
		t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
	}
	if strings.Index(err.String(), "type") < 0 {
		t.Fatal("expected type error; got", err)
	}
	// Non-encoder to GobDecoder: error
	b.Reset()
	err = enc.Encode(GobTest2{17, "ABC"})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	y := &GobTest1{}
	err = dec.Decode(y)
	if err == nil {
		t.Fatal("expected decode error for mistmatched fields (non-encoder to decoder)")
	}
	if strings.Index(err.String(), "type") < 0 {
		t.Fatal("expected type error; got", err)
	}
}

// Even though ByteStruct is a struct, it's treated as a singleton at the top level.
func TestGobEncoderStructSingleton(t *testing.T) {
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	err := enc.Encode(&ByteStruct{'A'})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(ByteStruct)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.a != 'A' {
		t.Errorf("expected 'A' got %c", x.a)
	}
}

func TestGobEncoderNonStructSingleton(t *testing.T) {
	b := new(bytes.Buffer)
	enc := NewEncoder(b)
	err := enc.Encode(Gobber(1234))
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	var x Gobber
	err = dec.Decode(&x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x != 1234 {
		t.Errorf("expected 1234 got %c", x)
	}
}

func TestGobEncoderIgnoreStructField(t *testing.T) {
	b := new(bytes.Buffer)
	// First a field that's a structure.
	enc := NewEncoder(b)
	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTestIgnoreEncoder)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.X != 17 {
		t.Errorf("expected 17 got %c", x.X)
	}
}

func TestGobEncoderIgnoreNonStructField(t *testing.T) {
	b := new(bytes.Buffer)
	// First a field that's a structure.
	enc := NewEncoder(b)
	gobber := Gobber(23)
	err := enc.Encode(GobTest3{17, &gobber})
	if err != nil {
		t.Fatal("encode error:", err)
	}
	dec := NewDecoder(b)
	x := new(GobTestIgnoreEncoder)
	err = dec.Decode(x)
	if err != nil {
		t.Fatal("decode error:", err)
	}
	if x.X != 17 {
		t.Errorf("expected 17 got %c", x.X)
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Mute Communications Ltd.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package msg

import (
	"encoding/binary"
	"encoding/hex"
	"encoding/json"
	"io"

	"github.com/mutecomm/mute/cipher"
	"github.com/mutecomm/mute/encode/base64"
	"github.com/mutecomm/mute/keyserver/hashchain"
	"github.com/mutecomm/mute/log"
	"github.com/mutecomm/mute/msg/padding"
	"github.com/mutecomm/mute/uid"
	"github.com/mutecomm/mute/uid/identity"
	"github.com/mutecomm/mute/uid/length"
	"github.com/mutecomm/mute/util/digits"
	"golang.org/x/crypto/nacl/box"
)

// lengthEncryptedHeader defines the length of an encrypted header.
// This must always be the same in all messages! 5852 + 1316 = 7168.
const lengthEncryptedHeader = 7168

// Some wiggle room which can be taken out of padding if the need arises.
const wiggleRoom = 1316

// Header status codes.
const (
	statusOK    = 0
	statusReset = 1
	statusError = 2
)

type header struct {
	Ciphersuite                 string
	RecipientPubHash            string
	RecipientTempHash           string
	SenderSessionPub            uid.KeyEntry
	SenderIdentity              string // identity of sender
	SenderIdentityPubHash       string
	SenderIdentityPub           uid.KeyEntry
	NextSenderSessionPub        *uid.KeyEntry // optional
	NextRecipientSessionPubSeen *uid.KeyEntry // only if seen
	NymAddress                  string
	MaxDelay                    uint64
	SenderSessionCount          uint64 // total number of messages sent in sessions before this SenderSessionPub was used
	SenderMessageCount          uint64 // total number of messages sent with this SenderSessionPub
	SenderUID                   string // complete UID message in JSON
	SenderLastKeychainHash      string
	Status                      uint8 // always a single digit in JSON!
	Padding                     string
}

type headerPacket struct {
	Nonce                 [24]byte // for NaCL
	LengthEncryptedHeader uint16   // the length of the encrypted header
	EncryptedHeader       []byte   // the actual encrypted header
}

func newHeader(
	sender, recipient *uid.Message,
	recipientTemp, senderSession, nextSenderSessionPub,
	nextRecipientSessionPubSeen *uid.KeyEntry,
	senderLastKeychainHash string,
	rand io.Reader,
) (*header, error) {
	if len(senderLastKeychainHash) != hashchain.EntryBase64Len {
		return nil, log.Errorf("msg: last hashchain entry '%s' does not have base64 length %d (but %d)",
			senderLastKeychainHash, hashchain.EntryBase64Len, len(senderLastKeychainHash))
	}
	h := &header{
		Ciphersuite:                 uid.DefaultCiphersuite, // at the moment we only support one ciphersuite
		RecipientPubHash:            recipient.PubHash(),
		RecipientTempHash:           recipientTemp.HASH,
		SenderIdentity:              sender.Identity(),
		SenderSessionPub:            *senderSession,
		SenderIdentityPubHash:       sender.PubHash(),
		SenderIdentityPub:           *sender.PubKey(),
		NextSenderSessionPub:        nextSenderSessionPub,
		NextRecipientSessionPubSeen: nextRecipientSessionPubSeen,
		NymAddress:                  sender.UIDContent.NYMADDRESS, // TODO: set the correct nymaddress!
		MaxDelay:                    0,                            // TODO
		SenderSessionCount:          0,                            // TODO
		SenderMessageCount:          0,                            // TODO
		SenderUID:                   string(sender.JSON()),
		SenderLastKeychainHash:      senderLastKeychainHash,
		Status:                      statusOK, // TODO
		Padding:                     "",       // is set below
	}

	// calculate padding length
	padLen := wiggleRoom
	// pad sender identity
	if len(h.SenderIdentity) > identity.MaxLen {
		return nil, log.Error("msg: sender identity is too long")
	}
	padLen += identity.MaxLen - len(h.SenderIdentity)
	// pad nextSenderSessionPub
	if nextSenderSessionPub == nil {
		padLen += length.KeyEntryECDHE25519 - length.Nil
	}
	// pad nextRecipientSessionPubSeen
	if nextRecipientSessionPubSeen == nil {
		padLen += length.KeyEntryECDHE25519 - length.Nil
	}
	// pad nym address
	if len(h.NymAddress) > length.MaxNymAddress {
		return nil, log.Error("msg: nym address is too long")
	}
	padLen += length.MaxNymAddress - len(h.NymAddress)
	// pad integers
	padLen += 20 - digits.Count(h.MaxDelay)
	padLen += 20 - digits.Count(h.SenderSessionCount)
	padLen += 20 - digits.Count(h.SenderMessageCount)
	// pad sender UIDMessage
	if len(h.SenderUID) > length.MaxUIDMessage {
		return nil, log.Error("msg: sender UIDMesssage is too long")
	}
	padLen += length.MaxUIDMessage - len(h.SenderUID)
	// generate padding
	randLen := padLen/2 + padLen%2
	pad, err := padding.Generate(randLen, cipher.RandReader)
	if err != nil {
		return nil, err
	}
	// set padding
	p := hex.EncodeToString(pad)
	if padLen%2 == 1 {
		p = p[:len(p)-1]
	}
	h.Padding = p
	return h, nil
}

func newHeaderPacket(h *header, recipientIdentityPub, senderHeaderPriv *[32]byte, rand io.Reader) (*headerPacket, error) {
	var hp headerPacket
	jsn, err := json.Marshal(h)
	if err != nil {
		return nil, err
	}
	if _, err := io.ReadFull(rand, hp.Nonce[:]); err != nil {
		return nil, log.Error(err)
	}
	hp.EncryptedHeader = box.Seal(hp.EncryptedHeader, jsn, &hp.Nonce, recipientIdentityPub, senderHeaderPriv)
	hp.LengthEncryptedHeader = uint16(len(hp.EncryptedHeader))
	if hp.LengthEncryptedHeader != lengthEncryptedHeader {
		return nil, log.Errorf("msg: encrypted header has wrong length (%d != %d)",
			hp.LengthEncryptedHeader, lengthEncryptedHeader)
	}
	return &hp, nil
}

func (hp *headerPacket) write(w io.Writer) error {
	log.Debugf("hp.Nonce: %s", base64.Encode(hp.Nonce[:]))
	if _, err := w.Write(hp.Nonce[:]); err != nil {
		return log.Error(err)
	}
	log.Debugf("hp.LengthEncryptedHeader: %d", hp.LengthEncryptedHeader)
	if err := binary.Write(w, binary.BigEndian, hp.LengthEncryptedHeader); err != nil {
		return log.Error(err)
	}
	if _, err := w.Write(hp.EncryptedHeader); err != nil {
		return log.Error(err)
	}
	return nil
}

func readHeader(
	senderHeaderPub *[32]byte,
	recipientIdentities []*uid.KeyEntry,
	r io.Reader,
) (int, *uid.KeyEntry, *header, error) {
	var hp headerPacket
	// read nonce
	if _, err := io.ReadFull(r, hp.Nonce[:]); err != nil {
		return 0, nil, nil, log.Error(err)
	}
	log.Debugf("hp.Nonce: %s", base64.Encode(hp.Nonce[:]))
	// read length of encrypted header
	if err := binary.Read(r, binary.BigEndian, &hp.LengthEncryptedHeader); err != nil {
		return 0, nil, nil, log.Error(err)
	}
	log.Debugf("hp.LengthEncryptedHeader: %d", hp.LengthEncryptedHeader)
	// read encrypted header
	hp.EncryptedHeader = make([]byte, hp.LengthEncryptedHeader)
	if _, err := io.ReadFull(r, hp.EncryptedHeader); err != nil {
		return 0, nil, nil, log.Error(err)
	}
	// try to decrypt header
	var jsn []byte
	var suc bool
	var recipientID *uid.KeyEntry
	var i int
	for idx, ke := range recipientIdentities {
		jsn, suc = box.Open(jsn, hp.EncryptedHeader, &hp.Nonce, senderHeaderPub, ke.PrivateKey32())
		if suc {
			i = idx
			recipientID = ke
			break
		}
	}
	if !suc {
		return 0, nil, nil, log.Error("msg: could not find key to decrypt header")
	}
	var h header
	if err := json.Unmarshal(jsn, &h); err != nil {
		return 0, nil, nil, err
	}
	return i, recipientID, &h, nil
}
<commit_msg>msg: rename argument<commit_after>// Copyright (c) 2015 Mute Communications Ltd.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package msg

import (
	"encoding/binary"
	"encoding/hex"
	"encoding/json"
	"io"

	"github.com/mutecomm/mute/cipher"
	"github.com/mutecomm/mute/encode/base64"
	"github.com/mutecomm/mute/keyserver/hashchain"
	"github.com/mutecomm/mute/log"
	"github.com/mutecomm/mute/msg/padding"
	"github.com/mutecomm/mute/uid"
	"github.com/mutecomm/mute/uid/identity"
	"github.com/mutecomm/mute/uid/length"
	"github.com/mutecomm/mute/util/digits"
	"golang.org/x/crypto/nacl/box"
)

// lengthEncryptedHeader defines the length of an encrypted header.
// This must always be the same in all messages! 5852 + 1316 = 7168.
const lengthEncryptedHeader = 7168

// Some wiggle room which can be taken out of padding if the need arises.
const wiggleRoom = 1316

// Header status codes.
const (
	statusOK    = 0
	statusReset = 1
	statusError = 2
)

type header struct {
	Ciphersuite                 string
	RecipientPubHash            string
	RecipientTempHash           string
	SenderSessionPub            uid.KeyEntry
	SenderIdentity              string // identity of sender
	SenderIdentityPubHash       string
	SenderIdentityPub           uid.KeyEntry
	NextSenderSessionPub        *uid.KeyEntry // optional
	NextRecipientSessionPubSeen *uid.KeyEntry // only if seen
	NymAddress                  string
	MaxDelay                    uint64
	SenderSessionCount          uint64 // total number of messages sent in sessions before this SenderSessionPub was used
	SenderMessageCount          uint64 // total number of messages sent with this SenderSessionPub
	SenderUID                   string // complete UID message in JSON
	SenderLastKeychainHash      string
	Status                      uint8 // always a single digit in JSON!
	Padding                     string
}

type headerPacket struct {
	Nonce                 [24]byte // for NaCL
	LengthEncryptedHeader uint16   // the length of the encrypted header
	EncryptedHeader       []byte   // the actual encrypted header
}

func newHeader(
	sender, recipient *uid.Message,
	recipientTemp, senderSessionPub, nextSenderSessionPub,
	nextRecipientSessionPubSeen *uid.KeyEntry,
	senderLastKeychainHash string,
	rand io.Reader,
) (*header, error) {
	if len(senderLastKeychainHash) != hashchain.EntryBase64Len {
		return nil, log.Errorf("msg: last hashchain entry '%s' does not have base64 length %d (but %d)",
			senderLastKeychainHash, hashchain.EntryBase64Len, len(senderLastKeychainHash))
	}
	h := &header{
		Ciphersuite:                 uid.DefaultCiphersuite, // at the moment we only support one ciphersuite
		RecipientPubHash:            recipient.PubHash(),
		RecipientTempHash:           recipientTemp.HASH,
		SenderIdentity:              sender.Identity(),
		SenderSessionPub:            *senderSessionPub,
		SenderIdentityPubHash:       sender.PubHash(),
		SenderIdentityPub:           *sender.PubKey(),
		NextSenderSessionPub:        nextSenderSessionPub,
		NextRecipientSessionPubSeen: nextRecipientSessionPubSeen,
		NymAddress:                  sender.UIDContent.NYMADDRESS, // TODO: set the correct nymaddress!
		MaxDelay:                    0,                            // TODO
		SenderSessionCount:          0,                            // TODO
		SenderMessageCount:          0,                            // TODO
		SenderUID:                   string(sender.JSON()),
		SenderLastKeychainHash:      senderLastKeychainHash,
		Status:                      statusOK, // TODO
		Padding:                     "",       // is set below
	}

	// calculate padding length
	padLen := wiggleRoom
	// pad sender identity
	if len(h.SenderIdentity) > identity.MaxLen {
		return nil, log.Error("msg: sender identity is too long")
	}
	padLen += identity.MaxLen - len(h.SenderIdentity)
	// pad nextSenderSessionPub
	if nextSenderSessionPub == nil {
		padLen += length.KeyEntryECDHE25519 - length.Nil
	}
	// pad nextRecipientSessionPubSeen
	if nextRecipientSessionPubSeen == nil {
		padLen += length.KeyEntryECDHE25519 - length.Nil
	}
	// pad nym address
	if len(h.NymAddress) > length.MaxNymAddress {
		return nil, log.Error("msg: nym address is too long")
	}
	padLen += length.MaxNymAddress - len(h.NymAddress)
	// pad integers
	padLen += 20 - digits.Count(h.MaxDelay)
	padLen += 20 - digits.Count(h.SenderSessionCount)
	padLen += 20 - digits.Count(h.SenderMessageCount)
	// pad sender UIDMessage
	if len(h.SenderUID) > length.MaxUIDMessage {
		return nil, log.Error("msg: sender UIDMesssage is too long")
	}
	padLen += length.MaxUIDMessage - len(h.SenderUID)
	// generate padding
	randLen := padLen/2 + padLen%2
	pad, err := padding.Generate(randLen, cipher.RandReader)
	if err != nil {
		return nil, err
	}
	// set padding
	p := hex.EncodeToString(pad)
	if padLen%2 == 1 {
		p = p[:len(p)-1]
	}
	h.Padding = p
	return h, nil
}

func newHeaderPacket(h *header, recipientIdentityPub, senderHeaderPriv *[32]byte, rand io.Reader) (*headerPacket, error) {
	var hp headerPacket
	jsn, err := json.Marshal(h)
	if err != nil {
		return nil, err
	}
	if _, err := io.ReadFull(rand, hp.Nonce[:]); err != nil {
		return nil, log.Error(err)
	}
	hp.EncryptedHeader = box.Seal(hp.EncryptedHeader, jsn, &hp.Nonce, recipientIdentityPub, senderHeaderPriv)
	hp.LengthEncryptedHeader = uint16(len(hp.EncryptedHeader))
	if hp.LengthEncryptedHeader != lengthEncryptedHeader {
		return nil, log.Errorf("msg: encrypted header has wrong length (%d != %d)",
			hp.LengthEncryptedHeader, lengthEncryptedHeader)
	}
	return &hp, nil
}

func (hp *headerPacket) write(w io.Writer) error {
	log.Debugf("hp.Nonce: %s", base64.Encode(hp.Nonce[:]))
	if _, err := w.Write(hp.Nonce[:]); err != nil {
		return log.Error(err)
	}
	log.Debugf("hp.LengthEncryptedHeader: %d", hp.LengthEncryptedHeader)
	if err := binary.Write(w, binary.BigEndian, hp.LengthEncryptedHeader); err != nil {
		return log.Error(err)
	}
	if _, err := w.Write(hp.EncryptedHeader); err != nil {
		return log.Error(err)
	}
	return nil
}

func readHeader(
	senderHeaderPub *[32]byte,
	recipientIdentities []*uid.KeyEntry,
	r io.Reader,
) (int, *uid.KeyEntry, *header, error) {
	var hp headerPacket
	// read nonce
	if _, err := io.ReadFull(r, hp.Nonce[:]); err != nil {
		return 0, nil, nil, log.Error(err)
	}
	log.Debugf("hp.Nonce: %s", base64.Encode(hp.Nonce[:]))
	// read length of encrypted header
	if err := binary.Read(r, binary.BigEndian, &hp.LengthEncryptedHeader); err != nil {
		return 0, nil, nil, log.Error(err)
	}
	log.Debugf("hp.LengthEncryptedHeader: %d", hp.LengthEncryptedHeader)
	// read encrypted header
	hp.EncryptedHeader = make([]byte, hp.LengthEncryptedHeader)
	if _, err := io.ReadFull(r, hp.EncryptedHeader); err != nil {
		return 0, nil, nil, log.Error(err)
	}
	// try to decrypt header
	var jsn []byte
	var suc bool
	var recipientID *uid.KeyEntry
	var i int
	for idx, ke := range recipientIdentities {
		jsn, suc = box.Open(jsn, hp.EncryptedHeader, &hp.Nonce, senderHeaderPub, ke.PrivateKey32())
		if suc {
			i = idx
			recipientID = ke
			break
		}
	}
	if !suc {
		return 0, nil, nil, log.Error("msg: could not find key to decrypt header")
	}
	var h header
	if err := json.Unmarshal(jsn, &h); err != nil {
		return 0, nil, nil, err
	}
	return i, recipientID, &h, nil
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"log"
	"os"
	"strings"

	docker "github.com/fsouza/go-dockerclient"
)

type Volume struct {
	container *docker.APIContainers
	path      string
}

func (v *Volume) getBareFilename() string {
	str, err := getTrueName(v.container)
	if err != nil {
		log.Fatal(err.Error())
	}

	// remove leading backslash
	str = str[1:]

	// remove the "-volumes" suffix used to identify the container
	// as a data-only container in the first place
	if strings.HasSuffix(str, "-volumes") {
		str = str[0 : len(str)-7]
	}

	// Add the volume path with backslashes replaced by minuses.
	// Accidentally, this also give double minus
	// between the container name and the path.
	str += strings.Replace(v.path, "/", "-", -1)

	return str
}

func backupVolume(cli *docker.Client, directory string, v Volume) (string, error) {
	filename := v.getBareFilename() + ".tar"
	path := "/backup/" + filename
	hostpath := directory + filename

	//cmd := "tar zcvf " + path + " " + v.path
	//log.Println(cmd)

	vols := make(map[string]struct{})
	vols["/backup/"] = struct{}{}

	binds := []string{
		directory + ":/backup/",
	}

	conf := &docker.Config{
		Cmd:         []string{"tar", "cvf", path, v.path},
		Image:       "busybox",
		VolumesFrom: v.container.ID,
		Volumes:     vols,
	}
	hostconf := &docker.HostConfig{
		Binds:       binds,
		VolumesFrom: []string{v.container.ID},
	}
	opts := docker.CreateContainerOptions{
		Config:     conf,
		HostConfig: hostconf,
	}

	cont, err := cli.CreateContainer(opts)
	if err != nil {
		return "", err
	}

	//defer cli.RemoveContainer(docker.RemoveContainerOptions{ID: cont.ID, Force: true})

	err = cli.StartContainer(cont.ID, hostconf)
	if err != nil {
		return "", err
	}

	retcode, err := cli.WaitContainer(cont.ID)
	if err != nil {
		os.Remove(hostpath)
		return "", err
	}

	if retcode != 0 {
		os.Remove(hostpath)
		str := fmt.Sprintf("Failed to create volume backup - tar return code is %d", retcode)
		return "", errors.New(str)
	}

	fileinfo, err := os.Stat(hostpath)
	if err != nil {
		return "", err
	}

	if false == fileinfo.Mode().IsRegular() {
		str := fmt.Sprintf("Failed to create volume backup - created file %s is not regular", hostpath)
		return "", errors.New(str)
	}

	return hostpath, nil
}

//func createVolumeFilename
<commit_msg>create archive with current UID<commit_after>package main

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

	docker "github.com/fsouza/go-dockerclient"
)

type Volume struct {
	container *docker.APIContainers
	path      string
}

func (v *Volume) getBareFilename() string {
	str, err := getTrueName(v.container)
	if err != nil {
		log.Fatal(err.Error())
	}

	// remove leading backslash
	str = str[1:]

	// remove the "-volumes" suffix used to identify the container
	// as a data-only container in the first place
	if strings.HasSuffix(str, "-volumes") {
		str = str[0 : len(str)-7]
	}

	// Add the volume path with backslashes replaced by minuses.
	// Accidentally, this also give double minus
	// between the container name and the path.
	str += strings.Replace(v.path, "/", "-", -1)

	return str
}

func backupVolume(cli *docker.Client, directory string, v Volume) (string, error) {
	filename := v.getBareFilename() + ".tar"
	path := "/backup/" + filename
	hostpath := directory + filename

	user := strconv.Itoa(os.Geteuid())

	//cmd := "tar zcvf " + path + " " + v.path
	//log.Println(cmd)

	vols := make(map[string]struct{})
	vols["/backup/"] = struct{}{}

	binds := []string{
		directory + ":/backup/",
	}

	conf := &docker.Config{
		Cmd:         []string{"tar", "cvf", path, v.path},
		Image:       "busybox",
		User:        user,
		VolumesFrom: v.container.ID,
		Volumes:     vols,
	}
	hostconf := &docker.HostConfig{
		Binds:       binds,
		VolumesFrom: []string{v.container.ID},
	}
	opts := docker.CreateContainerOptions{
		Config:     conf,
		HostConfig: hostconf,
	}

	cont, err := cli.CreateContainer(opts)
	if err != nil {
		return "", err
	}

	//defer cli.RemoveContainer(docker.RemoveContainerOptions{ID: cont.ID, Force: true})

	err = cli.StartContainer(cont.ID, hostconf)
	if err != nil {
		return "", err
	}

	retcode, err := cli.WaitContainer(cont.ID)
	if err != nil {
		os.Remove(hostpath)
		return "", err
	}

	if retcode != 0 {
		os.Remove(hostpath)
		str := fmt.Sprintf("Failed to create volume backup - tar return code is %d", retcode)
		return "", errors.New(str)
	}

	fileinfo, err := os.Stat(hostpath)
	if err != nil {
		return "", err
	}

	if false == fileinfo.Mode().IsRegular() {
		str := fmt.Sprintf("Failed to create volume backup - created file %s is not regular", hostpath)
		return "", errors.New(str)
	}

	return hostpath, nil
}

//func createVolumeFilename
<|endoftext|>


<commit_before>// Package plugin provides some types and functions common among plugin.
package plugin

import (
	"errors"
	"fmt"

	"github.com/miekg/dns"
	ot "github.com/opentracing/opentracing-go"
	"github.com/prometheus/client_golang/prometheus"
	"golang.org/x/net/context"
)

type (
	// Plugin is a middle layer which represents the traditional
	// idea of plugin: it chains one Handler to the next by being
	// passed the next Handler in the chain.
	Plugin func(Handler) Handler

	// Handler is like dns.Handler except ServeDNS may return an rcode
	// and/or error.
	//
	// If ServeDNS writes to the response body, it should return a status
	// code. If the status code is not one of the following:
	//
	// * SERVFAIL (dns.RcodeServerFailure)
	//
	// * REFUSED (dns.RecodeRefused)
	//
	// * FORMERR (dns.RcodeFormatError)
	//
	// * NOTIMP (dns.RcodeNotImplemented)
	//
	// CoreDNS assumes *no* reply has yet been written. All other response
	// codes signal other handlers above it that the response message is
	// already written, and that they should not write to it also.
	//
	// If ServeDNS encounters an error, it should return the error value
	// so it can be logged by designated error-handling plugin.
	//
	// If writing a response after calling another ServeDNS method, the
	// returned rcode SHOULD be used when writing the response.
	//
	// If handling errors after calling another ServeDNS method, the
	// returned error value SHOULD be logged or handled accordingly.
	//
	// Otherwise, return values should be propagated down the plugin
	// chain by returning them unchanged.
	Handler interface {
		ServeDNS(context.Context, dns.ResponseWriter, *dns.Msg) (int, error)
		Name() string
	}

	// HandlerFunc is a convenience type like dns.HandlerFunc, except
	// ServeDNS returns an rcode and an error. See Handler
	// documentation for more information.
	HandlerFunc func(context.Context, dns.ResponseWriter, *dns.Msg) (int, error)
)

// ServeDNS implements the Handler interface.
func (f HandlerFunc) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
	return f(ctx, w, r)
}

// Name implements the Handler interface.
func (f HandlerFunc) Name() string { return "handlerfunc" }

// Error returns err with 'plugin/name: ' prefixed to it.
func Error(name string, err error) error { return fmt.Errorf("%s/%s: %s", "plugin", name, err) }

// NextOrFailure calls next.ServeDNS when next is not nill, otherwise it will return, a ServerFailure
// and a nil error.
func NextOrFailure(name string, next Handler, ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { // nolint: golint
	if next != nil {
		if span := ot.SpanFromContext(ctx); span != nil {
			child := span.Tracer().StartSpan(next.Name(), ot.ChildOf(span.Context()))
			defer child.Finish()
			ctx = ot.ContextWithSpan(ctx, child)
		}
		return next.ServeDNS(ctx, w, r)
	}

	return dns.RcodeServerFailure, Error(name, errors.New("no next plugin found"))
}

// ClientWrite returns true if the response has been written to the client.
// Each plugin to adhire to this protocol.
func ClientWrite(rcode int) bool {
	switch rcode {
	case dns.RcodeServerFailure:
		fallthrough
	case dns.RcodeRefused:
		fallthrough
	case dns.RcodeFormatError:
		fallthrough
	case dns.RcodeNotImplemented:
		return false
	}
	return true
}

// Namespace is the namespace used for the metrics.
const Namespace = "coredns"

// TimeBuckets is based on Prometheus client_golang prometheus.DefBuckets
var TimeBuckets = prometheus.ExponentialBuckets(0.25, 2, 16) // from 0.25ms to 8 seconds
<commit_msg>Fix time bucketing of response time (#1274)<commit_after>// Package plugin provides some types and functions common among plugin.
package plugin

import (
	"errors"
	"fmt"

	"github.com/miekg/dns"
	ot "github.com/opentracing/opentracing-go"
	"github.com/prometheus/client_golang/prometheus"
	"golang.org/x/net/context"
)

type (
	// Plugin is a middle layer which represents the traditional
	// idea of plugin: it chains one Handler to the next by being
	// passed the next Handler in the chain.
	Plugin func(Handler) Handler

	// Handler is like dns.Handler except ServeDNS may return an rcode
	// and/or error.
	//
	// If ServeDNS writes to the response body, it should return a status
	// code. If the status code is not one of the following:
	//
	// * SERVFAIL (dns.RcodeServerFailure)
	//
	// * REFUSED (dns.RecodeRefused)
	//
	// * FORMERR (dns.RcodeFormatError)
	//
	// * NOTIMP (dns.RcodeNotImplemented)
	//
	// CoreDNS assumes *no* reply has yet been written. All other response
	// codes signal other handlers above it that the response message is
	// already written, and that they should not write to it also.
	//
	// If ServeDNS encounters an error, it should return the error value
	// so it can be logged by designated error-handling plugin.
	//
	// If writing a response after calling another ServeDNS method, the
	// returned rcode SHOULD be used when writing the response.
	//
	// If handling errors after calling another ServeDNS method, the
	// returned error value SHOULD be logged or handled accordingly.
	//
	// Otherwise, return values should be propagated down the plugin
	// chain by returning them unchanged.
	Handler interface {
		ServeDNS(context.Context, dns.ResponseWriter, *dns.Msg) (int, error)
		Name() string
	}

	// HandlerFunc is a convenience type like dns.HandlerFunc, except
	// ServeDNS returns an rcode and an error. See Handler
	// documentation for more information.
	HandlerFunc func(context.Context, dns.ResponseWriter, *dns.Msg) (int, error)
)

// ServeDNS implements the Handler interface.
func (f HandlerFunc) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
	return f(ctx, w, r)
}

// Name implements the Handler interface.
func (f HandlerFunc) Name() string { return "handlerfunc" }

// Error returns err with 'plugin/name: ' prefixed to it.
func Error(name string, err error) error { return fmt.Errorf("%s/%s: %s", "plugin", name, err) }

// NextOrFailure calls next.ServeDNS when next is not nill, otherwise it will return, a ServerFailure
// and a nil error.
func NextOrFailure(name string, next Handler, ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { // nolint: golint
	if next != nil {
		if span := ot.SpanFromContext(ctx); span != nil {
			child := span.Tracer().StartSpan(next.Name(), ot.ChildOf(span.Context()))
			defer child.Finish()
			ctx = ot.ContextWithSpan(ctx, child)
		}
		return next.ServeDNS(ctx, w, r)
	}

	return dns.RcodeServerFailure, Error(name, errors.New("no next plugin found"))
}

// ClientWrite returns true if the response has been written to the client.
// Each plugin to adhire to this protocol.
func ClientWrite(rcode int) bool {
	switch rcode {
	case dns.RcodeServerFailure:
		fallthrough
	case dns.RcodeRefused:
		fallthrough
	case dns.RcodeFormatError:
		fallthrough
	case dns.RcodeNotImplemented:
		return false
	}
	return true
}

// Namespace is the namespace used for the metrics.
const Namespace = "coredns"

// TimeBuckets is based on Prometheus client_golang prometheus.DefBuckets
var TimeBuckets = prometheus.ExponentialBuckets(0.00025, 2, 16) // from 0.25ms to 8 seconds
<|endoftext|>