<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"strings"
	"syscall"
)

func main() {
	var dependencies []StaticLibrary
	parallels := 0
	done := make(chan bool)

	// set parallel numbers
	runtime.GOMAXPROCS(runtime.NumCPU())
	jobs := runtime.NumCPU()

	// Parse flags
	version := flag.String("v", NGINX_VERSION, "nginx version")
	nginxConfPath := flag.String("c", "", "configuration file for building nginx")
	modulesConfPath := flag.String("m", "", "configuration file for 3rd party modules")
	workParentDir := flag.String("d", "", "working directory")
	verbose := flag.Bool("verbose", false, "verbose mode")
	pcreStatic := flag.Bool("pcre", false, "embedded PCRE statically")
	pcreVersion := flag.String("pcreversion", PCRE_VERSION, "PCRE version")
	openSSLStatic := flag.Bool("openssl", false, "embedded PCRE statically")
	openSSLVersion := flag.String("opensslversion", OPENSSL_VERSION, "OpenSSL version")
	zlibStatic := flag.Bool("zlib", false, "embedded zlib statically")
	zlibVersion := flag.String("zlibversion", ZLIB_VERSION, "zlib version")
	clear := flag.Bool("clear", false, "remove entries in working directory")
	versionb := flag.Bool("version", false, "print nginx-build versions")
	versions := flag.Bool("versions", false, "print nginx versions")
	flag.Parse()

	if *versionb {
		printNginxBuildVersion()
		os.Exit(0)
	}

	if *versions {
		printNginxVersions()
		os.Exit(0)
	}

	// set verbose mode
	VerboseEnabled = *verbose

	nginxBuilder := makeBuilder(COMPONENT_NGINX, *version)
	pcreBuilder := makeBuilder(COMPONENT_PCRE, *pcreVersion)
	openSSLBuilder := makeBuilder(COMPONENT_OPENSSL, *openSSLVersion)
	zlibBuilder := makeBuilder(COMPONENT_ZLIB, *zlibVersion)

	// change default umask
	_ = syscall.Umask(0)

	versionCheck(*version)

	nginxConf, err := fileGetContents(*nginxConfPath)
	if err != nil {
		log.Fatal(err.Error())
	}

	modules3rd, err := loadModules3rdFile(*modulesConfPath)
	if err != nil {
		log.Fatal(err.Error())
	}

	if len(*workParentDir) == 0 {
		log.Fatal("set working directory with -d")
	}

	if !fileExists(*workParentDir) {
		log.Fatalf("working directory(%s) does not exist.", *workParentDir)
	}

	workDir := *workParentDir + "/" + *version
	if *clear {
		err := os.RemoveAll(workDir)
		if err != nil {
			log.Fatal(err.Error())
		}
	}

	if !fileExists(workDir) {
		err := os.Mkdir(workDir, 0755)
		if err != nil {
			log.Fatalf("Failed to create working directory(%s) does not exist.", workDir)
		}
	}

	rootDir := saveCurrentDir()
	// cd workDir
	err = os.Chdir(workDir)
	if err != nil {
		log.Fatal(err.Error())
	}

	if *pcreStatic {
		parallels++
		go downloadAndExtractParallel(&pcreBuilder, done)
	}

	if *openSSLStatic {
		parallels++
		go downloadAndExtractParallel(&openSSLBuilder, done)
	}

	if *zlibStatic {
		parallels++
		go downloadAndExtractParallel(&zlibBuilder, done)
	}

	parallels++
	go downloadAndExtractParallel(&nginxBuilder, done)

	if len(modules3rd) > 0 {
		parallels += len(modules3rd)
		for _, m := range modules3rd {
			go downloadAndExtractModule3rdParallel(m, done)
		}

	}

	// wait until all downloading processes by goroutine finish
	for i := 0; i < parallels; i++ {
		<-done
	}

	if len(modules3rd) > 0 {
		for _, m := range modules3rd {
			provideModule3rd(m)
		}
	}

	// cd workDir/nginx-${version}
	os.Chdir(nginxBuilder.sourcePath())

	if *pcreStatic {
		dependencies = append(dependencies, makeStaticLibrary(&pcreBuilder))
	}

	if *openSSLStatic {
		dependencies = append(dependencies, makeStaticLibrary(&openSSLBuilder))
	}

	if *zlibStatic {
		dependencies = append(dependencies, makeStaticLibrary(&zlibBuilder))
	}

	log.Printf("Generate configure script for %s.....", nginxBuilder.sourcePath())

	if *pcreStatic && strings.Contains(nginxConf, pcreBuilder.option()) {
		log.Printf("[warn]Using '%s' is discouraged. Instead give '-pcre' and '-pcreversion' to 'nginx-build'", pcreBuilder.option())
	}

	if *openSSLStatic && strings.Contains(nginxConf, openSSLBuilder.option()) {
		log.Printf("[warn]Using '%s' is discouraged. Instead give '-openssl' and '-opensslversion' to 'nginx-build'", openSSLBuilder.option())

	}

	if *zlibStatic && strings.Contains(nginxConf, zlibBuilder.option()) {
		log.Printf("[warn]Using '%s' is discouraged. Instead give '-zlib' and '-zlibversion' to 'nginx-build'", zlibBuilder.option())
	}

	if strings.Contains(nginxConf, "--add-module=") {
		log.Println("[warn]Using '--add-module' is discouraged. Instead give ini-file with '-m' to 'nginx-build'")
	}

	configureScript := configureGen(nginxConf, modules3rd, dependencies)
	err = ioutil.WriteFile("./nginx-configure", []byte(configureScript), 0655)
	if err != nil {
		log.Fatalf("Failed to generate configure script for %s", nginxBuilder.sourcePath())
	}
	log.Printf("Configure %s.....", nginxBuilder.sourcePath())
	err = configureNginx()
	if err != nil {
		log.Fatalf("Failed to configure %s", nginxBuilder.sourcePath())
	}

	log.Printf("Build %s.....", nginxBuilder.sourcePath())
	if *openSSLStatic {
		// This is a workaround for protecting a failure of building nginx with OpenSSL.
		// Unfortunately build of nginx with static OpenSSL fails by multi-CPUs.
		jobs = 1
	}
	err = buildNginx(jobs)
	if err != nil {
		fmt.Println(err.Error())
		log.Fatalf("Failed to build %s", nginxBuilder.sourcePath())
	}

	printLastMsg(workDir, nginxBuilder.sourcePath())

	// cd rootDir
	os.Chdir(rootDir)
}
<commit_msg>fix bug(detecting options for embedding (zlib|pcre|openssl) is mistaken.)<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"strings"
	"syscall"
)

func main() {
	var dependencies []StaticLibrary
	parallels := 0
	done := make(chan bool)

	// set parallel numbers
	runtime.GOMAXPROCS(runtime.NumCPU())
	jobs := runtime.NumCPU()

	// Parse flags
	version := flag.String("v", NGINX_VERSION, "nginx version")
	nginxConfPath := flag.String("c", "", "configuration file for building nginx")
	modulesConfPath := flag.String("m", "", "configuration file for 3rd party modules")
	workParentDir := flag.String("d", "", "working directory")
	verbose := flag.Bool("verbose", false, "verbose mode")
	pcreStatic := flag.Bool("pcre", false, "embedded PCRE statically")
	pcreVersion := flag.String("pcreversion", PCRE_VERSION, "PCRE version")
	openSSLStatic := flag.Bool("openssl", false, "embedded PCRE statically")
	openSSLVersion := flag.String("opensslversion", OPENSSL_VERSION, "OpenSSL version")
	zlibStatic := flag.Bool("zlib", false, "embedded zlib statically")
	zlibVersion := flag.String("zlibversion", ZLIB_VERSION, "zlib version")
	clear := flag.Bool("clear", false, "remove entries in working directory")
	versionb := flag.Bool("version", false, "print nginx-build versions")
	versions := flag.Bool("versions", false, "print nginx versions")
	flag.Parse()

	if *versionb {
		printNginxBuildVersion()
		os.Exit(0)
	}

	if *versions {
		printNginxVersions()
		os.Exit(0)
	}

	// set verbose mode
	VerboseEnabled = *verbose

	nginxBuilder := makeBuilder(COMPONENT_NGINX, *version)
	pcreBuilder := makeBuilder(COMPONENT_PCRE, *pcreVersion)
	openSSLBuilder := makeBuilder(COMPONENT_OPENSSL, *openSSLVersion)
	zlibBuilder := makeBuilder(COMPONENT_ZLIB, *zlibVersion)

	// change default umask
	_ = syscall.Umask(0)

	versionCheck(*version)

	nginxConf, err := fileGetContents(*nginxConfPath)
	if err != nil {
		log.Fatal(err.Error())
	}

	modules3rd, err := loadModules3rdFile(*modulesConfPath)
	if err != nil {
		log.Fatal(err.Error())
	}

	if len(*workParentDir) == 0 {
		log.Fatal("set working directory with -d")
	}

	if !fileExists(*workParentDir) {
		log.Fatalf("working directory(%s) does not exist.", *workParentDir)
	}

	workDir := *workParentDir + "/" + *version
	if *clear {
		err := os.RemoveAll(workDir)
		if err != nil {
			log.Fatal(err.Error())
		}
	}

	if !fileExists(workDir) {
		err := os.Mkdir(workDir, 0755)
		if err != nil {
			log.Fatalf("Failed to create working directory(%s) does not exist.", workDir)
		}
	}

	rootDir := saveCurrentDir()
	// cd workDir
	err = os.Chdir(workDir)
	if err != nil {
		log.Fatal(err.Error())
	}

	if *pcreStatic {
		parallels++
		go downloadAndExtractParallel(&pcreBuilder, done)
	}

	if *openSSLStatic {
		parallels++
		go downloadAndExtractParallel(&openSSLBuilder, done)
	}

	if *zlibStatic {
		parallels++
		go downloadAndExtractParallel(&zlibBuilder, done)
	}

	parallels++
	go downloadAndExtractParallel(&nginxBuilder, done)

	if len(modules3rd) > 0 {
		parallels += len(modules3rd)
		for _, m := range modules3rd {
			go downloadAndExtractModule3rdParallel(m, done)
		}

	}

	// wait until all downloading processes by goroutine finish
	for i := 0; i < parallels; i++ {
		<-done
	}

	if len(modules3rd) > 0 {
		for _, m := range modules3rd {
			provideModule3rd(m)
		}
	}

	// cd workDir/nginx-${version}
	os.Chdir(nginxBuilder.sourcePath())

	if *pcreStatic {
		dependencies = append(dependencies, makeStaticLibrary(&pcreBuilder))
	}

	if *openSSLStatic {
		dependencies = append(dependencies, makeStaticLibrary(&openSSLBuilder))
	}

	if *zlibStatic {
		dependencies = append(dependencies, makeStaticLibrary(&zlibBuilder))
	}

	log.Printf("Generate configure script for %s.....", nginxBuilder.sourcePath())

	if *pcreStatic && strings.Contains(nginxConf, pcreBuilder.option()+"=") {
		log.Printf("[warn]Using '%s' is discouraged. Instead give '-pcre' and '-pcreversion' to 'nginx-build'", pcreBuilder.option())
	}

	if *openSSLStatic && strings.Contains(nginxConf, openSSLBuilder.option()+"=") {
		log.Printf("[warn]Using '%s' is discouraged. Instead give '-openssl' and '-opensslversion' to 'nginx-build'", openSSLBuilder.option())

	}

	if *zlibStatic && strings.Contains(nginxConf, zlibBuilder.option()+"=") {
		log.Printf("[warn]Using '%s' is discouraged. Instead give '-zlib' and '-zlibversion' to 'nginx-build'", zlibBuilder.option())
	}

	if strings.Contains(nginxConf, "--add-module=") {
		log.Println("[warn]Using '--add-module' is discouraged. Instead give ini-file with '-m' to 'nginx-build'")
	}

	configureScript := configureGen(nginxConf, modules3rd, dependencies)
	err = ioutil.WriteFile("./nginx-configure", []byte(configureScript), 0655)
	if err != nil {
		log.Fatalf("Failed to generate configure script for %s", nginxBuilder.sourcePath())
	}
	log.Printf("Configure %s.....", nginxBuilder.sourcePath())
	err = configureNginx()
	if err != nil {
		log.Fatalf("Failed to configure %s", nginxBuilder.sourcePath())
	}

	log.Printf("Build %s.....", nginxBuilder.sourcePath())
	if *openSSLStatic {
		// This is a workaround for protecting a failure of building nginx with OpenSSL.
		// Unfortunately build of nginx with static OpenSSL fails by multi-CPUs.
		jobs = 1
	}
	err = buildNginx(jobs)
	if err != nil {
		fmt.Println(err.Error())
		log.Fatalf("Failed to build %s", nginxBuilder.sourcePath())
	}

	printLastMsg(workDir, nginxBuilder.sourcePath())

	// cd rootDir
	os.Chdir(rootDir)
}
<|endoftext|>


