<commit_before>// The gosym command prints symbols in Go source code.
package main

import (
	"bufio"
	"bytes"
	"code.google.com/p/rog-go/exp/go/ast"
	"code.google.com/p/rog-go/exp/go/printer"
	"code.google.com/p/rog-go/exp/go/sym"
	"code.google.com/p/rog-go/exp/go/token"
	"code.google.com/p/rog-go/exp/go/types"
	"flag"
	"fmt"
	"go/build"
	"log"
	"os"
	"path/filepath"
	"strings"
	"sync"
)

// TODO allow changing of package identifiers too.

// caveats:
// - map keys
// - no declaration for init
// - type switches?
// - embedded types
// - import to .
// - test files are ignored.
// - can't change package identifiers
// - there's no way to give an error if renaming creates a
//	clash of symbols.

//gosym list [-t] [pkg...]
//
//list all symbols in all named packages.
//	foo/filename.go:23:3: package referenced-package name type-kind
//
//gosym used pkg...
//
//	reads lines in long format; prints any definitions (in long format)
//	found in pkgs that are used by any other packages.
//
//gosym unused pkg
//	reads lines in long format; prints any definitions (in long format)
//	found in pkgs that are not used by any other packages.
//
//gosym unexport
//	reads lines in long or short format; changes any
//	identifier names to be uncapitalised.
//
//gosym short
//	reads lines in long or short format; prints them in short format.
//
//gosym rename from1 to1 from2 to2 ...
//	reads lines in long or short format; renames symbols according
//	to the given rules.
//
//gosym write [pkg...]
//	reads lines in short format; makes any requested changes,
//	restricting changes to the listed packages.
var verbose = flag.Bool("v", false, "print warning messages")

func main() {
	printf := func(f string, a ...interface{}) { fmt.Fprintf(os.Stderr, f, a...) }
	flag.Usage = func() {
		printf("usage: gosym [flags] [pkgpath...]\n")
		flag.PrintDefaults()
		printf("%s", `
Gosym prints a line for each identifier used in the given
packages. Each line printed has at least 5 space-separated fields
in the following format:
	file-position package referenced-package name type-kind

The file-position field holds the location of the identifier.
The package field holds the path of the package containing the identifier.
The referenced-package field holds the path of the package
where the identifier is defined.
The name field holds the name of the identifier (in X.Y format if
it is defined as a member of another type X).
The type-kind field holds the type class of identifier (const,
type, var or func), and ends with a "+" sign if this line
marks the definition of the identifier.

When the -w flag is specified, gosym reads lines from its standard
symbols and changes symbols in the named packages accordingly. It
expects lines in the same format that it prints. Each identifier at the
line's file-position is changed to the name field.  If the type-kind
field ends with a "+" sign, all occurrences of the identifier will be
changed. Nothing will be changed outside the named packages.

As with gofix, writes are destructive - make sure your
source files are backed up before using gosym -w.
`)
		os.Exit(2)
	}
	flag.Parse()
	if flag.NArg() == 0 {
		flag.Usage()
	}
	name := flag.Arg(0)
	var c cmd
	var args []string
	for _, e := range cmds {
		if e.name == name {
			e.fset.Parse(flag.Args()[1:])
			c = e.c
			args = e.fset.Args()
			break
		}
	}
	if c == nil {
		flag.Usage()
	}
	if err := runCmd(c, args); err != nil {
		log.Printf("gosym %s: %v", name, err)
		os.Exit(1)
	}
}

func runCmd(c cmd, args []string) error {
	types.Panic = false
	initGoPath()
	ctxt := newContext()
	defer ctxt.stdout.Flush()
	return c.run(ctxt, args)
}

type cmd interface {
	run(*context, []string) error
}

type cmdEntry struct {
	name string
	c cmd
	fset *flag.FlagSet
}

var cmds []cmdEntry

func register(name string, c cmd, fset *flag.FlagSet) {
	if fset == nil {
		fset = flag.NewFlagSet("gosym "+name, flag.ExitOnError)
	}
	cmds = append(cmds, cmdEntry{
		name: name,
		c: c,
		fset: fset,
	})
}

type context struct {
	mu sync.Mutex
	*sym.Context
	pkgCache map[string]*ast.Package
	pkgDirs  map[string]string // map from directory to package name.
	stdout   *bufio.Writer
}

func newContext() *context {
	ctxt := &context{
		pkgDirs: make(map[string]string),
		stdout:  bufio.NewWriter(os.Stdout),
		Context: sym.NewContext(),
	}
	ctxt.Logf = func(pos token.Pos, f string, a ...interface{}) {
		if !*verbose {
			return
		}
		log.Printf("%v: %s", ctxt.position(pos), fmt.Sprintf(f, a...))
	}
	return ctxt
}

func initGoPath() {
	// take GOPATH, set types.GoPath to it if it's not empty.
	p := os.Getenv("GOPATH")
	if p == "" {
		return
	}
	gopath := strings.Split(p, ":")
	for i, d := range gopath {
		gopath[i] = filepath.Join(d, "src")
	}
	r := os.Getenv("GOROOT")
	if r != "" {
		gopath = append(gopath, r+"/src/pkg")
	}
	types.GoPath = gopath
}

func (ctxt *context) positionToImportPath(p token.Position) string {
	if p.Filename == "" {
		panic("empty file name")
	}
	dir := filepath.Dir(p.Filename)
	if pkg, ok := ctxt.pkgDirs[dir]; ok {
		return pkg
	}
	bpkg, err := build.Import(".", dir, build.FindOnly)
	if err != nil {
		panic(fmt.Errorf("cannot reverse-map filename to package: %v", err))
	}
	ctxt.pkgDirs[dir] = bpkg.ImportPath
	return bpkg.ImportPath
}

func (ctxt *context) printf(f string, a ...interface{}) {
	fmt.Fprintf(ctxt.stdout, f, a...)
}

func (ctxt *context) position(pos token.Pos) token.Position {
	return ctxt.FileSet.Position(pos)
}

var emptyFileSet = token.NewFileSet()

func pretty(n ast.Node) string {
	var b bytes.Buffer
	printer.Fprint(&b, emptyFileSet, n)
	return b.String()
}
<commit_msg>exp/cmd/gosym: verbose by default<commit_after>// The gosym command prints symbols in Go source code.
package main

import (
	"bufio"
	"bytes"
	"code.google.com/p/rog-go/exp/go/ast"
	"code.google.com/p/rog-go/exp/go/printer"
	"code.google.com/p/rog-go/exp/go/sym"
	"code.google.com/p/rog-go/exp/go/token"
	"code.google.com/p/rog-go/exp/go/types"
	"flag"
	"fmt"
	"go/build"
	"log"
	"os"
	"path/filepath"
	"strings"
	"sync"
)

// TODO allow changing of package identifiers too.

// caveats:
// - map keys
// - no declaration for init
// - type switches?
// - embedded types
// - import to .
// - test files are ignored.
// - can't change package identifiers
// - there's no way to give an error if renaming creates a
//	clash of symbols.

//gosym list [-t] [pkg...]
//
//list all symbols in all named packages.
//	foo/filename.go:23:3: package referenced-package name type-kind
//
//gosym used pkg...
//
//	reads lines in long format; prints any definitions (in long format)
//	found in pkgs that are used by any other packages.
//
//gosym unused pkg
//	reads lines in long format; prints any definitions (in long format)
//	found in pkgs that are not used by any other packages.
//
//gosym unexport
//	reads lines in long or short format; changes any
//	identifier names to be uncapitalised.
//
//gosym short
//	reads lines in long or short format; prints them in short format.
//
//gosym rename from1 to1 from2 to2 ...
//	reads lines in long or short format; renames symbols according
//	to the given rules.
//
//gosym write [pkg...]
//	reads lines in short format; makes any requested changes,
//	restricting changes to the listed packages.
var verbose = flag.Bool("v", true, "print warning messages")

func main() {
	printf := func(f string, a ...interface{}) { fmt.Fprintf(os.Stderr, f, a...) }
	flag.Usage = func() {
		printf("usage: gosym [flags] [pkgpath...]\n")
		flag.PrintDefaults()
		printf("%s", `
Gosym prints a line for each identifier used in the given
packages. Each line printed has at least 5 space-separated fields
in the following format:
	file-position package referenced-package name type-kind

The file-position field holds the location of the identifier.
The package field holds the path of the package containing the identifier.
The referenced-package field holds the path of the package
where the identifier is defined.
The name field holds the name of the identifier (in X.Y format if
it is defined as a member of another type X).
The type-kind field holds the type class of identifier (const,
type, var or func), and ends with a "+" sign if this line
marks the definition of the identifier.

When the -w flag is specified, gosym reads lines from its standard
symbols and changes symbols in the named packages accordingly. It
expects lines in the same format that it prints. Each identifier at the
line's file-position is changed to the name field.  If the type-kind
field ends with a "+" sign, all occurrences of the identifier will be
changed. Nothing will be changed outside the named packages.

As with gofix, writes are destructive - make sure your
source files are backed up before using gosym -w.
`)
		os.Exit(2)
	}
	flag.Parse()
	if flag.NArg() == 0 {
		flag.Usage()
	}
	name := flag.Arg(0)
	var c cmd
	var args []string
	for _, e := range cmds {
		if e.name == name {
			e.fset.Parse(flag.Args()[1:])
			c = e.c
			args = e.fset.Args()
			break
		}
	}
	if c == nil {
		flag.Usage()
	}
	if err := runCmd(c, args); err != nil {
		log.Printf("gosym %s: %v", name, err)
		os.Exit(1)
	}
}

func runCmd(c cmd, args []string) error {
	types.Panic = false
	initGoPath()
	ctxt := newContext()
	defer ctxt.stdout.Flush()
	return c.run(ctxt, args)
}

type cmd interface {
	run(*context, []string) error
}

type cmdEntry struct {
	name string
	c cmd
	fset *flag.FlagSet
}

var cmds []cmdEntry

func register(name string, c cmd, fset *flag.FlagSet) {
	if fset == nil {
		fset = flag.NewFlagSet("gosym "+name, flag.ExitOnError)
	}
	cmds = append(cmds, cmdEntry{
		name: name,
		c: c,
		fset: fset,
	})
}

type context struct {
	mu sync.Mutex
	*sym.Context
	pkgCache map[string]*ast.Package
	pkgDirs  map[string]string // map from directory to package name.
	stdout   *bufio.Writer
}

func newContext() *context {
	ctxt := &context{
		pkgDirs: make(map[string]string),
		stdout:  bufio.NewWriter(os.Stdout),
		Context: sym.NewContext(),
	}
	ctxt.Logf = func(pos token.Pos, f string, a ...interface{}) {
		if !*verbose {
			return
		}
		log.Printf("%v: %s", ctxt.position(pos), fmt.Sprintf(f, a...))
	}
	return ctxt
}

func initGoPath() {
	// take GOPATH, set types.GoPath to it if it's not empty.
	p := os.Getenv("GOPATH")
	if p == "" {
		return
	}
	gopath := strings.Split(p, ":")
	for i, d := range gopath {
		gopath[i] = filepath.Join(d, "src")
	}
	r := os.Getenv("GOROOT")
	if r != "" {
		gopath = append(gopath, r+"/src/pkg")
	}
	types.GoPath = gopath
}

func (ctxt *context) positionToImportPath(p token.Position) string {
	if p.Filename == "" {
		panic("empty file name")
	}
	dir := filepath.Dir(p.Filename)
	if pkg, ok := ctxt.pkgDirs[dir]; ok {
		return pkg
	}
	bpkg, err := build.Import(".", dir, build.FindOnly)
	if err != nil {
		panic(fmt.Errorf("cannot reverse-map filename to package: %v", err))
	}
	ctxt.pkgDirs[dir] = bpkg.ImportPath
	return bpkg.ImportPath
}

func (ctxt *context) printf(f string, a ...interface{}) {
	fmt.Fprintf(ctxt.stdout, f, a...)
}

func (ctxt *context) position(pos token.Pos) token.Position {
	return ctxt.FileSet.Position(pos)
}

var emptyFileSet = token.NewFileSet()

