<commit_before>// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package framework is a package helping setting up end-to-end testing across a
// Kubernetes cluster.
package framework

import (
	"fmt"
	"net"
	"time"

	"k8s.io/apimachinery/pkg/labels"

	"agones.dev/agones/pkg/apis/stable/v1alpha1"
	"agones.dev/agones/pkg/client/clientset/versioned"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/kubernetes"

	// required to use gcloud login see: https://github.com/kubernetes/client-go/issues/242
	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
	"k8s.io/client-go/tools/clientcmd"
)

// Framework is a testing framework
type Framework struct {
	KubeClient      kubernetes.Interface
	AgonesClient    versioned.Interface
	GameServerImage string
	PullSecret      string
}

// New setups a testing framework using a kubeconfig path and the game server image to use for testing.
func New(kubeconfig, gsimage string, pullSecret string) (*Framework, error) {
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
	if err != nil {
		return nil, errors.Wrap(err, "build config from flags failed")
	}

	kubeClient, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, errors.Wrap(err, "creating new kube-client failed")
	}

	agonesClient, err := versioned.NewForConfig(config)
	if err != nil {
		return nil, errors.Wrap(err, "creating new agones-client failed")
	}

	return &Framework{
		KubeClient:      kubeClient,
		AgonesClient:    agonesClient,
		GameServerImage: gsimage,
		PullSecret:      pullSecret,
	}, nil
}

// CreateGameServerAndWaitUntilReady Creates a GameServer and wait for its state to become ready.
func (f *Framework) CreateGameServerAndWaitUntilReady(ns string, gs *v1alpha1.GameServer) (*v1alpha1.GameServer, error) {
	newGs, err := f.AgonesClient.StableV1alpha1().GameServers(ns).Create(gs)
	if err != nil {
		return nil, fmt.Errorf("creating %v GameServer instances failed (%v): %v", gs.Spec, gs.Name, err)
	}

	logrus.WithField("name", newGs.ObjectMeta.Name).Info("GameServer created, waiting for Ready")

	readyGs, err := f.WaitForGameServerState(newGs, v1alpha1.Ready, 5*time.Minute)

	if err != nil {
		return nil, fmt.Errorf("waiting for %v GameServer instance readiness timed out (%v): %v",
			gs.Spec, gs.Name, err)
	}
	if len(readyGs.Status.Ports) == 0 {
		return nil, fmt.Errorf("Ready GameServer instance has no port: %v", readyGs.Status)
	}

	return readyGs, nil
}

// WaitForGameServerState Waits untils the gameserver reach a given state before the timeout expires
func (f *Framework) WaitForGameServerState(gs *v1alpha1.GameServer, state v1alpha1.State,
	timeout time.Duration) (*v1alpha1.GameServer, error) {
	var pollErr error
	var readyGs *v1alpha1.GameServer

	err := wait.PollImmediate(2*time.Second, timeout, func() (bool, error) {
		readyGs, pollErr = f.AgonesClient.StableV1alpha1().GameServers(gs.Namespace).Get(gs.Name, metav1.GetOptions{})

		if pollErr != nil {
			return false, nil
		}

		if readyGs.Status.State == state {
			return true, nil
		}

		return false, nil
	})
	if err != nil {
		return nil, errors.Wrapf(pollErr, "waiting for GameServer to be %v %v/%v: %v",
			state, gs.Namespace, gs.Name, err)
	}
	return readyGs, nil
}

// WaitForFleetCondition waits for the Fleet to be in a specific condition
func (f *Framework) WaitForFleetCondition(flt *v1alpha1.Fleet, condition func(fleet *v1alpha1.Fleet) bool) error {
	err := wait.PollImmediate(2*time.Second, 120*time.Second, func() (bool, error) {
		fleet, err := f.AgonesClient.StableV1alpha1().Fleets(flt.ObjectMeta.Namespace).Get(flt.ObjectMeta.Name, metav1.GetOptions{})
		if err != nil {
			return true, err
		}

		return condition(fleet), nil
	})
	return err
}

// ListGameServersFromFleet lists GameServers from a particular fleet
func (f *Framework) ListGameServersFromFleet(flt *v1alpha1.Fleet) ([]v1alpha1.GameServer, error) {
	var results []v1alpha1.GameServer

	opts := metav1.ListOptions{LabelSelector: labels.Set{v1alpha1.FleetGameServerSetLabel: flt.ObjectMeta.Name}.String()}
	gsSetList, err := f.AgonesClient.StableV1alpha1().GameServerSets(flt.ObjectMeta.Namespace).List(opts)
	if err != nil {
		return results, err
	}

	for _, gsSet := range gsSetList.Items {
		opts := metav1.ListOptions{LabelSelector: labels.Set{v1alpha1.GameServerSetGameServerLabel: gsSet.ObjectMeta.Name}.String()}
		gsList, err := f.AgonesClient.StableV1alpha1().GameServers(flt.ObjectMeta.Namespace).List(opts)
		if err != nil {
			return results, err
		}

		results = append(results, gsList.Items...)
	}

	return results, nil
}

// FleetReadyCountCondition checks the ready count in a fleet
func FleetReadyCount(amount int32) func(fleet *v1alpha1.Fleet) bool {
	return func(fleet *v1alpha1.Fleet) bool {
		return fleet.Status.ReadyReplicas == amount
	}
}

// WaitForFleetGameServersCondition wait for all GameServers for a given
// fleet to match the spec.replicas and match a a condition
func (f *Framework) WaitForFleetGameServersCondition(flt *v1alpha1.Fleet, cond func(server v1alpha1.GameServer) bool) error {
	return wait.Poll(2*time.Second, 5*time.Minute, func() (done bool, err error) {
		gsList, err := f.ListGameServersFromFleet(flt)
		if err != nil {
			return false, err
		}

		if int32(len(gsList)) != flt.Spec.Replicas {
			return false, nil
		}

		if err != nil {
			return false, err
		}

		for _, gs := range gsList {
			if !cond(gs) {
				return false, nil
			}
		}

		return true, nil
	})
}

// CleanUp Delete all Agones resources in a given namespace
func (f *Framework) CleanUp(ns string) error {
	logrus.Info("Done. Cleaning up now.")
	err := f.AgonesClient.StableV1alpha1().Fleets(ns).DeleteCollection(&metav1.DeleteOptions{}, metav1.ListOptions{})
	if err != nil {
		return err
	}

	return f.AgonesClient.StableV1alpha1().GameServers(ns).
		DeleteCollection(&metav1.DeleteOptions{}, metav1.ListOptions{})
}

// PingGameServer pings a gameserver and returns its reply
func PingGameServer(msg, address string) (reply string, err error) {
	conn, err := net.Dial("udp", address)
	if err != nil {
		return "", err
	}
	defer func() {
		err = conn.Close()
	}()
	_, err = conn.Write([]byte(msg))
	if err != nil {
		return "", errors.Wrapf(err, "Could not write message %s", msg)
	}
	b := make([]byte, 1024)

	err = conn.SetReadDeadline(time.Now().Add(30 * time.Second))
	if err != nil {
		return "", err
	}
	n, err := conn.Read(b)
	if err != nil {
		return "", err
	}
	return string(b[:n]), nil
}
<commit_msg>Make WaitForFleetCondition take up to 5 minutes<commit_after>// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package framework is a package helping setting up end-to-end testing across a
// Kubernetes cluster.
package framework

import (
	"fmt"
	"net"
	"time"

	"agones.dev/agones/pkg/apis/stable/v1alpha1"
	"agones.dev/agones/pkg/client/clientset/versioned"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/kubernetes"

	// required to use gcloud login see: https://github.com/kubernetes/client-go/issues/242
	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
	"k8s.io/client-go/tools/clientcmd"
)

// Framework is a testing framework
type Framework struct {
	KubeClient      kubernetes.Interface
	AgonesClient    versioned.Interface
	GameServerImage string
	PullSecret      string
}

// New setups a testing framework using a kubeconfig path and the game server image to use for testing.
func New(kubeconfig, gsimage string, pullSecret string) (*Framework, error) {
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
	if err != nil {
		return nil, errors.Wrap(err, "build config from flags failed")
	}

	kubeClient, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, errors.Wrap(err, "creating new kube-client failed")
	}

	agonesClient, err := versioned.NewForConfig(config)
	if err != nil {
		return nil, errors.Wrap(err, "creating new agones-client failed")
	}

	return &Framework{
		KubeClient:      kubeClient,
		AgonesClient:    agonesClient,
		GameServerImage: gsimage,
		PullSecret:      pullSecret,
	}, nil
}

// CreateGameServerAndWaitUntilReady Creates a GameServer and wait for its state to become ready.
func (f *Framework) CreateGameServerAndWaitUntilReady(ns string, gs *v1alpha1.GameServer) (*v1alpha1.GameServer, error) {
	newGs, err := f.AgonesClient.StableV1alpha1().GameServers(ns).Create(gs)
	if err != nil {
		return nil, fmt.Errorf("creating %v GameServer instances failed (%v): %v", gs.Spec, gs.Name, err)
	}

	logrus.WithField("name", newGs.ObjectMeta.Name).Info("GameServer created, waiting for Ready")

	readyGs, err := f.WaitForGameServerState(newGs, v1alpha1.Ready, 5*time.Minute)

	if err != nil {
		return nil, fmt.Errorf("waiting for %v GameServer instance readiness timed out (%v): %v",
			gs.Spec, gs.Name, err)
	}
	if len(readyGs.Status.Ports) == 0 {
		return nil, fmt.Errorf("Ready GameServer instance has no port: %v", readyGs.Status)
	}

	return readyGs, nil
}

// WaitForGameServerState Waits untils the gameserver reach a given state before the timeout expires
func (f *Framework) WaitForGameServerState(gs *v1alpha1.GameServer, state v1alpha1.State,
	timeout time.Duration) (*v1alpha1.GameServer, error) {
	var pollErr error
	var readyGs *v1alpha1.GameServer

	err := wait.PollImmediate(2*time.Second, timeout, func() (bool, error) {
		readyGs, pollErr = f.AgonesClient.StableV1alpha1().GameServers(gs.Namespace).Get(gs.Name, metav1.GetOptions{})

		if pollErr != nil {
			return false, nil
		}

		if readyGs.Status.State == state {
			return true, nil
		}

		return false, nil
	})
	if err != nil {
		return nil, errors.Wrapf(pollErr, "waiting for GameServer to be %v %v/%v: %v",
			state, gs.Namespace, gs.Name, err)
	}
	return readyGs, nil
}

// WaitForFleetCondition waits for the Fleet to be in a specific condition
func (f *Framework) WaitForFleetCondition(flt *v1alpha1.Fleet, condition func(fleet *v1alpha1.Fleet) bool) error {
	err := wait.PollImmediate(2*time.Second, 5*time.Minute, func() (bool, error) {
		fleet, err := f.AgonesClient.StableV1alpha1().Fleets(flt.ObjectMeta.Namespace).Get(flt.ObjectMeta.Name, metav1.GetOptions{})
		if err != nil {
			return true, err
		}

		return condition(fleet), nil
	})
	return err
}

// ListGameServersFromFleet lists GameServers from a particular fleet
func (f *Framework) ListGameServersFromFleet(flt *v1alpha1.Fleet) ([]v1alpha1.GameServer, error) {
	var results []v1alpha1.GameServer

	opts := metav1.ListOptions{LabelSelector: labels.Set{v1alpha1.FleetGameServerSetLabel: flt.ObjectMeta.Name}.String()}
	gsSetList, err := f.AgonesClient.StableV1alpha1().GameServerSets(flt.ObjectMeta.Namespace).List(opts)
	if err != nil {
		return results, err
	}

	for _, gsSet := range gsSetList.Items {
		opts := metav1.ListOptions{LabelSelector: labels.Set{v1alpha1.GameServerSetGameServerLabel: gsSet.ObjectMeta.Name}.String()}
		gsList, err := f.AgonesClient.StableV1alpha1().GameServers(flt.ObjectMeta.Namespace).List(opts)
		if err != nil {
			return results, err
		}

		results = append(results, gsList.Items...)
	}

	return results, nil
}

