<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/tajtiattila/vjoy"
	"github.com/tajtiattila/xinput"
	"os"
	"time"
)

var (
	savecfg  = flag.String("save", "", "save default configfile into file specified and exit")
	loadcfg  = flag.String("cfg", "", "configfile to use")
	quiet    = flag.Bool("quiet", false, "don't print info at startup")
	prtver   = flag.Bool("version", false, "print version and exit")
	funcs    = flag.Bool("funcs", false, "print available functions and exit")
	webgui   = flag.Bool("web", false, "enable web gui")
	addr     = flag.String("addr", ":7489", "web gui address")  // "JY"
	sharedir = flag.String("share", "share", "share directory") // "JY"
	Version  = "development"
)

const (
	LTriggerPull  = 1 << 10
	RTriggerPull  = 1 << 11
	LTriggerTouch = 1 << 16
	RTriggerTouch = 1 << 17
)

func main() {
	cfg := NewConfig()
	flag.Parse()

	if flag.NArg() != 0 {
		abort("Positional arguments not supported")
	}

	var cfgch <-chan *Config
	exit := false
	if *prtver {
		fmt.Println(Version)
		exit = true
	}
	if *savecfg != "" {
		err := cfg.Save(*savecfg)
		if err != nil {
			abort(err)
		}
		exit = true
	}
	if *funcs {
		fmt.Println("Axis functions:")
		axisFuncs.Print()
		fmt.Println("Stick functions:")
		stickFuncs.Print()
		exit = true
	}
	if exit {
		return
	}

	if *loadcfg != "" {
		err := cfg.Load(*loadcfg)
		if err != nil {
			abort(err)
		}
		cfgch = autoloadconfig(*loadcfg)
	} else {
		fn := "joyster.cfg"
		if err := cfg.Load(fn); err != nil {
			// no error, but reset to default
			cfg = NewConfig()
			fmt.Println(err)
		} else {
			cfgch = autoloadconfig(fn)
		}
	}

	if !*quiet {
		fmt.Println("joyster version:", Version)
		fmt.Println("vJoy version:", vjoy.Version())
		fmt.Println("  Product:       ", vjoy.ProductString())
		fmt.Println("  Manufacturer:  ", vjoy.ManufacturerString())
		fmt.Println("  Serial number: ", vjoy.SerialNumberString())
	}
	d, err := vjoy.Acquire(1)
	if err != nil {
		abort(err)
	}
	defer d.Relinquish()

	if *webgui {
		WebGUI(*addr, *sharedir)
	}

	var xs xinput.State
	t := &ticker{config: cfg, gamepad: &xs.Gamepad, dev: d}
	for {
		xinput.GetState(0, &xs)
		t.update()
		time.Sleep(time.Duration(cfg.UpdateMicros) * time.Microsecond)
		select {
		case cfg := <-cfgch:
			t.config = cfg
		default:
		}
	}
}

type ticker struct {
	config  *Config
	gamepad *xinput.Gamepad

	lastb uint32

	view viewaccumulatelogic

	dev *vjoy.Device

	st Status
}

func (t *ticker) update() {
	t.updateAxes()
	t.updateButtons()
	t.updateFlight()

	t.updateDevice()
	t.updateListeners()
}

func (t *ticker) updateDevice() {
	d, o := t.dev, &t.st.O
	d.Axis(vjoy.AxisX).Setf(o.X)
	d.Axis(vjoy.AxisY).Setf(o.Y)
	d.Axis(vjoy.AxisZ).Setf(o.Z)
	d.Axis(vjoy.AxisRX).Setf(o.RX)
	d.Axis(vjoy.AxisRY).Setf(o.RY)
	d.Axis(vjoy.AxisRZ).Setf(o.RZ)
	d.Axis(vjoy.Slider0).Setf(o.U)
	d.Axis(vjoy.Slider1).Setf(o.V)
	d.Update()
}

func (t *ticker) updateListeners() {
	DefaultStatusDispatcher.Update(&t.st)
}

func (t *ticker) updateFlight() {
	b := uint32(t.gamepad.Buttons)
	if t.config.RollToYaw {
		if (((b ^ t.lastb) & b) & uint32(xinput.LEFT_THUMB)) != 0 {
			t.st.RollToYaw = !t.st.RollToYaw
			t.st.TriggerYaw = false
		}
	}
	if t.config.HeadLook != nil {
		if (((b ^ t.lastb) & b) & uint32(xinput.RIGHT_THUMB)) != 0 {
			t.st.HeadLook = !t.st.HeadLook
		}
	}
	if t.config.TriggerAxis != nil {
		if (((b ^ t.lastb) & b) & t.config.TriggerAxis.imask) != 0 {
			t.st.TriggerYaw = !t.st.TriggerYaw
			if t.st.TriggerYaw {
				t.st.RollToYaw = false
			}
		}
	}
	t.lastb = b
}

func (t *ticker) updateAxes() {
	var ls, rs StickPos
	ls.Init(t.gamepad.ThumbLX, t.gamepad.ThumbLY)
	rs.Init(t.gamepad.ThumbRX, t.gamepad.ThumbRY)

	i := &t.st.I
	i.LX, i.LY = ls.Values()
	i.RX, i.RY = rs.Values()

	ls.Apply(t.config.leftStickLogic)
	rs.Apply(t.config.rightStickLogic)

	t.st.LXf, t.st.LYf = ls.Values()
	t.st.RXf, t.st.RYf = rs.Values()

	lx, ly := t.st.LXf, t.st.LYf
	rx, ry := t.st.RXf, t.st.RYf

	o := &t.st.O
	if t.st.RollToYaw {
		o.X = 0
		o.Y = ly
		o.Z = lx
	} else {
		o.X = lx
		o.Y = ly
		o.Z = 0
	}
	if t.st.HeadLook {
		o.RX, o.RY = 0, 0
		o.U, o.V = t.view.update(t.config, rx, ry)
	} else {
		o.RX, o.RY = rx, ry
		o.U, o.V = t.view.jumpToOrigin(t.config)
	}

	ltr := float32(t.gamepad.LeftTrigger) / 255
	rtr := float32(t.gamepad.RightTrigger) / 255
	t.st.I.LTrigger, t.st.I.RTrigger = ltr, rtr
	if t.config.LeftTrigger.Axis {
		t.dev.Axis(vjoy.AxisZ).Setuf(ltr)
	}
	if t.config.RightTrigger.Axis {
		t.dev.Axis(vjoy.AxisRZ).Setuf(rtr)
	}
}

func (t *ticker) updateButtons() {
	btns := uint32(t.gamepad.Buttons)
	lv, rv := uint16(t.gamepad.LeftTrigger), uint16(t.gamepad.RightTrigger)
	if t.st.TriggerYaw {
		tac := t.config.TriggerAxis
		lx, rx := lv > tac.breakthreshold, rv > tac.breakthreshold
		if lx == rx {
			if lx {
				btns |= tac.breakmask
			}
		} else {
			lf := triggermap(lv, tac.axisthreshold, tac.Pow)
			rf := triggermap(rv, tac.axisthreshold, tac.Pow)
			t.st.O.Z += rf - lf
		}
	} else {
		if t.config.LeftTrigger.touch <= lv {
			if t.config.LeftTrigger.pull <= lv {
				btns |= LTriggerPull
			} else {
				btns |= LTriggerTouch
			}
		}
		if t.config.RightTrigger.touch <= rv {
			if t.config.RightTrigger.pull <= rv {
				btns |= RTriggerPull
			} else {
				btns |= RTriggerTouch
			}
		}
	}
	t.st.I.Buttons = uint64(btns)
	for _, bc := range t.config.Buttons {
		bc.handler.Handle(t, bc, (btns&bc.fmask) == bc.imask)
	}
}

func (t *ticker) SetButton(idx uint, value bool) {
	t.dev.Button(idx).Set(value)
	if value {
		t.st.O.Buttons |= 1 << idx
	} else {
		t.st.O.Buttons &= ^(1 << idx)
	}
}

func abort(a ...interface{}) {
	fmt.Println(a...)
	os.Exit(1)
}

func autoloadconfig(fn string) <-chan *Config {
	ch := make(chan *Config)
	if fi, err := os.Stat(fn); err == nil {
		t := fi.ModTime()
		go func() {
			for {
				if fi, err := os.Stat(fn); err == nil && fi.ModTime().After(t) {
					t = fi.ModTime()
					cfg := new(Config)
					if err := cfg.Load(fn); err == nil {
						ch <- cfg
						fmt.Println("new config loaded")
					} else {
						fmt.Println("config error:", err)
					}
				}
				time.Sleep(time.Second)
			}
		}()
	} else {
		panic("autoloadcfg " + fn + err.Error())
	}
	return ch
}
<commit_msg>main: respect quiet flag, print config loaded message<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/tajtiattila/vjoy"
	"github.com/tajtiattila/xinput"
	"os"
	"time"
)

var (
	savecfg  = flag.String("save", "", "save default configfile into file specified and exit")
	loadcfg  = flag.String("cfg", "", "configfile to use")
	quiet    = flag.Bool("quiet", false, "don't print info at startup")
	prtver   = flag.Bool("version", false, "print version and exit")
	funcs    = flag.Bool("funcs", false, "print available functions and exit")
	webgui   = flag.Bool("web", false, "enable web gui")
	addr     = flag.String("addr", ":7489", "web gui address")  // "JY"
	sharedir = flag.String("share", "share", "share directory") // "JY"
	Version  = "development"
)

const (
	LTriggerPull  = 1 << 10
	RTriggerPull  = 1 << 11
	LTriggerTouch = 1 << 16
	RTriggerTouch = 1 << 17
)

func main() {
	cfg := NewConfig()
	flag.Parse()

	if flag.NArg() != 0 {
		abort("Positional arguments not supported")
	}

	var cfgch <-chan *Config
	exit := false
	if *prtver {
		fmt.Println(Version)
		exit = true
	}
	if *savecfg != "" {
		err := cfg.Save(*savecfg)
		if err != nil {
			abort(err)
		}
		exit = true
	}
	if *funcs {
		fmt.Println("Axis functions:")
		axisFuncs.Print()
		fmt.Println("Stick functions:")
		stickFuncs.Print()
		exit = true
	}
	if exit {
		return
	}

	if !*quiet {
		fmt.Println("joyster version:", Version)
		fmt.Println("vJoy version:", vjoy.Version())
		fmt.Println("  Product:       ", vjoy.ProductString())
		fmt.Println("  Manufacturer:  ", vjoy.ManufacturerString())
		fmt.Println("  Serial number: ", vjoy.SerialNumberString())
	}

	if *loadcfg != "" {
		err := cfg.Load(*loadcfg)
		if err != nil {
			abort(err)
		}
		if !*quiet {
			fmt.Println(*loadcfg, "loaded")
		}
		cfgch = autoloadconfig(*loadcfg)
	} else {
		fn := "joyster.cfg"
		if err := cfg.Load(fn); err != nil {
			// no error, but reset to default
			cfg = NewConfig()
			fmt.Println(err)
		} else {
			if !*quiet {
				fmt.Println(fn, "loaded")
			}
			cfgch = autoloadconfig(fn)
		}
	}

	d, err := vjoy.Acquire(1)
	if err != nil {
		abort(err)
	}
	defer d.Relinquish()

	if *webgui {
		WebGUI(*addr, *sharedir)
	}

	var xs xinput.State
	t := &ticker{config: cfg, gamepad: &xs.Gamepad, dev: d}
	for {
		xinput.GetState(0, &xs)
		t.update()
		time.Sleep(time.Duration(cfg.UpdateMicros) * time.Microsecond)
		select {
		case cfg := <-cfgch:
			t.config = cfg
		default:
		}
	}
}

type ticker struct {
	config  *Config
	gamepad *xinput.Gamepad

	lastb uint32

	view viewaccumulatelogic

	dev *vjoy.Device

	st Status
}

func (t *ticker) update() {
	t.updateAxes()
	t.updateButtons()
	t.updateFlight()

	t.updateDevice()
	t.updateListeners()
}

func (t *ticker) updateDevice() {
	d, o := t.dev, &t.st.O
	d.Axis(vjoy.AxisX).Setf(o.X)
	d.Axis(vjoy.AxisY).Setf(o.Y)
	d.Axis(vjoy.AxisZ).Setf(o.Z)
	d.Axis(vjoy.AxisRX).Setf(o.RX)
	d.Axis(vjoy.AxisRY).Setf(o.RY)
	d.Axis(vjoy.AxisRZ).Setf(o.RZ)
	d.Axis(vjoy.Slider0).Setf(o.U)
	d.Axis(vjoy.Slider1).Setf(o.V)
	d.Update()
}

func (t *ticker) updateListeners() {
	DefaultStatusDispatcher.Update(&t.st)
}

