<commit_before>/*
Copyright 2016 The Rook Authors. All rights reserved.

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

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

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

package object

import (
	"encoding/json"
	"strconv"
	"strings"
	"syscall"

	"github.com/pkg/errors"
	"github.com/rook/rook/pkg/util/exec"
)

const (
	RGWErrorNone = iota
	RGWErrorUnknown
	RGWErrorNotFound
	RGWErrorBadData
	RGWErrorParse
	ErrorCodeFileExists = 17
)

// An ObjectUser defines the details of an object store user.
type ObjectUser struct {
	UserID      string  `json:"userId"`
	DisplayName *string `json:"displayName"`
	Email       *string `json:"email"`
	AccessKey   *string `json:"accessKey"`
	SecretKey   *string `json:"secretKey"`
	SystemUser  bool    `json:"systemuser"`
}

// ListUsers lists the object pool users.
func ListUsers(c *Context) ([]string, int, error) {
	result, err := runAdminCommand(c, "user", "list")
	if err != nil {
		return nil, RGWErrorUnknown, errors.Wrap(err, "failed to list users")
	}

	var s []string
	if err := json.Unmarshal([]byte(result), &s); err != nil {
		return nil, RGWErrorParse, errors.Wrapf(err, "failed to read users info result=%s", result)
	}

	return s, RGWErrorNone, nil
}

type rgwUserInfo struct {
	UserID      string `json:"user_id"`
	DisplayName string `json:"display_name"`
	Email       string `json:"email"`
	Keys        []struct {
		AccessKey string `json:"access_key"`
		SecretKey string `json:"secret_key"`
	}
}

func decodeUser(data string) (*ObjectUser, int, error) {
	var user rgwUserInfo
	err := json.Unmarshal([]byte(data), &user)
	if err != nil {
		return nil, RGWErrorParse, errors.Wrapf(err, "failed to unmarshal json. %s", data)
	}

	rookUser := ObjectUser{UserID: user.UserID, DisplayName: &user.DisplayName, Email: &user.Email}

	if len(user.Keys) > 0 {
		rookUser.AccessKey = &user.Keys[0].AccessKey
		rookUser.SecretKey = &user.Keys[0].SecretKey
	} else {
		return nil, RGWErrorBadData, errors.New("AccessKey and SecretKey are missing")
	}

	return &rookUser, RGWErrorNone, nil
}

// GetUser returns the user with the given ID.
func GetUser(c *Context, id string) (*ObjectUser, int, error) {
	logger.Debugf("getting s3 user %q", id)

	// note: err is set for non-existent user but result output is also empty
	result, err := runAdminCommand(c, "user", "info", "--uid", id)
	if strings.Contains(result, "no user info saved") {
		return nil, RGWErrorNotFound, errors.New("warn: s3 user not found")
	}
	if err != nil {
		return nil, RGWErrorUnknown, errors.Wrapf(err, "radosgw-admin command err. %s", result)
	}
	return decodeUser(result)
}

// CreateUser creates a new user with the information given.
func CreateUser(c *Context, user ObjectUser) (*ObjectUser, int, error) {
	logger.Debugf("creating s3 user %q", user.UserID)

	if strings.TrimSpace(user.UserID) == "" {
		return nil, RGWErrorBadData, errors.New("userId cannot be empty")
	}

	if user.DisplayName == nil {
		return nil, RGWErrorBadData, errors.New("displayName is required")
	}

	args := []string{
		"user",
		"create",
		"--uid", user.UserID,
		"--display-name", *user.DisplayName,
	}

	if user.Email != nil {
		args = append(args, "--email", *user.Email)
	}

	if user.SystemUser {
		args = append(args, "--system")
	}

	result, err := runAdminCommand(c, args...)
	if err != nil {
		if strings.Contains(result, "could not create user: unable to create user, user: ") {
			return nil, ErrorCodeFileExists, errors.New("s3 user already exists")
		}

		if strings.Contains(result, "could not create user: unable to create user, email: ") && strings.Contains(result, " is the email address an existing user") {
			return nil, RGWErrorBadData, errors.New("email already in use")
		}

		// We don't know what happened
		return nil, RGWErrorUnknown, errors.Wrap(err, "failed to create s3 user")
	}

	return decodeUser(result)
}

// UpdateUser updates the user whose ID matches the user.
func UpdateUser(c *Context, user ObjectUser) (*ObjectUser, int, error) {
	logger.Infof("updating s3 user %q", user.UserID)

	args := []string{"user", "modify", "--uid", user.UserID}

	if user.DisplayName != nil {
		args = append(args, "--display-name", *user.DisplayName)
	}
	if user.Email != nil {
		args = append(args, "--email", *user.Email)
	}

	body, err := runAdminCommand(c, args...)
	if err != nil {
		return nil, RGWErrorUnknown, errors.Wrap(err, "failed to update s3 user")
	}

	if body == "could not modify user: unable to modify user, user not found" {
		return nil, RGWErrorNotFound, errors.New("s3 user not found")
	}

	return decodeUser(body)
}

// DeleteUser deletes the user with the given ID.
func DeleteUser(c *Context, id string, opts ...string) (string, error) {
	args := []string{"user", "rm", "--uid", id}
	if opts != nil {
		args = append(args, opts...)
	}
	result, err := runAdminCommand(c, args...)
	if err != nil {
		// If User does not exist return success
		if code, ok := exec.ExitStatus(err); ok && code == int(syscall.ENOENT) {
			return result, nil
		}
	}

	return result, errors.Wrap(err, "failed to delete s3 user")
}

// SetQuotaUserBucketMax will set maximum bucket quota for a user
func SetQuotaUserBucketMax(c *Context, id string, max int) (string, error) {
	logger.Infof("Setting user %q max buckets to %d", id, max)
	args := []string{"--quota-scope", "user", "--max-buckets", strconv.Itoa(max)}
	result, err := setUserQuota(c, id, args)
	if err != nil {
		err = errors.Wrap(err, "failed setting bucket max")
	}
	return result, err
}

func setUserQuota(c *Context, id string, args []string) (string, error) {
	args = append([]string{"quota", "set", "--uid", id}, args...)
	result, err := runAdminCommand(c, args...)
	if err != nil {
		err = errors.Wrap(err, "failed to set max buckets for user")
	}
	return result, err
}

// LinkUser will link a user to a bucket
func LinkUser(c *Context, id, bucket string) (string, int, error) {
	logger.Infof("Linking (user: %s) (bucket: %s)", id, bucket)
	args := []string{"bucket", "link", "--uid", id, "--bucket", bucket}
	result, err := runAdminCommand(c, args...)
	if err != nil {
		return "", RGWErrorUnknown, err
	}
	if strings.Contains(result, "bucket entry point user mismatch") {
		return "", RGWErrorNotFound, err
	}
	return result, RGWErrorNone, nil
}

// EnableUserQuota will allows to enable quota defined for a user
func EnableUserQuota(c *Context, id string) (string, error) {
	logger.Debug("Enabling user quota for %q", id)
	args := []string{"quota", "enable", "--quota-scope", "user", "--uid", id}
	result, err := runAdminCommand(c, args...)
	if err != nil {
		err = errors.Wrap(err, "failed to enable quota for the user")
	}
	return result, err

}

// SetQuotaUserObject allows to set maximum limit on objects for a user
func SetQuotaUserObjectMax(c *Context, id string, maxobjects string) (string, error) {
	logger.Debugf("Setting user %q max objects to %s", id, maxobjects)
	args := []string{"--quota-scope", "user", "--max-objects", maxobjects}
	result, err := setUserQuota(c, id, args)
	if err != nil {
		err = errors.Wrap(err, "failed setting object max")
	}
	return result, err
}

// SetQuotaUserMaxSize allows to set maximum size for a user
func SetQuotaUserMaxSize(c *Context, id string, maxsize string) (string, error) {
	logger.Debugf("Setting user %q max size to %s", id, maxsize)
	args := []string{"--quota-scope", "user", "--max-size", maxsize}
	result, err := setUserQuota(c, id, args)
	if err != nil {
		err = errors.Wrap(err, "failed setting max size")
	}
	return result, err
}
<commit_msg>ceph: enhance delete cephObjectStoreUser logging<commit_after>/*
Copyright 2016 The Rook Authors. All rights reserved.

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

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

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

package object

import (
	"encoding/json"
	"strconv"
	"strings"
	"syscall"

	"github.com/pkg/errors"
	"github.com/rook/rook/pkg/util/exec"
)

const (
	RGWErrorNone = iota
	RGWErrorUnknown
	RGWErrorNotFound
	RGWErrorBadData
	RGWErrorParse
	ErrorCodeFileExists = 17
)

// An ObjectUser defines the details of an object store user.
type ObjectUser struct {
	UserID      string  `json:"userId"`
	DisplayName *string `json:"displayName"`
	Email       *string `json:"email"`
	AccessKey   *string `json:"accessKey"`
	SecretKey   *string `json:"secretKey"`
	SystemUser  bool    `json:"systemuser"`
}

// ListUsers lists the object pool users.
func ListUsers(c *Context) ([]string, int, error) {
	result, err := runAdminCommand(c, "user", "list")
	if err != nil {
		return nil, RGWErrorUnknown, errors.Wrap(err, "failed to list users")
	}

	var s []string
	if err := json.Unmarshal([]byte(result), &s); err != nil {
		return nil, RGWErrorParse, errors.Wrapf(err, "failed to read users info result=%s", result)
	}

	return s, RGWErrorNone, nil
}

type rgwUserInfo struct {
	UserID      string `json:"user_id"`
	DisplayName string `json:"display_name"`
	Email       string `json:"email"`
	Keys        []struct {
		AccessKey string `json:"access_key"`
		SecretKey string `json:"secret_key"`
	}
}

func decodeUser(data string) (*ObjectUser, int, error) {
	var user rgwUserInfo
	err := json.Unmarshal([]byte(data), &user)
	if err != nil {
		return nil, RGWErrorParse, errors.Wrapf(err, "failed to unmarshal json. %s", data)
	}

	rookUser := ObjectUser{UserID: user.UserID, DisplayName: &user.DisplayName, Email: &user.Email}

	if len(user.Keys) > 0 {
		rookUser.AccessKey = &user.Keys[0].AccessKey
		rookUser.SecretKey = &user.Keys[0].SecretKey
	} else {
		return nil, RGWErrorBadData, errors.New("AccessKey and SecretKey are missing")
	}

	return &rookUser, RGWErrorNone, nil
}

// GetUser returns the user with the given ID.
func GetUser(c *Context, id string) (*ObjectUser, int, error) {
	logger.Debugf("getting s3 user %q", id)

	// note: err is set for non-existent user but result output is also empty
	result, err := runAdminCommand(c, "user", "info", "--uid", id)
	if strings.Contains(result, "no user info saved") {
		return nil, RGWErrorNotFound, errors.New("warn: s3 user not found")
	}
	if err != nil {
		return nil, RGWErrorUnknown, errors.Wrapf(err, "radosgw-admin command err. %s", result)
	}
	return decodeUser(result)
}

// CreateUser creates a new user with the information given.
func CreateUser(c *Context, user ObjectUser) (*ObjectUser, int, error) {
	logger.Debugf("creating s3 user %q", user.UserID)

	if strings.TrimSpace(user.UserID) == "" {
		return nil, RGWErrorBadData, errors.New("userId cannot be empty")
	}

	if user.DisplayName == nil {
		return nil, RGWErrorBadData, errors.New("displayName is required")
	}

	args := []string{
		"user",
		"create",
		"--uid", user.UserID,
		"--display-name", *user.DisplayName,
	}

	if user.Email != nil {
		args = append(args, "--email", *user.Email)
	}

	if user.SystemUser {
		args = append(args, "--system")
	}

	result, err := runAdminCommand(c, args...)
	if err != nil {
		if strings.Contains(result, "could not create user: unable to create user, user: ") {
			return nil, ErrorCodeFileExists, errors.New("s3 user already exists")
		}

		if strings.Contains(result, "could not create user: unable to create user, email: ") && strings.Contains(result, " is the email address an existing user") {
			return nil, RGWErrorBadData, errors.New("email already in use")
		}

		// We don't know what happened
		return nil, RGWErrorUnknown, errors.Wrap(err, "failed to create s3 user")
	}

	return decodeUser(result)
}

// UpdateUser updates the user whose ID matches the user.
func UpdateUser(c *Context, user ObjectUser) (*ObjectUser, int, error) {
	logger.Infof("updating s3 user %q", user.UserID)

	args := []string{"user", "modify", "--uid", user.UserID}

	if user.DisplayName != nil {
		args = append(args, "--display-name", *user.DisplayName)
	}
	if user.Email != nil {
		args = append(args, "--email", *user.Email)
	}

	body, err := runAdminCommand(c, args...)
	if err != nil {
		return nil, RGWErrorUnknown, errors.Wrap(err, "failed to update s3 user")
	}

	if body == "could not modify user: unable to modify user, user not found" {
		return nil, RGWErrorNotFound, errors.New("s3 user not found")
	}

	return decodeUser(body)
}

func ListUserBuckets(c *Context, id string, opts ...string) (string, error) {

	args := []string{"bucket", "list", "--uid", id}
	if opts != nil {
		args = append(args, opts...)
	}

	result, err := runAdminCommand(c, args...)

	return result, errors.Wrapf(err, "failed to list buckets for user uid=%q", id)
}

// DeleteUser deletes the user with the given ID.
func DeleteUser(c *Context, id string, opts ...string) (string, error) {
	args := []string{"user", "rm", "--uid", id}
	if opts != nil {
		args = append(args, opts...)
	}
	result, err := runAdminCommand(c, args...)
	if err != nil {
		// If User does not exist return success
		if code, ok := exec.ExitStatus(err); ok && code == int(syscall.ENOENT) {
			return result, nil
		}

		res, innerErr := ListUserBuckets(c, id)
		if innerErr == nil && res != "" && res != "[]" {
			return result, errors.Wrapf(err, "s3 user uid=%q have following buckets %q", id, res)
		}
	}

	return result, errors.Wrapf(err, "failed to delete s3 user uid=%q", id)
}

// SetQuotaUserBucketMax will set maximum bucket quota for a user
func SetQuotaUserBucketMax(c *Context, id string, max int) (string, error) {
	logger.Infof("Setting user %q max buckets to %d", id, max)
	args := []string{"--quota-scope", "user", "--max-buckets", strconv.Itoa(max)}
	result, err := setUserQuota(c, id, args)
	if err != nil {
		err = errors.Wrap(err, "failed setting bucket max")
	}
	return result, err
}

func setUserQuota(c *Context, id string, args []string) (string, error) {
	args = append([]string{"quota", "set", "--uid", id}, args...)
	result, err := runAdminCommand(c, args...)
	if err != nil {
		err = errors.Wrap(err, "failed to set max buckets for user")
	}
	return result, err
}

// LinkUser will link a user to a bucket
func LinkUser(c *Context, id, bucket string) (string, int, error) {
	logger.Infof("Linking (user: %s) (bucket: %s)", id, bucket)
	args := []string{"bucket", "link", "--uid", id, "--bucket", bucket}
	result, err := runAdminCommand(c, args...)
	if err != nil {
		return "", RGWErrorUnknown, err
	}
	if strings.Contains(result, "bucket entry point user mismatch") {
		return "", RGWErrorNotFound, err
	}
	return result, RGWErrorNone, nil
}

// EnableUserQuota will allows to enable quota defined for a user
func EnableUserQuota(c *Context, id string) (string, error) {
	logger.Debug("Enabling user quota for %q", id)
	args := []string{"quota", "enable", "--quota-scope", "user", "--uid", id}
	result, err := runAdminCommand(c, args...)
	if err != nil {
		err = errors.Wrap(err, "failed to enable quota for the user")
	}
	return result, err

}

// SetQuotaUserObject allows to set maximum limit on objects for a user
func SetQuotaUserObjectMax(c *Context, id string, maxobjects string) (string, error) {
	logger.Debugf("Setting user %q max objects to %s", id, maxobjects)
	args := []string{"--quota-scope", "user", "--max-objects", maxobjects}
	result, err := setUserQuota(c, id, args)
	if err != nil {
		err = errors.Wrap(err, "failed setting object max")
	}
	return result, err
}

// SetQuotaUserMaxSize allows to set maximum size for a user
func SetQuotaUserMaxSize(c *Context, id string, maxsize string) (string, error) {
	logger.Debugf("Setting user %q max size to %s", id, maxsize)
	args := []string{"--quota-scope", "user", "--max-size", maxsize}
	result, err := setUserQuota(c, id, args)
	if err != nil {
		err = errors.Wrap(err, "failed setting max size")
	}
	return result, err
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/transfer"

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

func resourceAwsTransferServer() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsTransferServerCreate,
		Read:   resourceAwsTransferServerRead,
		Update: resourceAwsTransferServerUpdate,
		Delete: resourceAwsTransferServerDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},

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

			"invocation_role": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateArn,
			},

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

			"identity_provider_type": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Default:  transfer.IdentityProviderTypeServiceManaged,
				ValidateFunc: validation.StringInSlice([]string{
					transfer.IdentityProviderTypeServiceManaged,
					transfer.IdentityProviderTypeApiGateway,
				}, false),
			},

			"logging_role": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateArn,
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceAwsTransferServerCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn
	tags := tagsFromMapTransferServer(d.Get("tags").(map[string]interface{}))

	createOpts := &transfer.CreateServerInput{
		Tags: tags,
	}

	identityProviderDetails := &transfer.IdentityProviderDetails{}
	if attr, ok := d.GetOk("invocation_role"); ok {
		identityProviderDetails.InvocationRole = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("url"); ok {
		identityProviderDetails.Url = aws.String(attr.(string))
	}

	if identityProviderDetails.Url != nil || identityProviderDetails.InvocationRole != nil {
		createOpts.IdentityProviderDetails = identityProviderDetails
	}

	if attr, ok := d.GetOk("identity_provider_type"); ok {
		createOpts.IdentityProviderType = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("logging_role"); ok {
		createOpts.LoggingRole = aws.String(attr.(string))
	}

	log.Printf("[DEBUG] Create Transfer Server Option: %#v", createOpts)

	resp, err := conn.CreateServer(createOpts)
	if err != nil {
		return fmt.Errorf("Error creating Transfer Server: %s", err)
	}

	d.SetId(*resp.ServerId)

	return resourceAwsTransferServerRead(d, meta)
}

func resourceAwsTransferServerRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn

	descOpts := &transfer.DescribeServerInput{
		ServerId: aws.String(d.Id()),
	}

	log.Printf("[DEBUG] Describe Transfer Server Option: %#v", descOpts)

	resp, err := conn.DescribeServer(descOpts)
	if err != nil {
		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			log.Printf("[WARN] Transfer Server (%s) not found, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return err
	}

	endpoint := fmt.Sprintf("%s.server.transfer.%s.amazonaws.com", d.Id(), meta.(*AWSClient).region)

	d.Set("arn", resp.Server.Arn)
	d.Set("endpoint", endpoint)
	d.Set("invocation_role", "")
	d.Set("url", "")
	if resp.Server.IdentityProviderDetails != nil {
		d.Set("invocation_role", aws.StringValue(resp.Server.IdentityProviderDetails.InvocationRole))
		d.Set("url", aws.StringValue(resp.Server.IdentityProviderDetails.Url))
	}
	d.Set("identity_provider_type", resp.Server.IdentityProviderType)
	d.Set("logging_role", resp.Server.LoggingRole)

	if err := d.Set("tags", tagsToMapTransferServer(resp.Server.Tags)); err != nil {
		return fmt.Errorf("Error setting tags: %s", err)
	}
	return nil
}

func resourceAwsTransferServerUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn
	updateFlag := false
	updateOpts := &transfer.UpdateServerInput{
		ServerId: aws.String(d.Id()),
	}

	if d.HasChange("logging_role") {
		updateFlag = true
		updateOpts.LoggingRole = aws.String(d.Get("logging_role").(string))
	}

	if d.HasChange("invocation_role") || d.HasChange("url") {
		identityProviderDetails := &transfer.IdentityProviderDetails{}
		updateFlag = true
		if attr, ok := d.GetOk("invocation_role"); ok {
			identityProviderDetails.InvocationRole = aws.String(attr.(string))
		}

		if attr, ok := d.GetOk("url"); ok {
			identityProviderDetails.Url = aws.String(attr.(string))
		}
		updateOpts.IdentityProviderDetails = identityProviderDetails
	}

	if updateFlag {
		_, err := conn.UpdateServer(updateOpts)
		if err != nil {
			if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
				log.Printf("[WARN] Transfer Server (%s) not found, removing from state", d.Id())
				d.SetId("")
				return nil
			}
			return fmt.Errorf("error updating Transfer Server (%s): %s", d.Id(), err)
		}
	}

	if err := setTagsTransferServer(conn, d); err != nil {
		return fmt.Errorf("Error update tags: %s", err)
	}

	return resourceAwsTransferServerRead(d, meta)
}

func resourceAwsTransferServerDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn

	delOpts := &transfer.DeleteServerInput{
		ServerId: aws.String(d.Id()),
	}

	log.Printf("[DEBUG] Delete Transfer Server Option: %#v", delOpts)

	_, err := conn.DeleteServer(delOpts)
	if err != nil {
		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			return nil
		}
		return fmt.Errorf("error deleting Transfer Server (%s): %s", d.Id(), err)
	}

	return nil
}
<commit_msg>Add wait deletion function<commit_after>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/transfer"

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

func resourceAwsTransferServer() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsTransferServerCreate,
		Read:   resourceAwsTransferServerRead,
		Update: resourceAwsTransferServerUpdate,
		Delete: resourceAwsTransferServerDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},

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

			"invocation_role": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateArn,
			},

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

			"identity_provider_type": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Default:  transfer.IdentityProviderTypeServiceManaged,
				ValidateFunc: validation.StringInSlice([]string{
					transfer.IdentityProviderTypeServiceManaged,
					transfer.IdentityProviderTypeApiGateway,
				}, false),
			},

			"logging_role": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateArn,
			},

			"tags": tagsSchema(),
		},
	}
}

func resourceAwsTransferServerCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn
	tags := tagsFromMapTransferServer(d.Get("tags").(map[string]interface{}))

	createOpts := &transfer.CreateServerInput{
		Tags: tags,
	}

	identityProviderDetails := &transfer.IdentityProviderDetails{}
	if attr, ok := d.GetOk("invocation_role"); ok {
		identityProviderDetails.InvocationRole = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("url"); ok {
		identityProviderDetails.Url = aws.String(attr.(string))
	}

	if identityProviderDetails.Url != nil || identityProviderDetails.InvocationRole != nil {
		createOpts.IdentityProviderDetails = identityProviderDetails
	}

	if attr, ok := d.GetOk("identity_provider_type"); ok {
		createOpts.IdentityProviderType = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("logging_role"); ok {
		createOpts.LoggingRole = aws.String(attr.(string))
	}

	log.Printf("[DEBUG] Create Transfer Server Option: %#v", createOpts)

	resp, err := conn.CreateServer(createOpts)
	if err != nil {
		return fmt.Errorf("Error creating Transfer Server: %s", err)
	}

	d.SetId(*resp.ServerId)

	return resourceAwsTransferServerRead(d, meta)
}

func resourceAwsTransferServerRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn

	descOpts := &transfer.DescribeServerInput{
		ServerId: aws.String(d.Id()),
	}

	log.Printf("[DEBUG] Describe Transfer Server Option: %#v", descOpts)

	resp, err := conn.DescribeServer(descOpts)
	if err != nil {
		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			log.Printf("[WARN] Transfer Server (%s) not found, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return err
	}

	endpoint := fmt.Sprintf("%s.server.transfer.%s.amazonaws.com", d.Id(), meta.(*AWSClient).region)

	d.Set("arn", resp.Server.Arn)
	d.Set("endpoint", endpoint)
	d.Set("invocation_role", "")
	d.Set("url", "")
	if resp.Server.IdentityProviderDetails != nil {
		d.Set("invocation_role", aws.StringValue(resp.Server.IdentityProviderDetails.InvocationRole))
		d.Set("url", aws.StringValue(resp.Server.IdentityProviderDetails.Url))
	}
	d.Set("identity_provider_type", resp.Server.IdentityProviderType)
	d.Set("logging_role", resp.Server.LoggingRole)

	if err := d.Set("tags", tagsToMapTransferServer(resp.Server.Tags)); err != nil {
		return fmt.Errorf("Error setting tags: %s", err)
	}
	return nil
}

func resourceAwsTransferServerUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn
	updateFlag := false
	updateOpts := &transfer.UpdateServerInput{
		ServerId: aws.String(d.Id()),
	}

	if d.HasChange("logging_role") {
		updateFlag = true
		updateOpts.LoggingRole = aws.String(d.Get("logging_role").(string))
	}

	if d.HasChange("invocation_role") || d.HasChange("url") {
		identityProviderDetails := &transfer.IdentityProviderDetails{}
		updateFlag = true
		if attr, ok := d.GetOk("invocation_role"); ok {
			identityProviderDetails.InvocationRole = aws.String(attr.(string))
		}

		if attr, ok := d.GetOk("url"); ok {
			identityProviderDetails.Url = aws.String(attr.(string))
		}
		updateOpts.IdentityProviderDetails = identityProviderDetails
	}

	if updateFlag {
		_, err := conn.UpdateServer(updateOpts)
		if err != nil {
			if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
				log.Printf("[WARN] Transfer Server (%s) not found, removing from state", d.Id())
				d.SetId("")
				return nil
			}
			return fmt.Errorf("error updating Transfer Server (%s): %s", d.Id(), err)
		}
	}

	if err := setTagsTransferServer(conn, d); err != nil {
		return fmt.Errorf("Error update tags: %s", err)
	}

	return resourceAwsTransferServerRead(d, meta)
}

func resourceAwsTransferServerDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).transferconn

	delOpts := &transfer.DeleteServerInput{
		ServerId: aws.String(d.Id()),
	}

	log.Printf("[DEBUG] Delete Transfer Server Option: %#v", delOpts)

	_, err := conn.DeleteServer(delOpts)
	if err != nil {
		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			return nil
		}
		return fmt.Errorf("error deleting Transfer Server (%s): %s", d.Id(), err)
	}

	if err := waitForTransferServerDeletion(conn, d.Id()); err != nil {
		return fmt.Errorf("error waiting for Transfer Server (%s): %s", d.Id(), err)
	}

	return nil
}

func waitForTransferServerDeletion(conn *transfer.Transfer, serverID string) error {
	params := &transfer.DescribeServerInput{
		ServerId: aws.String(serverID),
	}

	return resource.Retry(10*time.Minute, func() *resource.RetryError {
		_, err := conn.DescribeServer(params)

		if isAWSErr(err, transfer.ErrCodeResourceNotFoundException, "") {
			return nil
		}

		if err != nil {
			return resource.NonRetryableError(err)
		}

		return resource.RetryableError(fmt.Errorf("Transfer Server (%s) still exists", serverID))
	})
}
<|endoftext|>


<commit_before>package persist

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/dancannon/gorethink"
)

func (b *BlockRef) Size() uint64 {
	return b.Upper - b.Lower
}

// NewClock returns a new clock for a given branch
func NewClock(branch string) *Clock {
	return &Clock{branch, 0}
}

func ClockEq(c1 *Clock, c2 *Clock) bool {
	return c1.Branch == c2.Branch && c1.Clock == c2.Clock
}

func CloneClock(c *Clock) *Clock {
	return &Clock{
		Branch: c.Branch,
		Clock:  c.Clock,
	}
}

// "master/2"
func StringToClock(s string) (*Clock, error) {
	parts := strings.Split(s, "/")
	if len(parts) != 2 {
		return nil, fmt.Errorf("invalid clock string: %s", s)
	}
	clock, err := strconv.Atoi(parts[1])
	if err != nil {
		return nil, fmt.Errorf("invalid clock string: %v", err)
	}
	return &Clock{
		Branch: parts[0],
		Clock:  uint64(clock),
	}, nil
}

// NewChild returns the child of a FullClock
// [(master, 0), (foo, 0)] -> [(master, 0), (foo, 1)]
func NewChild(parent FullClock) FullClock {
	if len(parent) == 0 {
		return parent
	} else {
		lastClock := CloneClock(FullClockHead(parent))
		lastClock.Clock += 1
		return append(parent[:len(parent)-1], lastClock)
	}
}

// FullClockParent returns the parent of a full clock, or nil if the clock has no parent
// [(master, 2), (foo, 1)] -> [(master, 2), (foo, 0)]
// [(master, 2), (foo, 0)] -> [(master, 2)]
func FullClockParent(child FullClock) FullClock {
	if len(child) > 0 {
		lastClock := CloneClock(FullClockHead(child))
		if lastClock.Clock > 0 {
			lastClock.Clock -= 1
			return append(child[:len(child)-1], lastClock)
		} else if len(child) > 1 {
			return child[:len(child)-1]
		}
	}
	return nil
}

// FullClock is an array of clocks, e.g. [(master, 2), (foo, 3)]
type FullClock []*Clock

/*
func (fc FullClock) Size() int {
	return len(fc)
}

// ToArray converts a FullClock to an array of arrays.
// This is useful in indexing BranchClocks in RethinkDB.
func (fc FullClock) ToArray() (res []interface{}) {
	for _, clock := range fc {
		res = append(res, []interface{}{clock.Branch, clock.Clock})
	}
	return res
}*/
func FullClockHead(fc FullClock) *Clock {
	if len(fc) == 0 {
		return nil
	}
	return fc[len(fc)-1]
}

