<commit_before>// Package operating (as oppose to system) holds platform-independant code.
package operating

import (
	"sync"

	metrics "github.com/rcrowley/go-metrics"
	sigar "github.com/rzab/gosigar"
)

// Memory type is a struct of memory metrics.
type Memory struct {
	Kind       string
	Total      string
	Used       string
	Free       string
	UsePercent string
}

// MEM type has a list of Memory.
type MEM struct {
	List []Memory
}

type RAM struct {
	Memory
	Extra1 uint64 // linux:buffered // darwin:wired
	Extra2 uint64 // linux:cached   // darwin:active
}

// DiskMeta type has common for DiskBytes and DiskInodes fields.
type DiskMeta struct {
	DevName string
	DirName string
}

// DiskBytes type is a struct of disk bytes metrics.
type DiskBytes struct {
	DiskMeta
	Total      string // with units
	Used       string // with units
	Avail      string // with units
	UsePercent string // without %
}

// DiskInodes type is a struct of disk inodes metrics.
type DiskInodes struct {
	DiskMeta
	Inodes      string // with units
	Iused       string // with units
	Ifree       string // with units
	IusePercent string // without %
}

// DFbytes type has a list of DiskBytes.
type DFbytes struct {
	List []DiskBytes
}

// DFinodes type has a list of DiskInodes.
type DFinodes struct {
	List []DiskInodes
}

// InterfaceInfo type is a struct of interface metrics.
type InterfaceInfo struct {
	Name     string
	In       string // with units
	Out      string // with units
	DeltaIn  string // with units
	DeltaOut string // with units
}

// Interfaces type has a list of Interface.
type Interfaces struct {
	List []InterfaceInfo
}

// ProcInfo type is an internal account of a process.
type ProcInfo struct {
	PID      uint
	Priority int
	Nice     int
	Time     uint64
	Name     string
	UID      uint
	Size     uint64
	Resident uint64
}

// ProcData type is a public (for index context, json marshaling) account of a process.
type ProcData struct {
	PID      uint
	UID      uint
	Priority int
	Nice     int
	Time     string
	Name     string
	User     string
	Size     string // with units
	Resident string // with units
}

type RAMUpdater interface {
	UpdateRAM(sigar.Mem, uint64, uint64)
}

type MetricRAM struct {
	Free  metrics.Gauge
	Total metrics.Gauge
	Extra RAMUpdater
}

func ExtraNewMetricRAM(r metrics.Registry, extra RAMUpdater) *MetricRAM {
	return &MetricRAM{
		Free:  metrics.NewRegisteredGauge("memory.memory-free", r),
		Total: metrics.NewRegisteredGauge("memory.memory-total", metrics.NewRegistry()),
		Extra: extra,
	}
}

func (mr *MetricRAM) Update(got sigar.Mem, extra1, extra2 uint64) {
	mr.Free.Update(int64(got.Free))
	mr.Total.Update(int64(got.Total))
	if mr.Extra != nil {
		mr.Extra.UpdateRAM(got, extra1, extra2)
	}
}

func (mr *MetricRAM) UsedValue() uint64 { // Total - Free
	return uint64(mr.Total.Snapshot().Value() - mr.Free.Snapshot().Value())
}

type MetricLoad struct {
	Short metrics.GaugeFloat64
	Mid   metrics.GaugeFloat64
	Long  metrics.GaugeFloat64
}

func NewMetricLoad(r metrics.Registry) *MetricLoad {
	return &MetricLoad{
		Short: metrics.NewRegisteredGaugeFloat64("load.shortterm", r),
		Mid:   metrics.NewRegisteredGaugeFloat64("load.midterm", r),
		Long:  metrics.NewRegisteredGaugeFloat64("load.longterm", r),
	}
}

type MetricSwap struct {
	Free metrics.Gauge
	Used metrics.Gauge
}

func NewMetricSwap(r metrics.Registry) MetricSwap {
	return MetricSwap{
		Free: metrics.NewRegisteredGauge("swap.swap-free", r),
		Used: metrics.NewRegisteredGauge("swap.swap-used", r),
	}
}

func (ms *MetricSwap) TotalValue() uint64 { // Free + Used
	return uint64(ms.Free.Snapshot().Value() + ms.Used.Snapshot().Value())
}

func (ms *MetricSwap) Update(got sigar.Swap) {
	ms.Free.Update(int64(got.Free))
	ms.Used.Update(int64(got.Used))
}

// GaugeDiff holds two Gauge metrics: the first is the exported one.
// Caveat: The exported metric value is 0 initially, not "nan", until updated.
type GaugeDiff struct {
	Delta    metrics.Gauge // Delta as the primary metric.
	Absolute metrics.Gauge // Absolute keeps the absolute value, not exported as it's registered in private registry.
	Previous metrics.Gauge // Previous keeps the previous absolute value, not exported as it's registered in private registry.
	Mutex    sync.Mutex
}

func NewGaugeDiff(name string, r metrics.Registry) *GaugeDiff {
	return &GaugeDiff{
		Delta:    metrics.NewRegisteredGauge(name, r),
		Absolute: metrics.NewRegisteredGauge(name+"-absolute", metrics.NewRegistry()),
		Previous: metrics.NewRegisteredGauge(name+"-previous", metrics.NewRegistry()),
	}
}

func (gd *GaugeDiff) Values() (int64, int64) {
	gd.Mutex.Lock()
	defer gd.Mutex.Unlock()
	return gd.Delta.Snapshot().Value(), gd.Absolute.Snapshot().Value()
}

func (gd *GaugeDiff) UpdateAbsolute(absolute int64) int64 {
	gd.Mutex.Lock()
	defer gd.Mutex.Unlock()
	previous := gd.Previous.Snapshot().Value()
	gd.Absolute.Update(absolute)
	gd.Previous.Update(absolute)
	if previous == 0 { // do not .Update
		return 0
	}
	if absolute < previous { // counters got reset
		previous = 0
	}
	delta := absolute - previous
	gd.Delta.Update(delta)
	return delta
}

type GaugePercent struct {
	Percent  metrics.GaugeFloat64 // Percent as the primary metric.
	Previous metrics.Gauge
	Mutex    sync.Mutex
}

func NewGaugePercent(name string, r metrics.Registry) *GaugePercent {
	return &GaugePercent{
		Percent:  metrics.NewRegisteredGaugeFloat64(name, r),
		Previous: metrics.NewRegisteredGauge(name+"-previous", metrics.NewRegistry()),
	}
}

func (gp *GaugePercent) SnapshotValueUint() uint {
	return uint(gp.Percent.Snapshot().Value())
}

func (gp *GaugePercent) UpdatePercent(totalDelta int64, uabsolute uint64) {
	gp.Mutex.Lock()
	defer gp.Mutex.Unlock()
	previous := gp.Previous.Snapshot().Value()
	absolute := int64(uabsolute)
	gp.Previous.Update(absolute)
	if previous != 0 /* otherwise do not update */ &&
		absolute >= previous /* otherwise counters got reset */ &&
		totalDelta != 0 /* otherwise there were no previous value for Total */ {
		percent := float64(100) * float64(absolute-previous) / float64(totalDelta) // TODO rounding good?
		if percent > 100.0 {
			percent = 100.0
		}
		gp.Percent.Update(percent)
	}
}

// CPUInfo type has a list of CoreInfo.
type CPUInfo struct {
	List []CoreInfo
}

// CoreInfo type is a struct of core metrics.
type CoreInfo struct {
	N    string
	User uint // percent without "%"
	Sys  uint // percent without "%"
	Wait uint // percent without "%"
	Idle uint // percent without "%"
}

type CPUUpdater interface {
	UpdateCPU(sigar.Cpu, int64)
}

type MetricCPU struct {
	*CPU
}

type CPU struct {
	metrics.Healthcheck        // derive from one of (go-)metric types, otherwise it won't be registered
	N                   string // The "cpu-N"
	User                *GaugePercent
	Nice                *GaugePercent
	Sys                 *GaugePercent
	Wait                *GaugePercent
	Idle                *GaugePercent
	Total               *GaugeDiff
	Extra               CPUUpdater
}

func (mc MetricCPU) Update(scpu sigar.Cpu) {
	totalDelta := mc.Total.UpdateAbsolute(int64(scpu.Total()))
	mc.User.UpdatePercent(totalDelta, scpu.User)
	mc.Nice.UpdatePercent(totalDelta, scpu.Nice)
	mc.Sys.UpdatePercent(totalDelta, scpu.Sys)
	mc.Wait.UpdatePercent(totalDelta, scpu.Wait)
	mc.Idle.UpdatePercent(totalDelta, scpu.Idle)
	if mc.Extra != nil {
		mc.Extra.UpdateCPU(scpu, totalDelta)
	}
}

func ExtraNewMetricCPU(r metrics.Registry, name string, extra CPUUpdater) *MetricCPU {
	return &MetricCPU{
		CPU: &CPU{
			N:     name,
			User:  NewGaugePercent(name+".user", r),
			Nice:  NewGaugePercent(name+".nice", r),
			Sys:   NewGaugePercent(name+".system", r),
			Wait:  NewGaugePercent(name+".wait", r),
			Idle:  NewGaugePercent(name+".idle", r),
			Total: NewGaugeDiff(name+"-total", metrics.NewRegistry()),
			Extra: extra,
		},
	}
}

// AddSCPU adds other to dst field by field.
func AddSCPU(dst *sigar.Cpu, other sigar.Cpu) {
	dst.User += other.User
	dst.Nice += other.Nice
	dst.Sys += other.Sys
	dst.Wait += other.Wait
	dst.Idle += other.Idle
	dst.Irq += other.Irq
	dst.SoftIrq += other.SoftIrq
	dst.Stolen += other.Stolen
}

type MetricString interface {
	Snapshot() MetricString
	Value() string
	Update(string)
}

type StandardMetricString struct {
	string
	Mutex sync.Mutex
}

type MetricStringSnapshot StandardMetricString

func (mss *MetricStringSnapshot) Snapshot() MetricString { return mss }
func (mss *MetricStringSnapshot) Value() string          { return mss.string }
func (*MetricStringSnapshot) Update(string)              { panic("Update called on a MetricStringSnapshot") }

func (sms *StandardMetricString) Snapshot() MetricString {
	sms.Mutex.Lock()
	defer sms.Mutex.Unlock()
	return ((*MetricStringSnapshot)(sms))
}

func (sms *StandardMetricString) Value() string {
	sms.Mutex.Lock()
	defer sms.Mutex.Unlock()
	return sms.string
}

func (sms *StandardMetricString) Update(new string) {
	sms.Mutex.Lock()
	defer sms.Mutex.Unlock()
	sms.string = new
}

type MetricDF struct {
	*DF
}

type DF struct {
	metrics.Healthcheck // derive from one of (go-)metric types, otherwise it won't be registered
	DevName             MetricString
	Free                metrics.GaugeFloat64
	Reserved            metrics.GaugeFloat64
	Total               metrics.Gauge
	Used                metrics.GaugeFloat64
	Avail               metrics.Gauge
	UsePercent          metrics.GaugeFloat64
	Inodes              metrics.Gauge
	Iused               metrics.Gauge
	Ifree               metrics.Gauge
	IusePercent         metrics.GaugeFloat64
	DirName             MetricString
}

