<commit_before>package edf

import (
	"fmt"
	mmap "github.com/riobard/go-mmap"
	"os"
	"runtime"
)

// EdfFile represents a mapped file on disk or
// and anonymous mapping for instance storage
type EdfFile struct {
	f           *os.File
	m           []mmap.Mmap
	segmentSize uint64
	pageSize    uint64
}

// GetPageSize returns the pageSize of an EdfFile
func (e *EdfFile) GetPageSize() uint64 {
	return e.pageSize
}

// GetSegmentSize returns the segmentSize of an EdfFile
func (e *EdfFile) GetSegmentSize() uint64 {
	return e.segmentSize
}

// EdfPosition represents a start and finish point
// within the mapping
type EdfPosition struct {
	Segment uint64
	Byte    uint64
}

// EdfRange represents a start and an end segment
// mapped in an EdfFile and also the byte offsets
// within that segment
type EdfRange struct {
	Start       EdfPosition
	End         EdfPosition
	segmentSize uint64
}

// Size returns the size (in bytes) of a given EdfRange
func (r *EdfRange) Size() uint64 {
	ret := uint64(r.End.Segment-r.Start.Segment) * r.segmentSize
	ret += uint64(r.End.Byte - r.Start.Byte)
	return ret
}

// edfCallFree is a half-baked finalizer called on garbage
// collection to ensure that the mapping gets freed
func edfCallFree(e *EdfFile) {
	e.Unmap(EDF_UNMAP_NOSYNC)
}

// EdfAnonMap maps the EdfFile structure into RAM
// IMPORTANT: everything's lost if unmapped
func EdfAnonMap() (*EdfFile, error) {

	var err error

	ret := new(EdfFile)

	// Figure out the flags
	protFlags := mmap.PROT_READ | mmap.PROT_WRITE
	mapFlags := mmap.MAP_FILE | mmap.MAP_SHARED
	// Create mapping references
	ret.m = make([]mmap.Mmap, 0)
	// Get the page size
	pageSize := int64(os.Getpagesize())
	// Segment size is the size of each mapped region
	ret.pageSize = uint64(pageSize)
	ret.segmentSize = uint64(EDF_LENGTH) * uint64(os.Getpagesize())

	// Map the memory
	for i := int64(0); i < EDF_SIZE; i += int64(EDF_LENGTH) * pageSize {
		thisMapping, err := mmap.AnonMap(int(ret.segmentSize), protFlags, mapFlags)
		if err != nil {
			// TODO: cleanup
			return nil, err
		}
		ret.m = append(ret.m, thisMapping)
	}

	// Generate the header
	ret.createHeader()
	err = ret.writeInitialData()

	// Make sure this gets unmapped on garbage collection
	runtime.SetFinalizer(ret, edfCallFree)

	return ret, err
}

// EdfMap takes an os.File and returns an EdfMappedFile
// structure, which represents the mmap'd underlying file
//
// The `mode` parameter takes the following values
//      EDF_CREATE: EdfMap will truncate the file to the right length and write the correct header information
//      EDF_READ_WRITE: EdfMap will verify header information
//      EDF_READ_ONLY:  EdfMap will verify header information
// IMPORTANT: EDF_LENGTH (edf.go) controls the size of the address
// space mapping. This means that the file can be truncated to the
// correct size without remapping. On 32-bit systems, this
// is set to 2GiB.
func EdfMap(f *os.File, mode int) (*EdfFile, error) {
	var err error

	// Set up various things
	ret := new(EdfFile)
	ret.f = f
	ret.m = make([]mmap.Mmap, 0)

	// Figure out the flags
	protFlags := mmap.PROT_READ
	if mode == EDF_READ_WRITE || mode == EDF_CREATE {
		protFlags |= mmap.PROT_WRITE
	}
	mapFlags := mmap.MAP_FILE | mmap.MAP_SHARED
	// Get the page size
	pageSize := int64(os.Getpagesize())
	// Segment size is the size of each mapped region
	ret.pageSize = uint64(pageSize)
	ret.segmentSize = uint64(EDF_LENGTH) * uint64(os.Getpagesize())

	// Map the file
	for i := int64(0); i < EDF_SIZE; i += int64(EDF_LENGTH) * pageSize {
		thisMapping, err := mmap.Map(f, i*pageSize, int(int64(EDF_LENGTH)*pageSize), protFlags, mapFlags)
		if err != nil {
			// TODO: cleanup
			return nil, err
		}
		ret.m = append(ret.m, thisMapping)
	}

	// Verify or generate the header
	if mode == EDF_READ_WRITE || mode == EDF_READ_ONLY {
		err = ret.VerifyHeader()
		if err != nil {
			return nil, err
		}
	} else if mode == EDF_CREATE {
		err = ret.truncate(4)
		if err != nil {
			return nil, err
		}
		ret.createHeader()
		err = ret.writeInitialData()
	} else {
		err = fmt.Errorf("Unrecognised flags")
	}

	// Make sure this gets unmapped on garbage collection
	runtime.SetFinalizer(ret, edfCallFree)

	return ret, err

}

// Range returns the segment offset and range of
// two positions in the file.
func (e *EdfFile) Range(byteStart uint64, byteEnd uint64) EdfRange {
	var ret EdfRange
	ret.Start.Segment = byteStart / e.segmentSize
	ret.End.Segment = byteEnd / e.segmentSize
	ret.Start.Byte = byteStart % e.segmentSize
	ret.End.Byte = byteEnd % e.segmentSize
	ret.segmentSize = e.segmentSize
	return ret
}

// GetPageRange returns the segment offset and range of
// two pages in the file.
func (e *EdfFile) GetPageRange(pageStart uint64, pageEnd uint64) EdfRange {
	return e.Range(pageStart*e.pageSize, pageEnd*e.pageSize+e.pageSize-1)
}

// VerifyHeader checks that this version of Golearn can
// read the file presented.
func (e *EdfFile) VerifyHeader() error {
	// Check the magic bytes
	diff := (e.m[0][0] ^ byte('G')) | (e.m[0][1] ^ byte('O'))
	diff |= (e.m[0][2] ^ byte('L')) | (e.m[0][3] ^ byte('N'))
	if diff != 0 {
		return fmt.Errorf("Invalid magic bytes")
	}
	// Check the file version
	version := uint32FromBytes(e.m[0][4:8])
	if version != EDF_VERSION {
		return fmt.Errorf("Unsupported version: %d", version)
	}
	// Check the page size
	pageSize := uint32FromBytes(e.m[0][8:12])
	if pageSize != uint32(os.Getpagesize()) {
		return fmt.Errorf("Unsupported page size: (file: %d, system: %d", pageSize, os.Getpagesize())
	}
	return nil
}

// createHeader writes a valid header file into the file.
// Unexported since it can cause data loss.
func (e *EdfFile) createHeader() {
	e.m[0][0] = byte('G')
	e.m[0][1] = byte('O')
	e.m[0][2] = byte('L')
	e.m[0][3] = byte('N')
	uint32ToBytes(EDF_VERSION, e.m[0][4:8])
	uint32ToBytes(uint32(os.Getpagesize()), e.m[0][8:12])
	e.Sync()
}

// writeInitialData writes system thread information
func (e *EdfFile) writeInitialData() error {
	var t Thread
	t.name = "SYSTEM"
	t.id = 1
	err := e.WriteThread(&t)
	if err != nil {
		return err
	}
	t.name = "FIXED"
	t.id = 2
	err = e.WriteThread(&t)
	return err
}

// GetThreadCount returns the number of threads in this file.
func (e *EdfFile) GetThreadCount() uint32 {
	// The number of threads is stored in bytes 12-16 in the header
	return uint32FromBytes(e.m[0][12:])
}

// incrementThreadCount increments the record of the number
// of threads in this file
func (e *EdfFile) incrementThreadCount() uint32 {
	cur := e.GetThreadCount()
	cur++
	uint32ToBytes(cur, e.m[0][12:])
	return cur
}

// GetThreads returns the thread identifier -> name map.
func (e *EdfFile) GetThreads() (map[uint32]string, error) {
	ret := make(map[uint32]string)
	count := e.GetThreadCount()
	// The starting block
	block := uint64(1)
	for {
		// Decode the block offset
		r := e.GetPageRange(block, block)
		if r.Start.Segment != r.End.Segment {
			return nil, fmt.Errorf("Thread range split across segments")
		}
		bytes := e.m[r.Start.Segment]
		bytes = bytes[r.Start.Byte : r.End.Byte+1]
		// The first 8 bytes say where to go next
		block = uint64FromBytes(bytes)
		bytes = bytes[8:]

		for {
			length := uint32FromBytes(bytes)
			if length == 0 {
				break
			}
			t := &Thread{}
			size := t.Deserialize(bytes)
			bytes = bytes[size:]
			ret[t.id] = t.name[0:len(t.name)]
		}
		// If next block offset is zero, no more threads to read
		if block == 0 {
			break
		}
	}
	// Hey? What's wrong with you!
	if len(ret) != int(count) {
		return ret, fmt.Errorf("Thread mismatch: %d/%d, indicates possible corruption", len(ret), count)
	}
	return ret, nil
}

// Sync writes information to physical storage.
func (e *EdfFile) Sync() error {
	for _, m := range e.m {
		err := m.Sync(mmap.MS_SYNC)
		if err != nil {
			return err
		}
	}
	return nil
}

// truncate changes the size of the underlying file
// The size of the address space doesn't change.
func (e *EdfFile) truncate(size int64) error {
	pageSize := int64(os.Getpagesize())
	newSize := pageSize * size

	// Synchronise
	// e.Sync()

	// Double-check that we're not reducing file size
	fileInfo, err := e.f.Stat()
	if err != nil {
		return err
	}
	if fileInfo.Size() > newSize {
		return fmt.Errorf("Can't reduce file size!")
	}

	// Truncate the file
	err = e.f.Truncate(newSize)
	if err != nil {
		return err
	}

	// Verify that the file is larger now than it was
	fileInfo, err = e.f.Stat()
	if err != nil {
		return err
	}
	if fileInfo.Size() != newSize {
		return fmt.Errorf("Truncation failed: %d, %d", fileInfo.Size(), newSize)
	}
	return err
}

// Unmap unlinks the EdfFile from the address space.
// EDF_UNMAP_NOSYNC skips calling Sync() on the underlying
// file before this happens.
// IMPORTANT: attempts to use this mapping after Unmap() is
// called will result in crashes.
func (e *EdfFile) Unmap(flags int) error {
	// Sync the file
	e.Sync()
	if flags != EDF_UNMAP_NOSYNC {
		e.Sync()
	}
	// Unmap the file
	for _, m := range e.m {
		err := m.Unmap()
		if err != nil {
			return err
		}
	}
	return nil
}

// ResolveRange returns a slice of byte slices representing
// the underlying memory referenced by EdfRange.
//
// WARNING: slow.
func (e *EdfFile) ResolveRange(r EdfRange) [][]byte {
	var ret [][]byte
	segCounter := 0
	for segment := r.Start.Segment; segment <= r.End.Segment; segment++ {
		if segment == r.Start.Segment {
			ret = append(ret, e.m[segment][r.Start.Byte:])
		} else if segment == r.End.Segment {
			ret = append(ret, e.m[segment][:r.End.Byte+1])
		} else {
			ret = append(ret, e.m[segment])
		}
		segCounter++
	}
	return ret
}

// IResolveRange returns a byte slice representing the current EdfRange
// and returns a value saying whether there's more. Subsequent calls to IncrementallyResolveRange
// should use the value returned by the previous one until no more ranges are available.
func (e *EdfFile) IResolveRange(r EdfRange, prev uint64) ([]byte, uint64) {
	segment := r.Start.Segment + prev
	if segment > r.End.Segment {
		return nil, 0
	}
	if segment == r.Start.Segment {
		return e.m[segment][r.Start.Byte:], prev + 1
	}
	if segment == r.End.Segment {
		return e.m[segment][:r.End.Byte+1], 0
	}
	return e.m[segment], prev + 1
}
<commit_msg>Changing mmap repo<commit_after>package edf

import (
	"fmt"
	mmap "github.com/Sentimentron/go-mmap"
	"os"
	"runtime"
)

// EdfFile represents a mapped file on disk or
// and anonymous mapping for instance storage
type EdfFile struct {
	f           *os.File
	m           []mmap.Mmap
	segmentSize uint64
	pageSize    uint64
}

// GetPageSize returns the pageSize of an EdfFile
func (e *EdfFile) GetPageSize() uint64 {
	return e.pageSize
}

// GetSegmentSize returns the segmentSize of an EdfFile
func (e *EdfFile) GetSegmentSize() uint64 {
	return e.segmentSize
}

