<commit_before>package eth

import (
	"crypto/ecdsa"
	"fmt"
	"strings"
	"sync"

	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethdb"
	"github.com/ethereum/go-ethereum/ethutil"
	"github.com/ethereum/go-ethereum/event"
	ethlogger "github.com/ethereum/go-ethereum/logger"
	"github.com/ethereum/go-ethereum/p2p"
	"github.com/ethereum/go-ethereum/p2p/discover"
	"github.com/ethereum/go-ethereum/pow/ezp"
	"github.com/ethereum/go-ethereum/rpc"
	"github.com/ethereum/go-ethereum/whisper"
)

var logger = ethlogger.NewLogger("SERV")

type Config struct {
	Name     string
	KeyStore string
	DataDir  string
	LogFile  string
	LogLevel int
	KeyRing  string

	MaxPeers   int
	Port       string
	NATType    string
	PMPGateway string

	// This should be a space-separated list of
	// discovery node URLs.
	BootNodes string

	// This key is used to identify the node on the network.
	// If nil, an ephemeral key is used.
	NodeKey *ecdsa.PrivateKey

	Shh  bool
	Dial bool

	KeyManager *crypto.KeyManager
}

func (cfg *Config) parseBootNodes() []*discover.Node {
	var ns []*discover.Node
	for _, url := range strings.Split(cfg.BootNodes, " ") {
		if url == "" {
			continue
		}
		n, err := discover.ParseNode(url)
		if err != nil {
			logger.Errorf("Bootstrap URL %s: %v\n", url, err)
			continue
		}
		ns = append(ns, n)
	}
	return ns
}

type Ethereum struct {
	// Channel for shutting down the ethereum
	shutdownChan chan bool
	quit         chan bool

	// DB interface
	db        ethutil.Database
	blacklist p2p.Blacklist

	//*** SERVICES ***
	// State manager for processing new blocks and managing the over all states
	blockProcessor *core.BlockProcessor
	txPool         *core.TxPool
	chainManager   *core.ChainManager
	blockPool      *BlockPool
	whisper        *whisper.Whisper

	net      *p2p.Server
	eventMux *event.TypeMux
	txSub    event.Subscription
	blockSub event.Subscription

	RpcServer  rpc.RpcServer
	WsServer   rpc.RpcServer
	keyManager *crypto.KeyManager

	logger ethlogger.LogSystem

	synclock  sync.Mutex
	syncGroup sync.WaitGroup

	Mining bool
}

func New(config *Config) (*Ethereum, error) {
	// Boostrap database
	logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel)
	db, err := ethdb.NewLDBDatabase("blockchain")
	if err != nil {
		return nil, err
	}

	// Perform database sanity checks
	d, _ := db.Get([]byte("ProtocolVersion"))
	protov := ethutil.NewValue(d).Uint()
	if protov != ProtocolVersion && protov != 0 {
		return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, ethutil.Config.ExecPath+"/database")
	}

	// Create new keymanager
	var keyManager *crypto.KeyManager
	switch config.KeyStore {
	case "db":
		keyManager = crypto.NewDBKeyManager(db)
	case "file":
		keyManager = crypto.NewFileKeyManager(config.DataDir)
	default:
		return nil, fmt.Errorf("unknown keystore type: %s", config.KeyStore)
	}
	// Initialise the keyring
	keyManager.Init(config.KeyRing, 0, false)

	saveProtocolVersion(db)
	//ethutil.Config.Db = db

	eth := &Ethereum{
		shutdownChan: make(chan bool),
		quit:         make(chan bool),
		db:           db,
		keyManager:   keyManager,
		blacklist:    p2p.NewBlacklist(),
		eventMux:     &event.TypeMux{},
		logger:       logger,
	}

	eth.chainManager = core.NewChainManager(db, eth.EventMux())
	eth.txPool = core.NewTxPool(eth.EventMux())
	eth.blockProcessor = core.NewBlockProcessor(db, eth.txPool, eth.chainManager, eth.EventMux())
	eth.chainManager.SetProcessor(eth.blockProcessor)
	eth.whisper = whisper.New()

	hasBlock := eth.chainManager.HasBlock
	insertChain := eth.chainManager.InsertChain
	eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify)

	ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool)
	protocols := []p2p.Protocol{ethProto, eth.whisper.Protocol()}
	nat, err := p2p.ParseNAT(config.NATType, config.PMPGateway)
	if err != nil {
		return nil, err
	}
	netprv := config.NodeKey
	if netprv == nil {
		if netprv, err = crypto.GenerateKey(); err != nil {
			return nil, fmt.Errorf("could not generate server key: %v", err)
		}
	}
	eth.net = &p2p.Server{
		PrivateKey:     netprv,
		Name:           config.Name,
		MaxPeers:       config.MaxPeers,
		Protocols:      protocols,
		Blacklist:      eth.blacklist,
		NAT:            nat,
		NoDial:         !config.Dial,
		BootstrapNodes: config.parseBootNodes(),
	}
	if len(config.Port) > 0 {
		eth.net.ListenAddr = ":" + config.Port
	}

	return eth, nil
}

func (s *Ethereum) KeyManager() *crypto.KeyManager {
	return s.keyManager
}

func (s *Ethereum) Logger() ethlogger.LogSystem {
	return s.logger
}

func (s *Ethereum) Name() string {
	return s.net.Name
}

func (s *Ethereum) ChainManager() *core.ChainManager {
	return s.chainManager
}

func (s *Ethereum) BlockProcessor() *core.BlockProcessor {
	return s.blockProcessor
}

func (s *Ethereum) TxPool() *core.TxPool {
	return s.txPool
}

func (s *Ethereum) BlockPool() *BlockPool {
	return s.blockPool
}

func (s *Ethereum) Whisper() *whisper.Whisper {
	return s.whisper
}

func (s *Ethereum) EventMux() *event.TypeMux {
	return s.eventMux
}
func (self *Ethereum) Db() ethutil.Database {
	return self.db
}

func (s *Ethereum) IsMining() bool {
	return s.Mining
}

func (s *Ethereum) IsListening() bool {
	// XXX TODO
	return false
}

func (s *Ethereum) PeerCount() int {
	return s.net.PeerCount()
}

func (s *Ethereum) Peers() []*p2p.Peer {
	return s.net.Peers()
}

func (s *Ethereum) MaxPeers() int {
	return s.net.MaxPeers
}

func (s *Ethereum) Coinbase() []byte {
	return nil // TODO
}

// Start the ethereum
func (s *Ethereum) Start() error {
	err := s.net.Start()
	if err != nil {
		return err
	}

	// Start services
	s.txPool.Start()
	s.blockPool.Start()

	if s.whisper != nil {
		s.whisper.Start()
	}

	// broadcast transactions
	s.txSub = s.eventMux.Subscribe(core.TxPreEvent{})
	go s.txBroadcastLoop()

	// broadcast mined blocks
	s.blockSub = s.eventMux.Subscribe(core.NewMinedBlockEvent{})
	go s.blockBroadcastLoop()

	logger.Infoln("Server started")
	return nil
}

func (self *Ethereum) SuggestPeer(nodeURL string) error {
	n, err := discover.ParseNode(nodeURL)
	if err != nil {
		return fmt.Errorf("invalid node URL: %v", err)
	}
	self.net.SuggestPeer(n)
	return nil
}

func (s *Ethereum) Stop() {
	// Close the database
	defer s.db.Close()

	close(s.quit)

	s.txSub.Unsubscribe()    // quits txBroadcastLoop
	s.blockSub.Unsubscribe() // quits blockBroadcastLoop

	if s.RpcServer != nil {
		s.RpcServer.Stop()
	}
	if s.WsServer != nil {
		s.WsServer.Stop()
	}
	s.txPool.Stop()
	s.eventMux.Stop()
	s.blockPool.Stop()
	if s.whisper != nil {
		s.whisper.Stop()
	}

	logger.Infoln("Server stopped")
	close(s.shutdownChan)
}

// This function will wait for a shutdown and resumes main thread execution
func (s *Ethereum) WaitForShutdown() {
	<-s.shutdownChan
}

// now tx broadcasting is taken out of txPool
// handled here via subscription, efficiency?
func (self *Ethereum) txBroadcastLoop() {
	// automatically stops if unsubscribe
	for obj := range self.txSub.Chan() {
		event := obj.(core.TxPreEvent)
		self.net.Broadcast("eth", TxMsg, event.Tx.RlpData())
	}
}

func (self *Ethereum) blockBroadcastLoop() {
	// automatically stops if unsubscribe
	for obj := range self.blockSub.Chan() {
		switch ev := obj.(type) {
		case core.NewMinedBlockEvent:
			self.net.Broadcast("eth", NewBlockMsg, ev.Block.RlpData(), ev.Block.Td)
		}
	}
}

func saveProtocolVersion(db ethutil.Database) {
	d, _ := db.Get([]byte("ProtocolVersion"))
	protocolVersion := ethutil.NewValue(d).Uint()

	if protocolVersion == 0 {
		db.Put([]byte("ProtocolVersion"), ethutil.NewValue(ProtocolVersion).Bytes())
	}
}
<commit_msg>eth: remove unused Ethereum sync fields<commit_after>package eth

import (
	"crypto/ecdsa"
	"fmt"
	"strings"

	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethdb"
	"github.com/ethereum/go-ethereum/ethutil"
	"github.com/ethereum/go-ethereum/event"
	ethlogger "github.com/ethereum/go-ethereum/logger"
	"github.com/ethereum/go-ethereum/p2p"
	"github.com/ethereum/go-ethereum/p2p/discover"
	"github.com/ethereum/go-ethereum/pow/ezp"
	"github.com/ethereum/go-ethereum/rpc"
	"github.com/ethereum/go-ethereum/whisper"
)

var logger = ethlogger.NewLogger("SERV")

type Config struct {
	Name     string
	KeyStore string
	DataDir  string
	LogFile  string
	LogLevel int
	KeyRing  string

	MaxPeers   int
	Port       string
	NATType    string
	PMPGateway string

	// This should be a space-separated list of
	// discovery node URLs.
	BootNodes string

	// This key is used to identify the node on the network.
	// If nil, an ephemeral key is used.
	NodeKey *ecdsa.PrivateKey

	Shh  bool
	Dial bool

	KeyManager *crypto.KeyManager
}

func (cfg *Config) parseBootNodes() []*discover.Node {
	var ns []*discover.Node
	for _, url := range strings.Split(cfg.BootNodes, " ") {
		if url == "" {
			continue
		}
		n, err := discover.ParseNode(url)
		if err != nil {
			logger.Errorf("Bootstrap URL %s: %v\n", url, err)
			continue
		}
		ns = append(ns, n)
	}
	return ns
}

type Ethereum struct {
	// Channel for shutting down the ethereum
	shutdownChan chan bool
	quit         chan bool

	// DB interface
	db        ethutil.Database
	blacklist p2p.Blacklist

	//*** SERVICES ***
	// State manager for processing new blocks and managing the over all states
	blockProcessor *core.BlockProcessor
	txPool         *core.TxPool
	chainManager   *core.ChainManager
	blockPool      *BlockPool
	whisper        *whisper.Whisper

	net      *p2p.Server
	eventMux *event.TypeMux
	txSub    event.Subscription
	blockSub event.Subscription

	RpcServer  rpc.RpcServer
	WsServer   rpc.RpcServer
	keyManager *crypto.KeyManager

	logger ethlogger.LogSystem

	Mining bool
}

func New(config *Config) (*Ethereum, error) {
	// Boostrap database
	logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel)
	db, err := ethdb.NewLDBDatabase("blockchain")
	if err != nil {
		return nil, err
	}

	// Perform database sanity checks
	d, _ := db.Get([]byte("ProtocolVersion"))
	protov := ethutil.NewValue(d).Uint()
	if protov != ProtocolVersion && protov != 0 {
		return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, ethutil.Config.ExecPath+"/database")
	}

	// Create new keymanager
	var keyManager *crypto.KeyManager
	switch config.KeyStore {
	case "db":
		keyManager = crypto.NewDBKeyManager(db)
	case "file":
		keyManager = crypto.NewFileKeyManager(config.DataDir)
	default:
		return nil, fmt.Errorf("unknown keystore type: %s", config.KeyStore)
	}
	// Initialise the keyring
	keyManager.Init(config.KeyRing, 0, false)

	saveProtocolVersion(db)
	//ethutil.Config.Db = db

	eth := &Ethereum{
		shutdownChan: make(chan bool),
		quit:         make(chan bool),
		db:           db,
		keyManager:   keyManager,
		blacklist:    p2p.NewBlacklist(),
		eventMux:     &event.TypeMux{},
		logger:       logger,
	}

	eth.chainManager = core.NewChainManager(db, eth.EventMux())
	eth.txPool = core.NewTxPool(eth.EventMux())
	eth.blockProcessor = core.NewBlockProcessor(db, eth.txPool, eth.chainManager, eth.EventMux())
	eth.chainManager.SetProcessor(eth.blockProcessor)
	eth.whisper = whisper.New()

	hasBlock := eth.chainManager.HasBlock
	insertChain := eth.chainManager.InsertChain
	eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify)

	ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool)
	protocols := []p2p.Protocol{ethProto, eth.whisper.Protocol()}
	nat, err := p2p.ParseNAT(config.NATType, config.PMPGateway)
	if err != nil {
		return nil, err
	}
	netprv := config.NodeKey
	if netprv == nil {
		if netprv, err = crypto.GenerateKey(); err != nil {
			return nil, fmt.Errorf("could not generate server key: %v", err)
		}
	}
	eth.net = &p2p.Server{
		PrivateKey:     netprv,
		Name:           config.Name,
		MaxPeers:       config.MaxPeers,
		Protocols:      protocols,
		Blacklist:      eth.blacklist,
		NAT:            nat,
		NoDial:         !config.Dial,
		BootstrapNodes: config.parseBootNodes(),
	}
	if len(config.Port) > 0 {
		eth.net.ListenAddr = ":" + config.Port
	}

	return eth, nil
}

