<commit_before>package junos

// Establishing a session
func Example() {
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()
}

// To View the entire configuration, use the keyword "full" for the first
// argument. If anything else outside of "full" is specified, it will return
// the configuration of the specified top-level stanza only. So "security" would return everything
// under the "security" stanza.
func Example_viewConfiguration() {
	// Output format can be "text" or "xml"
	config, err := jnpr.GetConfig("full", "text")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(config)
}

// Comparing and Rolling Back Configurations
func Example_rollbackConfigurations() {
	// If you want to view the difference between the current configuration and a rollback
	// one, then you can use the ConfigDiff() function to specify a previous config:
	diff, err := jnpr.ConfigDiff(3)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(diff)

	// You can rollback to a previous state, or the rescue configuration by using
	// the RollbackConfig() function:
	err := jnpr.RollbackConfig(3)
	if err != nil {
		fmt.Println(err)
	}

	// Create a rescue config from the active configuration.
	jnpr.Rescue("save")

	// You can also delete a rescue config.
	jnpr.Rescue("delete")

	// Rollback to the "rescue" configuration.
	err := jnpr.RollbackConfig("rescue")
	if err != nil {
		fmt.Println(err)
	}
}

// Device Configuration
func Example_configuringDevices() {
	// Use the LoadConfig() function to load the configuration from a file.

	// When configuring a device, it is good practice to lock the configuration database,
	// load the config, commit the configuration, and then unlock the configuration database.
	// You can do this with the following functions: Lock(), Commit(), Unlock()

	// Multiple ways to commit a configuration

	// Commit the configuration as normal
	Commit()

	// Check the configuration for any syntax errors (NOTE: you must still issue a Commit() afterwards)
	CommitCheck()

	// Commit at a later time, i.e. 4:30 PM
	CommitAt("16:30:00")

	// Rollback configuration if a Commit() is not issued within the given <minutes>.
	CommitConfirm(15)

	// You can configure the Junos device by uploading a local file, or pulling from an
	// FTP/HTTP server. The LoadConfig() function takes three arguments:

	// filename or URL, format, and a boolean (true/false) "commit-on-load"

	// If you specify a URL, it must be in the following format:

	// ftp://<username>:<password>@hostname/pathname/file-name
	// http://<username>:<password>@hostname/pathname/file-name

	// Note: The default value for the FTP path variable is the user’s home directory. Thus,
	// by default the file path to the configuration file is relative to the user directory.
	// To specify an absolute path when using FTP, start the path with the characters %2F;
	// for example: ftp://username:password@hostname/%2Fpath/filename.

	// The format of the commands within the file must be one of the following types:

	// set
	// system name-server 1.1.1.1

	// text
	// system {
	//     name-server 1.1.1.1;
	// }

	// xml
	// <system>
	//     <name-server>
	//         <name>1.1.1.1</name>
	//     </name-server>
	// </system>

	// If the third option is "true" then after the configuration is loaded, a commit
	// will be issued. If set to "false," you will have to commit the configuration
	// using one of the Commit() functions.
	jnpr.Lock()
	err := jnpr.LoadConfig("path-to-file.txt", "set", true)
	if err != nil {
		fmt.Println(err)
	}
	jnpr.Unlock()
}

// Running Commands on a Device
func Example_runCommands() {
	// You can run operational mode commands such as "show" and "request" by using the
	// Command() function. Output formats can be "text" or "xml":

	// Results returned in text format
	txtOutput, err := jnpr.Command("show chassis hardware", "text")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(txtOutput)

	// Results returned in XML format
	xmlOutput, err := jnpr.Command("show chassis hardware", "xml")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(xmlOutput)
}

func Example_displayPlatform_Information() {
	// When you call the PrintFacts() function, it just prints out the platform
	// and software information to the console.
	jnpr.PrintFacts()

	// You can also loop over the struct field that contains this information yourself:
	fmt.Printf("Hostname: %s", jnpr.Hostname)
	for _, data := range jnpr.Platform {
		fmt.Printf("Model: %s, Version: %s", data.Model, data.Version)
	}
	// Output: Model: SRX240H2, Version: 12.1X47-D10.4
}
<commit_msg>Added more examples<commit_after>package junos

// Establishing a session to the Junos device.
func Example() {
	jnpr, err := junos.NewSession(host, user, password)
	if err != nil {
		log.Fatal(err)
	}
	defer jnpr.Close()
}

// To View the entire configuration, use the keyword "full" for the first
// argument. If anything else outside of "full" is specified, it will return
// the configuration of the specified top-level stanza only. So "security" would return everything
// under the "security" stanza.
func Example_viewConfiguration() {
	// Output format can be "text" or "xml".
	config, err := jnpr.GetConfig("full", "text")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(config)
}

// Comparing and working with rollback configurations.
func Example_rollbackConfigurations() {
	// If you want to view the difference between the current configuration and a rollback
	// one, then you can use the ConfigDiff() function to specify a previous config:
	diff, err := jnpr.ConfigDiff(3)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(diff)

	// You can rollback to a previous state, or the rescue configuration by using
	// the RollbackConfig() function:
	err := jnpr.RollbackConfig(3)
	if err != nil {
		fmt.Println(err)
	}

	// Create a rescue config from the active configuration.
	jnpr.Rescue("save")

	// You can also delete a rescue config.
	jnpr.Rescue("delete")

	// Rollback to the "rescue" configuration.
	err := jnpr.RollbackConfig("rescue")
	if err != nil {
		fmt.Println(err)
	}
}

// Configuring devices.
func Example_configuringDevices() {
	// Use the LoadConfig() function to load the configuration from a file.

	// When configuring a device, it is good practice to lock the configuration database,
	// load the config, commit the configuration, and then unlock the configuration database.
	// You can do this with the following functions: Lock(), Commit(), Unlock().

	// Multiple ways to commit a configuration.

	// Commit the configuration as normal.
	Commit()

	// Check the configuration for any syntax errors (NOTE: you must still issue a Commit() afterwards).
	CommitCheck()

	// Commit at a later time, i.e. 4:30 PM.
	CommitAt("16:30:00")

	// Rollback configuration if a Commit() is not issued within the given <minutes>.
	CommitConfirm(15)

	// You can configure the Junos device by uploading a local file, or pulling from an
	// FTP/HTTP server. The LoadConfig() function takes three arguments:

	// filename or URL, format, and a boolean (true/false) "commit-on-load".

	// If you specify a URL, it must be in the following format:

	// ftp://<username>:<password>@hostname/pathname/file-name
	// http://<username>:<password>@hostname/pathname/file-name

	// Note: The default value for the FTP path variable is the user’s home directory. Thus,
	// by default the file path to the configuration file is relative to the user directory.
	// To specify an absolute path when using FTP, start the path with the characters %2F;
	// for example: ftp://username:password@hostname/%2Fpath/filename.

	// The format of the commands within the file must be one of the following types:

	// set
	// system name-server 1.1.1.1

	// text
	// system {
	//     name-server 1.1.1.1;
	// }

	// xml
	// <system>
	//     <name-server>
	//         <name>1.1.1.1</name>
	//     </name-server>
	// </system>

	// If the third option is "true" then after the configuration is loaded, a commit
	// will be issued. If set to "false," you will have to commit the configuration
	// using one of the Commit() functions.
	jnpr.Lock()
	err := jnpr.LoadConfig("path-to-file.txt", "set", true)
	if err != nil {
		fmt.Println(err)
	}
	jnpr.Unlock()
}

// Running operational mode commands on a device.
func Example_runCommands() {
	// You can run operational mode commands such as "show" and "request" by using the
	// Command() function. Output formats can be "text" or "xml".

	// Results returned in text format.
	txtOutput, err := jnpr.Command("show chassis hardware", "text")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(txtOutput)

	// Results returned in XML format.
	xmlOutput, err := jnpr.Command("show chassis hardware", "xml")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(xmlOutput)
}

// Viewing basic information about the device.
func Example_deviceInformation() {
	// When you call the PrintFacts() function, it just prints out the platform
	// and software information to the console.
	jnpr.PrintFacts()

	// You can also loop over the struct field that contains this information yourself:
	fmt.Printf("Hostname: %s", jnpr.Hostname)
	for _, data := range jnpr.Platform {
		fmt.Printf("Model: %s, Version: %s", data.Model, data.Version)
	}
	// Output: Model: SRX240H2, Version: 12.1X47-D10.4
}
<|endoftext|>


<commit_before>package weixin

import (
	"encoding/xml"
	"errors"
	"io/ioutil"
	"net/http"
)
import "github.com/omigo/log"

// HandleAccess 接入微信公众平台开发，并接口来自微信服务器的消息
func HandleAccess(w http.ResponseWriter, r *http.Request) {
	log.Debugf("%s", r.URL)

	q := r.URL.Query()
	signature := q.Get("signature")
	timestamp := q.Get("timestamp")
	nonce := q.Get("nonce")

	// 每次都验证 URL，以判断来源是否合法
	if !ValidateURL(Token, timestamp, nonce, signature) {
		http.Error(w, "validate url error, request not from weixin?", http.StatusUnauthorized)
		return
	}

	switch r.Method {
	// 如果是 GET 请求，表示这是接入验证请求
	case "GET":
		w.Write([]byte(q.Get("echostr")))
	case "POST":
		processMessage(w, r)
	default:
		http.Error(w, "only GET or POST method allowed", http.StatusUnauthorized)
	}
}

// 处理所有来自微信的消息，已经验证过 URL 和 Method 了
func processMessage(w http.ResponseWriter, r *http.Request) {
	q := r.URL.Query()
	timestamp := q.Get("timestamp")
	nonce := q.Get("nonce")
	encryptType := q.Get("encrypt_type")
	msgSignature := q.Get("msg_signature")

	// 读取报文
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Error(err)
		http.Error(w, "read body error", http.StatusNotAcceptable)
		return
	}
	r.Body.Close()
	log.Debugf("from weixin: %s", body)

	msg, err := parseBody(encryptType, timestamp, nonce, msgSignature, body)
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// 处理消息
	reply := HandleMessage(msg)

	// 如果返回为 nil，表示不需要回复，结束
	if reply == nil {
		return
	}

	// 如果返回不为 nil，表示需要回复
	ret, err := packReply(reply, encryptType, timestamp, nonce)
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	log.Debugf("to weixin: %s", ret)
	w.Header().Set("Content-Type", "text/xml; charset=utf-8")
	w.Write(ret)
}

func parseBody(encryptType, timestamp, nonce, msgSignature string, body []byte) (msg *Message, err error) {
	msg = &Message{}
	// 如果报文被加密了，先要验签解密
	if encryptType == "aes" {
		encMsg := &EncMessage{}
		// 解析加密的 xml
		err = xml.Unmarshal(body, encMsg)
		if err != nil {
			return nil, err
		}
		msg.ToUserName = encMsg.ToUserName
		msg.Encrypt = encMsg.Encrypt

		if !CheckSignature(Token, timestamp, nonce, encMsg.Encrypt, msgSignature) {
			return nil, errors.New("check signature error")
		}

		body, err = DecryptMsg(encMsg.Encrypt, EncodingAESKey, AppId)
		if err != nil {
			return nil, err
		}
		log.Debugf("receive: %s", body)
	}

	// 解析 xml
	err = xml.Unmarshal(body, msg)
	if err != nil {
		return nil, err
	}

	return msg, nil
}

func packReply(reply ReplyMsg, encryptType, timestamp, nonce string) (ret []byte, err error) {
	switch reply.(type) {
	case *ReplyText:
		reply.SetMsgType(MsgTypeText)
	case *ReplyImage:
		reply.SetMsgType(MsgTypeImage)
	case *ReplyVoice:
		reply.SetMsgType(MsgTypeVoice)
	case *ReplyVideo:
		reply.SetMsgType(MsgTypeVideo)
	case *ReplyMusic:
		reply.SetMsgType(MsgTypeMusic)
	case *ReplyNews:
		reply.SetMsgType(MsgTypeNews)
	default:
		panic("unexpected custom message type")
	}

	ret, err = xml.MarshalIndent(reply, "", "  ")
	if err != nil {
		return nil, err
	}
	log.Debugf("replay: %s", ret)

	// 如果接收的消息加密了，那么回复的消息也需要签名加密
	if encryptType == "aes" {
		b64Enc, err := EncryptMsg(ret, EncodingAESKey, AppId)
		if err != nil {
			return nil, err
		}
		encMsg := EncMessage{
			Encrypt:      b64Enc,
			MsgSignature: Signature(Token, timestamp, nonce, b64Enc),
			TimeStamp:    timestamp,
			Nonce:        nonce, // 随机数
		}
		ret, err = xml.MarshalIndent(encMsg, "", "    ")
		if err != nil {
			return nil, err
		}
	}
	return ret, nil
}
<commit_msg>优化：服务端 request 不需要主动调用 r.Body.Close() 方法<commit_after>package weixin