// EdfPosition represents a start and finish point
// within the mapping
type EdfPosition struct {
	Segment uint64
	Byte    uint64
}

// EdfRange represents a start and an end segment
// mapped in an EdfFile and also the byte offsets
// within that segment
type EdfRange struct {
	Start       EdfPosition
	End         EdfPosition
	segmentSize uint64
}

// Size returns the size (in bytes) of a given EdfRange
func (r *EdfRange) Size() uint64 {
	ret := uint64(r.End.Segment-r.Start.Segment) * r.segmentSize
	ret += uint64(r.End.Byte - r.Start.Byte)
	return ret
}

// edfCallFree is a half-baked finalizer called on garbage
// collection to ensure that the mapping gets freed
func edfCallFree(e *EdfFile) {
	e.Unmap(EDF_UNMAP_NOSYNC)
}

// EdfAnonMap maps the EdfFile structure into RAM
// IMPORTANT: everything's lost if unmapped
func EdfAnonMap() (*EdfFile, error) {

	var err error

	ret := new(EdfFile)

	// Figure out the flags
	protFlags := mmap.PROT_READ | mmap.PROT_WRITE
	mapFlags := mmap.MAP_FILE | mmap.MAP_SHARED
	// Create mapping references
	ret.m = make([]mmap.Mmap, 0)
	// Get the page size
	pageSize := int64(os.Getpagesize())
	// Segment size is the size of each mapped region
	ret.pageSize = uint64(pageSize)
	ret.segmentSize = uint64(EDF_LENGTH) * uint64(os.Getpagesize())

	// Map the memory
	for i := int64(0); i < EDF_SIZE; i += int64(EDF_LENGTH) * pageSize {
		thisMapping, err := mmap.AnonMap(int(ret.segmentSize), protFlags, mapFlags)
		if err != nil {
			// TODO: cleanup
			return nil, err
		}
		ret.m = append(ret.m, thisMapping)
	}

	// Generate the header
	ret.createHeader()
	err = ret.writeInitialData()

	// Make sure this gets unmapped on garbage collection
	runtime.SetFinalizer(ret, edfCallFree)

	return ret, err
}

// EdfMap takes an os.File and returns an EdfMappedFile
// structure, which represents the mmap'd underlying file
//
// The `mode` parameter takes the following values
//      EDF_CREATE: EdfMap will truncate the file to the right length and write the correct header information
//      EDF_READ_WRITE: EdfMap will verify header information
//      EDF_READ_ONLY:  EdfMap will verify header information
// IMPORTANT: EDF_LENGTH (edf.go) controls the size of the address
// space mapping. This means that the file can be truncated to the
// correct size without remapping. On 32-bit systems, this
// is set to 2GiB.
func EdfMap(f *os.File, mode int) (*EdfFile, error) {
	var err error

	// Set up various things
	ret := new(EdfFile)
	ret.f = f
	ret.m = make([]mmap.Mmap, 0)

	// Figure out the flags
	protFlags := mmap.PROT_READ
	if mode == EDF_READ_WRITE || mode == EDF_CREATE {
		protFlags |= mmap.PROT_WRITE
	}
	mapFlags := mmap.MAP_FILE | mmap.MAP_SHARED
	// Get the page size
	pageSize := int64(os.Getpagesize())
	// Segment size is the size of each mapped region
	ret.pageSize = uint64(pageSize)
	ret.segmentSize = uint64(EDF_LENGTH) * uint64(os.Getpagesize())

	// Map the file
	for i := int64(0); i < EDF_SIZE; i += int64(EDF_LENGTH) * pageSize {
		thisMapping, err := mmap.Map(f, i*pageSize, int(int64(EDF_LENGTH)*pageSize), protFlags, mapFlags)
		if err != nil {
			// TODO: cleanup
			return nil, err
		}
		ret.m = append(ret.m, thisMapping)
	}

	// Verify or generate the header
	if mode == EDF_READ_WRITE || mode == EDF_READ_ONLY {
		err = ret.VerifyHeader()
		if err != nil {
			return nil, err
		}
	} else if mode == EDF_CREATE {
		err = ret.truncate(4)
		if err != nil {
			return nil, err
		}
		ret.createHeader()
		err = ret.writeInitialData()
	} else {
		err = fmt.Errorf("Unrecognised flags")
	}

	// Make sure this gets unmapped on garbage collection
	runtime.SetFinalizer(ret, edfCallFree)

	return ret, err

}

// Range returns the segment offset and range of
// two positions in the file.
func (e *EdfFile) Range(byteStart uint64, byteEnd uint64) EdfRange {
	var ret EdfRange
	ret.Start.Segment = byteStart / e.segmentSize
	ret.End.Segment = byteEnd / e.segmentSize
	ret.Start.Byte = byteStart % e.segmentSize
	ret.End.Byte = byteEnd % e.segmentSize
	ret.segmentSize = e.segmentSize
	return ret
}

// GetPageRange returns the segment offset and range of
// two pages in the file.
func (e *EdfFile) GetPageRange(pageStart uint64, pageEnd uint64) EdfRange {
	return e.Range(pageStart*e.pageSize, pageEnd*e.pageSize+e.pageSize-1)
}

// VerifyHeader checks that this version of Golearn can
// read the file presented.
func (e *EdfFile) VerifyHeader() error {
	// Check the magic bytes
	diff := (e.m[0][0] ^ byte('G')) | (e.m[0][1] ^ byte('O'))
	diff |= (e.m[0][2] ^ byte('L')) | (e.m[0][3] ^ byte('N'))
	if diff != 0 {
		return fmt.Errorf("Invalid magic bytes")
	}
	// Check the file version
	version := uint32FromBytes(e.m[0][4:8])
	if version != EDF_VERSION {
		return fmt.Errorf("Unsupported version: %d", version)
	}
	// Check the page size
	pageSize := uint32FromBytes(e.m[0][8:12])
	if pageSize != uint32(os.Getpagesize()) {
		return fmt.Errorf("Unsupported page size: (file: %d, system: %d", pageSize, os.Getpagesize())
	}
	return nil
}

// createHeader writes a valid header file into the file.
// Unexported since it can cause data loss.
func (e *EdfFile) createHeader() {
	e.m[0][0] = byte('G')
	e.m[0][1] = byte('O')
	e.m[0][2] = byte('L')
	e.m[0][3] = byte('N')
	uint32ToBytes(EDF_VERSION, e.m[0][4:8])
	uint32ToBytes(uint32(os.Getpagesize()), e.m[0][8:12])
	e.Sync()
}

// writeInitialData writes system thread information
func (e *EdfFile) writeInitialData() error {
	var t Thread
	t.name = "SYSTEM"
	t.id = 1
	err := e.WriteThread(&t)
	if err != nil {
		return err
	}
	t.name = "FIXED"
	t.id = 2
	err = e.WriteThread(&t)
	return err
}

// GetThreadCount returns the number of threads in this file.
func (e *EdfFile) GetThreadCount() uint32 {
	// The number of threads is stored in bytes 12-16 in the header
	return uint32FromBytes(e.m[0][12:])
}

// incrementThreadCount increments the record of the number
// of threads in this file
func (e *EdfFile) incrementThreadCount() uint32 {
	cur := e.GetThreadCount()
	cur++
	uint32ToBytes(cur, e.m[0][12:])
	return cur
}

// GetThreads returns the thread identifier -> name map.
func (e *EdfFile) GetThreads() (map[uint32]string, error) {
	ret := make(map[uint32]string)
	count := e.GetThreadCount()
	// The starting block
	block := uint64(1)
	for {
		// Decode the block offset
		r := e.GetPageRange(block, block)
		if r.Start.Segment != r.End.Segment {
			return nil, fmt.Errorf("Thread range split across segments")
		}
		bytes := e.m[r.Start.Segment]
		bytes = bytes[r.Start.Byte : r.End.Byte+1]
		// The first 8 bytes say where to go next
		block = uint64FromBytes(bytes)
		bytes = bytes[8:]

		for {
			length := uint32FromBytes(bytes)
			if length == 0 {
				break
			}
			t := &Thread{}
			size := t.Deserialize(bytes)
			bytes = bytes[size:]
			ret[t.id] = t.name[0:len(t.name)]
		}
		// If next block offset is zero, no more threads to read
		if block == 0 {
			break
		}
	}
	// Hey? What's wrong with you!
	if len(ret) != int(count) {
		return ret, fmt.Errorf("Thread mismatch: %d/%d, indicates possible corruption", len(ret), count)
	}
	return ret, nil
}

// Sync writes information to physical storage.
func (e *EdfFile) Sync() error {
	for _, m := range e.m {
		err := m.Sync(mmap.MS_SYNC)
		if err != nil {
			return err
		}
	}
	return nil
}

// truncate changes the size of the underlying file
// The size of the address space doesn't change.
func (e *EdfFile) truncate(size int64) error {
	pageSize := int64(os.Getpagesize())
	newSize := pageSize * size

	// Synchronise
	// e.Sync()

	// Double-check that we're not reducing file size
	fileInfo, err := e.f.Stat()
	if err != nil {
		return err
	}
	if fileInfo.Size() > newSize {
		return fmt.Errorf("Can't reduce file size!")
	}

	// Truncate the file
	err = e.f.Truncate(newSize)
	if err != nil {
		return err
	}

	// Verify that the file is larger now than it was
	fileInfo, err = e.f.Stat()
	if err != nil {
		return err
	}
	if fileInfo.Size() != newSize {
		return fmt.Errorf("Truncation failed: %d, %d", fileInfo.Size(), newSize)
	}
	return err
}

// Unmap unlinks the EdfFile from the address space.
// EDF_UNMAP_NOSYNC skips calling Sync() on the underlying
// file before this happens.
// IMPORTANT: attempts to use this mapping after Unmap() is
// called will result in crashes.
func (e *EdfFile) Unmap(flags int) error {
	// Sync the file
	e.Sync()
	if flags != EDF_UNMAP_NOSYNC {
		e.Sync()
	}
	// Unmap the file
	for _, m := range e.m {
		err := m.Unmap()
		if err != nil {
			return err
		}
	}
	return nil
}

// ResolveRange returns a slice of byte slices representing
// the underlying memory referenced by EdfRange.
//
// WARNING: slow.
func (e *EdfFile) ResolveRange(r EdfRange) [][]byte {
	var ret [][]byte
	segCounter := 0
	for segment := r.Start.Segment; segment <= r.End.Segment; segment++ {
		if segment == r.Start.Segment {
			ret = append(ret, e.m[segment][r.Start.Byte:])
		} else if segment == r.End.Segment {
			ret = append(ret, e.m[segment][:r.End.Byte+1])
		} else {
			ret = append(ret, e.m[segment])
		}
		segCounter++
	}
	return ret
}

// IResolveRange returns a byte slice representing the current EdfRange
// and returns a value saying whether there's more. Subsequent calls to IncrementallyResolveRange
// should use the value returned by the previous one until no more ranges are available.
func (e *EdfFile) IResolveRange(r EdfRange, prev uint64) ([]byte, uint64) {
	segment := r.Start.Segment + prev
	if segment > r.End.Segment {
		return nil, 0
	}
	if segment == r.Start.Segment {
		return e.m[segment][r.Start.Byte:], prev + 1
	}
	if segment == r.End.Segment {
		return e.m[segment][:r.End.Byte+1], 0
	}
	return e.m[segment], prev + 1
}
<|endoftext|>


<commit_before>package graphite

import (
	"bytes"
	"fmt"
	"log"
	"net"
	"time"
)

// Graphite is a struct that defines the relevant properties of a graphite
// connection
type Graphite struct {
	Host    string
	Port    int
	Timeout time.Duration
	Prefix	string
	conn    net.Conn
	nop     bool
}

// defaultTimeout is the default number of seconds that we're willing to wait
// before forcing the connection establishment to fail
const defaultTimeout = 5

// IsNop is a getter for *graphite.Graphite.nop
func (graphite *Graphite) IsNop() bool {
	if graphite.nop {
		return true
	}
	return false
}

// Given a Graphite struct, Connect populates the Graphite.conn field with an
// appropriate TCP connection
func (graphite *Graphite) Connect() error {
	if !graphite.IsNop() {
		if graphite.conn != nil {
			graphite.conn.Close()
		}

		address := fmt.Sprintf("%s:%d", graphite.Host, graphite.Port)

		if graphite.Timeout == 0 {
			graphite.Timeout = defaultTimeout * time.Second
		}

		conn, err := net.DialTimeout("tcp", address, graphite.Timeout)
		if err != nil {
			return err
		}

		graphite.conn = conn
	}

	return nil
}