func (s *Ethereum) KeyManager() *crypto.KeyManager {
	return s.keyManager
}

func (s *Ethereum) Logger() ethlogger.LogSystem {
	return s.logger
}

func (s *Ethereum) Name() string {
	return s.net.Name
}

func (s *Ethereum) ChainManager() *core.ChainManager {
	return s.chainManager
}

func (s *Ethereum) BlockProcessor() *core.BlockProcessor {
	return s.blockProcessor
}

func (s *Ethereum) TxPool() *core.TxPool {
	return s.txPool
}

func (s *Ethereum) BlockPool() *BlockPool {
	return s.blockPool
}

func (s *Ethereum) Whisper() *whisper.Whisper {
	return s.whisper
}

func (s *Ethereum) EventMux() *event.TypeMux {
	return s.eventMux
}
func (self *Ethereum) Db() ethutil.Database {
	return self.db
}

func (s *Ethereum) IsMining() bool {
	return s.Mining
}

func (s *Ethereum) IsListening() bool {
	// XXX TODO
	return false
}

func (s *Ethereum) PeerCount() int {
	return s.net.PeerCount()
}

func (s *Ethereum) Peers() []*p2p.Peer {
	return s.net.Peers()
}

func (s *Ethereum) MaxPeers() int {
	return s.net.MaxPeers
}

func (s *Ethereum) Coinbase() []byte {
	return nil // TODO
}

// Start the ethereum
func (s *Ethereum) Start() error {
	err := s.net.Start()
	if err != nil {
		return err
	}

	// Start services
	s.txPool.Start()
	s.blockPool.Start()

	if s.whisper != nil {
		s.whisper.Start()
	}

	// broadcast transactions
	s.txSub = s.eventMux.Subscribe(core.TxPreEvent{})
	go s.txBroadcastLoop()

	// broadcast mined blocks
	s.blockSub = s.eventMux.Subscribe(core.NewMinedBlockEvent{})
	go s.blockBroadcastLoop()

	logger.Infoln("Server started")
	return nil
}

func (self *Ethereum) SuggestPeer(nodeURL string) error {
	n, err := discover.ParseNode(nodeURL)
	if err != nil {
		return fmt.Errorf("invalid node URL: %v", err)
	}
	self.net.SuggestPeer(n)
	return nil
}

func (s *Ethereum) Stop() {
	// Close the database
	defer s.db.Close()

	close(s.quit)

	s.txSub.Unsubscribe()    // quits txBroadcastLoop
	s.blockSub.Unsubscribe() // quits blockBroadcastLoop

	if s.RpcServer != nil {
		s.RpcServer.Stop()
	}
	if s.WsServer != nil {
		s.WsServer.Stop()
	}
	s.txPool.Stop()
	s.eventMux.Stop()
	s.blockPool.Stop()
	if s.whisper != nil {
		s.whisper.Stop()
	}

	logger.Infoln("Server stopped")
	close(s.shutdownChan)
}

// This function will wait for a shutdown and resumes main thread execution
func (s *Ethereum) WaitForShutdown() {
	<-s.shutdownChan
}

// now tx broadcasting is taken out of txPool
// handled here via subscription, efficiency?
func (self *Ethereum) txBroadcastLoop() {
	// automatically stops if unsubscribe
	for obj := range self.txSub.Chan() {
		event := obj.(core.TxPreEvent)
		self.net.Broadcast("eth", TxMsg, event.Tx.RlpData())
	}
}

func (self *Ethereum) blockBroadcastLoop() {
	// automatically stops if unsubscribe
	for obj := range self.blockSub.Chan() {
		switch ev := obj.(type) {
		case core.NewMinedBlockEvent:
			self.net.Broadcast("eth", NewBlockMsg, ev.Block.RlpData(), ev.Block.Td)
		}
	}
}

func saveProtocolVersion(db ethutil.Database) {
	d, _ := db.Get([]byte("ProtocolVersion"))
	protocolVersion := ethutil.NewValue(d).Uint()

	if protocolVersion == 0 {
		db.Put([]byte("ProtocolVersion"), ethutil.NewValue(ProtocolVersion).Bytes())
	}
}
<|endoftext|>


<commit_before>package supervisor

import (
	//"github.com/pborman/uuid"

	"github.com/starkandwayne/shield/db"
	//"github.com/starkandwayne/shield/timespec"
)

type Job struct {
	Job *db.Job
}

func (s *Supervisor) GetAllJobs() ([]*Job, error) {
	jobs, err := s.Database.GetAllJobs(&db.JobFilter{})
	if err != nil {
		return nil, err
	}

	l := make([]*Job, len(jobs))
	for i, j := range jobs {
		l[i] = &Job{Job:j}
	}
	return l, nil
}

func (j *Job) Task() *Task {
	t := NewPendingTask(db.BACKUP)
	t.StorePlugin = j.Job.StorePlugin
	t.StoreEndpoint = j.Job.StoreEndpoint
	t.TargetPlugin = j.Job.TargetPlugin
	t.TargetEndpoint = j.Job.TargetEndpoint
	t.Agent = j.Job.Agent
	return t
}

func (j *Job) Reschedule() error {
	return j.Job.Reschedule()
}

func (j *Job) Runnable() bool {
	return j.Job.Runnable()
}
<commit_msg>go fmt ftw<commit_after>package supervisor

import (
	//"github.com/pborman/uuid"

	"github.com/starkandwayne/shield/db"
	//"github.com/starkandwayne/shield/timespec"
)

type Job struct {
	Job *db.Job
}

func (s *Supervisor) GetAllJobs() ([]*Job, error) {
	jobs, err := s.Database.GetAllJobs(&db.JobFilter{})
	if err != nil {
		return nil, err
	}

	l := make([]*Job, len(jobs))
	for i, j := range jobs {
		l[i] = &Job{Job: j}
	}
	return l, nil
}

func (j *Job) Task() *Task {
	t := NewPendingTask(db.BACKUP)
	t.StorePlugin = j.Job.StorePlugin
	t.StoreEndpoint = j.Job.StoreEndpoint
	t.TargetPlugin = j.Job.TargetPlugin
	t.TargetEndpoint = j.Job.TargetEndpoint
	t.Agent = j.Job.Agent
	return t
}

func (j *Job) Reschedule() error {
	return j.Job.Reschedule()
}

func (j *Job) Runnable() bool {
	return j.Job.Runnable()
}
<|endoftext|>


<commit_before>package importpaths

import (
	"disposa.blue/margo"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"sync"
	"time"
)

var (
	qidCache = struct {
		sync.Mutex
		m map[string]*qidNode
	}{m: map[string]*qidNode{}}
)

type qidNode struct {
	sync.Mutex
	Pkg     *build.Package
	EntName string
	DirMod  time.Time
	EntMod  time.Time
}

func PathFilter(path string) bool {
	return margo.FilterPath(path) &&
		margo.FilterPathExt(path) &&
		!strings.Contains(filepath.Base(path), "node_modules")
}

func MakeImportPathsFunc(pathFilter margo.PathFilterFunc) margo.ImportPathsFunc {
	return func(srcDir string, bctx *build.Context) map[string]string {
		return ImportPaths(srcDir, bctx, pathFilter)
	}
}

func ImportPaths(srcDir string, bctx *build.Context, pathFilter margo.PathFilterFunc) map[string]string {
	rootDirs := bctx.SrcDirs()

	importDir := func(dir string) *build.Package {
		p := quickImportDir(bctx, rootDirs, dir)
		if p != nil && p.Name != "" && p.ImportPath != "" {
			return p
		}
		return nil
	}

	srcImportPath := quickImportPath(srcDir)

	var pkgs []*build.Package
	for _, dir := range rootDirs {
		pkgs = append(pkgs, importablePackages(dir, importDir, pathFilter)...)
	}

	res := make(map[string]string, len(pkgs))
	res["unsafe"] = "" // this package doesn't exist on-disk

	const vdir = "/vendor/"
	var vendored []*build.Package
	for _, p := range pkgs {
		switch {
		case p.Name == "main":
		// it's rarely useful to import `package main`
		case p.ImportPath == "builtin":
		// this package exists for documentation only
		case strings.HasPrefix(p.ImportPath, vdir[1:]) || strings.Contains(p.ImportPath, vdir):
			// fill these in after everything else so we can tag them
			vendored = append(vendored, p)
		default:
			res[p.ImportPath] = importsName(p)
		}
	}
	if srcImportPath != "" {
		sfx := srcImportPath + "/"
		for _, p := range vendored {
			name := importsName(p) + " [vendored]"
			ipath := p.ImportPath
			vpos := strings.LastIndex(ipath, vdir)
			switch {
			case vpos > 0:
				pfx := ipath[:vpos+1]
				if strings.HasPrefix(sfx, pfx) {
					ipath := ipath[vpos+len(vdir):]
					res[ipath] = name
				}
			case strings.HasPrefix(ipath, vdir[1:]):
				ipath := ipath[len(vdir)-1:]
				res[ipath] = name
			}
		}
	}
	return res
}

func quickImportPath(srcDir string) string {
	dir := filepath.ToSlash(filepath.Clean(srcDir))
	if i := strings.LastIndex(dir, "/src/"); i >= 0 {
		return dir[i+5:]
	}
	return ""
}

var buildIgnoreRx = regexp.MustCompile(`^\+build\s+ignore`)

func quickImportDir(bctx *build.Context, rootDirs []string, srcDir string) *build.Package {
	srcDir = filepath.Clean(srcDir)
	qidCache.Lock()
	qn := qidCache.m[srcDir]
	if qn == nil {
		qn = &qidNode{
			Pkg: &build.Package{
				Dir:        srcDir,
				ImportPath: quickImportPath(srcDir),
			},
		}
		qidCache.m[srcDir] = qn
	}
	qidCache.Unlock()

	qn.Lock()
	defer qn.Unlock()

	if qn.Pkg.ImportPath == "" {
		return nil
	}

	dirMod := fileModTime(srcDir)
	if dirMod.IsZero() {
		return nil
	}

	if qn.DirMod.Equal(dirMod) {
		if qn.Pkg.Name == "" {
			// not a Go pkg
			return nil
		}
		if qn.EntName != "" && qn.EntMod.Equal(fileModTime(filepath.Join(srcDir, qn.EntName))) {
			return qn.Pkg
		}
	}

	// reset cache
	qn.DirMod = dirMod
	qn.EntName = ""
	qn.Pkg.Name = ""

	f, err := os.Open(srcDir)
	if err != nil {
		return nil
	}
	defer f.Close()

	fset := token.NewFileSet()
search:
	for {
		names, _ := f.Readdirnames(100)
		if len(names) == 0 {
			break
		}
		for _, nm := range names {
			ignore := !strings.HasSuffix(nm, ".go") ||
				strings.HasSuffix(nm, "_test.go") ||
				strings.HasPrefix(nm, ".") ||
				strings.HasPrefix(nm, "_")

			if ignore {
				continue
			}

			path := filepath.Join(srcDir, nm)
			entMod := fileModTime(path)
			if entMod.IsZero() {
				continue
			}

			mode := parser.PackageClauseOnly | parser.ParseComments
			af, _ := parser.ParseFile(fset, path, nil, mode)
			if af == nil {
				continue
			}

			for _, cg := range af.Comments {
				for _, c := range cg.List {
					if buildIgnoreRx.MatchString(c.Text) {
						continue search
					}
				}
			}

			qn.Pkg.Name = astFileName(af)
			if qn.Pkg.Name != "" {
				qn.EntName = nm
				qn.EntMod = entMod
				return qn.Pkg
			}
		}
	}
	return nil
}

func fileModTime(fn string) time.Time {
	if fi := fileInfo(fn); fi != nil {
		return fi.ModTime()
	}
	return time.Time{}
}

func fileInfo(fn string) os.FileInfo {
	fi, _ := os.Lstat(fn)
	return fi
}

func astFileName(af *ast.File) string {
	if af == nil || af.Name == nil {
		return ""
	}
	name := af.Name.String()
	if name == "" || name == "documentation" {
		return ""
	}
	for _, g := range af.Comments {
		for _, c := range g.List {
			for _, ln := range strings.Split(c.Text, "\n") {
				ln = strings.TrimSpace(ln)
				if strings.HasPrefix(ln, "+build ") && strings.Index(ln+" ", " ignore ") > 0 {
					return ""
				}
			}
		}
	}
	return name
}

func importsName(p *build.Package) string {
	return p.Name
}

func importablePackages(root string, importDir func(path string) *build.Package, pathFilter margo.PathFilterFunc) []*build.Package {
	dirs := allDirNames(root, pathFilter)
	var ents []*build.Package
	for _, dir := range dirs {
		if p := importDir(dir); p != nil {
			ents = append(ents, p)
		}
	}
	return ents
}

func allDirNames(dir string, pathFilter margo.PathFilterFunc) []string {
	dirs := dirNames(dir, pathFilter)
	for _, dir := range dirs {
		dirs = append(dirs, allDirNames(dir, pathFilter)...)
	}
	return dirs
}

func dirNames(dir string, pathFilter func(basename string) bool) []string {
	f, err := os.Open(dir)
	if err != nil {
		return nil
	}
	defer f.Close()

	var dirs []string
	for {
		names, _ := f.Readdirnames(100)
		if len(names) == 0 {
			break
		}
		for _, nm := range names {
			path := filepath.Join(dir, nm)
			if !pathFilter(path) {
				continue
			}
			fi := fileInfo(path)
			if fi != nil && fi.IsDir() {
				dirs = append(dirs, path)
			}
		}
	}

	return dirs
}
<commit_msg>fix failure to list some packges in the imports palette<commit_after>package importpaths

import (
	"disposa.blue/margo"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"
)

var (
	qidCache = struct {
		sync.Mutex
		m map[string]*qidNode
	}{m: map[string]*qidNode{}}
)

type qidNode struct {
	sync.Mutex
	Pkg     *build.Package
	EntName string
	DirMod  time.Time
	EntMod  time.Time
}

