<commit_before>// Copyright 2015 CloudAwan 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 deploy

import (
	"encoding/json"
	"errors"
	"github.com/cloudawan/cloudone/application"
	"github.com/cloudawan/cloudone/control"
	"github.com/cloudawan/cloudone_utility/random"
	"io/ioutil"
	"os"
	"os/exec"
	"strconv"
	"time"
)

type DeployClusterApplication struct {
	Name                              string
	Namespace                         string
	Size                              int
	EnvironmentSlice                  []interface{}
	ReplicationControllerExtraJsonMap map[string]interface{}
	ServiceName                       string
	ReplicationControllerNameSlice    []string
	CreatedTime                       time.Time
}

func InitializeDeployClusterApplication(kubeapiHost string, kubeapiPort int, namespace string, name string, environmentSlice []interface{}, size int, replicationControllerExtraJsonMap map[string]interface{}) error {
	replicationControllerAndRelatedPodSlice, err := control.GetAllReplicationControllerAndRelatedPodSlice(kubeapiHost, kubeapiPort, namespace)
	if err != nil {
		log.Error("Fail to get all replication controller name error %s", err)
		return err
	}

	serviceSlice, err := control.GetAllService(kubeapiHost, kubeapiPort, namespace)
	if err != nil {
		log.Error("Fail to get all service error %s", err)
		return err
	}

	// Service
	serviceName := name
	serviceExist := false
	selectorMap := make(map[string]interface{})
	for _, service := range serviceSlice {
		if service.Name == serviceName {
			serviceExist = true
			for key, value := range service.Selector {
				selectorMap[key] = value
			}
		}
	}

	// Replication Controller
	owningReplicationControllerNameSlice := make([]string, 0)
	if len(selectorMap) > 0 {
		for _, replicationControllerAndRelatedPod := range replicationControllerAndRelatedPodSlice {
			// if all selectors in service are in the replication controller, the service owns the replication controller
			allFit := true
			for key, value := range selectorMap {
				if value != replicationControllerAndRelatedPod.Selector[key] {
					allFit = false
					break
				}
			}
			if allFit {
				owningReplicationControllerNameSlice = append(owningReplicationControllerNameSlice, replicationControllerAndRelatedPod.Name)
			}
		}
	}

	// Service is must since it is used to provide endpoint for others to use
	if serviceExist {
		deployClusterApplication := &DeployClusterApplication{
			name,
			namespace,
			size,
			environmentSlice,
			replicationControllerExtraJsonMap,
			serviceName,
			owningReplicationControllerNameSlice,
			time.Now(),
		}

		return GetStorage().SaveDeployClusterApplication(deployClusterApplication)
	} else {
		log.Error("The service doesn't exist for cluster application deployment with name %s", name)
		return errors.New("The service doesn't exist for cluster application deployment with name " + name)
	}
}

func GetAllDeployClusterApplication() ([]DeployClusterApplication, error) {
	return GetStorage().LoadAllDeployClusterApplication()
}

func GetAllDeployClusterApplicationInNamespace(namespace string) ([]DeployClusterApplication, error) {
	deployClusterApplicationSlice, err := GetStorage().LoadAllDeployClusterApplication()
	if err != nil {
		log.Error(err)
		return nil, err
	}

	filteredDeployClusterApplicationSlice := make([]DeployClusterApplication, 0)
	for _, deployClusterApplication := range deployClusterApplicationSlice {
		if deployClusterApplication.Namespace == namespace {
			filteredDeployClusterApplicationSlice = append(filteredDeployClusterApplicationSlice, deployClusterApplication)
		}
	}

	return filteredDeployClusterApplicationSlice, nil
}

func GetDeployClusterApplication(namespace string, name string) (*DeployClusterApplication, error) {
	return GetStorage().LoadDeployClusterApplication(namespace, name)
}

func ResizeDeployClusterApplication(kubeapiHost string, kubeapiPort int, namespace string, name string, environmentSlice []interface{}, size int) error {
	cluster, err := application.GetStorage().LoadClusterApplication(name)
	if err != nil {
		log.Error("Load cluster application error %s", err)
		return err
	}

	replicationControllerJsonMap := make(map[string]interface{})
	err = json.Unmarshal([]byte(cluster.ReplicationControllerJson), &replicationControllerJsonMap)
	if err != nil {
		log.Error("Unmarshal replication controller json for cluster application error %s", err)
		return err
	}

	// Add environment variable
	if environmentSlice != nil {
		if replicationControllerJsonMap["spec"] != nil {
			containerSlice := replicationControllerJsonMap["spec"].(map[string]interface{})["template"].(map[string]interface{})["spec"].(map[string]interface{})["containers"].([]interface{})
			for i := 0; i < len(containerSlice); i++ {
				_, ok := containerSlice[i].(map[string]interface{})["env"].([]interface{})
				if ok {
					for _, environment := range environmentSlice {
						containerSlice[i].(map[string]interface{})["env"] = append(containerSlice[i].(map[string]interface{})["env"].([]interface{}), environment)
					}
				} else {
					containerSlice[i].(map[string]interface{})["env"] = environmentSlice
				}
			}
		}
	}

	replicationControllerByteSlice, err := json.Marshal(replicationControllerJsonMap)
	if err != nil {
		log.Error("Marshal replication controller json for cluster application error %s", err)
		return err
	}

	environmentByteSlice, err := json.Marshal(environmentSlice)
	if err != nil {
		log.Error("Marshal environment json for cluster application error %s", err)
		return err
	}

	// Generate random work space
	workingDirectory := "/tmp/tmp_" + random.UUID()
	replicationControllerFileName := "replication-controller.json"
	scriptFileName := "script"
	environmentFileName := "environment.json"

	// Check working space
	if _, err := os.Stat(workingDirectory); os.IsNotExist(err) {
		err := os.MkdirAll(workingDirectory, os.ModePerm)
		if err != nil {
			log.Error("Create non-existing directory %s error: %s", workingDirectory, err)
			return err
		}
	}

	err = ioutil.WriteFile(workingDirectory+string(os.PathSeparator)+environmentFileName, environmentByteSlice, os.ModePerm)
	if err != nil {
		log.Error("Write environment json file for cluster application error %s", err)
		return err
	}

	err = ioutil.WriteFile(workingDirectory+string(os.PathSeparator)+replicationControllerFileName, replicationControllerByteSlice, os.ModePerm)
	if err != nil {
		log.Error("Write replication controller json file for cluster application error %s", err)
		return err
	}

	err = ioutil.WriteFile(workingDirectory+string(os.PathSeparator)+scriptFileName, []byte(cluster.ScriptContent), os.ModePerm)
	if err != nil {
		log.Error("Write script file for cluster application error %s", err)
		return err
	}

	switch cluster.ScriptType {
	case "none":
		deployClusterApplication, err := GetDeployClusterApplication(namespace, name)
		if err != nil {
			log.Error("Get deploy cluster application error %s", err)
			return err
		}
		for _, replicationControllerName := range deployClusterApplication.ReplicationControllerNameSlice {
			err := control.UpdateReplicationControllerSize(kubeapiHost, kubeapiPort, namespace, replicationControllerName, size)
			if err != nil {
				log.Error("Resize replication controller %s error %s", replicationControllerName, err)
				return err
			}
		}
	case "python":
		command := exec.Command("python", scriptFileName,
			"--application_name="+name,
			"--kubeapi_host_and_port=http://"+kubeapiHost+":"+strconv.Itoa(kubeapiPort),
			"--namespace="+namespace,
			"--size="+strconv.Itoa(size),
			"--replication_controller_file_name="+replicationControllerFileName,
			"--environment_file_name="+environmentFileName,
			"--timeout_in_second=120",
			"--action=resize")
		command.Dir = workingDirectory
		out, err := command.CombinedOutput()
		log.Debug(string(out))
		if err != nil {
			log.Error("Run python script file for cluster application error %s", err)
			return errors.New("Error: " + err.Error() + " Output: " + string(out))
		}
	default:
		log.Error("No such script type: %s", cluster.ScriptType)
		return errors.New("No such script type: " + cluster.ScriptType)
	}

	// Remove working space
	err = os.RemoveAll(workingDirectory)
	if err != nil {
		log.Error("Remove the working directory for cluster application error %s", err)
		return err
	}

	// Update deploy data
	deployClusterApplication, err := GetStorage().LoadDeployClusterApplication(namespace, name)
	if err != nil {
		log.Error("Update the deploy cluster application with error %s", err)
		return err
	}
	deployClusterApplication.Size = size
	deployClusterApplication.EnvironmentSlice = environmentSlice
	err = GetStorage().SaveDeployClusterApplication(deployClusterApplication)
	if err != nil {
		log.Error("Save the deploy cluster application error %s", err)
		return err
	}

	return nil
}

func DeleteDeployClusterApplication(kubeapiHost string, kubeapiPort int, namespace string, name string) error {
	cluster, err := application.GetStorage().LoadClusterApplication(name)
	if err != nil {
		log.Error("Load cluster application error %s", err)
		return err
	}

	// Remove deploy cluster application
	err = GetStorage().DeleteDeployClusterApplication(namespace, name)
	if err != nil {
		log.Error("Delete the deploy cluster application error %s", err)
		return err
	}

	// Generate random work space
	workingDirectory := "/tmp/tmp_" + random.UUID()
	scriptFileName := "script"

	// Check working space
	if _, err := os.Stat(workingDirectory); os.IsNotExist(err) {
		err := os.MkdirAll(workingDirectory, os.ModePerm)
		if err != nil {
			log.Error("Create non-existing directory %s error: %s", workingDirectory, err)
			return err
		}
	}

	err = ioutil.WriteFile(workingDirectory+string(os.PathSeparator)+scriptFileName, []byte(cluster.ScriptContent), os.ModePerm)
	if err != nil {
		log.Error("Write script file for cluster application error %s", err)
		return err
	}

	switch cluster.ScriptType {
	case "none":
		deployClusterApplication, err := GetDeployClusterApplication(namespace, name)
		if err != nil {
			log.Error("Get deploy cluster application error %s", err)
			return err
		}

		for _, replicationControllerName := range deployClusterApplication.ReplicationControllerNameSlice {
			err := control.DeleteReplicationControllerAndRelatedPod(kubeapiHost, kubeapiPort, namespace, replicationControllerName)
			if err != nil {
				log.Error("Delete replication controller %s error %s", replicationControllerName, err)
				return err
			}
		}

		err = control.DeleteService(kubeapiHost, kubeapiPort, namespace, deployClusterApplication.ServiceName)
		if err != nil {
			log.Error("Delete service %s error %s", deployClusterApplication.ServiceName, err)
			return err
		}
	case "python":
		command := exec.Command("python", scriptFileName,
			"--application_name="+name,
			"--kubeapi_host_and_port=http://"+kubeapiHost+":"+strconv.Itoa(kubeapiPort),
			"--namespace="+namespace,
			"--timeout_in_second=120",
			"--action=delete")
		command.Dir = workingDirectory
		out, err := command.CombinedOutput()
		log.Debug(string(out))
		if err != nil {
			log.Error("Run python script file for cluster application error %s", err)
			return errors.New("Error: " + err.Error() + " Output: " + string(out))
		}
	default:
		log.Error("No such script type: %s", cluster.ScriptType)
		return errors.New("No such script type: " + cluster.ScriptType)
	}

	// Remove working space
	err = os.RemoveAll(workingDirectory)
	if err != nil {
		log.Error("Remove the working directory for cluster application error %s", err)
		return err
	}

	return nil
}
<commit_msg>Fix the wrong place to load<commit_after>// Copyright 2015 CloudAwan 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 deploy

import (
	"encoding/json"
	"errors"
	"github.com/cloudawan/cloudone/application"
	"github.com/cloudawan/cloudone/control"
	"github.com/cloudawan/cloudone_utility/random"
	"io/ioutil"
	"os"
	"os/exec"
	"strconv"
	"time"
)

type DeployClusterApplication struct {
	Name                              string
	Namespace                         string
	Size                              int
	EnvironmentSlice                  []interface{}
	ReplicationControllerExtraJsonMap map[string]interface{}
	ServiceName                       string
	ReplicationControllerNameSlice    []string
	CreatedTime                       time.Time
}