import (
	"encoding/xml"
	"errors"
	"io/ioutil"
	"net/http"
)
import "github.com/omigo/log"

// HandleAccess 接入微信公众平台开发，并接口来自微信服务器的消息
func HandleAccess(w http.ResponseWriter, r *http.Request) {
	log.Debugf("%s", r.URL)

	q := r.URL.Query()
	signature := q.Get("signature")
	timestamp := q.Get("timestamp")
	nonce := q.Get("nonce")

	// 每次都验证 URL，以判断来源是否合法
	if !ValidateURL(Token, timestamp, nonce, signature) {
		http.Error(w, "validate url error, request not from weixin?", http.StatusUnauthorized)
		return
	}

	switch r.Method {
	// 如果是 GET 请求，表示这是接入验证请求
	case "GET":
		w.Write([]byte(q.Get("echostr")))
	case "POST":
		processMessage(w, r)
	default:
		http.Error(w, "only GET or POST method allowed", http.StatusUnauthorized)
	}
}

// 处理所有来自微信的消息，已经验证过 URL 和 Method 了
func processMessage(w http.ResponseWriter, r *http.Request) {
	q := r.URL.Query()
	timestamp := q.Get("timestamp")
	nonce := q.Get("nonce")
	encryptType := q.Get("encrypt_type")
	msgSignature := q.Get("msg_signature")

	// 读取报文
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Error(err)
		http.Error(w, "read body error", http.StatusNotAcceptable)
		return
	}
	log.Debugf("from weixin: %s", body)

	// r.Body.Close() 这里是服务端，不需要主动调用关闭方法，http.Request.Body 有如下注释：
	//
	// Body is the request's body.
	//
	// For client requests a nil body means the request has no
	// body, such as a GET request. The HTTP Client's Transport
	// is responsible for calling the Close method.
	//
	// For server requests the Request Body is always non-nil
	// but will return EOF immediately when no body is present.
	// The Server will close the request body. The ServeHTTP
	// Handler does not need to.

	msg, err := parseBody(encryptType, timestamp, nonce, msgSignature, body)
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// 处理消息
	reply := HandleMessage(msg)

	// 如果返回为 nil，表示不需要回复，结束
	if reply == nil {
		return
	}

	// 如果返回不为 nil，表示需要回复
	ret, err := packReply(reply, encryptType, timestamp, nonce)
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	log.Debugf("to weixin: %s", ret)
	w.Header().Set("Content-Type", "text/xml; charset=utf-8")
	w.Write(ret)
}

func parseBody(encryptType, timestamp, nonce, msgSignature string, body []byte) (msg *Message, err error) {
	msg = &Message{}
	// 如果报文被加密了，先要验签解密
	if encryptType == "aes" {
		encMsg := &EncMessage{}
		// 解析加密的 xml
		err = xml.Unmarshal(body, encMsg)
		if err != nil {
			return nil, err
		}
		msg.ToUserName = encMsg.ToUserName
		msg.Encrypt = encMsg.Encrypt

		if !CheckSignature(Token, timestamp, nonce, encMsg.Encrypt, msgSignature) {
			return nil, errors.New("check signature error")
		}

		body, err = DecryptMsg(encMsg.Encrypt, EncodingAESKey, AppId)
		if err != nil {
			return nil, err
		}
		log.Debugf("receive: %s", body)
	}

	// 解析 xml
	err = xml.Unmarshal(body, msg)
	if err != nil {
		return nil, err
	}

	return msg, nil
}

func packReply(reply ReplyMsg, encryptType, timestamp, nonce string) (ret []byte, err error) {
	switch reply.(type) {
	case *ReplyText:
		reply.SetMsgType(MsgTypeText)
	case *ReplyImage:
		reply.SetMsgType(MsgTypeImage)
	case *ReplyVoice:
		reply.SetMsgType(MsgTypeVoice)
	case *ReplyVideo:
		reply.SetMsgType(MsgTypeVideo)
	case *ReplyMusic:
		reply.SetMsgType(MsgTypeMusic)
	case *ReplyNews:
		reply.SetMsgType(MsgTypeNews)
	default:
		panic("unexpected custom message type")
	}

	ret, err = xml.MarshalIndent(reply, "", "  ")
	if err != nil {
		return nil, err
	}
	log.Debugf("replay: %s", ret)

	// 如果接收的消息加密了，那么回复的消息也需要签名加密
	if encryptType == "aes" {
		b64Enc, err := EncryptMsg(ret, EncodingAESKey, AppId)
		if err != nil {
			return nil, err
		}
		encMsg := EncMessage{
			Encrypt:      b64Enc,
			MsgSignature: Signature(Token, timestamp, nonce, b64Enc),
			TimeStamp:    timestamp,
			Nonce:        nonce, // 随机数
		}
		ret, err = xml.MarshalIndent(encMsg, "", "    ")
		if err != nil {
			return nil, err
		}
	}
	return ret, nil
}
<|endoftext|>


<commit_before>package pollers

import (
	"bytes"
	"github.com/freeformz/shh/mm"
  "os"
  "io"
  "bufio"
	"log"
	"time"
)

type Cpu struct{}

func (poller Cpu) Poll(tick time.Time, measurements chan *mm.Measurement) {
  file, err := os.Open("/proc/stat")
  if err != nil {
    log.Fatal(err)
  }

  reader := bufio.NewReader(file)
  for {
    line, err := reader.ReadBytes('\n')
    if err != nil {
      if err == io.EOF {
        break
      }
      log.Fatal(err)
    }

    if bytes.HasPrefix(line, []byte("cpu")) {
      fields := bytes.Fields(line)
      cpu := string(fields[0])
      measurements <- &mm.Measurement{tick, cpu + ".user", fields[1]}
      measurements <- &mm.Measurement{tick, cpu + ".nice", fields[2]}
      measurements <- &mm.Measurement{tick, cpu + ".system", fields[3]}
      measurements <- &mm.Measurement{tick, cpu + ".idle", fields[4]}
      measurements <- &mm.Measurement{tick, cpu + ".iowait", fields[5]}
      measurements <- &mm.Measurement{tick, cpu + ".irq", fields[6]}
      measurements <- &mm.Measurement{tick, cpu + ".softirq", fields[7]}
      measurements <- &mm.Measurement{tick, cpu + ".steal", fields[8]}
      measurements <- &mm.Measurement{tick, cpu + ".guest", fields[9]}
    }
  }
}

func (poller Cpu) Name() string {
	return "cpu"
}
<commit_msg>go fmt<commit_after>package pollers

import (
	"bufio"
	"bytes"
	"github.com/freeformz/shh/mm"
	"io"
	"log"
	"os"
	"time"
)

type Cpu struct{}

func (poller Cpu) Poll(tick time.Time, measurements chan *mm.Measurement) {
	file, err := os.Open("/proc/stat")
	if err != nil {
		log.Fatal(err)
	}

	reader := bufio.NewReader(file)
	for {
		line, err := reader.ReadBytes('\n')
		if err != nil {
			if err == io.EOF {
				break
			}
			log.Fatal(err)
		}

		if bytes.HasPrefix(line, []byte("cpu")) {
			fields := bytes.Fields(line)
			cpu := string(fields[0])
			measurements <- &mm.Measurement{tick, cpu + ".user", fields[1]}
			measurements <- &mm.Measurement{tick, cpu + ".nice", fields[2]}
			measurements <- &mm.Measurement{tick, cpu + ".system", fields[3]}
			measurements <- &mm.Measurement{tick, cpu + ".idle", fields[4]}
			measurements <- &mm.Measurement{tick, cpu + ".iowait", fields[5]}
			measurements <- &mm.Measurement{tick, cpu + ".irq", fields[6]}
			measurements <- &mm.Measurement{tick, cpu + ".softirq", fields[7]}
			measurements <- &mm.Measurement{tick, cpu + ".steal", fields[8]}
			measurements <- &mm.Measurement{tick, cpu + ".guest", fields[9]}
		}
	}
}

func (poller Cpu) Name() string {
	return "cpu"
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"os/exec"
	"os/signal"
	"path"
	"regexp"

	"github.com/codegangsta/cli"
)

func handleShutdown(l net.Listener) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)

	for {
		select {
		case <-c:
			l.Close()
			os.Exit(0)
		}
	}
}

type commandFn func(stdout, stderr io.Writer) error

func handleConnection(conn net.Conn, fn commandFn) {
	log.Printf("server: handleConnection")
	for {
		bufbytes := make([]byte, 1024)
		nr, err := conn.Read(bufbytes)

		// handle error
		if err == io.EOF {
			log.Printf("server: client connect closed")
			return
		} else if err != nil {
			log.Printf("server read error: %#v", err.Error())
			return
		}

		data := bufbytes[0:nr]
		fmt.Fprintf(conn, "echo: ")
		conn.Write(data)
		log.Printf("server got: %s", data)

		// TODO: allow overriding Stdout with log output
		w := io.MultiWriter(conn, os.Stdout)

		if err := fn(w, w); err != nil {
			log.Printf("callback error: %s", err.Error())
		}
	}
}

// address returns networkk and address that fits
// the use of either net.Dial or net.Listen
func address(listen string) (network, address string) {
	reIP := regexp.MustCompile("^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\:(\\d{2,5}$)")
	rePort := regexp.MustCompile("^(\\d+)$")
	switch {
	case reIP.MatchString(listen):
		network = "tcp"
		address = listen
	case rePort.MatchString(listen):
		network = "tcp"
		address = ":" + listen
	default:
		network = "unix"
		address = listen
	}
	return
}

func actionHook(c *cli.Context) {
	l, err := net.Listen(address(c.String("listen")))
	if err != nil {
		panic(err)
	}

	// cleanly disconnect the socket
	go handleShutdown(l)

	// define git source to update from
	src := gitSource{c.String("remote"), c.String("branch")}

	for {
		conn, err := l.Accept()
		if err != nil {
			panic(err)
		}

		go handleConnection(conn, func(stdout, stderr io.Writer) error {
			if err := gitFetch(src, stdout, stderr); err != nil {
				return err
			}
			if err := gitCheckOut(src, stdout, stderr); err != nil {
				return err
			}
			return nil
		})
	}
}

func actionSetup(c *cli.Context) {
	rootPath, err := gitRootPath()
	if err != nil {
		log.Fatalf("error: %s", rootPath)
	}
	filename := path.Join(rootPath, ".git/hooks/post-checkout")

	// if file not exists, create the file
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		log.Printf("file not exists")
		f, err := os.Create(filename)
		if err != nil {
			log.Fatalf("error: %s", err)
			return
		}
		fmt.Fprintf(f, "#!/bin/sh\n")
		fmt.Fprintf(f, "#\n")
		fmt.Fprintf(f, "# An example hook script to prepare a packed repository for use over\n")
		fmt.Fprintf(f, "# dumb transports.\n")
		fmt.Fprintf(f, "#\n")
		fmt.Fprintf(f, "# To enable this hook, rename this file to \"post-checkout\".\n")
		fmt.Fprintf(f, "exec echo \"checkout completed.\"\n")
		f.Close()

		os.Chmod(filename, 0777)
	}

	cmd := exec.Command("vi", filename)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stdout
	if err := cmd.Run(); err != nil {
		log.Fatalf("error: %s", err)
	}
}
<commit_msg>Server will close conneciton when git checkout done<commit_after>package main

import (
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"os/exec"
	"os/signal"
	"path"
	"regexp"

	"github.com/codegangsta/cli"
)

func handleShutdown(l net.Listener) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)

	for {
		select {
		case <-c:
			l.Close()
			os.Exit(0)
		}
	}
}

type commandFn func(stdout, stderr io.Writer) error

func handleConnection(conn net.Conn, fn commandFn) {
	log.Printf("server: handleConnection")
	defer conn.Close()

	for {
		bufbytes := make([]byte, 1024)
		nr, err := conn.Read(bufbytes)

		// handle error
		if err == io.EOF {
			log.Printf("server: client connect closed")
			return
		} else if err != nil {
			log.Printf("server read error: %#v", err.Error())
			return
		}

		data := bufbytes[0:nr]
		fmt.Fprintf(conn, "echo: ")
		conn.Write(data)
		log.Printf("server got: %s", data)

		// TODO: allow overriding Stdout with log output
		w := io.MultiWriter(conn, os.Stdout)

		if err := fn(w, w); err == io.EOF {
			log.Printf("server: connection terminated")
			return
		} else if err != nil {
			log.Printf("callback error: %s", err.Error())
			return
		}
	}
}