func PathFilter(path string) bool {
	return margo.FilterPath(path) &&
		margo.FilterPathExt(path) &&
		!strings.Contains(filepath.Base(path), "node_modules")
}

func MakeImportPathsFunc(pathFilter margo.PathFilterFunc) margo.ImportPathsFunc {
	return func(srcDir string, bctx *build.Context) map[string]string {
		return ImportPaths(srcDir, bctx, pathFilter)
	}
}

func ImportPaths(srcDir string, bctx *build.Context, pathFilter margo.PathFilterFunc) map[string]string {
	rootDirs := bctx.SrcDirs()
	importDir := func(dir string) *build.Package {
		p := quickImportDir(bctx, rootDirs, dir)
		if p != nil && p.Name != "" && p.ImportPath != "" {
			return p
		}
		return nil
	}

	srcImportPath := quickImportPath(srcDir)

	var pkgs []*build.Package
	for _, dir := range rootDirs {
		pkgs = append(pkgs, importablePackages(dir, importDir, pathFilter)...)
	}

	res := make(map[string]string, len(pkgs))
	res["unsafe"] = "" // this package doesn't exist on-disk

	const vdir = "/vendor/"
	var vendored []*build.Package
	for _, p := range pkgs {
		switch {
		case p.Name == "main":
		// it's rarely useful to import `package main`
		case p.ImportPath == "builtin":
		// this package exists for documentation only
		case strings.HasPrefix(p.ImportPath, vdir[1:]) || strings.Contains(p.ImportPath, vdir):
			// fill these in after everything else so we can tag them
			vendored = append(vendored, p)
		default:
			res[p.ImportPath] = importsName(p)
		}
	}
	if srcImportPath != "" {
		sfx := srcImportPath + "/"
		for _, p := range vendored {
			name := importsName(p) + " [vendored]"
			ipath := p.ImportPath
			vpos := strings.LastIndex(ipath, vdir)
			switch {
			case vpos > 0:
				pfx := ipath[:vpos+1]
				if strings.HasPrefix(sfx, pfx) {
					ipath := ipath[vpos+len(vdir):]
					res[ipath] = name
				}
			case strings.HasPrefix(ipath, vdir[1:]):
				ipath := ipath[len(vdir)-1:]
				res[ipath] = name
			}
		}
	}
	return res
}

func quickImportPath(srcDir string) string {
	dir := filepath.ToSlash(filepath.Clean(srcDir))
	if i := strings.LastIndex(dir, "/src/"); i >= 0 {
		return dir[i+5:]
	}
	return ""
}

func quickImportDir(bctx *build.Context, rootDirs []string, srcDir string) *build.Package {
	srcDir = filepath.Clean(srcDir)
	qidCache.Lock()
	qn := qidCache.m[srcDir]
	if qn == nil {
		qn = &qidNode{
			Pkg: &build.Package{
				Dir:        srcDir,
				ImportPath: quickImportPath(srcDir),
			},
		}
		qidCache.m[srcDir] = qn
	}
	qidCache.Unlock()

	qn.Lock()
	defer qn.Unlock()

	if qn.Pkg.ImportPath == "" {
		return nil
	}

	dirMod := fileModTime(srcDir)
	if dirMod.IsZero() {
		return nil
	}

	if qn.DirMod.Equal(dirMod) {
		if qn.Pkg.Name == "" {
			// not a Go pkg
			return nil
		}
		if qn.EntName != "" && qn.EntMod.Equal(fileModTime(filepath.Join(srcDir, qn.EntName))) {
			return qn.Pkg
		}
	}

	// reset cache
	qn.DirMod = dirMod
	qn.EntName = ""
	qn.Pkg.Name = ""

	f, err := os.Open(srcDir)
	if err != nil {
		return nil
	}
	defer f.Close()

	fset := token.NewFileSet()
	for {
		names, _ := f.Readdirnames(100)
		if len(names) == 0 {
			break
		}
		for _, nm := range names {
			ignore := !strings.HasSuffix(nm, ".go") ||
				strings.HasSuffix(nm, "_test.go") ||
				strings.HasPrefix(nm, ".") ||
				strings.HasPrefix(nm, "_")

			if ignore {
				continue
			}

			path := filepath.Join(srcDir, nm)
			entMod := fileModTime(path)
			if entMod.IsZero() {
				continue
			}

			mode := parser.PackageClauseOnly | parser.ParseComments
			af, _ := parser.ParseFile(fset, path, nil, mode)
			if af == nil {
				continue
			}

			if ok, _ := bctx.MatchFile(srcDir, nm); !ok {
				continue
			}

			qn.Pkg.Name = astFileName(af)
			if qn.Pkg.Name != "" {
				qn.EntName = nm
				qn.EntMod = entMod
				return qn.Pkg
			}
		}
	}
	return nil
}

func fileModTime(fn string) time.Time {
	if fi := fileInfo(fn); fi != nil {
		return fi.ModTime()
	}
	return time.Time{}
}

func fileInfo(fn string) os.FileInfo {
	fi, _ := os.Lstat(fn)
	return fi
}

func astFileName(af *ast.File) string {
	if af == nil || af.Name == nil {
		return ""
	}
	name := af.Name.String()
	if name == "" || name == "documentation" {
		return ""
	}
	for _, g := range af.Comments {
		for _, c := range g.List {
			for _, ln := range strings.Split(c.Text, "\n") {
				ln = strings.TrimSpace(ln)
				if strings.HasPrefix(ln, "+build ") && strings.Index(ln+" ", " ignore ") > 0 {
					return ""
				}
			}
		}
	}
	return name
}

func importsName(p *build.Package) string {
	return p.Name
}

func importablePackages(root string, importDir func(path string) *build.Package, pathFilter margo.PathFilterFunc) []*build.Package {
	dirs := allDirNames(root, pathFilter)
	var ents []*build.Package
	for _, dir := range dirs {
		if p := importDir(dir); p != nil {
			ents = append(ents, p)
		}
	}
	return ents
}

func allDirNames(dir string, pathFilter margo.PathFilterFunc) []string {
	dirs := dirNames(dir, pathFilter)
	for _, dir := range dirs {
		dirs = append(dirs, allDirNames(dir, pathFilter)...)
	}
	return dirs
}

func dirNames(dir string, pathFilter func(basename string) bool) []string {
	f, err := os.Open(dir)
	if err != nil {
		return nil
	}
	defer f.Close()

	var dirs []string
	for {
		names, _ := f.Readdirnames(100)
		if len(names) == 0 {
			break
		}
		for _, nm := range names {
			path := filepath.Join(dir, nm)
			if !pathFilter(path) {
				continue
			}
			fi := fileInfo(path)
			if fi != nil && fi.IsDir() {
				dirs = append(dirs, path)
			}
		}
	}

	return dirs
}
<|endoftext|>


<commit_before>/* Copyright (c) 2014, Daniel Martí <mvdan@mvdan.cc> */
/* See LICENSE for licensing information */

package main

import (
	"compress/gzip"
	"fmt"
	"io"
	"log"
	"math/rand"
	"net/http"
	"os"
	"path"
	"regexp"
	"strconv"
	"strings"
	"time"
)

const (
	chars   = "abcdefghijklmnopqrstuvwxyz0123456789"
	idSize  = 8
	siteUrl = "http://localhost:9090"
	listen  = "localhost:9090"
	dataDir = "data"
	maxSize = 1 << 20
	minLife = 1 * time.Minute
	defLife = 1 * time.Hour
	maxLife = 72 * time.Hour

	// GET error messages
	invalidId     = "Invalid paste id."
	pasteNotFound = "Paste doesn't exist."
	unknownError  = "Something went wrong. Woop woop woop woop!"
	// POST error messages
	missingForm = "Form with paste could not be found."
)

var validId *regexp.Regexp = regexp.MustCompile("^[a-z0-9]{" + strconv.FormatInt(idSize, 10) + "}$")

func pathId(id string) string {
	return path.Join(id[0:2], id[2:4], id[4:8])
}

func randomId() string {
	s := make([]byte, idSize)
	var offset uint = 0
	for {
		r := rand.Int63()
		for i := 0; i < 8; i++ {
			randbyte := int(r&0xff) % len(chars)
			s[offset] = chars[randbyte]
			offset++
			if offset == idSize {
				return string(s)
			}
			r >>= 8
		}
	}
	return strings.Repeat(chars[0:1], idSize)
}

func endLife(pastePath string) {
	err := os.Remove(pastePath)
	if err != nil {
		log.Printf("Could not end the life of %s: %s", pastePath, err)
		timer := time.NewTimer(minLife)
		go func() {
			<-timer.C
			endLife(pastePath)
		}()
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		id := r.URL.Path[1:]
		if len(id) == 0 {
			fmt.Fprintf(w, "<form action=\"%s\" method=\"post\" enctype=\"multipart/form-data\"><textarea cols=80 rows=48 name=\"paste\"></textarea>
<button type=\"submit\">paste</button></form>", siteUrl)
			return
		}
		if !validId.MatchString(id) {
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, "%s\n", invalidId)
			return
		}
		pastePath := pathId(id)
		pasteFile, err := os.Open(pastePath)
		if err != nil {
			w.WriteHeader(http.StatusNotFound)
			fmt.Fprintf(w, "%s\n", pasteNotFound)
			return
		}
		compReader, err := gzip.NewReader(pasteFile)
		if err != nil {
			log.Printf("Could not open a compression reader for %s: %s", pastePath, err)
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "%s\n", unknownError)
			return
		}
		io.Copy(w, compReader)
		compReader.Close()
		pasteFile.Close()

	case "POST":
		r.Body = http.MaxBytesReader(w, r.Body, maxSize)
		var id, pastePath string
		for {
			id = randomId()
			pastePath = pathId(id)
			if _, err := os.Stat(pastePath); os.IsNotExist(err) {
				break
			}
		}
		err := r.ParseMultipartForm(maxSize << 1)
		if err != nil {
			log.Printf("Could not parse POST multipart form: %s", err)
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, "%s\n", unknownError)
			return
		}
		var life time.Duration
		vs, found := r.Form["life"]
		if !found {
			life = defLife
		} else {
			life, err = time.ParseDuration(vs[0])
		}
		if life < minLife {
			life = minLife
		} else if life > maxLife {
			life = maxLife
		}
		vs, found = r.Form["paste"]
		if !found {
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, "%s\n", missingForm)
			return
		}
		dir, _ := path.Split(pastePath)
		err = os.MkdirAll(dir, 0700)
		if err != nil {
			log.Printf("Could not create directories leading to %s: %s", pastePath, err)
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "%s\n", unknownError)
			return
		}
		timer := time.NewTimer(life)
		go func() {
			<-timer.C
			endLife(pastePath)
		}()
		pasteFile, err := os.OpenFile(pastePath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
		if err != nil {
			log.Printf("Could not create new paste pasteFile %s: %s", pastePath, err)
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "%s\n", unknownError)
			return
		}
		compWriter := gzip.NewWriter(pasteFile)
		_, err = io.WriteString(compWriter, vs[0])
		compWriter.Close()
		pasteFile.Close()
		if err != nil {
			log.Printf("Could not write compressed data into %s: %s", pastePath, err)
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "%s\n", unknownError)
			return
		}
		fmt.Fprintf(w, "%s/%s\n", siteUrl, id)
	}
}

func main() {
	os.Mkdir(dataDir, 0700)
	err := os.Chdir(dataDir)
	if err != nil {
		log.Printf("Could not enter data directory %s: %s", dataDir, err)
		return
	}
	http.HandleFunc("/", handler)
	http.ListenAndServe(listen, nil)
}
<commit_msg>Use an html template, more logging, fixes<commit_after>/* Copyright (c) 2014, Daniel Martí <mvdan@mvdan.cc> */
/* See LICENSE for licensing information */

package main

import (
	"compress/gzip"
	"fmt"
	"html/template"
	"io"
	"log"
	"math/rand"
	"net/http"
	"os"
	"path"
	"regexp"
	"strconv"
	"strings"
	"time"
)

const (
	chars     = "abcdefghijklmnopqrstuvwxyz0123456789"
	idSize    = 8
	siteUrl   = "http://localhost:9090"
	listen    = "localhost:9090"
	indexTmpl = "index.html"
	dataDir   = "data"
	maxSize   = 1 << 20
	minLife   = 1 * time.Minute
	defLife   = 1 * time.Hour
	maxLife   = 24 * time.Hour

	// GET error messages
	invalidId     = "Invalid paste id."
	pasteNotFound = "Paste doesn't exist."
	unknownError  = "Something went wrong. Woop woop woop woop!"
	// POST error messages
	missingForm = "Paste could not be found inside the posted form."
	invalidLife = "The lifetime specified is invalid (units: s,m,h)."
	smallLife   = "The lifetime specified is too small (min: %s)."
	largeLife   = "The lifetime specified is too large (max: %s)."
)

var validId *regexp.Regexp = regexp.MustCompile("^[a-z0-9]{" + strconv.FormatInt(idSize, 10) + "}$")

var indexTemplate *template.Template

func pathId(id string) string {
	return path.Join(id[0:2], id[2:4], id[4:8])
}

func randomId() string {
	s := make([]byte, idSize)
	var offset uint = 0
	for {
		r := rand.Int63()
		for i := 0; i < 8; i++ {
			randbyte := int(r&0xff) % len(chars)
			s[offset] = chars[randbyte]
			offset++
			if offset == idSize {
				return string(s)
			}
			r >>= 8
		}
	}
	return strings.Repeat(chars[0:1], idSize)
}

