<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"strconv"
	"syscall"
	"time"

	"github.com/grafana/grafana/pkg/log"
	"github.com/grafana/grafana/pkg/login"
	"github.com/grafana/grafana/pkg/metrics"
	"github.com/grafana/grafana/pkg/plugins"
	alertingInit "github.com/grafana/grafana/pkg/services/alerting/init"
	"github.com/grafana/grafana/pkg/services/eventpublisher"
	"github.com/grafana/grafana/pkg/services/notifications"
	"github.com/grafana/grafana/pkg/services/search"
	"github.com/grafana/grafana/pkg/services/sqlstore"
	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/social"
)

var version = "3.1.0"
var commit = "NA"
var buildstamp string
var build_date string

var configFile = flag.String("config", "", "path to config file")
var homePath = flag.String("homepath", "", "path to grafana install/home path, defaults to working directory")
var pidFile = flag.String("pidfile", "", "path to pid file")
var exitChan = make(chan int)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	v := flag.Bool("v", false, "prints current version and exits")
	flag.Parse()
	if *v {
		fmt.Printf("Version %s (commit: %s)\n", version, commit)
		os.Exit(0)
	}

	buildstampInt64, _ := strconv.ParseInt(buildstamp, 10, 64)
	if buildstampInt64 == 0 {
		buildstampInt64 = time.Now().Unix()
	}

	setting.BuildVersion = version
	setting.BuildCommit = commit
	setting.BuildStamp = buildstampInt64

	go listenToSystemSignels()

	flag.Parse()
	writePIDFile()
	initRuntime()
	metrics.Init()

	search.Init()
	login.Init()
	social.NewOAuthService()
	eventpublisher.Init()
	plugins.Init()
	alertingInit.Init()

	if err := notifications.Init(); err != nil {
		log.Fatal(3, "Notification service failed to initialize", err)
	}

	StartServer()
	exitChan <- 0
}

func initRuntime() {
	err := setting.NewConfigContext(&setting.CommandLineArgs{
		Config:   *configFile,
		HomePath: *homePath,
		Args:     flag.Args(),
	})

	if err != nil {
		log.Fatal(3, err.Error())
	}

	logger := log.New("main")
	logger.Info("Starting Grafana", "version", version, "commit", commit, "compiled", time.Unix(setting.BuildStamp, 0))

	setting.LogConfigurationInfo()

	sqlstore.NewEngine()
	sqlstore.EnsureAdminUser()
}

func writePIDFile() {
	if *pidFile == "" {
		return
	}

	// Ensure the required directory structure exists.
	err := os.MkdirAll(filepath.Dir(*pidFile), 0700)
	if err != nil {
		log.Fatal(3, "Failed to verify pid directory", err)
	}

	// Retrieve the PID and write it.
	pid := strconv.Itoa(os.Getpid())
	if err := ioutil.WriteFile(*pidFile, []byte(pid), 0644); err != nil {
		log.Fatal(3, "Failed to write pidfile", err)
	}
}

func listenToSystemSignels() {
	signalChan := make(chan os.Signal, 1)
	code := 0

	signal.Notify(signalChan, os.Interrupt, os.Kill, syscall.SIGTERM)

	select {
	case sig := <-signalChan:
		log.Info("Received signal %s. shutting down", sig)
	case code = <-exitChan:
		switch code {
		case 0:
			log.Info("Shutting down")
		default:
			log.Warn("Shutting down")
		}
	}

	log.Close()
	os.Exit(code)
}
<commit_msg>fix typo<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"strconv"
	"syscall"
	"time"

	"github.com/grafana/grafana/pkg/log"
	"github.com/grafana/grafana/pkg/login"
	"github.com/grafana/grafana/pkg/metrics"
	"github.com/grafana/grafana/pkg/plugins"
	alertingInit "github.com/grafana/grafana/pkg/services/alerting/init"
	"github.com/grafana/grafana/pkg/services/eventpublisher"
	"github.com/grafana/grafana/pkg/services/notifications"
	"github.com/grafana/grafana/pkg/services/search"
	"github.com/grafana/grafana/pkg/services/sqlstore"
	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/social"
)

var version = "3.1.0"
var commit = "NA"
var buildstamp string
var build_date string

var configFile = flag.String("config", "", "path to config file")
var homePath = flag.String("homepath", "", "path to grafana install/home path, defaults to working directory")
var pidFile = flag.String("pidfile", "", "path to pid file")
var exitChan = make(chan int)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	v := flag.Bool("v", false, "prints current version and exits")
	flag.Parse()
	if *v {
		fmt.Printf("Version %s (commit: %s)\n", version, commit)
		os.Exit(0)
	}

	buildstampInt64, _ := strconv.ParseInt(buildstamp, 10, 64)
	if buildstampInt64 == 0 {
		buildstampInt64 = time.Now().Unix()
	}

	setting.BuildVersion = version
	setting.BuildCommit = commit
	setting.BuildStamp = buildstampInt64

	go listenToSystemSignals()

	flag.Parse()
	writePIDFile()
	initRuntime()
	metrics.Init()

	search.Init()
	login.Init()
	social.NewOAuthService()
	eventpublisher.Init()
	plugins.Init()
	alertingInit.Init()

	if err := notifications.Init(); err != nil {
		log.Fatal(3, "Notification service failed to initialize", err)
	}

	StartServer()
	exitChan <- 0
}

func initRuntime() {
	err := setting.NewConfigContext(&setting.CommandLineArgs{
		Config:   *configFile,
		HomePath: *homePath,
		Args:     flag.Args(),
	})

	if err != nil {
		log.Fatal(3, err.Error())
	}

	logger := log.New("main")
	logger.Info("Starting Grafana", "version", version, "commit", commit, "compiled", time.Unix(setting.BuildStamp, 0))

	setting.LogConfigurationInfo()

	sqlstore.NewEngine()
	sqlstore.EnsureAdminUser()
}

func writePIDFile() {
	if *pidFile == "" {
		return
	}

	// Ensure the required directory structure exists.
	err := os.MkdirAll(filepath.Dir(*pidFile), 0700)
	if err != nil {
		log.Fatal(3, "Failed to verify pid directory", err)
	}

	// Retrieve the PID and write it.
	pid := strconv.Itoa(os.Getpid())
	if err := ioutil.WriteFile(*pidFile, []byte(pid), 0644); err != nil {
		log.Fatal(3, "Failed to write pidfile", err)
	}
}

func listenToSystemSignals() {
	signalChan := make(chan os.Signal, 1)
	code := 0

	signal.Notify(signalChan, os.Interrupt, os.Kill, syscall.SIGTERM)

	select {
	case sig := <-signalChan:
		log.Info("Received signal %s. shutting down", sig)
	case code = <-exitChan:
		switch code {
		case 0:
			log.Info("Shutting down")
		default:
			log.Warn("Shutting down")
		}
	}

	log.Close()
	os.Exit(code)
}
<|endoftext|>


<commit_before>package analysis

import (
	"math"

	"gonum.org/v1/gonum/stat"

	"github.com/eseymour/cryptopals/pkg/crypto/xor"
)

// English language letter distribution generated by using 1-gram data collected
// by Peter Norvig at http://norvig.com/mayzner.html
var englishDistribution = [26]float64{
	0.08040605150731232, 0.014846487698236691, 0.03343773688810862,
	0.038169582783224694, 0.12492062534197067, 0.02403123383775965,
	0.018693758446142437, 0.05053301406632262, 0.07569277540220806,
	0.0015877372404490017, 0.00540513489633885, 0.0406898604777074,
	0.02511760599410516, 0.07233629221774214, 0.076406929387264,
	0.02135891018410595, 0.0012046892068254826, 0.06279420706085999,
	0.06512766562623011, 0.0927556484289489, 0.02729701843405106,
	0.01053251617932296, 0.01675664190911723, 0.002348568874531159,
	0.016649800974448417, 0.0008995069366664322,
}

// BreakXOREncryptByteKey finds byte key that is most likely to be the actual
// key to decode the ciphertext using character frequency analysis from English
// text. Lower scores indicate greater confidence that the key is correct
func BreakXOREncryptByteKey(ciphertext []byte) (key byte, score float64) {
	score = math.Inf(0)

	plaintext := make([]byte, len(ciphertext))
	for candidate := 0; candidate <= math.MaxUint8; candidate++ {
		xor.EncryptByteKey(plaintext, ciphertext, byte(candidate))

		var candidateFrequencies [26]float64
		count := 0
		for _, c := range plaintext {
			switch {
			case 'a' <= c && c <= 'z':
				c -= 'a'
			case 'A' <= c && c <= 'Z':
				c -= 'A'
			default:
				continue
			}
			candidateFrequencies[c]++
			count++
		}

		var expectedFrequencies [26]float64
		for i, p := range englishDistribution {
			expectedFrequencies[i] = p * float64(count)
		}

		// Scores are ChiSquare and multiplied by the ratio of plaintext length and
		// number of alphabet characters found
		candidateScore := stat.ChiSquare(candidateFrequencies[:], expectedFrequencies[:])
		candidateScore *= float64(len(plaintext)) / float64(count)

		if candidateScore < score {
			score = candidateScore
			key = byte(candidate)
		}
	}

	return key, score
}
<commit_msg>Make crypto/analysis functions return chiSquare instead of arbitrary score<commit_after>package analysis

import (
	"math"

	"gonum.org/v1/gonum/stat"

	"github.com/eseymour/cryptopals/pkg/crypto/xor"
)

// English language letter distribution generated by using 1-gram data collected
// by Peter Norvig at http://norvig.com/mayzner.html
var englishDistribution = [26]float64{
	0.08040605150731232, 0.014846487698236691, 0.03343773688810862,
	0.038169582783224694, 0.12492062534197067, 0.02403123383775965,
	0.018693758446142437, 0.05053301406632262, 0.07569277540220806,
	0.0015877372404490017, 0.00540513489633885, 0.0406898604777074,
	0.02511760599410516, 0.07233629221774214, 0.076406929387264,
	0.02135891018410595, 0.0012046892068254826, 0.06279420706085999,
	0.06512766562623011, 0.0927556484289489, 0.02729701843405106,
	0.01053251617932296, 0.01675664190911723, 0.002348568874531159,
	0.016649800974448417, 0.0008995069366664322,
}

// BreakXOREncryptByteKey finds byte key that is most likely to be the actual
// key to decode the ciphertext using character frequency analysis from English
// text. Lower scores indicate greater confidence that the key is correct
func BreakXOREncryptByteKey(ciphertext []byte) (key byte, chiSquare float64) {
	score := math.Inf(0)

	plaintext := make([]byte, len(ciphertext))
	for candidate := 0; candidate <= math.MaxUint8; candidate++ {
		xor.EncryptByteKey(plaintext, ciphertext, byte(candidate))

		var candidateFrequencies [26]float64
		count := 0
		for _, c := range plaintext {
			switch {
			case 'a' <= c && c <= 'z':
				c -= 'a'
			case 'A' <= c && c <= 'Z':
				c -= 'A'
			default:
				continue
			}
			candidateFrequencies[c]++
			count++
		}

		var expectedFrequencies [26]float64
		for i, p := range englishDistribution {
			expectedFrequencies[i] = p * float64(count)
		}

		// Scores are ChiSquare and multiplied by the ratio of plaintext length and
		// number of alphabet characters found
		candidateChiSquare := stat.ChiSquare(candidateFrequencies[:], expectedFrequencies[:])
		candidateScore := candidateChiSquare * float64(len(plaintext)) / float64(count)

		if candidateScore < score {
			score = candidateScore
			chiSquare = candidateChiSquare
			key = byte(candidate)
		}
	}

	return key, chiSquare
}
<|endoftext|>


<commit_before>/*
 Copyright 2010 Jeremy Wall (jeremy@marzhillstudios.com)
 Use of this source code is governed by the Artistic License 2.0.
 That License is included in the LICENSE file.
*/
package transform

import (
	. "html"
	v "container/vector"
	"log"
	s "strings"
)

type SelectorQuery struct {
	*v.Vector
}