func (t *ticker) updateFlight() {
	b := uint32(t.gamepad.Buttons)
	if t.config.RollToYaw {
		if (((b ^ t.lastb) & b) & uint32(xinput.LEFT_THUMB)) != 0 {
			t.st.RollToYaw = !t.st.RollToYaw
			t.st.TriggerYaw = false
		}
	}
	if t.config.HeadLook != nil {
		if (((b ^ t.lastb) & b) & uint32(xinput.RIGHT_THUMB)) != 0 {
			t.st.HeadLook = !t.st.HeadLook
		}
	}
	if t.config.TriggerAxis != nil {
		if (((b ^ t.lastb) & b) & t.config.TriggerAxis.imask) != 0 {
			t.st.TriggerYaw = !t.st.TriggerYaw
			if t.st.TriggerYaw {
				t.st.RollToYaw = false
			}
		}
	}
	t.lastb = b
}

func (t *ticker) updateAxes() {
	var ls, rs StickPos
	ls.Init(t.gamepad.ThumbLX, t.gamepad.ThumbLY)
	rs.Init(t.gamepad.ThumbRX, t.gamepad.ThumbRY)

	i := &t.st.I
	i.LX, i.LY = ls.Values()
	i.RX, i.RY = rs.Values()

	ls.Apply(t.config.leftStickLogic)
	rs.Apply(t.config.rightStickLogic)

	t.st.LXf, t.st.LYf = ls.Values()
	t.st.RXf, t.st.RYf = rs.Values()

	lx, ly := t.st.LXf, t.st.LYf
	rx, ry := t.st.RXf, t.st.RYf

	o := &t.st.O
	if t.st.RollToYaw {
		o.X = 0
		o.Y = ly
		o.Z = lx
	} else {
		o.X = lx
		o.Y = ly
		o.Z = 0
	}
	if t.st.HeadLook {
		o.RX, o.RY = 0, 0
		o.U, o.V = t.view.update(t.config, rx, ry)
	} else {
		o.RX, o.RY = rx, ry
		o.U, o.V = t.view.jumpToOrigin(t.config)
	}

	ltr := float32(t.gamepad.LeftTrigger) / 255
	rtr := float32(t.gamepad.RightTrigger) / 255
	t.st.I.LTrigger, t.st.I.RTrigger = ltr, rtr
	if t.config.LeftTrigger.Axis {
		t.dev.Axis(vjoy.AxisZ).Setuf(ltr)
	}
	if t.config.RightTrigger.Axis {
		t.dev.Axis(vjoy.AxisRZ).Setuf(rtr)
	}
}

func (t *ticker) updateButtons() {
	btns := uint32(t.gamepad.Buttons)
	lv, rv := uint16(t.gamepad.LeftTrigger), uint16(t.gamepad.RightTrigger)
	if t.st.TriggerYaw {
		tac := t.config.TriggerAxis
		lx, rx := lv > tac.breakthreshold, rv > tac.breakthreshold
		if lx == rx {
			if lx {
				btns |= tac.breakmask
			}
		} else {
			lf := triggermap(lv, tac.axisthreshold, tac.Pow)
			rf := triggermap(rv, tac.axisthreshold, tac.Pow)
			t.st.O.Z += rf - lf
		}
	} else {
		if t.config.LeftTrigger.touch <= lv {
			if t.config.LeftTrigger.pull <= lv {
				btns |= LTriggerPull
			} else {
				btns |= LTriggerTouch
			}
		}
		if t.config.RightTrigger.touch <= rv {
			if t.config.RightTrigger.pull <= rv {
				btns |= RTriggerPull
			} else {
				btns |= RTriggerTouch
			}
		}
	}
	t.st.I.Buttons = uint64(btns)
	for _, bc := range t.config.Buttons {
		bc.handler.Handle(t, bc, (btns&bc.fmask) == bc.imask)
	}
}

func (t *ticker) SetButton(idx uint, value bool) {
	t.dev.Button(idx).Set(value)
	if value {
		t.st.O.Buttons |= 1 << idx
	} else {
		t.st.O.Buttons &= ^(1 << idx)
	}
}

func abort(a ...interface{}) {
	fmt.Println(a...)
	os.Exit(1)
}

func autoloadconfig(fn string) <-chan *Config {
	ch := make(chan *Config)
	if fi, err := os.Stat(fn); err == nil {
		t := fi.ModTime()
		go func() {
			for {
				if fi, err := os.Stat(fn); err == nil && fi.ModTime().After(t) {
					t = fi.ModTime()
					cfg := new(Config)
					if err := cfg.Load(fn); err == nil {
						ch <- cfg
						if !*quiet {
							fmt.Println("new config loaded")
						}
					} else {
						fmt.Println("config error:", err)
					}
				}
				time.Sleep(time.Second)
			}
		}()
	} else {
		panic("autoloadcfg " + fn + err.Error())
	}
	return ch
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
	"sync"
)

func runCommand(wg *sync.WaitGroup, commandIndex int, phase nodeData, cmd *exec.Cmd) {
	if wg != nil {
		defer wg.Done()
	}

	out, err := cmd.CombinedOutput()
	if err != nil {
		errMsg := fmt.Sprintf("ERROR (continue=%t): %s. OUT: %s\n", phase.ContinueOnFailure, err.Error(), string(out))
		if !phase.ContinueOnFailure {
			logger.Fatallnf(errMsg)
		} else {
			logger.Errorlnf(errMsg)
			return
		}
	}

	commandName := strings.TrimSpace(fmt.Sprintf(`(INDEX %d) "%s" %+v`, commandIndex, cmd.Path, cmd.Args))
	logger.PrintCommandOutput(commandName, string(out))
}

func runPhase(setup *setup, phaseName string, phase nodeData) {
	var wg sync.WaitGroup

	cmds, err := phase.GetExecCommandsFromSteps(setup.Variables)
	if err != nil {
		logger.Fatallnf(err.Error())
	}

	if phase.RunParallel {
		wg.Add(len(cmds))
	}

	logger.Infolnf("Running step %s", phaseName)
	for ind, c := range cmds {
		var wgToUse *sync.WaitGroup = nil
		if phase.RunParallel {
			wgToUse = &wg
		}

		go runCommand(wgToUse, ind, phase, c)
	}

	if phase.RunParallel {
		wg.Wait()
	}
}

func main() {
	if len(os.Args) < 2 {
		logger.Fatallnf("The first command-line argument must be the YAML file path.")
	}

	yamlFilePath := os.Args[1]

	setup, err := ParseYamlFile(yamlFilePath)
	if err != nil {
		logger.Fatallnf(err.Error())
	}

	for name, phase := range setup.Phases {
		runPhase(setup, name, phase)
	}
}
<commit_msg>Do not use goroutine if `RunParallel` is false.<commit_after>package main

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
	"sync"
)

func runCommand(wg *sync.WaitGroup, commandIndex int, phase nodeData, cmd *exec.Cmd) {
	if wg != nil {
		defer wg.Done()
	}

	out, err := cmd.CombinedOutput()
	if err != nil {
		errMsg := fmt.Sprintf("ERROR (continue=%t): %s. OUT: %s\n", phase.ContinueOnFailure, err.Error(), string(out))
		if !phase.ContinueOnFailure {
			logger.Fatallnf(errMsg)
		} else {
			logger.Errorlnf(errMsg)
			return
		}
	}

	commandName := strings.TrimSpace(fmt.Sprintf(`(INDEX %d) "%s" %+v`, commandIndex, cmd.Path, cmd.Args))
	logger.PrintCommandOutput(commandName, string(out))
}

func runPhase(setup *setup, phaseName string, phase nodeData) {
	var wg sync.WaitGroup

	cmds, err := phase.GetExecCommandsFromSteps(setup.Variables)
	if err != nil {
		logger.Fatallnf(err.Error())
	}

	if phase.RunParallel {
		wg.Add(len(cmds))
	}

	logger.Infolnf("Running step %s", phaseName)
	for ind, c := range cmds {
		var wgToUse *sync.WaitGroup = nil
		if phase.RunParallel {
			wgToUse = &wg
			go runCommand(wgToUse, ind, phase, c)
		} else {
			runCommand(wgToUse, ind, phase, c)
		}
	}

	if phase.RunParallel {
		wg.Wait()
	}
}

func main() {
	if len(os.Args) < 2 {
		logger.Fatallnf("The first command-line argument must be the YAML file path.")
	}

	yamlFilePath := os.Args[1]

	setup, err := ParseYamlFile(yamlFilePath)
	if err != nil {
		logger.Fatallnf(err.Error())
	}

	for name, phase := range setup.Phases {
		runPhase(setup, name, phase)
	}
}
<|endoftext|>


<commit_before>package main

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

//function to collect post requests
func parsePost(w http.ResponseWriter, r *http.Request) {

	fmt.Println(r.Method)

	if r.Method == "POST" {

		//fmt.Printf("Req: %s %s\n", r.Host, r.URL.Path)
		//url := html.EscapeString(r.URL.Path)
		//fmt.Println(url)
		//spliturl := strings.Split(url, "/")
		//for _, str := range spliturl {
		//	fmt.Println(str)
		//}

		//before := s[0]
		//after := s[1]
		//fmt.Println(before,after)

		body, err := ioutil.ReadAll(r.Body)
		if err != nil {

			http.Error(w, "Error reading request body", http.StatusInternalServerError)
		}

		fmt.Println(string(body))

		fmt.Fprint(w, "Success")

	} else {

		http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
	}
}

func main() {

	//accept front end files
	fs := http.FileServer(http.Dir("dashboard"))
	http.Handle("/dashboard/", http.StripPrefix("/dashboard", fs))

	//create mux to identify post type
	mux := http.NewServeMux()
	mux.HandleFunc("/push", parsePost)

	/*s := "postgres://user:pass@host.com:5432/path?k=v#f"

	  u, err := url.Parse(s)
	  if err != nil {
	      panic(err)
	  }
	  fmt.Println(u.Scheme)

	  fmt.Println(u.User)
	  fmt.Println(u.User.Username())
	  p, _ := u.User.Password()
	  fmt.Println(p)

	  fmt.Println(u.Host)
	  host, port, _ := net.SplitHostPort(u.Host)
	  fmt.Println(host)
	  fmt.Println(port)
	  fmt.Println(u.Path)
	  fmt.Println(u.Fragment)
	  fmt.Println(u.RawQuery)
	  m, _ := url.ParseQuery(u.RawQuery)
	  fmt.Println(m)
	  fmt.Println(m["k"][0])
	*/

	log.Println("Listening...")
	http.ListenAndServe(":8080", mux)
}
<commit_msg>Add comments.  Remove unused code<commit_after>package main

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

//function to collect post requests
func parsePost(w http.ResponseWriter, r *http.Request) {

	//Check if request is a POST request
	if r.Method == "POST" {

		//Read the body of the request.  If thers an error, return an error.
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "Error reading request body", http.StatusInternalServerError)
			return
		}

		//Print out body for debug
		fmt.Println(string(body))

		//Parse body JSON into object

		//Send success as a response
		fmt.Fprint(w, "Success")

	} else {
		//Return an error if not POST
		http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
	}
}

func main() {

	//accept front end files
	fs := http.FileServer(http.Dir("dashboard"))
	http.Handle("/dashboard/", http.StripPrefix("/dashboard", fs))

	//create mux to identify post type
	mux := http.NewServeMux()
	mux.HandleFunc("/push", parsePost)

	/*s := "postgres://user:pass@host.com:5432/path?k=v#f"

	  u, err := url.Parse(s)
	  if err != nil {
	      panic(err)
	  }
	  fmt.Println(u.Scheme)

	  fmt.Println(u.User)
	  fmt.Println(u.User.Username())
	  p, _ := u.User.Password()
	  fmt.Println(p)

	  fmt.Println(u.Host)
	  host, port, _ := net.SplitHostPort(u.Host)
	  fmt.Println(host)
	  fmt.Println(port)
	  fmt.Println(u.Path)
	  fmt.Println(u.Fragment)
	  fmt.Println(u.RawQuery)
	  m, _ := url.ParseQuery(u.RawQuery)
	  fmt.Println(m)
	  fmt.Println(m["k"][0])
	*/

	log.Println("Listening...")
	http.ListenAndServe(":8080", mux)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path"
	"runtime"
	"runtime/pprof"
	"sort"
	"strconv"
	"strings"
	"sync"
)

const (
	CmdDisplayMax = 32
	// max length of /proc/$PID/comm
	CommMax = 16
	// from ps_mem - average error due to truncation in the kernel
	// pss calculations
	PssAdjust    = .5
	pageSize     = 4096
	mapDetailLen = len("Size:                  4 kB")

	usage = `Usage: %s [OPTION...]
Simple, accurate RAM and swap reporting.

Options:
`
)

var (
	memProfile string
	cpuProfile string

	tyPss          = []byte("Pss:")
	tySwap         = []byte("Swap:")
	tyPrivateClean = []byte("Private_Clean:")
	tyPrivateDirty = []byte("Private_Dirty:")
)