// FleetReadyCountCondition checks the ready count in a fleet
func FleetReadyCount(amount int32) func(fleet *v1alpha1.Fleet) bool {
	return func(fleet *v1alpha1.Fleet) bool {
		return fleet.Status.ReadyReplicas == amount
	}
}

// WaitForFleetGameServersCondition wait for all GameServers for a given
// fleet to match the spec.replicas and match a a condition
func (f *Framework) WaitForFleetGameServersCondition(flt *v1alpha1.Fleet, cond func(server v1alpha1.GameServer) bool) error {
	return wait.Poll(2*time.Second, 5*time.Minute, func() (done bool, err error) {
		gsList, err := f.ListGameServersFromFleet(flt)
		if err != nil {
			return false, err
		}

		if int32(len(gsList)) != flt.Spec.Replicas {
			return false, nil
		}

		if err != nil {
			return false, err
		}

		for _, gs := range gsList {
			if !cond(gs) {
				return false, nil
			}
		}

		return true, nil
	})
}

// CleanUp Delete all Agones resources in a given namespace
func (f *Framework) CleanUp(ns string) error {
	logrus.Info("Done. Cleaning up now.")
	err := f.AgonesClient.StableV1alpha1().Fleets(ns).DeleteCollection(&metav1.DeleteOptions{}, metav1.ListOptions{})
	if err != nil {
		return err
	}

	return f.AgonesClient.StableV1alpha1().GameServers(ns).
		DeleteCollection(&metav1.DeleteOptions{}, metav1.ListOptions{})
}

// PingGameServer pings a gameserver and returns its reply
func PingGameServer(msg, address string) (reply string, err error) {
	conn, err := net.Dial("udp", address)
	if err != nil {
		return "", err
	}
	defer func() {
		err = conn.Close()
	}()
	_, err = conn.Write([]byte(msg))
	if err != nil {
		return "", errors.Wrapf(err, "Could not write message %s", msg)
	}
	b := make([]byte, 1024)

	err = conn.SetReadDeadline(time.Now().Add(30 * time.Second))
	if err != nil {
		return "", err
	}
	n, err := conn.Read(b)
	if err != nil {
		return "", err
	}
	return string(b[:n]), nil
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors All rights reserved.

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

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

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

// To run the e2e tests against one or more hosts on gce: $ go run run_e2e.go --hosts <comma separated hosts>
// Requires gcloud compute ssh access to the hosts
package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"strings"
	"sync"
	"time"

	"runtime"

	"github.com/golang/glog"
	"k8s.io/kubernetes/test/e2e_node/gcloud"
	"path/filepath"
)

type RunFunc func(host string, port string) ([]byte, error)

type Result struct {
	host   string
	output []byte
	err    error
}

var u = sync.WaitGroup{}
var zone = flag.String("zone", "", "gce zone the hosts live in")
var hosts = flag.String("hosts", "", "hosts to test")
var wait = flag.Bool("wait", false, "if true, wait for input before running tests")
var kubeOutputRelPath = flag.String("k8s-build-output", "_output/local/bin/linux/amd64", "Where k8s binary files are written")

var kubeRoot = ""

const buildScriptRelPath = "hack/build-go.sh"
const ginkoTestRelPath = "test/e2e_node"
const healthyTimeoutDuration = time.Minute * 3

func main() {
	flag.Parse()
	if *hosts == "" {
		glog.Fatalf("Must specific --hosts flag")
	}

	// Figure out the kube root
	_, path, _, _ := runtime.Caller(0)
	kubeRoot, _ = filepath.Split(path)
	kubeRoot = strings.Split(kubeRoot, "/test/e2e_node")[0]

	// Build the go code
	out, err := exec.Command(filepath.Join(kubeRoot, buildScriptRelPath)).CombinedOutput()
	if err != nil {
		glog.Fatalf("Failed to build go packages %s: %v", out, err)
	}

	// Copy kubelet to each host and run test
	if *wait {
		u.Add(1)
	}

	w := sync.WaitGroup{}
	for _, h := range strings.Split(*hosts, ",") {
		w.Add(1)
		go func(host string) {
			out, err := runTests(host)
			if err != nil {
				glog.Infof("Failure Finished Host %s Test Suite %s %v", host, out, err)
			} else {
				glog.Infof("Success Finished Host %s Test Suite %s", host, out)
			}
			w.Done()
		}(h)
	}

	// Maybe wait for user input before running tests
	if *wait {
		WaitForUser()
	}

	// Wait for the tests to finish
	w.Wait()
	glog.Infof("Done")
}

func WaitForUser() {
	scanner := bufio.NewScanner(os.Stdin)
	fmt.Printf("Enter \"y\" to run tests\n")
	for scanner.Scan() {
		if strings.ToUpper(scanner.Text()) != "Y\n" {
			break
		}
		fmt.Printf("Enter \"y\" to run tests\n")
	}
	u.Done()
}

func runTests(fullhost string) ([]byte, error) {
	host := strings.Split(fullhost, ".")[0]
	c := gcloud.NewGCloudClient(host, *zone)
	// TODO(pwittrock): Come up with something better for bootstrapping the environment.
	eh, err := c.RunAndWaitTillHealthy(
		false, false, "4001", healthyTimeoutDuration, "v2/keys/", "etcd", "--data-dir", "./", "--name", "e2e-node")
	defer func() { eh.TearDown() }()
	if err != nil {
		return nil, fmt.Errorf("Host %s failed to run command %v", host, err)
	}

	apiBin := filepath.Join(kubeRoot, *kubeOutputRelPath, "kube-apiserver")
	ah, err := c.RunAndWaitTillHealthy(
		true, true, "8080", healthyTimeoutDuration, "healthz", apiBin, "--service-cluster-ip-range",
		"10.0.0.1/24", "--insecure-bind-address", "0.0.0.0", "--etcd-servers", "http://127.0.0.1:4001",
		"--cluster-name", "kubernetes", "--v", "2", "--kubelet-port", "10250")
	defer func() { ah.TearDown() }()
	if err != nil {
		return nil, fmt.Errorf("Host %s failed to run command %v", host, err)
	}

	kubeletBin := filepath.Join(kubeRoot, *kubeOutputRelPath, "kubelet")
	kh, err := c.RunAndWaitTillHealthy(
		true, true, "10255", healthyTimeoutDuration, "healthz", kubeletBin, "--api-servers", "http://127.0.0.1:8080",
		"--logtostderr", "--address", "0.0.0.0", "--port", "10250")
	defer func() { kh.TearDown() }()
	if err != nil {
		return nil, fmt.Errorf("Host %s failed to run command %v", host, err)
	}

	// Run the tests
	glog.Infof("Kubelet healthy on host %s", host)
	glog.Infof("Kubelet host %s tunnel running on port %s", host, ah.LPort)
	u.Wait()
	glog.Infof("Running ginkgo tests against host %s", host)
	ginkoTests := filepath.Join(kubeRoot, ginkoTestRelPath)
	return exec.Command(
		"ginkgo", ginkoTests, "--",
		"--kubelet-address", fmt.Sprintf("http://127.0.0.1:%s", kh.LPort),
		"--api-server-address", fmt.Sprintf("http://127.0.0.1:%s", ah.LPort),
		"--node-name", fullhost,
		"-logtostderr").CombinedOutput()
}
<commit_msg>remove cluster-name flag from e2e tests because it doesn't exist anymore<commit_after>/*
Copyright 2015 The Kubernetes Authors All rights reserved.

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

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

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

// To run the e2e tests against one or more hosts on gce: $ go run run_e2e.go --hosts <comma separated hosts>
// Requires gcloud compute ssh access to the hosts
package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"strings"
	"sync"
	"time"

	"runtime"

	"github.com/golang/glog"
	"k8s.io/kubernetes/test/e2e_node/gcloud"
	"path/filepath"
)

type RunFunc func(host string, port string) ([]byte, error)

type Result struct {
	host   string
	output []byte
	err    error
}

var u = sync.WaitGroup{}
var zone = flag.String("zone", "", "gce zone the hosts live in")
var hosts = flag.String("hosts", "", "hosts to test")
var wait = flag.Bool("wait", false, "if true, wait for input before running tests")
var kubeOutputRelPath = flag.String("k8s-build-output", "_output/local/bin/linux/amd64", "Where k8s binary files are written")

var kubeRoot = ""

const buildScriptRelPath = "hack/build-go.sh"
const ginkoTestRelPath = "test/e2e_node"
const healthyTimeoutDuration = time.Minute * 3

func main() {
	flag.Parse()
	if *hosts == "" {
		glog.Fatalf("Must specific --hosts flag")
	}

	// Figure out the kube root
	_, path, _, _ := runtime.Caller(0)
	kubeRoot, _ = filepath.Split(path)
	kubeRoot = strings.Split(kubeRoot, "/test/e2e_node")[0]

	// Build the go code
	out, err := exec.Command(filepath.Join(kubeRoot, buildScriptRelPath)).CombinedOutput()
	if err != nil {
		glog.Fatalf("Failed to build go packages %s: %v", out, err)
	}

	// Copy kubelet to each host and run test
	if *wait {
		u.Add(1)
	}

	w := sync.WaitGroup{}
	for _, h := range strings.Split(*hosts, ",") {
		w.Add(1)
		go func(host string) {
			out, err := runTests(host)
			if err != nil {
				glog.Infof("Failure Finished Host %s Test Suite %s %v", host, out, err)
			} else {
				glog.Infof("Success Finished Host %s Test Suite %s", host, out)
			}
			w.Done()
		}(h)
	}

	// Maybe wait for user input before running tests
	if *wait {
		WaitForUser()
	}

	// Wait for the tests to finish
	w.Wait()
	glog.Infof("Done")
}

func WaitForUser() {
	scanner := bufio.NewScanner(os.Stdin)
	fmt.Printf("Enter \"y\" to run tests\n")
	for scanner.Scan() {
		if strings.ToUpper(scanner.Text()) != "Y\n" {
			break
		}
		fmt.Printf("Enter \"y\" to run tests\n")
	}
	u.Done()
}

func runTests(fullhost string) ([]byte, error) {
	host := strings.Split(fullhost, ".")[0]
	c := gcloud.NewGCloudClient(host, *zone)
	// TODO(pwittrock): Come up with something better for bootstrapping the environment.
	eh, err := c.RunAndWaitTillHealthy(
		false, false, "4001", healthyTimeoutDuration, "v2/keys/", "etcd", "--data-dir", "./", "--name", "e2e-node")
	defer func() { eh.TearDown() }()
	if err != nil {
		return nil, fmt.Errorf("Host %s failed to run command %v", host, err)
	}

	apiBin := filepath.Join(kubeRoot, *kubeOutputRelPath, "kube-apiserver")
	ah, err := c.RunAndWaitTillHealthy(
		true, true, "8080", healthyTimeoutDuration, "healthz", apiBin, "--service-cluster-ip-range",
		"10.0.0.1/24", "--insecure-bind-address", "0.0.0.0", "--etcd-servers", "http://127.0.0.1:4001",
		"--v", "2", "--kubelet-port", "10250")
	defer func() { ah.TearDown() }()
	if err != nil {
		return nil, fmt.Errorf("Host %s failed to run command %v", host, err)
	}

	kubeletBin := filepath.Join(kubeRoot, *kubeOutputRelPath, "kubelet")
	kh, err := c.RunAndWaitTillHealthy(
		true, true, "10255", healthyTimeoutDuration, "healthz", kubeletBin, "--api-servers", "http://127.0.0.1:8080",
		"--logtostderr", "--address", "0.0.0.0", "--port", "10250")
	defer func() { kh.TearDown() }()
	if err != nil {
		return nil, fmt.Errorf("Host %s failed to run command %v", host, err)
	}

	// Run the tests
	glog.Infof("Kubelet healthy on host %s", host)
	glog.Infof("Kubelet host %s tunnel running on port %s", host, ah.LPort)
	u.Wait()
	glog.Infof("Running ginkgo tests against host %s", host)
	ginkoTests := filepath.Join(kubeRoot, ginkoTestRelPath)
	return exec.Command(
		"ginkgo", ginkoTests, "--",
		"--kubelet-address", fmt.Sprintf("http://127.0.0.1:%s", kh.LPort),
		"--api-server-address", fmt.Sprintf("http://127.0.0.1:%s", ah.LPort),
		"--node-name", fullhost,
		"-logtostderr").CombinedOutput()
}
<|endoftext|>