func InitializeDeployClusterApplication(kubeapiHost string, kubeapiPort int, namespace string, name string, environmentSlice []interface{}, size int, replicationControllerExtraJsonMap map[string]interface{}) error {
	replicationControllerAndRelatedPodSlice, err := control.GetAllReplicationControllerAndRelatedPodSlice(kubeapiHost, kubeapiPort, namespace)
	if err != nil {
		log.Error("Fail to get all replication controller name error %s", err)
		return err
	}

	serviceSlice, err := control.GetAllService(kubeapiHost, kubeapiPort, namespace)
	if err != nil {
		log.Error("Fail to get all service error %s", err)
		return err
	}

	// Service
	serviceName := name
	serviceExist := false
	selectorMap := make(map[string]interface{})
	for _, service := range serviceSlice {
		if service.Name == serviceName {
			serviceExist = true
			for key, value := range service.Selector {
				selectorMap[key] = value
			}
		}
	}

	// Replication Controller
	owningReplicationControllerNameSlice := make([]string, 0)
	if len(selectorMap) > 0 {
		for _, replicationControllerAndRelatedPod := range replicationControllerAndRelatedPodSlice {
			// if all selectors in service are in the replication controller, the service owns the replication controller
			allFit := true
			for key, value := range selectorMap {
				if value != replicationControllerAndRelatedPod.Selector[key] {
					allFit = false
					break
				}
			}
			if allFit {
				owningReplicationControllerNameSlice = append(owningReplicationControllerNameSlice, replicationControllerAndRelatedPod.Name)
			}
		}
	}

	// Service is must since it is used to provide endpoint for others to use
	if serviceExist {
		deployClusterApplication := &DeployClusterApplication{
			name,
			namespace,
			size,
			environmentSlice,
			replicationControllerExtraJsonMap,
			serviceName,
			owningReplicationControllerNameSlice,
			time.Now(),
		}

		return GetStorage().SaveDeployClusterApplication(deployClusterApplication)
	} else {
		log.Error("The service doesn't exist for cluster application deployment with name %s", name)
		return errors.New("The service doesn't exist for cluster application deployment with name " + name)
	}
}

func GetAllDeployClusterApplication() ([]DeployClusterApplication, error) {
	return GetStorage().LoadAllDeployClusterApplication()
}

func GetAllDeployClusterApplicationInNamespace(namespace string) ([]DeployClusterApplication, error) {
	deployClusterApplicationSlice, err := GetStorage().LoadAllDeployClusterApplication()
	if err != nil {
		log.Error(err)
		return nil, err
	}

	filteredDeployClusterApplicationSlice := make([]DeployClusterApplication, 0)
	for _, deployClusterApplication := range deployClusterApplicationSlice {
		if deployClusterApplication.Namespace == namespace {
			filteredDeployClusterApplicationSlice = append(filteredDeployClusterApplicationSlice, deployClusterApplication)
		}
	}

	return filteredDeployClusterApplicationSlice, nil
}

func GetDeployClusterApplication(namespace string, name string) (*DeployClusterApplication, error) {
	return GetStorage().LoadDeployClusterApplication(namespace, name)
}

func ResizeDeployClusterApplication(kubeapiHost string, kubeapiPort int, namespace string, name string, environmentSlice []interface{}, size int) error {
	cluster, err := application.GetStorage().LoadClusterApplication(name)
	if err != nil {
		log.Error("Load cluster application error %s", err)
		return err
	}

	replicationControllerJsonMap := make(map[string]interface{})
	err = json.Unmarshal([]byte(cluster.ReplicationControllerJson), &replicationControllerJsonMap)
	if err != nil {
		log.Error("Unmarshal replication controller json for cluster application error %s", err)
		return err
	}

	// Add environment variable
	if environmentSlice != nil {
		if replicationControllerJsonMap["spec"] != nil {
			containerSlice := replicationControllerJsonMap["spec"].(map[string]interface{})["template"].(map[string]interface{})["spec"].(map[string]interface{})["containers"].([]interface{})
			for i := 0; i < len(containerSlice); i++ {
				_, ok := containerSlice[i].(map[string]interface{})["env"].([]interface{})
				if ok {
					for _, environment := range environmentSlice {
						containerSlice[i].(map[string]interface{})["env"] = append(containerSlice[i].(map[string]interface{})["env"].([]interface{}), environment)
					}
				} else {
					containerSlice[i].(map[string]interface{})["env"] = environmentSlice
				}
			}
		}
	}

	replicationControllerByteSlice, err := json.Marshal(replicationControllerJsonMap)
	if err != nil {
		log.Error("Marshal replication controller json for cluster application error %s", err)
		return err
	}

	environmentByteSlice, err := json.Marshal(environmentSlice)
	if err != nil {
		log.Error("Marshal environment json for cluster application error %s", err)
		return err
	}

	// Generate random work space
	workingDirectory := "/tmp/tmp_" + random.UUID()
	replicationControllerFileName := "replication-controller.json"
	scriptFileName := "script"
	environmentFileName := "environment.json"

	// Check working space
	if _, err := os.Stat(workingDirectory); os.IsNotExist(err) {
		err := os.MkdirAll(workingDirectory, os.ModePerm)
		if err != nil {
			log.Error("Create non-existing directory %s error: %s", workingDirectory, err)
			return err
		}
	}

	err = ioutil.WriteFile(workingDirectory+string(os.PathSeparator)+environmentFileName, environmentByteSlice, os.ModePerm)
	if err != nil {
		log.Error("Write environment json file for cluster application error %s", err)
		return err
	}

	err = ioutil.WriteFile(workingDirectory+string(os.PathSeparator)+replicationControllerFileName, replicationControllerByteSlice, os.ModePerm)
	if err != nil {
		log.Error("Write replication controller json file for cluster application error %s", err)
		return err
	}

	err = ioutil.WriteFile(workingDirectory+string(os.PathSeparator)+scriptFileName, []byte(cluster.ScriptContent), os.ModePerm)
	if err != nil {
		log.Error("Write script file for cluster application error %s", err)
		return err
	}

	switch cluster.ScriptType {
	case "none":
		deployClusterApplication, err := GetDeployClusterApplication(namespace, name)
		if err != nil {
			log.Error("Get deploy cluster application error %s", err)
			return err
		}
		for _, replicationControllerName := range deployClusterApplication.ReplicationControllerNameSlice {
			err := control.UpdateReplicationControllerSize(kubeapiHost, kubeapiPort, namespace, replicationControllerName, size)
			if err != nil {
				log.Error("Resize replication controller %s error %s", replicationControllerName, err)
				return err
			}
		}
	case "python":
		command := exec.Command("python", scriptFileName,
			"--application_name="+name,
			"--kubeapi_host_and_port=http://"+kubeapiHost+":"+strconv.Itoa(kubeapiPort),
			"--namespace="+namespace,
			"--size="+strconv.Itoa(size),
			"--replication_controller_file_name="+replicationControllerFileName,
			"--environment_file_name="+environmentFileName,
			"--timeout_in_second=120",
			"--action=resize")
		command.Dir = workingDirectory
		out, err := command.CombinedOutput()
		log.Debug(string(out))
		if err != nil {
			log.Error("Run python script file for cluster application error %s", err)
			return errors.New("Error: " + err.Error() + " Output: " + string(out))
		}
	default:
		log.Error("No such script type: %s", cluster.ScriptType)
		return errors.New("No such script type: " + cluster.ScriptType)
	}

	// Remove working space
	err = os.RemoveAll(workingDirectory)
	if err != nil {
		log.Error("Remove the working directory for cluster application error %s", err)
		return err
	}

	// Update deploy data
	deployClusterApplication, err := GetStorage().LoadDeployClusterApplication(namespace, name)
	if err != nil {
		log.Error("Update the deploy cluster application with error %s", err)
		return err
	}
	deployClusterApplication.Size = size
	deployClusterApplication.EnvironmentSlice = environmentSlice
	err = GetStorage().SaveDeployClusterApplication(deployClusterApplication)
	if err != nil {
		log.Error("Save the deploy cluster application error %s", err)
		return err
	}

	return nil
}