func FullClockBranch(fc FullClock) string {
	return FullClockHead(fc).Branch
}

// BranchClockToArray converts a BranchClock to an array.
// Putting this function here so it stays in sync with ToArray.
func FullClockToArray(fullClock gorethink.Term) gorethink.Term {
	return fullClock.Map(func(clock gorethink.Term) []interface{} {
		return []interface{}{clock.Field("Branch"), clock.Field("Clock")}
	})
}

func (c *Clock) ToArray() []interface{} {
	return []interface{}{c.Branch, c.Clock}
}

func ClockToArray(clock gorethink.Term) []interface{} {
	return []interface{}{clock.Field("Branch"), clock.Field("Clock")}
}

func (c *Clock) ToCommitID() string {
	return fmt.Sprintf("%s/%d", c.Branch, c.Clock)
}

func (d *Diff) CommitID() string {
	return d.Clock.ToCommitID()
}

// A ClockRangeList is an ordered list of ClockRanges
type ClockRangeList struct {
	ranges []*ClockRange
}

// A ClockRange represents a range of clocks
type ClockRange struct {
	Branch string
	Left   uint64
	Right  uint64
}

// NewClockRangeList creates a ClockRangeList that represents all clock ranges
// in between the two given FullClocks.
func NewClockRangeList(from FullClock, to FullClock) ClockRangeList {
	var crl ClockRangeList
	crl.AddFullClock(to)
	crl.SubFullClock(from)
	return crl
}