<commit_before>// Copyright 2015 Home24 AG. All rights reserved.
// Proprietary license.
package scenario

import (
	"github.com/ant0ine/go-json-rest/rest"
	"github.com/urakozz/go-json-rest-middleware-jwt"
	"net/http"
	"time"
	"encoding/json"
	"github.com/urakozz/transpoint.io/src/domain"
	"log"
)

func NewWebApi() http.Handler {
	Authenticator := func(userId, password string) bool {

		res, err := userRepository.GetUserById(userId)
		if err != nil || res == "" {
			return false
		}
		user := domain.NewUser()
		err = json.Unmarshal([]byte(res), user)

		return nil == err && user.Pass == domain.HashPassword(password)
	}

	var jwt_middleware = &jwt.JWTMiddleware{
		Key:        []byte("testKey"),
		Realm:      "Unitrans",
		Timeout:    time.Second * 30,
		MaxRefresh: time.Hour * 24,
		Authenticator: Authenticator,
	}

	var DevStack = []rest.Middleware{
		&rest.AccessLogApacheMiddleware{},
		&rest.TimerMiddleware{},
		&rest.RecorderMiddleware{},
		&rest.PoweredByMiddleware{},
		&rest.RecoverMiddleware{
			EnableResponseStackTrace: true,
		},
		&rest.JsonIndentMiddleware{},
	}
	api := rest.NewApi()

	api.Use(DevStack...)
	api.Use(&rest.CorsMiddleware{
		RejectNonCorsRequests: false,
		OriginValidator: func(origin string, request *rest.Request) bool {
			return true
		},
		AllowedMethods: []string{"*"},
		AllowedHeaders: []string{"*"},
		AccessControlAllowCredentials: true,
		AccessControlMaxAge:           3600,
	})
	api.Use(&rest.IfMiddleware{
		Condition: func(request *rest.Request) bool {
			return request.URL.Path != "/login" && request.URL.Path != "/refresh"
		},
		IfTrue: jwt_middleware,
	})
	api_router, _ := rest.MakeRouter(
		rest.Post("/login", jwt_middleware.LoginHandler),
		rest.Get("/test", handle_auth),
		rest.Get("/refresh", jwt_middleware.RefreshHandler),
		rest.Get("/register", Register),
	)
	api.SetApp(api_router)
	return api.MakeHandler()
}

func handle_auth(w rest.ResponseWriter, r *rest.Request) {
	w.WriteJson(map[string]string{"authed": r.Env["REMOTE_USER"].(string)})
}

func Register(w rest.ResponseWriter, r *rest.Request) {
	var form struct {
		Id string      `json:"username"`
		Pass  string   `json:"password"`
	}
	r.DecodeJsonPayload(&form)

	res, err := userRepository.GetUserById(form.Id)
	if err != nil || res == "" || form.Pass == "" {
		rest.Error(w, "Invalid input", 400)
	}

	user := &domain.User{Id:form.Id, Pass:domain.HashPassword(form.Pass)}
	bytes, _ := json.Marshal(user)
	userRepository.SaveUserById(form.Id, string(bytes))
	res, err = userRepository.GetUserById(form.Id)
	log.Println(res, err)
	w.WriteJson(map[string]string{"Status":"OK"})
}

<commit_msg>allowed methods<commit_after>// Copyright 2015 Home24 AG. All rights reserved.
// Proprietary license.
package scenario

import (
	"github.com/ant0ine/go-json-rest/rest"
	"github.com/urakozz/go-json-rest-middleware-jwt"
	"net/http"
	"time"
	"encoding/json"
	"github.com/urakozz/transpoint.io/src/domain"
	"log"
)

func NewWebApi() http.Handler {
	Authenticator := func(userId, password string) bool {

		res, err := userRepository.GetUserById(userId)
		if err != nil || res == "" {
			return false
		}
		user := domain.NewUser()
		err = json.Unmarshal([]byte(res), user)

		return nil == err && user.Pass == domain.HashPassword(password)
	}

	var jwt_middleware = &jwt.JWTMiddleware{
		Key:        []byte("testKey"),
		Realm:      "Unitrans",
		Timeout:    time.Second * 30,
		MaxRefresh: time.Hour * 24,
		Authenticator: Authenticator,
	}

	var DevStack = []rest.Middleware{
		&rest.AccessLogApacheMiddleware{},
		&rest.TimerMiddleware{},
		&rest.RecorderMiddleware{},
		&rest.PoweredByMiddleware{},
		&rest.RecoverMiddleware{
			EnableResponseStackTrace: true,
		},
		&rest.JsonIndentMiddleware{},
	}
	api := rest.NewApi()

	api.Use(DevStack...)
	api.Use(&rest.CorsMiddleware{
		RejectNonCorsRequests: false,
		OriginValidator: func(origin string, request *rest.Request) bool {
			return true
		},
		AllowedMethods: []string{"GET", "POST", "PUT"},
		AllowedHeaders: []string{"Authorization", "Accept", "Content-Type", "X-Custom-Header", "Origin"},
		AccessControlAllowCredentials: true,
		AccessControlMaxAge:           3600,
	})
	api.Use(&rest.IfMiddleware{
		Condition: func(request *rest.Request) bool {
			return request.URL.Path != "/login" && request.URL.Path != "/refresh"
		},
		IfTrue: jwt_middleware,
	})
	api_router, _ := rest.MakeRouter(
		rest.Post("/login", jwt_middleware.LoginHandler),
		rest.Get("/test", handle_auth),
		rest.Get("/refresh", jwt_middleware.RefreshHandler),
		rest.Get("/register", Register),
	)
	api.SetApp(api_router)
	return api.MakeHandler()
}

func handle_auth(w rest.ResponseWriter, r *rest.Request) {
	w.WriteJson(map[string]string{"authed": r.Env["REMOTE_USER"].(string)})
}

func Register(w rest.ResponseWriter, r *rest.Request) {
	var form struct {
		Id string      `json:"username"`
		Pass  string   `json:"password"`
	}
	r.DecodeJsonPayload(&form)

	res, err := userRepository.GetUserById(form.Id)
	if err != nil || res == "" || form.Pass == "" {
		rest.Error(w, "Invalid input", 400)
	}

	user := &domain.User{Id:form.Id, Pass:domain.HashPassword(form.Pass)}
	bytes, _ := json.Marshal(user)
	userRepository.SaveUserById(form.Id, string(bytes))
	res, err = userRepository.GetUserById(form.Id)
	log.Println(res, err)
	w.WriteJson(map[string]string{"Status":"OK"})
}

<|endoftext|>


<commit_before>package pipedrive

import (
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"regexp"
)

func LogURLs(a *API) error {
	r := regexp.MustCompile(fmt.Sprintf("api_token=%s", a.token))
	a.logURL = func(u string) {
		prettyURL := r.ReplaceAllString(u, "api_token=…")
		fmt.Println(prettyURL)
	}

	return nil
}

func CustomURLLogger(logger func(u string), elipsifyToken bool) Option {
	return func(a *API) error {
		r := regexp.MustCompile(fmt.Sprintf("api_token=%s", a.token))
		a.logURL = func(u string) {
			prettyURL := u
			if elipsifyToken {
				prettyURL = r.ReplaceAllString(u, "api_token=…")
			}
			logger(prettyURL)
		}

		return nil
	}
}

func FixedToken(token string) Option {
	return func(a *API) error {
		if token == "" {
			return errors.New("Token must not be empty")
		}
		a.token = token
		return nil
	}
}

func HTTPFetcher(a *API) error {
	a.eps = endpoints{
		pipelineDeals: "https://api.pipedrive.com/v1/pipelines/%d/deals?everyone=0&start=%d&filter_id=%d",
		deals:         "https://api.pipedrive.com/v1/deals/%d/updates?start=%d",
		deal:          "https://api.pipedrive.com/v1/deals/%d",
		dealFilter:    "https://api.pipedrive.com/v1/deals?start=%d&filter_id=%d",
		pipelines:     "https://api.pipedrive.com/v1/pipelines",
		stages:        "https://api.pipedrive.com/v1/stages?pipeline_id=%d",
		filters:       "https://api.pipedrive.com/v1/filters",
	}

	a.getEndpoint = func(endpoint string) (*http.Response, error) {
		u, err := url.Parse(endpoint)
		if err != nil {
			return nil, err
		}
		values := u.Query()
		values.Add("api_token", a.token)
		u.RawQuery = values.Encode()
		a.logURL(u.String())
		res, err := http.Get(u.String())
		return res, err
	}
	return nil
}
<commit_msg>add option to fetch token from environment<commit_after>package pipedrive

import (
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"regexp"
)

var ErrEmptyToken = errors.New("Token must not be empty")

func LogURLs(a *API) error {
	r := regexp.MustCompile(fmt.Sprintf("api_token=%s", a.token))
	a.logURL = func(u string) {
		prettyURL := r.ReplaceAllString(u, "api_token=…")
		fmt.Println(prettyURL)
	}

	return nil
}

func CustomURLLogger(logger func(u string), elipsifyToken bool) Option {
	return func(a *API) error {
		r := regexp.MustCompile(fmt.Sprintf("api_token=%s", a.token))
		a.logURL = func(u string) {
			prettyURL := u
			if elipsifyToken {
				prettyURL = r.ReplaceAllString(u, "api_token=…")
			}
			logger(prettyURL)
		}

		return nil
	}
}

func FixedToken(token string) Option {
	return func(a *API) error {
		if token == "" {
			return ErrEmptyToken
		}
		a.token = token
		return nil
	}
}

func EnvToken(envName string) Option {
	return func(a *API) error {
		if envName == "" {
			envName = "PDTOKEN"
		}

		token := os.Getenv(envName)
		if token == "" {
			return ErrEmptyToken
		}
		a.token = token

		return nil
	}
}

func HTTPFetcher(a *API) error {
	a.eps = endpoints{
		pipelineDeals: "https://api.pipedrive.com/v1/pipelines/%d/deals?everyone=0&start=%d&filter_id=%d",
		deals:         "https://api.pipedrive.com/v1/deals/%d/updates?start=%d",
		deal:          "https://api.pipedrive.com/v1/deals/%d",
		dealFilter:    "https://api.pipedrive.com/v1/deals?start=%d&filter_id=%d",
		pipelines:     "https://api.pipedrive.com/v1/pipelines",
		stages:        "https://api.pipedrive.com/v1/stages?pipeline_id=%d",
		filters:       "https://api.pipedrive.com/v1/filters",
	}

	a.getEndpoint = func(endpoint string) (*http.Response, error) {
		u, err := url.Parse(endpoint)
		if err != nil {
			return nil, err
		}
		values := u.Query()
		values.Add("api_token", a.token)
		u.RawQuery = values.Encode()
		a.logURL(u.String())
		res, err := http.Get(u.String())
		return res, err
	}
	return nil
}
<|endoftext|>


<commit_before>package kite

import (
	"encoding/json"
	"io/ioutil"
	"kite/protocol"
	"log"
	"strings"
)

// Options is passed to kite.New when creating new instance.
type Options struct {
	// Mandatory fields
	Kitename    string
	Version     string
	Environment string
	Region      string

	// Optional fields
	PublicIP   string              // default: 0.0.0.0
	Port       string              // default: random
	Path       string              // default: /<kitename>
	Visibility protocol.Visibility // default: protocol.Private

	// Do not authenticate incoming requests
	DisableAuthentication bool
}