type Selector struct {
	Type    byte // a bitmask of the selector types
	TagType string // "*" for any tag otherwise the name of the tag
	Val string // the value we are matching against if id class or pseudo
	Attr map[string]string
}

const (
	TAGNAME byte = iota // zero value so the default
	CLASS   byte = '.'
	ID      byte = '#'
	PSEUDO  byte = ':'
	ANY     byte = '*'
	ATTR    byte = '['
)

const (
	SELECTOR_CHARS string = ".:#["
)

func newAnyTagClassOrIdSelector(str string) *Selector {
	return &Selector{
		Type:    str[0],
		TagType: "*",
		Val:     str[1:],
	}
}

func newAnyTagSelector(str string) *Selector {
	return &Selector{
		Type:    str[0],
		TagType: "*",
	}
}

func splitAttrs(str string) []string {
	attrs := s.FieldsFunc(str[1:len(str)-1], func(c int) bool {
		if c == '=' {
			return true
		}
		return false
	})
	return attrs
}

func newAnyTagAttrSelector(str string) *Selector {
	attrs := splitAttrs(str)
	return &Selector{
		TagType: "*",
		Type:    str[0],
		Attr:    map[string]string{attrs[0]: attrs[1]},
	}
}

func newTagNameSelector(str string) *Selector {
	return &Selector{
		Type:    TAGNAME,
		TagType: str,
	}
}

func newTagNameWithConstraints(str string, i int) *Selector {
	// TODO(jwall): indexAny use [CLASS,...]
	var selector = new(Selector)
	switch str[i] {
	case CLASS, ID, PSEUDO: // with class or id
		selector = newAnyTagClassOrIdSelector(str[i:])
	case ATTR: // with attribute
		selector = newAnyTagAttrSelector(str[i:])
	default:
		panic("Invalid constraint type for the tagname selector")
	}
	selector.TagType = str[0:i]
	//selector.Type = TAGNAME
	return selector
}

func NewSelector(str string) *Selector {
	str = s.TrimSpace(str) // trim whitespace
	// TODO(jwall): split on one of ".:#["
	var selector *Selector
	switch str[0] {
	case CLASS, ID: // Any tagname with class or id
		selector = newAnyTagClassOrIdSelector(str)
	case ANY: // Any tagname
		selector = newAnyTagSelector(str)
	case ATTR: // any tagname with attribute
		// TODO(jwall): expanded attribute selectors
		selector = newAnyTagAttrSelector(str)
	default: // TAGNAME
		// TODO(jwall): indexAny use [CLASS,...]
		if i := s.IndexAny(str, SELECTOR_CHARS); i != -1 {
			selector = newTagNameWithConstraints(str, i)
		} else { // just a tagname
			selector = newTagNameSelector(str)
		}
	}
	return selector
}

func NewSelectorQuery(sel ...string) *SelectorQuery {
	q := SelectorQuery{Vector: new(v.Vector)}
	for _, str := range sel {
		selPart := NewSelector(str)
		if selPart == nil {
			log.Panic("Invalid Selector in query")
		}
		q.Push(selPart)
	}
	return &q
}

func testSelectorAttrs(attrs []Attribute, sel *Selector) bool {
	result := false
	for key, val := range sel.Attr {
		result = result || testAttr(attrs, key, val)
	}
	return result
}

func testAttr(attrs []Attribute, key string, val string) bool {
	for _, attr := range attrs {
		if attr.Key == key && attr.Val == val {
			return true
		}
	}
	return false
}

func testNode(node *Node, sel Selector) bool {
	if sel.TagType == "*" {
		attrs := node.Attr
		// TODO(jwall): abstract this out
		switch sel.Type {
		case ID:
			if testAttr(attrs, "id",  sel.Val) {
				return true
			}
		case CLASS:
			if testAttr(attrs, "class", sel.Val) {
				return true
			}
		case ATTR:
			if testSelectorAttrs(attrs, &sel) {
				return true
			}
			//case PSEUDO:
			//TODO(jwall): implement these
		}
	} else {
		if node.Data == sel.TagType {
			attrs := node.Attr
			switch sel.Type {
			case ID:
				if testAttr(attrs, "id", sel.Val) {
					return true
				}
			case CLASS:
				if testAttr(attrs, "class", sel.Val) {
					return true
				}
			case ATTR:
				if testSelectorAttrs(attrs, &sel) {
					return true
				}
			//case PSEUDO:
			//TODO(jwall): implement these
			default:
				return true
			}
		}
	}
	return false
}

/*
 Apply the css selector to a document.

 Returns a Vector of nodes that the selector matched.
*/
func (sel *SelectorQuery) Apply(doc *Document) *v.Vector {
	interesting := new(v.Vector)
	return interesting
}

/*
 Replace each node the selector matches with the passed in node.

 Applies the selector against the doc and replaces the returned
 Nodes with the passed in n HtmlNode.
*/
func (sel *SelectorQuery) Replace(doc *Document, n *Node) {
	nv := sel.Apply(doc)
	for i := 0; i <= nv.Len(); i++ {
		// Change to take into account new usage of *Node
		//nv.At(i).(*Node).Copy(n)
	}
	return
}
<commit_msg>added a todo<commit_after>/*
 Copyright 2010 Jeremy Wall (jeremy@marzhillstudios.com)
 Use of this source code is governed by the Artistic License 2.0.
 That License is included in the LICENSE file.
*/
package transform

import (
	. "html"
	v "container/vector"
	"log"
	s "strings"
)

type SelectorQuery struct {
	*v.Vector
}

type Selector struct {
	Type    byte // a bitmask of the selector types
	TagType string // "*" for any tag otherwise the name of the tag
	Val string // the value we are matching against if id class or pseudo
	Attr map[string]string
}

const (
	TAGNAME byte = iota // zero value so the default
	CLASS   byte = '.'
	ID      byte = '#'
	PSEUDO  byte = ':'
	ANY     byte = '*'
	ATTR    byte = '['
)

const (
	SELECTOR_CHARS string = ".:#["
)

func newAnyTagClassOrIdSelector(str string) *Selector {
	return &Selector{
		Type:    str[0],
		TagType: "*",
		Val:     str[1:],
	}
}

func newAnyTagSelector(str string) *Selector {
	return &Selector{
		Type:    str[0],
		TagType: "*",
	}
}

func splitAttrs(str string) []string {
	attrs := s.FieldsFunc(str[1:len(str)-1], func(c int) bool {
		if c == '=' {
			return true
		}
		return false
	})
	return attrs
}

func newAnyTagAttrSelector(str string) *Selector {
	attrs := splitAttrs(str)
	return &Selector{
		TagType: "*",
		Type:    str[0],
		Attr:    map[string]string{attrs[0]: attrs[1]},
	}
}

func newTagNameSelector(str string) *Selector {
	return &Selector{
		Type:    TAGNAME,
		TagType: str,
	}
}

func newTagNameWithConstraints(str string, i int) *Selector {
	// TODO(jwall): indexAny use [CLASS,...]
	var selector = new(Selector)
	switch str[i] {
	case CLASS, ID, PSEUDO: // with class or id
		selector = newAnyTagClassOrIdSelector(str[i:])
	case ATTR: // with attribute
		selector = newAnyTagAttrSelector(str[i:])
	default:
		panic("Invalid constraint type for the tagname selector")
	}
	selector.TagType = str[0:i]
	//selector.Type = TAGNAME
	return selector
}

func NewSelector(str string) *Selector {
	str = s.TrimSpace(str) // trim whitespace
	// TODO(jwall): split on one of ".:#["
	var selector *Selector
	switch str[0] {
	case CLASS, ID: // Any tagname with class or id
		selector = newAnyTagClassOrIdSelector(str)
	case ANY: // Any tagname
		selector = newAnyTagSelector(str)
	case ATTR: // any tagname with attribute
		// TODO(jwall): expanded attribute selectors
		selector = newAnyTagAttrSelector(str)
	default: // TAGNAME
		// TODO(jwall): indexAny use [CLASS,...]
		if i := s.IndexAny(str, SELECTOR_CHARS); i != -1 {
			selector = newTagNameWithConstraints(str, i)
		} else { // just a tagname
			selector = newTagNameSelector(str)
		}
	}
	return selector
}

func NewSelectorQuery(sel ...string) *SelectorQuery {
	q := SelectorQuery{Vector: new(v.Vector)}
	for _, str := range sel {
		selPart := NewSelector(str)
		if selPart == nil {
			log.Panic("Invalid Selector in query")
		}
		q.Push(selPart)
	}
	return &q
}

func testSelectorAttrs(attrs []Attribute, sel *Selector) bool {
	result := false
	for key, val := range sel.Attr {
		result = result || testAttr(attrs, key, val)
	}
	return result
}

func testAttr(attrs []Attribute, key string, val string) bool {
	for _, attr := range attrs {
		// TODO(jwall): we need to handle the multiple match types
		// [att] [att=val] [att~=val] [att|=val]?
		if attr.Key == key && attr.Val == val {
			return true
		}
	}
	return false
}

func testNode(node *Node, sel Selector) bool {
	if sel.TagType == "*" {
		attrs := node.Attr
		// TODO(jwall): abstract this out
		switch sel.Type {
		case ID:
			if testAttr(attrs, "id",  sel.Val) {
				return true
			}
		case CLASS:
			if testAttr(attrs, "class", sel.Val) {
				return true
			}
		case ATTR:
			if testSelectorAttrs(attrs, &sel) {
				return true
			}
			//case PSEUDO:
			//TODO(jwall): implement these
		}
	} else {
		if node.Data == sel.TagType {
			attrs := node.Attr
			switch sel.Type {
			case ID:
				if testAttr(attrs, "id", sel.Val) {
					return true
				}
			case CLASS:
				if testAttr(attrs, "class", sel.Val) {
					return true
				}
			case ATTR:
				if testSelectorAttrs(attrs, &sel) {
					return true
				}
			//case PSEUDO:
			//TODO(jwall): implement these
			default:
				return true
			}
		}
	}
	return false
}

/*
 Apply the css selector to a document.

 Returns a Vector of nodes that the selector matched.
*/
func (sel *SelectorQuery) Apply(doc *Document) *v.Vector {
	interesting := new(v.Vector)
	return interesting
}

/*
 Replace each node the selector matches with the passed in node.

 Applies the selector against the doc and replaces the returned
 Nodes with the passed in n HtmlNode.
*/
func (sel *SelectorQuery) Replace(doc *Document, n *Node) {
	nv := sel.Apply(doc)
	for i := 0; i <= nv.Len(); i++ {
		// Change to take into account new usage of *Node
		//nv.At(i).(*Node).Copy(n)
	}
	return
}
<|endoftext|>


<commit_before>package rule

import (
	"io"
	"strings"
)

// DefaultRuleSet is the list of rules that are built into the inspector
const defaultRuleSet = `---
# Python 2.5+ is installed on all nodes
# This is required by ansible
- kind: Python2Version
  when: []
  supportedVersions:
   - Python 2.5
   - Python 2.6
   - Python 2.7

# Executables required by kubelet
- kind: ExecutableInPath
  when: ["worker"]
  executable: iptables
- kind: ExecutableInPath
  when: ["worker"]
  executable: iptables-save
- kind: ExecutableInPath
  when: ["worker"]
  executable: iptables-restore

# Kubelet depends on glibc
- kind: PackageAvailable
  when: ["ubuntu", "worker"]
  packageName: libc6
  packageVersion: ".*"
- kind: PackageAvailable
  when: ["centos", "worker"]
  packageName: glibc.x86_64
  packageVersion: ".*"

# Ensure python 2.7+ is installed
- kind: PackageAvailable
  when: ["centos"]
  packageName: python.x86_64
  packageVersion: "^2\\.7"
- kind: PackageAvailable
  when: ["ubuntu"]
  packageName: "^python2\\.7$"
  packageVersion: ".*"

# Ports used by etcd are available
- kind: TCPPortAvailable
  when: ["etcd"]
  port: 2379
- kind: TCPPortAvailable
  when: ["etcd"]
  port: 6666
- kind: TCPPortAvailable
  when: ["etcd"]
  port: 2380
- kind: TCPPortAvailable
  when: ["etcd"]
  port: 6660

# Ports used by etcd are accessible
- kind: TCPPortAccessible
  when: ["etcd"]
  port: 2379
  timeout: 5s
- kind: TCPPortAccessible
  when: ["etcd"]
  port: 6666
  timeout: 5s
- kind: TCPPortAccessible
  when: ["etcd"]
  port: 2379
  timeout: 5s
- kind: TCPPortAccessible
  when: ["etcd"]
  port: 2380
  timeout: 5s
- kind: TCPPortAccessible
  when: ["etcd"]
  port: 6666
  timeout: 5s
- kind: TCPPortAccessible
  when: ["etcd"]
  port: 6660
  timeout: 5s

# Ports used by K8s master are available
- kind: TCPPortAvailable
  when: ["master"]
  port: 6443
- kind: TCPPortAvailable
  when: ["master"]
  port: 8080

# Ports used by K8s master are accessible
- kind: TCPPortAccessible
  when: ["master"]
  port: 6443
  timeout: 5s
- kind: TCPPortAccessible
  when: ["master"]
  port: 8080
  timeout: 5s
`