func DeleteDeployClusterApplication(kubeapiHost string, kubeapiPort int, namespace string, name string) error {
	cluster, err := application.GetStorage().LoadClusterApplication(name)
	if err != nil {
		log.Error("Load cluster application error %s", err)
		return err
	}

	deployClusterApplication, err := GetDeployClusterApplication(namespace, name)
	if err != nil {
		log.Error("Get deploy cluster application error %s", err)
		return err
	}

	// Remove deploy cluster application
	err = GetStorage().DeleteDeployClusterApplication(namespace, name)
	if err != nil {
		log.Error("Delete the deploy cluster application error %s", err)
		return err
	}

	// Generate random work space
	workingDirectory := "/tmp/tmp_" + random.UUID()
	scriptFileName := "script"

	// Check working space
	if _, err := os.Stat(workingDirectory); os.IsNotExist(err) {
		err := os.MkdirAll(workingDirectory, os.ModePerm)
		if err != nil {
			log.Error("Create non-existing directory %s error: %s", workingDirectory, err)
			return err
		}
	}

	err = ioutil.WriteFile(workingDirectory+string(os.PathSeparator)+scriptFileName, []byte(cluster.ScriptContent), os.ModePerm)
	if err != nil {
		log.Error("Write script file for cluster application error %s", err)
		return err
	}

	switch cluster.ScriptType {
	case "none":
		for _, replicationControllerName := range deployClusterApplication.ReplicationControllerNameSlice {
			err := control.DeleteReplicationControllerAndRelatedPod(kubeapiHost, kubeapiPort, namespace, replicationControllerName)
			if err != nil {
				log.Error("Delete replication controller %s error %s", replicationControllerName, err)
				return err
			}
		}

		err = control.DeleteService(kubeapiHost, kubeapiPort, namespace, deployClusterApplication.ServiceName)
		if err != nil {
			log.Error("Delete service %s error %s", deployClusterApplication.ServiceName, err)
			return err
		}
	case "python":
		command := exec.Command("python", scriptFileName,
			"--application_name="+name,
			"--kubeapi_host_and_port=http://"+kubeapiHost+":"+strconv.Itoa(kubeapiPort),
			"--namespace="+namespace,
			"--timeout_in_second=120",
			"--action=delete")
		command.Dir = workingDirectory
		out, err := command.CombinedOutput()
		log.Debug(string(out))
		if err != nil {
			log.Error("Run python script file for cluster application error %s", err)
			return errors.New("Error: " + err.Error() + " Output: " + string(out))
		}
	default:
		log.Error("No such script type: %s", cluster.ScriptType)
		return errors.New("No such script type: " + cluster.ScriptType)
	}

	// Remove working space
	err = os.RemoveAll(workingDirectory)
	if err != nil {
		log.Error("Remove the working directory for cluster application error %s", err)
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package Milena

type topicConsumer interface {

}
<commit_msg>rm useless file<commit_after><|endoftext|>


<commit_before>package iptables

// This package is originally from Docker and has been modified for use by the
// Flynn project. See the NOTICE and LICENSE files for licensing and copyright
// details.

import (
	"errors"
	"fmt"
	"net"
	"os"
	"os/exec"
	"strings"
)

type Action string

const (
	Add    Action = "-A"
	Delete Action = "-D"
)

var (
	ErrIptablesNotFound = errors.New("Iptables not found")
	nat                 = []string{"-t", "nat"}
	supportsXlock       = false
)

type Chain struct {
	Name   string
	Bridge string
}

func init() {
	supportsXlock = exec.Command("iptables", "--wait", "-L", "-n").Run() == nil
}

func NewChain(name, bridge string) (*Chain, error) {
	if output, err := Raw("-t", "nat", "-N", name); err != nil {
		return nil, err
	} else if len(output) != 0 {
		return nil, fmt.Errorf("Error creating new iptables chain: %s", output)
	}
	chain := &Chain{
		Name:   name,
		Bridge: bridge,
	}

	if err := chain.Prerouting(Add, "-m", "addrtype", "--dst-type", "LOCAL"); err != nil {
		return nil, fmt.Errorf("failed to update PREROUTING chain: %s", err)
	}
	if err := chain.Output(Add, "-m", "addrtype", "--dst-type", "LOCAL"); err != nil {
		return nil, fmt.Errorf("failed to update OUTPUT chain: %s", err)
	}
	if _, err := Raw("-t", "nat", "-A", "POSTROUTING", "-m", "addrtype", "--src-type", "LOCAL", "-o", bridge, "-j", "MASQUERADE"); err != nil {
		return nil, fmt.Errorf("failed to update POSTROUTING chain: %s", err)
	}
	return chain, nil
}

func RemoveExistingChain(name string) error {
	chain := &Chain{
		Name: name,
	}
	return chain.Remove()
}

func (c *Chain) Forward(action Action, ip net.IP, port, rangeEnd int, proto, destAddr string) error {
	daddr := ip.String()
	if ip.IsUnspecified() {
		// iptables interprets "0.0.0.0" as "0.0.0.0/32", whereas we
		// want "0.0.0.0/0". "0/0" is correctly interpreted as "any
		// value" by both iptables and ip6tables.
		daddr = "0/0"
	}
	if output, err := Raw("-t", "nat", fmt.Sprint(action), c.Name,
		"-p", proto,
		"-d", daddr,
		"--dport", fmt.Sprintf("%d:%d", port, rangeEnd),
		"-j", "DNAT",
		"--to-destination", destAddr); err != nil && action != Delete {
		return err
	} else if len(output) != 0 && action != Delete {
		return fmt.Errorf("Error iptables forward: %s", output)
	}

	fAction := action
	if fAction == Add {
		fAction = "-I"
	}
	if output, err := Raw(string(fAction), "FORWARD",
		"!", "-i", c.Bridge,
		"-o", c.Bridge,
		"-p", proto,
		"-d", destAddr,
		"--dport", fmt.Sprintf("%d:%d", port, rangeEnd),
		"-j", "ACCEPT"); err != nil && action != Delete {
		return err
	} else if len(output) != 0 && action != Delete {
		return fmt.Errorf("Error iptables forward: %s", output)
	}

	if output, err := Raw("-t", "nat", string(fAction), "POSTROUTING",
		"-p", proto,
		"-s", destAddr,
		"-d", destAddr,
		"--dport", fmt.Sprintf("%d:%d", port, rangeEnd),
		"-j", "MASQUERADE"); err != nil && action != Delete {
		return err
	} else if len(output) != 0 && action != Delete {
		return fmt.Errorf("Error iptables forward: %s", output)
	}

	return nil
}

func (c *Chain) Prerouting(action Action, args ...string) error {
	a := append(nat, fmt.Sprint(action), "PREROUTING")
	if len(args) > 0 {
		a = append(a, args...)
	}
	if output, err := Raw(append(a, "-j", c.Name)...); err != nil {
		return err
	} else if len(output) != 0 {
		return fmt.Errorf("Error iptables prerouting: %s", output)
	}
	return nil
}

func (c *Chain) Output(action Action, args ...string) error {
	a := append(nat, fmt.Sprint(action), "OUTPUT")
	if len(args) > 0 {
		a = append(a, args...)
	}
	if output, err := Raw(append(a, "-j", c.Name)...); err != nil {
		return err
	} else if len(output) != 0 {
		return fmt.Errorf("Error iptables output: %s", output)
	}
	return nil
}

func (c *Chain) Remove() error {
	// Ignore errors - This could mean the chains were never set up
	c.Prerouting(Delete, "-m", "addrtype", "--dst-type", "LOCAL")
	c.Output(Delete, "-m", "addrtype", "--dst-type", "LOCAL")
	Raw("-t", "nat", "-D", "POSTROUTING", "-m", "addrtype", "--src-type", "LOCAL", "-o", c.Bridge, "-j", "MASQUERADE")

	c.Prerouting(Delete)
	c.Output(Delete)

	Raw("-t", "nat", "-F", c.Name)
	Raw("-t", "nat", "-X", c.Name)

	return nil
}

// Check if an existing rule exists
func Exists(args ...string) bool {
	if _, err := Raw(append([]string{"-C"}, args...)...); err != nil {
		return false
	}
	return true
}

func Raw(args ...string) ([]byte, error) {
	path, err := exec.LookPath("iptables")
	if err != nil {
		return nil, ErrIptablesNotFound
	}

	if supportsXlock {
		args = append([]string{"--wait"}, args...)
	}

	if os.Getenv("DEBUG") != "" {
		fmt.Fprintf(os.Stderr, fmt.Sprintf("[debug] %s, %v\n", path, args))
	}

	output, err := exec.Command(path, args...).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("iptables failed: iptables %v: %s (%s)", strings.Join(args, " "), output, err)
	}

	// ignore iptables' message about xtables lock
	if strings.Contains(string(output), "waiting for it to exit") {
		output = []byte("")
	}

	return output, err
}
<commit_msg>Require bridge for RemoveExistingChain<commit_after>package iptables

// This package is originally from Docker and has been modified for use by the
// Flynn project. See the NOTICE and LICENSE files for licensing and copyright
// details.

import (
	"errors"
	"fmt"
	"net"
	"os"
	"os/exec"
	"strings"
)

type Action string

const (
	Add    Action = "-A"
	Delete Action = "-D"
)

var (
	ErrIptablesNotFound = errors.New("Iptables not found")
	nat                 = []string{"-t", "nat"}
	supportsXlock       = false
)

type Chain struct {
	Name   string
	Bridge string
}

func init() {
	supportsXlock = exec.Command("iptables", "--wait", "-L", "-n").Run() == nil
}

func NewChain(name, bridge string) (*Chain, error) {
	if output, err := Raw("-t", "nat", "-N", name); err != nil {
		return nil, err
	} else if len(output) != 0 {
		return nil, fmt.Errorf("Error creating new iptables chain: %s", output)
	}
	chain := &Chain{
		Name:   name,
		Bridge: bridge,
	}

	if err := chain.Prerouting(Add, "-m", "addrtype", "--dst-type", "LOCAL"); err != nil {
		return nil, fmt.Errorf("failed to update PREROUTING chain: %s", err)
	}
	if err := chain.Output(Add, "-m", "addrtype", "--dst-type", "LOCAL"); err != nil {
		return nil, fmt.Errorf("failed to update OUTPUT chain: %s", err)
	}
	if _, err := Raw("-t", "nat", "-A", "POSTROUTING", "-m", "addrtype", "--src-type", "LOCAL", "-o", bridge, "-j", "MASQUERADE"); err != nil {
		return nil, fmt.Errorf("failed to update POSTROUTING chain: %s", err)
	}
	return chain, nil
}

func RemoveExistingChain(name, bridge string) error {
	chain := &Chain{
		Name:   name,
		Bridge: bridge,
	}
	return chain.Remove()
}

func (c *Chain) Forward(action Action, ip net.IP, port, rangeEnd int, proto, destAddr string) error {
	daddr := ip.String()
	if ip.IsUnspecified() {
		// iptables interprets "0.0.0.0" as "0.0.0.0/32", whereas we
		// want "0.0.0.0/0". "0/0" is correctly interpreted as "any
		// value" by both iptables and ip6tables.
		daddr = "0/0"
	}
	if output, err := Raw("-t", "nat", fmt.Sprint(action), c.Name,
		"-p", proto,
		"-d", daddr,
		"--dport", fmt.Sprintf("%d:%d", port, rangeEnd),
		"-j", "DNAT",
		"--to-destination", destAddr); err != nil && action != Delete {
		return err
	} else if len(output) != 0 && action != Delete {
		return fmt.Errorf("Error iptables forward: %s", output)
	}

	fAction := action
	if fAction == Add {
		fAction = "-I"
	}
	if output, err := Raw(string(fAction), "FORWARD",
		"!", "-i", c.Bridge,
		"-o", c.Bridge,
		"-p", proto,
		"-d", destAddr,
		"--dport", fmt.Sprintf("%d:%d", port, rangeEnd),
		"-j", "ACCEPT"); err != nil && action != Delete {
		return err
	} else if len(output) != 0 && action != Delete {
		return fmt.Errorf("Error iptables forward: %s", output)
	}

	if output, err := Raw("-t", "nat", string(fAction), "POSTROUTING",
		"-p", proto,
		"-s", destAddr,
		"-d", destAddr,
		"--dport", fmt.Sprintf("%d:%d", port, rangeEnd),
		"-j", "MASQUERADE"); err != nil && action != Delete {
		return err
	} else if len(output) != 0 && action != Delete {
		return fmt.Errorf("Error iptables forward: %s", output)
	}

	return nil
}

func (c *Chain) Prerouting(action Action, args ...string) error {
	a := append(nat, fmt.Sprint(action), "PREROUTING")
	if len(args) > 0 {
		a = append(a, args...)
	}
	if output, err := Raw(append(a, "-j", c.Name)...); err != nil {
		return err
	} else if len(output) != 0 {
		return fmt.Errorf("Error iptables prerouting: %s", output)
	}
	return nil
}

func (c *Chain) Output(action Action, args ...string) error {
	a := append(nat, fmt.Sprint(action), "OUTPUT")
	if len(args) > 0 {
		a = append(a, args...)
	}
	if output, err := Raw(append(a, "-j", c.Name)...); err != nil {
		return err
	} else if len(output) != 0 {
		return fmt.Errorf("Error iptables output: %s", output)
	}
	return nil
}

func (c *Chain) Remove() error {
	// Ignore errors - This could mean the chains were never set up
	c.Prerouting(Delete, "-m", "addrtype", "--dst-type", "LOCAL")
	c.Output(Delete, "-m", "addrtype", "--dst-type", "LOCAL")
	Raw("-t", "nat", "-D", "POSTROUTING", "-m", "addrtype", "--src-type", "LOCAL", "-o", c.Bridge, "-j", "MASQUERADE")

	c.Prerouting(Delete)
	c.Output(Delete)

	Raw("-t", "nat", "-F", c.Name)
	Raw("-t", "nat", "-X", c.Name)

	return nil
}

// Check if an existing rule exists
func Exists(args ...string) bool {
	if _, err := Raw(append([]string{"-C"}, args...)...); err != nil {
		return false
	}
	return true
}

func Raw(args ...string) ([]byte, error) {
	path, err := exec.LookPath("iptables")
	if err != nil {
		return nil, ErrIptablesNotFound
	}

	if supportsXlock {
		args = append([]string{"--wait"}, args...)
	}

	if os.Getenv("DEBUG") != "" {
		fmt.Fprintf(os.Stderr, fmt.Sprintf("[debug] %s, %v\n", path, args))
	}

	output, err := exec.Command(path, args...).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("iptables failed: iptables %v: %s (%s)", strings.Join(args, " "), output, err)
	}

	// ignore iptables' message about xtables lock
	if strings.Contains(string(output), "waiting for it to exit") {
		output = []byte("")
	}

	return output, err
}
<|endoftext|>


<commit_before>package harness

import (
	"github.com/robfig/revel"
	"go/ast"
	"go/parser"
	"go/token"
	"io/ioutil"
	"log"
	"reflect"
	"strings"
	"testing"
)

const validationKeysSource = `
package test

func (c *Application) testFunc(a, b int, user models.User) revel.Result {
	// Line 5
	c.Validation.Required(a)
	c.Validation.Required(a).Message("Error message")
	c.Validation.Required(a).
		Message("Error message")

	// Line 11
	c.Validation.Required(user.Name)
	c.Validation.Required(user.Name).Message("Error message")

	// Line 15
	c.Validation.MinSize(b, 12)
	c.Validation.MinSize(b, 12).Message("Error message")
	c.Validation.MinSize(b,
		12)

	// Line 21
	c.Validation.Required(b == 5)
}

func (m Model) Validate(v *revel.Validation) {
	// Line 26
	v.Required(m.name)
	v.Required(m.name == "something").
		Message("Error Message")
}
`

var expectedValidationKeys = []map[int]string{
	{
		6:  "a",
		7:  "a",
		8:  "a",
		12: "user.Name",
		13: "user.Name",
		16: "b",
		17: "b",
		19: "b",
		22: "b",
	}, {
		27: "m.name",
		28: "m.name",
	},
}

// This tests the recording of line number to validation key of the preceeding
// example source.
func TestGetValidationKeys(t *testing.T) {
	fset := token.NewFileSet()

	file, err := parser.ParseFile(fset, "validationKeysSource", validationKeysSource, 0)
	if err != nil {
		t.Fatal(err)
	}
	if len(file.Decls) != 2 {
		t.Fatal("Expected 2 decl in the source, found", len(file.Decls))
	}

	for i, decl := range file.Decls {
		lineKeys := getValidationKeys(fset, decl.(*ast.FuncDecl), map[string]string{"rev": revel.REVEL_IMPORT_PATH})
		for k, v := range expectedValidationKeys[i] {
			if lineKeys[k] != v {
				t.Errorf("Not found - %d: %v - Actual Map: %v", k, v, lineKeys)
			}
		}

		if len(lineKeys) != len(expectedValidationKeys[i]) {
			t.Error("Validation key map not the same size as expected:", lineKeys)
		}
	}
}