// Update reads usage and fs and updates the corresponding fields in DF.
func (md *DF) Update(fs sigar.FileSystem, usage sigar.FileSystemUsage) {
	md.DevName.Update(fs.DevName)
	md.DirName.Update(fs.DirName)
	md.Free.Update(float64(usage.Free << 10))
	md.Reserved.Update(float64((usage.Free - usage.Avail) << 10))
	md.Total.Update(int64(usage.Total << 10))
	md.Used.Update(float64(usage.Used << 10))
	md.Avail.Update(int64(usage.Avail << 10))
	md.UsePercent.Update(usage.UsePercent())
	md.Inodes.Update(int64(usage.Files))
	md.Iused.Update(int64(usage.Files - usage.FreeFiles))
	md.Ifree.Update(int64(usage.FreeFiles))
	if iusePercent := 0.0; usage.Files != 0 {
		iusePercent = float64(100) * float64(usage.Files-usage.FreeFiles) / float64(usage.Files)
		md.IusePercent.Update(iusePercent)
	}
}

// MetricInterface hold a pointer to Interface.
type MetricInterface struct {
	*Interface
}

// Interface is a set of interface metrics.
type Interface struct {
	metrics.Healthcheck // derive from one of (go-)metric types, otherwise it won't be registered
	Name                string
	BytesIn             *GaugeDiff
	BytesOut            *GaugeDiff
	ErrorsIn            *GaugeDiff
	ErrorsOut           *GaugeDiff
	PacketsIn           *GaugeDiff
	PacketsOut          *GaugeDiff
}

// Update reads ifdata and updates the corresponding fields in Interface.
func (i *Interface) Update(ifdata Getifdata) {
	i.BytesIn.UpdateAbsolute(int64(ifdata.GetInBytes()))
	i.BytesOut.UpdateAbsolute(int64(ifdata.GetOutBytes()))
	i.ErrorsIn.UpdateAbsolute(int64(ifdata.GetInErrors()))
	i.ErrorsOut.UpdateAbsolute(int64(ifdata.GetOutErrors()))
	i.PacketsIn.UpdateAbsolute(int64(ifdata.GetInPackets()))
	i.PacketsOut.UpdateAbsolute(int64(ifdata.GetOutPackets()))
}

type Getifdata interface {
	GetInBytes() uint
	GetOutBytes() uint
	GetInErrors() uint
	GetOutErrors() uint
	GetInPackets() uint
	GetOutPackets() uint
}

type Vgmachine struct {
	UUID             string
	Name             string
	Provider         string
	State            string
	Vagrantfile_path string // Directory
}
<commit_msg>fix race condition in MetricStringSnapshot<commit_after>// Package operating (as oppose to system) holds platform-independant code.
package operating

import (
	"sync"

	metrics "github.com/rcrowley/go-metrics"
	sigar "github.com/rzab/gosigar"
)

// Memory type is a struct of memory metrics.
type Memory struct {
	Kind       string
	Total      string
	Used       string
	Free       string
	UsePercent string
}

// MEM type has a list of Memory.
type MEM struct {
	List []Memory
}

type RAM struct {
	Memory
	Extra1 uint64 // linux:buffered // darwin:wired
	Extra2 uint64 // linux:cached   // darwin:active
}

// DiskMeta type has common for DiskBytes and DiskInodes fields.
type DiskMeta struct {
	DevName string
	DirName string
}

// DiskBytes type is a struct of disk bytes metrics.
type DiskBytes struct {
	DiskMeta
	Total      string // with units
	Used       string // with units
	Avail      string // with units
	UsePercent string // without %
}

// DiskInodes type is a struct of disk inodes metrics.
type DiskInodes struct {
	DiskMeta
	Inodes      string // with units
	Iused       string // with units
	Ifree       string // with units
	IusePercent string // without %
}

// DFbytes type has a list of DiskBytes.
type DFbytes struct {
	List []DiskBytes
}

// DFinodes type has a list of DiskInodes.
type DFinodes struct {
	List []DiskInodes
}

// InterfaceInfo type is a struct of interface metrics.
type InterfaceInfo struct {
	Name     string
	In       string // with units
	Out      string // with units
	DeltaIn  string // with units
	DeltaOut string // with units
}

// Interfaces type has a list of Interface.
type Interfaces struct {
	List []InterfaceInfo
}

// ProcInfo type is an internal account of a process.
type ProcInfo struct {
	PID      uint
	Priority int
	Nice     int
	Time     uint64
	Name     string
	UID      uint
	Size     uint64
	Resident uint64
}

// ProcData type is a public (for index context, json marshaling) account of a process.
type ProcData struct {
	PID      uint
	UID      uint
	Priority int
	Nice     int
	Time     string
	Name     string
	User     string
	Size     string // with units
	Resident string // with units
}

type RAMUpdater interface {
	UpdateRAM(sigar.Mem, uint64, uint64)
}

type MetricRAM struct {
	Free  metrics.Gauge
	Total metrics.Gauge
	Extra RAMUpdater
}

func ExtraNewMetricRAM(r metrics.Registry, extra RAMUpdater) *MetricRAM {
	return &MetricRAM{
		Free:  metrics.NewRegisteredGauge("memory.memory-free", r),
		Total: metrics.NewRegisteredGauge("memory.memory-total", metrics.NewRegistry()),
		Extra: extra,
	}
}

func (mr *MetricRAM) Update(got sigar.Mem, extra1, extra2 uint64) {
	mr.Free.Update(int64(got.Free))
	mr.Total.Update(int64(got.Total))
	if mr.Extra != nil {
		mr.Extra.UpdateRAM(got, extra1, extra2)
	}
}

func (mr *MetricRAM) UsedValue() uint64 { // Total - Free
	return uint64(mr.Total.Snapshot().Value() - mr.Free.Snapshot().Value())
}

type MetricLoad struct {
	Short metrics.GaugeFloat64
	Mid   metrics.GaugeFloat64
	Long  metrics.GaugeFloat64
}

func NewMetricLoad(r metrics.Registry) *MetricLoad {
	return &MetricLoad{
		Short: metrics.NewRegisteredGaugeFloat64("load.shortterm", r),
		Mid:   metrics.NewRegisteredGaugeFloat64("load.midterm", r),
		Long:  metrics.NewRegisteredGaugeFloat64("load.longterm", r),
	}
}

type MetricSwap struct {
	Free metrics.Gauge
	Used metrics.Gauge
}

func NewMetricSwap(r metrics.Registry) MetricSwap {
	return MetricSwap{
		Free: metrics.NewRegisteredGauge("swap.swap-free", r),
		Used: metrics.NewRegisteredGauge("swap.swap-used", r),
	}
}

func (ms *MetricSwap) TotalValue() uint64 { // Free + Used
	return uint64(ms.Free.Snapshot().Value() + ms.Used.Snapshot().Value())
}

func (ms *MetricSwap) Update(got sigar.Swap) {
	ms.Free.Update(int64(got.Free))
	ms.Used.Update(int64(got.Used))
}

// GaugeDiff holds two Gauge metrics: the first is the exported one.
// Caveat: The exported metric value is 0 initially, not "nan", until updated.
type GaugeDiff struct {
	Delta    metrics.Gauge // Delta as the primary metric.
	Absolute metrics.Gauge // Absolute keeps the absolute value, not exported as it's registered in private registry.
	Previous metrics.Gauge // Previous keeps the previous absolute value, not exported as it's registered in private registry.
	Mutex    sync.Mutex
}

func NewGaugeDiff(name string, r metrics.Registry) *GaugeDiff {
	return &GaugeDiff{
		Delta:    metrics.NewRegisteredGauge(name, r),
		Absolute: metrics.NewRegisteredGauge(name+"-absolute", metrics.NewRegistry()),
		Previous: metrics.NewRegisteredGauge(name+"-previous", metrics.NewRegistry()),
	}
}

func (gd *GaugeDiff) Values() (int64, int64) {
	gd.Mutex.Lock()
	defer gd.Mutex.Unlock()
	return gd.Delta.Snapshot().Value(), gd.Absolute.Snapshot().Value()
}

func (gd *GaugeDiff) UpdateAbsolute(absolute int64) int64 {
	gd.Mutex.Lock()
	defer gd.Mutex.Unlock()
	previous := gd.Previous.Snapshot().Value()
	gd.Absolute.Update(absolute)
	gd.Previous.Update(absolute)
	if previous == 0 { // do not .Update
		return 0
	}
	if absolute < previous { // counters got reset
		previous = 0
	}
	delta := absolute - previous
	gd.Delta.Update(delta)
	return delta
}

type GaugePercent struct {
	Percent  metrics.GaugeFloat64 // Percent as the primary metric.
	Previous metrics.Gauge
	Mutex    sync.Mutex
}

func NewGaugePercent(name string, r metrics.Registry) *GaugePercent {
	return &GaugePercent{
		Percent:  metrics.NewRegisteredGaugeFloat64(name, r),
		Previous: metrics.NewRegisteredGauge(name+"-previous", metrics.NewRegistry()),
	}
}

func (gp *GaugePercent) SnapshotValueUint() uint {
	return uint(gp.Percent.Snapshot().Value())
}

func (gp *GaugePercent) UpdatePercent(totalDelta int64, uabsolute uint64) {
	gp.Mutex.Lock()
	defer gp.Mutex.Unlock()
	previous := gp.Previous.Snapshot().Value()
	absolute := int64(uabsolute)
	gp.Previous.Update(absolute)
	if previous != 0 /* otherwise do not update */ &&
		absolute >= previous /* otherwise counters got reset */ &&
		totalDelta != 0 /* otherwise there were no previous value for Total */ {
		percent := float64(100) * float64(absolute-previous) / float64(totalDelta) // TODO rounding good?
		if percent > 100.0 {
			percent = 100.0
		}
		gp.Percent.Update(percent)
	}
}

// CPUInfo type has a list of CoreInfo.
type CPUInfo struct {
	List []CoreInfo
}

// CoreInfo type is a struct of core metrics.
type CoreInfo struct {
	N    string
	User uint // percent without "%"
	Sys  uint // percent without "%"
	Wait uint // percent without "%"
	Idle uint // percent without "%"
}

type CPUUpdater interface {
	UpdateCPU(sigar.Cpu, int64)
}

type MetricCPU struct {
	*CPU
}

type CPU struct {
	metrics.Healthcheck        // derive from one of (go-)metric types, otherwise it won't be registered
	N                   string // The "cpu-N"
	User                *GaugePercent
	Nice                *GaugePercent
	Sys                 *GaugePercent
	Wait                *GaugePercent
	Idle                *GaugePercent
	Total               *GaugeDiff
	Extra               CPUUpdater
}

func (mc MetricCPU) Update(scpu sigar.Cpu) {
	totalDelta := mc.Total.UpdateAbsolute(int64(scpu.Total()))
	mc.User.UpdatePercent(totalDelta, scpu.User)
	mc.Nice.UpdatePercent(totalDelta, scpu.Nice)
	mc.Sys.UpdatePercent(totalDelta, scpu.Sys)
	mc.Wait.UpdatePercent(totalDelta, scpu.Wait)
	mc.Idle.UpdatePercent(totalDelta, scpu.Idle)
	if mc.Extra != nil {
		mc.Extra.UpdateCPU(scpu, totalDelta)
	}
}

