<commit_before>package main_test

import (
	"fmt"
	"os/exec"
	"strings"
	"time"

	receptorrunner "github.com/cloudfoundry-incubator/receptor/cmd/receptor/testrunner"
	Bbs "github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
	"github.com/cloudfoundry/gunk/diegonats"
	"github.com/cloudfoundry/gunk/timeprovider"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/pivotal-golang/lager/lagertest"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/ginkgomon"
)

var _ = Describe("Syncing desired state with CC", func() {
	var (
		gnatsdProcess ifrit.Process
		natsClient    diegonats.NATSClient
		bbs           *Bbs.BBS

		receptorProcess ifrit.Process

		runner  ifrit.Runner
		process ifrit.Process
	)

	startNATS := func() {
		gnatsdProcess, natsClient = diegonats.StartGnatsd(natsPort)
	}

	stopNATS := func() {
		ginkgomon.Kill(gnatsdProcess)
	}

	startReceptor := func() ifrit.Process {
		return ginkgomon.Invoke(receptorrunner.New(receptorPath, receptorrunner.Args{
			Address:                  fmt.Sprintf("127.0.0.1:%d", receptorPort),
			EtcdCluster:              strings.Join(etcdRunner.NodeURLS(), ","),
			InitialHeartbeatInterval: 1 * time.Second,
		}))
	}

	newNSyncRunner := func() *ginkgomon.Runner {
		return ginkgomon.New(ginkgomon.Config{
			Name:          "nsync",
			AnsiColorCode: "97m",
			StartCheck:    "nsync.listener.started",
			Command: exec.Command(
				listenerPath,
				"-etcdCluster", strings.Join(etcdRunner.NodeURLS(), ","),
				"-diegoAPIURL", fmt.Sprintf("http://127.0.0.1:%d", receptorPort),
				"-natsAddresses", fmt.Sprintf("127.0.0.1:%d", natsPort),
				"-circuses", `{"some-stack": "some-health-check.tar.gz"}`,
				"-dockerCircusPath", "the/docker/circus/path.tgz",
				"-fileServerURL", "http://file-server.com",
				"-heartbeatInterval", "1s",
				"-logLevel", "debug",
			),
		})
	}

	BeforeEach(func() {
		bbs = Bbs.NewBBS(etcdRunner.Adapter(), timeprovider.NewTimeProvider(), lagertest.NewTestLogger("test"))
		receptorProcess = startReceptor()
		runner = newNSyncRunner()
	})

	AfterEach(func() {
		ginkgomon.Interrupt(receptorProcess)
	})

	var publishDesireWithInstances = func(nInstances int) {
		err := natsClient.Publish("diego.desire.app", []byte(fmt.Sprintf(`
      {
        "process_guid": "the-guid",
        "droplet_uri": "http://the-droplet.uri.com",
        "start_command": "the-start-command",
        "memory_mb": 128,
        "disk_mb": 512,
        "file_descriptors": 32,
        "num_instances": %d,
        "stack": "some-stack",
        "log_guid": "the-log-guid"
      }
    `, nInstances)))
		Ω(err).ShouldNot(HaveOccurred())
	}

	var createRunningInstance = func(processGuid, instanceGuid string, index int) {
		err := bbs.ReportActualLRPAsRunning(models.ActualLRP{
			ProcessGuid:  processGuid,
			InstanceGuid: instanceGuid,
			Domain:       "domain",
			Index:        index,
		}, "cell-0")
		Ω(err).ShouldNot(HaveOccurred())
	}

	var publishKillIndex = func(processGuid string, index int) {
		err := natsClient.Publish("diego.stop.index", []byte(fmt.Sprintf(`
      {
        "process_guid": "%s",
        "index": %d
      }
    `, processGuid, index)))
		Ω(err).ShouldNot(HaveOccurred())
	}

	Context("when NATS is up", func() {
		BeforeEach(func() {
			startNATS()
		})

		AfterEach(func() {
			stopNATS()
		})

		Context("and the nsync listener is started", func() {
			BeforeEach(func() {
				process = ginkgomon.Invoke(runner)
			})

			AfterEach(func() {
				ginkgomon.Interrupt(process)
			})

			Describe("and a 'diego.desire.app' message is recieved", func() {
				BeforeEach(func() {
					publishDesireWithInstances(3)
				})

				It("registers an app desire in etcd", func() {
					Eventually(bbs.DesiredLRPs, 10).Should(HaveLen(1))
				})

				Context("when an app is no longer desired", func() {
					BeforeEach(func() {
						Eventually(bbs.DesiredLRPs).Should(HaveLen(1))

						publishDesireWithInstances(0)
					})

					It("should remove the desired state from etcd", func() {
						Eventually(bbs.DesiredLRPs).Should(HaveLen(0))
					})
				})
			})

			Describe("and message to stop a particular index is recieved", func() {
				var processGuid = "process-guid"

				BeforeEach(func() {
					createRunningInstance(processGuid, "instance-0", 0)
					createRunningInstance(processGuid, "instance-1", 1)
					createRunningInstance(processGuid, "instance-2", 1)
					publishKillIndex(processGuid, 1)
				})

				It("requests instances at the correct index are stopped", func() {
					Eventually(bbs.StopLRPInstances).Should(HaveLen(2))

					Ω(bbs.StopLRPInstances()).Should(ConsistOf(
						models.StopLRPInstance{
							ProcessGuid:  processGuid,
							InstanceGuid: "instance-1",
							Index:        1,
						},
						models.StopLRPInstance{
							ProcessGuid:  processGuid,
							InstanceGuid: "instance-2",
							Index:        1,
						},
					))
				})
			})

			Context("and a second nsync listener is started", func() {
				var (
					desiredLRPChanges <-chan models.DesiredLRPChange
					stopWatching      chan<- bool

					secondRunner  *ginkgomon.Runner
					secondProcess ifrit.Process
				)

				BeforeEach(func() {
					secondRunner = newNSyncRunner()
					secondRunner.StartCheck = ""

					secondProcess = ginkgomon.Invoke(secondRunner)

					changes, stop, _ := bbs.WatchForDesiredLRPChanges()

					desiredLRPChanges = changes
					stopWatching = stop
				})

				AfterEach(func() {
					close(stopWatching)
					ginkgomon.Interrupt(secondProcess)
				})

				Describe("the second listener", func() {
					It("does not become active", func() {
						Consistently(secondRunner.Buffer, 5*time.Second).ShouldNot(gbytes.Say("nsync.listener.started"))
					})
				})

				Context("and the first listener goes away", func() {
					BeforeEach(func() {
						ginkgomon.Interrupt(process)
					})

					Describe("the second listener", func() {
						It("eventually becomes active", func() {
							Eventually(secondRunner.Buffer, 5*time.Second).Should(gbytes.Say("nsync.listener.started"))
						})
					})
				})

				Context("and a 'diego.desire.app' message is received", func() {
					BeforeEach(func() {
						publishDesireWithInstances(3)
					})

					It("does not emit duplicate events", func() {
						Eventually(desiredLRPChanges).Should(Receive())
						Consistently(desiredLRPChanges).ShouldNot(Receive())
					})
				})
			})
		})
	})

	Describe("when NATS is not up", func() {
		Context("and the nsync listener is started", func() {

			BeforeEach(func() {
				process = ifrit.Background(runner)
			})

			AfterEach(func() {
				defer stopNATS()
				defer ginkgomon.Interrupt(process)
			})

			It("starts only after nats comes up", func() {
				Consistently(process.Ready()).ShouldNot(BeClosed())

				startNATS()
				Eventually(process.Ready(), 5*time.Second).Should(BeClosed())
			})
		})
	})
})
<commit_msg>remove integration test covered by inigo<commit_after>package main_test

import (
	"fmt"
	"os/exec"
	"strings"
	"time"

	receptorrunner "github.com/cloudfoundry-incubator/receptor/cmd/receptor/testrunner"
	Bbs "github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
	"github.com/cloudfoundry/gunk/diegonats"
	"github.com/cloudfoundry/gunk/timeprovider"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/pivotal-golang/lager/lagertest"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/ginkgomon"
)

var _ = Describe("Syncing desired state with CC", func() {
	var (
		gnatsdProcess ifrit.Process
		natsClient    diegonats.NATSClient
		bbs           *Bbs.BBS

		receptorProcess ifrit.Process

		runner  ifrit.Runner
		process ifrit.Process
	)

	startNATS := func() {
		gnatsdProcess, natsClient = diegonats.StartGnatsd(natsPort)
	}

	stopNATS := func() {
		ginkgomon.Kill(gnatsdProcess)
	}

	startReceptor := func() ifrit.Process {
		return ginkgomon.Invoke(receptorrunner.New(receptorPath, receptorrunner.Args{
			Address:                  fmt.Sprintf("127.0.0.1:%d", receptorPort),
			EtcdCluster:              strings.Join(etcdRunner.NodeURLS(), ","),
			InitialHeartbeatInterval: 1 * time.Second,
		}))
	}

	newNSyncRunner := func() *ginkgomon.Runner {
		return ginkgomon.New(ginkgomon.Config{
			Name:          "nsync",
			AnsiColorCode: "97m",
			StartCheck:    "nsync.listener.started",
			Command: exec.Command(
				listenerPath,
				"-etcdCluster", strings.Join(etcdRunner.NodeURLS(), ","),
				"-diegoAPIURL", fmt.Sprintf("http://127.0.0.1:%d", receptorPort),
				"-natsAddresses", fmt.Sprintf("127.0.0.1:%d", natsPort),
				"-circuses", `{"some-stack": "some-health-check.tar.gz"}`,
				"-dockerCircusPath", "the/docker/circus/path.tgz",
				"-fileServerURL", "http://file-server.com",
				"-heartbeatInterval", "1s",
				"-logLevel", "debug",
			),
		})
	}

	BeforeEach(func() {
		bbs = Bbs.NewBBS(etcdRunner.Adapter(), timeprovider.NewTimeProvider(), lagertest.NewTestLogger("test"))
		receptorProcess = startReceptor()
		runner = newNSyncRunner()
	})

	AfterEach(func() {
		ginkgomon.Interrupt(receptorProcess)
	})

	var publishDesireWithInstances = func(nInstances int) {
		err := natsClient.Publish("diego.desire.app", []byte(fmt.Sprintf(`
      {
        "process_guid": "the-guid",
        "droplet_uri": "http://the-droplet.uri.com",
        "start_command": "the-start-command",
        "memory_mb": 128,
        "disk_mb": 512,
        "file_descriptors": 32,
        "num_instances": %d,
        "stack": "some-stack",
        "log_guid": "the-log-guid"
      }
    `, nInstances)))
		Ω(err).ShouldNot(HaveOccurred())
	}

	Context("when NATS is up", func() {
		BeforeEach(func() {
			startNATS()
		})

		AfterEach(func() {
			stopNATS()
		})

		Context("and the nsync listener is started", func() {
			BeforeEach(func() {
				process = ginkgomon.Invoke(runner)
			})

			AfterEach(func() {
				ginkgomon.Interrupt(process)
			})

			Describe("and a 'diego.desire.app' message is recieved", func() {
				BeforeEach(func() {
					publishDesireWithInstances(3)
				})

				It("registers an app desire in etcd", func() {
					Eventually(bbs.DesiredLRPs, 10).Should(HaveLen(1))
				})

				Context("when an app is no longer desired", func() {
					BeforeEach(func() {
						Eventually(bbs.DesiredLRPs).Should(HaveLen(1))

						publishDesireWithInstances(0)
					})

					It("should remove the desired state from etcd", func() {
						Eventually(bbs.DesiredLRPs).Should(HaveLen(0))
					})
				})
			})

			Context("and a second nsync listener is started", func() {
				var (
					desiredLRPChanges <-chan models.DesiredLRPChange
					stopWatching      chan<- bool

					secondRunner  *ginkgomon.Runner
					secondProcess ifrit.Process
				)

				BeforeEach(func() {
					secondRunner = newNSyncRunner()
					secondRunner.StartCheck = ""

					secondProcess = ginkgomon.Invoke(secondRunner)

					changes, stop, _ := bbs.WatchForDesiredLRPChanges()

					desiredLRPChanges = changes
					stopWatching = stop
				})

				AfterEach(func() {
					close(stopWatching)
					ginkgomon.Interrupt(secondProcess)
				})

				Describe("the second listener", func() {
					It("does not become active", func() {
						Consistently(secondRunner.Buffer, 5*time.Second).ShouldNot(gbytes.Say("nsync.listener.started"))
					})
				})

				Context("and the first listener goes away", func() {
					BeforeEach(func() {
						ginkgomon.Interrupt(process)
					})

					Describe("the second listener", func() {
						It("eventually becomes active", func() {
							Eventually(secondRunner.Buffer, 5*time.Second).Should(gbytes.Say("nsync.listener.started"))
						})
					})
				})

				Context("and a 'diego.desire.app' message is received", func() {
					BeforeEach(func() {
						publishDesireWithInstances(3)
					})

					It("does not emit duplicate events", func() {
						Eventually(desiredLRPChanges).Should(Receive())
						Consistently(desiredLRPChanges).ShouldNot(Receive())
					})
				})
			})
		})
	})

	Describe("when NATS is not up", func() {
		Context("and the nsync listener is started", func() {

			BeforeEach(func() {
				process = ifrit.Background(runner)
			})

			AfterEach(func() {
				defer stopNATS()
				defer ginkgomon.Interrupt(process)
			})

			It("starts only after nats comes up", func() {
				Consistently(process.Ready()).ShouldNot(BeClosed())

				startNATS()
				Eventually(process.Ready(), 5*time.Second).Should(BeClosed())
			})
		})
	})
})
<|endoftext|>


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