// Given a Metric struct, the SendMetric method sends the supplied metric to the
// Graphite connection that the method is called upon
func (graphite *Graphite) SendMetric(metric Metric) error {
	metrics := make([]Metric, 1)
	metrics[0] = metric

	return graphite.sendMetrics(metrics)
}

// Given a slice of Metrics, the SendMetrics method sends the metrics, as a
// batch, to the Graphite connection that the method is called upon
func (graphite *Graphite) SendMetrics(metrics []Metric) error {
	return graphite.sendMetrics(metrics)
}

// sendMetrics is an internal function that is used to write to the TCP
// connection in order to communicate metrics to the remote Graphite host
func (graphite *Graphite) sendMetrics(metrics []Metric) error {
	zeroed_metric := Metric{} // ignore unintialized metrics
	if !graphite.IsNop() {
		buf := bytes.NewBufferString("")
		for _, metric := range metrics {
			if metric == zeroed_metric {
				continue // ignore unintialized metrics
			}
			if metric.Timestamp == 0 {
				metric.Timestamp = time.Now().Unix()
			}
			metric_name := ""
			if graphite.Prefix != "" {
				metric_name = fmt.Sprintf("%s.%s", graphite.Prefix, metric.Name)
			} else {
				metric_name = metric.Name
			}
			buf.WriteString(fmt.Sprintf("%s %s %d\n", metric_name, metric.Value, metric.Timestamp))
		}
		_, err := graphite.conn.Write(buf.Bytes())
		//fmt.Print("Sent msg:", buf.String(), "'")
		if err != nil {
			return err
		}
	} else {
		for _, metric := range metrics {
			log.Printf("Graphite: %s\n", metric)
		}
	}
	return nil
}

// The SimpleSend method can be used to just pass a metric name and value and
// have it be sent to the Graphite host with the current timestamp
func (graphite *Graphite) SimpleSend(stat string, value string) error {
	metrics := make([]Metric, 1)
	metrics[0] = NewMetric(stat, value, time.Now().Unix())
	err := graphite.sendMetrics(metrics)
	if err != nil {
		return err
	}
	return nil
}

// NewGraphiteHost is a factory method that's used to create a new Graphite
// connection given a hostname and a port number
func NewGraphite(host string, port int) (*Graphite, error) {
	Graphite := &Graphite{Host: host, Port: port}
	err := Graphite.Connect()
	if err != nil {
		return nil, err
	}

	return Graphite, nil
}

// NewGraphiteNop is a factory method that returns a Graphite struct but will
// not actually try to send any packets to a remote host and, instead, will just
// log. This is useful if you want to use Graphite in a project but don't want
// to make Graphite a requirement for the project.
func NewGraphiteNop(host string, port int) *Graphite {
	graphiteNop := &Graphite{Host: host, Port: port, nop: true}
	return graphiteNop
}
<commit_msg>feat: support disconnecting<commit_after>package graphite

import (
	"bytes"
	"fmt"
	"log"
	"net"
	"time"
)

// Graphite is a struct that defines the relevant properties of a graphite
// connection
type Graphite struct {
	Host    string
	Port    int
	Timeout time.Duration
	Prefix	string
	conn    net.Conn
	nop     bool
}

// defaultTimeout is the default number of seconds that we're willing to wait
// before forcing the connection establishment to fail
const defaultTimeout = 5

// IsNop is a getter for *graphite.Graphite.nop
func (graphite *Graphite) IsNop() bool {
	if graphite.nop {
		return true
	}
	return false
}

// Given a Graphite struct, Connect populates the Graphite.conn field with an
// appropriate TCP connection
func (graphite *Graphite) Connect() error {
	if !graphite.IsNop() {
		if graphite.conn != nil {
			graphite.conn.Close()
		}

		address := fmt.Sprintf("%s:%d", graphite.Host, graphite.Port)

		if graphite.Timeout == 0 {
			graphite.Timeout = defaultTimeout * time.Second
		}

		conn, err := net.DialTimeout("tcp", address, graphite.Timeout)
		if err != nil {
			return err
		}

		graphite.conn = conn
	}

	return nil
}

// Given a Graphite struct, Disconnect closes the Graphite.conn field
func (graphite *Graphite) Disconnect() error {
	err := graphite.conn.Close()
	graphite.conn = nil
	return err
}

// Given a Metric struct, the SendMetric method sends the supplied metric to the
// Graphite connection that the method is called upon
func (graphite *Graphite) SendMetric(metric Metric) error {
	metrics := make([]Metric, 1)
	metrics[0] = metric

	return graphite.sendMetrics(metrics)
}

// Given a slice of Metrics, the SendMetrics method sends the metrics, as a
// batch, to the Graphite connection that the method is called upon
func (graphite *Graphite) SendMetrics(metrics []Metric) error {
	return graphite.sendMetrics(metrics)
}

// sendMetrics is an internal function that is used to write to the TCP
// connection in order to communicate metrics to the remote Graphite host
func (graphite *Graphite) sendMetrics(metrics []Metric) error {
	zeroed_metric := Metric{} // ignore unintialized metrics
	if !graphite.IsNop() {
		buf := bytes.NewBufferString("")
		for _, metric := range metrics {
			if metric == zeroed_metric {
				continue // ignore unintialized metrics
			}
			if metric.Timestamp == 0 {
				metric.Timestamp = time.Now().Unix()
			}
			metric_name := ""
			if graphite.Prefix != "" {
				metric_name = fmt.Sprintf("%s.%s", graphite.Prefix, metric.Name)
			} else {
				metric_name = metric.Name
			}
			buf.WriteString(fmt.Sprintf("%s %s %d\n", metric_name, metric.Value, metric.Timestamp))
		}
		_, err := graphite.conn.Write(buf.Bytes())
		//fmt.Print("Sent msg:", buf.String(), "'")
		if err != nil {
			return err
		}
	} else {
		for _, metric := range metrics {
			log.Printf("Graphite: %s\n", metric)
		}
	}
	return nil
}

// The SimpleSend method can be used to just pass a metric name and value and
// have it be sent to the Graphite host with the current timestamp
func (graphite *Graphite) SimpleSend(stat string, value string) error {
	metrics := make([]Metric, 1)
	metrics[0] = NewMetric(stat, value, time.Now().Unix())
	err := graphite.sendMetrics(metrics)
	if err != nil {
		return err
	}
	return nil
}

// NewGraphiteHost is a factory method that's used to create a new Graphite
// connection given a hostname and a port number
func NewGraphite(host string, port int) (*Graphite, error) {
	Graphite := &Graphite{Host: host, Port: port}
	err := Graphite.Connect()
	if err != nil {
		return nil, err
	}

	return Graphite, nil
}