func ExtraNewMetricCPU(r metrics.Registry, name string, extra CPUUpdater) *MetricCPU {
	return &MetricCPU{
		CPU: &CPU{
			N:     name,
			User:  NewGaugePercent(name+".user", r),
			Nice:  NewGaugePercent(name+".nice", r),
			Sys:   NewGaugePercent(name+".system", r),
			Wait:  NewGaugePercent(name+".wait", r),
			Idle:  NewGaugePercent(name+".idle", r),
			Total: NewGaugeDiff(name+"-total", metrics.NewRegistry()),
			Extra: extra,
		},
	}
}

// AddSCPU adds other to dst field by field.
func AddSCPU(dst *sigar.Cpu, other sigar.Cpu) {
	dst.User += other.User
	dst.Nice += other.Nice
	dst.Sys += other.Sys
	dst.Wait += other.Wait
	dst.Idle += other.Idle
	dst.Irq += other.Irq
	dst.SoftIrq += other.SoftIrq
	dst.Stolen += other.Stolen
}

type MetricString interface {
	Snapshot() MetricString
	Value() string
	Update(string)
}

type StandardMetricString struct {
	string
	Mutex sync.Mutex
}

type MetricStringSnapshot string

func (mss MetricStringSnapshot) Snapshot() MetricString { return mss }
func (mss MetricStringSnapshot) Value() string          { return string(mss) }
func (MetricStringSnapshot) Update(string)              { panic("Update called on a MetricStringSnapshot") }

func (sms *StandardMetricString) Snapshot() MetricString {
	sms.Mutex.Lock()
	defer sms.Mutex.Unlock()
	return MetricStringSnapshot(sms.string)
}

func (sms *StandardMetricString) Value() string {
	sms.Mutex.Lock()
	defer sms.Mutex.Unlock()
	return sms.string
}

func (sms *StandardMetricString) Update(new string) {
	sms.Mutex.Lock()
	defer sms.Mutex.Unlock()
	sms.string = new
}

type MetricDF struct {
	*DF
}

type DF struct {
	metrics.Healthcheck // derive from one of (go-)metric types, otherwise it won't be registered
	DevName             MetricString
	Free                metrics.GaugeFloat64
	Reserved            metrics.GaugeFloat64
	Total               metrics.Gauge
	Used                metrics.GaugeFloat64
	Avail               metrics.Gauge
	UsePercent          metrics.GaugeFloat64
	Inodes              metrics.Gauge
	Iused               metrics.Gauge
	Ifree               metrics.Gauge
	IusePercent         metrics.GaugeFloat64
	DirName             MetricString
}

// Update reads usage and fs and updates the corresponding fields in DF.
func (md *DF) Update(fs sigar.FileSystem, usage sigar.FileSystemUsage) {
	md.DevName.Update(fs.DevName)
	md.DirName.Update(fs.DirName)
	md.Free.Update(float64(usage.Free << 10))
	md.Reserved.Update(float64((usage.Free - usage.Avail) << 10))
	md.Total.Update(int64(usage.Total << 10))
	md.Used.Update(float64(usage.Used << 10))
	md.Avail.Update(int64(usage.Avail << 10))
	md.UsePercent.Update(usage.UsePercent())
	md.Inodes.Update(int64(usage.Files))
	md.Iused.Update(int64(usage.Files - usage.FreeFiles))
	md.Ifree.Update(int64(usage.FreeFiles))
	if iusePercent := 0.0; usage.Files != 0 {
		iusePercent = float64(100) * float64(usage.Files-usage.FreeFiles) / float64(usage.Files)
		md.IusePercent.Update(iusePercent)
	}
}

// MetricInterface hold a pointer to Interface.
type MetricInterface struct {
	*Interface
}

// Interface is a set of interface metrics.
type Interface struct {
	metrics.Healthcheck // derive from one of (go-)metric types, otherwise it won't be registered
	Name                string
	BytesIn             *GaugeDiff
	BytesOut            *GaugeDiff
	ErrorsIn            *GaugeDiff
	ErrorsOut           *GaugeDiff
	PacketsIn           *GaugeDiff
	PacketsOut          *GaugeDiff
}

// Update reads ifdata and updates the corresponding fields in Interface.
func (i *Interface) Update(ifdata Getifdata) {
	i.BytesIn.UpdateAbsolute(int64(ifdata.GetInBytes()))
	i.BytesOut.UpdateAbsolute(int64(ifdata.GetOutBytes()))
	i.ErrorsIn.UpdateAbsolute(int64(ifdata.GetInErrors()))
	i.ErrorsOut.UpdateAbsolute(int64(ifdata.GetOutErrors()))
	i.PacketsIn.UpdateAbsolute(int64(ifdata.GetInPackets()))
	i.PacketsOut.UpdateAbsolute(int64(ifdata.GetOutPackets()))
}

type Getifdata interface {
	GetInBytes() uint
	GetOutBytes() uint
	GetInErrors() uint
	GetOutErrors() uint
	GetInPackets() uint
	GetOutPackets() uint
}

type Vgmachine struct {
	UUID             string
	Name             string
	Provider         string
	State            string
	Vagrantfile_path string // Directory
}
<|endoftext|>


<commit_before>package tameshigiri

import "testing"

func ExampleAssertion() {
    var t         = &testing.T{}
    var assertion = Assertion{ T: t }
    var expected  = 123
    var actual    = 123

    assertion.Equals(expected, actual, "Something must be wrong.")
}
<commit_msg>Updated the documentation.<commit_after>package tameshigiri

import "testing"