var TypeExprs = map[string]TypeExpr{
	"int":        TypeExpr{"int", "", 0},
	"*int":       TypeExpr{"*int", "", 1},
	"[]int":      TypeExpr{"[]int", "", 2},
	"...int":     TypeExpr{"[]int", "", 2},
	"[]*int":     TypeExpr{"[]*int", "", 3},
	"...*int":    TypeExpr{"[]*int", "", 3},
	"MyType":     TypeExpr{"MyType", "pkg", 0},
	"*MyType":    TypeExpr{"*MyType", "pkg", 1},
	"[]MyType":   TypeExpr{"[]MyType", "pkg", 2},
	"...MyType":  TypeExpr{"[]MyType", "pkg", 2},
	"[]*MyType":  TypeExpr{"[]*MyType", "pkg", 3},
	"...*MyType": TypeExpr{"[]*MyType", "pkg", 3},
}

func TestTypeExpr(t *testing.T) {
	for typeStr, expected := range TypeExprs {
		// Handle arrays and ... myself, since ParseExpr() does not.
		array := strings.HasPrefix(typeStr, "[]")
		if array {
			typeStr = typeStr[2:]
		}

		ellipsis := strings.HasPrefix(typeStr, "...")
		if ellipsis {
			typeStr = typeStr[3:]
		}

		expr, err := parser.ParseExpr(typeStr)
		if err != nil {
			t.Error("Failed to parse test expr:", typeStr)
			continue
		}

		if array {
			expr = &ast.ArrayType{expr.Pos(), nil, expr}
		}
		if ellipsis {
			expr = &ast.Ellipsis{expr.Pos(), expr}
		}

		actual := NewTypeExpr("pkg", expr)
		if !reflect.DeepEqual(expected, actual) {
			t.Error("Fail, expected", expected, ", was", actual)
		}
	}
}

func TestProcessBookingSource(t *testing.T) {
	revel.Init("", "github.com/robfig/revel/samples/booking", "")
	sourceInfo, err := ProcessSource([]string{revel.AppPath})
	if err != nil {
		t.Fatal("Failed to process booking source with error:", err)
	}

	CONTROLLER_PKG := "github.com/robfig/revel/samples/booking/app/controllers"
	expectedControllerSpecs := []*TypeInfo{
		{"GorpController", CONTROLLER_PKG, "controllers", nil, nil},
		{"Application", CONTROLLER_PKG, "controllers", nil, nil},
		{"Hotels", CONTROLLER_PKG, "controllers", nil, nil},
	}
	if len(sourceInfo.ControllerSpecs) != len(expectedControllerSpecs) {
		t.Errorf("Unexpected number of controllers found.  Expected %d, Found %d",
			len(expectedControllerSpecs), len(sourceInfo.ControllerSpecs))
	}

NEXT_TEST:
	for _, expected := range expectedControllerSpecs {
		for _, actual := range sourceInfo.ControllerSpecs {
			if actual.StructName == expected.StructName {
				if actual.ImportPath != expected.ImportPath {
					t.Errorf("%s expected to have import path %s, actual %s",
						actual.StructName, expected.ImportPath, actual.ImportPath)
				}
				if actual.PackageName != expected.PackageName {
					t.Errorf("%s expected to have package name %s, actual %s",
						actual.StructName, expected.PackageName, actual.PackageName)
				}
				continue NEXT_TEST
			}
		}
		t.Errorf("Expected to find controller %s, but did not.  Actuals: %s",
			expected.StructName, sourceInfo.ControllerSpecs)
	}
}

func BenchmarkProcessBookingSource(b *testing.B) {
	revel.Init("", "github.com/robfig/revel/samples/booking", "")
	revel.TRACE = log.New(ioutil.Discard, "", 0)
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		_, err := ProcessSource(revel.CodePaths)
		if err != nil {
			b.Error("Unexpected error:", err)
		}
	}
}
<commit_msg>Fix harness test<commit_after>package harness

import (
	"github.com/robfig/revel"
	"go/ast"
	"go/parser"
	"go/token"
	"io/ioutil"
	"log"
	"reflect"
	"strings"
	"testing"
)

const validationKeysSource = `
package test

func (c *Application) testFunc(a, b int, user models.User) revel.Result {
	// Line 5
	c.Validation.Required(a)
	c.Validation.Required(a).Message("Error message")
	c.Validation.Required(a).
		Message("Error message")

	// Line 11
	c.Validation.Required(user.Name)
	c.Validation.Required(user.Name).Message("Error message")

	// Line 15
	c.Validation.MinSize(b, 12)
	c.Validation.MinSize(b, 12).Message("Error message")
	c.Validation.MinSize(b,
		12)

	// Line 21
	c.Validation.Required(b == 5)
}

func (m Model) Validate(v *revel.Validation) {
	// Line 26
	v.Required(m.name)
	v.Required(m.name == "something").
		Message("Error Message")
}
`

var expectedValidationKeys = []map[int]string{
	{
		6:  "a",
		7:  "a",
		8:  "a",
		12: "user.Name",
		13: "user.Name",
		16: "b",
		17: "b",
		19: "b",
		22: "b",
	}, {
		27: "m.name",
		28: "m.name",
	},
}

// This tests the recording of line number to validation key of the preceeding
// example source.
func TestGetValidationKeys(t *testing.T) {
	fset := token.NewFileSet()

	file, err := parser.ParseFile(fset, "validationKeysSource", validationKeysSource, 0)
	if err != nil {
		t.Fatal(err)
	}
	if len(file.Decls) != 2 {
		t.Fatal("Expected 2 decl in the source, found", len(file.Decls))
	}

	for i, decl := range file.Decls {
		lineKeys := getValidationKeys(fset, decl.(*ast.FuncDecl), map[string]string{"revel": revel.REVEL_IMPORT_PATH})
		for k, v := range expectedValidationKeys[i] {
			if lineKeys[k] != v {
				t.Errorf("Not found - %d: %v - Actual Map: %v", k, v, lineKeys)
			}
		}

		if len(lineKeys) != len(expectedValidationKeys[i]) {
			t.Error("Validation key map not the same size as expected:", lineKeys)
		}
	}
}

var TypeExprs = map[string]TypeExpr{
	"int":        TypeExpr{"int", "", 0},
	"*int":       TypeExpr{"*int", "", 1},
	"[]int":      TypeExpr{"[]int", "", 2},
	"...int":     TypeExpr{"[]int", "", 2},
	"[]*int":     TypeExpr{"[]*int", "", 3},
	"...*int":    TypeExpr{"[]*int", "", 3},
	"MyType":     TypeExpr{"MyType", "pkg", 0},
	"*MyType":    TypeExpr{"*MyType", "pkg", 1},
	"[]MyType":   TypeExpr{"[]MyType", "pkg", 2},
	"...MyType":  TypeExpr{"[]MyType", "pkg", 2},
	"[]*MyType":  TypeExpr{"[]*MyType", "pkg", 3},
	"...*MyType": TypeExpr{"[]*MyType", "pkg", 3},
}

func TestTypeExpr(t *testing.T) {
	for typeStr, expected := range TypeExprs {
		// Handle arrays and ... myself, since ParseExpr() does not.
		array := strings.HasPrefix(typeStr, "[]")
		if array {
			typeStr = typeStr[2:]
		}

		ellipsis := strings.HasPrefix(typeStr, "...")
		if ellipsis {
			typeStr = typeStr[3:]
		}

		expr, err := parser.ParseExpr(typeStr)
		if err != nil {
			t.Error("Failed to parse test expr:", typeStr)
			continue
		}

		if array {
			expr = &ast.ArrayType{expr.Pos(), nil, expr}
		}
		if ellipsis {
			expr = &ast.Ellipsis{expr.Pos(), expr}
		}

		actual := NewTypeExpr("pkg", expr)
		if !reflect.DeepEqual(expected, actual) {
			t.Error("Fail, expected", expected, ", was", actual)
		}
	}
}

func TestProcessBookingSource(t *testing.T) {
	revel.Init("", "github.com/robfig/revel/samples/booking", "")
	sourceInfo, err := ProcessSource([]string{revel.AppPath})
	if err != nil {
		t.Fatal("Failed to process booking source with error:", err)
	}

	CONTROLLER_PKG := "github.com/robfig/revel/samples/booking/app/controllers"
	expectedControllerSpecs := []*TypeInfo{
		{"GorpController", CONTROLLER_PKG, "controllers", nil, nil},
		{"Application", CONTROLLER_PKG, "controllers", nil, nil},
		{"Hotels", CONTROLLER_PKG, "controllers", nil, nil},
	}
	if len(sourceInfo.ControllerSpecs) != len(expectedControllerSpecs) {
		t.Errorf("Unexpected number of controllers found.  Expected %d, Found %d",
			len(expectedControllerSpecs), len(sourceInfo.ControllerSpecs))
	}

NEXT_TEST:
	for _, expected := range expectedControllerSpecs {
		for _, actual := range sourceInfo.ControllerSpecs {
			if actual.StructName == expected.StructName {
				if actual.ImportPath != expected.ImportPath {
					t.Errorf("%s expected to have import path %s, actual %s",
						actual.StructName, expected.ImportPath, actual.ImportPath)
				}
				if actual.PackageName != expected.PackageName {
					t.Errorf("%s expected to have package name %s, actual %s",
						actual.StructName, expected.PackageName, actual.PackageName)
				}
				continue NEXT_TEST
			}
		}
		t.Errorf("Expected to find controller %s, but did not.  Actuals: %s",
			expected.StructName, sourceInfo.ControllerSpecs)
	}
}

func BenchmarkProcessBookingSource(b *testing.B) {
	revel.Init("", "github.com/robfig/revel/samples/booking", "")
	revel.TRACE = log.New(ioutil.Discard, "", 0)
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		_, err := ProcessSource(revel.CodePaths)
		if err != nil {
			b.Error("Unexpected error:", err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"path"
	"strings"
)

// cli flags
var (
	uploadDir string
	baseUrl   string
	port      int
	host      string
)

func init() {
	flag.StringVar(&uploadDir, "uploaddir", "/var/www/oop/",
		"where to keep uploaded files")
	flag.StringVar(&baseUrl, "url", "",
		"base url content is served from")
	flag.StringVar(&host, "host", "", "host to listen on")
	flag.IntVar(&port, "port", 8080, "port to listen on")

	flag.Parse()

	if baseUrl == "" {
		log.Fatal("-url is required")
	}
}

func main() {
	http.HandleFunc("/delete", handleDelete)
	http.HandleFunc("/up", handleUpload)
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		if req.URL.Path != "/" {
			log.Printf("not found: %s", req.URL.Path)
			http.NotFound(w, req)
			return
		}

		handleIndex(w, req)
	})

	addr := fmt.Sprintf("%s:%d", host, port)

	log.Printf("starting server on %s", addr)
	http.ListenAndServe(addr, nil)
}

func handleUpload(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "not allowed", http.StatusMethodNotAllowed)
		return
	}

	file, header, err := r.FormFile("file")
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	defer file.Close()

	s := strings.Split(header.Filename, ".")
	name, ext := s[0], s[len(s)-1]

	tmpfile, err := ioutil.TempFile(uploadDir, fmt.Sprintf("*.%s", ext))
	if err != nil {
		log.Printf("create temp file: %+v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer tmpfile.Close()

	log.Printf("receiving file: %s.%s => %s", name, ext, tmpfile.Name())

	if b, err := io.Copy(tmpfile, file); err != nil {
		log.Printf("download failed: %+v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	} else {
		log.Printf("%s completed (%d bytes)", tmpfile.Name(), b)
	}

	url, _ := url.Parse(baseUrl)
	url.Path = path.Join(url.Path, path.Base(tmpfile.Name()))
	w.Write([]byte(url.String()))
}

func handleDelete(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "not allowed", http.StatusMethodNotAllowed)
		return
	}

	panic("not implemented")
}