// validate fields of the options struct. It exits if an error is occured.
func (o *Options) validate() {
	if o.Kitename == "" {
		log.Fatal("ERROR: options.Kitename field is not set")
	}

	if digits := strings.Split(o.Version, "."); len(digits) != 3 {
		log.Fatal("ERROR: please use 3-digits semantic versioning for options.version")
	}

	if o.Region == "" {
		log.Fatal("ERROR: options.Region field is not set")
	}

	if o.Environment == "" {
		log.Fatal("ERROR: options.Environment field is not set")
	}

	if o.PublicIP == "" {
		o.PublicIP = "127.0.0.1"
	}

	if o.Port == "" {
		o.Port = "0" // OS binds to an automatic port
	}

	if o.Path == "" {
		o.Path = "/" + o.Kitename
	}

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

	if o.Visibility == protocol.Visibility("") {
		o.Visibility = protocol.Private
	}
}

// Read options from a file.
func ReadKiteOptions(configfile string) (*Options, error) {
	file, err := ioutil.ReadFile(configfile)
	if err != nil {
		return nil, err
	}

	options := &Options{}
	return options, json.Unmarshal(file, &options)
}
<commit_msg>listen all interfaces by default<commit_after>package kite

import (
	"encoding/json"
	"io/ioutil"
	"kite/protocol"
	"log"
	"strings"
)

// Options is passed to kite.New when creating new instance.
type Options struct {
	// Mandatory fields
	Kitename    string
	Version     string
	Environment string
	Region      string

	// Optional fields
	PublicIP   string              // default: 0.0.0.0
	Port       string              // default: random
	Path       string              // default: /<kitename>
	Visibility protocol.Visibility // default: protocol.Private

	// Do not authenticate incoming requests
	DisableAuthentication bool
}

// validate fields of the options struct. It exits if an error is occured.
func (o *Options) validate() {
	if o.Kitename == "" {
		log.Fatal("ERROR: options.Kitename field is not set")
	}

	if digits := strings.Split(o.Version, "."); len(digits) != 3 {
		log.Fatal("ERROR: please use 3-digits semantic versioning for options.version")
	}

	if o.Region == "" {
		log.Fatal("ERROR: options.Region field is not set")
	}

	if o.Environment == "" {
		log.Fatal("ERROR: options.Environment field is not set")
	}

	if o.PublicIP == "" {
		o.PublicIP = "0.0.0.0"
	}

	if o.Port == "" {
		o.Port = "0" // OS binds to an automatic port
	}

	if o.Path == "" {
		o.Path = "/" + o.Kitename
	}

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

	if o.Visibility == protocol.Visibility("") {
		o.Visibility = protocol.Private
	}
}

// Read options from a file.
func ReadKiteOptions(configfile string) (*Options, error) {
	file, err := ioutil.ReadFile(configfile)
	if err != nil {
		return nil, err
	}

	options := &Options{}
	return options, json.Unmarshal(file, &options)
}
<|endoftext|>


<commit_before>package SpedRead