func pretty(n ast.Node) string {
	var b bytes.Buffer
	printer.Fprint(&b, emptyFileSet, n)
	return b.String()
}
<|endoftext|>


<commit_before>package api

import (
	"errors"
	"math"
	"net/http"
	"net/url"
	"socialapi/config"
	// TODO delete these socialapi dependencies
	socialmodels "socialapi/models"
	socialhelpers "socialapi/workers/api/modules/helpers"
	"socialapi/workers/notification/models"
	"strconv"

	"github.com/jinzhu/gorm"
	"github.com/koding/api/helpers"
	// "github.com/koding/bongo"
)

var (
	NOTIFICATION_LIMIT = 8
	ACTOR_LIMIT        = 3
	cacheEnabled       = false
)

func init() {
	helpers.MustInitLogger("NotificationAPI", false)
}

func List(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	q := socialhelpers.GetQuery(u)
	if err := validateNotificationRequest(q); err != nil {
		return socialhelpers.NewBadRequestResponse(err)
	}

	conf := config.Get()
	cacheEnabled = conf.Notification.CacheEnabled

	urlQuery := u.Query()
	cache, err := strconv.ParseBool(urlQuery.Get("cache"))
	if err == nil {
		cacheEnabled = cache
	}

	return socialhelpers.HandleResultAndError(fetchNotifications(q))
}

func Glance(u *url.URL, h http.Header, req *models.Notification) (int, http.Header, interface{}, error) {
	q := socialmodels.NewQuery()
	q.AccountId = req.AccountId
	if err := validateNotificationRequest(q); err != nil {
		return socialhelpers.NewBadRequestResponse(err)
	}
	if err := req.Glance(); err != nil {
		return socialhelpers.NewBadRequestResponse(err)
	}

	return socialhelpers.NewDefaultOKResponse()
}

func fetchNotifications(q *socialmodels.Query) (*models.NotificationResponse, error) {
	var list *models.NotificationResponse
	var err error

	// TODO enable cache
	// first check redis
	// var cacheInstance *cache.NotificationCache
	// if cacheEnabled {
	// 	cacheInstance = cache.NewNotificationCache()
	// 	cacheInstance.ActorLimit = ACTOR_LIMIT
	// 	list, err = cacheInstance.FetchNotifications(q.AccountId)
	// 	if err != nil {
	// 		log.Error("Cache error: %s", err)
	// 	}
	// 	if err == nil && len(list.Notifications) > 0 {
	// 		return list, nil
	// 	}
	// }

	n := models.NewNotification()
	list, err = n.List(q)
	if err != nil {
		return nil, err
	}

	// TODO enable cache update
	// go func() {
	// 	if cacheEnabled {
	// 		if err := cacheInstance.UpdateCachedNotifications(q.AccountId, list); err != nil {
	// 			log.Error("Cache cannot be updated: %s", err)
	// 		}
	// 	}
	// }()

	return list, nil
}

func validateNotificationRequest(q *socialmodels.Query) error {
	if err := validateAccount(q.AccountId); err != nil {
		return err
	}
	// update the limit if it is needed
	q.Limit = int(math.Min(float64(q.Limit), float64(NOTIFICATION_LIMIT)))

	return nil
}

func validateAccount(accountId int64) error {
	a := socialmodels.NewAccount()
	if accountId == 0 {
		return errors.New("Account id cannot be empty")
	}

	if err := a.ById(accountId); err != nil {
		if err == gorm.RecordNotFound {
			return errors.New("Account is not valid")
		}
		return err
	}

	return nil
}

func validateMessage(messageId int64) error {
	if err := socialmodels.NewChannelMessage().ById(messageId); err != nil {
		if err == gorm.RecordNotFound {
			return errors.New("Channel message does not exist")
		}
		return err
	}

	return nil
}
<commit_msg>Notification: notification api log initialization is regressed<commit_after>package api

import (
	"errors"
	"math"
	"net/http"
	"net/url"
	"socialapi/config"
	// TODO delete these socialapi dependencies
	socialmodels "socialapi/models"
	socialhelpers "socialapi/workers/api/modules/helpers"
	"socialapi/workers/notification/models"
	"strconv"

	"github.com/jinzhu/gorm"
	// "github.com/koding/bongo"
)

var (
	NOTIFICATION_LIMIT = 8
	ACTOR_LIMIT        = 3
	cacheEnabled       = false
)

const (
	NOTIFICATION_TYPE_SUBSCRIBE   = "subscribe"
	NOTIFICATION_TYPE_UNSUBSCRIBE = "unsubscribe"
)

func List(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	q := socialhelpers.GetQuery(u)
	if err := validateNotificationRequest(q); err != nil {
		return socialhelpers.NewBadRequestResponse(err)
	}

	conf := config.Get()
	cacheEnabled = conf.Notification.CacheEnabled

	urlQuery := u.Query()
	cache, err := strconv.ParseBool(urlQuery.Get("cache"))
	if err == nil {
		cacheEnabled = cache
	}

	return socialhelpers.HandleResultAndError(fetchNotifications(q))
}

func Glance(u *url.URL, h http.Header, req *models.Notification) (int, http.Header, interface{}, error) {
	q := socialmodels.NewQuery()
	q.AccountId = req.AccountId
	if err := validateNotificationRequest(q); err != nil {
		return socialhelpers.NewBadRequestResponse(err)
	}
	if err := req.Glance(); err != nil {
		return socialhelpers.NewBadRequestResponse(err)
	}

	return socialhelpers.NewDefaultOKResponse()
}

func fetchNotifications(q *socialmodels.Query) (*models.NotificationResponse, error) {
	var list *models.NotificationResponse
	var err error

	// TODO enable cache
	// first check redis
	// var cacheInstance *cache.NotificationCache
	// if cacheEnabled {
	// 	cacheInstance = cache.NewNotificationCache()
	// 	cacheInstance.ActorLimit = ACTOR_LIMIT
	// 	list, err = cacheInstance.FetchNotifications(q.AccountId)
	// 	if err != nil {
	// 		log.Error("Cache error: %s", err)
	// 	}
	// 	if err == nil && len(list.Notifications) > 0 {
	// 		return list, nil
	// 	}
	// }

	n := models.NewNotification()
	list, err = n.List(q)
	if err != nil {
		return nil, err
	}

	// TODO enable cache update
	// go func() {
	// 	if cacheEnabled {
	// 		if err := cacheInstance.UpdateCachedNotifications(q.AccountId, list); err != nil {
	// 			log.Error("Cache cannot be updated: %s", err)
	// 		}
	// 	}
	// }()

	return list, nil
}

func validateNotificationRequest(q *socialmodels.Query) error {
	if err := validateAccount(q.AccountId); err != nil {
		return err
	}
	// update the limit if it is needed
	q.Limit = int(math.Min(float64(q.Limit), float64(NOTIFICATION_LIMIT)))

	return nil
}

func validateAccount(accountId int64) error {
	a := socialmodels.NewAccount()
	if accountId == 0 {
		return errors.New("Account id cannot be empty")
	}

	if err := a.ById(accountId); err != nil {
		if err == gorm.RecordNotFound {
			return errors.New("Account is not valid")
		}
		return err
	}

	return nil
}

func validateMessage(messageId int64) error {
	if err := socialmodels.NewChannelMessage().ById(messageId); err != nil {
		if err == gorm.RecordNotFound {
			return errors.New("Channel message does not exist")
		}
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package google

import (
	"fmt"
	"testing"

	"code.google.com/p/google-api-go-client/compute/v1"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccComputeInstanceTemplate_basic(t *testing.T) {
	var instanceTemplate compute.InstanceTemplate

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccComputeInstanceTemplate_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckComputeInstanceTemplateExists(
						"google_compute_instance_template.foobar", &instanceTemplate),
					testAccCheckComputeInstanceTemplateTag(&instanceTemplate, "foo"),
					testAccCheckComputeInstanceTemplateMetadata(&instanceTemplate, "foo", "bar"),
					testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "debian-7-wheezy-v20140814", true, true),
				),
			},
		},
	})
}

func TestAccComputeInstanceTemplate_IP(t *testing.T) {
	var instanceTemplate compute.InstanceTemplate

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccComputeInstanceTemplate_ip,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckComputeInstanceTemplateExists(
						"google_compute_instance_template.foobar", &instanceTemplate),
					testAccCheckComputeInstanceTemplateNetwork(&instanceTemplate),
				),
			},
		},
	})
}

func TestAccComputeInstanceTemplate_disks(t *testing.T) {
	var instanceTemplate compute.InstanceTemplate

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccComputeInstanceTemplate_disks,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckComputeInstanceTemplateExists(
						"google_compute_instance_template.foobar", &instanceTemplate),
					testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "debian-7-wheezy-v20140814", true, true),
					testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "foo_existing_disk", false, false),
				),
			},
		},
	})
}

func testAccCheckComputeInstanceTemplateDestroy(s *terraform.State) error {
	config := testAccProvider.Meta().(*Config)

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

		_, err := config.clientCompute.InstanceTemplates.Get(
			config.Project, rs.Primary.ID).Do()
		if err == nil {
			return fmt.Errorf("Instance template still exists")
		}
	}

	return nil
}

func testAccCheckComputeInstanceTemplateExists(n string, instanceTemplate *compute.InstanceTemplate) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		config := testAccProvider.Meta().(*Config)

		found, err := config.clientCompute.InstanceTemplates.Get(
			config.Project, rs.Primary.ID).Do()
		if err != nil {
			return err
		}

		if found.Name != rs.Primary.ID {
			return fmt.Errorf("Instance template not found")
		}

		*instanceTemplate = *found

		return nil
	}
}

func testAccCheckComputeInstanceTemplateMetadata(
	instanceTemplate *compute.InstanceTemplate,
	k string, v string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if instanceTemplate.Properties.Metadata == nil {
			return fmt.Errorf("no metadata")
		}

		for _, item := range instanceTemplate.Properties.Metadata.Items {
			if k != item.Key {
				continue
			}

			if v == item.Value {
				return nil
			}

			return fmt.Errorf("bad value for %s: %s", k, item.Value)
		}

		return fmt.Errorf("metadata not found: %s", k)
	}
}

func testAccCheckComputeInstanceTemplateNetwork(instanceTemplate *compute.InstanceTemplate) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		for _, i := range instanceTemplate.Properties.NetworkInterfaces {
			for _, c := range i.AccessConfigs {
				if c.NatIP == "" {
					return fmt.Errorf("no NAT IP")
				}
			}
		}

		return nil
	}
}

func testAccCheckComputeInstanceTemplateDisk(instanceTemplate *compute.InstanceTemplate, source string, delete bool, boot bool) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if instanceTemplate.Properties.Disks == nil {
			return fmt.Errorf("no disks")
		}

		for _, disk := range instanceTemplate.Properties.Disks {
			if disk.InitializeParams == nil {
				// Check disk source
				if disk.Source == source {
					if disk.AutoDelete == delete && disk.Boot == boot {
						return nil
					}
				}
			} else {
				// Check source image
				if disk.InitializeParams.SourceImage == source {
					if disk.AutoDelete == delete && disk.Boot == boot {
						return nil
					}
				}
			}
		}

		return fmt.Errorf("Disk not found: %s", source)
	}
}

func testAccCheckComputeInstanceTemplateTag(instanceTemplate *compute.InstanceTemplate, n string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if instanceTemplate.Properties.Tags == nil {
			return fmt.Errorf("no tags")
		}

		for _, k := range instanceTemplate.Properties.Tags.Items {
			if k == n {
				return nil
			}
		}

		return fmt.Errorf("tag not found: %s", n)
	}
}

const testAccComputeInstanceTemplate_basic = `
resource "google_compute_instance_template" "foobar" {
	name = "terraform-test"
	machine_type = "n1-standard-1"
	can_ip_forward = false
	tags = ["foo", "bar"]

	disk {
		source_image = "debian-7-wheezy-v20140814"
		auto_delete = true
		boot = true
	}

	network {
		source = "default"
	}

	metadata {
		foo = "bar"
	}

	service_account {
		scopes = ["userinfo-email", "compute-ro", "storage-ro"]
	}
}`