func handleIndex(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "not allowed", http.StatusMethodNotAllowed)
		return
	}

	w.Header().Add("Content-Type", "text/html")
	w.Write([]byte(`
<!doctype html>

  <title>oop</title>
  <meta name="viewport"
        content="width=device-width, initial-scale=1">

oop

<form method="post" action="up" enctype="multipart/form-data">
  <input type="file" name="file">

  <input type="submit" value="Upload">
</form>
`))
}
<commit_msg>Switch mode of uploaded file to 0644<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"path"
	"strings"
)

// cli flags
var (
	uploadDir string
	baseUrl   string
	port      int
	host      string
)

func init() {
	flag.StringVar(&uploadDir, "uploaddir", "/var/www/oop/",
		"where to keep uploaded files")
	flag.StringVar(&baseUrl, "url", "",
		"base url content is served from")
	flag.StringVar(&host, "host", "", "host to listen on")
	flag.IntVar(&port, "port", 8080, "port to listen on")

	flag.Parse()

	if baseUrl == "" {
		log.Fatal("-url is required")
	}
}

func main() {
	http.HandleFunc("/delete", handleDelete)
	http.HandleFunc("/up", handleUpload)
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		if req.URL.Path != "/" {
			log.Printf("not found: %s", req.URL.Path)
			http.NotFound(w, req)
			return
		}

		handleIndex(w, req)
	})

	addr := fmt.Sprintf("%s:%d", host, port)

	log.Printf("starting server on %s", addr)
	http.ListenAndServe(addr, nil)
}

func handleUpload(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "not allowed", http.StatusMethodNotAllowed)
		return
	}

	file, header, err := r.FormFile("file")
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	defer file.Close()

	s := strings.Split(header.Filename, ".")
	name, ext := s[0], s[len(s)-1]

	tmpfile, err := ioutil.TempFile(uploadDir, fmt.Sprintf("*.%s", ext))
	if err != nil {
		log.Printf("create temp file: %+v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer tmpfile.Close()

	log.Printf("receiving file: %s.%s => %s", name, ext, tmpfile.Name())

	if b, err := io.Copy(tmpfile, file); err != nil {
		log.Printf("download failed: %+v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	} else {
		log.Printf("%s completed (%d bytes)", tmpfile.Name(), b)
	}

	// Tempfiles are created as 0600, which means other processes
	// won't be able to read them.
	if err := os.Chmod(tmpfile.Name(), 0644); err != nil {
		log.Printf("chmod failed: %+v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	url, _ := url.Parse(baseUrl)
	url.Path = path.Join(url.Path, path.Base(tmpfile.Name()))
	w.Write([]byte(url.String()))
}

func handleDelete(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "not allowed", http.StatusMethodNotAllowed)
		return
	}

	panic("not implemented")
}

func handleIndex(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "not allowed", http.StatusMethodNotAllowed)
		return
	}

	w.Header().Add("Content-Type", "text/html")
	w.Write([]byte(`
<!doctype html>

  <title>oop</title>
  <meta name="viewport"
        content="width=device-width, initial-scale=1">

oop

<form method="post" action="up" enctype="multipart/form-data">
  <input type="file" name="file">

  <input type="submit" value="Upload">
</form>
`))
}
<|endoftext|>


<commit_before>package template

/*
The `NewProtocol` method is used to define the protocol and to register
the handlers that will be called if a certain type of message is received.
The handlers will be treated according to their signature.

The protocol-file defines the actions that the protocol needs to do in each
step. The root-node will call the `Start`-method of the protocol. Each
node will only use the `Handle`-methods, and not call `Start` again.
*/

import (
	"errors"

	"github.com/dedis/cothority/log"
	"github.com/dedis/cothority/network"
	"github.com/dedis/cothority/sda"
)

func init() {
	network.RegisterPacketType(Announce{})
	network.RegisterPacketType(Reply{})
	sda.GlobalProtocolRegister(Name, NewProtocol)
}

// ProtocolTemplate just holds a message that is passed to all children. It
// also defines a channel that will receive the number of children. Only the
// root-node will write to the channel.
type ProtocolTemplate struct {
	*sda.TreeNodeInstance
	Message    string
	ChildCount chan int
}

// NewProtocol initialises the structure for use in one round
func NewProtocol(n *sda.TreeNodeInstance) (sda.ProtocolInstance, error) {
	t := &ProtocolTemplate{
		TreeNodeInstance: n,
		ChildCount:       make(chan int),
	}
	for _, handler := range []interface{}{t.HandleAnnounce, t.HandleReply} {
		if err := t.RegisterHandler(handler); err != nil {
			return nil, errors.New("couldn't register handler: " + err.Error())
		}
	}
	return t, nil
}

// Start sends the Announce-message to all children
func (p *ProtocolTemplate) Start() error {
	log.Lvl3("Starting Template")
	return p.HandleAnnounce(StructAnnounce{p.TreeNode(),
		Announce{"cothority rulez!"}})
}

// HandleAnnounce is the first message and is used to send an ID that
// is stored in all nodes.
func (p *ProtocolTemplate) HandleAnnounce(msg StructAnnounce) error {
	p.Message = msg.Message
	if !p.IsLeaf() {
		// If we have children, send the same message to all of them
		p.SendToChildren(&msg.Announce)
	} else {
		// If we're the leaf, start to reply
		p.HandleReply(nil)
	}
	return nil
}

// HandleReply is the message going up the tree and holding a counter
// to verify the number of nodes.
func (p *ProtocolTemplate) HandleReply(reply []StructReply) error {
	children := 1
	for _, c := range reply {
		children += c.ChildrenCount
	}
	log.Lvl3(p.ServerIdentity().Address, "is done with total of", children)
	if !p.IsRoot() {
		log.Lvl3("Sending to parent")
		return p.SendTo(p.Parent(), &Reply{children})
	}
	log.Lvl3("Root-node is done - nbr of children found:", children)
	p.ChildCount <- children
	return nil
}
<commit_msg>adding done to protocol<commit_after>package template

/*
The `NewProtocol` method is used to define the protocol and to register
the handlers that will be called if a certain type of message is received.
The handlers will be treated according to their signature.

The protocol-file defines the actions that the protocol needs to do in each
step. The root-node will call the `Start`-method of the protocol. Each
node will only use the `Handle`-methods, and not call `Start` again.
*/

import (
	"errors"

	"github.com/dedis/cothority/log"
	"github.com/dedis/cothority/network"
	"github.com/dedis/cothority/sda"
)

func init() {
	network.RegisterPacketType(Announce{})
	network.RegisterPacketType(Reply{})
	sda.GlobalProtocolRegister(Name, NewProtocol)
}

// ProtocolTemplate just holds a message that is passed to all children. It
// also defines a channel that will receive the number of children. Only the
// root-node will write to the channel.
type ProtocolTemplate struct {
	*sda.TreeNodeInstance
	Message    string
	ChildCount chan int
}

// NewProtocol initialises the structure for use in one round
func NewProtocol(n *sda.TreeNodeInstance) (sda.ProtocolInstance, error) {
	t := &ProtocolTemplate{
		TreeNodeInstance: n,
		ChildCount:       make(chan int),
	}
	for _, handler := range []interface{}{t.HandleAnnounce, t.HandleReply} {
		if err := t.RegisterHandler(handler); err != nil {
			return nil, errors.New("couldn't register handler: " + err.Error())
		}
	}
	return t, nil
}

// Start sends the Announce-message to all children
func (p *ProtocolTemplate) Start() error {
	log.Lvl3("Starting Template")
	return p.HandleAnnounce(StructAnnounce{p.TreeNode(),
		Announce{"cothority rulez!"}})
}

// HandleAnnounce is the first message and is used to send an ID that
// is stored in all nodes.
func (p *ProtocolTemplate) HandleAnnounce(msg StructAnnounce) error {
	p.Message = msg.Message
	if !p.IsLeaf() {
		// If we have children, send the same message to all of them
		p.SendToChildren(&msg.Announce)
	} else {
		// If we're the leaf, start to reply
		p.HandleReply(nil)
	}
	return nil
}

// HandleReply is the message going up the tree and holding a counter
// to verify the number of nodes.
func (p *ProtocolTemplate) HandleReply(reply []StructReply) error {
	defer p.Done()

	children := 1
	for _, c := range reply {
		children += c.ChildrenCount
	}
	log.Lvl3(p.ServerIdentity().Address, "is done with total of", children)
	if !p.IsRoot() {
		log.Lvl3("Sending to parent")
		return p.SendTo(p.Parent(), &Reply{children})
	}
	log.Lvl3("Root-node is done - nbr of children found:", children)
	p.ChildCount <- children
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"time"
	"fmt"
	"log"
	"flag"
	"math/rand"
	"github.com/yaricom/goNEAT/experiments"
	"github.com/yaricom/goNEAT/neat"
	"github.com/yaricom/goNEAT/neat/genetics"
	"github.com/yaricom/goNEAT/experiments/xor"
	"github.com/yaricom/goNEAT/experiments/pole"
)

// The experiment runner boilerplate code
func main() {
	var out_dir_path = flag.String("out", "./out", "The output directory to store results.")
	var context_path = flag.String("context", "./data/xor.neat", "The execution context configuration file.")
	var genome_path = flag.String("genome", "./data/xorstartgenes", "The seed genome to start with.")
	var experiment_name = flag.String("experiment", "XOR", "The name of experiment to run. [XOR, cart_pole, cart_2pole_markov, cart_2pole_non-markov]")
	var trials_count = flag.Int("trials", 0, "The numbar of trials for experiment. Overrides the one set in configuration.")
	var log_level = flag.Int("log_level", -1, "The logger level to be used. Overrides the one set in configuration.")

	flag.Parse()

	// Seed the random-number generator with current time so that
	// the numbers will be different every time we run.
	rand.Seed(time.Now().Unix())

	// Load context configuration
	configFile, err := os.Open(*context_path)
	if err != nil {
		log.Fatal("Failed to open context configuration file: ", err)
	}
	context := neat.LoadContext(configFile)

	// Load Genome
	log.Printf("Loading start genome for %s experiment\n", *experiment_name)
	genomeFile, err := os.Open(*genome_path)
	if err != nil {
		log.Fatal("Failed to open genome file: ", err)
	}
	start_genome, err := genetics.ReadGenome(genomeFile, 1)
	if err != nil {
		log.Fatal("Failed to read start genome: ", err)
	}
	fmt.Println(start_genome)

	// Check if output dir exists
	out_dir := *out_dir_path
	if _, err := os.Stat(out_dir); err == nil {
		// backup it
		back_up_dir := fmt.Sprintf("%s-%s", out_dir, time.Now().Format("2006-01-02T15_04_05"))
		// clear it
		err = os.Rename(out_dir, back_up_dir)
		if err != nil {
			log.Fatal("Failed to do previous results backup: ", err)
		}
	}
	// create output dir
	err = os.MkdirAll(out_dir, os.ModePerm)
	if err != nil {
		log.Fatal("Failed to create output directory: ", err)
	}

	// Override context configuration parameters with ones set from command line
	if *trials_count > 0 {
		context.NumRuns = *trials_count
	}
	if *log_level >= 0 {
		neat.LogLevel = neat.LoggerLevel(*log_level)
	}

	// The 100 generation XOR experiment
	experiment := experiments.Experiment{
		Id:0,
		Trials:make(experiments.Trials, context.NumRuns),
	}
	var generationEvaluator experiments.GenerationEvaluator
	if *experiment_name == "XOR" {
		generationEvaluator = xor.XORGenerationEvaluator{OutputPath:out_dir}
	} else if *experiment_name == "cart_pole" {
		generationEvaluator = pole.CartPoleGenerationEvaluator{
			OutputPath:out_dir,
			WinBalancingSteps:500000,
			RandomStart:true,
		}
	} else if *experiment_name == "cart_2pole_markov" {
		generationEvaluator = pole.CartDoublePoleGenerationEvaluator{
			OutputPath:out_dir,
			Markov:true,
			ActionType:experiments.ContinuousAction,
		}
	} else if *experiment_name == "cart_2pole_non-markov" {
		generationEvaluator = pole.CartDoublePoleGenerationEvaluator{
			OutputPath:out_dir,
			Markov:false,
			ActionType:experiments.ContinuousAction,
		}
	}

	err = experiment.Execute(context, start_genome, generationEvaluator)
	if err != nil {
		log.Fatal("Failed to perform XOR experiment: ", err)
	}

	// Print statistics
	experiment.PrintStatistics()

	fmt.Printf(">>> Start genome file:  %s\n", *genome_path)
	fmt.Printf(">>> Configuration file: %s\n", *context_path)
}<commit_msg>Added experimental results persistence<commit_after>package main