func endLife(id string) {
	pastePath := pathId(id)
	err := os.Remove(pastePath)
	if err == nil {
		log.Printf("Removed paste: %s", id)
	} else {
		log.Printf("Could not end the life of %s: %s", id, err)
		timer := time.NewTimer(minLife)
		go func() {
			<-timer.C
			endLife(id)
		}()
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	var err error
	switch r.Method {
	case "GET":
		id := r.URL.Path[1:]
		if len(id) == 0 {
			indexTemplate.Execute(w, siteUrl)
			return
		}
		if !validId.MatchString(id) {
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, "%s\n", invalidId)
			return
		}
		pastePath := pathId(id)
		pasteFile, err := os.Open(pastePath)
		if err != nil {
			w.WriteHeader(http.StatusNotFound)
			fmt.Fprintf(w, "%s\n", pasteNotFound)
			return
		}
		compReader, err := gzip.NewReader(pasteFile)
		if err != nil {
			log.Printf("Could not open a compression reader for %s: %s", pastePath, err)
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "%s\n", unknownError)
			return
		}
		io.Copy(w, compReader)
		compReader.Close()
		pasteFile.Close()

	case "POST":
		r.Body = http.MaxBytesReader(w, r.Body, maxSize)
		var id, pastePath string
		for {
			id = randomId()
			pastePath = pathId(id)
			if _, err := os.Stat(pastePath); os.IsNotExist(err) {
				break
			}
		}
		if err = r.ParseMultipartForm(maxSize << 1); err != nil {
			log.Printf("Could not parse POST multipart form: %s", err)
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, "%s\n", unknownError)
			return
		}
		var life time.Duration
		var content string
		if vs, found := r.Form["life"]; !found {
			life = defLife
		} else {
			life, err = time.ParseDuration(vs[0])
			if err != nil {
				w.WriteHeader(http.StatusBadRequest)
				fmt.Fprintf(w, "%s\n", invalidLife)
				return
			}
		}
		if life < minLife || life > maxLife {
			w.WriteHeader(http.StatusBadRequest)
			if life < minLife {
				fmt.Fprintf(w, "%s\n", smallLife, minLife)
			} else {
				fmt.Fprintf(w, "%s\n", largeLife, maxLife)
			}
			return
		}
		if vs, found := r.Form["paste"]; found {
			content = vs[0]
		} else {
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, "%s\n", missingForm)
			return
		}
		dir, _ := path.Split(pastePath)
		if err = os.MkdirAll(dir, 0700); err != nil {
			log.Printf("Could not create directories leading to %s: %s", pastePath, err)
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "%s\n", unknownError)
			return
		}
		timer := time.NewTimer(life)
		go func() {
			<-timer.C
			endLife(id)
		}()
		pasteFile, err := os.OpenFile(pastePath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
		if err != nil {
			log.Printf("Could not create new paste pasteFile %s: %s", pastePath, err)
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "%s\n", unknownError)
			return
		}
		compWriter := gzip.NewWriter(pasteFile)
		_, err = io.WriteString(compWriter, content)
		compWriter.Close()
		pasteFile.Close()
		if err != nil {
			log.Printf("Could not write compressed data into %s: %s", pastePath, err)
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "%s\n", unknownError)
			return
		}
		log.Printf("Created a new paste: %s (lifetime: %s)", id, life)
		fmt.Fprintf(w, "%s/%s\n", siteUrl, id)
	}
}

func main() {
	var err error
	if indexTemplate, err = template.ParseFiles(indexTmpl); err != nil {
		log.Printf("Could not load template %s: %s", indexTmpl, err)
		return
	}
	if err = os.RemoveAll(dataDir); err != nil {
		log.Printf("Could not clean data directory %s: %s", dataDir, err)
		return
	}
	if err = os.Mkdir(dataDir, 0700); err != nil {
		log.Printf("Could not create data directory %s: %s", dataDir, err)
		return
	}
	if err = os.Chdir(dataDir); err != nil {
		log.Printf("Could not enter data directory %s: %s", dataDir, err)
		return
	}
	http.HandleFunc("/", handler)
	http.ListenAndServe(listen, nil)
}
<|endoftext|>


<commit_before>package jsonpatch

import (
	"bytes"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
)

const (
	eRaw = iota
	eDoc
	eAry
)

type lazyNode struct {
	raw   *json.RawMessage
	doc   partialDoc
	ary   partialArray
	which int
}

type operation map[string]*json.RawMessage

// Patch is an ordered collection of operations.
type Patch []operation

type partialDoc map[string]*lazyNode
type partialArray []*lazyNode

type container interface {
	get(key string) (*lazyNode, error)
	set(key string, val *lazyNode) error
	remove(key string) error
}

func newLazyNode(raw *json.RawMessage) *lazyNode {
	return &lazyNode{raw: raw, doc: nil, ary: nil, which: eRaw}
}

func (n *lazyNode) MarshalJSON() ([]byte, error) {
	switch n.which {
	case eRaw:
		return *n.raw, nil
	case eDoc:
		return json.Marshal(n.doc)
	case eAry:
		return json.Marshal(n.ary)
	default:
		return nil, fmt.Errorf("Unknown type")
	}
}

func (n *lazyNode) UnmarshalJSON(data []byte) error {
	dest := make(json.RawMessage, len(data))
	copy(dest, data)
	n.raw = &dest
	n.which = eRaw
	return nil
}

func (n *lazyNode) intoDoc() (*partialDoc, error) {
	if n.which == eDoc {
		return &n.doc, nil
	}

	err := json.Unmarshal(*n.raw, &n.doc)

	if err != nil {
		return nil, err
	}

	n.which = eDoc
	return &n.doc, nil
}

func (n *lazyNode) intoAry() (*partialArray, error) {
	if n.which == eAry {
		return &n.ary, nil
	}

	err := json.Unmarshal(*n.raw, &n.ary)

	if err != nil {
		return nil, err
	}

	n.which = eAry
	return &n.ary, nil
}

func (n *lazyNode) compact() []byte {
	buf := &bytes.Buffer{}

	err := json.Compact(buf, *n.raw)

	if err != nil {
		return *n.raw
	}

	return buf.Bytes()
}

func (n *lazyNode) tryDoc() bool {
	err := json.Unmarshal(*n.raw, &n.doc)

	if err != nil {
		return false
	}

	n.which = eDoc
	return true
}

func (n *lazyNode) tryAry() bool {
	err := json.Unmarshal(*n.raw, &n.ary)

	if err != nil {
		return false
	}

	n.which = eAry
	return true
}

func (n *lazyNode) equal(o *lazyNode) bool {
	if n.which == eRaw {
		if !n.tryDoc() && !n.tryAry() {
			if o.which != eRaw {
				return false
			}

			return bytes.Equal(n.compact(), o.compact())
		}
	}

	if n.which == eDoc {
		if o.which == eRaw {
			if !o.tryDoc() {
				return false
			}
		}

		if o.which != eDoc {
			return false
		}

		for k, v := range n.doc {
			ov, ok := o.doc[k]

			if !ok {
				return false
			}

			if v == nil && ov == nil {
				continue
			}

			if !v.equal(ov) {
				return false
			}
		}

		return true
	}

	if o.which != eAry && !o.tryAry() {
		return false
	}

	if len(n.ary) != len(o.ary) {
		return false
	}

	for idx, val := range n.ary {
		if !val.equal(o.ary[idx]) {
			return false
		}
	}

	return true
}

func (o operation) kind() string {
	if obj, ok := o["op"]; ok {
		var op string

		err := json.Unmarshal(*obj, &op)

		if err != nil {
			return "unknown"
		}

		return op
	}

	return "unknown"
}

func (o operation) path() string {
	if obj, ok := o["path"]; ok {
		var op string

		err := json.Unmarshal(*obj, &op)

		if err != nil {
			return "unknown"
		}

		return op
	}

	return "unknown"
}

func (o operation) from() string {
	if obj, ok := o["from"]; ok {
		var op string

		err := json.Unmarshal(*obj, &op)

		if err != nil {
			return "unknown"
		}

		return op
	}

	return "unknown"
}

func (o operation) value() *lazyNode {
	if obj, ok := o["value"]; ok {
		return newLazyNode(obj)
	}

	return nil
}

func isArray(buf []byte) bool {
Loop:
	for _, c := range buf {
		switch c {
		case ' ':
		case '\n':
		case '\t':
			continue
		case '[':
			return true
		default:
			break Loop
		}
	}

	return false
}

func findObject(pd *partialDoc, path string) (container, string) {
	doc := container(pd)

	split := strings.Split(path, "/")

	parts := split[1 : len(split)-1]

	key := split[len(split)-1]

	var err error

	for _, part := range parts {

		next, ok := doc.get(part)

		if next == nil || ok != nil {
			return nil, ""
		}

		if isArray(*next.raw) {
			doc, err = next.intoAry()

			if err != nil {
				return nil, ""
			}
		} else {
			doc, err = next.intoDoc()

			if err != nil {
				return nil, ""
			}
		}
	}

	return doc, key
}

func (d *partialDoc) set(key string, val *lazyNode) error {
	(*d)[key] = val
	return nil
}

func (d *partialDoc) get(key string) (*lazyNode, error) {
	return (*d)[key], nil
}

func (d *partialDoc) remove(key string) error {
	delete(*d, key)
	return nil
}

func (d *partialArray) set(key string, val *lazyNode) error {
	if key == "-" {
		*d = append(*d, val)
		return nil
	}

	idx, err := strconv.Atoi(key)

	if err != nil {
		return err
	}

	ary := make([]*lazyNode, len(*d)+1)

	cur := *d

	copy(ary[0:idx], cur[0:idx])
	ary[idx] = val
	copy(ary[idx+1:], cur[idx:])

	*d = ary
	return nil
}

func (d *partialArray) get(key string) (*lazyNode, error) {
	idx, err := strconv.Atoi(key)

	if err != nil {
		return nil, err
	}

	return (*d)[idx], nil
}

func (d *partialArray) remove(key string) error {
	idx, err := strconv.Atoi(key)

	if err != nil {
		return err
	}

	cur := *d

	ary := make([]*lazyNode, len(cur)-1)

	copy(ary[0:idx], cur[0:idx])
	copy(ary[idx:], cur[idx+1:])

	*d = ary
	return nil

}

func (p Patch) add(doc *partialDoc, op operation) error {
	path := op.path()

	con, key := findObject(doc, path)

	if con == nil {
		return fmt.Errorf("Missing container: %s", path)
	}

	con.set(key, op.value())

	return nil
}

func (p Patch) remove(doc *partialDoc, op operation) error {
	path := op.path()

	con, key := findObject(doc, path)

	return con.remove(key)
}

func (p Patch) replace(doc *partialDoc, op operation) error {
	path := op.path()

	con, key := findObject(doc, path)

	con.set(key, op.value())

	return nil
}

func (p Patch) move(doc *partialDoc, op operation) error {
	from := op.from()

	con, key := findObject(doc, from)

	val, err := con.get(key)

	if err != nil {
		return err
	}

	con.remove(key)

	path := op.path()

	con, key = findObject(doc, path)

	con.set(key, val)

	return nil
}

func (p Patch) test(doc *partialDoc, op operation) error {
	path := op.path()

	con, key := findObject(doc, path)

	val, err := con.get(key)

	if err != nil {
		return err
	}

	if val == nil {
		if op.value().raw == nil {
			return nil
		} else {
			return fmt.Errorf("Testing value %s failed", path)
		}
	}

	if val.equal(op.value()) {
		return nil
	}

	return fmt.Errorf("Testing value %s failed", path)
}

// Equal indicates if 2 JSON documents have the same structural equality.
func Equal(a, b []byte) bool {
	ra := make(json.RawMessage, len(a))
	copy(ra, a)
	la := newLazyNode(&ra)

	rb := make(json.RawMessage, len(b))
	copy(rb, b)
	lb := newLazyNode(&rb)

	return la.equal(lb)
}

// DecodePatch decodes the passed JSON document as an RFC 6902 patch.
func DecodePatch(buf []byte) (Patch, error) {
	var p Patch

	err := json.Unmarshal(buf, &p)

	if err != nil {
		return nil, err
	}

	return p, nil
}

// Apply mutates a JSON document according to the patch, and returns the new
// document.
func (p Patch) Apply(doc []byte) ([]byte, error) {
	pd := &partialDoc{}

	err := json.Unmarshal(doc, pd)

	if err != nil {
		return nil, err
	}

	err = nil

	for _, op := range p {
		switch op.kind() {
		case "add":
			err = p.add(pd, op)
		case "remove":
			err = p.remove(pd, op)
		case "replace":
			err = p.replace(pd, op)
		case "move":
			err = p.move(pd, op)
		case "test":
			err = p.test(pd, op)
		default:
			err = fmt.Errorf("Unexpected kind: %s", op.kind())
		}

		if err != nil {
			return nil, err
		}
	}

	return json.Marshal(pd)
}
<commit_msg>Add ApplyIndent for pretty print<commit_after>package jsonpatch

import (
	"bytes"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
)

const (
	eRaw = iota
	eDoc
	eAry
)

type lazyNode struct {
	raw   *json.RawMessage
	doc   partialDoc
	ary   partialArray
	which int
}

type operation map[string]*json.RawMessage

// Patch is an ordered collection of operations.
type Patch []operation

type partialDoc map[string]*lazyNode
type partialArray []*lazyNode

type container interface {
	get(key string) (*lazyNode, error)
	set(key string, val *lazyNode) error
	remove(key string) error
}

func newLazyNode(raw *json.RawMessage) *lazyNode {
	return &lazyNode{raw: raw, doc: nil, ary: nil, which: eRaw}
}

func (n *lazyNode) MarshalJSON() ([]byte, error) {
	switch n.which {
	case eRaw:
		return *n.raw, nil
	case eDoc:
		return json.Marshal(n.doc)
	case eAry:
		return json.Marshal(n.ary)
	default:
		return nil, fmt.Errorf("Unknown type")
	}
}

func (n *lazyNode) UnmarshalJSON(data []byte) error {
	dest := make(json.RawMessage, len(data))
	copy(dest, data)
	n.raw = &dest
	n.which = eRaw
	return nil
}

func (n *lazyNode) intoDoc() (*partialDoc, error) {
	if n.which == eDoc {
		return &n.doc, nil
	}

	err := json.Unmarshal(*n.raw, &n.doc)

	if err != nil {
		return nil, err
	}

	n.which = eDoc
	return &n.doc, nil
}