// NewGraphiteNop is a factory method that returns a Graphite struct but will
// not actually try to send any packets to a remote host and, instead, will just
// log. This is useful if you want to use Graphite in a project but don't want
// to make Graphite a requirement for the project.
func NewGraphiteNop(host string, port int) *Graphite {
	graphiteNop := &Graphite{Host: host, Port: port, nop: true}
	return graphiteNop
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type grtCmd struct {
	method   string
	protocol string
	domain   string
	endpoint string
	getVars  map[string]string
	body     string
}

func NewGrtCmd() grtCmd {
	var cmd grtCmd

	cmd.method = "GET"
	cmd.protocol = "http"
	cmd.domain = "gerrit.dev.returnpath.net"
	cmd.endpoint = "/a/changes/"
	cmd.getVars = map[string]string{
		"q": "status:open",
	}
	cmd.body = ""

	return cmd
}

func (this grtCmd) Call() string {
	var client http.Client
	getQry := ""

	for k, v := range this.getVars {
		getQry += k + "=" + v + "&"
	}

	getQry = getQry[:len(getQry)-1]

	resp, err := client.Get(this.protocol + "://" + this.domain + this.endpoint + getQry)
	if err != nil {
		log.Fatal(err)
	}

	req, err := http.NewRequest("GET", "http://gerrit.dev.returnpath.net/a/changes/?q=status:open", nil)
	if err != nil {
		log.Fatal(err)
	}

	resp, err = client.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	user := GetConfigValue("gerrit.user")
	pass := GetConfigValue("gerrit.pass")

	auth := GetAuthorization(user, pass, resp)
	digest := GetAuthString(auth, req.URL, req.Method, 1)
	fmt.Println(digest)
	req.Header.Add("Authorization", digest)

	resp, err = client.Do(req)

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	return string(body)
}
<commit_msg>Bug fixes and authentication improvement made<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type grtCmd struct {
	digest   string
	method   string
	protocol string
	domain   string
	endpoint string
	getVars  map[string]string
	body     string
}

func NewGrtCmd() grtCmd {
	var cmd grtCmd

	cmd.method = "GET"
	cmd.protocol = "http"
	cmd.domain = "gerrit.dev.returnpath.net"
	cmd.endpoint = "/a/changes/"
	cmd.getVars = map[string]string{
		"q": "status:open",
	}
	cmd.body = ""

	resp, err := client.Get(this.protocol + "://" + this.domain + this.endpoint + getQry)
	if err != nil {
		log.Fatal(err)
	}

	req, err := http.NewRequest(cmd.method, cmd.protocol+"://"+cmd.domain+cmd.endpoint, nil)
	if err != nil {
		log.Fatal(err)
	}

	user := GetConfigValue("gerrit.user")
	pass := GetConfigValue("gerrit.pass")
	auth := GetAuthorization(user, pass, resp)
	cmd.digest = GetAuthString(auth, req.URL, req.Method, 1)

	return cmd
}

func (this grtCmd) Call() string {
	var client http.Client
	getQry := ""

	for k, v := range this.getVars {
		getQry += k + "=" + v + "&"
	}

	if len(getQry) > 0 {
		getQry = "?" + getQry[:len(getQry)-1]
	}

	resp, err := client.Get(this.protocol + "://" + this.domain + this.endpoint + getQry)
	if err != nil {
		log.Fatal(err)
	}

	req, err := http.NewRequest(this.method, this.protocol+"://"+this.domain+this.endpoint+getQry, nil)
	if err != nil {
		log.Fatal(err)
	}

	resp, err = client.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	req.Header.Add("Authorization", digest)

	resp, err = client.Do(req)

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	return string(body)
}
<|endoftext|>


<commit_before>package base

import (
	crand "crypto/rand"
	"errors"
	"log"
	"math/big"
	"math/rand"
	"net/http"
	"strconv"

	"github.com/zenazn/goji/web"
)

var (
	ErrorSessionNotFound error = errors.New("No session found matching that Id")
)

/*
Session represents a web session
*/
type Session struct {
	id     string
	dirty  bool
	Values map[string]interface{}
}

/*
Get the id for this session
*/
func (s *Session) Id() string {
	return s.id
}

func (s *Session) SetId(id string) {
	s.id = id
}

/*
Has anything been set in this Session since it was retrieved?
*/
func (s *Session) IsDirty() bool {
	return s.dirty
}

/*
Set whether this Session is dirty.  Normally this is done automatically
by Put
*/
func (s *Session) SetDirty(dirty bool) {
	s.dirty = dirty
}

/*
Retrieve a value from the Session
*/
func (s *Session) Get(key string) (interface{}, bool) {
	val, ok := s.Values[key]
	return val, ok
}

/*
Save a value in the Session
*/
func (s *Session) Put(key string, value interface{}) {
	s.Values[key] = value
	s.dirty = true
}

/*
Delete a value from the session
*/
func (s *Session) Del(key string) {
	delete(s.Values, key)
	s.dirty = true
}

/*
SessionHolder is an interface for a session repository.
*/
type SessionHolder interface {
	/*
	   Get the session associated with the current request, if there is one.
	*/
	Get(c web.C, r *http.Request) (*Session, error)

	/*
	   Create a new session

	   Note the implementation should create the session dirty so it will be saved
	   when the response is processed.  It should also add the session to c.Env["session"]
	   for easy access
	*/
	Create(c web.C) *Session

	/*
	   Destroy a session so that it can no longer be retrieved
	*/
	Destroy(c web.C, session *Session) error

	/*
	   Save a session
	*/
	Save(c web.C, session *Session) error

	/*
		AddToResponse writes the session cookie into the http response
	*/
	AddToResponse(c web.C, session *Session, w http.ResponseWriter)
}

/*
BaseSessionHolder is a building block you can use to build a SessionHolder implementation
*/
type BaseSessionHolder struct {
	Timeout    int
	RandSource rand.Source
}

func NewBaseSessionHolder(timeout int) BaseSessionHolder {
	seed, err := crand.Int(crand.Reader, big.NewInt(0x7FFFFFFFFFFFFFFF))
	if err != nil {
		log.Panicf("Could not get a random seed for session generation, %v", err)
	}

	return BaseSessionHolder{
		Timeout:    timeout,
		RandSource: rand.NewSource(seed.Int64()),
	}
}

/*
Create builds a session object, adds it to c.Env["session"] and marks it as dirty
*/
func (sh *BaseSessionHolder) Create(c web.C) *Session {
	session := &Session{
		id:     sh.generateSessionId(),
		Values: make(map[string]interface{}, 0),
		dirty:  true,
	}
	c.Env["session"] = session
	return session
}

/*
GetSessionId extracts the session ID from a request if one is present.

Note this is not part of the SessionHolder interface - it is intended to
be used as a building block by SessionHolder implementations
*/
func (sh *BaseSessionHolder) GetSessionId(r *http.Request) string {
	cookie, err := r.Cookie("sessionid")
	if err != nil {
		return ""
	}
	return cookie.Value
}

func (sh *BaseSessionHolder) generateSessionId() string {
	a := uint64(sh.RandSource.Int63())
	b := uint64(sh.RandSource.Int63())

	return strconv.FormatUint(a, 36) + strconv.FormatUint(b, 36)
}

/*
Add the Session to the response

Basically this means setting a cookie
*/
func (sh *BaseSessionHolder) AddToResponse(c web.C, session *Session, w http.ResponseWriter) {
	cookie := http.Cookie{
		Name:   "sessionid",
		Value:  session.Id(),
		Path:   "/",
		MaxAge: sh.Timeout,
	}
	http.SetCookie(w, &cookie)
}

/*
MemorySessionHolder is an in-memory session holder.  Only really useful for testing
*/
type MemorySessionHolder struct {
	BaseSessionHolder
	store map[string]*Session
}

func NewMemorySessionHolder(timeout int) SessionHolder {
	return &MemorySessionHolder{
		BaseSessionHolder: NewBaseSessionHolder(timeout),
		store:             make(map[string]*Session, 0),
	}
}

func (sh *MemorySessionHolder) Get(c web.C, r *http.Request) (*Session, error) {
	sessionId := sh.GetSessionId(r)
	session, ok := sh.store[sessionId]
	if !ok {
		return nil, ErrorSessionNotFound
	}
	return session, nil
}

func (sh *MemorySessionHolder) Destroy(c web.C, session *Session) error {
	delete(sh.store, session.Id())
	delete(c.Env, "session")
	return nil
}

/*
   Save a session
*/
func (sh *MemorySessionHolder) Save(c web.C, session *Session) error {
	sh.store[session.Id()] = session
	return nil
}

func SessionFromEnv(c *web.C) (*Session, bool) {
	s, ok := c.Env["session"]
	if ok && s != nil {
		return s.(*Session), true
	}
	return nil, false
}

/*
BuildSessionMiddleware builds middleware with the provided SessionHolder.  The middleware

 - adds the SessionHolder to c.Env["sessionholder"] so application code can create and delete sessions
 - finds the session associated with the request (if any) and puts it in c.Env["session"]
 - saves the session if dirty and the request is processed without a panic

Add the middleware as follows

  mux := web.New()
  mux.Use(redis.BuildRedis(":6379"))
  sh := redis.NewSessionHolder()
  mux.Use(redis.BuildSessionMiddleware(sh))
  // Add handlers that use sessions

The middleware does not create new sessions.  To create a session do the following.

  session := c.Env["session"].(*Session)
  if session != nil {
	  sh := c.Env["sessionholder"].(SessionHolder)
	  session := sh.Create()
  }
*/
func BuildSessionMiddleware(sh SessionHolder) func(c *web.C, h http.Handler) http.Handler {
	return func(c *web.C, h http.Handler) http.Handler {
		handler := func(w http.ResponseWriter, r *http.Request) {
			// Always store the session holder in context so that handlers can create or destroy sessions
			c.Env["sessionholder"] = sh

			session, err := sh.Get(*c, r)
			if err == nil {
				session.SetDirty(false)
				c.Env["session"] = session
			} else {
				if err != ErrorSessionNotFound {
					log.Printf("error loading session %v", err)
					http.Error(w, "Failed to load session data", http.StatusServiceUnavailable)
				}
			}
			h.ServeHTTP(w, r)

			// TODO: should this be saved via defer() so it even happens after a panic
			// TODO: retrieve from response?
			session, ok := SessionFromEnv(c)
			if ok && session.IsDirty() {
				err := sh.Save(*c, session)
				if err != nil {
					log.Printf("Failed to save session - %v", err)
				}
			}
		}
		return http.HandlerFunc(handler)
	}
}
<commit_msg>Fix comment typo<commit_after>package base

import (
	crand "crypto/rand"
	"errors"
	"log"
	"math/big"
	"math/rand"
	"net/http"
	"strconv"

	"github.com/zenazn/goji/web"
)

var (
	ErrorSessionNotFound error = errors.New("No session found matching that Id")
)

/*
Session represents a web session
*/
type Session struct {
	id     string
	dirty  bool
	Values map[string]interface{}
}

/*
Get the id for this session
*/
func (s *Session) Id() string {
	return s.id
}

func (s *Session) SetId(id string) {
	s.id = id
}

/*
Has anything been set in this Session since it was retrieved?
*/
func (s *Session) IsDirty() bool {
	return s.dirty
}

/*
Set whether this Session is dirty.  Normally this is done automatically
by Put
*/
func (s *Session) SetDirty(dirty bool) {
	s.dirty = dirty
}

/*
Retrieve a value from the Session
*/
func (s *Session) Get(key string) (interface{}, bool) {
	val, ok := s.Values[key]
	return val, ok
}

/*
Save a value in the Session
*/
func (s *Session) Put(key string, value interface{}) {
	s.Values[key] = value
	s.dirty = true
}

/*
Delete a value from the session
*/
func (s *Session) Del(key string) {
	delete(s.Values, key)
	s.dirty = true
}

/*
SessionHolder is an interface for a session repository.
*/
type SessionHolder interface {
	/*
	   Get the session associated with the current request, if there is one.
	*/
	Get(c web.C, r *http.Request) (*Session, error)

	/*
	   Create a new session

	   Note the implementation should create the session dirty so it will be saved
	   when the response is processed.  It should also add the session to c.Env["session"]
	   for easy access
	*/
	Create(c web.C) *Session

	/*
	   Destroy a session so that it can no longer be retrieved
	*/
	Destroy(c web.C, session *Session) error

	/*
	   Save a session
	*/
	Save(c web.C, session *Session) error

	/*
		AddToResponse writes the session cookie into the http response
	*/
	AddToResponse(c web.C, session *Session, w http.ResponseWriter)
}

/*
BaseSessionHolder is a building block you can use to build a SessionHolder implementation
*/
type BaseSessionHolder struct {
	Timeout    int
	RandSource rand.Source
}

func NewBaseSessionHolder(timeout int) BaseSessionHolder {
	seed, err := crand.Int(crand.Reader, big.NewInt(0x7FFFFFFFFFFFFFFF))
	if err != nil {
		log.Panicf("Could not get a random seed for session generation, %v", err)
	}

	return BaseSessionHolder{
		Timeout:    timeout,
		RandSource: rand.NewSource(seed.Int64()),
	}
}

/*
Create builds a session object, adds it to c.Env["session"] and marks it as dirty
*/
func (sh *BaseSessionHolder) Create(c web.C) *Session {
	session := &Session{
		id:     sh.generateSessionId(),
		Values: make(map[string]interface{}, 0),
		dirty:  true,
	}
	c.Env["session"] = session
	return session
}

/*
GetSessionId extracts the session ID from a request if one is present.

Note this is not part of the SessionHolder interface - it is intended to
be used as a building block by SessionHolder implementations
*/
func (sh *BaseSessionHolder) GetSessionId(r *http.Request) string {
	cookie, err := r.Cookie("sessionid")
	if err != nil {
		return ""
	}
	return cookie.Value
}

func (sh *BaseSessionHolder) generateSessionId() string {
	a := uint64(sh.RandSource.Int63())
	b := uint64(sh.RandSource.Int63())

	return strconv.FormatUint(a, 36) + strconv.FormatUint(b, 36)
}

/*
Add the Session to the response

Basically this means setting a cookie
*/
func (sh *BaseSessionHolder) AddToResponse(c web.C, session *Session, w http.ResponseWriter) {
	cookie := http.Cookie{
		Name:   "sessionid",
		Value:  session.Id(),
		Path:   "/",
		MaxAge: sh.Timeout,
	}
	http.SetCookie(w, &cookie)
}

/*
MemorySessionHolder is an in-memory session holder.  Only really useful for testing
*/
type MemorySessionHolder struct {
	BaseSessionHolder
	store map[string]*Session
}

func NewMemorySessionHolder(timeout int) SessionHolder {
	return &MemorySessionHolder{
		BaseSessionHolder: NewBaseSessionHolder(timeout),
		store:             make(map[string]*Session, 0),
	}
}

func (sh *MemorySessionHolder) Get(c web.C, r *http.Request) (*Session, error) {
	sessionId := sh.GetSessionId(r)
	session, ok := sh.store[sessionId]
	if !ok {
		return nil, ErrorSessionNotFound
	}
	return session, nil
}

func (sh *MemorySessionHolder) Destroy(c web.C, session *Session) error {
	delete(sh.store, session.Id())
	delete(c.Env, "session")
	return nil
}

/*
   Save a session
*/
func (sh *MemorySessionHolder) Save(c web.C, session *Session) error {
	sh.store[session.Id()] = session
	return nil
}

func SessionFromEnv(c *web.C) (*Session, bool) {
	s, ok := c.Env["session"]
	if ok && s != nil {
		return s.(*Session), true
	}
	return nil, false
}

/*
BuildSessionMiddleware builds middleware with the provided SessionHolder.  The middleware

 - adds the SessionHolder to c.Env["sessionholder"] so application code can create and delete sessions
 - finds the session associated with the request (if any) and puts it in c.Env["session"]
 - saves the session if dirty and the request is processed without a panic

Add the middleware as follows

  mux := web.New()
  mux.Use(redis.BuildRedis(":6379"))
  sh := redis.NewSessionHolder()
  mux.Use(redis.BuildSessionMiddleware(sh))
  // Add handlers that use sessions

The middleware does not create new sessions.  To create a session do the following.

  session := c.Env["session"].(*Session)
  if session == nil {
	  sh := c.Env["sessionholder"].(SessionHolder)
	  session = sh.Create()
  }
*/
func BuildSessionMiddleware(sh SessionHolder) func(c *web.C, h http.Handler) http.Handler {
	return func(c *web.C, h http.Handler) http.Handler {
		handler := func(w http.ResponseWriter, r *http.Request) {
			// Always store the session holder in context so that handlers can create or destroy sessions
			c.Env["sessionholder"] = sh

			session, err := sh.Get(*c, r)
			if err == nil {
				session.SetDirty(false)
				c.Env["session"] = session
			} else {
				if err != ErrorSessionNotFound {
					log.Printf("error loading session %v", err)
					http.Error(w, "Failed to load session data", http.StatusServiceUnavailable)
				}
			}
			h.ServeHTTP(w, r)

			// TODO: should this be saved via defer() so it even happens after a panic
			// TODO: retrieve from response?
			session, ok := SessionFromEnv(c)
			if ok && session.IsDirty() {
				err := sh.Save(*c, session)
				if err != nil {
					log.Printf("Failed to save session - %v", err)
				}
			}
		}
		return http.HandlerFunc(handler)
	}
}
<|endoftext|>


<commit_before>package bbs_test

import (
	"github.com/cloudfoundry-incubator/runtime-schema/bbs"

	. "github.com/onsi/ginkgo"
)

var _ = Describe("BBS", func() {
	It("should compile and be able to construct and return each BBS", func() {
		receptorTaskHandlerURL := "http://example.com"
		bbs.NewBBS(etcdClient, consulAdapter, receptorTaskHandlerURL, clock, logger)
		bbs.NewRepBBS(etcdClient, consulAdapter, receptorTaskHandlerURL, clock, logger)
		bbs.NewConvergerBBS(etcdClient, consulAdapter, receptorTaskHandlerURL, clock, logger)
		bbs.NewNsyncBBS(consulAdapter, clock, logger)
		bbs.NewAuctioneerBBS(etcdClient, consulAdapter, receptorTaskHandlerURL, clock, logger)
		bbs.NewMetricsBBS(etcdClient, consulAdapter, clock, logger)
		bbs.NewRouteEmitterBBS(consulAdapter, clock, logger)
		bbs.NewTpsBBS(consulAdapter, clock, logger)
		bbs.NewVeritasBBS(etcdClient, clock, logger)
	})
})
<commit_msg>BBS tests must pass<commit_after>package bbs_test

import (
	"github.com/cloudfoundry-incubator/runtime-schema/bbs"

	. "github.com/onsi/ginkgo"
)

var _ = Describe("BBS", func() {
	It("should compile and be able to construct and return each BBS", func() {
		receptorTaskHandlerURL := "http://example.com"
		bbs.NewBBS(etcdClient, consulAdapter, receptorTaskHandlerURL, clock, logger)
		bbs.NewRepBBS(etcdClient, consulAdapter, receptorTaskHandlerURL, clock, logger)
		bbs.NewConvergerBBS(etcdClient, consulAdapter, receptorTaskHandlerURL, clock, logger)
		bbs.NewNsyncBBS(consulAdapter, clock, logger)
		bbs.NewAuctioneerBBS(etcdClient, consulAdapter, receptorTaskHandlerURL, clock, logger)
		bbs.NewMetricsBBS(etcdClient, consulAdapter, clock, logger)
		bbs.NewRouteEmitterBBS(consulAdapter, clock, logger)
		bbs.NewTpsBBS(consulAdapter, clock, logger)
		bbs.NewVeritasBBS(etcdClient, consulAdapter, clock, logger)
	})
})
<|endoftext|>


<commit_before>package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/", func(c *gin.Context) {
        c.String(200, "200")
    })
    r.GET("/ping", func(c *gin.Context) {
        c.String(200, "pong")
    })

    // Listen and server on 0.0.0.0:8080
    r.Run(":8080")
}
<commit_msg>change port<commit_after>package main