<commit_before>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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

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

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

package kubectl

import (
	"fmt"
	"strings"
	"time"

	fuzz "github.com/google/gofuzz"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/meta"
	client "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/util/wait"
)

const (
	Interval = time.Second * 1
	Timeout  = time.Minute * 5
)

// A Reaper handles terminating an object as gracefully as possible.
// timeout is how long we'll wait for the termination to be successful
// gracePeriod is time given to an API object for it to delete itself cleanly (e.g. pod shutdown)
type Reaper interface {
	Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error)
}

type NoSuchReaperError struct {
	kind string
}

func (n *NoSuchReaperError) Error() string {
	return fmt.Sprintf("no reaper has been implemented for %q", n.kind)
}

func IsNoSuchReaperError(err error) bool {
	_, ok := err.(*NoSuchReaperError)
	return ok
}

func ReaperFor(kind string, c client.Interface) (Reaper, error) {
	switch kind {
	case "ReplicationController":
		return &ReplicationControllerReaper{c, Interval, Timeout}, nil
	case "DaemonSet":
		return &DaemonSetReaper{c, Interval, Timeout}, nil
	case "Pod":
		return &PodReaper{c}, nil
	case "Service":
		return &ServiceReaper{c}, nil
	case "Job":
		return &JobReaper{c, Interval, Timeout}, nil
	}
	return nil, &NoSuchReaperError{kind}
}

func ReaperForReplicationController(c client.Interface, timeout time.Duration) (Reaper, error) {
	return &ReplicationControllerReaper{c, Interval, timeout}, nil
}

type ReplicationControllerReaper struct {
	client.Interface
	pollInterval, timeout time.Duration
}
type DaemonSetReaper struct {
	client.Interface
	pollInterval, timeout time.Duration
}
type JobReaper struct {
	client.Interface
	pollInterval, timeout time.Duration
}
type PodReaper struct {
	client.Interface
}
type ServiceReaper struct {
	client.Interface
}

type objInterface interface {
	Delete(name string) error
	Get(name string) (meta.Interface, error)
}

// getOverlappingControllers finds rcs that this controller overlaps, as well as rcs overlapping this controller.
func getOverlappingControllers(c client.ReplicationControllerInterface, rc *api.ReplicationController) ([]api.ReplicationController, error) {
	rcs, err := c.List(labels.Everything())
	if err != nil {
		return nil, fmt.Errorf("error getting replication controllers: %v", err)
	}
	var matchingRCs []api.ReplicationController
	rcLabels := labels.Set(rc.Spec.Selector)
	for _, controller := range rcs.Items {
		newRCLabels := labels.Set(controller.Spec.Selector)
		if labels.SelectorFromSet(newRCLabels).Matches(rcLabels) || labels.SelectorFromSet(rcLabels).Matches(newRCLabels) {
			matchingRCs = append(matchingRCs, controller)
		}
	}
	return matchingRCs, nil
}

func (reaper *ReplicationControllerReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) {
	rc := reaper.ReplicationControllers(namespace)
	scaler, err := ScalerFor("ReplicationController", *reaper)
	if err != nil {
		return "", err
	}
	ctrl, err := rc.Get(name)
	if err != nil {
		return "", err
	}
	if timeout == 0 {
		timeout = Timeout + time.Duration(10*ctrl.Spec.Replicas)*time.Second
	}

	// The rc manager will try and detect all matching rcs for a pod's labels,
	// and only sync the oldest one. This means if we have a pod with labels
	// [(k1: v1), (k2: v2)] and two rcs: rc1 with selector [(k1=v1)], and rc2 with selector [(k1=v1),(k2=v2)],
	// the rc manager will sync the older of the two rcs.
	//
	// If there are rcs with a superset of labels, eg:
	// deleting: (k1=v1), superset: (k2=v2, k1=v1)
	//	- It isn't safe to delete the rc because there could be a pod with labels
	//	  (k1=v1) that isn't managed by the superset rc. We can't scale it down
	//	  either, because there could be a pod (k2=v2, k1=v1) that it deletes
	//	  causing a fight with the superset rc.
	// If there are rcs with a subset of labels, eg:
	// deleting: (k2=v2, k1=v1), subset: (k1=v1), superset: (k2=v2, k1=v1, k3=v3)
	//  - Even if it's safe to delete this rc without a scale down because all it's pods
	//	  are being controlled by the subset rc the code returns an error.

	// In theory, creating overlapping controllers is user error, so the loop below
	// tries to account for this logic only in the common case, where we end up
	// with multiple rcs that have an exact match on selectors.

	overlappingCtrls, err := getOverlappingControllers(rc, ctrl)
	if err != nil {
		return "", fmt.Errorf("error getting replication controllers: %v", err)
	}
	exactMatchRCs := []api.ReplicationController{}
	overlapRCs := []string{}
	for _, overlappingRC := range overlappingCtrls {
		if len(overlappingRC.Spec.Selector) == len(ctrl.Spec.Selector) {
			exactMatchRCs = append(exactMatchRCs, overlappingRC)
		} else {
			overlapRCs = append(overlapRCs, overlappingRC.Name)
		}
	}
	if len(overlapRCs) > 0 {
		return "", fmt.Errorf(
			"Detected overlapping controllers for rc %v: %v, please manage deletion individually with --cascade=false.",
			ctrl.Name, strings.Join(overlapRCs, ","))
	}
	if len(exactMatchRCs) == 1 {
		// No overlapping controllers.
		retry := NewRetryParams(reaper.pollInterval, reaper.timeout)
		waitForReplicas := NewRetryParams(reaper.pollInterval, timeout)
		if err = scaler.Scale(namespace, name, 0, nil, retry, waitForReplicas); err != nil {
			return "", err
		}
	}
	if err := rc.Delete(name); err != nil {
		return "", err
	}
	return fmt.Sprintf("%s stopped", name), nil
}

func (reaper *DaemonSetReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) {
	daemon, err := reaper.Experimental().DaemonSets(namespace).Get(name)
	if err != nil {
		return "", err
	}

	// Update the daemon set to select for a non-existent NodeName.
	// The daemon set controller will then kill all the daemon pods corresponding to daemon set.
	nodes, err := reaper.Nodes().List(labels.Everything(), fields.Everything())
	if err != nil {
		return "", err
	}
	var fuzzer = fuzz.New()
	var nameExists bool

	var nodeName string
	fuzzer.Fuzz(&nodeName)
	nameExists = false
	for _, node := range nodes.Items {
		nameExists = nameExists || node.Name == nodeName
	}
	if nameExists {
		// Probability of reaching here is extremely low, most likely indicates a programming bug/library error.
		return "", fmt.Errorf("Name collision generating an unused node name. Please retry this operation.")
	}

	daemon.Spec.Template.Spec.NodeName = nodeName

	reaper.Experimental().DaemonSets(namespace).Update(daemon)

	// Wait for the daemon set controller to kill all the daemon pods.
	if err := wait.Poll(reaper.pollInterval, reaper.timeout, func() (bool, error) {
		updatedDS, err := reaper.Experimental().DaemonSets(namespace).Get(name)
		if err != nil {
			return false, nil
		}
		return updatedDS.Status.CurrentNumberScheduled+updatedDS.Status.NumberMisscheduled == 0, nil
	}); err != nil {
		return "", err
	}

	if err := reaper.Experimental().DaemonSets(namespace).Delete(name); err != nil {
		return "", err
	}
	return fmt.Sprintf("%s stopped", name), nil
}

func (reaper *JobReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) {
	jobs := reaper.Experimental().Jobs(namespace)
	scaler, err := ScalerFor("Job", *reaper)
	if err != nil {
		return "", err
	}
	job, err := jobs.Get(name)
	if err != nil {
		return "", err
	}
	if timeout == 0 {
		// we will never have more active pods than job.Spec.Parallelism
		parallelism := *job.Spec.Parallelism
		timeout = Timeout + time.Duration(10*parallelism)*time.Second
	}

	// TODO: handle overlapping jobs
	retry := NewRetryParams(reaper.pollInterval, reaper.timeout)
	waitForJobs := NewRetryParams(reaper.pollInterval, timeout)
	if err = scaler.Scale(namespace, name, 0, nil, retry, waitForJobs); err != nil {
		return "", err
	}
	if err := jobs.Delete(name, gracePeriod); err != nil {
		return "", err
	}
	return fmt.Sprintf("%s stopped", name), nil
}

func (reaper *PodReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) {
	pods := reaper.Pods(namespace)
	_, err := pods.Get(name)
	if err != nil {
		return "", err
	}
	if err := pods.Delete(name, gracePeriod); err != nil {
		return "", err
	}

	return fmt.Sprintf("%s stopped", name), nil
}

func (reaper *ServiceReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) {
	services := reaper.Services(namespace)
	_, err := services.Get(name)
	if err != nil {
		return "", err
	}
	if err := services.Delete(name); err != nil {
		return "", err
	}
	return fmt.Sprintf("%s stopped", name), nil
}
<commit_msg>use unconditional update and check error of update in DaemonSet reaper<commit_after>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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

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

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

package kubectl

import (
	"fmt"
	"strings"
	"time"

	fuzz "github.com/google/gofuzz"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/meta"
	client "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/util/wait"
)

const (
	Interval = time.Second * 1
	Timeout  = time.Minute * 5
)

// A Reaper handles terminating an object as gracefully as possible.
// timeout is how long we'll wait for the termination to be successful
// gracePeriod is time given to an API object for it to delete itself cleanly (e.g. pod shutdown)
type Reaper interface {
	Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error)
}

type NoSuchReaperError struct {
	kind string
}

func (n *NoSuchReaperError) Error() string {
	return fmt.Sprintf("no reaper has been implemented for %q", n.kind)
}

func IsNoSuchReaperError(err error) bool {
	_, ok := err.(*NoSuchReaperError)
	return ok
}

func ReaperFor(kind string, c client.Interface) (Reaper, error) {
	switch kind {
	case "ReplicationController":
		return &ReplicationControllerReaper{c, Interval, Timeout}, nil
	case "DaemonSet":
		return &DaemonSetReaper{c, Interval, Timeout}, nil
	case "Pod":
		return &PodReaper{c}, nil
	case "Service":
		return &ServiceReaper{c}, nil
	case "Job":
		return &JobReaper{c, Interval, Timeout}, nil
	}
	return nil, &NoSuchReaperError{kind}
}

func ReaperForReplicationController(c client.Interface, timeout time.Duration) (Reaper, error) {
	return &ReplicationControllerReaper{c, Interval, timeout}, nil
}

type ReplicationControllerReaper struct {
	client.Interface
	pollInterval, timeout time.Duration
}
type DaemonSetReaper struct {
	client.Interface
	pollInterval, timeout time.Duration
}
type JobReaper struct {
	client.Interface
	pollInterval, timeout time.Duration
}
type PodReaper struct {
	client.Interface
}
type ServiceReaper struct {
	client.Interface
}

type objInterface interface {
	Delete(name string) error
	Get(name string) (meta.Interface, error)
}

// getOverlappingControllers finds rcs that this controller overlaps, as well as rcs overlapping this controller.
func getOverlappingControllers(c client.ReplicationControllerInterface, rc *api.ReplicationController) ([]api.ReplicationController, error) {
	rcs, err := c.List(labels.Everything())
	if err != nil {
		return nil, fmt.Errorf("error getting replication controllers: %v", err)
	}
	var matchingRCs []api.ReplicationController
	rcLabels := labels.Set(rc.Spec.Selector)
	for _, controller := range rcs.Items {
		newRCLabels := labels.Set(controller.Spec.Selector)
		if labels.SelectorFromSet(newRCLabels).Matches(rcLabels) || labels.SelectorFromSet(rcLabels).Matches(newRCLabels) {
			matchingRCs = append(matchingRCs, controller)
		}
	}
	return matchingRCs, nil
}