// This binary fetches all repos of a user or organization and clones
// them.  It is strongly recommended to get a personal API token from
// https://github.com/settings/tokens, save the token in a file, and
// point the --token option to it.
package main

import (
	"flag"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/google/go-github/github"
	"golang.org/x/oauth2"
)

func main() {
	dest := flag.String("dest", "", "destination directory")
	org := flag.String("org", "", "organization to mirror")
	user := flag.String("user", "", "user to mirror")
	token := flag.String("token",
		filepath.Join(os.Getenv("HOME"), ".github-token"),
		"file holding API token.")
	forks := flag.Bool("forks", false, "also mirror forks.")
	namePattern := flag.String("name", "", "only clone repos whose name matches the given regexp.")
	flag.Parse()

	if *dest == "" {
		log.Fatal("must set --dest")
	}
	if *org == "" && *user == "" {
		log.Fatal("must set --org or --user")
	}
	destDir := filepath.Join(*dest, "github.com")
	if err := os.MkdirAll(destDir, 0755); err != nil {
		log.Fatal(err)
	}

	client := github.NewClient(nil)
	if *token != "" {
		content, err := ioutil.ReadFile(*token)
		if err != nil {
			log.Fatal(err)
		}

		ts := oauth2.StaticTokenSource(
			&oauth2.Token{
				AccessToken: strings.TrimSpace(string(content)),
			})
		tc := oauth2.NewClient(oauth2.NoContext, ts)
		client = github.NewClient(tc)
	}

	var repos []github.Repository
	var err error
	if *org != "" {
		repos, err = getOrgRepos(client, *org)
	} else if *user != "" {
		repos, err = getUserRepos(client, *user)
	}
	if err != nil {
		log.Fatal(err)
	}

	if !*forks {
		trimmed := repos[:0]
		for _, r := range repos {
			if r.Fork == nil || !*r.Fork {
				trimmed = append(trimmed, r)
			}
		}
		repos = trimmed
	}

	if *namePattern != "" {
		re, err := regexp.Compile(*namePattern)
		if err != nil {
			log.Fatal(err)
		}
		trimmed := repos[:0]
		for _, r := range repos {
			if r.Name != nil && re.FindString(*r.Name) != "" {
				trimmed = append(trimmed, r)
			}
		}
		repos = trimmed
	}

	if err := cloneRepos(destDir, repos); err != nil {
		log.Fatal(err)
	}
}

func getOrgRepos(client *github.Client, org string) ([]github.Repository, error) {
	var allRepos []github.Repository
	opt := &github.RepositoryListByOrgOptions{}
	for {
		repos, resp, err := client.Repositories.ListByOrg(org, opt)
		if err != nil {
			return nil, err
		}
		if len(repos) == 0 {
			break
		}
		var names []string
		for _, r := range repos {
			names = append(names, *r.Name)
		}
		log.Println(strings.Join(names, " "))

		opt.Page = resp.NextPage
		allRepos = append(allRepos, repos...)
		if resp.NextPage == 0 {
			break
		}
	}
	return allRepos, nil
}

func getUserRepos(client *github.Client, user string) ([]github.Repository, error) {
	var allRepos []github.Repository
	opt := &github.RepositoryListOptions{}
	for {
		repos, resp, err := client.Repositories.List(user, opt)
		if err != nil {
			return nil, err
		}
		if len(repos) == 0 {
			break
		}

		var names []string
		for _, r := range repos {
			names = append(names, *r.Name)
		}
		log.Println(strings.Join(names, " "))

		opt.Page = resp.NextPage
		allRepos = append(allRepos, repos...)
		if resp.NextPage == 0 {
			break
		}
	}
	return allRepos, nil
}

func cloneRepos(destDir string, repos []github.Repository) error {
	for _, r := range repos {
		parent := filepath.Join(destDir, filepath.Dir(*r.FullName))
		if err := os.MkdirAll(parent, 0755); err != nil {
			return err
		}

		base := *r.Name + ".git"
		if _, err := os.Lstat(filepath.Join(parent, base)); err == nil {
			continue
		}

		cmd := exec.Command("git", "clone", "--mirror", "--recursive", *r.CloneURL, base)
		cmd.Dir = parent
		log.Println("running:", cmd.Args)
		if err := cmd.Run(); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>cmd/zoekt-mirror-github: fix build<commit_after>// Copyright 2016 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.

// This binary fetches all repos of a user or organization and clones
// them.  It is strongly recommended to get a personal API token from
// https://github.com/settings/tokens, save the token in a file, and
// point the --token option to it.
package main

import (
	"flag"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/google/go-github/github"
	"golang.org/x/oauth2"
)

func main() {
	dest := flag.String("dest", "", "destination directory")
	org := flag.String("org", "", "organization to mirror")
	user := flag.String("user", "", "user to mirror")
	token := flag.String("token",
		filepath.Join(os.Getenv("HOME"), ".github-token"),
		"file holding API token.")
	forks := flag.Bool("forks", false, "also mirror forks.")
	namePattern := flag.String("name", "", "only clone repos whose name matches the given regexp.")
	flag.Parse()

	if *dest == "" {
		log.Fatal("must set --dest")
	}
	if *org == "" && *user == "" {
		log.Fatal("must set --org or --user")
	}
	destDir := filepath.Join(*dest, "github.com")
	if err := os.MkdirAll(destDir, 0755); err != nil {
		log.Fatal(err)
	}

	client := github.NewClient(nil)
	if *token != "" {
		content, err := ioutil.ReadFile(*token)
		if err != nil {
			log.Fatal(err)
		}

		ts := oauth2.StaticTokenSource(
			&oauth2.Token{
				AccessToken: strings.TrimSpace(string(content)),
			})
		tc := oauth2.NewClient(oauth2.NoContext, ts)
		client = github.NewClient(tc)
	}

	var repos []*github.Repository
	var err error
	if *org != "" {
		repos, err = getOrgRepos(client, *org)
	} else if *user != "" {
		repos, err = getUserRepos(client, *user)
	}
	if err != nil {
		log.Fatal(err)
	}

	if !*forks {
		trimmed := repos[:0]
		for _, r := range repos {
			if r.Fork == nil || !*r.Fork {
				trimmed = append(trimmed, r)
			}
		}
		repos = trimmed
	}

	if *namePattern != "" {
		re, err := regexp.Compile(*namePattern)
		if err != nil {
			log.Fatal(err)
		}
		trimmed := repos[:0]
		for _, r := range repos {
			if r.Name != nil && re.FindString(*r.Name) != "" {
				trimmed = append(trimmed, r)
			}
		}
		repos = trimmed
	}

	if err := cloneRepos(destDir, repos); err != nil {
		log.Fatal(err)
	}
}

func getOrgRepos(client *github.Client, org string) ([]*github.Repository, error) {
	var allRepos []*github.Repository
	opt := &github.RepositoryListByOrgOptions{}
	for {
		repos, resp, err := client.Repositories.ListByOrg(org, opt)
		if err != nil {
			return nil, err
		}
		if len(repos) == 0 {
			break
		}
		var names []string
		for _, r := range repos {
			names = append(names, *r.Name)
		}
		log.Println(strings.Join(names, " "))

		opt.Page = resp.NextPage
		allRepos = append(allRepos, repos...)
		if resp.NextPage == 0 {
			break
		}
	}
	return allRepos, nil
}

func getUserRepos(client *github.Client, user string) ([]*github.Repository, error) {
	var allRepos []*github.Repository
	opt := &github.RepositoryListOptions{}
	for {
		repos, resp, err := client.Repositories.List(user, opt)
		if err != nil {
			return nil, err
		}
		if len(repos) == 0 {
			break
		}

		var names []string
		for _, r := range repos {
			names = append(names, *r.Name)
		}
		log.Println(strings.Join(names, " "))

		opt.Page = resp.NextPage
		allRepos = append(allRepos, repos...)
		if resp.NextPage == 0 {
			break
		}
	}
	return allRepos, nil
}

func cloneRepos(destDir string, repos []*github.Repository) error {
	for _, r := range repos {
		parent := filepath.Join(destDir, filepath.Dir(*r.FullName))
		if err := os.MkdirAll(parent, 0755); err != nil {
			return err
		}

		base := *r.Name + ".git"
		if _, err := os.Lstat(filepath.Join(parent, base)); err == nil {
			continue
		}

		cmd := exec.Command("git", "clone", "--mirror", "--recursive", *r.CloneURL, base)
		cmd.Dir = parent
		log.Println("running:", cmd.Args)
		if err := cmd.Run(); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package api

// Cluster represents high-level information about a LXD cluster.
type Cluster struct {
	ServerName string `json:"server_name" yaml:"server_name"`
	Enabled    bool   `json:"enabled" yaml:"enabled"`
}

// ClusterPut represents the fields required to bootstrap or join a LXD
// cluster.
//
// API extension: cluster
type ClusterPut struct {
	Cluster        `yaml:",inline"`
	ClusterAddress string `json:"cluster_address" yaml:"cluster_address"`
	ClusterCert    string `json:"cluster_cert" yaml:"cluster_cert"`
}

// ClusterMemberPost represents the fields required to rename a LXD node.
//
// API extension: clustering
type ClusterMemberPost struct {
	ServerName string `json:"server_name" yaml:"server_name"`
}

// ClusterMember represents the a LXD node in the cluster.
//
// API extension: clustering
type ClusterMember struct {
	ServerName string `json:"server_name" yaml:"server_name"`
	URL        string `json:"url" yaml:"url"`
	Database   bool   `json:"database" yaml:"database"`
	Status     string `json:"status" yaml:"status"`
	Message    string `json:"message" yaml:"message"`
}
<commit_msg>api: Fixed clustering API extension headers<commit_after>package api

// Cluster represents high-level information about a LXD cluster.
//
// API extension: clustering
type Cluster struct {
	ServerName string `json:"server_name" yaml:"server_name"`
	Enabled    bool   `json:"enabled" yaml:"enabled"`
}

// ClusterPut represents the fields required to bootstrap or join a LXD
// cluster.
//
// API extension: clustering
type ClusterPut struct {
	Cluster        `yaml:",inline"`
	ClusterAddress string `json:"cluster_address" yaml:"cluster_address"`
	ClusterCert    string `json:"cluster_cert" yaml:"cluster_cert"`
}

// ClusterMemberPost represents the fields required to rename a LXD node.
//
// API extension: clustering
type ClusterMemberPost struct {
	ServerName string `json:"server_name" yaml:"server_name"`
}

// ClusterMember represents the a LXD node in the cluster.
//
// API extension: clustering
type ClusterMember struct {
	ServerName string `json:"server_name" yaml:"server_name"`
	URL        string `json:"url" yaml:"url"`
	Database   bool   `json:"database" yaml:"database"`
	Status     string `json:"status" yaml:"status"`
	Message    string `json:"message" yaml:"message"`
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"strconv"
	"time"
)

var commands = map[string]struct {
	nargs  int
	f      func(url string, args []string)
	argstr string
}{
	"upload":  {-1, uploadCommand, "/src/dir /dest/dir"},
	"ls":      {0, lsCommand, "[path]"},
	"rm":      {0, rmCommand, "path"},
	"getconf": {0, getConfCommand, ""},
	"setconf": {2, setConfCommand, "prop value"},
	"info":    {0, infoCommand, ""},
	"fsck":    {0, fsckCommand, ""},
	"backup":  {-1, backupCommand, "filename"},
	"restore": {-1, restoreCommand, "filename"},
	"induce":  {1, induceCommand, "taskname"},
}

func init() {
	log.SetFlags(log.Lmicroseconds)

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr,
			"Usage:\n  %s http://cbfs:8484/ cmd [-opts] cmdargs\n",
			os.Args[0])

		fmt.Fprintf(os.Stderr, "\nCommands:\n")

		for k, v := range commands {
			fmt.Fprintf(os.Stderr, "  %s %s\n", k, v.argstr)
		}

		fmt.Fprintf(os.Stderr, "\n---- Subcommand Options ----\n")

		fmt.Fprintf(os.Stderr, "\nls:\n")
		lsFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nrm:\n")
		rmFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nupload:\n")
		uploadFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nfsck:\n")
		fsckFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nbackup <filename>:\n")
		backupFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nrestore <filename>:\n")
		restoreFlags.PrintDefaults()
		os.Exit(1)
	}

}

func relativeUrl(u, path string) string {
	du, err := url.Parse(u)
	if err != nil {
		log.Fatalf("Error parsing url: %v", err)
	}

	du.Path = path
	if du.Path[0] != '/' {
		du.Path = "/" + du.Path
	}

	return du.String()
}

func parseDuration(s string) time.Duration {
	d, err := time.ParseDuration(s)
	if err != nil {
		log.Fatalf("Unable to parse duration: %v", err)
	}
	return d
}

func parseInt(s string) int {
	i, err := strconv.Atoi(s)
	if err != nil {
		log.Fatalf("Error parsing int: %v", err)
	}
	return i
}

func main() {
	flag.Parse()

	if flag.NArg() < 2 {
		flag.Usage()
	}

	u := flag.Arg(0)

	cmdName := flag.Arg(1)
	cmd, ok := commands[cmdName]
	if !ok {
		fmt.Fprintf(os.Stderr, "Unknown command: %v\n", cmdName)
		flag.Usage()
	}
	if cmd.nargs == 0 {
	} else if cmd.nargs < 0 {
		reqargs := -cmd.nargs
		if flag.NArg()-2 < reqargs {
			fmt.Fprintf(os.Stderr, "Incorrect arguments for %v\n", cmdName)
			flag.Usage()
		}
	} else {
		if flag.NArg()-2 != cmd.nargs {
			fmt.Fprintf(os.Stderr, "Incorrect arguments for %v\n", cmdName)
			flag.Usage()
		}
	}

	cmd.f(u, flag.Args()[2:])
}
<commit_msg>Display info help.<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"strconv"
	"time"
)

var commands = map[string]struct {
	nargs  int
	f      func(url string, args []string)
	argstr string
}{
	"upload":  {-1, uploadCommand, "/src/dir /dest/dir"},
	"ls":      {0, lsCommand, "[path]"},
	"rm":      {0, rmCommand, "path"},
	"getconf": {0, getConfCommand, ""},
	"setconf": {2, setConfCommand, "prop value"},
	"info":    {0, infoCommand, ""},
	"fsck":    {0, fsckCommand, ""},
	"backup":  {-1, backupCommand, "filename"},
	"restore": {-1, restoreCommand, "filename"},
	"induce":  {1, induceCommand, "taskname"},
}

func init() {
	log.SetFlags(log.Lmicroseconds)

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr,
			"Usage:\n  %s http://cbfs:8484/ cmd [-opts] cmdargs\n",
			os.Args[0])

		fmt.Fprintf(os.Stderr, "\nCommands:\n")

		for k, v := range commands {
			fmt.Fprintf(os.Stderr, "  %s %s\n", k, v.argstr)
		}

		fmt.Fprintf(os.Stderr, "\n---- Subcommand Options ----\n")

		fmt.Fprintf(os.Stderr, "\nls:\n")
		lsFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nrm:\n")
		rmFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nupload:\n")
		uploadFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nfsck:\n")
		fsckFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\ninfo:\n")
		infoFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nbackup <filename>:\n")
		backupFlags.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nrestore <filename>:\n")
		restoreFlags.PrintDefaults()
		os.Exit(1)
	}

}