// address returns networkk and address that fits
// the use of either net.Dial or net.Listen
func address(listen string) (network, address string) {
	reIP := regexp.MustCompile("^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\:(\\d{2,5}$)")
	rePort := regexp.MustCompile("^(\\d+)$")
	switch {
	case reIP.MatchString(listen):
		network = "tcp"
		address = listen
	case rePort.MatchString(listen):
		network = "tcp"
		address = ":" + listen
	default:
		network = "unix"
		address = listen
	}
	return
}

func actionHook(c *cli.Context) {
	l, err := net.Listen(address(c.String("listen")))
	if err != nil {
		panic(err)
	}

	// cleanly disconnect the socket
	go handleShutdown(l)

	// define git source to update from
	src := gitSource{c.String("remote"), c.String("branch")}

	for {
		conn, err := l.Accept()
		if err != nil {
			panic(err)
		}

		go handleConnection(conn, func(stdout, stderr io.Writer) error {
			if err := gitFetch(src, stdout, stderr); err != nil {
				return err
			}
			if err := gitCheckOut(src, stdout, stderr); err != nil {
				return err
			}
			return io.EOF
		})
	}
}

func actionSetup(c *cli.Context) {
	rootPath, err := gitRootPath()
	if err != nil {
		log.Fatalf("error: %s", rootPath)
	}
	filename := path.Join(rootPath, ".git/hooks/post-checkout")

	// if file not exists, create the file
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		log.Printf("file not exists")
		f, err := os.Create(filename)
		if err != nil {
			log.Fatalf("error: %s", err)
			return
		}
		fmt.Fprintf(f, "#!/bin/sh\n")
		fmt.Fprintf(f, "#\n")
		fmt.Fprintf(f, "# An example hook script to prepare a packed repository for use over\n")
		fmt.Fprintf(f, "# dumb transports.\n")
		fmt.Fprintf(f, "#\n")
		fmt.Fprintf(f, "# To enable this hook, rename this file to \"post-checkout\".\n")
		fmt.Fprintf(f, "exec echo \"checkout completed.\"\n")
		f.Close()

		os.Chmod(filename, 0777)
	}

	cmd := exec.Command("vi", filename)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stdout
	if err := cmd.Run(); err != nil {
		log.Fatalf("error: %s", err)
	}
}
<|endoftext|>


<commit_before>// 4crossbuild builds the circuit on a remote host (usually with a different OS
// and/or architecture) and ships the result locally.
package main

import (
	"bytes"
	"flag"
	"io/ioutil"
	"path"
	"os"
	"strings"
	"text/template"
)

var (
	flagBinary           = flag.String("binary", "4r", "Preferred name for the resulting runtime binary")
	flagJail             = flag.String("jail", path.Join(os.Getenv("HOME"), "_circuit/build"), "Build jail directory")

	flagAppRepo          = flag.String("app", "", "App repository")
	flagAppPath          = flag.String("appsrc", "", "GOPATH relative to app repository")

	flagPkg              = flag.String("pkg", "", "Package to import for side-effects in circuit runtime binary")

	flagShow             = flag.Bool("show", false, "Show output of underlying build commands")
	flagRebuildGo        = flag.Bool("rebuildgo", false, "Force fetch and rebuild of the Go compiler")

	flagZookeeperInclude = flag.String("zinclude", path.Join(os.Getenv("HOME"), "local/include/c-client-src") , "Zookeeper C headers directory")
	flagZookeeperLib     = flag.String("zlib", path.Join(os.Getenv("HOME"), "local/lib") , "Zookeeper libraries directory")

	flagCircuitRepo      = flag.String("cir", "git@github.com:tumblr/gocircuit.git", "Circuit repository")
	flagCircuitPath      = flag.String("cirsrc", ".", "GOPATH relative to circuit repository")
)

/*
	Build jail layout:
		_build/go
		_build/app/src
		_build/circuit/src
*/

var x struct {
	env       Env
	jail      string
	appPkgs   []string
	binary    string
	zinclude  string
	zlib      string
	goRoot    string
	goBin     string
	goCmd     string
	goPath    map[string]string
}

func main() {
	flag.Parse()

	// Initialize build environment
	x.binary = *flagBinary
	x.env = OSEnv()
	x.jail = *flagJail
	x.appPkgs = []string{*flagPkg}
	x.zinclude = *flagZookeeperInclude
	x.zlib = *flagZookeeperLib
	x.goPath = make(map[string]string)

	// Make jail if not present
	var err error
	if err = os.MkdirAll(x.jail, 0700); err != nil {
		Fatalf("Problem creating build jail (%s)\n", err)
	}

	Errorf("Building Go compiler\n")
	buildGoCompiler(*flagRebuildGo)

	Errorf("Updating circuit repository\n")
	fetchRepo("circuit", *flagCircuitRepo, *flagCircuitPath)

	Errorf("Updating app repository\n")
	fetchRepo("app", *flagAppRepo, *flagAppPath)

	Errorf("Building circuit binaries\n")
	buildCircuit()

	Errorf("Shipping install package\n")
	bundleDir := shipCircuit()
	Errorf("Build successful!\n")

	// Print temporary directory containing bundle
	Printf("%s\n", bundleDir)
}

func shipCircuit() string {
	tmpdir, err := MakeTempDir()
	if err != nil {
		Fatalf("Problem making packaging directory (%s)\n", err)
	}

	// Copy binaries over to shipping directory
	println("+Packaging", x.binary)
	binpkg := binPkg()
	shipFile := path.Join(tmpdir, x.binary)
	if _, err = CopyFile(path.Join(binpkg, x.binary), shipFile); err != nil {
		Fatalf("Problem copying circuit binary (%s)\n", err)
	}
	if err = os.Chmod(shipFile, 0755); err != nil {
		Fatalf("Problem chmod'ing circuit binary (%s)\n", err)
	}

	// zookeeper lib
	println("+Packaging Zookeeper libraries")
	if err = ShellCopyFile(path.Join(x.zlib, "libzookeeper*"), tmpdir + "/"); err != nil {
		Fatalf("Problem copying Zookeeper library files (%s)\n", err)
	}

	return tmpdir
}

// Source code of a circuit runtime executable
const mainSrc = `
package main
import (
	_ "circuit/load"
	{{range .}}
	_ "{{.}}"
	{{end}}
)
func main() {}
`

func binPkg() string {
	return path.Join(x.goPath["circuit"], "src", "autopkg", x.binary)
}

func buildCircuit() {

	// Prepare cgo environment for Zookeeper
	// TODO: Add Zookeeper build step. Don't rely on a prebuilt one.
	x.env.Set("CGO_CFLAGS", "-I" + x.zinclude)
	x.env.Set("CGO_LDFLAGS", "-L" + x.zlib + " -lm -lpthread -lzookeeper_mt")
	defer x.env.Unset("CGO_CFLAGS")
	defer x.env.Unset("CGO_LDFLAGS")

	// Create a package for the runtime executable
	binpkg := binPkg()
	if err := os.MkdirAll(binpkg, 0700); err != nil {
		Fatalf("Problem creating runtime package %s (%s)\n", binpkg, err)
	}

	// Write main.go
	t := template.New("main")
	template.Must(t.Parse(mainSrc))
	var w bytes.Buffer
	if err := t.Execute(&w, x.appPkgs); err != nil {
		Fatalf("Problem preparing main.go (%s)\n", err)
	}
	if err := ioutil.WriteFile(path.Join(binpkg, "main.go"), w.Bytes(), 0664); err != nil {
		Fatalf("Problem writing main.go (%s)\n", err)
	}

	// Build circuit runtime binary
	println("+Building", x.binary)
	if err := Exec(x.env, binpkg, x.goCmd, "build"); err != nil {
		Fatalf("Problem compiling main.go (%s)\n", err)
	}
}

// repoName returns the top-level name of a GIT repository from its URL
// E.g. git@github.com:tumblr/cirapp.git -> cirapp
func repoName(repo string) string {
	if strings.HasSuffix(repo, ".git") {
		repo = repo[:len(repo) - len(".git")]
	}
__For:
	for i := len(repo) - 1; i >= 0; i-- {
		switch repo[i] {
		case ':', '/', '@':
			repo = repo[i + 1:]
			break __For
		}
	}
	return repo
}

func isGitRepo(s string) bool {
	return strings.HasSuffix(s, ".git")
}

/*
	_build/namespace/src/cloned_user_repo/a/src/a/b/c
	[-------------------]					repoSrc
	[------------------------------------]			repoPath
	[===============]					GOPATH, if gopath == ""
	[======================================]		GOPATH, if gopath == "/a"
*/
func fetchRepo(namespace, repo, gopath string) {

	// Make _build/namespace/src
	repoSrc := path.Join(x.jail, path.Join(namespace, "src"))
	if err := os.MkdirAll(repoSrc, 0700); err != nil {
		Fatalf("Problem creating app source path %s (%s)\n", repoSrc, err)
	}
	repoPath := path.Join(repoSrc, repoName(repo))

	// Check whether repo directory exists
	ok, err := Exists(repoPath)
	if err != nil {
		Fatalf("Problem stat'ing %s (%s)", repoPath, err)
	}
	if !ok {
		// If not, clone the source tree
		if err = Exec(nil, repoSrc, "git", "clone", repo); err != nil {
			Fatalf("Problem cloning repo %s (%s)", repo, err)
		}
	} else {
		// If user repo exists in the jail, and a repo URL is given, then pull updates
		if isGitRepo(repo) {
			// Pull changes
			if err = Exec(nil, repoPath, "git", "pull", "origin", "master"); err != nil {
				Fatalf("Problem pulling repo in %s (%s)", repoPath, err)
			}
		}
	}

	// Create build environment for building in this repo
	oldGoPath := x.env.Get("GOPATH")
	var p string
	if gopath == "" {
		p = path.Join(x.jail, namespace)
	} else {
		p = path.Join(repoPath, gopath)
	}
	x.env.Set("GOPATH", p + ":" + oldGoPath)
	x.goPath[namespace] = p
}

func buildGoCompiler(rebuild bool) {
	// Check whether compiler subdirectory directory exists,
	// $jail/go
	ok, err := Exists(path.Join(x.jail, "/go"))
	if err != nil {
		Fatalf("Problem stat'ing %s (%s)", path.Join(x.jail, "/go"), err)
	}
	//Errorf("EEE %#v\n", x.env.Environ())
	if !ok {
		// If not, fetch the source tree
		if err = Exec(x.env, x.jail, "hg", "clone", "-u", "tip", "https://code.google.com/p/go"); err != nil {
			Fatalf("Problem cloning Go repository (%s)", err)
		}
		// Force rebuild
		rebuild = true
	} else {
		if rebuild {
			// Pull changes
			if err = Exec(x.env, path.Join(x.jail, "/go"), "hg", "pull"); err != nil {
				Fatalf("Problem pulling Go repository changes (%s)", err)
			}
			// Update working copy
			if err = Exec(x.env, path.Join(x.jail, "/go"), "hg", "update"); err != nil {
				Fatalf("Problem updating Go repository changes (%s)", err)
			}
		}
	}
	if rebuild {
		// Build Go compiler
		if err = Exec(x.env, path.Join(x.jail, "/go/src"), path.Join(x.jail, "/go/src/all.bash")); err != nil {
			if !IsExitError(err) {
				Fatalf("Problem building Go (%s)", err)
			}
		}
	}

	// Create build environment for building with this compiler
	x.goRoot = path.Join(x.jail, "/go")
	x.goBin = path.Join(x.goRoot, "/bin")
	x.goCmd = path.Join(x.goBin, "go")
	x.env.Set("PATH", x.goBin + ":" + x.env.Get("PATH"))
	x.env.Set("GOROOT", x.goRoot)
}
<commit_msg>fix in build<commit_after>// 4crossbuild builds the circuit on a remote host (usually with a different OS
// and/or architecture) and ships the result locally.
package main

import (
	"bytes"
	"flag"
	"io/ioutil"
	"path"
	"os"
	"strings"
	"text/template"
)

var (
	flagBinary           = flag.String("binary", "4r", "Preferred name for the resulting runtime binary")
	flagJail             = flag.String("jail", path.Join(os.Getenv("HOME"), "_circuit/build"), "Build jail directory")

	flagAppRepo          = flag.String("app", "", "App repository")
	flagAppPath          = flag.String("appsrc", "", "GOPATH relative to app repository")

	flagPkg              = flag.String("pkg", "", "Package to import for side-effects in circuit runtime binary")

	flagShow             = flag.Bool("show", false, "Show output of underlying build commands")
	flagRebuildGo        = flag.Bool("rebuildgo", false, "Force fetch and rebuild of the Go compiler")

	flagZookeeperInclude = flag.String("zinclude", path.Join(os.Getenv("HOME"), "local/include/c-client-src") , "Zookeeper C headers directory")
	flagZookeeperLib     = flag.String("zlib", path.Join(os.Getenv("HOME"), "local/lib") , "Zookeeper libraries directory")

	flagCircuitRepo      = flag.String("cir", "git@github.com:tumblr/gocircuit.git", "Circuit repository")
	flagCircuitPath      = flag.String("cirsrc", ".", "GOPATH relative to circuit repository")
)