import (
	"os"
	"time"
	"fmt"
	"log"
	"flag"
	"math/rand"
	"github.com/yaricom/goNEAT/experiments"
	"github.com/yaricom/goNEAT/neat"
	"github.com/yaricom/goNEAT/neat/genetics"
	"github.com/yaricom/goNEAT/experiments/xor"
	"github.com/yaricom/goNEAT/experiments/pole"
)

// The experiment runner boilerplate code
func main() {
	var out_dir_path = flag.String("out", "./out", "The output directory to store results.")
	var context_path = flag.String("context", "./data/xor.neat", "The execution context configuration file.")
	var genome_path = flag.String("genome", "./data/xorstartgenes", "The seed genome to start with.")
	var experiment_name = flag.String("experiment", "XOR", "The name of experiment to run. [XOR, cart_pole, cart_2pole_markov, cart_2pole_non-markov]")
	var trials_count = flag.Int("trials", 0, "The numbar of trials for experiment. Overrides the one set in configuration.")
	var log_level = flag.Int("log_level", -1, "The logger level to be used. Overrides the one set in configuration.")

	flag.Parse()

	// Seed the random-number generator with current time so that
	// the numbers will be different every time we run.
	rand.Seed(time.Now().Unix())

	// Load context configuration
	configFile, err := os.Open(*context_path)
	if err != nil {
		log.Fatal("Failed to open context configuration file: ", err)
	}
	context := neat.LoadContext(configFile)

	// Load Genome
	log.Printf("Loading start genome for %s experiment\n", *experiment_name)
	genomeFile, err := os.Open(*genome_path)
	if err != nil {
		log.Fatal("Failed to open genome file: ", err)
	}
	start_genome, err := genetics.ReadGenome(genomeFile, 1)
	if err != nil {
		log.Fatal("Failed to read start genome: ", err)
	}
	fmt.Println(start_genome)

	// Check if output dir exists
	out_dir := *out_dir_path
	if _, err := os.Stat(out_dir); err == nil {
		// backup it
		back_up_dir := fmt.Sprintf("%s-%s", out_dir, time.Now().Format("2006-01-02T15_04_05"))
		// clear it
		err = os.Rename(out_dir, back_up_dir)
		if err != nil {
			log.Fatal("Failed to do previous results backup: ", err)
		}
	}
	// create output dir
	err = os.MkdirAll(out_dir, os.ModePerm)
	if err != nil {
		log.Fatal("Failed to create output directory: ", err)
	}

	// Override context configuration parameters with ones set from command line
	if *trials_count > 0 {
		context.NumRuns = *trials_count
	}
	if *log_level >= 0 {
		neat.LogLevel = neat.LoggerLevel(*log_level)
	}

	// The 100 generation XOR experiment
	experiment := experiments.Experiment{
		Id:0,
		Trials:make(experiments.Trials, context.NumRuns),
	}
	var generationEvaluator experiments.GenerationEvaluator
	if *experiment_name == "XOR" {
		generationEvaluator = xor.XORGenerationEvaluator{OutputPath:out_dir}
	} else if *experiment_name == "cart_pole" {
		generationEvaluator = pole.CartPoleGenerationEvaluator{
			OutputPath:out_dir,
			WinBalancingSteps:500000,
			RandomStart:true,
		}
	} else if *experiment_name == "cart_2pole_markov" {
		generationEvaluator = pole.CartDoublePoleGenerationEvaluator{
			OutputPath:out_dir,
			Markov:true,
			ActionType:experiments.ContinuousAction,
		}
	} else if *experiment_name == "cart_2pole_non-markov" {
		generationEvaluator = pole.CartDoublePoleGenerationEvaluator{
			OutputPath:out_dir,
			Markov:false,
			ActionType:experiments.ContinuousAction,
		}
	}

	err = experiment.Execute(context, start_genome, generationEvaluator)
	if err != nil {
		log.Fatal("Failed to perform XOR experiment: ", err)
	}

	// Print statistics
	experiment.PrintStatistics()

	fmt.Printf(">>> Start genome file:  %s\n", *genome_path)
	fmt.Printf(">>> Configuration file: %s\n", *context_path)

	// Save experiment data
	expResPath := fmt.Sprintf("%s/%s.dat", out_dir, *experiment_name)
	expResFile, err := os.Create(expResPath)
	if err == nil {
		err = experiment.Write(expResFile)
	}
	if err != nil {
		log.Fatal("Failed to save experiment results", err)
	}
}<|endoftext|>


<commit_before>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

// The provider package holds constants identifying known provider types.
// They have hitherto only been used for nefarious purposes; no new code
// should use them, and when old code is updated to no longer use them
// they must be deleted.
package provider

const (
	Azure     = "azure"
	Dummy     = "dummy"
	EC2       = "ec2"
	Joyent    = "joyent"
	Local     = "local"
	MAAS      = "maas"
	Manual    = "manual"
	Null      = "null"
	OpenStack = "openstack"
)

// IsManual returns true iff the specified provider
// type refers to the manual provider.
func IsManual(provider string) bool {
	return provider == Null || provider == Manual
}
<commit_msg>provider: remove unused constants<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

// The provider package holds constants identifying known provider types.
// They have hitherto only been used for nefarious purposes; no new code
// should use them, and when old code is updated to no longer use them
// they must be deleted.
package provider

const (
	Joyent    = "joyent"
	Local     = "local"
	MAAS      = "maas"
)

// IsManual returns true iff the specified provider
// type refers to the manual provider.
func IsManual(provider string) bool {
	switch provider {
	case "null", "manual":
		return true
	default:
		return false
	}
}
<|endoftext|>


<commit_before>package main

// #cgo CFLAGS: -Iajtcl/inc -Iajtcl/target/linux
// #cgo LDFLAGS: -Lajtcl -lajtcl
// #include <stdio.h>
// #include <aj_debug.h>
// #include <aj_guid.h>
// #include <aj_creds.h>
// #include "alljoyn.h"
//
// AJ_BusAttachment c_bus;
// AJ_Message c_message;
// AJ_Message c_reply;
//
// uint32_t Get_AJ_Message_msgId() {
//   return c_message.msgId;
// }
//
// uint32_t Get_AJ_Message_bodyLen() {
//   return c_message.hdr->bodyLen;
// }
//
// const char * Get_AJ_Message_signature() {
//    return c_message.signature;
// }
//
// const char * Get_AJ_Message_objPath() {
//    return c_message.objPath;
// }
//
// const char * Get_AJ_Message_iface() {
//    return c_message.iface;
// }
//
// const char * Get_AJ_Message_member() {
//    return c_message.member;
// }
//
// const char * Get_AJ_Message_destination() {
//    return c_message.destination;
// }
//
// void * Get_AJ_ReplyMessage() {
// 	return &c_reply;
// }
//
// void * Get_AJ_Message() {
//   return &c_message;
// }
// void * Get_AJ_BusAttachment() {
//   return &c_bus;
// }
//
// void * Allocate_AJ_Object_Array(uint32_t array_size) {
//   return AJ_Malloc(sizeof(AJ_Object)*array_size);
// }
//
// void * Create_AJ_Object(uint32_t index, void * array, char* path, AJ_InterfaceDescription* interfaces, uint8_t flags, void* context) {
//	 AJ_Object * obj = array + index * sizeof(AJ_Object);
//   obj->path = path;
//	 obj->interfaces = interfaces;
//   obj->flags = flags;
//   obj->context = context;
//   return obj;
// }
//
//
import "C"
import (
	"bytes"
	"encoding/binary"
	"github.com/godbus/dbus"
	"github.com/godbus/dbus/introspect"
	"log"
	"unsafe"
)

type IntrospectProvider func(dbusService, dbusPath string) (node *introspect.Node, err error)

type AllJoynBindingInfo struct {
	allJoynService string
	allJoynPath    string
	dbusPath       string
	introspectData *introspect.Node
}

type AllJoynBridge struct {
	bus                *dbus.Conn
	introspectProvider IntrospectProvider
	services           map[string][]*AllJoynBindingInfo
}

func NewAllJoynBridge(bus *dbus.Conn, introspectProvider IntrospectProvider) *AllJoynBridge {
	bridge := new(AllJoynBridge)
	bridge.bus = bus
	bridge.services = make(map[string][]*AllJoynBindingInfo)
	bridge.introspectProvider = introspectProvider

	return bridge
}

func ParseArgumentOrProperty(name, access, _type string) string {
	s := name
	if access == "in" || access == "write" {
		s = s + "<"
	} else if access == "out" || access == "read" {
		s = s + ">"
	} else {
		s = s + "="
	}
	s = s + _type
	return s
}

func ParseArguments(args []introspect.Arg) string {
	argString := ""
	for _, arg := range args {
		argString = argString + " " + ParseArgumentOrProperty(arg.Name, arg.Direction, arg.Type)
	}
	return argString
}

func ParseAllJoynInterfaces(interfaces []introspect.Interface) []C.AJ_InterfaceDescription {
	res := make([]C.AJ_InterfaceDescription, 0)

	for _, iface := range interfaces {
		desc := make([]*C.char, 0)
		desc = append(desc, C.CString(iface.Name))

		for _, method := range iface.Methods {
			methogString := "?" + method.Name
			argString := ParseArguments(method.Args)
			log.Print(methogString + argString)
			desc = append(desc, C.CString(methogString+argString))
		}

		for _, signal := range iface.Signals {
			signalString := "!" + signal.Name
			argString := ParseArguments(signal.Args)
			log.Print(signalString + argString)
			desc = append(desc, C.CString(signalString+argString))
		}

		for _, prop := range iface.Properties {
			propString := "@" + ParseArgumentOrProperty(prop.Name, prop.Access, prop.Type)
			log.Print(propString)
			desc = append(desc, C.CString(propString))
		}

		desc = append(desc, nil)
		log.Print(desc)
		res = append(res, (C.AJ_InterfaceDescription)(&desc[0]))
	}
	res = append(res, nil)
	return res
}

var interfaces []C.AJ_InterfaceDescription

func GetAllJoynObjects(services []*AllJoynBindingInfo) unsafe.Pointer {
	array := C.Allocate_AJ_Object_Array(C.uint32_t(len(services) + 1))

	for i, service := range services {
		interfaces = ParseAllJoynInterfaces(service.introspectData.Interfaces)
		C.Create_AJ_Object(C.uint32_t(i), array, C.CString(service.introspectData.Name), &interfaces[0], C.uint8_t(0), unsafe.Pointer(nil))
		C.Create_AJ_Object(C.uint32_t(i+1), array, nil, nil, 0, nil)
	}

	return array
}