func relativeUrl(u, path string) string {
	du, err := url.Parse(u)
	if err != nil {
		log.Fatalf("Error parsing url: %v", err)
	}

	du.Path = path
	if du.Path[0] != '/' {
		du.Path = "/" + du.Path
	}

	return du.String()
}

func parseDuration(s string) time.Duration {
	d, err := time.ParseDuration(s)
	if err != nil {
		log.Fatalf("Unable to parse duration: %v", err)
	}
	return d
}

func parseInt(s string) int {
	i, err := strconv.Atoi(s)
	if err != nil {
		log.Fatalf("Error parsing int: %v", err)
	}
	return i
}

func main() {
	flag.Parse()

	if flag.NArg() < 2 {
		flag.Usage()
	}

	u := flag.Arg(0)

	cmdName := flag.Arg(1)
	cmd, ok := commands[cmdName]
	if !ok {
		fmt.Fprintf(os.Stderr, "Unknown command: %v\n", cmdName)
		flag.Usage()
	}
	if cmd.nargs == 0 {
	} else if cmd.nargs < 0 {
		reqargs := -cmd.nargs
		if flag.NArg()-2 < reqargs {
			fmt.Fprintf(os.Stderr, "Incorrect arguments for %v\n", cmdName)
			flag.Usage()
		}
	} else {
		if flag.NArg()-2 != cmd.nargs {
			fmt.Fprintf(os.Stderr, "Incorrect arguments for %v\n", cmdName)
			flag.Usage()
		}
	}

	cmd.f(u, flag.Args()[2:])
}
<|endoftext|>


<commit_before>package assert

// True panics if argument is false.
func True(x bool) {
	assertTrue(x)
}

// Nil panics if argument is not nil
func Nil(err error) {
	assertTrue(err != nil)
}

// Unreachable panics unconditionally.
func Unreachable() {
	panic("internal error: unreachable statement executed")
}

func assertTrue(cond bool) {
	if !cond {
		panic("internal error: assertion failed")
	}
}
<commit_msg>better error message in case of assert.Nil failure<commit_after>package assert

// True panics if argument is false.
func True(x bool) {
	assertTrue(x)
}

// Nil panics if argument is not nil
func Nil(err error) {
	if err != nil {
		panic("internal error: assertion failed (" + err.Error() + ")")
	}
}

// Unreachable panics unconditionally.
func Unreachable() {
	panic("internal error: unreachable statement executed")
}

func assertTrue(cond bool) {
	if !cond {
		panic("internal error: assertion failed")
	}
}
<|endoftext|>


<commit_before>package dierollerpkg

import (
	"fmt"
	"math/rand"
	"sort"
	"strings"
	"time"
)

type DieRoll struct {
	dice     int
	sides    int
	modifier DieModifier
	keep     int
	history  []DieRollResult
}

// constructor
func NewDieRoll(dice, sides int, modifier string, keep int) *DieRoll {
	return &DieRoll{
		dice:     dice,
		sides:    sides,
		modifier: *DieModifierParse(modifier),
		keep:     keep,
		history:  make([]DieRollResult, 0),
	}
}

// getters
func (dr *DieRoll) Dice() int {
	return dr.dice
}
func (dr *DieRoll) Sides() int {
	return dr.sides
}
func (dr *DieRoll) Modifier() DieModifier {
	return dr.modifier
}
func (dr *DieRoll) Keep() int {
	return dr.keep
}
func (dr *DieRoll) History() []DieRollResult {
	return dr.history
}

// Last result returned by die roller
func (dr *DieRoll) LastRoll() *DieRollResult {
	if len(dr.history) == 0 {
		return nil
	} else {
		return &dr.history[len(dr.history)-1]
	}
}

// Appender
func (dr *DieRoll) AddHistory(drr DieRollResult) {
	old := dr.History()
	temp := append(old, drr)
	dr.history = temp
}

// Roll a die
func (dr *DieRoll) Roll() DieRollResult {
	// generate the rolls
	rolls := make(DieRolls, dr.Dice())
	rand.Seed(time.Now().UnixNano())
	for i := range rolls {
		rolls[i] = rand.Intn(dr.Sides()) + 1
		rand.Seed(rand.Int63())
	}
	// sort them from highest to lowest
	// because Less for DieRolls is defined in reverse (>)
	sort.Sort(rolls)
	// sum the highest keep rolls
	sum := 0
	kept := rolls[0:dr.Keep()]
	for _, v := range kept {
		sum += v
	}
	// apply the modifier
	switch dr.Modifier().ModType {
	case DieModifierTypeAdd:
		sum += dr.Modifier().Amount
	case DieModifierTypeMultiply:
		sum *= dr.Modifier().Amount
	case DieModifierTypeSubtract:
		sum -= dr.Modifier().Amount
	}
	result := DieRollResult{sum, kept}
	dr.AddHistory(result)
	return result
}

// override normal convert to string method
func (dr *DieRoll) String() string {
	return fmt.Sprintf("dice: %d sides: %d mod: %v keep: %d history: (%s)", dr.Dice(), dr.Sides(), dr.Modifier(), dr.Keep(), dr.HistoryAsString())
}

// output as standardized string
func (dr *DieRoll) standardstring(verbose bool) string {
	d := fmt.Sprintf("%dD%d", dr.Dice(), dr.Sides())
	k := fmt.Sprintf("K%d", dr.Keep())
	if dr.Keep() == dr.Dice() {
		k = ""
	}
	m := fmt.Sprintf("%v", dr.Modifier())
	r := ""
	if verbose && dr.LastRoll() != nil {
		r = fmt.Sprintf(" (%s)", dr.LastRoll().Rolls)
	}
	return strings.Trim(fmt.Sprintf("%s%s%s%s", d, k, m, r), "")
}

func (dr *DieRoll) StandardString() string {
	return dr.standardstring(false)
}

func (dr *DieRoll) StandardStringVerbose() string {
	return dr.standardstring(true)
}

// convert history slice to a string
func (dr *DieRoll) HistoryAsString() string {
	s := make([]string, len(dr.history))
	for i, v := range dr.history {
		// convert to string and wrap with braces
		s[i] = fmt.Sprintf("{%s}", v)
	}
	return fmt.Sprintf("%d entries: %s", len(s), strings.Join(s, ","))
}
<commit_msg>Corrected seeding problem...<commit_after>package dierollerpkg

import (
	"fmt"
	"math/rand"
	"sort"
	"strings"
	"time"
)

type DieRoll struct {
	dice     int
	sides    int
	modifier DieModifier
	keep     int
	history  []DieRollResult
}

// constructor
func NewDieRoll(dice, sides int, modifier string, keep int) *DieRoll {
	rand.Seed(time.Now().UnixNano())
	return &DieRoll{
		dice:     dice,
		sides:    sides,
		modifier: *DieModifierParse(modifier),
		keep:     keep,
		history:  make([]DieRollResult, 0),
	}
}

// getters
func (dr *DieRoll) Dice() int {
	return dr.dice
}
func (dr *DieRoll) Sides() int {
	return dr.sides
}
func (dr *DieRoll) Modifier() DieModifier {
	return dr.modifier
}
func (dr *DieRoll) Keep() int {
	return dr.keep
}
func (dr *DieRoll) History() []DieRollResult {
	return dr.history
}

// Last result returned by die roller
func (dr *DieRoll) LastRoll() *DieRollResult {
	if len(dr.history) == 0 {
		return nil
	} else {
		return &dr.history[len(dr.history)-1]
	}
}

// Appender
func (dr *DieRoll) AddHistory(drr DieRollResult) {
	old := dr.History()
	temp := append(old, drr)
	dr.history = temp
}

// Roll a die
func (dr *DieRoll) Roll() DieRollResult {
	// generate the rolls
	rolls := make(DieRolls, dr.Dice())
	for i := range rolls {
		rolls[i] = rand.Intn(dr.Sides()) + 1
		rand.Seed(rand.Int63())
	}
	// sort them from highest to lowest
	// because Less for DieRolls is defined in reverse (>)
	sort.Sort(rolls)
	// sum the highest keep rolls
	sum := 0
	kept := rolls[0:dr.Keep()]
	for _, v := range kept {
		sum += v
	}
	// apply the modifier
	switch dr.Modifier().ModType {
	case DieModifierTypeAdd:
		sum += dr.Modifier().Amount
	case DieModifierTypeMultiply:
		sum *= dr.Modifier().Amount
	case DieModifierTypeSubtract:
		sum -= dr.Modifier().Amount
	}
	result := DieRollResult{sum, kept}
	dr.AddHistory(result)
	return result
}

// override normal convert to string method
func (dr *DieRoll) String() string {
	return fmt.Sprintf("dice: %d sides: %d mod: %v keep: %d history: (%s)", dr.Dice(), dr.Sides(), dr.Modifier(), dr.Keep(), dr.HistoryAsString())
}