const testAccComputeInstanceTemplate_ip = `
resource "google_compute_address" "foo" {
	name = "foo"
}

resource "google_compute_instance_template" "foobar" {
	name = "terraform-test"
	machine_type = "n1-standard-1"
	tags = ["foo", "bar"]

	disk {
		source_image = "debian-7-wheezy-v20140814"
	}

	network {
		source = "default"
		address = "${google_compute_address.foo.address}"
	}

	metadata {
		foo = "bar"
	}
}`

const testAccComputeInstanceTemplate_disks = `
resource "google_compute_instance_template" "foobar" {
	name = "terraform-test"
	machine_type = "n1-standard-1"

	disk {
		source_image = "debian-7-wheezy-v20140814"
		auto_delete = true
		boot = true
	}

	disk {
		source = "foo_existing_disk"
		auto_delete = false
		boot = false
	}

	network {
		source = "default"
	}

	metadata {
		foo = "bar"
	}
}`
<commit_msg>Update GCE Instance Template tests now that existing disk must exist prior to template creation.<commit_after>package google

import (
	"fmt"
	"testing"

	"code.google.com/p/google-api-go-client/compute/v1"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccComputeInstanceTemplate_basic(t *testing.T) {
	var instanceTemplate compute.InstanceTemplate

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccComputeInstanceTemplate_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckComputeInstanceTemplateExists(
						"google_compute_instance_template.foobar", &instanceTemplate),
					testAccCheckComputeInstanceTemplateTag(&instanceTemplate, "foo"),
					testAccCheckComputeInstanceTemplateMetadata(&instanceTemplate, "foo", "bar"),
					testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "debian-7-wheezy-v20140814", true, true),
				),
			},
		},
	})
}

func TestAccComputeInstanceTemplate_IP(t *testing.T) {
	var instanceTemplate compute.InstanceTemplate

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccComputeInstanceTemplate_ip,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckComputeInstanceTemplateExists(
						"google_compute_instance_template.foobar", &instanceTemplate),
					testAccCheckComputeInstanceTemplateNetwork(&instanceTemplate),
				),
			},
		},
	})
}

func TestAccComputeInstanceTemplate_disks(t *testing.T) {
	var instanceTemplate compute.InstanceTemplate

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccComputeInstanceTemplate_disks,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckComputeInstanceTemplateExists(
						"google_compute_instance_template.foobar", &instanceTemplate),
					testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "debian-7-wheezy-v20140814", true, true),
					testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "terraform-test-foobar", false, false),
				),
			},
		},
	})
}

func testAccCheckComputeInstanceTemplateDestroy(s *terraform.State) error {
	config := testAccProvider.Meta().(*Config)

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

		_, err := config.clientCompute.InstanceTemplates.Get(
			config.Project, rs.Primary.ID).Do()
		if err == nil {
			return fmt.Errorf("Instance template still exists")
		}
	}

	return nil
}

func testAccCheckComputeInstanceTemplateExists(n string, instanceTemplate *compute.InstanceTemplate) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		config := testAccProvider.Meta().(*Config)

		found, err := config.clientCompute.InstanceTemplates.Get(
			config.Project, rs.Primary.ID).Do()
		if err != nil {
			return err
		}

		if found.Name != rs.Primary.ID {
			return fmt.Errorf("Instance template not found")
		}

		*instanceTemplate = *found

		return nil
	}
}

func testAccCheckComputeInstanceTemplateMetadata(
	instanceTemplate *compute.InstanceTemplate,
	k string, v string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if instanceTemplate.Properties.Metadata == nil {
			return fmt.Errorf("no metadata")
		}

		for _, item := range instanceTemplate.Properties.Metadata.Items {
			if k != item.Key {
				continue
			}

			if v == item.Value {
				return nil
			}

			return fmt.Errorf("bad value for %s: %s", k, item.Value)
		}

		return fmt.Errorf("metadata not found: %s", k)
	}
}

func testAccCheckComputeInstanceTemplateNetwork(instanceTemplate *compute.InstanceTemplate) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		for _, i := range instanceTemplate.Properties.NetworkInterfaces {
			for _, c := range i.AccessConfigs {
				if c.NatIP == "" {
					return fmt.Errorf("no NAT IP")
				}
			}
		}

		return nil
	}
}

func testAccCheckComputeInstanceTemplateDisk(instanceTemplate *compute.InstanceTemplate, source string, delete bool, boot bool) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if instanceTemplate.Properties.Disks == nil {
			return fmt.Errorf("no disks")
		}

		for _, disk := range instanceTemplate.Properties.Disks {
			if disk.InitializeParams == nil {
				// Check disk source
				if disk.Source == source {
					if disk.AutoDelete == delete && disk.Boot == boot {
						return nil
					}
				}
			} else {
				// Check source image
				if disk.InitializeParams.SourceImage == source {
					if disk.AutoDelete == delete && disk.Boot == boot {
						return nil
					}
				}
			}
		}

		return fmt.Errorf("Disk not found: %s", source)
	}
}

func testAccCheckComputeInstanceTemplateTag(instanceTemplate *compute.InstanceTemplate, n string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if instanceTemplate.Properties.Tags == nil {
			return fmt.Errorf("no tags")
		}

		for _, k := range instanceTemplate.Properties.Tags.Items {
			if k == n {
				return nil
			}
		}

		return fmt.Errorf("tag not found: %s", n)
	}
}

const testAccComputeInstanceTemplate_basic = `
resource "google_compute_instance_template" "foobar" {
	name = "terraform-test"
	machine_type = "n1-standard-1"
	can_ip_forward = false
	tags = ["foo", "bar"]

	disk {
		source_image = "debian-7-wheezy-v20140814"
		auto_delete = true
		boot = true
	}

	network {
		source = "default"
	}

	metadata {
		foo = "bar"
	}

	service_account {
		scopes = ["userinfo-email", "compute-ro", "storage-ro"]
	}
}`

const testAccComputeInstanceTemplate_ip = `
resource "google_compute_address" "foo" {
	name = "foo"
}

resource "google_compute_instance_template" "foobar" {
	name = "terraform-test"
	machine_type = "n1-standard-1"
	tags = ["foo", "bar"]

	disk {
		source_image = "debian-7-wheezy-v20140814"
	}

	network {
		source = "default"
		address = "${google_compute_address.foo.address}"
	}

	metadata {
		foo = "bar"
	}
}`

const testAccComputeInstanceTemplate_disks = `
resource "google_compute_disk" "foobar" {
	name = "terraform-test-foobar"
	image = "debian-7-wheezy-v20140814"
	size = 10
	type = "pd-ssd"
	zone = "us-central1-a"
}

resource "google_compute_instance_template" "foobar" {
	name = "terraform-test"
	machine_type = "n1-standard-1"

	disk {
		source_image = "debian-7-wheezy-v20140814"
		auto_delete = true
		boot = true
	}

	disk {
		source = "terraform-test-foobar"
		auto_delete = false
		boot = false
	}

	network {
		source = "default"
	}

	metadata {
		foo = "bar"
	}
}`
<|endoftext|>


<commit_before>package store

import (
	"encoding/json"
	"errors"
	"fmt"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/aslanides/gocrud/req"
	"github.com/aslanides/gocrud/x"
)

// Update stores the create and update instructions, acting as the modifier
// to the entity Update relates to.
type Update struct {
	kind     string
	id       string
	source   string
	children []*Update
	parent   *Update
	edges    map[string]interface{}
	NanoTs   int64
}

// NewUpdate is the main entrypoint to updates. Returns back a Update
// object pointer, to run create and update operations on.
func NewUpdate(kind, id string) *Update {
	log.WithFields(logrus.Fields{
		"func": "NewUpdate",
		"kind": kind,
		"id":   id,
	}).Debug("Called")
	n := new(Update)
	n.kind = kind
	n.id = id
	n.NanoTs = time.Now().UnixNano()
	return n
}

// SetSource sets the author of the update. Generally, the userid of the
// modifier.
func (n *Update) SetSource(source string) *Update {
	n.source = source
	return n
}

// AddChild creates a new entity with the given kind, and creates a
// directed relationship from current entity to this new child entity.
// This is useful to generate arbitrarily deep and complex data structures,
// for e.g. Posts by Users, Comments on Posts, Likes on Posts etc.
//
// Retuns the Update pointer for the child entity, so any update operations
// done on this pointer would be reflected in the child entity. Note that
// a child can only have one parent by design.
func (n *Update) AddChild(kind string) *Update {
	log.WithField("childkind", kind).Debug("AddChild")
	child := new(Update)
	child.parent = n
	child.kind = kind
	child.NanoTs = n.NanoTs
	child.source = n.source
	n.children = append(n.children, child)
	return child
}

// Set allows you to set the property and value on the current entity.
// This would effectively replace any other value this property had,
// on this entity node pointer represents.
// But, no actual data would be overwritten though, as per the retention
// principle.
func (n *Update) Set(property string, value interface{}) *Update {
	log.WithField(property, value).Debug("Set")
	if n.edges == nil {
		n.edges = make(map[string]interface{})
	}
	n.edges[property] = value
	return n
}

// Marks the current entity for deletion. This is equivalent to doing a
// Set("delete_me", true), and then running q.FilterOut("delete_me") during
// query phase. Nothing is actually deleted though, as per the retention
// principle.
func (n *Update) MarkDeleted() *Update {
	return n.Set("_delete_", true)
}

func (n *Update) MarkRestored() *Update {
	return n.Set("_delete_", false)
}

func (n *Update) recPrint(l int) {
	log.Printf("Update[%d]: %+v", l, n)
	for _, child := range n.children {
		child.recPrint(l + 1)
	}
}

func (n *Update) root() *Update {
	for n.parent != nil {
		n = n.parent
	}
	return n
}

// Print finds the root from the given Update pointer, and does a recursive
// print on the tree for debugging purposes.
func (n *Update) Print() *Update {
	n = n.root()
	n.recPrint(0)
	return n
}

func (n *Update) Id() string {
	return n.id
}

func (n *Update) setCommitTs(tsNano int64) {
	n.NanoTs = tsNano
	for _, child := range n.children {
		child.setCommitTs(tsNano)
	}
}

// SetCommitTs allows you to set the commit timestamp of the update.
// The timestamp provided should be in nano-seconds. SetCommitTs
// can only be called on the root update node.
func (n *Update) SetCommitTs(tsNano int64) *Update {
	if n.parent != nil {
		log.Error("SetCommitTs called on a child node. Ignoring...")
		return n
	}
	n.setCommitTs(tsNano)
	return n
}

func (n *Update) doExecute(c *req.Context, its *[]*x.Instruction) error {
	for pred, val := range n.edges {
		if len(n.source) == 0 {
			return errors.New(fmt.Sprintf(
				"No source specified for id: %v kind: %v", n.id, n.kind))
		}

		i := new(x.Instruction)
		i.SubjectId = n.id
		i.SubjectType = n.kind
		i.Predicate = pred

		if b, err := json.Marshal(val); err != nil {
			return err
		} else {
			i.Object = b
		}
		i.Source = n.source
		i.NanoTs = n.NanoTs
		log.WithField("instruction", i).Debug("Pushing to list")
		*its = append(*its, i)
	}

	if len(n.children) == 0 {
		return nil
	}
	if len(n.source) == 0 {
		return errors.New(fmt.Sprintf(
			"No source specified for id: %v kind: %v", n.id, n.kind))
	}

	// Children can only be added, not deleted via API. But they can be stopped
	// from being retrieved.
	// Scenario: How do I stop childA from being retrieved?
	// Answer:
	// Modify child by adding a 'deleted' edge
	// Get(ChildKind, ChildId).Set("deleted", true).Execute(c)
	//
	// Then for retrieval from parent:
	// NewQuery(ParentKind, ParentId).Collect(ChildKind).FilterOut("deleted")
	// This would remove all children with a 'deleted' edge.
	// Better still
	// Get(ChildKind, ChildId).MarkDeleted().Execute(c)
	// would automatically filter out that child and it's children
	// from being retrieved.

	for _, child := range n.children {
		if len(child.id) > 0 {
			log.WithField("child_id", child.id).Fatal(
				"Child id should be empty for all current use cases")
			return errors.New("Non empty child id")
		}

		for idx := 0; ; idx++ { // Retry loop.
			child.id = x.UniqueString(c.NumCharsUnique)
			log.WithField("id", child.id).Debug("Checking availability of new id")
			if isnew := Get().IsNew(child.id); isnew {
				log.WithField("id", child.id).Debug("New id available")
				break
			}
			if idx >= 30 {
				return errors.New("Unable to find new id")
			}
		}
		// Create edge from parent to child
		i := new(x.Instruction)
		i.SubjectId = n.id
		i.SubjectType = n.kind
		i.Predicate = child.kind
		i.ObjectId = child.id
		i.Source = n.source
		i.NanoTs = n.NanoTs
		log.WithField("instruction", i).Debug("Pushing to list")
		*its = append(*its, i)

		// Create edge from child to parent
		i = new(x.Instruction)
		i.SubjectId = child.id
		i.SubjectType = child.kind
		i.Predicate = "_parent_"
		i.ObjectId = n.id
		i.Source = n.source
		i.NanoTs = n.NanoTs
		log.WithField("instruction", i).Debug("Pushing to list")
		*its = append(*its, i)

		if err := child.doExecute(c, its); err != nil {
			return err
		}
	}
	return nil
}