// store info about a command (group of processes), similar to how
// ps_mem works.
type CmdMemInfo struct {
	PIDs    []int
	Name    string
	Pss     float64
	Private uint64
	Swapped uint64
}

type MapInfo struct {
	Inode uint64
	Name  string
}

// mapLine is a line from /proc/$PID/maps, or one of the same header
// lines from smaps.
func NewMapInfo(mapLine []byte) MapInfo {
	var mi MapInfo
	var err error
	pieces := splitSpaces(mapLine)
	if len(pieces) == 6 {
		mi.Name = string(pieces[5])
	}
	mi.Inode, err = ParseUint(pieces[4], 10, 64)
	if err != nil {
		panic(fmt.Sprintf("NewMapInfo: Atoi(%s): %s (%s)",
			string(pieces[4]), err, string(mapLine)))
	}
	return mi
}

func (mi MapInfo) IsAnon() bool {
	return mi.Inode == 0
}

// isDigit returns true if the rune d represents an ascii digit
// between 0 and 9, inclusive.
func isDigit(d uint8) bool {
	return d >= '0' && d <= '9'
}

// pidList returns a list of the process-IDs of every currently
// running process on the local system.
func pidList() ([]int, error) {
	procLs, err := ioutil.ReadDir("/proc")
	if err != nil {
		return nil, fmt.Errorf("ReadDir(/proc): %s", err)
	}

	pids := make([]int, 0, len(procLs))
	for _, pInfo := range procLs {
		if !isDigit(pInfo.Name()[0]) || !pInfo.IsDir() {
			continue
		}
		pidInt, err := strconv.Atoi(pInfo.Name())
		if err != nil {
			return nil, fmt.Errorf("Atoi(%s): %s", pInfo.Name(), err)
		}
		pids = append(pids, pidInt)
	}
	return pids, nil
}

// procName gets the process name for a worker.  It first checks the
// value of /proc/$PID/cmdline.  If setproctitle(3) has been called,
// it will use this.  Otherwise it uses the value of
// path.Base(/proc/$PID/exe), which has info on whether the executable
// has changed since the process was exec'ed.
func procName(pid int) (string, error) {
	p, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pid))
	// this would return an error if the PID doesn't
	// exist, or if the PID refers to a kernel thread.
	if err != nil {
		return "", nil
	}
	// cmdline is the null separated list of command line
	// arguments for the process, unless setproctitle(3)
	// has been called, in which case it is the
	argsB, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
	if err != nil {
		return "", fmt.Errorf("ReadFile(%s): %s", fmt.Sprintf("/proc/%d/cmdline", pid), err)
	}
	args := strings.Split(string(argsB), "\000")
	n := args[0]

	nTrunc := n
	if len(n) > CommMax {
		nTrunc = n[:CommMax]
	}
	if strings.HasPrefix(p, nTrunc) {
		n = path.Base(p)
	}
	return n, nil
}

// splitSpaces returns a slice of byte slices which are the space
// delimited words from the original byte slice.  Unlike
// strings.Split($X, " "), runs of multiple spaces in a row are
// discarded.  NOTE WELL: this only checks for spaces (' '), other
// unicode whitespace isn't supported.
func splitSpaces(b []byte) [][]byte {
	// most lines in smaps have the form "Swap: 4 kB", so
	// preallocate the slice's array appropriately.
	res := make([][]byte, 0, 3)
	start := 0
	lenB := len(b)
	for i := 0; i < lenB - 1; i++ {
		if b[i] == ' ' {
			start = i + 1
		} else if b[i+1] == ' ' {
			res = append(res, b[start:i+1])
			start = i + 1
		}
	}
	if start != lenB && b[start] != ' ' {
		res = append(res, b[start:lenB])
	}
	return res
}

// procMem returns the amount of Pss, shared, and swapped out memory
// used.  The swapped out amount refers to anonymous pages only.
func procMem(pid int) (pss float64, priv, swap uint64, err error) {
	fPath := fmt.Sprintf("/proc/%d/smaps", pid)
	f, err := os.Open(fPath)
	if err != nil {
		err = fmt.Errorf("os.Open(%s): %s", fPath, err)
		return
	}
	//var curr MapInfo
	r := bufio.NewReaderSize(f, pageSize)
	for {
		var l []byte
		var isPrefix bool
		l, isPrefix, err = r.ReadLine()
		// this should never happen, so take the easy way out.
		if isPrefix {
			err = fmt.Errorf("ReadLine(%s): isPrefix", fPath)
		}
		if err != nil {
			// if we've got EOF, then we're simply done
			// processing smaps.
			if err == io.EOF {
				err = nil
				break
			}
			// otherwise error out
			err = fmt.Errorf("ReadLine(%s): %s", fPath, err)
			return
		}

		if len(l) != mapDetailLen {
			//curr = NewMapInfo(l)
			continue
		}
		pieces := splitSpaces(l)
		ty := pieces[0]
		var v uint64
		if bytes.Equal(ty, tyPss) {
			v, err = ParseUint(pieces[1], 10, 64)
			if err != nil {
				err = fmt.Errorf("Atoi(%s): %s", string(pieces[1]), err)
				return
			}
			pss += float64(v) + PssAdjust
		} else if bytes.Equal(ty, tyPrivateClean) || bytes.Equal(ty, tyPrivateDirty) {
			v, err = ParseUint(pieces[1], 10, 64)
			if err != nil {
				err = fmt.Errorf("Atoi(%s): %s", string(pieces[1]), err)
				return
			}
			priv += v
		} else if bytes.Equal(ty, tySwap) {
			v, err = ParseUint(pieces[1], 10, 64)
			if err != nil {
				err = fmt.Errorf("Atoi(%s): %s", string(pieces[1]), err)
				return
			}
			swap += v
		}
	}
	return
}

func worker(pidRequest chan int, wg *sync.WaitGroup, result chan *CmdMemInfo) {
	for pid := range pidRequest {
		var err error
		cmi := new(CmdMemInfo)

		cmi.PIDs = []int{pid}
		cmi.Name, err = procName(pid)
		if err != nil {
			log.Printf("procName(%d): %s", pid, err)
			wg.Done()
			continue
		} else if cmi.Name == "" {
			// XXX: This happens with kernel
			// threads. maybe warn? idk.
			wg.Done()
			continue
		}

		cmi.Pss, cmi.Private, cmi.Swapped, err = procMem(pid)
		if err != nil {
			log.Printf("procMem(%d): %s", pid, err)
			wg.Done()
			continue
		}

		result <- cmi
		wg.Done()
	}
}

type byTotal []*CmdMemInfo

func (c byTotal) Len() int           { return len(c) }
func (c byTotal) Less(i, j int) bool { return c[i].Pss < c[j].Pss }
func (c byTotal) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, usage, os.Args[0])
		flag.PrintDefaults()
	}

	flag.StringVar(&memProfile, "memprofile", "",
		"write memory profile to this file")
	flag.StringVar(&cpuProfile, "cpuprofile", "",
		"write cpu profile to this file")

	flag.Parse()
}

// startProfiling enables memory and/or CPU profiling if the
// appropriate command line flags have been set.
func startProfiling() {
	var err error
	// if we've passed in filenames to dump profiling data too,
	// start collecting profiling data.
	if memProfile != "" {
		runtime.MemProfileRate = 1
	}
	if cpuProfile != "" {
		var f *os.File
		if f, err = os.Create(cpuProfile); err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
	}
}

func stopProfiling() {
	if memProfile != "" {
		runtime.GC()
		f, err := os.Create(memProfile)
		if err != nil {
			log.Println(err)
		}
		pprof.WriteHeapProfile(f)
		f.Close()
	}
	if cpuProfile != "" {
		pprof.StopCPUProfile()
		cpuProfile = ""
	}
}

func main() {
	startProfiling()
	defer stopProfiling()

	// need to be root to read map info for other user's
	// processes.
	if os.Geteuid() != 0 {
		fmt.Printf("FATAL: root required.\n")
		return
	}

	pids, err := pidList()
	if err != nil {
		log.Printf("pidList: %s", err)
		return
	}

	var wg sync.WaitGroup
	work := make(chan int, len(pids))
	result := make(chan *CmdMemInfo, len(pids))

	// give us as much parallelism as possible
	nCPU := runtime.NumCPU()
	runtime.GOMAXPROCS(nCPU)
	for i := 0; i < nCPU; i++ {
		go worker(work, &wg, result)
	}

	wg.Add(len(pids))
	for _, pid := range pids {
		work <- pid
	}
	wg.Wait()

	// aggregate similar processes by command name.
	cmdMap := map[string]*CmdMemInfo{}
loop:
	for {
		// this only works correctly because we a channel
		// where the buffer size >= the number of potential
		// results.
		select {
		case c := <-result:
			n := c.Name
			if _, ok := cmdMap[n]; !ok {
				cmdMap[n] = c
				continue
			}
			cmdMap[n].PIDs = append(cmdMap[n].PIDs, c.PIDs...)
			cmdMap[n].Pss += c.Pss
			cmdMap[n].Private += c.Private
			cmdMap[n].Swapped += c.Swapped
		default:
			break loop
		}
	}

	// extract map values to a slice so we can sort them
	cmds := make([]*CmdMemInfo, 0, len(cmdMap))
	for _, c := range cmdMap {
		cmds = append(cmds, c)
	}
	sort.Sort(byTotal(cmds))

	// keep track of total RAM and swap usage
	var totPss, totSwap float64

	fmt.Printf("%10s%10s%10s\t%s\n", "MB RAM", "PRIVATE", "SWAPPED", "PROCESS (COUNT)")
	for _, c := range cmds {
		n := c.Name
		if len(n) > CmdDisplayMax {
			if n[0] == '[' {
				n = n[:strings.IndexRune(n, ']')+1]
			} else {
				n = n[:CmdDisplayMax]
			}
		}
		s := ""
		if c.Swapped > 0 {
			swap := float64(c.Swapped) / 1024.
			totSwap += swap
			s = fmt.Sprintf("%10.1f", swap)
		}
		pss := float64(c.Pss) / 1024.
		fmt.Printf("%10.1f%10.1f%10s\t%s (%d)\n", pss, float64(c.Private)/1024., s, n, len(c.PIDs))
		totPss += pss
	}
	fmt.Printf("#%9.1f%20.1f\tTOTAL USED BY PROCESSES\n", totPss, totSwap)
}
<commit_msg>splitSpaces: call len(b) directly<commit_after>package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path"
	"runtime"
	"runtime/pprof"
	"sort"
	"strconv"
	"strings"
	"sync"
)

const (
	CmdDisplayMax = 32
	// max length of /proc/$PID/comm
	CommMax = 16
	// from ps_mem - average error due to truncation in the kernel
	// pss calculations
	PssAdjust    = .5
	pageSize     = 4096
	mapDetailLen = len("Size:                  4 kB")

	usage = `Usage: %s [OPTION...]
Simple, accurate RAM and swap reporting.

Options:
`
)

var (
	memProfile string
	cpuProfile string

	tyPss          = []byte("Pss:")
	tySwap         = []byte("Swap:")
	tyPrivateClean = []byte("Private_Clean:")
	tyPrivateDirty = []byte("Private_Dirty:")
)

// store info about a command (group of processes), similar to how
// ps_mem works.
type CmdMemInfo struct {
	PIDs    []int
	Name    string
	Pss     float64
	Private uint64
	Swapped uint64
}

type MapInfo struct {
	Inode uint64
	Name  string
}

// mapLine is a line from /proc/$PID/maps, or one of the same header
// lines from smaps.
func NewMapInfo(mapLine []byte) MapInfo {
	var mi MapInfo
	var err error
	pieces := splitSpaces(mapLine)
	if len(pieces) == 6 {
		mi.Name = string(pieces[5])
	}
	mi.Inode, err = ParseUint(pieces[4], 10, 64)
	if err != nil {
		panic(fmt.Sprintf("NewMapInfo: Atoi(%s): %s (%s)",
			string(pieces[4]), err, string(mapLine)))
	}
	return mi
}

func (mi MapInfo) IsAnon() bool {
	return mi.Inode == 0
}

// isDigit returns true if the rune d represents an ascii digit
// between 0 and 9, inclusive.
func isDigit(d uint8) bool {
	return d >= '0' && d <= '9'
}

// pidList returns a list of the process-IDs of every currently
// running process on the local system.
func pidList() ([]int, error) {
	procLs, err := ioutil.ReadDir("/proc")
	if err != nil {
		return nil, fmt.Errorf("ReadDir(/proc): %s", err)
	}

	pids := make([]int, 0, len(procLs))
	for _, pInfo := range procLs {
		if !isDigit(pInfo.Name()[0]) || !pInfo.IsDir() {
			continue
		}
		pidInt, err := strconv.Atoi(pInfo.Name())
		if err != nil {
			return nil, fmt.Errorf("Atoi(%s): %s", pInfo.Name(), err)
		}
		pids = append(pids, pidInt)
	}
	return pids, nil
}