func (a *AllJoynBridge) StartAllJoyn(dbusService string) *dbus.Error {
	objects := GetAllJoynObjects(a.services[dbusService])
	// go func() {
	C.AJ_Initialize()
	C.AJ_RegisterObjects((*C.AJ_Object)(objects), nil)
	C.AJ_PrintXML((*C.AJ_Object)(objects))
	connected := false
	var status C.AJ_Status = C.AJ_OK
	busAttachment := C.Get_AJ_BusAttachment()
	msg := C.Get_AJ_Message()
	reply := C.Get_AJ_ReplyMessage()

	var data uintptr
	var actual C.size_t

	log.Printf("CreateAJ_BusAttachment(): %+v", busAttachment)

	for {
		if !connected {
			status = C.AJ_StartService((*C.AJ_BusAttachment)(busAttachment),
				nil,
				60*1000, // TODO: Move connection timeout to config
				C.FALSE,
				25, // TODO: Move port to config
				C.CString(dbusService),
				C.AJ_NAME_REQ_DO_NOT_QUEUE,
				nil)

			if status != C.AJ_OK {
				continue
			}

			log.Printf("StartService returned %d, %+v", status, busAttachment)

			connected = true
		}

		status = C.AJ_UnmarshalMsg((*C.AJ_BusAttachment)(busAttachment), (*C.AJ_Message)(msg),
			5*1000) // TODO: Move unmarshal timeout to config
		log.Printf("AJ_UnmarshalMsg: %+v", status)

		if C.AJ_ERR_TIMEOUT == status {
			continue
		}

		if C.AJ_OK == status {

			msgId := C.Get_AJ_Message_msgId()
			log.Printf("Received message: %+v", msgId)

			switch {
			case msgId == C.AJ_METHOD_ACCEPT_SESSION:
				{
					// uint16_t port;
					// char* joiner;
					// uint32_t sessionId;

					// AJ_UnmarshalArgs(&msg, "qus", &port, &sessionId, &joiner);
					status = C.AJ_BusReplyAcceptSession((*C.AJ_Message)(msg), C.TRUE)
					log.Printf("ACCEPT_SESSION: %+v", msgId)
				}

			case msgId == C.AJ_SIGNAL_SESSION_LOST_WITH_REASON:
				{
					// uint32_t id, reason;
					// AJ_UnmarshalArgs(&msg, "uu", &id, &reason);
					// AJ_AlwaysPrintf(("Session lost. ID = %u, reason = %u", id, reason));
					log.Printf("Session lost: %+v", msgId)
				}
			case (uint32(msgId) & 0x01000000) != 0:
				{
					b := make([]byte, 0)
					signature := C.GoString(C.Get_AJ_Message_signature())
					bodyLen := C.Get_AJ_Message_bodyLen()
					for i := 0; i < int(bodyLen); i++ {
						status = C.AJ_UnmarshalRaw((*C.AJ_Message)(msg), (*unsafe.Pointer)(unsafe.Pointer(&data)), C.size_t(1), (*C.size_t)(unsafe.Pointer(&actual)))
						if status == C.AJ_OK {
							b = append(b, C.GoBytes(unsafe.Pointer(data), C.int(actual))...)
							log.Printf("Reading RAW message, status = %d, actual = %d", status, actual)
						} else {
							log.Printf("Error while reading message body, status = %d", status)
							break
						}
					}
					s, err := ParseSignature(signature)

					if err != nil {
						log.Printf("Error parsing signature: %s", err)
						break
					}

					d := newDecoder(bytes.NewReader(b), binary.LittleEndian)
					res, err := d.Decode(s)

					if err != nil {
						log.Printf("Error decoding message [%+v] : %s", b, err)
						break
					}

					log.Printf("Received application alljoyn message, signature: %s, bytes: %+v, decoded: %+v", signature, b, res)

					objPath := C.GoString(C.Get_AJ_Message_objPath())
					member := C.GoString(C.Get_AJ_Message_member())
					destination := C.GoString(C.Get_AJ_Message_destination())
					iface := C.GoString(C.Get_AJ_Message_iface())

					log.Printf("Message [objPath, member, iface, destination]: %s, %s, %s, %s", objPath, member, iface, destination)

					for _, service := range a.services[dbusService] {
						if (service.allJoynPath == objPath) && (service.allJoynService == destination) {
							remote := a.bus.Object(dbusService, dbus.ObjectPath(service.dbusPath))
							res := remote.Call(iface+"."+member, 0, res...)

							if res.Err != nil {
								log.Printf("Error calling dbus method (%s): %s", iface+"."+member, res.Err)
								return dbus.NewError(res.Err.Error(), nil)
							}

							C.AJ_MarshalReplyMsg((*C.AJ_Message)(msg), (*C.AJ_Message)(reply))
							buf := new(bytes.Buffer)
							enc := newEncoder(buf, binary.LittleEndian)
							err = enc.Encode(res.Body...)
							if err != nil {
								log.Printf("Error encoding result: %s", err)
								break
							}
							log.Printf("Encoded reply: %+v", buf.Bytes())
							C.AJ_DeliverMsgPartial((*C.AJ_Message)(reply), C.uint32_t(buf.Len()))
							C.AJ_MarshalRaw((*C.AJ_Message)(reply), unsafe.Pointer(&buf.Bytes()[0]), C.size_t(buf.Len()))
							C.AJ_DeliverMsg((*C.AJ_Message)(reply))
							break
						}
					}
				}
			default:
				/* Pass to the built-in handlers. */
				log.Printf("Passing msgId %+v to AllJoyn", msgId)
				status = C.AJ_BusHandleBusMessage((*C.AJ_Message)(msg))
			}
		}

		/* Messages MUST be discarded to free resources. */
		C.AJ_CloseMsg((*C.AJ_Message)(msg))

		if status == C.AJ_ERR_READ {
			C.AJ_Disconnect((*C.AJ_BusAttachment)(busAttachment))
			log.Print("AllJoyn disconnected, retrying")
			connected = false
			C.AJ_Sleep(1000 * 2) // TODO: Move sleep time to const
		}
	}
	// }()
	return nil
}

func (a *AllJoynBridge) addService(service string, info *AllJoynBindingInfo) {
	services, ok := a.services[service]
	if ok {
		a.services[service] = append(services, info)
	} else {
		a.services[service] = []*AllJoynBindingInfo{info}
	}
}

func (a *AllJoynBridge) AddService(dbusPath, dbusService, allJoynPath, allJoynService string) *dbus.Error {
	node, err := a.introspectProvider(dbusService, dbusPath)

	if err != nil {
		log.Printf("Error getting introspect from [%s, %s]: %s", dbusService, dbusPath, err)
	}

	a.addService(dbusService, &AllJoynBindingInfo{allJoynService, allJoynPath, dbusPath, node})

	log.Printf("Received introspect: %+v", node)

	return nil
}

func main() {
	bus, err := dbus.SystemBus()
	bus.RequestName("com.devicehive.alljoyn.bridge",
		dbus.NameFlagDoNotQueue)

	if err != nil {
		log.Panic(err)
	}

	allJoynBridge := NewAllJoynBridge(bus, func(dbusService, dbusPath string) (*introspect.Node, error) {
		return introspect.Call(bus.Object(dbusService, dbus.ObjectPath(dbusPath)))
	})

	bus.Export(allJoynBridge, "/com/devicehive/alljoyn/bridge", "com.devicehive.alljoyn.bridge")
	select {}
}
<commit_msg>Logging<commit_after>package main

// #cgo CFLAGS: -Iajtcl/inc -Iajtcl/target/linux
// #cgo LDFLAGS: -Lajtcl -lajtcl
// #include <stdio.h>
// #include <aj_debug.h>
// #include <aj_guid.h>
// #include <aj_creds.h>
// #include "alljoyn.h"
//
// AJ_BusAttachment c_bus;
// AJ_Message c_message;
// AJ_Message c_reply;
//
// uint32_t Get_AJ_Message_msgId() {
//   return c_message.msgId;
// }
//
// uint32_t Get_AJ_Message_bodyLen() {
//   return c_message.hdr->bodyLen;
// }
//
// const char * Get_AJ_Message_signature() {
//    return c_message.signature;
// }
//
// const char * Get_AJ_Message_objPath() {
//    return c_message.objPath;
// }
//
// const char * Get_AJ_Message_iface() {
//    return c_message.iface;
// }
//
// const char * Get_AJ_Message_member() {
//    return c_message.member;
// }
//
// const char * Get_AJ_Message_destination() {
//    return c_message.destination;
// }
//
// void * Get_AJ_ReplyMessage() {
// 	return &c_reply;
// }
//
// void * Get_AJ_Message() {
//   return &c_message;
// }
// void * Get_AJ_BusAttachment() {
//   return &c_bus;
// }
//
// void * Allocate_AJ_Object_Array(uint32_t array_size) {
//   return AJ_Malloc(sizeof(AJ_Object)*array_size);
// }
//
// void * Create_AJ_Object(uint32_t index, void * array, char* path, AJ_InterfaceDescription* interfaces, uint8_t flags, void* context) {
//	 AJ_Object * obj = array + index * sizeof(AJ_Object);
//   obj->path = path;
//	 obj->interfaces = interfaces;
//   obj->flags = flags;
//   obj->context = context;
//   return obj;
// }
//
//
import "C"
import (
	"bytes"
	"encoding/binary"
	"github.com/godbus/dbus"
	"github.com/godbus/dbus/introspect"
	"log"
	"unsafe"
)

type IntrospectProvider func(dbusService, dbusPath string) (node *introspect.Node, err error)

type AllJoynBindingInfo struct {
	allJoynService string
	allJoynPath    string
	dbusPath       string
	introspectData *introspect.Node
}

type AllJoynBridge struct {
	bus                *dbus.Conn
	introspectProvider IntrospectProvider
	services           map[string][]*AllJoynBindingInfo
}

func NewAllJoynBridge(bus *dbus.Conn, introspectProvider IntrospectProvider) *AllJoynBridge {
	bridge := new(AllJoynBridge)
	bridge.bus = bus
	bridge.services = make(map[string][]*AllJoynBindingInfo)
	bridge.introspectProvider = introspectProvider

	return bridge
}

func ParseArgumentOrProperty(name, access, _type string) string {
	s := name
	if access == "in" || access == "write" {
		s = s + "<"
	} else if access == "out" || access == "read" {
		s = s + ">"
	} else {
		s = s + "="
	}
	s = s + _type
	return s
}

func ParseArguments(args []introspect.Arg) string {
	argString := ""
	for _, arg := range args {
		argString = argString + " " + ParseArgumentOrProperty(arg.Name, arg.Direction, arg.Type)
	}
	return argString
}

func ParseAllJoynInterfaces(interfaces []introspect.Interface) []C.AJ_InterfaceDescription {
	res := make([]C.AJ_InterfaceDescription, 0)

	for _, iface := range interfaces {
		desc := make([]*C.char, 0)
		desc = append(desc, C.CString(iface.Name))

		for _, method := range iface.Methods {
			methogString := "?" + method.Name
			argString := ParseArguments(method.Args)
			log.Print(methogString + argString)
			desc = append(desc, C.CString(methogString+argString))
		}

		for _, signal := range iface.Signals {
			signalString := "!" + signal.Name
			argString := ParseArguments(signal.Args)
			log.Print(signalString + argString)
			desc = append(desc, C.CString(signalString+argString))
		}

		for _, prop := range iface.Properties {
			propString := "@" + ParseArgumentOrProperty(prop.Name, prop.Access, prop.Type)
			log.Print(propString)
			desc = append(desc, C.CString(propString))
		}

		desc = append(desc, nil)
		log.Print(desc)
		res = append(res, (C.AJ_InterfaceDescription)(&desc[0]))
	}
	res = append(res, nil)
	return res
}

var interfaces []C.AJ_InterfaceDescription

func GetAllJoynObjects(services []*AllJoynBindingInfo) unsafe.Pointer {
	array := C.Allocate_AJ_Object_Array(C.uint32_t(len(services) + 1))

	for i, service := range services {
		interfaces = ParseAllJoynInterfaces(service.introspectData.Interfaces)
		C.Create_AJ_Object(C.uint32_t(i), array, C.CString(service.introspectData.Name), &interfaces[0], C.uint8_t(0), unsafe.Pointer(nil))
		C.Create_AJ_Object(C.uint32_t(i+1), array, nil, nil, 0, nil)
	}

	return array
}