func (l *ClockRangeList) AddFullClock(fc FullClock) {
	for _, c := range fc {
		l.AddClock(c)
	}
}

// AddClock adds a range [0, c.Clock]
func (l *ClockRangeList) AddClock(c *Clock) {
	for _, r := range l.ranges {
		if r.Branch == c.Branch {
			if c.Clock > r.Right {
				r.Right = c.Clock
			}
			return
		}
	}
	l.ranges = append(l.ranges, &ClockRange{
		Branch: c.Branch,
		Left:   0,
		Right:  c.Clock,
	})
}

func (l *ClockRangeList) SubFullClock(fc FullClock) {
	for _, c := range fc {
		l.SubClock(c)
	}
}

// SubClock substracts a range [0, c.Clock]
func (l *ClockRangeList) SubClock(c *Clock) {
	// only keep non-empty ranges
	var newRanges []*ClockRange
	for _, r := range l.ranges {
		if r.Branch == c.Branch {
			r.Left = c.Clock + 1
		}
		if r.Left <= r.Right {
			newRanges = append(newRanges, r)
		}
	}
	l.ranges = newRanges
}

func (l *ClockRangeList) Ranges() []*ClockRange {
	return l.ranges
}
<commit_msg>Document the clock library and fix linter issues<commit_after>package persist

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/dancannon/gorethink"
)

// Size returns the size of a block ref
func (b *BlockRef) Size() uint64 {
	return b.Upper - b.Lower
}

// NewClock returns a new clock for a given branch
func NewClock(branch string) *Clock {
	return &Clock{branch, 0}
}

// ClockEq returns if two clocks are equal
func ClockEq(c1 *Clock, c2 *Clock) bool {
	return c1.Branch == c2.Branch && c1.Clock == c2.Clock
}

// CloneClock clones a clock
func CloneClock(c *Clock) *Clock {
	return &Clock{
		Branch: c.Branch,
		Clock:  c.Clock,
	}
}

// StringToClock converts a string like "master/2" to a clock
func StringToClock(s string) (*Clock, error) {
	parts := strings.Split(s, "/")
	if len(parts) != 2 {
		return nil, fmt.Errorf("invalid clock string: %s", s)
	}
	clock, err := strconv.Atoi(parts[1])
	if err != nil {
		return nil, fmt.Errorf("invalid clock string: %v", err)
	}
	return &Clock{
		Branch: parts[0],
		Clock:  uint64(clock),
	}, nil
}