// procName gets the process name for a worker.  It first checks the
// value of /proc/$PID/cmdline.  If setproctitle(3) has been called,
// it will use this.  Otherwise it uses the value of
// path.Base(/proc/$PID/exe), which has info on whether the executable
// has changed since the process was exec'ed.
func procName(pid int) (string, error) {
	p, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pid))
	// this would return an error if the PID doesn't
	// exist, or if the PID refers to a kernel thread.
	if err != nil {
		return "", nil
	}
	// cmdline is the null separated list of command line
	// arguments for the process, unless setproctitle(3)
	// has been called, in which case it is the
	argsB, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
	if err != nil {
		return "", fmt.Errorf("ReadFile(%s): %s", fmt.Sprintf("/proc/%d/cmdline", pid), err)
	}
	args := strings.Split(string(argsB), "\000")
	n := args[0]

	nTrunc := n
	if len(n) > CommMax {
		nTrunc = n[:CommMax]
	}
	if strings.HasPrefix(p, nTrunc) {
		n = path.Base(p)
	}
	return n, nil
}

// splitSpaces returns a slice of byte slices which are the space
// delimited words from the original byte slice.  Unlike
// strings.Split($X, " "), runs of multiple spaces in a row are
// discarded.  NOTE WELL: this only checks for spaces (' '), other
// unicode whitespace isn't supported.
func splitSpaces(b []byte) [][]byte {
	// most lines in smaps have the form "Swap: 4 kB", so
	// preallocate the slice's array appropriately.
	res := make([][]byte, 0, 3)
	start := 0
	for i := 0; i < len(b)-1; i++ {
		if b[i] == ' ' {
			start = i + 1
		} else if b[i+1] == ' ' {
			res = append(res, b[start:i+1])
			start = i + 1
		}
	}
	if start != len(b) && b[start] != ' ' {
		res = append(res, b[start:])
	}
	return res
}

// procMem returns the amount of Pss, shared, and swapped out memory
// used.  The swapped out amount refers to anonymous pages only.
func procMem(pid int) (pss float64, priv, swap uint64, err error) {
	fPath := fmt.Sprintf("/proc/%d/smaps", pid)
	f, err := os.Open(fPath)
	if err != nil {
		err = fmt.Errorf("os.Open(%s): %s", fPath, err)
		return
	}
	//var curr MapInfo
	r := bufio.NewReaderSize(f, pageSize)
	for {
		var l []byte
		var isPrefix bool
		l, isPrefix, err = r.ReadLine()
		// this should never happen, so take the easy way out.
		if isPrefix {
			err = fmt.Errorf("ReadLine(%s): isPrefix", fPath)
		}
		if err != nil {
			// if we've got EOF, then we're simply done
			// processing smaps.
			if err == io.EOF {
				err = nil
				break
			}
			// otherwise error out
			err = fmt.Errorf("ReadLine(%s): %s", fPath, err)
			return
		}

		if len(l) != mapDetailLen {
			//curr = NewMapInfo(l)
			continue
		}
		pieces := splitSpaces(l)
		ty := pieces[0]
		var v uint64
		if bytes.Equal(ty, tyPss) {
			v, err = ParseUint(pieces[1], 10, 64)
			if err != nil {
				err = fmt.Errorf("Atoi(%s): %s", string(pieces[1]), err)
				return
			}
			pss += float64(v) + PssAdjust
		} else if bytes.Equal(ty, tyPrivateClean) || bytes.Equal(ty, tyPrivateDirty) {
			v, err = ParseUint(pieces[1], 10, 64)
			if err != nil {
				err = fmt.Errorf("Atoi(%s): %s", string(pieces[1]), err)
				return
			}
			priv += v
		} else if bytes.Equal(ty, tySwap) {
			v, err = ParseUint(pieces[1], 10, 64)
			if err != nil {
				err = fmt.Errorf("Atoi(%s): %s", string(pieces[1]), err)
				return
			}
			swap += v
		}
	}
	return
}

func worker(pidRequest chan int, wg *sync.WaitGroup, result chan *CmdMemInfo) {
	for pid := range pidRequest {
		var err error
		cmi := new(CmdMemInfo)

		cmi.PIDs = []int{pid}
		cmi.Name, err = procName(pid)
		if err != nil {
			log.Printf("procName(%d): %s", pid, err)
			wg.Done()
			continue
		} else if cmi.Name == "" {
			// XXX: This happens with kernel
			// threads. maybe warn? idk.
			wg.Done()
			continue
		}

		cmi.Pss, cmi.Private, cmi.Swapped, err = procMem(pid)
		if err != nil {
			log.Printf("procMem(%d): %s", pid, err)
			wg.Done()
			continue
		}

		result <- cmi
		wg.Done()
	}
}

type byTotal []*CmdMemInfo

func (c byTotal) Len() int           { return len(c) }
func (c byTotal) Less(i, j int) bool { return c[i].Pss < c[j].Pss }
func (c byTotal) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, usage, os.Args[0])
		flag.PrintDefaults()
	}

	flag.StringVar(&memProfile, "memprofile", "",
		"write memory profile to this file")
	flag.StringVar(&cpuProfile, "cpuprofile", "",
		"write cpu profile to this file")

	flag.Parse()
}

// startProfiling enables memory and/or CPU profiling if the
// appropriate command line flags have been set.
func startProfiling() {
	var err error
	// if we've passed in filenames to dump profiling data too,
	// start collecting profiling data.
	if memProfile != "" {
		runtime.MemProfileRate = 1
	}
	if cpuProfile != "" {
		var f *os.File
		if f, err = os.Create(cpuProfile); err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
	}
}

func stopProfiling() {
	if memProfile != "" {
		runtime.GC()
		f, err := os.Create(memProfile)
		if err != nil {
			log.Println(err)
		}
		pprof.WriteHeapProfile(f)
		f.Close()
	}
	if cpuProfile != "" {
		pprof.StopCPUProfile()
		cpuProfile = ""
	}
}

func main() {
	startProfiling()
	defer stopProfiling()

	// need to be root to read map info for other user's
	// processes.
	if os.Geteuid() != 0 {
		fmt.Printf("FATAL: root required.\n")
		return
	}

	pids, err := pidList()
	if err != nil {
		log.Printf("pidList: %s", err)
		return
	}

	var wg sync.WaitGroup
	work := make(chan int, len(pids))
	result := make(chan *CmdMemInfo, len(pids))

	// give us as much parallelism as possible
	nCPU := runtime.NumCPU()
	runtime.GOMAXPROCS(nCPU)
	for i := 0; i < nCPU; i++ {
		go worker(work, &wg, result)
	}

	wg.Add(len(pids))
	for _, pid := range pids {
		work <- pid
	}
	wg.Wait()

	// aggregate similar processes by command name.
	cmdMap := map[string]*CmdMemInfo{}
loop:
	for {
		// this only works correctly because we a channel
		// where the buffer size >= the number of potential
		// results.
		select {
		case c := <-result:
			n := c.Name
			if _, ok := cmdMap[n]; !ok {
				cmdMap[n] = c
				continue
			}
			cmdMap[n].PIDs = append(cmdMap[n].PIDs, c.PIDs...)
			cmdMap[n].Pss += c.Pss
			cmdMap[n].Private += c.Private
			cmdMap[n].Swapped += c.Swapped
		default:
			break loop
		}
	}

	// extract map values to a slice so we can sort them
	cmds := make([]*CmdMemInfo, 0, len(cmdMap))
	for _, c := range cmdMap {
		cmds = append(cmds, c)
	}
	sort.Sort(byTotal(cmds))

	// keep track of total RAM and swap usage
	var totPss, totSwap float64

	fmt.Printf("%10s%10s%10s\t%s\n", "MB RAM", "PRIVATE", "SWAPPED", "PROCESS (COUNT)")
	for _, c := range cmds {
		n := c.Name
		if len(n) > CmdDisplayMax {
			if n[0] == '[' {
				n = n[:strings.IndexRune(n, ']')+1]
			} else {
				n = n[:CmdDisplayMax]
			}
		}
		s := ""
		if c.Swapped > 0 {
			swap := float64(c.Swapped) / 1024.
			totSwap += swap
			s = fmt.Sprintf("%10.1f", swap)
		}
		pss := float64(c.Pss) / 1024.
		fmt.Printf("%10.1f%10.1f%10s\t%s (%d)\n", pss, float64(c.Private)/1024., s, n, len(c.PIDs))
		totPss += pss
	}
	fmt.Printf("#%9.1f%20.1f\tTOTAL USED BY PROCESSES\n", totPss, totSwap)
}
<|endoftext|>


<commit_before>package main

import "fmt"

var version = "v0.2.0"
var dirty = ""

func main() {
	displayVersion := fmt.Sprintf("rip %s%s",
		version,
		dirty)
	Execute(displayVersion)
}
<commit_msg>bump version -> v0.2.1<commit_after>package main

import "fmt"

var version = "v0.2.1"
var dirty = ""

func main() {
	displayVersion := fmt.Sprintf("rip %s%s",
		version,
		dirty)
	Execute(displayVersion)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strings"
	"os/exec"
	"io/ioutil"

	"github.com/drone/drone-plugin-go/plugin"
)

type Fabric struct {
	Commands  []string `json:"commands"`
}

func main() {
	workspace := plugin.Workspace{}
	vargs := Fabric{}

	plugin.Param("workspace", &workspace)
	plugin.Param("vargs", &vargs)

	// parse the parameters
	if err := plugin.Parse(); err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	err := ioutil.WriteFile("/tmp/ssh_key", []byte(workspace.Keys.Public), 0644)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	fabfile := fmt.Sprintf("--fabfile=%s/fabfile.py", workspace.Path)

	for _, c := range vargs.Commands {
		command := fmt.Sprintf("%s %s", fabfile, c)
		fabArgs := strings.Split(command, " ")
		fabArgs = append(fabArgs, "-i", "/tmp/ssh_key")
		_, err := exec.Command("fab", fabArgs...).Output()
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(2)
		}
	}
}
<commit_msg>Am I generating the error?<commit_after>package main

import (
	"fmt"
	"os"
	"strings"
	"os/exec"
	"io/ioutil"

	"github.com/drone/drone-plugin-go/plugin"
)

type Fabric struct {
	Commands  []string `json:"commands"`
}

func main() {
	workspace := plugin.Workspace{}
	vargs := Fabric{}

	plugin.Param("workspace", &workspace)
	plugin.Param("vargs", &vargs)

	// parse the parameters
	if err := plugin.Parse(); err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	err := ioutil.WriteFile("/tmp/ssh_key", []byte(workspace.Keys.Public), 0644)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	fabfile := fmt.Sprintf("--fabfile=%s/fabfile.py", workspace.Path)

	for _, c := range vargs.Commands {
		command := fmt.Sprintf("%s %s", fabfile, c)
		fabArgs := strings.Split(command, " ")
		fabArgs = append(fabArgs, "-i", "/tmp/ssh_key")
		_, err := exec.Command("fab", fabArgs...).Output()
		if err != nil {
			fmt.Println(err)
			os.Exit(1000)
		}
	}
}
<|endoftext|>


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

import (
	"bufio"
	"context"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"flag"
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"

	"golang.org/x/sync/errgroup"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/prometheus/common/log"
)

var (
	printVersion = flag.Bool("version", false, "Print the version and exit")

	cfgFile  = flag.String("config.file", "expexp.yaml", "The path to the configuration file.")
	cfgDirs  StringSliceFlag
	skipDirs = flag.Bool("config.skip-dirs", false, "Skip non existent -config.dirs entries instead of terminating.")

	addr = flag.String("web.listen-address", ":9999", "The address to listen on for HTTP requests.")

	bearerToken     = flag.String("web.bearer.token", "", "Bearer authentication token.")
	bearerTokenFile = flag.String("web.bearer.token-file", "", "File containing the Bearer authentication token.")

	certPath = flag.String("web.tls.cert", "cert.pem", "Path to cert")
	keyPath  = flag.String("web.tls.key", "key.pem", "Path to key")
	caPath   = flag.String("web.tls.ca", "ca.pem", "Path to CA to auth clients against")
	verify   = flag.Bool("web.tls.verify", false, "Disable client verification")
	tlsAddr  = flag.String("web.tls.listen-address", "", "The address to listen on for HTTPS requests.")

	tPath = flag.String("web.telemetry-path", "/metrics", "The address to listen on for HTTP requests.")
	pPath = flag.String("web.proxy-path", "/proxy", "The address to listen on for HTTP requests.")

	proxyDuration = prometheus.NewSummaryVec(
		prometheus.SummaryOpts{
			Name: "expexp_proxy_duration_seconds",
			Help: "Duration of proxying requests to configured exporters",
		},
		[]string{"module"},
	)
	proxyErrorCount = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "expexp_proxy_errors_total",
			Help: "Counts of errors",
		},
		[]string{"module"},
	)
	proxyTimeoutCount = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "expexp_proxy_timeout_errors_total",
			Help: "Counts of the number of times a proxy timeout occurred",
		},
		[]string{"module"},
	)

	proxyMalformedCount = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "expexp_malformed_content_errors_total",
			Help: "Counts of unparsable scrape content errors",
		},
		[]string{"module"},
	)
)