//
func ExampleAssertion() {
    var t         = &testing.T{}
    var assertion = Assertion{ T: t }
    var expected  = 123
    var actual    = 123

    assertion.IsTrue(expected == actual, "Ye")
    assertion.IsFalse(expected != actual, "Ne")
    assertion.Equals(expected, actual, "Eh?")

    // This example shows all passed assertions.
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

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

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

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

package e2e_node

import (
	"bytes"
	"fmt"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/uuid"
	"k8s.io/kubernetes/pkg/api/v1"
	"k8s.io/kubernetes/test/e2e/framework"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = framework.KubeDescribe("Kubelet", func() {
	f := framework.NewDefaultFramework("kubelet-test")
	var podClient *framework.PodClient
	BeforeEach(func() {
		podClient = f.PodClient()
	})
	Context("when scheduling a busybox command in a pod", func() {
		podName := "busybox-scheduling-" + string(uuid.NewUUID())
		It("it should print the output to logs [Conformance]", func() {
			podClient.CreateSync(&v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name: podName,
				},
				Spec: v1.PodSpec{
					// Don't restart the Pod since it is expected to exit
					RestartPolicy: v1.RestartPolicyNever,
					Containers: []v1.Container{
						{
							Image:   "gcr.io/google_containers/busybox:1.24",
							Name:    podName,
							Command: []string{"sh", "-c", "echo 'Hello World' ; sleep 240"},
						},
					},
				},
			})
			Eventually(func() string {
				sinceTime := metav1.NewTime(time.Now().Add(time.Duration(-1 * time.Hour)))
				rc, err := podClient.GetLogs(podName, &v1.PodLogOptions{SinceTime: &sinceTime}).Stream()
				if err != nil {
					return ""
				}
				defer rc.Close()
				buf := new(bytes.Buffer)
				buf.ReadFrom(rc)
				return buf.String()
			}, time.Minute, time.Second*4).Should(Equal("Hello World\n"))
		})
	})
	Context("when scheduling a busybox command that always fails in a pod", func() {
		var podName string

		BeforeEach(func() {
			podName = "bin-false" + string(uuid.NewUUID())
			podClient.Create(&v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name: podName,
				},
				Spec: v1.PodSpec{
					// Don't restart the Pod since it is expected to exit
					RestartPolicy: v1.RestartPolicyNever,
					Containers: []v1.Container{
						{
							Image:   "gcr.io/google_containers/busybox:1.24",
							Name:    podName,
							Command: []string{"/bin/false"},
						},
					},
				},
			})
		})

		It("should have an error terminated reason", func() {
			Eventually(func() error {
				podData, err := podClient.Get(podName, metav1.GetOptions{})
				if err != nil {
					return err
				}
				if len(podData.Status.ContainerStatuses) != 1 {
					return fmt.Errorf("expected only one container in the pod %q", podName)
				}
				contTerminatedState := podData.Status.ContainerStatuses[0].State.Terminated
				if contTerminatedState == nil {
					return fmt.Errorf("expected state to be terminated. Got pod status: %+v", podData.Status)
				}
				if contTerminatedState.Reason != "Error" {
					return fmt.Errorf("expected terminated state reason to be error. Got %+v", contTerminatedState)
				}
				return nil
			}, time.Minute, time.Second*4).Should(BeNil())
		})

		It("should be possible to delete", func() {
			err := podClient.Delete(podName, &metav1.DeleteOptions{})
			Expect(err).To(BeNil(), fmt.Sprintf("Error deleting Pod %v", err))
		})
	})
	Context("when scheduling a read only busybox container", func() {
		podName := "busybox-readonly-fs" + string(uuid.NewUUID())
		It("it should not write to root filesystem [Conformance]", func() {
			isReadOnly := true
			podClient.CreateSync(&v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name: podName,
				},
				Spec: v1.PodSpec{
					// Don't restart the Pod since it is expected to exit
					RestartPolicy: v1.RestartPolicyNever,
					Containers: []v1.Container{
						{
							Image:   "gcr.io/google_containers/busybox:1.24",
							Name:    podName,
							Command: []string{"sh", "-c", "echo test > /file; sleep 240"},
							SecurityContext: &v1.SecurityContext{
								ReadOnlyRootFilesystem: &isReadOnly,
							},
						},
					},
				},
			})
			Eventually(func() string {
				rc, err := podClient.GetLogs(podName, &v1.PodLogOptions{}).Stream()
				if err != nil {
					return ""
				}
				defer rc.Close()
				buf := new(bytes.Buffer)
				buf.ReadFrom(rc)
				return buf.String()
			}, time.Minute, time.Second*4).Should(Equal("sh: can't create /file: Read-only file system\n"))
		})
	})
})
<commit_msg>test/e2e_node: tie together expected string and exec<commit_after>/*
Copyright 2016 The Kubernetes Authors.

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

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

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

package e2e_node

import (
	"bytes"
	"fmt"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/uuid"
	"k8s.io/kubernetes/pkg/api/v1"
	"k8s.io/kubernetes/test/e2e/framework"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = framework.KubeDescribe("Kubelet", func() {
	f := framework.NewDefaultFramework("kubelet-test")
	var podClient *framework.PodClient
	BeforeEach(func() {
		podClient = f.PodClient()
	})
	Context("when scheduling a busybox command in a pod", func() {
		podName := "busybox-scheduling-" + string(uuid.NewUUID())
		It("it should print the output to logs [Conformance]", func() {
			podClient.CreateSync(&v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name: podName,
				},
				Spec: v1.PodSpec{
					// Don't restart the Pod since it is expected to exit
					RestartPolicy: v1.RestartPolicyNever,
					Containers: []v1.Container{
						{
							Image:   "gcr.io/google_containers/busybox:1.24",
							Name:    podName,
							Command: []string{"sh", "-c", "echo 'Hello World' ; sleep 240"},
						},
					},
				},
			})
			Eventually(func() string {
				sinceTime := metav1.NewTime(time.Now().Add(time.Duration(-1 * time.Hour)))
				rc, err := podClient.GetLogs(podName, &v1.PodLogOptions{SinceTime: &sinceTime}).Stream()
				if err != nil {
					return ""
				}
				defer rc.Close()
				buf := new(bytes.Buffer)
				buf.ReadFrom(rc)
				return buf.String()
			}, time.Minute, time.Second*4).Should(Equal("Hello World\n"))
		})
	})
	Context("when scheduling a busybox command that always fails in a pod", func() {
		var podName string

		BeforeEach(func() {
			podName = "bin-false" + string(uuid.NewUUID())
			podClient.Create(&v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name: podName,
				},
				Spec: v1.PodSpec{
					// Don't restart the Pod since it is expected to exit
					RestartPolicy: v1.RestartPolicyNever,
					Containers: []v1.Container{
						{
							Image:   "gcr.io/google_containers/busybox:1.24",
							Name:    podName,
							Command: []string{"/bin/false"},
						},
					},
				},
			})
		})

		It("should have an error terminated reason", func() {
			Eventually(func() error {
				podData, err := podClient.Get(podName, metav1.GetOptions{})
				if err != nil {
					return err
				}
				if len(podData.Status.ContainerStatuses) != 1 {
					return fmt.Errorf("expected only one container in the pod %q", podName)
				}
				contTerminatedState := podData.Status.ContainerStatuses[0].State.Terminated
				if contTerminatedState == nil {
					return fmt.Errorf("expected state to be terminated. Got pod status: %+v", podData.Status)
				}
				if contTerminatedState.Reason != "Error" {
					return fmt.Errorf("expected terminated state reason to be error. Got %+v", contTerminatedState)
				}
				return nil
			}, time.Minute, time.Second*4).Should(BeNil())
		})

		It("should be possible to delete", func() {
			err := podClient.Delete(podName, &metav1.DeleteOptions{})
			Expect(err).To(BeNil(), fmt.Sprintf("Error deleting Pod %v", err))
		})
	})
	Context("when scheduling a read only busybox container", func() {
		podName := "busybox-readonly-fs" + string(uuid.NewUUID())
		It("it should not write to root filesystem [Conformance]", func() {
			isReadOnly := true
			podClient.CreateSync(&v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name: podName,
				},
				Spec: v1.PodSpec{
					// Don't restart the Pod since it is expected to exit
					RestartPolicy: v1.RestartPolicyNever,
					Containers: []v1.Container{
						{
							Image:   "gcr.io/google_containers/busybox:1.24",
							Name:    podName,
							Command: []string{"/bin/sh", "-c", "echo test > /file; sleep 240"},
							SecurityContext: &v1.SecurityContext{
								ReadOnlyRootFilesystem: &isReadOnly,
							},
						},
					},
				},
			})
			Eventually(func() string {
				rc, err := podClient.GetLogs(podName, &v1.PodLogOptions{}).Stream()
				if err != nil {
					return ""
				}
				defer rc.Close()
				buf := new(bytes.Buffer)
				buf.ReadFrom(rc)
				return buf.String()
			}, time.Minute, time.Second*4).Should(Equal("/bin/sh: can't create /file: Read-only file system\n"))
		})
	})
})
<|endoftext|>


<commit_before>package xmlrpc

import (
	"reflect"
	"fmt"
)

func Params(params ...) []ParamValue {
	pStruct := reflect.NewValue(params).(*reflect.StructValue)
	par := make([]ParamValue, pStruct.NumField())

	for n := 0; n < len(par); n++ {
		par[n] = param(pStruct.Field(n))
	}
	return par
}

func structParams(v *reflect.StructValue) StructValue {
	p := make(StructValue, v.NumField())
	for n := 0; n < v.NumField(); n++ {
		key := v.Type().(*reflect.StructType).Field(n).Name
		p[key] = param(v.Field(n))
	}
	return p
}

func byteParams(params *reflect.SliceValue) Base64Value {
	par := make([]byte, params.Len())

	for n := 0; n < len(par); n++ {
		par[n] = params.Elem(n).(*reflect.Uint8Value).Get()
	}
	return Base64Value(par)
}

func arrayParams(params *reflect.SliceValue) ArrayValue {
	par := make([]ParamValue, params.Len())

	for n := 0; n < len(par); n++ {
		par[n] = param(params.Elem(n))
	}
	return par
}

func param(param interface{}) ParamValue {
	switch v := param.(type) {
	case *reflect.IntValue:
		return IntValue(v.Get())
	case *reflect.BoolValue:
		return BooleanValue(v.Get())
	case *reflect.StringValue:
		return StringValue(v.Get())
	case *reflect.FloatValue:
		return DoubleValue(v.Get())
	case *reflect.SliceValue:
		if _, ok := v.Type().(*reflect.SliceType).Elem().(*reflect.Uint8Type); ok { // A []byte is really a Base64Type
			return byteParams(v)
		}
		return arrayParams(v)
	case *reflect.StructValue:
		return structParams(v)
	}
	return StringValue(fmt.Sprintf("Error: Unknown Param Type (%T)\n", param))
}
<commit_msg>Added comments<commit_after>package xmlrpc

import (
	"reflect"
	"fmt"
)

// Given a list of args return an array of `ParamValue`s
func Params(params ...) []ParamValue {
	pStruct := reflect.NewValue(params).(*reflect.StructValue)
	par := make([]ParamValue, pStruct.NumField())

	for n := 0; n < len(par); n++ {
		par[n] = param(pStruct.Field(n))
	}
	return par
}

func structParams(v *reflect.StructValue) StructValue {
	p := make(StructValue, v.NumField())
	for n := 0; n < v.NumField(); n++ {
		key := v.Type().(*reflect.StructType).Field(n).Name
		p[key] = param(v.Field(n))
	}
	return p
}

func byteParams(params *reflect.SliceValue) Base64Value {
	par := make([]byte, params.Len())

	for n := 0; n < len(par); n++ {
		par[n] = params.Elem(n).(*reflect.Uint8Value).Get()
	}
	return Base64Value(par)
}

func arrayParams(params *reflect.SliceValue) ArrayValue {
	par := make([]ParamValue, params.Len())

	for n := 0; n < len(par); n++ {
		par[n] = param(params.Elem(n))
	}
	return par
}

func param(param interface{}) ParamValue {
	switch v := param.(type) {
	case *reflect.IntValue:
		return IntValue(v.Get())
	case *reflect.BoolValue:
		return BooleanValue(v.Get())
	case *reflect.StringValue:
		return StringValue(v.Get())
	case *reflect.FloatValue:
		return DoubleValue(v.Get())
	case *reflect.SliceValue:
		if _, ok := v.Type().(*reflect.SliceType).Elem().(*reflect.Uint8Type); ok { // A []byte is really a Base64Type
			return byteParams(v)
		}
		return arrayParams(v)
	case *reflect.StructValue:
		return structParams(v)
	}
	return StringValue(fmt.Sprintf("Error: Unknown Param Type (%T)\n", param))
}
<|endoftext|>


<commit_before>package xz

/*
#cgo LDFLAGS: -llzma
#include <lzma.h>
*/
import "C"

import _ "unsafe"

// Provide thin wrappers around functions and constants provided by the liblzma
// library. The liblzma library by Lasse Collin is used because there are no
// available pure Go implementations that support the newer xz file format.

// Status code constants.
const lzma_OK = C.LZMA_OK
const lzma_STREAM_END = C.LZMA_STREAM_END
const lzma_NO_CHECK = C.LZMA_NO_CHECK
const lzma_UNSUPPORTED_CHECK = C.LZMA_UNSUPPORTED_CHECK
const lzma_GET_CHECK = C.LZMA_GET_CHECK
const lzma_MEM_ERROR = C.LZMA_MEM_ERROR
const lzma_MEMLIMIT_ERROR = C.LZMA_MEMLIMIT_ERROR
const lzma_FORMAT_ERROR = C.LZMA_FORMAT_ERROR
const lzma_OPTIONS_ERROR = C.LZMA_OPTIONS_ERROR
const lzma_DATA_ERROR = C.LZMA_DATA_ERROR
const lzma_BUF_ERROR = C.LZMA_BUF_ERROR
const lzma_PROG_ERROR = C.LZMA_PROG_ERROR

// Flushing mode constants.
const lzma_RUN = C.LZMA_RUN
const lzma_SYNC_FLUSH = C.LZMA_SYNC_FLUSH
const lzma_FULL_FLUSH = C.LZMA_FULL_FLUSH
const lzma_FINISH = C.LZMA_FINISH

// Go error wrapper for underlying liblzma errors.
type zerr struct {
	code int
}

func newZerr(z *lzmaStream, code C.int) error {
	if code == lzma_OK {
		return nil
	} else {
		return &zerr{int(code)}
	}
}

func (ze *zerr) Error() string {
	name := "[UNKNOWN] Unknown error"
	switch ze.code {
	case lzma_STREAM_END:
		name = "[STREAM_END] End of stream was reached"
	case lzma_NO_CHECK:
		name = "[NO_CHECK] Input stream has no integrity check"
	case lzma_UNSUPPORTED_CHECK:
		name = "[UNSUPPORTED_CHECK] Cannot calculate the integrity check"
	case lzma_GET_CHECK:
		name = "[GET_CHECK] Integrity check type is now available"
	case lzma_MEM_ERROR:
		name = "[MEM_ERROR] Cannot allocate memory"
	case lzma_MEMLIMIT_ERROR:
		name = "[MEMLIMIT_ERROR] Memory usage limit was reached"
	case lzma_FORMAT_ERROR:
		name = "[FORMAT_ERROR] File format not recognized"
	case lzma_OPTIONS_ERROR:
		name = "[OPTIONS_ERROR] Invalid or unsupported options"
	case lzma_DATA_ERROR:
		name = "[DATA_ERROR] Data is corrupt"
	case lzma_BUF_ERROR:
		name = "[BUF_ERROR] No progress is possible"
	case lzma_PROG_ERROR:
		name = "[PROG_ERROR] Programming error"
	}
	return name
}

func zerrMatch(err error, errnoMatches ...int) bool {
	if ze, ok := err.(*zerr); ok {
		for _, errMatch := range errnoMatches {
			if ze.code == errMatch {
				return true
			}
		}
	}
	return false
}

func zerrIgnore(err error, errnoIgns ...int) error {
	if zerrMatch(err, errnoIgns...) {
		return nil
	}
	return err
}

// Go wrapper around the liblzma stream struct.
type lzmaStream C.lzma_stream
<commit_msg>Finish Go bindings for basic liblzma functions<commit_after>package xz

/*
#cgo LDFLAGS: -llzma
#include "lzma.h"

void initStream(lzma_stream* strm) {
	lzma_stream _strm = LZMA_STREAM_INIT;
	(*strm) = _strm;
}
*/
import "C"