import (
	"bufio"
	"github.com/chapzin/parse-efd-fiscal/Models/NotaFiscal"
	"github.com/chapzin/parse-efd-fiscal/SpedExec"
	"github.com/chapzin/parse-efd-fiscal/tools"
	"github.com/clbanning/mxj"
	"github.com/jinzhu/gorm"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

var id int
var maxid = 98

// Ler todos os arquivos de uma determinada pasta
func RecursiveSpeds(path string, dialect string, conexao string, digitosCodigo string) {
	filepath.Walk(path, func(file string, f os.FileInfo, err error) error {
		if f.IsDir() == false {
			ext := filepath.Ext(file)
			if ext == ".txt" {
				tools.CheckErr(err)
				r := SpedExec.Regs{}
				r.Digito = digitosCodigo
				id++
				go InsertSped(file, &r, dialect, conexao)

			}

			if ext == ".xml" {
				id++
				go InsertXml(file, dialect, conexao, digitosCodigo)

			}
			wait()
		}
		return nil
	})
}

func wait() {
	for {
		if id >= maxid {
			time.Sleep(1 * time.Second)
		} else {
			return
		}
	}

}

func InsertXml(xml string, dialect string, conexao string, digitosCodigo string) {
	digitosCodigo2 := tools.ConvInt(digitosCodigo)
	db, err := gorm.Open(dialect, conexao)
	// Teste de lista produtos
	xmlFile, err := ioutil.ReadFile(xml)
	reader := tools.ConvXml(xml)
	tools.CheckErr(err)
	nfe, errOpenXml := mxj.NewMapXml(xmlFile)
	tools.CheckErr(errOpenXml)
	// Preenchendo o header da nfe
	nNf := reader("ide", "nNF")
	chnfe := reader("infProt", "chNFe")
	natOp := reader("ide", "natOp")
	indPag := reader("ide", "indPag")
	mod := reader("ide", "mod")
	serie := reader("ide", "serie")
	dEmit := reader("ide", "dEmi")
	if dEmit == "" {
		dhEmit := reader("ide", "dhEmi")
		dEmit = dhEmit
	}
	tpNf := reader("ide", "tpNF")
	tpImp := reader("ide", "tpImp")
	tpEmis := reader("ide", "tpEmis")
	cdv := reader("ide", "cDV")
	tpAmb := reader("ide", "tpAmb")
	finNFe := reader("ide", "finNFe")
	procEmi := reader("ide", "procEmi")

	// Preenchendo itens
	codigo, err := nfe.ValuesForKey("cProd")
	ean, err := nfe.ValuesForKey("cEAN")
	descricao, err := nfe.ValuesForKey("xProd")
	ncm, err := nfe.ValuesForKey("NCM")
	cfop, err := nfe.ValuesForKey("CFOP")
	unid, err := nfe.ValuesForKey("uCom")
	qtd, err := nfe.ValuesForKey("qCom")
	vUnit, err := nfe.ValuesForKey("vUnCom")
	vTotal, err := nfe.ValuesForKey("vProd")
	// Preenchendo Destinatario
	cnpj := reader("dest", "CNPJ")
	xNome := reader("dest", "xNome")
	xLgr := reader("enderDest", "xLgr")
	nro := reader("enderDest", "nro")
	xCpl := reader("enderDest", "xCpl")
	xBairro := reader("enderDest", "xBairro")
	cMun := reader("enderDest", "cMun")
	xMun := reader("enderDest", "xMun")
	uf := reader("enderDest", "UF")
	cep := reader("enderDest", "CEP")
	cPais := reader("enderDest", "cPais")
	xPais := reader("enderDest", "xPais")
	fone := reader("enderDest", "fone")
	ie := reader("dest", "IE")
	// Preenchendo Emitente
	cnpje := reader("emit", "CNPJ")
	xNomee := reader("emit", "xNome")
	xLgre := reader("enderEmit", "xLgr")
	nroe := reader("enderEmit", "nro")
	xCple := reader("enderEmit", "xCpl")
	xBairroe := reader("enderEmit", "xBairro")
	cMune := reader("enderEmit", "cMun")
	xMune := reader("enderEmit", "xMun")
	ufe := reader("enderEmit", "UF")
	cepe := reader("enderEmit", "CEP")
	cPaise := reader("enderEmit", "cPais")
	xPaise := reader("enderEmit", "xPais")
	fonee := reader("enderEmit", "fone")
	iee := reader("emit", "IE")

	destinatario := NotaFiscal.Destinatario{
		CNPJ:    cnpj,
		XNome:   xNome,
		XLgr:    xLgr,
		Nro:     nro,
		XCpl:    xCpl,
		XBairro: xBairro,
		CMun:    cMun,
		XMun:    xMun,
		Uf:      uf,
		Cep:     cep,
		CPais:   cPais,
		XPais:   xPais,
		Fone:    fone,
		Ie:      ie,
	}

	emitentede := NotaFiscal.Emitente{
		CNPJ:    cnpje,
		XNome:   xNomee,
		XLgr:    xLgre,
		Nro:     nroe,
		XCpl:    xCple,
		XBairro: xBairroe,
		CMun:    cMune,
		XMun:    xMune,
		Uf:      ufe,
		Cep:     cepe,
		CPais:   cPaise,
		XPais:   xPaise,
		Fone:    fonee,
		Ie:      iee,
	}

	var itens []NotaFiscal.Item

	for i, _ := range codigo {
		i2 := i + 1
		codigoi := tools.AdicionaDigitosCodigo(codigo[i].(string), digitosCodigo2)
		eani := ean[i].(string)
		descricaoi := descricao[i].(string)
		ncmi := ncm[i].(string)
		cfopi := cfop[i].(string)
		unidi := unid[i].(string)
		qtdi := qtd[i].(string)
		vuniti := vUnit[i].(string)
		vtotali := vTotal[i2].(string)

		Item := NotaFiscal.Item{
			Codigo:    codigoi,
			Ean:       eani,
			Descricao: descricaoi,
			Ncm:       ncmi,
			Cfop:      cfopi,
			Unid:      unidi,
			Qtd:       tools.ConvFloat(qtdi),
			VUnit:     tools.ConvFloat(vuniti),
			VTotal:    tools.ConvFloat(vtotali),
			DtEmit:    tools.ConvertDataXml(dEmit),
		}
		itens = append(itens, Item)
		//fmt.Printf("%#v\n",Item)
	}

	notafiscal := NotaFiscal.NotaFiscal{
		NNF:          nNf,
		ChNFe:        chnfe,
		NatOp:        natOp,
		IndPag:       indPag,
		Mod:          mod,
		Serie:        serie,
		DEmi:         tools.ConvertDataXml(dEmit),
		TpNF:         tpNf,
		TpImp:        tpImp,
		TpEmis:       tpEmis,
		CDV:          cdv,
		TpAmb:        tpAmb,
		FinNFe:       finNFe,
		ProcEmi:      procEmi,
		Emitente:     emitentede,
		Destinatario: destinatario,
		Itens:        itens,
	}
	db.NewRecord(notafiscal)
	db.Create(&notafiscal)
	db.Close()
	id--
}

func InsertSped(sped string, r *SpedExec.Regs, dialect string, conexao string) {
	db, err := gorm.Open(dialect, conexao)
	file, err := os.Open(sped)
	tools.CheckErr(err)
	defer file.Close()
	scanner := bufio.NewScanner(file)
	// guarda cada linha em indice diferente do slice
	for scanner.Scan() {
		ProcessRows(scanner.Text(), r, *db)
	}
	id--
}

func ProcessRows(line string, r *SpedExec.Regs, db gorm.DB) {
	if line == "" {
		return
	}
	if line[:1] == "|" {
		line = strings.Replace(line, ",", ".", -1)
		ln := strings.Split(line, "|")
		SpedExec.TrataLinha(ln[1], line, r, db)
	}
}
<commit_msg>fix extension read<commit_after>package SpedRead

import (
	"bufio"
	"github.com/chapzin/parse-efd-fiscal/Models/NotaFiscal"
	"github.com/chapzin/parse-efd-fiscal/SpedExec"
	"github.com/chapzin/parse-efd-fiscal/tools"
	"github.com/clbanning/mxj"
	"github.com/jinzhu/gorm"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

var id int
var maxid = 98

// Ler todos os arquivos de uma determinada pasta
func RecursiveSpeds(path string, dialect string, conexao string, digitosCodigo string) {
	filepath.Walk(path, func(file string, f os.FileInfo, err error) error {
		if f.IsDir() == false {
			ext := filepath.Ext(file)
			if ext == ".txt" || ext == ".TXT" {
				tools.CheckErr(err)
				r := SpedExec.Regs{}
				r.Digito = digitosCodigo
				id++
				go InsertSped(file, &r, dialect, conexao)

			}

			if ext == ".xml" || ext == ".XML" {
				id++
				go InsertXml(file, dialect, conexao, digitosCodigo)

			}
			wait()
		}
		return nil
	})
}

func wait() {
	for {
		if id >= maxid {
			time.Sleep(1 * time.Second)
		} else {
			return
		}
	}

}

func InsertXml(xml string, dialect string, conexao string, digitosCodigo string) {
	digitosCodigo2 := tools.ConvInt(digitosCodigo)
	db, err := gorm.Open(dialect, conexao)
	// Teste de lista produtos
	xmlFile, err := ioutil.ReadFile(xml)
	reader := tools.ConvXml(xml)
	tools.CheckErr(err)
	nfe, errOpenXml := mxj.NewMapXml(xmlFile)
	tools.CheckErr(errOpenXml)
	// Preenchendo o header da nfe
	nNf := reader("ide", "nNF")
	chnfe := reader("infProt", "chNFe")
	natOp := reader("ide", "natOp")
	indPag := reader("ide", "indPag")
	mod := reader("ide", "mod")
	serie := reader("ide", "serie")
	dEmit := reader("ide", "dEmi")
	if dEmit == "" {
		dhEmit := reader("ide", "dhEmi")
		dEmit = dhEmit
	}
	tpNf := reader("ide", "tpNF")
	tpImp := reader("ide", "tpImp")
	tpEmis := reader("ide", "tpEmis")
	cdv := reader("ide", "cDV")
	tpAmb := reader("ide", "tpAmb")
	finNFe := reader("ide", "finNFe")
	procEmi := reader("ide", "procEmi")

	// Preenchendo itens
	codigo, err := nfe.ValuesForKey("cProd")
	ean, err := nfe.ValuesForKey("cEAN")
	descricao, err := nfe.ValuesForKey("xProd")
	ncm, err := nfe.ValuesForKey("NCM")
	cfop, err := nfe.ValuesForKey("CFOP")
	unid, err := nfe.ValuesForKey("uCom")
	qtd, err := nfe.ValuesForKey("qCom")
	vUnit, err := nfe.ValuesForKey("vUnCom")
	vTotal, err := nfe.ValuesForKey("vProd")
	// Preenchendo Destinatario
	cnpj := reader("dest", "CNPJ")
	xNome := reader("dest", "xNome")
	xLgr := reader("enderDest", "xLgr")
	nro := reader("enderDest", "nro")
	xCpl := reader("enderDest", "xCpl")
	xBairro := reader("enderDest", "xBairro")
	cMun := reader("enderDest", "cMun")
	xMun := reader("enderDest", "xMun")
	uf := reader("enderDest", "UF")
	cep := reader("enderDest", "CEP")
	cPais := reader("enderDest", "cPais")
	xPais := reader("enderDest", "xPais")
	fone := reader("enderDest", "fone")
	ie := reader("dest", "IE")
	// Preenchendo Emitente
	cnpje := reader("emit", "CNPJ")
	xNomee := reader("emit", "xNome")
	xLgre := reader("enderEmit", "xLgr")
	nroe := reader("enderEmit", "nro")
	xCple := reader("enderEmit", "xCpl")
	xBairroe := reader("enderEmit", "xBairro")
	cMune := reader("enderEmit", "cMun")
	xMune := reader("enderEmit", "xMun")
	ufe := reader("enderEmit", "UF")
	cepe := reader("enderEmit", "CEP")
	cPaise := reader("enderEmit", "cPais")
	xPaise := reader("enderEmit", "xPais")
	fonee := reader("enderEmit", "fone")
	iee := reader("emit", "IE")

	destinatario := NotaFiscal.Destinatario{
		CNPJ:    cnpj,
		XNome:   xNome,
		XLgr:    xLgr,
		Nro:     nro,
		XCpl:    xCpl,
		XBairro: xBairro,
		CMun:    cMun,
		XMun:    xMun,
		Uf:      uf,
		Cep:     cep,
		CPais:   cPais,
		XPais:   xPais,
		Fone:    fone,
		Ie:      ie,
	}

	emitentede := NotaFiscal.Emitente{
		CNPJ:    cnpje,
		XNome:   xNomee,
		XLgr:    xLgre,
		Nro:     nroe,
		XCpl:    xCple,
		XBairro: xBairroe,
		CMun:    cMune,
		XMun:    xMune,
		Uf:      ufe,
		Cep:     cepe,
		CPais:   cPaise,
		XPais:   xPaise,
		Fone:    fonee,
		Ie:      iee,
	}

	var itens []NotaFiscal.Item

	for i, _ := range codigo {
		i2 := i + 1
		codigoi := tools.AdicionaDigitosCodigo(codigo[i].(string), digitosCodigo2)
		eani := ean[i].(string)
		descricaoi := descricao[i].(string)
		ncmi := ncm[i].(string)
		cfopi := cfop[i].(string)
		unidi := unid[i].(string)
		qtdi := qtd[i].(string)
		vuniti := vUnit[i].(string)
		vtotali := vTotal[i2].(string)

		Item := NotaFiscal.Item{
			Codigo:    codigoi,
			Ean:       eani,
			Descricao: descricaoi,
			Ncm:       ncmi,
			Cfop:      cfopi,
			Unid:      unidi,
			Qtd:       tools.ConvFloat(qtdi),
			VUnit:     tools.ConvFloat(vuniti),
			VTotal:    tools.ConvFloat(vtotali),
			DtEmit:    tools.ConvertDataXml(dEmit),
		}
		itens = append(itens, Item)
		//fmt.Printf("%#v\n",Item)
	}

	notafiscal := NotaFiscal.NotaFiscal{
		NNF:          nNf,
		ChNFe:        chnfe,
		NatOp:        natOp,
		IndPag:       indPag,
		Mod:          mod,
		Serie:        serie,
		DEmi:         tools.ConvertDataXml(dEmit),
		TpNF:         tpNf,
		TpImp:        tpImp,
		TpEmis:       tpEmis,
		CDV:          cdv,
		TpAmb:        tpAmb,
		FinNFe:       finNFe,
		ProcEmi:      procEmi,
		Emitente:     emitentede,
		Destinatario: destinatario,
		Itens:        itens,
	}
	db.NewRecord(notafiscal)
	db.Create(&notafiscal)
	db.Close()
	id--
}

func InsertSped(sped string, r *SpedExec.Regs, dialect string, conexao string) {
	db, err := gorm.Open(dialect, conexao)
	file, err := os.Open(sped)
	tools.CheckErr(err)
	defer file.Close()
	scanner := bufio.NewScanner(file)
	// guarda cada linha em indice diferente do slice
	for scanner.Scan() {
		ProcessRows(scanner.Text(), r, *db)
	}
	id--
}

func ProcessRows(line string, r *SpedExec.Regs, db gorm.DB) {
	if line == "" {
		return
	}
	if line[:1] == "|" {
		line = strings.Replace(line, ",", ".", -1)
		ln := strings.Split(line, "|")
		SpedExec.TrataLinha(ln[1], line, r, db)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/mitchellh/go-homedir"
)

var (
	ShortGitHubURI = regexp.MustCompile(`^[\w\-.]+/[\w\-.]+$`)
	GitHubURI      = regexp.MustCompile(`^github.com/[\w\-.]+/[\w\-.]+$`)
	BitbucketURI   = regexp.MustCompile(`^bitbucket.org/[\w\-.]+/[\w\-.]+$`)
)

func ToSourceURI(uri string) string {
	switch {
	case ShortGitHubURI.MatchString(uri):
		return "https://github.com/" + uri
	case GitHubURI.MatchString(uri):
		return "https://" + uri
	case BitbucketURI.MatchString(uri):
		return "https://" + uri
	default:
		return uri
	}
}

var (
	home, errInit = homedir.Dir()
	dotvim        = filepath.Join(home, ".vim")
)

func ToDestinationPath(uri, filetype string) string {
	name := filepath.Base(uri)
	if filetype == "" {
		return filepath.Join(dotvim, "bundle", name)
	}
	return filepath.Join(dotvim, "ftbundle", filetype, name)
}

func ListPackages(filetype string) error {
	var path string
	if filetype == "" {
		path = filepath.Join(dotvim, "bundle")
	} else {
		path = filepath.Join(dotvim, "ftbundle", filetype)
	}

	// Ignore err for filetype doesn't exist.
	files, _ := ioutil.ReadDir(path)
	for _, file := range files {
		fmt.Println(file.Name())
	}
	return nil
}

type Package struct {
	src string
	dst string
}

func NewPackage(uri, filetype string) *Package {
	return &Package{
		src: ToSourceURI(uri),
		dst: ToDestinationPath(uri, filetype),
	}
}

func (p *Package) installed() bool {
	_, err := os.Stat(p.dst)
	return err == nil
}

func (p *Package) Install() error {
	if p.installed() {
		return nil
	}

	if _, err := exec.LookPath("git"); err != nil {
		return err
	}
	c := exec.Command("git", "clone", p.src, p.dst)

	errBuf := bytes.NewBuffer(make([]byte, 0))
	c.Stderr = errBuf
	if err := c.Run(); err != nil {
		return fmt.Errorf("%s", strings.TrimSpace(errBuf.String()))
	}
	return nil
}

func (p *Package) Remove() error {
	if p.installed() {
		return os.RemoveAll(p.dst)
	}
	return nil
}

func (p *Package) Update() error {
	if p.installed() {
		if err := p.Remove(); err != nil {
			return err
		}
	}
	return p.Install()
}
<commit_msg>Refactoring Package.Update<commit_after>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/mitchellh/go-homedir"
)

var (
	ShortGitHubURI = regexp.MustCompile(`^[\w\-.]+/[\w\-.]+$`)
	GitHubURI      = regexp.MustCompile(`^github.com/[\w\-.]+/[\w\-.]+$`)
	BitbucketURI   = regexp.MustCompile(`^bitbucket.org/[\w\-.]+/[\w\-.]+$`)
)

func ToSourceURI(uri string) string {
	switch {
	case ShortGitHubURI.MatchString(uri):
		return "https://github.com/" + uri
	case GitHubURI.MatchString(uri):
		return "https://" + uri
	case BitbucketURI.MatchString(uri):
		return "https://" + uri
	default:
		return uri
	}
}

var (
	home, errInit = homedir.Dir()
	dotvim        = filepath.Join(home, ".vim")
)

func ToDestinationPath(uri, filetype string) string {
	name := filepath.Base(uri)
	if filetype == "" {
		return filepath.Join(dotvim, "bundle", name)
	}
	return filepath.Join(dotvim, "ftbundle", filetype, name)
}

func ListPackages(filetype string) error {
	var path string
	if filetype == "" {
		path = filepath.Join(dotvim, "bundle")
	} else {
		path = filepath.Join(dotvim, "ftbundle", filetype)
	}

	// Ignore err for filetype doesn't exist.
	files, _ := ioutil.ReadDir(path)
	for _, file := range files {
		fmt.Println(file.Name())
	}
	return nil
}

type Package struct {
	src string
	dst string
}

func NewPackage(uri, filetype string) *Package {
	return &Package{
		src: ToSourceURI(uri),
		dst: ToDestinationPath(uri, filetype),
	}
}

func (p *Package) installed() bool {
	_, err := os.Stat(p.dst)
	return err == nil
}

func (p *Package) Install() error {
	if p.installed() {
		return nil
	}

	if _, err := exec.LookPath("git"); err != nil {
		return err
	}
	c := exec.Command("git", "clone", p.src, p.dst)

	errBuf := bytes.NewBuffer(make([]byte, 0))
	c.Stderr = errBuf
	if err := c.Run(); err != nil {
		return fmt.Errorf("%s", strings.TrimSpace(errBuf.String()))
	}
	return nil
}

func (p *Package) Remove() error {
	if p.installed() {
		return os.RemoveAll(p.dst)
	}
	return nil
}

func (p *Package) Update() error {
	if err := p.Remove(); err != nil {
		return err
	}
	return p.Install()
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/mitchellh/go-homedir"
)

var (
	ShortGitHubURI = regexp.MustCompile(`^[\w\-.]+/[\w\-.]+$`)
	GitHubURI      = regexp.MustCompile(`^github.com/[\w\-.]+/[\w\-.]+$`)
	BitbucketURI   = regexp.MustCompile(`^bitbucket.org/[\w\-.]+/[\w\-.]+$`)
)

func ToSourceURI(uri string) string {
	switch {
	case ShortGitHubURI.MatchString(uri):
		return "https://github.com/" + uri
	case GitHubURI.MatchString(uri):
		return "https://" + uri
	case BitbucketURI.MatchString(uri):
		return "https://" + uri
	default:
		return uri
	}
}

var (
	home, errInit = homedir.Dir()
	dotvim        = filepath.Join(home, ".vim")
)

func ToDestinationPath(uri, filetype string) string {
	name := filepath.Base(uri)
	if filetype == "" {
		return filepath.Join(dotvim, "bundle", name)
	}
	return filepath.Join(dotvim, "ftbundle", filetype, name)
}

func ListPackages(filetype string) error {
	var path string
	if filetype == "" {
		path = filepath.Join(dotvim, "bundle")
	} else {
		path = filepath.Join(dotvim, "ftbundle", filetype)
	}

	// Ignore err for filetype doesn't exist.
	files, _ := ioutil.ReadDir(path)
	for _, file := range files {
		fmt.Println(file.Name())
	}
	return nil
}

type Package struct {
	src string
	dst string
}

func NewPackage(uri, filetype string) *Package {
	return &Package{
		src: ToSourceURI(uri),
		dst: ToDestinationPath(uri, filetype),
	}
}

func (p *Package) toInstallCommand() *exec.Cmd {
	return exec.Command("git", "clone", p.src, p.dst)
}

func (p *Package) installed() bool {
	_, err := os.Stat(p.dst)
	return err == nil
}

func (p *Package) Install() error {
	if p.installed() {
		return nil
	}
	if _, err := exec.LookPath("git"); err != nil {
		return err
	}

	errMessage := bytes.NewBuffer(make([]byte, 0))

	installcmd := p.toInstallCommand()
	installcmd.Stderr = errMessage
	if err := installcmd.Run(); err != nil {
		return fmt.Errorf("%s", strings.TrimSpace(errMessage.String()))
	}
	return nil
}

func (p *Package) Remove() error {
	if p.installed() {
		return os.RemoveAll(p.dst)
	}
	return nil
}

func (p *Package) Update() error {
	if p.installed() {
		if err := p.Remove(); err != nil {
			return err
		}
	}
	return p.Install()
}
<commit_msg>Remove Package.toInstallCommand<commit_after>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/mitchellh/go-homedir"
)

var (
	ShortGitHubURI = regexp.MustCompile(`^[\w\-.]+/[\w\-.]+$`)
	GitHubURI      = regexp.MustCompile(`^github.com/[\w\-.]+/[\w\-.]+$`)
	BitbucketURI   = regexp.MustCompile(`^bitbucket.org/[\w\-.]+/[\w\-.]+$`)
)

func ToSourceURI(uri string) string {
	switch {
	case ShortGitHubURI.MatchString(uri):
		return "https://github.com/" + uri
	case GitHubURI.MatchString(uri):
		return "https://" + uri
	case BitbucketURI.MatchString(uri):
		return "https://" + uri
	default:
		return uri
	}
}

var (
	home, errInit = homedir.Dir()
	dotvim        = filepath.Join(home, ".vim")
)

func ToDestinationPath(uri, filetype string) string {
	name := filepath.Base(uri)
	if filetype == "" {
		return filepath.Join(dotvim, "bundle", name)
	}
	return filepath.Join(dotvim, "ftbundle", filetype, name)
}

func ListPackages(filetype string) error {
	var path string
	if filetype == "" {
		path = filepath.Join(dotvim, "bundle")
	} else {
		path = filepath.Join(dotvim, "ftbundle", filetype)
	}

	// Ignore err for filetype doesn't exist.
	files, _ := ioutil.ReadDir(path)
	for _, file := range files {
		fmt.Println(file.Name())
	}
	return nil
}

type Package struct {
	src string
	dst string
}

func NewPackage(uri, filetype string) *Package {
	return &Package{
		src: ToSourceURI(uri),
		dst: ToDestinationPath(uri, filetype),
	}
}

func (p *Package) installed() bool {
	_, err := os.Stat(p.dst)
	return err == nil
}

func (p *Package) Install() error {
	if p.installed() {
		return nil
	}
	if _, err := exec.LookPath("git"); err != nil {
		return err
	}

	errMessage := bytes.NewBuffer(make([]byte, 0))

	installcmd := exec.Command("git", "clone", p.src, p.dst)
	installcmd.Stderr = errMessage
	if err := installcmd.Run(); err != nil {
		return fmt.Errorf("%s", strings.TrimSpace(errMessage.String()))
	}
	return nil
}

func (p *Package) Remove() error {
	if p.installed() {
		return os.RemoveAll(p.dst)
	}
	return nil
}

func (p *Package) Update() error {
	if p.installed() {
		if err := p.Remove(); err != nil {
			return err
		}
	}
	return p.Install()
}
<|endoftext|>


<commit_before>// Copyright 2015 The Cockroach 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. See the AUTHORS file
// for names of contributors.
//
// Author: joezxy (joe.zxy@foxmail.com)

package rpc

import (
	"net"
	"testing"
	"time"

	"github.com/cockroachdb/cockroach/proto"
	"github.com/cockroachdb/cockroach/util"
)

func TestInvalidAddrLength(t *testing.T) {

	// The provided addrs is nil, so its length will be always
	// less than the specified response number
	ret, err := Send(Options{N: 1}, "", nil, nil, nil, nil)

	// the expected return is nil and SendError
	if _, ok := err.(SendError); !ok || ret != nil {
		t.Fatalf("Shorter addrs should return nil and SendError.")
	}
}

// TestSendToOneClient verifies that Send correctly sends a request
// to one server using the heartbeat RPC.
func TestSendToOneClient(t *testing.T) {
	rpcContext := NewTestContext(t)
	s := createAndStartNewServer(rpcContext, t)
	defer s.Close()

	opts := Options{
		N:               1,
		Ordering:        OrderStable,
		SendNextTimeout: 1 * time.Second,
		Timeout:         1 * time.Second,
	}
	replies, err := sendPing(opts, []net.Addr{s.Addr()}, rpcContext)
	if err != nil {
		t.Fatal(err)
	}
	if len(replies) != 1 {
		t.Errorf("Exactly one reply is expected, but got %v", len(replies))
	}
}

// TestSendToMultipleClients verifies that Send correctly sends
// multiple requests to multiple server using the heartbeat RPC.
func TestSendToMultipleClients(t *testing.T) {
	rpcContext := NewTestContext(t)
	numServers := 4
	var addrs []net.Addr
	for i := 0; i < numServers; i++ {
		s := createAndStartNewServer(rpcContext, t)
		defer s.Close()
		addrs = append(addrs, s.Addr())
	}
	for n := 1; n < numServers; n++ {
		// Send n requests.
		opts := Options{
			N:               n,
			Ordering:        OrderStable,
			SendNextTimeout: 1 * time.Second,
			Timeout:         1 * time.Second,
		}
		replies, err := sendPing(opts, addrs, rpcContext)
		if err != nil {
			t.Fatal(err)
		}
		if len(replies) != n {
			t.Errorf("%v replies are expected, but got %v", n, len(replies))
		}
	}
}

// TestRetryableError verifies that Send returns a retryable error
// when it hits an RPC error.
func TestRetryableError(t *testing.T) {
	rpcContext := NewTestContext(t)
	s := createAndStartNewServer(rpcContext, t)

	// Wait until the server becomes ready and shut down the server.
	c := NewClient(s.Addr(), nil, rpcContext)
	<-c.Ready
	// Directly call Close() to close the connection without
	// removing the client from the cache.
	c.Client.Close()
	s.Close()

	opts := Options{
		N:               1,
		Ordering:        OrderStable,
		SendNextTimeout: 1 * time.Second,
		Timeout:         1 * time.Second,
	}
	_, err := sendPing(opts, []net.Addr{s.Addr()}, rpcContext)
	if err == nil {
		t.Fatalf("Unexpected success")
	}
	retryErr, ok := err.(util.Retryable)
	if !ok {
		t.Fatalf("Unexpected error type: %v", err)
	}
	if !retryErr.CanRetry() {
		t.Errorf("Expected retryable error: %v", retryErr)
	}
}

// TestUnretryableError verifies that Send returns an unretryable
// error when it hits a critical error.
func TestUnretryableError(t *testing.T) {
	rpcContext := NewTestContext(t)
	s := createAndStartNewServer(rpcContext, t)

	opts := Options{
		N:               1,
		Ordering:        OrderStable,
		SendNextTimeout: 1 * time.Second,
		Timeout:         5 * time.Second,
	}
	getArgs := func(addr net.Addr) interface{} {
		return &proto.PingRequest{}
	}
	// Make getRetry return a non-proto value so that the proto
	// integrity check fails.
	getReply := func() interface{} {
		return 0
	}
	_, err := Send(opts, "Heartbeat.Ping", []net.Addr{s.Addr()}, getArgs, getReply, rpcContext)
	if err == nil {
		t.Fatalf("Unexpected success")
	}
	retryErr, ok := err.(util.Retryable)
	if !ok {
		t.Fatalf("Unexpected error type: %v", err)
	}
	if retryErr.CanRetry() {
		t.Errorf("Unexpected retryable error: %v", retryErr)
	}
}

// TestClientNotReady verifies that Send gets an RPC error when a client
// does not become ready.
func TestClientNotReady(t *testing.T) {
	rpcContext := NewTestContext(t)

	opts := Options{
		N:               1,
		Ordering:        OrderStable,
		SendNextTimeout: 1 * time.Nanosecond,
		Timeout:         1 * time.Nanosecond,
	}
	// Send RPC to an address where no server is running.
	_, err := sendPing(opts, []net.Addr{util.CreateTestAddr("tcp")}, rpcContext)
	if err == nil {
		t.Fatalf("Unexpected success")
	}
	retryErr, ok := err.(util.Retryable)
	if !ok {
		t.Fatalf("Unexpected error type: %v", err)
	}
	if !retryErr.CanRetry() {
		t.Errorf("Expected retryable error: %v", retryErr)
	}

	// Send the RPC again with no timeout.
	opts.SendNextTimeout = 0 * time.Nanosecond
	opts.Timeout = 0 * time.Nanosecond
	c := make(chan interface{})
	go func() {
		sendPing(opts, []net.Addr{util.CreateTestAddr("tcp")}, rpcContext)
		close(c)
	}()
	select {
	case <-c:
		t.Fatalf("Unexpected end of rpc call")
	case <-time.After(1 * time.Millisecond):
	}
}

// TestComplexScenarios verifies various complex success/failure scenarios by
// mocking sendOne.
func TestComplexScenarios(t *testing.T) {
	rpcContext := NewTestContext(t)

	testCases := []struct {
		numServers               int
		numRequests              int
		numErrors                int
		numRetryableErrors       int
		success                  bool
		isRetryableErrorExpected bool
	}{
		// --- Success scenarios ---
		{1, 1, 0, 0, true, false},
		{5, 1, 0, 0, true, false},
		{5, 5, 0, 0, true, false},
		// There are some errors, but enough RPCs succeed.
		{5, 1, 1, 0, true, false},
		{5, 1, 4, 0, true, false},
		{5, 3, 2, 0, true, false},

		// --- Failure scenarios ---
		// Too many requests.
		{1, 5, 0, 0, false, false},
		// All RPCs fail.
		{5, 1, 5, 0, false, false},
		// Some RPCs fail and we do not have enough remaining clients.
		{5, 3, 3, 0, false, false},
		// All RPCs fail, but some of the errors are retryable.
		{5, 1, 5, 1, false, true},
		{5, 3, 5, 3, false, true},
		// Some RPCs fail, but we do have enough remaining clients and recoverable errors.
		{5, 3, 3, 1, false, true},
		{5, 3, 4, 2, false, true},
	}
	for i, test := range testCases {
		// Copy the values to avoid data race. sendOneFn might
		// be called after this test case finishes.
		numErrors := test.numErrors
		numRetryableErrors := test.numRetryableErrors

		var serverAddrs []net.Addr
		for j := 0; j < test.numServers; j++ {
			s := createAndStartNewServer(rpcContext, t)
			defer s.Close()
			serverAddrs = append(serverAddrs, s.Addr())
		}

		opts := Options{
			N:               test.numRequests,
			Ordering:        OrderStable,
			SendNextTimeout: 1 * time.Second,
			Timeout:         1 * time.Second,
		}
		getArgs := func(addr net.Addr) interface{} {
			return addr
		}
		getReply := func() interface{} {
			return 0
		}

		// Mock sendOne.
		sendOneFn = func(client *Client, timeout time.Duration, method string, args, reply interface{},
			c chan interface{}) {
			addr := args.(net.Addr)
			addrID := -1
			for serverAddrID, serverAddr := range serverAddrs {
				if serverAddr.String() == addr.String() {
					addrID = serverAddrID
					break
				}
			}
			if addrID == -1 {
				t.Fatalf("%d: %v is not found in serverAddrs: %v", i, addr, serverAddrs)
			}
			if addrID < numErrors {
				c <- SendError{
					errMsg:   "test",
					canRetry: addrID < numRetryableErrors,
				}
				return
			}

			c <- nil
		}
		defer func() { sendOneFn = sendOne }()

		replies, err := Send(opts, "Heartbeat.Ping", serverAddrs, getArgs, getReply, rpcContext)
		if test.success {
			if len(replies) != test.numRequests {
				t.Errorf("%d: %v replies are expected, but got %v", i, test.numRequests, len(replies))
			}
			continue
		}

		retryErr, ok := err.(util.Retryable)
		if !ok {
			t.Fatalf("%d: Unexpected error type: %v", i, err)
		}
		if retryErr.CanRetry() != test.isRetryableErrorExpected {
			t.Errorf("%d: Unexpected error: %v", i, retryErr)
		}
	}
}

// createAndStartNewServer creates and starts a new server with a test address.
func createAndStartNewServer(rpcContext *Context, t *testing.T) *Server {
	s := NewServer(util.CreateTestAddr("tcp"), rpcContext)
	if err := s.Start(); err != nil {
		t.Fatal(err)
	}
	return s
}

// sendPing sends Ping requests to specified addresses using Send.
func sendPing(opts Options, addrs []net.Addr, rpcContext *Context) ([]interface{}, error) {
	getArgs := func(addr net.Addr) interface{} {
		return &proto.PingRequest{}
	}
	getReply := func() interface{} {
		return &proto.PingResponse{}
	}
	return Send(opts, "Heartbeat.Ping", addrs, getArgs, getReply, rpcContext)
}
<commit_msg>Fix a race between TestClientNotReady and TestCompplexScenarios.<commit_after>// Copyright 2015 The Cockroach 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. See the AUTHORS file
// for names of contributors.
//
// Author: joezxy (joe.zxy@foxmail.com)

package rpc

import (
	"net"
	"testing"
	"time"

	"github.com/cockroachdb/cockroach/proto"
	"github.com/cockroachdb/cockroach/util"
)

func TestInvalidAddrLength(t *testing.T) {

	// The provided addrs is nil, so its length will be always
	// less than the specified response number
	ret, err := Send(Options{N: 1}, "", nil, nil, nil, nil)

	// the expected return is nil and SendError
	if _, ok := err.(SendError); !ok || ret != nil {
		t.Fatalf("Shorter addrs should return nil and SendError.")
	}
}

// TestSendToOneClient verifies that Send correctly sends a request
// to one server using the heartbeat RPC.
func TestSendToOneClient(t *testing.T) {
	rpcContext := NewTestContext(t)
	s := createAndStartNewServer(rpcContext, t)
	defer s.Close()

	opts := Options{
		N:               1,
		Ordering:        OrderStable,
		SendNextTimeout: 1 * time.Second,
		Timeout:         1 * time.Second,
	}
	replies, err := sendPing(opts, []net.Addr{s.Addr()}, rpcContext)
	if err != nil {
		t.Fatal(err)
	}
	if len(replies) != 1 {
		t.Errorf("Exactly one reply is expected, but got %v", len(replies))
	}
}

// TestSendToMultipleClients verifies that Send correctly sends
// multiple requests to multiple server using the heartbeat RPC.
func TestSendToMultipleClients(t *testing.T) {
	rpcContext := NewTestContext(t)
	numServers := 4
	var addrs []net.Addr
	for i := 0; i < numServers; i++ {
		s := createAndStartNewServer(rpcContext, t)
		defer s.Close()
		addrs = append(addrs, s.Addr())
	}
	for n := 1; n < numServers; n++ {
		// Send n requests.
		opts := Options{
			N:               n,
			Ordering:        OrderStable,
			SendNextTimeout: 1 * time.Second,
			Timeout:         1 * time.Second,
		}
		replies, err := sendPing(opts, addrs, rpcContext)
		if err != nil {
			t.Fatal(err)
		}
		if len(replies) != n {
			t.Errorf("%v replies are expected, but got %v", n, len(replies))
		}
	}
}

// TestRetryableError verifies that Send returns a retryable error
// when it hits an RPC error.
func TestRetryableError(t *testing.T) {
	rpcContext := NewTestContext(t)
	s := createAndStartNewServer(rpcContext, t)

	// Wait until the server becomes ready and shut down the server.
	c := NewClient(s.Addr(), nil, rpcContext)
	<-c.Ready
	// Directly call Close() to close the connection without
	// removing the client from the cache.
	c.Client.Close()
	s.Close()

	opts := Options{
		N:               1,
		Ordering:        OrderStable,
		SendNextTimeout: 1 * time.Second,
		Timeout:         1 * time.Second,
	}
	_, err := sendPing(opts, []net.Addr{s.Addr()}, rpcContext)
	if err == nil {
		t.Fatalf("Unexpected success")
	}
	retryErr, ok := err.(util.Retryable)
	if !ok {
		t.Fatalf("Unexpected error type: %v", err)
	}
	if !retryErr.CanRetry() {
		t.Errorf("Expected retryable error: %v", retryErr)
	}
}

// TestUnretryableError verifies that Send returns an unretryable
// error when it hits a critical error.
func TestUnretryableError(t *testing.T) {
	rpcContext := NewTestContext(t)
	s := createAndStartNewServer(rpcContext, t)

	opts := Options{
		N:               1,
		Ordering:        OrderStable,
		SendNextTimeout: 1 * time.Second,
		Timeout:         5 * time.Second,
	}
	getArgs := func(addr net.Addr) interface{} {
		return &proto.PingRequest{}
	}
	// Make getRetry return a non-proto value so that the proto
	// integrity check fails.
	getReply := func() interface{} {
		return 0
	}
	_, err := Send(opts, "Heartbeat.Ping", []net.Addr{s.Addr()}, getArgs, getReply, rpcContext)
	if err == nil {
		t.Fatalf("Unexpected success")
	}
	retryErr, ok := err.(util.Retryable)
	if !ok {
		t.Fatalf("Unexpected error type: %v", err)
	}
	if retryErr.CanRetry() {
		t.Errorf("Unexpected retryable error: %v", retryErr)
	}
}

// TestClientNotReady verifies that Send gets an RPC error when a client
// does not become ready.
func TestClientNotReady(t *testing.T) {
	rpcContext := NewTestContext(t)
	addr := util.CreateTestAddr("tcp")

	opts := Options{
		N:               1,
		Ordering:        OrderStable,
		SendNextTimeout: 1 * time.Nanosecond,
		Timeout:         1 * time.Nanosecond,
	}
	// Send RPC to an address where no server is running.
	_, err := sendPing(opts, []net.Addr{addr}, rpcContext)
	if err == nil {
		t.Fatalf("Unexpected success")
	}
	retryErr, ok := err.(util.Retryable)
	if !ok {
		t.Fatalf("Unexpected error type: %v", err)
	}
	if !retryErr.CanRetry() {
		t.Errorf("Expected retryable error: %v", retryErr)
	}

	// Send the RPC again with no timeout.
	opts.SendNextTimeout = 0 * time.Nanosecond
	opts.Timeout = 0 * time.Nanosecond
	c := make(chan interface{})
	go func() {
		sendPing(opts, []net.Addr{addr}, rpcContext)
		close(c)
	}()
	select {
	case <-c:
		t.Fatalf("Unexpected end of rpc call")
	case <-time.After(1 * time.Millisecond):
	}

	// Grab the client for our invalid address and close it. This will
	// cause the blocked ping RPC to finish.
	client := NewClient(addr, nil, rpcContext)
	client.Close()
	select {
	case <-c:
	case <-time.After(100 * time.Millisecond):
		t.Fatalf("RPC call failed to return")
	}
}

// TestComplexScenarios verifies various complex success/failure scenarios by
// mocking sendOne.
func TestComplexScenarios(t *testing.T) {
	rpcContext := NewTestContext(t)

	testCases := []struct {
		numServers               int
		numRequests              int
		numErrors                int
		numRetryableErrors       int
		success                  bool
		isRetryableErrorExpected bool
	}{
		// --- Success scenarios ---
		{1, 1, 0, 0, true, false},
		{5, 1, 0, 0, true, false},
		{5, 5, 0, 0, true, false},
		// There are some errors, but enough RPCs succeed.
		{5, 1, 1, 0, true, false},
		{5, 1, 4, 0, true, false},
		{5, 3, 2, 0, true, false},

		// --- Failure scenarios ---
		// Too many requests.
		{1, 5, 0, 0, false, false},
		// All RPCs fail.
		{5, 1, 5, 0, false, false},
		// Some RPCs fail and we do not have enough remaining clients.
		{5, 3, 3, 0, false, false},
		// All RPCs fail, but some of the errors are retryable.
		{5, 1, 5, 1, false, true},
		{5, 3, 5, 3, false, true},
		// Some RPCs fail, but we do have enough remaining clients and recoverable errors.
		{5, 3, 3, 1, false, true},
		{5, 3, 4, 2, false, true},
	}
	for i, test := range testCases {
		// Copy the values to avoid data race. sendOneFn might
		// be called after this test case finishes.
		numErrors := test.numErrors
		numRetryableErrors := test.numRetryableErrors

		var serverAddrs []net.Addr
		for j := 0; j < test.numServers; j++ {
			s := createAndStartNewServer(rpcContext, t)
			defer s.Close()
			serverAddrs = append(serverAddrs, s.Addr())
		}

		opts := Options{
			N:               test.numRequests,
			Ordering:        OrderStable,
			SendNextTimeout: 1 * time.Second,
			Timeout:         1 * time.Second,
		}
		getArgs := func(addr net.Addr) interface{} {
			return addr
		}
		getReply := func() interface{} {
			return 0
		}

		// Mock sendOne.
		sendOneFn = func(client *Client, timeout time.Duration, method string, args, reply interface{},
			c chan interface{}) {
			addr := args.(net.Addr)
			addrID := -1
			for serverAddrID, serverAddr := range serverAddrs {
				if serverAddr.String() == addr.String() {
					addrID = serverAddrID
					break
				}
			}
			if addrID == -1 {
				t.Fatalf("%d: %v is not found in serverAddrs: %v", i, addr, serverAddrs)
			}
			if addrID < numErrors {
				c <- SendError{
					errMsg:   "test",
					canRetry: addrID < numRetryableErrors,
				}
				return
			}

			c <- nil
		}
		defer func() { sendOneFn = sendOne }()

		replies, err := Send(opts, "Heartbeat.Ping", serverAddrs, getArgs, getReply, rpcContext)
		if test.success {
			if len(replies) != test.numRequests {
				t.Errorf("%d: %v replies are expected, but got %v", i, test.numRequests, len(replies))
			}
			continue
		}

		retryErr, ok := err.(util.Retryable)
		if !ok {
			t.Fatalf("%d: Unexpected error type: %v", i, err)
		}
		if retryErr.CanRetry() != test.isRetryableErrorExpected {
			t.Errorf("%d: Unexpected error: %v", i, retryErr)
		}
	}
}

// createAndStartNewServer creates and starts a new server with a test address.
func createAndStartNewServer(rpcContext *Context, t *testing.T) *Server {
	s := NewServer(util.CreateTestAddr("tcp"), rpcContext)
	if err := s.Start(); err != nil {
		t.Fatal(err)
	}
	return s
}

// sendPing sends Ping requests to specified addresses using Send.
func sendPing(opts Options, addrs []net.Addr, rpcContext *Context) ([]interface{}, error) {
	getArgs := func(addr net.Addr) interface{} {
		return &proto.PingRequest{}
	}
	getReply := func() interface{} {
		return &proto.PingResponse{}
	}
	return Send(opts, "Heartbeat.Ping", addrs, getArgs, getReply, rpcContext)
}
<|endoftext|>


<commit_before>/*
	Copyright (C) 2016 vLife Systems Ltd <http://vlifesystems.com>
	This file is part of rhkit.

	rhkit is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	rhkit is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with rhkit; see the file COPYING.  If not, see
	<http://www.gnu.org/licenses/>.
*/

package rhkit

import (
	"errors"
	"fmt"
	"github.com/lawrencewoodman/ddataset"
	"github.com/vlifesystems/rhkit/experiment"
	"github.com/vlifesystems/rhkit/rule"
)

// AssessRules runs the rules against the experiment and returns an
// Assessment along with any errors
func AssessRules(
	rules []rule.Rule,
	e *experiment.Experiment,
) (*Assessment, error) {
	ruleAssessors := make([]*ruleAssessor, len(rules))
	for i, rule := range rules {
		ruleAssessors[i] = newRuleAssessor(rule, e.Aggregators, e.Goals)
	}

	numRecords, err := processDataset(e.Dataset, ruleAssessors)
	if err != nil {
		return &Assessment{}, err
	}
	goodRuleAssessors, err := filterGoodRuleAssessors(ruleAssessors, numRecords)
	if err != nil {
		return &Assessment{}, err
	}

	assessment, err := newAssessment(numRecords, goodRuleAssessors, e.Goals)
	return assessment, err
}

func filterGoodRuleAssessors(
	ruleAssessments []*ruleAssessor,
	numRecords int64,
) ([]*ruleAssessor, error) {
	goodRuleAssessors := make([]*ruleAssessor, 0)
	for _, ruleAssessment := range ruleAssessments {
		numMatches, exists :=
			ruleAssessment.GetAggregatorValue("numMatches", numRecords)
		if !exists {
			// TODO: Create a proper error for this?
			err := errors.New("numMatches doesn't exist in aggregators")
			return goodRuleAssessors, err
		}
		numMatchesInt, isInt := numMatches.Int()
		if !isInt {
			// TODO: Create a proper error for this?
			err := errors.New(fmt.Sprintf("Can't cast to Int: %q", numMatches))
			return goodRuleAssessors, err
		}
		if numMatchesInt > 0 {
			goodRuleAssessors = append(goodRuleAssessors, ruleAssessment)
		}
	}
	return goodRuleAssessors, nil
}

func processDataset(
	dataset ddataset.Dataset,
	ruleAssessors []*ruleAssessor,
) (int64, error) {
	numRecords := int64(0)
	conn, err := dataset.Open()
	if err != nil {
		return numRecords, err
	}
	defer conn.Close()

	for conn.Next() {
		record := conn.Read()
		numRecords++
		for _, ruleAssessor := range ruleAssessors {
			err := ruleAssessor.NextRecord(record)
			if err != nil {
				return numRecords, err
			}
		}
	}

	return numRecords, conn.Err()
}
<commit_msg>Panic rather than error in filterGoodRuleAssessors<commit_after>/*
	Copyright (C) 2016 vLife Systems Ltd <http://vlifesystems.com>
	This file is part of rhkit.

	rhkit is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	rhkit is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with rhkit; see the file COPYING.  If not, see
	<http://www.gnu.org/licenses/>.
*/

package rhkit

import (
	"fmt"
	"github.com/lawrencewoodman/ddataset"
	"github.com/vlifesystems/rhkit/experiment"
	"github.com/vlifesystems/rhkit/rule"
)

// AssessRules runs the rules against the experiment and returns an
// Assessment along with any errors
func AssessRules(
	rules []rule.Rule,
	e *experiment.Experiment,
) (*Assessment, error) {
	ruleAssessors := make([]*ruleAssessor, len(rules))
	for i, rule := range rules {
		ruleAssessors[i] = newRuleAssessor(rule, e.Aggregators, e.Goals)
	}

	numRecords, err := processDataset(e.Dataset, ruleAssessors)
	if err != nil {
		return &Assessment{}, err
	}
	goodRuleAssessors := filterGoodRuleAssessors(ruleAssessors, numRecords)
	assessment, err := newAssessment(numRecords, goodRuleAssessors, e.Goals)
	return assessment, err
}

func filterGoodRuleAssessors(
	ruleAssessments []*ruleAssessor,
	numRecords int64,
) []*ruleAssessor {
	goodRuleAssessors := make([]*ruleAssessor, 0)
	for _, ruleAssessment := range ruleAssessments {
		numMatches, exists :=
			ruleAssessment.GetAggregatorValue("numMatches", numRecords)
		if !exists {
			panic("numMatches doesn't exist in aggregators")
		}
		numMatchesInt, isInt := numMatches.Int()
		if !isInt {
			panic(fmt.Sprintf("can't cast numMatches to Int: %s", numMatches))
		}
		if numMatchesInt > 0 {
			goodRuleAssessors = append(goodRuleAssessors, ruleAssessment)
		}
	}
	return goodRuleAssessors
}

func processDataset(
	dataset ddataset.Dataset,
	ruleAssessors []*ruleAssessor,
) (int64, error) {
	numRecords := int64(0)
	conn, err := dataset.Open()
	if err != nil {
		return numRecords, err
	}
	defer conn.Close()

	for conn.Next() {
		record := conn.Read()
		numRecords++
		for _, ruleAssessor := range ruleAssessors {
			err := ruleAssessor.NextRecord(record)
			if err != nil {
				return numRecords, err
			}
		}
	}

	return numRecords, conn.Err()
}
<|endoftext|>


<commit_before>package saltboot

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"

	"github.com/sequenceiq/salt-bootstrap/saltboot/model"
	"gopkg.in/yaml.v2"
)