func init() {
	// register the collector metrics in the default
	// registry.
	prometheus.MustRegister(proxyDuration)
	prometheus.MustRegister(proxyTimeoutCount)
	prometheus.MustRegister(proxyErrorCount)
	prometheus.MustRegister(proxyMalformedCount)
	prometheus.MustRegister(cmdStartsCount)
	prometheus.MustRegister(cmdFailsCount)
	flag.Var(&cfgDirs, "config.dirs", "The path to directories of configuration files, can be specified multiple times.")
	//log.AddFlags(flag.CommandLine)
}

func main() {
	flag.Parse()
	if *printVersion {
		fmt.Fprintf(os.Stderr, "Version: %s\n", versionStr())
		os.Exit(0)
	}
	cfg := &config{
		Modules: make(map[string]*moduleConfig),
		XXX:     make(map[string]interface{}),
	}
	if *cfgFile != "" {
		r, err := os.Open(*cfgFile)
		if err != nil {
			log.Fatalf("%+v", err)
		}
		cfg, err = readConfig(r)
		if err != nil {
			log.Fatalf("%+v", err)
		}
		_ = r.Close()
		for mn, _ := range cfg.Modules {
			log.Debugf("read module config '%s' from: %s", mn, *cfgFile)
		}
	}

cfgDirs:
	for _, cfgDir := range cfgDirs {
		mfs, err := ioutil.ReadDir(cfgDir)
		if err != nil {
			if *skipDirs && os.IsNotExist(err) {
				log.Warnf("skipping non existent config.dirs entry '%s'", cfgDir)
				continue cfgDirs
			}
			log.Fatalf("failed reading directory: %s, %v", cfgDir, err)
		}

		yamlSuffixes := map[string]bool{
			".yml":  true,
			".yaml": true,
		}
		for _, mf := range mfs {
			fullpath := filepath.Join(cfgDir, mf.Name())
			if mf.IsDir() || !yamlSuffixes[filepath.Ext(mf.Name())] {
				log.Warnf("skipping non-yaml file %v", fullpath)
				continue
			}
			mn := strings.TrimSuffix(mf.Name(), filepath.Ext(mf.Name()))
			if _, ok := cfg.Modules[mn]; ok {
				log.Fatalf("module %s is already defined", mn)
			}
			r, err := os.Open(fullpath)
			if err != nil {
				log.Fatalf("failed to open config file: %s: %v", fullpath, err)
			}
			mcfg, err := readModuleConfig(mn, r)
			_ = r.Close()
			if err != nil {
				log.Fatalf("failed reading configs %s, %s", fullpath, err)
			}
			log.Debugf("read module config '%s' from: %s", mn, fullpath)
			cfg.Modules[mn] = mcfg
		}
	}
	if len(cfg.Modules) == 0 {
		log.Errorln("no modules loaded from any config file")
	}

	var bToken string
	if *bearerToken != "" {
		bToken = *bearerToken
	}
	if *bearerTokenFile != "" {
		if bToken != "" {
			log.Fatalln("web.bearer.token and web.bearer.token-file are mutually exclusive options")
		}
		f, err := os.Open(*bearerTokenFile)
		if err != nil {
			log.Fatalf("error opening bearer.token-file '%s': %v", *bearerTokenFile, err)
		}
		defer f.Close()
		sc := bufio.NewScanner(f)
		if !sc.Scan() {
			if err := sc.Err(); err != nil {
				log.Fatalf("error reading first line ot web.bearer.token-file '%s': %v", *bearerTokenFile, err)
			}
			log.Fatalf("error reading token from first line of web.bearer.token-file '%s'", *bearerTokenFile)
		}
		t := strings.TrimSpace(sc.Text())
		if t == "" {
			log.Fatalf("first line of bearer.token-file must contain the token '%s'", *bearerTokenFile)
		}
		_ = f.Close()
		bToken = t
	}

	proxyPath := path.Clean("/" + *pPath)
	telePath := path.Clean("/" + *tPath)
	if proxyPath == telePath {
		log.Fatalf("flags -web.proxy-path and -web.telemetry-path can not be set to the same value: %s", proxyPath)
	}

	http.HandleFunc(proxyPath, cfg.doProxy)
	http.HandleFunc("/", cfg.listModules)
	http.Handle(telePath, promhttp.Handler())

	var handler http.Handler
	if bToken == "" {
		handler = http.DefaultServeMux
	} else {
		handler = &BearerAuthMiddleware{http.DefaultServeMux, bToken}
	}

	eg, ctx := errgroup.WithContext(context.Background())

	if *addr == "" && *tlsAddr == "" {
		log.Info("No web addresses to listen on, nothing to do!")
		os.Exit(0)
	}

	if *addr != "" {
		eg.Go(func() error {
			return http.ListenAndServe(*addr, handler)
		})
	}

	if *tlsAddr != "" {
		eg.Go(func() error {
			cert, err := tls.LoadX509KeyPair(*certPath, *keyPath)
			if err != nil {
				log.Fatalf("Could not parse key/cert, " + err.Error())
			}

			tlsConfig := tls.Config{
				Certificates: []tls.Certificate{cert},
			}
			tlsConfig.BuildNameToCertificate()

			if *verify {
				pool := x509.NewCertPool()
				cabs, err := ioutil.ReadFile(*caPath)
				if err != nil {
					log.Fatalf("Could not open ca file,, " + err.Error())
				}
				ok := pool.AppendCertsFromPEM(cabs)
				if !ok {
					log.Fatalf("Failed loading ca certs")
				}
				tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
				tlsConfig.ClientCAs = pool
			}

			srvr := http.Server{
				Addr:      *tlsAddr,
				TLSConfig: &tlsConfig,
				Handler:   handler,
			}
			err = srvr.ListenAndServeTLS(*certPath, *keyPath)
			if err != nil {
				log.Fatalf("Failed starting TLS server, %v", err)
			}
			return err
		})
	}

	<-ctx.Done()
	log.Fatal(ctx.Err())
}

func (cfg *config) doProxy(w http.ResponseWriter, r *http.Request) {
	mod, ok := r.URL.Query()["module"]
	if !ok {
		log.Errorf("no module given")
		http.Error(w, fmt.Sprintf("require parameter module is missing%v\n", mod), http.StatusBadRequest)
		return
	}

	log.Debugf("running module %v\n", mod)

	var h http.Handler
	if m, ok := cfg.Modules[mod[0]]; !ok {
		proxyErrorCount.WithLabelValues("unknown").Inc()
		log.Warnf("unknown module requested  %v\n", mod)
		http.Error(w, fmt.Sprintf("unknown module %v\n", mod), http.StatusNotFound)
		return
	} else {
		m.name = mod[0]
		h = m
	}

	h.ServeHTTP(w, r)
}

func (cfg *config) listModules(w http.ResponseWriter, r *http.Request) {
	switch r.Header.Get("Accept") {
	case "application/json":
		log.Debugf("Listing modules in json")
		moduleJson, err := json.Marshal(cfg.Modules)
		if err != nil {
			log.Error(err)
			http.Error(w, "Failed to produce JSON", http.StatusInternalServerError)
		}
		w.Header().Set("Content-Type", "application/json")
		w.Write(moduleJson)
	default:
		log.Debugf("Listing modules in html")
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		tmpl := template.Must(template.New("modules").Parse(`

Exporters:

					{{range $name, $cfg := .Modules}}

{{$name}}

					{{end}}

`))
		err := tmpl.Execute(w, cfg)
		if err != nil {
			log.Error(err)
			http.Error(w, "Can't execute the template", http.StatusInternalServerError)
		}
	}
	return
}

func (m moduleConfig) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	st := time.Now()
	defer func() {
		proxyDuration.WithLabelValues(m.name).Observe(float64(time.Since(st)) / float64(time.Second))
	}()

	nr := r
	cancel := func() {}
	if m.Timeout != 0 {
		log.Debugf("setting module %v timeout to %v", m.name, m.Timeout)

		var ctx context.Context
		ctx, cancel = context.WithTimeout(r.Context(), m.Timeout)
		nr = r.WithContext(ctx)
	}
	defer cancel()

	switch m.Method {
	case "exec":
		m.Exec.mcfg = &m
		m.Exec.ServeHTTP(w, nr)
	case "http":
		m.HTTP.mcfg = &m
		m.HTTP.ServeHTTP(w, nr)
	default:
		log.Errorf("unknown module method  %v\n", m.Method)
		proxyErrorCount.WithLabelValues(m.name).Inc()
		http.Error(w, fmt.Sprintf("unknown module method %v\n", m.Method), http.StatusNotFound)
		return
	}
}

// StringSliceFlags collects multiple uses of a named flag into a slice.
type StringSliceFlag []string

func (s *StringSliceFlag) String() string {
	// Just some representation output, not actually used to parse the input,
	// the flag is instead supposed to be specified multiple times.
	return strings.Join(*s, ", ")
}

func (s *StringSliceFlag) Set(value string) error {
	*s = append(*s, value)
	return nil
}
<commit_msg>Add missing return on http.Error<commit_after>// Copyright 2016 Qubit Ltd.
// 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 main

import (
	"bufio"
	"context"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"flag"
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"

	"golang.org/x/sync/errgroup"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/prometheus/common/log"
)

var (
	printVersion = flag.Bool("version", false, "Print the version and exit")

	cfgFile  = flag.String("config.file", "expexp.yaml", "The path to the configuration file.")
	cfgDirs  StringSliceFlag
	skipDirs = flag.Bool("config.skip-dirs", false, "Skip non existent -config.dirs entries instead of terminating.")

	addr = flag.String("web.listen-address", ":9999", "The address to listen on for HTTP requests.")

	bearerToken     = flag.String("web.bearer.token", "", "Bearer authentication token.")
	bearerTokenFile = flag.String("web.bearer.token-file", "", "File containing the Bearer authentication token.")

	certPath = flag.String("web.tls.cert", "cert.pem", "Path to cert")
	keyPath  = flag.String("web.tls.key", "key.pem", "Path to key")
	caPath   = flag.String("web.tls.ca", "ca.pem", "Path to CA to auth clients against")
	verify   = flag.Bool("web.tls.verify", false, "Disable client verification")
	tlsAddr  = flag.String("web.tls.listen-address", "", "The address to listen on for HTTPS requests.")

	tPath = flag.String("web.telemetry-path", "/metrics", "The address to listen on for HTTP requests.")
	pPath = flag.String("web.proxy-path", "/proxy", "The address to listen on for HTTP requests.")

	proxyDuration = prometheus.NewSummaryVec(
		prometheus.SummaryOpts{
			Name: "expexp_proxy_duration_seconds",
			Help: "Duration of proxying requests to configured exporters",
		},
		[]string{"module"},
	)
	proxyErrorCount = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "expexp_proxy_errors_total",
			Help: "Counts of errors",
		},
		[]string{"module"},
	)
	proxyTimeoutCount = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "expexp_proxy_timeout_errors_total",
			Help: "Counts of the number of times a proxy timeout occurred",
		},
		[]string{"module"},
	)

	proxyMalformedCount = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "expexp_malformed_content_errors_total",
			Help: "Counts of unparsable scrape content errors",
		},
		[]string{"module"},
	)
)

func init() {
	// register the collector metrics in the default
	// registry.
	prometheus.MustRegister(proxyDuration)
	prometheus.MustRegister(proxyTimeoutCount)
	prometheus.MustRegister(proxyErrorCount)
	prometheus.MustRegister(proxyMalformedCount)
	prometheus.MustRegister(cmdStartsCount)
	prometheus.MustRegister(cmdFailsCount)
	flag.Var(&cfgDirs, "config.dirs", "The path to directories of configuration files, can be specified multiple times.")
	//log.AddFlags(flag.CommandLine)
}