// NewChild returns the child of a FullClock
// [(master, 0), (foo, 0)] -> [(master, 0), (foo, 1)]
func NewChild(parent FullClock) FullClock {
	if len(parent) == 0 {
		return parent
	}
	lastClock := CloneClock(FullClockHead(parent))
	lastClock.Clock++
	return append(parent[:len(parent)-1], lastClock)
}

// FullClockParent returns the parent of a full clock, or nil if the clock has no parent
// [(master, 2), (foo, 1)] -> [(master, 2), (foo, 0)]
// [(master, 2), (foo, 0)] -> [(master, 2)]
func FullClockParent(child FullClock) FullClock {
	if len(child) > 0 {
		lastClock := CloneClock(FullClockHead(child))
		if lastClock.Clock > 0 {
			lastClock.Clock--
			return append(child[:len(child)-1], lastClock)
		} else if len(child) > 1 {
			return child[:len(child)-1]
		}
	}
	return nil
}

// FullClock is an array of clocks, e.g. [(master, 2), (foo, 3)]
type FullClock []*Clock

// FullClockHead returns the last element of a FullClock
func FullClockHead(fc FullClock) *Clock {
	if len(fc) == 0 {
		return nil
	}
	return fc[len(fc)-1]
}

// FullClockBranch returns the branch of the last element of the FullClock
func FullClockBranch(fc FullClock) string {
	return FullClockHead(fc).Branch
}

// FullClockToArray converts a FullClock to an array.
func FullClockToArray(fullClock gorethink.Term) gorethink.Term {
	return fullClock.Map(func(clock gorethink.Term) []interface{} {
		return []interface{}{clock.Field("Branch"), clock.Field("Clock")}
	})
}

// ToArray converts a clock to an array
func (c *Clock) ToArray() []interface{} {
	return []interface{}{c.Branch, c.Clock}
}

// ClockToArray is the same as Clock.ToArray except that it operates on a
// gorethink Term
func ClockToArray(clock gorethink.Term) []interface{} {
	return []interface{}{clock.Field("Branch"), clock.Field("Clock")}
}

// ToCommitID converts a clock to a string like "master/2"
func (c *Clock) ToCommitID() string {
	return fmt.Sprintf("%s/%d", c.Branch, c.Clock)
}

// CommitID returns the CommitID of the clock associated with the diff
func (d *Diff) CommitID() string {
	return d.Clock.ToCommitID()
}

// ClockRangeList is an ordered list of ClockRanges
type ClockRangeList struct {
	ranges []*ClockRange
}

// ClockRange represents a range of clocks
type ClockRange struct {
	Branch string
	Left   uint64
	Right  uint64
}

// NewClockRangeList creates a ClockRangeList that represents all clock ranges
// in between the two given FullClocks.
func NewClockRangeList(from FullClock, to FullClock) ClockRangeList {
	var crl ClockRangeList
	crl.AddFullClock(to)
	crl.SubFullClock(from)
	return crl
}

// AddFullClock adds a FullClock to the ClockRange
func (l *ClockRangeList) AddFullClock(fc FullClock) {
	for _, c := range fc {
		l.AddClock(c)
	}
}

// AddClock adds a range [0, c.Clock]
func (l *ClockRangeList) AddClock(c *Clock) {
	for _, r := range l.ranges {
		if r.Branch == c.Branch {
			if c.Clock > r.Right {
				r.Right = c.Clock
			}
			return
		}
	}
	l.ranges = append(l.ranges, &ClockRange{
		Branch: c.Branch,
		Left:   0,
		Right:  c.Clock,
	})
}

// SubFullClock subtracts a FullClock from the ClockRange
func (l *ClockRangeList) SubFullClock(fc FullClock) {
	for _, c := range fc {
		l.SubClock(c)
	}
}

// SubClock substracts a range [0, c.Clock]
func (l *ClockRangeList) SubClock(c *Clock) {
	// only keep non-empty ranges
	var newRanges []*ClockRange
	for _, r := range l.ranges {
		if r.Branch == c.Branch {
			r.Left = c.Clock + 1
		}
		if r.Left <= r.Right {
			newRanges = append(newRanges, r)
		}
	}
	l.ranges = newRanges
}

// Ranges return the clock ranges stored in a ClockRangeList
func (l *ClockRangeList) Ranges() []*ClockRange {
	return l.ranges
}
<|endoftext|>


<commit_before>// Copyright 2011 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.

package main

var helpImportpath = &Command{
	UsageLine: "importpath",
	Short:     "description of import paths",
	Long: `
Many commands apply to a set of packages named by import paths:

	go action [importpath...]

An import path that is a rooted path or that begins with
a . or .. element is interpreted as a file system path and
denotes the package in that directory.

Otherwise, the import path P denotes the package found in
the directory DIR/src/P for some DIR listed in the GOPATH
environment variable (see 'go help gopath').

If no import paths are given, the action applies to the
package in the current directory.

The special import path "all" expands to all package directories
found in all the GOPATH trees.  For example, 'go list all'
lists all the packages on the local system.

The special import path "std" is like all but expands to just the
packages in the standard Go library.

An import path is a pattern if it includes one or more "..." wildcards,
each of which can match any string, including the empty string and
strings containing slashes.  Such a pattern expands to all package
directories found in the GOPATH trees with names matching the
patterns.  For example, encoding/... expands to all packages
in the encoding tree.

An import path can also name a package to be downloaded from
a remote repository.  Run 'go help remote' for details.

Every package in a program must have a unique import path.
By convention, this is arranged by starting each path with a
unique prefix that belongs to you.  For example, paths used
internally at Google all begin with 'google', and paths
denoting remote repositories begin with the path to the code,
such as 'code.google.com/p/project'.
	`,
}

var helpRemote = &Command{
	UsageLine: "remote",
	Short:     "remote import path syntax",
	Long: `

An import path (see 'go help importpath') denotes a package
stored in the local file system.  Certain import paths also
describe how to obtain the source code for the package using
a revision control system.

A few common code hosting sites have special syntax:

	BitBucket (Mercurial)

		import "bitbucket.org/user/project"
		import "bitbucket.org/user/project/sub/directory"

	GitHub (Git)

		import "github.com/user/project"
		import "github.com/user/project/sub/directory"

	Google Code Project Hosting (Git, Mercurial, Subversion)

		import "code.google.com/p/project"
		import "code.google.com/p/project/sub/directory"

		import "code.google.com/p/project.subrepository"
		import "code.google.com/p/project.subrepository/sub/directory"

	Launchpad (Bazaar)

		import "launchpad.net/project"
		import "launchpad.net/project/series"
		import "launchpad.net/project/series/sub/directory"

		import "launchpad.net/~user/project/branch"
		import "launchpad.net/~user/project/branch/sub/directory"

For code hosted on other servers, an import path of the form

	repository.vcs/path

specifies the given repository, with or without the .vcs suffix,
using the named version control system, and then the path inside
that repository.  The supported version control systems are:

	Bazaar      .bzr
	Git         .git
	Mercurial   .hg
	Subversion  .svn

For example,

	import "example.org/user/foo.hg"

denotes the root directory of the Mercurial repository at
example.org/user/foo or foo.hg, and

	import "example.org/repo.git/foo/bar"

denotes the foo/bar directory of the Git repository at
example.com/repo or repo.git.

When a version control system supports multiple protocols,
each is tried in turn when downloading.  For example, a Git
download tries git://, then https://, then http://.

New downloaded packages are written to the first directory
listed in the GOPATH environment variable (see 'go help gopath').

The go command attempts to download the version of the
package appropriate for the Go release being used.
Run 'go help install' for more.
	`,
}

var helpGopath = &Command{
	UsageLine: "gopath",
	Short:     "GOPATH environment variable",
	Long: `
The GOPATH environment variable lists places to look for Go code.
On Unix, the value is a colon-separated string.
On Windows, the value is a semicolon-separated string.
On Plan 9, the value is a list.

GOPATH must be set to build and install packages outside the
standard Go tree.

Each directory listed in GOPATH must have a prescribed structure:

The src/ directory holds source code.  The path below 'src'
determines the import path or executable name.

The pkg/ directory holds installed package objects.
As in the Go tree, each target operating system and
architecture pair has its own subdirectory of pkg
(pkg/GOOS_GOARCH).

If DIR is a directory listed in the GOPATH, a package with
source in DIR/src/foo/bar can be imported as "foo/bar" and
has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a".

The bin/ directory holds compiled commands.
Each command is named for its source directory, but only
the final element, not the entire path.  That is, the
command with source in DIR/src/foo/quux is installed into
DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
so that you can add DIR/bin to your PATH to get at the
installed commands.

Here's an example directory layout:

    GOPATH=/home/user/gocode

    /home/user/gocode/
        src/
            foo/
                bar/               (go code in package bar)
                    x.go
                quux/              (go code in package main)
                    y.go
        bin/
            quux                   (installed command)
        pkg/
            linux_amd64/
                foo/
                    bar.a          (installed package object)

Go searches each directory listed in GOPATH to find source code,
but new packages are always downloaded into the first directory
in the list.
	`,
}
<commit_msg>cmd/go: explain x... vs. x/... in help importpath Fixes issue 3110.<commit_after>// Copyright 2011 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.

package main

var helpImportpath = &Command{
	UsageLine: "importpath",
	Short:     "description of import paths",
	Long: `
Many commands apply to a set of packages named by import paths:

	go action [importpath...]

An import path that is a rooted path or that begins with
a . or .. element is interpreted as a file system path and
denotes the package in that directory.

Otherwise, the import path P denotes the package found in
the directory DIR/src/P for some DIR listed in the GOPATH
environment variable (see 'go help gopath').

If no import paths are given, the action applies to the
package in the current directory.

The special import path "all" expands to all package directories
found in all the GOPATH trees.  For example, 'go list all'
lists all the packages on the local system.

The special import path "std" is like all but expands to just the
packages in the standard Go library.

An import path is a pattern if it includes one or more "..." wildcards,
each of which can match any string, including the empty string and
strings containing slashes.  Such a pattern expands to all package
directories found in the GOPATH trees with names matching the
patterns.  For example, encoding/... expands to all package
in subdirectories of the encoding tree, while net... expands to
net and all its subdirectories.

An import path can also name a package to be downloaded from
a remote repository.  Run 'go help remote' for details.

Every package in a program must have a unique import path.
By convention, this is arranged by starting each path with a
unique prefix that belongs to you.  For example, paths used
internally at Google all begin with 'google', and paths
denoting remote repositories begin with the path to the code,
such as 'code.google.com/p/project'.
	`,
}

