<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/mq"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSMqConfiguration_basic(t *testing.T) {
	configurationName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsMqConfigurationDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccMqConfigurationConfig(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttrSet("aws_mq_configuration.test", "arn"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "description", "TfAccTest MQ Configuration"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_type", "ActiveMQ"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_version", "5.15.0"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "latest_revision", "2"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "name", configurationName),
				),
			},
			{
				Config: testAccMqConfigurationConfig_descriptionUpdated(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttrSet("aws_mq_configuration.test", "arn"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "description", "TfAccTest MQ Configuration Updated"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_type", "ActiveMQ"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_version", "5.15.0"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "latest_revision", "3"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "name", configurationName),
				),
			},
		},
	})
}

func TestAccAWSMqConfiguration_withData(t *testing.T) {
	configurationName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsMqConfigurationDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccMqConfigurationWithDataConfig(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttrSet("aws_mq_configuration.test", "arn"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "description", "TfAccTest MQ Configuration"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_type", "ActiveMQ"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_version", "5.15.0"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "latest_revision", "2"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "name", configurationName),
				),
			},
		},
	})
}

func TestAccAWSMqConfiguration_updateTags(t *testing.T) {
	configurationName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsMqConfigurationDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccMqConfigurationConfig_updateTags1(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.%", "1"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.env", "test"),
				),
			},
			{
				Config: testAccMqConfigurationConfig_updateTags2(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.%", "2"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.env", "test2"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.role", "test-role"),
				),
			},
			{
				Config: testAccMqConfigurationConfig_updateTags3(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.%", "1"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.role", "test-role"),
				),
			},
		},
	})
}

func testAccCheckAwsMqConfigurationDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).mqconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_mq_configuration" {
			continue
		}

		input := &mq.DescribeConfigurationInput{
			ConfigurationId: aws.String(rs.Primary.ID),
		}

		_, err := conn.DescribeConfiguration(input)
		if err != nil {
			if isAWSErr(err, "NotFoundException", "") {
				return nil
			}
			return err
		}

		// TODO: Delete is not available in the API
		return nil
		//return fmt.Errorf("Expected MQ configuration to be destroyed, %s found", rs.Primary.ID)
	}

	return nil
}

func testAccCheckAwsMqConfigurationExists(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		_, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		return nil
	}
}

func testAccMqConfigurationConfig(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
</broker>
DATA
}`, configurationName)
}

func testAccMqConfigurationConfig_descriptionUpdated(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration Updated"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
</broker>
DATA
}`, configurationName)
}

func testAccMqConfigurationWithDataConfig(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
  <plugins>
    <authorizationPlugin>
      <map>
        <authorizationMap>
          <authorizationEntries>
            <authorizationEntry admin="guests,users" queue="GUEST.>" read="guests" write="guests,users"/>
            <authorizationEntry admin="guests,users" read="guests,users" topic="ActiveMQ.Advisory.>" write="guests,users"/>
          </authorizationEntries>
          <tempDestinationAuthorizationEntry>
            <tempDestinationAuthorizationEntry admin="tempDestinationAdmins" read="tempDestinationAdmins" write="tempDestinationAdmins"/>
          </tempDestinationAuthorizationEntry>
        </authorizationMap>
      </map>
    </authorizationPlugin>
    <forcePersistencyModeBrokerPlugin persistenceFlag="true"/>
    <statisticsBrokerPlugin/>
    <timeStampingBrokerPlugin ttlCeiling="86400000" zeroExpirationOverride="86400000"/>
  </plugins>
</broker>
DATA
}`, configurationName)
}

func testAccMqConfigurationConfig_updateTags1(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
</broker>
DATA

	tags {
		env = "test"
	}
}`, configurationName)
}

func testAccMqConfigurationConfig_updateTags2(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
</broker>
DATA

	tags {
		env = "test2"
		role = "test-role"
	}
}`, configurationName)
}

func testAccMqConfigurationConfig_updateTags3(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
</broker>
DATA

	tags {
		role = "test-role"
	}
}`, configurationName)
}
<commit_msg>tests/resource/aws_mq_configuration: Ensure tags configurations use equals<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/mq"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSMqConfiguration_basic(t *testing.T) {
	configurationName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsMqConfigurationDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccMqConfigurationConfig(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttrSet("aws_mq_configuration.test", "arn"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "description", "TfAccTest MQ Configuration"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_type", "ActiveMQ"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_version", "5.15.0"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "latest_revision", "2"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "name", configurationName),
				),
			},
			{
				Config: testAccMqConfigurationConfig_descriptionUpdated(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttrSet("aws_mq_configuration.test", "arn"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "description", "TfAccTest MQ Configuration Updated"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_type", "ActiveMQ"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_version", "5.15.0"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "latest_revision", "3"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "name", configurationName),
				),
			},
		},
	})
}

func TestAccAWSMqConfiguration_withData(t *testing.T) {
	configurationName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsMqConfigurationDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccMqConfigurationWithDataConfig(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttrSet("aws_mq_configuration.test", "arn"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "description", "TfAccTest MQ Configuration"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_type", "ActiveMQ"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "engine_version", "5.15.0"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "latest_revision", "2"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "name", configurationName),
				),
			},
		},
	})
}

func TestAccAWSMqConfiguration_updateTags(t *testing.T) {
	configurationName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5))

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsMqConfigurationDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccMqConfigurationConfig_updateTags1(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.%", "1"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.env", "test"),
				),
			},
			{
				Config: testAccMqConfigurationConfig_updateTags2(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.%", "2"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.env", "test2"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.role", "test-role"),
				),
			},
			{
				Config: testAccMqConfigurationConfig_updateTags3(configurationName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsMqConfigurationExists("aws_mq_configuration.test"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.%", "1"),
					resource.TestCheckResourceAttr("aws_mq_configuration.test", "tags.role", "test-role"),
				),
			},
		},
	})
}

func testAccCheckAwsMqConfigurationDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).mqconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_mq_configuration" {
			continue
		}

		input := &mq.DescribeConfigurationInput{
			ConfigurationId: aws.String(rs.Primary.ID),
		}

		_, err := conn.DescribeConfiguration(input)
		if err != nil {
			if isAWSErr(err, "NotFoundException", "") {
				return nil
			}
			return err
		}

		// TODO: Delete is not available in the API
		return nil
		//return fmt.Errorf("Expected MQ configuration to be destroyed, %s found", rs.Primary.ID)
	}

	return nil
}

func testAccCheckAwsMqConfigurationExists(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		_, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		return nil
	}
}

func testAccMqConfigurationConfig(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
</broker>
DATA
}`, configurationName)
}

func testAccMqConfigurationConfig_descriptionUpdated(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration Updated"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
</broker>
DATA
}`, configurationName)
}

func testAccMqConfigurationWithDataConfig(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
  <plugins>
    <authorizationPlugin>
      <map>
        <authorizationMap>
          <authorizationEntries>
            <authorizationEntry admin="guests,users" queue="GUEST.>" read="guests" write="guests,users"/>
            <authorizationEntry admin="guests,users" read="guests,users" topic="ActiveMQ.Advisory.>" write="guests,users"/>
          </authorizationEntries>
          <tempDestinationAuthorizationEntry>
            <tempDestinationAuthorizationEntry admin="tempDestinationAdmins" read="tempDestinationAdmins" write="tempDestinationAdmins"/>
          </tempDestinationAuthorizationEntry>
        </authorizationMap>
      </map>
    </authorizationPlugin>
    <forcePersistencyModeBrokerPlugin persistenceFlag="true"/>
    <statisticsBrokerPlugin/>
    <timeStampingBrokerPlugin ttlCeiling="86400000" zeroExpirationOverride="86400000"/>
  </plugins>
</broker>
DATA
}`, configurationName)
}

func testAccMqConfigurationConfig_updateTags1(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
</broker>
DATA

	tags = {
		env = "test"
	}
}`, configurationName)
}

func testAccMqConfigurationConfig_updateTags2(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
</broker>
DATA

	tags = {
		env = "test2"
		role = "test-role"
	}
}`, configurationName)
}

func testAccMqConfigurationConfig_updateTags3(configurationName string) string {
	return fmt.Sprintf(`