func (n *lazyNode) intoAry() (*partialArray, error) {
	if n.which == eAry {
		return &n.ary, nil
	}

	err := json.Unmarshal(*n.raw, &n.ary)

	if err != nil {
		return nil, err
	}

	n.which = eAry
	return &n.ary, nil
}

func (n *lazyNode) compact() []byte {
	buf := &bytes.Buffer{}

	err := json.Compact(buf, *n.raw)

	if err != nil {
		return *n.raw
	}

	return buf.Bytes()
}

func (n *lazyNode) tryDoc() bool {
	err := json.Unmarshal(*n.raw, &n.doc)

	if err != nil {
		return false
	}

	n.which = eDoc
	return true
}

func (n *lazyNode) tryAry() bool {
	err := json.Unmarshal(*n.raw, &n.ary)

	if err != nil {
		return false
	}

	n.which = eAry
	return true
}

func (n *lazyNode) equal(o *lazyNode) bool {
	if n.which == eRaw {
		if !n.tryDoc() && !n.tryAry() {
			if o.which != eRaw {
				return false
			}

			return bytes.Equal(n.compact(), o.compact())
		}
	}

	if n.which == eDoc {
		if o.which == eRaw {
			if !o.tryDoc() {
				return false
			}
		}

		if o.which != eDoc {
			return false
		}

		for k, v := range n.doc {
			ov, ok := o.doc[k]

			if !ok {
				return false
			}

			if v == nil && ov == nil {
				continue
			}

			if !v.equal(ov) {
				return false
			}
		}

		return true
	}

	if o.which != eAry && !o.tryAry() {
		return false
	}

	if len(n.ary) != len(o.ary) {
		return false
	}

	for idx, val := range n.ary {
		if !val.equal(o.ary[idx]) {
			return false
		}
	}

	return true
}

func (o operation) kind() string {
	if obj, ok := o["op"]; ok {
		var op string

		err := json.Unmarshal(*obj, &op)

		if err != nil {
			return "unknown"
		}

		return op
	}

	return "unknown"
}

func (o operation) path() string {
	if obj, ok := o["path"]; ok {
		var op string

		err := json.Unmarshal(*obj, &op)

		if err != nil {
			return "unknown"
		}

		return op
	}

	return "unknown"
}

func (o operation) from() string {
	if obj, ok := o["from"]; ok {
		var op string

		err := json.Unmarshal(*obj, &op)

		if err != nil {
			return "unknown"
		}

		return op
	}

	return "unknown"
}

func (o operation) value() *lazyNode {
	if obj, ok := o["value"]; ok {
		return newLazyNode(obj)
	}

	return nil
}

func isArray(buf []byte) bool {
Loop:
	for _, c := range buf {
		switch c {
		case ' ':
		case '\n':
		case '\t':
			continue
		case '[':
			return true
		default:
			break Loop
		}
	}

	return false
}

func findObject(pd *partialDoc, path string) (container, string) {
	doc := container(pd)

	split := strings.Split(path, "/")

	parts := split[1 : len(split)-1]

	key := split[len(split)-1]

	var err error

	for _, part := range parts {

		next, ok := doc.get(part)

		if next == nil || ok != nil {
			return nil, ""
		}

		if isArray(*next.raw) {
			doc, err = next.intoAry()

			if err != nil {
				return nil, ""
			}
		} else {
			doc, err = next.intoDoc()

			if err != nil {
				return nil, ""
			}
		}
	}

	return doc, key
}

func (d *partialDoc) set(key string, val *lazyNode) error {
	(*d)[key] = val
	return nil
}

func (d *partialDoc) get(key string) (*lazyNode, error) {
	return (*d)[key], nil
}

func (d *partialDoc) remove(key string) error {
	delete(*d, key)
	return nil
}

func (d *partialArray) set(key string, val *lazyNode) error {
	if key == "-" {
		*d = append(*d, val)
		return nil
	}

	idx, err := strconv.Atoi(key)

	if err != nil {
		return err
	}

	ary := make([]*lazyNode, len(*d)+1)

	cur := *d

	copy(ary[0:idx], cur[0:idx])
	ary[idx] = val
	copy(ary[idx+1:], cur[idx:])

	*d = ary
	return nil
}

func (d *partialArray) get(key string) (*lazyNode, error) {
	idx, err := strconv.Atoi(key)

	if err != nil {
		return nil, err
	}

	return (*d)[idx], nil
}

func (d *partialArray) remove(key string) error {
	idx, err := strconv.Atoi(key)

	if err != nil {
		return err
	}

	cur := *d

	ary := make([]*lazyNode, len(cur)-1)

	copy(ary[0:idx], cur[0:idx])
	copy(ary[idx:], cur[idx+1:])

	*d = ary
	return nil

}

func (p Patch) add(doc *partialDoc, op operation) error {
	path := op.path()

	con, key := findObject(doc, path)

	if con == nil {
		return fmt.Errorf("Missing container: %s", path)
	}

	con.set(key, op.value())

	return nil
}

func (p Patch) remove(doc *partialDoc, op operation) error {
	path := op.path()

	con, key := findObject(doc, path)

	return con.remove(key)
}

func (p Patch) replace(doc *partialDoc, op operation) error {
	path := op.path()

	con, key := findObject(doc, path)

	con.set(key, op.value())

	return nil
}

func (p Patch) move(doc *partialDoc, op operation) error {
	from := op.from()

	con, key := findObject(doc, from)

	val, err := con.get(key)

	if err != nil {
		return err
	}

	con.remove(key)

	path := op.path()

	con, key = findObject(doc, path)

	con.set(key, val)

	return nil
}

func (p Patch) test(doc *partialDoc, op operation) error {
	path := op.path()

	con, key := findObject(doc, path)

	val, err := con.get(key)

	if err != nil {
		return err
	}

	if val == nil {
		if op.value().raw == nil {
			return nil
		} else {
			return fmt.Errorf("Testing value %s failed", path)
		}
	}

	if val.equal(op.value()) {
		return nil
	}

	return fmt.Errorf("Testing value %s failed", path)
}

// Equal indicates if 2 JSON documents have the same structural equality.
func Equal(a, b []byte) bool {
	ra := make(json.RawMessage, len(a))
	copy(ra, a)
	la := newLazyNode(&ra)

	rb := make(json.RawMessage, len(b))
	copy(rb, b)
	lb := newLazyNode(&rb)

	return la.equal(lb)
}

// DecodePatch decodes the passed JSON document as an RFC 6902 patch.
func DecodePatch(buf []byte) (Patch, error) {
	var p Patch

	err := json.Unmarshal(buf, &p)

	if err != nil {
		return nil, err
	}

	return p, nil
}

// Apply mutates a JSON document according to the patch, and returns the new
// document.
func (p Patch) Apply(doc []byte) ([]byte, error) {
	res, err := p.ApplyIndent(doc, "")
	return res, err
}

// ApplyIndent mutates a JSON document according to the patch, and returns the new
// document indented.
func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) {
	pd := &partialDoc{}

	err := json.Unmarshal(doc, pd)

	if err != nil {
		return nil, err
	}

	err = nil

	for _, op := range p {
		switch op.kind() {
		case "add":
			err = p.add(pd, op)
		case "remove":
			err = p.remove(pd, op)
		case "replace":
			err = p.replace(pd, op)
		case "move":
			err = p.move(pd, op)
		case "test":
			err = p.test(pd, op)
		default:
			err = fmt.Errorf("Unexpected kind: %s", op.kind())
		}

		if err != nil {
			return nil, err
		}
	}

	if indent != "" {
		return json.MarshalIndent(pd, "", indent)
	}

	return json.Marshal(pd)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"sync"
	"testing"
	"time"

	"github.com/doozr/guac"
)

func TestReceiveRunsReceiverInBackground(t *testing.T) {
	receiver := func(events guac.EventChan, done DoneChan) error {
		events <- "test"
		return nil
	}
	done := make(DoneChan)
	waitGroup := sync.WaitGroup{}

	events := receive(receiver, done, &waitGroup)
	select {
	case e := <-events:
		if e.(string) != "test" {
			t.Fatal("Expected test event")
		}
	case <-time.After(2 * time.Second):
		t.Fatal("Expected event within 2 seconds")
	}

	waitGroup.Wait()
}

func TestReceiveShutDownCleanlyWithErrors(t *testing.T) {
	receiver := func(events guac.EventChan, done DoneChan) error {
		events <- "test"
		return fmt.Errorf("Error!")
	}
	done := make(DoneChan)
	waitGroup := sync.WaitGroup{}

	events := receive(receiver, done, &waitGroup)
	select {
	case e := <-events:
		if e.(string) != "test" {
			t.Fatal("Expected test event")
		}
	case <-time.After(2 * time.Second):
		t.Fatal("Expected event within 2 seconds")
	}

	waitGroup.Wait()
}

type TestRealTimeReceiver struct {
	receive func() (interface{}, error)
}

func (r TestRealTimeReceiver) Receive() (interface{}, error) {
	return r.receive()
}

func TestReceiverPushesEventsToChannel(t *testing.T) {
	client := TestRealTimeReceiver{
		receive: func() (interface{}, error) {
			return "test event", nil
		},
	}
	receiver := createEventReceiver(client)

	events := make(guac.EventChan)
	done := make(DoneChan)
	go receiver(events, done)

	select {
	case e := <-events:
		if e.(string) != "test event" {
			t.Fatal("Expected test event ", e)
		}
	case <-time.After(2 * time.Second):
		t.Fatal("Expected event within 2 seconds")
	}

	close(done)
}

func TestReceiverQuitsOnError(t *testing.T) {
	client := TestRealTimeReceiver{
		receive: func() (interface{}, error) {
			return nil, fmt.Errorf("Error!")
		},
	}
	receiver := createEventReceiver(client)

	events := make(guac.EventChan)
	done := make(DoneChan)
	err := receiver(events, done)

	if err == nil {
		t.Fatal("Expected error")
	}
}

func TestReceiverReturnsErrorOnNilEvent(t *testing.T) {
	client := TestRealTimeReceiver{
		receive: func() (interface{}, error) {
			return nil, nil
		},
	}
	receiver := createEventReceiver(client)

	events := make(guac.EventChan)
	done := make(DoneChan)
	err := receiver(events, done)

	if err == nil {
		t.Fatal("Expected error")
	}
}

func TestReceiverShutsDownWhenDoneClosed(t *testing.T) {
	client := TestRealTimeReceiver{
		receive: func() (interface{}, error) {
			return "test event", nil
		},
	}
	receiver := createEventReceiver(client)

	events := make(guac.EventChan)
	done := make(DoneChan)
	close(done)
	err := receiver(events, done)

	if err != nil {
		t.Fatal("Expected no error ", err)
	}

	select {
	case e := <-events:
		t.Fatal("Expected nothing on queue ", e)
	default:
	}
}

func TestReceiverReturnsNoErrorWhenDoneClosed(t *testing.T) {
	client := TestRealTimeReceiver{
		receive: func() (interface{}, error) {
			return nil, fmt.Errorf("Error!")
		},
	}
	receiver := createEventReceiver(client)

	events := make(guac.EventChan)
	done := make(DoneChan)
	close(done)
	err := receiver(events, done)

	if err != nil {
		t.Fatal("Expected no error ", err)
	}

	select {
	case e := <-events:
		t.Fatal("Expected nothing on queue ", e)
	default:
	}
}
<commit_msg>Clean up receive tests<commit_after>package main

import (
	"fmt"
	"sync"
	"testing"
	"time"

	"github.com/doozr/guac"
)

func testReceiveSuccess(t *testing.T, receiver EventReceiver) {
	done := make(DoneChan)
	waitGroup := sync.WaitGroup{}

	events := receive(receiver, done, &waitGroup)
	select {
	case e := <-events:
		if e.(string) != "test" {
			t.Fatal("Expected test event")
		}
	case <-time.After(2 * time.Second):
		t.Fatal("Expected event within 2 seconds")
	}

	waitGroup.Wait()
}

func TestReceiveRunsReceiverInBackground(t *testing.T) {
	receiver := func(events guac.EventChan, done DoneChan) error {
		events <- "test"
		return nil
	}
	testReceiveSuccess(t, receiver)
}

func TestReceiveShutDownCleanlyWithErrors(t *testing.T) {
	receiver := func(events guac.EventChan, done DoneChan) error {
		events <- "test"
		return fmt.Errorf("Error!")
	}
	testReceiveSuccess(t, receiver)
}

type TestRealTimeReceiver struct {
	receive func() (interface{}, error)
}

func (r TestRealTimeReceiver) Receive() (interface{}, error) {
	return r.receive()
}

func TestReceiverPushesEventsToChannel(t *testing.T) {
	client := TestRealTimeReceiver{
		receive: func() (interface{}, error) {
			return "test event", nil
		},
	}
	receiver := createEventReceiver(client)

	events := make(guac.EventChan)
	done := make(DoneChan)
	go receiver(events, done)

	select {
	case e := <-events:
		if e.(string) != "test event" {
			t.Fatal("Expected test event ", e)
		}
	case <-time.After(2 * time.Second):
		t.Fatal("Expected event within 2 seconds")
	}

	close(done)
}

func TestReceiverQuitsOnError(t *testing.T) {
	client := TestRealTimeReceiver{
		receive: func() (interface{}, error) {
			return nil, fmt.Errorf("Error!")
		},
	}
	receiver := createEventReceiver(client)

	events := make(guac.EventChan)
	done := make(DoneChan)
	err := receiver(events, done)

	if err == nil {
		t.Fatal("Expected error")
	}
}

func TestReceiverReturnsErrorOnNilEvent(t *testing.T) {
	client := TestRealTimeReceiver{
		receive: func() (interface{}, error) {
			return nil, nil
		},
	}
	receiver := createEventReceiver(client)

	events := make(guac.EventChan)
	done := make(DoneChan)
	err := receiver(events, done)

	if err == nil {
		t.Fatal("Expected error")
	}
}