// Execute finds the root from the given Update pointer, recursively generates
// the set of instructions to store, and commits them. Returns any errors
// encountered during these steps.
func (n *Update) Execute(c *req.Context) error {
	if c.NumCharsUnique <= 0 {
		log.Fatal("Invalid number of chars for generating unique ids. Set req.Context.NumCharsUnique")
		return errors.New("Invalid req.Context.NumCharsUnique")
	}

	n = n.root()

	var its []*x.Instruction
	err := n.doExecute(c, &its)
	if err != nil {
		return err
	}
	if len(its) == 0 {
		return errors.New("No instructions generated")
	}

	if rerr := Get().Commit(its); rerr != nil {
		return rerr
	}

	if c.HasIndexer {
		// This block of code figures out which entities have been modified,
		// and sends them off to be updated by indexer.
		updates := make(map[x.Entity]bool)
		for _, it := range its {
			e := x.Entity{Kind: it.SubjectType, Id: it.SubjectId}
			if _, present := updates[e]; present { // find distinct entities
				continue
			}
			c.Updates <- e
			updates[e] = true
		}
	}
	return nil
}
<commit_msg>Revert "Add MarkRestored()"<commit_after>package store

import (
	"encoding/json"
	"errors"
	"fmt"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/aslanides/gocrud/req"
	"github.com/aslanides/gocrud/x"
)

// Update stores the create and update instructions, acting as the modifier
// to the entity Update relates to.
type Update struct {
	kind     string
	id       string
	source   string
	children []*Update
	parent   *Update
	edges    map[string]interface{}
	NanoTs   int64
}

// NewUpdate is the main entrypoint to updates. Returns back a Update
// object pointer, to run create and update operations on.
func NewUpdate(kind, id string) *Update {
	log.WithFields(logrus.Fields{
		"func": "NewUpdate",
		"kind": kind,
		"id":   id,
	}).Debug("Called")
	n := new(Update)
	n.kind = kind
	n.id = id
	n.NanoTs = time.Now().UnixNano()
	return n
}

// SetSource sets the author of the update. Generally, the userid of the
// modifier.
func (n *Update) SetSource(source string) *Update {
	n.source = source
	return n
}

// AddChild creates a new entity with the given kind, and creates a
// directed relationship from current entity to this new child entity.
// This is useful to generate arbitrarily deep and complex data structures,
// for e.g. Posts by Users, Comments on Posts, Likes on Posts etc.
//
// Retuns the Update pointer for the child entity, so any update operations
// done on this pointer would be reflected in the child entity. Note that
// a child can only have one parent by design.
func (n *Update) AddChild(kind string) *Update {
	log.WithField("childkind", kind).Debug("AddChild")
	child := new(Update)
	child.parent = n
	child.kind = kind
	child.NanoTs = n.NanoTs
	child.source = n.source
	n.children = append(n.children, child)
	return child
}

// Set allows you to set the property and value on the current entity.
// This would effectively replace any other value this property had,
// on this entity node pointer represents.
// But, no actual data would be overwritten though, as per the retention
// principle.
func (n *Update) Set(property string, value interface{}) *Update {
	log.WithField(property, value).Debug("Set")
	if n.edges == nil {
		n.edges = make(map[string]interface{})
	}
	n.edges[property] = value
	return n
}

// Marks the current entity for deletion. This is equivalent to doing a
// Set("delete_me", true), and then running q.FilterOut("delete_me") during
// query phase. Nothing is actually deleted though, as per the retention
// principle.
func (n *Update) MarkDeleted() *Update {
	return n.Set("_delete_", true)
}

func (n *Update) recPrint(l int) {
	log.Printf("Update[%d]: %+v", l, n)
	for _, child := range n.children {
		child.recPrint(l + 1)
	}
}

func (n *Update) root() *Update {
	for n.parent != nil {
		n = n.parent
	}
	return n
}

// Print finds the root from the given Update pointer, and does a recursive
// print on the tree for debugging purposes.
func (n *Update) Print() *Update {
	n = n.root()
	n.recPrint(0)
	return n
}

func (n *Update) Id() string {
	return n.id
}

func (n *Update) setCommitTs(tsNano int64) {
	n.NanoTs = tsNano
	for _, child := range n.children {
		child.setCommitTs(tsNano)
	}
}

// SetCommitTs allows you to set the commit timestamp of the update.
// The timestamp provided should be in nano-seconds. SetCommitTs
// can only be called on the root update node.
func (n *Update) SetCommitTs(tsNano int64) *Update {
	if n.parent != nil {
		log.Error("SetCommitTs called on a child node. Ignoring...")
		return n
	}
	n.setCommitTs(tsNano)
	return n
}

func (n *Update) doExecute(c *req.Context, its *[]*x.Instruction) error {
	for pred, val := range n.edges {
		if len(n.source) == 0 {
			return errors.New(fmt.Sprintf(
				"No source specified for id: %v kind: %v", n.id, n.kind))
		}

		i := new(x.Instruction)
		i.SubjectId = n.id
		i.SubjectType = n.kind
		i.Predicate = pred

		if b, err := json.Marshal(val); err != nil {
			return err
		} else {
			i.Object = b
		}
		i.Source = n.source
		i.NanoTs = n.NanoTs
		log.WithField("instruction", i).Debug("Pushing to list")
		*its = append(*its, i)
	}

	if len(n.children) == 0 {
		return nil
	}
	if len(n.source) == 0 {
		return errors.New(fmt.Sprintf(
			"No source specified for id: %v kind: %v", n.id, n.kind))
	}

	// Children can only be added, not deleted via API. But they can be stopped
	// from being retrieved.
	// Scenario: How do I stop childA from being retrieved?
	// Answer:
	// Modify child by adding a 'deleted' edge
	// Get(ChildKind, ChildId).Set("deleted", true).Execute(c)
	//
	// Then for retrieval from parent:
	// NewQuery(ParentKind, ParentId).Collect(ChildKind).FilterOut("deleted")
	// This would remove all children with a 'deleted' edge.
	// Better still
	// Get(ChildKind, ChildId).MarkDeleted().Execute(c)
	// would automatically filter out that child and it's children
	// from being retrieved.

	for _, child := range n.children {
		if len(child.id) > 0 {
			log.WithField("child_id", child.id).Fatal(
				"Child id should be empty for all current use cases")
			return errors.New("Non empty child id")
		}

		for idx := 0; ; idx++ { // Retry loop.
			child.id = x.UniqueString(c.NumCharsUnique)
			log.WithField("id", child.id).Debug("Checking availability of new id")
			if isnew := Get().IsNew(child.id); isnew {
				log.WithField("id", child.id).Debug("New id available")
				break
			}
			if idx >= 30 {
				return errors.New("Unable to find new id")
			}
		}
		// Create edge from parent to child
		i := new(x.Instruction)
		i.SubjectId = n.id
		i.SubjectType = n.kind
		i.Predicate = child.kind
		i.ObjectId = child.id
		i.Source = n.source
		i.NanoTs = n.NanoTs
		log.WithField("instruction", i).Debug("Pushing to list")
		*its = append(*its, i)

		// Create edge from child to parent
		i = new(x.Instruction)
		i.SubjectId = child.id
		i.SubjectType = child.kind
		i.Predicate = "_parent_"
		i.ObjectId = n.id
		i.Source = n.source
		i.NanoTs = n.NanoTs
		log.WithField("instruction", i).Debug("Pushing to list")
		*its = append(*its, i)

		if err := child.doExecute(c, its); err != nil {
			return err
		}
	}
	return nil
}

// Execute finds the root from the given Update pointer, recursively generates
// the set of instructions to store, and commits them. Returns any errors
// encountered during these steps.
func (n *Update) Execute(c *req.Context) error {
	if c.NumCharsUnique <= 0 {
		log.Fatal("Invalid number of chars for generating unique ids. Set req.Context.NumCharsUnique")
		return errors.New("Invalid req.Context.NumCharsUnique")
	}

	n = n.root()

	var its []*x.Instruction
	err := n.doExecute(c, &its)
	if err != nil {
		return err
	}
	if len(its) == 0 {
		return errors.New("No instructions generated")
	}

	if rerr := Get().Commit(its); rerr != nil {
		return rerr
	}

	if c.HasIndexer {
		// This block of code figures out which entities have been modified,
		// and sends them off to be updated by indexer.
		updates := make(map[x.Entity]bool)
		for _, it := range its {
			e := x.Entity{Kind: it.SubjectType, Id: it.SubjectId}
			if _, present := updates[e]; present { // find distinct entities
				continue
			}
			c.Updates <- e
			updates[e] = true
		}
	}
	return nil
}
<|endoftext|>