/*
	Build jail layout:
		_build/go
		_build/app/src
		_build/circuit/src
*/

var x struct {
	env       Env
	jail      string
	appPkgs   []string
	binary    string
	zinclude  string
	zlib      string
	goRoot    string
	goBin     string
	goCmd     string
	goPath    map[string]string
}

func main() {
	flag.Parse()

	// Initialize build environment
	x.binary = *flagBinary
	x.env = OSEnv()
	x.jail = *flagJail
	x.appPkgs = []string{*flagPkg}
	x.zinclude = *flagZookeeperInclude
	x.zlib = *flagZookeeperLib
	x.goPath = make(map[string]string)

	// Make jail if not present
	var err error
	if err = os.MkdirAll(x.jail, 0700); err != nil {
		Fatalf("Problem creating build jail (%s)\n", err)
	}

	Errorf("Building Go compiler\n")
	buildGoCompiler(*flagRebuildGo)

	Errorf("Updating circuit repository\n")
	fetchRepo("circuit", *flagCircuitRepo, *flagCircuitPath)

	Errorf("Updating app repository\n")
	fetchRepo("app", *flagAppRepo, *flagAppPath)

	Errorf("Building circuit binaries\n")
	buildCircuit()

	Errorf("Shipping install package\n")
	bundleDir := shipCircuit()
	Errorf("Build successful!\n")

	// Print temporary directory containing bundle
	Printf("%s\n", bundleDir)
}

func shipCircuit() string {
	tmpdir, err := MakeTempDir()
	if err != nil {
		Fatalf("Problem making packaging directory (%s)\n", err)
	}

	// Copy binaries over to shipping directory
	println("+Packaging", x.binary)
	binpkg := binPkg()
	shipFile := path.Join(tmpdir, x.binary)
	if _, err = CopyFile(path.Join(binpkg, x.binary), shipFile); err != nil {
		Fatalf("Problem copying circuit binary (%s)\n", err)
	}
	if err = os.Chmod(shipFile, 0755); err != nil {
		Fatalf("Problem chmod'ing circuit binary (%s)\n", err)
	}

	// zookeeper lib
	println("+Packaging Zookeeper libraries")
	if err = ShellCopyFile(path.Join(x.zlib, "libzookeeper*"), tmpdir + "/"); err != nil {
		Fatalf("Problem copying Zookeeper library files (%s)\n", err)
	}

	return tmpdir
}

// Source code of a circuit runtime executable
const mainSrc = `
package main
import (
	_ "circuit/load"
	{{range .}}
	_ "{{.}}"
	{{end}}
)
func main() {}
`

func binPkg() string {
	return path.Join(x.goPath["circuit"], "src", "autopkg", x.binary)
}

func buildCircuit() {

	// Prepare cgo environment for Zookeeper
	// TODO: Add Zookeeper build step. Don't rely on a prebuilt one.
	x.env.Set("CGO_CFLAGS", "-I" + x.zinclude)
	x.env.Set("CGO_LDFLAGS", "-L" + x.zlib + " -lm -lpthread -lzookeeper_mt")
	defer x.env.Unset("CGO_CFLAGS")
	defer x.env.Unset("CGO_LDFLAGS")

	// Create a package for the runtime executable
	binpkg := binPkg()
	if err := os.MkdirAll(binpkg, 0700); err != nil {
		Fatalf("Problem creating runtime package %s (%s)\n", binpkg, err)
	}

	// Write main.go
	t := template.New("main")
	template.Must(t.Parse(mainSrc))
	var w bytes.Buffer
	if err := t.Execute(&w, x.appPkgs); err != nil {
		Fatalf("Problem preparing main.go (%s)\n", err)
	}
	if err := ioutil.WriteFile(path.Join(binpkg, "main.go"), w.Bytes(), 0664); err != nil {
		Fatalf("Problem writing main.go (%s)\n", err)
	}

	// Build circuit runtime binary
	println("+Building", x.binary)
	if err := Exec(x.env, binpkg, x.goCmd, "build"); err != nil {
		Fatalf("Problem compiling main.go (%s)\n", err)
	}
}

// repoName returns the top-level name of a GIT repository from its URL
// E.g. git@github.com:tumblr/cirapp.git -> cirapp
func repoName(repo string) string {
	if strings.HasSuffix(repo, ".git") {
		repo = repo[:len(repo) - len(".git")]
	}
__For:
	for i := len(repo) - 1; i >= 0; i-- {
		switch repo[i] {
		case ':', '/', '@':
			repo = repo[i + 1:]
			break __For
		}
	}
	return repo
}

/*
	_build/namespace/src/cloned_user_repo/a/src/a/b/c
	[-------------------]					repoSrc
	[------------------------------------]			repoPath
	[===============]					GOPATH, if gopath == ""
	[======================================]		GOPATH, if gopath == "/a"
*/
func fetchRepo(namespace, repo, gopath string) {

	// Make _build/namespace/src
	repoSrc := path.Join(x.jail, path.Join(namespace, "src"))
	if err := os.MkdirAll(repoSrc, 0700); err != nil {
		Fatalf("Problem creating app source path %s (%s)\n", repoSrc, err)
	}
	repoPath := path.Join(repoSrc, repoName(repo))

	// Check whether repo directory exists
	ok, err := Exists(repoPath)
	if err != nil {
		Fatalf("Problem stat'ing %s (%s)", repoPath, err)
	}
	if !ok {
		// If not, clone the source tree
		if err = Exec(nil, repoSrc, "git", "clone", repo); err != nil {
			Fatalf("Problem cloning repo %s (%s)", repo, err)
		}
	} else {
		// Pull changes
		if err = Exec(nil, repoPath, "git", "pull", "origin", "master"); err != nil {
			Fatalf("Problem pulling repo in %s (%s)", repoPath, err)
		}
	}

	// Create build environment for building in this repo
	oldGoPath := x.env.Get("GOPATH")
	var p string
	if gopath == "" {
		p = path.Join(x.jail, namespace)
	} else {
		p = path.Join(repoPath, gopath)
	}
	x.env.Set("GOPATH", p + ":" + oldGoPath)
	x.goPath[namespace] = p
}

func buildGoCompiler(rebuild bool) {
	// Check whether compiler subdirectory directory exists,
	// $jail/go
	ok, err := Exists(path.Join(x.jail, "/go"))
	if err != nil {
		Fatalf("Problem stat'ing %s (%s)", path.Join(x.jail, "/go"), err)
	}
	//Errorf("EEE %#v\n", x.env.Environ())
	if !ok {
		// If not, fetch the source tree
		if err = Exec(x.env, x.jail, "hg", "clone", "-u", "tip", "https://code.google.com/p/go"); err != nil {
			Fatalf("Problem cloning Go repository (%s)", err)
		}
		// Force rebuild
		rebuild = true
	} else {
		if rebuild {
			// Pull changes
			if err = Exec(x.env, path.Join(x.jail, "/go"), "hg", "pull"); err != nil {
				Fatalf("Problem pulling Go repository changes (%s)", err)
			}
			// Update working copy
			if err = Exec(x.env, path.Join(x.jail, "/go"), "hg", "update"); err != nil {
				Fatalf("Problem updating Go repository changes (%s)", err)
			}
		}
	}
	if rebuild {
		// Build Go compiler
		if err = Exec(x.env, path.Join(x.jail, "/go/src"), path.Join(x.jail, "/go/src/all.bash")); err != nil {
			if !IsExitError(err) {
				Fatalf("Problem building Go (%s)", err)
			}
		}
	}

	// Create build environment for building with this compiler
	x.goRoot = path.Join(x.jail, "/go")
	x.goBin = path.Join(x.goRoot, "/bin")
	x.goCmd = path.Join(x.goBin, "go")
	x.env.Set("PATH", x.goBin + ":" + x.env.Get("PATH"))
	x.env.Set("GOROOT", x.goRoot)
}
<|endoftext|>


<commit_before>package activitystreams

// Actor Types
const (
	ApplicationType  ActivityVocabularyType = "Application"
	GroupType        ActivityVocabularyType = "Group"
	OrganizationType ActivityVocabularyType = "Organization"
	PersonType       ActivityVocabularyType = "Person"
	ServiceType      ActivityVocabularyType = "Service"
)

var validActorTypes = [...]ActivityVocabularyType{
	ApplicationType,
	GroupType,
	OrganizationType,
	PersonType,
	ServiceType,
}

// Endpoints a json object which maps additional (typically server/domain-wide)
// endpoints which may be useful either for this actor or someone referencing this actor.
// This mapping may be nested inside the actor document as the value or may be a link to
// a JSON-LD document with these properties.
type Endpoints struct {
	// UploadMedia Upload endpoint URI for this user for binary data.
	UploadMedia Item `jsonld:"uploadMedia,omitempty"`
	// OauthAuthorizationEndpoint Endpoint URI so this actor's clients may access remote ActivityStreams objects which require authentication
	// to access. To use this endpoint, the client posts an x-www-form-urlencoded id parameter with the value being
	// the id of the requested ActivityStreams object.
	OauthAuthorizationEndpoint Item `jsonld:"oauthAuthorizationEndpoint,omitempty"`
	// OauthTokenEndpoint If OAuth 2.0 bearer tokens [RFC6749] [RFC6750] are being used for authenticating client to server interactions,
	// this endpoint specifies a URI at which a browser-authenticated user may obtain a new authorization grant.
	OauthTokenEndpoint Item `jsonld:"oauthTokenEndpoint,omitempty"`
	// ProvideClientKey  If OAuth 2.0 bearer tokens [RFC6749] [RFC6750] are being used for authenticating client to server interactions,
	// this endpoint specifies a URI at which a client may acquire an access token.
	ProvideClientKey Item `jsonld:"provideClientKey,omitempty"`
	// SignClientKey If Linked Data Signatures and HTTP Signatures are being used for authentication and authorization,
	// this endpoint specifies a URI at which browser-authenticated users may authorize a client's public
	// key for client to server interactions.
	SignClientKey Item `jsonld:"signClientKey,omitempty"`
	// SharedInbox If Linked Data Signatures and HTTP Signatures are being used for authentication and authorization,
	// this endpoint specifies a URI at which a client key may be signed by the actor's key for a time window to
	// act on behalf of the actor in interacting with foreign servers.
	SharedInbox Item `jsonld:"sharedInbox,omitempty"`
}

type WillAct interface {
	GetActor() Actor
}

// Actor is generally one of the ActivityStreams Actor Types, but they don't have to be.
// For example, a Profile object might be used as an actor, or a type from an ActivityStreams extension.
// Actors are retrieved like any other Object in ActivityPub.
// Like other ActivityStreams objects, actors have an id, which is a URI.
type Actor Item

type (
	// Application describes a software application.
	Application = Object

	// Group represents a formal or informal collective of Actors.
	Group = Object

	// Organization represents an organization.
	Organization = Object

	// Person represents an individual person.
	Person = Object

	// Service represents a service of any kind.
	Service = Object
)

// ValidActorType validates the passed type against the valid actor types
func ValidActorType(typ ActivityVocabularyType) bool {
	for _, v := range validActorTypes {
		if v == typ {
			return true
		}
	}
	return false
}

// ActorNew initializes an Actor type actor
func ActorNew(id ObjectID, typ ActivityVocabularyType) *Object {
	if !ValidActorType(typ) {
		typ = ActorType
	}

	a := Object{ID: id, Type: typ}
	a.Name = NaturalLanguageValueNew()
	a.Content = NaturalLanguageValueNew()
	a.Summary = NaturalLanguageValueNew()

	return &a
}

// ApplicationNew initializes an Application type actor
func ApplicationNew(id ObjectID) *Application {
	a := ActorNew(id, ApplicationType)
	o := Application(*a)
	return &o
}

// GroupNew initializes a Group type actor
func GroupNew(id ObjectID) *Group {
	a := ActorNew(id, GroupType)
	o := Group(*a)
	return &o
}

// OrganizationNew initializes an Organization type actor
func OrganizationNew(id ObjectID) *Organization {
	a := ActorNew(id, OrganizationType)
	o := Organization(*a)
	return &o
}