func TestReceiverShutsDownWhenDoneClosed(t *testing.T) {
	client := TestRealTimeReceiver{
		receive: func() (interface{}, error) {
			return "test event", nil
		},
	}
	receiver := createEventReceiver(client)

	events := make(guac.EventChan)
	done := make(DoneChan)
	close(done)

	receiver(events, done)

	select {
	case e := <-events:
		t.Fatal("Expected nothing on queue ", e)
	default:
	}
}

func TestReceiverReturnsNoErrorWhenDoneClosed(t *testing.T) {
	client := TestRealTimeReceiver{
		receive: func() (interface{}, error) {
			return nil, fmt.Errorf("Error!")
		},
	}
	receiver := createEventReceiver(client)

	events := make(guac.EventChan)
	done := make(DoneChan)
	close(done)

	err := receiver(events, done)
	if err != nil {
		t.Fatal("Expected no error ", err)
	}
}
<|endoftext|>


<commit_before>package tests_test

import (
	"flag"
	"net/url"

	"github.com/gorilla/websocket"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"k8s.io/client-go/pkg/api"
	"kubevirt.io/kubevirt/pkg/api/v1"
	"kubevirt.io/kubevirt/pkg/kubecli"
	"kubevirt.io/kubevirt/tests"
	"time"
)

var _ = Describe("Vmlifecycle", func() {

	flag.Parse()

	restClient, err := kubecli.GetRESTClient()
	tests.PanicOnError(err)
	var vm *v1.VM
	var dial func(vm string, console string) *websocket.Conn

	BeforeEach(func() {
		tests.MustCleanup()

		vm = tests.NewRandomVMWithSerialConsole()

		dial = func(vm string, console string) *websocket.Conn {
			wsUrl, err := url.Parse(flag.Lookup("master").Value.String())
			Expect(err).ToNot(HaveOccurred())
			wsUrl.Scheme = "ws"
			wsUrl.Path = "/apis/kubevirt.io/v1alpha1/namespaces/default/vms/" + vm + "/console"
			wsUrl.RawQuery = "console=" + console
			c, _, err := websocket.DefaultDialer.Dial(wsUrl.String(), nil)
			Expect(err).ToNot(HaveOccurred())
			return c
		}
	})

	Context("New VM with a serial console given", func() {

		It("should be allowed to connect to the console", func(done Done) {
			Expect(restClient.Post().Resource("vms").Namespace(api.NamespaceDefault).Body(vm).Do().Error()).To(Succeed())
			tests.WaitForSuccessfulVMStart(vm)
			ws := dial(vm.ObjectMeta.GetName(), "serial0")
			defer ws.Close()
			close(done)
		}, 60)

		It("should be returned that we are running cirros", func(done Done) {
			Expect(restClient.Post().Resource("vms").Namespace(api.NamespaceDefault).Body(vm).Do().Error()).To(Succeed())
			tests.WaitForSuccessfulVMStart(vm)
			ws := dial(vm.ObjectMeta.GetName(), "serial0")
			defer ws.Close()
			Eventually(func() string {
				_, data, err := ws.ReadMessage()
				Expect(err).ToNot(HaveOccurred())
				return string(data)
			}, 60*time.Second).Should(ContainSubstring("checking http://169.254.169.254/2009-04-04/instance-id"))
			close(done)
		}, 90)

		AfterEach(func() {
			tests.MustCleanup()
		})
	})
})
<commit_msg>Fix flaky functional test which check for CirrOS boot message<commit_after>package tests_test

import (
	"flag"
	"net/url"

	"github.com/gorilla/websocket"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"k8s.io/client-go/pkg/api"
	"kubevirt.io/kubevirt/pkg/api/v1"
	"kubevirt.io/kubevirt/pkg/kubecli"
	"kubevirt.io/kubevirt/tests"
	"strings"
	"time"
)

var _ = Describe("Vmlifecycle", func() {

	flag.Parse()

	restClient, err := kubecli.GetRESTClient()
	tests.PanicOnError(err)
	var vm *v1.VM
	var dial func(vm string, console string) *websocket.Conn

	BeforeEach(func() {
		tests.MustCleanup()

		vm = tests.NewRandomVMWithSerialConsole()

		dial = func(vm string, console string) *websocket.Conn {
			wsUrl, err := url.Parse(flag.Lookup("master").Value.String())
			Expect(err).ToNot(HaveOccurred())
			wsUrl.Scheme = "ws"
			wsUrl.Path = "/apis/kubevirt.io/v1alpha1/namespaces/default/vms/" + vm + "/console"
			wsUrl.RawQuery = "console=" + console
			c, _, err := websocket.DefaultDialer.Dial(wsUrl.String(), nil)
			Expect(err).ToNot(HaveOccurred())
			return c
		}
	})

	Context("New VM with a serial console given", func() {

		It("should be allowed to connect to the console", func(done Done) {
			Expect(restClient.Post().Resource("vms").Namespace(api.NamespaceDefault).Body(vm).Do().Error()).To(Succeed())
			tests.WaitForSuccessfulVMStart(vm)
			ws := dial(vm.ObjectMeta.GetName(), "serial0")
			defer ws.Close()
			close(done)
		}, 60)

		It("should be returned that we are running cirros", func(done Done) {
			Expect(restClient.Post().Resource("vms").Namespace(api.NamespaceDefault).Body(vm).Do().Error()).To(Succeed())
			tests.WaitForSuccessfulVMStart(vm)
			ws := dial(vm.ObjectMeta.GetName(), "serial0")
			defer ws.Close()
			// Check for the typical cloud init error messages
			// TODO, use a reader instead and use ReadLine from bufio
			next := ""
			Eventually(func() string {
				for {
					if index := strings.Index(next, "\n"); index != -1 {
						line := next[0:index]
						next = next[index+1:]
						return line
					}
					_, data, err := ws.ReadMessage()
					Expect(err).ToNot(HaveOccurred())
					next = next + string(data)
				}
			}, 60*time.Second).Should(ContainSubstring("checking http://169.254.169.254/2009-04-04/instance-id"))
			close(done)
		}, 90)

		AfterEach(func() {
			tests.MustCleanup()
		})
	})
})
<|endoftext|>


<commit_before>package actions

import (
	"fmt"
	"math"
	"net/http"
	"net/url"
	"testing"

	. "github.com/smartystreets/goconvey/convey"
	"github.com/stellar/go-stellar-base/xdr"
	"github.com/stellar/horizon/render/problem"
	"github.com/stellar/horizon/test"
	"github.com/zenazn/goji/web"
)

func TestHelpers(t *testing.T) {
	Convey("Action Helpers", t, func() {
		r, _ := http.NewRequest("GET", "/?limit=2&cursor=hello", nil)

		action := &Base{
			Ctx: test.Context(),
			GojiCtx: web.C{
				URLParams: map[string]string{
					"blank":             "",
					"zero":              "0",
					"two":               "2",
					"32min":             fmt.Sprint(math.MinInt32),
					"32max":             fmt.Sprint(math.MaxInt32),
					"64min":             fmt.Sprint(math.MinInt64),
					"64max":             fmt.Sprint(math.MaxInt64),
					"native_asset_type": "native",
					"4_asset_type":      "credit_alphanum4",
					"4_asset_code":      "USD",
					"4_asset_issuer":    "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H",
					"12_asset_type":     "credit_alphanum12",
					"12_asset_code":     "USD",
					"12_asset_issuer":   "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H",
				},
				Env: map[interface{}]interface{}{},
			},
			R: r,
		}

		Convey("GetInt32", func() {
			result := action.GetInt32("blank")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, 0)

			result = action.GetInt32("zero")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, 0)

			result = action.GetInt32("two")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, 2)

			result = action.GetInt32("32max")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, math.MaxInt32)

			result = action.GetInt32("32min")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, math.MinInt32)

			result = action.GetInt32("limit")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, 2)

			_ = action.GetInt32("64max")
			So(action.Err, ShouldHaveSameTypeAs, &problem.P{})
			p := action.Err.(*problem.P)
			So(p.Type, ShouldEqual, "bad_request")
			So(p.Extras["invalid_field"], ShouldEqual, "64max")
			action.Err = nil

			_ = action.GetInt32("64min")
			So(action.Err, ShouldHaveSameTypeAs, &problem.P{})
			p = action.Err.(*problem.P)
			So(p.Type, ShouldEqual, "bad_request")
			So(p.Extras["invalid_field"], ShouldEqual, "64min")
			action.Err = nil

		})

		Convey("GetInt64", func() {
			result := action.GetInt64("blank")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, 0)

			result = action.GetInt64("zero")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, 0)

			result = action.GetInt64("two")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, 2)

			result = action.GetInt64("64max")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, math.MaxInt64)

			result = action.GetInt64("64min")
			So(action.Err, ShouldBeNil)
			So(result, ShouldEqual, math.MinInt64)
		})

		Convey("GetPagingParams", func() {
			cursor, order, limit := action.GetPagingParams()
			So(cursor, ShouldEqual, "hello")
			So(limit, ShouldEqual, 2)
			So(order, ShouldEqual, "")
		})

		Convey("GetAccountID", func() {
			_ = action.GetAccountID("4_asset_issuer")
			So(action.Err, ShouldBeNil)
		})

		Convey("GetAsset", func() {
			ts := action.GetAsset("native_")
			So(action.Err, ShouldBeNil)
			So(ts.Type, ShouldEqual, xdr.AssetTypeAssetTypeNative)

			ts = action.GetAsset("4_")
			So(action.Err, ShouldBeNil)
			So(ts.Type, ShouldEqual, xdr.AssetTypeAssetTypeCreditAlphanum4)

			ts = action.GetAsset("12_")
			So(action.Err, ShouldBeNil)
			So(ts.Type, ShouldEqual, xdr.AssetTypeAssetTypeCreditAlphanum12)

			So(action.Err, ShouldBeNil)
			action.GetAsset("cursor")
			So(action.Err, ShouldNotBeNil)
		})

		Convey("GetAssetType", func() {
			t := action.GetAssetType("native_asset_type")
			So(t, ShouldEqual, xdr.AssetTypeAssetTypeNative)

			t = action.GetAssetType("4_asset_type")
			So(t, ShouldEqual, xdr.AssetTypeAssetTypeCreditAlphanum4)

			t = action.GetAssetType("12_asset_type")
			So(t, ShouldEqual, xdr.AssetTypeAssetTypeCreditAlphanum12)

			So(action.Err, ShouldBeNil)
			action.GetAssetType("cursor")
			So(action.Err, ShouldNotBeNil)
		})

		Convey("Last-Event-ID overrides cursor", func() {
			action.R.Header.Set("Last-Event-ID", "from_header")
			cursor, _, _ := action.GetPagingParams()
			So(cursor, ShouldEqual, "from_header")
		})

		Convey("Form values override query values", func() {
			So(action.GetString("cursor"), ShouldEqual, "hello")

			action.R.Form = url.Values{
				"cursor": {"goodbye"},
			}
			So(action.GetString("cursor"), ShouldEqual, "goodbye")
		})

		Convey("regression: GetPagQuery does not overwrite err", func() {
			r, _ := http.NewRequest("GET", "/?limit=foo", nil)
			action.R = r
			_, _, _ = action.GetPagingParams()

			So(action.Err, ShouldNotBeNil)
			_ = action.GetPageQuery()
			So(action.Err, ShouldNotBeNil)
		})

		Convey("Path() return the action's http path", func() {
			r, _ := http.NewRequest("GET", "/foo-bar/blah?limit=foo", nil)
			action.R = r
			So(action.Path(), ShouldEqual, "/foo-bar/blah")
		})
	})
}
<commit_msg>Remove go convey from actions package<commit_after>package actions

import (
	"fmt"
	"math"
	"net/http"
	"net/url"
	"testing"

	"github.com/stellar/go-stellar-base/xdr"
	"github.com/stellar/horizon/render/problem"
	"github.com/stellar/horizon/test"
	"github.com/zenazn/goji/web"
)

func TestGetAccountID(t *testing.T) {
	tt := test.Start(t)
	defer tt.Finish()
	action := makeTestAction()

	aid := action.GetAccountID("4_asset_issuer")
	tt.Assert.NoError(action.Err)
	tt.Assert.Equal(
		"GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H",
		aid.Address(),
	)
}

func TestGetAsset(t *testing.T) {
	tt := test.Start(t)
	defer tt.Finish()
	action := makeTestAction()

	ts := action.GetAsset("native_")
	if tt.Assert.NoError(action.Err) {
		tt.Assert.Equal(xdr.AssetTypeAssetTypeNative, ts.Type)
	}

	ts = action.GetAsset("4_")
	if tt.Assert.NoError(action.Err) {
		tt.Assert.Equal(xdr.AssetTypeAssetTypeCreditAlphanum4, ts.Type)
	}

	ts = action.GetAsset("12_")
	if tt.Assert.NoError(action.Err) {
		tt.Assert.Equal(xdr.AssetTypeAssetTypeCreditAlphanum12, ts.Type)
	}

	// bad path
	action.GetAsset("cursor")
	tt.Assert.Error(action.Err)
}

func TestGetAssetType(t *testing.T) {
	tt := test.Start(t)
	defer tt.Finish()
	action := makeTestAction()

	ts := action.GetAssetType("native_asset_type")
	if tt.Assert.NoError(action.Err) {
		tt.Assert.Equal(xdr.AssetTypeAssetTypeNative, ts)
	}

	ts = action.GetAssetType("4_asset_type")
	if tt.Assert.NoError(action.Err) {
		tt.Assert.Equal(xdr.AssetTypeAssetTypeCreditAlphanum4, ts)
	}

	ts = action.GetAssetType("12_asset_type")
	if tt.Assert.NoError(action.Err) {
		tt.Assert.Equal(xdr.AssetTypeAssetTypeCreditAlphanum12, ts)
	}
}