import "os"
import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/", func(c *gin.Context) {
        c.String(200, "200")
    })
    r.GET("/ping", func(c *gin.Context) {
        c.String(200, "pong")
    })

    // Listen and server on 0.0.0.0:8080
    r.Run(":"+os.Getenv("PORT"))
}
<|endoftext|>


<commit_before>package eqemuconfig

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"time"
)

type Config struct {
	World     World     `xml:"world,omitempty"`
	Database  Database  `xml:"database,omitempty"`
	QuestsDir string    `xml:"directories>quests,omitempty"`
	Discord   Discord   `xml:"discord,omitempty"`
	Twitter   []Twitter `xml:"twitter,omitempty"`
	Github    Github    `xml:"github,omitempty"`
}

type World struct {
	Shortname string `xml:"shortname"`
	Longname  string `xml:"longname"`
	Tcp       Tcp    `xml:"tcp,omitempty"`
	Telnet    Telnet `xml:"telnet,omitempty"`
}

//This was used by configs prior to 4/16 patch
type Tcp struct {
	Ip     string `xml:"ip,attr"`
	Port   string `xml:"port,attr"`
	Telnet string `xml:"telnet,attr"`
}

//This is used by configs after 4/16 patch
type Telnet struct {
	Ip      string `xml:"ip,attr"`
	Port    string `xml:"port,attr"`
	Enabled string `xml:"enabled,attr"`
}

type Database struct {
	Host     string `xml:"host"`
	Port     string `xml:"port"`
	Username string `xml:"username"`
	Password string `xml:"password"`
	Db       string `xml:"db"`
}

type Discord struct {
	Username       string        `xml:"username,omitempty"`
	Password       string        `xml:"password,omitempty"`
	ServerID       string        `xml:"serverid,omitempty"`
	ChannelID      string        `xml:"channelid,omitempty"`
	RefreshRate    time.Duration `xml:"refreshrate,omitempty"`
	ItemUrl        string        `xml:"itemurl,omitempty"`
	Channels       []Channel     `xml:"channel"`
	Admins         []Admin       `xml:"admin"`
	TelnetUsername string        `xml:"telnetusername,omitempty"`
	TelnetPassword string        `xml:"telnetpassword,omitempty"`
}

type Channel struct {
	ChannelID   string `xml:"channelid,attr"`
	ChannelName string `xml:"channelname,attr"`
}

type Admin struct {
	Name string `xml:"name,attr"`
	Id   string `xml:"id,attr"`
}

type Twitter struct {
	Owner             string `xml:"owner,attr,omitempty"`
	ConsumerKey       string `xml:"consumerkey,attr,omitempty"`
	ConsumerSecret    string `xml:"consumersecret,attr,omitempty"`
	AccessToken       string `xml:"accesstoken,attr,omitempty"`
	AccessTokenSecret string `xml:"accesstokensecret,attr,omitempty"`
}

type Github struct {
	PersonalAccessToken string `xml:"personalaccesstoken,attr,omitempty"`
	RepoUser            string `xml:"repouser,attr,omitempty"`
	RepoName            string `xml:"reponame,attr,omitempty"`
	RefreshRate         int64  `xml:"refreshrate,attr,omitempty"`
	IssueLabel          string `xml:"issuelabel,attr,omitempty"`
	ItemLabel           string `xml:"itemlabel,attr,omitempty"`
	NPCLabel            string `xml:"npclabel,attr,omitempty"`
	CharacterLabel      string `xml:"characterlabel,attr,omitempty"`
}

type Graph struct {
	TablePrefix string `xml:"tableprefix,attr,omitempty"`
}

var config *Config

func GetConfig() (respConfig *Config, err error) {
	if config != nil {
		respConfig = config
		return
	}

	f, err := os.Open("eqemu_config.xml")
	if err != nil {
		//try to load via env variable
		if err.Error() == "no such file or directory" {
			err = fmt.Errorf("Error opening config: %s", err.Error())
			return
		}

		path := os.Getenv("EQEMU_CONFIG")
		if f, err = os.Open(path); err != nil {
			err = fmt.Errorf("Error opening config: %s", err.Error())
			return
		}
	}
	config = &Config{}
	dec := xml.NewDecoder(f)
	err = dec.Decode(config)
	if err != nil {
		if !strings.Contains(err.Error(), "EOF") {
			err = fmt.Errorf("Error decoding config: %s", err.Error())
			return
		}

		//This may be a ?> issue, let's fix it.
		bConfig, rErr := ioutil.ReadFile("eqemu_config.xml")
		if rErr != nil {
			err = fmt.Errorf("Error reading config: %s", rErr.Error())
			return
		}
		strConfig := strings.Replace(string(bConfig), "<?xml version=\"1.0\">", "<?xml version=\"1.0\"?>", 1)
		err = xml.Unmarshal([]byte(strConfig), config)
		if err != nil {
			err = fmt.Errorf("Failed to unmarshal config: %s", err.Error())
			return
		}
	}
	err = f.Close()
	if err != nil {
		err = fmt.Errorf("Failed to close config: %s", err.Error())
		return
	}
	if config.QuestsDir == "" {
		config.QuestsDir = "quests"
	}
	respConfig = config
	return
}
<commit_msg>Added json support<commit_after>package eqemuconfig

import (
	"encoding/json"
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"time"
)

type Config struct {
	World     World     `json:"world,omitempty" xml:"world,omitempty"`
	Database  Database  `json:"database,omitempty" xml:"database,omitempty"`
	QuestsDir string    `json:"directories>quests,omitempty" xml:"directories>quests,omitempty"`
	Discord   Discord   `json:"discord,omitempty" xml:"discord,omitempty"`
	Twitter   []Twitter `json:"twitter,omitempty" xml:"twitter,omitempty"`
	Github    Github    `json:"github,omitempty" xml:"github,omitempty"`
}

type World struct {
	Shortname string `json:"shortname" xml:"shortname"`
	Longname  string `json:"longname" xml:"longname"`
	Tcp       Tcp    `json:"tcp,omitempty" xml:"tcp,omitempty"`
	Telnet    Telnet `json:"telnet,omitempty" xml:"telnet,omitempty"`
}

//This was used by configs prior to 4/16 patch
type Tcp struct {
	Ip     string `json:"ip,attr" xml:"ip,attr"`
	Port   string `json:"port,attr" xml:"port,attr"`
	Telnet string `json:"telnet,attr" xml:"telnet,attr"`
}

//This is used by configs after 4/16 patch
type Telnet struct {
	Ip      string `json:"ip,attr" xml:"ip,attr"`
	Port    string `json:"port,attr" xml:"port,attr"`
	Enabled string `json:"enabled,attr" xml:"enabled,attr"`
}

type Database struct {
	Host     string `json:"host" xml:"host"`
	Port     string `json:"port" xml:"port"`
	Username string `json:"username" xml:"username"`
	Password string `json:"password" xml:"password"`
	Db       string `json:"db" xml:"db"`
}

type Discord struct {
	Username       string        `json:"username,omitempty" xml:"username,omitempty"`
	Password       string        `json:"password,omitempty" xml:"password,omitempty"`
	ServerID       string        `json:"serverid,omitempty" xml:"serverid,omitempty"`
	ChannelID      string        `json:"channelid,omitempty" xml:"channelid,omitempty"`
	RefreshRate    time.Duration `json:"refreshrate,omitempty" xml:"refreshrate,omitempty"`
	ItemUrl        string        `json:"itemurl,omitempty" xml:"itemurl,omitempty"`
	Channels       []Channel     `json:"channel" xml:"channel"`
	Admins         []Admin       `json:"admin" xml:"admin"`
	TelnetUsername string        `json:"telnetusername,omitempty" xml:"telnetusername,omitempty"`
	TelnetPassword string        `json:"telnetpassword,omitempty" xml:"telnetpassword,omitempty"`
}

type Channel struct {
	ChannelID   string `json:"channelid,attr" xml:"channelid,attr"`
	ChannelName string `json:"channelname,attr" xml:"channelname,attr"`
}

type Admin struct {
	Name string `json:"name,attr" xml:"name,attr"`
	Id   string `json:"id,attr" xml:"id,attr"`
}

type Twitter struct {
	Owner             string `json:"owner,attr,omitempty" xml:"owner,attr,omitempty"`
	ConsumerKey       string `json:"consumerkey,attr,omitempty" xml:"consumerkey,attr,omitempty"`
	ConsumerSecret    string `json:"consumersecret,attr,omitempty" xml:"consumersecret,attr,omitempty"`
	AccessToken       string `json:"accesstoken,attr,omitempty" xml:"accesstoken,attr,omitempty"`
	AccessTokenSecret string `json:"accesstokensecret,attr,omitempty" xml:"accesstokensecret,attr,omitempty"`
}

type Github struct {
	PersonalAccessToken string `json:"personalaccesstoken,attr,omitempty" xml:"personalaccesstoken,attr,omitempty"`
	RepoUser            string `json:"repouser,attr,omitempty" xml:"repouser,attr,omitempty"`
	RepoName            string `json:"reponame,attr,omitempty" xml:"reponame,attr,omitempty"`
	RefreshRate         int64  `json:"refreshrate,attr,omitempty" xml:"refreshrate,attr,omitempty"`
	IssueLabel          string `json:"issuelabel,attr,omitempty" xml:"issuelabel,attr,omitempty"`
	ItemLabel           string `json:"itemlabel,attr,omitempty" xml:"itemlabel,attr,omitempty"`
	NPCLabel            string `json:"npclabel,attr,omitempty" xml:"npclabel,attr,omitempty"`
	CharacterLabel      string `json:"characterlabel,attr,omitempty" xml:"characterlabel,attr,omitempty"`
}

type Graph struct {
	TablePrefix string `json:"tableprefix,attr,omitempty" xml:"tableprefix,attr,omitempty"`
}

var config *Config

func GetConfig() (respConfig *Config, err error) {
	if config != nil {
		respConfig = config
		return
	}

	respConfig, err = loadJson()
	if err != nil {
		respConfig, err = loadXML()
		if err != nil {
			return
		}
	}
	return
}

func loadJson() (respConfig *Config, err error) {
	f, err := os.Open("eqemu_config.json")
	if err != nil {
		//try to load via env variable
		if err.Error() == "no such file or directory" {
			err = fmt.Errorf("Error opening config: %s", err.Error())
			return
		}

		path := os.Getenv("EQEMU_CONFIG")
		if f, err = os.Open(path); err != nil {
			err = fmt.Errorf("Error opening config: %s", err.Error())
			return
		}
	}
	config = &Config{}
	dec := json.NewDecoder(f)
	err = dec.Decode(config)
	if err != nil {
		if !strings.Contains(err.Error(), "EOF") {
			err = fmt.Errorf("Error decoding config: %s", err.Error())
			return
		}

		//This may be a ?> issue, let's fix it.
		bConfig, rErr := ioutil.ReadFile("eqemu_config.json")
		if rErr != nil {
			err = fmt.Errorf("Error reading config: %s", rErr.Error())
			return
		}
		err = json.Unmarshal(bConfig, config)
		if err != nil {
			err = fmt.Errorf("Failed to unmarshal config: %s", err.Error())
			return
		}
	}
	err = f.Close()
	if err != nil {
		err = fmt.Errorf("Failed to close config: %s", err.Error())
		return
	}
	if config.QuestsDir == "" {
		config.QuestsDir = "quests"
	}
	respConfig = config
	return
}