// output as standardized string
func (dr *DieRoll) standardstring(verbose bool) string {
	d := fmt.Sprintf("%dD%d", dr.Dice(), dr.Sides())
	k := fmt.Sprintf("K%d", dr.Keep())
	if dr.Keep() == dr.Dice() {
		k = ""
	}
	m := fmt.Sprintf("%v", dr.Modifier())
	r := ""
	if verbose && dr.LastRoll() != nil {
		r = fmt.Sprintf(" (%s)", dr.LastRoll().Rolls)
	}
	return strings.Trim(fmt.Sprintf("%s%s%s%s", d, k, m, r), "")
}

func (dr *DieRoll) StandardString() string {
	return dr.standardstring(false)
}

func (dr *DieRoll) StandardStringVerbose() string {
	return dr.standardstring(true)
}

// convert history slice to a string
func (dr *DieRoll) HistoryAsString() string {
	s := make([]string, len(dr.history))
	for i, v := range dr.history {
		// convert to string and wrap with braces
		s[i] = fmt.Sprintf("{%s}", v)
	}
	return fmt.Sprintf("%d entries: %s", len(s), strings.Join(s, ","))
}
<|endoftext|>


<commit_before>// Copyright © 2017 Aeneas Rekkas <aeneas+oss@aeneas.io>
//
// 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 jwk_test

import (
	"flag"
	"fmt"
	"log"
	"os"
	"testing"

	"github.com/ory/hydra/integration"
	. "github.com/ory/hydra/jwk"
)

var managers = map[string]Manager{
	"memory": new(MemoryManager),
}

var testGenerator = &RS256Generator{}

var encryptionKey, _ = RandomBytes(32)

func TestMain(m *testing.M) {
	flag.Parse()
	if !testing.Short() {
		connectToPG()
		connectToMySQL()
	}

	s := m.Run()
	integration.KillAll()
	os.Exit(s)
}

func connectToPG() {
	var db = integration.ConnectToPostgres()
	s := &SQLManager{DB: db, Cipher: &AEAD{Key: encryptionKey}}
	if _, err := s.CreateSchemas(); err != nil {
		log.Fatalf("Could not create postgres schema: %v", err)
	}

	managers["postgres"] = s
}

func connectToMySQL() {
	var db = integration.ConnectToMySQL()
	s := &SQLManager{DB: db, Cipher: &AEAD{Key: encryptionKey}}

	if _, err := s.CreateSchemas(); err != nil {
		log.Fatalf("Could not create postgres schema: %v", err)
	}

	managers["mysql"] = s
}

func TestManagerKey(t *testing.T) {
	ks, _ := testGenerator.Generate("TestManagerKey")

	for name, m := range managers {
		t.Run(fmt.Sprintf("case=%s", name), TestHelperManagerKey(m, ks, "TestManagerKey"))
	}
}

func TestManagerKeySet(t *testing.T) {
	ks, _ := testGenerator.Generate("TestManagerKeySet")
	ks.Key("private")

	for name, m := range managers {
		t.Run(fmt.Sprintf("case=%s", name), TestHelperManagerKeySet(m, ks, "TestManagerKeySet"))
	}
}
<commit_msg>jwk: Parallelizes database instantiation in tests<commit_after>// Copyright © 2017 Aeneas Rekkas <aeneas+oss@aeneas.io>
//
// 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 jwk_test

import (
	"flag"
	"fmt"
	"log"
	"os"
	"testing"

	"github.com/ory/hydra/integration"
	. "github.com/ory/hydra/jwk"
)

var managers = map[string]Manager{
	"memory": new(MemoryManager),
}

var testGenerator = &RS256Generator{}

var encryptionKey, _ = RandomBytes(32)

func TestMain(m *testing.M) {
	flag.Parse()
	if !testing.Short() {
		if !testing.Short() {
			integration.BootParallel([]func(){
				connectToPG,
				connectToMySQL,
			})
		}
	}

	s := m.Run()
	integration.KillAll()
	os.Exit(s)
}

func connectToPG() {
	var db = integration.ConnectToPostgres()
	s := &SQLManager{DB: db, Cipher: &AEAD{Key: encryptionKey}}
	if _, err := s.CreateSchemas(); err != nil {
		log.Fatalf("Could not create postgres schema: %v", err)
	}

	managers["postgres"] = s
}

func connectToMySQL() {
	var db = integration.ConnectToMySQL()
	s := &SQLManager{DB: db, Cipher: &AEAD{Key: encryptionKey}}

	if _, err := s.CreateSchemas(); err != nil {
		log.Fatalf("Could not create postgres schema: %v", err)
	}

	managers["mysql"] = s
}

func TestManagerKey(t *testing.T) {
	ks, _ := testGenerator.Generate("TestManagerKey")

	for name, m := range managers {
		t.Run(fmt.Sprintf("case=%s", name), TestHelperManagerKey(m, ks, "TestManagerKey"))
	}
}

func TestManagerKeySet(t *testing.T) {
	ks, _ := testGenerator.Generate("TestManagerKeySet")
	ks.Key("private")

	for name, m := range managers {
		t.Run(fmt.Sprintf("case=%s", name), TestHelperManagerKeySet(m, ks, "TestManagerKeySet"))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"os/exec"
	"syscall"
	"time"
)

type SimpleDynoDriver struct {
}

func (dd *SimpleDynoDriver) Build(release *Release) error {
	return nil
}

func (dd *SimpleDynoDriver) Start(ex *Executor) error {
	ex.cmd = exec.Command(ex.args[0], ex.args[1:]...)

	ex.cmd.Stdin = os.Stdin
	ex.cmd.Stdout = os.Stdout
	ex.cmd.Stderr = os.Stderr

	// Fill environment vector from Heroku configuration.
	for k, v := range ex.release.config {
		ex.cmd.Env = append(ex.cmd.Env, k+"="+v)
	}

	ex.cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}

	err := ex.cmd.Start()
	if err != nil {
		return err
	}

	ex.waiting = make(chan struct{})
	return nil
}

func (dd *SimpleDynoDriver) Wait(ex *Executor) (s *ExitStatus) {
	s = &ExitStatus{}
	if s.err = ex.cmd.Wait(); s.err != nil {
		if eErr, ok := s.err.(*exec.ExitError); ok {
			if status, ok := eErr.Sys().(syscall.WaitStatus); ok {
				s.code = status.ExitStatus()
			}
		}
	}

	ex.waiting <- struct{}{}
	return s
}

func (dd *SimpleDynoDriver) Stop(ex *Executor) error {
	p := ex.cmd.Process

	group, err := os.FindProcess(-1 * p.Pid)
	if err != nil {
		return err
	}

	// Begin graceful shutdown via SIGTERM.
	group.Signal(syscall.SIGTERM)

	for {
		select {
		case <-time.After(10 * time.Second):
			log.Println("sigkill", group)
			group.Signal(syscall.SIGKILL)
		case <-ex.waiting:
			log.Println("waited", group)
			return nil
		}
		log.Println("spin", group)
		time.Sleep(1)
	}
}
<commit_msg>Fix dyno driver "simple" for OneShot processes<commit_after>package main

import (
	"log"
	"os"
	"os/exec"
	"syscall"
	"time"
)

type SimpleDynoDriver struct {
}

func (dd *SimpleDynoDriver) Build(release *Release) error {
	return nil
}

func (dd *SimpleDynoDriver) Start(ex *Executor) error {
	ex.cmd = exec.Command(ex.args[0], ex.args[1:]...)

	ex.cmd.Stdin = os.Stdin
	ex.cmd.Stdout = os.Stdout
	ex.cmd.Stderr = os.Stderr

	// Fill environment vector from Heroku configuration.
	for k, v := range ex.release.config {
		ex.cmd.Env = append(ex.cmd.Env, k+"="+v)
	}

	ex.cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}

	err := ex.cmd.Start()
	if err != nil {
		return err
	}

	ex.waiting = make(chan struct{})
	return nil
}

func (dd *SimpleDynoDriver) Wait(ex *Executor) (s *ExitStatus) {
	s = &ExitStatus{}
	err := ex.cmd.Wait()
	if err != nil {
		if eErr, ok := err.(*exec.ExitError); ok {
			if status, ok := eErr.Sys().(syscall.WaitStatus); ok {
				s.code = status.ExitStatus()
			}
		} else {
			// Non ExitErrors are propagated: they are
			// liable to be errors in starting the
			// process.
			s.err = err
		}
	}

	go func() {
		ex.waiting <- struct{}{}
	}()

	return s
}