func (reaper *ReplicationControllerReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) {
	rc := reaper.ReplicationControllers(namespace)
	scaler, err := ScalerFor("ReplicationController", *reaper)
	if err != nil {
		return "", err
	}
	ctrl, err := rc.Get(name)
	if err != nil {
		return "", err
	}
	if timeout == 0 {
		timeout = Timeout + time.Duration(10*ctrl.Spec.Replicas)*time.Second
	}

	// The rc manager will try and detect all matching rcs for a pod's labels,
	// and only sync the oldest one. This means if we have a pod with labels
	// [(k1: v1), (k2: v2)] and two rcs: rc1 with selector [(k1=v1)], and rc2 with selector [(k1=v1),(k2=v2)],
	// the rc manager will sync the older of the two rcs.
	//
	// If there are rcs with a superset of labels, eg:
	// deleting: (k1=v1), superset: (k2=v2, k1=v1)
	//	- It isn't safe to delete the rc because there could be a pod with labels
	//	  (k1=v1) that isn't managed by the superset rc. We can't scale it down
	//	  either, because there could be a pod (k2=v2, k1=v1) that it deletes
	//	  causing a fight with the superset rc.
	// If there are rcs with a subset of labels, eg:
	// deleting: (k2=v2, k1=v1), subset: (k1=v1), superset: (k2=v2, k1=v1, k3=v3)
	//  - Even if it's safe to delete this rc without a scale down because all it's pods
	//	  are being controlled by the subset rc the code returns an error.

	// In theory, creating overlapping controllers is user error, so the loop below
	// tries to account for this logic only in the common case, where we end up
	// with multiple rcs that have an exact match on selectors.

	overlappingCtrls, err := getOverlappingControllers(rc, ctrl)
	if err != nil {
		return "", fmt.Errorf("error getting replication controllers: %v", err)
	}
	exactMatchRCs := []api.ReplicationController{}
	overlapRCs := []string{}
	for _, overlappingRC := range overlappingCtrls {
		if len(overlappingRC.Spec.Selector) == len(ctrl.Spec.Selector) {
			exactMatchRCs = append(exactMatchRCs, overlappingRC)
		} else {
			overlapRCs = append(overlapRCs, overlappingRC.Name)
		}
	}
	if len(overlapRCs) > 0 {
		return "", fmt.Errorf(
			"Detected overlapping controllers for rc %v: %v, please manage deletion individually with --cascade=false.",
			ctrl.Name, strings.Join(overlapRCs, ","))
	}
	if len(exactMatchRCs) == 1 {
		// No overlapping controllers.
		retry := NewRetryParams(reaper.pollInterval, reaper.timeout)
		waitForReplicas := NewRetryParams(reaper.pollInterval, timeout)
		if err = scaler.Scale(namespace, name, 0, nil, retry, waitForReplicas); err != nil {
			return "", err
		}
	}
	if err := rc.Delete(name); err != nil {
		return "", err
	}
	return fmt.Sprintf("%s stopped", name), nil
}

func (reaper *DaemonSetReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) {
	ds, err := reaper.Experimental().DaemonSets(namespace).Get(name)
	if err != nil {
		return "", err
	}

	// Update the daemon set to select for a non-existent NodeName.
	// The daemon set controller will then kill all the daemon pods corresponding to daemon set.
	nodes, err := reaper.Nodes().List(labels.Everything(), fields.Everything())
	if err != nil {
		return "", err
	}
	var fuzzer = fuzz.New()
	var nameExists bool

	var nodeName string
	fuzzer.Fuzz(&nodeName)
	nameExists = false
	for _, node := range nodes.Items {
		nameExists = nameExists || node.Name == nodeName
	}
	if nameExists {
		// Probability of reaching here is extremely low, most likely indicates a programming bug/library error.
		return "", fmt.Errorf("Name collision generating an unused node name. Please retry this operation.")
	}

	ds.Spec.Template.Spec.NodeName = nodeName
	// force update to avoid version conflict
	ds.ResourceVersion = ""

	if ds, err = reaper.Experimental().DaemonSets(namespace).Update(ds); err != nil {
		return "", err
	}

	// Wait for the daemon set controller to kill all the daemon pods.
	if err := wait.Poll(reaper.pollInterval, reaper.timeout, func() (bool, error) {
		updatedDS, err := reaper.Experimental().DaemonSets(namespace).Get(name)
		if err != nil {
			return false, nil
		}
		return updatedDS.Status.CurrentNumberScheduled+updatedDS.Status.NumberMisscheduled == 0, nil
	}); err != nil {
		return "", err
	}

	if err := reaper.Experimental().DaemonSets(namespace).Delete(name); err != nil {
		return "", err
	}
	return fmt.Sprintf("%s stopped", name), nil
}

func (reaper *JobReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) {
	jobs := reaper.Experimental().Jobs(namespace)
	scaler, err := ScalerFor("Job", *reaper)
	if err != nil {
		return "", err
	}
	job, err := jobs.Get(name)
	if err != nil {
		return "", err
	}
	if timeout == 0 {
		// we will never have more active pods than job.Spec.Parallelism
		parallelism := *job.Spec.Parallelism
		timeout = Timeout + time.Duration(10*parallelism)*time.Second
	}

	// TODO: handle overlapping jobs
	retry := NewRetryParams(reaper.pollInterval, reaper.timeout)
	waitForJobs := NewRetryParams(reaper.pollInterval, timeout)
	if err = scaler.Scale(namespace, name, 0, nil, retry, waitForJobs); err != nil {
		return "", err
	}
	if err := jobs.Delete(name, gracePeriod); err != nil {
		return "", err
	}
	return fmt.Sprintf("%s stopped", name), nil
}

func (reaper *PodReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) {
	pods := reaper.Pods(namespace)
	_, err := pods.Get(name)
	if err != nil {
		return "", err
	}
	if err := pods.Delete(name, gracePeriod); err != nil {
		return "", err
	}

	return fmt.Sprintf("%s stopped", name), nil
}

func (reaper *ServiceReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) (string, error) {
	services := reaper.Services(namespace)
	_, err := services.Get(name)
	if err != nil {
		return "", err
	}
	if err := services.Delete(name); err != nil {
		return "", err
	}
	return fmt.Sprintf("%s stopped", name), nil
}
<|endoftext|>


<commit_before>package fbot

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

// Version is the version of the library.
const Version = "0.0.1"

const (
	// EventMessage represents the message event.
	EventMessage = "message"
	// EventDelivery represents the message-delivery event.
	EventDelivery = "delivery"
	// EventPostback represents the postback event.
	EventPostback = "postback"
)

// Bot is the object that receives and sends
// messages to the Messenger Platform.
type Bot struct {
	Config    *Config
	Callbacks map[string]func(*Event)
}

// Config represents the required configuration to
// receive and send message to the Messenger Platform.
type Config struct {
	AccessToken string
	AppSecret   string
	VerifyToken string
}

// NewBot creates a new instance of Bot.
func NewBot(config Config) *Bot {
	return &Bot{
		Config:    &config,
		Callbacks: make(map[string]func(*Event)),
	}
}

// Event represents the event fired by the webhook.
type Event struct {
	Sender    *User     `json:"sender"`
	Recipient *User     `json:"recipient"`
	Timestamp int64     `json:"timestamp,omitempty"`
	Message   *Message  `json:"message"`
	Delivery  *Delivery `json:"delivery"`
	Postback  *Postback `json:"postback"`
}

// User represents the user that acts like sender or recipient.
type User struct {
	ID          int64  `json:"id,omitempty"`
	PhoneNumber string `json:"phone_number,omitempty"`
}

// Message represents the message callback object.
type Message struct {
	Mid         string        `json:"mid,omitempty"`
	Seq         int           `json:"seq,omitempty"`
	Text        string        `json:"text,omitempty"`
	Attachment  *Attachment   `json:"attachment,omitempty"`
	Attachments []*Attachment `json:"attachments,omitempty"`
}

// Attachment represents the attachment object included in the message.
type Attachment struct {
	Type    string   `json:"type"`
	Payload *Payload `json:"payload"`
}

// Payload represents the attachment payload data.
type Payload struct {
	URL string `json:"url,omitempty"`
}

// Delivery represents the message-delivered callback object.
type Delivery struct {
	Mids      []string `json:"mids"`
	Watermark int64    `json:"watermark"`
	Seq       int      `json:"seq"`
}

// Postback respresents the postback callback object.
type Postback struct {
	Payload string `json:"payload"`
}

// On registers a callback for the given eventName.
func (bot *Bot) On(eventName string, callback func(*Event)) {
	bot.Callbacks[eventName] = callback
}

func (bot Bot) trigger(event *Event) {
	var eventName string

	if event.Message != nil {
		eventName = EventMessage
	} else if event.Delivery != nil {
		eventName = EventDelivery
	} else if event.Postback != nil {
		eventName = EventPostback
	} else {
		return
	}

	if callback, ok := bot.Callbacks[eventName]; ok {
		callback(event)
	}
}

const baseURL = "https://graph.facebook.com/v2.6/me/messages?access_token=%s"

// DeliverParams represents the message params sent by deliver.
type DeliverParams struct {
	Recipient *User    `json:"recipient"`
	Message   *Message `json:"message"`
}