import "unsafe"
import "reflect"

// Provide thin wrappers around functions and constants provided by the liblzma
// library. The liblzma library by Lasse Collin is used because there are no
// available pure Go implementations that support the newer xz file format.

// Status code constants.
const lzma_OK = C.LZMA_OK
const lzma_STREAM_END = C.LZMA_STREAM_END
const lzma_NO_CHECK = C.LZMA_NO_CHECK
const lzma_UNSUPPORTED_CHECK = C.LZMA_UNSUPPORTED_CHECK
const lzma_GET_CHECK = C.LZMA_GET_CHECK
const lzma_MEM_ERROR = C.LZMA_MEM_ERROR
const lzma_MEMLIMIT_ERROR = C.LZMA_MEMLIMIT_ERROR
const lzma_FORMAT_ERROR = C.LZMA_FORMAT_ERROR
const lzma_OPTIONS_ERROR = C.LZMA_OPTIONS_ERROR
const lzma_DATA_ERROR = C.LZMA_DATA_ERROR
const lzma_BUF_ERROR = C.LZMA_BUF_ERROR
const lzma_PROG_ERROR = C.LZMA_PROG_ERROR

// Flushing mode constants.
const lzma_RUN = C.LZMA_RUN
const lzma_SYNC_FLUSH = C.LZMA_SYNC_FLUSH
const lzma_FULL_FLUSH = C.LZMA_FULL_FLUSH
const lzma_FINISH = C.LZMA_FINISH

// Encoder flag constants.
const lzma_PRESET_DEFAULT = C.LZMA_PRESET_DEFAULT
const lzma_PRESET_LEVEL_MASK = C.LZMA_PRESET_LEVEL_MASK
const lzma_PRESET_EXTREME = C.LZMA_PRESET_EXTREME

// Decoder flag constants.
const lzma_TELL_NO_CHECK = C.LZMA_TELL_NO_CHECK
const lzma_TELL_UNSUPPORTED_CHECK = C.LZMA_TELL_UNSUPPORTED_CHECK
const lzma_TELL_ANY_CHECK = C.LZMA_TELL_ANY_CHECK
const lzma_CONCATENATED = C.LZMA_CONCATENATED

// Integrity check constants.
const lzma_CHECK_NONE = C.LZMA_CHECK_NONE
const lzma_CHECK_CRC32 = C.LZMA_CHECK_CRC32
const lzma_CHECK_CRC64 = C.LZMA_CHECK_CRC64
const lzma_CHECK_SHA256 = C.LZMA_CHECK_SHA256

// Go error wrapper for underlying liblzma errors.
type lzmaErr struct {
	code int
}

func newLzmaErr(code C.lzma_ret) error {
	if code == lzma_OK {
		return nil
	} else {
		return &lzmaErr{int(code)}
	}
}

func (ze *lzmaErr) Error() string {
	name := "[UNKNOWN] Unknown error"
	switch ze.code {
	case lzma_STREAM_END:
		name = "[STREAM_END] End of stream was reached"
	case lzma_NO_CHECK:
		name = "[NO_CHECK] Input stream has no integrity check"
	case lzma_UNSUPPORTED_CHECK:
		name = "[UNSUPPORTED_CHECK] Cannot calculate the integrity check"
	case lzma_GET_CHECK:
		name = "[GET_CHECK] Integrity check type is now available"
	case lzma_MEM_ERROR:
		name = "[MEM_ERROR] Cannot allocate memory"
	case lzma_MEMLIMIT_ERROR:
		name = "[MEMLIMIT_ERROR] Memory usage limit was reached"
	case lzma_FORMAT_ERROR:
		name = "[FORMAT_ERROR] File format not recognized"
	case lzma_OPTIONS_ERROR:
		name = "[OPTIONS_ERROR] Invalid or unsupported options"
	case lzma_DATA_ERROR:
		name = "[DATA_ERROR] Data is corrupt"
	case lzma_BUF_ERROR:
		name = "[BUF_ERROR] No progress is possible"
	case lzma_PROG_ERROR:
		name = "[PROG_ERROR] Programming error"
	}
	return name
}

func lzmaErrMatch(err error, errnoMatches ...int) bool {
	if ze, ok := err.(*lzmaErr); ok {
		for _, errMatch := range errnoMatches {
			if ze.code == errMatch {
				return true
			}
		}
	}
	return false
}

func lzmaErrIgnore(err error, errnoIgns ...int) error {
	if lzmaErrMatch(err, errnoIgns...) {
		return nil
	}
	return err
}

// Go wrapper around the liblzma stream struct.
type lzmaStream C.lzma_stream

// Return a pointer to a blank version of a lzma_stream.
func newStream() *lzmaStream {
	strm := new(lzmaStream)
	C.initStream((*C.lzma_stream)(strm))
	return strm
}

// Initialize a compressor stream.
func encodeInit(preset int, check int) (*lzmaStream, error) {
	strm := newStream()
	err := newLzmaErr(C.lzma_easy_encoder(
		(*C.lzma_stream)(strm),
		C.uint32_t(preset),
		C.lzma_check(check),
	))
	if (err != nil) {
		strm = nil
	}
	return strm, err
}

// Initialize a decompressor stream.
func decodeInit(memLimit int64, flags int) (*lzmaStream, error) {
	strm := newStream()
	err := newLzmaErr(C.lzma_auto_decoder(
		(*C.lzma_stream)(strm),
		(C.uint64_t)(memLimit),
		(C.uint32_t)(flags),
	))
	if (err != nil) {
		strm = nil
	}
	return strm, err
}

// Generic lzma function to either encode or decode.
func (z *lzmaStream) code(action int) error {
	return newLzmaErr(C.lzma_code(
		(*C.lzma_stream)(z),
		(C.lzma_action(action)),
	))
}

// Clean up the lzma stream.
func (z *lzmaStream) end() {
	C.lzma_end((*C.lzma_stream)(z))
}

// Set a Go slice as the input buffer.
func (z *lzmaStream) setInput(buffer []byte) {
	bufPtr, bufLen := slicePtrLen(buffer)
	z.next_in = (*C.uint8_t)(unsafe.Pointer(bufPtr))
	z.avail_in = C.size_t(bufLen)
}

// Set a Go slice as the output buffer.
func (z *lzmaStream) setOutput(buffer []byte) {
	bufPtr, bufLen := slicePtrLen(buffer)
	z.next_out = (*C.uint8_t)(unsafe.Pointer(bufPtr))
	z.avail_out = C.size_t(bufLen)
}

// Split a Go slice into a C pointer and length.
func slicePtrLen(data []byte) (uintptr, int) {
	dataSlice := (*reflect.SliceHeader)(unsafe.Pointer(&data))
	return dataSlice.Data, dataSlice.Len
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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 integration

import (
	"flag"
	"fmt"
	"math"
	"os"
	"runtime"
	"strconv"
	"strings"
	"testing"
	"time"

	"k8s.io/minikube/pkg/minikube/constants"
	"k8s.io/minikube/pkg/minikube/driver"
)

// General configuration: used to set the VM Driver
var startArgs = flag.String("minikube-start-args", "", "Arguments to pass to minikube start")

// Flags for faster local integration testing
var forceProfile = flag.String("profile", "", "force tests to run against a particular profile")
var cleanup = flag.Bool("cleanup", true, "cleanup failed test run")
var enableGvisor = flag.Bool("gvisor", false, "run gvisor integration test (slow)")
var postMortemLogs = flag.Bool("postmortem-logs", true, "show logs after a failed test run")
var timeOutMultiplier = flag.Float64("timeout-multiplier", 1, "multiply the timeout for the tests")

// Paths to files - normally set for CI
var binaryPath = flag.String("binary", "../../out/minikube", "path to minikube binary")
var testdataDir = flag.String("testdata-dir", "testdata", "the directory relative to test/integration where the testdata lives")

// Node names are consistent, let's store these for easy access later
const (
	SecondNodeName = "m02"
	ThirdNodeName  = "m03"
)

// TestMain is the test main
func TestMain(m *testing.M) {
	flag.Parse()
	setMaxParallelism()

	start := time.Now()
	code := m.Run()
	fmt.Printf("Tests completed in %s (result code %d)\n", time.Since(start), code)
	os.Exit(code)
}

// setMaxParallelism caps the max parallelism. Go assumes 1 core per test, whereas minikube needs 2 cores per test.
func setMaxParallelism() {

	flagVal := flag.Lookup("test.parallel").Value.String()
	requested, err := strconv.Atoi(flagVal)
	if err != nil {
		fmt.Fprintf(os.Stderr, "unable to parse --test.parallel value: %q\n", flagVal)
		return
	}

	maxp := runtime.GOMAXPROCS(0)

	// Do not ignore what the user has explicitly set
	if requested != maxp {
		fmt.Fprintf(os.Stderr, "--test-parallel=%d was set via flags (system has %d cores)\n", requested, maxp)
		return
	}

	if maxp == 2 {
		fmt.Fprintf(os.Stderr, "Found %d cores, will not round down core count.\n", maxp)
		return
	}

	// Each "minikube start" consumes up to 2 cores, though the average usage is somewhat lower
	limit := int(math.Floor(float64(maxp) / 1.75))

	fmt.Fprintf(os.Stderr, "Found %d cores, limiting parallelism with --test.parallel=%d\n", maxp, limit)
	if err := flag.Set("test.parallel", strconv.Itoa(limit)); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to set test.parallel: %v\n", err)
	}
	runtime.GOMAXPROCS(limit)
}

// StartArgs returns the arguments normally used for starting minikube
func StartArgs() []string {
	return strings.Split(*startArgs, " ")
}

// Target returns where the minikube binary can be found
func Target() string {
	return *binaryPath
}

// NoneDriver returns whether or not this test is using the none driver
func NoneDriver() bool {
	return strings.Contains(*startArgs, "--driver=none") || strings.Contains(*startArgs, "--vm-driver=none")
}

// HyperVDriver returns whether or not this test is using the Hyper-V driver
func HyperVDriver() bool {
	return strings.Contains(*startArgs, "--driver=hyperv") || strings.Contains(*startArgs, "--vm-driver=hyperv")
}

// DockerDriver returns whether or not this test is using the docker or podman driver
func DockerDriver() bool {
	return strings.Contains(*startArgs, "--driver=docker") || strings.Contains(*startArgs, "--vm-driver=docker")
}

// PodmanDriver returns whether or not this test is using the docker or podman driver
func PodmanDriver() bool {
	return strings.Contains(*startArgs, "--vm-driver=podman") || strings.Contains(*startArgs, "driver=podman")
}

// KicDriver returns whether or not this test is using the docker or podman driver
func KicDriver() bool {
	return DockerDriver() || PodmanDriver()
}

// ContainerRuntime returns the name of a specific container runtime if it was specified
func ContainerRuntime() string {
	flag := "--container-runtime="
	if !strings.Contains(*startArgs, flag) {
		return constants.DefaultContainerRuntime
	}
	for _, s := range StartArgs() {
		if strings.HasPrefix(s, flag) {
			return strings.TrimPrefix(s, flag)
		}
	}
	return ""
}