<commit_before><commit_msg>Use timeformat similar to kitchen (possibly fixes #5)<commit_after><|endoftext|>


<commit_before>package server

import (
	"encoding/json"
	"fmt"
	"net/http"
	"sort"

	"golang.org/x/net/context"

	"github.com/influxdata/chronograf"
	"github.com/influxdata/chronograf/oauth2"
	"github.com/influxdata/chronograf/organizations"
)

type meLinks struct {
	Self string `json:"self"` // Self link mapping to this resource
}

type meResponse struct {
	*chronograf.User
	Links               meLinks                   `json:"links"`
	Organizations       []chronograf.Organization `json:"organizations,omitempty"`
	CurrentOrganization *chronograf.Organization  `json:"currentOrganization,omitempty"`
}

// If new user response is nil, return an empty meResponse because it
// indicates authentication is not needed
func newMeResponse(usr *chronograf.User) meResponse {
	base := "/chronograf/v1/users"
	name := "me"
	if usr != nil {
		name = PathEscape(fmt.Sprintf("%d", usr.ID))
	}

	return meResponse{
		User: usr,
		Links: meLinks{
			Self: fmt.Sprintf("%s/%s", base, name),
		},
	}
}

// TODO: This Scheme value is hard-coded temporarily since we only currently
// support OAuth2. This hard-coding should be removed whenever we add
// support for other authentication schemes.
func getScheme(ctx context.Context) (string, error) {
	return "oauth2", nil
}

func getPrincipal(ctx context.Context) (oauth2.Principal, error) {
	principal, ok := ctx.Value(oauth2.PrincipalKey).(oauth2.Principal)
	if !ok {
		return oauth2.Principal{}, fmt.Errorf("Token not found")
	}

	return principal, nil
}

func getValidPrincipal(ctx context.Context) (oauth2.Principal, error) {
	p, err := getPrincipal(ctx)
	if err != nil {
		return p, err
	}
	if p.Subject == "" {
		return oauth2.Principal{}, fmt.Errorf("Token not found")
	}
	if p.Issuer == "" {
		return oauth2.Principal{}, fmt.Errorf("Token not found")
	}
	return p, nil
}

type meRequest struct {
	// Organization is the OrganizationID
	Organization string `json:"organization"`
}

// UpdateMe changes the user's current organization on the JWT and responds
// with the same semantics as Me
func (s *Service) UpdateMe(auth oauth2.Authenticator) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		serverCtx := serverContext(ctx)
		principal, err := auth.Validate(ctx, r)
		if err != nil {
			s.Logger.Error(fmt.Sprintf("Invalid principal: %v", err))
			Error(w, http.StatusForbidden, "invalid principal", s.Logger)
			return
		}
		var req meRequest
		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
			invalidJSON(w, s.Logger)
			return
		}

		// validate that the organization exists
		org, err := s.Store.Organizations(serverCtx).Get(serverCtx, chronograf.OrganizationQuery{ID: &req.Organization})
		if err != nil {
			Error(w, http.StatusBadRequest, err.Error(), s.Logger)
			return
		}

		// validate that user belongs to organization
		ctx = context.WithValue(ctx, organizations.ContextKey, req.Organization)

		p, err := getValidPrincipal(ctx)
		if err != nil {
			invalidData(w, err, s.Logger)
			return
		}
		if p.Organization == "" {
			defaultOrg, err := s.Store.Organizations(serverCtx).DefaultOrganization(serverCtx)
			if err != nil {
				unknownErrorWithMessage(w, err, s.Logger)
				return
			}
			p.Organization = defaultOrg.ID
		}
		scheme, err := getScheme(ctx)
		if err != nil {
			invalidData(w, err, s.Logger)
			return
		}
		_, err = s.Store.Users(ctx).Get(ctx, chronograf.UserQuery{
			Name:     &p.Subject,
			Provider: &p.Issuer,
			Scheme:   &scheme,
		})
		if err == chronograf.ErrUserNotFound {
			// If the user was not found, check to see if they are a super admin. If
			// they are, add them to the organization.
			u, err := s.Store.Users(serverCtx).Get(serverCtx, chronograf.UserQuery{
				Name:     &p.Subject,
				Provider: &p.Issuer,
				Scheme:   &scheme,
			})
			if err != nil {
				Error(w, http.StatusForbidden, err.Error(), s.Logger)
				return
			}

			if u.SuperAdmin == false {
				// Since a user is not a part of this organization and not a super admin,
				// we should tell them that they are Forbidden (403) from accessing this resource
				Error(w, http.StatusForbidden, chronograf.ErrUserNotFound.Error(), s.Logger)
				return
			}

			// If the user is a super admin give them an admin role in the
			// requested organization.
			u.Roles = append(u.Roles, chronograf.Role{
				Organization: org.ID,
				Name:         org.DefaultRole,
			})
			if err := s.Store.Users(serverCtx).Update(serverCtx, u); err != nil {
				unknownErrorWithMessage(w, err, s.Logger)
				return
			}
		} else if err != nil {
			Error(w, http.StatusBadRequest, err.Error(), s.Logger)
			return
		}

		// TODO: change to principal.CurrentOrganization
		principal.Organization = req.Organization

		if err := auth.Authorize(ctx, w, principal); err != nil {
			Error(w, http.StatusInternalServerError, err.Error(), s.Logger)
			return
		}

		ctx = context.WithValue(ctx, oauth2.PrincipalKey, principal)

		s.Me(w, r.WithContext(ctx))
	}
}

// Me does a findOrCreate based on the username in the context
func (s *Service) Me(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	if !s.UseAuth {
		// If there's no authentication, return an empty user
		res := newMeResponse(nil)
		encodeJSON(w, http.StatusOK, res, s.Logger)
		return
	}

	p, err := getValidPrincipal(ctx)
	if err != nil {
		invalidData(w, err, s.Logger)
		return
	}
	scheme, err := getScheme(ctx)
	if err != nil {
		invalidData(w, err, s.Logger)
		return
	}

	ctx = context.WithValue(ctx, organizations.ContextKey, p.Organization)
	serverCtx := serverContext(ctx)

	if p.Organization == "" {
		defaultOrg, err := s.Store.Organizations(serverCtx).DefaultOrganization(serverCtx)
		if err != nil {
			unknownErrorWithMessage(w, err, s.Logger)
			return
		}
		p.Organization = defaultOrg.ID
	}

	usr, err := s.Store.Users(serverCtx).Get(serverCtx, chronograf.UserQuery{
		Name:     &p.Subject,
		Provider: &p.Issuer,
		Scheme:   &scheme,
	})
	if err != nil && err != chronograf.ErrUserNotFound {
		unknownErrorWithMessage(w, err, s.Logger)
		return
	}

	defaultOrg, err := s.Store.Organizations(serverCtx).DefaultOrganization(serverCtx)
	if err != nil {
		unknownErrorWithMessage(w, err, s.Logger)
		return
	}
	if usr != nil {

		if defaultOrg.Public || usr.SuperAdmin == true {
			// If the default organization is public, or the user is a super admin
			// they will always have a role in the default organization
			defaultOrgID := defaultOrg.ID
			if !hasRoleInDefaultOrganization(usr, defaultOrgID) {
				usr.Roles = append(usr.Roles, chronograf.Role{
					Organization: defaultOrgID,
					Name:         defaultOrg.DefaultRole,
				})
				if err := s.Store.Users(serverCtx).Update(serverCtx, usr); err != nil {
					unknownErrorWithMessage(w, err, s.Logger)
					return
				}
			}
		}

		// If the default org is private and the user has no roles, they should not have access
		if !defaultOrg.Public && len(usr.Roles) == 0 {
			Error(w, http.StatusForbidden, "This organization is private. To gain access, you must be explicitly added by an administrator.", s.Logger)
			return
		}
		currentOrg, err := s.Store.Organizations(serverCtx).Get(serverCtx, chronograf.OrganizationQuery{ID: &p.Organization})
		if err == chronograf.ErrOrganizationNotFound {
			// The intent is to force a the user to go through another auth flow
			Error(w, http.StatusForbidden, "user's current organization was not found", s.Logger)
			return
		}
		if err != nil {
			unknownErrorWithMessage(w, err, s.Logger)
			return
		}

		orgs, err := s.usersOrganizations(serverCtx, usr)
		if err != nil {
			unknownErrorWithMessage(w, err, s.Logger)
			return
		}
		res := newMeResponse(usr)
		res.Organizations = orgs
		res.CurrentOrganization = currentOrg
		encodeJSON(w, http.StatusOK, res, s.Logger)
		return
	}

	// TODO(desa) get rid of this
	// If users must be explicitly added to the default organization, respond with 403
	// forbidden
	if !defaultOrg.Public {
		Error(w, http.StatusForbidden, "This organization is private. To gain access, you must be explicitly added by an administrator.", s.Logger)
		return
	}
	// Because we didnt find a user, making a new one
	user := &chronograf.User{
		Name:     p.Subject,
		Provider: p.Issuer,
		// TODO: This Scheme value is hard-coded temporarily since we only currently
		// support OAuth2. This hard-coding should be removed whenever we add
		// support for other authentication schemes.
		Scheme: scheme,
		// TODO(desa): this needs a better name
		SuperAdmin: s.newUsersAreSuperAdmin(),
	}

	roles, err := s.mapPrincipalToRoles(serverCtx, p)
	if err != nil {
		Error(w, http.StatusInternalServerError, err.Error(), s.Logger)
		return
	}

	user.Roles = roles

	newUser, err := s.Store.Users(serverCtx).Add(serverCtx, user)
	if err != nil {
		msg := fmt.Errorf("error storing user %s: %v", user.Name, err)
		unknownErrorWithMessage(w, msg, s.Logger)
		return
	}

	orgs, err := s.usersOrganizations(serverCtx, newUser)
	if err != nil {
		unknownErrorWithMessage(w, err, s.Logger)
		return
	}
	currentOrg, err := s.Store.Organizations(serverCtx).Get(serverCtx, chronograf.OrganizationQuery{ID: &p.Organization})
	if err != nil {
		unknownErrorWithMessage(w, err, s.Logger)
		return
	}
	res := newMeResponse(newUser)
	res.Organizations = orgs
	res.CurrentOrganization = currentOrg
	encodeJSON(w, http.StatusOK, res, s.Logger)
}

func (s *Service) firstUser() bool {
	serverCtx := serverContext(context.Background())
	numUsers, err := s.Store.Users(serverCtx).Num(serverCtx)
	if err != nil {
		return false
	}

	return numUsers == 0
}
func (s *Service) newUsersAreSuperAdmin() bool {
	// It's not necessary to enforce that the first user is superAdmin here, since
	// superAdminNewUsers defaults to true, but there's nothing else in the
	// application that dictates that it must be true.
	// So for that reason, we kept this here for now. We've discussed the
	// future possibility of allowing users to override default values via CLI and
	// this case could possibly happen then.
	if s.firstUser() {
		return true
	}
	serverCtx := serverContext(context.Background())
	cfg, err := s.Store.Config(serverCtx).Get(serverCtx)
	if err != nil {
		return false
	}
	return cfg.Auth.SuperAdminNewUsers
}

func (s *Service) usersOrganizations(ctx context.Context, u *chronograf.User) ([]chronograf.Organization, error) {
	if u == nil {
		// TODO(desa): better error
		return nil, fmt.Errorf("user was nil")
	}

	orgIDs := map[string]bool{}
	for _, role := range u.Roles {
		orgIDs[role.Organization] = true
	}

	orgs := []chronograf.Organization{}
	for orgID, _ := range orgIDs {
		org, err := s.Store.Organizations(ctx).Get(ctx, chronograf.OrganizationQuery{ID: &orgID})
		if err != nil {
			return nil, err
		}
		orgs = append(orgs, *org)
	}

	sort.Slice(orgs, func(i, j int) bool {
		return orgs[i].ID < orgs[j].ID
	})

	return orgs, nil
}

func hasRoleInDefaultOrganization(u *chronograf.User, orgID string) bool {
	for _, role := range u.Roles {
		if role.Organization == orgID {
			return true
		}
	}

	return false
}
<commit_msg>Pseudo code for removal of Public<commit_after>package server

import (
	"encoding/json"
	"fmt"
	"net/http"
	"sort"

	"golang.org/x/net/context"

	"github.com/influxdata/chronograf"
	"github.com/influxdata/chronograf/oauth2"
	"github.com/influxdata/chronograf/organizations"
)

type meLinks struct {
	Self string `json:"self"` // Self link mapping to this resource
}

type meResponse struct {
	*chronograf.User
	Links               meLinks                   `json:"links"`
	Organizations       []chronograf.Organization `json:"organizations,omitempty"`
	CurrentOrganization *chronograf.Organization  `json:"currentOrganization,omitempty"`
}

// If new user response is nil, return an empty meResponse because it
// indicates authentication is not needed
func newMeResponse(usr *chronograf.User) meResponse {
	base := "/chronograf/v1/users"
	name := "me"
	if usr != nil {
		name = PathEscape(fmt.Sprintf("%d", usr.ID))
	}

	return meResponse{
		User: usr,
		Links: meLinks{
			Self: fmt.Sprintf("%s/%s", base, name),
		},
	}
}

// TODO: This Scheme value is hard-coded temporarily since we only currently
// support OAuth2. This hard-coding should be removed whenever we add
// support for other authentication schemes.
func getScheme(ctx context.Context) (string, error) {
	return "oauth2", nil
}

func getPrincipal(ctx context.Context) (oauth2.Principal, error) {
	principal, ok := ctx.Value(oauth2.PrincipalKey).(oauth2.Principal)
	if !ok {
		return oauth2.Principal{}, fmt.Errorf("Token not found")
	}

	return principal, nil
}

func getValidPrincipal(ctx context.Context) (oauth2.Principal, error) {
	p, err := getPrincipal(ctx)
	if err != nil {
		return p, err
	}
	if p.Subject == "" {
		return oauth2.Principal{}, fmt.Errorf("Token not found")
	}
	if p.Issuer == "" {
		return oauth2.Principal{}, fmt.Errorf("Token not found")
	}
	return p, nil
}

type meRequest struct {
	// Organization is the OrganizationID
	Organization string `json:"organization"`
}