type SaltActionRequest struct {
	Master  SaltMaster   `json:"master,omitempty"`
	Minions []SaltMinion `json:"minions,omitempty"`
	Action  string       `json:"action"`
}

type SaltAuth struct {
	Password string `json:"password,omitempty"`
}

type SaltMaster struct {
	Address string     `json:"address"`
	Auth    SaltAuth   `json:"auth,omitempty"`
}

type SaltMinion struct {
	Address   string   `json:"address"`
	Roles     []string `json:"roles,omitempty"`
	Server    string   `json:"server,omitempty"`
	HostGroup string   `json:"hostGroup,omitempty"`
}

type SaltPillar struct {
	Path string                 `json:"path"`
	Json map[string]interface{} `json:"json"`
}

func (saltMinion SaltMinion) AsByteArray() []byte {
	b, _ := json.Marshal(saltMinion)
	return b
}

func (saltMaster SaltMaster) AsByteArray() []byte {
	b, _ := json.Marshal(saltMaster)
	return b
}

type GrainConfig struct {
	HostGroup string   `json:"hostgroup" yaml:"hostgroup"`
	Roles     []string `json:"roles" yaml:"roles"`
}

func (r SaltActionRequest) String() string {
	b, _ := json.Marshal(r)
	return fmt.Sprintf(string(b))
}