func TestGetInt32(t *testing.T) {
	tt := test.Start(t)
	defer tt.Finish()
	action := makeTestAction()

	result := action.GetInt32("blank")
	tt.Assert.NoError(action.Err)
	tt.Assert.Equal(int32(0), result)

	result = action.GetInt32("zero")
	tt.Assert.NoError(action.Err)
	tt.Assert.Equal(int32(0), result)

	result = action.GetInt32("two")
	tt.Assert.NoError(action.Err)
	tt.Assert.Equal(int32(2), result)

	result = action.GetInt32("32max")
	tt.Assert.NoError(action.Err)
	tt.Assert.EqualValues(int32(math.MaxInt32), result)

	result = action.GetInt32("32min")
	tt.Assert.NoError(action.Err)
	tt.Assert.EqualValues(int32(math.MinInt32), result)

	result = action.GetInt32("limit")
	tt.Assert.NoError(action.Err)
	tt.Assert.EqualValues(int32(2), result)

	// overflows
	action.Err = nil
	_ = action.GetInt32("64max")
	if tt.Assert.IsType(&problem.P{}, action.Err) {
		p := action.Err.(*problem.P)
		tt.Assert.Equal("bad_request", p.Type)
		tt.Assert.Equal("64max", p.Extras["invalid_field"])
	}

	action.Err = nil
	_ = action.GetInt32("64min")
	if tt.Assert.IsType(&problem.P{}, action.Err) {
		p := action.Err.(*problem.P)
		tt.Assert.Equal("bad_request", p.Type)
		tt.Assert.Equal("64min", p.Extras["invalid_field"])
	}
}

func TestGetInt64(t *testing.T) {
	tt := test.Start(t)
	defer tt.Finish()
	action := makeTestAction()

	result := action.GetInt64("blank")
	tt.Assert.NoError(action.Err)
	tt.Assert.EqualValues(int64(0), result)

	result = action.GetInt64("zero")
	tt.Assert.NoError(action.Err)
	tt.Assert.EqualValues(int64(0), result)

	result = action.GetInt64("two")
	tt.Assert.NoError(action.Err)
	tt.Assert.Equal(int64(2), result)

	result = action.GetInt64("64max")
	tt.Assert.NoError(action.Err)
	tt.Assert.EqualValues(int64(math.MaxInt64), result)

	result = action.GetInt64("64min")
	tt.Assert.NoError(action.Err)
	tt.Assert.Equal(int64(math.MinInt64), result)
}

func TestGetPagingParams(t *testing.T) {
	tt := test.Start(t)
	defer tt.Finish()
	action := makeTestAction()

	// happy path
	cursor, order, limit := action.GetPagingParams()
	tt.Assert.NoError(action.Err)
	tt.Assert.Equal("hello", cursor)
	tt.Assert.Equal(uint64(2), limit)
	tt.Assert.Equal("", order)

	//Last-Event-ID overrides cursor
	action.R.Header.Set("Last-Event-ID", "from_header")
	cursor, _, _ = action.GetPagingParams()
	tt.Assert.NoError(action.Err)
	tt.Assert.Equal("from_header", cursor)

	// regression: GetPagQuery does not overwrite err
	r, _ := http.NewRequest("GET", "/?limit=foo", nil)
	action.R = r
	_, _, _ = action.GetPagingParams()
	tt.Assert.Error(action.Err)
	_ = action.GetPageQuery()
	tt.Assert.Error(action.Err)
}

func TestGetString(t *testing.T) {
	tt := test.Start(t)
	defer tt.Finish()
	action := makeTestAction()

	tt.Assert.Equal("hello", action.GetString("cursor"))
	action.R.Form = url.Values{
		"cursor": {"goodbye"},
	}
	tt.Assert.Equal("goodbye", action.GetString("cursor"))
}

func TestPath(t *testing.T) {
	tt := test.Start(t)
	defer tt.Finish()
	action := makeTestAction()

	tt.Assert.Equal("/foo-bar/blah", action.Path())
}

func makeTestAction() *Base {
	r, _ := http.NewRequest("GET", "/foo-bar/blah?limit=2&cursor=hello", nil)
	action := &Base{
		Ctx: test.Context(),
		GojiCtx: web.C{
			URLParams: map[string]string{
				"blank":             "",
				"zero":              "0",
				"two":               "2",
				"32min":             fmt.Sprint(math.MinInt32),
				"32max":             fmt.Sprint(math.MaxInt32),
				"64min":             fmt.Sprint(math.MinInt64),
				"64max":             fmt.Sprint(math.MaxInt64),
				"native_asset_type": "native",
				"4_asset_type":      "credit_alphanum4",
				"4_asset_code":      "USD",
				"4_asset_issuer":    "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H",
				"12_asset_type":     "credit_alphanum12",
				"12_asset_code":     "USD",
				"12_asset_issuer":   "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H",
			},
			Env: map[interface{}]interface{}{},
		},
		R: r,
	}
	return action
}
<|endoftext|>


<commit_before><commit_msg>Fixed major transition bug.<commit_after><|endoftext|>


<commit_before>// Copyright 2018 Authors of Cilium
//
// 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 k8sTest

import (
	. "github.com/cilium/cilium/test/ginkgo-ext"
	"github.com/cilium/cilium/test/helpers"

	. "github.com/onsi/gomega"
	"github.com/sirupsen/logrus"
)

var (
	microscopeTestName = "K8sValidatedMicroscope"
)

var _ = Describe(microscopeTestName, func() {

	var (
		kubectl *helpers.Kubectl
		logger  *logrus.Entry
	)

	BeforeAll(func() {
		logger = log.WithFields(logrus.Fields{"testName": microscopeTestName})
		logger.Info("Starting")
		kubectl = helpers.CreateKubectl(helpers.K8s1VMName(), logger)

		err := kubectl.CiliumInstall(helpers.CiliumDSPath)
		Expect(err).To(BeNil(), "Cilium cannot be installed")

		ExpectCiliumReady(kubectl)
	})

	AfterFailed(func() {
		kubectl.CiliumReport(helpers.KubeSystemNamespace,
			"cilium endpoint list")
	})

	AfterAll(func() {
		ExpectAllPodsTerminated(kubectl)
	})

	It("Runs microscope", func() {
		microscopeErr, microscopeCancel := kubectl.MicroscopeStart()
		Expect(microscopeErr).To(BeNil(), "Microscope cannot be started")

		err := helpers.WithTimeout(func() bool {
			res := kubectl.ExecPodCmd("kube-system", "microscope", "pgrep -f microscope")
			return res.WasSuccessful()
		}, "running microscope processes not found",
			&helpers.TimeoutConfig{
				Ticker:  5,
				Timeout: 120,
			})

		Expect(err).To(BeNil())

		kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
		Expect(microscopeCancel()).To(BeNil(), "cannot stop microscope")

		err = helpers.WithTimeout(func() bool {
			res := kubectl.ExecPodCmd("kube-system", "microscope", "pgrep -f microscope")
			return !res.WasSuccessful()
		}, "found running microscope processes; no microscope processes should be running",
			&helpers.TimeoutConfig{
				Ticker:  5,
				Timeout: 120,
			})
		Expect(err).To(BeNil())
	})
})
<commit_msg>test/k8sT: disable microscope test temporarily<commit_after>// Copyright 2018 Authors of Cilium
//
// 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 k8sTest

import (
	. "github.com/cilium/cilium/test/ginkgo-ext"
	"github.com/cilium/cilium/test/helpers"

	. "github.com/onsi/gomega"
	"github.com/sirupsen/logrus"
)

var (
	microscopeTestName = "K8sDisabledValidatedMicroscope"
)

var _ = Describe(microscopeTestName, func() {

	var (
		kubectl *helpers.Kubectl
		logger  *logrus.Entry
	)

	BeforeAll(func() {
		logger = log.WithFields(logrus.Fields{"testName": microscopeTestName})
		logger.Info("Starting")
		kubectl = helpers.CreateKubectl(helpers.K8s1VMName(), logger)

		err := kubectl.CiliumInstall(helpers.CiliumDSPath)
		Expect(err).To(BeNil(), "Cilium cannot be installed")

		ExpectCiliumReady(kubectl)
	})

	AfterFailed(func() {
		kubectl.CiliumReport(helpers.KubeSystemNamespace,
			"cilium endpoint list")
	})

	AfterAll(func() {
		ExpectAllPodsTerminated(kubectl)
	})

	It("Runs microscope", func() {
		microscopeErr, microscopeCancel := kubectl.MicroscopeStart()
		Expect(microscopeErr).To(BeNil(), "Microscope cannot be started")

		err := helpers.WithTimeout(func() bool {
			res := kubectl.ExecPodCmd("kube-system", "microscope", "pgrep -f microscope")
			return res.WasSuccessful()
		}, "running microscope processes not found",
			&helpers.TimeoutConfig{
				Ticker:  5,
				Timeout: 120,
			})

		Expect(err).To(BeNil())

		kubectl.ValidateNoErrorsOnLogs(CurrentGinkgoTestDescription().Duration)
		Expect(microscopeCancel()).To(BeNil(), "cannot stop microscope")

		err = helpers.WithTimeout(func() bool {
			res := kubectl.ExecPodCmd("kube-system", "microscope", "pgrep -f microscope")
			return !res.WasSuccessful()
		}, "found running microscope processes; no microscope processes should be running",
			&helpers.TimeoutConfig{
				Ticker:  5,
				Timeout: 120,
			})
		Expect(err).To(BeNil())
	})
})
<|endoftext|>


<commit_before>package libkb

import (
	"bytes"
	"crypto/sha256"
	"fmt"
	"github.com/keybase/go-triplesec"
	"github.com/ugorji/go/codec"
)

var (
	mh codec.MsgpackHandle
)

var SHA256_CODE int = 8

type KeybasePacketHash struct {
	typ   int `codec:"type"`
	value []byte
}

type KeybasePacket struct {
	body    interface{}
	hash    KeybasePacketHash
	tag     int
	version int
}

type P3SKBBody struct {
	priv P3SKBPriv
	pub  []byte
}

type P3SKBPriv struct {
	data       []byte
	encryption int
}

func KeyBundleToP3SKB(key *PgpKeyBundle, tsec *triplesec.Cipher) (ret *KeybasePacket, err error) {
	ret = &KeybasePacket{
		version: KEYBASE_PACKET_V1,
		tag:     TAG_P3SKB, // Keybase tags starts at 513 (OpenPGP are 0-30)
	}
	body := &P3SKBBody{
		priv: P3SKBPriv{
			encryption: int(triplesec.Version), // Version 3 is the current TripleSec version
		},
	}
	var buf bytes.Buffer
	key.PrimaryKey.Serialize(&buf)
	body.pub = buf.Bytes()

	buf.Reset()
	key.PrivateKey.Serialize(&buf)
	body.priv.data, err = tsec.Encrypt(buf.Bytes())
	if err != nil {
		return
	}

	ret.body = body
	ret.hash.value, err = ret.Hash()

	return
}

func (p *KeybasePacket) Hash() (ret []byte, err error) {
	zb := [0]byte{}
	tmp := p.hash.value
	defer func() {
		p.hash.value = tmp
	}()
	p.hash.value = zb[:]
	p.hash.typ = SHA256_CODE

	var encoded []byte
	if encoded, err = p.Encode(); err != nil {
		return
	}

	sum := sha256.Sum256(encoded)
	ret = sum[:]
	return
}

func (p *KeybasePacket) HashMe() error {
	var err error
	p.hash.value, err = p.Hash()
	return err
}

func (p *KeybasePacket) CheckHash() error {
	var gotten []byte
	var err error
	given := p.hash.value
	if p.hash.typ != SHA256_CODE {
		err = fmt.Errorf("Bad hash code: %d", p.hash.typ)
	} else if gotten, err = p.Hash(); err != nil {

	} else if !FastByteArrayEq(gotten, given) {
		err = fmt.Errorf("Bad packet hash")
	}
	return err
}

func (p *KeybasePacket) Encode() ([]byte, error) {
	var encoded []byte
	err := codec.NewEncoderBytes(&encoded, &mh).Encode(p)
	return encoded, err
}

func (p *KeybasePacket) BinaryUnmarshaler(data []byte) error {
	err := codec.NewDecoderBytes(data, &mh).Decode(p)
	if err != nil {
		return err
	}
	var body interface{}

	switch p.tag {
	case TAG_P3SKB:
		body = &P3SKBBody{}
	default:
		return fmt.Errorf("Unknown packet tag: %d", p.tag)
	}
	var encoded []byte
	err = codec.NewEncoderBytes(&encoded, &mh).Encode(p.body)
	if err != nil {
		return err
	}
	err = codec.NewDecoderBytes(encoded, &mh).Decode(body)
	if err != nil {
		return err
	}
	p.body = body
	if err = p.CheckHash(); err != nil {
		return err
	}

	return nil
}

func DecodePacket(data []byte) (*KeybasePacket, error) {
	p := &KeybasePacket{}
	err := p.BinaryUnmarshaler(data)
	if err != nil {
		p = nil
	}
	return p, err
}
<commit_msg>this didn't work, back it out<commit_after>package libkb

import (
	"bytes"
	"crypto/sha256"
	"fmt"
	"github.com/keybase/go-jsonw"
	"github.com/keybase/go-triplesec"
	"github.com/ugorji/go/codec"
)

var (
	mh codec.MsgpackHandle
)

var SHA256_CODE int = 8

type KeybasePacketHash struct {
	typ   int `codec:"type"`
	value []byte
}

type KeybasePacket struct {
	body    interface{}
	hash    KeybasePacketHash
	tag     int
	version int
}

type P3SKBBody struct {
	priv P3SKBPriv
	pub  []byte
}

type P3SKBPriv struct {
	data       []byte
	encryption int
}