resource "aws_mq_configuration" "test" {
  description = "TfAccTest MQ Configuration"
  name = "%s"
  engine_type = "ActiveMQ"
  engine_version = "5.15.0"
  data = <<DATA
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<broker xmlns="http://activemq.apache.org/schema/core">
</broker>
DATA

	tags = {
		role = "test-role"
	}
}`, configurationName)
}
<|endoftext|>


<commit_before>package client

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func EnvAsHeader(req *http.Request, selectedEnv []string) {
	detectedEnv := os.Environ()
	if len(selectedEnv) > 0 {
		detectedEnv = selectedEnv
	}

	for _, e := range detectedEnv {
		kv := strings.Split(e, "=")
		name := kv[0]
		req.Header.Set(name, os.Getenv(name))
	}
}

type apiErr struct {
	Message string `json:"message"`
}

type callID struct {
	CallID string `json:"call_id"`
	Error  apiErr `json:"error"`
}

func CallFN(u string, content io.Reader, output io.Writer, method string, env []string) error {
	if method == "" {
		if content == nil {
			method = "GET"
		} else {
			method = "POST"
		}
	}

	req, err := http.NewRequest(method, u, content)
	if err != nil {
		return fmt.Errorf("error running route: %s", err)
	}

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

	if len(env) > 0 {
		EnvAsHeader(req, env)
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return fmt.Errorf("error running route: %s", err)
	}
	if call_id, found := resp.Header["Fn_call_id"]; found {
		fmt.Fprint(output, fmt.Sprintf("Call ID: %v\n", call_id[0]))
		io.Copy(output, resp.Body)
	} else {
		c := &callID{}
		json.NewDecoder(resp.Body).Decode(c)
		if c.CallID != "" {
			fmt.Fprint(output, fmt.Sprintf("Call ID: %v\n", c.CallID))
		} else {
			fmt.Fprint(output, fmt.Sprintf("Error: %v\n", c.Error.Message))
		}
	}

	if resp.StatusCode >= 400 {
		// TODO: parse out error message
		return fmt.Errorf("error calling function: status %v", resp.StatusCode)
	}

	return nil
}
<commit_msg>Addressing comments<commit_after>package client

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

const FN_CALL_ID = "Fn_call_id"

func EnvAsHeader(req *http.Request, selectedEnv []string) {
	detectedEnv := os.Environ()
	if len(selectedEnv) > 0 {
		detectedEnv = selectedEnv
	}

	for _, e := range detectedEnv {
		kv := strings.Split(e, "=")
		name := kv[0]
		req.Header.Set(name, os.Getenv(name))
	}
}

type apiErr struct {
	Message string `json:"message"`
}

type callID struct {
	CallID string `json:"call_id"`
	Error  apiErr `json:"error"`
}

func CallFN(u string, content io.Reader, output io.Writer, method string, env []string) error {
	if method == "" {
		if content == nil {
			method = "GET"
		} else {
			method = "POST"
		}
	}

	req, err := http.NewRequest(method, u, content)
	if err != nil {
		return fmt.Errorf("error running route: %s", err)
	}

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

	if len(env) > 0 {
		EnvAsHeader(req, env)
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return fmt.Errorf("error running route: %s", err)
	}
	// for sync calls
	if call_id, found := resp.Header[FN_CALL_ID]; found {
		fmt.Fprint(output, fmt.Sprintf("Call ID: %v\n", call_id[0]))
		io.Copy(output, resp.Body)
	} else {
		// for async calls and error discovering
		c := &callID{}
		err = json.NewDecoder(resp.Body).Decode(c)
		if err == nil {
			// decode would not fail in both cases:
			// - call id in body
			// - error in body
			// that's why we need to check values of attributes
			if c.CallID != "" {
				fmt.Fprint(output, fmt.Sprintf("Call ID: %v\n", c.CallID))
			} else {
				fmt.Fprint(output, fmt.Sprintf("Error: %v\n", c.Error.Message))
			}
		} else {
			return err
		}
	}

	if resp.StatusCode >= 400 {
		// TODO: parse out error message
		return fmt.Errorf("error calling function: status %v", resp.StatusCode)
	}

	return nil
}
<|endoftext|>


<commit_before>package cli

import (
	"fmt"
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/go-utils/colorstring"
	"github.com/bitrise-io/go-utils/pathutil"
	"github.com/bitrise-io/goinp/goinp"
	"github.com/bitrise-tools/releaseman/git"
	"github.com/bitrise-tools/releaseman/releaseman"
	"github.com/codegangsta/cli"
)

//=======================================
// Utility
//=======================================

func collectConfigParams(config releaseman.Config, c *cli.Context) (releaseman.Config, error) {
	var err error

	//
	// Fill development branch
	if config, err = fillDevelopmetnBranch(config, c); err != nil {
		return releaseman.Config{}, err
	}

	//
	// Ensure current branch
	if err := ensureCurrentBranch(config); err != nil {
		return releaseman.Config{}, err
	}

	//
	// Fill release branch
	if config, err = fillReleaseBranch(config, c); err != nil {
		return releaseman.Config{}, err
	}

	//
	// Fill release version
	if config, err = fillVersion(config, c); err != nil {
		return releaseman.Config{}, err
	}

	//
	// Fill changelog path
	if config, err = fillChangelogPath(config, c); err != nil {
		return releaseman.Config{}, err
	}

	return config, nil
}

//=======================================
// Main
//=======================================

func create(c *cli.Context) {
	//
	// Fail if git is not clean
	if err := ensureCleanGit(); err != nil {
		log.Fatalf("Ensure clean git failed, error: %#v", err)
	}

	//
	// Build config
	config := releaseman.Config{}
	configPath := ""
	if c.IsSet("config") {
		configPath = c.String("config")
	} else {
		configPath = releaseman.DefaultConfigPth
	}

	if exist, err := pathutil.IsPathExists(configPath); err != nil {
		log.Warnf("Failed to check if path exist, error: %#v", err)
	} else if exist {
		config, err = releaseman.NewConfigFromFile(configPath)
		if err != nil {
			log.Fatalf("Failed to parse release config at (%s), error: %#v", configPath, err)
		}
	}

	config, err := collectConfigParams(config, c)
	if err != nil {
		log.Fatalf("Failed to collect config params, error: %#v", err)
	}

	printRollBackMessage()

	//
	// Validate config
	config.Print(releaseman.FullMode)

	if !releaseman.IsCIMode {
		ok, err := goinp.AskForBool("Are you ready for release?")
		if err != nil {
			log.Fatalf("Failed to ask for input, error: %s", err)
		}
		if !ok {
			log.Fatal("Aborted release")
		}
	}

	//
	// Run set version script
	if c.IsSet(SetVersionScriptKey) {
		setVersionScript := c.String(SetVersionScriptKey)
		if err := runSetVersionScript(setVersionScript, config.Release.Version); err != nil {
			log.Fatalf("Failed to run set version script, error: %#v", err)
		}
	}

	//
	// Generate Changelog
	startCommit, err := git.FirstCommit()
	if err != nil {
		log.Fatalf("Failed to get first commit, error: %#v", err)
	}

	endCommit, err := git.LatestCommit()
	if err != nil {
		log.Fatalf("Failed to get latest commit, error: %#v", err)
	}

	taggedCommits, err := git.TaggedCommits()
	if err != nil {
		log.Fatalf("Failed to get tagged commits, error: %#v", err)
	}

	startDate := startCommit.Date
	endDate := endCommit.Date
	relevantTags := taggedCommits
	appendChangelog := false

	if config.Changelog.Path != "" {
		if exist, err := pathutil.IsPathExists(config.Changelog.Path); err != nil {
			log.Fatalf("Failed to check if path exist, error: %#v", err)
		} else if exist {
			if len(taggedCommits) > 0 {
				startCommit = taggedCommits[len(taggedCommits)-1]
				startDate = startCommit.Date
				relevantTags = []git.CommitModel{startCommit}
				appendChangelog = true
			}
		}
	}

	printCollectingCommits(startCommit, config.Release.Version)

	fmt.Println()
	log.Infof("=> Generating changelog...")
	commits, err := git.GetCommitsBetween(startDate, endDate)
	if err != nil {
		log.Fatalf("Failed to get commits, error: %#v", err)
	}
	if err := releaseman.WriteChangelog(commits, relevantTags, config, appendChangelog); err != nil {
		log.Fatalf("Failed to write changelog, error: %#v", err)
	}

	//
	// Create release git changes
	fmt.Println()
	log.Infof("=> Adding changes to git...")
	changes, err := git.GetChangedFiles()
	if err != nil {
		log.Fatalf("Failed to get changes, error: %s", err)
	}
	log.Infof("Changes: %#v", changes)
	os.Exit(1)

	if err := git.Add(changes); err != nil {
		log.Fatalf("Failed to git add, error: %s", err)
	}
	if err := git.Commit(fmt.Sprintf("v%s", config.Release.Version)); err != nil {
		log.Fatalf("Failed to git commit, error: %s", err)
	}

	fmt.Println()
	log.Infof("=> Merging changes into release branch...")
	if err := git.CheckoutBranch(config.Release.ReleaseBranch); err != nil {
		log.Fatalf("Failed to git checkout, error: %s", err)
	}
	mergeCommitMessage := fmt.Sprintf("Merge %s into %s, release: v%s", config.Release.DevelopmentBranch, config.Release.ReleaseBranch, config.Release.Version)
	if err := git.Merge(config.Release.DevelopmentBranch, mergeCommitMessage); err != nil {
		log.Fatalf("Failed to git merge, error: %s", err)
	}

	fmt.Println()
	log.Infof("=> Tagging release branch...")
	if err := git.Tag(config.Release.Version); err != nil {
		log.Fatalf("Failed to git tag, error: %s", err)
	}
	if err := git.CheckoutBranch(config.Release.DevelopmentBranch); err != nil {
		log.Fatalf("Failed to git checkout, error: %s", err)
	}

	fmt.Println()
	log.Infoln(colorstring.Greenf("v%s released 🚀", config.Release.Version))
	log.Infoln("Take a look at your git, and if you are happy with the release, push the changes.")
}
<commit_msg>temp rollback<commit_after>package cli

import (
	"fmt"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/go-utils/colorstring"
	"github.com/bitrise-io/go-utils/pathutil"
	"github.com/bitrise-io/goinp/goinp"
	"github.com/bitrise-tools/releaseman/git"
	"github.com/bitrise-tools/releaseman/releaseman"
	"github.com/codegangsta/cli"
)

//=======================================
// Utility
//=======================================

func collectConfigParams(config releaseman.Config, c *cli.Context) (releaseman.Config, error) {
	var err error

	//
	// Fill development branch
	if config, err = fillDevelopmetnBranch(config, c); err != nil {
		return releaseman.Config{}, err
	}

	//
	// Ensure current branch
	if err := ensureCurrentBranch(config); err != nil {
		return releaseman.Config{}, err
	}

	//
	// Fill release branch
	if config, err = fillReleaseBranch(config, c); err != nil {
		return releaseman.Config{}, err
	}

	//
	// Fill release version
	if config, err = fillVersion(config, c); err != nil {
		return releaseman.Config{}, err
	}

	//
	// Fill changelog path
	if config, err = fillChangelogPath(config, c); err != nil {
		return releaseman.Config{}, err
	}

	return config, nil
}

//=======================================
// Main
//=======================================

func create(c *cli.Context) {
	//
	// Fail if git is not clean
	if err := ensureCleanGit(); err != nil {
		log.Fatalf("Ensure clean git failed, error: %#v", err)
	}

	//
	// Build config
	config := releaseman.Config{}
	configPath := ""
	if c.IsSet("config") {
		configPath = c.String("config")
	} else {
		configPath = releaseman.DefaultConfigPth
	}

	if exist, err := pathutil.IsPathExists(configPath); err != nil {
		log.Warnf("Failed to check if path exist, error: %#v", err)
	} else if exist {
		config, err = releaseman.NewConfigFromFile(configPath)
		if err != nil {
			log.Fatalf("Failed to parse release config at (%s), error: %#v", configPath, err)
		}
	}

	config, err := collectConfigParams(config, c)
	if err != nil {
		log.Fatalf("Failed to collect config params, error: %#v", err)
	}

	printRollBackMessage()

	//
	// Validate config
	config.Print(releaseman.FullMode)

	if !releaseman.IsCIMode {
		ok, err := goinp.AskForBool("Are you ready for release?")
		if err != nil {
			log.Fatalf("Failed to ask for input, error: %s", err)
		}
		if !ok {
			log.Fatal("Aborted release")
		}
	}

	//
	// Run set version script
	if c.IsSet(SetVersionScriptKey) {
		setVersionScript := c.String(SetVersionScriptKey)
		if err := runSetVersionScript(setVersionScript, config.Release.Version); err != nil {
			log.Fatalf("Failed to run set version script, error: %#v", err)
		}
	}

	//
	// Generate Changelog
	startCommit, err := git.FirstCommit()
	if err != nil {
		log.Fatalf("Failed to get first commit, error: %#v", err)
	}

	endCommit, err := git.LatestCommit()
	if err != nil {
		log.Fatalf("Failed to get latest commit, error: %#v", err)
	}

	taggedCommits, err := git.TaggedCommits()
	if err != nil {
		log.Fatalf("Failed to get tagged commits, error: %#v", err)
	}

	startDate := startCommit.Date
	endDate := endCommit.Date
	relevantTags := taggedCommits
	appendChangelog := false

	if config.Changelog.Path != "" {
		if exist, err := pathutil.IsPathExists(config.Changelog.Path); err != nil {
			log.Fatalf("Failed to check if path exist, error: %#v", err)
		} else if exist {
			if len(taggedCommits) > 0 {
				startCommit = taggedCommits[len(taggedCommits)-1]
				startDate = startCommit.Date
				relevantTags = []git.CommitModel{startCommit}
				appendChangelog = true
			}
		}
	}

	printCollectingCommits(startCommit, config.Release.Version)

	fmt.Println()
	log.Infof("=> Generating changelog...")
	commits, err := git.GetCommitsBetween(startDate, endDate)
	if err != nil {
		log.Fatalf("Failed to get commits, error: %#v", err)
	}
	if err := releaseman.WriteChangelog(commits, relevantTags, config, appendChangelog); err != nil {
		log.Fatalf("Failed to write changelog, error: %#v", err)
	}

	//
	// Create release git changes
	fmt.Println()
	log.Infof("=> Adding changes to git...")
	changes, err := git.GetChangedFiles()
	if err != nil {
		log.Fatalf("Failed to get changes, error: %s", err)
	}
	if err := git.Add(changes); err != nil {
		log.Fatalf("Failed to git add, error: %s", err)
	}
	if err := git.Commit(fmt.Sprintf("v%s", config.Release.Version)); err != nil {
		log.Fatalf("Failed to git commit, error: %s", err)
	}

	fmt.Println()
	log.Infof("=> Merging changes into release branch...")
	if err := git.CheckoutBranch(config.Release.ReleaseBranch); err != nil {
		log.Fatalf("Failed to git checkout, error: %s", err)
	}
	mergeCommitMessage := fmt.Sprintf("Merge %s into %s, release: v%s", config.Release.DevelopmentBranch, config.Release.ReleaseBranch, config.Release.Version)
	if err := git.Merge(config.Release.DevelopmentBranch, mergeCommitMessage); err != nil {
		log.Fatalf("Failed to git merge, error: %s", err)
	}

	fmt.Println()
	log.Infof("=> Tagging release branch...")
	if err := git.Tag(config.Release.Version); err != nil {
		log.Fatalf("Failed to git tag, error: %s", err)
	}
	if err := git.CheckoutBranch(config.Release.DevelopmentBranch); err != nil {
		log.Fatalf("Failed to git checkout, error: %s", err)
	}

	fmt.Println()
	log.Infoln(colorstring.Greenf("v%s released 🚀", config.Release.Version))
	log.Infoln("Take a look at your git, and if you are happy with the release, push the changes.")
}
<|endoftext|>


<commit_before>package operators

import (
	"fmt"
	"strings"

	. "github.com/onsi/ginkgo"

	exutil "github.com/openshift/origin/test/extended/util"
	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/sets"
	e2e "k8s.io/kubernetes/test/e2e/framework"
)

var _ = Describe("[Feature:Platform][Smoke] Managed cluster should", func() {
	oc := exutil.NewCLIWithoutNamespace("operators")

	It("ensure control plane pods do not run in best-effort QoS", func() {
		// iterate over the references to find valid images
		pods, err := oc.KubeFramework().ClientSet.CoreV1().Pods("").List(metav1.ListOptions{})
		if err != nil {
			e2e.Failf("unable to list pods: %v", err)
		}

		// list of pods that use images not in the release payload
		invalidPodQoS := sets.NewString()
		// a pod in a namespace that begins with kube-* or openshift-* must come from our release payload
		// TODO components in openshift-operators may not come from our payload, may want to weaken restriction
		namespacePrefixes := sets.NewString("kube-", "openshift-")
		excludeNamespaces := sets.NewString("openshift-marketplace", "openshift-operator-lifecycle-manager", "openshift-monitoring")
		excludePodPrefix := sets.NewString("revision-pruner-", "installer-")
		for _, pod := range pods.Items {
			// exclude non-control plane namespaces
			if !hasPrefixSet(pod.Namespace, namespacePrefixes) {
				continue
			}
			if excludeNamespaces.Has(pod.Namespace) {
				continue
			}
			if hasPrefixSet(pod.Name, excludePodPrefix) {
				continue
			}
			if pod.Status.QOSClass == v1.PodQOSBestEffort {
				invalidPodQoS.Insert(fmt.Sprintf("%s/%s is running in best-effort QoS", pod.Namespace, pod.Name))
			}
		}
		numInvalidPodQoS := len(invalidPodQoS)
		if numInvalidPodQoS > 0 {
			e2e.Failf("\n%d pods found in best-effort QoS:\n%s", numInvalidPodQoS, strings.Join(invalidPodQoS.List(), "\n"))
		}
	})
})
<commit_msg>tests/extended: remove openshift-monitoring from QoS check exclusion list<commit_after>package operators

import (
	"fmt"
	"strings"

	. "github.com/onsi/ginkgo"

	exutil "github.com/openshift/origin/test/extended/util"
	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/sets"
	e2e "k8s.io/kubernetes/test/e2e/framework"
)

var _ = Describe("[Feature:Platform][Smoke] Managed cluster should", func() {
	oc := exutil.NewCLIWithoutNamespace("operators")

	It("ensure control plane pods do not run in best-effort QoS", func() {
		// iterate over the references to find valid images
		pods, err := oc.KubeFramework().ClientSet.CoreV1().Pods("").List(metav1.ListOptions{})
		if err != nil {
			e2e.Failf("unable to list pods: %v", err)
		}

		// list of pods that use images not in the release payload
		invalidPodQoS := sets.NewString()
		// a pod in a namespace that begins with kube-* or openshift-* must come from our release payload
		// TODO components in openshift-operators may not come from our payload, may want to weaken restriction
		namespacePrefixes := sets.NewString("kube-", "openshift-")
		excludeNamespaces := sets.NewString("openshift-marketplace", "openshift-operator-lifecycle-manager")
		excludePodPrefix := sets.NewString("revision-pruner-", "installer-")
		for _, pod := range pods.Items {
			// exclude non-control plane namespaces
			if !hasPrefixSet(pod.Namespace, namespacePrefixes) {
				continue
			}
			if excludeNamespaces.Has(pod.Namespace) {
				continue
			}
			if hasPrefixSet(pod.Name, excludePodPrefix) {
				continue
			}
			if pod.Status.QOSClass == v1.PodQOSBestEffort {
				invalidPodQoS.Insert(fmt.Sprintf("%s/%s is running in best-effort QoS", pod.Namespace, pod.Name))
			}
		}
		numInvalidPodQoS := len(invalidPodQoS)
		if numInvalidPodQoS > 0 {
			e2e.Failf("\n%d pods found in best-effort QoS:\n%s", numInvalidPodQoS, strings.Join(invalidPodQoS.List(), "\n"))
		}
	})
})
<|endoftext|>


<commit_before>package util

import (
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/onsi/ginkgo/config"
	"github.com/onsi/ginkgo/reporters/stenographer"
	"github.com/onsi/ginkgo/types"
)

const maxDescriptionLength = 100

type SimpleReporter struct {
	stenographer stenographer.Stenographer
	Output       io.Writer
}

func NewSimpleReporter() *SimpleReporter {
	return &SimpleReporter{
		Output:       os.Stdout,
		stenographer: stenographer.New(!config.DefaultReporterConfig.NoColor),
	}
}

func (r *SimpleReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
	fmt.Fprintf(r.Output, "=== SUITE %s (%d total specs, %d will run):\n", summary.SuiteDescription, summary.NumberOfTotalSpecs, summary.NumberOfSpecsThatWillBeRun)
}

func (r *SimpleReporter) BeforeSuiteDidRun(*types.SetupSummary) {
}

func (r *SimpleReporter) SpecWillRun(spec *types.SpecSummary) {
	r.printRunLine(spec)
}

func (r *SimpleReporter) SpecDidComplete(spec *types.SpecSummary) {
	r.handleSpecFailure(spec)
	r.printStatusLine(spec)
}

func (r *SimpleReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {
}

func (r *SimpleReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
}

func (r *SimpleReporter) handleSpecFailure(spec *types.SpecSummary) {
	switch spec.State {
	case types.SpecStateFailed:
		r.stenographer.AnnounceSpecFailed(spec, true, false)
	case types.SpecStatePanicked:
		r.stenographer.AnnounceSpecPanicked(spec, true, false)
	case types.SpecStateTimedOut:
		r.stenographer.AnnounceSpecTimedOut(spec, true, false)
	}
}

func (r *SimpleReporter) printStatusLine(spec *types.SpecSummary) {
	runTime := ""
	if runTime = fmt.Sprintf(" (%v)", spec.RunTime); runTime == " (0)" {
		runTime = ""
	}
	fmt.Fprintf(r.Output, "%4s%-16s %s%s\n", " ", stateToString(spec.State), specDescription(spec), runTime)
}

func (r *SimpleReporter) printRunLine(spec *types.SpecSummary) {
	fmt.Fprintf(r.Output, "=== RUN %s:\n", trimLocation(spec.ComponentCodeLocations[1]))
}

func specDescription(spec *types.SpecSummary) string {
	name := ""
	for _, t := range spec.ComponentTexts[1:len(spec.ComponentTexts)] {
		name += strings.TrimSpace(t) + " "
	}
	if len(name) == 0 {
		name = fmt.Sprintf("FIXME: Spec without valid name (%s)", spec.ComponentTexts)
	}
	return short(strings.TrimSpace(name))
}

func short(s string) string {
	runes := []rune(s)
	if len(runes) > maxDescriptionLength {
		return string(runes[:maxDescriptionLength]) + " ..."
	}
	return s
}

func bold(v string) string {
	return "\033[1m" + v + "\033[0m"
}

func red(v string) string {
	return "\033[31m" + v + "\033[0m"
}

func magenta(v string) string {
	return "\033[35m" + v + "\033[0m"
}

func stateToString(s types.SpecState) string {
	switch s {
	case types.SpecStatePassed:
		return bold("ok")
	case types.SpecStateSkipped:
		return magenta("skip")
	case types.SpecStateFailed:
		return red("fail")
	case types.SpecStateTimedOut:
		return red("timed")
	case types.SpecStatePanicked:
		return red("panic")
	case types.SpecStatePending:
		return magenta("pending")
	default:
		return bold(fmt.Sprintf("%v", s))
	}
}

func trimLocation(l types.CodeLocation) string {
	delimiter := "/openshift/origin/"
	return fmt.Sprintf("%q", l.FileName[strings.LastIndex(l.FileName, delimiter)+len(delimiter):])
}
<commit_msg>React to ginkgo changes<commit_after>package util

import (
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/onsi/ginkgo/config"
	"github.com/onsi/ginkgo/reporters/stenographer"
	"github.com/onsi/ginkgo/types"
)

const maxDescriptionLength = 100

type SimpleReporter struct {
	stenographer stenographer.Stenographer
	Output       io.Writer
}

func NewSimpleReporter() *SimpleReporter {
	return &SimpleReporter{
		Output:       os.Stdout,
		stenographer: stenographer.New(!config.DefaultReporterConfig.NoColor, false),
	}
}

func (r *SimpleReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
	fmt.Fprintf(r.Output, "=== SUITE %s (%d total specs, %d will run):\n", summary.SuiteDescription, summary.NumberOfTotalSpecs, summary.NumberOfSpecsThatWillBeRun)
}

func (r *SimpleReporter) BeforeSuiteDidRun(*types.SetupSummary) {
}

func (r *SimpleReporter) SpecWillRun(spec *types.SpecSummary) {
	r.printRunLine(spec)
}

func (r *SimpleReporter) SpecDidComplete(spec *types.SpecSummary) {
	r.handleSpecFailure(spec)
	r.printStatusLine(spec)
}

func (r *SimpleReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {
}

func (r *SimpleReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
}

func (r *SimpleReporter) handleSpecFailure(spec *types.SpecSummary) {
	switch spec.State {
	case types.SpecStateFailed:
		r.stenographer.AnnounceSpecFailed(spec, true, false)
	case types.SpecStatePanicked:
		r.stenographer.AnnounceSpecPanicked(spec, true, false)
	case types.SpecStateTimedOut:
		r.stenographer.AnnounceSpecTimedOut(spec, true, false)
	}
}

func (r *SimpleReporter) printStatusLine(spec *types.SpecSummary) {
	runTime := ""
	if runTime = fmt.Sprintf(" (%v)", spec.RunTime); runTime == " (0)" {
		runTime = ""
	}
	fmt.Fprintf(r.Output, "%4s%-16s %s%s\n", " ", stateToString(spec.State), specDescription(spec), runTime)
}

func (r *SimpleReporter) printRunLine(spec *types.SpecSummary) {
	fmt.Fprintf(r.Output, "=== RUN %s:\n", trimLocation(spec.ComponentCodeLocations[1]))
}

func specDescription(spec *types.SpecSummary) string {
	name := ""
	for _, t := range spec.ComponentTexts[1:len(spec.ComponentTexts)] {
		name += strings.TrimSpace(t) + " "
	}
	if len(name) == 0 {
		name = fmt.Sprintf("FIXME: Spec without valid name (%s)", spec.ComponentTexts)
	}
	return short(strings.TrimSpace(name))
}

func short(s string) string {
	runes := []rune(s)
	if len(runes) > maxDescriptionLength {
		return string(runes[:maxDescriptionLength]) + " ..."
	}
	return s
}

func bold(v string) string {
	return "\033[1m" + v + "\033[0m"
}

func red(v string) string {
	return "\033[31m" + v + "\033[0m"
}

func magenta(v string) string {
	return "\033[35m" + v + "\033[0m"
}

func stateToString(s types.SpecState) string {
	switch s {
	case types.SpecStatePassed:
		return bold("ok")
	case types.SpecStateSkipped:
		return magenta("skip")
	case types.SpecStateFailed:
		return red("fail")
	case types.SpecStateTimedOut:
		return red("timed")
	case types.SpecStatePanicked:
		return red("panic")
	case types.SpecStatePending:
		return magenta("pending")
	default:
		return bold(fmt.Sprintf("%v", s))
	}
}

func trimLocation(l types.CodeLocation) string {
	delimiter := "/openshift/origin/"
	return fmt.Sprintf("%q", l.FileName[strings.LastIndex(l.FileName, delimiter)+len(delimiter):])
}
<|endoftext|>


<commit_before>package client

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"hash"
	"io"
	"net/http"
	"net/url"
	"strings"

	"github.com/tent/hawk-go"
)

// Credentials for taskcluster and methods to sign requests.
type Credentials struct {
	ClientID         string   `json:"clientId"`
	AccessToken      string   `json:"accessToken"`
	Certificate      string   `json:"certificate"`
	AuthorizedScopes []string `json:"authorizedScopes"`
}

// PayloadHash creates payload hash calculator for given content-type
func PayloadHash(contentType string) hash.Hash {
	a := hawk.Auth{
		Credentials: hawk.Credentials{
			Hash: sha256.New,
		},
	}
	return a.PayloadHash(contentType)
}

type certificate struct {
	Version   int      `json:"version"`
	Scopes    []string `json:"scopes"`
	Start     int64    `json:"start"`
	Expiry    int64    `json:"expiry"`
	Seed      string   `json:"seed"`
	Signature string   `json:"signature"`
	Issuer    string   `json:"issuer,omitempty"`
}

type ext struct {
	Certificate      *certificate `json:"certificate,omitempty"`
	AuthorizedScopes *[]string    `json:"authorizedScopes,omitempty"`
}

func nonce() string {
	b := make([]byte, 8)
	_, err := io.ReadFull(rand.Reader, b)
	if err != nil {
		panic(err)
	}
	return base64.StdEncoding.EncodeToString(b)[:8]
}

func (c *Credentials) newAuth(method, url string, h hash.Hash) (*hawk.Auth, error) {
	// Create a hawk auth
	a, err := hawk.NewURLAuth(url, &hawk.Credentials{
		ID:   c.ClientID,
		Key:  c.AccessToken,
		Hash: sha256.New,
	}, 0)
	if err != nil {
		return nil, err
	}
	a.Method = method

	// Add ext, if needed
	var e ext
	if c.Certificate != "" {
		err = json.Unmarshal([]byte(c.Certificate), &e.Certificate)
		if err != nil {
			return nil, fmt.Errorf("Failed to parse certificate, error: %s", err)
		}
	}
	if len(c.AuthorizedScopes) > 0 {
		e.AuthorizedScopes = &c.AuthorizedScopes
	}
	if e.Certificate != nil || e.AuthorizedScopes != nil {
		s, _ := json.Marshal(e)
		a.Ext = string(s)
	}

	// Set payload hash
	if h != nil {
		a.SetHash(h)
	}

	return a, nil
}

// SignHeader generates a request signature for Authorization
func (c *Credentials) SignHeader(method, url string, h hash.Hash) (string, error) {
	a, err := c.newAuth(strings.ToUpper(method), url, h)
	if err != nil {
		return "", err
	}
	a.Nonce = nonce()
	return a.RequestHeader(), nil
}

// SignURL will generate a (bewit) signed URL
func (c *Credentials) SignURL(URL string) (string, error) {
	a, err := c.newAuth("GET", URL, nil)
	if err != nil {
		return "", err
	}
	URL += "?bewit=" + url.QueryEscape(a.Bewit())
	return URL, nil
}

// SignRequest will add an Authorization header
func (c *Credentials) SignRequest(req *http.Request, hash hash.Hash) error {
	s, err := c.SignHeader(req.Method, req.URL.String(), hash)
	req.Header.Set("Authorization", s)
	return err
}
<commit_msg>Fix #78 - Encode the ext field<commit_after>package client

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"hash"
	"io"
	"net/http"
	"net/url"
	"strings"

	"github.com/tent/hawk-go"
)

// Credentials for taskcluster and methods to sign requests.
type Credentials struct {
	ClientID         string   `json:"clientId"`
	AccessToken      string   `json:"accessToken"`
	Certificate      string   `json:"certificate"`
	AuthorizedScopes []string `json:"authorizedScopes"`
}

// PayloadHash creates payload hash calculator for given content-type
func PayloadHash(contentType string) hash.Hash {
	a := hawk.Auth{
		Credentials: hawk.Credentials{
			Hash: sha256.New,
		},
	}
	return a.PayloadHash(contentType)
}

type certificate struct {
	Version   int      `json:"version"`
	Scopes    []string `json:"scopes"`
	Start     int64    `json:"start"`
	Expiry    int64    `json:"expiry"`
	Seed      string   `json:"seed"`
	Signature string   `json:"signature"`
	Issuer    string   `json:"issuer,omitempty"`
}

type ext struct {
	Certificate      *certificate `json:"certificate,omitempty"`
	AuthorizedScopes *[]string    `json:"authorizedScopes,omitempty"`
}

func nonce() string {
	b := make([]byte, 8)
	_, err := io.ReadFull(rand.Reader, b)
	if err != nil {
		panic(err)
	}
	return base64.StdEncoding.EncodeToString(b)[:8]
}

func (c *Credentials) newAuth(method, url string, h hash.Hash) (*hawk.Auth, error) {
	// Create a hawk auth
	a, err := hawk.NewURLAuth(url, &hawk.Credentials{
		ID:   c.ClientID,
		Key:  c.AccessToken,
		Hash: sha256.New,
	}, 0)
	if err != nil {
		return nil, err
	}
	a.Method = method

	// Add ext, if needed
	var e ext
	if c.Certificate != "" {
		err = json.Unmarshal([]byte(c.Certificate), &e.Certificate)
		if err != nil {
			return nil, fmt.Errorf("Failed to parse certificate, error: %s", err)
		}
	}
	if len(c.AuthorizedScopes) > 0 {
		e.AuthorizedScopes = &c.AuthorizedScopes
	}
	if e.Certificate != nil || e.AuthorizedScopes != nil {
		s, _ := json.Marshal(e)
		if string(s) != "{}" {
			a.Ext = base64.StdEncoding.EncodeToString(s)
		} else {
			a.Ext = string(s)
		}
	}

	// Set payload hash
	if h != nil {
		a.SetHash(h)
	}

	return a, nil
}

// SignHeader generates a request signature for Authorization
func (c *Credentials) SignHeader(method, url string, h hash.Hash) (string, error) {
	a, err := c.newAuth(strings.ToUpper(method), url, h)
	if err != nil {
		return "", err
	}
	a.Nonce = nonce()
	return a.RequestHeader(), nil
}

// SignURL will generate a (bewit) signed URL
func (c *Credentials) SignURL(URL string) (string, error) {
	a, err := c.newAuth("GET", URL, nil)
	if err != nil {
		return "", err
	}
	URL += "?bewit=" + url.QueryEscape(a.Bewit())
	return URL, nil
}

// SignRequest will add an Authorization header
func (c *Credentials) SignRequest(req *http.Request, hash hash.Hash) error {
	s, err := c.SignHeader(req.Method, req.URL.String(), hash)
	req.Header.Set("Authorization", s)
	return err
}
<|endoftext|>


<commit_before>// Copyright 2015 The Vanadium 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 test

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"v.io/jiri"
	"v.io/jiri/collect"
	"v.io/x/devtools/internal/test"
)

func vanadiumReleaseKubeStaging(jirix *jiri.X, testName string, opts ...Opt) (_ *test.Result, e error) {
	manifestPath := os.Getenv(manifestEnvVar)
	if manifestPath == "" {
		return nil, fmt.Errorf("%s environment variable not set", manifestEnvVar)
	}
	version := cleanupVersionString(filepath.Base(manifestPath))
	return vanadiumReleaseKubeCommon(jirix, testName, "staging", version)
}

func vanadiumReleaseKubeProduction(jirix *jiri.X, testName string, opts ...Opt) (_ *test.Result, e error) {
	version := ""
	if snapshotTimestamp := os.Getenv(snapshotTimestampEnvVar); snapshotTimestamp != "" {
		version = cleanupVersionString(snapshotTimestamp)
	}
	return vanadiumReleaseKubeCommon(jirix, testName, "production", version)
}

func vanadiumReleaseKubeCommon(jirix *jiri.X, testName, updateType, version string) (_ *test.Result, e error) {
	cleanup, err := initTest(jirix, testName, []string{"v23:base"})
	if err != nil {
		return nil, newInternalError(err, "Init")
	}
	defer collect.Error(func() error { return cleanup() }, &e)

	// Build and run vprodupdater.
	s := jirix.NewSeq()
	if err := s.Last("jiri", "go", "install", "v.io/infrastructure/vprodupdater/"); err != nil {
		return nil, newInternalError(err, "Build vprodupdater")
	}
	vprodupdaterBin := filepath.Join(jirix.Root, "infrastructure", "go", "bin", "vprodupdater")
	args := []string{
		"update",
		fmt.Sprintf("-type=%s", updateType),
		fmt.Sprintf("-tag=%s", version),
	}
	if err := s.Capture(jirix.Stdout(), jirix.Stderr()).Last(vprodupdaterBin, args...); err != nil {
		return nil, newInternalError(err, "Run vprodupdater")
	}
	return &test.Result{Status: test.Passed}, nil
}

func cleanupVersionString(version string) string {
	// Remove all separators to make the version string look cleaner.
	for _, s := range []string{"-", ".", ":"} {
		version = strings.Replace(version, s, "", -1)
	}
	return "manifest-" + version
}
<commit_msg>jiri-test/internal/test: Matching change for v.io/c/20980<commit_after>// Copyright 2015 The Vanadium 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 test

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"v.io/jiri"
	"v.io/jiri/collect"
	"v.io/x/devtools/internal/test"
)

func vanadiumReleaseKubeStaging(jirix *jiri.X, testName string, opts ...Opt) (_ *test.Result, e error) {
	manifestPath := os.Getenv(manifestEnvVar)
	if manifestPath == "" {
		return nil, fmt.Errorf("%s environment variable not set", manifestEnvVar)
	}
	version := cleanupVersionString(filepath.Base(manifestPath))
	return vanadiumReleaseKubeCommon(jirix, testName, "staging", version)
}

func vanadiumReleaseKubeProduction(jirix *jiri.X, testName string, opts ...Opt) (_ *test.Result, e error) {
	version := ""
	if snapshotTimestamp := os.Getenv(snapshotTimestampEnvVar); snapshotTimestamp != "" {
		version = cleanupVersionString(snapshotTimestamp)
	}
	return vanadiumReleaseKubeCommon(jirix, testName, "production", version)
}

func vanadiumReleaseKubeCommon(jirix *jiri.X, testName, updateType, version string) (_ *test.Result, e error) {
	cleanup, err := initTest(jirix, testName, []string{"v23:base"})
	if err != nil {
		return nil, newInternalError(err, "Init")
	}
	defer collect.Error(func() error { return cleanup() }, &e)

	// Build and run vprodupdater.
	s := jirix.NewSeq()
	if err := s.Last("jiri", "go", "install", "v.io/infrastructure/vprodupdater/"); err != nil {
		return nil, newInternalError(err, "Build vprodupdater")
	}
	vprodupdaterBin := filepath.Join(jirix.Root, "infrastructure", "go", "bin", "vprodupdater")
	args := []string{
		"update-all",
		fmt.Sprintf("-type=%s", updateType),
		fmt.Sprintf("-tag=%s", version),
	}
	if err := s.Capture(jirix.Stdout(), jirix.Stderr()).Last(vprodupdaterBin, args...); err != nil {
		return nil, newInternalError(err, "Run vprodupdater")
	}
	return &test.Result{Status: test.Passed}, nil
}

func cleanupVersionString(version string) string {
	// Remove all separators to make the version string look cleaner.
	for _, s := range []string{"-", ".", ":"} {
		version = strings.Replace(version, s, "", -1)
	}
	return "manifest-" + version
}
<|endoftext|>


<commit_before>package schema

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"testing"

	"github.com/xeipuuv/gojsonschema"
)

// SchemaValidator uses the gojsonschema library to validate the JSON encoding
// of Go objects against a pre-defined JSON schema.
type SchemaValidator struct {
	// Schema is the JSON schema to validate against.
	//
	// Subject is the instance of Go type that will be validated.
	Schema, Subject gojsonschema.JSONLoader
}

func NewSchemaValidator(t *testing.T, schemaName string, got interface{}) *SchemaValidator {
	dir, err := os.Getwd()
	if err != nil {
		t.Fatal(err)
	}

	schema := gojsonschema.NewReferenceLoader(fmt.Sprintf(
		"file:///%s",
		filepath.Join(dir, "schema/", schemaName),
	))

	marshalled, err := json.Marshal(got)
	if err != nil {
		t.Fatal(err)
	}

	subject := gojsonschema.NewStringLoader(string(marshalled))

	return &SchemaValidator{
		Schema:  schema,
		Subject: subject,
	}
}

// Validate validates a Go object against JSON schema in a testing environment.
// If the validation fails, then the test will fail after logging all of the
// validation errors experienced by the validator.
func Validate(t *testing.T, schemaName string, got interface{}) {
	NewSchemaValidator(t, schemaName, got).Assert(t)
}

// Refute ensures that a particular Go object does not validate the JSON schema
// given.
//
// If validation against the schema is successful, then the test will fail after
// logging.
func Refute(t *testing.T, schemaName string, got interface{}) {
	NewSchemaValidator(t, schemaName, got).Refute(t)
}

// Assert preforms the validation assertion against the given *testing.T.
func (v *SchemaValidator) Assert(t *testing.T) {
	if result, err := gojsonschema.Validate(v.Schema, v.Subject); err != nil {
		t.Fatal(err)
	} else if !result.Valid() {
		for _, err := range result.Errors() {
			t.Logf("Validation error: %s", err.Description())
		}
		t.Fail()
	}
}

// Refute refutes that the given subject will validate against a particular
// schema.
func (v *SchemaValidator) Refute(t *testing.T) {
	if result, err := gojsonschema.Validate(v.Schema, v.Subject); err != nil {
		t.Fatal(err)
	} else if result.Valid() {
		t.Fatal("api/schema: expected validation to fail, succeeded")
	}
}
<commit_msg>Windows fix: don't use filepath, produces backslash path separators<commit_after>package schema

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"testing"

	"github.com/xeipuuv/gojsonschema"
)

// SchemaValidator uses the gojsonschema library to validate the JSON encoding
// of Go objects against a pre-defined JSON schema.
type SchemaValidator struct {
	// Schema is the JSON schema to validate against.
	//
	// Subject is the instance of Go type that will be validated.
	Schema, Subject gojsonschema.JSONLoader
}

func NewSchemaValidator(t *testing.T, schemaName string, got interface{}) *SchemaValidator {
	dir, err := os.Getwd()
	if err != nil {
		t.Fatal(err)
	}
	// Platform compatibility: use "/" separators always for file://
	dir = strings.Replace(dir, "\\", "/", -1)

	schema := gojsonschema.NewReferenceLoader(fmt.Sprintf(
		"file:///%s/schema/%s", dir, schemaName),
	)

	marshalled, err := json.Marshal(got)
	if err != nil {
		t.Fatal(err)
	}

	subject := gojsonschema.NewStringLoader(string(marshalled))

	return &SchemaValidator{
		Schema:  schema,
		Subject: subject,
	}
}

// Validate validates a Go object against JSON schema in a testing environment.
// If the validation fails, then the test will fail after logging all of the
// validation errors experienced by the validator.
func Validate(t *testing.T, schemaName string, got interface{}) {
	NewSchemaValidator(t, schemaName, got).Assert(t)
}

// Refute ensures that a particular Go object does not validate the JSON schema
// given.
//
// If validation against the schema is successful, then the test will fail after
// logging.
func Refute(t *testing.T, schemaName string, got interface{}) {
	NewSchemaValidator(t, schemaName, got).Refute(t)
}

// Assert preforms the validation assertion against the given *testing.T.
func (v *SchemaValidator) Assert(t *testing.T) {
	if result, err := gojsonschema.Validate(v.Schema, v.Subject); err != nil {
		t.Fatal(err)
	} else if !result.Valid() {
		for _, err := range result.Errors() {
			t.Logf("Validation error: %s", err.Description())
		}
		t.Fail()
	}
}

// Refute refutes that the given subject will validate against a particular
// schema.
func (v *SchemaValidator) Refute(t *testing.T) {
	if result, err := gojsonschema.Validate(v.Schema, v.Subject); err != nil {
		t.Fatal(err)
	} else if result.Valid() {
		t.Fatal("api/schema: expected validation to fail, succeeded")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"sort"
	"strings"

	"github.com/containerd/containerd/sys"
	"github.com/docker/go-connections/sockets"
	"github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
	"github.com/moby/buildkit/cache/cacheimport"
	"github.com/moby/buildkit/control"
	"github.com/moby/buildkit/frontend"
	"github.com/moby/buildkit/frontend/dockerfile"
	"github.com/moby/buildkit/frontend/gateway"
	"github.com/moby/buildkit/session"
	"github.com/moby/buildkit/util/appcontext"
	"github.com/moby/buildkit/util/appdefaults"
	"github.com/moby/buildkit/util/profiler"
	"github.com/moby/buildkit/worker"
	"github.com/moby/buildkit/worker/base"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
	netcontext "golang.org/x/net/context"
	"golang.org/x/sync/errgroup"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

type workerInitializerOpt struct {
	sessionManager *session.Manager
	root           string
}

type workerInitializer struct {
	fn func(c *cli.Context, common workerInitializerOpt) ([]worker.Worker, error)
	// less priority number, more preferred
	priority int
}

var (
	appFlags           []cli.Flag
	workerInitializers []workerInitializer
)

func registerWorkerInitializer(wi workerInitializer, flags ...cli.Flag) {
	workerInitializers = append(workerInitializers, wi)
	sort.Slice(workerInitializers,
		func(i, j int) bool {
			return workerInitializers[i].priority < workerInitializers[j].priority
		})
	appFlags = append(appFlags, flags...)
}

func main() {
	app := cli.NewApp()
	app.Name = "buildkitd"
	app.Usage = "build daemon"

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug",
			Usage: "enable debug output in logs",
		},
		cli.StringFlag{
			Name:  "root",
			Usage: "path to state directory",
			Value: appdefaults.Root,
		},
		cli.StringSliceFlag{
			Name:  "addr",
			Usage: "listening address (socket or tcp)",
			Value: &cli.StringSlice{appdefaults.Address},
		},
		cli.StringFlag{
			Name:  "debugaddr",
			Usage: "debugging address (eg. 0.0.0.0:6060)",
			Value: "",
		},
		cli.StringFlag{
			Name:  "tlscert",
			Usage: "certificate file to use",
		},
		cli.StringFlag{
			Name:  "tlskey",
			Usage: "key file to use",
		},
		cli.StringFlag{
			Name:  "tlscacert",
			Usage: "ca certificate to verify clients",
		},
	}

	app.Flags = append(app.Flags, appFlags...)

	app.Action = func(c *cli.Context) error {
		ctx, cancel := context.WithCancel(appcontext.Context())
		defer cancel()

		if debugAddr := c.GlobalString("debugaddr"); debugAddr != "" {
			if err := setupDebugHandlers(debugAddr); err != nil {
				return err
			}
		}
		opts := []grpc.ServerOption{unaryInterceptor(ctx), grpc.StreamInterceptor(otgrpc.OpenTracingStreamServerInterceptor(tracer))}
		creds, err := serverCredentials(c)
		if err != nil {
			return err
		}
		if creds != nil {
			opts = append(opts, creds)
		}
		server := grpc.NewServer(opts...)

		// relative path does not work with nightlyone/lockfile
		root, err := filepath.Abs(c.GlobalString("root"))
		if err != nil {
			return err
		}

		if err := os.MkdirAll(root, 0700); err != nil {
			return errors.Wrapf(err, "failed to create %s", root)
		}

		controller, err := newController(c, root)
		if err != nil {
			return err
		}

		controller.Register(server)

		errCh := make(chan error, 1)
		addrs := c.GlobalStringSlice("addr")
		if len(addrs) > 1 {
			addrs = addrs[1:] // https://github.com/urfave/cli/issues/160
		}
		if err := serveGRPC(server, addrs, errCh); err != nil {
			return err
		}

		select {
		case serverErr := <-errCh:
			err = serverErr
			cancel()
		case <-ctx.Done():
			err = ctx.Err()
		}

		logrus.Infof("stopping server")
		server.GracefulStop()

		return err
	}
	app.Before = func(context *cli.Context) error {
		if context.GlobalBool("debug") {
			logrus.SetLevel(logrus.DebugLevel)
		}
		return nil
	}

	app.After = func(context *cli.Context) error {
		if closeTracer != nil {
			return closeTracer.Close()
		}
		return nil
	}

	profiler.Attach(app)

	if err := app.Run(os.Args); err != nil {
		fmt.Fprintf(os.Stderr, "buildkitd: %s\n", err)
		os.Exit(1)
	}
}

func serveGRPC(server *grpc.Server, addrs []string, errCh chan error) error {
	if len(addrs) == 0 {
		return errors.New("--addr cannot be empty")
	}
	eg, _ := errgroup.WithContext(context.Background())
	listeners := make([]net.Listener, 0, len(addrs))
	for _, addr := range addrs {
		l, err := getListener(addr)
		if err != nil {
			for _, l := range listeners {
				l.Close()
			}
			return err
		}
		listeners = append(listeners, l)
	}
	for _, l := range listeners {
		func(l net.Listener) {
			eg.Go(func() error {
				defer l.Close()
				logrus.Infof("running server on %s", l.Addr())
				return server.Serve(l)
			})
		}(l)
	}
	go func() {
		errCh <- eg.Wait()
	}()
	return nil
}

func getListener(addr string) (net.Listener, error) {
	addrSlice := strings.SplitN(addr, "://", 2)
	proto := addrSlice[0]
	listenAddr := addrSlice[1]
	switch proto {
	case "unix", "npipe":
		return sys.GetLocalListener(listenAddr, os.Getuid(), os.Getgid())
	case "tcp":
		return sockets.NewTCPSocket(listenAddr, nil)
	default:
		return nil, errors.Errorf("addr %s not supported", addr)
	}
}

func unaryInterceptor(globalCtx context.Context) grpc.ServerOption {
	withTrace := otgrpc.OpenTracingServerInterceptor(tracer, otgrpc.LogPayloads())

	return grpc.UnaryInterceptor(func(ctx netcontext.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
		ctx, cancel := context.WithCancel(ctx)
		defer cancel()

		go func() {
			select {
			case <-ctx.Done():
			case <-globalCtx.Done():
				cancel()
			}
		}()

		resp, err = withTrace(ctx, req, info, handler)
		if err != nil {
			logrus.Errorf("%s returned error: %+v", info.FullMethod, err)
		}
		return
	})
}

func serverCredentials(c *cli.Context) (grpc.ServerOption, error) {
	certFile := c.GlobalString("tlscert")
	keyFile := c.GlobalString("tlskey")
	caFile := c.GlobalString("tlscacert")
	if certFile == "" && keyFile == "" {
		return nil, nil
	}
	err := errors.New("you must specify key and cert file if one is specified")
	if certFile == "" {
		return nil, err
	}
	if keyFile == "" {
		return nil, err
	}
	certificate, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return nil, errors.Wrap(err, "could not load server key pair")
	}
	tlsConf := &tls.Config{
		Certificates: []tls.Certificate{certificate},
	}
	if caFile != "" {
		certPool := x509.NewCertPool()
		ca, err := ioutil.ReadFile(caFile)
		if err != nil {
			return nil, errors.Wrap(err, "could not read ca certificate")
		}
		// Append the client certificates from the CA
		if ok := certPool.AppendCertsFromPEM(ca); !ok {
			return nil, errors.New("failed to append ca cert")
		}
		tlsConf.ClientAuth = tls.RequireAndVerifyClientCert
		tlsConf.ClientCAs = certPool
	}
	creds := grpc.Creds(credentials.NewTLS(tlsConf))
	return creds, nil
}

func newController(c *cli.Context, root string) (*control.Controller, error) {
	sessionManager, err := session.NewManager()
	if err != nil {
		return nil, err
	}
	wc, err := newWorkerController(c, workerInitializerOpt{
		sessionManager: sessionManager,
		root:           root,
	})
	if err != nil {
		return nil, err
	}
	frontends := map[string]frontend.Frontend{}
	frontends["dockerfile.v0"] = dockerfile.NewDockerfileFrontend()
	frontends["gateway.v0"] = gateway.NewGatewayFrontend()

	// cache exporter and importer are manager concepts but as there is no
	// way to pull data into specific worker yet we currently set them up
	// as part of default worker
	var ce *cacheimport.CacheExporter
	var ci *cacheimport.CacheImporter

	w, err := wc.GetDefault()
	if err != nil {
		return nil, err
	}

	wt := w.(*base.Worker)
	ce = wt.CacheExporter
	ci = wt.CacheImporter

	return control.NewController(control.Opt{
		SessionManager:   sessionManager,
		WorkerController: wc,
		Frontends:        frontends,
		CacheExporter:    ce,
		CacheImporter:    ci,
	})
}

func newWorkerController(c *cli.Context, wiOpt workerInitializerOpt) (*worker.Controller, error) {
	wc := &worker.Controller{}
	nWorkers := 0
	for _, wi := range workerInitializers {
		ws, err := wi.fn(c, wiOpt)
		if err != nil {
			return nil, err
		}
		for _, w := range ws {
			logrus.Infof("found worker %q, labels=%v", w.ID(), w.Labels())
			if err = wc.Add(w); err != nil {
				return nil, err
			}
			nWorkers++
		}
	}
	if nWorkers == 0 {
		return nil, errors.New("no worker found, rebuild the buildkit daemon?")
	}
	defaultWorker, err := wc.GetDefault()
	if err != nil {
		return nil, err
	}
	logrus.Infof("found %d workers, default=%q", nWorkers, defaultWorker.ID())
	logrus.Warn("currently, only the default worker can be used.")
	return wc, nil
}

func attrMap(sl []string) (map[string]string, error) {
	m := map[string]string{}
	for _, v := range sl {
		parts := strings.SplitN(v, "=", 2)
		if len(parts) != 2 {
			return nil, errors.Errorf("invalid value %s", v)
		}
		m[parts[0]] = parts[1]
	}
	return m, nil
}
<commit_msg>buildkitd: fix index-out-of-range panic in parsing wrong addr string<commit_after>package main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"sort"
	"strings"

	"github.com/containerd/containerd/sys"
	"github.com/docker/go-connections/sockets"
	"github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
	"github.com/moby/buildkit/cache/cacheimport"
	"github.com/moby/buildkit/control"
	"github.com/moby/buildkit/frontend"
	"github.com/moby/buildkit/frontend/dockerfile"
	"github.com/moby/buildkit/frontend/gateway"
	"github.com/moby/buildkit/session"
	"github.com/moby/buildkit/util/appcontext"
	"github.com/moby/buildkit/util/appdefaults"
	"github.com/moby/buildkit/util/profiler"
	"github.com/moby/buildkit/worker"
	"github.com/moby/buildkit/worker/base"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
	netcontext "golang.org/x/net/context"
	"golang.org/x/sync/errgroup"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

type workerInitializerOpt struct {
	sessionManager *session.Manager
	root           string
}

type workerInitializer struct {
	fn func(c *cli.Context, common workerInitializerOpt) ([]worker.Worker, error)
	// less priority number, more preferred
	priority int
}

var (
	appFlags           []cli.Flag
	workerInitializers []workerInitializer
)

func registerWorkerInitializer(wi workerInitializer, flags ...cli.Flag) {
	workerInitializers = append(workerInitializers, wi)
	sort.Slice(workerInitializers,
		func(i, j int) bool {
			return workerInitializers[i].priority < workerInitializers[j].priority
		})
	appFlags = append(appFlags, flags...)
}

func main() {
	app := cli.NewApp()
	app.Name = "buildkitd"
	app.Usage = "build daemon"

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug",
			Usage: "enable debug output in logs",
		},
		cli.StringFlag{
			Name:  "root",
			Usage: "path to state directory",
			Value: appdefaults.Root,
		},
		cli.StringSliceFlag{
			Name:  "addr",
			Usage: "listening address (socket or tcp)",
			Value: &cli.StringSlice{appdefaults.Address},
		},
		cli.StringFlag{
			Name:  "debugaddr",
			Usage: "debugging address (eg. 0.0.0.0:6060)",
			Value: "",
		},
		cli.StringFlag{
			Name:  "tlscert",
			Usage: "certificate file to use",
		},
		cli.StringFlag{
			Name:  "tlskey",
			Usage: "key file to use",
		},
		cli.StringFlag{
			Name:  "tlscacert",
			Usage: "ca certificate to verify clients",
		},
	}

	app.Flags = append(app.Flags, appFlags...)

	app.Action = func(c *cli.Context) error {
		ctx, cancel := context.WithCancel(appcontext.Context())
		defer cancel()

		if debugAddr := c.GlobalString("debugaddr"); debugAddr != "" {
			if err := setupDebugHandlers(debugAddr); err != nil {
				return err
			}
		}
		opts := []grpc.ServerOption{unaryInterceptor(ctx), grpc.StreamInterceptor(otgrpc.OpenTracingStreamServerInterceptor(tracer))}
		creds, err := serverCredentials(c)
		if err != nil {
			return err
		}
		if creds != nil {
			opts = append(opts, creds)
		}
		server := grpc.NewServer(opts...)

		// relative path does not work with nightlyone/lockfile
		root, err := filepath.Abs(c.GlobalString("root"))
		if err != nil {
			return err
		}

		if err := os.MkdirAll(root, 0700); err != nil {
			return errors.Wrapf(err, "failed to create %s", root)
		}

		controller, err := newController(c, root)
		if err != nil {
			return err
		}

		controller.Register(server)

		errCh := make(chan error, 1)
		addrs := c.GlobalStringSlice("addr")
		if len(addrs) > 1 {
			addrs = addrs[1:] // https://github.com/urfave/cli/issues/160
		}
		if err := serveGRPC(server, addrs, errCh); err != nil {
			return err
		}

		select {
		case serverErr := <-errCh:
			err = serverErr
			cancel()
		case <-ctx.Done():
			err = ctx.Err()
		}

		logrus.Infof("stopping server")
		server.GracefulStop()

		return err
	}
	app.Before = func(context *cli.Context) error {
		if context.GlobalBool("debug") {
			logrus.SetLevel(logrus.DebugLevel)
		}
		return nil
	}

	app.After = func(context *cli.Context) error {
		if closeTracer != nil {
			return closeTracer.Close()
		}
		return nil
	}

	profiler.Attach(app)

	if err := app.Run(os.Args); err != nil {
		fmt.Fprintf(os.Stderr, "buildkitd: %s\n", err)
		os.Exit(1)
	}
}

func serveGRPC(server *grpc.Server, addrs []string, errCh chan error) error {
	if len(addrs) == 0 {
		return errors.New("--addr cannot be empty")
	}
	eg, _ := errgroup.WithContext(context.Background())
	listeners := make([]net.Listener, 0, len(addrs))
	for _, addr := range addrs {
		l, err := getListener(addr)
		if err != nil {
			for _, l := range listeners {
				l.Close()
			}
			return err
		}
		listeners = append(listeners, l)
	}
	for _, l := range listeners {
		func(l net.Listener) {
			eg.Go(func() error {
				defer l.Close()
				logrus.Infof("running server on %s", l.Addr())
				return server.Serve(l)
			})
		}(l)
	}
	go func() {
		errCh <- eg.Wait()
	}()
	return nil
}

func getListener(addr string) (net.Listener, error) {
	addrSlice := strings.SplitN(addr, "://", 2)
	if len(addrSlice) < 2 {
		return nil, errors.Errorf("address %s does not contain proto, you meant unix://%s ?",
			addr, addr)
	}
	proto := addrSlice[0]
	listenAddr := addrSlice[1]
	switch proto {
	case "unix", "npipe":
		return sys.GetLocalListener(listenAddr, os.Getuid(), os.Getgid())
	case "tcp":
		return sockets.NewTCPSocket(listenAddr, nil)
	default:
		return nil, errors.Errorf("addr %s not supported", addr)
	}
}

func unaryInterceptor(globalCtx context.Context) grpc.ServerOption {
	withTrace := otgrpc.OpenTracingServerInterceptor(tracer, otgrpc.LogPayloads())

	return grpc.UnaryInterceptor(func(ctx netcontext.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
		ctx, cancel := context.WithCancel(ctx)
		defer cancel()

		go func() {
			select {
			case <-ctx.Done():
			case <-globalCtx.Done():
				cancel()
			}
		}()

		resp, err = withTrace(ctx, req, info, handler)
		if err != nil {
			logrus.Errorf("%s returned error: %+v", info.FullMethod, err)
		}
		return
	})
}

func serverCredentials(c *cli.Context) (grpc.ServerOption, error) {
	certFile := c.GlobalString("tlscert")
	keyFile := c.GlobalString("tlskey")
	caFile := c.GlobalString("tlscacert")
	if certFile == "" && keyFile == "" {
		return nil, nil
	}
	err := errors.New("you must specify key and cert file if one is specified")
	if certFile == "" {
		return nil, err
	}
	if keyFile == "" {
		return nil, err
	}
	certificate, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return nil, errors.Wrap(err, "could not load server key pair")
	}
	tlsConf := &tls.Config{
		Certificates: []tls.Certificate{certificate},
	}
	if caFile != "" {
		certPool := x509.NewCertPool()
		ca, err := ioutil.ReadFile(caFile)
		if err != nil {
			return nil, errors.Wrap(err, "could not read ca certificate")
		}
		// Append the client certificates from the CA
		if ok := certPool.AppendCertsFromPEM(ca); !ok {
			return nil, errors.New("failed to append ca cert")
		}
		tlsConf.ClientAuth = tls.RequireAndVerifyClientCert
		tlsConf.ClientCAs = certPool
	}
	creds := grpc.Creds(credentials.NewTLS(tlsConf))
	return creds, nil
}

func newController(c *cli.Context, root string) (*control.Controller, error) {
	sessionManager, err := session.NewManager()
	if err != nil {
		return nil, err
	}
	wc, err := newWorkerController(c, workerInitializerOpt{
		sessionManager: sessionManager,
		root:           root,
	})
	if err != nil {
		return nil, err
	}
	frontends := map[string]frontend.Frontend{}
	frontends["dockerfile.v0"] = dockerfile.NewDockerfileFrontend()
	frontends["gateway.v0"] = gateway.NewGatewayFrontend()

	// cache exporter and importer are manager concepts but as there is no
	// way to pull data into specific worker yet we currently set them up
	// as part of default worker
	var ce *cacheimport.CacheExporter
	var ci *cacheimport.CacheImporter

	w, err := wc.GetDefault()
	if err != nil {
		return nil, err
	}

	wt := w.(*base.Worker)
	ce = wt.CacheExporter
	ci = wt.CacheImporter

	return control.NewController(control.Opt{
		SessionManager:   sessionManager,
		WorkerController: wc,
		Frontends:        frontends,
		CacheExporter:    ce,
		CacheImporter:    ci,
	})
}

func newWorkerController(c *cli.Context, wiOpt workerInitializerOpt) (*worker.Controller, error) {
	wc := &worker.Controller{}
	nWorkers := 0
	for _, wi := range workerInitializers {
		ws, err := wi.fn(c, wiOpt)
		if err != nil {
			return nil, err
		}
		for _, w := range ws {
			logrus.Infof("found worker %q, labels=%v", w.ID(), w.Labels())
			if err = wc.Add(w); err != nil {
				return nil, err
			}
			nWorkers++
		}
	}
	if nWorkers == 0 {
		return nil, errors.New("no worker found, rebuild the buildkit daemon?")
	}
	defaultWorker, err := wc.GetDefault()
	if err != nil {
		return nil, err
	}
	logrus.Infof("found %d workers, default=%q", nWorkers, defaultWorker.ID())
	logrus.Warn("currently, only the default worker can be used.")
	return wc, nil
}

func attrMap(sl []string) (map[string]string, error) {
	m := map[string]string{}
	for _, v := range sl {
		parts := strings.SplitN(v, "=", 2)
		if len(parts) != 2 {
			return nil, errors.Errorf("invalid value %s", v)
		}
		m[parts[0]] = parts[1]
	}
	return m, nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"os"
	"strings"
	"time"

	"github.com/cloudfoundry-incubator/cf-debug-server"
	"github.com/cloudfoundry-incubator/cf-lager"
	"github.com/cloudfoundry-incubator/converger/converger_process"
	"github.com/cloudfoundry-incubator/converger/lrpreprocessor"
	"github.com/cloudfoundry-incubator/converger/lrpwatcher"
	Bbs "github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/bbs/lock_bbs"
	_ "github.com/cloudfoundry/dropsonde/autowire"
	"github.com/cloudfoundry/gunk/timeprovider"
	"github.com/cloudfoundry/storeadapter/etcdstoreadapter"
	"github.com/cloudfoundry/storeadapter/workerpool"
	"github.com/nu7hatch/gouuid"
	"github.com/pivotal-golang/lager"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/sigmon"
)

var etcdCluster = flag.String(
	"etcdCluster",
	"http://127.0.0.1:4001",
	"comma-separated list of etcd addresses (http://ip:port)",
)

var heartbeatInterval = flag.Duration(
	"heartbeatInterval",
	lock_bbs.HEARTBEAT_INTERVAL,
	"the interval between heartbeats to the lock",
)

var convergeRepeatInterval = flag.Duration(
	"convergeRepeatInterval",
	30*time.Second,
	"the interval between runs of the converge process",
)

var kickPendingTaskDuration = flag.Duration(
	"kickPendingTaskDuration",
	30*time.Second,
	"the interval, in seconds, between kicks to pending tasks",
)

var expireCompletedTaskDuration = flag.Duration(
	"expireCompletedTaskDuration",
	120*time.Second,
	"completed, unresolved tasks are deleted after this duration",
)

var expirePendingTaskDuration = flag.Duration(
	"expirePendingTaskDuration",
	30*time.Minute,
	"unclaimed tasks are marked as failed, after this duration",
)

var kickPendingLRPStartAuctionDuration = flag.Duration(
	"kickPendingLRPStartAuctionDuration",
	30*time.Second,
	"the interval between kicks to pending start auctions for long-running process",
)

var expireClaimedLRPStartAuctionDuration = flag.Duration(
	"expireClaimedLRPStartAuctionDuration",
	300*time.Second,
	"unclaimed start auctions for long-running processes are deleted, after this interval",
)

func main() {
	flag.Parse()

	logger := cf_lager.New("converger")

	bbs := initializeBBS(logger)

	cf_debug_server.Run()

	uuid, err := uuid.NewV4()
	if err != nil {
		logger.Fatal("Couldn't generate uuid", err)
	}

	heartbeater := bbs.NewConvergeLock(uuid.String(), *heartbeatInterval)

	converger := converger_process.New(
		bbs,
		logger,
		*convergeRepeatInterval,
		*kickPendingTaskDuration,
		*expirePendingTaskDuration,
		*expireCompletedTaskDuration,
		*kickPendingLRPStartAuctionDuration,
		*expireClaimedLRPStartAuctionDuration,
	)

	watcher := lrpwatcher.New(bbs, lrpreprocessor.New(bbs), logger)

	group := grouper.NewOrdered(os.Interrupt, grouper.Members{
		{"heartbeater", heartbeater},
		{"converger", converger},
		{"watcher", watcher},
	})

	logger.Info("started-waiting-for-lock")

	process := ifrit.Invoke(sigmon.New(group))

	logger.Info("acquired-lock")

	err = <-process.Wait()
	if err != nil {
		logger.Error("exited-with-failure", err)
		os.Exit(1)
	}

	logger.Info("exited")
}

func initializeBBS(logger lager.Logger) Bbs.ConvergerBBS {
	etcdAdapter := etcdstoreadapter.NewETCDStoreAdapter(
		strings.Split(*etcdCluster, ","),
		workerpool.NewWorkerPool(10),
	)

	err := etcdAdapter.Connect()
	if err != nil {
		logger.Fatal("failed-to-connect-to-etcd", err)
	}

	return Bbs.NewConvergerBBS(etcdAdapter, timeprovider.NewTimeProvider(), logger)
}
<commit_msg>Use gunk workpool [#80393556]<commit_after>package main

import (
	"flag"
	"os"
	"strings"
	"time"

	"github.com/cloudfoundry-incubator/cf-debug-server"
	"github.com/cloudfoundry-incubator/cf-lager"
	"github.com/cloudfoundry-incubator/converger/converger_process"
	"github.com/cloudfoundry-incubator/converger/lrpreprocessor"
	"github.com/cloudfoundry-incubator/converger/lrpwatcher"
	Bbs "github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/bbs/lock_bbs"
	_ "github.com/cloudfoundry/dropsonde/autowire"
	"github.com/cloudfoundry/gunk/timeprovider"
	"github.com/cloudfoundry/gunk/workpool"
	"github.com/cloudfoundry/storeadapter/etcdstoreadapter"
	"github.com/nu7hatch/gouuid"
	"github.com/pivotal-golang/lager"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/sigmon"
)

var etcdCluster = flag.String(
	"etcdCluster",
	"http://127.0.0.1:4001",
	"comma-separated list of etcd addresses (http://ip:port)",
)

var heartbeatInterval = flag.Duration(
	"heartbeatInterval",
	lock_bbs.HEARTBEAT_INTERVAL,
	"the interval between heartbeats to the lock",
)

var convergeRepeatInterval = flag.Duration(
	"convergeRepeatInterval",
	30*time.Second,
	"the interval between runs of the converge process",
)

var kickPendingTaskDuration = flag.Duration(
	"kickPendingTaskDuration",
	30*time.Second,
	"the interval, in seconds, between kicks to pending tasks",
)

var expireCompletedTaskDuration = flag.Duration(
	"expireCompletedTaskDuration",
	120*time.Second,
	"completed, unresolved tasks are deleted after this duration",
)

var expirePendingTaskDuration = flag.Duration(
	"expirePendingTaskDuration",
	30*time.Minute,
	"unclaimed tasks are marked as failed, after this duration",
)

var kickPendingLRPStartAuctionDuration = flag.Duration(
	"kickPendingLRPStartAuctionDuration",
	30*time.Second,
	"the interval between kicks to pending start auctions for long-running process",
)

var expireClaimedLRPStartAuctionDuration = flag.Duration(
	"expireClaimedLRPStartAuctionDuration",
	300*time.Second,
	"unclaimed start auctions for long-running processes are deleted, after this interval",
)

func main() {
	flag.Parse()

	logger := cf_lager.New("converger")

	bbs := initializeBBS(logger)

	cf_debug_server.Run()

	uuid, err := uuid.NewV4()
	if err != nil {
		logger.Fatal("Couldn't generate uuid", err)
	}

	heartbeater := bbs.NewConvergeLock(uuid.String(), *heartbeatInterval)

	converger := converger_process.New(
		bbs,
		logger,
		*convergeRepeatInterval,
		*kickPendingTaskDuration,
		*expirePendingTaskDuration,
		*expireCompletedTaskDuration,
		*kickPendingLRPStartAuctionDuration,
		*expireClaimedLRPStartAuctionDuration,
	)

	watcher := lrpwatcher.New(bbs, lrpreprocessor.New(bbs), logger)

	group := grouper.NewOrdered(os.Interrupt, grouper.Members{
		{"heartbeater", heartbeater},
		{"converger", converger},
		{"watcher", watcher},
	})

	logger.Info("started-waiting-for-lock")

	process := ifrit.Invoke(sigmon.New(group))

	logger.Info("acquired-lock")

	err = <-process.Wait()
	if err != nil {
		logger.Error("exited-with-failure", err)
		os.Exit(1)
	}

	logger.Info("exited")
}

func initializeBBS(logger lager.Logger) Bbs.ConvergerBBS {
	etcdAdapter := etcdstoreadapter.NewETCDStoreAdapter(
		strings.Split(*etcdCluster, ","),
		workpool.NewWorkPool(10),
	)

	err := etcdAdapter.Connect()
	if err != nil {
		logger.Fatal("failed-to-connect-to-etcd", err)
	}

	return Bbs.NewConvergerBBS(etcdAdapter, timeprovider.NewTimeProvider(), logger)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"flag"
	"fmt"
	"github.com/Symantec/Dominator/dom/herd"
	"github.com/Symantec/Dominator/dom/rpcd"
	"github.com/Symantec/Dominator/lib/constants"
	liblog "github.com/Symantec/Dominator/lib/log"
	"github.com/Symantec/Dominator/lib/log/debuglogger"
	"github.com/Symantec/Dominator/lib/logbuf"
	"github.com/Symantec/Dominator/lib/mdb"
	"github.com/Symantec/Dominator/lib/mdb/mdbd"
	objectserver "github.com/Symantec/Dominator/lib/objectserver/filesystem"
	"github.com/Symantec/Dominator/lib/srpc/setupserver"
	"github.com/Symantec/Dominator/lib/wsyscall"
	"github.com/Symantec/tricorder/go/tricorder"
	"log"
	_ "net/http/pprof"
	"os"
	"os/user"
	"path"
	"runtime"
	"strconv"
	"syscall"
	"time"
)

const dirPerms = syscall.S_IRWXU

var (
	debug = flag.Bool("debug", false,
		"If true, show debugging output")
	fdLimit = flag.Uint64("fdLimit", getFdLimit(),
		"Maximum number of open file descriptors (this limits concurrent connection attempts)")
	imageServerHostname = flag.String("imageServerHostname", "localhost",
		"Hostname of image server")
	imageServerPortNum = flag.Uint("imageServerPortNum",
		constants.ImageServerPortNumber,
		"Port number of image server")
	mdbFile = flag.String("mdbFile", "mdb",
		"File to read MDB data from, relative to stateDir (default format is JSON)")
	minInterval = flag.Uint("minInterval", 1,
		"Minimum interval between loops (in seconds)")
	objectsDir = flag.String("objectsDir", "objects",
		"Directory containing computed objects, relative to stateDir")
	permitInsecureMode = flag.Bool("permitInsecureMode", false,
		"If true, run in insecure mode. This gives remote access to all")
	portNum = flag.Uint("portNum", constants.DominatorPortNumber,
		"Port number to allocate and listen on for HTTP/RPC")
	stateDir = flag.String("stateDir", "/var/lib/Dominator",
		"Name of dominator state directory.")
	username = flag.String("username", "",
		"If running as root, username to switch to.")
)

func showMdb(mdb *mdb.Mdb) {
	fmt.Println()
	mdb.DebugWrite(os.Stdout)
	fmt.Println()
}

func getFdLimit() uint64 {
	var rlim syscall.Rlimit
	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
		panic(err)
	}
	return rlim.Max
}

func setUser(username string) error {
	// Lock to OS thread so that UID change sticks to this goroutine and the
	// re-exec at the end. wsyscall.SetAllUid() only affects one thread on
	// Linux.
	runtime.LockOSThread()
	if username == "" {
		return errors.New("-username argument missing")
	}
	newUser, err := user.Lookup(username)
	if err != nil {
		return err
	}
	uid, err := strconv.Atoi(newUser.Uid)
	if err != nil {
		return err
	}
	gid, err := strconv.Atoi(newUser.Gid)
	if err != nil {
		return err
	}
	if uid == 0 {
		return errors.New("Do not run the Dominator as root")
		os.Exit(1)
	}
	if err := wsyscall.SetAllGid(gid); err != nil {
		return err
	}
	if err := wsyscall.SetAllUid(uid); err != nil {
		return err
	}
	return syscall.Exec(os.Args[0], os.Args, os.Environ())
}

func pathJoin(first, second string) string {
	if path.IsAbs(second) {
		return path.Clean(second)
	}
	return path.Join(first, second)
}

func newObjectServer(objectsDir string, logger liblog.DebugLogger) (
	*objectserver.ObjectServer, error) {
	fi, err := os.Stat(objectsDir)
	if err != nil {
		if err := os.Mkdir(objectsDir, dirPerms); err != nil {
			return nil, err
		}
	} else if !fi.IsDir() {
		return nil, fmt.Errorf("%s is not a directory\n", objectsDir)
	}
	return objectserver.NewObjectServer(objectsDir, logger)
}

func main() {
	flag.Parse()
	tricorder.RegisterFlags()
	circularBuffer := logbuf.New()
	logger := debuglogger.New(log.New(circularBuffer, "", log.LstdFlags))
	if err := setupserver.SetupTls(); err != nil {
		logger.Println(err)
		circularBuffer.Flush()
		if !*permitInsecureMode {
			os.Exit(1)
		}
	}
	rlim := syscall.Rlimit{*fdLimit, *fdLimit}
	if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
		fmt.Fprintf(os.Stderr, "Cannot set FD limit\t%s\n", err)
		os.Exit(1)
	}
	if os.Geteuid() == 0 {
		if err := setUser(*username); err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
	}
	fi, err := os.Lstat(*stateDir)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot stat: %s\t%s\n", *stateDir, err)
		os.Exit(1)
	}
	if !fi.IsDir() {
		fmt.Fprintf(os.Stderr, "%s is not a directory\n", *stateDir)
		os.Exit(1)
	}
	interval := time.Duration(*minInterval) * time.Second
	mdbChannel := mdbd.StartMdbDaemon(path.Join(*stateDir, *mdbFile), logger)
	objectServer, err := newObjectServer(path.Join(*stateDir, *objectsDir),
		logger)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot load objectcache: %s\n", err)
		os.Exit(1)
	}
	metricsDir, err := tricorder.RegisterDirectory("/dominator/herd")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot create metrics directory: %s\n", err)
		os.Exit(1)
	}
	herd := herd.NewHerd(fmt.Sprintf("%s:%d", *imageServerHostname,
		*imageServerPortNum), objectServer, metricsDir, logger)
	herd.AddHtmlWriter(circularBuffer)
	rpcd.Setup(herd, logger)
	if err = herd.StartServer(*portNum, true); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to create http server\t%s\n", err)
		os.Exit(1)
	}
	scanTokenChannel := make(chan bool, 1)
	scanTokenChannel <- true
	nextCycleStopTime := time.Now().Add(interval)
	for {
		select {
		case mdb := <-mdbChannel:
			herd.MdbUpdate(mdb)
			if *debug {
				showMdb(mdb)
			}
		case <-scanTokenChannel:
			// Scan one sub.
			if herd.PollNextSub() { // We've reached the end of a scan cycle.
				if *debug {
					fmt.Print(".")
				}
				go func(sleepDuration time.Duration) {
					time.Sleep(sleepDuration)
					nextCycleStopTime = time.Now().Add(interval)
					scanTokenChannel <- true
				}(nextCycleStopTime.Sub(time.Now()))
			} else {
				scanTokenChannel <- true
			}
		}
	}
}
<commit_msg>Switch dominator to lib/log/serverlogger package.<commit_after>package main

import (
	"errors"
	"flag"
	"fmt"
	"github.com/Symantec/Dominator/dom/herd"
	"github.com/Symantec/Dominator/dom/rpcd"
	"github.com/Symantec/Dominator/lib/constants"
	"github.com/Symantec/Dominator/lib/log"
	"github.com/Symantec/Dominator/lib/log/serverlogger"
	"github.com/Symantec/Dominator/lib/mdb"
	"github.com/Symantec/Dominator/lib/mdb/mdbd"
	objectserver "github.com/Symantec/Dominator/lib/objectserver/filesystem"
	"github.com/Symantec/Dominator/lib/srpc/setupserver"
	"github.com/Symantec/Dominator/lib/wsyscall"
	"github.com/Symantec/tricorder/go/tricorder"
	_ "net/http/pprof"
	"os"
	"os/user"
	"path"
	"runtime"
	"strconv"
	"syscall"
	"time"
)

const dirPerms = syscall.S_IRWXU

var (
	debug = flag.Bool("debug", false,
		"If true, show debugging output")
	fdLimit = flag.Uint64("fdLimit", getFdLimit(),
		"Maximum number of open file descriptors (this limits concurrent connection attempts)")
	imageServerHostname = flag.String("imageServerHostname", "localhost",
		"Hostname of image server")
	imageServerPortNum = flag.Uint("imageServerPortNum",
		constants.ImageServerPortNumber,
		"Port number of image server")
	mdbFile = flag.String("mdbFile", "mdb",
		"File to read MDB data from, relative to stateDir (default format is JSON)")
	minInterval = flag.Uint("minInterval", 1,
		"Minimum interval between loops (in seconds)")
	objectsDir = flag.String("objectsDir", "objects",
		"Directory containing computed objects, relative to stateDir")
	permitInsecureMode = flag.Bool("permitInsecureMode", false,
		"If true, run in insecure mode. This gives remote access to all")
	portNum = flag.Uint("portNum", constants.DominatorPortNumber,
		"Port number to allocate and listen on for HTTP/RPC")
	stateDir = flag.String("stateDir", "/var/lib/Dominator",
		"Name of dominator state directory.")
	username = flag.String("username", "",
		"If running as root, username to switch to.")
)

func showMdb(mdb *mdb.Mdb) {
	fmt.Println()
	mdb.DebugWrite(os.Stdout)
	fmt.Println()
}

func getFdLimit() uint64 {
	var rlim syscall.Rlimit
	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
		panic(err)
	}
	return rlim.Max
}

func setUser(username string) error {
	// Lock to OS thread so that UID change sticks to this goroutine and the
	// re-exec at the end. wsyscall.SetAllUid() only affects one thread on
	// Linux.
	runtime.LockOSThread()
	if username == "" {
		return errors.New("-username argument missing")
	}
	newUser, err := user.Lookup(username)
	if err != nil {
		return err
	}
	uid, err := strconv.Atoi(newUser.Uid)
	if err != nil {
		return err
	}
	gid, err := strconv.Atoi(newUser.Gid)
	if err != nil {
		return err
	}
	if uid == 0 {
		return errors.New("Do not run the Dominator as root")
		os.Exit(1)
	}
	if err := wsyscall.SetAllGid(gid); err != nil {
		return err
	}
	if err := wsyscall.SetAllUid(uid); err != nil {
		return err
	}
	return syscall.Exec(os.Args[0], os.Args, os.Environ())
}

func pathJoin(first, second string) string {
	if path.IsAbs(second) {
		return path.Clean(second)
	}
	return path.Join(first, second)
}

func newObjectServer(objectsDir string, logger log.DebugLogger) (
	*objectserver.ObjectServer, error) {
	fi, err := os.Stat(objectsDir)
	if err != nil {
		if err := os.Mkdir(objectsDir, dirPerms); err != nil {
			return nil, err
		}
	} else if !fi.IsDir() {
		return nil, fmt.Errorf("%s is not a directory\n", objectsDir)
	}
	return objectserver.NewObjectServer(objectsDir, logger)
}

func main() {
	flag.Parse()
	tricorder.RegisterFlags()
	logger := serverlogger.New("")
	if err := setupserver.SetupTls(); err != nil {
		if *permitInsecureMode {
			logger.Println(err)
		} else {
			logger.Fatalln(err)
		}
	}
	rlim := syscall.Rlimit{*fdLimit, *fdLimit}
	if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
		fmt.Fprintf(os.Stderr, "Cannot set FD limit\t%s\n", err)
		os.Exit(1)
	}
	if os.Geteuid() == 0 {
		if err := setUser(*username); err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
	}
	fi, err := os.Lstat(*stateDir)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot stat: %s\t%s\n", *stateDir, err)
		os.Exit(1)
	}
	if !fi.IsDir() {
		fmt.Fprintf(os.Stderr, "%s is not a directory\n", *stateDir)
		os.Exit(1)
	}
	interval := time.Duration(*minInterval) * time.Second
	mdbChannel := mdbd.StartMdbDaemon(path.Join(*stateDir, *mdbFile), logger)
	objectServer, err := newObjectServer(path.Join(*stateDir, *objectsDir),
		logger)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot load objectcache: %s\n", err)
		os.Exit(1)
	}
	metricsDir, err := tricorder.RegisterDirectory("/dominator/herd")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot create metrics directory: %s\n", err)
		os.Exit(1)
	}
	herd := herd.NewHerd(fmt.Sprintf("%s:%d", *imageServerHostname,
		*imageServerPortNum), objectServer, metricsDir, logger)
	herd.AddHtmlWriter(logger)
	rpcd.Setup(herd, logger)
	if err = herd.StartServer(*portNum, true); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to create http server\t%s\n", err)
		os.Exit(1)
	}
	scanTokenChannel := make(chan bool, 1)
	scanTokenChannel <- true
	nextCycleStopTime := time.Now().Add(interval)
	for {
		select {
		case mdb := <-mdbChannel:
			herd.MdbUpdate(mdb)
			if *debug {
				showMdb(mdb)
			}
		case <-scanTokenChannel:
			// Scan one sub.
			if herd.PollNextSub() { // We've reached the end of a scan cycle.
				if *debug {
					fmt.Print(".")
				}
				go func(sleepDuration time.Duration) {
					time.Sleep(sleepDuration)
					nextCycleStopTime = time.Now().Add(interval)
					scanTokenChannel <- true
				}(nextCycleStopTime.Sub(time.Now()))
			} else {
				scanTokenChannel <- true
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/maprost/gox/gxcfg"
	"github.com/maprost/gox/gxutil/gxgo"
	"log"
)

func main() {
	var err error
	cfgFile := "config.gox"

	// read parameter

	// load config file
	err = gxcfg.InitConfig(cfgFile, gxcfg.DatabaseAccessLink)
	if err != nil {
		log.Fatal("Can't init config: ", err.Error())
	}

	// run godep
	err = gxgo.GoDep()
	if err != nil {
		log.Fatal("Can't run godep: ", err.Error())
	}

	// build (go build)
	err = gxgo.Compile()
	if err != nil {
		log.Fatal("Can't comile: ", err.Error())
	}

	// init dependencies

	// test (go test)

	// build docker images
}
<commit_msg>improve build mode<commit_after>package main

import (
	"github.com/maprost/gox/gxcfg"
	"github.com/maprost/gox/gxutil/gxgo"
	"log"
)

func main() {
	var err error
	cfgFile := "config.gox"

	// read parameter

	// load config file
	err = gxcfg.InitConfig(cfgFile, gxcfg.DatabaseAccessLink)
	if err != nil {
		log.Fatal("Can't init config: ", err.Error())
	}

	// run godep
	err = gxgo.GoDep()
	if err != nil {
		log.Fatal("Can't run godep: ", err.Error())
	}

	// remove old container
	err = gxgo.Remove()
	if err != nil {
		log.Fatal("Can't remove old container: ", err.Error())
	}

	// build (go build)
	err = gxgo.Compile()
	if err != nil {
		log.Fatal("Can't comile: ", err.Error())
	}

	// init dependencies

	// test (go test)

	// build docker images
}
<|endoftext|>