// Deliver uses the Send API to deliver messages.
func (bot Bot) Deliver(params DeliverParams) error {
	url := fmt.Sprintf(baseURL, bot.Config.AccessToken)

	json, err := json.Marshal(&params)

	if err != nil {
		return err
	}

	_, err = http.Post(url, "application/json", bytes.NewBuffer(json))

	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Bump version.<commit_after>package fbot

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

// Version is the version of the library.
const Version = "0.0.2"

const (
	// EventMessage represents the message event.
	EventMessage = "message"
	// EventDelivery represents the message-delivery event.
	EventDelivery = "delivery"
	// EventPostback represents the postback event.
	EventPostback = "postback"
)

// Bot is the object that receives and sends
// messages to the Messenger Platform.
type Bot struct {
	Config    *Config
	Callbacks map[string]func(*Event)
}

// Config represents the required configuration to
// receive and send message to the Messenger Platform.
type Config struct {
	AccessToken string
	AppSecret   string
	VerifyToken string
}

// NewBot creates a new instance of Bot.
func NewBot(config Config) *Bot {
	return &Bot{
		Config:    &config,
		Callbacks: make(map[string]func(*Event)),
	}
}

// Event represents the event fired by the webhook.
type Event struct {
	Sender    *User     `json:"sender"`
	Recipient *User     `json:"recipient"`
	Timestamp int64     `json:"timestamp,omitempty"`
	Message   *Message  `json:"message"`
	Delivery  *Delivery `json:"delivery"`
	Postback  *Postback `json:"postback"`
}

// User represents the user that acts like sender or recipient.
type User struct {
	ID          int64  `json:"id,omitempty"`
	PhoneNumber string `json:"phone_number,omitempty"`
}

// Message represents the message callback object.
type Message struct {
	Mid         string        `json:"mid,omitempty"`
	Seq         int           `json:"seq,omitempty"`
	Text        string        `json:"text,omitempty"`
	Attachment  *Attachment   `json:"attachment,omitempty"`
	Attachments []*Attachment `json:"attachments,omitempty"`
}

// Attachment represents the attachment object included in the message.
type Attachment struct {
	Type    string   `json:"type"`
	Payload *Payload `json:"payload"`
}

// Payload represents the attachment payload data.
type Payload struct {
	URL string `json:"url,omitempty"`
}

// Delivery represents the message-delivered callback object.
type Delivery struct {
	Mids      []string `json:"mids"`
	Watermark int64    `json:"watermark"`
	Seq       int      `json:"seq"`
}

// Postback respresents the postback callback object.
type Postback struct {
	Payload string `json:"payload"`
}

// On registers a callback for the given eventName.
func (bot *Bot) On(eventName string, callback func(*Event)) {
	bot.Callbacks[eventName] = callback
}

func (bot Bot) trigger(event *Event) {
	var eventName string

	if event.Message != nil {
		eventName = EventMessage
	} else if event.Delivery != nil {
		eventName = EventDelivery
	} else if event.Postback != nil {
		eventName = EventPostback
	} else {
		return
	}

	if callback, ok := bot.Callbacks[eventName]; ok {
		callback(event)
	}
}

const baseURL = "https://graph.facebook.com/v2.6/me/messages?access_token=%s"

// DeliverParams represents the message params sent by deliver.
type DeliverParams struct {
	Recipient *User    `json:"recipient"`
	Message   *Message `json:"message"`
}

// Deliver uses the Send API to deliver messages.
func (bot Bot) Deliver(params DeliverParams) error {
	url := fmt.Sprintf(baseURL, bot.Config.AccessToken)

	json, err := json.Marshal(&params)

	if err != nil {
		return err
	}

	_, err = http.Post(url, "application/json", bytes.NewBuffer(json))

	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package instant

import (
	"bytes"
	"crypto/md5"
	"encoding/xml"
	"fmt"
)

// Feed struct represents Facebook Instant Articles RSS feed.
// See https://developers.facebook.com/docs/instant-articles/publishing/setup-rss-feed for more info.
type Feed struct {
	Version string  `xml:"version,attr"`
	Content string  `xml:"xmlns:content,attr"`
	Channel channel `xml:"channel"`
}

type channel struct {
	Title         string `xml:"title"`
	LastBuildDate string `xml:"lastBuildDate"`
	Language      string `xml:"language"`
	Link          string `xml:"link"`
	Description   string `xml:"description"`
	Item          []item `xml:"item"`
}

type item struct {
	Title       string   `xml:"title"`
	GUID        string   `xml:"guid"`
	Description string   `xml:"description"`
	Link        string   `xml:"link"`
	Author      []string `xml:"author"`
	PubDate     string   `xml:"pubDate"`
	Encoded     []byte   `xml:",innerxml"`
}

// SetTitle of feed. Optional.
func (f *Feed) SetTitle(s string) {
	f.Channel.Title = s
}

// SetLink for feed. Optional.
func (f *Feed) SetLink(url string) {
	f.Channel.Link = url
}

// SetDescription set feed description. Optional.
func (f *Feed) SetDescription(s string) {
	f.Channel.Description = s
}

// SetLanguage sets feed language, default is set to en-us.
func (f *Feed) SetLanguage(l string) {
	f.Channel.Language = l
}

// // SetLastBuildDate sets feed last build date.
// func (f *Feed) setLastBuildDate(d time.Time) {
// }

// AddArticle to feed. Md5 checksum of URL will be used as GUID.
func (f *Feed) AddArticle(a Article) error {
	return f.addArticle(a, "")
}

// AddArticleWithGUID to feed.
func (f *Feed) AddArticleWithGUID(a Article, guid string) error {
	return f.addArticle(a, guid)
}

func (f *Feed) addArticle(a Article, guid string) error {

	b, err := xml.Marshal(a)
	if err != nil {
		return err
	}

	if guid == "" {
		guid = fmt.Sprintf("%x", md5.Sum([]byte(a.Head.Link.Href)))
	}

	var buff bytes.Buffer
	buff.WriteString("\n<content:encoded><![CDATA[\n")
	buff.Write(b)
	buff.WriteString("\n]]></content:encoded>")

	i := item{
		Title:       a.Body.Article.Header.H1,
		Description: a.Body.Article.Header.H2,
		Link:        a.Head.Link.Href,
		GUID:        guid,
		Encoded:     buff.Bytes(),
	}

	// if no subtitle, set first para as description
	if i.Description == "" && a.Body.Article.Content != nil {
		for _, ifc := range a.Body.Article.Content {
			switch ifc.(type) {
			case P:
				if ifc.(P).Text != "" {
					i.Description = string(ifc.(P).Text)
					break
				}
			}
		}
	}

	// set latest article date as pubDate
	for _, d := range a.Body.Article.Header.Time {
		if d.Datetime > i.PubDate {
			i.PubDate = d.Datetime
		}
	}

	// set latest article date to feed LastBuildDate
	if i.PubDate > f.Channel.LastBuildDate {
		f.Channel.LastBuildDate = i.PubDate
	}

	for _, auth := range a.Body.Article.Header.Address {
		i.Author = append(i.Author, auth.A.Text)
	}

	f.Channel.Item = append(f.Channel.Item, i)

	return nil
}

// MarshalXML for xml.Marshaler interface
func (f Feed) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	feed := struct {
		Version string  `xml:"version,attr"`
		Content string  `xml:"xmlns:content,attr"`
		Channel channel `xml:"channel"`
	}{
		Version: f.Version,
		Content: f.Content,
		Channel: f.Channel,
	}

	feed.Version = "2.0"
	feed.Content = "http://purl.org/rss/1.0/modules/content/"
	if feed.Channel.Language == "" {
		feed.Channel.Language = "en-us"
	}

	start.Name.Local = "rss" // rename root element from Article to html
	return e.EncodeElement(feed, start)
}

// RSS is synonym for xml.Marshal(f)
func (f Feed) RSS() ([]byte, error) {
	return xml.Marshal(f)
}
<commit_msg>Bugfix break loop<commit_after>package instant

import (
	"bytes"
	"crypto/md5"
	"encoding/xml"
	"fmt"
)

// Feed struct represents Facebook Instant Articles RSS feed.
// See https://developers.facebook.com/docs/instant-articles/publishing/setup-rss-feed for more info.
type Feed struct {
	Version string  `xml:"version,attr"`
	Content string  `xml:"xmlns:content,attr"`
	Channel channel `xml:"channel"`
}

type channel struct {
	Title         string `xml:"title"`
	LastBuildDate string `xml:"lastBuildDate"`
	Language      string `xml:"language"`
	Link          string `xml:"link"`
	Description   string `xml:"description"`
	Item          []item `xml:"item"`
}

type item struct {
	Title       string   `xml:"title"`
	GUID        string   `xml:"guid"`
	Description string   `xml:"description"`
	Link        string   `xml:"link"`
	Author      []string `xml:"author"`
	PubDate     string   `xml:"pubDate"`
	Encoded     []byte   `xml:",innerxml"`
}

// SetTitle of feed. Optional.
func (f *Feed) SetTitle(s string) {
	f.Channel.Title = s
}

// SetLink for feed. Optional.
func (f *Feed) SetLink(url string) {
	f.Channel.Link = url
}

// SetDescription set feed description. Optional.
func (f *Feed) SetDescription(s string) {
	f.Channel.Description = s
}

// SetLanguage sets feed language, default is set to en-us.
func (f *Feed) SetLanguage(l string) {
	f.Channel.Language = l
}

// // SetLastBuildDate sets feed last build date.
// func (f *Feed) setLastBuildDate(d time.Time) {
// }

// AddArticle to feed. Md5 checksum of URL will be used as GUID.
func (f *Feed) AddArticle(a Article) error {
	return f.addArticle(a, "")
}

// AddArticleWithGUID to feed.
func (f *Feed) AddArticleWithGUID(a Article, guid string) error {
	return f.addArticle(a, guid)
}

func (f *Feed) addArticle(a Article, guid string) error {

	b, err := xml.Marshal(a)
	if err != nil {
		return err
	}

	if guid == "" {
		guid = fmt.Sprintf("%x", md5.Sum([]byte(a.Head.Link.Href)))
	}

	var buff bytes.Buffer
	buff.WriteString("\n<content:encoded><![CDATA[\n")
	buff.Write(b)
	buff.WriteString("\n]]></content:encoded>")

	i := item{
		Title:       a.Body.Article.Header.H1,
		Description: a.Body.Article.Header.H2,
		Link:        a.Head.Link.Href,
		GUID:        guid,
		Encoded:     buff.Bytes(),
	}

	// if no subtitle, set first para as description
	if i.Description == "" && a.Body.Article.Content != nil {
	loop:
		for _, ifc := range a.Body.Article.Content {
			switch ifc.(type) {
			case P:
				if ifc.(P).Text != "" {
					i.Description = string(ifc.(P).Text)
					break loop
				}
			}
		}
	}

	// set latest article date as pubDate
	for _, d := range a.Body.Article.Header.Time {
		if d.Datetime > i.PubDate {
			i.PubDate = d.Datetime
		}
	}

	// set latest article date to feed LastBuildDate
	if i.PubDate > f.Channel.LastBuildDate {
		f.Channel.LastBuildDate = i.PubDate
	}

	for _, auth := range a.Body.Article.Header.Address {
		i.Author = append(i.Author, auth.A.Text)
	}

	f.Channel.Item = append(f.Channel.Item, i)

	return nil
}

// MarshalXML for xml.Marshaler interface
func (f Feed) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	feed := struct {
		Version string  `xml:"version,attr"`
		Content string  `xml:"xmlns:content,attr"`
		Channel channel `xml:"channel"`
	}{
		Version: f.Version,
		Content: f.Content,
		Channel: f.Channel,
	}

	feed.Version = "2.0"
	feed.Content = "http://purl.org/rss/1.0/modules/content/"
	if feed.Channel.Language == "" {
		feed.Channel.Language = "en-us"
	}

	start.Name.Local = "rss" // rename root element from Article to html
	return e.EncodeElement(feed, start)
}

// RSS is synonym for xml.Marshal(f)
func (f Feed) RSS() ([]byte, error) {
	return xml.Marshal(f)
}
<|endoftext|>


<commit_before>package spvwallet

import (
	"encoding/json"
	"github.com/OpenBazaar/wallet-interface"
	"golang.org/x/net/proxy"
	"net"
	"net/http"
	"time"
)

type httpClient interface {
	Get(string) (*http.Response, error)
}

type feeCache struct {
	fees        *Fees
	lastUpdated time.Time
}

type Fees struct {
	Priority uint64 `json:"priority"`
	Normal   uint64 `json:"normal"`
	Economic uint64 `json:"economic"`
}

type FeeProvider struct {
	maxFee      uint64
	priorityFee uint64
	normalFee   uint64
	economicFee uint64
	feeAPI      string

	httpClient httpClient

	cache *feeCache
}

func NewFeeProvider(maxFee, priorityFee, normalFee, economicFee uint64, feeAPI string, proxy proxy.Dialer) *FeeProvider {
	fp := FeeProvider{
		maxFee:      maxFee,
		priorityFee: priorityFee,
		normalFee:   normalFee,
		economicFee: economicFee,
		feeAPI:      feeAPI,
		cache:       new(feeCache),
	}
	dial := net.Dial
	if proxy != nil {
		dial = proxy.Dial
	}
	tbTransport := &http.Transport{Dial: dial}
	httpClient := &http.Client{Transport: tbTransport, Timeout: time.Second * 10}
	fp.httpClient = httpClient
	return &fp
}

func (fp *FeeProvider) GetFeePerByte(feeLevel wallet.FeeLevel) uint64 {
	if fp.feeAPI == "" {
		return fp.defaultFee(feeLevel)
	}
	fees := new(Fees)
	if time.Since(fp.cache.lastUpdated) > time.Minute {
		resp, err := fp.httpClient.Get(fp.feeAPI)
		if err != nil {
			return fp.defaultFee(feeLevel)
		}

		defer resp.Body.Close()

		err = json.NewDecoder(resp.Body).Decode(&fees)
		if err != nil {
			return fp.defaultFee(feeLevel)
		}
		fp.cache.lastUpdated = time.Now()
		fp.cache.fees = fees
	} else {
		fees = fp.cache.fees
	}
	switch feeLevel {
	case wallet.PRIOIRTY:
		return fp.selectFee(fees.Priority, wallet.PRIOIRTY)
	case wallet.NORMAL:
		return fp.selectFee(fees.Normal, wallet.PRIOIRTY)
	case wallet.ECONOMIC:
		return fp.selectFee(fees.Economic, wallet.PRIOIRTY)
	case wallet.FEE_BUMP:
		return fp.selectFee(fees.Priority, wallet.PRIOIRTY)
	default:
		return fp.normalFee
	}
}

func (fp *FeeProvider) selectFee(fee uint64, feeLevel wallet.FeeLevel) uint64 {
	if fee > fp.maxFee {
		return fp.maxFee
	} else if fee == 0 {
		return fp.defaultFee(feeLevel)
	} else {
		return fee
	}
}

func(fp *FeeProvider) defaultFee(feeLevel wallet.FeeLevel) uint64 {
	switch feeLevel {
	case wallet.PRIOIRTY:
		return fp.priorityFee
	case wallet.NORMAL:
		return fp.normalFee
	case wallet.ECONOMIC:
		return fp.economicFee
	case wallet.FEE_BUMP:
		return fp.priorityFee
	default:
		return fp.normalFee
	}
}<commit_msg>Run gofmt<commit_after>package spvwallet