// PersonNew initializes a Person type actor
func PersonNew(id ObjectID) *Person {
	a := ActorNew(id, PersonType)
	o := Person(*a)
	return &o
}

// ServiceNew initializes a Service type actor
func ServiceNew(id ObjectID) *Service {
	a := ActorNew(id, ServiceType)
	o := Service(*a)
	return &o
}
<commit_msg>Making Actor types aliases of Object<commit_after>package activitystreams

// Actor Types
const (
	ApplicationType  ActivityVocabularyType = "Application"
	GroupType        ActivityVocabularyType = "Group"
	OrganizationType ActivityVocabularyType = "Organization"
	PersonType       ActivityVocabularyType = "Person"
	ServiceType      ActivityVocabularyType = "Service"
)

var validActorTypes = [...]ActivityVocabularyType{
	ApplicationType,
	GroupType,
	OrganizationType,
	PersonType,
	ServiceType,
}

// Actor is generally one of the ActivityStreams Actor Types, but they don't have to be.
// For example, a Profile object might be used as an actor, or a type from an ActivityStreams extension.
// Actors are retrieved like any other Object in ActivityPub.
// Like other ActivityStreams objects, actors have an id, which is a URI.
type Actor Item

type (
	// Application describes a software application.
	Application = Object

	// Group represents a formal or informal collective of Actors.
	Group = Object

	// Organization represents an organization.
	Organization = Object

	// Person represents an individual person.
	Person = Object

	// Service represents a service of any kind.
	Service = Object
)

// ValidActorType validates the passed type against the valid actor types
func ValidActorType(typ ActivityVocabularyType) bool {
	for _, v := range validActorTypes {
		if v == typ {
			return true
		}
	}
	return false
}

// ActorNew initializes an Actor type actor
func ActorNew(id ObjectID, typ ActivityVocabularyType) *Object {
	if !ValidActorType(typ) {
		typ = ActorType
	}

	a := Object{ID: id, Type: typ}
	a.Name = NaturalLanguageValueNew()
	a.Content = NaturalLanguageValueNew()
	a.Summary = NaturalLanguageValueNew()

	return &a
}

// ApplicationNew initializes an Application type actor
func ApplicationNew(id ObjectID) *Application {
	a := ActorNew(id, ApplicationType)
	o := Application(*a)
	return &o
}

// GroupNew initializes a Group type actor
func GroupNew(id ObjectID) *Group {
	a := ActorNew(id, GroupType)
	o := Group(*a)
	return &o
}

// OrganizationNew initializes an Organization type actor
func OrganizationNew(id ObjectID) *Organization {
	a := ActorNew(id, OrganizationType)
	o := Organization(*a)
	return &o
}

// PersonNew initializes a Person type actor
func PersonNew(id ObjectID) *Person {
	a := ActorNew(id, PersonType)
	o := Person(*a)
	return &o
}

// ServiceNew initializes a Service type actor
func ServiceNew(id ObjectID) *Service {
	a := ActorNew(id, ServiceType)
	o := Service(*a)
	return &o
}
<|endoftext|>


<commit_before>package integration

import (
	"strings"
	"testing"
)

func TestExecPS(t *testing.T) {
	if testing.Short() {
		return
	}

	rootfs, err := newRootFs()
	if err != nil {
		t.Fatal(err)
	}
	defer remove(rootfs)

	config := newTemplateConfig(rootfs)
	buffers, exitCode, err := runContainer(config, "", "ps")
	if err != nil {
		t.Fatal(err)
	}

	if exitCode != 0 {
		t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
	}

	lines := strings.Split(buffers.Stdout.String(), "\n")
	if len(lines) < 2 {
		t.Fatalf("more than one process running for output %q", buffers.Stdout.String())
	}
	expected := `1 root     ps`
	actual := strings.Trim(lines[1], "\n ")
	if actual != expected {
		t.Fatalf("expected output %q but received %q", expected, actual)
	}
}
<commit_msg>Add test for IPC host sharing<commit_after>package integration

import (
	"os"
	"strings"
	"testing"
)

func TestExecPS(t *testing.T) {
	if testing.Short() {
		return
	}

	rootfs, err := newRootFs()
	if err != nil {
		t.Fatal(err)
	}
	defer remove(rootfs)

	config := newTemplateConfig(rootfs)
	buffers, exitCode, err := runContainer(config, "", "ps")
	if err != nil {
		t.Fatal(err)
	}

	if exitCode != 0 {
		t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
	}

	lines := strings.Split(buffers.Stdout.String(), "\n")
	if len(lines) < 2 {
		t.Fatalf("more than one process running for output %q", buffers.Stdout.String())
	}
	expected := `1 root     ps`
	actual := strings.Trim(lines[1], "\n ")
	if actual != expected {
		t.Fatalf("expected output %q but received %q", expected, actual)
	}
}

func TestIPCHost(t *testing.T) {
	if testing.Short() {
		return
	}

	rootfs, err := newRootFs()
	if err != nil {
		t.Fatal(err)
	}
	defer remove(rootfs)

	l, err := os.Readlink("/proc/1/ns/ipc")
	if err != nil {
		t.Fatal(err)
	}

	config := newTemplateConfig(rootfs)
	config.Namespaces["NEWIPC"] = false
	buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/ipc")
	if err != nil {
		t.Fatal(err)
	}

	if exitCode != 0 {
		t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
	}

	if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual != l {
		t.Fatalf("ipc link not equal to host link %q %q", actual, l)
	}
}
<|endoftext|>


<commit_before>// Copyright © 2017 Circonus, Inc. <support@circonus.com>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

package plugins

import (
	"context"
	"encoding/json"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/circonus-labs/circonus-agent/api"
	"github.com/circonus-labs/circonus-agent/internal/config"
	cgm "github.com/circonus-labs/circonus-gometrics/v3"
	"github.com/maier/go-appstats"
	"github.com/pkg/errors"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"github.com/spf13/viper"
)

// Plugins defines plugin manager
type Plugins struct {
	active        map[string]*plugin
	plugList      []string
	ctx           context.Context
	logger        zerolog.Logger
	pluginDir     string
	reservedNames map[string]bool
	running       bool
	sync.RWMutex
}

// Plugin defines a specific plugin
type plugin struct {
	cmd             *exec.Cmd
	command         string
	ctx             context.Context
	id              string
	instanceArgs    []string
	instanceID      string
	lastError       error
	lastRunDuration time.Duration
	currStart       time.Time
	lastStart       time.Time
	lastEnd         time.Time
	logger          zerolog.Logger
	metrics         *cgm.Metrics
	name            string
	prevMetrics     *cgm.Metrics
	runDir          string
	running         bool
	runTTL          time.Duration
	baseTags        []string
	sync.Mutex
}

const (
	fieldDelimiter  = "\t"
	metricDelimiter = "`"
	nullMetricValue = "[[null]]"
)

// New returns a new instance of the plugins manager
func New(ctx context.Context, defaultPluginPath string) (*Plugins, error) {
	p := Plugins{
		ctx:           ctx,
		running:       false,
		logger:        log.With().Str("pkg", "plugins").Logger(),
		reservedNames: map[string]bool{"prom": true, "write": true, "statsd": true},
		active:        make(map[string]*plugin),
	}

	pluginDir := viper.GetString(config.KeyPluginDir)
	pluginList := viper.GetStringSlice(config.KeyPluginList)

	// if neither specified, use default plugin directory
	if pluginDir == "" && len(pluginList) == 0 {
		pluginDir = defaultPluginPath
	}

	if pluginDir != "" && len(pluginList) > 0 {
		return nil, errors.New("invalid configuration cannot specifiy plugin-dir AND plugin-list")
	}

	if pluginDir == "" {
		for _, cmdSpec := range pluginList {
			if _, err := os.Stat(cmdSpec); err != nil {
				p.logger.Warn().Err(err).Str("cmd", cmdSpec).Msg("skipping")
			}
		}
		return &p, nil
	}

	errMsg := "Invalid plugin directory"
	absDir, err := filepath.Abs(pluginDir)
	if err != nil {
		return nil, errors.Wrap(err, errMsg)
	}

	pluginDir = absDir

	fi, err := os.Stat(pluginDir)
	if err != nil {
		if os.IsNotExist(err) {
			p.logger.Warn().Err(err).Str("path", pluginDir).Msg("not found, ignoring")
			p.pluginDir = ""
			return &p, nil
		}
		return nil, errors.Wrap(err, errMsg)
	}

	if !fi.Mode().IsDir() {
		return nil, errors.Errorf(errMsg+" (%s) not a directory", pluginDir)
	}

	// also try opening, to verify permissions
	// if last dir on path is not accessible to user, stat doesn't return EPERM
	f, err := os.Open(pluginDir)
	if err != nil {
		return nil, errors.Wrap(err, errMsg)
	}
	f.Close()

	p.pluginDir = pluginDir

	return &p, nil
}

// Flush plugin metrics
func (p *Plugins) Flush(pluginName string) *cgm.Metrics {
	p.RLock()
	defer p.RUnlock()

	appstats.SetString("plugins.last_flush", time.Now().String())
	// appstats.MapSet("plugins", "last_flush", time.Now())

	metrics := cgm.Metrics{}

	for pluginID, plug := range p.active {
		if pluginName == "" || // all plugins
			pluginID == pluginName || // specific plugin
			strings.HasPrefix(pluginID, pluginName+metricDelimiter) { // specific plugin with instances

			m := plug.drain()
			for mn, mv := range *m {
				metrics[pluginID+metricDelimiter+mn] = mv
			}
		}
	}

	return &metrics
}

// Stop any long running plugins
func (p *Plugins) Stop() error {
	p.logger.Info().Msg("stopping")
	return nil
}

// Run one or all plugins
func (p *Plugins) Run(pluginName string) error {
	p.Lock()

	if p.running {
		msg := "plugin run already in progress"
		p.logger.Info().Msg(msg)
		p.Unlock()
		return errors.Errorf(msg)
	}

	if len(p.plugList) == 0 {
		p.plugList = make([]string, len(p.active))
		i := 0
		for name := range p.active {
			p.plugList[i] = name
			i++
		}
	}

	start := time.Now()
	appstats.SetString("plugins.last_run_start", start.String())
	// appstats.MapSet("plugins", "last_run_start", start)

	p.running = true
	p.Unlock()

	var wg sync.WaitGroup

	if pluginName != "" {
		numFound := 0
		for pluginID, pluginRef := range p.active {
			if pluginID == pluginName || // specific plugin
				strings.HasPrefix(pluginID, pluginName+"`") { // specific plugin with instances
				numFound++
				wg.Add(1)
				p.logger.Debug().Str("id", pluginID).Msg("running")
				go func(id string, plug *plugin) {
					plug.exec()
					plug.logger.Debug().Str("id", id).Str("duration", time.Since(start).String()).Msg("done")
					wg.Done()
				}(pluginID, pluginRef)
			}
		}
		if numFound == 0 {
			p.logger.Error().Str("id", pluginName).Msg("invalid/unknown")
			p.running = false
			return errors.Errorf("invalid plugin (%s)", pluginName)
		}
	} else {
		p.logger.Debug().Str("plugin(s)", strings.Join(p.plugList, ",")).Msg("running")
		for pluginID, pluginRef := range p.active {
			wg.Add(1)
			go func(id string, plug *plugin) {
				plug.exec()
				plug.logger.Debug().Str("id", id).Str("duration", time.Since(start).String()).Msg("done")
				wg.Done()
			}(pluginID, pluginRef)
		}
	}

	wg.Wait()

	appstats.SetString("plugins.last_run_end", time.Now().String())
	appstats.SetString("plugins.last_run_duration", time.Since(start).String())
	// appstats.MapSet("plugins", "last_run_end", time.Now())
	// appstats.MapSet("plugins", "last_run_duration", time.Since(start))

	p.Lock()
	p.running = false
	p.logger.Debug().Str("duration", time.Since(start).String()).Msg("all plugins done")
	p.Unlock()

	return nil
}

// IsValid determines if a specific plugin is valid
func (p *Plugins) IsValid(pluginName string) bool {
	if pluginName == "" {
		return false
	}

	p.RLock()
	defer p.RUnlock()

	for pluginID := range p.active {
		// specific plugin       plugin with instances
		if pluginID == pluginName || strings.HasPrefix(pluginID, pluginName+"`") {
			return true
		}
	}

	return false
}

// IsInternal checks to see if the plugin is one of the internal plugins (write|statsd)
func (p *Plugins) IsInternal(pluginName string) bool {
	if pluginName == "" {
		return false
	}
	_, reserved := p.reservedNames[pluginName]

	return reserved
}