func (dd *SimpleDynoDriver) Stop(ex *Executor) error {
	p := ex.cmd.Process

	group, err := os.FindProcess(-1 * p.Pid)
	if err != nil {
		return err
	}

	// Begin graceful shutdown via SIGTERM.
	group.Signal(syscall.SIGTERM)

	for {
		select {
		case <-time.After(10 * time.Second):
			log.Println("sigkill", group)
			group.Signal(syscall.SIGKILL)
		case <-ex.waiting:
			log.Println("waited", group)
			return nil
		}
		log.Println("spin", group)
		time.Sleep(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"

	"github.com/segmentio/kafka-go"
)

func main() {
	address := "localhost:9092"
	conn, err := kafka.DialContext(context.Background(), "tcp", address)
	if err != nil {
		panic(err)
	}
	conn.Close()
	fmt.Printf("success to connect %s\n", address)

	topic := "ifaas-face"
	// make a new reader that consumes from topic-A
	r := kafka.NewReader(kafka.ReaderConfig{
		Brokers:  []string{address},
		GroupID:  "monitor",
		Topic:    topic,
		MinBytes: 10e3, // 10KB
		MaxBytes: 10e6, // 10MB
	})

	ctx := context.Background()
	for {
		m, err := r.FetchMessage(ctx)
		if err != nil {
			break
		}
		fmt.Printf("message at topic/partition/offset %v/%v/%v: %s = %s\n", m.Topic, m.Partition, m.Offset, string(m.Key), string(m.Value))
		r.CommitMessages(ctx, m)
	}

	r.Close()
}
<commit_msg>update data<commit_after>package main

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/segmentio/kafka-go"
)

type MonitorResponse struct {
	RespCode    int       `json:"respCode"`
	RespMessage string    `json:"respMessage"`
	RespRemark  string    `json:"respRemark"`
	Data        []Monitor `json:"data"`
	Type        string    `json:"type"`
	Time        string    `json:"time"`
	Operator    string    `json:"operator"`
	Operation   string    `json:"operation"`
}

type Monitor struct {
	faceURL       string `json:"faceUrl"`
	imageURL      string `json:"imageUrl"`
	sourceId      string `json:"sourceId"`
	imageId       string `json:"imageId"`
	tid           string `json:"tid"`
	faceId        string `json:"faceId"`
	snapTime      string `json:"snapTime"`
	alarmTime     string `json:"alarmTime"`
	personId      string `json:"personId"`
	blackDetailId string `json:"blackDetailId"`
	confidence    string `json:"confidence"`
}

/*
{
    "datas":[
        {
            "faceUrl":"/group1/M00/1D/AB/wKgLHVuvRIeAbJIYAAAR7EQwYfo184.jpg",
            "imageUrl":"/group1/M00/1D/AB/wKgLHVuvRIeAbJIYAAAR7EQwYfo185.jpg",
            "sourceId":"123",
            "imageId":"45678",
            "tid":"15123731804323888",
            "faceId":"1512373180432389",
            "snapTime":"2018-09-29 18:48:01",
            "alarmTime":"2018-09-29 18:48:01",
            "personId":"123",
            "blackDetailId":"1212121",
            "confidence":"0.82"
        }
    ],
    "operation":"insert",
    "operator":"ifass-engine",
    "retKeys":"tid",
    "time":"2018-09-29 18:48:01",
    "type":"alarm"
}
*/

func main() {
	address := "localhost:9092"
	conn, err := kafka.DialContext(context.Background(), "tcp", address)
	if err != nil {
		panic(err)
	}
	conn.Close()
	fmt.Printf("success to connect %s\n", address)

	topic := "ifaas-face"
	// make a new reader that consumes from topic-A
	r := kafka.NewReader(kafka.ReaderConfig{
		Brokers:  []string{address},
		GroupID:  "monitor",
		Topic:    topic,
		MinBytes: 10e3, // 10KB
		MaxBytes: 10e6, // 10MB
	})

	ctx := context.Background()
	for {
		m, err := r.FetchMessage(ctx)
		if err != nil {
			break
		}
		fmt.Printf("message at topic/partition/offset %v/%v/%v: %s = %s\n", m.Topic, m.Partition, m.Offset, string(m.Key), string(m.Value))

		var resp MonitorResponse
		if err := json.Unmarshal(m.Value, &resp); err != nil {
			panic(err)
		}
		fmt.Println("==>", resp)

		r.CommitMessages(ctx, m)
	}

	r.Close()
}
<|endoftext|>


<commit_before>package keys

import (
	"context"
	"fmt"
	"os"
	"testing"
	"time"

	"github.com/hyperledger/burrow/integration"

	"github.com/hyperledger/burrow/crypto"
	"github.com/hyperledger/burrow/crypto/sha3"
	"github.com/hyperledger/burrow/logging"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"google.golang.org/grpc"
)

type hashInfo struct {
	data     string
	expected string
}

var hashData = map[string]hashInfo{
	"sha256":    {"hi", "8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4"},
	"ripemd160": {"hi", "242485AB6BFD3502BCB3442EA2E211687B8E4D89"},
}

var (
	KEY_TYPES  = []string{"ed25519", "secp256k1"}
	HASH_TYPES = []string{"sha256", "ripemd160"}
)

func TestMain(m *testing.M) {
	failedCh := make(chan error)
	testDir, cleanup := integration.EnterTestDirectory()
	defer cleanup()
	// start the server
	go func() {
		failedCh <- StartStandAloneServer(testDir, DefaultHost, TestPort, false, logging.NewNoopLogger())
	}()
	ret := m.Run()
	select {
	case err := <-failedCh:
		if err != nil {
			panic(err)
		}
	default:
		os.Exit(ret)
	}
}

func grpcKeysClient() KeysClient {
	var opts []grpc.DialOption
	opts = append(opts, grpc.WithInsecure())
	conn, err := grpc.Dial(DefaultHost+":"+TestPort, opts...)
	if err != nil {
		fmt.Printf("Failed to connect to grpc server: %v\n", err)
		os.Exit(1)
	}
	return NewKeysClient(conn)
}

func testServerKeygenAndPub(t *testing.T, typ string) {
	c := grpcKeysClient()
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	genresp, err := c.GenerateKey(ctx, &GenRequest{CurveType: typ})
	require.NoError(t, err)

	addr := genresp.Address
	resp, err := c.PublicKey(ctx, &PubRequest{Address: addr})
	require.NoError(t, err)

	addrB, err := crypto.AddressFromHexString(addr)
	require.NoError(t, err)

	curveType, err := crypto.CurveTypeFromString(typ)
	require.NoError(t, err)

	publicKey, err := crypto.PublicKeyFromBytes(resp.GetPublicKey(), curveType)
	require.NoError(t, err)
	assert.Equal(t, addrB, publicKey.GetAddress())
}

func TestServerKeygenAndPub(t *testing.T) {
	for _, typ := range KEY_TYPES {
		testServerKeygenAndPub(t, typ)
	}
}

func testServerSignAndVerify(t *testing.T, typ string) {
	c := grpcKeysClient()
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	genresp, err := c.GenerateKey(ctx, &GenRequest{CurveType: typ})
	require.NoError(t, err)

	addr := genresp.Address
	resp, err := c.PublicKey(ctx, &PubRequest{Address: addr})
	require.NoError(t, err)

	hash := sha3.Sha3([]byte("the hash of something!"))

	sig, err := c.Sign(ctx, &SignRequest{Address: addr, Message: hash})
	require.NoError(t, err)

	_, err = c.Verify(ctx, &VerifyRequest{
		Signature: sig.GetSignature(),
		PublicKey: resp.GetPublicKey(),
		Message:   hash,
	})
	require.NoError(t, err)
}

func TestServerSignAndVerify(t *testing.T) {
	for _, typ := range KEY_TYPES {
		testServerSignAndVerify(t, typ)
	}
}

func testServerHash(t *testing.T, typ string) {
	hData := hashData[typ]
	data, expected := hData.data, hData.expected

	c := grpcKeysClient()
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	resp, err := c.Hash(ctx, &HashRequest{Hashtype: typ, Message: []byte(data)})
	require.NoError(t, err)

	require.Equal(t, expected, resp.GetHash())
}

func TestServerHash(t *testing.T) {
	for _, typ := range HASH_TYPES {
		testServerHash(t, typ)
	}
}
<commit_msg>Remove server_test<commit_after><|endoftext|>


<commit_before>package drivers

// S3Credentials represents the credentials to access a bucket.
type S3Credentials struct {
	AccessKey string `json:"access_key"`
	SecretKey string `json:"secret_key"`
}

// Bucket represents a storage bucket.
type Bucket struct {
	name       string
	pool       string
	poolConfig map[string]string
	config     map[string]string
	driver     Driver
}

// NewBucket instantiates a new Bucket struct.
func NewBucket(driver Driver, poolName string, bucketName string, bucketConfig map[string]string, poolConfig map[string]string) Bucket {
	return Bucket{
		name:       bucketName,
		pool:       poolName,
		poolConfig: poolConfig,
		config:     bucketConfig,
		driver:     driver,
	}
}

// Name returns volume's name.
func (b Bucket) Name() string {
	return b.name
}

// Pool returns the volume's pool name.
func (b Bucket) Pool() string {
	return b.pool
}

// Config returns the volume's (unexpanded) config.
func (b Bucket) Config() map[string]string {
	return b.config
}
<commit_msg>lxd/storage/drivers/bucket: Removes unused Bucket type<commit_after>package drivers

// S3Credentials represents the credentials to access a bucket.
type S3Credentials struct {
	AccessKey string `json:"access_key"`
	SecretKey string `json:"secret_key"`
}
<|endoftext|>


<commit_before>package storage

import (
	"io"
	"time"

	"github.com/lxc/lxd/lxd/backup"
	backupConfig "github.com/lxc/lxd/lxd/backup/config"
	"github.com/lxc/lxd/lxd/cluster/request"
	"github.com/lxc/lxd/lxd/instance"
	"github.com/lxc/lxd/lxd/migration"
	"github.com/lxc/lxd/lxd/operations"
	"github.com/lxc/lxd/lxd/revert"
	"github.com/lxc/lxd/lxd/storage/drivers"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/instancewriter"
)

// MountInfo represents info about the result of a mount operation.
type MountInfo struct {
	DiskPath string // The location of the block disk (if supported).
}

// Type represents a LXD storage pool type.
type Type interface {
	ValidateName(name string) error
	Validate(config map[string]string) error
}

// Pool represents a LXD storage pool.
type Pool interface {
	Type

	// Pool.
	ID() int64
	Name() string
	Driver() drivers.Driver
	Description() string
	Status() string
	LocalStatus() string
	ToAPI() api.StoragePool

	GetResources() (*api.ResourcesStoragePool, error)
	IsUsed() (bool, error)
	Delete(clientType request.ClientType, op *operations.Operation) error
	Update(clientType request.ClientType, newDesc string, newConfig map[string]string, op *operations.Operation) error

	Create(clientType request.ClientType, op *operations.Operation) error
	Mount() (bool, error)
	Unmount() (bool, error)

	ApplyPatch(name string) error

	GetVolume(volumeType drivers.VolumeType, contentType drivers.ContentType, name string, config map[string]string) drivers.Volume

	// Instances.
	CreateInstance(inst instance.Instance, op *operations.Operation) error
	CreateInstanceFromBackup(srcBackup backup.Info, srcData io.ReadSeeker, op *operations.Operation) (func(instance.Instance) error, revert.Hook, error)
	CreateInstanceFromCopy(inst instance.Instance, src instance.Instance, snapshots bool, allowInconsistent bool, op *operations.Operation) error
	CreateInstanceFromImage(inst instance.Instance, fingerprint string, op *operations.Operation) error
	CreateInstanceFromMigration(inst instance.Instance, conn io.ReadWriteCloser, args migration.VolumeTargetArgs, op *operations.Operation) error
	RenameInstance(inst instance.Instance, newName string, op *operations.Operation) error
	DeleteInstance(inst instance.Instance, op *operations.Operation) error
	UpdateInstance(inst instance.Instance, newDesc string, newConfig map[string]string, op *operations.Operation) error
	UpdateInstanceBackupFile(inst instance.Instance, op *operations.Operation) error
	GenerateInstanceBackupConfig(inst instance.Instance, snapshots bool, op *operations.Operation) (*backupConfig.Config, error)
	CheckInstanceBackupFileSnapshots(backupConf *backupConfig.Config, projectName string, deleteMissing bool, op *operations.Operation) ([]*api.InstanceSnapshot, error)
	ImportInstance(inst instance.Instance, poolVol *backupConfig.Config, op *operations.Operation) error

	MigrateInstance(inst instance.Instance, conn io.ReadWriteCloser, args *migration.VolumeSourceArgs, op *operations.Operation) error
	RefreshInstance(inst instance.Instance, src instance.Instance, srcSnapshots []instance.Instance, allowInconsistent bool, op *operations.Operation) error
	BackupInstance(inst instance.Instance, tarWriter *instancewriter.InstanceTarWriter, optimized bool, snapshots bool, op *operations.Operation) error

	GetInstanceUsage(inst instance.Instance) (int64, error)
	SetInstanceQuota(inst instance.Instance, size string, vmStateSize string, op *operations.Operation) error

	MountInstance(inst instance.Instance, op *operations.Operation) (*MountInfo, error)
	UnmountInstance(inst instance.Instance, op *operations.Operation) error

	// Instance snapshots.
	CreateInstanceSnapshot(inst instance.Instance, src instance.Instance, op *operations.Operation) error
	RenameInstanceSnapshot(inst instance.Instance, newName string, op *operations.Operation) error
	DeleteInstanceSnapshot(inst instance.Instance, op *operations.Operation) error
	RestoreInstanceSnapshot(inst instance.Instance, src instance.Instance, op *operations.Operation) error
	MountInstanceSnapshot(inst instance.Instance, op *operations.Operation) (*MountInfo, error)
	UnmountInstanceSnapshot(inst instance.Instance, op *operations.Operation) error
	UpdateInstanceSnapshot(inst instance.Instance, newDesc string, newConfig map[string]string, op *operations.Operation) error

	// Images.
	EnsureImage(fingerprint string, op *operations.Operation) error
	DeleteImage(fingerprint string, op *operations.Operation) error
	UpdateImage(fingerprint string, newDesc string, newConfig map[string]string, op *operations.Operation) error

	// Custom volumes.
	CreateCustomVolume(projectName string, volName string, desc string, config map[string]string, contentType drivers.ContentType, op *operations.Operation) error
	CreateCustomVolumeFromCopy(projectName string, srcProjectName string, volName, desc string, config map[string]string, srcPoolName, srcVolName string, snapshots bool, op *operations.Operation) error
	UpdateCustomVolume(projectName string, volName string, newDesc string, newConfig map[string]string, op *operations.Operation) error
	RenameCustomVolume(projectName string, volName string, newVolName string, op *operations.Operation) error
	DeleteCustomVolume(projectName string, volName string, op *operations.Operation) error
	GetCustomVolumeDisk(projectName string, volName string) (string, error)
	GetCustomVolumeUsage(projectName string, volName string) (int64, error)
	MountCustomVolume(projectName string, volName string, op *operations.Operation) error
	UnmountCustomVolume(projectName string, volName string, op *operations.Operation) (bool, error)
	ImportCustomVolume(projectName string, poolVol *backupConfig.Config, op *operations.Operation) error
	RefreshCustomVolume(projectName string, srcProjectName string, volName, desc string, config map[string]string, srcPoolName, srcVolName string, snapshots bool, op *operations.Operation) error
	GenerateCustomVolumeBackupConfig(projectName string, volName string, snapshots bool, op *operations.Operation) (*backupConfig.Config, error)

	// Custom volume snapshots.
	CreateCustomVolumeSnapshot(projectName string, volName string, newSnapshotName string, newExpiryDate time.Time, op *operations.Operation) error
	RenameCustomVolumeSnapshot(projectName string, volName string, newSnapshotName string, op *operations.Operation) error
	DeleteCustomVolumeSnapshot(projectName string, volName string, op *operations.Operation) error
	UpdateCustomVolumeSnapshot(projectName string, volName string, newDesc string, newConfig map[string]string, newExpiryDate time.Time, op *operations.Operation) error
	RestoreCustomVolume(projectName string, volName string, snapshotName string, op *operations.Operation) error

	// Custom volume migration.
	MigrationTypes(contentType drivers.ContentType, refresh bool) []migration.Type
	CreateCustomVolumeFromMigration(projectName string, conn io.ReadWriteCloser, args migration.VolumeTargetArgs, op *operations.Operation) error
	MigrateCustomVolume(projectName string, conn io.ReadWriteCloser, args *migration.VolumeSourceArgs, op *operations.Operation) error

	// Custom volume backups.
	BackupCustomVolume(projectName string, volName string, tarWriter *instancewriter.InstanceTarWriter, optimized bool, snapshots bool, op *operations.Operation) error
	CreateCustomVolumeFromBackup(srcBackup backup.Info, srcData io.ReadSeeker, op *operations.Operation) error

	// Storage volume recovery.
	ListUnknownVolumes(op *operations.Operation) (map[string][]*backupConfig.Config, error)
}
<commit_msg>lxd/storage/pool/interface: Add bucket management definitions<commit_after>package storage

import (
	"io"
	"time"

	"github.com/lxc/lxd/lxd/backup"
	backupConfig "github.com/lxc/lxd/lxd/backup/config"
	"github.com/lxc/lxd/lxd/cluster/request"
	"github.com/lxc/lxd/lxd/instance"
	"github.com/lxc/lxd/lxd/migration"
	"github.com/lxc/lxd/lxd/operations"
	"github.com/lxc/lxd/lxd/revert"
	"github.com/lxc/lxd/lxd/storage/drivers"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/instancewriter"
)

// MountInfo represents info about the result of a mount operation.
type MountInfo struct {
	DiskPath string // The location of the block disk (if supported).
}

// Type represents a LXD storage pool type.
type Type interface {
	ValidateName(name string) error
	Validate(config map[string]string) error
}

// Pool represents a LXD storage pool.
type Pool interface {
	Type

	// Pool.
	ID() int64
	Name() string
	Driver() drivers.Driver
	Description() string
	Status() string
	LocalStatus() string
	ToAPI() api.StoragePool

	GetResources() (*api.ResourcesStoragePool, error)
	IsUsed() (bool, error)
	Delete(clientType request.ClientType, op *operations.Operation) error
	Update(clientType request.ClientType, newDesc string, newConfig map[string]string, op *operations.Operation) error

	Create(clientType request.ClientType, op *operations.Operation) error
	Mount() (bool, error)
	Unmount() (bool, error)

	ApplyPatch(name string) error

	GetVolume(volumeType drivers.VolumeType, contentType drivers.ContentType, name string, config map[string]string) drivers.Volume

	// Instances.
	CreateInstance(inst instance.Instance, op *operations.Operation) error
	CreateInstanceFromBackup(srcBackup backup.Info, srcData io.ReadSeeker, op *operations.Operation) (func(instance.Instance) error, revert.Hook, error)
	CreateInstanceFromCopy(inst instance.Instance, src instance.Instance, snapshots bool, allowInconsistent bool, op *operations.Operation) error
	CreateInstanceFromImage(inst instance.Instance, fingerprint string, op *operations.Operation) error
	CreateInstanceFromMigration(inst instance.Instance, conn io.ReadWriteCloser, args migration.VolumeTargetArgs, op *operations.Operation) error
	RenameInstance(inst instance.Instance, newName string, op *operations.Operation) error
	DeleteInstance(inst instance.Instance, op *operations.Operation) error
	UpdateInstance(inst instance.Instance, newDesc string, newConfig map[string]string, op *operations.Operation) error
	UpdateInstanceBackupFile(inst instance.Instance, op *operations.Operation) error
	GenerateInstanceBackupConfig(inst instance.Instance, snapshots bool, op *operations.Operation) (*backupConfig.Config, error)
	CheckInstanceBackupFileSnapshots(backupConf *backupConfig.Config, projectName string, deleteMissing bool, op *operations.Operation) ([]*api.InstanceSnapshot, error)
	ImportInstance(inst instance.Instance, poolVol *backupConfig.Config, op *operations.Operation) error

	MigrateInstance(inst instance.Instance, conn io.ReadWriteCloser, args *migration.VolumeSourceArgs, op *operations.Operation) error
	RefreshInstance(inst instance.Instance, src instance.Instance, srcSnapshots []instance.Instance, allowInconsistent bool, op *operations.Operation) error
	BackupInstance(inst instance.Instance, tarWriter *instancewriter.InstanceTarWriter, optimized bool, snapshots bool, op *operations.Operation) error

	GetInstanceUsage(inst instance.Instance) (int64, error)
	SetInstanceQuota(inst instance.Instance, size string, vmStateSize string, op *operations.Operation) error

	MountInstance(inst instance.Instance, op *operations.Operation) (*MountInfo, error)
	UnmountInstance(inst instance.Instance, op *operations.Operation) error

	// Instance snapshots.
	CreateInstanceSnapshot(inst instance.Instance, src instance.Instance, op *operations.Operation) error
	RenameInstanceSnapshot(inst instance.Instance, newName string, op *operations.Operation) error
	DeleteInstanceSnapshot(inst instance.Instance, op *operations.Operation) error
	RestoreInstanceSnapshot(inst instance.Instance, src instance.Instance, op *operations.Operation) error
	MountInstanceSnapshot(inst instance.Instance, op *operations.Operation) (*MountInfo, error)
	UnmountInstanceSnapshot(inst instance.Instance, op *operations.Operation) error
	UpdateInstanceSnapshot(inst instance.Instance, newDesc string, newConfig map[string]string, op *operations.Operation) error

	// Images.
	EnsureImage(fingerprint string, op *operations.Operation) error
	DeleteImage(fingerprint string, op *operations.Operation) error
	UpdateImage(fingerprint string, newDesc string, newConfig map[string]string, op *operations.Operation) error

	// Buckets.
	CreateBucket(projectName string, bucket api.StorageBucketsPost, op *operations.Operation) error
	UpdateBucket(projectName string, bucketName string, bucket api.StorageBucketPut, op *operations.Operation) error
	DeleteBucket(projectName string, bucketName string, op *operations.Operation) error
	CreateBucketKey(projectName string, bucketName string, key api.StorageBucketKeysPost, op *operations.Operation) (*api.StorageBucketKey, error)
	UpdateBucketKey(projectName string, bucketName string, keyName string, key api.StorageBucketKeyPut, op *operations.Operation) error
	DeleteBucketKey(projectName string, bucketName string, keyName string, op *operations.Operation) error

	// Custom volumes.
	CreateCustomVolume(projectName string, volName string, desc string, config map[string]string, contentType drivers.ContentType, op *operations.Operation) error
	CreateCustomVolumeFromCopy(projectName string, srcProjectName string, volName, desc string, config map[string]string, srcPoolName, srcVolName string, snapshots bool, op *operations.Operation) error
	UpdateCustomVolume(projectName string, volName string, newDesc string, newConfig map[string]string, op *operations.Operation) error
	RenameCustomVolume(projectName string, volName string, newVolName string, op *operations.Operation) error
	DeleteCustomVolume(projectName string, volName string, op *operations.Operation) error
	GetCustomVolumeDisk(projectName string, volName string) (string, error)
	GetCustomVolumeUsage(projectName string, volName string) (int64, error)
	MountCustomVolume(projectName string, volName string, op *operations.Operation) error
	UnmountCustomVolume(projectName string, volName string, op *operations.Operation) (bool, error)
	ImportCustomVolume(projectName string, poolVol *backupConfig.Config, op *operations.Operation) error
	RefreshCustomVolume(projectName string, srcProjectName string, volName, desc string, config map[string]string, srcPoolName, srcVolName string, snapshots bool, op *operations.Operation) error
	GenerateCustomVolumeBackupConfig(projectName string, volName string, snapshots bool, op *operations.Operation) (*backupConfig.Config, error)

	// Custom volume snapshots.
	CreateCustomVolumeSnapshot(projectName string, volName string, newSnapshotName string, newExpiryDate time.Time, op *operations.Operation) error
	RenameCustomVolumeSnapshot(projectName string, volName string, newSnapshotName string, op *operations.Operation) error
	DeleteCustomVolumeSnapshot(projectName string, volName string, op *operations.Operation) error
	UpdateCustomVolumeSnapshot(projectName string, volName string, newDesc string, newConfig map[string]string, newExpiryDate time.Time, op *operations.Operation) error
	RestoreCustomVolume(projectName string, volName string, snapshotName string, op *operations.Operation) error

	// Custom volume migration.
	MigrationTypes(contentType drivers.ContentType, refresh bool) []migration.Type
	CreateCustomVolumeFromMigration(projectName string, conn io.ReadWriteCloser, args migration.VolumeTargetArgs, op *operations.Operation) error
	MigrateCustomVolume(projectName string, conn io.ReadWriteCloser, args *migration.VolumeSourceArgs, op *operations.Operation) error

	// Custom volume backups.
	BackupCustomVolume(projectName string, volName string, tarWriter *instancewriter.InstanceTarWriter, optimized bool, snapshots bool, op *operations.Operation) error
	CreateCustomVolumeFromBackup(srcBackup backup.Info, srcData io.ReadSeeker, op *operations.Operation) error

	// Storage volume recovery.
	ListUnknownVolumes(op *operations.Operation) (map[string][]*backupConfig.Config, error)
}
<|endoftext|>


<commit_before>package knsq

import (
	"bytes"
	"errors"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"

	"github.com/bitly/nsq/nsq"
)

type Client interface {
	// CreateTopic makes sure a topic exists on the given nsqd.
	CreateTopic(topic string) error
	// Send sends a message on a topic to the specified nsqd.
	Send(topic string, body io.Reader) error
}

// HttpClient implements the Client interface using HTTP requests.
type HttpClient struct {
	*url.URL
}

func (h HttpClient) CreateTopic(topic string) error {
	resp, err := http.Get(h.String() + "/create_topic?topic=" + topic)
	if resp != nil && resp.Body != nil {
		resp.Body.Close()
	}
	return err
}

func (h HttpClient) Send(topic string, body io.Reader) error {
	reqURL := h.String() + "/put?topic=" + topic
	log.Printf("Sending %s message to: %s", topic, reqURL)
	resp, err := http.DefaultClient.Post(reqURL, "application/json", body)
	if resp != nil && resp.Body != nil {
		defer resp.Body.Close()
	}
	return err
}

// TODO: Does this thing need to be thread-safe?
type rwcClient struct {
	io.ReadWriteCloser
	read   chan string
	write  chan *nsq.Command
	manage chan *manageRequest
}

// NewTCPClient creates an implementation of the Client interface
// using the TCP API of NSQd.
func NewTCPClient(addr string) (Client, error) {
	c, err := net.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}

	_, err = c.Write(nsq.MagicV2)
	client := &rwcClient{ReadWriteCloser: c, read: make(chan string), write: make(chan *nsq.Command), manage: make(chan *manageRequest)}

	go client.readLoop()
	go client.writeLoop()
	go client.manageLoop()

	return client, err
}