func KeyBundleToP3SKB(key *PgpKeyBundle, tsec *triplesec.Cipher) (ret *KeybasePacket, err error) {
	ret = &KeybasePacket{
		version: KEYBASE_PACKET_V1,
		tag:     TAG_P3SKB, // Keybase tags starts at 513 (OpenPGP are 0-30)
	}
	body := &P3SKBBody{
		priv: P3SKBPriv{
			encryption: int(triplesec.Version), // Version 3 is the current TripleSec version
		},
	}
	var buf bytes.Buffer
	key.PrimaryKey.Serialize(&buf)
	body.pub = buf.Bytes()

	buf.Reset()
	key.PrivateKey.Serialize(&buf)
	body.priv.data, err = tsec.Encrypt(buf.Bytes())
	if err != nil {
		return
	}

	ret.body = body
	ret.hash.value, err = ret.Hash()

	return
}

func (p *KeybasePacket) Hash() (ret []byte, err error) {
	zb := [0]byte{}
	tmp := p.hash.value
	defer func() {
		p.hash.value = tmp
	}()
	p.hash.value = zb[:]
	p.hash.typ = SHA256_CODE

	var encoded []byte
	if encoded, err = p.Encode(); err != nil {
		return
	}

	sum := sha256.Sum256(encoded)
	ret = sum[:]
	return
}

func (p *KeybasePacket) HashMe() error {
	var err error
	p.hash.value, err = p.Hash()
	return err
}

func (p *KeybasePacket) CheckHash() error {
	var gotten []byte
	var err error
	given := p.hash.value
	if p.hash.typ != SHA256_CODE {
		err = fmt.Errorf("Bad hash code: %d", p.hash.typ)
	} else if gotten, err = p.Hash(); err != nil {

	} else if !FastByteArrayEq(gotten, given) {
		err = fmt.Errorf("Bad packet hash")
	}
	return err
}

func (p *KeybasePacket) Encode() ([]byte, error) {
	var encoded []byte
	err := codec.NewEncoderBytes(&encoded, &mh).Encode(p)
	return encoded, err
}

func DecodePacketFromMsgpack(data []byte) (ret *KeybasePacket, err error) {

	var gen interface{}
	err = codec.NewDecoderBytes(data, &mh).Decode(&gen)
	if err != nil {
		return
	}
	jw := jsonw.NewWrapper(gen)
	fmt.Printf("%s\n", jw.MarshalToDebug())
	return DecodePacketFromJson(jw)
}

func DecodePacketHashFromJson(jw *jsonw.Wrapper) (ret KeybasePacketHash, err error) {
	jw.AtKey("type").GetIntVoid(&ret.typ, &err)
	jw.AtKey("value").GetBytesVoid(&ret.value, &err)
	return
}

func DecodedP3SKBFromJson(jw *jsonw.Wrapper) (ret P3SKBBody, err error) {
	jw.AtKey("pub").GetBytesVoid(&ret.pub, &err)
	if err != nil {
		return
	}
	ret.priv, err = DecodeP3SBKPrivFromJson(jw.AtKey("priv"))
	return
}

func DecodeP3SBKPrivFromJson(jw *jsonw.Wrapper) (ret P3SKBPriv, err error) {
	jw.AtKey("data").GetBytesVoid(&ret.data, &err)
	jw.AtKey("encryption").GetIntVoid(&ret.encryption, &err)
	return
}

func DecodePacketFromJson(jw *jsonw.Wrapper) (ret *KeybasePacket, err error) {

	ret = &KeybasePacket{}
	jw.AtKey("tag").GetIntVoid(&ret.tag, &err)
	jw.AtKey("version").GetIntVoid(&ret.version, &err)
	if err != nil {
		return
	}
	ret.hash, err = DecodePacketHashFromJson(jw.AtKey("hash"))
	if err != nil {
		return
	}
	switch ret.tag {
	case TAG_P3SKB:
		ret.body, err = DecodedP3SKBFromJson(jw.AtKey("body"))
	default:
		err = fmt.Errorf("Unknown packet tag: %d", ret.tag)
		return
	}
	if err = ret.CheckHash(); err != nil {
		return
	}

	return
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/base64"
	"io/ioutil"
	"log"
	"os"
)

// FileTokenStorage implements the TokenStorage interface.
// It is one possible implementation for storing user credentials.
type FileTokenStorage struct {
	token         string
	tokenFileName string
}

// SetFileName sets the file name used to store the token in
func (ts *FileTokenStorage) SetFileName(path string) {
	ts.tokenFileName = path
}

// Save persists the token to a file
func (ts *FileTokenStorage) Save(token token) error {
	log.Printf("Saving token [%s]", token.tokenString)
	encodedToken := base64.StdEncoding.EncodeToString([]byte(token.tokenString))
	log.Printf("Saving token (encoded) [%s]", encodedToken)
	ts.token = encodedToken
	return ioutil.WriteFile(ts.tokenFileName, []byte(encodedToken), 0644)
}

// Load loads the persisted token from file
func (ts *FileTokenStorage) Load() (*token, error) {
	if _,err := os.Stat(ts.tokenFileName); err == nil {
		out, err := ioutil.ReadFile(ts.tokenFileName)
		ts.token = string(out)
		log.Printf("Loaded token [%s]", ts.token)
		return Token(ts.token), err
	}
	token := Token("")
	token.Invalidate()
	return token, nil
}
<commit_msg>Removed FileTokenStorage.go<commit_after><|endoftext|>


<commit_before>// Copyright 2016 The rkt 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.

// +build host coreos src kvm

package main

import (
	"fmt"
	"testing"

	"github.com/rkt/rkt/tests/testutils"
)

// TestRunConflictingFlags tests that 'rkt run' will complain and abort
// if conflicting flags are specified together with a pod manifest.
func TestRunConflictingFlags(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	runConflictingFlagsMsg := "conflicting flags set with --pod-manifest (see --help)"
	podManifestFlag := "--pod-manifest=/dev/null"
	conflictingFlags := []struct {
		flag string
		args string
	}{
		{"--inherit-env", ""},
		{"--no-store", ""},
		{"--store-only", ""},
		{"--port=", "foo:80"},
		{"--set-env=", "foo=bar"},
		{"--volume=", "foo,kind=host,source=/tmp"},
		{"--mount=", "volume=foo,target=/tmp --volume=foo,kind=host,source=/tmp"},
	}
	imageConflictingFlags := []struct {
		flag string
		args string
	}{
		{"--exec=", "/bin/sh"},
		{"--user=", "user_foo"},
		{"--group=", "group_foo"},
	}

	for _, cf := range conflictingFlags {
		cmd := fmt.Sprintf("%s run %s %s%s", ctx.Cmd(), podManifestFlag, cf.flag, cf.args)
		runRktAndCheckOutput(t, cmd, runConflictingFlagsMsg, true)
	}
	for _, icf := range imageConflictingFlags {
		cmd := fmt.Sprintf("%s run dummy-image.aci %s %s%s", ctx.Cmd(), podManifestFlag, icf.flag, icf.args)
		runRktAndCheckOutput(t, cmd, runConflictingFlagsMsg, true)
	}
}
<commit_msg>functional tests: add pre-start hook test<commit_after>// Copyright 2016 The rkt 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.

// +build host coreos src kvm

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"testing"

	"github.com/rkt/rkt/common"
	"github.com/rkt/rkt/pkg/aci/acitest"
	"github.com/rkt/rkt/tests/testutils"

	"github.com/appc/spec/schema"
	"github.com/appc/spec/schema/types"
)

// TestRunConflictingFlags tests that 'rkt run' will complain and abort
// if conflicting flags are specified together with a pod manifest.
func TestRunConflictingFlags(t *testing.T) {
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	runConflictingFlagsMsg := "conflicting flags set with --pod-manifest (see --help)"
	podManifestFlag := "--pod-manifest=/dev/null"
	conflictingFlags := []struct {
		flag string
		args string
	}{
		{"--inherit-env", ""},
		{"--no-store", ""},
		{"--store-only", ""},
		{"--port=", "foo:80"},
		{"--set-env=", "foo=bar"},
		{"--volume=", "foo,kind=host,source=/tmp"},
		{"--mount=", "volume=foo,target=/tmp --volume=foo,kind=host,source=/tmp"},
	}
	imageConflictingFlags := []struct {
		flag string
		args string
	}{
		{"--exec=", "/bin/sh"},
		{"--user=", "user_foo"},
		{"--group=", "group_foo"},
	}

	for _, cf := range conflictingFlags {
		cmd := fmt.Sprintf("%s run %s %s%s", ctx.Cmd(), podManifestFlag, cf.flag, cf.args)
		runRktAndCheckOutput(t, cmd, runConflictingFlagsMsg, true)
	}
	for _, icf := range imageConflictingFlags {
		cmd := fmt.Sprintf("%s run dummy-image.aci %s %s%s", ctx.Cmd(), podManifestFlag, icf.flag, icf.args)
		runRktAndCheckOutput(t, cmd, runConflictingFlagsMsg, true)
	}
}

// TestPreStart tests that pre-start events are run, and they run as root even
// when the app itself runs as an unprivileged user.
func TestPreStart(t *testing.T) {
	prestartManifest := schema.ImageManifest{
		Name: "coreos.com/rkt-prestart-test",
		App: &types.App{
			Exec: types.Exec{"/inspect"},
			User: "1000", Group: "1000",
			WorkingDirectory: "/",
			EventHandlers: []types.EventHandler{
				{"pre-start", types.Exec{
					"/inspect",
					"--print-user",
				}},
			},
		},
		Labels: types.Labels{
			{"version", "1.29.0"},
			{"arch", common.GetArch()},
			{"os", common.GetOS()},
		},
	}

	prestartManifestStr, err := acitest.ImageManifestString(&prestartManifest)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	prestartManifestFile := "prestart-manifest.json"
	if err := ioutil.WriteFile(prestartManifestFile, []byte(prestartManifestStr), 0600); err != nil {
		t.Fatalf("Cannot write prestart manifest: %v", err)
	}
	defer os.Remove(prestartManifestFile)
	prestartImage := patchTestACI("rkt-prestart.aci", fmt.Sprintf("--manifest=%s", prestartManifestFile))
	defer os.Remove(prestartImage)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	rktCmd := fmt.Sprintf("%s --insecure-options=image run %s", ctx.Cmd(), prestartImage)
	expectedLine := "User: uid=0 euid=0 gid=0 egid=0"
	runRktAndCheckOutput(t, rktCmd, expectedLine, false)
}
<|endoftext|>


<commit_before>// csvsplit: Split a .csv into multiple files.
package main

import (
	"encoding/csv"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
)

var (
	flagRecords = flag.Int("records", 0, "The number of records per file")
	flagInput = flag.String("input", "", "Filename of the input file to split (if blank, uses stdin)")
	flagOutput = flag.String("output", "", "filename / path of the file output (optional)")
	flagHeaders = flag.Int("headers", 0, "Number of header lines in the input file (will be repeated in each output file")
)

func main() {
	flag.Parse()

	// Sanity check flags
	if *flagRecords < 1 || *flagHeaders < 0 || *flagHeaders >= *flagRecords {
		flag.Usage()
		os.Exit(1)
	}

	// Get input from a given file or stdin
	var reader *csv.Reader
	if *flagInput != "" {
		inputFile, err := os.Open(*flagInput)
		if err != nil {
			log.Fatal(err)
		}
		defer inputFile.Close()
		reader = csv.NewReader(inputFile)
	} else {
		reader = csv.NewReader(os.Stdin)
	}

	records := make([][]string, 0)
	fileCount := 1
	for {
		record, err := reader.Read()
		if err == io.EOF {
			break
		} else if err != nil {
			log.Fatal(err)
		}

		records = append(records, record)
		if len(records) == *flagRecords {
			saveCSVFile(records, fileCount)
			// Reset records to include just the header lines (if any)
			records = records[:*flagHeaders]
			fileCount += 1
		}
	}
	if len(records) > 0 {
		saveCSVFile(records, fileCount)
	}
}

func saveCSVFile(r [][]string, fileCount int) {
	fileName := fmt.Sprintf("%v%03d%v", *flagOutput, fileCount, ".csv")

	// Make sure we don't overwrite existing files
	if _, err := os.Stat(fileName); err == nil {
		log.Fatal("File exists: ", fileName)
	}

	f, err := os.Create(fileName)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	writer := csv.NewWriter(f)
	writer.WriteAll(r)
}
<commit_msg>gofmt fix<commit_after>// csvsplit: Split a .csv into multiple files.
package main

import (
	"encoding/csv"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
)

var (
	flagRecords = flag.Int("records", 0, "The number of records per file")
	flagInput   = flag.String("input", "", "Filename of the input file to split (if blank, uses stdin)")
	flagOutput  = flag.String("output", "", "filename / path of the file output (optional)")
	flagHeaders = flag.Int("headers", 0, "Number of header lines in the input file (will be repeated in each output file")
)

func main() {
	flag.Parse()

	// Sanity check flags
	if *flagRecords < 1 || *flagHeaders < 0 || *flagHeaders >= *flagRecords {
		flag.Usage()
		os.Exit(1)
	}

	// Get input from a given file or stdin
	var reader *csv.Reader
	if *flagInput != "" {
		inputFile, err := os.Open(*flagInput)
		if err != nil {
			log.Fatal(err)
		}
		defer inputFile.Close()
		reader = csv.NewReader(inputFile)
	} else {
		reader = csv.NewReader(os.Stdin)
	}

	records := make([][]string, 0)
	fileCount := 1
	for {
		record, err := reader.Read()
		if err == io.EOF {
			break
		} else if err != nil {
			log.Fatal(err)
		}

		records = append(records, record)
		if len(records) == *flagRecords {
			saveCSVFile(records, fileCount)
			// Reset records to include just the header lines (if any)
			records = records[:*flagHeaders]
			fileCount += 1
		}
	}
	if len(records) > 0 {
		saveCSVFile(records, fileCount)
	}
}

func saveCSVFile(r [][]string, fileCount int) {
	fileName := fmt.Sprintf("%v%03d%v", *flagOutput, fileCount, ".csv")

	// Make sure we don't overwrite existing files
	if _, err := os.Stat(fileName); err == nil {
		log.Fatal("File exists: ", fileName)
	}

	f, err := os.Create(fileName)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	writer := csv.NewWriter(f)
	writer.WriteAll(r)
}
<|endoftext|>