// Inventory returns list of active plugins
func (p *Plugins) Inventory() []byte {
	p.Lock()
	defer p.Unlock()
	inventory := api.Inventory{}
	for id, plug := range p.active {
		plug.Lock()
		pinfo := api.Plugin{
			ID:              id,
			Name:            plug.id,
			Instance:        plug.instanceID,
			Command:         plug.command,
			Args:            plug.instanceArgs,
			LastRunStart:    plug.lastStart.Format(time.RFC3339Nano),
			LastRunEnd:      plug.lastEnd.Format(time.RFC3339Nano),
			LastRunDuration: plug.lastRunDuration.String(),
		}
		if plug.lastError != nil {
			pinfo.LastError = plug.lastError.Error()
		}
		plug.Unlock()
		inventory = append(inventory, pinfo)
	}
	data, err := json.Marshal(inventory)
	if err != nil {
		p.logger.Fatal().Err(err).Msg("inventory -> json")
	}
	return data
}
<commit_msg>upd: short-circuit no active plugins (emit dbg msg)<commit_after>// Copyright © 2017 Circonus, Inc. <support@circonus.com>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

package plugins

import (
	"context"
	"encoding/json"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/circonus-labs/circonus-agent/api"
	"github.com/circonus-labs/circonus-agent/internal/config"
	cgm "github.com/circonus-labs/circonus-gometrics/v3"
	"github.com/maier/go-appstats"
	"github.com/pkg/errors"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"github.com/spf13/viper"
)

// Plugins defines plugin manager
type Plugins struct {
	active        map[string]*plugin
	plugList      []string
	ctx           context.Context
	logger        zerolog.Logger
	pluginDir     string
	reservedNames map[string]bool
	running       bool
	sync.RWMutex
}

// Plugin defines a specific plugin
type plugin struct {
	cmd             *exec.Cmd
	command         string
	ctx             context.Context
	id              string
	instanceArgs    []string
	instanceID      string
	lastError       error
	lastRunDuration time.Duration
	currStart       time.Time
	lastStart       time.Time
	lastEnd         time.Time
	logger          zerolog.Logger
	metrics         *cgm.Metrics
	name            string
	prevMetrics     *cgm.Metrics
	runDir          string
	running         bool
	runTTL          time.Duration
	baseTags        []string
	sync.Mutex
}

const (
	fieldDelimiter  = "\t"
	metricDelimiter = "`"
	nullMetricValue = "[[null]]"
)

// New returns a new instance of the plugins manager
func New(ctx context.Context, defaultPluginPath string) (*Plugins, error) {
	p := Plugins{
		ctx:           ctx,
		running:       false,
		logger:        log.With().Str("pkg", "plugins").Logger(),
		reservedNames: map[string]bool{"prom": true, "write": true, "statsd": true},
		active:        make(map[string]*plugin),
	}

	pluginDir := viper.GetString(config.KeyPluginDir)
	pluginList := viper.GetStringSlice(config.KeyPluginList)

	// if neither specified, use default plugin directory
	if pluginDir == "" && len(pluginList) == 0 {
		pluginDir = defaultPluginPath
	}

	if pluginDir != "" && len(pluginList) > 0 {
		return nil, errors.New("invalid configuration cannot specifiy plugin-dir AND plugin-list")
	}

	if pluginDir == "" {
		for _, cmdSpec := range pluginList {
			if _, err := os.Stat(cmdSpec); err != nil {
				p.logger.Warn().Err(err).Str("cmd", cmdSpec).Msg("skipping")
			}
		}
		return &p, nil
	}

	errMsg := "Invalid plugin directory"
	absDir, err := filepath.Abs(pluginDir)
	if err != nil {
		return nil, errors.Wrap(err, errMsg)
	}

	pluginDir = absDir

	fi, err := os.Stat(pluginDir)
	if err != nil {
		if os.IsNotExist(err) {
			p.logger.Warn().Err(err).Str("path", pluginDir).Msg("not found, ignoring")
			p.pluginDir = ""
			return &p, nil
		}
		return nil, errors.Wrap(err, errMsg)
	}

	if !fi.Mode().IsDir() {
		return nil, errors.Errorf(errMsg+" (%s) not a directory", pluginDir)
	}

	// also try opening, to verify permissions
	// if last dir on path is not accessible to user, stat doesn't return EPERM
	f, err := os.Open(pluginDir)
	if err != nil {
		return nil, errors.Wrap(err, errMsg)
	}
	f.Close()

	p.pluginDir = pluginDir

	return &p, nil
}

// Flush plugin metrics
func (p *Plugins) Flush(pluginName string) *cgm.Metrics {
	p.RLock()
	defer p.RUnlock()

	appstats.SetString("plugins.last_flush", time.Now().String())
	// appstats.MapSet("plugins", "last_flush", time.Now())

	metrics := cgm.Metrics{}

	for pluginID, plug := range p.active {
		if pluginName == "" || // all plugins
			pluginID == pluginName || // specific plugin
			strings.HasPrefix(pluginID, pluginName+metricDelimiter) { // specific plugin with instances

			m := plug.drain()
			for mn, mv := range *m {
				metrics[pluginID+metricDelimiter+mn] = mv
			}
		}
	}

	return &metrics
}

// Stop any long running plugins
func (p *Plugins) Stop() error {
	p.logger.Info().Msg("stopping")
	return nil
}

// Run one or all plugins
func (p *Plugins) Run(pluginName string) error {
	p.Lock()

	if p.running {
		msg := "plugin run already in progress"
		p.logger.Info().Msg(msg)
		p.Unlock()
		return errors.Errorf(msg)
	}

	if len(p.active) == 0 {
		p.logger.Debug().Msg("no active plugins, skipping run")
		p.Unlock()
		return nil
	}

	if len(p.plugList) == 0 {
		p.plugList = make([]string, len(p.active))
		i := 0
		for name := range p.active {
			p.plugList[i] = name
			i++
		}
	}

	start := time.Now()
	appstats.SetString("plugins.last_run_start", start.String())
	// appstats.MapSet("plugins", "last_run_start", start)

	p.running = true
	p.Unlock()

	var wg sync.WaitGroup

	if pluginName != "" {
		numFound := 0
		for pluginID, pluginRef := range p.active {
			if pluginID == pluginName || // specific plugin
				strings.HasPrefix(pluginID, pluginName+"`") { // specific plugin with instances
				numFound++
				wg.Add(1)
				p.logger.Debug().Str("id", pluginID).Msg("running")
				go func(id string, plug *plugin) {
					plug.exec()
					plug.logger.Debug().Str("id", id).Str("duration", time.Since(start).String()).Msg("done")
					wg.Done()
				}(pluginID, pluginRef)
			}
		}
		if numFound == 0 {
			p.logger.Error().Str("id", pluginName).Msg("invalid/unknown")
			p.running = false
			return errors.Errorf("invalid plugin (%s)", pluginName)
		}
	} else {
		p.logger.Debug().Str("plugin(s)", strings.Join(p.plugList, ",")).Msg("running")
		for pluginID, pluginRef := range p.active {
			wg.Add(1)
			go func(id string, plug *plugin) {
				plug.exec()
				plug.logger.Debug().Str("id", id).Str("duration", time.Since(start).String()).Msg("done")
				wg.Done()
			}(pluginID, pluginRef)
		}
	}

	wg.Wait()

	appstats.SetString("plugins.last_run_end", time.Now().String())
	appstats.SetString("plugins.last_run_duration", time.Since(start).String())
	// appstats.MapSet("plugins", "last_run_end", time.Now())
	// appstats.MapSet("plugins", "last_run_duration", time.Since(start))

	p.Lock()
	p.running = false
	p.logger.Debug().Str("duration", time.Since(start).String()).Msg("all plugins done")
	p.Unlock()

	return nil
}

// IsValid determines if a specific plugin is valid
func (p *Plugins) IsValid(pluginName string) bool {
	if pluginName == "" {
		return false
	}

	p.RLock()
	defer p.RUnlock()

	for pluginID := range p.active {
		// specific plugin       plugin with instances
		if pluginID == pluginName || strings.HasPrefix(pluginID, pluginName+"`") {
			return true
		}
	}

	return false
}

// IsInternal checks to see if the plugin is one of the internal plugins (write|statsd)
func (p *Plugins) IsInternal(pluginName string) bool {
	if pluginName == "" {
		return false
	}
	_, reserved := p.reservedNames[pluginName]

	return reserved
}

// Inventory returns list of active plugins
func (p *Plugins) Inventory() []byte {
	p.Lock()
	defer p.Unlock()
	inventory := api.Inventory{}
	for id, plug := range p.active {
		plug.Lock()
		pinfo := api.Plugin{
			ID:              id,
			Name:            plug.id,
			Instance:        plug.instanceID,
			Command:         plug.command,
			Args:            plug.instanceArgs,
			LastRunStart:    plug.lastStart.Format(time.RFC3339Nano),
			LastRunEnd:      plug.lastEnd.Format(time.RFC3339Nano),
			LastRunDuration: plug.lastRunDuration.String(),
		}
		if plug.lastError != nil {
			pinfo.LastError = plug.lastError.Error()
		}
		plug.Unlock()
		inventory = append(inventory, pinfo)
	}
	data, err := json.Marshal(inventory)
	if err != nil {
		p.logger.Fatal().Err(err).Msg("inventory -> json")
	}
	return data
}
<|endoftext|>


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

package tree

import (
	"fmt"
	"rand"
	"time"
)

func init() {
	rand.Seed(time.Nanoseconds())
}

// A Tree is a binary tree with integer values.
type Tree struct {
	Left  *Tree
	Value int
	Right *Tree
}

// New returns a new, random binary tree holding the values k, 2k, ..., 10k.
func New(k int) *Tree {
	var t *Tree
	for _, v := range rand.Perm(10) {
		t = insert(t, (1+v)*k)
	}
	return t
}

func insert(t *Tree, v int) *Tree {
	if t == nil {
		return &Tree{nil, v, nil}
	}
	if v < t.Value {
		t.Left = insert(t.Left, v)
		return t
	}
	t.Right = insert(t.Right, v)
	return t
}

func (t *Tree) String() string {
	if t == nil {
		return "()"
	}
	s := ""
	if t.Left != nil {
		s += t.Left.String() + " "
	}
	s += fmt.Sprint(t.Value)
	if t.Right != nil {
		s += " " + t.Right.String()
	}
	return "(" + s + ")"
}
<commit_msg>sync tree<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tree

import (
	"fmt"
	"rand"
)

// A Tree is a binary tree with integer values.
type Tree struct {
	Left  *Tree
	Value int
	Right *Tree
}

// New returns a new, random binary tree holding the values k, 2k, ..., 10k.
func New(k int) *Tree {
	var t *Tree
	for _, v := range rand.Perm(10) {
		t = insert(t, (1+v)*k)
	}
	return t
}

func insert(t *Tree, v int) *Tree {
	if t == nil {
		return &Tree{nil, v, nil}
	}
	if v < t.Value {
		t.Left = insert(t.Left, v)
	} else {
		t.Right = insert(t.Right, v)
	}
	return t
}

func (t *Tree) String() string {
	if t == nil {
		return "()"
	}
	s := ""
	if t.Left != nil {
		s += t.Left.String() + " "
	}
	s += fmt.Sprint(t.Value)
	if t.Right != nil {
		s += " " + t.Right.String()
	}
	return "(" + s + ")"
}
<|endoftext|>


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

// Package driver contains interfaces that needs to be implemented by
// various GPIO implementations.
package driver // import "golang.org/x/exp/io/gpio/driver"

// Direction determines the direction of the pin. A pin could be
// configured to be an input or an output.
type Direction string

const (
	In  = Direction("in")
	Out = Direction("out")
	// TODO(jbd): Bidirectional pins?
)

// Opener is an interface to be implemented by GPIO drivers.
type Opener interface {
	Open() (Conn, error)
}

// Conn represents an open GPIO connection. Each driver should implement
// this interface to provide a full implementation of the GPIO protocol.
type Conn interface {
	// Value returns the value of the pin. 0 for low values, 1 for high.
	Value(pin int) (int, error)

	// SetValue sets the value of the pin. 0 for low values, 1 for high.
	SetValue(pin int, v int) error

	// SetDirection sets the direction of the pin.
	SetDirection(pin int, dir Direction) error

	// Close closes the connection and frees the underlying resources.
	Close() error
}
<commit_msg>io/gpio: support mapping of virtual pin numbers to physical numbers<commit_after>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package driver contains interfaces that needs to be implemented by
// various GPIO implementations.
package driver // import "golang.org/x/exp/io/gpio/driver"

// Direction determines the direction of the pin. A pin could be
// configured to be an input or an output.
type Direction string

const (
	In  = Direction("in")
	Out = Direction("out")
	// TODO(jbd): Bidirectional pins?
)