func (a *AllJoynBridge) StartAllJoyn(dbusService string) *dbus.Error {
	objects := GetAllJoynObjects(a.services[dbusService])
	// go func() {
	C.AJ_Initialize()
	C.AJ_RegisterObjects((*C.AJ_Object)(objects), nil)
	C.AJ_PrintXML((*C.AJ_Object)(objects))
	connected := false
	var status C.AJ_Status = C.AJ_OK
	busAttachment := C.Get_AJ_BusAttachment()
	msg := C.Get_AJ_Message()
	reply := C.Get_AJ_ReplyMessage()

	var data uintptr
	var actual C.size_t

	log.Printf("CreateAJ_BusAttachment(): %+v", busAttachment)

	for {
		if !connected {
			status = C.AJ_StartService((*C.AJ_BusAttachment)(busAttachment),
				nil,
				60*1000, // TODO: Move connection timeout to config
				C.FALSE,
				25, // TODO: Move port to config
				C.CString(dbusService),
				C.AJ_NAME_REQ_DO_NOT_QUEUE,
				nil)

			if status != C.AJ_OK {
				continue
			}

			log.Printf("StartService returned %d, %+v", status, busAttachment)

			connected = true
		}

		status = C.AJ_UnmarshalMsg((*C.AJ_BusAttachment)(busAttachment), (*C.AJ_Message)(msg),
			5*1000) // TODO: Move unmarshal timeout to config
		log.Printf("AJ_UnmarshalMsg: %+v", status)

		if C.AJ_ERR_TIMEOUT == status {
			continue
		}

		if C.AJ_OK == status {

			msgId := C.Get_AJ_Message_msgId()
			log.Printf("Received message: %+v", msgId)

			switch {
			case msgId == C.AJ_METHOD_ACCEPT_SESSION:
				{
					// uint16_t port;
					// char* joiner;
					// uint32_t sessionId;

					// AJ_UnmarshalArgs(&msg, "qus", &port, &sessionId, &joiner);
					status = C.AJ_BusReplyAcceptSession((*C.AJ_Message)(msg), C.TRUE)
					log.Printf("ACCEPT_SESSION: %+v", msgId)
				}

			case msgId == C.AJ_SIGNAL_SESSION_LOST_WITH_REASON:
				{
					// uint32_t id, reason;
					// AJ_UnmarshalArgs(&msg, "uu", &id, &reason);
					// AJ_AlwaysPrintf(("Session lost. ID = %u, reason = %u", id, reason));
					log.Printf("Session lost: %+v", msgId)
				}
			case (uint32(msgId) & 0x01000000) != 0:
				{
					b := make([]byte, 0)
					signature := C.GoString(C.Get_AJ_Message_signature())
					bodyLen := C.Get_AJ_Message_bodyLen()
					for i := 0; i < int(bodyLen); i++ {
						status = C.AJ_UnmarshalRaw((*C.AJ_Message)(msg), (*unsafe.Pointer)(unsafe.Pointer(&data)), C.size_t(1), (*C.size_t)(unsafe.Pointer(&actual)))
						if status == C.AJ_OK {
							b = append(b, C.GoBytes(unsafe.Pointer(data), C.int(actual))...)
							log.Printf("Reading RAW message, status = %d, actual = %d", status, actual)
						} else {
							log.Printf("Error while reading message body, status = %d", status)
							break
						}
					}
					s, err := ParseSignature(signature)

					if err != nil {
						log.Printf("Error parsing signature: %s", err)
						break
					}

					d := newDecoder(bytes.NewReader(b), binary.LittleEndian)
					res, err := d.Decode(s)

					if err != nil {
						log.Printf("Error decoding message [%+v] : %s", b, err)
						break
					}

					log.Printf("Received application alljoyn message, signature: %s, bytes: %+v, decoded: %+v", signature, b, res)

					objPath := C.GoString(C.Get_AJ_Message_objPath())
					member := C.GoString(C.Get_AJ_Message_member())
					destination := C.GoString(C.Get_AJ_Message_destination())
					iface := C.GoString(C.Get_AJ_Message_iface())

					log.Printf("Message [objPath, member, iface, destination]: %s, %s, %s, %s", objPath, member, iface, destination)

					for _, service := range a.services[dbusService] {
						if (service.allJoynPath == objPath) && (service.allJoynService == destination) {
							log.Print("Found matching dbus service: %+v", service)
							remote := a.bus.Object(dbusService, dbus.ObjectPath(service.dbusPath))
							res := remote.Call(iface+"."+member, 0, res...)

							if res.Err != nil {
								log.Printf("Error calling dbus method (%s): %s", iface+"."+member, res.Err)
								return dbus.NewError(res.Err.Error(), nil)
							}

							C.AJ_MarshalReplyMsg((*C.AJ_Message)(msg), (*C.AJ_Message)(reply))
							buf := new(bytes.Buffer)
							enc := newEncoder(buf, binary.LittleEndian)
							err = enc.Encode(res.Body...)
							if err != nil {
								log.Printf("Error encoding result: %s", err)
								break
							}
							log.Printf("Encoded reply: %+v", buf.Bytes())
							C.AJ_DeliverMsgPartial((*C.AJ_Message)(reply), C.uint32_t(buf.Len()))
							C.AJ_MarshalRaw((*C.AJ_Message)(reply), unsafe.Pointer(&buf.Bytes()[0]), C.size_t(buf.Len()))
							C.AJ_DeliverMsg((*C.AJ_Message)(reply))
							break
						}
					}
				}
			default:
				/* Pass to the built-in handlers. */
				log.Printf("Passing msgId %+v to AllJoyn", msgId)
				status = C.AJ_BusHandleBusMessage((*C.AJ_Message)(msg))
			}
		}

		/* Messages MUST be discarded to free resources. */
		C.AJ_CloseMsg((*C.AJ_Message)(msg))

		if status == C.AJ_ERR_READ {
			C.AJ_Disconnect((*C.AJ_BusAttachment)(busAttachment))
			log.Print("AllJoyn disconnected, retrying")
			connected = false
			C.AJ_Sleep(1000 * 2) // TODO: Move sleep time to const
		}
	}
	// }()
	return nil
}

func (a *AllJoynBridge) addService(service string, info *AllJoynBindingInfo) {
	services, ok := a.services[service]
	if ok {
		a.services[service] = append(services, info)
	} else {
		a.services[service] = []*AllJoynBindingInfo{info}
	}
}

func (a *AllJoynBridge) AddService(dbusPath, dbusService, allJoynPath, allJoynService string) *dbus.Error {
	node, err := a.introspectProvider(dbusService, dbusPath)

	if err != nil {
		log.Printf("Error getting introspect from [%s, %s]: %s", dbusService, dbusPath, err)
	}

	a.addService(dbusService, &AllJoynBindingInfo{allJoynService, allJoynPath, dbusPath, node})

	log.Printf("Received introspect: %+v", node)

	return nil
}

func main() {
	bus, err := dbus.SystemBus()
	bus.RequestName("com.devicehive.alljoyn.bridge",
		dbus.NameFlagDoNotQueue)

	if err != nil {
		log.Panic(err)
	}

	allJoynBridge := NewAllJoynBridge(bus, func(dbusService, dbusPath string) (*introspect.Node, error) {
		return introspect.Call(bus.Object(dbusService, dbus.ObjectPath(dbusPath)))
	})

	bus.Export(allJoynBridge, "/com/devicehive/alljoyn/bridge", "com.devicehive.alljoyn.bridge")
	select {}
}
<|endoftext|>


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

package isvcs

import (
	"github.com/control-center/go-zookeeper/zk"
	"github.com/zenoss/glog"

	"time"
)

var Zookeeper IServiceDefinition
var zookeeper *IService

func initZK() {
	var err error
	Zookeeper = IServiceDefinition{
		ID:      ZookeeperISVC.ID,
		Name:    "zookeeper",
		Repo:    ZK_IMAGE_REPO,
		Tag:     ZK_IMAGE_TAG,
		Command: func() string { return "exec start-zookeeper" },
		PortBindings: []portBinding{
			// client port
			{
				HostIp:         "0.0.0.0",
				HostIpOverride: "",
				HostPort:       2181,
			},
			// exhibitor port
			{
				HostIp:         "127.0.0.1",
				HostIpOverride: "SERVICED_ISVC_ZOOKEEPER_PORT_12181_HOSTIP",
				HostPort:       12181,
			},
			// peer port
			{
				HostIp:         "0.0.0.0",
				HostIpOverride: "",
				HostPort:       2888,
			},
			// leader port
			{
				HostIp:         "0.0.0.0",
				HostIpOverride: "",
				HostPort:       3888,
			},
		},
		Volumes: map[string]string{"data": "/var/zookeeper"},
	}

	defaultHealthCheck := healthCheckDefinition{
		healthCheck: zkHealthCheck,
		Interval:    DEFAULT_HEALTHCHECK_INTERVAL,
		Timeout:     DEFAULT_HEALTHCHECK_TIMEOUT,
	}

	Zookeeper.HealthChecks = map[string]healthCheckDefinition{
		DEFAULT_HEALTHCHECK_NAME: defaultHealthCheck,
	}

	zookeeper, err = NewIService(Zookeeper)
	if err != nil {
		glog.Fatalf("Error initializing zookeeper container: %s", err)
	}
}

// a health check for zookeeper
func zkHealthCheck(halt <-chan struct{}) error {
	// minUptime til zookeeper is considered available
	minUptime := time.Second * 2
	// timer to verify that the service has been available for the min duration
	timer := time.NewTimer(minUptime)
	timer.Stop()
	defer timer.Stop()
	// flag to determine if the timer is set or not
	stopped := true
	for {
		// establish a zookeeper connection
		conn, _, err := zk.Connect([]string{"127.0.0.1:2181"}, time.Second*10)
		if err != nil {
			glog.V(1).Infof("Could not connect to zookeeper: %s", err)
			timer.Stop()
			stopped = true
		} else {
			// Verify that you can read from root (even if root is empty)
			if _, _, err := conn.Children("/"); err != nil {
				glog.V(1).Infof("Zookeeper not ready: %s", err)
				timer.Stop()
				stopped = true
			} else if stopped {
				// Reset the success timer if it is stopped
				timer.Reset(minUptime)
				stopped = false
			}
		}
		// close the client connection
		if conn != nil {
			conn.Close()
		}
		select {
		case <-halt:
			glog.V(1).Infof("Quit healthcheck for zookeeper")
			return nil
		case <-timer.C:
			glog.V(1).Infof("Zookeeper running, browser at http://localhost:12181/exhibitor/v1/ui/index.html")
			return nil
		default:
			time.Sleep(time.Second)
		}
	}
}
<commit_msg>change healtcheck to use zk session state<commit_after>// Copyright 2014 The Serviced Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package isvcs

import (
	"github.com/control-center/go-zookeeper/zk"
	"github.com/zenoss/glog"

	"time"
)

var Zookeeper IServiceDefinition
var zookeeper *IService

func initZK() {
	var err error
	Zookeeper = IServiceDefinition{
		ID:      ZookeeperISVC.ID,
		Name:    "zookeeper",
		Repo:    ZK_IMAGE_REPO,
		Tag:     ZK_IMAGE_TAG,
		Command: func() string { return "exec start-zookeeper" },
		PortBindings: []portBinding{
			// client port
			{
				HostIp:         "0.0.0.0",
				HostIpOverride: "",
				HostPort:       2181,
			},
			// exhibitor port
			{
				HostIp:         "127.0.0.1",
				HostIpOverride: "SERVICED_ISVC_ZOOKEEPER_PORT_12181_HOSTIP",
				HostPort:       12181,
			},
			// peer port
			{
				HostIp:         "0.0.0.0",
				HostIpOverride: "",
				HostPort:       2888,
			},
			// leader port
			{
				HostIp:         "0.0.0.0",
				HostIpOverride: "",
				HostPort:       3888,
			},
		},
		Volumes: map[string]string{"data": "/var/zookeeper"},
	}

	defaultHealthCheck := healthCheckDefinition{
		healthCheck: zkHealthCheck,
		Interval:    DEFAULT_HEALTHCHECK_INTERVAL,
		Timeout:     DEFAULT_HEALTHCHECK_TIMEOUT,
	}

	Zookeeper.HealthChecks = map[string]healthCheckDefinition{
		DEFAULT_HEALTHCHECK_NAME: defaultHealthCheck,
	}

	zookeeper, err = NewIService(Zookeeper)
	if err != nil {
		glog.Fatalf("Error initializing zookeeper container: %s", err)
	}
}

// a health check for zookeeper
func zkHealthCheck(halt <-chan struct{}) error {
	for {
		// establish a zookeeper connection
		conn, ec, err := zk.Connect([]string{"127.0.0.1:2181"}, time.Second*10)
		defer func() {
			if conn != nil {
				conn.Close()
			}
		}()
		if err != nil {
			glog.V(1).Infof("Could not connect to zookeeper: %s", err)
			time.Sleep(1 * time.Second)
		} else {
			//wait for session
			sesstionTimeout := 5 * time.Second
			sessionTimer := time.NewTimer(sesstionTimeout)
			defer sessionTimer.Stop()
			timedOut := false
			for !timedOut {
				select {
				case e := <-ec:
					if e.State == zk.StateHasSession {
						// success
						glog.V(1).Infof("Zookeeper running, browser at http://localhost:12181/exhibitor/v1/ui/index.html")
						return nil
					}
				case <-halt:
					glog.V(1).Infof("Quit healthcheck for zookeeper")
					return nil
				case <-sessionTimer.C:
					//Fall through loop and try again
					glog.V(1).Infof("ZK Session not available in %s", sesstionTimeout)
					timedOut = true
				}
			}
		}
	}
}
<|endoftext|>