// GithubActionRunner returns true if running inside a github action runner
func GithubActionRunner() bool {
	// based on https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables
	return os.Getenv("GITHUB_ACTIONS") == "true"
}

func ContainerdContainerRuntime() bool {
	return strings.Contains(*startArgs, "--container-runtime=containerd")
}

// arm64Platform returns true if running on arm64/* platform
func arm64Platform() bool {
	return runtime.GOARCH == "arm64"
}

// NeedsPortForward returns access to endpoints with this driver needs port forwarding
// (Docker on non-Linux platforms requires ports to be forwarded to 127.0.0.1)
func NeedsPortForward() bool {
	return KicDriver() && (runtime.GOOS == "windows" || runtime.GOOS == "darwin") || driver.IsMicrosoftWSL()
}

// CanCleanup returns if cleanup is allowed
func CanCleanup() bool {
	return *cleanup
}

// Minutes will return timeout in minutes based on how slow the machine is
func Minutes(n int) time.Duration {
	return time.Duration(*timeOutMultiplier) * time.Duration(n) * time.Minute
}

// Seconds will return timeout in minutes based on how slow the machine is
func Seconds(n int) time.Duration {
	return time.Duration(*timeOutMultiplier) * time.Duration(n) * time.Second
}

// TestingKicBaseImage will return true if the integraiton test is running against a passed --base-image flag
func TestingKicBaseImage() bool {
	return strings.Contains(*startArgs, "base-image")
}
<commit_msg>fix function<commit_after>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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 integration

import (
	"flag"
	"fmt"
	"math"
	"os"
	"runtime"
	"strconv"
	"strings"
	"testing"
	"time"

	"k8s.io/minikube/pkg/minikube/constants"
	"k8s.io/minikube/pkg/minikube/driver"
)

// General configuration: used to set the VM Driver
var startArgs = flag.String("minikube-start-args", "", "Arguments to pass to minikube start")

// Flags for faster local integration testing
var forceProfile = flag.String("profile", "", "force tests to run against a particular profile")
var cleanup = flag.Bool("cleanup", true, "cleanup failed test run")
var enableGvisor = flag.Bool("gvisor", false, "run gvisor integration test (slow)")
var postMortemLogs = flag.Bool("postmortem-logs", true, "show logs after a failed test run")
var timeOutMultiplier = flag.Float64("timeout-multiplier", 1, "multiply the timeout for the tests")

// Paths to files - normally set for CI
var binaryPath = flag.String("binary", "../../out/minikube", "path to minikube binary")
var testdataDir = flag.String("testdata-dir", "testdata", "the directory relative to test/integration where the testdata lives")

// Node names are consistent, let's store these for easy access later
const (
	SecondNodeName = "m02"
	ThirdNodeName  = "m03"
)

// TestMain is the test main
func TestMain(m *testing.M) {
	flag.Parse()
	setMaxParallelism()

	start := time.Now()
	code := m.Run()
	fmt.Printf("Tests completed in %s (result code %d)\n", time.Since(start), code)
	os.Exit(code)
}

// setMaxParallelism caps the max parallelism. Go assumes 1 core per test, whereas minikube needs 2 cores per test.
func setMaxParallelism() {

	flagVal := flag.Lookup("test.parallel").Value.String()
	requested, err := strconv.Atoi(flagVal)
	if err != nil {
		fmt.Fprintf(os.Stderr, "unable to parse --test.parallel value: %q\n", flagVal)
		return
	}

	maxp := runtime.GOMAXPROCS(0)

	// Do not ignore what the user has explicitly set
	if requested != maxp {
		fmt.Fprintf(os.Stderr, "--test-parallel=%d was set via flags (system has %d cores)\n", requested, maxp)
		return
	}

	if maxp == 2 {
		fmt.Fprintf(os.Stderr, "Found %d cores, will not round down core count.\n", maxp)
		return
	}

	// Each "minikube start" consumes up to 2 cores, though the average usage is somewhat lower
	limit := int(math.Floor(float64(maxp) / 1.75))

	fmt.Fprintf(os.Stderr, "Found %d cores, limiting parallelism with --test.parallel=%d\n", maxp, limit)
	if err := flag.Set("test.parallel", strconv.Itoa(limit)); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to set test.parallel: %v\n", err)
	}
	runtime.GOMAXPROCS(limit)
}

// StartArgs returns the arguments normally used for starting minikube
func StartArgs() []string {
	return strings.Split(*startArgs, " ")
}

// Target returns where the minikube binary can be found
func Target() string {
	return *binaryPath
}

// NoneDriver returns whether or not this test is using the none driver
func NoneDriver() bool {
	return strings.Contains(*startArgs, "--driver=none") || strings.Contains(*startArgs, "--vm-driver=none")
}

// HyperVDriver returns whether or not this test is using the Hyper-V driver
func HyperVDriver() bool {
	return strings.Contains(*startArgs, "--driver=hyperv") || strings.Contains(*startArgs, "--vm-driver=hyperv")
}

// DockerDriver returns whether or not this test is using the docker or podman driver
func DockerDriver() bool {
	return strings.Contains(*startArgs, "--driver=docker") || strings.Contains(*startArgs, "--vm-driver=docker")
}

// PodmanDriver returns whether or not this test is using the docker or podman driver
func PodmanDriver() bool {
	return strings.Contains(*startArgs, "--vm-driver=podman") || strings.Contains(*startArgs, "driver=podman")
}

// KicDriver returns whether or not this test is using the docker or podman driver
func KicDriver() bool {
	return DockerDriver() || PodmanDriver()
}

// ContainerRuntime returns the name of a specific container runtime if it was specified
func ContainerRuntime() string {
	flag := "--container-runtime="
	for _, s := range StartArgs() {
		if strings.HasPrefix(s, flag) {
			return strings.TrimPrefix(s, flag)
		}
	}
	return constants.DefaultContainerRuntime
}

// GithubActionRunner returns true if running inside a github action runner
func GithubActionRunner() bool {
	// based on https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables
	return os.Getenv("GITHUB_ACTIONS") == "true"
}

func ContainerdContainerRuntime() bool {
	return strings.Contains(*startArgs, "--container-runtime=containerd")
}

// arm64Platform returns true if running on arm64/* platform
func arm64Platform() bool {
	return runtime.GOARCH == "arm64"
}

// NeedsPortForward returns access to endpoints with this driver needs port forwarding
// (Docker on non-Linux platforms requires ports to be forwarded to 127.0.0.1)
func NeedsPortForward() bool {
	return KicDriver() && (runtime.GOOS == "windows" || runtime.GOOS == "darwin") || driver.IsMicrosoftWSL()
}

// CanCleanup returns if cleanup is allowed
func CanCleanup() bool {
	return *cleanup
}

// Minutes will return timeout in minutes based on how slow the machine is
func Minutes(n int) time.Duration {
	return time.Duration(*timeOutMultiplier) * time.Duration(n) * time.Minute
}

// Seconds will return timeout in minutes based on how slow the machine is
func Seconds(n int) time.Duration {
	return time.Duration(*timeOutMultiplier) * time.Duration(n) * time.Second
}

// TestingKicBaseImage will return true if the integraiton test is running against a passed --base-image flag
func TestingKicBaseImage() bool {
	return strings.Contains(*startArgs, "base-image")
}
<|endoftext|>


<commit_before>package lncfg

import (
	"context"
	"crypto/tls"
	"encoding/hex"
	"fmt"
	"net"
	"strconv"
	"strings"

	"github.com/btcsuite/btcd/btcec"
	"github.com/lightningnetwork/lnd/lnwire"
	"github.com/lightningnetwork/lnd/tor"
)

var (
	loopBackAddrs = []string{"localhost", "127.0.0.1", "[::1]"}
)

// TCPResolver is a function signature that resolves an address on a given
// network.
type TCPResolver = func(network, addr string) (*net.TCPAddr, error)

// NormalizeAddresses returns a new slice with all the passed addresses
// normalized with the given default port and all duplicates removed.
func NormalizeAddresses(addrs []string, defaultPort string,
	tcpResolver TCPResolver) ([]net.Addr, error) {

	result := make([]net.Addr, 0, len(addrs))
	seen := map[string]struct{}{}

	for _, addr := range addrs {
		parsedAddr, err := ParseAddressString(
			addr, defaultPort, tcpResolver,
		)
		if err != nil {
			return nil, err
		}

		if _, ok := seen[parsedAddr.String()]; !ok {
			result = append(result, parsedAddr)
			seen[parsedAddr.String()] = struct{}{}
		}
	}

	return result, nil
}

// EnforceSafeAuthentication enforces "safe" authentication taking into account
// the interfaces that the RPC servers are listening on, and if macaroons and
// TLS is activated or not. To protect users from using dangerous config
// combinations, we'll prevent disabling authentication if the server is
// listening on a public interface.
func EnforceSafeAuthentication(addrs []net.Addr, macaroonsActive,
	tlsActive bool) error {

	// We'll now examine all addresses that this RPC server is listening
	// on. If it's a localhost address or a private address, we'll skip it,
	// otherwise, we'll return an error if macaroons are inactive.
	for _, addr := range addrs {
		if IsLoopback(addr.String()) || IsUnix(addr) || IsPrivate(addr) {
			continue
		}

		if !macaroonsActive {
			return fmt.Errorf("detected RPC server listening on "+
				"publicly reachable interface %v with "+
				"authentication disabled! Refusing to start "+
				"with --no-macaroons specified", addr)
		}

		if !tlsActive {
			return fmt.Errorf("detected RPC server listening on "+
				"publicly reachable interface %v with "+
				"encryption disabled! Refusing to start "+
				"with --notls specified", addr)
		}
	}

	return nil
}

// parseNetwork parses the network type of the given address.
func parseNetwork(addr net.Addr) string {
	switch addr := addr.(type) {
	// TCP addresses resolved through net.ResolveTCPAddr give a default
	// network of "tcp", so we'll map back the correct network for the given
	// address. This ensures that we can listen on the correct interface
	// (IPv4 vs IPv6).
	case *net.TCPAddr:
		if addr.IP.To4() != nil {
			return "tcp4"
		}
		return "tcp6"

	default:
		return addr.Network()
	}
}

// ListenOnAddress creates a listener that listens on the given address.
func ListenOnAddress(addr net.Addr) (net.Listener, error) {
	return net.Listen(parseNetwork(addr), addr.String())
}

// TLSListenOnAddress creates a TLS listener that listens on the given address.
func TLSListenOnAddress(addr net.Addr,
	config *tls.Config) (net.Listener, error) {
	return tls.Listen(parseNetwork(addr), addr.String(), config)
}

// IsLoopback returns true if an address describes a loopback interface.
func IsLoopback(addr string) bool {
	for _, loopback := range loopBackAddrs {
		if strings.Contains(addr, loopback) {
			return true
		}
	}

	return false
}

// IsUnix returns true if an address describes an Unix socket address.
func IsUnix(addr net.Addr) bool {
	return strings.HasPrefix(addr.Network(), "unix")
}