func loadXML() (respConfig *Config, err error) {
	f, err := os.Open("eqemu_config.xml")
	if err != nil {
		//try to load via env variable
		if err.Error() == "no such file or directory" {
			err = fmt.Errorf("Error opening config: %s", err.Error())
			return
		}

		path := os.Getenv("EQEMU_CONFIG")
		if f, err = os.Open(path); err != nil {
			err = fmt.Errorf("Error opening config: %s", err.Error())
			return
		}
	}
	config = &Config{}
	dec := xml.NewDecoder(f)
	err = dec.Decode(config)
	if err != nil {
		if !strings.Contains(err.Error(), "EOF") {
			err = fmt.Errorf("Error decoding config: %s", err.Error())
			return
		}

		//This may be a ?> issue, let's fix it.
		bConfig, rErr := ioutil.ReadFile("eqemu_config.xml")
		if rErr != nil {
			err = fmt.Errorf("Error reading config: %s", rErr.Error())
			return
		}
		strConfig := strings.Replace(string(bConfig), "<?xml version=\"1.0\">", "<?xml version=\"1.0\"?>", 1)
		err = xml.Unmarshal([]byte(strConfig), config)
		if err != nil {
			err = fmt.Errorf("Failed to unmarshal config: %s", err.Error())
			return
		}
	}
	err = f.Close()
	if err != nil {
		err = fmt.Errorf("Failed to close config: %s", err.Error())
		return
	}
	if config.QuestsDir == "" {
		config.QuestsDir = "quests"
	}
	respConfig = config
	return
}
<|endoftext|>


<commit_before>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 fs_test

import (
	. "github.com/jacobsa/ogletest"
	"testing"
)

func TestFileSystemTest(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

type FileSystemTest struct {
}

func init() { RegisterTestSuite(&FileSystemTest{}) }

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *FileSystemTest) DoesFoo() {
	ExpectEq("TODO", "")
}
<commit_msg>Expanded test stub.<commit_after>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 fs_test

import (
	. "github.com/jacobsa/ogletest"
	"testing"
)

func TestFileSystemTest(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// ReadDir
////////////////////////////////////////////////////////////////////////

type ReadDirTest struct {
}

func init() { RegisterTestSuite(&ReadDirTest{}) }

func (t *ReadDirTest) DoesFoo() {
	ExpectEq("TODO", "")
}

////////////////////////////////////////////////////////////////////////
// OpenForReading
////////////////////////////////////////////////////////////////////////

type OpenForReadingTest struct {
}

func init() { RegisterTestSuite(&OpenForReadingTest{}) }

func (t *OpenForReadingTest) DoesFoo() {
	ExpectEq("TODO", "")
}
<|endoftext|>


<commit_before>package readers

import (
	"encoding/json"
	"github.com/cloudfoundry/gosigar"
)

func init() {
	Register("Free", NewFree)
}

func NewFree() IReader {
	m := &Free{}
	m.Data = make(map[string]map[string]interface{})
	return m
}

// Free is a reader that scrapes swapory data and presents it in the form similar to `free`.
// Data source: https://github.com/cloudfoundry/gosigar/tree/master
type Free struct {
	Data map[string]map[string]interface{}
}

// Run gathers free data from gosigar.
func (m *Free) Run() error {
	mem := sigar.Mem{}
	err := mem.Get()
	if err != nil {
		return err
	}

	swap := sigar.Swap{}
	err = swap.Get()
	if err != nil {
		return err
	}

	m.Data["Memory"] = make(map[string]interface{})
	m.Data["Swap"] = make(map[string]interface{})

	m.Data["Memory"]["Total"] = mem.Total
	m.Data["Memory"]["TotalMB"] = mem.Total / 1000 / 1000
	m.Data["Memory"]["TotalGB"] = mem.Total / 1000 / 1000 / 1000

	m.Data["Memory"]["Used"] = mem.Used
	m.Data["Memory"]["UsedMB"] = mem.Used / 1000 / 1000
	m.Data["Memory"]["UsedGB"] = mem.Used / 1000 / 1000 / 1000

	m.Data["Memory"]["UsedPercent"] = int(float64(mem.Used) / float64(mem.Total) * 100)

	m.Data["Memory"]["Free"] = mem.Free
	m.Data["Memory"]["FreeMB"] = mem.Free / 1000 / 1000
	m.Data["Memory"]["FreeGB"] = mem.Free / 1000 / 1000 / 1000

	m.Data["Memory"]["FreePercent"] = int(float64(mem.Free) / float64(mem.Total) * 100)

	m.Data["Memory"]["ActualUsed"] = mem.ActualUsed
	m.Data["Memory"]["ActualUsedMB"] = mem.ActualUsed / 1000 / 1000
	m.Data["Memory"]["ActualUsedGB"] = mem.ActualUsed / 1000 / 1000 / 1000

	m.Data["Memory"]["ActualUsedPercent"] = int(float64(mem.ActualUsed) / float64(mem.Total) * 100)

	m.Data["Memory"]["ActualFree"] = mem.ActualFree
	m.Data["Memory"]["ActualFreeMB"] = mem.ActualFree / 1000 / 1000
	m.Data["Memory"]["ActualFreeGB"] = mem.ActualFree / 1000 / 1000 / 1000

	m.Data["Memory"]["ActualFreePercent"] = int(float64(mem.ActualFree) / float64(mem.Total) * 100)

	m.Data["Swap"]["Total"] = swap.Total
	m.Data["Memory"]["TotalMB"] = swap.Total / 1000 / 1000
	m.Data["Memory"]["TotalGB"] = swap.Total / 1000 / 1000 / 1000

	m.Data["Swap"]["Used"] = swap.Used
	m.Data["Memory"]["UsedMB"] = swap.Used / 1000 / 1000
	m.Data["Memory"]["UsedGB"] = swap.Used / 1000 / 1000 / 1000

	m.Data["Swap"]["Free"] = swap.Free
	m.Data["Swap"]["FreeMB"] = swap.Free / 1000 / 1000
	m.Data["Swap"]["FreeGB"] = swap.Free / 1000 / 1000 / 1000

	m.Data["Memory"]["SwapFreePercent"] = int(float64(swap.Free) / float64(swap.Total) * 100)

	return nil
}

// ToJson serialize Data field to JSON.
func (m *Free) ToJson() ([]byte, error) {
	return json.Marshal(m.Data)
}
<commit_msg>Fix labeling bugs in free.go<commit_after>package readers

import (
	"encoding/json"
	"github.com/cloudfoundry/gosigar"
)

func init() {
	Register("Free", NewFree)
}

func NewFree() IReader {
	m := &Free{}
	m.Data = make(map[string]map[string]interface{})
	return m
}

// Free is a reader that scrapes swapory data and presents it in the form similar to `free`.
// Data source: https://github.com/cloudfoundry/gosigar/tree/master
type Free struct {
	Data map[string]map[string]interface{}
}

// Run gathers free data from gosigar.
func (m *Free) Run() error {
	mem := sigar.Mem{}
	err := mem.Get()
	if err != nil {
		return err
	}

	swap := sigar.Swap{}
	err = swap.Get()
	if err != nil {
		return err
	}

	m.Data["Memory"] = make(map[string]interface{})
	m.Data["Swap"] = make(map[string]interface{})

	m.Data["Memory"]["Total"] = mem.Total
	m.Data["Memory"]["TotalMB"] = mem.Total / 1000 / 1000
	m.Data["Memory"]["TotalGB"] = mem.Total / 1000 / 1000 / 1000

	m.Data["Memory"]["Used"] = mem.Used
	m.Data["Memory"]["UsedMB"] = mem.Used / 1000 / 1000
	m.Data["Memory"]["UsedGB"] = mem.Used / 1000 / 1000 / 1000

	m.Data["Memory"]["UsedPercent"] = int(float64(mem.Used) / float64(mem.Total) * 100)

	m.Data["Memory"]["Free"] = mem.Free
	m.Data["Memory"]["FreeMB"] = mem.Free / 1000 / 1000
	m.Data["Memory"]["FreeGB"] = mem.Free / 1000 / 1000 / 1000

	m.Data["Memory"]["FreePercent"] = int(float64(mem.Free) / float64(mem.Total) * 100)

	m.Data["Memory"]["ActualUsed"] = mem.ActualUsed
	m.Data["Memory"]["ActualUsedMB"] = mem.ActualUsed / 1000 / 1000
	m.Data["Memory"]["ActualUsedGB"] = mem.ActualUsed / 1000 / 1000 / 1000

	m.Data["Memory"]["ActualUsedPercent"] = int(float64(mem.ActualUsed) / float64(mem.Total) * 100)

	m.Data["Memory"]["ActualFree"] = mem.ActualFree
	m.Data["Memory"]["ActualFreeMB"] = mem.ActualFree / 1000 / 1000
	m.Data["Memory"]["ActualFreeGB"] = mem.ActualFree / 1000 / 1000 / 1000

	m.Data["Memory"]["ActualFreePercent"] = int(float64(mem.ActualFree) / float64(mem.Total) * 100)

	m.Data["Swap"]["Total"] = swap.Total
	m.Data["Swap"]["TotalMB"] = swap.Total / 1000 / 1000
	m.Data["Swap"]["TotalGB"] = swap.Total / 1000 / 1000 / 1000

	m.Data["Swap"]["Used"] = swap.Used
	m.Data["Swap"]["UsedMB"] = swap.Used / 1000 / 1000
	m.Data["Swap"]["UsedGB"] = swap.Used / 1000 / 1000 / 1000

	m.Data["Swap"]["Free"] = swap.Free
	m.Data["Swap"]["FreeMB"] = swap.Free / 1000 / 1000
	m.Data["Swap"]["FreeGB"] = swap.Free / 1000 / 1000 / 1000

	m.Data["Swap"]["FreePercent"] = int(float64(swap.Free) / float64(swap.Total) * 100)

	return nil
}

// ToJson serialize Data field to JSON.
func (m *Free) ToJson() ([]byte, error) {
	return json.Marshal(m.Data)
}
<|endoftext|>


<commit_before>/*
Copyright 2020 The Jetstack cert-manager contributors.

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 framework

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
	"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
	apiextensionsinstall "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install"
	v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	jsonserializer "k8s.io/apimachinery/pkg/runtime/serializer/json"
	"k8s.io/apimachinery/pkg/runtime/serializer/versioning"
	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
	"k8s.io/client-go/rest"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/envtest"

	webhooktesting "github.com/jetstack/cert-manager/cmd/webhook/app/testing"
	"github.com/jetstack/cert-manager/pkg/api"
	apitesting "github.com/jetstack/cert-manager/pkg/api/testing"
)

func init() {
	// Set environment variables for controller-runtime's envtest package.
	// This is done once as we cannot scope environment variables to a single
	// invocation of RunControlPlane due to envtest's design.
	setUpEnvTestEnv()
}

type StopFunc func()

func RunControlPlane(t *testing.T) (*rest.Config, StopFunc) {
	webhookOpts, stopWebhook := webhooktesting.StartWebhookServer(t, []string{})
	crdsDir := apitesting.CRDDirectory(t)
	crds := readCustomResourcesAtPath(t, crdsDir)
	for _, crd := range crds {
		t.Logf("Found CRD with name %q", crd.Name)
	}
	patchCRDConversion(crds, webhookOpts.URL, webhookOpts.CAPEM)

	env := &envtest.Environment{
		AttachControlPlaneOutput: false,
		CRDs:                     crdsToRuntimeObjects(crds),
	}

	config, err := env.Start()
	if err != nil {
		t.Fatalf("failed to start control plane: %v", err)
	}

	cl, err := client.New(config, client.Options{Scheme: api.Scheme})
	if err != nil {
		t.Fatal(err)
	}

	// installing the validating webhooks, not using WebhookInstallOptions as it patches the CA to be it's own
	err = cl.Create(context.Background(), getValidatingWebhookConfig(webhookOpts.URL, webhookOpts.CAPEM))
	if err != nil {
		t.Fatal(err)
	}

	// installing the mutating webhooks, not using WebhookInstallOptions as it patches the CA to be it's own
	err = cl.Create(context.Background(), getMutatingWebhookConfig(webhookOpts.URL, webhookOpts.CAPEM))
	if err != nil {
		t.Fatal(err)
	}

	return config, func() {
		defer stopWebhook()
		if err := env.Stop(); err != nil {
			t.Logf("failed to shut down control plane, not failing test: %v", err)
		}
	}
}

var (
	internalScheme = runtime.NewScheme()
)

func init() {
	utilruntime.Must(metav1.AddMetaToScheme(internalScheme))
	apiextensionsinstall.Install(internalScheme)
}

func patchCRDConversion(crds []*v1.CustomResourceDefinition, url string, caPEM []byte) {
	for _, crd := range crds {
		if crd.Spec.Conversion == nil {
			continue
		}
		if crd.Spec.Conversion.Webhook == nil {
			continue
		}
		if crd.Spec.Conversion.Webhook.ClientConfig == nil {
			continue
		}
		if crd.Spec.Conversion.Webhook.ClientConfig.Service == nil {
			continue
		}
		path := ""
		if crd.Spec.Conversion.Webhook.ClientConfig.Service.Path != nil {
			path = *crd.Spec.Conversion.Webhook.ClientConfig.Service.Path
		}
		url := fmt.Sprintf("%s%s", url, path)
		crd.Spec.Conversion.Webhook.ClientConfig.URL = &url
		crd.Spec.Conversion.Webhook.ClientConfig.CABundle = caPEM
		crd.Spec.Conversion.Webhook.ClientConfig.Service = nil
	}
}

func readCustomResourcesAtPath(t *testing.T, path string) []*v1.CustomResourceDefinition {
	serializer := jsonserializer.NewSerializerWithOptions(jsonserializer.DefaultMetaFactory, internalScheme, internalScheme, jsonserializer.SerializerOptions{
		Yaml: true,
	})
	converter := runtime.UnsafeObjectConvertor(internalScheme)
	codec := versioning.NewCodec(serializer, serializer, converter, internalScheme, internalScheme, internalScheme, runtime.InternalGroupVersioner, runtime.InternalGroupVersioner, internalScheme.Name())

	var crds []*v1.CustomResourceDefinition
	if err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if filepath.Ext(path) != ".yaml" {
			return nil
		}
		crd, err := readCRDsAtPath(codec, converter, path)
		if err != nil {
			return err
		}
		crds = append(crds, crd...)
		return nil
	}); err != nil {
		t.Fatal(err)
	}
	return crds
}

func readCRDsAtPath(codec runtime.Codec, converter runtime.ObjectConvertor, path string) ([]*v1.CustomResourceDefinition, error) {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	dataStr := string(data)
	datas := strings.Split(dataStr, "\n---\n")
	var crds []*v1.CustomResourceDefinition
	for _, d := range datas {
		// skip empty YAML documents
		if strings.TrimSpace(d) == "" {
			continue
		}

		internalCRD := &apiextensions.CustomResourceDefinition{}
		if _, _, err := codec.Decode([]byte(d), nil, internalCRD); err != nil {
			return nil, err
		}

		out := &v1.CustomResourceDefinition{}
		if err := converter.Convert(internalCRD, out, nil); err != nil {
			return nil, err
		}

		crds = append(crds, out)
	}

	return crds, nil
}

func crdsToRuntimeObjects(in []*v1.CustomResourceDefinition) []runtime.Object {
	out := make([]runtime.Object, len(in))

	for i, crd := range in {
		out[i] = runtime.Object(crd)
	}

	return out
}

func getValidatingWebhookConfig(url string, caPEM []byte) runtime.Object {
	failurePolicy := admissionregistrationv1beta1.Fail
	sideEffects := admissionregistrationv1beta1.SideEffectClassNone
	validateURL := fmt.Sprintf("%s/validate", url)
	webhook := admissionregistrationv1beta1.ValidatingWebhookConfiguration{
		ObjectMeta: metav1.ObjectMeta{
			Name: "cert-manager-webhook",
		},
		Webhooks: []admissionregistrationv1beta1.ValidatingWebhook{
			{
				Name: "webhook.cert-manager.io",
				ClientConfig: admissionregistrationv1beta1.WebhookClientConfig{
					URL:      &validateURL,
					CABundle: caPEM,
				},
				Rules: []admissionregistrationv1beta1.RuleWithOperations{
					{
						Operations: []admissionregistrationv1beta1.OperationType{
							admissionregistrationv1beta1.Create,
							admissionregistrationv1beta1.Update,
						},
						Rule: admissionregistrationv1beta1.Rule{
							APIGroups:   []string{"cert-manager.io", "acme.cert-manager.io"},
							APIVersions: []string{"*"},
							Resources:   []string{"*/*"},
						},
					},
				},
				FailurePolicy: &failurePolicy,
				SideEffects:   &sideEffects,
			},
		},
	}

	return &webhook
}