// DefaultRules returns the list of rules that are built into the inspector
func DefaultRules() []Rule {
	rules, err := UnmarshalRulesYAML([]byte(defaultRuleSet))
	if err != nil {
		// The default rules should not contain errors
		// If they do, panic so that we catch them during tests
		panic(err)
	}
	return rules
}

// DumpDefaultRules writes the default rule set to a file
func DumpDefaultRules(writer io.Writer) error {
	_, err := io.Copy(writer, strings.NewReader(defaultRuleSet))
	if err != nil {
		return err
	}
	return nil
}
<commit_msg>KIS-13: Clean up default rules<commit_after>package rule

import (
	"io"
	"strings"
)

// DefaultRuleSet is the list of rules that are built into the inspector
const defaultRuleSet = `---
# Python 2.5+ is installed on all nodes
# This is required by ansible
- kind: Python2Version
  when: []
  supportedVersions:
   - Python 2.5
   - Python 2.6
   - Python 2.7

# Executables required by kubelet
- kind: ExecutableInPath
  when: ["worker"]
  executable: iptables
- kind: ExecutableInPath
  when: ["worker"]
  executable: iptables-save
- kind: ExecutableInPath
  when: ["worker"]
  executable: iptables-restore

# Ports used by etcd are available
- kind: TCPPortAvailable
  when: ["etcd"]
  port: 2379
- kind: TCPPortAvailable
  when: ["etcd"]
  port: 6666
- kind: TCPPortAvailable
  when: ["etcd"]
  port: 2380
- kind: TCPPortAvailable
  when: ["etcd"]
  port: 6660

# Ports used by etcd are accessible
- kind: TCPPortAccessible
  when: ["etcd"]
  port: 2379
  timeout: 5s
- kind: TCPPortAccessible
  when: ["etcd"]
  port: 6666
  timeout: 5s
- kind: TCPPortAccessible
  when: ["etcd"]
  port: 2380
  timeout: 5s
- kind: TCPPortAccessible
  when: ["etcd"]
  port: 6660
  timeout: 5s

# Ports used by K8s master are available
- kind: TCPPortAvailable
  when: ["master"]
  port: 6443
- kind: TCPPortAvailable
  when: ["master"]
  port: 8080

# Ports used by K8s master are accessible
- kind: TCPPortAccessible
  when: ["master"]
  port: 6443
  timeout: 5s
- kind: TCPPortAccessible
  when: ["master"]
  port: 8080
  timeout: 5s

# TODO: Add kismatic package checks
`

// DefaultRules returns the list of rules that are built into the inspector
func DefaultRules() []Rule {
	rules, err := UnmarshalRulesYAML([]byte(defaultRuleSet))
	if err != nil {
		// The default rules should not contain errors
		// If they do, panic so that we catch them during tests
		panic(err)
	}
	return rules
}