// IsPrivate returns true if the address is private. The definitions are,
//   https://en.wikipedia.org/wiki/Link-local_address
//   https://en.wikipedia.org/wiki/Multicast_address
//   Local IPv4 addresses, https://tools.ietf.org/html/rfc1918
//   Local IPv6 addresses, https://tools.ietf.org/html/rfc4193
func IsPrivate(addr net.Addr) bool {
	switch addr := addr.(type) {
	case *net.TCPAddr:
		// Check 169.254.0.0/16 and fe80::/10.
		if addr.IP.IsLinkLocalUnicast() {
			return true
		}

		// Check 224.0.0.0/4 and ff00::/8.
		if addr.IP.IsLinkLocalMulticast() {
			return true
		}

		// Check 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16.
		if ip4 := addr.IP.To4(); ip4 != nil {
			return ip4[0] == 10 ||
				(ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
				(ip4[0] == 192 && ip4[1] == 168)
		}

		// Check fc00::/7.
		return len(addr.IP) == net.IPv6len && addr.IP[0]&0xfe == 0xfc

	default:
		return false
	}
}

// ParseAddressString converts an address in string format to a net.Addr that is
// compatible with lnd. UDP is not supported because lnd needs reliable
// connections. We accept a custom function to resolve any TCP addresses so
// that caller is able control exactly how resolution is performed.
func ParseAddressString(strAddress string, defaultPort string,
	tcpResolver TCPResolver) (net.Addr, error) {

	var parsedNetwork, parsedAddr string

	// Addresses can either be in network://address:port format,
	// network:address:port, address:port, or just port. We want to support
	// all possible types.
	if strings.Contains(strAddress, "://") {
		parts := strings.Split(strAddress, "://")
		parsedNetwork, parsedAddr = parts[0], parts[1]
	} else if strings.Contains(strAddress, ":") {
		parts := strings.Split(strAddress, ":")
		parsedNetwork = parts[0]
		parsedAddr = strings.Join(parts[1:], ":")
	}

	// Only TCP and Unix socket addresses are valid. We can't use IP or
	// UDP only connections for anything we do in lnd.
	switch parsedNetwork {
	case "unix", "unixpacket":
		return net.ResolveUnixAddr(parsedNetwork, parsedAddr)

	case "tcp", "tcp4", "tcp6":
		return tcpResolver(
			parsedNetwork, verifyPort(parsedAddr, defaultPort),
		)

	case "ip", "ip4", "ip6", "udp", "udp4", "udp6", "unixgram":
		return nil, fmt.Errorf("only TCP or unix socket "+
			"addresses are supported: %s", parsedAddr)

	default:
		// We'll now possibly apply the default port, use the local
		// host short circuit, or parse out an all interfaces listen.
		addrWithPort := verifyPort(strAddress, defaultPort)
		rawHost, rawPort, _ := net.SplitHostPort(addrWithPort)

		// If we reach this point, then we'll check to see if we have
		// an onion addresses, if so, we can directly pass the raw
		// address and port to create the proper address.
		if tor.IsOnionHost(rawHost) {
			portNum, err := strconv.Atoi(rawPort)
			if err != nil {
				return nil, err
			}

			return &tor.OnionAddr{
				OnionService: rawHost,
				Port:         portNum,
			}, nil
		}

		// Otherwise, we'll attempt the resolve the host. The Tor
		// resolver is unable to resolve local addresses, so we'll use
		// the system resolver instead.
		if rawHost == "" || IsLoopback(rawHost) {
			return net.ResolveTCPAddr("tcp", addrWithPort)
		}

		return tcpResolver("tcp", addrWithPort)
	}
}

// ParseLNAddressString converts a string of the form <pubkey>@<addr> into an
// lnwire.NetAddress. The <pubkey> must be presented in hex, and result in a
// 33-byte, compressed public key that lies on the secp256k1 curve. The <addr>
// may be any address supported by ParseAddressString. If no port is specified,
// the defaultPort will be used. Any tcp addresses that need resolving will be
// resolved using the custom TCPResolver.
func ParseLNAddressString(strAddress string, defaultPort string,
	tcpResolver TCPResolver) (*lnwire.NetAddress, error) {

	// Split the address string around the @ sign.
	parts := strings.Split(strAddress, "@")

	// The string is malformed if there are not exactly two parts.
	if len(parts) != 2 {
		return nil, fmt.Errorf("invalid lightning address %s: "+
			"must be of the form <pubkey-hex>@<addr>", strAddress)
	}

	// Now, take the first portion as the hex pubkey, and the latter as the
	// address string.
	parsedPubKey, parsedAddr := parts[0], parts[1]

	// Decode the hex pubkey to get the raw compressed pubkey bytes.
	pubKeyBytes, err := hex.DecodeString(parsedPubKey)
	if err != nil {
		return nil, fmt.Errorf("invalid lightning address pubkey: %v", err)
	}

	// The compressed pubkey should have a length of exactly 33 bytes.
	if len(pubKeyBytes) != 33 {
		return nil, fmt.Errorf("invalid lightning address pubkey: "+
			"length must be 33 bytes, found %d", len(pubKeyBytes))
	}

	// Parse the pubkey bytes to verify that it corresponds to valid public
	// key on the secp256k1 curve.
	pubKey, err := btcec.ParsePubKey(pubKeyBytes, btcec.S256())
	if err != nil {
		return nil, fmt.Errorf("invalid lightning address pubkey: %v", err)
	}

	// Finally, parse the address string using our generic address parser.
	addr, err := ParseAddressString(parsedAddr, defaultPort, tcpResolver)
	if err != nil {
		return nil, fmt.Errorf("invalid lightning address address: %v", err)
	}

	return &lnwire.NetAddress{
		IdentityKey: pubKey,
		Address:     addr,
	}, nil
}

// verifyPort makes sure that an address string has both a host and a port. If
// there is no port found, the default port is appended. If the address is just
// a port, then we'll assume that the user is using the short cut to specify a
// localhost:port address.
func verifyPort(address string, defaultPort string) string {
	host, port, err := net.SplitHostPort(address)
	if err != nil {
		// If the address itself is just an integer, then we'll assume
		// that we're mapping this directly to a localhost:port pair.
		// This ensures we maintain the legacy behavior.
		if _, err := strconv.Atoi(address); err == nil {
			return net.JoinHostPort("localhost", address)
		}

		// Otherwise, we'll assume that the address just failed to
		// attach its own port, so we'll use the default port. In the
		// case of IPv6 addresses, if the host is already surrounded by
		// brackets, then we'll avoid using the JoinHostPort function,
		// since it will always add a pair of brackets.
		if strings.HasPrefix(address, "[") {
			return address + ":" + defaultPort
		}
		return net.JoinHostPort(address, defaultPort)
	}

	// In the case that both the host and port are empty, we'll use the
	// default port.
	if host == "" && port == "" {
		return ":" + defaultPort
	}

	return address
}

// ClientAddressDialer creates a gRPC dialer that can also dial unix socket
// addresses instead of just TCP addresses.
func ClientAddressDialer(defaultPort string) func(context.Context,
	string) (net.Conn, error) {

	return func(ctx context.Context, addr string) (net.Conn, error) {
		parsedAddr, err := ParseAddressString(
			addr, defaultPort, net.ResolveTCPAddr,
		)
		if err != nil {
			return nil, err
		}

		d := net.Dialer{}
		return d.DialContext(
			ctx, parsedAddr.Network(), parsedAddr.String(),
		)
	}
}
<commit_msg>fix: correct no-rest-tls parameter in error message<commit_after>package lncfg

import (
	"context"
	"crypto/tls"
	"encoding/hex"
	"fmt"
	"net"
	"strconv"
	"strings"

	"github.com/btcsuite/btcd/btcec"
	"github.com/lightningnetwork/lnd/lnwire"
	"github.com/lightningnetwork/lnd/tor"
)

var (
	loopBackAddrs = []string{"localhost", "127.0.0.1", "[::1]"}
)

// TCPResolver is a function signature that resolves an address on a given
// network.
type TCPResolver = func(network, addr string) (*net.TCPAddr, error)

// NormalizeAddresses returns a new slice with all the passed addresses
// normalized with the given default port and all duplicates removed.
func NormalizeAddresses(addrs []string, defaultPort string,
	tcpResolver TCPResolver) ([]net.Addr, error) {

	result := make([]net.Addr, 0, len(addrs))
	seen := map[string]struct{}{}

	for _, addr := range addrs {
		parsedAddr, err := ParseAddressString(
			addr, defaultPort, tcpResolver,
		)
		if err != nil {
			return nil, err
		}

		if _, ok := seen[parsedAddr.String()]; !ok {
			result = append(result, parsedAddr)
			seen[parsedAddr.String()] = struct{}{}
		}
	}

	return result, nil
}

// EnforceSafeAuthentication enforces "safe" authentication taking into account
// the interfaces that the RPC servers are listening on, and if macaroons and
// TLS is activated or not. To protect users from using dangerous config
// combinations, we'll prevent disabling authentication if the server is
// listening on a public interface.
func EnforceSafeAuthentication(addrs []net.Addr, macaroonsActive,
	tlsActive bool) error {

	// We'll now examine all addresses that this RPC server is listening
	// on. If it's a localhost address or a private address, we'll skip it,
	// otherwise, we'll return an error if macaroons are inactive.
	for _, addr := range addrs {
		if IsLoopback(addr.String()) || IsUnix(addr) || IsPrivate(addr) {
			continue
		}

		if !macaroonsActive {
			return fmt.Errorf("detected RPC server listening on "+
				"publicly reachable interface %v with "+
				"authentication disabled! Refusing to start "+
				"with --no-macaroons specified", addr)
		}

		if !tlsActive {
			return fmt.Errorf("detected RPC server listening on "+
				"publicly reachable interface %v with "+
				"encryption disabled! Refusing to start "+
				"with --no-rest-tls specified", addr)
		}
	}

	return nil
}

// parseNetwork parses the network type of the given address.
func parseNetwork(addr net.Addr) string {
	switch addr := addr.(type) {
	// TCP addresses resolved through net.ResolveTCPAddr give a default
	// network of "tcp", so we'll map back the correct network for the given
	// address. This ensures that we can listen on the correct interface
	// (IPv4 vs IPv6).
	case *net.TCPAddr:
		if addr.IP.To4() != nil {
			return "tcp4"
		}
		return "tcp6"

	default:
		return addr.Network()
	}
}

// ListenOnAddress creates a listener that listens on the given address.
func ListenOnAddress(addr net.Addr) (net.Listener, error) {
	return net.Listen(parseNetwork(addr), addr.String())
}

// TLSListenOnAddress creates a TLS listener that listens on the given address.
func TLSListenOnAddress(addr net.Addr,
	config *tls.Config) (net.Listener, error) {
	return tls.Listen(parseNetwork(addr), addr.String(), config)
}

// IsLoopback returns true if an address describes a loopback interface.
func IsLoopback(addr string) bool {
	for _, loopback := range loopBackAddrs {
		if strings.Contains(addr, loopback) {
			return true
		}
	}

	return false
}

// IsUnix returns true if an address describes an Unix socket address.
func IsUnix(addr net.Addr) bool {
	return strings.HasPrefix(addr.Network(), "unix")
}

// IsPrivate returns true if the address is private. The definitions are,
//   https://en.wikipedia.org/wiki/Link-local_address
//   https://en.wikipedia.org/wiki/Multicast_address
//   Local IPv4 addresses, https://tools.ietf.org/html/rfc1918
//   Local IPv6 addresses, https://tools.ietf.org/html/rfc4193
func IsPrivate(addr net.Addr) bool {
	switch addr := addr.(type) {
	case *net.TCPAddr:
		// Check 169.254.0.0/16 and fe80::/10.
		if addr.IP.IsLinkLocalUnicast() {
			return true
		}

		// Check 224.0.0.0/4 and ff00::/8.
		if addr.IP.IsLinkLocalMulticast() {
			return true
		}

		// Check 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16.
		if ip4 := addr.IP.To4(); ip4 != nil {
			return ip4[0] == 10 ||
				(ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
				(ip4[0] == 192 && ip4[1] == 168)
		}

		// Check fc00::/7.
		return len(addr.IP) == net.IPv6len && addr.IP[0]&0xfe == 0xfc

	default:
		return false
	}
}

// ParseAddressString converts an address in string format to a net.Addr that is
// compatible with lnd. UDP is not supported because lnd needs reliable
// connections. We accept a custom function to resolve any TCP addresses so
// that caller is able control exactly how resolution is performed.
func ParseAddressString(strAddress string, defaultPort string,
	tcpResolver TCPResolver) (net.Addr, error) {

	var parsedNetwork, parsedAddr string

	// Addresses can either be in network://address:port format,
	// network:address:port, address:port, or just port. We want to support
	// all possible types.
	if strings.Contains(strAddress, "://") {
		parts := strings.Split(strAddress, "://")
		parsedNetwork, parsedAddr = parts[0], parts[1]
	} else if strings.Contains(strAddress, ":") {
		parts := strings.Split(strAddress, ":")
		parsedNetwork = parts[0]
		parsedAddr = strings.Join(parts[1:], ":")
	}

	// Only TCP and Unix socket addresses are valid. We can't use IP or
	// UDP only connections for anything we do in lnd.
	switch parsedNetwork {
	case "unix", "unixpacket":
		return net.ResolveUnixAddr(parsedNetwork, parsedAddr)

	case "tcp", "tcp4", "tcp6":
		return tcpResolver(
			parsedNetwork, verifyPort(parsedAddr, defaultPort),
		)

	case "ip", "ip4", "ip6", "udp", "udp4", "udp6", "unixgram":
		return nil, fmt.Errorf("only TCP or unix socket "+
			"addresses are supported: %s", parsedAddr)

	default:
		// We'll now possibly apply the default port, use the local
		// host short circuit, or parse out an all interfaces listen.
		addrWithPort := verifyPort(strAddress, defaultPort)
		rawHost, rawPort, _ := net.SplitHostPort(addrWithPort)

		// If we reach this point, then we'll check to see if we have
		// an onion addresses, if so, we can directly pass the raw
		// address and port to create the proper address.
		if tor.IsOnionHost(rawHost) {
			portNum, err := strconv.Atoi(rawPort)
			if err != nil {
				return nil, err
			}

			return &tor.OnionAddr{
				OnionService: rawHost,
				Port:         portNum,
			}, nil
		}

		// Otherwise, we'll attempt the resolve the host. The Tor
		// resolver is unable to resolve local addresses, so we'll use
		// the system resolver instead.
		if rawHost == "" || IsLoopback(rawHost) {
			return net.ResolveTCPAddr("tcp", addrWithPort)
		}

		return tcpResolver("tcp", addrWithPort)
	}
}

// ParseLNAddressString converts a string of the form <pubkey>@<addr> into an
// lnwire.NetAddress. The <pubkey> must be presented in hex, and result in a
// 33-byte, compressed public key that lies on the secp256k1 curve. The <addr>
// may be any address supported by ParseAddressString. If no port is specified,
// the defaultPort will be used. Any tcp addresses that need resolving will be
// resolved using the custom TCPResolver.
func ParseLNAddressString(strAddress string, defaultPort string,
	tcpResolver TCPResolver) (*lnwire.NetAddress, error) {

	// Split the address string around the @ sign.
	parts := strings.Split(strAddress, "@")

	// The string is malformed if there are not exactly two parts.
	if len(parts) != 2 {
		return nil, fmt.Errorf("invalid lightning address %s: "+
			"must be of the form <pubkey-hex>@<addr>", strAddress)
	}

	// Now, take the first portion as the hex pubkey, and the latter as the
	// address string.
	parsedPubKey, parsedAddr := parts[0], parts[1]

	// Decode the hex pubkey to get the raw compressed pubkey bytes.
	pubKeyBytes, err := hex.DecodeString(parsedPubKey)
	if err != nil {
		return nil, fmt.Errorf("invalid lightning address pubkey: %v", err)
	}

	// The compressed pubkey should have a length of exactly 33 bytes.
	if len(pubKeyBytes) != 33 {
		return nil, fmt.Errorf("invalid lightning address pubkey: "+
			"length must be 33 bytes, found %d", len(pubKeyBytes))
	}

	// Parse the pubkey bytes to verify that it corresponds to valid public
	// key on the secp256k1 curve.
	pubKey, err := btcec.ParsePubKey(pubKeyBytes, btcec.S256())
	if err != nil {
		return nil, fmt.Errorf("invalid lightning address pubkey: %v", err)
	}

	// Finally, parse the address string using our generic address parser.
	addr, err := ParseAddressString(parsedAddr, defaultPort, tcpResolver)
	if err != nil {
		return nil, fmt.Errorf("invalid lightning address address: %v", err)
	}

	return &lnwire.NetAddress{
		IdentityKey: pubKey,
		Address:     addr,
	}, nil
}

// verifyPort makes sure that an address string has both a host and a port. If
// there is no port found, the default port is appended. If the address is just
// a port, then we'll assume that the user is using the short cut to specify a
// localhost:port address.
func verifyPort(address string, defaultPort string) string {
	host, port, err := net.SplitHostPort(address)
	if err != nil {
		// If the address itself is just an integer, then we'll assume
		// that we're mapping this directly to a localhost:port pair.
		// This ensures we maintain the legacy behavior.
		if _, err := strconv.Atoi(address); err == nil {
			return net.JoinHostPort("localhost", address)
		}

		// Otherwise, we'll assume that the address just failed to
		// attach its own port, so we'll use the default port. In the
		// case of IPv6 addresses, if the host is already surrounded by
		// brackets, then we'll avoid using the JoinHostPort function,
		// since it will always add a pair of brackets.
		if strings.HasPrefix(address, "[") {
			return address + ":" + defaultPort
		}
		return net.JoinHostPort(address, defaultPort)
	}

	// In the case that both the host and port are empty, we'll use the
	// default port.
	if host == "" && port == "" {
		return ":" + defaultPort
	}

	return address
}

// ClientAddressDialer creates a gRPC dialer that can also dial unix socket
// addresses instead of just TCP addresses.
func ClientAddressDialer(defaultPort string) func(context.Context,
	string) (net.Conn, error) {

	return func(ctx context.Context, addr string) (net.Conn, error) {
		parsedAddr, err := ParseAddressString(
			addr, defaultPort, net.ResolveTCPAddr,
		)
		if err != nil {
			return nil, err
		}

		d := net.Dialer{}
		return d.DialContext(
			ctx, parsedAddr.Network(), parsedAddr.String(),
		)
	}
}
<|endoftext|>


<commit_before>package logger

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	ltsv "github.com/doloopwhile/logrusltsv"
	"os"
	"runtime"
	"strconv"
	"time"
)

func init() {
	logLevel := os.Getenv("KINU_LOG_LEVEL")

	level, err := logrus.ParseLevel(logLevel)
	if err != nil {
		Panic(err)
	}
	logrus.SetLevel(level)

	formatterType := os.Getenv("KINU_LOG_FORMAT")
	switch formatterType {
	case "json":
		logrus.SetFormatter(&logrus.JSONFormatter{})
	case "ltsv":
		logrus.SetFormatter(&ltsv.Formatter{})
	default:
		logrus.SetFormatter(&logrus.TextFormatter{})
	}

	logrus.SetOutput(os.Stdout)
}

func WithFields(fields logrus.Fields) *logrus.Entry {
	return logrus.WithFields(fields)
}

func Debug(args ...interface{}) {
	logrus.Debug(args)
}

func Info(args ...interface{}) {
	logrus.Info(args)
}

func Warn(args ...interface{}) {
	logrus.Warn(args)
}

func Error(args ...interface{}) {
	logrus.Error(args)
}

func Fatal(args ...interface{}) {
	logrus.Fatal(args)
}

func Panic(args ...interface{}) {
	logrus.Panic(args)
}

func ErrorDebug(err error) error {
	if logrus.GetLevel() > logrus.DebugLevel {
		return err
	}

	_, file, line, _ := runtime.Caller(1)
	WithFields(logrus.Fields{
		"file": file + ":" + strconv.Itoa(line),
	}).Error(err.Error())

	return err
}

func TrackResult(tag string, startTime time.Time) {
	WithFields(logrus.Fields{
		"process_time": strconv.Itoa(int(time.Now().Sub(startTime)/time.Millisecond)) + "ms",
	}).Debug(fmt.Sprintf("%s process time", tag))
}
<commit_msg>Set default log level<commit_after>package logger

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	ltsv "github.com/doloopwhile/logrusltsv"
	"os"
	"runtime"
	"strconv"
	"time"
)