// UpdateMe changes the user's current organization on the JWT and responds
// with the same semantics as Me
func (s *Service) UpdateMe(auth oauth2.Authenticator) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		serverCtx := serverContext(ctx)
		principal, err := auth.Validate(ctx, r)
		if err != nil {
			s.Logger.Error(fmt.Sprintf("Invalid principal: %v", err))
			Error(w, http.StatusForbidden, "invalid principal", s.Logger)
			return
		}
		var req meRequest
		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
			invalidJSON(w, s.Logger)
			return
		}

		// validate that the organization exists
		org, err := s.Store.Organizations(serverCtx).Get(serverCtx, chronograf.OrganizationQuery{ID: &req.Organization})
		if err != nil {
			Error(w, http.StatusBadRequest, err.Error(), s.Logger)
			return
		}

		// validate that user belongs to organization
		ctx = context.WithValue(ctx, organizations.ContextKey, req.Organization)

		p, err := getValidPrincipal(ctx)
		if err != nil {
			invalidData(w, err, s.Logger)
			return
		}
		if p.Organization == "" {
			defaultOrg, err := s.Store.Organizations(serverCtx).DefaultOrganization(serverCtx)
			if err != nil {
				unknownErrorWithMessage(w, err, s.Logger)
				return
			}
			p.Organization = defaultOrg.ID
		}
		scheme, err := getScheme(ctx)
		if err != nil {
			invalidData(w, err, s.Logger)
			return
		}
		_, err = s.Store.Users(ctx).Get(ctx, chronograf.UserQuery{
			Name:     &p.Subject,
			Provider: &p.Issuer,
			Scheme:   &scheme,
		})
		if err == chronograf.ErrUserNotFound {
			// If the user was not found, check to see if they are a super admin. If
			// they are, add them to the organization.
			u, err := s.Store.Users(serverCtx).Get(serverCtx, chronograf.UserQuery{
				Name:     &p.Subject,
				Provider: &p.Issuer,
				Scheme:   &scheme,
			})
			if err != nil {
				Error(w, http.StatusForbidden, err.Error(), s.Logger)
				return
			}

			if u.SuperAdmin == false {
				// Since a user is not a part of this organization and not a super admin,
				// we should tell them that they are Forbidden (403) from accessing this resource
				Error(w, http.StatusForbidden, chronograf.ErrUserNotFound.Error(), s.Logger)
				return
			}

			// If the user is a super admin give them an admin role in the
			// requested organization.
			u.Roles = append(u.Roles, chronograf.Role{
				Organization: org.ID,
				Name:         org.DefaultRole,
			})
			if err := s.Store.Users(serverCtx).Update(serverCtx, u); err != nil {
				unknownErrorWithMessage(w, err, s.Logger)
				return
			}
		} else if err != nil {
			Error(w, http.StatusBadRequest, err.Error(), s.Logger)
			return
		}

		// TODO: change to principal.CurrentOrganization
		principal.Organization = req.Organization

		if err := auth.Authorize(ctx, w, principal); err != nil {
			Error(w, http.StatusInternalServerError, err.Error(), s.Logger)
			return
		}

		ctx = context.WithValue(ctx, oauth2.PrincipalKey, principal)

		s.Me(w, r.WithContext(ctx))
	}
}