import (
	"encoding/json"
	"github.com/OpenBazaar/wallet-interface"
	"golang.org/x/net/proxy"
	"net"
	"net/http"
	"time"
)

type httpClient interface {
	Get(string) (*http.Response, error)
}

type feeCache struct {
	fees        *Fees
	lastUpdated time.Time
}

type Fees struct {
	Priority uint64 `json:"priority"`
	Normal   uint64 `json:"normal"`
	Economic uint64 `json:"economic"`
}

type FeeProvider struct {
	maxFee      uint64
	priorityFee uint64
	normalFee   uint64
	economicFee uint64
	feeAPI      string

	httpClient httpClient

	cache *feeCache
}

func NewFeeProvider(maxFee, priorityFee, normalFee, economicFee uint64, feeAPI string, proxy proxy.Dialer) *FeeProvider {
	fp := FeeProvider{
		maxFee:      maxFee,
		priorityFee: priorityFee,
		normalFee:   normalFee,
		economicFee: economicFee,
		feeAPI:      feeAPI,
		cache:       new(feeCache),
	}
	dial := net.Dial
	if proxy != nil {
		dial = proxy.Dial
	}
	tbTransport := &http.Transport{Dial: dial}
	httpClient := &http.Client{Transport: tbTransport, Timeout: time.Second * 10}
	fp.httpClient = httpClient
	return &fp
}

func (fp *FeeProvider) GetFeePerByte(feeLevel wallet.FeeLevel) uint64 {
	if fp.feeAPI == "" {
		return fp.defaultFee(feeLevel)
	}
	fees := new(Fees)
	if time.Since(fp.cache.lastUpdated) > time.Minute {
		resp, err := fp.httpClient.Get(fp.feeAPI)
		if err != nil {
			return fp.defaultFee(feeLevel)
		}

		defer resp.Body.Close()

		err = json.NewDecoder(resp.Body).Decode(&fees)
		if err != nil {
			return fp.defaultFee(feeLevel)
		}
		fp.cache.lastUpdated = time.Now()
		fp.cache.fees = fees
	} else {
		fees = fp.cache.fees
	}
	switch feeLevel {
	case wallet.PRIOIRTY:
		return fp.selectFee(fees.Priority, wallet.PRIOIRTY)
	case wallet.NORMAL:
		return fp.selectFee(fees.Normal, wallet.PRIOIRTY)
	case wallet.ECONOMIC:
		return fp.selectFee(fees.Economic, wallet.PRIOIRTY)
	case wallet.FEE_BUMP:
		return fp.selectFee(fees.Priority, wallet.PRIOIRTY)
	default:
		return fp.normalFee
	}
}

func (fp *FeeProvider) selectFee(fee uint64, feeLevel wallet.FeeLevel) uint64 {
	if fee > fp.maxFee {
		return fp.maxFee
	} else if fee == 0 {
		return fp.defaultFee(feeLevel)
	} else {
		return fee
	}
}

func (fp *FeeProvider) defaultFee(feeLevel wallet.FeeLevel) uint64 {
	switch feeLevel {
	case wallet.PRIOIRTY:
		return fp.priorityFee
	case wallet.NORMAL:
		return fp.normalFee
	case wallet.ECONOMIC:
		return fp.economicFee
	case wallet.FEE_BUMP:
		return fp.priorityFee
	default:
		return fp.normalFee
	}
}
<|endoftext|>


<commit_before>package dbox

import (
	"time"
)

var _ Object = (*File)(nil)
var _ Object = (*Bucket)(nil)

var (
	NameKey          = "NameKey"
	MapDataIDMetaKey = "MapDataID"
	RawDataIDMetaKey = "RawDataID"
	CreatedAtKey     = "CreatedAt"
	UpdatedAtKey     = "UpdatedAt"

	BucketKey                = "BucketKey"
	MapDataStoreNameKey      = "MapDataStoreNameKey"
	RawDataStoreNameKey      = "RawDataStoreNameKey"
	MetaDataFileStoreNameKey = "MetaDataFileStoreNameKey"
)

type EntityType string

var (
	FileEntityType   EntityType = "file"
	BucketEntityType EntityType = "bucket"
)

func NewBucket() *Bucket {

	return &Bucket{
		File: File{
			store:     BucketStore,
			MapObject: NewMapObject(BucketStore),
		},
	}
}

type Bucket struct {
	File
}

func (Bucket) Type() EntityType {
	return BucketEntityType
}

func (b Bucket) SetMapDataStoreName(v string) {
	mapSet(b.Meta(), MapDataStoreNameKey, v)
}

func (b Bucket) SetRawDataStoreName(v string) {
	mapSet(b.Meta(), RawDataStoreNameKey, v)
}

func (b Bucket) SetMetaDataStoreName(v string) {
	mapSet(b.Meta(), MetaDataFileStoreNameKey, v)
}

func (b Bucket) MapDataStoreName() string {
	return mapString(b.Meta(), MapDataStoreNameKey)
}

func (b Bucket) RawDataStoreName() string {
	return mapString(b.Meta(), RawDataStoreNameKey)
}

func (b Bucket) MetaDataStoreName() string {
	return mapString(b.Meta(), MetaDataFileStoreNameKey)
}

func NewFile(store Store) *File {

	return &File{
		store:     store,
		MapObject: NewMapObject(store),
	}
}

type File struct {
	*MapObject

	mdata *MapObject
	rdata *RawObject

	store Store

	mapDataStore Store
	rawDataStore Store

	invalid       bool
	reasoninvalid error
	isnew         bool
}

func (f *File) SetMapDataStore(s Store) {
	f.mapDataStore = s
}

func (f File) mdataStore() Store {
	if f.mapDataStore != nil {
		return f.mapDataStore
	}

	return f.store
}

func (f *File) mdataObj() *MapObject {
	if f.mdata == nil {
		var err error

		f.mdata = NewMapObject(f.mdataStore())

		if len(f.mapDataID()) != 0 {
			err = f.mdataStore().Get(f.mapDataID(), f.mdata)
		}

		if err == ErrNotFound || len(f.mapDataID()) == 0 {
			// f.mdata.Sync()
			f.mdata.setNewIDIfNew()
			f.setMapDataID(f.mdata.ID())
			// f.setNewIDIfNew()
			// f.syncOnlyMeta() // update file props
		} else if err != nil {
			// handler error
			f.invalid = true
			f.reasoninvalid = err

			// TODO: How to address the error?
		}
	}

	return f.mdata
}

func (f *File) SetRawDataStore(s Store) {
	f.rawDataStore = s
}

func (f File) rdataStore() Store {
	if f.rawDataStore != nil {
		return f.rawDataStore
	}

	return f.store
}

func (f *File) rdataObj() Object {
	if f.rdata == nil {
		var err error

		f.rdata = NewRawObject(f.rdataStore())

		if len(f.rawDataID()) != 0 {
			err = f.rdataStore().Get(f.rawDataID(), f.rdata)
		}

		if err == ErrNotFound || len(f.rawDataID()) == 0 {
			// f.rdata.Sync()
			f.rdata.setNewIDIfNew()
			f.setRawDataID(f.rdata.ID())
			// f.setNewIDIfNew()
			// f.syncOnlyMeta() // update file props
		} else if err != nil {
			// handler error
			f.invalid = true
			f.reasoninvalid = err

			// TODO: How to address the error?
		}
	}

	return f.rdata
}

func (f File) String() string {
	return f.Name()
}

func (File) Type() EntityType {
	return FileEntityType
}

func (f File) Bucket() string {
	return mapString(f.Meta(), BucketKey)
}

func (f File) SetBucket(v string) {
	mapSet(f.Meta(), BucketKey, v)
}

func (f File) Name() string {

	return mapString(f.Meta(), NameKey)
}

func (f File) SetName(v string) {
	mapSet(f.Meta(), NameKey, v)
}

func (f File) UpdatedAt() time.Time {
	return time.Unix(mapInt64(f.Meta(), UpdatedAtKey), 0)
}

func (f File) CreatedAt() time.Time {
	return time.Unix(mapInt64(f.Meta(), CreatedAtKey), 0)
}

// Meta meta data file
func (f *File) Meta() map[string]interface{} {

	return f.MapObject.Map()
}

// MapData struct data file
func (f *File) MapData() map[string]interface{} {

	return f.mdataObj().Map()
}

// RawData raw data file
func (f *File) RawData() Object {

	return f.rdataObj()
}

func (f *File) Delete() error {
	if f.invalid {
		return f.reasoninvalid
	}

	if f.IsNew() {
		return ErrEmptyID
	}

	if len(f.Name()) == 0 {
		return ErrEmptyName
	}

	if err := f.mdataStore().Delete(f.mdataObj()); err != nil {
		return err
	}

	if err := f.rdataStore().Delete(f.rdataObj()); err != nil {
		return err
	}

	return f.store.Delete(f)
}

func (f *File) syncOnlyMeta() error {

	if f.IsNew() {
		f.setNewIDIfNew()
		f.BeforeCreate()
	}

	f.BeforeUpdate()

	return f.MapObject.Sync()
}

func (f *File) Sync() error {
	if f.invalid {
		return f.reasoninvalid
	}

	if err := f.syncOnlyMeta(); err != nil {
		return err
	}

	//

	if f.mdata != nil {
		if err := f.mdataObj().Sync(); err != nil {
			return err
		}
	}

	if f.rdata != nil {
		if err := f.rdataObj().Sync(); err != nil {
			return err
		}
	}

	return f.store.Save(f)
}

//----------
// helpfull
//---------

func (f *File) BeforeCreate() {
	mapSet(f.Meta(), CreatedAtKey, time.Now().Unix())
}

func (f *File) BeforeUpdate() {
	mapSet(f.Meta(), UpdatedAtKey, time.Now().Unix())
}

func (f File) mapDataID() string {
	return mapString(f.Meta(), MapDataIDMetaKey)
}

func (f File) setMapDataID(id string) {
	mapSet(f.Meta(), MapDataIDMetaKey, id)
}

func (f File) rawDataID() string {
	return mapString(f.Meta(), RawDataIDMetaKey)
}

func (f File) setRawDataID(id string) {
	mapSet(f.Meta(), RawDataIDMetaKey, id)
}

// --------

func NewFileID(id string, store Store) (file *File, err error) {
	file = NewFile(store)

	err = store.Get(id, file)

	if err == nil {
		// file.init()
	}

	return
}

// NewFileName return file by filename.
// In cases where file not exist, file name accepts values from arguments.
func NewFileName(name string, store Store) (file *File, err error) {
	file = NewFile(store)

	err = store.(FileStore).GetByName(name, file)

	if err == ErrNotFound {
		file.SetName(name)
	}

	return
}

// LoadOrNewFile return file by bucket name and filename.
// If not exist bucket, file accepts values nil, err accepts values ErrNotFoundBucket.
// If not exist file, file accepts values nil, err accepts values ErrNotFound.
// In cases where file not exist, file name and file bucket name accepts values from arguments.
func LoadOrNewFile(bucketName string, fileName string) (file *File, err error) {
	bucket, err := BucketByName(bucketName)
	if err != nil {

		if err == ErrNotFound {
			return nil, ErrNotFoundBucket
		}

		return
	}

	file, err = NewFileName(fileName, MustStore(bucket.MetaDataStoreName()))
	file.SetMapDataStore(MustStore(bucket.MapDataStoreName()))
	file.SetRawDataStore(MustStore(bucket.RawDataStoreName()))

	if err == ErrNotFound {
		file.SetName(fileName)
		file.SetBucket(bucketName)
	}

	return
}

// BucketByName return bucket from name
// if not exist file, file accepts values nil, err accepts values ErrNotFound
func BucketByName(name string) (file *Bucket, err error) {
	file = NewBucket()
	err = BucketStore.(FileStore).GetByName(name, file)

	return
}
<commit_msg>add helpful func<commit_after>package dbox

import (
	"time"
)

var _ Object = (*File)(nil)
var _ Object = (*Bucket)(nil)

var (
	NameKey          = "NameKey"
	MapDataIDMetaKey = "MapDataID"
	RawDataIDMetaKey = "RawDataID"
	CreatedAtKey     = "CreatedAt"
	UpdatedAtKey     = "UpdatedAt"

	BucketKey                = "BucketKey"
	MapDataStoreNameKey      = "MapDataStoreNameKey"
	RawDataStoreNameKey      = "RawDataStoreNameKey"
	MetaDataFileStoreNameKey = "MetaDataFileStoreNameKey"
)