func (r SaltActionRequest) distributeAction(user string, pass string) (result []model.Response) {
	log.Printf("[distributeAction] distribute salt state command to targets: %s", r.String())

	var targets []string
	var minionPayload []Payload
	for _, minion := range r.Minions {
		targets = append(targets, minion.Address)
		if minion.Server == "" {
			minion.Server = r.Master.Address
		}
		minionPayload = append(minionPayload, minion)
	}

	for res := range DistributePayload(targets, minionPayload, SaltMinionEp + "/" + r.Action, user, pass) {
		result = append(result, res)
	}
	if len(r.Master.Address) > 0 {
		result = append(result, <-DistributePayload([]string{r.Master.Address}, []Payload{r.Master}, SaltServerEp + "/" + r.Action, user, pass))
	}
	return result
}

func SaltMinionRunRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltMinionRunRequestHandler] execute salt run request")

	decoder := json.NewDecoder(req.Body)
	var saltMinion SaltMinion
	err := decoder.Decode(&saltMinion)
	if err != nil {
		log.Printf("[SaltMinionRunRequestHandler] [ERROR] couldn't decode json: %s", err)
		model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
		return
	}

	grainConfig := GrainConfig{Roles: saltMinion.Roles, HostGroup: saltMinion.HostGroup}
	grainYaml, err := yaml.Marshal(grainConfig)
	var resp model.Response
	if err != nil {
		resp = model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}
		resp.WriteHttp(w)
		return
	}

	err = os.MkdirAll("/etc/salt/minion.d", 0755)
	if err != nil {
		resp = model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}
		resp.WriteHttp(w)
		return
	}

	masterConf := []byte("master: " + saltMinion.Server)
	err = ioutil.WriteFile("/etc/salt/minion.d/master.conf", masterConf, 0644)
	if err != nil {
		resp = model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}
		resp.WriteHttp(w)
		return
	}

	err = ioutil.WriteFile("/etc/salt/grains", grainYaml, 0644)
	if err != nil {
		resp = model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}
		resp.WriteHttp(w)
		return
	}
	resp, _ = LaunchService("salt-minion")
	resp.WriteHttp(w)
}

func SaltMinionStopRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltMinionStopRequestHandler] execute salt minion stop request")

	decoder := json.NewDecoder(req.Body)
	var saltMinion SaltMinion
	err := decoder.Decode(&saltMinion)
	if err != nil {
		log.Printf("[SaltMinionRunRequestHandler] [ERROR] couldn't decode json: %s", err)
		model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
		return
	}

	resp, _ := StopService("salt-minion")
	resp.WriteHttp(w)
}

func SaltServerRunRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltServerRunRequestHandler] execute salt run request")

	decoder := json.NewDecoder(req.Body)
	var saltMaster SaltMaster
	err := decoder.Decode(&saltMaster)
	if err != nil {
		log.Printf("[SaltServerRunRequestHandler] [ERROR] couldn't decode json: %s", err)
		model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
		return
	}

	resp, err := CreateUser(saltMaster)
	resp.WriteHttp(w)
	if err != nil {
		return
	}

	resp, err = LaunchService("salt-master")
	resp.WriteHttp(w)

	if err != nil {
		return
	}

	resp, _ = LaunchService("salt-api")
	resp.WriteHttp(w)
}

func SaltServerStopRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltServerStopRequestHandler] execute salt master stop request")
	resp, err := StopService("salt-master")
	resp.WriteHttp(w)
	if err != nil {
		return
	}
	resp, _ = StopService("salt-api")
	resp.WriteHttp(w)
}

func (pillar SaltPillar) WritePillar() (outStr string, err error) {
	file := "/srv/pillar" + pillar.Path
	dir := file[0:strings.LastIndex(file, "/")]

	log.Printf("[SaltPillar.WritePillar] mkdir %s", dir)
	err = os.MkdirAll(dir, 0644)
	if err != nil {
		return "Failed to create dir " + dir, err
	}

	yml, _ := yaml.Marshal(pillar.Json)
	log.Printf("[SaltPillarRequestHandler] generated yaml from json %s", string(yml))
	err = ioutil.WriteFile(file, yml, 0644)
	if err != nil {
		return "Failed to write to " + file, err
	}
	return "Salt pillar successfully written to " + file, err
}

func SaltPillarRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltPillarRequestHandler] execute salt pillar save request")
	decoder := json.NewDecoder(req.Body)
	var saltPillar SaltPillar
	err := decoder.Decode(&saltPillar)
	if err != nil {
		log.Printf("[SaltPillarRequestHandler] [ERROR] couldn't decode json: %s", err)
		model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
		return
	}

	if !strings.HasSuffix(saltPillar.Path, ".sls") {
		log.Printf("[SaltPillarRequestHandler] [ERROR] path is not ending with '.sls' suffix %s", saltPillar.Path)
		model.Response{Status: "path is not ending with '.sls' suffix"}.WriteBadRequestHttp(w)
		return
	}
	if !strings.HasPrefix(saltPillar.Path, "/") {
		log.Printf("[SaltPillarRequestHandler] [ERROR] path is not starting with '/' %s", saltPillar.Path)
		model.Response{Status: "path is not starting with '/'"}.WriteBadRequestHttp(w)
		return
	}
	if strings.Contains(saltPillar.Path, "..") {
		log.Printf("[SaltPillarRequestHandler] [ERROR] path cannot contain '..' charachters %s", saltPillar.Path)
		model.Response{Status: "path cannot contain '..' charachters"}.WriteBadRequestHttp(w)
		return
	}

	jsonString, _ := json.Marshal(saltPillar.Json)
	log.Printf("[SaltPillarRequestHandler] Recieved arbitrary json: %s", jsonString)

	outStr, err := saltPillar.WritePillar()
	if err != nil {
		log.Printf("[SaltPillarRequestHandler] failed to execute salt pillar save config: %s", err.Error())
		model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}.WriteHttp(w)
	} else {
		cResp := model.Response{Status: outStr}.WriteHttp(w)
		log.Printf("[SaltPillarRequestHandler] save salt pillar request executed: %s", cResp.String())
	}
}

func SaltActionDistributeRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltActionDistributeRequestHandler] execute Salt state distribute request")

	decoder := json.NewDecoder(req.Body)
	var saltActionRequest SaltActionRequest
	err := decoder.Decode(&saltActionRequest)
	if err != nil {
		log.Printf("[SaltActionDistributeRequestHandler] [ERROR] couldn't decode json: %s", err)
		model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
		return
	}

	user, pass := GetAuthUserPass(req)
	result := saltActionRequest.distributeAction(user, pass)
	cResp := model.Responses{Responses: result}
	log.Printf("[SaltActionDistributeRequestHandler] distribute salt state command request executed: %s", cResp.String())
	json.NewEncoder(w).Encode(cResp)
}
<commit_msg>CLOUD-67234 Sysv scripts starts the salt minion twice<commit_after>package saltboot

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"

	"github.com/sequenceiq/salt-bootstrap/saltboot/model"
	"gopkg.in/yaml.v2"
)

type SaltActionRequest struct {
	Master  SaltMaster   `json:"master,omitempty"`
	Minions []SaltMinion `json:"minions,omitempty"`
	Action  string       `json:"action"`
}

type SaltAuth struct {
	Password string `json:"password,omitempty"`
}

type SaltMaster struct {
	Address string     `json:"address"`
	Auth    SaltAuth   `json:"auth,omitempty"`
}

type SaltMinion struct {
	Address   string   `json:"address"`
	Roles     []string `json:"roles,omitempty"`
	Server    string   `json:"server,omitempty"`
	HostGroup string   `json:"hostGroup,omitempty"`
}

type SaltPillar struct {
	Path string                 `json:"path"`
	Json map[string]interface{} `json:"json"`
}

func (saltMinion SaltMinion) AsByteArray() []byte {
	b, _ := json.Marshal(saltMinion)
	return b
}

func (saltMaster SaltMaster) AsByteArray() []byte {
	b, _ := json.Marshal(saltMaster)
	return b
}

type GrainConfig struct {
	HostGroup string   `json:"hostgroup" yaml:"hostgroup"`
	Roles     []string `json:"roles" yaml:"roles"`
}

func (r SaltActionRequest) String() string {
	b, _ := json.Marshal(r)
	return fmt.Sprintf(string(b))
}

func (r SaltActionRequest) distributeAction(user string, pass string) (result []model.Response) {
	log.Printf("[distributeAction] distribute salt state command to targets: %s", r.String())

	var targets []string
	var minionPayload []Payload
	for _, minion := range r.Minions {
		targets = append(targets, minion.Address)
		if minion.Server == "" {
			minion.Server = r.Master.Address
		}
		minionPayload = append(minionPayload, minion)
	}

	for res := range DistributePayload(targets, minionPayload, SaltMinionEp + "/" + r.Action, user, pass) {
		result = append(result, res)
	}
	if len(r.Master.Address) > 0 {
		result = append(result, <-DistributePayload([]string{r.Master.Address}, []Payload{r.Master}, SaltServerEp + "/" + r.Action, user, pass))
	}
	return result
}

func SaltMinionRunRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltMinionRunRequestHandler] execute salt-minion run request")

	decoder := json.NewDecoder(req.Body)
	var saltMinion SaltMinion
	err := decoder.Decode(&saltMinion)
	if err != nil {
		log.Printf("[SaltMinionRunRequestHandler] [ERROR] couldn't decode json: %s", err)
		model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
		return
	}
	log.Printf("[SaltMinionRunRequestHandler] received json: %s", saltMinion.AsByteArray())

	grainConfig := GrainConfig{Roles: saltMinion.Roles, HostGroup: saltMinion.HostGroup}
	grainYaml, err := yaml.Marshal(grainConfig)
	var resp model.Response
	if err != nil {
		resp = model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}
		resp.WriteHttp(w)
		return
	}

	err = os.MkdirAll("/etc/salt/minion.d", 0755)
	if err != nil {
		resp = model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}
		resp.WriteHttp(w)
		return
	}

	masterConf := []byte("master: " + saltMinion.Server)
	err = ioutil.WriteFile("/etc/salt/minion.d/master.conf", masterConf, 0644)
	if err != nil {
		resp = model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}
		resp.WriteHttp(w)
		return
	}

	err = ioutil.WriteFile("/etc/salt/grains", grainYaml, 0644)
	if err != nil {
		resp = model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}
		resp.WriteHttp(w)
		return
	}
	psOutput, err := ExecCmd("ps", "aux")
	alreadyRunning := strings.Contains(psOutput, "salt-minion")

	if alreadyRunning {
		log.Printf("[SaltMinionRunRequestHandler] salt-minion is already running %s", psOutput)
		resp = model.Response{StatusCode: http.StatusOK, Status: "salt-minion already running"}
		resp.WriteHttp(w)
		return
	} else {
		log.Printf("[SaltMinionRunRequestHandler] salt-minion is not running and will be started")
	}
	resp, _ = LaunchService("salt-minion")
	log.Printf("[SaltMinionRunRequestHandler] execute salt-minion run request")
	resp.WriteHttp(w)
}

func SaltMinionStopRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltMinionStopRequestHandler] execute salt-minion stop request")

	decoder := json.NewDecoder(req.Body)
	var saltMinion SaltMinion
	err := decoder.Decode(&saltMinion)
	if err != nil {
		log.Printf("[SaltMinionRunRequestHandler] [ERROR] couldn't decode json: %s", err)
		model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
		return
	}
	log.Printf("[SaltMinionRunRequestHandler] received json: %s", saltMinion.AsByteArray())

	resp, _ := StopService("salt-minion")
	resp.WriteHttp(w)
}

func SaltServerRunRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltServerRunRequestHandler] execute salt run request")

	decoder := json.NewDecoder(req.Body)
	var saltMaster SaltMaster
	err := decoder.Decode(&saltMaster)
	if err != nil {
		log.Printf("[SaltServerRunRequestHandler] [ERROR] couldn't decode json: %s", err)
		model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
		return
	}

	resp, err := CreateUser(saltMaster)
	resp.WriteHttp(w)
	if err != nil {
		return
	}

	resp, err = LaunchService("salt-master")
	resp.WriteHttp(w)

	if err != nil {
		return
	}

	resp, _ = LaunchService("salt-api")
	resp.WriteHttp(w)
}

func SaltServerStopRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltServerStopRequestHandler] execute salt master stop request")
	resp, err := StopService("salt-master")
	resp.WriteHttp(w)
	if err != nil {
		return
	}
	resp, _ = StopService("salt-api")
	resp.WriteHttp(w)
}

func (pillar SaltPillar) WritePillar() (outStr string, err error) {
	file := "/srv/pillar" + pillar.Path
	dir := file[0:strings.LastIndex(file, "/")]

	log.Printf("[SaltPillar.WritePillar] mkdir %s", dir)
	err = os.MkdirAll(dir, 0644)
	if err != nil {
		return "Failed to create dir " + dir, err
	}

	yml, _ := yaml.Marshal(pillar.Json)
	log.Printf("[SaltPillarRequestHandler] generated yaml from json %s", string(yml))
	err = ioutil.WriteFile(file, yml, 0644)
	if err != nil {
		return "Failed to write to " + file, err
	}
	return "Salt pillar successfully written to " + file, err
}

func SaltPillarRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltPillarRequestHandler] execute salt pillar save request")
	decoder := json.NewDecoder(req.Body)
	var saltPillar SaltPillar
	err := decoder.Decode(&saltPillar)
	if err != nil {
		log.Printf("[SaltPillarRequestHandler] [ERROR] couldn't decode json: %s", err)
		model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
		return
	}

	if !strings.HasSuffix(saltPillar.Path, ".sls") {
		log.Printf("[SaltPillarRequestHandler] [ERROR] path is not ending with '.sls' suffix %s", saltPillar.Path)
		model.Response{Status: "path is not ending with '.sls' suffix"}.WriteBadRequestHttp(w)
		return
	}
	if !strings.HasPrefix(saltPillar.Path, "/") {
		log.Printf("[SaltPillarRequestHandler] [ERROR] path is not starting with '/' %s", saltPillar.Path)
		model.Response{Status: "path is not starting with '/'"}.WriteBadRequestHttp(w)
		return
	}
	if strings.Contains(saltPillar.Path, "..") {
		log.Printf("[SaltPillarRequestHandler] [ERROR] path cannot contain '..' charachters %s", saltPillar.Path)
		model.Response{Status: "path cannot contain '..' charachters"}.WriteBadRequestHttp(w)
		return
	}

	jsonString, _ := json.Marshal(saltPillar.Json)
	log.Printf("[SaltPillarRequestHandler] Recieved arbitrary json: %s", jsonString)

	outStr, err := saltPillar.WritePillar()
	if err != nil {
		log.Printf("[SaltPillarRequestHandler] failed to execute salt pillar save config: %s", err.Error())
		model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}.WriteHttp(w)
	} else {
		cResp := model.Response{Status: outStr}.WriteHttp(w)
		log.Printf("[SaltPillarRequestHandler] save salt pillar request executed: %s", cResp.String())
	}
}

func SaltActionDistributeRequestHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("[SaltActionDistributeRequestHandler] execute Salt state distribute request")

	decoder := json.NewDecoder(req.Body)
	var saltActionRequest SaltActionRequest
	err := decoder.Decode(&saltActionRequest)
	if err != nil {
		log.Printf("[SaltActionDistributeRequestHandler] [ERROR] couldn't decode json: %s", err)
		model.Response{Status: err.Error()}.WriteBadRequestHttp(w)
		return
	}

	user, pass := GetAuthUserPass(req)
	result := saltActionRequest.distributeAction(user, pass)
	cResp := model.Responses{Responses: result}
	log.Printf("[SaltActionDistributeRequestHandler] distribute salt state command request executed: %s", cResp.String())
	json.NewEncoder(w).Encode(cResp)
}
<|endoftext|>


<commit_before>package main

import "fmt"
import "./cryptutils"

// test commit
func main() {
	fmt.Println(cryptutils.PKCS7Padding([]byte("YELLOW SUBMARINE"), 10))
}
<commit_msg>test commit<commit_after>package main

import "fmt"
import "./cryptutils"

func main() {
	fmt.Println(cryptutils.PKCS7Padding([]byte("YELLOW SUBMARINE"), 10))
}
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2016 Maciej Borzecki

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package main

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
	"github.com/pkg/errors"
	"log"
	"os"
	"path"
)

const (
	defaultDbName = "q3stat.db"
)

type DB struct {
	db *gorm.DB
}

func NewDB() *DB {
	return &DB{}
}

func (d *DB) Open() error {
	p := C.Dbpath
	fi, _ := os.Stat(p)
	if fi.IsDir() == true {
		p = path.Join(p, defaultDbName)
	}

	log.Printf("opening DB file: %s", p)

	db, err := gorm.Open("sqlite3", p)
	if err != nil {
		return errors.Wrap(err, "failed to open DB")
	}

	d.db = db

	return nil
}

func (d *DB) Conn() *gorm.DB {
	return d.db
}

func (d *DB) Close() {
	if d.db != nil {
		d.db.Close()
	}
}
<commit_msg>db: implement transactional and connectable interfaces<commit_after>// The MIT License (MIT)

// Copyright (c) 2016 Maciej Borzecki

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package main

import (
	"github.com/bboozzoo/q3stats/store"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
	"github.com/pkg/errors"
	"log"
	"os"
	"path"
)

const (
	defaultDbName = "q3stat.db"
)

type DB struct {
	db *gorm.DB
}

func NewDB() *DB {
	return &DB{}
}

func (d *DB) Open() error {
	p := C.Dbpath
	fi, _ := os.Stat(p)
	if fi.IsDir() == true {
		p = path.Join(p, defaultDbName)
	}

	log.Printf("opening DB file: %s", p)

	db, err := gorm.Open("sqlite3", p)
	if err != nil {
		return errors.Wrap(err, "failed to open DB")
	}

	d.db = db

	return nil
}

func (d *DB) Conn() *gorm.DB {
	return d.db
}

func (d *DB) Close() {
	if d.db != nil {
		d.db.Close()
	}
}

// return DB transaction wrapper
func (db *DB) Begin() store.DBTransaction {
	return &dbTx{
		db: db.db.Begin(),
	}
}

// helper DB transaction wrapper
type dbTx struct {
	db *gorm.DB
}

func (dbt *dbTx) Conn() *gorm.DB {
	return dbt.db
}

func (dbt *dbTx) Commit() {
	dbt.db.Commit()
}
<|endoftext|>