<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"os"
)

func upload(url string, data map[string]string,
	paramname string, filename string,
) error {
	client := &http.Client{}
	bodyBuf := &bytes.Buffer{}
	bodyWriter := multipart.NewWriter(bodyBuf)

	fileWriter, err := bodyWriter.CreateFormFile(paramname, filename)
	if err != nil {
		fmt.Println("error writing to buffer")
		return err
	}

	f, err := os.Open(filename)
	if err != nil {
		fmt.Println("error open file")
		return err
	}

	_, err = io.Copy(fileWriter, f)
	if err != nil {
		return err
	}

	for k, v := range data {
		bodyWriter.WriteField(k, v)
	}

	contentType := bodyWriter.FormDataContentType()
	bodyWriter.Close()

	req, err := http.NewRequest("POST", url, bodyBuf)
	req.Header.Set("Content-Type", contentType)
	req.Header.Set("User-Agent", "go-bild/0.1.0")

	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	fmt.Println(resp.StatusCode)
	fmt.Println(string(respBody))
	return nil

}

func main() {
	data := map[string]string{
		"t":      "1",
		"C1":     "ON",
		"upload": "1",
	}
	url := "http://www.bild.me/index.php"
	upload(url, data, "F1", "up-download.jpg")
}
<commit_msg>parse response<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"os"
	"strings"
)

func upload(url string, data map[string]string,
	paramname string, filename string,
) error {
	client := &http.Client{}
	bodyBuf := &bytes.Buffer{}
	bodyWriter := multipart.NewWriter(bodyBuf)

	fileWriter, err := bodyWriter.CreateFormFile(paramname, filename)
	if err != nil {
		fmt.Println("error writing to buffer")
		return err
	}

	f, err := os.Open(filename)
	if err != nil {
		fmt.Println("error open file")
		return err
	}

	_, err = io.Copy(fileWriter, f)
	if err != nil {
		return err
	}

	for k, v := range data {
		bodyWriter.WriteField(k, v)
	}

	contentType := bodyWriter.FormDataContentType()
	bodyWriter.Close()

	req, err := http.NewRequest("POST", url, bodyBuf)
	req.Header.Set("Content-Type", contentType)
	req.Header.Set("User-Agent", "go-bild/0.1.0")

	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	body := string(respBody)
	fmt.Println(resp.StatusCode)
	// fmt.Println(body)
	urls := strings.Split(body, "\n")
	fmt.Println(urls[0])
	fmt.Println(urls[len(urls)-1])
	return nil

}

func main() {
	data := map[string]string{
		"t":      "1",
		"C1":     "ON",
		"upload": "1",
	}
	url := "http://www.bild.me/index.php"
	upload(url, data, "F1", "up-download.jpg")
}
<|endoftext|>