type EntityType string

var (
	FileEntityType   EntityType = "file"
	BucketEntityType EntityType = "bucket"
)

func NewBucket() *Bucket {

	return &Bucket{
		File: File{
			store:     BucketStore,
			MapObject: NewMapObject(BucketStore),
		},
	}
}

type Bucket struct {
	File
}

func (Bucket) Type() EntityType {
	return BucketEntityType
}

func (b Bucket) SetMapDataStoreName(v string) {
	mapSet(b.Meta(), MapDataStoreNameKey, v)
}

func (b Bucket) SetRawDataStoreName(v string) {
	mapSet(b.Meta(), RawDataStoreNameKey, v)
}

func (b Bucket) SetMetaDataStoreName(v string) {
	mapSet(b.Meta(), MetaDataFileStoreNameKey, v)
}

func (b Bucket) MapDataStoreName() string {
	return mapString(b.Meta(), MapDataStoreNameKey)
}

func (b Bucket) RawDataStoreName() string {
	return mapString(b.Meta(), RawDataStoreNameKey)
}

func (b Bucket) MetaDataStoreName() string {
	return mapString(b.Meta(), MetaDataFileStoreNameKey)
}

func NewFile(store Store) *File {

	return &File{
		store:     store,
		MapObject: NewMapObject(store),
	}
}

type File struct {
	*MapObject

	mdata *MapObject
	rdata *RawObject

	store Store

	mapDataStore Store
	rawDataStore Store

	invalid       bool
	reasoninvalid error
	isnew         bool
}

func (f *File) SetMapDataStore(s Store) {
	f.mapDataStore = s
}

func (f File) mdataStore() Store {
	if f.mapDataStore != nil {
		return f.mapDataStore
	}

	return f.store
}

func (f *File) mdataObj() *MapObject {
	if f.mdata == nil {
		var err error

		f.mdata = NewMapObject(f.mdataStore())

		if len(f.mapDataID()) != 0 {
			err = f.mdataStore().Get(f.mapDataID(), f.mdata)
		}

		if err == ErrNotFound || len(f.mapDataID()) == 0 {
			// f.mdata.Sync()
			f.mdata.setNewIDIfNew()
			f.setMapDataID(f.mdata.ID())
			// f.setNewIDIfNew()
			// f.syncOnlyMeta() // update file props
		} else if err != nil {
			// handler error
			f.invalid = true
			f.reasoninvalid = err

			// TODO: How to address the error?
		}
	}

	return f.mdata
}

func (f *File) SetRawDataStore(s Store) {
	f.rawDataStore = s
}

func (f File) rdataStore() Store {
	if f.rawDataStore != nil {
		return f.rawDataStore
	}

	return f.store
}

func (f *File) rdataObj() Object {
	if f.rdata == nil {
		var err error

		f.rdata = NewRawObject(f.rdataStore())

		if len(f.rawDataID()) != 0 {
			err = f.rdataStore().Get(f.rawDataID(), f.rdata)
		}

		if err == ErrNotFound || len(f.rawDataID()) == 0 {
			// f.rdata.Sync()
			f.rdata.setNewIDIfNew()
			f.setRawDataID(f.rdata.ID())
			// f.setNewIDIfNew()
			// f.syncOnlyMeta() // update file props
		} else if err != nil {
			// handler error
			f.invalid = true
			f.reasoninvalid = err

			// TODO: How to address the error?
		}
	}

	return f.rdata
}

func (f File) String() string {
	return f.Name()
}

func (File) Type() EntityType {
	return FileEntityType
}

func (f File) Bucket() string {
	return mapString(f.Meta(), BucketKey)
}

func (f File) SetBucket(v string) {
	mapSet(f.Meta(), BucketKey, v)
}

func (f File) Name() string {

	return mapString(f.Meta(), NameKey)
}

func (f File) SetName(v string) {
	mapSet(f.Meta(), NameKey, v)
}

func (f File) UpdatedAt() time.Time {
	return time.Unix(mapInt64(f.Meta(), UpdatedAtKey), 0)
}

func (f File) CreatedAt() time.Time {
	return time.Unix(mapInt64(f.Meta(), CreatedAtKey), 0)
}

// Meta meta data file
func (f *File) Meta() map[string]interface{} {

	return f.MapObject.Map()
}

// MapData struct data file
func (f *File) MapData() map[string]interface{} {

	return f.mdataObj().Map()
}

// SetMapData set struct data file
func (f *File) SetMapData(v map[string]interface{}) {
	f.mdataObj().SetMap(v)
}

// RawData raw data file
func (f *File) RawData() Object {

	return f.rdataObj()
}

func (f *File) Delete() error {
	if f.invalid {
		return f.reasoninvalid
	}

	if f.IsNew() {
		return ErrEmptyID
	}

	if len(f.Name()) == 0 {
		return ErrEmptyName
	}

	if err := f.mdataStore().Delete(f.mdataObj()); err != nil {
		return err
	}

	if err := f.rdataStore().Delete(f.rdataObj()); err != nil {
		return err
	}

	return f.store.Delete(f)
}

func (f *File) syncOnlyMeta() error {

	if f.IsNew() {
		f.setNewIDIfNew()
		f.BeforeCreate()
	}

	f.BeforeUpdate()

	return f.MapObject.Sync()
}

func (f *File) Sync() error {
	if f.invalid {
		return f.reasoninvalid
	}

	if err := f.syncOnlyMeta(); err != nil {
		return err
	}

	//

	if f.mdata != nil {
		if err := f.mdataObj().Sync(); err != nil {
			return err
		}
	}

	if f.rdata != nil {
		if err := f.rdataObj().Sync(); err != nil {
			return err
		}
	}

	return f.store.Save(f)
}

//----------
// helpfull
//---------

func (f *File) BeforeCreate() {
	mapSet(f.Meta(), CreatedAtKey, time.Now().Unix())
}

func (f *File) BeforeUpdate() {
	mapSet(f.Meta(), UpdatedAtKey, time.Now().Unix())
}

func (f File) mapDataID() string {
	return mapString(f.Meta(), MapDataIDMetaKey)
}

func (f File) setMapDataID(id string) {
	mapSet(f.Meta(), MapDataIDMetaKey, id)
}

func (f File) rawDataID() string {
	return mapString(f.Meta(), RawDataIDMetaKey)
}

func (f File) setRawDataID(id string) {
	mapSet(f.Meta(), RawDataIDMetaKey, id)
}

// --------

func NewFileID(id string, store Store) (file *File, err error) {
	file = NewFile(store)

	err = store.Get(id, file)

	if err == nil {
		// file.init()
	}

	return
}

// NewFileName return file by filename.
// In cases where file not exist, file name accepts values from arguments.
func NewFileName(name string, store Store) (file *File, err error) {
	file = NewFile(store)

	err = store.(FileStore).GetByName(name, file)

	if err == ErrNotFound {
		file.SetName(name)
	}

	return
}

// LoadOrNewFile return file by bucket name and filename.
// If not exist bucket, file accepts values nil, err accepts values ErrNotFoundBucket.
// If not exist file, file accepts values nil, err accepts values ErrNotFound.
// In cases where file not exist, file name and file bucket name accepts values from arguments.
func LoadOrNewFile(bucketName string, fileName string) (file *File, err error) {
	bucket, err := BucketByName(bucketName)
	if err != nil {

		if err == ErrNotFound {
			return nil, ErrNotFoundBucket
		}

		return
	}

	file, err = NewFileName(fileName, MustStore(bucket.MetaDataStoreName()))
	file.SetMapDataStore(MustStore(bucket.MapDataStoreName()))
	file.SetRawDataStore(MustStore(bucket.RawDataStoreName()))

	if err == ErrNotFound {
		file.SetName(fileName)
		file.SetBucket(bucketName)
	}

	return
}

// BucketByName return bucket from name
// if not exist file, file accepts values nil, err accepts values ErrNotFound
func BucketByName(name string) (file *Bucket, err error) {
	file = NewBucket()
	err = BucketStore.(FileStore).GetByName(name, file)

	return
}
<|endoftext|>


<commit_before>// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 13/12/2010 by Laurent Le Goff

package draw2d

import (
	"io/ioutil"
	"log"
	"path"

	"code.google.com/p/freetype-go/freetype/truetype"
)

var (
	fontFolder = "../resource/font/"
	fonts      = make(map[string]*truetype.Font)
)

type FontStyle byte

const (
	FontStyleNormal FontStyle = iota
	FontStyleBold
	FontStyleItalic
)

type FontFamily byte

const (
	FontFamilySans FontFamily = iota
	FontFamilySerif
	FontFamilyMono
)

type FontData struct {
	Name   string
	Family FontFamily
	Style  FontStyle
}

func FontFileName(fontData FontData) string {
	fontFileName := fontData.Name
	switch fontData.Family {
	case FontFamilySans:
		fontFileName += "s"
	case FontFamilySerif:
		fontFileName += "r"
	case FontFamilyMono:
		fontFileName += "m"
	}
	if fontData.Style&FontStyleBold != 0 {
		fontFileName += "b"
	} else {
		fontFileName += "r"
	}

	if fontData.Style&FontStyleItalic != 0 {
		fontFileName += "i"
	}
	fontFileName += ".ttf"
	return fontFileName
}

func RegisterFont(fontData FontData, font *truetype.Font) {
	fonts[FontFileName(fontData)] = font
}

func GetFont(fontData FontData) *truetype.Font {
	fontFileName := FontFileName(fontData)
	font := fonts[fontFileName]
	if font != nil {
		return font
	}
	fonts[fontFileName] = loadFont(fontFileName)
	return fonts[fontFileName]
}

func GetFontFolder() string {
	return fontFolder
}

func SetFontFolder(folder string) {
	fontFolder = folder
}

func loadFont(fontFileName string) *truetype.Font {
	fontBytes, err := ioutil.ReadFile(path.Join(fontFolder, fontFileName))
	if err != nil {
		log.Println(err)
		return nil
	}
	font, err := truetype.Parse(fontBytes)
	if err != nil {
		log.Println(err)
		return nil
	}
	return font
}
<commit_msg>use clean path for font folder<commit_after>// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 13/12/2010 by Laurent Le Goff

package draw2d

import (
	"io/ioutil"
	"log"
	"path"
	"path/filepath"

	"code.google.com/p/freetype-go/freetype/truetype"
)

var (
	fontFolder = "../resource/font/"
	fonts      = make(map[string]*truetype.Font)
)

type FontStyle byte

const (
	FontStyleNormal FontStyle = iota
	FontStyleBold
	FontStyleItalic
)

type FontFamily byte

const (
	FontFamilySans FontFamily = iota
	FontFamilySerif
	FontFamilyMono
)

type FontData struct {
	Name   string
	Family FontFamily
	Style  FontStyle
}

func FontFileName(fontData FontData) string {
	fontFileName := fontData.Name
	switch fontData.Family {
	case FontFamilySans:
		fontFileName += "s"
	case FontFamilySerif:
		fontFileName += "r"
	case FontFamilyMono:
		fontFileName += "m"
	}
	if fontData.Style&FontStyleBold != 0 {
		fontFileName += "b"
	} else {
		fontFileName += "r"
	}

	if fontData.Style&FontStyleItalic != 0 {
		fontFileName += "i"
	}
	fontFileName += ".ttf"
	return fontFileName
}

func RegisterFont(fontData FontData, font *truetype.Font) {
	fonts[FontFileName(fontData)] = font
}

func GetFont(fontData FontData) *truetype.Font {
	fontFileName := FontFileName(fontData)
	font := fonts[fontFileName]
	if font != nil {
		return font
	}
	fonts[fontFileName] = loadFont(fontFileName)
	return fonts[fontFileName]
}

func GetFontFolder() string {
	return fontFolder
}

func SetFontFolder(folder string) {
	fontFolder = filepath.Clean(folder)
}