// DumpDefaultRules writes the default rule set to a file
func DumpDefaultRules(writer io.Writer) error {
	_, err := io.Copy(writer, strings.NewReader(defaultRuleSet))
	if err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Nuclio Authors.

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

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

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

package worker

import (
	"time"

	"github.com/nuclio/nuclio/pkg/processor/cloudevent"
	"github.com/nuclio/nuclio/pkg/processor/runtime"
	"github.com/nuclio/nuclio/pkg/processor/status"
	"github.com/nuclio/nuclio/pkg/processor/util/clock"

	"github.com/nuclio/logger"
	"github.com/nuclio/nuclio-sdk-go"
)

// Worker holds all the required state and context to handle a single request
type Worker struct {
	logger               logger.Logger
	context              nuclio.Context
	index                int
	runtime              runtime.Runtime
	statistics           Statistics
	structuredCloudEvent cloudevent.Structured
	binaryCloudEvent     cloudevent.Binary
	eventTime            *time.Time
}

// NewWorker creates a new worker
func NewWorker(parentLogger logger.Logger,
	index int,
	runtime runtime.Runtime) (*Worker, error) {

	newWorker := Worker{
		logger:  parentLogger,
		index:   index,
		runtime: runtime,
	}

	// return an instance of the default worker
	return &newWorker, nil
}

// ProcessEvent sends the event to the associated runtime
func (w *Worker) ProcessEvent(event nuclio.Event, functionLogger logger.Logger) (interface{}, error) {

	w.eventTime = clock.Now()

	// process the event at the runtime
	response, err := w.runtime.ProcessEvent(event, functionLogger)
	w.eventTime = nil

	// check if there was a processing error. if so, log it
	if err != nil {
		w.statistics.EventsHandleError++

		// use the override function logger if passed, otherwise ask the runtime for the
		// function logger
		loggerInstance := functionLogger
		if loggerInstance == nil {
			loggerInstance = w.runtime.GetFunctionLogger()
		}

		loggerInstance.WarnWith("Function returned error", "event_id", event.GetID(), "err", err)
	} else {
		w.statistics.EventsHandleSuccess++
	}

	return response, err
}

// GetStatistics returns a pointer to the statistics object. This must not be modified by the reader
func (w *Worker) GetStatistics() *Statistics {
	return &w.statistics
}

// GetIndex returns the index of the worker, as specified during creation
func (w *Worker) GetIndex() int {
	return w.index
}

// GetRuntime returns the runtime of the worker, as specified during creation
func (w *Worker) GetRuntime() runtime.Runtime {
	return w.runtime
}

// GetStatus returns the status of the worker, as updated by the runtime
func (w *Worker) GetStatus() status.Status {
	return w.runtime.GetStatus()
}

// Stop stops the worker and associated runtime
func (w *Worker) Stop() error {
	return w.runtime.Stop()
}

// GetStructuredCloudEvent return a structued clould event
func (w *Worker) GetStructuredCloudEvent() *cloudevent.Structured {
	return &w.structuredCloudEvent
}

// GetBinaryCloudEvent return a binary cloud event
func (w *Worker) GetBinaryCloudEvent() *cloudevent.Binary {
	return &w.binaryCloudEvent
}

// GetEventTime return current event time, nil if we're not handling event
func (w *Worker) GetEventTime() *time.Time {
	return w.eventTime
}

// ResetEventTime resets the event time
func (w *Worker) ResetEventTime() {
	w.eventTime = nil
}

// Restart restarts the worker
func (w *Worker) Restart() error {
	w.eventTime = nil
	return w.runtime.Restart()
}

// SupportsRestart returns true if the underlying runtime supports restart
func (w *Worker) SupportsRestart() bool {
	return w.runtime.SupportsRestart()
}
<commit_msg>Properly count function errors when runtime is RPC or returned as part of "Response" (#1260)<commit_after>/*
Copyright 2017 The Nuclio Authors.

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

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

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

package worker

import (
	"net/http"
	"time"

	"github.com/nuclio/nuclio/pkg/processor/cloudevent"
	"github.com/nuclio/nuclio/pkg/processor/runtime"
	"github.com/nuclio/nuclio/pkg/processor/status"
	"github.com/nuclio/nuclio/pkg/processor/util/clock"

	"github.com/nuclio/logger"
	"github.com/nuclio/nuclio-sdk-go"
)

// Worker holds all the required state and context to handle a single request
type Worker struct {
	logger               logger.Logger
	context              nuclio.Context
	index                int
	runtime              runtime.Runtime
	statistics           Statistics
	structuredCloudEvent cloudevent.Structured
	binaryCloudEvent     cloudevent.Binary
	eventTime            *time.Time
}

// NewWorker creates a new worker
func NewWorker(parentLogger logger.Logger,
	index int,
	runtime runtime.Runtime) (*Worker, error) {

	newWorker := Worker{
		logger:  parentLogger,
		index:   index,
		runtime: runtime,
	}

	// return an instance of the default worker
	return &newWorker, nil
}

// ProcessEvent sends the event to the associated runtime
func (w *Worker) ProcessEvent(event nuclio.Event, functionLogger logger.Logger) (interface{}, error) {

	w.eventTime = clock.Now()

	// process the event at the runtime
	response, err := w.runtime.ProcessEvent(event, functionLogger)
	w.eventTime = nil

	// check if there was a processing error. if so, log it
	if err != nil {
		w.statistics.EventsHandleError++
	} else {
		success := true

		switch typedResponse := response.(type) {
		case *nuclio.Response:
			success = typedResponse.StatusCode < http.StatusBadRequest
		case nuclio.Response:
			success = typedResponse.StatusCode < http.StatusBadRequest
		}

		if success {
			w.statistics.EventsHandleSuccess++
		} else {
			w.statistics.EventsHandleError++
		}
	}

	return response, err
}

// GetStatistics returns a pointer to the statistics object. This must not be modified by the reader
func (w *Worker) GetStatistics() *Statistics {
	return &w.statistics
}

// GetIndex returns the index of the worker, as specified during creation
func (w *Worker) GetIndex() int {
	return w.index
}

// GetRuntime returns the runtime of the worker, as specified during creation
func (w *Worker) GetRuntime() runtime.Runtime {
	return w.runtime
}

// GetStatus returns the status of the worker, as updated by the runtime
func (w *Worker) GetStatus() status.Status {
	return w.runtime.GetStatus()
}

// Stop stops the worker and associated runtime
func (w *Worker) Stop() error {
	return w.runtime.Stop()
}

// GetStructuredCloudEvent return a structued clould event
func (w *Worker) GetStructuredCloudEvent() *cloudevent.Structured {
	return &w.structuredCloudEvent
}

// GetBinaryCloudEvent return a binary cloud event
func (w *Worker) GetBinaryCloudEvent() *cloudevent.Binary {
	return &w.binaryCloudEvent
}

// GetEventTime return current event time, nil if we're not handling event
func (w *Worker) GetEventTime() *time.Time {
	return w.eventTime
}

// ResetEventTime resets the event time
func (w *Worker) ResetEventTime() {
	w.eventTime = nil
}

// Restart restarts the worker
func (w *Worker) Restart() error {
	w.eventTime = nil
	return w.runtime.Restart()
}

// SupportsRestart returns true if the underlying runtime supports restart
func (w *Worker) SupportsRestart() bool {
	return w.runtime.SupportsRestart()
}
<|endoftext|>


<commit_before>package targets

import (
	"os"
	"sync"
	"time"

	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/hpcloud/tail"
	"github.com/prometheus/common/model"

	"github.com/grafana/loki/pkg/promtail/api"
	"github.com/grafana/loki/pkg/promtail/positions"
	"github.com/grafana/loki/pkg/util"
)

type tailer struct {
	logger    log.Logger
	handler   api.EntryHandler
	positions positions.Positions

	path string
	tail *tail.Tail

	posAndSizeMtx sync.Mutex

	quit chan struct{}
	done chan struct{}
}

func newTailer(logger log.Logger, handler api.EntryHandler, positions positions.Positions, path string) (*tailer, error) {
	// Simple check to make sure the file we are tailing doesn't
	// have a position already saved which is past the end of the file.
	fi, err := os.Stat(path)
	if err != nil {
		return nil, err
	}
	pos, err := positions.Get(path)
	if err != nil {
		return nil, err
	}

	if fi.Size() < pos {
		positions.Remove(path)
	}

	tail, err := tail.TailFile(path, tail.Config{
		Follow: true,
		Poll:   true,
		ReOpen: true,
		Location: &tail.SeekInfo{
			Offset: pos,
			Whence: 0,
		},
	})
	if err != nil {
		return nil, err
	}

	logger = log.With(logger, "component", "tailer")
	tailer := &tailer{
		logger:    logger,
		handler:   api.AddLabelsMiddleware(model.LabelSet{FilenameLabel: model.LabelValue(path)}).Wrap(handler),
		positions: positions,

		path: path,
		tail: tail,
		quit: make(chan struct{}),
		done: make(chan struct{}),
	}
	tail.Logger = util.NewLogAdapater(logger)

	go tailer.run()
	filesActive.Add(1.)
	return tailer, nil
}

func (t *tailer) run() {
	level.Info(t.logger).Log("msg", "start tailing file", "path", t.path)
	positionSyncPeriod := t.positions.SyncPeriod()
	positionWait := time.NewTicker(positionSyncPeriod)

	defer func() {
		positionWait.Stop()
		close(t.done)
	}()

	for {
		select {
		case <-positionWait.C:
			err := t.markPositionAndSize()
			if err != nil {
				level.Error(t.logger).Log("msg", "error getting tail position and/or size", "path", t.path, "error", err)
				continue
			}

		case line, ok := <-t.tail.Lines:
			if !ok {
				return
			}

			if line.Err != nil {
				level.Error(t.logger).Log("msg", "error reading line", "path", t.path, "error", line.Err)
			}

			readLines.WithLabelValues(t.path).Inc()
			logLengthHistogram.WithLabelValues(t.path).Observe(float64(len(line.Text)))
			if err := t.handler.Handle(model.LabelSet{}, line.Time, line.Text); err != nil {
				level.Error(t.logger).Log("msg", "error handling line", "path", t.path, "error", err)
			}
		case <-t.quit:
			return
		}
	}
}

func (t *tailer) markPositionAndSize() error {
	// Lock this update as there are 2 timers calling this routine, the sync in filetarget and the positions sync in this file.
	t.posAndSizeMtx.Lock()
	defer t.posAndSizeMtx.Unlock()

	pos, err := t.tail.Tell()
	if err != nil {
		return err
	}
	readBytes.WithLabelValues(t.path).Set(float64(pos))
	t.positions.Put(t.path, pos)

	size, err := t.tail.Size()
	if err != nil {
		return err
	}
	totalBytes.WithLabelValues(t.path).Set(float64(size))

	return nil
}

func (t *tailer) stop() error {
	// Save the current position before shutting down tailer
	err := t.markPositionAndSize()
	if err != nil {
		level.Error(t.logger).Log("msg", "error getting tail position", "path", t.path, "error", err)
	}
	err = t.tail.Stop()
	close(t.quit)
	<-t.done
	filesActive.Add(-1.)
	// When we stop tailing the file, also un-export metrics related to the file
	readBytes.DeleteLabelValues(t.path)
	totalBytes.DeleteLabelValues(t.path)
	logLengthHistogram.DeleteLabelValues(t.path)
	level.Info(t.logger).Log("msg", "stopped tailing file", "path", t.path)
	return err
}

func (t *tailer) cleanup() {
	t.positions.Remove(t.path)
}
<commit_msg>remove the read lines counter when the log file stops being tailed<commit_after>package targets

import (
	"os"
	"sync"
	"time"

	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/hpcloud/tail"
	"github.com/prometheus/common/model"

	"github.com/grafana/loki/pkg/promtail/api"
	"github.com/grafana/loki/pkg/promtail/positions"
	"github.com/grafana/loki/pkg/util"
)

type tailer struct {
	logger    log.Logger
	handler   api.EntryHandler
	positions positions.Positions

	path string
	tail *tail.Tail

	posAndSizeMtx sync.Mutex

	quit chan struct{}
	done chan struct{}
}

func newTailer(logger log.Logger, handler api.EntryHandler, positions positions.Positions, path string) (*tailer, error) {
	// Simple check to make sure the file we are tailing doesn't
	// have a position already saved which is past the end of the file.
	fi, err := os.Stat(path)
	if err != nil {
		return nil, err
	}
	pos, err := positions.Get(path)
	if err != nil {
		return nil, err
	}

	if fi.Size() < pos {
		positions.Remove(path)
	}

	tail, err := tail.TailFile(path, tail.Config{
		Follow: true,
		Poll:   true,
		ReOpen: true,
		Location: &tail.SeekInfo{
			Offset: pos,
			Whence: 0,
		},
	})
	if err != nil {
		return nil, err
	}

	logger = log.With(logger, "component", "tailer")
	tailer := &tailer{
		logger:    logger,
		handler:   api.AddLabelsMiddleware(model.LabelSet{FilenameLabel: model.LabelValue(path)}).Wrap(handler),
		positions: positions,

		path: path,
		tail: tail,
		quit: make(chan struct{}),
		done: make(chan struct{}),
	}
	tail.Logger = util.NewLogAdapater(logger)

	go tailer.run()
	filesActive.Add(1.)
	return tailer, nil
}

func (t *tailer) run() {
	level.Info(t.logger).Log("msg", "start tailing file", "path", t.path)
	positionSyncPeriod := t.positions.SyncPeriod()
	positionWait := time.NewTicker(positionSyncPeriod)

	defer func() {
		positionWait.Stop()
		close(t.done)
	}()

	for {
		select {
		case <-positionWait.C:
			err := t.markPositionAndSize()
			if err != nil {
				level.Error(t.logger).Log("msg", "error getting tail position and/or size", "path", t.path, "error", err)
				continue
			}

		case line, ok := <-t.tail.Lines:
			if !ok {
				return
			}

			if line.Err != nil {
				level.Error(t.logger).Log("msg", "error reading line", "path", t.path, "error", line.Err)
			}

			readLines.WithLabelValues(t.path).Inc()
			logLengthHistogram.WithLabelValues(t.path).Observe(float64(len(line.Text)))
			if err := t.handler.Handle(model.LabelSet{}, line.Time, line.Text); err != nil {
				level.Error(t.logger).Log("msg", "error handling line", "path", t.path, "error", err)
			}
		case <-t.quit:
			return
		}
	}
}

func (t *tailer) markPositionAndSize() error {
	// Lock this update as there are 2 timers calling this routine, the sync in filetarget and the positions sync in this file.
	t.posAndSizeMtx.Lock()
	defer t.posAndSizeMtx.Unlock()

	pos, err := t.tail.Tell()
	if err != nil {
		return err
	}
	readBytes.WithLabelValues(t.path).Set(float64(pos))
	t.positions.Put(t.path, pos)

	size, err := t.tail.Size()
	if err != nil {
		return err
	}
	totalBytes.WithLabelValues(t.path).Set(float64(size))

	return nil
}

func (t *tailer) stop() error {
	// Save the current position before shutting down tailer
	err := t.markPositionAndSize()
	if err != nil {
		level.Error(t.logger).Log("msg", "error getting tail position", "path", t.path, "error", err)
	}
	err = t.tail.Stop()
	close(t.quit)
	<-t.done
	filesActive.Add(-1.)
	// When we stop tailing the file, also un-export metrics related to the file
	readLines.DeleteLabelValues(t.path)
	readBytes.DeleteLabelValues(t.path)
	totalBytes.DeleteLabelValues(t.path)
	logLengthHistogram.DeleteLabelValues(t.path)
	level.Info(t.logger).Log("msg", "stopped tailing file", "path", t.path)
	return err
}

func (t *tailer) cleanup() {
	t.positions.Remove(t.path)
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Skaffold Authors

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

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

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

package deploy

import (
	"bufio"
	"bytes"
	"context"
	"io"
	"io/ioutil"
	"os/exec"
	"strings"

	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/build"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"gopkg.in/yaml.v2"
)

// for testing
var warner Warner = &logrusWarner{}

// KubectlDeployer deploys workflows using kubectl CLI.
type KubectlDeployer struct {
	*v1alpha2.KubectlDeploy

	workingDir  string
	kubeContext string
}

// NewKubectlDeployer returns a new KubectlDeployer for a DeployConfig filled
// with the needed configuration for `kubectl apply`
func NewKubectlDeployer(workingDir string, cfg *v1alpha2.KubectlDeploy, kubeContext string) *KubectlDeployer {
	return &KubectlDeployer{
		KubectlDeploy: cfg,
		workingDir:    workingDir,
		kubeContext:   kubeContext,
	}
}

func (k *KubectlDeployer) Labels() map[string]string {
	return map[string]string{
		constants.Labels.Deployer: "kubectl",
	}
}

// Deploy templates the provided manifests with a simple `find and replace` and
// runs `kubectl apply` on those manifests
func (k *KubectlDeployer) Deploy(ctx context.Context, out io.Writer, builds []build.Artifact) ([]Artifact, error) {
	manifests, err := k.readManifests()
	if err != nil {
		return nil, errors.Wrap(err, "reading manifests")
	}

	manifests, err = manifests.replaceImages(builds)
	if err != nil {
		return nil, errors.Wrap(err, "replacing images in manifests")
	}

	err = kubectl(manifests.reader(), out, k.kubeContext, k.Flags.Global, "apply", k.Flags.Apply, "-f", "-")
	if err != nil {
		return nil, errors.Wrap(err, "deploying manifests")
	}

	return parseManifestsForDeploys(manifests)
}

// Cleanup deletes what was deployed by calling Deploy.
func (k *KubectlDeployer) Cleanup(ctx context.Context, out io.Writer) error {
	manifests, err := k.readManifests()
	if err != nil {
		return errors.Wrap(err, "reading manifests")
	}

	if err := kubectl(manifests.reader(), out, k.kubeContext, k.Flags.Global, "delete", k.Flags.Delete, "--grace-period=1", "--ignore-not-found=true", "-f", "-"); err != nil {
		return errors.Wrap(err, "deleting manifests")
	}

	return nil
}

func (k *KubectlDeployer) Dependencies() ([]string, error) {
	return k.manifestFiles(k.KubectlDeploy.Manifests)
}

func kubectl(in io.Reader, out io.Writer, kubeContext string, globalFlags []string, command string, commandFlags []string, arg ...string) error {
	args := []string{"--context", kubeContext}
	args = append(args, globalFlags...)
	args = append(args, command)
	args = append(args, commandFlags...)
	args = append(args, arg...)

	cmd := exec.Command("kubectl", args...)
	cmd.Stdin = in
	cmd.Stdout = out
	cmd.Stderr = out

	return util.RunCmd(cmd)
}

func (k *KubectlDeployer) manifestFiles(manifests []string) ([]string, error) {
	list, err := util.ExpandPathsGlob(k.workingDir, manifests)
	if err != nil {
		return nil, errors.Wrap(err, "expanding kubectl manifest paths")
	}

	var filteredManifests []string
	for _, f := range list {
		if !util.IsSupportedKubernetesFormat(f) {
			if !util.StrSliceContains(manifests, f) {
				logrus.Infof("refusing to deploy/delete non {json, yaml} file %s", f)
				logrus.Info("If you still wish to deploy this file, please specify it directly, outside a glob pattern.")
				continue
			}
		}
		filteredManifests = append(filteredManifests, f)
	}

	return filteredManifests, nil
}

func parseManifestsForDeploys(manifests manifestList) ([]Artifact, error) {
	results := []Artifact{}
	for _, manifest := range manifests {
		b := bufio.NewReader(bytes.NewReader(manifest))
		results = append(results, parseReleaseInfo("", b)...)
	}
	return results, nil
}

// readManifests reads the manifests to deploy/delete.
func (k *KubectlDeployer) readManifests() (manifestList, error) {
	files, err := k.manifestFiles(k.Manifests)
	if err != nil {
		return nil, errors.Wrap(err, "expanding user manifest list")
	}
	var manifests manifestList

	for _, manifest := range files {
		buf, err := ioutil.ReadFile(manifest)
		if err != nil {
			return nil, errors.Wrap(err, "reading manifest")
		}

		parts := bytes.Split(buf, []byte("\n---"))
		for _, part := range parts {
			manifests = append(manifests, part)
		}
	}

	for _, m := range k.RemoteManifests {
		manifest, err := k.readRemoteManifest(m)
		if err != nil {
			return nil, errors.Wrap(err, "get remote manifests")
		}

		manifests = append(manifests, manifest)
	}

	logrus.Debugln("manifests", manifests.String())

	return manifests, nil
}

func (k *KubectlDeployer) readRemoteManifest(name string) ([]byte, error) {
	var args []string
	if parts := strings.Split(name, ":"); len(parts) > 1 {
		args = append(args, "--namespace", parts[0])
		name = parts[1]
	}
	args = append(args, name, "-o", "yaml")

	var manifest bytes.Buffer
	err := kubectl(nil, &manifest, k.kubeContext, k.Flags.Global, "get", nil, args...)
	if err != nil {
		return nil, errors.Wrap(err, "getting manifest")
	}

	return manifest.Bytes(), nil
}

type replacement struct {
	tag   string
	found bool
}

type manifestList [][]byte

func (l *manifestList) String() string {
	var str string
	for i, manifest := range *l {
		if i != 0 {
			str += "\n---\n"
		}
		str += string(bytes.TrimSpace(manifest))
	}
	return str
}

func (l *manifestList) reader() io.Reader {
	return strings.NewReader(l.String())
}

func (l *manifestList) replaceImages(builds []build.Artifact) (manifestList, error) {
	replacements := map[string]*replacement{}
	for _, build := range builds {
		replacements[build.ImageName] = &replacement{
			tag: build.Tag,
		}
	}

	var updatedManifests manifestList

	for _, manifest := range *l {
		m := make(map[interface{}]interface{})
		if err := yaml.Unmarshal(manifest, &m); err != nil {
			return nil, errors.Wrap(err, "reading kubernetes YAML")
		}

		if len(m) == 0 {
			continue
		}

		recursiveReplaceImage(m, replacements)

		updatedManifest, err := yaml.Marshal(m)
		if err != nil {
			return nil, errors.Wrap(err, "marshalling yaml")
		}

		updatedManifests = append(updatedManifests, updatedManifest)
	}

	for name, replacement := range replacements {
		if !replacement.found {
			warner.Warnf("image [%s] is not used by the deployment", name)
		}
	}

	logrus.Debugln("manifests with tagged images", updatedManifests.String())

	return updatedManifests, nil
}

func recursiveReplaceImage(i interface{}, replacements map[string]*replacement) {
	switch t := i.(type) {
	case []interface{}:
		for _, v := range t {
			recursiveReplaceImage(v, replacements)
		}
	case map[interface{}]interface{}:
		for k, v := range t {
			if k.(string) != "image" {
				recursiveReplaceImage(v, replacements)
				continue
			}

			image := v.(string)
			parsed, err := docker.ParseReference(image)
			if err != nil {
				warner.Warnf("Couldn't parse image: %s", v)
				continue
			}

			if img, present := replacements[parsed.BaseName]; present {
				if parsed.FullyQualified {
					if img.tag == image {
						img.found = true
					}
				} else {
					t[k] = img.tag
					img.found = true
				}
			}
		}
	}
}
<commit_msg>Skip the deployment if no manifests are defined<commit_after>/*
Copyright 2018 The Skaffold Authors

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

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

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

package deploy

import (
	"bufio"
	"bytes"
	"context"
	"io"
	"io/ioutil"
	"os/exec"
	"strings"

	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/build"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"gopkg.in/yaml.v2"
)

// for testing
var warner Warner = &logrusWarner{}

// KubectlDeployer deploys workflows using kubectl CLI.
type KubectlDeployer struct {
	*v1alpha2.KubectlDeploy

	workingDir  string
	kubeContext string
}

// NewKubectlDeployer returns a new KubectlDeployer for a DeployConfig filled
// with the needed configuration for `kubectl apply`
func NewKubectlDeployer(workingDir string, cfg *v1alpha2.KubectlDeploy, kubeContext string) *KubectlDeployer {
	return &KubectlDeployer{
		KubectlDeploy: cfg,
		workingDir:    workingDir,
		kubeContext:   kubeContext,
	}
}

func (k *KubectlDeployer) Labels() map[string]string {
	return map[string]string{
		constants.Labels.Deployer: "kubectl",
	}
}

// Deploy templates the provided manifests with a simple `find and replace` and
// runs `kubectl apply` on those manifests
func (k *KubectlDeployer) Deploy(ctx context.Context, out io.Writer, builds []build.Artifact) ([]Artifact, error) {
	manifests, err := k.readManifests()
	if err != nil {
		return nil, errors.Wrap(err, "reading manifests")
	}

	if manifests.Empty() {
		return []Artifact{}, nil
	}

	manifests, err = manifests.replaceImages(builds)
	if err != nil {
		return nil, errors.Wrap(err, "replacing images in manifests")
	}

	err = kubectl(manifests.reader(), out, k.kubeContext, k.Flags.Global, "apply", k.Flags.Apply, "-f", "-")
	if err != nil {
		return nil, errors.Wrap(err, "deploying manifests")
	}

	return parseManifestsForDeploys(manifests)
}

// Cleanup deletes what was deployed by calling Deploy.
func (k *KubectlDeployer) Cleanup(ctx context.Context, out io.Writer) error {
	manifests, err := k.readManifests()
	if err != nil {
		return errors.Wrap(err, "reading manifests")
	}

	if err := kubectl(manifests.reader(), out, k.kubeContext, k.Flags.Global, "delete", k.Flags.Delete, "--grace-period=1", "--ignore-not-found=true", "-f", "-"); err != nil {
		return errors.Wrap(err, "deleting manifests")
	}

	return nil
}

func (k *KubectlDeployer) Dependencies() ([]string, error) {
	return k.manifestFiles(k.KubectlDeploy.Manifests)
}

func kubectl(in io.Reader, out io.Writer, kubeContext string, globalFlags []string, command string, commandFlags []string, arg ...string) error {
	args := []string{"--context", kubeContext}
	args = append(args, globalFlags...)
	args = append(args, command)
	args = append(args, commandFlags...)
	args = append(args, arg...)

	cmd := exec.Command("kubectl", args...)
	cmd.Stdin = in
	cmd.Stdout = out
	cmd.Stderr = out

	return util.RunCmd(cmd)
}

func (k *KubectlDeployer) manifestFiles(manifests []string) ([]string, error) {
	list, err := util.ExpandPathsGlob(k.workingDir, manifests)
	if err != nil {
		return nil, errors.Wrap(err, "expanding kubectl manifest paths")
	}

	var filteredManifests []string
	for _, f := range list {
		if !util.IsSupportedKubernetesFormat(f) {
			if !util.StrSliceContains(manifests, f) {
				logrus.Infof("refusing to deploy/delete non {json, yaml} file %s", f)
				logrus.Info("If you still wish to deploy this file, please specify it directly, outside a glob pattern.")
				continue
			}
		}
		filteredManifests = append(filteredManifests, f)
	}

	return filteredManifests, nil
}

func parseManifestsForDeploys(manifests manifestList) ([]Artifact, error) {
	results := []Artifact{}
	for _, manifest := range manifests {
		b := bufio.NewReader(bytes.NewReader(manifest))
		results = append(results, parseReleaseInfo("", b)...)
	}
	return results, nil
}

// readManifests reads the manifests to deploy/delete.
func (k *KubectlDeployer) readManifests() (manifestList, error) {
	files, err := k.manifestFiles(k.Manifests)
	if err != nil {
		return nil, errors.Wrap(err, "expanding user manifest list")
	}
	var manifests manifestList

	for _, manifest := range files {
		buf, err := ioutil.ReadFile(manifest)
		if err != nil {
			return nil, errors.Wrap(err, "reading manifest")
		}

		parts := bytes.Split(buf, []byte("\n---"))
		for _, part := range parts {
			manifests = append(manifests, part)
		}
	}

	for _, m := range k.RemoteManifests {
		manifest, err := k.readRemoteManifest(m)
		if err != nil {
			return nil, errors.Wrap(err, "get remote manifests")
		}

		manifests = append(manifests, manifest)
	}

	logrus.Debugln("manifests", manifests.String())

	return manifests, nil
}

func (k *KubectlDeployer) readRemoteManifest(name string) ([]byte, error) {
	var args []string
	if parts := strings.Split(name, ":"); len(parts) > 1 {
		args = append(args, "--namespace", parts[0])
		name = parts[1]
	}
	args = append(args, name, "-o", "yaml")

	var manifest bytes.Buffer
	err := kubectl(nil, &manifest, k.kubeContext, k.Flags.Global, "get", nil, args...)
	if err != nil {
		return nil, errors.Wrap(err, "getting manifest")
	}

	return manifest.Bytes(), nil
}

type replacement struct {
	tag   string
	found bool
}

type manifestList [][]byte

func (l *manifestList) String() string {
	var str string
	for i, manifest := range *l {
		if i != 0 {
			str += "\n---\n"
		}
		str += string(bytes.TrimSpace(manifest))
	}
	return str
}

func (l *manifestList) Empty() bool {
	return len(*l) == 0
}

func (l *manifestList) reader() io.Reader {
	return strings.NewReader(l.String())
}

func (l *manifestList) replaceImages(builds []build.Artifact) (manifestList, error) {
	replacements := map[string]*replacement{}
	for _, build := range builds {
		replacements[build.ImageName] = &replacement{
			tag: build.Tag,
		}
	}

	var updatedManifests manifestList

	for _, manifest := range *l {
		m := make(map[interface{}]interface{})
		if err := yaml.Unmarshal(manifest, &m); err != nil {
			return nil, errors.Wrap(err, "reading kubernetes YAML")
		}

		if len(m) == 0 {
			continue
		}

		recursiveReplaceImage(m, replacements)

		updatedManifest, err := yaml.Marshal(m)
		if err != nil {
			return nil, errors.Wrap(err, "marshalling yaml")
		}

		updatedManifests = append(updatedManifests, updatedManifest)
	}

	for name, replacement := range replacements {
		if !replacement.found {
			warner.Warnf("image [%s] is not used by the deployment", name)
		}
	}

	logrus.Debugln("manifests with tagged images", updatedManifests.String())

	return updatedManifests, nil
}

func recursiveReplaceImage(i interface{}, replacements map[string]*replacement) {
	switch t := i.(type) {
	case []interface{}:
		for _, v := range t {
			recursiveReplaceImage(v, replacements)
		}
	case map[interface{}]interface{}:
		for k, v := range t {
			if k.(string) != "image" {
				recursiveReplaceImage(v, replacements)
				continue
			}

			image := v.(string)
			parsed, err := docker.ParseReference(image)
			if err != nil {
				warner.Warnf("Couldn't parse image: %s", v)
				continue
			}

			if img, present := replacements[parsed.BaseName]; present {
				if parsed.FullyQualified {
					if img.tag == image {
						img.found = true
					}
				} else {
					t[k] = img.tag
					img.found = true
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
  "io"
  "time"
  "log"
  "fmt"
  "github.com/gorilla/mux"
  "net/http"
  "encoding/json"
)

type Deploy struct {
  DeployedAt time.Time
  Sha string
}

var revisions []Deploy = make([]Deploy, 0)

func ListRevisions(w http.ResponseWriter, req *http.Request) {
  b, err := json.Marshal(revisions)
  if err == nil {
    io.WriteString(w, string(b))
  } else {
    io.WriteString(w, "[]")
  }
}

func CreateRevision(w http.ResponseWriter, req *http.Request) {
  dec := json.NewDecoder(req.Body)

  var deploy Deploy
  err := dec.Decode(&deploy)
  if err != nil && err != io.EOF {
    log.Fatal(err)
  } else {
    deploy.DeployedAt = time.Now()
  }

  revisions = append(revisions, deploy);
  io.WriteString(w, "")
}

func init() {
  r := mux.NewRouter()
  r.HandleFunc("/revisions", ListRevisions).
    Methods("GET")
  r.HandleFunc("/revisions", CreateRevision).
    Methods("POST")
  http.Handle("/", r)
}

func main() {
  fmt.Printf("Server listening on port %d\n", 8080)
  http.ListenAndServe(":8080", nil)
}<commit_msg>make the port configurable<commit_after>package main

import (
  "io"
  "time"
  "log"
  "fmt"
  "github.com/gorilla/mux"
  "net/http"
  "encoding/json"
  "os"
)

type Deploy struct {
  DeployedAt time.Time
  Sha string
}

var revisions []Deploy = make([]Deploy, 0)

func ListRevisions(w http.ResponseWriter, req *http.Request) {
  b, err := json.Marshal(revisions)
  w.Header().Set("Content-Type", "application/json; charset=utf-8")
  if err == nil {
    io.WriteString(w, string(b))
  } else {
    io.WriteString(w, "[]")
  }
}

func CreateRevision(w http.ResponseWriter, req *http.Request) {
  dec := json.NewDecoder(req.Body)

  var deploy Deploy
  err := dec.Decode(&deploy)
  if err != nil && err != io.EOF {
    log.Fatal(err)
  } else {
    deploy.DeployedAt = time.Now()
  }

  revisions = append(revisions, deploy);
  io.WriteString(w, "")
}

func init() {
  r := mux.NewRouter()
  r.HandleFunc("/revisions", ListRevisions).
    Methods("GET")
  r.HandleFunc("/revisions", CreateRevision).
    Methods("POST")
  http.Handle("/", r)
}

func main() {
  var port string = os.Getenv("PORT")
  if port == "" {
    port = "8080"
  }
  fmt.Printf("Server listening on port %s\n", port)
  http.ListenAndServe(":"+port, nil)
}<|endoftext|>


<commit_before>package parser

import (
	"fmt"

	"github.com/labstack/echo"
)

type (
	user struct {
		Name   string `json:"name"`
		Email  string `json:"email"`
		MiBAID string `json:"mibaId"`
	}

	platform struct {
		Key     string `json:"key"`
		Version string `json:"version"`
	}

	device struct {
		Name   string `json:"name"`
		Brand  string `json:"brand"`
		Screen screen `json:"screen"`
	}

	screen struct {
		Width  int `json:"width"`
		Height int `json:"height"`
		PPI    int `json:"ppi"`
	}

	browser struct {
		Name    string `json:"name"`
		Version string `json:"version"`
	}

	Request struct {
		Rating   int      `json:"rating"`
		Comment  string   `json:"comment"`
		App      string   `json:"app"`   // The app key
		Range    string   `json:"range"` // The range key
		User     user     `json:"user"`
		Platform platform `json:"platform"`
		Device   device   `json:"device"`
		Browser  browser  `json:"browser"`
	}
)

func Parse(context echo.Context) (*Request, error) {
	request := new(Request)

	if err := context.Bind(request); err != nil {
		fmt.Println("Error parsing request:", err)

		return request, err
	}

	return request, nil
}
<commit_msg>Updated Parser<commit_after>package parser

import (
	"fmt"

	"github.com/labstack/echo"
)

type (
	user struct {
		Name   string `json:"name"`
		Email  string `json:"email"`
		MiBAID string `json:"mibaId"`
	}

	platform struct {
		Key     string `json:"key"`
		Version string `json:"version"`
	}

	device struct {
		Name   string `json:"name"`
		Brand  string `json:"brand"`
		Screen screen `json:"screen"`
	}

	screen struct {
		Width  int `json:"width"`
		Height int `json:"height"`
		PPI    int `json:"ppi"`
	}

	browser struct {
		Name    string `json:"name"`
		Version string `json:"version"`
	}

	Request struct {
		Rating      int      `json:"rating"`
		Description string   `json:"description"`
		Comment     string   `json:"comment"`
		App         string   `json:"app"`   // The app key
		Range       string   `json:"range"` // The range key
		User        user     `json:"user"`
		Platform    platform `json:"platform"`
		Device      device   `json:"device"`
		Browser     browser  `json:"browser"`
	}
)

func Parse(context echo.Context) (*Request, error) {
	request := new(Request)

	if err := context.Bind(request); err != nil {
		fmt.Println("Error parsing request:", err)

		return request, err
	}

	return request, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/vmware/govmomi"
	"github.com/vmware/govmomi/vim25/mo"
	"github.com/vmware/govmomi/vim25/types"
)

func resourceVm() *schema.Resource {
	return &schema.Resource{
		Create: resourceVmCreate,
		Read:   resourceVmRead,
		Update: resourceVmUpdate,
		Delete: resourceVmDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"source": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"datacenter": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"folder": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"host": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"pool": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"linked_clone": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
			},
		},
	}
}

func resourceVmCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*govmomi.Client)

	ref, err := client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%s/vm/%s", d.Get("datacenter").(string), d.Get("source").(string)))
	if err != nil {
		return fmt.Errorf("Error reading vm: %s", err)
	}
	vm, ok := ref.(*govmomi.VirtualMachine)
	if !ok {
		return fmt.Errorf("Error reading vm")
	}

	ref, err = client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%v/vm/%v", d.Get("datacenter").(string), d.Get("folder").(string)))
	if err != nil {
		return fmt.Errorf("Error reading folder: %s", err)
	}
	f, ok := ref.(*govmomi.Folder)
	if !ok {
		return fmt.Errorf("Error reading folder")
	}

	ref, err = client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%v/host/%v/Resources/%v", d.Get("datacenter").(string), d.Get("host").(string), d.Get("pool").(string)))
	if err != nil {
		return fmt.Errorf("Error reading resource pool: %s", err)
	}
	p, ok := ref.(*govmomi.ResourcePool)
	if !ok {
		return fmt.Errorf("Error reading resource pool")
	}
	pref := p.Reference()

/////////////
	var o mo.VirtualMachine
	err = client.Properties(vm.Reference(), []string{"snapshot"}, &o)
	if err != nil {
		return fmt.Errorf("Error reading snapshot")
	}
	if o.Snapshot == nil {
		return fmt.Errorf("Base VM has no snapshots")
	}
	sref := o.Snapshot.CurrentSnapshot
/////////////

	relocateSpec := types.VirtualMachineRelocateSpec{
		Pool: &pref,
	}
	linkedClone := d.Get("linked_clone").(bool)
	if linkedClone {
		relocateSpec.DiskMoveType = "createNewChildDiskBacking"
	}
	cloneSpec := types.VirtualMachineCloneSpec{
		Snapshot: sref,
		Location: relocateSpec,
	}
	name := d.Get("name").(string)

	task, err := vm.Clone(f, name, cloneSpec)
	if err != nil {
		return fmt.Errorf("Error clonning vm: %s", err)
	}
	_, err = task.WaitForResult(nil)
	if err != nil {
		return fmt.Errorf("Error clonning vm: %s", err)
	}

	d.SetId(name)
	log.Printf("[INFO] Create VM: %s", d.Id())
	return nil
}

func resourceVmRead(d *schema.ResourceData, meta interface{}) error {
	return nil
}

func resourceVmUpdate(d *schema.ResourceData, meta interface{}) error {
	return nil
}

func resourceVmDelete(d *schema.ResourceData, meta interface{}) error {
	return nil
}
<commit_msg>use vSphere machine UUID as Terraform resource ID<commit_after>package main

import (
	"fmt"
	"log"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/vmware/govmomi"
	"github.com/vmware/govmomi/vim25/mo"
	"github.com/vmware/govmomi/vim25/types"
)

func resourceVm() *schema.Resource {
	return &schema.Resource{
		Create: resourceVmCreate,
		Read:   resourceVmRead,
		Update: resourceVmUpdate,
		Delete: resourceVmDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"source": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"datacenter": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"folder": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"host": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"pool": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"linked_clone": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
			},
		},
	}
}

func resourceVmCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*govmomi.Client)

	ref, err := client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%s/vm/%s", d.Get("datacenter").(string), d.Get("source").(string)))
	if err != nil {
		return fmt.Errorf("Error reading vm: %s", err)
	}
	vm, ok := ref.(*govmomi.VirtualMachine)
	if !ok {
		return fmt.Errorf("Error reading vm")
	}

	ref, err = client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%v/vm/%v", d.Get("datacenter").(string), d.Get("folder").(string)))
	if err != nil {
		return fmt.Errorf("Error reading folder: %s", err)
	}
	f, ok := ref.(*govmomi.Folder)
	if !ok {
		return fmt.Errorf("Error reading folder")
	}

	ref, err = client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%v/host/%v/Resources/%v", d.Get("datacenter").(string), d.Get("host").(string), d.Get("pool").(string)))
	if err != nil {
		return fmt.Errorf("Error reading resource pool: %s", err)
	}
	p, ok := ref.(*govmomi.ResourcePool)
	if !ok {
		return fmt.Errorf("Error reading resource pool")
	}
	pref := p.Reference()

/////////////
	var o mo.VirtualMachine
	err = client.Properties(vm.Reference(), []string{"snapshot"}, &o)
	if err != nil {
		return fmt.Errorf("Error reading snapshot")
	}
	if o.Snapshot == nil {
		return fmt.Errorf("Base VM has no snapshots")
	}
	sref := o.Snapshot.CurrentSnapshot
/////////////

	relocateSpec := types.VirtualMachineRelocateSpec{
		Pool: &pref,
	}
	linkedClone := d.Get("linked_clone").(bool)
	if linkedClone {
		relocateSpec.DiskMoveType = "createNewChildDiskBacking"
	}
	cloneSpec := types.VirtualMachineCloneSpec{
		Snapshot: sref,
		Location: relocateSpec,
	}
	name := d.Get("name").(string)

	task, err := vm.Clone(f, name, cloneSpec)
	if err != nil {
		return fmt.Errorf("Error clonning vm: %s", err)
	}
	_, err = task.WaitForResult(nil)
	if err != nil {
		return fmt.Errorf("Error clonning vm: %s", err)
	}

	err = client.Properties(vm.Reference(), []string{"config.uuid"}, &o)
	if err != nil {
		return fmt.Errorf("Error reading UUID")
	}
	d.SetId(o.Config.Uuid)
	return nil
}

func resourceVmRead(d *schema.ResourceData, meta interface{}) error {
	return nil
}

func resourceVmUpdate(d *schema.ResourceData, meta interface{}) error {
	return nil
}

func resourceVmDelete(d *schema.ResourceData, meta interface{}) error {
	return nil
}
<|endoftext|>


<commit_before>package response551

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/go51/string551"
	"github.com/go51/time551"
	"html/template"
	"net/http"
)

type RedirectType struct {
	uri  string
	code int
	text string
}

func Redirect(uri string, code int) RedirectType {
	return RedirectType{
		uri:  uri,
		code: code,
		text: http.StatusText(code),
	}
}

func (r RedirectType) Code() int {
	return r.code
}

func (r RedirectType) Text() string {
	return r.text
}

func (r RedirectType) Uri() string {
	return r.uri
}

type ErrorType struct {
	code    int
	text    string
	message string
}

func Error(code int, message string) ErrorType {
	return ErrorType{
		code:    code,
		text:    http.StatusText(code),
		message: message,
	}
}

func (e ErrorType) Code() int {
	return e.code
}

func (e ErrorType) Text() string {
	return e.text
}

func (e ErrorType) Message() string {
	return e.message
}

func (e ErrorType) String() string {
	return e.message
}

func Response(w http.ResponseWriter, r *http.Request, data interface{}, packageName, routeName string, user interface{}, appConfig interface{}) {
	if redirectType, ok := interface{}(data).(RedirectType); ok {
		// Redirect Type
		http.Redirect(w, r, redirectType.uri, redirectType.code)
		return
	} else if errorType, ok := interface{}(data).(ErrorType); ok {
		// Error Type
		http.Error(w, errorType.message, errorType.code)
		return
	} else if param, ok := interface{}(data).(map[string]interface{}); ok {
		if isJSON(r) {
			jsonOutput(w, param)
		} else {
			// View template rendering
			param["user"] = user
			param["config"] = appConfig
			htmlOutput(w, param, packageName, routeName)
		}
		return
	}

	fmt.Fprintf(w, "%v", data)

}

func isJSON(r *http.Request) bool {
	format := string551.Lower(r.FormValue("format"))

	if format == "json" {
		return true
	} else {
		return false
	}
}

var templates = make(map[string]*template.Template)

func htmlOutput(w http.ResponseWriter, data interface{}, packageName, routeName string) {

	var err error = nil
	tmpl := templates[packageName+"/"+routeName]

	if tmpl == nil {
		templateFiles := []string{
			"view/template/base.html",
			"view/" + packageName + "/" + routeName + ".html",
		}

		tmpl, err = template.New(packageName + "/" + routeName).Funcs(funcMap()).ParseFiles(templateFiles...)
		if err != nil {
			http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
			return
		}

		templates[packageName+"/"+routeName] = tmpl

	}

	buf := &bytes.Buffer{}

	err = tmpl.ExecuteTemplate(buf, "base", data)
	if err != nil {
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}

	fmt.Fprint(w, buf)

}

func jsonOutput(w http.ResponseWriter, data interface{}) {
	jsonData, err := json.Marshal(data)
	if err != nil {
		panic(err)
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(jsonData)
}

func funcMap() template.FuncMap {
	funcMap := template.FuncMap{}

	funcMap["raw"] = func(text string) template.HTML {
		return template.HTML(text)
	}
	funcMap["url"] = UrlFunction
	funcMap["rightRune"] = string551.RightRune
	funcMap["right"] = string551.Right
	funcMap["elapsed"] = time551.Elapsed

	return funcMap

}

type urlFunc func(name string, parameter ...string) string

var UrlFunction urlFunc
<commit_msg>refs #23 開発環境ではテンプレートをキャッシュしない<commit_after>package response551

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/go51/string551"
	"github.com/go51/time551"
	"html/template"
	"net/http"
	"os"
)

type RedirectType struct {
	uri  string
	code int
	text string
}

func Redirect(uri string, code int) RedirectType {
	return RedirectType{
		uri:  uri,
		code: code,
		text: http.StatusText(code),
	}
}

func (r RedirectType) Code() int {
	return r.code
}

func (r RedirectType) Text() string {
	return r.text
}

func (r RedirectType) Uri() string {
	return r.uri
}

type ErrorType struct {
	code    int
	text    string
	message string
}

func Error(code int, message string) ErrorType {
	return ErrorType{
		code:    code,
		text:    http.StatusText(code),
		message: message,
	}
}

func (e ErrorType) Code() int {
	return e.code
}

func (e ErrorType) Text() string {
	return e.text
}

func (e ErrorType) Message() string {
	return e.message
}

func (e ErrorType) String() string {
	return e.message
}

func Response(w http.ResponseWriter, r *http.Request, data interface{}, packageName, routeName string, user interface{}, appConfig interface{}) {
	if redirectType, ok := interface{}(data).(RedirectType); ok {
		// Redirect Type
		http.Redirect(w, r, redirectType.uri, redirectType.code)
		return
	} else if errorType, ok := interface{}(data).(ErrorType); ok {
		// Error Type
		http.Error(w, errorType.message, errorType.code)
		return
	} else if param, ok := interface{}(data).(map[string]interface{}); ok {
		if isJSON(r) {
			jsonOutput(w, param)
		} else {
			// View template rendering
			param["user"] = user
			param["config"] = appConfig
			htmlOutput(w, param, packageName, routeName)
		}
		return
	}

	fmt.Fprintf(w, "%v", data)

}

func isJSON(r *http.Request) bool {
	format := string551.Lower(r.FormValue("format"))

	if format == "json" {
		return true
	} else {
		return false
	}
}

var templates = make(map[string]*template.Template)

func htmlOutput(w http.ResponseWriter, data interface{}, packageName, routeName string) {

	var err error = nil
	tmpl := templates[packageName+"/"+routeName]

	if tmpl == nil {
		templateFiles := []string{
			"view/template/base.html",
			"view/" + packageName + "/" + routeName + ".html",
		}

		tmpl, err = template.New(packageName + "/" + routeName).Funcs(funcMap()).ParseFiles(templateFiles...)
		if err != nil {
			http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
			return
		}

		if getConfigEnv() == "prod" {
			templates[packageName+"/"+routeName] = tmpl
		}

	}

	buf := &bytes.Buffer{}

	err = tmpl.ExecuteTemplate(buf, "base", data)
	if err != nil {
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}

	fmt.Fprint(w, buf)

}

func jsonOutput(w http.ResponseWriter, data interface{}) {
	jsonData, err := json.Marshal(data)
	if err != nil {
		panic(err)
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(jsonData)
}

func funcMap() template.FuncMap {
	funcMap := template.FuncMap{}

	funcMap["raw"] = func(text string) template.HTML {
		return template.HTML(text)
	}
	funcMap["url"] = UrlFunction
	funcMap["rightRune"] = string551.RightRune
	funcMap["right"] = string551.Right
	funcMap["elapsed"] = time551.Elapsed

	return funcMap

}

type urlFunc func(name string, parameter ...string) string

var UrlFunction urlFunc

func getConfigEnv() string {
	return os.Getenv("GORAI_ENV")
}
<|endoftext|>


<commit_before>// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com

// Package logging defines application-wide logging implementation.
package logging

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"runtime"

	"github.com/documize/community/core/env"
	"github.com/jmoiron/sqlx"
)

// Logger is how we log.
type Logger struct {
	db    *sqlx.DB
	log   *log.Logger
	trace bool // shows Info() entries
}

// Info logs message.
func (l Logger) Info(message string) {
	l.log.Println(message)
}

// Infof logs message via Sprintf.
func (l Logger) Infof(message string, a ...interface{}) {
	l.log.Println(fmt.Sprintf(message, a))
}

// Trace logs message if tracing enabled.
func (l Logger) Trace(message string) {
	if l.trace {
		l.log.Println(message)
	}
}

// Error logs error with message.
func (l Logger) Error(message string, err error) {
	l.log.Println(message)
	l.log.Println(err)

	stack := make([]byte, 4096)
	runtime.Stack(stack, false)
	if idx := bytes.IndexByte(stack, 0); idx > 0 && idx < len(stack) {
		stack = stack[:idx] // remove trailing nulls from stack dump
	}

	l.log.Println(fmt.Sprintf("%s", stack))
}

// SetDB associates database connection with given logger.
// Logger will also record messages to database given valid database connection.
func (l Logger) SetDB(logger env.Logger, db *sqlx.DB) env.Logger {
	l.db = db
	return logger
}

// NewLogger returns initialized logging instance.
func NewLogger(trace bool) env.Logger {
	l := log.New(os.Stdout, "", 0)
	l.SetOutput(os.Stdout)
	// log.SetOutput(os.Stdout)

	var logger Logger
	logger.log = l
	logger.trace = trace

	return logger
}
<commit_msg>Allow logger.Info multiple args<commit_after>// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com

// Package logging defines application-wide logging implementation.
package logging

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"runtime"

	"github.com/documize/community/core/env"
	"github.com/jmoiron/sqlx"
)

// Logger is how we log.
type Logger struct {
	db    *sqlx.DB
	log   *log.Logger
	trace bool // shows Info() entries
}

// Info logs message.
func (l Logger) Info(message string) {
	l.log.Println(message)
}

// Infof logs message via Sprintf.
func (l Logger) Infof(message string, a ...interface{}) {
	l.log.Println(fmt.Sprintf(message, a...))
}

// Trace logs message if tracing enabled.
func (l Logger) Trace(message string) {
	if l.trace {
		l.log.Println(message)
	}
}

// Error logs error with message.
func (l Logger) Error(message string, err error) {
	l.log.Println(message)
	l.log.Println(err)

	stack := make([]byte, 4096)
	runtime.Stack(stack, false)
	if idx := bytes.IndexByte(stack, 0); idx > 0 && idx < len(stack) {
		stack = stack[:idx] // remove trailing nulls from stack dump
	}

	l.log.Println(fmt.Sprintf("%s", stack))
}

// SetDB associates database connection with given logger.
// Logger will also record messages to database given valid database connection.
func (l Logger) SetDB(logger env.Logger, db *sqlx.DB) env.Logger {
	l.db = db
	return logger
}

// NewLogger returns initialized logging instance.
func NewLogger(trace bool) env.Logger {
	l := log.New(os.Stdout, "", 0)
	l.SetOutput(os.Stdout)
	// log.SetOutput(os.Stdout)

	var logger Logger
	logger.log = l
	logger.trace = trace

	return logger
}
<|endoftext|>


<commit_before>package controllers

import (
	"strings"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/robxu9/kahinah/models"
	"menteslibres.net/gosexy/to"
)

const (
	PERMISSION_ADMIN     = "kahinah.admin"
	PERMISSION_QA        = "kahinah.qa"
	PERMISSION_WHITELIST = "kahinah.whitelist"

	PERMISSION_ADVISORY = "kahinah.advisory"
)

var (
	adminWhitelist = strings.Split(beego.AppConfig.String("admin::adminwhitelist"), ";")
	Whitelist      = to.Bool(beego.AppConfig.String("admin::whitelist"))
)

func init() {
	models.PermRegister(PERMISSION_ADMIN)
	models.PermRegister(PERMISSION_QA)
	models.PermRegister(PERMISSION_WHITELIST)
	models.PermRegister(PERMISSION_ADVISORY)
}

func adminCheck(this *beego.Controller) {
	user := models.IsLoggedIn(this)

	if user == "" {
		this.Abort("403")
	}

	loggedin := false

	for _, v := range adminWhitelist {
		if v == user {
			loggedin = true
		}
	}

	if !loggedin {
		models.PermAbortCheck(this, PERMISSION_ADMIN)
	}
}

type AdminController struct {
	BaseController
}

func (this *AdminController) Get() {
	adminCheck(&this.Controller)

	this.Data["Loc"] = 0
	this.Data["Tab"] = -1

	perms := make(map[string][]string)

	for _, perm := range models.PermGetAll() {
		perms[perm.Permission] = make([]string, 0)

		for _, v := range perm.Users {
			perms[perm.Permission] = append(perms[perm.Permission], v.Email)
		}
	}

	this.Data["Title"] = "Admin"
	this.Data["Permissions"] = perms
	this.TplNames = "admin.tpl"
}

func (this *AdminController) Post() {

	if this.GetString("email") != "" {
		user := models.FindUserNoCreate(this.GetString("email"))
		if user == nil {
			flash := beego.NewFlash()
			flash.Error("No such email " + this.GetString("email") + "!")
			flash.Store(&this.Controller)
		} else {
			o := orm.NewOrm()
			m2m := o.QueryM2M(user, "Permissions")
			this.Data["User"] = user
			if this.GetString("add") != "" {
				addperm := this.GetString("add")
				addpermobj := models.PermGet(addperm)
				if addpermobj == nil {
					flash := beego.NewFlash()
					flash.Error("No such permission " + addperm + "!")
					flash.Store(&this.Controller)
				} else {
					if !m2m.Exist(addpermobj) {
						_, err := m2m.Add(addpermobj)
						if err != nil {
							panic(err)
						}
					}
				}
			}
			if this.GetString("rm") != "" {
				rmperm := this.GetString("rm")
				rmpermobj := models.PermGet(rmperm)
				if rmpermobj == nil {
					flash := beego.NewFlash()
					flash.Error("No such permission " + rmperm + "!")
					flash.Store(&this.Controller)
				} else {
					_, err := m2m.Remove(rmpermobj)
					if err != nil {
						panic(err)
					}
				}
			}
		}
	}

	this.Get()

}
<commit_msg>fix admin controller security<commit_after>package controllers

import (
	"strings"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/robxu9/kahinah/models"
	"menteslibres.net/gosexy/to"
)

const (
	PERMISSION_ADMIN     = "kahinah.admin"
	PERMISSION_QA        = "kahinah.qa"
	PERMISSION_WHITELIST = "kahinah.whitelist"

	PERMISSION_ADVISORY = "kahinah.advisory"
)

var (
	adminWhitelist = strings.Split(beego.AppConfig.String("admin::adminwhitelist"), ";")
	Whitelist      = to.Bool(beego.AppConfig.String("admin::whitelist"))
)

func init() {
	models.PermRegister(PERMISSION_ADMIN)
	models.PermRegister(PERMISSION_QA)
	models.PermRegister(PERMISSION_WHITELIST)
	models.PermRegister(PERMISSION_ADVISORY)
}

func adminCheck(this *beego.Controller) {
	user := models.IsLoggedIn(this)

	if user == "" {
		this.Abort("403")
	}

	loggedin := false

	for _, v := range adminWhitelist {
		if v == user {
			loggedin = true
		}
	}

	if !loggedin {
		models.PermAbortCheck(this, PERMISSION_ADMIN)
	}
}

type AdminController struct {
	BaseController
}

func (this *AdminController) Get() {
	adminCheck(&this.Controller)

	this.Data["Loc"] = 0
	this.Data["Tab"] = -1

	if this.GetString("email") != "" {
		user := models.FindUserNoCreate(this.GetString("email"))
		if user == nil {
			flash := beego.NewFlash()
			flash.Error("No such email " + this.GetString("email") + "!")
			flash.Store(&this.Controller)
		} else {
			this.Data["User"] = user
		}
	}

	perms := make(map[string][]string)

	for _, perm := range models.PermGetAll() {
		perms[perm.Permission] = make([]string, 0)

		for _, v := range perm.Users {
			perms[perm.Permission] = append(perms[perm.Permission], v.Email)
		}
	}

	this.Data["Title"] = "Admin"
	this.Data["Permissions"] = perms
	this.TplNames = "admin.tpl"
}

func (this *AdminController) Post() {
	adminCheck(&this.Controller)

	if this.GetString("email") != "" {
		user := models.FindUserNoCreate(this.GetString("email"))
		if user == nil {
			flash := beego.NewFlash()
			flash.Error("No such email " + this.GetString("email") + "!")
			flash.Store(&this.Controller)
		} else {
			o := orm.NewOrm()
			m2m := o.QueryM2M(user, "Permissions")
			this.Data["User"] = user
			if this.GetString("add") != "" {
				addperm := this.GetString("add")
				addpermobj := models.PermGet(addperm)
				if addpermobj == nil {
					flash := beego.NewFlash()
					flash.Error("No such permission " + addperm + "!")
					flash.Store(&this.Controller)
				} else {
					if !m2m.Exist(addpermobj) {
						_, err := m2m.Add(addpermobj)
						if err != nil {
							panic(err)
						}
					}
				}
			}
			if this.GetString("rm") != "" {
				rmperm := this.GetString("rm")
				rmpermobj := models.PermGet(rmperm)
				if rmpermobj == nil {
					flash := beego.NewFlash()
					flash.Error("No such permission " + rmperm + "!")
					flash.Store(&this.Controller)
				} else {
					_, err := m2m.Remove(rmpermobj)
					if err != nil {
						panic(err)
					}
				}
			}
		}
	}

	this.Get()

}
<|endoftext|>


<commit_before>package controllers

import (
	"net/http"

	"gopkg.in/gin-gonic/gin.v1"
)

type enterRequest struct {
	baseRequest
	AppFriends uint8  `json:"appFriends,string" binding:"required"`
	Referer    string `json:"referer" binding:"required"`
	SrcExtID   string `json:"srcExtId" binding:"required"`
}

type enterResponse struct {
	ReqMsgID               uint64     `json:"reqMsgId"`
	UserID                 uint32     `json:"userId"`
	ReachedStage01         uint8      `json:"reachedStage01"`
	ReachedStage02         uint8      `json:"reachedStage02"`
	ReachedSubStage01      uint8      `json:"reachedSubStage01"`
	ReachedSubStage02      uint8      `json:"reachedSubStage02"`
	IgnoreSavePointBlock   bool       `json:"ignoreSavePointBlock"`
	RemainingTries         uint8      `json:"remainingTries"`
	Credits                uint16     `json:"credits"`
	InfinityExtra00        bool       `json:"inifinityExtra00"`
	InfinityExtra01        bool       `json:"inifinityExtra01"`
	InfinityExtra02        bool       `json:"inifinityExtra02"`
	InfinityExtra03        bool       `json:"inifinityExtra03"`
	InfinityExtra04        bool       `json:"inifinityExtra04"`
	InfinityExtra05        bool       `json:"inifinityExtra05"`
	InfinityExtra06        bool       `json:"inifinityExtra06"`
	InfinityExtra07        bool       `json:"inifinityExtra07"`
	InfinityExtra08        bool       `json:"inifinityExtra08"`
	InfinityExtra09        bool       `json:"inifinityExtra09"`
	BonusCredits           uint16     `json:"bonusCredits"`
	AppFriendsBonusCredits uint16     `json:"appFriendsBonusCredits"`
	OfferAvailable         bool       `json:"offerAvailable"`
	FirstGame              bool       `json:"firstGame"`
	StagesProgressStat01   [8]uint32  `json:"stagesProgressStat01"`
	StagesProgressStat02   [8]uint32  `json:"stagesProgressStat02"`
	SubStagesRecordStats01 [8][]uint8 `json:"subStagesRecordStats01"`
	SubStagesRecordStats02 [8][]uint8 `json:"subStagesRecordStats02"`
}

// ReqEnter first request from client. Return user info and user progress
func ReqEnter(c *gin.Context) {
	request := enterRequest{}
	if err := c.BindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, getErrBody(err))
		return
	}
	// logic
	response := enterResponse{
		ReqMsgID: request.MsgID,
	}
	c.JSON(http.StatusOK, response)
}
<commit_msg>debug<commit_after>package controllers

import (
	"log"
	"net/http"

	"gopkg.in/gin-gonic/gin.v1"
)

type enterRequest struct {
	baseRequest
	AppFriends uint8  `json:"appFriends,string" binding:"required"`
	Referer    string `json:"referer" binding:"required"`
	SrcExtID   string `json:"srcExtId" binding:"required"`
}

type enterResponse struct {
	ReqMsgID               uint64     `json:"reqMsgId"`
	UserID                 uint32     `json:"userId"`
	ReachedStage01         uint8      `json:"reachedStage01"`
	ReachedStage02         uint8      `json:"reachedStage02"`
	ReachedSubStage01      uint8      `json:"reachedSubStage01"`
	ReachedSubStage02      uint8      `json:"reachedSubStage02"`
	IgnoreSavePointBlock   bool       `json:"ignoreSavePointBlock"`
	RemainingTries         uint8      `json:"remainingTries"`
	Credits                uint16     `json:"credits"`
	InfinityExtra00        bool       `json:"inifinityExtra00"`
	InfinityExtra01        bool       `json:"inifinityExtra01"`
	InfinityExtra02        bool       `json:"inifinityExtra02"`
	InfinityExtra03        bool       `json:"inifinityExtra03"`
	InfinityExtra04        bool       `json:"inifinityExtra04"`
	InfinityExtra05        bool       `json:"inifinityExtra05"`
	InfinityExtra06        bool       `json:"inifinityExtra06"`
	InfinityExtra07        bool       `json:"inifinityExtra07"`
	InfinityExtra08        bool       `json:"inifinityExtra08"`
	InfinityExtra09        bool       `json:"inifinityExtra09"`
	BonusCredits           uint16     `json:"bonusCredits"`
	AppFriendsBonusCredits uint16     `json:"appFriendsBonusCredits"`
	OfferAvailable         bool       `json:"offerAvailable"`
	FirstGame              bool       `json:"firstGame"`
	StagesProgressStat01   [8]uint32  `json:"stagesProgressStat01"`
	StagesProgressStat02   [8]uint32  `json:"stagesProgressStat02"`
	SubStagesRecordStats01 [8][]uint8 `json:"subStagesRecordStats01"`
	SubStagesRecordStats02 [8][]uint8 `json:"subStagesRecordStats02"`
}

// ReqEnter first request from client. Return user info and user progress
func ReqEnter(c *gin.Context) {
	request := enterRequest{}
	log.Print("before bind")
	if err := c.BindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, getErrBody(err))
		return
	}
	// logic
	response := enterResponse{
		ReqMsgID: request.MsgID,
	}
	c.JSON(http.StatusOK, response)
}
<|endoftext|>


<commit_before>package controllers

import (
	"github.com/Marktown/frontend/backends/file_system"
	"text/scanner"
)

type PathItem struct {
	Path  string     `json:"name"`
	Items []PathItem `json:"items"`
}

type Textfile struct {
	Data string `json:"data"`
}

type FilesController struct {
	BaseController
}

func (this *FilesController) Prepare() {
	this.SetupEnv()
	this.Layout = "layouts/default.html.tpl"
}

func (this *FilesController) Index() {
	fs := file_system.NewFileStore()
	fs.RootPath = "tests/assets/testfolder/"
	list, err := fs.ReadDir("")
	//TODO error handling
	if err != nil {
		return
	}
	//TODO use ReadDirTree for recursive reading, must be implemented
	pathItems := PathItem{"/", []PathItem{}}
	items := make([]PathItem, len(list))
	for index, file := range list {
		items[index] = PathItem{file.Name(), []PathItem{}}
	}
	pathItems.Items = items
	this.Data["json"] = &pathItems
	this.ServeJson()
}

func (this *FilesController) New() {
	this.TplNames = "files/new.html.tpl"
}

func (this *FilesController) Read() {
	textfile := Textfile{}
	fs := file_system.NewFileStore()
	fs.RootPath = "tests/assets/testfolder/"
	reader, err := fs.ReadFile(this.GetString("path"))
	if err != nil {
		return
	}

	textfile.Data = ""
	var s scanner.Scanner
	s.Init(reader)
	s.Whitespace = 1
	tok := s.Scan()
	for tok != scanner.EOF {
		textfile.Data += s.TokenText()
		tok = s.Scan()
	}
	this.Data["json"] = &textfile
	this.ServeJson()
}

func (this *FilesController) Update() {
	this.TplNames = "files/update.html.tpl"
}

func (this *FilesController) Delete() {
	this.TplNames = "files/delete.html.tpl"
}
<commit_msg>Add some todo comments<commit_after>package controllers

import (
	"github.com/Marktown/frontend/backends/file_system"
	"text/scanner"
)

type PathItem struct {
	Path  string     `json:"name"`
	Items []PathItem `json:"items"`
}

type Textfile struct {
	Data string `json:"data"`
}

type FilesController struct {
	BaseController
}

func (this *FilesController) Prepare() {
	this.SetupEnv()
	this.Layout = "layouts/default.html.tpl"
}

func (this *FilesController) Index() {
	fs := file_system.NewFileStore()
	fs.RootPath = "tests/assets/testfolder/"
	list, err := fs.ReadDir("")
	//TODO error handling
	if err != nil {
		return
	}
	//TODO use ReadDirTree for recursive reading, must be implemented
	pathItems := PathItem{"/", []PathItem{}}
	items := make([]PathItem, len(list))
	for index, file := range list {
		items[index] = PathItem{file.Name(), []PathItem{}}
	}
	pathItems.Items = items
	this.Data["json"] = &pathItems
	this.ServeJson()
}

func (this *FilesController) New() {
	this.TplNames = "files/new.html.tpl"
}

func (this *FilesController) Read() {
	textfile := Textfile{}
	fs := file_system.NewFileStore()
	fs.RootPath = "tests/assets/testfolder/"
	reader, err := fs.ReadFile(this.GetString("path"))
	//TODO error handling
	if err != nil {
		// possibilities:
		// * "file does not exist"
		// * redirect to create-new-file
		return
	}

	textfile.Data = ""
	var s scanner.Scanner
	s.Init(reader)
	s.Whitespace = 1
	tok := s.Scan()
	for tok != scanner.EOF {
		textfile.Data += s.TokenText()
		tok = s.Scan()
	}
	this.Data["json"] = &textfile
	this.ServeJson()
}

func (this *FilesController) Update() {
	this.TplNames = "files/update.html.tpl"
}

func (this *FilesController) Delete() {
	this.TplNames = "files/delete.html.tpl"
}
<|endoftext|>