<commit_before>/*

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

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

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

// Package kubectl implements the HNC kubectl plugin
package kubectl

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

	"github.com/spf13/cobra"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/scheme"
	_ "k8s.io/client-go/plugin/pkg/client/auth"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"

	tenancy "github.com/kubernetes-sigs/multi-tenancy/incubator/hnc/api/v1alpha1"
)

var k8sClient *kubernetes.Clientset
var hncClient *rest.RESTClient

func init() {
	tenancy.AddToScheme(scheme.Scheme)
}

var rootCmd = &cobra.Command{
	Use:   "kubectl-hnc",
	Short: "Manipulate the hierarchy",
	PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
		var err error
		// use the current context in kubeconfig
		kubeconfig := os.Getenv("KUBECONFIG") // TODO: check args first
		if len(kubeconfig) == 0 {
			kubeconfig = filepath.Join(homeDir(), ".kube", "config")
		}
		config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
		if err != nil {
			return err
		}

		// create the K8s clientset
		k8sClient, err = kubernetes.NewForConfig(config)
		if err != nil {
			return err
		}

		// create the HNC clientset
		hncConfig := *config
		hncConfig.ContentConfig.GroupVersion = &tenancy.GroupVersion
		hncConfig.APIPath = "/apis"
		hncConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
		hncConfig.UserAgent = rest.DefaultKubernetesUserAgent()
		hncClient, err = rest.UnversionedRESTClientFor(&hncConfig)
		if err != nil {
			return err
		}

		return nil
	},
}

func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func homeDir() string {
	if h := os.Getenv("HOME"); h != "" {
		return h
	}
	return os.Getenv("USERPROFILE") // windows
}

func getHierarchy(nnm string) *tenancy.HierarchyConfiguration {
	if _, err := k8sClient.CoreV1().Namespaces().Get(nnm, metav1.GetOptions{}); err != nil {
		fmt.Printf("Error reading namespace %s: %s\n", nnm, err)
		os.Exit(1)
	}
	hier := &tenancy.HierarchyConfiguration{}
	hier.Name = tenancy.Singleton
	hier.Namespace = nnm
	err := hncClient.Get().Resource("hierarchies").Namespace(nnm).Name(tenancy.Singleton).Do().Into(hier)
	if err != nil && !errors.IsNotFound(err) {
		fmt.Printf("Error reading hierarchy for %s: %s\n", nnm, err)
		os.Exit(1)
	}
	return hier
}

func updateHierarchy(hier *tenancy.HierarchyConfiguration, reason string) {
	nnm := hier.Namespace
	var err error
	if hier.CreationTimestamp.IsZero() {
		err = hncClient.Post().Resource("hierarchies").Namespace(nnm).Name(tenancy.Singleton).Body(hier).Do().Error()
	} else {
		err = hncClient.Put().Resource("hierarchies").Namespace(nnm).Name(tenancy.Singleton).Body(hier).Do().Error()
	}
	if err != nil {
		fmt.Printf("Error %s: %s\n", reason, err)
		os.Exit(1)
	}
}
<commit_msg>kubectl hnc set-parent command fix<commit_after>/*

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

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

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

// Package kubectl implements the HNC kubectl plugin
package kubectl

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

	"github.com/spf13/cobra"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/scheme"
	_ "k8s.io/client-go/plugin/pkg/client/auth"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"

	tenancy "github.com/kubernetes-sigs/multi-tenancy/incubator/hnc/api/v1alpha1"
)

var k8sClient *kubernetes.Clientset
var hncClient *rest.RESTClient

func init() {
	tenancy.AddToScheme(scheme.Scheme)
}

var rootCmd = &cobra.Command{
	Use:   "kubectl-hnc",
	Short: "Manipulate the hierarchy",
	PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
		var err error
		// use the current context in kubeconfig
		kubeconfig := os.Getenv("KUBECONFIG") // TODO: check args first
		if len(kubeconfig) == 0 {
			kubeconfig = filepath.Join(homeDir(), ".kube", "config")
		}
		config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
		if err != nil {
			return err
		}

		// create the K8s clientset
		k8sClient, err = kubernetes.NewForConfig(config)
		if err != nil {
			return err
		}

		// create the HNC clientset
		hncConfig := *config
		hncConfig.ContentConfig.GroupVersion = &tenancy.GroupVersion
		hncConfig.APIPath = "/apis"
		hncConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
		hncConfig.UserAgent = rest.DefaultKubernetesUserAgent()
		hncClient, err = rest.UnversionedRESTClientFor(&hncConfig)
		if err != nil {
			return err
		}

		return nil
	},
}

func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func homeDir() string {
	if h := os.Getenv("HOME"); h != "" {
		return h
	}
	return os.Getenv("USERPROFILE") // windows
}

func getHierarchy(nnm string) *tenancy.HierarchyConfiguration {
	if _, err := k8sClient.CoreV1().Namespaces().Get(nnm, metav1.GetOptions{}); err != nil {
		fmt.Printf("Error reading namespace %s: %s\n", nnm, err)
		os.Exit(1)
	}
	hier := &tenancy.HierarchyConfiguration{}
	hier.Name = tenancy.Singleton
	hier.Namespace = nnm
	err := hncClient.Get().Resource("hierarchyconfigurations").Namespace(nnm).Name(tenancy.Singleton).Do().Into(hier)
	if err != nil && !errors.IsNotFound(err) {
		fmt.Printf("Error reading hierarchy for %s: %s\n", nnm, err)
		os.Exit(1)
	}
	return hier
}

func updateHierarchy(hier *tenancy.HierarchyConfiguration, reason string) {
	nnm := hier.Namespace
	var err error
	if hier.CreationTimestamp.IsZero() {
		err = hncClient.Post().Resource("hierarchyconfigurations").Namespace(nnm).Name(tenancy.Singleton).Body(hier).Do().Error()
	} else {
		err = hncClient.Put().Resource("hierarchyconfigurations").Namespace(nnm).Name(tenancy.Singleton).Body(hier).Do().Error()
	}
	if err != nil {
		fmt.Printf("Error %s: %s\n", reason, err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package iso

import (
	"errors"
	"fmt"
	"log"
	"path"
	"strings"
	"time"

	"github.com/mitchellh/multistep"
	"github.com/mitchellh/packer/common"
	"github.com/mitchellh/packer/helper/communicator"
	hconfig "github.com/mitchellh/packer/helper/config"
	"github.com/mitchellh/packer/packer"
	"github.com/mitchellh/packer/template/interpolate"
	xsclient "github.com/xenserver/go-xenserver-client"
	xscommon "github.com/xenserver/packer-builder-xenserver/builder/xenserver/common"
)

type config struct {
	common.PackerConfig   `mapstructure:",squash"`
	xscommon.CommonConfig `mapstructure:",squash"`

	VMMemory      uint              `mapstructure:"vm_memory"`
	DiskSize      uint              `mapstructure:"disk_size"`
	CloneTemplate string            `mapstructure:"clone_template"`
	VMOtherConfig map[string]string `mapstructure:"vm_other_config"`

	ISOChecksum     string   `mapstructure:"iso_checksum"`
	ISOChecksumType string   `mapstructure:"iso_checksum_type"`
	ISOUrls         []string `mapstructure:"iso_urls"`
	ISOUrl          string   `mapstructure:"iso_url"`
	ISOName         string   `mapstructure:"iso_name"`

	PlatformArgs map[string]string `mapstructure:"platform_args"`

	RawInstallTimeout string        `mapstructure:"install_timeout"`
	InstallTimeout    time.Duration ``

	ctx interpolate.Context
}

type Builder struct {
	config config
	runner multistep.Runner
}

func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error) {

	var errs *packer.MultiError

	err := hconfig.Decode(&self.config, &hconfig.DecodeOpts{
		Interpolate: true,
		InterpolateFilter: &interpolate.RenderFilter{
			Exclude: []string{
				"boot_command",
			},
		},
	}, raws...)

	if err != nil {
		packer.MultiErrorAppend(errs, err)
	}

	errs = packer.MultiErrorAppend(
		errs, self.config.CommonConfig.Prepare(&self.config.ctx, &self.config.PackerConfig)...)
	errs = packer.MultiErrorAppend(errs, self.config.SSHConfig.Prepare(&self.config.ctx)...)

	// Set default values

	if self.config.RawInstallTimeout == "" {
		self.config.RawInstallTimeout = "200m"
	}

	if self.config.DiskSize == 0 {
		self.config.DiskSize = 40000
	}

	if self.config.VMMemory == 0 {
		self.config.VMMemory = 1024
	}

	if self.config.CloneTemplate == "" {
		self.config.CloneTemplate = "Other install media"
	}

	if len(self.config.PlatformArgs) == 0 {
		pargs := make(map[string]string)
		pargs["viridian"] = "false"
		pargs["nx"] = "true"
		pargs["pae"] = "true"
		pargs["apic"] = "true"
		pargs["timeoffset"] = "0"
		pargs["acpi"] = "1"
		self.config.PlatformArgs = pargs
	}

	// Template substitution

	templates := map[string]*string{
		"clone_template":    &self.config.CloneTemplate,
		"iso_checksum":      &self.config.ISOChecksum,
		"iso_checksum_type": &self.config.ISOChecksumType,
		"iso_url":           &self.config.ISOUrl,
		"iso_name":          &self.config.ISOName,
		"install_timeout":   &self.config.RawInstallTimeout,
	}
	for i := range self.config.ISOUrls {
		templates[fmt.Sprintf("iso_urls[%d]", i)] = &self.config.ISOUrls[i]
	}

	// Validation

	self.config.InstallTimeout, err = time.ParseDuration(self.config.RawInstallTimeout)
	if err != nil {
		errs = packer.MultiErrorAppend(
			errs, fmt.Errorf("Failed to parse install_timeout: %s", err))
	}

	if self.config.ISOName == "" {

		// If ISO name is not specified, assume a URL and checksum has been provided.

		if self.config.ISOChecksumType == "" {
			errs = packer.MultiErrorAppend(
				errs, errors.New("The iso_checksum_type must be specified."))
		} else {
			self.config.ISOChecksumType = strings.ToLower(self.config.ISOChecksumType)
			if self.config.ISOChecksumType != "none" {
				if self.config.ISOChecksum == "" {
					errs = packer.MultiErrorAppend(
						errs, errors.New("Due to the file size being large, an iso_checksum is required."))
				} else {
					self.config.ISOChecksum = strings.ToLower(self.config.ISOChecksum)
				}

				if hash := common.HashForType(self.config.ISOChecksumType); hash == nil {
					errs = packer.MultiErrorAppend(
						errs, fmt.Errorf("Unsupported checksum type: %s", self.config.ISOChecksumType))
				}

			}
		}

		if len(self.config.ISOUrls) == 0 {
			if self.config.ISOUrl == "" {
				errs = packer.MultiErrorAppend(
					errs, errors.New("One of iso_url or iso_urls must be specified."))
			} else {
				self.config.ISOUrls = []string{self.config.ISOUrl}
			}
		} else if self.config.ISOUrl != "" {
			errs = packer.MultiErrorAppend(
				errs, errors.New("Only one of iso_url or iso_urls may be specified."))
		}

		for i, url := range self.config.ISOUrls {
			self.config.ISOUrls[i], err = common.DownloadableURL(url)
			if err != nil {
				errs = packer.MultiErrorAppend(
					errs, fmt.Errorf("Failed to parse iso_urls[%d]: %s", i, err))
			}
		}
	} else {

		// An ISO name has been provided. It should be attached from an available SR.

	}

	if len(errs.Errors) > 0 {
		retErr = errors.New(errs.Error())
	}

	return nil, retErr

}

func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
	//Setup XAPI client
	client := xsclient.NewXenAPIClient(self.config.HostIp, self.config.Username, self.config.Password)

	err := client.Login()
	if err != nil {
		return nil, err.(error)
	}
	ui.Say("XAPI client session established")

	client.GetHosts()

	//Share state between the other steps using a statebag
	state := new(multistep.BasicStateBag)
	state.Put("cache", cache)
	state.Put("client", client)
	state.Put("config", self.config)
	state.Put("commonconfig", self.config.CommonConfig)
	state.Put("hook", hook)
	state.Put("ui", ui)

	httpReqChan := make(chan string, 1)

	//Build the steps
	download_steps := []multistep.Step{
		&common.StepDownload{
			Checksum:     self.config.ISOChecksum,
			ChecksumType: self.config.ISOChecksumType,
			Description:  "ISO",
			ResultKey:    "iso_path",
			Url:          self.config.ISOUrls,
		},
	}

	steps := []multistep.Step{
		&xscommon.StepPrepareOutputDir{
			Force: self.config.PackerForce,
			Path:  self.config.OutputDir,
		},
		&common.StepCreateFloppy{
			Files: self.config.FloppyFiles,
		},
		&xscommon.StepHTTPServer{
			Chan: httpReqChan,
		},
		&xscommon.StepUploadVdi{
			VdiNameFunc: func() string {
				return "Packer-floppy-disk"
			},
			ImagePathFunc: func() string {
				if floppyPath, ok := state.GetOk("floppy_path"); ok {
					return floppyPath.(string)
				}
				return ""
			},
			VdiUuidKey: "floppy_vdi_uuid",
		},
		&xscommon.StepUploadVdi{
			VdiNameFunc: func() string {
				if len(self.config.ISOUrls) > 0 {
					return path.Base(self.config.ISOUrls[0])
				}
				return ""
			},
			ImagePathFunc: func() string {
				if isoPath, ok := state.GetOk("iso_path"); ok {
					return isoPath.(string)
				}
				return ""
			},
			VdiUuidKey: "iso_vdi_uuid",
		},
		&xscommon.StepFindVdi{
			VdiName:    self.config.ToolsIsoName,
			VdiUuidKey: "tools_vdi_uuid",
		},
		&xscommon.StepFindVdi{
			VdiName:    self.config.ISOName,
			VdiUuidKey: "isoname_vdi_uuid",
		},
		new(stepCreateInstance),
		&xscommon.StepAttachVdi{
			VdiUuidKey: "floppy_vdi_uuid",
			VdiType:    xsclient.Floppy,
		},
		&xscommon.StepAttachVdi{
			VdiUuidKey: "iso_vdi_uuid",
			VdiType:    xsclient.CD,
		},
		&xscommon.StepAttachVdi{
			VdiUuidKey: "isoname_vdi_uuid",
			VdiType:    xsclient.CD,
		},
		&xscommon.StepAttachVdi{
			VdiUuidKey: "tools_vdi_uuid",
			VdiType:    xsclient.CD,
		},
		new(xscommon.StepStartVmPaused),
		new(xscommon.StepGetVNCPort),
		&xscommon.StepForwardPortOverSSH{
			RemotePort:  xscommon.InstanceVNCPort,
			RemoteDest:  xscommon.InstanceVNCIP,
			HostPortMin: self.config.HostPortMin,
			HostPortMax: self.config.HostPortMax,
			ResultKey:   "local_vnc_port",
		},
		new(xscommon.StepBootWait),
		&xscommon.StepTypeBootCommand{
			Ctx: self.config.ctx,
		},
		&xscommon.StepWaitForIP{
			Chan:    httpReqChan,
			Timeout: self.config.InstallTimeout, // @todo change this
		},
		&xscommon.StepForwardPortOverSSH{
			RemotePort:  xscommon.InstanceSSHPort,
			RemoteDest:  xscommon.InstanceSSHIP,
			HostPortMin: self.config.HostPortMin,
			HostPortMax: self.config.HostPortMax,
			ResultKey:   "local_ssh_port",
		},
		&communicator.StepConnect{
			Config:    &self.config.SSHConfig.Comm,
			Host:      xscommon.CommHost,
			SSHConfig: xscommon.SSHConfigFunc(self.config.CommonConfig.SSHConfig),
			SSHPort:   xscommon.SSHPort,
		},
		new(common.StepProvision),
		new(xscommon.StepShutdown),
		&xscommon.StepDetachVdi{
			VdiUuidKey: "iso_vdi_uuid",
		},
		&xscommon.StepDetachVdi{
			VdiUuidKey: "tools_vdi_uuid",
		},
		&xscommon.StepDetachVdi{
			VdiUuidKey: "floppy_vdi_uuid",
		},
		new(xscommon.StepExport),
	}

	if self.config.ISOName == "" {
		steps = append(download_steps, steps...)
	}

	self.runner = &multistep.BasicRunner{Steps: steps}
	self.runner.Run(state)

	if rawErr, ok := state.GetOk("error"); ok {
		return nil, rawErr.(error)
	}

	// If we were interrupted or cancelled, then just exit.
	if _, ok := state.GetOk(multistep.StateCancelled); ok {
		return nil, errors.New("Build was cancelled.")
	}
	if _, ok := state.GetOk(multistep.StateHalted); ok {
		return nil, errors.New("Build was halted.")
	}

	artifact, _ := xscommon.NewArtifact(self.config.OutputDir)

	return artifact, nil
}

func (self *Builder) Cancel() {
	if self.runner != nil {
		log.Println("Cancelling the step runner...")
		self.runner.Cancel()
	}
	fmt.Println("Cancelling the builder")
}
<commit_msg>CP-18791: Make appliance-specs building stable<commit_after>package iso

import (
	"errors"
	"fmt"
	"log"
	"path"
	"strings"
	"time"

	"github.com/mitchellh/multistep"
	"github.com/mitchellh/packer/common"
	"github.com/mitchellh/packer/helper/communicator"
	hconfig "github.com/mitchellh/packer/helper/config"
	"github.com/mitchellh/packer/packer"
	"github.com/mitchellh/packer/template/interpolate"
	xsclient "github.com/xenserver/go-xenserver-client"
	xscommon "github.com/xenserver/packer-builder-xenserver/builder/xenserver/common"
)

type config struct {
	common.PackerConfig   `mapstructure:",squash"`
	xscommon.CommonConfig `mapstructure:",squash"`

	VMMemory      uint              `mapstructure:"vm_memory"`
	DiskSize      uint              `mapstructure:"disk_size"`
	CloneTemplate string            `mapstructure:"clone_template"`
	VMOtherConfig map[string]string `mapstructure:"vm_other_config"`

	ISOChecksum     string   `mapstructure:"iso_checksum"`
	ISOChecksumType string   `mapstructure:"iso_checksum_type"`
	ISOUrls         []string `mapstructure:"iso_urls"`
	ISOUrl          string   `mapstructure:"iso_url"`
	ISOName         string   `mapstructure:"iso_name"`

	PlatformArgs map[string]string `mapstructure:"platform_args"`

	RawInstallTimeout string        `mapstructure:"install_timeout"`
	InstallTimeout    time.Duration ``

	ctx interpolate.Context
}

type Builder struct {
	config config
	runner multistep.Runner
}

func (self *Builder) Prepare(raws ...interface{}) (params []string, retErr error) {

	var errs *packer.MultiError

	err := hconfig.Decode(&self.config, &hconfig.DecodeOpts{
		Interpolate: true,
		InterpolateFilter: &interpolate.RenderFilter{
			Exclude: []string{
				"boot_command",
			},
		},
	}, raws...)

	if err != nil {
		packer.MultiErrorAppend(errs, err)
	}

	errs = packer.MultiErrorAppend(
		errs, self.config.CommonConfig.Prepare(&self.config.ctx, &self.config.PackerConfig)...)
	errs = packer.MultiErrorAppend(errs, self.config.SSHConfig.Prepare(&self.config.ctx)...)

	// Set default values

	if self.config.RawInstallTimeout == "" {
		self.config.RawInstallTimeout = "200m"
	}

	if self.config.DiskSize == 0 {
		self.config.DiskSize = 40000
	}

	if self.config.VMMemory == 0 {
		self.config.VMMemory = 1024
	}

	if self.config.CloneTemplate == "" {
		self.config.CloneTemplate = "Other install media"
	}

	if len(self.config.PlatformArgs) == 0 {
		pargs := make(map[string]string)
		pargs["viridian"] = "false"
		pargs["nx"] = "true"
		pargs["pae"] = "true"
		pargs["apic"] = "true"
		pargs["timeoffset"] = "0"
		pargs["acpi"] = "1"
		self.config.PlatformArgs = pargs
	}

	// Template substitution

	templates := map[string]*string{
		"clone_template":    &self.config.CloneTemplate,
		"iso_checksum":      &self.config.ISOChecksum,
		"iso_checksum_type": &self.config.ISOChecksumType,
		"iso_url":           &self.config.ISOUrl,
		"iso_name":          &self.config.ISOName,
		"install_timeout":   &self.config.RawInstallTimeout,
	}
	for i := range self.config.ISOUrls {
		templates[fmt.Sprintf("iso_urls[%d]", i)] = &self.config.ISOUrls[i]
	}

	// Validation

	self.config.InstallTimeout, err = time.ParseDuration(self.config.RawInstallTimeout)
	if err != nil {
		errs = packer.MultiErrorAppend(
			errs, fmt.Errorf("Failed to parse install_timeout: %s", err))
	}

	if self.config.ISOName == "" {

		// If ISO name is not specified, assume a URL and checksum has been provided.

		if self.config.ISOChecksumType == "" {
			errs = packer.MultiErrorAppend(
				errs, errors.New("The iso_checksum_type must be specified."))
		} else {
			self.config.ISOChecksumType = strings.ToLower(self.config.ISOChecksumType)
			if self.config.ISOChecksumType != "none" {
				if self.config.ISOChecksum == "" {
					errs = packer.MultiErrorAppend(
						errs, errors.New("Due to the file size being large, an iso_checksum is required."))
				} else {
					self.config.ISOChecksum = strings.ToLower(self.config.ISOChecksum)
				}

				if hash := common.HashForType(self.config.ISOChecksumType); hash == nil {
					errs = packer.MultiErrorAppend(
						errs, fmt.Errorf("Unsupported checksum type: %s", self.config.ISOChecksumType))
				}

			}
		}

		if len(self.config.ISOUrls) == 0 {
			if self.config.ISOUrl == "" {
				errs = packer.MultiErrorAppend(
					errs, errors.New("One of iso_url or iso_urls must be specified."))
			} else {
				self.config.ISOUrls = []string{self.config.ISOUrl}
			}
		} else if self.config.ISOUrl != "" {
			errs = packer.MultiErrorAppend(
				errs, errors.New("Only one of iso_url or iso_urls may be specified."))
		}

		for i, url := range self.config.ISOUrls {
			self.config.ISOUrls[i], err = common.DownloadableURL(url)
			if err != nil {
				errs = packer.MultiErrorAppend(
					errs, fmt.Errorf("Failed to parse iso_urls[%d]: %s", i, err))
			}
		}
	} else {

		// An ISO name has been provided. It should be attached from an available SR.

	}

	if len(errs.Errors) > 0 {
		retErr = errors.New(errs.Error())
	}

	return nil, retErr

}

func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
	//Setup XAPI client
	client := xsclient.NewXenAPIClient(self.config.HostIp, self.config.Username, self.config.Password)

	err := client.Login()
	if err != nil {
		return nil, err.(error)
	}
	ui.Say("XAPI client session established")

	client.GetHosts()

	//Share state between the other steps using a statebag
	state := new(multistep.BasicStateBag)
	state.Put("cache", cache)
	state.Put("client", client)
	state.Put("config", self.config)
	state.Put("commonconfig", self.config.CommonConfig)
	state.Put("hook", hook)
	state.Put("ui", ui)

	httpReqChan := make(chan string, 1)

	//Build the steps
	download_steps := []multistep.Step{
		&common.StepDownload{
			Checksum:     self.config.ISOChecksum,
			ChecksumType: self.config.ISOChecksumType,
			Description:  "ISO",
			ResultKey:    "iso_path",
			Url:          self.config.ISOUrls,
		},
	}

	steps := []multistep.Step{
		&xscommon.StepPrepareOutputDir{
			Force: self.config.PackerForce,
			Path:  self.config.OutputDir,
		},
		&common.StepCreateFloppy{
			Files: self.config.FloppyFiles,
		},
		&xscommon.StepHTTPServer{
			Chan: httpReqChan,
		},
		&xscommon.StepUploadVdi{
			VdiNameFunc: func() string {
				return "Packer-floppy-disk"
			},
			ImagePathFunc: func() string {
				if floppyPath, ok := state.GetOk("floppy_path"); ok {
					return floppyPath.(string)
				}
				return ""
			},
			VdiUuidKey: "floppy_vdi_uuid",
		},
		&xscommon.StepUploadVdi{
			VdiNameFunc: func() string {
				if len(self.config.ISOUrls) > 0 {
					return path.Base(self.config.ISOUrls[0])
				}
				return ""
			},
			ImagePathFunc: func() string {
				if isoPath, ok := state.GetOk("iso_path"); ok {
					return isoPath.(string)
				}
				return ""
			},
			VdiUuidKey: "iso_vdi_uuid",
		},
		&xscommon.StepFindVdi{
			VdiName:    self.config.ToolsIsoName,
			VdiUuidKey: "tools_vdi_uuid",
		},
		&xscommon.StepFindVdi{
			VdiName:    self.config.ISOName,
			VdiUuidKey: "isoname_vdi_uuid",
		},
		new(stepCreateInstance),
		&xscommon.StepAttachVdi{
			VdiUuidKey: "floppy_vdi_uuid",
			VdiType:    xsclient.Floppy,
		},
		&xscommon.StepAttachVdi{
			VdiUuidKey: "iso_vdi_uuid",
			VdiType:    xsclient.CD,
		},
		&xscommon.StepAttachVdi{
			VdiUuidKey: "isoname_vdi_uuid",
			VdiType:    xsclient.CD,
		},
		&xscommon.StepAttachVdi{
			VdiUuidKey: "tools_vdi_uuid",
			VdiType:    xsclient.CD,
		},
		new(xscommon.StepStartVmPaused),
		new(xscommon.StepGetVNCPort),
		&xscommon.StepForwardPortOverSSH{
			RemotePort:  xscommon.InstanceVNCPort,
			RemoteDest:  xscommon.InstanceVNCIP,
			HostPortMin: self.config.HostPortMin,
			HostPortMax: self.config.HostPortMax,
			ResultKey:   "local_vnc_port",
		},
		new(xscommon.StepBootWait),
		&xscommon.StepTypeBootCommand{
			Ctx: self.config.ctx,
		},
		&xscommon.StepWaitForIP{
			Chan:    httpReqChan,
			Timeout: self.config.InstallTimeout, // @todo change this
		},
		&xscommon.StepForwardPortOverSSH{
			RemotePort:  xscommon.InstanceSSHPort,
			RemoteDest:  xscommon.InstanceSSHIP,
			HostPortMin: self.config.HostPortMin,
			HostPortMax: self.config.HostPortMax,
			ResultKey:   "local_ssh_port",
		},
		&communicator.StepConnect{
			Config:    &self.config.SSHConfig.Comm,
			Host:      xscommon.CommHost,
			SSHConfig: xscommon.SSHConfigFunc(self.config.CommonConfig.SSHConfig),
			SSHPort:   xscommon.SSHPort,
		},
		new(common.StepProvision),
		new(xscommon.StepShutdown),
		&xscommon.StepDetachVdi{
			VdiUuidKey: "iso_vdi_uuid",
		},
		&xscommon.StepDetachVdi{
			VdiUuidKey: "isoname_vdi_uuid",
		},
		&xscommon.StepDetachVdi{
			VdiUuidKey: "tools_vdi_uuid",
		},
		&xscommon.StepDetachVdi{
			VdiUuidKey: "floppy_vdi_uuid",
		},
		new(xscommon.StepExport),
	}

	if self.config.ISOName == "" {
		steps = append(download_steps, steps...)
	}

	self.runner = &multistep.BasicRunner{Steps: steps}
	self.runner.Run(state)

	if rawErr, ok := state.GetOk("error"); ok {
		return nil, rawErr.(error)
	}

	// If we were interrupted or cancelled, then just exit.
	if _, ok := state.GetOk(multistep.StateCancelled); ok {
		return nil, errors.New("Build was cancelled.")
	}
	if _, ok := state.GetOk(multistep.StateHalted); ok {
		return nil, errors.New("Build was halted.")
	}

	artifact, _ := xscommon.NewArtifact(self.config.OutputDir)

	return artifact, nil
}

func (self *Builder) Cancel() {
	if self.runner != nil {
		log.Println("Cancelling the step runner...")
		self.runner.Cancel()
	}
	fmt.Println("Cancelling the builder")
}
<|endoftext|>


<commit_before>// Copyright 2013 Prometheus Team
// 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 api

import (
	"encoding/json"
	"errors"
	"net/http"
	"sort"
	"time"

	"code.google.com/p/gorest"
	"github.com/golang/glog"

	clientmodel "github.com/prometheus/client_golang/model"

	"github.com/prometheus/prometheus/rules"
	"github.com/prometheus/prometheus/rules/ast"
	"github.com/prometheus/prometheus/stats"
)

func (serv MetricsService) setAccessControlHeaders(rb *gorest.ResponseBuilder) {
	rb.AddHeader("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Origin")
	rb.AddHeader("Access-Control-Allow-Methods", "GET")
	rb.AddHeader("Access-Control-Allow-Origin", "*")
	rb.AddHeader("Access-Control-Expose-Headers", "Date")
}

func (serv MetricsService) Query(expr string, asText string) string {
	exprNode, err := rules.LoadExprFromString(expr)
	if err != nil {
		return ast.ErrorToJSON(err)
	}

	timestamp := serv.time.Now()

	rb := serv.ResponseBuilder()
	serv.setAccessControlHeaders(rb)
	var format ast.OutputFormat
	// BUG(julius): Use Content-Type negotiation.
	if asText == "" {
		format = ast.JSON
		rb.SetContentType(gorest.Application_Json)
	} else {
		format = ast.TEXT
		rb.SetContentType(gorest.Text_Plain)
	}

	queryStats := stats.NewTimerGroup()
	result := ast.EvalToString(exprNode, timestamp, format, serv.Storage, queryStats)
	glog.Infof("Instant query: %s\nQuery stats:\n%s\n", expr, queryStats)
	return result
}

func (serv MetricsService) QueryRange(expr string, end int64, duration int64, step int64) string {
	exprNode, err := rules.LoadExprFromString(expr)
	if err != nil {
		return ast.ErrorToJSON(err)
	}
	if exprNode.Type() != ast.VECTOR {
		return ast.ErrorToJSON(errors.New("Expression does not evaluate to vector type"))
	}
	rb := serv.ResponseBuilder()
	serv.setAccessControlHeaders(rb)
	rb.SetContentType(gorest.Application_Json)

	if end == 0 {
		end = serv.time.Now().Unix()
	}

	if step < 1 {
		step = 1
	}

	if end-duration < 0 {
		duration = end
	}

	// Align the start to step "tick" boundary.
	end -= end % step

	queryStats := stats.NewTimerGroup()

	evalTimer := queryStats.GetTimer(stats.TotalEvalTime).Start()
	matrix, err := ast.EvalVectorRange(
		exprNode.(ast.VectorNode),
		time.Unix(end-duration, 0).UTC(),
		time.Unix(end, 0).UTC(),
		time.Duration(step)*time.Second,
		serv.Storage,
		queryStats)
	if err != nil {
		return ast.ErrorToJSON(err)
	}
	evalTimer.Stop()

	sortTimer := queryStats.GetTimer(stats.ResultSortTime).Start()
	sort.Sort(matrix)
	sortTimer.Stop()

	jsonTimer := queryStats.GetTimer(stats.JsonEncodeTime).Start()
	result := ast.TypedValueToJSON(matrix, "matrix")
	jsonTimer.Stop()

	glog.Infof("Range query: %s\nQuery stats:\n%s\n", expr, queryStats)
	return result
}

func (serv MetricsService) Metrics() string {
	metricNames, err := serv.Storage.GetAllValuesForLabel(clientmodel.MetricNameLabel)
	rb := serv.ResponseBuilder()
	serv.setAccessControlHeaders(rb)
	rb.SetContentType(gorest.Application_Json)
	if err != nil {
		glog.Error("Error loading metric names: ", err)
		rb.SetResponseCode(http.StatusInternalServerError)
		return err.Error()
	}
	sort.Sort(metricNames)
	resultBytes, err := json.Marshal(metricNames)
	if err != nil {
		glog.Error("Error marshalling metric names: ", err)
		rb.SetResponseCode(http.StatusInternalServerError)
		return err.Error()
	}
	return string(resultBytes)
}
<commit_msg>Always set CORS headers at beginning of API handler.<commit_after>// Copyright 2013 Prometheus Team
// 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 api

import (
	"encoding/json"
	"errors"
	"net/http"
	"sort"
	"time"

	"code.google.com/p/gorest"
	"github.com/golang/glog"

	clientmodel "github.com/prometheus/client_golang/model"

	"github.com/prometheus/prometheus/rules"
	"github.com/prometheus/prometheus/rules/ast"
	"github.com/prometheus/prometheus/stats"
)

func (serv MetricsService) setAccessControlHeaders(rb *gorest.ResponseBuilder) {
	rb.AddHeader("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Origin")
	rb.AddHeader("Access-Control-Allow-Methods", "GET")
	rb.AddHeader("Access-Control-Allow-Origin", "*")
	rb.AddHeader("Access-Control-Expose-Headers", "Date")
}

func (serv MetricsService) Query(expr string, asText string) string {
	rb := serv.ResponseBuilder()
	serv.setAccessControlHeaders(rb)

	exprNode, err := rules.LoadExprFromString(expr)
	if err != nil {
		return ast.ErrorToJSON(err)
	}

	timestamp := serv.time.Now()

	var format ast.OutputFormat
	// BUG(julius): Use Content-Type negotiation.
	if asText == "" {
		format = ast.JSON
		rb.SetContentType(gorest.Application_Json)
	} else {
		format = ast.TEXT
		rb.SetContentType(gorest.Text_Plain)
	}

	queryStats := stats.NewTimerGroup()
	result := ast.EvalToString(exprNode, timestamp, format, serv.Storage, queryStats)
	glog.Infof("Instant query: %s\nQuery stats:\n%s\n", expr, queryStats)
	return result
}

func (serv MetricsService) QueryRange(expr string, end int64, duration int64, step int64) string {
	rb := serv.ResponseBuilder()
	serv.setAccessControlHeaders(rb)

	exprNode, err := rules.LoadExprFromString(expr)
	if err != nil {
		return ast.ErrorToJSON(err)
	}
	if exprNode.Type() != ast.VECTOR {
		return ast.ErrorToJSON(errors.New("Expression does not evaluate to vector type"))
	}
	rb.SetContentType(gorest.Application_Json)

	if end == 0 {
		end = serv.time.Now().Unix()
	}

	if step < 1 {
		step = 1
	}

	if end-duration < 0 {
		duration = end
	}

	// Align the start to step "tick" boundary.
	end -= end % step

	queryStats := stats.NewTimerGroup()

	evalTimer := queryStats.GetTimer(stats.TotalEvalTime).Start()
	matrix, err := ast.EvalVectorRange(
		exprNode.(ast.VectorNode),
		time.Unix(end-duration, 0).UTC(),
		time.Unix(end, 0).UTC(),
		time.Duration(step)*time.Second,
		serv.Storage,
		queryStats)
	if err != nil {
		return ast.ErrorToJSON(err)
	}
	evalTimer.Stop()

	sortTimer := queryStats.GetTimer(stats.ResultSortTime).Start()
	sort.Sort(matrix)
	sortTimer.Stop()

	jsonTimer := queryStats.GetTimer(stats.JsonEncodeTime).Start()
	result := ast.TypedValueToJSON(matrix, "matrix")
	jsonTimer.Stop()

	glog.Infof("Range query: %s\nQuery stats:\n%s\n", expr, queryStats)
	return result
}

func (serv MetricsService) Metrics() string {
	rb := serv.ResponseBuilder()
	serv.setAccessControlHeaders(rb)

	metricNames, err := serv.Storage.GetAllValuesForLabel(clientmodel.MetricNameLabel)
	rb.SetContentType(gorest.Application_Json)
	if err != nil {
		glog.Error("Error loading metric names: ", err)
		rb.SetResponseCode(http.StatusInternalServerError)
		return err.Error()
	}
	sort.Sort(metricNames)
	resultBytes, err := json.Marshal(metricNames)
	if err != nil {
		glog.Error("Error marshalling metric names: ", err)
		rb.SetResponseCode(http.StatusInternalServerError)
		return err.Error()
	}
	return string(resultBytes)
}
<|endoftext|>


<commit_before>package sshego

import (
	"fmt"
	"math/rand"
	"sync"
	"time"

	ssh "github.com/glycerine/sshego/xendor/github.com/glycerine/xcryptossh"
)

// UHPTower is an 1:M non-blocking value-loadable channel.
//
// Each subscriber gets their own private channel, and it
// will get a copy of whatever is sent to UHPTower.
//
// Sends don't block, as subscribers are given buffered channels.
//
type UHPTower struct {
	subs   []chan *UHP
	mut    sync.Mutex
	closed bool

	halt *ssh.Halter
}

// NewUHPTower makes a new UHPTower.
func NewUHPTower(halt *ssh.Halter) *UHPTower {
	if halt == nil {
		halt = ssh.NewHalter()
	}
	tower := &UHPTower{
		halt: halt,
	}
	return tower
}

// Subscribe if given notify (notify is optional)
// will return notify and notify will receive
// all Broadcast values. If notify is nil, Subscribe
// will allocate a new channel and return that.
// When provided, notify must be a size 1 buffered
// or an unbuffered chan, or we panic.
func (b *UHPTower) Subscribe(notify chan *UHP) (ch chan *UHP) {
	b.mut.Lock()
	if notify == nil {
		ch = make(chan *UHP, 1)
	} else {
		if cap(notify) > 1 {
			panic("UHPTower.Subscribe error: notify must be a size 0 or 1 buffered channel")
		}
		ch = notify
	}
	b.subs = append(b.subs, ch)
	b.mut.Unlock()
	return ch
}

func (b *UHPTower) Unsub(x chan *UHP) {
	b.mut.Lock()
	defer b.mut.Unlock()

	// find it
	k := -1
	for i := range b.subs {
		if b.subs[i] == x {
			k = i
			break
		}
	}
	if k == -1 {
		// not found
		return
	}
	// found. delete it
	b.subs = append(b.subs[:k], b.subs[k+1:]...)
}

var ErrClosed = fmt.Errorf("channel closed")

// Broadcast sends a copy of val to all subs.
// Any old unreceived values are purged
// from the receive queues before sending.
// Since the receivers are all buffered
// channels, Broadcast should never block
// waiting on a receiver.
//
// Any subscriber who subscribes after the Broadcast will not
// receive the Broadcast value, as it is not
// stored internally.
//
func (b *UHPTower) Broadcast(val *UHP) error {
	b.mut.Lock()
	defer b.mut.Unlock()
	if b.closed {
		return ErrClosed
	}
	for i := range b.subs {
		// clear any old
		select {
		case <-b.subs[i]:
		default:
		}

		// apply the new
		select {
		case b.subs[i] <- val:
		case <-b.halt.ReqStopChan():
			return b.internalClose()
		case <-time.After(10 * time.Second):
			pp("UHPTower.Broadcast() blocked: could not send for 10 seconds.")
			// return or panic?
			panic("big problem: Broadcast blocked for 10 seconds! Prefer buffered channel of size 1 for Tower subscribe channels.")
		}
	}
	return nil
}

func (b *UHPTower) Signal(val *UHP) error {
	b.mut.Lock()
	defer b.mut.Unlock()
	if b.closed {
		return ErrClosed
	}
	n := len(b.subs)
	i := rand.Intn(n)
	b.subs[i] <- val
	return nil
}

func (b *UHPTower) Close() (err error) {
	b.mut.Lock()
	err = b.internalClose()
	b.mut.Unlock()
	return
}

// for internal use only, caller must have locked b.mut
func (b *UHPTower) internalClose() error {
	if b.closed {
		return ErrClosed
	}
	b.closed = true

	for i := range b.subs {
		close(b.subs[i])
	}
	b.halt.MarkDone()
	return nil
}

func (b *UHPTower) Clear() {
	b.mut.Lock()
	for i := range b.subs {
		select {
		case <-b.subs[i]:
		default:
		}
	}
	b.mut.Unlock()
}
<commit_msg>atg. buzz Subscribe allows unbuffered and any buffer size channels to be Subscribed.<commit_after>package sshego

import (
	"fmt"
	"math/rand"
	"sync"
	"time"

	ssh "github.com/glycerine/sshego/xendor/github.com/glycerine/xcryptossh"
)

// UHPTower is an 1:M non-blocking value-loadable channel.
//
// Each subscriber gets their own private channel, and it
// will get a copy of whatever is sent to UHPTower.
//
// Sends don't block, as subscribers are given buffered channels.
//
type UHPTower struct {
	subs   []chan *UHP
	mut    sync.Mutex
	closed bool

	halt *ssh.Halter
}

// NewUHPTower makes a new UHPTower.
func NewUHPTower(halt *ssh.Halter) *UHPTower {
	if halt == nil {
		halt = ssh.NewHalter()
	}
	tower := &UHPTower{
		halt: halt,
	}
	return tower
}

// Subscribe if given notify (notify is optional)
// will return notify and notify will receive
// all Broadcast values. If notify is nil, Subscribe
// will allocate a new channel and return that.
// When provided, notify should typically be a size 1 buffered
// chan. If other sizes of chan are used, be sure
// to service reads in a timely manner, or we
// will panic since Subscribe is meant to be
// non-blocking or minimally blocking for a very
// short time. Note that buffer size 1 channels
// are intended for lossy status: where if new
// status arrives before the old is read, it
// is desirable to discard the old and update
// to the new status value. To get non-lossy
// behavior, use an unbuffered notify or
// a buffer with size > 1. In both those
// cases, as above, you must arrange to
// service the channel promptly.
func (b *UHPTower) Subscribe(notify chan *UHP) (ch chan *UHP) {
	b.mut.Lock()
	if notify == nil {
		ch = make(chan *UHP, 1)
	} else {
		ch = notify
	}
	b.subs = append(b.subs, ch)
	b.mut.Unlock()
	return ch
}

func (b *UHPTower) Unsub(x chan *UHP) {
	b.mut.Lock()
	defer b.mut.Unlock()

	// find it
	k := -1
	for i := range b.subs {
		if b.subs[i] == x {
			k = i
			break
		}
	}
	if k == -1 {
		// not found
		return
	}
	// found. delete it
	b.subs = append(b.subs[:k], b.subs[k+1:]...)
}

var ErrClosed = fmt.Errorf("channel closed")

// Broadcast sends a copy of val to all subs.
// Any old unreceived values are purged
// from the receive queues before sending.
// Since the receivers are all buffered
// channels, Broadcast should never block
// waiting on a receiver.
//
// Any subscriber who subscribes after the Broadcast will not
// receive the Broadcast value, as it is not
// stored internally.
//
func (b *UHPTower) Broadcast(val *UHP) error {
	b.mut.Lock()
	defer b.mut.Unlock()
	if b.closed {
		return ErrClosed
	}
	for i := range b.subs {
		if cap(b.subs[i]) == 1 {
			// clear any old, so there is
			// space for the new without blocking.
			select {
			case <-b.subs[i]:
			default:
			}
		}

		// apply the new
		select {
		case b.subs[i] <- val:
		case <-b.halt.ReqStopChan():
			return b.internalClose()
		case <-time.After(10 * time.Second):
			pp("UHPTower.Broadcast() blocked: could not send for 10 seconds.")
			// return or panic?
			panic("big problem: Broadcast blocked for 10 seconds! Prefer buffered channel of size 1 for Tower subscribe channels.")
		}
	}
	return nil
}

func (b *UHPTower) Signal(val *UHP) error {
	b.mut.Lock()
	defer b.mut.Unlock()
	if b.closed {
		return ErrClosed
	}
	n := len(b.subs)
	i := rand.Intn(n)
	b.subs[i] <- val
	return nil
}

func (b *UHPTower) Close() (err error) {
	b.mut.Lock()
	err = b.internalClose()
	b.mut.Unlock()
	return
}

// for internal use only, caller must have locked b.mut
func (b *UHPTower) internalClose() error {
	if b.closed {
		return ErrClosed
	}
	b.closed = true

	for i := range b.subs {
		close(b.subs[i])
	}
	b.halt.MarkDone()
	return nil
}

func (b *UHPTower) Clear() {
	b.mut.Lock()
	for i := range b.subs {
		select {
		case <-b.subs[i]:
		default:
		}
	}
	b.mut.Unlock()
}
<|endoftext|>


<commit_before>// Copyright 2021 Google LLC
//
// 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 aggregatorservice contains the functions needed for handling the aggregation requests.
package aggregatorservice

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os/exec"
	"strings"

	log "github.com/golang/glog"
	"cloud.google.com/go/pubsub"
	"cloud.google.com/go/storage"
	"github.com/google/privacy-sandbox-aggregation-service/pipeline/ioutils"
	"github.com/google/privacy-sandbox-aggregation-service/service/query"
	"github.com/google/privacy-sandbox-aggregation-service/service/utils"
)

// DataflowCfg contains parameters necessary for running pipelines on Dataflow.
type DataflowCfg struct {
	Project         string
	Region          string
	TempLocation    string
	StagingLocation string
}

// ServerCfg contains file URIs necessary for the service.
type ServerCfg struct {
	PrivateKeyParamsURI             string
	DpfAggregatePartialReportBinary string
	WorkspaceURI                    string
}

// SharedInfoHandler handles HTTP requests for the information shared with other helpers.
type SharedInfoHandler struct {
	SharedInfo *query.HelperSharedInfo
}

func (h *SharedInfoHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	err := json.NewEncoder(w).Encode(h.SharedInfo)
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// QueryHandler handles the request in the pubsub messages.
type QueryHandler struct {
	ServerCfg                 ServerCfg
	PipelineRunner            string
	DataflowCfg               DataflowCfg
	Origin                    string
	SharedDir                 string
	RequestPubSubTopic        string
	RequestPubsubSubscription string

	PubSubTopicClient, PubSubSubscriptionClient *pubsub.Client
	GCSClient                                   *storage.Client
}

// Setup creates the cloud API clients.
func (h *QueryHandler) Setup(ctx context.Context) error {
	topicProject, _, err := utils.ParsePubSubResourceName(h.RequestPubSubTopic)
	if err != nil {
		return err
	}
	h.PubSubTopicClient, err = pubsub.NewClient(ctx, topicProject)
	if err != nil {
		return err
	}

	subscriptionProject, _, err := utils.ParsePubSubResourceName(h.RequestPubsubSubscription)
	if err != nil {
		return err
	}

	if subscriptionProject == topicProject {
		h.PubSubSubscriptionClient = h.PubSubTopicClient
	} else {
		h.PubSubSubscriptionClient, err = pubsub.NewClient(ctx, subscriptionProject)
		if err != nil {
			return err
		}

	}

	h.GCSClient, err = storage.NewClient(ctx)
	return err
}

// Close closes the cloud API clients.
func (h *QueryHandler) Close() {
	h.PubSubTopicClient.Close()
	h.PubSubSubscriptionClient.Close()
	h.GCSClient.Close()
}

// SetupPullRequests gets ready to pull requests contained in a PubSub message subscription, and handles the request.
func (h *QueryHandler) SetupPullRequests(ctx context.Context) error {
	_, subID, err := utils.ParsePubSubResourceName(h.RequestPubsubSubscription)
	if err != nil {
		return err
	}
	sub := h.PubSubSubscriptionClient.Subscription(subID)

	// Only allow pulling one message at a time to avoid overloading the memory.
	sub.ReceiveSettings.Synchronous = true
	sub.ReceiveSettings.MaxOutstandingMessages = 1
	return sub.Receive(ctx, func(ctx context.Context, msg *pubsub.Message) {
		request := &query.AggregateRequest{}
		err := json.Unmarshal(msg.Data, request)
		if err != nil {
			log.Error(err)
			msg.Nack()
			return
		}
		if err := h.aggregatePartialReportHierarchy(ctx, request); err != nil {
			log.Error(err)
			msg.Nack()
			return
		}
		msg.Ack()
	})
}

func getFinalPartialResultURI(resultDir, queryID, origin string) string {
	return ioutils.JoinPath(resultDir, fmt.Sprintf("%s_%s", queryID, strings.ReplaceAll(origin, ".", "_")))
}

func (h *QueryHandler) aggregatePartialReportHierarchy(ctx context.Context, request *query.AggregateRequest) error {
	config, err := query.ReadExpansionConfigFile(ctx, request.ExpandConfigURI)
	if err != nil {
		return nil
	}

	finalLevel := int32(len(config.PrefixLengths)) - 1
	if request.QueryLevel > finalLevel {
		return fmt.Errorf("expect request level <= finalLevel %d, got %d", finalLevel, request.QueryLevel)
	}

	partialReportURI := request.PartialReportURI
	outputDecryptedReportURI := ""
	if request.QueryLevel > 0 {
		// If it is not the first-level aggregation, check if the result from the partner helper is ready for the previous level.
		exist, err := utils.IsGCSObjectExist(ctx, h.GCSClient,
			query.GetRequestPartialResultURI(request.PartnerSharedInfo.SharedDir, request.QueryID, request.QueryLevel-1),
		)
		if err != nil {
			return err
		}
		if !exist {
			// When the partial result from the partner helper is not ready, nack the message with an error.
			return fmt.Errorf("result from %s for level %d of query %s is not ready", request.PartnerSharedInfo.Origin, request.QueryLevel-1, request.QueryID)
		}

		// If it is not the first-level aggregation, the pipeline should read the decrypted reports instead of the original encrypted ones.
		partialReportURI = query.GetRequestDecryptedReportURI(h.ServerCfg.WorkspaceURI, request.QueryID)
	} else {
		outputDecryptedReportURI = query.GetRequestDecryptedReportURI(h.ServerCfg.WorkspaceURI, request.QueryID)
	}

	expandParamsURI, err := query.GetRequestExpandParamsURI(ctx, config, request,
		h.ServerCfg.WorkspaceURI,
		h.SharedDir,
		request.PartnerSharedInfo.SharedDir,
	)
	if err != nil {
		return err
	}

	var outputResultURI string
	// The final-level results are not supposed to be shared with the partner helpers.
	if request.QueryLevel == finalLevel {
		outputResultURI = getFinalPartialResultURI(request.ResultDir, request.QueryID, h.Origin)
	} else {
		outputResultURI = query.GetRequestPartialResultURI(h.SharedDir, request.QueryID, request.QueryLevel)
	}

	args := []string{
		"--partial_report_uri=" + partialReportURI,
		"--expand_parameters_uri=" + expandParamsURI,
		"--partial_histogram_uri=" + outputResultURI,
		"--decrypted_report_uri=" + outputDecryptedReportURI,
		"--epsilon=" + fmt.Sprintf("%f", request.TotalEpsilon*config.PrivacyBudgetPerPrefix[request.QueryLevel]),
		"--private_key_params_uri=" + h.ServerCfg.PrivateKeyParamsURI,
		"--runner=" + h.PipelineRunner,
	}

	if h.PipelineRunner == "dataflow" {
		args = append(args,
			"--project="+h.DataflowCfg.Project,
			"--region="+h.DataflowCfg.Region,
			"--temp_location="+h.DataflowCfg.TempLocation,
			"--staging_location="+h.DataflowCfg.StagingLocation,
			"--worker_binary="+h.ServerCfg.DpfAggregatePartialReportBinary,
		)
	}

	str := h.ServerCfg.DpfAggregatePartialReportBinary
	for _, s := range args {
		str = fmt.Sprintf("%s\n%s", str, s)
	}
	log.Infof("Running command\n%s", str)

	cmd := exec.CommandContext(ctx, h.ServerCfg.DpfAggregatePartialReportBinary, args...)
	var out bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &stderr
	err = cmd.Run()
	if err != nil {
		log.Errorf("%s: %s", err, stderr.String())
		return err
	}
	log.Infof("output of cmd: %s", out.String())

	if request.QueryLevel == finalLevel {
		log.Infof("query %q complete", request.QueryID)
		return nil
	}

	// If the hierarchical query is not finished yet, publish the requests for the next-level aggregation.
	request.QueryLevel++
	_, topic, err := utils.ParsePubSubResourceName(h.RequestPubSubTopic)
	if err != nil {
		return err
	}
	return utils.PublishRequest(ctx, h.PubSubTopicClient, topic, request)
}

// ReadHelperSharedInfo reads the helper shared info from a URL.
func ReadHelperSharedInfo(client *http.Client, url, token string) (*query.HelperSharedInfo, error) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}

	if token != "" {
		req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
	}

	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.Status != "200 OK" {
		body, _ := ioutil.ReadAll(resp.Body)
		log.Infof("%v: %s", resp.Status, string(body))
		return nil, fmt.Errorf("Error reading shared info from %s: %s", url, resp.Status)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	info := &query.HelperSharedInfo{}
	if err := json.Unmarshal([]byte(body), info); err != nil {
		return nil, err
	}
	return info, nil
}
<commit_msg>Set job name of dataflow jobs to identifiable name<commit_after>// Copyright 2021 Google LLC
//
// 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 aggregatorservice contains the functions needed for handling the aggregation requests.
package aggregatorservice

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os/exec"
	"strings"

	log "github.com/golang/glog"
	"cloud.google.com/go/pubsub"
	"cloud.google.com/go/storage"
	"github.com/google/privacy-sandbox-aggregation-service/pipeline/ioutils"
	"github.com/google/privacy-sandbox-aggregation-service/service/query"
	"github.com/google/privacy-sandbox-aggregation-service/service/utils"
)

// DataflowCfg contains parameters necessary for running pipelines on Dataflow.
type DataflowCfg struct {
	Project         string
	Region          string
	TempLocation    string
	StagingLocation string
}

// ServerCfg contains file URIs necessary for the service.
type ServerCfg struct {
	PrivateKeyParamsURI             string
	DpfAggregatePartialReportBinary string
	WorkspaceURI                    string
}

// SharedInfoHandler handles HTTP requests for the information shared with other helpers.
type SharedInfoHandler struct {
	SharedInfo *query.HelperSharedInfo
}

func (h *SharedInfoHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	err := json.NewEncoder(w).Encode(h.SharedInfo)
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// QueryHandler handles the request in the pubsub messages.
type QueryHandler struct {
	ServerCfg                 ServerCfg
	PipelineRunner            string
	DataflowCfg               DataflowCfg
	Origin                    string
	SharedDir                 string
	RequestPubSubTopic        string
	RequestPubsubSubscription string

	PubSubTopicClient, PubSubSubscriptionClient *pubsub.Client
	GCSClient                                   *storage.Client
}

// Setup creates the cloud API clients.
func (h *QueryHandler) Setup(ctx context.Context) error {
	topicProject, _, err := utils.ParsePubSubResourceName(h.RequestPubSubTopic)
	if err != nil {
		return err
	}
	h.PubSubTopicClient, err = pubsub.NewClient(ctx, topicProject)
	if err != nil {
		return err
	}

	subscriptionProject, _, err := utils.ParsePubSubResourceName(h.RequestPubsubSubscription)
	if err != nil {
		return err
	}

	if subscriptionProject == topicProject {
		h.PubSubSubscriptionClient = h.PubSubTopicClient
	} else {
		h.PubSubSubscriptionClient, err = pubsub.NewClient(ctx, subscriptionProject)
		if err != nil {
			return err
		}

	}

	h.GCSClient, err = storage.NewClient(ctx)
	return err
}

// Close closes the cloud API clients.
func (h *QueryHandler) Close() {
	h.PubSubTopicClient.Close()
	h.PubSubSubscriptionClient.Close()
	h.GCSClient.Close()
}

// SetupPullRequests gets ready to pull requests contained in a PubSub message subscription, and handles the request.
func (h *QueryHandler) SetupPullRequests(ctx context.Context) error {
	_, subID, err := utils.ParsePubSubResourceName(h.RequestPubsubSubscription)
	if err != nil {
		return err
	}
	sub := h.PubSubSubscriptionClient.Subscription(subID)

	// Only allow pulling one message at a time to avoid overloading the memory.
	sub.ReceiveSettings.Synchronous = true
	sub.ReceiveSettings.MaxOutstandingMessages = 1
	return sub.Receive(ctx, func(ctx context.Context, msg *pubsub.Message) {
		request := &query.AggregateRequest{}
		err := json.Unmarshal(msg.Data, request)
		if err != nil {
			log.Error(err)
			msg.Nack()
			return
		}
		if err := h.aggregatePartialReportHierarchy(ctx, request); err != nil {
			log.Error(err)
			msg.Nack()
			return
		}
		msg.Ack()
	})
}

func getFinalPartialResultURI(resultDir, queryID, origin string) string {
	return ioutils.JoinPath(resultDir, fmt.Sprintf("%s_%s", queryID, strings.ReplaceAll(origin, ".", "_")))
}

func (h *QueryHandler) aggregatePartialReportHierarchy(ctx context.Context, request *query.AggregateRequest) error {
	config, err := query.ReadExpansionConfigFile(ctx, request.ExpandConfigURI)
	if err != nil {
		return nil
	}

	finalLevel := int32(len(config.PrefixLengths)) - 1
	if request.QueryLevel > finalLevel {
		return fmt.Errorf("expect request level <= finalLevel %d, got %d", finalLevel, request.QueryLevel)
	}

	partialReportURI := request.PartialReportURI
	outputDecryptedReportURI := ""
	if request.QueryLevel > 0 {
		// If it is not the first-level aggregation, check if the result from the partner helper is ready for the previous level.
		exist, err := utils.IsGCSObjectExist(ctx, h.GCSClient,
			query.GetRequestPartialResultURI(request.PartnerSharedInfo.SharedDir, request.QueryID, request.QueryLevel-1),
		)
		if err != nil {
			return err
		}
		if !exist {
			// When the partial result from the partner helper is not ready, nack the message with an error.
			return fmt.Errorf("result from %s for level %d of query %s is not ready", request.PartnerSharedInfo.Origin, request.QueryLevel-1, request.QueryID)
		}

		// If it is not the first-level aggregation, the pipeline should read the decrypted reports instead of the original encrypted ones.
		partialReportURI = query.GetRequestDecryptedReportURI(h.ServerCfg.WorkspaceURI, request.QueryID)
	} else {
		outputDecryptedReportURI = query.GetRequestDecryptedReportURI(h.ServerCfg.WorkspaceURI, request.QueryID)
	}

	expandParamsURI, err := query.GetRequestExpandParamsURI(ctx, config, request,
		h.ServerCfg.WorkspaceURI,
		h.SharedDir,
		request.PartnerSharedInfo.SharedDir,
	)
	if err != nil {
		return err
	}

	var outputResultURI string
	// The final-level results are not supposed to be shared with the partner helpers.
	if request.QueryLevel == finalLevel {
		outputResultURI = getFinalPartialResultURI(request.ResultDir, request.QueryID, h.Origin)
	} else {
		outputResultURI = query.GetRequestPartialResultURI(h.SharedDir, request.QueryID, request.QueryLevel)
	}

	args := []string{
		"--partial_report_uri=" + partialReportURI,
		"--expand_parameters_uri=" + expandParamsURI,
		"--partial_histogram_uri=" + outputResultURI,
		"--decrypted_report_uri=" + outputDecryptedReportURI,
		"--epsilon=" + fmt.Sprintf("%f", request.TotalEpsilon*config.PrivacyBudgetPerPrefix[request.QueryLevel]),
		"--private_key_params_uri=" + h.ServerCfg.PrivateKeyParamsURI,
		"--runner=" + h.PipelineRunner,
	}

	if h.PipelineRunner == "dataflow" {
		args = append(args,
			"--project="+h.DataflowCfg.Project,
			"--region="+h.DataflowCfg.Region,
			"--temp_location="+h.DataflowCfg.TempLocation,
			"--staging_location="+h.DataflowCfg.StagingLocation,
			// set jobname to queryID-level-origin
			"--job_name="+fmt.Sprintf("%s-%v-%s", request.QueryID, request.QueryLevel, h.Origin),
			"--worker_binary="+h.ServerCfg.DpfAggregatePartialReportBinary,
		)
	}

	str := h.ServerCfg.DpfAggregatePartialReportBinary
	for _, s := range args {
		str = fmt.Sprintf("%s\n%s", str, s)
	}
	log.Infof("Running command\n%s", str)

	cmd := exec.CommandContext(ctx, h.ServerCfg.DpfAggregatePartialReportBinary, args...)
	var out bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &stderr
	err = cmd.Run()
	if err != nil {
		log.Errorf("%s: %s", err, stderr.String())
		return err
	}
	log.Infof("output of cmd: %s", out.String())

	if request.QueryLevel == finalLevel {
		log.Infof("query %q complete", request.QueryID)
		return nil
	}

	// If the hierarchical query is not finished yet, publish the requests for the next-level aggregation.
	request.QueryLevel++
	_, topic, err := utils.ParsePubSubResourceName(h.RequestPubSubTopic)
	if err != nil {
		return err
	}
	return utils.PublishRequest(ctx, h.PubSubTopicClient, topic, request)
}

// ReadHelperSharedInfo reads the helper shared info from a URL.
func ReadHelperSharedInfo(client *http.Client, url, token string) (*query.HelperSharedInfo, error) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}

	if token != "" {
		req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
	}

	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.Status != "200 OK" {
		body, _ := ioutil.ReadAll(resp.Body)
		log.Infof("%v: %s", resp.Status, string(body))
		return nil, fmt.Errorf("Error reading shared info from %s: %s", url, resp.Status)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	info := &query.HelperSharedInfo{}
	if err := json.Unmarshal([]byte(body), info); err != nil {
		return nil, err
	}
	return info, nil
}
<|endoftext|>


<commit_before>package main
import (
	"github.com/APTrust/bagman/dpn"
	"github.com/APTrust/bagman/workers"
)

// dpn_package builds a DPN bag from an APTrust object.
func main() {
	procUtil := workers.CreateProcUtil()
	procUtil.MessageLog.Info("Connecting to NSQLookupd at %s", procUtil.Config.NsqLookupd)
	procUtil.MessageLog.Info("NSQDHttpAddress is %s", procUtil.Config.NsqdHttpAddress)
	consumer, err := workers.CreateNsqConsumer(&procUtil.Config, &procUtil.Config.DPNPackageWorker)
	if err != nil {
		procUtil.MessageLog.Fatal(err.Error())
	}
	procUtil.MessageLog.Info("dpn_package started")
	dpnConfig, err := dpn.LoadConfig("dpn/bagbuilder_config.json")
	if err != nil {
		procUtil.MessageLog.Fatal(err.Error())
	}
	packager := dpn.NewPackager(procUtil, dpnConfig.DefaultMetadata)
	consumer.AddHandler(packager)
	consumer.ConnectToNSQLookupd(procUtil.Config.NsqLookupd)

	// This reader blocks until we get an interrupt, so our program does not exit.
	<-consumer.StopChan

}
<commit_msg>Fixed build error<commit_after>package main
import (
	"github.com/APTrust/bagman/dpn"
	"github.com/APTrust/bagman/workers"
)

// dpn_package builds a DPN bag from an APTrust object.
func main() {
	procUtil := workers.CreateProcUtil()
	procUtil.MessageLog.Info("Connecting to NSQLookupd at %s", procUtil.Config.NsqLookupd)
	procUtil.MessageLog.Info("NSQDHttpAddress is %s", procUtil.Config.NsqdHttpAddress)
	consumer, err := workers.CreateNsqConsumer(&procUtil.Config, &procUtil.Config.DPNPackageWorker)
	if err != nil {
		procUtil.MessageLog.Fatal(err.Error())
	}
	procUtil.MessageLog.Info("dpn_package started")
	dpnConfig, err := dpn.LoadConfig("dpn/bagbuilder_config.json")
	if err != nil {
		procUtil.MessageLog.Fatal(err.Error())
	}
	packager := dpn.NewPackager(procUtil, dpnConfig)
	consumer.AddHandler(packager)
	consumer.ConnectToNSQLookupd(procUtil.Config.NsqLookupd)

	// This reader blocks until we get an interrupt, so our program does not exit.
	<-consumer.StopChan

}
<|endoftext|>


<commit_before>package audio

import (
	"encoding/binary"
	"errors"
	"github.com/gordonklaus/portaudio"
	"os"
	"time"
)

type action int
type Status int

type Recording struct {
	path        string
	streamInfo  portaudio.StreamParameters
	stream      *portaudio.Stream
	startedAt   time.Time
	file        *os.File
	err         error
	channels    int
	sampleSize  int
	buffer      portaudio.Buffer
	actionQueue chan action
	status      Status
	frameCount  int
}

// States for the recording
const (
	RECORDING Status = iota
	STOPPED
	PENDING
)

func (s Status) String() string {
	switch s {
	case RECORDING:
		return "Recording"
	case STOPPED:
		return "Stopped"
	case PENDING:
		return "Pending"
	default:
		return "Unknown"
	}
}

const (
	stop action = iota
	pause
)

const (
	aiffFORMSize       = 4
	aiffCOMMSize       = 8 + 18
	aiffSSNDHeaderSize = 16
	paBufferSize       = 128
)

func (r *Recording) Start() error {
	r.file, r.err = os.Create(r.path)
	f := r.file
	if r.err != nil {
		return r.err
	}
	// Form Chunk
	_, r.err = f.WriteString("FORM")
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(0))
	if r.err != nil {
		return r.err
	}
	_, r.err = f.WriteString("AIFF")
	if r.err != nil {
		return r.err
	}
	// Common Chunk
	_, r.err = f.WriteString("COMM")
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(18))
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int16(r.channels))
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(0))
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int16(r.sampleSize))
	if r.err != nil {
		return r.err
	}
	_, r.err = f.Write([]byte{0x40, 0x0e, 0xac, 0x44, 0, 0, 0, 0, 0, 0})
	if r.err != nil {
		return r.err
	}
	// Sound Data Chunk
	_, r.err = f.WriteString("SSND")
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(0))
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(0))
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(0))
	if r.err != nil {
		return r.err
	}
	r.startedAt = time.Now()
	switch r.sampleSize {
	case 32:
		tmpBuffer := make([]int32, r.channels*paBufferSize)
		r.buffer = tmpBuffer
	case 24:
		tmpBuffer := make([]portaudio.Int24, r.channels*paBufferSize)
		r.buffer = tmpBuffer
	case 16:
		tmpBuffer := make([]int16, r.channels*paBufferSize)
		r.buffer = tmpBuffer
	case 8:
		tmpBuffer := make([]int8, r.channels*paBufferSize)
		r.buffer = tmpBuffer
	default:
		r.err = errors.New("Invalid sample size")
		return r.err
	}
	go r.run()
	return nil
}

func (r *Recording) run() {
	r.frameCount = 0
	f := r.file
	defer func() {
		if r.err != nil {
			return
		}
		bytesPerSample := r.sampleSize / 8
		audioSize := r.frameCount * r.channels * bytesPerSample
		totalSize := aiffCOMMSize + aiffSSNDHeaderSize + audioSize + aiffFORMSize
		_, r.err = f.Seek(4, 0)
		if r.err != nil {
			return
		}
		r.err = binary.Write(f, binary.BigEndian, int32(totalSize))
		if r.err != nil {
			return
		}
		_, r.err = f.Seek(22, 0)
		if r.err != nil {
			return
		}
		r.err = binary.Write(f, binary.BigEndian, int32(frameCount))
		if r.err != nil {
			return
		}
		_, r.err = f.Seek(42, 0)
		if r.err != nil {
			return
		}
		r.err = binary.Write(f, binary.BigEndian, int32(audioSize+8))
		if r.err != nil {
			return
		}
		r.err = f.Close()
		r.stream.Close()
		r.status = STOPPED
	}()
	r.stream, r.err = portaudio.OpenStream(r.streamInfo, r.buffer)
	if r.err != nil {
		return
	}
	r.status = RECORDING
	r.err = r.stream.Start()
	if r.err != nil {
		return
	}
	for {
		r.stream.Read()
		switch r.sampleSize {
		case 32:
			tmpBuffer := r.buffer.([]int32)
			l := len(tmpBuffer) / r.channels
			r.err = binary.Write(f, binary.BigEndian, tmpBuffer)
			if r.err != nil {
				return
			}
			r.frameCount += l
		case 24:
			tmpBuffer := r.buffer.([]portaudio.Int24)
			l := len(tmpBuffer) / r.channels
			r.err = binary.Write(f, binary.BigEndian, tmpBuffer)
			if r.err != nil {
				return
			}
			r.frameCount += l
		case 16:
			tmpBuffer := r.buffer.([]int16)
			l := len(tmpBuffer) / r.channels
			r.err = binary.Write(f, binary.BigEndian, tmpBuffer)
			if r.err != nil {
				return
			}
			r.frameCount += l
		case 8:
			tmpBuffer := r.buffer.([]int8)
			l := len(tmpBuffer) / r.channels
			r.err = binary.Write(f, binary.BigEndian, tmpBuffer)
			if r.err != nil {
				return
			}
			r.frameCount += l
		default:
			r.err = errors.New("Invalid sample size")
			return
		}
		select {
		case <-r.actionQueue:
			return
		default:

		}
	}
}

func (r *Recording) Stop() {
	r.actionQueue <- stop
}

func (r *Recording) Status() Status {
	return r.status
}

func (r *Recording) Duration() time.Duration {
	nanoseconds := (float64(r.frameCount) / 44100) * float64(time.Second)
	return time.Duration(nanoseconds)
}

func NewRecording(path string, params portaudio.StreamParameters, channels, sampleSize int) *Recording {
	r := new(Recording)
	r.path = path
	r.actionQueue = make(chan action, 1)
	r.channels = channels
	r.sampleSize = sampleSize
	r.status = PENDING
	r.streamInfo = params
	return r
}

func (r *Recording) Error() error {
	return r.err
}
<commit_msg>Fix broken reference to frameCount from refactor<commit_after>package audio

import (
	"encoding/binary"
	"errors"
	"github.com/gordonklaus/portaudio"
	"os"
	"time"
)

type action int
type Status int

type Recording struct {
	path        string
	streamInfo  portaudio.StreamParameters
	stream      *portaudio.Stream
	startedAt   time.Time
	file        *os.File
	err         error
	channels    int
	sampleSize  int
	buffer      portaudio.Buffer
	actionQueue chan action
	status      Status
	frameCount  int
}

// States for the recording
const (
	RECORDING Status = iota
	STOPPED
	PENDING
)

func (s Status) String() string {
	switch s {
	case RECORDING:
		return "Recording"
	case STOPPED:
		return "Stopped"
	case PENDING:
		return "Pending"
	default:
		return "Unknown"
	}
}

const (
	stop action = iota
	pause
)

const (
	aiffFORMSize       = 4
	aiffCOMMSize       = 8 + 18
	aiffSSNDHeaderSize = 16
	paBufferSize       = 128
)

func (r *Recording) Start() error {
	r.file, r.err = os.Create(r.path)
	f := r.file
	if r.err != nil {
		return r.err
	}
	// Form Chunk
	_, r.err = f.WriteString("FORM")
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(0))
	if r.err != nil {
		return r.err
	}
	_, r.err = f.WriteString("AIFF")
	if r.err != nil {
		return r.err
	}
	// Common Chunk
	_, r.err = f.WriteString("COMM")
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(18))
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int16(r.channels))
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(0))
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int16(r.sampleSize))
	if r.err != nil {
		return r.err
	}
	_, r.err = f.Write([]byte{0x40, 0x0e, 0xac, 0x44, 0, 0, 0, 0, 0, 0})
	if r.err != nil {
		return r.err
	}
	// Sound Data Chunk
	_, r.err = f.WriteString("SSND")
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(0))
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(0))
	if r.err != nil {
		return r.err
	}
	r.err = binary.Write(f, binary.BigEndian, int32(0))
	if r.err != nil {
		return r.err
	}
	r.startedAt = time.Now()
	switch r.sampleSize {
	case 32:
		tmpBuffer := make([]int32, r.channels*paBufferSize)
		r.buffer = tmpBuffer
	case 24:
		tmpBuffer := make([]portaudio.Int24, r.channels*paBufferSize)
		r.buffer = tmpBuffer
	case 16:
		tmpBuffer := make([]int16, r.channels*paBufferSize)
		r.buffer = tmpBuffer
	case 8:
		tmpBuffer := make([]int8, r.channels*paBufferSize)
		r.buffer = tmpBuffer
	default:
		r.err = errors.New("Invalid sample size")
		return r.err
	}
	go r.run()
	return nil
}

func (r *Recording) run() {
	r.frameCount = 0
	f := r.file
	defer func() {
		if r.err != nil {
			return
		}
		bytesPerSample := r.sampleSize / 8
		audioSize := r.frameCount * r.channels * bytesPerSample
		totalSize := aiffCOMMSize + aiffSSNDHeaderSize + audioSize + aiffFORMSize
		_, r.err = f.Seek(4, 0)
		if r.err != nil {
			return
		}
		r.err = binary.Write(f, binary.BigEndian, int32(totalSize))
		if r.err != nil {
			return
		}
		_, r.err = f.Seek(22, 0)
		if r.err != nil {
			return
		}
		r.err = binary.Write(f, binary.BigEndian, int32(r.frameCount))
		if r.err != nil {
			return
		}
		_, r.err = f.Seek(42, 0)
		if r.err != nil {
			return
		}
		r.err = binary.Write(f, binary.BigEndian, int32(audioSize+8))
		if r.err != nil {
			return
		}
		r.err = f.Close()
		r.stream.Close()
		r.status = STOPPED
	}()
	r.stream, r.err = portaudio.OpenStream(r.streamInfo, r.buffer)
	if r.err != nil {
		return
	}
	r.status = RECORDING
	r.err = r.stream.Start()
	if r.err != nil {
		return
	}
	for {
		r.stream.Read()
		switch r.sampleSize {
		case 32:
			tmpBuffer := r.buffer.([]int32)
			l := len(tmpBuffer) / r.channels
			r.err = binary.Write(f, binary.BigEndian, tmpBuffer)
			if r.err != nil {
				return
			}
			r.frameCount += l
		case 24:
			tmpBuffer := r.buffer.([]portaudio.Int24)
			l := len(tmpBuffer) / r.channels
			r.err = binary.Write(f, binary.BigEndian, tmpBuffer)
			if r.err != nil {
				return
			}
			r.frameCount += l
		case 16:
			tmpBuffer := r.buffer.([]int16)
			l := len(tmpBuffer) / r.channels
			r.err = binary.Write(f, binary.BigEndian, tmpBuffer)
			if r.err != nil {
				return
			}
			r.frameCount += l
		case 8:
			tmpBuffer := r.buffer.([]int8)
			l := len(tmpBuffer) / r.channels
			r.err = binary.Write(f, binary.BigEndian, tmpBuffer)
			if r.err != nil {
				return
			}
			r.frameCount += l
		default:
			r.err = errors.New("Invalid sample size")
			return
		}
		select {
		case <-r.actionQueue:
			return
		default:

		}
	}
}

func (r *Recording) Stop() {
	r.actionQueue <- stop
}

func (r *Recording) Status() Status {
	return r.status
}

func (r *Recording) Duration() time.Duration {
	nanoseconds := (float64(r.frameCount) / 44100) * float64(time.Second)
	return time.Duration(nanoseconds)
}

func NewRecording(path string, params portaudio.StreamParameters, channels, sampleSize int) *Recording {
	r := new(Recording)
	r.path = path
	r.actionQueue = make(chan action, 1)
	r.channels = channels
	r.sampleSize = sampleSize
	r.status = PENDING
	r.streamInfo = params
	return r
}

func (r *Recording) Error() error {
	return r.err
}
<|endoftext|>


<commit_before>package audited

import "fmt"

type AuditedModel struct {
	CreatedBy string
	UpdatedBy string
}

func (model *AuditedModel) SetCreatedBy(createdBy interface{}) {
	model.CreatedBy = fmt.Sprintf("%v", createdBy)
}

func (model AuditedModel) GetCreatedBy() string {
	return model.CreatedBy
}

func (model *AuditedModel) SetUpdatedBy(updatedBy interface{}) {
	model.UpdatedBy = fmt.Sprintf("%v", updatedBy)
}

func (model AuditedModel) GetUpdatedBy() string {
	return model.UpdatedBy
}

// type Audited struct {
// 	gorm.Model
// 	ReferTable    string
// 	ReferId       string
// 	Action        string
// 	ChangeDetails string `sql:"size:65532"`
// 	Comment       string `sql:"size:1024"`
// }
<commit_msg>Set audited:current_user in middleware<commit_after>package audited

import (
	"fmt"

	"github.com/qor/qor/admin"
)

type AuditedModel struct {
	CreatedBy string
	UpdatedBy string
}

func (model *AuditedModel) SetCreatedBy(createdBy interface{}) {
	model.CreatedBy = fmt.Sprintf("%v", createdBy)
}

func (model AuditedModel) GetCreatedBy() string {
	return model.CreatedBy
}

func (model *AuditedModel) SetUpdatedBy(updatedBy interface{}) {
	model.UpdatedBy = fmt.Sprintf("%v", updatedBy)
}

func (model AuditedModel) GetUpdatedBy() string {
	return model.UpdatedBy
}

// type Audited struct {
// 	gorm.Model
// 	ReferTable    string
// 	ReferId       string
// 	Action        string
// 	ChangeDetails string `sql:"size:65532"`
// 	Comment       string `sql:"size:1024"`
// }

func (model *AuditedModel) InjectQorAdmin(res *admin.Resource) {
	// Middleware
	res.GetAdmin().GetRouter().Use(func(context *admin.Context, middleware *admin.Middleware) {
		context.SetDB(context.GetDB().Set("audited:current_user", context.CurrentUser))
		middleware.Next(context)
	})
}
<|endoftext|>


<commit_before>package user

import (
	"github.com/cloudfoundry/cli/cf/api"
	"github.com/cloudfoundry/cli/cf/api/feature_flags"
	"github.com/cloudfoundry/cli/cf/command_registry"
	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	. "github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/models"
	"github.com/cloudfoundry/cli/cf/requirements"
	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/simonleung8/flags"
)

type SetOrgRole struct {
	ui       terminal.UI
	config   core_config.Reader
	flagRepo feature_flags.FeatureFlagRepository
	userRepo api.UserRepository
	userReq  requirements.UserRequirement
	orgReq   requirements.OrganizationRequirement
}

func init() {
	command_registry.Register(&SetOrgRole{})
}

func (cmd *SetOrgRole) MetaData() command_registry.CommandMetadata {
	return command_registry.CommandMetadata{
		Name:        "set-org-role",
		Description: T("Assign an org role to a user"),
		Usage: T("CF_NAME set-org-role USERNAME ORG ROLE\n\n") +
			T("ROLES:\n") +
			T("   OrgManager - Invite and manage users, select and change plans, and set spending limits\n") +
			T("   BillingManager - Create and manage the billing account and payment info\n") +
			T("   OrgAuditor - Read-only access to org info and reports\n"),
	}
}

func (cmd *SetOrgRole) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) ([]requirements.Requirement, error) {
	if len(fc.Args()) != 3 {
		cmd.ui.Failed(T("Incorrect Usage. Requires USERNAME, ORG, ROLE as arguments\n\n") + command_registry.Commands.CommandUsage("set-org-role"))
	}

	var wantGuid bool
	if cmd.config.IsMinApiVersion("2.37.0") {
		setRolesByUsernameFlag, err := cmd.flagRepo.FindByName("set_roles_by_username")
		wantGuid = (err != nil || !setRolesByUsernameFlag.Enabled)
	} else {
		wantGuid = true
	}

	cmd.userReq = requirementsFactory.NewUserRequirement(fc.Args()[0], wantGuid)
	cmd.orgReq = requirementsFactory.NewOrganizationRequirement(fc.Args()[1])

	reqs := []requirements.Requirement{
		requirementsFactory.NewLoginRequirement(),
		cmd.userReq,
		cmd.orgReq,
	}

	return reqs, nil
}

func (cmd *SetOrgRole) SetDependency(deps command_registry.Dependency, pluginCall bool) command_registry.Command {
	cmd.ui = deps.Ui
	cmd.config = deps.Config
	cmd.userRepo = deps.RepoLocator.GetUserRepository()
	cmd.flagRepo = deps.RepoLocator.GetFeatureFlagRepository()
	return cmd
}

func (cmd *SetOrgRole) Execute(c flags.FlagContext) {
	user := cmd.userReq.GetUser()
	org := cmd.orgReq.GetOrganization()
	role := models.UserInputToOrgRole[c.Args()[2]]

	cmd.ui.Say(T("Assigning role {{.Role}} to user {{.TargetUser}} in org {{.TargetOrg}} as {{.CurrentUser}}...",
		map[string]interface{}{
			"Role":        terminal.EntityNameColor(role),
			"TargetUser":  terminal.EntityNameColor(user.Username),
			"TargetOrg":   terminal.EntityNameColor(org.Name),
			"CurrentUser": terminal.EntityNameColor(cmd.config.Username()),
		}))

	var err error
	if len(user.Guid) > 0 {
		err = cmd.userRepo.SetOrgRoleByGuid(user.Guid, org.Guid, role)
	} else {
		err = cmd.userRepo.SetOrgRoleByUsername(user.Username, org.Guid, role)
	}

	if err != nil {
		cmd.ui.Failed(err.Error())
	}

	cmd.ui.Ok()
}
<commit_msg>refactor set_org_role command into interface<commit_after>package user

import (
	"github.com/cloudfoundry/cli/cf/api"
	"github.com/cloudfoundry/cli/cf/api/feature_flags"
	"github.com/cloudfoundry/cli/cf/command_registry"
	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	. "github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/models"
	"github.com/cloudfoundry/cli/cf/requirements"
	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/simonleung8/flags"
)

type OrgRoleSetter interface {
	command_registry.Command
	SetOrgRole(orgGuid string, role, userGuid, userName string) error
}

type SetOrgRole struct {
	ui       terminal.UI
	config   core_config.Reader
	flagRepo feature_flags.FeatureFlagRepository
	userRepo api.UserRepository
	userReq  requirements.UserRequirement
	orgReq   requirements.OrganizationRequirement
}

func init() {
	command_registry.Register(&SetOrgRole{})
}

func (cmd *SetOrgRole) MetaData() command_registry.CommandMetadata {
	return command_registry.CommandMetadata{
		Name:        "set-org-role",
		Description: T("Assign an org role to a user"),
		Usage: T("CF_NAME set-org-role USERNAME ORG ROLE\n\n") +
			T("ROLES:\n") +
			T("   OrgManager - Invite and manage users, select and change plans, and set spending limits\n") +
			T("   BillingManager - Create and manage the billing account and payment info\n") +
			T("   OrgAuditor - Read-only access to org info and reports\n"),
	}
}

func (cmd *SetOrgRole) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) ([]requirements.Requirement, error) {
	if len(fc.Args()) != 3 {
		cmd.ui.Failed(T("Incorrect Usage. Requires USERNAME, ORG, ROLE as arguments\n\n") + command_registry.Commands.CommandUsage("set-org-role"))
	}

	var wantGuid bool
	if cmd.config.IsMinApiVersion("2.37.0") {
		setRolesByUsernameFlag, err := cmd.flagRepo.FindByName("set_roles_by_username")
		wantGuid = (err != nil || !setRolesByUsernameFlag.Enabled)
	} else {
		wantGuid = true
	}

	cmd.userReq = requirementsFactory.NewUserRequirement(fc.Args()[0], wantGuid)
	cmd.orgReq = requirementsFactory.NewOrganizationRequirement(fc.Args()[1])

	reqs := []requirements.Requirement{
		requirementsFactory.NewLoginRequirement(),
		cmd.userReq,
		cmd.orgReq,
	}

	return reqs, nil
}

func (cmd *SetOrgRole) SetDependency(deps command_registry.Dependency, pluginCall bool) command_registry.Command {
	cmd.ui = deps.Ui
	cmd.config = deps.Config
	cmd.userRepo = deps.RepoLocator.GetUserRepository()
	cmd.flagRepo = deps.RepoLocator.GetFeatureFlagRepository()
	return cmd
}

func (cmd *SetOrgRole) Execute(c flags.FlagContext) {
	user := cmd.userReq.GetUser()
	org := cmd.orgReq.GetOrganization()
	role := models.UserInputToOrgRole[c.Args()[2]]

	cmd.ui.Say(T("Assigning role {{.Role}} to user {{.TargetUser}} in org {{.TargetOrg}} as {{.CurrentUser}}...",
		map[string]interface{}{
			"Role":        terminal.EntityNameColor(role),
			"TargetUser":  terminal.EntityNameColor(user.Username),
			"TargetOrg":   terminal.EntityNameColor(org.Name),
			"CurrentUser": terminal.EntityNameColor(cmd.config.Username()),
		}))

	err := cmd.SetOrgRole(org.Guid, role, user.Guid, user.Username)
	if err != nil {
		cmd.ui.Failed(err.Error())
	}

	cmd.ui.Ok()
}

func (cmd *SetOrgRole) SetOrgRole(orgGuid string, role, userGuid, userName string) error {
	if len(userGuid) > 0 {
		return cmd.userRepo.SetOrgRoleByGuid(userGuid, orgGuid, role)
	}

	return cmd.userRepo.SetOrgRoleByUsername(userName, orgGuid, role)
}
<|endoftext|>