func main() {
	flag.Parse()
	if *printVersion {
		fmt.Fprintf(os.Stderr, "Version: %s\n", versionStr())
		os.Exit(0)
	}
	cfg := &config{
		Modules: make(map[string]*moduleConfig),
		XXX:     make(map[string]interface{}),
	}
	if *cfgFile != "" {
		r, err := os.Open(*cfgFile)
		if err != nil {
			log.Fatalf("%+v", err)
		}
		cfg, err = readConfig(r)
		if err != nil {
			log.Fatalf("%+v", err)
		}
		_ = r.Close()
		for mn, _ := range cfg.Modules {
			log.Debugf("read module config '%s' from: %s", mn, *cfgFile)
		}
	}

cfgDirs:
	for _, cfgDir := range cfgDirs {
		mfs, err := ioutil.ReadDir(cfgDir)
		if err != nil {
			if *skipDirs && os.IsNotExist(err) {
				log.Warnf("skipping non existent config.dirs entry '%s'", cfgDir)
				continue cfgDirs
			}
			log.Fatalf("failed reading directory: %s, %v", cfgDir, err)
		}

		yamlSuffixes := map[string]bool{
			".yml":  true,
			".yaml": true,
		}
		for _, mf := range mfs {
			fullpath := filepath.Join(cfgDir, mf.Name())
			if mf.IsDir() || !yamlSuffixes[filepath.Ext(mf.Name())] {
				log.Warnf("skipping non-yaml file %v", fullpath)
				continue
			}
			mn := strings.TrimSuffix(mf.Name(), filepath.Ext(mf.Name()))
			if _, ok := cfg.Modules[mn]; ok {
				log.Fatalf("module %s is already defined", mn)
			}
			r, err := os.Open(fullpath)
			if err != nil {
				log.Fatalf("failed to open config file: %s: %v", fullpath, err)
			}
			mcfg, err := readModuleConfig(mn, r)
			_ = r.Close()
			if err != nil {
				log.Fatalf("failed reading configs %s, %s", fullpath, err)
			}
			log.Debugf("read module config '%s' from: %s", mn, fullpath)
			cfg.Modules[mn] = mcfg
		}
	}
	if len(cfg.Modules) == 0 {
		log.Errorln("no modules loaded from any config file")
	}

	var bToken string
	if *bearerToken != "" {
		bToken = *bearerToken
	}
	if *bearerTokenFile != "" {
		if bToken != "" {
			log.Fatalln("web.bearer.token and web.bearer.token-file are mutually exclusive options")
		}
		f, err := os.Open(*bearerTokenFile)
		if err != nil {
			log.Fatalf("error opening bearer.token-file '%s': %v", *bearerTokenFile, err)
		}
		defer f.Close()
		sc := bufio.NewScanner(f)
		if !sc.Scan() {
			if err := sc.Err(); err != nil {
				log.Fatalf("error reading first line ot web.bearer.token-file '%s': %v", *bearerTokenFile, err)
			}
			log.Fatalf("error reading token from first line of web.bearer.token-file '%s'", *bearerTokenFile)
		}
		t := strings.TrimSpace(sc.Text())
		if t == "" {
			log.Fatalf("first line of bearer.token-file must contain the token '%s'", *bearerTokenFile)
		}
		_ = f.Close()
		bToken = t
	}

	proxyPath := path.Clean("/" + *pPath)
	telePath := path.Clean("/" + *tPath)
	if proxyPath == telePath {
		log.Fatalf("flags -web.proxy-path and -web.telemetry-path can not be set to the same value: %s", proxyPath)
	}

	http.HandleFunc(proxyPath, cfg.doProxy)
	http.HandleFunc("/", cfg.listModules)
	http.Handle(telePath, promhttp.Handler())

	var handler http.Handler
	if bToken == "" {
		handler = http.DefaultServeMux
	} else {
		handler = &BearerAuthMiddleware{http.DefaultServeMux, bToken}
	}

	eg, ctx := errgroup.WithContext(context.Background())

	if *addr == "" && *tlsAddr == "" {
		log.Info("No web addresses to listen on, nothing to do!")
		os.Exit(0)
	}

	if *addr != "" {
		eg.Go(func() error {
			return http.ListenAndServe(*addr, handler)
		})
	}

	if *tlsAddr != "" {
		eg.Go(func() error {
			cert, err := tls.LoadX509KeyPair(*certPath, *keyPath)
			if err != nil {
				log.Fatalf("Could not parse key/cert, " + err.Error())
			}

			tlsConfig := tls.Config{
				Certificates: []tls.Certificate{cert},
			}
			tlsConfig.BuildNameToCertificate()

			if *verify {
				pool := x509.NewCertPool()
				cabs, err := ioutil.ReadFile(*caPath)
				if err != nil {
					log.Fatalf("Could not open ca file,, " + err.Error())
				}
				ok := pool.AppendCertsFromPEM(cabs)
				if !ok {
					log.Fatalf("Failed loading ca certs")
				}
				tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
				tlsConfig.ClientCAs = pool
			}

			srvr := http.Server{
				Addr:      *tlsAddr,
				TLSConfig: &tlsConfig,
				Handler:   handler,
			}
			err = srvr.ListenAndServeTLS(*certPath, *keyPath)
			if err != nil {
				log.Fatalf("Failed starting TLS server, %v", err)
			}
			return err
		})
	}

	<-ctx.Done()
	log.Fatal(ctx.Err())
}

func (cfg *config) doProxy(w http.ResponseWriter, r *http.Request) {
	mod, ok := r.URL.Query()["module"]
	if !ok {
		log.Errorf("no module given")
		http.Error(w, fmt.Sprintf("require parameter module is missing%v\n", mod), http.StatusBadRequest)
		return
	}

	log.Debugf("running module %v\n", mod)

	var h http.Handler
	if m, ok := cfg.Modules[mod[0]]; !ok {
		proxyErrorCount.WithLabelValues("unknown").Inc()
		log.Warnf("unknown module requested  %v\n", mod)
		http.Error(w, fmt.Sprintf("unknown module %v\n", mod), http.StatusNotFound)
		return
	} else {
		m.name = mod[0]
		h = m
	}

	h.ServeHTTP(w, r)
}

func (cfg *config) listModules(w http.ResponseWriter, r *http.Request) {
	switch r.Header.Get("Accept") {
	case "application/json":
		log.Debugf("Listing modules in json")
		moduleJson, err := json.Marshal(cfg.Modules)
		if err != nil {
			log.Error(err)
			http.Error(w, "Failed to produce JSON", http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		w.Write(moduleJson)
	default:
		log.Debugf("Listing modules in html")
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		tmpl := template.Must(template.New("modules").Parse(`

Exporters:

					{{range $name, $cfg := .Modules}}

{{$name}}

					{{end}}

`))
		err := tmpl.Execute(w, cfg)
		if err != nil {
			log.Error(err)
			http.Error(w, "Can't execute the template", http.StatusInternalServerError)
		}
	}
	return
}

func (m moduleConfig) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	st := time.Now()
	defer func() {
		proxyDuration.WithLabelValues(m.name).Observe(float64(time.Since(st)) / float64(time.Second))
	}()

	nr := r
	cancel := func() {}
	if m.Timeout != 0 {
		log.Debugf("setting module %v timeout to %v", m.name, m.Timeout)

		var ctx context.Context
		ctx, cancel = context.WithTimeout(r.Context(), m.Timeout)
		nr = r.WithContext(ctx)
	}
	defer cancel()

	switch m.Method {
	case "exec":
		m.Exec.mcfg = &m
		m.Exec.ServeHTTP(w, nr)
	case "http":
		m.HTTP.mcfg = &m
		m.HTTP.ServeHTTP(w, nr)
	default:
		log.Errorf("unknown module method  %v\n", m.Method)
		proxyErrorCount.WithLabelValues(m.name).Inc()
		http.Error(w, fmt.Sprintf("unknown module method %v\n", m.Method), http.StatusNotFound)
		return
	}
}

// StringSliceFlags collects multiple uses of a named flag into a slice.
type StringSliceFlag []string

func (s *StringSliceFlag) String() string {
	// Just some representation output, not actually used to parse the input,
	// the flag is instead supposed to be specified multiple times.
	return strings.Join(*s, ", ")
}

func (s *StringSliceFlag) Set(value string) error {
	*s = append(*s, value)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/docker/docker/builder/parser"
	"os"
)

type Instruction struct {
	Node *parser.Node
}

func (i Instruction) MarshalJSON() ([]byte, error) {
	if i.Node.Next == nil {
		return json.Marshal(&struct {
			Instruction string `json:"instruction"`
		}{
			Instruction: i.Node.Value,
		})
	} else {
		return json.Marshal(&struct {
			Instruction string `json:"instruction"`
			Value       string `json:"value"`
		}{
			Instruction: i.Node.Value,
			Value:       i.Node.Next.Value,
		})
	}
}

func main() {
	var f *os.File
	var err error

	if len(os.Args) < 2 {
		fmt.Println("please supply filename(s)")
		os.Exit(1)
	}

	for _, fn := range os.Args[1:] {
		f, err = os.Open(fn)
		if err != nil {
			panic(err)
		}

		ast, err := parser.Parse(f)
		if err != nil {
			panic(err)
		} else {
			instructions := []Instruction{}
			for _, n := range ast.Children {
				in := Instruction{n}
				instructions = append(instructions, in)
			}
			b, _ := json.Marshal(instructions)
			fmt.Println(string(b))

			fmt.Println(ast.Dump())
		}
	}
}
<commit_msg>credit solution<commit_after>package main

// used http://stackoverflow.com/a/15997595/909579

import (
	"encoding/json"
	"fmt"
	"github.com/docker/docker/builder/parser"
	"os"
)

type Instruction struct {
	Node *parser.Node
}

func (i Instruction) MarshalJSON() ([]byte, error) {
	if i.Node.Next == nil {
		return json.Marshal(&struct {
			Instruction string `json:"instruction"`
		}{
			Instruction: i.Node.Value,
		})
	} else {
		return json.Marshal(&struct {
			Instruction string `json:"instruction"`
			Value       string `json:"value"`
		}{
			Instruction: i.Node.Value,
			Value:       i.Node.Next.Value,
		})
	}
}

func main() {
	var f *os.File
	var err error

	if len(os.Args) < 2 {
		fmt.Println("please supply filename(s)")
		os.Exit(1)
	}

	for _, fn := range os.Args[1:] {
		f, err = os.Open(fn)
		if err != nil {
			panic(err)
		}

		ast, err := parser.Parse(f)
		if err != nil {
			panic(err)
		} else {
			instructions := []Instruction{}
			for _, n := range ast.Children {
				in := Instruction{n}
				instructions = append(instructions, in)
			}
			b, _ := json.Marshal(instructions)
			fmt.Println(string(b))

			fmt.Println(ast.Dump())
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/facebookgo/grace/gracehttp"
	"github.com/gin-gonic/gin"
	"github.com/justinas/nosurf"
	"net/http"
	"strings"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/cors"
	"github.com/eirka/eirka-libs/db"
	"github.com/eirka/eirka-libs/redis"
	"github.com/eirka/eirka-libs/user"

	local "github.com/eirka/eirka-post/config"
	c "github.com/eirka/eirka-post/controllers"
	m "github.com/eirka/eirka-post/middleware"
	u "github.com/eirka/eirka-post/utils"
)

var (
	version = "0.9.1"
)

func init() {

	// Database connection settings
	dbase := db.Database{

		User:           local.Settings.Database.User,
		Password:       local.Settings.Database.Password,
		Proto:          local.Settings.Database.Proto,
		Host:           local.Settings.Database.Host,
		Database:       local.Settings.Database.Database,
		MaxIdle:        local.Settings.Database.MaxIdle,
		MaxConnections: local.Settings.Database.MaxConnections,
	}

	// Set up DB connection
	dbase.NewDb()

	// Get limits and stuff from database
	config.GetDatabaseSettings()

	// redis settings
	r := redis.Redis{
		// Redis address and max pool connections
		Protocol:       local.Settings.Redis.Protocol,
		Address:        local.Settings.Redis.Address,
		MaxIdle:        local.Settings.Redis.MaxIdle,
		MaxConnections: local.Settings.Redis.MaxConnections,
	}

	// Set up Redis connection
	r.NewRedisCache()

	// set auth middleware secret
	user.Secret = local.Settings.Session.Secret

	// print the starting info
	StartInfo()

	// Print out config
	config.Print()

	// Print out config
	local.Print()

	// check what services are available
	u.CheckServices()

	// Print capabilities
	u.Services.Print()

	// set cors domains
	cors.SetDomains(local.Settings.CORS.Sites, strings.Split("POST", ","))

}

func main() {
	r := gin.Default()

	r.Use(cors.CORS())

	r.GET("/uptime", c.UptimeController)
	r.NoRoute(c.ErrorController)

	// all users
	public := r.Group("/")
	public.Use(user.Auth(false))

	public.POST("/thread/new", m.GetAntiSpamCookie(), c.ThreadController)
	public.POST("/thread/reply", m.GetAntiSpamCookie(), c.ReplyController)
	public.POST("/tag/new", m.GetAntiSpamCookie(), c.NewTagController)
	public.POST("/tag/add", m.GetAntiSpamCookie(), c.AddTagController)
	public.POST("/register", c.RegisterController)
	public.POST("/login", c.LoginController)

	// requires user perms
	users := r.Group("/user")
	users.Use(user.Auth(true))

	users.POST("/favorite", c.FavoritesController)
	users.POST("/password", c.PasswordController)
	users.POST("/email", c.EmailController)

	csrf := nosurf.New(r)
	csrf.SetFailureHandler(http.HandlerFunc(csrfFailHandler))

	s := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", local.Settings.Post.Address, local.Settings.Post.Port),
		Handler: csrf,
	}

	gracehttp.Serve(s)

}

func csrfFailHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "%s\n", nosurf.Reason(r))
}