func getMutatingWebhookConfig(url string, caPEM []byte) runtime.Object {
	failurePolicy := admissionregistrationv1beta1.Fail
	sideEffects := admissionregistrationv1beta1.SideEffectClassNone
	validateURL := fmt.Sprintf("%s/mutate", url)
	webhook := admissionregistrationv1beta1.MutatingWebhookConfiguration{
		ObjectMeta: metav1.ObjectMeta{
			Name: "cert-manager-webhook",
		},
		Webhooks: []admissionregistrationv1beta1.MutatingWebhook{
			{
				Name: "webhook.cert-manager.io",
				ClientConfig: admissionregistrationv1beta1.WebhookClientConfig{
					URL:      &validateURL,
					CABundle: caPEM,
				},
				Rules: []admissionregistrationv1beta1.RuleWithOperations{
					{
						Operations: []admissionregistrationv1beta1.OperationType{
							admissionregistrationv1beta1.Create,
							admissionregistrationv1beta1.Update,
						},
						Rule: admissionregistrationv1beta1.Rule{
							APIGroups:   []string{"cert-manager.io", "acme.cert-manager.io"},
							APIVersions: []string{"*"},
							Resources:   []string{"*/*"},
						},
					},
				},
				FailurePolicy: &failurePolicy,
				SideEffects:   &sideEffects,
			},
		},
	}

	return &webhook
}
<commit_msg>test/integration/framework: simplify to avoid word "datas"<commit_after>/*
Copyright 2020 The Jetstack cert-manager contributors.

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 framework

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
	"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
	apiextensionsinstall "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install"
	v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	jsonserializer "k8s.io/apimachinery/pkg/runtime/serializer/json"
	"k8s.io/apimachinery/pkg/runtime/serializer/versioning"
	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
	"k8s.io/client-go/rest"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/envtest"

	webhooktesting "github.com/jetstack/cert-manager/cmd/webhook/app/testing"
	"github.com/jetstack/cert-manager/pkg/api"
	apitesting "github.com/jetstack/cert-manager/pkg/api/testing"
)

func init() {
	// Set environment variables for controller-runtime's envtest package.
	// This is done once as we cannot scope environment variables to a single
	// invocation of RunControlPlane due to envtest's design.
	setUpEnvTestEnv()
}

type StopFunc func()

func RunControlPlane(t *testing.T) (*rest.Config, StopFunc) {
	webhookOpts, stopWebhook := webhooktesting.StartWebhookServer(t, []string{})
	crdsDir := apitesting.CRDDirectory(t)
	crds := readCustomResourcesAtPath(t, crdsDir)
	for _, crd := range crds {
		t.Logf("Found CRD with name %q", crd.Name)
	}
	patchCRDConversion(crds, webhookOpts.URL, webhookOpts.CAPEM)

	env := &envtest.Environment{
		AttachControlPlaneOutput: false,
		CRDs:                     crdsToRuntimeObjects(crds),
	}

	config, err := env.Start()
	if err != nil {
		t.Fatalf("failed to start control plane: %v", err)
	}

	cl, err := client.New(config, client.Options{Scheme: api.Scheme})
	if err != nil {
		t.Fatal(err)
	}

	// installing the validating webhooks, not using WebhookInstallOptions as it patches the CA to be it's own
	err = cl.Create(context.Background(), getValidatingWebhookConfig(webhookOpts.URL, webhookOpts.CAPEM))
	if err != nil {
		t.Fatal(err)
	}

	// installing the mutating webhooks, not using WebhookInstallOptions as it patches the CA to be it's own
	err = cl.Create(context.Background(), getMutatingWebhookConfig(webhookOpts.URL, webhookOpts.CAPEM))
	if err != nil {
		t.Fatal(err)
	}

	return config, func() {
		defer stopWebhook()
		if err := env.Stop(); err != nil {
			t.Logf("failed to shut down control plane, not failing test: %v", err)
		}
	}
}

var (
	internalScheme = runtime.NewScheme()
)

func init() {
	utilruntime.Must(metav1.AddMetaToScheme(internalScheme))
	apiextensionsinstall.Install(internalScheme)
}

func patchCRDConversion(crds []*v1.CustomResourceDefinition, url string, caPEM []byte) {
	for _, crd := range crds {
		if crd.Spec.Conversion == nil {
			continue
		}
		if crd.Spec.Conversion.Webhook == nil {
			continue
		}
		if crd.Spec.Conversion.Webhook.ClientConfig == nil {
			continue
		}
		if crd.Spec.Conversion.Webhook.ClientConfig.Service == nil {
			continue
		}
		path := ""
		if crd.Spec.Conversion.Webhook.ClientConfig.Service.Path != nil {
			path = *crd.Spec.Conversion.Webhook.ClientConfig.Service.Path
		}
		url := fmt.Sprintf("%s%s", url, path)
		crd.Spec.Conversion.Webhook.ClientConfig.URL = &url
		crd.Spec.Conversion.Webhook.ClientConfig.CABundle = caPEM
		crd.Spec.Conversion.Webhook.ClientConfig.Service = nil
	}
}

func readCustomResourcesAtPath(t *testing.T, path string) []*v1.CustomResourceDefinition {
	serializer := jsonserializer.NewSerializerWithOptions(jsonserializer.DefaultMetaFactory, internalScheme, internalScheme, jsonserializer.SerializerOptions{
		Yaml: true,
	})
	converter := runtime.UnsafeObjectConvertor(internalScheme)
	codec := versioning.NewCodec(serializer, serializer, converter, internalScheme, internalScheme, internalScheme, runtime.InternalGroupVersioner, runtime.InternalGroupVersioner, internalScheme.Name())

	var crds []*v1.CustomResourceDefinition
	if err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if filepath.Ext(path) != ".yaml" {
			return nil
		}
		crd, err := readCRDsAtPath(codec, converter, path)
		if err != nil {
			return err
		}
		crds = append(crds, crd...)
		return nil
	}); err != nil {
		t.Fatal(err)
	}
	return crds
}

func readCRDsAtPath(codec runtime.Codec, converter runtime.ObjectConvertor, path string) ([]*v1.CustomResourceDefinition, error) {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	var crds []*v1.CustomResourceDefinition
	for _, d := range strings.Split(string(data), "\n---\n") {
		// skip empty YAML documents
		if strings.TrimSpace(d) == "" {
			continue
		}

		internalCRD := &apiextensions.CustomResourceDefinition{}
		if _, _, err := codec.Decode([]byte(d), nil, internalCRD); err != nil {
			return nil, err
		}

		out := &v1.CustomResourceDefinition{}
		if err := converter.Convert(internalCRD, out, nil); err != nil {
			return nil, err
		}

		crds = append(crds, out)
	}

	return crds, nil
}

func crdsToRuntimeObjects(in []*v1.CustomResourceDefinition) []runtime.Object {
	out := make([]runtime.Object, len(in))

	for i, crd := range in {
		out[i] = runtime.Object(crd)
	}

	return out
}

func getValidatingWebhookConfig(url string, caPEM []byte) runtime.Object {
	failurePolicy := admissionregistrationv1beta1.Fail
	sideEffects := admissionregistrationv1beta1.SideEffectClassNone
	validateURL := fmt.Sprintf("%s/validate", url)
	webhook := admissionregistrationv1beta1.ValidatingWebhookConfiguration{
		ObjectMeta: metav1.ObjectMeta{
			Name: "cert-manager-webhook",
		},
		Webhooks: []admissionregistrationv1beta1.ValidatingWebhook{
			{
				Name: "webhook.cert-manager.io",
				ClientConfig: admissionregistrationv1beta1.WebhookClientConfig{
					URL:      &validateURL,
					CABundle: caPEM,
				},
				Rules: []admissionregistrationv1beta1.RuleWithOperations{
					{
						Operations: []admissionregistrationv1beta1.OperationType{
							admissionregistrationv1beta1.Create,
							admissionregistrationv1beta1.Update,
						},
						Rule: admissionregistrationv1beta1.Rule{
							APIGroups:   []string{"cert-manager.io", "acme.cert-manager.io"},
							APIVersions: []string{"*"},
							Resources:   []string{"*/*"},
						},
					},
				},
				FailurePolicy: &failurePolicy,
				SideEffects:   &sideEffects,
			},
		},
	}

	return &webhook
}