func (c *rwcClient) readLoop() {
	for {
		resp, err := nsq.ReadResponse(c)
		if err != nil {
			log.Printf("ReadResponse returned: %v", err)
			break
		}
		resp = resp[4:] // trim initial zero-bytes.
		if bytes.Equal(resp, []byte("_heartbeat_")) {
			c.write <- nsq.Nop()
			continue
		}
		c.read <- string(resp)
	}
}

func (c *rwcClient) writeLoop() {
	for {
		cmd := <-c.write
		cmd.Write(c)
	}
}

type manageRequest struct {
	Cmd      *nsq.Command
	Response chan string
}

func (c *rwcClient) manageLoop() {
	for {
		req := <-c.manage
		c.write <- req.Cmd
		req.Response <- <-c.read
	}
}

func (c *rwcClient) CreateTopic(topic string) error {
	// FIXME: This is awful. NSQd has no command to create a topic
	// except via the HTTP API. Needs patching.
	cmd := nsq.Publish(topic, []byte("dummymsg"))

	respchan := make(chan string)
	c.manage <- &manageRequest{Cmd: cmd, Response: respchan}
	resp := <-respchan

	if resp != "OK" {
		return errors.New(resp)
	}

	return nil
}

func (c *rwcClient) Send(topic string, body io.Reader) error {
	buf, err := ioutil.ReadAll(body)
	if err != nil {
		return err
	}
	cmd := nsq.Publish(topic, buf)
	respchan := make(chan string)
	c.manage <- &manageRequest{Cmd: cmd, Response: respchan}
	resp := <-respchan

	if resp != "OK" {
		return errors.New(resp)
	}

	return nil
}
<commit_msg>use nsq.UnpackResponse to unpack messages coming from nsqd.<commit_after>package knsq

import (
	"bytes"
	"errors"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"

	"github.com/bitly/nsq/nsq"
)

type Client interface {
	// CreateTopic makes sure a topic exists on the given nsqd.
	CreateTopic(topic string) error
	// Send sends a message on a topic to the specified nsqd.
	Send(topic string, body io.Reader) error
}

// HttpClient implements the Client interface using HTTP requests.
type HttpClient struct {
	*url.URL
}

func (h HttpClient) CreateTopic(topic string) error {
	resp, err := http.Get(h.String() + "/create_topic?topic=" + topic)
	if resp != nil && resp.Body != nil {
		resp.Body.Close()
	}
	return err
}

func (h HttpClient) Send(topic string, body io.Reader) error {
	reqURL := h.String() + "/put?topic=" + topic
	log.Printf("Sending %s message to: %s", topic, reqURL)
	resp, err := http.DefaultClient.Post(reqURL, "application/json", body)
	if resp != nil && resp.Body != nil {
		defer resp.Body.Close()
	}
	return err
}