func StartInfo() {

	fmt.Println(strings.Repeat("*", 60))
	fmt.Printf("%-20v\n\n", "PRAM-POST")
	fmt.Printf("%-20v%40v\n", "Version", version)
	fmt.Println(strings.Repeat("*", 60))

}
<commit_msg>add csrf<commit_after>package main

import (
	"fmt"
	"github.com/facebookgo/grace/gracehttp"
	"github.com/gin-gonic/gin"
	"github.com/justinas/nosurf"
	"net/http"
	"strings"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/cors"
	"github.com/eirka/eirka-libs/db"
	"github.com/eirka/eirka-libs/redis"
	"github.com/eirka/eirka-libs/user"

	local "github.com/eirka/eirka-post/config"
	c "github.com/eirka/eirka-post/controllers"
	m "github.com/eirka/eirka-post/middleware"
	u "github.com/eirka/eirka-post/utils"
)

var (
	version = "0.9.1"
)

func init() {

	// Database connection settings
	dbase := db.Database{

		User:           local.Settings.Database.User,
		Password:       local.Settings.Database.Password,
		Proto:          local.Settings.Database.Proto,
		Host:           local.Settings.Database.Host,
		Database:       local.Settings.Database.Database,
		MaxIdle:        local.Settings.Database.MaxIdle,
		MaxConnections: local.Settings.Database.MaxConnections,
	}

	// Set up DB connection
	dbase.NewDb()

	// Get limits and stuff from database
	config.GetDatabaseSettings()

	// redis settings
	r := redis.Redis{
		// Redis address and max pool connections
		Protocol:       local.Settings.Redis.Protocol,
		Address:        local.Settings.Redis.Address,
		MaxIdle:        local.Settings.Redis.MaxIdle,
		MaxConnections: local.Settings.Redis.MaxConnections,
	}

	// Set up Redis connection
	r.NewRedisCache()

	// set auth middleware secret
	user.Secret = local.Settings.Session.Secret

	// print the starting info
	StartInfo()

	// Print out config
	config.Print()

	// Print out config
	local.Print()

	// check what services are available
	u.CheckServices()

	// Print capabilities
	u.Services.Print()

	// set cors domains
	cors.SetDomains(local.Settings.CORS.Sites, strings.Split("POST", ","))

}

func main() {
	r := gin.Default()

	r.Use(cors.CORS())

	r.GET("/uptime", c.UptimeController)
	r.NoRoute(c.ErrorController)

	// all users
	public := r.Group("/")
	public.Use(user.Auth(false))

	public.POST("/thread/new", m.GetAntiSpamCookie(), c.ThreadController)
	public.POST("/thread/reply", m.GetAntiSpamCookie(), c.ReplyController)
	public.POST("/tag/new", m.GetAntiSpamCookie(), c.NewTagController)
	public.POST("/tag/add", m.GetAntiSpamCookie(), c.AddTagController)
	public.POST("/register", c.RegisterController)
	public.POST("/login", c.LoginController)

	// requires user perms
	users := r.Group("/user")
	users.Use(user.Auth(true))

	users.POST("/favorite", c.FavoritesController)
	users.POST("/password", c.PasswordController)
	users.POST("/email", c.EmailController)

	csrf := nosurf.New(r)
	csrf.SetFailureHandler(http.HandlerFunc(csrfFailHandler))

	csrf.SetBaseCookie(http.Cookie{
		Path:     "/",
		HttpOnly: true,
	})

	s := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", local.Settings.Post.Address, local.Settings.Post.Port),
		Handler: csrf,
	}

	gracehttp.Serve(s)

}

func csrfFailHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "%s\n", nosurf.Reason(r))
}

func StartInfo() {

	fmt.Println(strings.Repeat("*", 60))
	fmt.Printf("%-20v\n\n", "PRAM-POST")
	fmt.Printf("%-20v%40v\n", "Version", version)
	fmt.Println(strings.Repeat("*", 60))

}
<|endoftext|>


<commit_before>package main // import "github.com/CenturyLinkLabs/panamaxcli"

import (
	"errors"
	"fmt"
	"os"
	"os/user"
	"strings"

	"github.com/CenturyLinkLabs/panamax-remote-agent-go/client"
	"github.com/CenturyLinkLabs/panamaxcli/actions"
	"github.com/CenturyLinkLabs/panamaxcli/config"
	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
)

var (
	Config   config.Config
	Commands []cli.Command
)

func init() {
	client.DefaultHTTPTimeout = 10

	Commands = []cli.Command{
		{
			Name:    "remote",
			Aliases: []string{"re"},
			Usage:   "Manage remotes",
			Subcommands: []cli.Command{
				{
					Name:    "list",
					Aliases: []string{"l"},
					Usage:   "List remotes",
					Action:  remoteListAction,
				},
				{
					Name:    "describe",
					Aliases: []string{"d"},
					Usage:   "Describe a remote",
					Before:  actionRequiresArgument("remote name"),
					Action:  remoteDescribeAction,
				},
				{
					Name:        "add",
					Usage:       "Add a remote",
					Description: "Arguments are the name of the remote and the path to the token file.",
					Before:      actionRequiresArgument("remote name", "file path"),
					Action:      remoteAddAction,
				},
				{
					Name:        "active",
					Usage:       "Set the active remote",
					Description: "Passing a remote name as an argument makes it the active remote.",
					Before:      actionRequiresArgument("remote name"),
					Action:      setActiveRemoteAction,
				},
				{
					Name:        "remove",
					Usage:       "Remove a remote",
					Description: "Argument is a remote name.",
					Before:      actionRequiresArgument("remote name"),
					Action:      removeRemoteAction,
				},
				{
					Name:        "token",
					Usage:       "Show the remote's token",
					Description: "Argument is a remote name.",
					Before:      actionRequiresArgument("remote name"),
					Action:      getTokenAction,
				},
			},
		},
		{
			Name:    "deployment",
			Aliases: []string{"de"},
			Usage:   "Manage deployments",
			Before:  actionRequiresActiveRemote,
			Subcommands: []cli.Command{
				{
					Name:    "list",
					Aliases: []string{"l"},
					Usage:   "List deployments",
					Action:  deploymentsListAction,
				},
				{
					Name:        "describe",
					Aliases:     []string{"d"},
					Usage:       "Describe a deployment",
					Description: "Argument is a deployment ID.",
					Before:      actionRequiresArgument("deployment ID"),
					Action:      describeDeploymentAction,
				},
				{
					Name:        "redeploy",
					Usage:       "Redeploy a deployment",
					Description: "Argument is a deployment ID.",
					Before:      actionRequiresArgument("deployment ID"),
					Action:      redeployDeploymentAction,
				},
				{
					Name:        "delete",
					Usage:       "Delete a deployment",
					Description: "Argument is a deployment ID.",
					Before:      actionRequiresArgument("deployment ID"),
					Action:      deleteDeploymentAction,
				},
			},
		},
	}
}

func main() {
	app := cli.NewApp()
	app.Name = "panamaxcli"
	app.Version = "0.0.1"
	app.Usage = "Panamax command-line utility."
	app.Authors = []cli.Author{{"CenturyLink Labs", "clt-labs-futuretech@centurylink.com"}}
	app.Commands = Commands
	app.Before = initializeApp
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug",
			Usage: "Enable verbose logging",
		},
	}

	app.Run(os.Args)
}

func initializeApp(c *cli.Context) error {
	if c.GlobalBool("debug") {
		// Remote Agent Client will write to logrus with helpful info!
		log.SetLevel(log.DebugLevel)
	}

	return loadConfig(c)
}

func loadConfig(c *cli.Context) error {
	usr, _ := user.Current()
	dir := usr.HomeDir
	fileConfig := config.FileConfig{Path: dir + "/.agents"}
	err := fileConfig.Load()
	if err != nil {
		log.Error(err)
		return err
	}
	Config = config.Config(&fileConfig)

	return nil
}

func actionRequiresArgument(args ...string) func(c *cli.Context) error {
	return func(c *cli.Context) error {
		if len(c.Args()) != len(args) {
			s := strings.Join(args, ", ")
			message := fmt.Sprintf("This command requires the following arguments: %s", s)
			log.Errorln(message)
			return errors.New(message)
		}

		return nil
	}
}

func actionRequiresActiveRemote(c *cli.Context) error {
	if Config.Active() == nil {
		message := "an active remote is required for this command"
		log.Errorln(message)
		return errors.New(message)
	}

	return nil
}