func init() {
	logLevel := os.Getenv("KINU_LOG_LEVEL")

	if len(logLevel) == 0 {
		logLevel = "info"
	}

	level, err := logrus.ParseLevel(logLevel)
	if err != nil {
		Panic(err)
	}
	logrus.SetLevel(level)

	formatterType := os.Getenv("KINU_LOG_FORMAT")
	switch formatterType {
	case "json":
		logrus.SetFormatter(&logrus.JSONFormatter{})
	case "ltsv":
		logrus.SetFormatter(&ltsv.Formatter{})
	default:
		logrus.SetFormatter(&logrus.TextFormatter{})
	}

	logrus.SetOutput(os.Stdout)
}

func WithFields(fields logrus.Fields) *logrus.Entry {
	return logrus.WithFields(fields)
}

func Debug(args ...interface{}) {
	logrus.Debug(args)
}

func Info(args ...interface{}) {
	logrus.Info(args)
}

func Warn(args ...interface{}) {
	logrus.Warn(args)
}

func Error(args ...interface{}) {
	logrus.Error(args)
}

func Fatal(args ...interface{}) {
	logrus.Fatal(args)
}

func Panic(args ...interface{}) {
	logrus.Panic(args)
}

func ErrorDebug(err error) error {
	if logrus.GetLevel() > logrus.DebugLevel {
		return err
	}

	_, file, line, _ := runtime.Caller(1)
	WithFields(logrus.Fields{
		"file": file + ":" + strconv.Itoa(line),
	}).Error(err.Error())

	return err
}

func TrackResult(tag string, startTime time.Time) {
	WithFields(logrus.Fields{
		"process_time": strconv.Itoa(int(time.Now().Sub(startTime)/time.Millisecond)) + "ms",
	}).Debug(fmt.Sprintf("%s process time", tag))
}
<|endoftext|>