// TODO: Does this thing need to be thread-safe?
type rwcClient struct {
	io.ReadWriteCloser
	read   chan string
	write  chan *nsq.Command
	manage chan *manageRequest
}

// NewTCPClient creates an implementation of the Client interface
// using the TCP API of NSQd.
func NewTCPClient(addr string) (Client, error) {
	c, err := net.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}

	_, err = c.Write(nsq.MagicV2)
	client := &rwcClient{ReadWriteCloser: c, read: make(chan string), write: make(chan *nsq.Command), manage: make(chan *manageRequest)}

	go client.readLoop()
	go client.writeLoop()
	go client.manageLoop()

	return client, err
}

func (c *rwcClient) readLoop() {
	for {
		resp, err := nsq.ReadResponse(c)
		if err != nil {
			log.Printf("ReadResponse returned: %v", err)
			break
		}
		_, resp, err = nsq.UnpackResponse(resp)
		if bytes.Equal(resp, []byte("_heartbeat_")) {
			c.write <- nsq.Nop()
			continue
		}
		c.read <- string(resp)
	}
}

func (c *rwcClient) writeLoop() {
	for {
		cmd := <-c.write
		cmd.Write(c)
	}
}

type manageRequest struct {
	Cmd      *nsq.Command
	Response chan string
}

func (c *rwcClient) manageLoop() {
	for {
		req := <-c.manage
		c.write <- req.Cmd
		req.Response <- <-c.read
	}
}

func (c *rwcClient) CreateTopic(topic string) error {
	// FIXME: This is awful. NSQd has no command to create a topic
	// except via the HTTP API. Needs patching.
	cmd := nsq.Publish(topic, []byte("dummymsg"))

	respchan := make(chan string)
	c.manage <- &manageRequest{Cmd: cmd, Response: respchan}
	resp := <-respchan

	if resp != "OK" {
		return errors.New(resp)
	}

	return nil
}

func (c *rwcClient) Send(topic string, body io.Reader) error {
	buf, err := ioutil.ReadAll(body)
	if err != nil {
		return err
	}
	cmd := nsq.Publish(topic, buf)
	respchan := make(chan string)
	c.manage <- &manageRequest{Cmd: cmd, Response: respchan}
	resp := <-respchan

	if resp != "OK" {
		return errors.New(resp)
	}

	return nil
}
<|endoftext|>


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

// Package storage implements a low-level interface for storing blobs in
// stable storage such as a database.
package storage // import "upspin.io/cloud/storage"

import (
	"strings"

	"upspin.io/errors"
)

// Storage is a low-level storage interface for services to store their data
// permanently. Storage implementations must be safe for concurrent use.
type Storage interface {
	// LinkBase returns the base URL from which any ref may be downloaded.
	// If the backend does not offer direct links it returns
	// upspin.ErrNotSupported.
	LinkBase() (base string, err error)

	// Download retrieves the bytes associated with a ref.
	Download(ref string) ([]byte, error)

	// Put stores the contents given as ref on the storage backend.
	Put(ref string, contents []byte) error

	// Delete permanently removes all storage space associated
	// with a ref.
	Delete(ref string) error
}

// StorageConstructor is a function that initializes and returns a Storage
// implementation with the given options.
type StorageConstructor func(*Opts) (Storage, error)

var registration = make(map[string]StorageConstructor)

// Opts holds configuration options for the storage backend.
// It is meant to be used by implementations of Storage.
type Opts struct {
	Opts map[string]string // key-value pair
}

// DialOpts is a daisy-chaining mechanism for setting options to a backend during Dial.
type DialOpts func(*Opts) error

// Register registers a new Storage under a name. It is typically used in init functions.
func Register(name string, fn StorageConstructor) error {
	const op = "cloud/storage.Register"
	if _, exists := registration[name]; exists {
		return errors.E(op, errors.Exist)
	}
	registration[name] = fn
	return nil
}

// WithOptions parses a string in the format "key1=value1,key2=value2,..." where keys and values
// are specific to each storage backend. Neither key nor value may contain the characters "," or "=".
// Use WithKeyValue repeatedly if these characters need to be used.
func WithOptions(options string) DialOpts {
	const op = "cloud/storage.WithOptions"
	return func(o *Opts) error {
		pairs := strings.Split(options, ",")
		for _, p := range pairs {
			kv := strings.Split(p, "=")
			if len(kv) != 2 {
				return errors.E(op, errors.Invalid, errors.Errorf("error parsing option %s", kv))
			}
			o.Opts[kv[0]] = kv[1]
		}
		return nil
	}
}

// WithKeyValue sets a key-value pair as option. If called multiple times with the same key, the last one wins.
func WithKeyValue(key, value string) DialOpts {
	return func(o *Opts) error {
		o.Opts[key] = value
		return nil
	}
}

// Dial dials the named storage backend using the dial options opts.
func Dial(name string, opts ...DialOpts) (Storage, error) {
	const op = "cloud/storage.Dial"
	fn, found := registration[name]
	if !found {
		return nil, errors.E(op, errors.Invalid, errors.Errorf("unknown storage backend type %q", name))
	}
	dOpts := &Opts{Opts: make(map[string]string)}
	var err error
	for _, o := range opts {
		if o != nil {
			err = o(dOpts)
			if err != nil {
				return nil, err
			}
		}
	}
	return fn(dOpts)
}
<commit_msg>cloud/storage: tolerate more than one equals sign in an option<commit_after>// Copyright 2016 The Upspin Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package storage implements a low-level interface for storing blobs in
// stable storage such as a database.
package storage // import "upspin.io/cloud/storage"

import (
	"strings"

	"upspin.io/errors"
)

// Storage is a low-level storage interface for services to store their data
// permanently. Storage implementations must be safe for concurrent use.
type Storage interface {
	// LinkBase returns the base URL from which any ref may be downloaded.
	// If the backend does not offer direct links it returns
	// upspin.ErrNotSupported.
	LinkBase() (base string, err error)

	// Download retrieves the bytes associated with a ref.
	Download(ref string) ([]byte, error)

	// Put stores the contents given as ref on the storage backend.
	Put(ref string, contents []byte) error

	// Delete permanently removes all storage space associated
	// with a ref.
	Delete(ref string) error
}

// StorageConstructor is a function that initializes and returns a Storage
// implementation with the given options.
type StorageConstructor func(*Opts) (Storage, error)

var registration = make(map[string]StorageConstructor)

// Opts holds configuration options for the storage backend.
// It is meant to be used by implementations of Storage.
type Opts struct {
	Opts map[string]string // key-value pair
}

// DialOpts is a daisy-chaining mechanism for setting options to a backend during Dial.
type DialOpts func(*Opts) error

// Register registers a new Storage under a name. It is typically used in init functions.
func Register(name string, fn StorageConstructor) error {
	const op = "cloud/storage.Register"
	if _, exists := registration[name]; exists {
		return errors.E(op, errors.Exist)
	}
	registration[name] = fn
	return nil
}

// WithOptions parses a string in the format "key1=value1,key2=value2,..." where keys and values
// are specific to each storage backend. Neither key nor value may contain the characters "," or "=".
// Use WithKeyValue repeatedly if these characters need to be used.
func WithOptions(options string) DialOpts {
	const op = "cloud/storage.WithOptions"
	return func(o *Opts) error {
		pairs := strings.Split(options, ",")
		for _, p := range pairs {
			kv := strings.SplitN(p, "=", 2)
			if len(kv) != 2 {
				return errors.E(op, errors.Invalid, errors.Errorf("error parsing option %s", kv))
			}
			o.Opts[kv[0]] = kv[1]
		}
		return nil
	}
}

// WithKeyValue sets a key-value pair as option. If called multiple times with the same key, the last one wins.
func WithKeyValue(key, value string) DialOpts {
	return func(o *Opts) error {
		o.Opts[key] = value
		return nil
	}
}

// Dial dials the named storage backend using the dial options opts.
func Dial(name string, opts ...DialOpts) (Storage, error) {
	const op = "cloud/storage.Dial"
	fn, found := registration[name]
	if !found {
		return nil, errors.E(op, errors.Invalid, errors.Errorf("unknown storage backend type %q", name))
	}
	dOpts := &Opts{Opts: make(map[string]string)}
	var err error
	for _, o := range opts {
		if o != nil {
			err = o(dOpts)
			if err != nil {
				return nil, err
			}
		}
	}
	return fn(dOpts)
}
<|endoftext|>


<commit_before>package cloudwatch

import (
	"encoding/json"
	"reflect"
	"time"

	"github.com/apex/go-apex"
)

// var (
// 	detailTypes = map[string]
// )

// Event represents a CloudWatch Event
type Event struct {
	ID         string    `json:"id"`
	DetailType string    `json:"detail-type"`
	Source     string    `json:"source"`
	Account    string    `json:"account"`
	Time       time.Time `json:"time"`
	Region     string    `json:"region"`
	Resources  []string  `json:"resources"`
	Detail     Detail    `json:"detail"`
}

// UnmarshalJSON extracts raw data into structured data
func (e *Event) UnmarshalJSON(b []byte) error {
	var aux struct {
		ID         string          `json:"id"`
		DetailType string          `json:"detail-type"`
		Source     string          `json:"source"`
		Account    string          `json:"account"`
		Time       time.Time       `json:"time"`
		Region     string          `json:"region"`
		Resources  []string        `json:"resources"`
		Detail     json.RawMessage `json:"detail"`
	}

	if err := json.Unmarshal(b, &aux); err != nil {
		return err
	}

	e.ID = aux.ID
	e.DetailType = aux.DetailType
	e.Source = aux.Source
	e.Account = aux.Account
	e.Time = aux.Time
	e.Region = aux.Region
	e.Resources = aux.Resources

	var detail Detail
	switch aux.Source {
	case "aws.autoscaling":
		detail = &AutoScalingGroupDetail{}
	case "aws.signin":
		detail = &ConsoleSignInDetail{}
	case "aws.ec2":
		detail = &EC2Detail{}
	default:
		detail = &EmptyDetail{}
	}

	if err := json.Unmarshal(aux.Detail, detail); err != nil {
		return err
	}

	e.Detail = detail

	return nil
}

// Detail represents specifics of the event
type Detail interface {
	List() []string
	Get(key string) (interface{}, bool)
}

// AutoScalingGroupDetail of the triggered event
type AutoScalingGroupDetail struct {
	ActivityID           string            `json:"ActivityId"`
	AutoScalingGroupName string            `json:"AutoScalingGroupName"`
	Cause                string            `json:"Cause"`
	Details              map[string]string `json:"Details"`
	EC2InstanceID        string            `json:"EC2InstanceId"`
	RequestID            string            `json:"RequestId"`
	StatusCode           string            `json:"StatusCode"`

	StartTime time.Time `json:"StartTime"`
	EndTime   time.Time `json:"EndTime"`
}

// List struct fields in the details
func (d *AutoScalingGroupDetail) List() []string {
	return listKeys(d)
}

// Get a value from details based on the key
func (d *AutoScalingGroupDetail) Get(key string) (interface{}, bool) {
	return keyValue(d, key)
}

// EC2Detail of the triggered event
type EC2Detail struct {
	InstanceID string `json:"instance-id"`
	State      string `json:"state"`
}

// List struct fields in the details
func (d *EC2Detail) List() []string {
	return listKeys(d)
}

// Get a value from details based on the key
func (d *EC2Detail) Get(key string) (interface{}, bool) {
	return keyValue(d, key)
}

// ConsoleSignInDetail of the triggered event
// This is useful for unknown or schedule event types
type ConsoleSignInDetail struct {
	EventID      string    `json:"eventID"`
	EventName    string    `json:"eventName"`
	EventSource  string    `json:"eventSource"`
	EventTime    time.Time `json:"eventTime"`
	EventType    string    `json:"eventType"`
	EventVersion string    `json:"eventVersion"`

	AWSRegion           string            `json:"awsRegion"`
	AdditionalEventData map[string]string `json:"additionalEventData"`
	RequestParams       interface{}       `json:"requestParameters"`
	ResponseElements    map[string]string `json:"responseElements"`
	SourceIPAddress     string            `json:"sourceIPAddress"`
	UserAgent           string            `json:"userAgent"`
	UserIdentity        map[string]string `json:"userIdentity"`
}

// List struct fields in the details
func (d *ConsoleSignInDetail) List() []string {
	return listKeys(d)
}

// Get a value from details based on the key
func (d *ConsoleSignInDetail) Get(key string) (interface{}, bool) {
	return keyValue(d, key)
}

// EmptyDetail of the triggered event
// This is useful for unknown or schedule event types
type EmptyDetail struct{}