var helpRemote = &Command{
	UsageLine: "remote",
	Short:     "remote import path syntax",
	Long: `

An import path (see 'go help importpath') denotes a package
stored in the local file system.  Certain import paths also
describe how to obtain the source code for the package using
a revision control system.

A few common code hosting sites have special syntax:

	BitBucket (Mercurial)

		import "bitbucket.org/user/project"
		import "bitbucket.org/user/project/sub/directory"

	GitHub (Git)

		import "github.com/user/project"
		import "github.com/user/project/sub/directory"

	Google Code Project Hosting (Git, Mercurial, Subversion)

		import "code.google.com/p/project"
		import "code.google.com/p/project/sub/directory"

		import "code.google.com/p/project.subrepository"
		import "code.google.com/p/project.subrepository/sub/directory"

	Launchpad (Bazaar)

		import "launchpad.net/project"
		import "launchpad.net/project/series"
		import "launchpad.net/project/series/sub/directory"

		import "launchpad.net/~user/project/branch"
		import "launchpad.net/~user/project/branch/sub/directory"

For code hosted on other servers, an import path of the form

	repository.vcs/path

specifies the given repository, with or without the .vcs suffix,
using the named version control system, and then the path inside
that repository.  The supported version control systems are:

	Bazaar      .bzr
	Git         .git
	Mercurial   .hg
	Subversion  .svn

For example,

	import "example.org/user/foo.hg"

denotes the root directory of the Mercurial repository at
example.org/user/foo or foo.hg, and

	import "example.org/repo.git/foo/bar"

denotes the foo/bar directory of the Git repository at
example.com/repo or repo.git.

When a version control system supports multiple protocols,
each is tried in turn when downloading.  For example, a Git
download tries git://, then https://, then http://.

New downloaded packages are written to the first directory
listed in the GOPATH environment variable (see 'go help gopath').

The go command attempts to download the version of the
package appropriate for the Go release being used.
Run 'go help install' for more.
	`,
}

var helpGopath = &Command{
	UsageLine: "gopath",
	Short:     "GOPATH environment variable",
	Long: `
The GOPATH environment variable lists places to look for Go code.
On Unix, the value is a colon-separated string.
On Windows, the value is a semicolon-separated string.
On Plan 9, the value is a list.

GOPATH must be set to build and install packages outside the
standard Go tree.

Each directory listed in GOPATH must have a prescribed structure:

The src/ directory holds source code.  The path below 'src'
determines the import path or executable name.

The pkg/ directory holds installed package objects.
As in the Go tree, each target operating system and
architecture pair has its own subdirectory of pkg
(pkg/GOOS_GOARCH).

If DIR is a directory listed in the GOPATH, a package with
source in DIR/src/foo/bar can be imported as "foo/bar" and
has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a".

The bin/ directory holds compiled commands.
Each command is named for its source directory, but only
the final element, not the entire path.  That is, the
command with source in DIR/src/foo/quux is installed into
DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
so that you can add DIR/bin to your PATH to get at the
installed commands.

Here's an example directory layout:

    GOPATH=/home/user/gocode

    /home/user/gocode/
        src/
            foo/
                bar/               (go code in package bar)
                    x.go
                quux/              (go code in package main)
                    y.go
        bin/
            quux                   (installed command)
        pkg/
            linux_amd64/
                foo/
                    bar.a          (installed package object)

Go searches each directory listed in GOPATH to find source code,
but new packages are always downloaded into the first directory
in the list.
	`,
}
<|endoftext|>


<commit_before>package piepan

import (
	"github.com/layeh/gumble/gumble"
)

func (in *Instance) OnConnect(e *gumble.ConnectEvent) {
	global, _ := in.state.Get("piepan")
	if obj := global.Object(); obj != nil {
		in.users = newUsersWrapper(in.client.Users())
		in.channels = newChannelsWrapper(in.client.Channels())

		obj.Set("Self", e.Client.Self())
		obj.Set("Users", in.users)
		obj.Set("Channels", in.channels)
	}

	for _, listener := range in.listeners["connect"] {
		in.callValue(listener, e)
	}
}

func (in *Instance) OnDisconnect(e *gumble.DisconnectEvent) {
	event := disconnectEventWrapper{
		Client: e.Client,
		Type:   int(e.Type),

		String: e.String,

		IsError: e.Type.Has(gumble.DisconnectError),
		IsUser:  e.Type.Has(gumble.DisconnectUser),

		IsOther:             e.Type.Has(gumble.DisconnectOther),
		IsVersion:           e.Type.Has(gumble.DisconnectVersion),
		IsUserName:          e.Type.Has(gumble.DisconnectUserName),
		IsUserCredentials:   e.Type.Has(gumble.DisconnectUserCredentials),
		IsServerPassword:    e.Type.Has(gumble.DisconnectServerPassword),
		IsUsernameInUse:     e.Type.Has(gumble.DisconnectUsernameInUse),
		IsServerFull:        e.Type.Has(gumble.DisconnectServerFull),
		IsNoCertificate:     e.Type.Has(gumble.DisconnectNoCertificate),
		IsAuthenticatorFail: e.Type.Has(gumble.DisconnectAuthenticatorFail),
	}

	in.users = nil
	in.channels = nil

	for _, listener := range in.listeners["disconnect"] {
		in.callValue(listener, &event)
	}
}

func (in *Instance) OnTextMessage(e *gumble.TextMessageEvent) {
	for _, listener := range in.listeners["message"] {
		in.callValue(listener, e)
	}
}

func (in *Instance) OnUserChange(e *gumble.UserChangeEvent) {
	event := userChangeEventWrapper{
		Client: e.Client,
		Type:   int(e.Type),
		User:   e.User,
		Actor:  e.Actor,

		String: e.String,

		IsConnected:             e.Type.Has(gumble.UserChangeConnected),
		IsDisconnected:          e.Type.Has(gumble.UserChangeDisconnected),
		IsKicked:                e.Type.Has(gumble.UserChangeKicked),
		IsBanned:                e.Type.Has(gumble.UserChangeBanned),
		IsRegistered:            e.Type.Has(gumble.UserChangeRegistered),
		IsUnregistered:          e.Type.Has(gumble.UserChangeUnregistered),
		IsChangeName:            e.Type.Has(gumble.UserChangeName),
		IsChangeChannel:         e.Type.Has(gumble.UserChangeChannel),
		IsChangeComment:         e.Type.Has(gumble.UserChangeComment),
		IsChangeAudio:           e.Type.Has(gumble.UserChangeAudio),
		IsChangeTexture:         e.Type.Has(gumble.UserChangeTexture),
		IsChangePrioritySpeaker: e.Type.Has(gumble.UserChangePrioritySpeaker),
		IsChangeRecording:       e.Type.Has(gumble.UserChangeRecording),
	}

	if event.IsConnected {
		in.users.add(e.User)
	} else if event.IsDisconnected {
		in.users.remove(e.User)
	}

	for _, listener := range in.listeners["userchange"] {
		in.callValue(listener, &event)
	}
}

func (in *Instance) OnChannelChange(e *gumble.ChannelChangeEvent) {
	event := channelChangeEventWrapper{
		Client:  e.Client,
		Type:    int(e.Type),
		Channel: e.Channel,

		IsCreated:           e.Type.Has(gumble.ChannelChangeCreated),
		IsRemoved:           e.Type.Has(gumble.ChannelChangeRemoved),
		IsMoved:             e.Type.Has(gumble.ChannelChangeMoved),
		IsChangeName:        e.Type.Has(gumble.ChannelChangeName),
		IsChangeDescription: e.Type.Has(gumble.ChannelChangeDescription),
		IsChangePosition:    e.Type.Has(gumble.ChannelChangePosition),
	}

	for _, listener := range in.listeners["channelchange"] {
		in.callValue(listener, &event)
	}
}

func (in *Instance) OnPermissionDenied(e *gumble.PermissionDeniedEvent) {
	event := permissionDeniedEventWrapper{
		Client:  e.Client,
		Type:    int(e.Type),
		Channel: e.Channel,
		User:    e.User,

		Permission: int(e.Permission),
		String:     e.String,

		IsOther:              e.Type.Has(gumble.PermissionDeniedOther),
		IsPermission:         e.Type.Has(gumble.PermissionDeniedPermission),
		IsSuperUser:          e.Type.Has(gumble.PermissionDeniedSuperUser),
		IsInvalidChannelName: e.Type.Has(gumble.PermissionDeniedInvalidChannelName),
		IsTextTooLong:        e.Type.Has(gumble.PermissionDeniedTextTooLong),
		IsTemporaryChannel:   e.Type.Has(gumble.PermissionDeniedTemporaryChannel),
		IsMissingCertificate: e.Type.Has(gumble.PermissionDeniedMissingCertificate),
		IsInvalidUserName:    e.Type.Has(gumble.PermissionDeniedInvalidUserName),
		IsChannelFull:        e.Type.Has(gumble.PermissionDeniedChannelFull),
		IsNestingLimit:       e.Type.Has(gumble.PermissionDeniedNestingLimit),
	}

	for _, listener := range in.listeners["permissiondenied"] {
		in.callValue(listener, &event)
	}
}

func (in *Instance) OnUserList(e *gumble.UserListEvent) {
}

func (in *Instance) OnAcl(e *gumble.AclEvent) {
}

func (in *Instance) OnBanList(e *gumble.BanListEvent) {
}

func (in *Instance) OnContextActionChange(e *gumble.ContextActionChangeEvent) {
}
<commit_msg>fix gumble API change<commit_after>package piepan

import (
	"github.com/layeh/gumble/gumble"
)

func (in *Instance) OnConnect(e *gumble.ConnectEvent) {
	global, _ := in.state.Get("piepan")
	if obj := global.Object(); obj != nil {
		in.users = newUsersWrapper(in.client.Users())
		in.channels = newChannelsWrapper(in.client.Channels())

		obj.Set("Self", e.Client.Self())
		obj.Set("Users", in.users)
		obj.Set("Channels", in.channels)
	}

	for _, listener := range in.listeners["connect"] {
		in.callValue(listener, e)
	}
}

func (in *Instance) OnDisconnect(e *gumble.DisconnectEvent) {
	event := disconnectEventWrapper{
		Client: e.Client,
		Type:   int(e.Type),

		String: e.String,

		IsError: e.Type.Has(gumble.DisconnectError),
		IsUser:  e.Type.Has(gumble.DisconnectUser),

		IsOther:             e.Type.Has(gumble.DisconnectOther),
		IsVersion:           e.Type.Has(gumble.DisconnectVersion),
		IsUserName:          e.Type.Has(gumble.DisconnectUserName),
		IsUserCredentials:   e.Type.Has(gumble.DisconnectUserCredentials),
		IsServerPassword:    e.Type.Has(gumble.DisconnectServerPassword),
		IsUsernameInUse:     e.Type.Has(gumble.DisconnectUsernameInUse),
		IsServerFull:        e.Type.Has(gumble.DisconnectServerFull),
		IsNoCertificate:     e.Type.Has(gumble.DisconnectNoCertificate),
		IsAuthenticatorFail: e.Type.Has(gumble.DisconnectAuthenticatorFail),
	}

	in.users = nil
	in.channels = nil

	for _, listener := range in.listeners["disconnect"] {
		in.callValue(listener, &event)
	}
}

func (in *Instance) OnTextMessage(e *gumble.TextMessageEvent) {
	for _, listener := range in.listeners["message"] {
		in.callValue(listener, e)
	}
}