// Opener is an interface to be implemented by GPIO drivers.
type Opener interface {
	Open() (Conn, error)
}

// Conn represents an open GPIO connection. Each driver should implement
// this interface to provide a full implementation of the GPIO protocol.
type Conn interface {
	// Value returns the value of the pin. 0 for low values, 1 for high.
	Value(pin int) (int, error)

	// SetValue sets the value of the pin. 0 for low values, 1 for high.
	SetValue(pin int, v int) error

	// SetDirection sets the direction of the pin.
	SetDirection(pin int, dir Direction) error

	// Map should map a virtual GPIO pin number to a physical pin number.
	// This is also useful to configure driver implementations for boards
	// with different GPIO pin layouts. E.g. GPIO 25 pin on a Raspberry Pi,
	// can be represented by a different physical pin out on a different
	// board.
	Map(virtual, physical int)

	// Close closes the connection and frees the underlying resources.
	Close() error
}
<|endoftext|>


<commit_before>// Copyright 2020 The LUCI 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 bqexporter

import (
	"context"

	"cloud.google.com/go/bigquery"
	"cloud.google.com/go/spanner"
	"github.com/golang/protobuf/descriptor"
	desc "github.com/golang/protobuf/protoc-gen-go/descriptor"
	"golang.org/x/sync/errgroup"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/runtime/protoiface"

	"go.chromium.org/luci/common/bq"
	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/common/logging"
	"go.chromium.org/luci/resultdb/internal/invocations"
	"go.chromium.org/luci/resultdb/internal/spanutil"
	"go.chromium.org/luci/resultdb/internal/testresults"
	"go.chromium.org/luci/resultdb/pbutil"
	bqpb "go.chromium.org/luci/resultdb/proto/bq"
	pb "go.chromium.org/luci/resultdb/proto/v1"
	"go.chromium.org/luci/server/span"
)

var testResultRowSchema bigquery.Schema

const testResultRowMessage = "luci.resultdb.bq.TestResultRow"

func init() {
	var err error
	if testResultRowSchema, err = generateTestResultRowSchema(); err != nil {
		panic(err)
	}
}

func generateTestResultRowSchema() (schema bigquery.Schema, err error) {
	fd, _ := descriptor.MessageDescriptorProto(&bqpb.TestResultRow{})
	// We also need to get FileDescriptorProto for StringPair, TestMetadata and FailureReason
	// because they are defined in different files.
	fdsp, _ := descriptor.MessageDescriptorProto(&pb.StringPair{})
	fdtmd, _ := descriptor.MessageDescriptorProto(&pb.TestMetadata{})
	fdfr, _ := descriptor.MessageDescriptorProto(&pb.FailureReason{})
	fdinv, _ := descriptor.MessageDescriptorProto(&bqpb.InvocationRecord{})
	fdset := &desc.FileDescriptorSet{File: []*desc.FileDescriptorProto{fd, fdsp, fdtmd, fdfr, fdinv}}
	return generateSchema(fdset, testResultRowMessage)
}

// Row size limit is 5MB according to
// https://cloud.google.com/bigquery/quotas#streaming_inserts
// Cap the summaryHTML's length to 4MB to ensure the row size is under
// limit.
const maxSummaryLength = 4e6

func invocationProtoToRecord(inv *pb.Invocation) *bqpb.InvocationRecord {
	return &bqpb.InvocationRecord{
		Id:    string(invocations.MustParseName(inv.Name)),
		Tags:  inv.Tags,
		Realm: inv.Realm,
	}
}

// testResultRowInput is information required to generate a TestResult BigQuery row.
type testResultRowInput struct {
	exported   *pb.Invocation
	parent     *pb.Invocation
	tr         *pb.TestResult
	exonerated bool
}

func (i *testResultRowInput) row() protoiface.MessageV1 {
	tr := i.tr

	ret := &bqpb.TestResultRow{
		Exported:      invocationProtoToRecord(i.exported),
		Parent:        invocationProtoToRecord(i.parent),
		Name:          tr.Name,
		TestId:        tr.TestId,
		ResultId:      tr.ResultId,
		Variant:       pbutil.VariantToStringPairs(tr.Variant),
		VariantHash:   tr.VariantHash,
		Expected:      tr.Expected,
		Status:        tr.Status.String(),
		SummaryHtml:   tr.SummaryHtml,
		StartTime:     tr.StartTime,
		Duration:      tr.Duration,
		Tags:          tr.Tags,
		Exonerated:    i.exonerated,
		PartitionTime: i.exported.CreateTime,
		TestMetadata:  tr.TestMetadata,
		FailureReason: tr.FailureReason,
	}

	if len(ret.SummaryHtml) > maxSummaryLength {
		ret.SummaryHtml = "[Trimmed] " + ret.SummaryHtml[:maxSummaryLength]
	}

	return ret
}

func (i *testResultRowInput) id() []byte {
	return []byte(i.tr.Name)
}

type testVariantKey struct {
	testID      string
	variantHash string
}

// queryExoneratedTestVariants reads exonerated test variants matching the predicate.
func queryExoneratedTestVariants(ctx context.Context, invIDs invocations.IDSet) (map[testVariantKey]struct{}, error) {
	st := spanner.NewStatement(`
		SELECT DISTINCT TestId, VariantHash,
		FROM TestExonerations
		WHERE InvocationId IN UNNEST(@invIDs)
	`)
	st.Params["invIDs"] = invIDs
	tvs := map[testVariantKey]struct{}{}
	var b spanutil.Buffer
	err := spanutil.Query(ctx, st, func(row *spanner.Row) error {
		var key testVariantKey
		if err := b.FromSpanner(row, &key.testID, &key.variantHash); err != nil {
			return err
		}
		tvs[key] = struct{}{}
		return nil
	})
	if err != nil {
		return nil, err
	}
	return tvs, nil
}

func (b *bqExporter) queryTestResults(
	ctx context.Context,
	exportedID invocations.ID,
	q testresults.Query,
	exoneratedTestVariants map[testVariantKey]struct{},
	batchC chan []rowInput) error {

	invs, err := invocations.ReadBatch(ctx, q.InvocationIDs)
	if err != nil {
		return err
	}

	rows := make([]rowInput, 0, b.MaxBatchRowCount)
	batchSize := 0 // Estimated size of rows in bytes.
	rowCount := 0
	err = q.Run(ctx, func(tr *pb.TestResult) error {
		_, exonerated := exoneratedTestVariants[testVariantKey{testID: tr.TestId, variantHash: tr.VariantHash}]
		parentID, _, _ := testresults.MustParseName(tr.Name)
		rows = append(rows, &testResultRowInput{
			exported:   invs[exportedID],
			parent:     invs[parentID],
			tr:         tr,
			exonerated: exonerated,
		})
		batchSize += proto.Size(tr)
		rowCount++
		if len(rows) >= b.MaxBatchRowCount || batchSize >= b.MaxBatchSizeApprox {
			select {
			case <-ctx.Done():
				return ctx.Err()
			case batchC <- rows:
			}
			rows = make([]rowInput, 0, b.MaxBatchRowCount)
			batchSize = 0
		}
		return nil
	})

	if err != nil {
		return err
	}

	if len(rows) > 0 {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case batchC <- rows:
		}
	}

	// Log the number of fetched rows so that later we can compare it to
	// the value in QueryTestResultsStatistics. This is to help debugging
	// crbug.com/1090671.
	logging.Debugf(ctx, "fetched %d rows for invocations %q", rowCount, q.InvocationIDs)
	return nil
}

// exportTestResultsToBigQuery queries test results in Spanner then exports them to BigQuery.
func (b *bqExporter) exportTestResultsToBigQuery(ctx context.Context, ins inserter, invID invocations.ID, bqExport *pb.BigQueryExport) error {
	ctx, cancel := span.ReadOnlyTransaction(ctx)
	defer cancel()

	exportInvocationBatch := func(ctx context.Context, invIDs invocations.IDSet) error {
		exoneratedTestVariants, err := queryExoneratedTestVariants(ctx, invIDs)
		if err != nil {
			return errors.Annotate(err, "query exoneration").Err()
		}

		// Query test results and export to BigQuery.
		batchC := make(chan []rowInput)

		// Batch exports rows to BigQuery.
		eg, ctx := errgroup.WithContext(ctx)

		eg.Go(func() error {
			return b.batchExportRows(ctx, ins, batchC, func(ctx context.Context, err bigquery.PutMultiError, rows []*bq.Row) {
				// Print up to 10 errors.
				for i := 0; i < 10 && i < len(err); i++ {
					tr := rows[err[i].RowIndex].Message.(*bqpb.TestResultRow)
					logging.Errorf(ctx, "failed to insert row for %s: %s", pbutil.TestResultName(tr.Parent.Id, tr.TestId, tr.ResultId), err[i].Error())
				}
				if len(err) > 10 {
					logging.Errorf(ctx, "%d more row insertions failed", len(err)-10)
				}
			})
		})

		q := testresults.Query{
			Predicate:     bqExport.GetTestResults().GetPredicate(),
			InvocationIDs: invIDs,
			Mask:          testresults.AllFields,
		}
		eg.Go(func() error {
			defer close(batchC)
			return b.queryTestResults(ctx, invID, q, exoneratedTestVariants, batchC)
		})

		return eg.Wait()
	}
	// Get the invocation set.
	err := getInvocationIDSet(ctx, invID, exportInvocationBatch)
	if err != nil {
		return errors.Annotate(err, "invocation id set").Err()
	}
	return nil
}
<commit_msg>ResultDB: Fix export when exported invocation is not in the batch<commit_after>// Copyright 2020 The LUCI 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 bqexporter

import (
	"context"

	"cloud.google.com/go/bigquery"
	"cloud.google.com/go/spanner"
	"github.com/golang/protobuf/descriptor"
	desc "github.com/golang/protobuf/protoc-gen-go/descriptor"
	"golang.org/x/sync/errgroup"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/runtime/protoiface"

	"go.chromium.org/luci/common/bq"
	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/common/logging"
	"go.chromium.org/luci/resultdb/internal/invocations"
	"go.chromium.org/luci/resultdb/internal/spanutil"
	"go.chromium.org/luci/resultdb/internal/testresults"
	"go.chromium.org/luci/resultdb/pbutil"
	bqpb "go.chromium.org/luci/resultdb/proto/bq"
	pb "go.chromium.org/luci/resultdb/proto/v1"
	"go.chromium.org/luci/server/span"
)

var testResultRowSchema bigquery.Schema

const testResultRowMessage = "luci.resultdb.bq.TestResultRow"

func init() {
	var err error
	if testResultRowSchema, err = generateTestResultRowSchema(); err != nil {
		panic(err)
	}
}

func generateTestResultRowSchema() (schema bigquery.Schema, err error) {
	fd, _ := descriptor.MessageDescriptorProto(&bqpb.TestResultRow{})
	// We also need to get FileDescriptorProto for StringPair, TestMetadata and FailureReason
	// because they are defined in different files.
	fdsp, _ := descriptor.MessageDescriptorProto(&pb.StringPair{})
	fdtmd, _ := descriptor.MessageDescriptorProto(&pb.TestMetadata{})
	fdfr, _ := descriptor.MessageDescriptorProto(&pb.FailureReason{})
	fdinv, _ := descriptor.MessageDescriptorProto(&bqpb.InvocationRecord{})
	fdset := &desc.FileDescriptorSet{File: []*desc.FileDescriptorProto{fd, fdsp, fdtmd, fdfr, fdinv}}
	return generateSchema(fdset, testResultRowMessage)
}

// Row size limit is 5MB according to
// https://cloud.google.com/bigquery/quotas#streaming_inserts
// Cap the summaryHTML's length to 4MB to ensure the row size is under
// limit.
const maxSummaryLength = 4e6

func invocationProtoToRecord(inv *pb.Invocation) *bqpb.InvocationRecord {
	return &bqpb.InvocationRecord{
		Id:    string(invocations.MustParseName(inv.Name)),
		Tags:  inv.Tags,
		Realm: inv.Realm,
	}
}

// testResultRowInput is information required to generate a TestResult BigQuery row.
type testResultRowInput struct {
	exported   *pb.Invocation
	parent     *pb.Invocation
	tr         *pb.TestResult
	exonerated bool
}