func getMutatingWebhookConfig(url string, caPEM []byte) runtime.Object {
	failurePolicy := admissionregistrationv1beta1.Fail
	sideEffects := admissionregistrationv1beta1.SideEffectClassNone
	validateURL := fmt.Sprintf("%s/mutate", url)
	webhook := admissionregistrationv1beta1.MutatingWebhookConfiguration{
		ObjectMeta: metav1.ObjectMeta{
			Name: "cert-manager-webhook",
		},
		Webhooks: []admissionregistrationv1beta1.MutatingWebhook{
			{
				Name: "webhook.cert-manager.io",
				ClientConfig: admissionregistrationv1beta1.WebhookClientConfig{
					URL:      &validateURL,
					CABundle: caPEM,
				},
				Rules: []admissionregistrationv1beta1.RuleWithOperations{
					{
						Operations: []admissionregistrationv1beta1.OperationType{
							admissionregistrationv1beta1.Create,
							admissionregistrationv1beta1.Update,
						},
						Rule: admissionregistrationv1beta1.Rule{
							APIGroups:   []string{"cert-manager.io", "acme.cert-manager.io"},
							APIVersions: []string{"*"},
							Resources:   []string{"*/*"},
						},
					},
				},
				FailurePolicy: &failurePolicy,
				SideEffects:   &sideEffects,
			},
		},
	}

	return &webhook
}
<|endoftext|>


<commit_before>// Copyright 2015 Hari haran. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/hariharan-uno/recon/lsb"
	"github.com/hariharan-uno/recon/memory"
)

func main() {
	log.SetPrefix("recon: ")

	lsbdata, err := lsb.CollectData()
	if err != nil {
		log.Println(err)
	}
	memdata, err := memory.CollectData()
	if err != nil {
		log.Println(err)
	}

	data := struct {
		Lsb    lsb.Data    `json:"lsb"`
		Memory memory.Data `json:"memory"`
	}{
		lsbdata,
		memdata,
	}
	b, err := json.MarshalIndent(data, "", "\t")
	if err != nil {
		fmt.Println("error:", err)
	}
	fmt.Printf("%s\n", b)
}
<commit_msg>Add cpudata in main<commit_after>// Copyright 2015 Hari haran. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/hariharan-uno/recon/cpu"
	"github.com/hariharan-uno/recon/lsb"
	"github.com/hariharan-uno/recon/memory"
)

func main() {
	log.SetPrefix("recon: ")

	lsbdata, err := lsb.CollectData()
	if err != nil {
		log.Println(err)
	}
	memdata, err := memory.CollectData()
	if err != nil {
		log.Println(err)
	}
	cpudata, err := cpu.CollectData()
	if err != nil {
		log.Println(err)
	}

	data := struct {
		Lsb    lsb.Data    `json:"lsb"`
		Memory memory.Data `json:"memory"`
		Cpu    cpu.Data    `json:"cpu"`
	}{
		lsbdata,
		memdata,
		cpudata,
	}
	b, err := json.MarshalIndent(data, "", "\t")
	if err != nil {
		fmt.Println("error:", err)
	}
	fmt.Printf("%s\n", b)
}
<|endoftext|>


<commit_before>package engine

import (
	"github.com/keybase/go/libkb"
)

type DeviceEngine struct {
	deviceName  string
	deviceID    libkb.DeviceId
	localEncKey []byte
	me          *libkb.User
	eldestKey   libkb.NaclKeyPair
	logui       libkb.LogUI
}

func NewDeviceEngine(me *libkb.User, logui libkb.LogUI) *DeviceEngine {
	return &DeviceEngine{me: me, logui: logui}
}

func (d *DeviceEngine) Init() error {
	return nil
}

func (d *DeviceEngine) Run(deviceName string) (err error) {
	d.deviceName = deviceName
	if d.deviceID, err = libkb.NewDeviceId(); err != nil {
		return
	}
	// do we need this?
	/*
		d.localEncKey, err = RandBytes(32)
		if err != nil {
			return err
		}
	*/

	G.Log.Debug("Device name:   %s", d.deviceName)
	G.Log.Debug("Device ID:     %x", d.deviceID)
	// G.Log.Info("Local Enc Key: %x", d.localEncKey)

	if err = d.pushEldestKey(); err != nil {
		return err
	}

	if wr := G.Env.GetConfigWriter(); wr != nil {
		if wr.SetDeviceId(&d.deviceID); err != nil {
			return
		} else if err = wr.Write(); err != nil {
			return
		} else {
			G.Log.Info("Setting Device ID to %s", d.deviceID)
		}
	}

	if err = d.pushDHKey(); err != nil {
		return
	}

	return
}

func (d *DeviceEngine) EldestKey() libkb.GenericKey {
	return d.eldestKey
}

func (d *DeviceEngine) pushEldestKey() error {
	eddsaPair, err := libkb.GenerateNaclSigningKeyPair()
	if err != nil {
		return err
	}
	G.Log.Debug("EdDSA: %s", eddsaPair.VerboseDescription())

	// copying stuff from keygen.go/GeneratePost
	fokid := libkb.GenericKeyToFOKID(eddsaPair)
	jw, err := d.me.SelfProof(eddsaPair, &fokid)
	if err != nil {
		return err
	}
	G.Log.Debug("self proof json: %s", jw.MarshalPretty())

	sig, sigid, linkid, err := libkb.SignJson(jw, eddsaPair)
	if err != nil {
		return err
	}

	pubkey, err := eddsaPair.Encode()
	if err != nil {
		return err
	}

	// save it to local keyring:
	_, err = libkb.WriteP3SKBToKeyring(eddsaPair, nil, d.logui)
	if err != nil {
		return err
	}

	args := libkb.HttpArgs{
		"sig_id_base":  libkb.S{Val: sigid.ToString(false)},
		"sig_id_short": libkb.S{Val: sigid.ToShortId()},
		"sig":          libkb.S{Val: sig},
		"public_key":   libkb.S{Val: pubkey},
		"is_primary":   libkb.I{Val: 1},
	}

	_, err = G.API.Post(libkb.ApiArg{
		Endpoint:    "key/add",
		NeedSession: true,
		Args:        args,
	})
	if err != nil {
		return err
	}

	d.eldestKey = eddsaPair
	d.me.SigChainBump(linkid, sigid)

	return nil
}

func (d *DeviceEngine) device() *libkb.Device {
	s := 1
	return &libkb.Device{
		Id:          d.deviceID.String(),
		Description: &d.deviceName,
		Type:        "desktop", // XXX always desktop?
		Status:      &s,
	}
}

func (d *DeviceEngine) pushDHKey() error {
	gen := libkb.NewNaclKeyGen(libkb.NaclKeyGenArg{
		Signer:    d.eldestKey,
		Primary:   d.eldestKey,
		Generator: libkb.GenerateNaclDHKeyPair,
		Type:      libkb.SUBKEY_TYPE,
		Me:        d.me,
		ExpireIn:  libkb.NACL_DH_EXPIRE_IN,
		Device:    d.device(),
		LogUI:     d.logui,
	})

	return gen.Run()
}
<commit_msg>also write per-device KID<commit_after>package engine

import (
	"github.com/keybase/go/libkb"
)

type DeviceEngine struct {
	deviceName  string
	deviceID    libkb.DeviceId
	localEncKey []byte
	me          *libkb.User
	eldestKey   libkb.NaclKeyPair
	logui       libkb.LogUI
}

func NewDeviceEngine(me *libkb.User, logui libkb.LogUI) *DeviceEngine {
	return &DeviceEngine{me: me, logui: logui}
}

func (d *DeviceEngine) Init() error {
	return nil
}

func (d *DeviceEngine) Run(deviceName string) (err error) {
	d.deviceName = deviceName
	if d.deviceID, err = libkb.NewDeviceId(); err != nil {
		return
	}
	// do we need this?
	/*
		d.localEncKey, err = RandBytes(32)
		if err != nil {
			return err
		}
	*/

	G.Log.Debug("Device name:   %s", d.deviceName)
	G.Log.Debug("Device ID:     %x", d.deviceID)
	// G.Log.Info("Local Enc Key: %x", d.localEncKey)

	if err = d.pushEldestKey(); err != nil {
		return err
	}

	if wr := G.Env.GetConfigWriter(); wr != nil {
		if wr.SetDeviceId(&d.deviceID); err != nil {
			return
		} else if err = wr.SetPerDeviceKID(d.EldestKey().GetKid()); err != nil {
			return
		} else if err = wr.Write(); err != nil {
			return
		} else {
			G.Log.Info("Setting Device ID to %s", d.deviceID)
		}
	}

	if err = d.pushDHKey(); err != nil {
		return
	}

	return
}

func (d *DeviceEngine) EldestKey() libkb.GenericKey {
	return d.eldestKey
}

func (d *DeviceEngine) pushEldestKey() error {
	eddsaPair, err := libkb.GenerateNaclSigningKeyPair()
	if err != nil {
		return err
	}
	G.Log.Debug("EdDSA: %s", eddsaPair.VerboseDescription())

	// copying stuff from keygen.go/GeneratePost
	fokid := libkb.GenericKeyToFOKID(eddsaPair)
	jw, err := d.me.SelfProof(eddsaPair, &fokid)
	if err != nil {
		return err
	}
	G.Log.Debug("self proof json: %s", jw.MarshalPretty())

	sig, sigid, linkid, err := libkb.SignJson(jw, eddsaPair)
	if err != nil {
		return err
	}

	pubkey, err := eddsaPair.Encode()
	if err != nil {
		return err
	}

	// save it to local keyring:
	_, err = libkb.WriteP3SKBToKeyring(eddsaPair, nil, d.logui)
	if err != nil {
		return err
	}

	args := libkb.HttpArgs{
		"sig_id_base":  libkb.S{Val: sigid.ToString(false)},
		"sig_id_short": libkb.S{Val: sigid.ToShortId()},
		"sig":          libkb.S{Val: sig},
		"public_key":   libkb.S{Val: pubkey},
		"is_primary":   libkb.I{Val: 1},
	}

	_, err = G.API.Post(libkb.ApiArg{
		Endpoint:    "key/add",
		NeedSession: true,
		Args:        args,
	})
	if err != nil {
		return err
	}

	d.eldestKey = eddsaPair
	d.me.SigChainBump(linkid, sigid)

	return nil
}

func (d *DeviceEngine) device() *libkb.Device {
	s := 1
	return &libkb.Device{
		Id:          d.deviceID.String(),
		Description: &d.deviceName,
		Type:        "desktop", // XXX always desktop?
		Status:      &s,
	}
}

func (d *DeviceEngine) pushDHKey() error {
	gen := libkb.NewNaclKeyGen(libkb.NaclKeyGenArg{
		Signer:    d.eldestKey,
		Primary:   d.eldestKey,
		Generator: libkb.GenerateNaclDHKeyPair,
		Type:      libkb.SUBKEY_TYPE,
		Me:        d.me,
		ExpireIn:  libkb.NACL_DH_EXPIRE_IN,
		Device:    d.device(),
		LogUI:     d.logui,
	})

	return gen.Run()
}
<|endoftext|>


<commit_before>package opal

// TODO

// Samsung EVO 860:
// d0raw: [0 0 0 144 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 16 12 17 0 0 0 0 0 0 0 0 0 0 0 0 2 16 12 31 0 0 0 0 0 0 0 0 0 0 0 0 3 16 28 1 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 2 2 16 12 0 0 0 9 0 160 0 0 0 0 0 1 2 3 16 16 16 4 0 1 0 0 4 0 9 0 0 0 0 0 0 0]
<commit_msg>Confirm NVMe works<commit_after>package opal

// TODO

// Samsung EVO 860:
// d0raw: [0 0 0 144 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 16 12 17 0 0 0 0 0 0 0 0 0 0 0 0 2 16 12 31 0 0 0 0 0 0 0 0 0 0 0 0 3 16 28 1 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 2 2 16 12 0 0 0 9 0 160 0 0 0 0 0 1 2 3 16 16 16 4 0 1 0 0 4 0 9 0 0 0 0 0 0 0]

// Samsung SSD 970 EVO Plus 500GB (NVMe)
// d0raw: [0 0 0 180 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 16 12 17 0 0 0 0 0 0 0 0 0 0 0 0 2 16 12 9 0 0 0 0 0 0 0 0 0 0 0 0 3 16 28 1 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 2 2 16 12 0 0 0 9 0 160 0 0 0 0 0 1 2 3 16 16 16 4 0 1 0 0 4 0 9 0 0 0 0 0 0 0 4 2 16 12 0 0 0 0 0 0 0 0 0 0 0 0 4 3 16 16 128 0 0 0 0 0 0 9 0 0 0 8 0 0 0 8]
<|endoftext|>