func (in *Instance) OnUserChange(e *gumble.UserChangeEvent) {
	event := userChangeEventWrapper{
		Client: e.Client,
		Type:   int(e.Type),
		User:   e.User,
		Actor:  e.Actor,

		String: e.String,

		IsConnected:             e.Type.Has(gumble.UserChangeConnected),
		IsDisconnected:          e.Type.Has(gumble.UserChangeDisconnected),
		IsKicked:                e.Type.Has(gumble.UserChangeKicked),
		IsBanned:                e.Type.Has(gumble.UserChangeBanned),
		IsRegistered:            e.Type.Has(gumble.UserChangeRegistered),
		IsUnregistered:          e.Type.Has(gumble.UserChangeUnregistered),
		IsChangeName:            e.Type.Has(gumble.UserChangeName),
		IsChangeChannel:         e.Type.Has(gumble.UserChangeChannel),
		IsChangeComment:         e.Type.Has(gumble.UserChangeComment),
		IsChangeAudio:           e.Type.Has(gumble.UserChangeAudio),
		IsChangeTexture:         e.Type.Has(gumble.UserChangeTexture),
		IsChangePrioritySpeaker: e.Type.Has(gumble.UserChangePrioritySpeaker),
		IsChangeRecording:       e.Type.Has(gumble.UserChangeRecording),
	}

	if event.IsConnected {
		in.users.add(e.User)
	} else if event.IsDisconnected {
		in.users.remove(e.User)
	}

	for _, listener := range in.listeners["userchange"] {
		in.callValue(listener, &event)
	}
}

func (in *Instance) OnChannelChange(e *gumble.ChannelChangeEvent) {
	event := channelChangeEventWrapper{
		Client:  e.Client,
		Type:    int(e.Type),
		Channel: e.Channel,

		IsCreated:           e.Type.Has(gumble.ChannelChangeCreated),
		IsRemoved:           e.Type.Has(gumble.ChannelChangeRemoved),
		IsMoved:             e.Type.Has(gumble.ChannelChangeMoved),
		IsChangeName:        e.Type.Has(gumble.ChannelChangeName),
		IsChangeDescription: e.Type.Has(gumble.ChannelChangeDescription),
		IsChangePosition:    e.Type.Has(gumble.ChannelChangePosition),
	}

	for _, listener := range in.listeners["channelchange"] {
		in.callValue(listener, &event)
	}
}

func (in *Instance) OnPermissionDenied(e *gumble.PermissionDeniedEvent) {
	event := permissionDeniedEventWrapper{
		Client:  e.Client,
		Type:    int(e.Type),
		Channel: e.Channel,
		User:    e.User,

		Permission: int(e.Permission),
		String:     e.String,

		IsOther:              e.Type.Has(gumble.PermissionDeniedOther),
		IsPermission:         e.Type.Has(gumble.PermissionDeniedPermission),
		IsSuperUser:          e.Type.Has(gumble.PermissionDeniedSuperUser),
		IsInvalidChannelName: e.Type.Has(gumble.PermissionDeniedInvalidChannelName),
		IsTextTooLong:        e.Type.Has(gumble.PermissionDeniedTextTooLong),
		IsTemporaryChannel:   e.Type.Has(gumble.PermissionDeniedTemporaryChannel),
		IsMissingCertificate: e.Type.Has(gumble.PermissionDeniedMissingCertificate),
		IsInvalidUserName:    e.Type.Has(gumble.PermissionDeniedInvalidUserName),
		IsChannelFull:        e.Type.Has(gumble.PermissionDeniedChannelFull),
		IsNestingLimit:       e.Type.Has(gumble.PermissionDeniedNestingLimit),
	}

	for _, listener := range in.listeners["permissiondenied"] {
		in.callValue(listener, &event)
	}
}

func (in *Instance) OnUserList(e *gumble.UserListEvent) {
}

func (in *Instance) OnACL(e *gumble.ACLEvent) {
}

func (in *Instance) OnBanList(e *gumble.BanListEvent) {
}

func (in *Instance) OnContextActionChange(e *gumble.ContextActionChangeEvent) {
}
<|endoftext|>


<commit_before>package osmpbf

import osm "github.com/paulmach/go.osm"

func extractTags(stringTable []string, keyIDs, valueIDs []uint32) osm.Tags {
	if len(keyIDs) == 0 {
		return nil
	}

	tags := make(osm.Tags, 0, len(keyIDs))
	for index, keyID := range keyIDs {
		tags = append(tags, osm.Tag{
			Key:   stringTable[keyID],
			Value: stringTable[valueIDs[index]],
		})
	}

	return tags
}

type tagUnpacker struct {
	stringTable []string
	keysVals    []int32
	index       int
}

// Next creates the tags from the stringtable and array of IDs.
// Used in DenseNodes encoding.
func (tu *tagUnpacker) Next() osm.Tags {
	var tags osm.Tags
	for tu.index < len(tu.keysVals) {
		keyID := tu.keysVals[tu.index]
		tu.index++
		if keyID == 0 {
			break
		}

		valID := tu.keysVals[tu.index]
		tu.index++

		tags = append(tags, osm.Tag{
			Key:   tu.stringTable[keyID],
			Value: tu.stringTable[valID],
		})
	}

	return tags
}
<commit_msg>osmpbf: prealloc tags during unpacking<commit_after>package osmpbf

import (
	osm "github.com/paulmach/go.osm"
)

func extractTags(stringTable []string, keyIDs, valueIDs []uint32) osm.Tags {
	if len(keyIDs) == 0 {
		return nil
	}

	tags := make(osm.Tags, 0, len(keyIDs))
	for index, keyID := range keyIDs {
		tags = append(tags, osm.Tag{
			Key:   stringTable[keyID],
			Value: stringTable[valueIDs[index]],
		})
	}

	return tags
}

type tagUnpacker struct {
	stringTable []string
	keysVals    []int32
	index       int
}

// Next creates the tags from the stringtable and array of IDs.
// Used in DenseNodes encoding.
func (tu *tagUnpacker) Next() osm.Tags {
	index := tu.index
	for index < len(tu.keysVals) {
		if tu.keysVals[index] == 0 {
			break
		}

		index += 2
	}

	count := index - tu.index
	if count == 0 {
		tu.index++
		return nil
	}

	tags := make(osm.Tags, 0, count/2)
	for tu.index < len(tu.keysVals) {
		keyID := tu.keysVals[tu.index]
		tu.index++
		if keyID == 0 {
			break
		}

		valID := tu.keysVals[tu.index]
		tu.index++

		tags = append(tags, osm.Tag{
			Key:   tu.stringTable[keyID],
			Value: tu.stringTable[valID],
		})
	}

	return tags
}
<|endoftext|>


<commit_before>package witness

import (
	"fmt"

	"github.com/asuleymanov/golos-go/transports"
)

const apiID = "witness_api"

//API plug-in structure
type API struct {
	caller transports.Caller
}

//NewAPI plug-in initialization
func NewAPI(caller transports.Caller) *API {
	return &API{caller}
}

var emptyParams = struct{}{}

func (api *API) call(method string, params, resp interface{}) error {
	return api.caller.Call("call", []interface{}{apiID, method, params}, resp)
}