// Me does a findOrCreate based on the username in the context
func (s *Service) Me(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	if !s.UseAuth {
		// If there's no authentication, return an empty user
		res := newMeResponse(nil)
		encodeJSON(w, http.StatusOK, res, s.Logger)
		return
	}

	p, err := getValidPrincipal(ctx)
	if err != nil {
		invalidData(w, err, s.Logger)
		return
	}
	scheme, err := getScheme(ctx)
	if err != nil {
		invalidData(w, err, s.Logger)
		return
	}

	ctx = context.WithValue(ctx, organizations.ContextKey, p.Organization)
	serverCtx := serverContext(ctx)

	/* ALTERNATE 1
		If existing
			If roles, let them in
			If no roles, purgatory

		If new
			Build new user
			Generate roles for user based on defined mappings
			If roles, save and let them in
			If no roles, tell them box is private
	*/

	/* ALTERNATE 2
		Find user => (existing)
		If no user => (new)
			Build new user, with superadmin based on setting
			Generate roles for user based on defined mappings

		If roles,
			(existing) => let them in
			(new) => save, let them in

		If no roles,
			(existing) => purgatory
			(new) => tell them box is private
	*/

	defaultOrg, err := s.Store.Organizations(serverCtx).DefaultOrganization(serverCtx)
		if err != nil {
			unknownErrorWithMessage(w, err, s.Logger)
			return

	if p.Organization == "" {
		p.Organization = defaultOrg.ID
	}

	usr, err := s.Store.Users(serverCtx).Get(serverCtx, chronograf.UserQuery{
		Name:     &p.Subject,
		Provider: &p.Issuer,
		Scheme:   &scheme,
	})
	if err != nil && err != chronograf.ErrUserNotFound {
		unknownErrorWithMessage(w, err, s.Logger)
		return
	}

	if usr != nil {

		if defaultOrg.Public || usr.SuperAdmin == true {
			// If the default organization is public, or the user is a super admin
			// they will always have a role in the default organization
			defaultOrgID := defaultOrg.ID
			if !hasRoleInDefaultOrganization(usr, defaultOrgID) {
				usr.Roles = append(usr.Roles, chronograf.Role{
					Organization: defaultOrgID,
					Name:         defaultOrg.DefaultRole,
				})
				if err := s.Store.Users(serverCtx).Update(serverCtx, usr); err != nil {
					unknownErrorWithMessage(w, err, s.Logger)
					return
				}
			}
		}

		// If the default org is private and the user has no roles, they should not have access
		if !defaultOrg.Public && len(usr.Roles) == 0 {
			Error(w, http.StatusForbidden, "This organization is private. To gain access, you must be explicitly added by an administrator.", s.Logger)
			return
		}
		currentOrg, err := s.Store.Organizations(serverCtx).Get(serverCtx, chronograf.OrganizationQuery{ID: &p.Organization})
		if err == chronograf.ErrOrganizationNotFound {
			// The intent is to force a the user to go through another auth flow
			Error(w, http.StatusForbidden, "user's current organization was not found", s.Logger)
			return
		}
		if err != nil {
			unknownErrorWithMessage(w, err, s.Logger)
			return
		}

		orgs, err := s.usersOrganizations(serverCtx, usr)
		if err != nil {
			unknownErrorWithMessage(w, err, s.Logger)
			return
		}
		res := newMeResponse(usr)
		res.Organizations = orgs
		res.CurrentOrganization = currentOrg
		encodeJSON(w, http.StatusOK, res, s.Logger)
		return
	}

	// TODO(desa) get rid of this
	// If users must be explicitly added to the default organization, respond with 403
	// forbidden
	if !defaultOrg.Public {
		Error(w, http.StatusForbidden, "This organization is private. To gain access, you must be explicitly added by an administrator.", s.Logger)
		return
	}
	// Because we didnt find a user, making a new one
	user := &chronograf.User{
		Name:     p.Subject,
		Provider: p.Issuer,
		// TODO: This Scheme value is hard-coded temporarily since we only currently
		// support OAuth2. This hard-coding should be removed whenever we add
		// support for other authentication schemes.
		Scheme: scheme,
		// TODO(desa): this needs a better name
		SuperAdmin: s.newUsersAreSuperAdmin(),
	}

	roles, err := s.mapPrincipalToRoles(serverCtx, p)
	if err != nil {
		Error(w, http.StatusInternalServerError, err.Error(), s.Logger)
		return
	}

	user.Roles = roles

	newUser, err := s.Store.Users(serverCtx).Add(serverCtx, user)
	if err != nil {
		msg := fmt.Errorf("error storing user %s: %v", user.Name, err)
		unknownErrorWithMessage(w, msg, s.Logger)
		return
	}

	orgs, err := s.usersOrganizations(serverCtx, newUser)
	if err != nil {
		unknownErrorWithMessage(w, err, s.Logger)
		return
	}
	currentOrg, err := s.Store.Organizations(serverCtx).Get(serverCtx, chronograf.OrganizationQuery{ID: &p.Organization})
	if err != nil {
		unknownErrorWithMessage(w, err, s.Logger)
		return
	}
	res := newMeResponse(newUser)
	res.Organizations = orgs
	res.CurrentOrganization = currentOrg
	encodeJSON(w, http.StatusOK, res, s.Logger)
}

func (s *Service) firstUser() bool {
	serverCtx := serverContext(context.Background())
	numUsers, err := s.Store.Users(serverCtx).Num(serverCtx)
	if err != nil {
		return false
	}

	return numUsers == 0
}
func (s *Service) newUsersAreSuperAdmin() bool {
	// It's not necessary to enforce that the first user is superAdmin here, since
	// superAdminNewUsers defaults to true, but there's nothing else in the
	// application that dictates that it must be true.
	// So for that reason, we kept this here for now. We've discussed the
	// future possibility of allowing users to override default values via CLI and
	// this case could possibly happen then.
	if s.firstUser() {
		return true
	}
	serverCtx := serverContext(context.Background())
	cfg, err := s.Store.Config(serverCtx).Get(serverCtx)
	if err != nil {
		return false
	}
	return cfg.Auth.SuperAdminNewUsers
}

func (s *Service) usersOrganizations(ctx context.Context, u *chronograf.User) ([]chronograf.Organization, error) {
	if u == nil {
		// TODO(desa): better error
		return nil, fmt.Errorf("user was nil")
	}

	orgIDs := map[string]bool{}
	for _, role := range u.Roles {
		orgIDs[role.Organization] = true
	}

	orgs := []chronograf.Organization{}
	for orgID, _ := range orgIDs {
		org, err := s.Store.Organizations(ctx).Get(ctx, chronograf.OrganizationQuery{ID: &orgID})
		if err != nil {
			return nil, err
		}
		orgs = append(orgs, *org)
	}

	sort.Slice(orgs, func(i, j int) bool {
		return orgs[i].ID < orgs[j].ID
	})

	return orgs, nil
}

func hasRoleInDefaultOrganization(u *chronograf.User, orgID string) bool {
	for _, role := range u.Roles {
		if role.Organization == orgID {
			return true
		}
	}

	return false
}
<|endoftext|>


<commit_before><commit_msg>flip whole channels (#16342)<commit_after><|endoftext|>


<commit_before><commit_msg>fixes format action for erroneous documents. now it only prints to the log and does not clear the document anymore.<commit_after><|endoftext|>


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

/*
An example of wrapping a C library in Go. This is the GNU
multiprecision library gmp's integer type mpz_t wrapped to look like
the Go package big's integer type Int.

This is a syntactically valid Go program—it can be parsed with the Go
parser and processed by godoc—but it is not compiled directly by 6g.
Instead, a separate tool, cgo, processes it to produce three output
files.  The first two, 6g.go and 6c.c, are a Go source file for 6g and
a C source file for 6c; both compile as part of the named package
(gmp, in this example).  The third, gcc.c, is a C source file for gcc;
it compiles into a shared object (.so) that is dynamically linked into
any 6.out that imports the first two files.

The stanza

	// #include <gmp.h>
	import "C"

is a signal to cgo.  The doc comment on the import of "C" provides
additional context for the C file.  Here it is just a single #include
but it could contain arbitrary C definitions to be imported and used.

Cgo recognizes any use of a qualified identifier C.xxx and uses gcc to
find the definition of xxx.  If xxx is a type, cgo replaces C.xxx with
a Go translation.  C arithmetic types translate to precisely-sized Go
arithmetic types.  A C struct translates to a Go struct, field by
field; unrepresentable fields are replaced with opaque byte arrays.  A
C union translates into a struct containing the first union member and
perhaps additional padding.  C arrays become Go arrays.  C pointers
become Go pointers.  C function pointers become Go's uintptr.
C void pointer's become Go's unsafe.Pointer.

For example, mpz_t is defined in <gmp.h> as:

	typedef unsigned long int mp_limb_t;

	typedef struct
	{
		int _mp_alloc;
		int _mp_size;
		mp_limb_t *_mp_d;
	} __mpz_struct;

	typedef __mpz_struct mpz_t[1];

Cgo generates:

	type _C_int int32
	type _C_mp_limb_t uint64
	type _C___mpz_struct struct {
		_mp_alloc _C_int;
		_mp_size _C_int;
		_mp_d *_C_mp_limb_t;
	}
	type _C_mpz_t [1]_C___mpz_struct

and then replaces each occurrence of a type C.xxx with _C_xxx.

If xxx is data, cgo arranges for C.xxx to refer to the C variable,
with the type translated as described above.  To do this, cgo must
introduce a Go variable that points at the C variable (the linker can
be told to initialize this pointer).  For example, if the gmp library
provided

	mpz_t zero;

then cgo would rewrite a reference to C.zero by introducing

	var _C_zero *C.mpz_t

and then replacing all instances of C.zero with (*_C_zero).

Cgo's most interesting translation is for functions.  If xxx is a C
function, then cgo rewrites C.xxx into a new function _C_xxx that
calls the C xxx in a standard pthread.  The new function translates
its arguments, calls xxx, and translates the return value.

Translation of parameters and the return value follows the type
translation above except that arrays passed as parameters translate
explicitly in Go to pointers to arrays, as they do (implicitly) in C.

Garbage collection is the big problem.  It is fine for the Go world to
have pointers into the C world and to free those pointers when they
are no longer needed.  To help, the Go code can define Go objects
holding the C pointers and use runtime.SetFinalizer on those Go objects.

It is much more difficult for the C world to have pointers into the Go
world, because the Go garbage collector is unaware of the memory
allocated by C.  The most important consideration is not to
constrain future implementations, so the rule is that Go code can
hand a Go pointer to C code but must separately arrange for
Go to hang on to a reference to the pointer until C is done with it.
*/
package gmp

/*
#cgo LDFLAGS: -lgmp
#include <gmp.h>
#include <stdlib.h>

// gmp 5.0.0+ changed the type of the 3rd argument to mp_bitcnt_t,
// so, to support older versions, we wrap these two functions.
void _mpz_mul_2exp(mpz_ptr a, mpz_ptr b, unsigned long n) {
	mpz_mul_2exp(a, b, n);
}
void _mpz_div_2exp(mpz_ptr a, mpz_ptr b, unsigned long n) {
	mpz_div_2exp(a, b, n);
}
*/
import "C"

import (
	"os"
	"unsafe"
)

/*
 * one of a kind
 */

// An Int represents a signed multi-precision integer.
// The zero value for an Int represents the value 0.
type Int struct {
	i    C.mpz_t
	init bool
}

// NewInt returns a new Int initialized to x.
func NewInt(x int64) *Int { return new(Int).SetInt64(x) }

// Int promises that the zero value is a 0, but in gmp
// the zero value is a crash.  To bridge the gap, the
// init bool says whether this is a valid gmp value.
// doinit initializes z.i if it needs it.  This is not inherent
// to FFI, just a mismatch between Go's convention of
// making zero values useful and gmp's decision not to.
func (z *Int) doinit() {
	if z.init {
		return
	}
	z.init = true
	C.mpz_init(&z.i[0])
}

// Bytes returns z's representation as a big-endian byte array.
func (z *Int) Bytes() []byte {
	b := make([]byte, (z.Len()+7)/8)
	n := C.size_t(len(b))
	C.mpz_export(unsafe.Pointer(&b[0]), &n, 1, 1, 1, 0, &z.i[0])
	return b[0:n]
}

// Len returns the length of z in bits.  0 is considered to have length 1.
func (z *Int) Len() int {
	z.doinit()
	return int(C.mpz_sizeinbase(&z.i[0], 2))
}

// Set sets z = x and returns z.
func (z *Int) Set(x *Int) *Int {
	z.doinit()
	C.mpz_set(&z.i[0], &x.i[0])
	return z
}

// SetBytes interprets b as the bytes of a big-endian integer
// and sets z to that value.
func (z *Int) SetBytes(b []byte) *Int {
	z.doinit()
	if len(b) == 0 {
		z.SetInt64(0)
	} else {
		C.mpz_import(&z.i[0], C.size_t(len(b)), 1, 1, 1, 0, unsafe.Pointer(&b[0]))
	}
	return z
}

// SetInt64 sets z = x and returns z.
func (z *Int) SetInt64(x int64) *Int {
	z.doinit()
	// TODO(rsc): more work on 32-bit platforms
	C.mpz_set_si(&z.i[0], C.long(x))
	return z
}

// SetString interprets s as a number in the given base
// and sets z to that value.  The base must be in the range [2,36].
// SetString returns an error if s cannot be parsed or the base is invalid.
func (z *Int) SetString(s string, base int) error {
	z.doinit()
	if base < 2 || base > 36 {
		return os.ErrInvalid
	}
	p := C.CString(s)
	defer C.free(unsafe.Pointer(p))
	if C.mpz_set_str(&z.i[0], p, C.int(base)) < 0 {
		return os.ErrInvalid
	}
	return nil
}

// String returns the decimal representation of z.
func (z *Int) String() string {
	if z == nil {
		return "nil"
	}
	z.doinit()
	p := C.mpz_get_str(nil, 10, &z.i[0])
	s := C.GoString(p)
	C.free(unsafe.Pointer(p))
	return s
}

func (z *Int) destroy() {
	if z.init {
		C.mpz_clear(&z.i[0])
	}
	z.init = false
}

/*
 * arithmetic
 */

// Add sets z = x + y and returns z.
func (z *Int) Add(x, y *Int) *Int {
	x.doinit()
	y.doinit()
	z.doinit()
	C.mpz_add(&z.i[0], &x.i[0], &y.i[0])
	return z
}

// Sub sets z = x - y and returns z.
func (z *Int) Sub(x, y *Int) *Int {
	x.doinit()
	y.doinit()
	z.doinit()
	C.mpz_sub(&z.i[0], &x.i[0], &y.i[0])
	return z
}

// Mul sets z = x * y and returns z.
func (z *Int) Mul(x, y *Int) *Int {
	x.doinit()
	y.doinit()
	z.doinit()
	C.mpz_mul(&z.i[0], &x.i[0], &y.i[0])
	return z
}

// Div sets z = x / y, rounding toward zero, and returns z.
func (z *Int) Div(x, y *Int) *Int {
	x.doinit()
	y.doinit()
	z.doinit()
	C.mpz_tdiv_q(&z.i[0], &x.i[0], &y.i[0])
	return z
}

// Mod sets z = x % y and returns z.
// Like the result of the Go % operator, z has the same sign as x.
func (z *Int) Mod(x, y *Int) *Int {
	x.doinit()
	y.doinit()
	z.doinit()
	C.mpz_tdiv_r(&z.i[0], &x.i[0], &y.i[0])
	return z
}

// Lsh sets z = x << s and returns z.
func (z *Int) Lsh(x *Int, s uint) *Int {
	x.doinit()
	z.doinit()
	C._mpz_mul_2exp(&z.i[0], &x.i[0], C.ulong(s))
	return z
}

// Rsh sets z = x >> s and returns z.
func (z *Int) Rsh(x *Int, s uint) *Int {
	x.doinit()
	z.doinit()
	C._mpz_div_2exp(&z.i[0], &x.i[0], C.ulong(s))
	return z
}

// Exp sets z = x^y % m and returns z.
// If m == nil, Exp sets z = x^y.
func (z *Int) Exp(x, y, m *Int) *Int {
	m.doinit()
	x.doinit()
	y.doinit()
	z.doinit()
	if m == nil {
		C.mpz_pow_ui(&z.i[0], &x.i[0], C.mpz_get_ui(&y.i[0]))
	} else {
		C.mpz_powm(&z.i[0], &x.i[0], &y.i[0], &m.i[0])
	}
	return z
}

func (z *Int) Int64() int64 {
	if !z.init {
		return 0
	}
	return int64(C.mpz_get_si(&z.i[0]))
}

// Neg sets z = -x and returns z.
func (z *Int) Neg(x *Int) *Int {
	x.doinit()
	z.doinit()
	C.mpz_neg(&z.i[0], &x.i[0])
	return z
}

// Abs sets z to the absolute value of x and returns z.
func (z *Int) Abs(x *Int) *Int {
	x.doinit()
	z.doinit()
	C.mpz_abs(&z.i[0], &x.i[0])
	return z
}

/*
 * functions without a clear receiver
 */

// CmpInt compares x and y. The result is
//
//   -1 if x <  y
//    0 if x == y
//   +1 if x >  y
//
func CmpInt(x, y *Int) int {
	x.doinit()
	y.doinit()
	switch cmp := C.mpz_cmp(&x.i[0], &y.i[0]); {
	case cmp < 0:
		return -1
	case cmp == 0:
		return 0
	}
	return +1
}

// DivModInt sets q = x / y and r = x % y.
func DivModInt(q, r, x, y *Int) {
	q.doinit()
	r.doinit()
	x.doinit()
	y.doinit()
	C.mpz_tdiv_qr(&q.i[0], &r.i[0], &x.i[0], &y.i[0])
}

// GcdInt sets d to the greatest common divisor of a and b,
// which must be positive numbers.
// If x and y are not nil, GcdInt sets x and y such that d = a*x + b*y.
// If either a or b is not positive, GcdInt sets d = x = y = 0.
func GcdInt(d, x, y, a, b *Int) {
	d.doinit()
	x.doinit()
	y.doinit()
	a.doinit()
	b.doinit()
	C.mpz_gcdext(&d.i[0], &x.i[0], &y.i[0], &a.i[0], &b.i[0])
}

// ProbablyPrime performs n Miller-Rabin tests to check whether z is prime.
// If it returns true, z is prime with probability 1 - 1/4^n.
// If it returns false, z is not prime.
func (z *Int) ProbablyPrime(n int) bool {
	z.doinit()
	return int(C.mpz_probab_prime_p(&z.i[0], C.int(n))) > 0
}
<commit_msg>misc/cgo/gmp: fix typo.<commit_after>// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
An example of wrapping a C library in Go. This is the GNU
multiprecision library gmp's integer type mpz_t wrapped to look like
the Go package big's integer type Int.

This is a syntactically valid Go program—it can be parsed with the Go
parser and processed by godoc—but it is not compiled directly by 6g.
Instead, a separate tool, cgo, processes it to produce three output
files.  The first two, 6g.go and 6c.c, are a Go source file for 6g and
a C source file for 6c; both compile as part of the named package
(gmp, in this example).  The third, gcc.c, is a C source file for gcc;
it compiles into a shared object (.so) that is dynamically linked into
any 6.out that imports the first two files.

The stanza

	// #include <gmp.h>
	import "C"

is a signal to cgo.  The doc comment on the import of "C" provides
additional context for the C file.  Here it is just a single #include
but it could contain arbitrary C definitions to be imported and used.

Cgo recognizes any use of a qualified identifier C.xxx and uses gcc to
find the definition of xxx.  If xxx is a type, cgo replaces C.xxx with
a Go translation.  C arithmetic types translate to precisely-sized Go
arithmetic types.  A C struct translates to a Go struct, field by
field; unrepresentable fields are replaced with opaque byte arrays.  A
C union translates into a struct containing the first union member and
perhaps additional padding.  C arrays become Go arrays.  C pointers
become Go pointers.  C function pointers become Go's uintptr.
C void pointers become Go's unsafe.Pointer.

For example, mpz_t is defined in <gmp.h> as:

	typedef unsigned long int mp_limb_t;

	typedef struct
	{
		int _mp_alloc;
		int _mp_size;
		mp_limb_t *_mp_d;
	} __mpz_struct;

	typedef __mpz_struct mpz_t[1];

Cgo generates:

	type _C_int int32
	type _C_mp_limb_t uint64
	type _C___mpz_struct struct {
		_mp_alloc _C_int;
		_mp_size _C_int;
		_mp_d *_C_mp_limb_t;
	}
	type _C_mpz_t [1]_C___mpz_struct

and then replaces each occurrence of a type C.xxx with _C_xxx.

If xxx is data, cgo arranges for C.xxx to refer to the C variable,
with the type translated as described above.  To do this, cgo must
introduce a Go variable that points at the C variable (the linker can
be told to initialize this pointer).  For example, if the gmp library
provided

	mpz_t zero;

then cgo would rewrite a reference to C.zero by introducing

	var _C_zero *C.mpz_t

and then replacing all instances of C.zero with (*_C_zero).

Cgo's most interesting translation is for functions.  If xxx is a C
function, then cgo rewrites C.xxx into a new function _C_xxx that
calls the C xxx in a standard pthread.  The new function translates
its arguments, calls xxx, and translates the return value.

Translation of parameters and the return value follows the type
translation above except that arrays passed as parameters translate
explicitly in Go to pointers to arrays, as they do (implicitly) in C.

Garbage collection is the big problem.  It is fine for the Go world to
have pointers into the C world and to free those pointers when they
are no longer needed.  To help, the Go code can define Go objects
holding the C pointers and use runtime.SetFinalizer on those Go objects.

It is much more difficult for the C world to have pointers into the Go
world, because the Go garbage collector is unaware of the memory
allocated by C.  The most important consideration is not to
constrain future implementations, so the rule is that Go code can
hand a Go pointer to C code but must separately arrange for
Go to hang on to a reference to the pointer until C is done with it.
*/
package gmp

/*
#cgo LDFLAGS: -lgmp
#include <gmp.h>
#include <stdlib.h>

// gmp 5.0.0+ changed the type of the 3rd argument to mp_bitcnt_t,
// so, to support older versions, we wrap these two functions.
void _mpz_mul_2exp(mpz_ptr a, mpz_ptr b, unsigned long n) {
	mpz_mul_2exp(a, b, n);
}
void _mpz_div_2exp(mpz_ptr a, mpz_ptr b, unsigned long n) {
	mpz_div_2exp(a, b, n);
}
*/
import "C"

import (
	"os"
	"unsafe"
)

/*
 * one of a kind
 */

// An Int represents a signed multi-precision integer.
// The zero value for an Int represents the value 0.
type Int struct {
	i    C.mpz_t
	init bool
}

// NewInt returns a new Int initialized to x.
func NewInt(x int64) *Int { return new(Int).SetInt64(x) }

// Int promises that the zero value is a 0, but in gmp
// the zero value is a crash.  To bridge the gap, the
// init bool says whether this is a valid gmp value.
// doinit initializes z.i if it needs it.  This is not inherent
// to FFI, just a mismatch between Go's convention of
// making zero values useful and gmp's decision not to.
func (z *Int) doinit() {
	if z.init {
		return
	}
	z.init = true
	C.mpz_init(&z.i[0])
}

// Bytes returns z's representation as a big-endian byte array.
func (z *Int) Bytes() []byte {
	b := make([]byte, (z.Len()+7)/8)
	n := C.size_t(len(b))
	C.mpz_export(unsafe.Pointer(&b[0]), &n, 1, 1, 1, 0, &z.i[0])
	return b[0:n]
}

// Len returns the length of z in bits.  0 is considered to have length 1.
func (z *Int) Len() int {
	z.doinit()
	return int(C.mpz_sizeinbase(&z.i[0], 2))
}

// Set sets z = x and returns z.
func (z *Int) Set(x *Int) *Int {
	z.doinit()
	C.mpz_set(&z.i[0], &x.i[0])
	return z
}

// SetBytes interprets b as the bytes of a big-endian integer
// and sets z to that value.
func (z *Int) SetBytes(b []byte) *Int {
	z.doinit()
	if len(b) == 0 {
		z.SetInt64(0)
	} else {
		C.mpz_import(&z.i[0], C.size_t(len(b)), 1, 1, 1, 0, unsafe.Pointer(&b[0]))
	}
	return z
}

// SetInt64 sets z = x and returns z.
func (z *Int) SetInt64(x int64) *Int {
	z.doinit()
	// TODO(rsc): more work on 32-bit platforms
	C.mpz_set_si(&z.i[0], C.long(x))
	return z
}

// SetString interprets s as a number in the given base
// and sets z to that value.  The base must be in the range [2,36].
// SetString returns an error if s cannot be parsed or the base is invalid.
func (z *Int) SetString(s string, base int) error {
	z.doinit()
	if base < 2 || base > 36 {
		return os.ErrInvalid
	}
	p := C.CString(s)
	defer C.free(unsafe.Pointer(p))
	if C.mpz_set_str(&z.i[0], p, C.int(base)) < 0 {
		return os.ErrInvalid
	}
	return nil
}

// String returns the decimal representation of z.
func (z *Int) String() string {
	if z == nil {
		return "nil"
	}
	z.doinit()
	p := C.mpz_get_str(nil, 10, &z.i[0])
	s := C.GoString(p)
	C.free(unsafe.Pointer(p))
	return s
}

func (z *Int) destroy() {
	if z.init {
		C.mpz_clear(&z.i[0])
	}
	z.init = false
}

/*
 * arithmetic
 */

// Add sets z = x + y and returns z.
func (z *Int) Add(x, y *Int) *Int {
	x.doinit()
	y.doinit()
	z.doinit()
	C.mpz_add(&z.i[0], &x.i[0], &y.i[0])
	return z
}

// Sub sets z = x - y and returns z.
func (z *Int) Sub(x, y *Int) *Int {
	x.doinit()
	y.doinit()
	z.doinit()
	C.mpz_sub(&z.i[0], &x.i[0], &y.i[0])
	return z
}

// Mul sets z = x * y and returns z.
func (z *Int) Mul(x, y *Int) *Int {
	x.doinit()
	y.doinit()
	z.doinit()
	C.mpz_mul(&z.i[0], &x.i[0], &y.i[0])
	return z
}

// Div sets z = x / y, rounding toward zero, and returns z.
func (z *Int) Div(x, y *Int) *Int {
	x.doinit()
	y.doinit()
	z.doinit()
	C.mpz_tdiv_q(&z.i[0], &x.i[0], &y.i[0])
	return z
}

// Mod sets z = x % y and returns z.
// Like the result of the Go % operator, z has the same sign as x.
func (z *Int) Mod(x, y *Int) *Int {
	x.doinit()
	y.doinit()
	z.doinit()
	C.mpz_tdiv_r(&z.i[0], &x.i[0], &y.i[0])
	return z
}

// Lsh sets z = x << s and returns z.
func (z *Int) Lsh(x *Int, s uint) *Int {
	x.doinit()
	z.doinit()
	C._mpz_mul_2exp(&z.i[0], &x.i[0], C.ulong(s))
	return z
}

// Rsh sets z = x >> s and returns z.
func (z *Int) Rsh(x *Int, s uint) *Int {
	x.doinit()
	z.doinit()
	C._mpz_div_2exp(&z.i[0], &x.i[0], C.ulong(s))
	return z
}

// Exp sets z = x^y % m and returns z.
// If m == nil, Exp sets z = x^y.
func (z *Int) Exp(x, y, m *Int) *Int {
	m.doinit()
	x.doinit()
	y.doinit()
	z.doinit()
	if m == nil {
		C.mpz_pow_ui(&z.i[0], &x.i[0], C.mpz_get_ui(&y.i[0]))
	} else {
		C.mpz_powm(&z.i[0], &x.i[0], &y.i[0], &m.i[0])
	}
	return z
}

func (z *Int) Int64() int64 {
	if !z.init {
		return 0
	}
	return int64(C.mpz_get_si(&z.i[0]))
}

// Neg sets z = -x and returns z.
func (z *Int) Neg(x *Int) *Int {
	x.doinit()
	z.doinit()
	C.mpz_neg(&z.i[0], &x.i[0])
	return z
}

// Abs sets z to the absolute value of x and returns z.
func (z *Int) Abs(x *Int) *Int {
	x.doinit()
	z.doinit()
	C.mpz_abs(&z.i[0], &x.i[0])
	return z
}

/*
 * functions without a clear receiver
 */

// CmpInt compares x and y. The result is
//
//   -1 if x <  y
//    0 if x == y
//   +1 if x >  y
//
func CmpInt(x, y *Int) int {
	x.doinit()
	y.doinit()
	switch cmp := C.mpz_cmp(&x.i[0], &y.i[0]); {
	case cmp < 0:
		return -1
	case cmp == 0:
		return 0
	}
	return +1
}

// DivModInt sets q = x / y and r = x % y.
func DivModInt(q, r, x, y *Int) {
	q.doinit()
	r.doinit()
	x.doinit()
	y.doinit()
	C.mpz_tdiv_qr(&q.i[0], &r.i[0], &x.i[0], &y.i[0])
}

// GcdInt sets d to the greatest common divisor of a and b,
// which must be positive numbers.
// If x and y are not nil, GcdInt sets x and y such that d = a*x + b*y.
// If either a or b is not positive, GcdInt sets d = x = y = 0.
func GcdInt(d, x, y, a, b *Int) {
	d.doinit()
	x.doinit()
	y.doinit()
	a.doinit()
	b.doinit()
	C.mpz_gcdext(&d.i[0], &x.i[0], &y.i[0], &a.i[0], &b.i[0])
}

// ProbablyPrime performs n Miller-Rabin tests to check whether z is prime.
// If it returns true, z is prime with probability 1 - 1/4^n.
// If it returns false, z is not prime.
func (z *Int) ProbablyPrime(n int) bool {
	z.doinit()
	return int(C.mpz_probab_prime_p(&z.i[0], C.int(n))) > 0
}
<|endoftext|>


<commit_before>package client // import "github.com/docker/docker/client"

import (
	"context"
	"encoding/json"
	"net/url"

	"github.com/containerd/containerd/platforms"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/network"
	"github.com/docker/docker/api/types/versions"
	specs "github.com/opencontainers/image-spec/specs-go/v1"
)

type configWrapper struct {
	*container.Config
	HostConfig       *container.HostConfig
	NetworkingConfig *network.NetworkingConfig
	Platform         *specs.Platform
}

// ContainerCreate creates a new container based on the given configuration.
// It can be associated with a name, but it's not mandatory.
func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.ContainerCreateCreatedBody, error) {
	var response container.ContainerCreateCreatedBody

	if err := cli.NewVersionError("1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil {
		return response, err
	}

	// When using API 1.24 and under, the client is responsible for removing the container
	if hostConfig != nil && versions.LessThan(cli.ClientVersion(), "1.25") {
		hostConfig.AutoRemove = false
	}

	if err := cli.NewVersionError("1.41", "specify container image platform"); platform != nil && err != nil {
		return response, err
	}

	query := url.Values{}
	if platform != nil {
		query.Set("platform", platforms.Format(*platform))
	}

	if containerName != "" {
		query.Set("name", containerName)
	}

	body := configWrapper{
		Config:           config,
		HostConfig:       hostConfig,
		NetworkingConfig: networkingConfig,
	}

	serverResp, err := cli.post(ctx, "/containers/create", query, body, nil)
	defer ensureReaderClosed(serverResp)
	if err != nil {
		return response, err
	}

	err = json.NewDecoder(serverResp.body).Decode(&response)
	return response, err
}
<commit_msg>client: remove unused Platform field from configWrapper<commit_after>package client // import "github.com/docker/docker/client"

import (
	"context"
	"encoding/json"
	"net/url"

	"github.com/containerd/containerd/platforms"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/network"
	"github.com/docker/docker/api/types/versions"
	specs "github.com/opencontainers/image-spec/specs-go/v1"
)

type configWrapper struct {
	*container.Config
	HostConfig       *container.HostConfig
	NetworkingConfig *network.NetworkingConfig
}

// ContainerCreate creates a new container based on the given configuration.
// It can be associated with a name, but it's not mandatory.
func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.ContainerCreateCreatedBody, error) {
	var response container.ContainerCreateCreatedBody

	if err := cli.NewVersionError("1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil {
		return response, err
	}

	// When using API 1.24 and under, the client is responsible for removing the container
	if hostConfig != nil && versions.LessThan(cli.ClientVersion(), "1.25") {
		hostConfig.AutoRemove = false
	}

	if err := cli.NewVersionError("1.41", "specify container image platform"); platform != nil && err != nil {
		return response, err
	}

	query := url.Values{}
	if platform != nil {
		query.Set("platform", platforms.Format(*platform))
	}

	if containerName != "" {
		query.Set("name", containerName)
	}

	body := configWrapper{
		Config:           config,
		HostConfig:       hostConfig,
		NetworkingConfig: networkingConfig,
	}

	serverResp, err := cli.post(ctx, "/containers/create", query, body, nil)
	defer ensureReaderClosed(serverResp)
	if err != nil {
		return response, err
	}

	err = json.NewDecoder(serverResp.body).Decode(&response)
	return response, err
}
<|endoftext|>