func loadFont(fontFileName string) *truetype.Font {
	fontBytes, err := ioutil.ReadFile(path.Join(fontFolder, fontFileName))
	if err != nil {
		log.Println(err)
		return nil
	}
	font, err := truetype.Parse(fontBytes)
	if err != nil {
		log.Println(err)
		return nil
	}
	return font
}
<|endoftext|>


<commit_before>package integration_test

import (
	"github.com/cloudfoundry/libbuildpack/cutlass"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("deploy a pushstate and reverse proxy app", func() {
	var app *cutlass.App
	AfterEach(func() {
		if app != nil {
			app.Destroy()
		}
		app = nil
	})

	BeforeEach(func() {
		app = cutlass.New(Fixtures("pushstate_and_proxy_pass"))
		PushAppAndConfirm(app)
	})

	It("", func() {
		By("enables pushstate", func() {
			Expect(app.GetBody("/")).To(ContainSubstring("This is the index file"))
			Expect(app.GetBody("/static.html")).To(ContainSubstring("This is a static file"))
			Expect(app.GetBody("/unknown")).To(ContainSubstring("This is the index file"))
		})

		By("proxies", func() {
			Expect(app.GetBody("/api")).To(ContainSubstring("This domain is established to be used for illustrative examples in documents"))
		})
	})
})
<commit_msg>Correct example.com text to be less change sensitive<commit_after>package integration_test

import (
	"github.com/cloudfoundry/libbuildpack/cutlass"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("deploy a pushstate and reverse proxy app", func() {
	var app *cutlass.App
	AfterEach(func() {
		if app != nil {
			app.Destroy()
		}
		app = nil
	})

	BeforeEach(func() {
		app = cutlass.New(Fixtures("pushstate_and_proxy_pass"))
		PushAppAndConfirm(app)
	})

	It("", func() {
		By("enables pushstate", func() {
			Expect(app.GetBody("/")).To(ContainSubstring("This is the index file"))
			Expect(app.GetBody("/static.html")).To(ContainSubstring("This is a static file"))
			Expect(app.GetBody("/unknown")).To(ContainSubstring("This is the index file"))
		})

		By("proxies", func() {
			Expect(app.GetBody("/api")).To(ContainSubstring("illustrative examples in documents"))
		})
	})
})
<|endoftext|>


<commit_before>package user

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

	"github.com/codegangsta/cli"
	"github.com/garlsecurity/securepassctl/spctl/service"
)

func init() {
	Command.Subcommands = append(Command.Subcommands,
		cli.Command{
			Name:        "disable",
			Usage:       "disable user",
			ArgsUsage:   "USERNAME",
			Description: "Disable a user from SecurePass.",
			Action:      ActionDisable,
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "yes, y",
					Usage: "Skip confirmation",
				},
			},
		})
}

// ActionDel provides the del subcommand
func ActionDisable(c *cli.Context) {
	if len(c.Args()) != 1 {
		log.Fatal("error: must specify a username")
	}

	username := c.Args()[0]

	if !c.Bool("yes") {
		var reply string
		fmt.Fprintf(os.Stderr, "Do you want to disable user %q? [y/N] ", username)
		fmt.Scanln(&reply)
		reply = strings.ToLower(reply)

		if reply != "y" && reply != "yes" {
			os.Exit(-1)
		}
	}

	if _, err := service.Service.UserDisable(username); err != nil {
		log.Fatalf("error: %v", err)
	}

	log.Printf("User %s deleted", username)

}
<commit_msg>fixed typo<commit_after>package user

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

	"github.com/codegangsta/cli"
	"github.com/garlsecurity/securepassctl/spctl/service"
)

func init() {
	Command.Subcommands = append(Command.Subcommands,
		cli.Command{
			Name:        "disable",
			Usage:       "disable user",
			ArgsUsage:   "USERNAME",
			Description: "Disable a user from SecurePass.",
			Action:      ActionDisable,
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "yes, y",
					Usage: "Skip confirmation",
				},
			},
		})
}

// ActionDel provides the del subcommand
func ActionDisable(c *cli.Context) {
	if len(c.Args()) != 1 {
		log.Fatal("error: must specify a username")
	}

	username := c.Args()[0]

	if !c.Bool("yes") {
		var reply string
		fmt.Fprintf(os.Stderr, "Do you want to disable user %q? [y/N] ", username)
		fmt.Scanln(&reply)
		reply = strings.ToLower(reply)

		if reply != "y" && reply != "yes" {
			os.Exit(-1)
		}
	}

	if _, err := service.Service.UserDisable(username); err != nil {
		log.Fatalf("error: %v", err)
	}

	log.Printf("User %s disabled", username)

}
<|endoftext|>


<commit_before>package data

import (
	"time"

	"gopkg.in/mgo.v2/bson"
)

type Project struct {
	ID         bson.ObjectId   `bson:"_id"`
	Name       string          `bson:"name"`
	OwnerId    bson.ObjectId   `bson:"owner_id"`
	MemberIds  []bson.ObjectId `bson:"member_ids"`
	CreatedAt  time.Time       `bson:"created_at"`
	ModifiedAt time.Time       `bson:"modified_at"`
}
<commit_msg>Implement GetProjectin Project<commit_after>package data

import (
	"time"

	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

type Project struct {
	ID         bson.ObjectId   `bson:"_id"`
	Name       string          `bson:"name"`
	OwnerId    bson.ObjectId   `bson:"owner_id"`
	MemberIds  []bson.ObjectId `bson:"member_ids"`
	CreatedAt  time.Time       `bson:"created_at"`
	ModifiedAt time.Time       `bson:"modified_at"`
}

func GetProject(id bson.ObjectId) (*Project, error) {
	pro := Project{}
	err := sess.DB("").C(projectC).FindId(id).One(&pro)
	if err == mgo.ErrNotFound {
		return nil, nil
	}
	if err != nil {
		return nil, err
	}
	return &pro, nil
}
<|endoftext|>


<commit_before>// Copyright Istio Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package util

import (
	"os"
	"strings"

	"github.com/ghodss/yaml"

	"istio.io/release-builder/pkg/model"

	"istio.io/pkg/log"
)

// RunMake runs a make command for the repo, with standard environment variables set
func RunMake(manifest model.Manifest, repo string, env []string, c ...string) error {
	cmd := VerboseCommand("make", c...)
	cmd.Env = os.Environ()
	cmd.Env = append(cmd.Env,
		"GOPATH="+manifest.WorkDir(),
		"TAG="+manifest.Version,
		"VERSION="+manifest.Version,
		"ISTIO_VERSION="+manifest.Version,
		"HUB="+manifest.Docker,
		"BUILD_WITH_CONTAINER=0", // Build should already run in container, having multiple layers of docker causes issues
	)
	cmd.Env = append(cmd.Env, env...)
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	cmd.Dir = manifest.RepoDir(repo)
	log.Infof("Running make %v with env=%v wd=%v", strings.Join(c, " "), strings.Join(env, " "), cmd.Dir)
	return cmd.Run()
}

// YamlLog logs a object as yaml
func YamlLog(prefix string, i interface{}) {
	manifestYaml, _ := yaml.Marshal(i)
	log.Infof("%s: %v", prefix, string(manifestYaml))
}
<commit_msg>Print the correct env variable (#77)<commit_after>// Copyright Istio Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package util

import (
	"os"
	"strings"

	"github.com/ghodss/yaml"

	"istio.io/release-builder/pkg/model"

	"istio.io/pkg/log"
)

// RunMake runs a make command for the repo, with standard environment variables set
func RunMake(manifest model.Manifest, repo string, env []string, c ...string) error {
	cmd := VerboseCommand("make", c...)
	cmd.Env = os.Environ()
	cmd.Env = append(cmd.Env,
		"GOPATH="+manifest.WorkDir(),
		"TAG="+manifest.Version,
		"VERSION="+manifest.Version,
		"ISTIO_VERSION="+manifest.Version,
		"HUB="+manifest.Docker,
		"BUILD_WITH_CONTAINER=0", // Build should already run in container, having multiple layers of docker causes issues
	)
	cmd.Env = append(cmd.Env, env...)
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	cmd.Dir = manifest.RepoDir(repo)
	log.Infof("Running make %v with env=%v wd=%v", strings.Join(c, " "), strings.Join(cmd.Env, " "), cmd.Dir)
	return cmd.Run()
}

// YamlLog logs a object as yaml
func YamlLog(prefix string, i interface{}) {
	manifestYaml, _ := yaml.Marshal(i)
	log.Infof("%s: %v", prefix, string(manifestYaml))
}
<|endoftext|>


<commit_before>/*
Copyright 2014 The Kubernetes Authors.

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

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

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

package version

// Base version information.
//
// This is the fallback data used when version information from git is not
// provided via go ldflags. It provides an approximation of the Kubernetes
// version for ad-hoc builds (e.g. `go build`) that cannot get the version
// information from git.
//
// If you are looking at these fields in the git tree, they look
// strange. They are modified on the fly by the build process. The
// in-tree values are dummy values used for "git archive", which also
// works for GitHub tar downloads.
//
// When releasing a new Kubernetes version, this file is updated by
// build-tools/mark_new_version.sh to reflect the new version, and then a
// git annotated tag (using format vX.Y where X == Major version and Y
// == Minor version) is created to point to the commit that updates
// pkg/version/base.go
var (
	// TODO: Deprecate gitMajor and gitMinor, use only gitVersion
	// instead. First step in deprecation, keep the fields but make
	// them irrelevant. (Next we'll take it out, which may muck with
	// scripts consuming the kubectl version output - but most of
	// these should be looking at gitVersion already anyways.)
	gitMajor string = "" // major version, always numeric
	gitMinor string = "" // minor version, numeric possibly followed by "+"

	// semantic version, derived by build scripts (see
	// https://github.com/kubernetes/kubernetes/blob/master/docs/design/versioning.md
	// for a detailed discussion of this field)
	//
	// TODO: This field is still called "gitVersion" for legacy
	// reasons. For prerelease versions, the build metadata on the
	// semantic version is a git hash, but the version itself is no
	// longer the direct output of "git describe", but a slight
	// translation to be semver compliant.
	gitVersion   string = "v0.0.0-master+$Format:%h$"
	gitCommit    string = "$Format:%H$"    // sha1 from git, output of $(git rev-parse HEAD)
	gitTreeState string = "not a git tree" // state of git tree, either "clean" or "dirty"

	buildDate string = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')
)
<commit_msg>published by bot (https://github.com/kubernetes/contrib/tree/master/mungegithub)<commit_after>/*
Copyright 2014 The Kubernetes Authors.

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

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

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

package version

// Base version information.
//
// This is the fallback data used when version information from git is not
// provided via go ldflags. It provides an approximation of the Kubernetes
// version for ad-hoc builds (e.g. `go build`) that cannot get the version
// information from git.
//
// If you are looking at these fields in the git tree, they look
// strange. They are modified on the fly by the build process. The
// in-tree values are dummy values used for "git archive", which also
// works for GitHub tar downloads.
//
// When releasing a new Kubernetes version, this file is updated by
// build/mark_new_version.sh to reflect the new version, and then a
// git annotated tag (using format vX.Y where X == Major version and Y
// == Minor version) is created to point to the commit that updates
// pkg/version/base.go
var (
	// TODO: Deprecate gitMajor and gitMinor, use only gitVersion
	// instead. First step in deprecation, keep the fields but make
	// them irrelevant. (Next we'll take it out, which may muck with
	// scripts consuming the kubectl version output - but most of
	// these should be looking at gitVersion already anyways.)
	gitMajor string = "" // major version, always numeric
	gitMinor string = "" // minor version, numeric possibly followed by "+"

	// semantic version, derived by build scripts (see
	// https://github.com/kubernetes/kubernetes/blob/master/docs/design/versioning.md
	// for a detailed discussion of this field)
	//
	// TODO: This field is still called "gitVersion" for legacy
	// reasons. For prerelease versions, the build metadata on the
	// semantic version is a git hash, but the version itself is no
	// longer the direct output of "git describe", but a slight
	// translation to be semver compliant.
	gitVersion   string = "v0.0.0-master+$Format:%h$"
	gitCommit    string = "$Format:%H$"    // sha1 from git, output of $(git rev-parse HEAD)
	gitTreeState string = "not a git tree" // state of git tree, either "clean" or "dirty"

	buildDate string = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')
)
<|endoftext|>