//GetActiveWitnesses api request get_active_witnesses
func (api *API) GetActiveWitnesses() ([]*string, error) {
	var resp []*string
	err := api.call("get_active_witnesses", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

//GetCurrentMedianHistoryPrice api request get_current_median_history_price
func (api *API) GetCurrentMedianHistoryPrice() (*CurrentMedianHistoryPrice, error) {
	var resp CurrentMedianHistoryPrice
	err := api.call("get_current_median_history_price", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

//GetFeedHistory api request get_feed_history
func (api *API) GetFeedHistory() (*FeedHistory, error) {
	var resp FeedHistory
	err := api.call("get_feed_history", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

//GetMinerQueue api request get_miner_queue
func (api *API) GetMinerQueue() ([]*string, error) {
	var resp []*string
	err := api.call("get_miner_queue", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

//GetWitnessByAccount api request get_witness_by_account
func (api *API) GetWitnessByAccount(author string) (*Witness, error) {
	var resp Witness
	err := api.call("get_witness_by_account", []string{author}, &resp)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

//GetWitnessCount api request get_witness_count
func (api *API) GetWitnessCount() (*uint32, error) {
	var resp uint32
	err := api.call("get_witness_count", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

//GetWitnessSchedule api request get_witness_schedule
func (api *API) GetWitnessSchedule() (*WitnessSchedule, error) {
	var resp WitnessSchedule
	err := api.call("get_witness_schedule", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

//GetWitnesses api request get_witnesses
func (api *API) GetWitnesses(id []uint32) ([]*Witness, error) {
	var resp []*Witness
	err := api.call("get_witnesses", [][]uint32{id}, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

//GetWitnessByVote api request get_witnesses_by_vote
func (api *API) GetWitnessByVote(author string, limit uint) ([]*Witness, error) {
	if limit > 1000 {
		return nil, fmt.Errorf("%v: get_witnesses_by_vote -> limit must not exceed 1000", apiID)
	}
	var resp []*Witness
	err := api.call("get_witnesses_by_vote", []interface{}{author, limit}, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

//LookupWitnessAccounts api request lookup_witness_accounts
func (api *API) LookupWitnessAccounts(author string, limit uint) ([]*string, error) {
	if limit > 1000 {
		return nil, fmt.Errorf("%v: lookup_witness_accounts -> limit must not exceed 1000", apiID)
	}
	var resp []*string
	err := api.call("lookup_witness_accounts", []interface{}{author, limit}, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
<commit_msg>Update api.go<commit_after>package witness

import (
	"fmt"

	"github.com/asuleymanov/golos-go/transports"
)

const apiID = "witness_api"

//API plug-in structure
type API struct {
	caller transports.Caller
}

//NewAPI plug-in initialization
func NewAPI(caller transports.Caller) *API {
	return &API{caller}
}

var emptyParams = []struct{}

func (api *API) call(method string, params, resp interface{}) error {
	return api.caller.Call("call", []interface{}{apiID, method, params}, resp)
}

//GetActiveWitnesses api request get_active_witnesses
func (api *API) GetActiveWitnesses() ([]*string, error) {
	var resp []*string
	err := api.call("get_active_witnesses", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

//GetCurrentMedianHistoryPrice api request get_current_median_history_price
func (api *API) GetCurrentMedianHistoryPrice() (*CurrentMedianHistoryPrice, error) {
	var resp CurrentMedianHistoryPrice
	err := api.call("get_current_median_history_price", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

//GetFeedHistory api request get_feed_history
func (api *API) GetFeedHistory() (*FeedHistory, error) {
	var resp FeedHistory
	err := api.call("get_feed_history", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

//GetMinerQueue api request get_miner_queue
func (api *API) GetMinerQueue() ([]*string, error) {
	var resp []*string
	err := api.call("get_miner_queue", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

//GetWitnessByAccount api request get_witness_by_account
func (api *API) GetWitnessByAccount(author string) (*Witness, error) {
	var resp Witness
	err := api.call("get_witness_by_account", []string{author}, &resp)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

//GetWitnessCount api request get_witness_count
func (api *API) GetWitnessCount() (*uint32, error) {
	var resp uint32
	err := api.call("get_witness_count", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

//GetWitnessSchedule api request get_witness_schedule
func (api *API) GetWitnessSchedule() (*WitnessSchedule, error) {
	var resp WitnessSchedule
	err := api.call("get_witness_schedule", emptyParams, &resp)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

//GetWitnesses api request get_witnesses
func (api *API) GetWitnesses(id []uint32) ([]*Witness, error) {
	var resp []*Witness
	err := api.call("get_witnesses", [][]uint32{id}, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

//GetWitnessByVote api request get_witnesses_by_vote
func (api *API) GetWitnessByVote(author string, limit uint) ([]*Witness, error) {
	if limit > 1000 {
		return nil, fmt.Errorf("%v: get_witnesses_by_vote -> limit must not exceed 1000", apiID)
	}
	var resp []*Witness
	err := api.call("get_witnesses_by_vote", []interface{}{author, limit}, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

//LookupWitnessAccounts api request lookup_witness_accounts
func (api *API) LookupWitnessAccounts(author string, limit uint) ([]*string, error) {
	if limit > 1000 {
		return nil, fmt.Errorf("%v: lookup_witness_accounts -> limit must not exceed 1000", apiID)
	}
	var resp []*string
	err := api.call("lookup_witness_accounts", []interface{}{author, limit}, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
<|endoftext|>


<commit_before>// Copyright 2017 tsuru-client authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"log"
	"os"

	"github.com/docker/machine/libmachine/drivers/plugin/localbinary"
	"github.com/tsuru/tsuru-client/tsuru/admin"
	"github.com/tsuru/tsuru-client/tsuru/client"
	"github.com/tsuru/tsuru-client/tsuru/installer"
	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/iaas/dockermachine"
	_ "github.com/tsuru/tsuru/provision/docker/cmds"
)

const (
	version = "1.3.0-rc2"
	header  = "Supported-Tsuru"
)

func buildManager(name string) *cmd.Manager {
	lookup := func(context *cmd.Context) error {
		return client.RunPlugin(context)
	}
	m := cmd.BuildBaseManager(name, version, header, lookup)
	m.Register(&client.AppRun{})
	m.Register(&client.AppInfo{})
	m.Register(&client.AppCreate{})
	m.Register(&client.AppRemove{})
	m.Register(&client.AppUpdate{})
	m.Register(&client.UnitAdd{})
	m.Register(&client.UnitRemove{})
	m.Register(&client.AppList{})
	m.Register(&client.AppLog{})
	m.Register(&client.AppGrant{})
	m.Register(&client.AppRevoke{})
	m.Register(&client.AppRestart{})
	m.Register(&client.AppStart{})
	m.Register(&client.AppStop{})
	m.Register(&admin.AppLockDelete{})
	m.Register(&client.CertificateSet{})
	m.Register(&client.CertificateUnset{})
	m.Register(&client.CertificateList{})
	m.Register(&client.CnameAdd{})
	m.Register(&client.CnameRemove{})
	m.Register(&client.EnvGet{})
	m.Register(&client.EnvSet{})
	m.Register(&client.EnvUnset{})
	m.Register(&client.KeyAdd{})
	m.Register(&client.KeyRemove{})
	m.Register(&client.KeyList{})
	m.Register(client.ServiceList{})
	m.Register(&client.ServiceInstanceAdd{})
	m.Register(&client.ServiceInstanceUpdate{})
	m.Register(&client.ServiceInstanceRemove{})
	m.Register(client.ServiceInfo{})
	m.Register(client.ServiceInstanceInfo{})
	m.Register(client.ServiceInstanceStatus{})
	m.Register(&client.ServiceInstanceGrant{})
	m.Register(&client.ServiceInstanceRevoke{})
	m.Register(&client.ServiceInstanceBind{})
	m.Register(&client.ServiceInstanceUnbind{})
	m.Register(&admin.PlatformList{})
	m.Register(&admin.PlatformAdd{})
	m.Register(&admin.PlatformUpdate{})
	m.Register(&admin.PlatformRemove{})
	m.Register(&client.PluginInstall{})
	m.Register(&client.PluginRemove{})
	m.Register(&client.PluginList{})
	m.Register(&client.AppSwap{})
	m.Register(&client.AppDeploy{})
	m.Register(&client.PlanList{})
	m.Register(&client.UserCreate{})
	m.Register(&client.ResetPassword{})
	m.Register(&client.UserRemove{})
	m.Register(&client.ListUsers{})
	m.Register(&client.TeamCreate{})
	m.Register(&client.TeamUpdate{})
	m.Register(&client.TeamRemove{})
	m.Register(&client.TeamList{})
	m.Register(&client.ChangePassword{})
	m.Register(&client.ShowAPIToken{})
	m.Register(&client.RegenerateAPIToken{})
	m.Register(&client.AppDeployList{})
	m.Register(&client.AppDeployRollback{})
	m.Register(&client.AppDeployRollbackUpdate{})
	m.Register(&client.AppDeployRebuild{})
	m.Register(&cmd.ShellToContainerCmd{})
	m.Register(&client.PoolList{})
	m.Register(&client.PermissionList{})
	m.Register(&client.RoleAdd{})
	m.Register(&client.RoleUpdate{})
	m.Register(&client.RoleRemove{})
	m.Register(&client.RoleList{})
	m.Register(&client.RoleInfo{})
	m.Register(&client.RolePermissionAdd{})
	m.Register(&client.RolePermissionRemove{})
	m.Register(&client.RoleAssign{})
	m.Register(&client.RoleDissociate{})
	m.Register(&client.RoleDefaultAdd{})
	m.Register(&client.RoleDefaultList{})
	m.Register(&client.RoleDefaultRemove{})
	m.Register(&installer.Install{})
	m.Register(&installer.Uninstall{})
	m.Register(&installer.InstallHostList{})
	m.Register(&installer.InstallSSH{})
	m.Register(&installer.InstallConfigInit{})
	m.Register(&admin.AddPoolToSchedulerCmd{})
	m.Register(&client.EventList{})
	m.Register(&client.EventInfo{})
	m.Register(&client.EventCancel{})
	m.Register(&client.RoutersList{})
	m.Register(&admin.TemplateList{})
	m.Register(&admin.TemplateAdd{})
	m.Register(&admin.TemplateRemove{})
	m.Register(&admin.MachineList{})
	m.Register(&admin.MachineDestroy{})
	m.Register(&admin.TemplateUpdate{})
	m.Register(&admin.PlanCreate{})
	m.Register(&admin.PlanRemove{})
	m.Register(&admin.UpdatePoolToSchedulerCmd{})
	m.Register(&admin.RemovePoolFromSchedulerCmd{})
	m.Register(&admin.ServiceCreate{})
	m.Register(&admin.ServiceDestroy{})
	m.Register(&admin.ServiceUpdate{})
	m.Register(&admin.ServiceDocGet{})
	m.Register(&admin.ServiceDocAdd{})
	m.Register(&admin.ServiceTemplate{})
	m.Register(&admin.UserQuotaView{})
	m.Register(&admin.UserChangeQuota{})
	m.Register(&admin.AppQuotaView{})
	m.Register(&admin.AppQuotaChange{})
	m.Register(&admin.AppRoutesRebuild{})
	m.Register(&admin.PoolConstraintList{})
	m.Register(&admin.PoolConstraintSet{})
	m.Register(&admin.EventBlockList{})
	m.Register(&admin.EventBlockAdd{})
	m.Register(&admin.EventBlockRemove{})
	m.Register(&client.TagList{})
	m.Register(&admin.NodeContainerList{})
	m.Register(&admin.NodeContainerAdd{})
	m.Register(&admin.NodeContainerInfo{})
	m.Register(&admin.NodeContainerUpdate{})
	m.Register(&admin.NodeContainerDelete{})
	m.Register(&admin.NodeContainerUpgrade{})
	m.Register(&admin.ClusterAdd{})
	m.Register(&admin.ClusterUpdate{})
	m.Register(&admin.ClusterRemove{})
	m.Register(&admin.ClusterList{})
	m.Register(&client.VolumeCreate{})
	m.Register(&client.VolumeUpdate{})
	m.Register(&client.VolumeList{})
	m.Register(&client.VolumePlansList{})
	m.Register(&client.VolumeDelete{})
	m.Register(&client.VolumeBind{})
	m.Register(&client.VolumeUnbind{})
	m.RegisterRemoved("bs-env-set", "You should use `tsuru node-container-update big-sibling` instead.")
	m.RegisterRemoved("bs-info", "You should use `tsuru node-container-info big-sibling` instead.")
	m.RegisterRemoved("bs-upgrade", "You should use `tsuru node-container-upgrade big-sibling` instead.")
	m.RegisterDeprecated(&admin.AddTeamsToPoolCmd{}, "pool-teams-add")
	m.RegisterDeprecated(&admin.RemoveTeamsFromPoolCmd{}, "pool-teams-remove")
	m.RegisterDeprecated(&admin.AddNodeCmd{}, "docker-node-add")
	m.RegisterDeprecated(&admin.RemoveNodeCmd{}, "docker-node-remove")
	m.RegisterDeprecated(&admin.UpdateNodeCmd{}, "docker-node-update")
	m.RegisterDeprecated(&admin.ListNodesCmd{}, "docker-node-list")
	m.RegisterDeprecated(&admin.GetNodeHealingConfigCmd{}, "docker-healing-info")
	m.RegisterDeprecated(&admin.SetNodeHealingConfigCmd{}, "docker-healing-update")
	m.RegisterDeprecated(&admin.DeleteNodeHealingConfigCmd{}, "docker-healing-delete")
	m.RegisterDeprecated(&admin.RebalanceNodeCmd{}, "containers-rebalance")
	m.RegisterDeprecated(&admin.AutoScaleRunCmd{}, "docker-autoscale-run")
	m.RegisterDeprecated(&admin.ListAutoScaleHistoryCmd{}, "docker-autoscale-list")
	m.RegisterDeprecated(&admin.AutoScaleInfoCmd{}, "docker-autoscale-info")
	m.RegisterDeprecated(&admin.AutoScaleSetRuleCmd{}, "docker-autoscale-rule-set")
	m.RegisterDeprecated(&admin.AutoScaleDeleteRuleCmd{}, "docker-autoscale-rule-remove")
	m.RegisterDeprecated(&admin.ListHealingHistoryCmd{}, "docker-healing-list")
	registerExtraCommands(m)
	return m
}

func registerExtraCommands(m *cmd.Manager) {
	for _, c := range cmd.ExtraCmds() {
		m.Register(c)
	}
}

func inDockerMachineDriverMode() bool {
	return os.Getenv(localbinary.PluginEnvKey) == localbinary.PluginEnvVal
}

func main() {
	if inDockerMachineDriverMode() {
		err := dockermachine.RunDriver(os.Getenv(localbinary.PluginEnvDriverName))
		if err != nil {
			log.Fatalf("Error running driver: %s", err)
		}
	} else {
		localbinary.CurrentBinaryIsDockerMachine = true
		name := cmd.ExtractProgramName(os.Args[0])
		m := buildManager(name)
		m.Run(os.Args[1:])
	}
}
<commit_msg>bump version to 1.4.0-rc1<commit_after>// Copyright 2017 tsuru-client authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"log"
	"os"

	"github.com/docker/machine/libmachine/drivers/plugin/localbinary"
	"github.com/tsuru/tsuru-client/tsuru/admin"
	"github.com/tsuru/tsuru-client/tsuru/client"
	"github.com/tsuru/tsuru-client/tsuru/installer"
	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/iaas/dockermachine"
	_ "github.com/tsuru/tsuru/provision/docker/cmds"
)

const (
	version = "1.4.0-rc1"
	header  = "Supported-Tsuru"
)

func buildManager(name string) *cmd.Manager {
	lookup := func(context *cmd.Context) error {
		return client.RunPlugin(context)
	}
	m := cmd.BuildBaseManager(name, version, header, lookup)
	m.Register(&client.AppRun{})
	m.Register(&client.AppInfo{})
	m.Register(&client.AppCreate{})
	m.Register(&client.AppRemove{})
	m.Register(&client.AppUpdate{})
	m.Register(&client.UnitAdd{})
	m.Register(&client.UnitRemove{})
	m.Register(&client.AppList{})
	m.Register(&client.AppLog{})
	m.Register(&client.AppGrant{})
	m.Register(&client.AppRevoke{})
	m.Register(&client.AppRestart{})
	m.Register(&client.AppStart{})
	m.Register(&client.AppStop{})
	m.Register(&admin.AppLockDelete{})
	m.Register(&client.CertificateSet{})
	m.Register(&client.CertificateUnset{})
	m.Register(&client.CertificateList{})
	m.Register(&client.CnameAdd{})
	m.Register(&client.CnameRemove{})
	m.Register(&client.EnvGet{})
	m.Register(&client.EnvSet{})
	m.Register(&client.EnvUnset{})
	m.Register(&client.KeyAdd{})
	m.Register(&client.KeyRemove{})
	m.Register(&client.KeyList{})
	m.Register(client.ServiceList{})
	m.Register(&client.ServiceInstanceAdd{})
	m.Register(&client.ServiceInstanceUpdate{})
	m.Register(&client.ServiceInstanceRemove{})
	m.Register(client.ServiceInfo{})
	m.Register(client.ServiceInstanceInfo{})
	m.Register(client.ServiceInstanceStatus{})
	m.Register(&client.ServiceInstanceGrant{})
	m.Register(&client.ServiceInstanceRevoke{})
	m.Register(&client.ServiceInstanceBind{})
	m.Register(&client.ServiceInstanceUnbind{})
	m.Register(&admin.PlatformList{})
	m.Register(&admin.PlatformAdd{})
	m.Register(&admin.PlatformUpdate{})
	m.Register(&admin.PlatformRemove{})
	m.Register(&client.PluginInstall{})
	m.Register(&client.PluginRemove{})
	m.Register(&client.PluginList{})
	m.Register(&client.AppSwap{})
	m.Register(&client.AppDeploy{})
	m.Register(&client.PlanList{})
	m.Register(&client.UserCreate{})
	m.Register(&client.ResetPassword{})
	m.Register(&client.UserRemove{})
	m.Register(&client.ListUsers{})
	m.Register(&client.TeamCreate{})
	m.Register(&client.TeamUpdate{})
	m.Register(&client.TeamRemove{})
	m.Register(&client.TeamList{})
	m.Register(&client.ChangePassword{})
	m.Register(&client.ShowAPIToken{})
	m.Register(&client.RegenerateAPIToken{})
	m.Register(&client.AppDeployList{})
	m.Register(&client.AppDeployRollback{})
	m.Register(&client.AppDeployRollbackUpdate{})
	m.Register(&client.AppDeployRebuild{})
	m.Register(&cmd.ShellToContainerCmd{})
	m.Register(&client.PoolList{})
	m.Register(&client.PermissionList{})
	m.Register(&client.RoleAdd{})
	m.Register(&client.RoleUpdate{})
	m.Register(&client.RoleRemove{})
	m.Register(&client.RoleList{})
	m.Register(&client.RoleInfo{})
	m.Register(&client.RolePermissionAdd{})
	m.Register(&client.RolePermissionRemove{})
	m.Register(&client.RoleAssign{})
	m.Register(&client.RoleDissociate{})
	m.Register(&client.RoleDefaultAdd{})
	m.Register(&client.RoleDefaultList{})
	m.Register(&client.RoleDefaultRemove{})
	m.Register(&installer.Install{})
	m.Register(&installer.Uninstall{})
	m.Register(&installer.InstallHostList{})
	m.Register(&installer.InstallSSH{})
	m.Register(&installer.InstallConfigInit{})
	m.Register(&admin.AddPoolToSchedulerCmd{})
	m.Register(&client.EventList{})
	m.Register(&client.EventInfo{})
	m.Register(&client.EventCancel{})
	m.Register(&client.RoutersList{})
	m.Register(&admin.TemplateList{})
	m.Register(&admin.TemplateAdd{})
	m.Register(&admin.TemplateRemove{})
	m.Register(&admin.MachineList{})
	m.Register(&admin.MachineDestroy{})
	m.Register(&admin.TemplateUpdate{})
	m.Register(&admin.PlanCreate{})
	m.Register(&admin.PlanRemove{})
	m.Register(&admin.UpdatePoolToSchedulerCmd{})
	m.Register(&admin.RemovePoolFromSchedulerCmd{})
	m.Register(&admin.ServiceCreate{})
	m.Register(&admin.ServiceDestroy{})
	m.Register(&admin.ServiceUpdate{})
	m.Register(&admin.ServiceDocGet{})
	m.Register(&admin.ServiceDocAdd{})
	m.Register(&admin.ServiceTemplate{})
	m.Register(&admin.UserQuotaView{})
	m.Register(&admin.UserChangeQuota{})
	m.Register(&admin.AppQuotaView{})
	m.Register(&admin.AppQuotaChange{})
	m.Register(&admin.AppRoutesRebuild{})
	m.Register(&admin.PoolConstraintList{})
	m.Register(&admin.PoolConstraintSet{})
	m.Register(&admin.EventBlockList{})
	m.Register(&admin.EventBlockAdd{})
	m.Register(&admin.EventBlockRemove{})
	m.Register(&client.TagList{})
	m.Register(&admin.NodeContainerList{})
	m.Register(&admin.NodeContainerAdd{})
	m.Register(&admin.NodeContainerInfo{})
	m.Register(&admin.NodeContainerUpdate{})
	m.Register(&admin.NodeContainerDelete{})
	m.Register(&admin.NodeContainerUpgrade{})
	m.Register(&admin.ClusterAdd{})
	m.Register(&admin.ClusterUpdate{})
	m.Register(&admin.ClusterRemove{})
	m.Register(&admin.ClusterList{})
	m.Register(&client.VolumeCreate{})
	m.Register(&client.VolumeUpdate{})
	m.Register(&client.VolumeList{})
	m.Register(&client.VolumePlansList{})
	m.Register(&client.VolumeDelete{})
	m.Register(&client.VolumeBind{})
	m.Register(&client.VolumeUnbind{})
	m.RegisterRemoved("bs-env-set", "You should use `tsuru node-container-update big-sibling` instead.")
	m.RegisterRemoved("bs-info", "You should use `tsuru node-container-info big-sibling` instead.")
	m.RegisterRemoved("bs-upgrade", "You should use `tsuru node-container-upgrade big-sibling` instead.")
	m.RegisterDeprecated(&admin.AddTeamsToPoolCmd{}, "pool-teams-add")
	m.RegisterDeprecated(&admin.RemoveTeamsFromPoolCmd{}, "pool-teams-remove")
	m.RegisterDeprecated(&admin.AddNodeCmd{}, "docker-node-add")
	m.RegisterDeprecated(&admin.RemoveNodeCmd{}, "docker-node-remove")
	m.RegisterDeprecated(&admin.UpdateNodeCmd{}, "docker-node-update")
	m.RegisterDeprecated(&admin.ListNodesCmd{}, "docker-node-list")
	m.RegisterDeprecated(&admin.GetNodeHealingConfigCmd{}, "docker-healing-info")
	m.RegisterDeprecated(&admin.SetNodeHealingConfigCmd{}, "docker-healing-update")
	m.RegisterDeprecated(&admin.DeleteNodeHealingConfigCmd{}, "docker-healing-delete")
	m.RegisterDeprecated(&admin.RebalanceNodeCmd{}, "containers-rebalance")
	m.RegisterDeprecated(&admin.AutoScaleRunCmd{}, "docker-autoscale-run")
	m.RegisterDeprecated(&admin.ListAutoScaleHistoryCmd{}, "docker-autoscale-list")
	m.RegisterDeprecated(&admin.AutoScaleInfoCmd{}, "docker-autoscale-info")
	m.RegisterDeprecated(&admin.AutoScaleSetRuleCmd{}, "docker-autoscale-rule-set")
	m.RegisterDeprecated(&admin.AutoScaleDeleteRuleCmd{}, "docker-autoscale-rule-remove")
	m.RegisterDeprecated(&admin.ListHealingHistoryCmd{}, "docker-healing-list")
	registerExtraCommands(m)
	return m
}

func registerExtraCommands(m *cmd.Manager) {
	for _, c := range cmd.ExtraCmds() {
		m.Register(c)
	}
}

func inDockerMachineDriverMode() bool {
	return os.Getenv(localbinary.PluginEnvKey) == localbinary.PluginEnvVal
}

func main() {
	if inDockerMachineDriverMode() {
		err := dockermachine.RunDriver(os.Getenv(localbinary.PluginEnvDriverName))
		if err != nil {
			log.Fatalf("Error running driver: %s", err)
		}
	} else {
		localbinary.CurrentBinaryIsDockerMachine = true
		name := cmd.ExtractProgramName(os.Args[0])
		m := buildManager(name)
		m.Run(os.Args[1:])
	}
}
<|endoftext|>


<commit_before>package main

import (
  "time"
  "code.google.com/p/go.net/websocket"
  "os"
  "github.com/arschles/eiger/lib/util"
  "github.com/arschles/eiger/lib/messages"
  "fmt"
  "log"
)

//this is the modulo for heartbeat messages.
//TODO: make this configurable
const HBMOD = 10

func heartbeatLoop(wsConn *websocket.Conn, interval time.Duration, diedCh chan<- error) {
  hostname, err := os.Hostname()
  if err != nil {
    diedCh <- err
    return
  }

  hbNum := 0
  for {
    msg := messages.Heartbeat{hostname, time.Now()}
    if hbNum % HBMOD == 0 {
      log.Printf("sending heartbeat message %s", msg)
    }
    hbNum++

    err := websocket.JSON.Send(wsConn, msg)
    //TODO: backoff or fail if the heartbeat loop keeps erroring
    if err != nil {
      util.LogWarnf("(error heartbeating) %s", err)
    }

    time.Sleep(interval)
  }
  diedCh <- fmt.Errorf("heartbeat loop stopped")
}
<commit_msg>adding heartbeat number<commit_after>package main

import (
  "time"
  "code.google.com/p/go.net/websocket"
  "os"
  "github.com/arschles/eiger/lib/util"
  "github.com/arschles/eiger/lib/messages"
  "fmt"
  "log"
)

//this is the modulo for heartbeat messages.
//TODO: make this configurable
const HBMOD = 10

func heartbeatLoop(wsConn *websocket.Conn, interval time.Duration, diedCh chan<- error) {
  hostname, err := os.Hostname()
  if err != nil {
    diedCh <- err
    return
  }

  hbNum := 0
  for {
    msg := messages.Heartbeat{hostname, time.Now()}
    if hbNum % HBMOD == 0 {
      log.Printf("sending heartbeat message %s (%d)", msg, hbNum)
    }
    hbNum++

    err := websocket.JSON.Send(wsConn, msg)
    //TODO: backoff or fail if the heartbeat loop keeps erroring
    if err != nil {
      util.LogWarnf("(error heartbeating) %s", err)
    }

    time.Sleep(interval)
  }
  diedCh <- fmt.Errorf("heartbeat loop stopped")
}
<|endoftext|>