// List struct fields in the details
func (d *EmptyDetail) List() []string {
	return listKeys(d)
}

// Get a value from details based on the key
func (d *EmptyDetail) Get(key string) (interface{}, bool) {
	return keyValue(d, key)
}

// Handler handles CloudWatch Events
type Handler interface {
	HandleCloudWatcEvent(*Event, *apex.Context) error
}

// HandlerFunc unmarshals CloudWatch Events before passing control.
type HandlerFunc func(*Event, *apex.Context) error

// Handle implements apex.Handler.
func (h HandlerFunc) Handle(data json.RawMessage, ctx *apex.Context) (interface{}, error) {
	var event Event

	if err := json.Unmarshal(data, &event); err != nil {
		return nil, err
	}

	return nil, h(&event, ctx)
}

// HandleFunc handles CloudWatch Events with callback function.
func HandleFunc(h HandlerFunc) {
	apex.Handle(h)
}

// Handle CloudWatch Events with handler.
func Handle(h Handler) {
	HandleFunc(HandlerFunc(h.HandleCloudWatcEvent))
}

func listKeys(i interface{}) []string {
	v := reflect.ValueOf(i).Elem()
	t := v.Type()

	values := []string{}
	for j := 0; j < v.NumField(); j++ {
		values = append(values, t.Field(j).Name)
	}

	return values

}

func keyValue(i interface{}, key string) (interface{}, bool) {
	v := reflect.ValueOf(i).Elem()
	t := v.Type()

	for j := 0; j < v.NumField(); j++ {
		k := t.Field(j).Name
		if k == key {
			return v.Field(j).Interface(), true
		}
	}

	return nil, false
}
<commit_msg>Remove detail interface<commit_after>package cloudwatch

import (
	"encoding/json"
	"reflect"
	"time"

	"github.com/apex/go-apex"
)

// Event represents a CloudWatch Event
type Event struct {
	ID         string          `json:"id"`
	DetailType string          `json:"detail-type"`
	Source     string          `json:"source"`
	Account    string          `json:"account"`
	Time       time.Time       `json:"time"`
	Region     string          `json:"region"`
	Resources  []string        `json:"resources"`
	Detail     json.RawMessage `json:"detail"`
}

// AutoScalingGroupDetail of the triggered event
type AutoScalingGroupDetail struct {
	ActivityID           string            `json:"ActivityId"`
	AutoScalingGroupName string            `json:"AutoScalingGroupName"`
	Cause                string            `json:"Cause"`
	Details              map[string]string `json:"Details"`
	EC2InstanceID        string            `json:"EC2InstanceId"`
	RequestID            string            `json:"RequestId"`
	StatusCode           string            `json:"StatusCode"`

	StartTime time.Time `json:"StartTime"`
	EndTime   time.Time `json:"EndTime"`
}

// EC2Detail of the triggered event
type EC2Detail struct {
	InstanceID string `json:"instance-id"`
	State      string `json:"state"`
}

// ConsoleSignInDetail of the triggered event
// This is useful for unknown or schedule event types
type ConsoleSignInDetail struct {
	EventID      string    `json:"eventID"`
	EventName    string    `json:"eventName"`
	EventSource  string    `json:"eventSource"`
	EventTime    time.Time `json:"eventTime"`
	EventType    string    `json:"eventType"`
	EventVersion string    `json:"eventVersion"`

	AWSRegion           string            `json:"awsRegion"`
	AdditionalEventData map[string]string `json:"additionalEventData"`
	RequestParams       interface{}       `json:"requestParameters"`
	ResponseElements    map[string]string `json:"responseElements"`
	SourceIPAddress     string            `json:"sourceIPAddress"`
	UserAgent           string            `json:"userAgent"`
	UserIdentity        map[string]string `json:"userIdentity"`
}

// Handler handles CloudWatch Events
type Handler interface {
	HandleCloudWatcEvent(*Event, *apex.Context) error
}

// HandlerFunc unmarshals CloudWatch Events before passing control.
type HandlerFunc func(*Event, *apex.Context) error

// Handle implements apex.Handler.
func (h HandlerFunc) Handle(data json.RawMessage, ctx *apex.Context) (interface{}, error) {
	var event Event

	if err := json.Unmarshal(data, &event); err != nil {
		return nil, err
	}

	return nil, h(&event, ctx)
}

// HandleFunc handles CloudWatch Events with callback function.
func HandleFunc(h HandlerFunc) {
	apex.Handle(h)
}

// Handle CloudWatch Events with handler.
func Handle(h Handler) {
	HandleFunc(HandlerFunc(h.HandleCloudWatcEvent))
}

func listKeys(i interface{}) []string {
	v := reflect.ValueOf(i).Elem()
	t := v.Type()

	values := []string{}
	for j := 0; j < v.NumField(); j++ {
		values = append(values, t.Field(j).Name)
	}

	return values

}

func keyValue(i interface{}, key string) (interface{}, bool) {
	v := reflect.ValueOf(i).Elem()
	t := v.Type()

	for j := 0; j < v.NumField(); j++ {
		k := t.Field(j).Name
		if k == key {
			return v.Field(j).Interface(), true
		}
	}

	return nil, false
}
<|endoftext|>


<commit_before>// Extract data from GRIB2 file into Tawhiri-ordered binary data file.
package main

import (
	"flag"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"path/filepath"

	"github.com/rjw57/aonui"
)

func main() {
	var tmpDir string

	flag.StringVar(&tmpDir, "tmpdir", "", "directory to store temporary files in")
	flag.Parse()

	if len(flag.Args()) != 2 {
		log.Fatal("Usage: aonuiextract <ingrib> <outbin>")
	}

	// Get arguments
	sourceFn := flag.Args()[0]
	destFn := flag.Args()[1]

	if tmpDir == "" {
		tmpDir = filepath.Dir(destFn)
	}

	// Create a temporary file
	tmpFile, err := ioutil.TempFile(tmpDir, filepath.Base(destFn)+".reordered.grib2.")
	if err != nil {
		log.Fatal(err)
	}
	tmpFile.Close()
	tmpFn := tmpFile.Name()
	defer func() { log.Print("Removing ", tmpFn); os.Remove(tmpFn) }()

	// Make sure to remove temporary files on keyboard interrupt
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for s := range c {
			log.Printf("captured %v, deleting temporary files", s)
			os.Remove(tmpFn)
			os.Exit(1)
		}
	}()

	log.Print("Re-ordering input GRIB to ", tmpFn)
	if err := aonui.ReorderGrib2(sourceFn, tmpFn); err != nil {
		log.Fatal(err)
	}

	log.Print("Expanding to ", destFn)
	if err := aonui.Wgrib2Extract(tmpFn, destFn); err != nil {
		log.Fatal(err)
	}
}
<commit_msg>aonuiextract: be more robust in ensuring temp files get removed<commit_after>// Extract data from GRIB2 file into Tawhiri-ordered binary data file.
package main

import (
	"flag"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"path/filepath"

	"github.com/rjw57/aonui"
)

func main() {
	var tmpDir string

	flag.StringVar(&tmpDir, "tmpdir", "", "directory to store temporary files in")
	flag.Parse()

	if len(flag.Args()) != 2 {
		log.Fatal("Usage: aonuiextract <ingrib> <outbin>")
	}

	// Get arguments
	sourceFn := flag.Args()[0]
	destFn := flag.Args()[1]
	if tmpDir == "" {
		tmpDir = filepath.Dir(destFn)
	}

	// Do work
	if err := extract(sourceFn, destFn, tmpDir); err != nil {
		log.Fatal(err)
	}
}

func extract(sourceFn, destFn, tmpDir string) error {
	// Create a temporary file
	tmpFile, err := ioutil.TempFile(tmpDir, filepath.Base(destFn)+".reordered.grib2.")
	if err != nil {
		return err
	}
	tmpFile.Close()
	tmpFn := tmpFile.Name()
	defer func() { log.Print("Removing ", tmpFn); os.Remove(tmpFn) }()

	// Make sure to remove temporary files on keyboard interrupt
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for s := range c {
			log.Printf("captured %v, deleting temporary files", s)
			os.Remove(tmpFn)
			os.Exit(1)
		}
	}()

	log.Print("Re-ordering input GRIB to ", tmpFn)
	if err := aonui.ReorderGrib2(sourceFn, tmpFn); err != nil {
		return err
	}

	log.Print("Expanding to ", destFn)
	if err := aonui.Wgrib2Extract(tmpFn, destFn); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/rkoesters/goblin/lib"
	"os"
	"path"
	"strings"
)

var dflag = flag.Bool("d", false, "print directory compenent")

func main() {
	lib.Usage = "string [suffix]"
	lib.InitFlag()
	flag.Parse()

	if flag.NArg() < 1 || flag.NArg() > 2 {
		flag.Usage()
		os.Exit(1)
	}

	dir, file := path.Split(flag.Arg(0))

	if *dflag {
		fmt.Println(dir)
		return
	}

	fmt.Println(strings.TrimSuffix(file, flag.Arg(1)))
}
<commit_msg>Added BUG note to cmd/basename.<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/rkoesters/goblin/lib"
	"os"
	"path"
	"strings"
)

// BUG(rkoesters) -d option shouldn't have trailing slash.
var dflag = flag.Bool("d", false, "print directory compenent")

func main() {
	lib.Usage = "string [suffix]"
	lib.InitFlag()
	flag.Parse()

	if flag.NArg() < 1 || flag.NArg() > 2 {
		flag.Usage()
		os.Exit(1)
	}

	dir, file := path.Split(flag.Arg(0))

	if *dflag {
		fmt.Println(dir)
		return
	}

	fmt.Println(strings.TrimSuffix(file, flag.Arg(1)))
}
<|endoftext|>


<commit_before>// Package commands defines CLI API
package commands

import (
	"os"
	"strings"

	"github.com/spf13/cobra"
)

// Is action remote?
var isRemote bool

// Is action local?
var isLocal bool

// Reinstall global modules from previous version?
var WithModules bool

// Command config
var Command = &cobra.Command{
	Use:     "ec [<language>@<version>]",
	Example: example,
	Hidden:  true,
}

// Add command to root command
func Register(cmd *cobra.Command) {
	Command.AddCommand(cmd)
}

// Init
func init() {
	Command.SetHelpTemplate(help)
	Command.SetUsageTemplate(usage)

	cobra.OnInitialize()

	flags := Command.PersistentFlags()
	flags.BoolVarP(&isRemote, "remote", "r", false, "Get remote versions")
	flags.BoolVarP(&isLocal, "local", "l", false, "Install as local version i.e. language will be installed only to local folder")
	flags.BoolVarP(&WithModules, "with-modules", "w", false, "Reinstall global modules from the previous version (currently works only for node.js)")
}

func augment() {
	// Insert command "install" in args
	os.Args = append(os.Args[:1], append([]string{"install"}, os.Args[1:]...)...)
}

func Execute() {

	args := os.Args[1:]
	if len(args) == 0 {
		augment()
		Command.Execute()

		return
	}

	// Until https://github.com/spf13/cobra/pull/369 is landed
	// Workaround to "forward" to a know command when no know command found
	_, _, err := Command.Find(args)
	if err != nil && strings.HasPrefix(err.Error(), "unknown command") {
		augment()
	}

	Command.Execute()
}
<commit_msg>Try be more perceptive with command detection<commit_after>// Package commands defines CLI API
package commands

import (
	"os"

	"github.com/spf13/cobra"
)

// Is action remote?
var isRemote bool

// Is action local?
var isLocal bool

// Reinstall global modules from previous version?
var WithModules bool

var use = "ec [<language>@<version>]"

// Command config
var Command = &cobra.Command{
	Use:     use,
	Example: example,
	Hidden:  true,
}

// Add command to root command
func Register(cmd *cobra.Command) {
	Command.AddCommand(cmd)
}

// Init
func init() {
	Command.SetHelpTemplate(help)
	Command.SetUsageTemplate(usage)

	cobra.OnInitialize()

	flags := Command.PersistentFlags()
	flags.BoolVarP(&isRemote, "remote", "r", false, "Get remote versions")
	flags.BoolVarP(&isLocal, "local", "l", false, "Install as local version i.e. language will be installed only to local folder")
	flags.BoolVarP(&WithModules, "with-modules", "w", false, "Reinstall global modules from the previous version (currently works only for node.js)")
}

func augment() {
	// Insert command "install" in args
	os.Args = append(os.Args[:1], append([]string{"install"}, os.Args[1:]...)...)
}

func Execute() {

	args := os.Args[1:]

	// Until https://github.com/spf13/cobra/pull/369 is landed
	// Workaround to "forward" to a know command when no know command found
	cmd, _, _ := Command.Find(args)

	if cmd.Use == use {
		augment()
	}

	Command.Execute()
}
<|endoftext|>