func remoteAddAction(c *cli.Context) {
	name := c.Args().First()
	path := c.Args().Get(1)

	output, err := actions.AddRemote(Config, name, path)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func removeRemoteAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.RemoveRemote(Config, name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func remoteListAction(c *cli.Context) {
	output := actions.ListRemotes(Config)
	fmt.Println(output.ToPrettyOutput())
}

func remoteDescribeAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.DescribeRemote(Config, name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func setActiveRemoteAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.SetActiveRemote(Config, name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func deploymentsListAction(c *cli.Context) {
	output, err := actions.ListDeployments(*Config.Active())

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(output.ToPrettyOutput())
}

func describeDeploymentAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.DescribeDeployment(*Config.Active(), name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func redeployDeploymentAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.RedeployDeployment(*Config.Active(), name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func deleteDeploymentAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.DeleteDeployment(*Config.Active(), name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func getTokenAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.GetRemoteToken(Config, name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}
<commit_msg>Handle error when current user can't be determined.<commit_after>package main // import "github.com/CenturyLinkLabs/panamaxcli"

import (
	"errors"
	"fmt"
	"os"
	"os/user"
	"strings"

	"github.com/CenturyLinkLabs/panamax-remote-agent-go/client"
	"github.com/CenturyLinkLabs/panamaxcli/actions"
	"github.com/CenturyLinkLabs/panamaxcli/config"
	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
)

var (
	Config   config.Config
	Commands []cli.Command
)

func init() {
	client.DefaultHTTPTimeout = 10

	Commands = []cli.Command{
		{
			Name:    "remote",
			Aliases: []string{"re"},
			Usage:   "Manage remotes",
			Subcommands: []cli.Command{
				{
					Name:    "list",
					Aliases: []string{"l"},
					Usage:   "List remotes",
					Action:  remoteListAction,
				},
				{
					Name:    "describe",
					Aliases: []string{"d"},
					Usage:   "Describe a remote",
					Before:  actionRequiresArgument("remote name"),
					Action:  remoteDescribeAction,
				},
				{
					Name:        "add",
					Usage:       "Add a remote",
					Description: "Arguments are the name of the remote and the path to the token file.",
					Before:      actionRequiresArgument("remote name", "file path"),
					Action:      remoteAddAction,
				},
				{
					Name:        "active",
					Usage:       "Set the active remote",
					Description: "Passing a remote name as an argument makes it the active remote.",
					Before:      actionRequiresArgument("remote name"),
					Action:      setActiveRemoteAction,
				},
				{
					Name:        "remove",
					Usage:       "Remove a remote",
					Description: "Argument is a remote name.",
					Before:      actionRequiresArgument("remote name"),
					Action:      removeRemoteAction,
				},
				{
					Name:        "token",
					Usage:       "Show the remote's token",
					Description: "Argument is a remote name.",
					Before:      actionRequiresArgument("remote name"),
					Action:      getTokenAction,
				},
			},
		},
		{
			Name:    "deployment",
			Aliases: []string{"de"},
			Usage:   "Manage deployments",
			Before:  actionRequiresActiveRemote,
			Subcommands: []cli.Command{
				{
					Name:    "list",
					Aliases: []string{"l"},
					Usage:   "List deployments",
					Action:  deploymentsListAction,
				},
				{
					Name:        "describe",
					Aliases:     []string{"d"},
					Usage:       "Describe a deployment",
					Description: "Argument is a deployment ID.",
					Before:      actionRequiresArgument("deployment ID"),
					Action:      describeDeploymentAction,
				},
				{
					Name:        "redeploy",
					Usage:       "Redeploy a deployment",
					Description: "Argument is a deployment ID.",
					Before:      actionRequiresArgument("deployment ID"),
					Action:      redeployDeploymentAction,
				},
				{
					Name:        "delete",
					Usage:       "Delete a deployment",
					Description: "Argument is a deployment ID.",
					Before:      actionRequiresArgument("deployment ID"),
					Action:      deleteDeploymentAction,
				},
			},
		},
	}
}

func main() {
	app := cli.NewApp()
	app.Name = "panamaxcli"
	app.Version = "0.0.1"
	app.Usage = "Panamax command-line utility."
	app.Authors = []cli.Author{{"CenturyLink Labs", "clt-labs-futuretech@centurylink.com"}}
	app.Commands = Commands
	app.Before = initializeApp
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug",
			Usage: "Enable verbose logging",
		},
	}

	app.Run(os.Args)
}

func initializeApp(c *cli.Context) error {
	if c.GlobalBool("debug") {
		// Remote Agent Client will write to logrus with helpful info!
		log.SetLevel(log.DebugLevel)
	}

	// Surprise! CLI wants an error from this method but, only uses it to abort
	// execution, not for display anywhere.
	if err := loadConfig(c); err != nil {
		log.Error(err)
	}

	return nil
}

func loadConfig(c *cli.Context) error {
	user, err := user.Current()
	if err != nil {
		return err
	}
	dir := user.HomeDir
	fileConfig := config.FileConfig{Path: dir + "/.agents"}
	if err := fileConfig.Load(); err != nil {
		log.Error(err)
		return err
	}
	Config = config.Config(&fileConfig)

	return nil
}

func actionRequiresArgument(args ...string) func(c *cli.Context) error {
	return func(c *cli.Context) error {
		if len(c.Args()) != len(args) {
			s := strings.Join(args, ", ")
			message := fmt.Sprintf("This command requires the following arguments: %s", s)
			log.Errorln(message)
			return errors.New(message)
		}

		return nil
	}
}

func actionRequiresActiveRemote(c *cli.Context) error {
	if Config.Active() == nil {
		message := "an active remote is required for this command"
		log.Errorln(message)
		return errors.New(message)
	}

	return nil
}

func remoteAddAction(c *cli.Context) {
	name := c.Args().First()
	path := c.Args().Get(1)

	output, err := actions.AddRemote(Config, name, path)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func removeRemoteAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.RemoveRemote(Config, name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func remoteListAction(c *cli.Context) {
	output := actions.ListRemotes(Config)
	fmt.Println(output.ToPrettyOutput())
}

func remoteDescribeAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.DescribeRemote(Config, name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func setActiveRemoteAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.SetActiveRemote(Config, name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func deploymentsListAction(c *cli.Context) {
	output, err := actions.ListDeployments(*Config.Active())

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(output.ToPrettyOutput())
}

func describeDeploymentAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.DescribeDeployment(*Config.Active(), name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func redeployDeploymentAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.RedeployDeployment(*Config.Active(), name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func deleteDeploymentAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.DeleteDeployment(*Config.Active(), name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}

func getTokenAction(c *cli.Context) {
	name := c.Args().First()
	output, err := actions.GetRemoteToken(Config, name)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output.ToPrettyOutput())
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"time"

	"github.com/StackExchange/dnscontrol/commands"
	_ "github.com/StackExchange/dnscontrol/providers/_all"
)

//go:generate go run build/generate/generate.go build/generate/featureMatrix.go

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	os.Exit(commands.Run(versionString()))
}

// Version management. 2 Goals:
// 1. Someone who just does "go get" has at least some information.
// 2. If built with build/build.go, more specific build information gets put in.
// Update the number here manually each release, so at least we have a range for go-get people.
var (
	SHA       = ""
	Version   = "0.2.7"
	BuildTime = ""
)

// printVersion prints the version banner.
func versionString() string {
	var version string
	if SHA != "" {
		version = fmt.Sprintf("%s (%s)", Version, SHA)
	} else {
		version = fmt.Sprintf("%s-dev", Version) // no SHA. '0.x.y-dev' indicates it is run from source without build script.
	}
	if BuildTime != "" {
		i, err := strconv.ParseInt(BuildTime, 10, 64)
		if err == nil {
			tm := time.Unix(i, 0)
			version += fmt.Sprintf(" built %s", tm.Format(time.RFC822))
		}
	}
	return fmt.Sprintf("dnscontrol %s", version)
}
<commit_msg>Release v2.8<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"time"

	"github.com/StackExchange/dnscontrol/commands"
	_ "github.com/StackExchange/dnscontrol/providers/_all"
)

//go:generate go run build/generate/generate.go build/generate/featureMatrix.go

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	os.Exit(commands.Run(versionString()))
}

// Version management. 2 Goals:
// 1. Someone who just does "go get" has at least some information.
// 2. If built with build/build.go, more specific build information gets put in.
// Update the number here manually each release, so at least we have a range for go-get people.
var (
	SHA       = ""
	Version   = "0.2.8"
	BuildTime = ""
)

// printVersion prints the version banner.
func versionString() string {
	var version string
	if SHA != "" {
		version = fmt.Sprintf("%s (%s)", Version, SHA)
	} else {
		version = fmt.Sprintf("%s-dev", Version) // no SHA. '0.x.y-dev' indicates it is run from source without build script.
	}
	if BuildTime != "" {
		i, err := strconv.ParseInt(BuildTime, 10, 64)
		if err == nil {
			tm := time.Unix(i, 0)
			version += fmt.Sprintf(" built %s", tm.Format(time.RFC822))
		}
	}
	return fmt.Sprintf("dnscontrol %s", version)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"

	"pault.ag/go/debian/control"
)

func main() {
	reader, err := NewArchiveContentsReader(
		"http://http.debian.net/debian",
		// "http://localhost/fnord/",
		"unstable-debug",
		"main",
		"amd64",
	)
	if err != nil {
		panic(err)
	}
	defer reader.Close()

	index, err := control.ParseBinaryIndex(bufio.NewReader(reader))
	if err != nil {
		panic(err)
	}

	for _, entry := range index {
		for _, buildId := range entry.XDebugBuildIds {
			fmt.Printf("%s %s %s %s\n", buildId, entry.Source, entry.Version, entry.Filename)
		}
	}
}
<commit_msg>Remove X-<commit_after>package main

import (
	"bufio"
	"fmt"

	"pault.ag/go/debian/control"
)

func main() {
	reader, err := NewArchiveContentsReader(
		"http://http.debian.net/debian",
		// "http://localhost/fnord/",
		"unstable-debug",
		"main",
		"amd64",
	)
	if err != nil {
		panic(err)
	}
	defer reader.Close()

	index, err := control.ParseBinaryIndex(bufio.NewReader(reader))
	if err != nil {
		panic(err)
	}

	for _, entry := range index {
		for _, buildId := range entry.DebugBuildIds {
			fmt.Printf("%s %s %s %s\n", buildId, entry.Source, entry.Version, entry.Filename)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/facebookgo/grace/gracehttp"
	"github.com/gin-gonic/gin"
	"net/http"
	"strings"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/cors"
	"github.com/eirka/eirka-libs/db"
	"github.com/eirka/eirka-libs/redis"
	"github.com/eirka/eirka-libs/user"

	local "github.com/eirka/eirka-post/config"
	c "github.com/eirka/eirka-post/controllers"
	m "github.com/eirka/eirka-post/middleware"
	u "github.com/eirka/eirka-post/utils"
)

var (
	version = "0.9.1"
)

func init() {

	// Database connection settings
	dbase := db.Database{

		User:           local.Settings.Database.User,
		Password:       local.Settings.Database.Password,
		Proto:          local.Settings.Database.Proto,
		Host:           local.Settings.Database.Host,
		Database:       local.Settings.Database.Database,
		MaxIdle:        local.Settings.Database.MaxIdle,
		MaxConnections: local.Settings.Database.MaxConnections,
	}

	// Set up DB connection
	dbase.NewDb()

	// Get limits and stuff from database
	config.GetDatabaseSettings()

	// redis settings
	r := redis.Redis{
		// Redis address and max pool connections
		Protocol:       local.Settings.Redis.Protocol,
		Address:        local.Settings.Redis.Address,
		MaxIdle:        local.Settings.Redis.MaxIdle,
		MaxConnections: local.Settings.Redis.MaxConnections,
	}

	// Set up Redis connection
	r.NewRedisCache()

	// set auth middleware secret
	auth.Secret = local.Settings.Session.Secret

	// print the starting info
	StartInfo()

	// Print out config
	config.Print()

	// Print out config
	local.Print()

	// check what services are available
	u.CheckServices()

	// Print capabilities
	u.Services.Print()

	// set cors domains
	cors.SetDomains(local.Settings.CORS.Sites, strings.Split("POST", ","))

}

func main() {
	r := gin.Default()

	r.Use(cors.CORS())

	r.NoRoute(c.ErrorController)

	// all users
	public := r.Group("/")
	public.Use(auth.Auth(false))

	public.POST("/thread/new", m.GetAntiSpamCookie(), c.ThreadController)
	public.POST("/thread/reply", m.GetAntiSpamCookie(), c.ReplyController)
	public.POST("/tag/new", m.GetAntiSpamCookie(), c.NewTagController)
	public.POST("/tag/add", m.GetAntiSpamCookie(), c.AddTagController)
	public.POST("/register", c.RegisterController)
	public.POST("/login", c.LoginController)

	// requires user perms
	users := r.Group("/user")
	users.Use(auth.Auth(true))

	users.POST("/favorite", c.FavoritesController)
	users.POST("/password", c.PasswordController)
	users.POST("/email", c.EmailController)

	s := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", local.Settings.Post.Address, local.Settings.Post.Port),
		Handler: r,
	}

	gracehttp.Serve(s)

}

func StartInfo() {

	fmt.Println(strings.Repeat("*", 60))
	fmt.Printf("%-20v\n\n", "PRAM-POST")
	fmt.Printf("%-20v%40v\n", "Version", version)
	fmt.Println(strings.Repeat("*", 60))

}
<commit_msg>move user functions to lib<commit_after>package main

import (
	"fmt"
	"github.com/facebookgo/grace/gracehttp"
	"github.com/gin-gonic/gin"
	"net/http"
	"strings"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/cors"
	"github.com/eirka/eirka-libs/db"
	"github.com/eirka/eirka-libs/redis"
	"github.com/eirka/eirka-libs/user"

	local "github.com/eirka/eirka-post/config"
	c "github.com/eirka/eirka-post/controllers"
	m "github.com/eirka/eirka-post/middleware"
	u "github.com/eirka/eirka-post/utils"
)

var (
	version = "0.9.1"
)

func init() {

	// Database connection settings
	dbase := db.Database{

		User:           local.Settings.Database.User,
		Password:       local.Settings.Database.Password,
		Proto:          local.Settings.Database.Proto,
		Host:           local.Settings.Database.Host,
		Database:       local.Settings.Database.Database,
		MaxIdle:        local.Settings.Database.MaxIdle,
		MaxConnections: local.Settings.Database.MaxConnections,
	}

	// Set up DB connection
	dbase.NewDb()

	// Get limits and stuff from database
	config.GetDatabaseSettings()

	// redis settings
	r := redis.Redis{
		// Redis address and max pool connections
		Protocol:       local.Settings.Redis.Protocol,
		Address:        local.Settings.Redis.Address,
		MaxIdle:        local.Settings.Redis.MaxIdle,
		MaxConnections: local.Settings.Redis.MaxConnections,
	}

	// Set up Redis connection
	r.NewRedisCache()

	// set auth middleware secret
	user.Secret = local.Settings.Session.Secret

	// print the starting info
	StartInfo()

	// Print out config
	config.Print()

	// Print out config
	local.Print()

	// check what services are available
	u.CheckServices()

	// Print capabilities
	u.Services.Print()

	// set cors domains
	cors.SetDomains(local.Settings.CORS.Sites, strings.Split("POST", ","))

}

func main() {
	r := gin.Default()

	r.Use(cors.CORS())

	r.NoRoute(c.ErrorController)

	// all users
	public := r.Group("/")
	public.Use(user.Auth(false))

	public.POST("/thread/new", m.GetAntiSpamCookie(), c.ThreadController)
	public.POST("/thread/reply", m.GetAntiSpamCookie(), c.ReplyController)
	public.POST("/tag/new", m.GetAntiSpamCookie(), c.NewTagController)
	public.POST("/tag/add", m.GetAntiSpamCookie(), c.AddTagController)
	public.POST("/register", c.RegisterController)
	public.POST("/login", c.LoginController)

	// requires user perms
	users := r.Group("/user")
	users.Use(user.Auth(true))

	users.POST("/favorite", c.FavoritesController)
	users.POST("/password", c.PasswordController)
	users.POST("/email", c.EmailController)

	s := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", local.Settings.Post.Address, local.Settings.Post.Port),
		Handler: r,
	}

	gracehttp.Serve(s)

}

func StartInfo() {

	fmt.Println(strings.Repeat("*", 60))
	fmt.Printf("%-20v\n\n", "PRAM-POST")
	fmt.Printf("%-20v%40v\n", "Version", version)
	fmt.Println(strings.Repeat("*", 60))

}
<|endoftext|>