func (i *testResultRowInput) row() protoiface.MessageV1 {
	tr := i.tr

	ret := &bqpb.TestResultRow{
		Exported:      invocationProtoToRecord(i.exported),
		Parent:        invocationProtoToRecord(i.parent),
		Name:          tr.Name,
		TestId:        tr.TestId,
		ResultId:      tr.ResultId,
		Variant:       pbutil.VariantToStringPairs(tr.Variant),
		VariantHash:   tr.VariantHash,
		Expected:      tr.Expected,
		Status:        tr.Status.String(),
		SummaryHtml:   tr.SummaryHtml,
		StartTime:     tr.StartTime,
		Duration:      tr.Duration,
		Tags:          tr.Tags,
		Exonerated:    i.exonerated,
		PartitionTime: i.exported.CreateTime,
		TestMetadata:  tr.TestMetadata,
		FailureReason: tr.FailureReason,
	}

	if len(ret.SummaryHtml) > maxSummaryLength {
		ret.SummaryHtml = "[Trimmed] " + ret.SummaryHtml[:maxSummaryLength]
	}

	return ret
}

func (i *testResultRowInput) id() []byte {
	return []byte(i.tr.Name)
}

type testVariantKey struct {
	testID      string
	variantHash string
}

// queryExoneratedTestVariants reads exonerated test variants matching the predicate.
func queryExoneratedTestVariants(ctx context.Context, invIDs invocations.IDSet) (map[testVariantKey]struct{}, error) {
	st := spanner.NewStatement(`
		SELECT DISTINCT TestId, VariantHash,
		FROM TestExonerations
		WHERE InvocationId IN UNNEST(@invIDs)
	`)
	st.Params["invIDs"] = invIDs
	tvs := map[testVariantKey]struct{}{}
	var b spanutil.Buffer
	err := spanutil.Query(ctx, st, func(row *spanner.Row) error {
		var key testVariantKey
		if err := b.FromSpanner(row, &key.testID, &key.variantHash); err != nil {
			return err
		}
		tvs[key] = struct{}{}
		return nil
	})
	if err != nil {
		return nil, err
	}
	return tvs, nil
}

func (b *bqExporter) queryTestResults(
	ctx context.Context,
	exported *pb.Invocation,
	q testresults.Query,
	exoneratedTestVariants map[testVariantKey]struct{},
	batchC chan []rowInput) error {

	invs, err := invocations.ReadBatch(ctx, q.InvocationIDs)
	if err != nil {
		return err
	}

	rows := make([]rowInput, 0, b.MaxBatchRowCount)
	batchSize := 0 // Estimated size of rows in bytes.
	rowCount := 0
	err = q.Run(ctx, func(tr *pb.TestResult) error {
		_, exonerated := exoneratedTestVariants[testVariantKey{testID: tr.TestId, variantHash: tr.VariantHash}]
		parentID, _, _ := testresults.MustParseName(tr.Name)
		rows = append(rows, &testResultRowInput{
			exported:   exported,
			parent:     invs[parentID],
			tr:         tr,
			exonerated: exonerated,
		})
		batchSize += proto.Size(tr)
		rowCount++
		if len(rows) >= b.MaxBatchRowCount || batchSize >= b.MaxBatchSizeApprox {
			select {
			case <-ctx.Done():
				return ctx.Err()
			case batchC <- rows:
			}
			rows = make([]rowInput, 0, b.MaxBatchRowCount)
			batchSize = 0
		}
		return nil
	})

	if err != nil {
		return err
	}

	if len(rows) > 0 {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case batchC <- rows:
		}
	}

	// Log the number of fetched rows so that later we can compare it to
	// the value in QueryTestResultsStatistics. This is to help debugging
	// crbug.com/1090671.
	logging.Debugf(ctx, "fetched %d rows for invocations %q", rowCount, q.InvocationIDs)
	return nil
}

// exportTestResultsToBigQuery queries test results in Spanner then exports them to BigQuery.
func (b *bqExporter) exportTestResultsToBigQuery(ctx context.Context, ins inserter, invID invocations.ID, bqExport *pb.BigQueryExport) error {
	ctx, cancel := span.ReadOnlyTransaction(ctx)
	defer cancel()

	exported, err := invocations.Read(ctx, invID)
	if err != nil {
		return err
	}
	exportInvocationBatch := func(ctx context.Context, invIDs invocations.IDSet) error {
		exoneratedTestVariants, err := queryExoneratedTestVariants(ctx, invIDs)
		if err != nil {
			return errors.Annotate(err, "query exoneration").Err()
		}

		// Query test results and export to BigQuery.
		batchC := make(chan []rowInput)

		// Batch exports rows to BigQuery.
		eg, ctx := errgroup.WithContext(ctx)

		eg.Go(func() error {
			return b.batchExportRows(ctx, ins, batchC, func(ctx context.Context, err bigquery.PutMultiError, rows []*bq.Row) {
				// Print up to 10 errors.
				for i := 0; i < 10 && i < len(err); i++ {
					tr := rows[err[i].RowIndex].Message.(*bqpb.TestResultRow)
					logging.Errorf(ctx, "failed to insert row for %s: %s", pbutil.TestResultName(tr.Parent.Id, tr.TestId, tr.ResultId), err[i].Error())
				}
				if len(err) > 10 {
					logging.Errorf(ctx, "%d more row insertions failed", len(err)-10)
				}
			})
		})

		q := testresults.Query{
			Predicate:     bqExport.GetTestResults().GetPredicate(),
			InvocationIDs: invIDs,
			Mask:          testresults.AllFields,
		}
		eg.Go(func() error {
			defer close(batchC)
			return b.queryTestResults(ctx, exported, q, exoneratedTestVariants, batchC)
		})

		return eg.Wait()
	}
	// Get the invocation set.
	if err := getInvocationIDSet(ctx, invID, exportInvocationBatch); err != nil {
		return errors.Annotate(err, "invocation id set").Err()
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"image"
	"image/color"
	"image/png"
	"os"
	"strconv"
)

func main() {
	flagColor := flag.String("color", "FFFFFF", "base color (6 digit hex)")
	flagOutput := flag.String("o", "out.png", "output file")
	flag.Parse()

	if len(flag.Args()) != 1 {
		flag.Usage()
		os.Exit(1)
	}

	c, err := strconv.ParseUint(*flagColor, 16, 24)
	if err != nil {
		flag.Usage()
		os.Exit(2)
	}
	ar := uint32(c >> 16 & 255)
	ag := uint32(c >> 8 & 255)
	ab := uint32(c & 255)

	f, err := os.Open(flag.Args()[0])
	if err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(3)
	}
	base, err := png.Decode(f)
	f.Close()
	if err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(4)
	}
	bounds := base.Bounds()
	result := image.NewRGBA(bounds)
	for x := bounds.Min.X; x < bounds.Max.X; x++ {
		for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
			r, g, b, a := base.At(x, y).RGBA()
			result.Set(x, y, color.RGBA{
				R: fade(r, ar),
				G: fade(g, ag),
				B: fade(b, ab),
				A: uint8(a),
			})
		}
	}
	f, err = os.Create(*flagOutput)
	if err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(5)
	}
	defer f.Close()
	err = png.Encode(f, result)
	if err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(6)
	}
}

func fade(base, accent uint32) uint8 {
	if base > 127 {
		return 255 - fade(255-base, 255-accent)
	}
	return uint8(base * accent / 127)
}
<commit_msg>fixed<commit_after>package main

import (
	"flag"
	"image"
	"image/color"
	"image/png"
	"os"
	"strconv"
)

func main() {
	flagColor := flag.String("color", "FFFFFF", "base color (6 digit hex)")
	flagOutput := flag.String("o", "out.png", "output file")
	flag.Parse()

	if len(flag.Args()) != 1 {
		flag.Usage()
		os.Exit(1)
	}

	c, err := strconv.ParseUint(*flagColor, 16, 24)
	if err != nil {
		flag.Usage()
		os.Exit(2)
	}
	ar := uint32(c >> 16 & 255)
	ag := uint32(c >> 8 & 255)
	ab := uint32(c & 255)

	f, err := os.Open(flag.Args()[0])
	if err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(3)
	}
	base, err := png.Decode(f)
	f.Close()
	if err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(4)
	}
	bounds := base.Bounds()
	result := image.NewRGBA(bounds)
	for x := bounds.Min.X; x < bounds.Max.X; x++ {
		for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
			r, g, b, a := base.At(x, y).RGBA()
			result.Set(x, y, color.RGBA{
				R: fade(r>>8, ar),
				G: fade(g>>8, ag),
				B: fade(b>>8, ab),
				A: uint8(a>>8),
			})
		}
	}
	f, err = os.Create(*flagOutput)
	if err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(5)
	}
	defer f.Close()
	err = png.Encode(f, result)
	if err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(6)
	}
}

func fade(base, accent uint32) uint8 {
	if base > 127 {
		return 255 - fade(255-base, 255-accent)
	}
	return uint8(base * accent / 127)
}
<|endoftext|>


<commit_before>package api

import (
	"encoding/json"
	"flag"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
	"time"
)

var url = flag.String("url", "http://107.178.208.130:80/burn", "Url to serve traffic to.")
var initQps = flag.Int("init_qps", 1, "Number of queries per second to initially send.")

var nsInSecond = int64(1000 * 1000 * 1000)
var nanoDelay = nsInSecond
var uptime = "Initial Uptime (not updated.)"
var latency = "None."

func sendQueries() {
	for true {
		for nanoDelay == 0 {
			time.Sleep(nsInSecond)
		}
		time.Sleep(time.Duration(nanoDelay))
		go sendOneQuery()
	}
}

func sendOneQuery() {
	sendTime := time.Now()
	resp, err := http.Get(*url)
	latency = time.Since(sendTime).String()
	if err != nil {
		log.Printf("%v", err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("%v", err)
		return
	}
	uptime = string(body)
	log.Printf("New Uptime: %s", uptime)
}

type queryInfo struct {
	Uptime  string `json:"uptime"`
	Latency string `json:"latency"`
}

func RegisterServiceHandlers() {
	nanoDelay = nsInSecond / int64(*initQps)
	http.HandleFunc("/api/qps", func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		qps, err := strconv.Atoi(r.FormValue("qps"))
		if err != nil {
			log.Printf("%v", err)
			return
		}
		if (qps == 0) {
			nanoDelay = 0
		} else {
			nanoDelay = nsInSecond / int64(qps)
		}
		log.Printf("Request(/api/qps) took %s", time.Since(start))
	})
	http.HandleFunc("/api/uptime", func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		encoder := json.NewEncoder(w)
		err := encoder.Encode(&queryInfo{
			Uptime:  uptime,
			Latency: latency,
		})
		// fmt.Fprintf(w, "{\"uptime\":%q \"latency\":%q}", uptime, latency)
		if err != nil {
			log.Printf("unalbe to marshal json: %v", err)
		}
		log.Printf("Request(/api/uptime) took %s", time.Since(start))
	})
	go sendQueries()
}
<commit_msg>Fix compile error<commit_after>package api

import (
	"encoding/json"
	"flag"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
	"time"
)

var url = flag.String("url", "http://107.178.208.130:80/burn", "Url to serve traffic to.")
var initQps = flag.Int("init_qps", 1, "Number of queries per second to initially send.")

var nsInSecond = int64(1000 * 1000 * 1000)
var nanoDelay = nsInSecond
var uptime = "Initial Uptime (not updated.)"
var latency = "None."

func sendQueries() {
	for true {
		for nanoDelay == 0 {
			time.Sleep(time.Duration(nsInSecond))
		}
		time.Sleep(time.Duration(nanoDelay))
		go sendOneQuery()
	}
}

func sendOneQuery() {
	sendTime := time.Now()
	resp, err := http.Get(*url)
	latency = time.Since(sendTime).String()
	if err != nil {
		log.Printf("%v", err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("%v", err)
		return
	}
	uptime = string(body)
	log.Printf("New Uptime: %s", uptime)
}

type queryInfo struct {
	Uptime  string `json:"uptime"`
	Latency string `json:"latency"`
}

func RegisterServiceHandlers() {
	nanoDelay = nsInSecond / int64(*initQps)
	http.HandleFunc("/api/qps", func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		qps, err := strconv.Atoi(r.FormValue("qps"))
		if err != nil {
			log.Printf("%v", err)
			return
		}
		if qps == 0 {
			nanoDelay = 0
		} else {
			nanoDelay = nsInSecond / int64(qps)
		}
		log.Printf("Request(/api/qps) took %s", time.Since(start))
	})
	http.HandleFunc("/api/uptime", func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		encoder := json.NewEncoder(w)
		err := encoder.Encode(&queryInfo{
			Uptime:  uptime,
			Latency: latency,
		})
		// fmt.Fprintf(w, "{\"uptime\":%q \"latency\":%q}", uptime, latency)
		if err != nil {
			log.Printf("unalbe to marshal json: %v", err)
		}
		log.Printf("Request(/api/uptime) took %s", time.Since(start))
	})
	go sendQueries()
}
<|endoftext|>