<commit_before>package qmp

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/pkg/errors"

	"github.com/lxc/lxd/lxd/revert"
	"github.com/lxc/lxd/shared"
)

// Status returns the current VM status.
func (m *Monitor) Status() (string, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			Status string `json:"status"`
		} `json:"return"`
	}

	// Query the status.
	err := m.run("query-status", "", &resp)
	if err != nil {
		return "", err
	}

	return resp.Return.Status, nil
}

// Console fetches the File for a particular console.
func (m *Monitor) Console(target string) (*os.File, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			Label    string `json:"label"`
			Filename string `json:"filename"`
		} `json:"return"`
	}

	// Query the consoles.
	err := m.run("query-chardev", "", &resp)
	if err != nil {
		return nil, err
	}

	// Look for the requested console.
	for _, v := range resp.Return {
		if v.Label == target {
			ptyPath := strings.TrimPrefix(v.Filename, "pty:")

			if !shared.PathExists(ptyPath) {
				continue
			}

			// Open the PTS device
			console, err := os.OpenFile(ptyPath, os.O_RDWR, 0600)
			if err != nil {
				return nil, err
			}

			return console, nil
		}
	}

	return nil, ErrMonitorBadConsole
}

// SendFile adds a new file descriptor to the QMP fd table associated to name.
func (m *Monitor) SendFile(name string, file *os.File) error {
	// Check if disconnected
	if m.disconnected {
		return ErrMonitorDisconnect
	}

	// Query the status.
	_, err := m.qmp.RunWithFile([]byte(fmt.Sprintf("{'execute': 'getfd', 'arguments': {'fdname': '%s'}}", name)), file)
	if err != nil {
		// Confirm the daemon didn't die.
		errPing := m.ping()
		if errPing != nil {
			return errPing
		}

		return err
	}

	return nil
}

// Migrate starts a migration stream.
func (m *Monitor) Migrate(uri string) error {
	// Query the status.
	err := m.run("migrate", fmt.Sprintf("{'uri': '%s'}", uri), nil)
	if err != nil {
		return err
	}

	// Wait until it completes or fails.
	for {
		time.Sleep(1 * time.Second)

		// Prepare the response.
		var resp struct {
			Return struct {
				Status string `json:"status"`
			} `json:"return"`
		}

		err := m.run("query-migrate", "", &resp)
		if err != nil {
			return err
		}

		if resp.Return.Status == "failed" {
			return fmt.Errorf("Migration call failed")
		}

		if resp.Return.Status == "completed" {
			break
		}
	}

	return nil
}

// MigrateIncoming starts the receiver of a migration stream.
func (m *Monitor) MigrateIncoming(uri string) error {
	// Query the status.
	err := m.run("migrate-incoming", fmt.Sprintf("{'uri': '%s'}", uri), nil)
	if err != nil {
		return err
	}

	// Wait until it completes or fails.
	for {
		time.Sleep(1 * time.Second)

		// Preapre the response.
		var resp struct {
			Return struct {
				Status string `json:"status"`
			} `json:"return"`
		}

		err := m.run("query-migrate", "", &resp)
		if err != nil {
			return err
		}

		if resp.Return.Status == "failed" {
			return fmt.Errorf("Migration call failed")
		}

		if resp.Return.Status == "completed" {
			break
		}
	}

	return nil
}

// Powerdown tells the VM to gracefully shutdown.
func (m *Monitor) Powerdown() error {
	return m.run("system_powerdown", "", nil)
}

// Start tells QEMU to start the emulation.
func (m *Monitor) Start() error {
	return m.run("cont", "", nil)
}

// Pause tells QEMU to temporarily stop the emulation.
func (m *Monitor) Pause() error {
	return m.run("stop", "", nil)
}

// Quit tells QEMU to exit immediately.
func (m *Monitor) Quit() error {
	return m.run("quit", "", nil)
}

// GetCPUs fetches the vCPU information for pinning.
func (m *Monitor) GetCPUs() ([]int, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			CPU int `json:"cpu-index"`
			PID int `json:"thread-id"`
		} `json:"return"`
	}

	// Query the consoles.
	err := m.run("query-cpus-fast", "", &resp)
	if err != nil {
		return nil, err
	}

	// Make a slice of PIDs.
	pids := []int{}
	for _, cpu := range resp.Return {
		pids = append(pids, cpu.PID)
	}

	return pids, nil
}

// GetMemorySizeBytes returns the current size of the base memory in bytes.
func (m *Monitor) GetMemorySizeBytes() (int64, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			BaseMemory int64 `json:"base-memory"`
		} `json:"return"`
	}

	err := m.run("query-memory-size-summary", "", &resp)
	if err != nil {
		return -1, err
	}

	return resp.Return.BaseMemory, nil
}

// GetMemoryBalloonSizeBytes returns effective size of the memory in bytes (considering the current balloon size).
func (m *Monitor) GetMemoryBalloonSizeBytes() (int64, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			Actual int64 `json:"actual"`
		} `json:"return"`
	}

	err := m.run("query-balloon", "", &resp)
	if err != nil {
		return -1, err
	}

	return resp.Return.Actual, nil
}

// SetMemoryBalloonSizeBytes sets the size of the memory in bytes (which will resize the balloon as needed).
func (m *Monitor) SetMemoryBalloonSizeBytes(sizeBytes int64) error {
	return m.run("balloon", fmt.Sprintf("{'value': %d}", sizeBytes), nil)
}

// AddNIC adds a NIC device.
func (m *Monitor) AddNIC(netDev map[string]interface{}, device map[string]string) error {
	revert := revert.New()
	defer revert.Fail()

	if netDev != nil {
		args, err := json.Marshal(netDev)
		if err != nil {
			return err
		}

		err = m.run("netdev_add", string(args), nil)
		if err != nil {
			return errors.Wrapf(err, "Failed adding NIC netdev")
		}

		revert.Add(func() {
			netDevDel := map[string]interface{}{
				"id": netDev["id"],
			}

			args, err := json.Marshal(netDevDel)
			if err != nil {
				return
			}

			err = m.run("netdev_del", string(args), nil)
			if err != nil {
				return
			}
		})
	}

	if device != nil {
		args, err := json.Marshal(device)
		if err != nil {
			return err
		}

		err = m.run("device_add", string(args), nil)
		if err != nil {
			return errors.Wrapf(err, "Failed adding NIC device")
		}
	}

	revert.Success()
	return nil
}

// RemoveNIC removes a NIC device.
func (m *Monitor) RemoveNIC(netDevID string, deviceID string) error {
	if deviceID != "" {
		deviceID := map[string]string{
			"id": deviceID,
		}

		args, err := json.Marshal(deviceID)
		if err != nil {
			return err
		}

		err = m.run("device_del", string(args), nil)
		if err != nil {
			// If the device has already been removed then all good.
			if err != nil && !strings.Contains(err.Error(), "not found") {
				return errors.Wrapf(err, "Failed removing NIC device")
			}
		}
	}

	if netDevID != "" {
		netDevID := map[string]string{
			"id": netDevID,
		}

		args, err := json.Marshal(netDevID)
		if err != nil {
			return err
		}

		err = m.run("netdev_del", string(args), nil)

		// Not all NICs need a netdev, so if its missing, its not a problem.
		if err != nil && !strings.Contains(err.Error(), "not found") {
			return errors.Wrapf(err, "Failed removing NIC netdev")
		}
	}

	return nil
}

// Reset VM.
func (m *Monitor) Reset() error {
	err := m.run("system_reset", "", nil)
	if err != nil {
		return errors.Wrapf(err, "Failed resetting")
	}

	return nil
}

// PCIClassInfo info about a device's class.
type PCIClassInfo struct {
	Class       int    `json:"class"`
	Description string `json:"desc"`
}

// PCIDevice represents a PCI device.
type PCIDevice struct {
	DevID    string       `json:"qdev_id"`
	Bus      int          `json:"bus"`
	Slot     int          `json:"slot"`
	Function int          `json:"function"`
	Devices  []PCIDevice  `json:"devices"`
	Class    PCIClassInfo `json:"class_info"`
	Bridge   PCIBridge    `json:"pci_bridge"`
}

// PCIBridge represents a PCI bridge.
type PCIBridge struct {
	Devices []PCIDevice `json:"devices"`
}

// QueryPCI returns info about PCI devices.
func (m *Monitor) QueryPCI() ([]PCIDevice, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			Devices []PCIDevice `json:"devices"`
		} `json:"return"`
	}

	err := m.run("query-pci", "", &resp)
	if err != nil {
		return nil, errors.Wrapf(err, "Failed querying PCI devices")
	}

	return resp.Return[0].Devices, nil
}
<commit_msg>lxd/instance/drivers/qmp/commands: Fixes potential crash in QueryPCI<commit_after>package qmp

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/pkg/errors"

	"github.com/lxc/lxd/lxd/revert"
	"github.com/lxc/lxd/shared"
)

// Status returns the current VM status.
func (m *Monitor) Status() (string, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			Status string `json:"status"`
		} `json:"return"`
	}

	// Query the status.
	err := m.run("query-status", "", &resp)
	if err != nil {
		return "", err
	}

	return resp.Return.Status, nil
}

// Console fetches the File for a particular console.
func (m *Monitor) Console(target string) (*os.File, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			Label    string `json:"label"`
			Filename string `json:"filename"`
		} `json:"return"`
	}

	// Query the consoles.
	err := m.run("query-chardev", "", &resp)
	if err != nil {
		return nil, err
	}

	// Look for the requested console.
	for _, v := range resp.Return {
		if v.Label == target {
			ptyPath := strings.TrimPrefix(v.Filename, "pty:")

			if !shared.PathExists(ptyPath) {
				continue
			}

			// Open the PTS device
			console, err := os.OpenFile(ptyPath, os.O_RDWR, 0600)
			if err != nil {
				return nil, err
			}

			return console, nil
		}
	}

	return nil, ErrMonitorBadConsole
}

// SendFile adds a new file descriptor to the QMP fd table associated to name.
func (m *Monitor) SendFile(name string, file *os.File) error {
	// Check if disconnected
	if m.disconnected {
		return ErrMonitorDisconnect
	}

	// Query the status.
	_, err := m.qmp.RunWithFile([]byte(fmt.Sprintf("{'execute': 'getfd', 'arguments': {'fdname': '%s'}}", name)), file)
	if err != nil {
		// Confirm the daemon didn't die.
		errPing := m.ping()
		if errPing != nil {
			return errPing
		}

		return err
	}

	return nil
}

// Migrate starts a migration stream.
func (m *Monitor) Migrate(uri string) error {
	// Query the status.
	err := m.run("migrate", fmt.Sprintf("{'uri': '%s'}", uri), nil)
	if err != nil {
		return err
	}

	// Wait until it completes or fails.
	for {
		time.Sleep(1 * time.Second)

		// Prepare the response.
		var resp struct {
			Return struct {
				Status string `json:"status"`
			} `json:"return"`
		}

		err := m.run("query-migrate", "", &resp)
		if err != nil {
			return err
		}

		if resp.Return.Status == "failed" {
			return fmt.Errorf("Migration call failed")
		}

		if resp.Return.Status == "completed" {
			break
		}
	}

	return nil
}

// MigrateIncoming starts the receiver of a migration stream.
func (m *Monitor) MigrateIncoming(uri string) error {
	// Query the status.
	err := m.run("migrate-incoming", fmt.Sprintf("{'uri': '%s'}", uri), nil)
	if err != nil {
		return err
	}

	// Wait until it completes or fails.
	for {
		time.Sleep(1 * time.Second)

		// Preapre the response.
		var resp struct {
			Return struct {
				Status string `json:"status"`
			} `json:"return"`
		}

		err := m.run("query-migrate", "", &resp)
		if err != nil {
			return err
		}

		if resp.Return.Status == "failed" {
			return fmt.Errorf("Migration call failed")
		}

		if resp.Return.Status == "completed" {
			break
		}
	}

	return nil
}

// Powerdown tells the VM to gracefully shutdown.
func (m *Monitor) Powerdown() error {
	return m.run("system_powerdown", "", nil)
}

// Start tells QEMU to start the emulation.
func (m *Monitor) Start() error {
	return m.run("cont", "", nil)
}

// Pause tells QEMU to temporarily stop the emulation.
func (m *Monitor) Pause() error {
	return m.run("stop", "", nil)
}

// Quit tells QEMU to exit immediately.
func (m *Monitor) Quit() error {
	return m.run("quit", "", nil)
}

// GetCPUs fetches the vCPU information for pinning.
func (m *Monitor) GetCPUs() ([]int, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			CPU int `json:"cpu-index"`
			PID int `json:"thread-id"`
		} `json:"return"`
	}

	// Query the consoles.
	err := m.run("query-cpus-fast", "", &resp)
	if err != nil {
		return nil, err
	}

	// Make a slice of PIDs.
	pids := []int{}
	for _, cpu := range resp.Return {
		pids = append(pids, cpu.PID)
	}

	return pids, nil
}

// GetMemorySizeBytes returns the current size of the base memory in bytes.
func (m *Monitor) GetMemorySizeBytes() (int64, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			BaseMemory int64 `json:"base-memory"`
		} `json:"return"`
	}

	err := m.run("query-memory-size-summary", "", &resp)
	if err != nil {
		return -1, err
	}

	return resp.Return.BaseMemory, nil
}

// GetMemoryBalloonSizeBytes returns effective size of the memory in bytes (considering the current balloon size).
func (m *Monitor) GetMemoryBalloonSizeBytes() (int64, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			Actual int64 `json:"actual"`
		} `json:"return"`
	}

	err := m.run("query-balloon", "", &resp)
	if err != nil {
		return -1, err
	}

	return resp.Return.Actual, nil
}

// SetMemoryBalloonSizeBytes sets the size of the memory in bytes (which will resize the balloon as needed).
func (m *Monitor) SetMemoryBalloonSizeBytes(sizeBytes int64) error {
	return m.run("balloon", fmt.Sprintf("{'value': %d}", sizeBytes), nil)
}

// AddNIC adds a NIC device.
func (m *Monitor) AddNIC(netDev map[string]interface{}, device map[string]string) error {
	revert := revert.New()
	defer revert.Fail()

	if netDev != nil {
		args, err := json.Marshal(netDev)
		if err != nil {
			return err
		}

		err = m.run("netdev_add", string(args), nil)
		if err != nil {
			return errors.Wrapf(err, "Failed adding NIC netdev")
		}

		revert.Add(func() {
			netDevDel := map[string]interface{}{
				"id": netDev["id"],
			}

			args, err := json.Marshal(netDevDel)
			if err != nil {
				return
			}

			err = m.run("netdev_del", string(args), nil)
			if err != nil {
				return
			}
		})
	}

	if device != nil {
		args, err := json.Marshal(device)
		if err != nil {
			return err
		}

		err = m.run("device_add", string(args), nil)
		if err != nil {
			return errors.Wrapf(err, "Failed adding NIC device")
		}
	}

	revert.Success()
	return nil
}

// RemoveNIC removes a NIC device.
func (m *Monitor) RemoveNIC(netDevID string, deviceID string) error {
	if deviceID != "" {
		deviceID := map[string]string{
			"id": deviceID,
		}

		args, err := json.Marshal(deviceID)
		if err != nil {
			return err
		}

		err = m.run("device_del", string(args), nil)
		if err != nil {
			// If the device has already been removed then all good.
			if err != nil && !strings.Contains(err.Error(), "not found") {
				return errors.Wrapf(err, "Failed removing NIC device")
			}
		}
	}

	if netDevID != "" {
		netDevID := map[string]string{
			"id": netDevID,
		}

		args, err := json.Marshal(netDevID)
		if err != nil {
			return err
		}

		err = m.run("netdev_del", string(args), nil)

		// Not all NICs need a netdev, so if its missing, its not a problem.
		if err != nil && !strings.Contains(err.Error(), "not found") {
			return errors.Wrapf(err, "Failed removing NIC netdev")
		}
	}

	return nil
}

// Reset VM.
func (m *Monitor) Reset() error {
	err := m.run("system_reset", "", nil)
	if err != nil {
		return errors.Wrapf(err, "Failed resetting")
	}

	return nil
}

// PCIClassInfo info about a device's class.
type PCIClassInfo struct {
	Class       int    `json:"class"`
	Description string `json:"desc"`
}

// PCIDevice represents a PCI device.
type PCIDevice struct {
	DevID    string       `json:"qdev_id"`
	Bus      int          `json:"bus"`
	Slot     int          `json:"slot"`
	Function int          `json:"function"`
	Devices  []PCIDevice  `json:"devices"`
	Class    PCIClassInfo `json:"class_info"`
	Bridge   PCIBridge    `json:"pci_bridge"`
}

// PCIBridge represents a PCI bridge.
type PCIBridge struct {
	Devices []PCIDevice `json:"devices"`
}

// QueryPCI returns info about PCI devices.
func (m *Monitor) QueryPCI() ([]PCIDevice, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			Devices []PCIDevice `json:"devices"`
		} `json:"return"`
	}

	err := m.run("query-pci", "", &resp)
	if err != nil {
		return nil, errors.Wrapf(err, "Failed querying PCI devices")
	}

	if len(resp.Return) > 0 {
		return resp.Return[0].Devices, nil
	}

	return nil, nil
}
<|endoftext|>


<commit_before>package log

import "os"
import "firempq/conf"
import "github.com/op/go-logging"

func InitLogging() {
	format := logging.MustStringFormatter(
		"%{color}%{time:2006-01-02 15:04:05.00000}: %{level}%{color:reset} %{shortfile} %{message}",
	)
	logbackend := logging.NewLogBackend(os.Stderr, "", 0)
	formatter := logging.NewBackendFormatter(logbackend, format)
	logging.SetBackend(formatter)
	logging.SetLevel(conf.CFG.LogLevel, "firempq")
	fixLogger()
}

func fixLogger() {
	Logger.ExtraCalldepth = 1
}

var Logger = logging.MustGetLogger("firempq")

var Error func(string, ...interface{}) = Logger.Error
var Critical func(string, ...interface{}) = Logger.Critical
var Warning func(string, ...interface{}) = Logger.Warning
var Notice func(string, ...interface{}) = Logger.Notice
var Info func(string, ...interface{}) = Logger.Info
var Debug func(string, ...interface{}) = Logger.Debug
<commit_msg>Added fatal error for the global logger.<commit_after>package log

import "os"
import "firempq/conf"
import "github.com/op/go-logging"
import "log"

func InitLogging() {
	format := logging.MustStringFormatter(
		"%{color}%{time:2006-01-02 15:04:05.00000}: %{level}%{color:reset} %{shortfile} %{message}",
	)
	logbackend := logging.NewLogBackend(os.Stderr, "", 0)
	formatter := logging.NewBackendFormatter(logbackend, format)
	logging.SetBackend(formatter)
	logging.SetLevel(conf.CFG.LogLevel, "firempq")
	fixLogger()
}

func fixLogger() {
	Logger.ExtraCalldepth = 1
}

var Logger = logging.MustGetLogger("firempq")

var Error func(string, ...interface{}) = Logger.Error
var Critical func(string, ...interface{}) = Logger.Critical
var Warning func(string, ...interface{}) = Logger.Warning
var Notice func(string, ...interface{}) = Logger.Notice
var Info func(string, ...interface{}) = Logger.Info
var Debug func(string, ...interface{}) = Logger.Debug
var Fatal func(string, ...interface{}) = log.Fatalf
<|endoftext|>


<commit_before>package logger

import (
	"bytes"
	"testing"
)

const (
	namet = name + ".Test"
)

func TestGetLevel(t *testing.T) {
	n := New("logger.Test.GetLevel")

	n.Info(n, "Starting")
	m := make(map[Logger]Priority)
	m[""] = DefaultPriority
	m["."] = DefaultPriority
	m["Test"] = DefaultPriority
	m[".Test"] = DefaultPriority

	SetLevel("Test2", Emergency)
	m["Test2"] = Emergency
	m["Test2.Test"] = Emergency
	m["Test2.Test.Test"] = Emergency
	m["Test2.Test.Test.Test"] = Emergency
	m["Test2.Test.Test.Test.Test"] = Emergency
	m["Test2.Test.Test.Test.Test.Test"] = Emergency

	for k, v := range m {
		o := GetLevel(k)
		if o != v {
			n.Error(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
			t.Fail()
		}
		n.Debug(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
	}
	n.Info(n, "Finished")
}

func TestGetParentLevel(t *testing.T) {
	n := New("logger.Test.getParentLevel")

	n.Info(n, "Starting")
	m := make(map[Logger]Priority)
	m["."] = DefaultPriority
	m["Test"] = DefaultPriority
	m["Test.Test"] = DefaultPriority

	SetLevel("Test2", Emergency)
	m["Test2"] = DefaultPriority
	m["Test2.Test"] = Emergency

	for k, v := range m {
		o := getParentLevel(k)
		if o != v {
			n.Error(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
			t.Fail()
		}
		n.Debug(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
	}
	n.Info(n, "Finished")
}

func TestGetParent(t *testing.T) {
	n := New("logger.Test.getParent")

	n.Info(n, "Starting")
	m := [][]Logger{
		{"", "."},
		{".Test", "."},
		{".", "."},
		{"Test", "."},
		{"Test.Test", "Test"},
		{"Test.Test.Test", "Test.Test"},
		{"Test.Test.Test.Test", "Test.Test.Test"},
	}

	for i := range m {
		a := m[i]

		k := a[0]
		v := a[1]

		o := getParent(k)
		if o != v {
			n.Error(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
			t.Fail()
		}
		n.Debug(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
	}
	n.Info(n, "Finished")
}

func TestGetParentOutputSame(t *testing.T) {
	l := New(namet + ".GetParent.Output.Same")

	p := Logger("Test")
	p.SetFormat("{{.Message}}")

	c := Logger("Test.Test")
	l.Info("Parent: '", getParent(c), "'")

	var b bytes.Buffer
	p.SetOutput(&b)

	p.Notice("Test Parent,")
	c.Notice("Test Child")

	o := b.String()
	v := "Test Parent,Test Child"

	l.Debug("GOT: ", o, ", EXPECTED: ", v)
	if o != v {
		l.Critical("GOT: ", o, ", EXPECTED: ", v)
		t.Fail()
	}
}

func TestGetParentOutputDifferent(t *testing.T) {
	l := New(namet + ".GetParent.Output.Different")

	p := Logger("Test")
	p.SetFormat("{{.Message}}")

	c := Logger("Test.Test")
	l.Info("Parent: '", getParent(c), "'")

	var b bytes.Buffer
	c.SetOutput(&b)

	p.Notice("Test Parent,")
	c.Notice("Test Child")

	o := b.String()
	v := "Test Child"

	l.Debug("GOT: ", o, ", EXPECTED: ", v)
	if o != v {
		l.Critical("GOT: ", o, ", EXPECTED: ", v)
		t.Fail()
	}
}

func TestPrintMessage(t *testing.T) {
	l := New(namet + ".PrintMessage")

	p := "\033[0m"
	b := "Test - " + p + p + "Debug" + p + " - "

	m := [][]string{
		{"", b},
		{"Test", b + "Test"},
		{"Test.Test", b + "Test.Test"},
		{"Test.Test.Test", b + "Test.Test.Test"},
	}

	r := list.GetLogger("Test")
	r.Format = "{{.Logger}} - {{.Priority}} - {{.Message}}"

	for _, d := range m {
		l.Info("Checking: ", d)

		k := d[0]
		v := d[1]

		var b bytes.Buffer
		r.Output = &b

		printMessage(r, Debug, k)
		o := b.String()

		l.Debug("GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
		if o != v {
			l.Critical("GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
			t.Fail()
		}
	}
}

func TestPrintMessageNoColor(t *testing.T) {
	l := New(namet + ".PrintMessage")

	m := [][]string{
		{"", "Test - Debug - "},
		{"Test", "Test - Debug - Test"},
		{"Test.Test", "Test - Debug - Test.Test"},
		{"Test.Test.Test", "Test - Debug - Test.Test.Test"},
	}

	r := list.GetLogger("Test")
	r.Format = "{{.Logger}} - {{.Priority}} - {{.Message}}"
	r.NoColor = true

	for _, d := range m {
		l.Info("Checking: ", d)

		k := d[0]
		v := d[1]

		var b bytes.Buffer
		r.Output = &b

		printMessage(r, Debug, k)
		o := b.String()

		l.Debug("GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
		if o != v {
			l.Critical("GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
			t.Fail()
		}
	}
}

func TestPrintColors(t *testing.T) {
	l := New("logger.Test.PrintColors")
	SetLevel("logger.Test.PrintColors", Disable)

	//TODO: Compare strings instead of printing.

	l.Debug("Debug")
	l.Info("Info")
	l.Notice("Notice")
	l.Warning("Warning")
	l.Error("Error")
	l.Critical("Critical")
	l.Alert("Alert")
	l.Emergency("Emergency")

	SetNoColor("logger.Test.PrintColors", true)
	l.Debug("NoColorDebug")
	l.Info("NoColorInfo")
	l.Notice("NoColorNotice")
	l.Warning("NoColorWarning")
	l.Error("NoColorError")
	l.Critical("NoColorCritical")
	l.Alert("NoColorAlert")
	l.Emergency("NoColorEmergency")
}

func TestCheckPriorityOK(t *testing.T) {
	l := New(namet + ".CheckPriority.OK")

	for k := range priorities {
		l.Info("Checking: ", k)

		e := checkPriority(k)
		l.Debug("Return of ", k, ": ", e)
		if e != nil {
			l.Critical(e)
			t.Fail()
		}
	}
}

func TestCheckPriorityFail(t *testing.T) {
	l := New(namet + ".CheckPriority.FAIL")

	k := Disable + 1

	l.Info("Checking: ", k)

	e := checkPriority(k)
	l.Debug("Return of ", k, ": ", e)
	if e == nil {
		l.Critical("Should not have succeeded")
		t.Fail()
		return
	}
}

func TestCheckPriorityFailDoesNotExist(t *testing.T) {
	l := New(namet + ".CheckPriority.FAIL.DoesNotExist")

	k := Disable + 1
	x := "priority does not exist"

	l.Info("Checking: ", k)

	e := checkPriority(k)
	l.Debug("Return of ", k, ": ", e)
	if e != nil {

		if e.Error() != x {
			l.Critical("Wrong error, EXPECTED: ", x, ", GOT: ", e.Error())
			t.Fail()
		}
	}
}

func TestGetPriorityFormat(t *testing.T) {
	l := New(namet + ".GetPriorityFormat")

	m := [][]int{
		{int(Debug), colornone, textnormal},
		{int(Notice), colorgreen, textnormal},
		{int(Info), colorblue, textnormal},
		{int(Warning), coloryellow, textnormal},
		{int(Error), coloryellow, textbold},
		{int(Critical), colorred, textnormal},
		{int(Alert), colorred, textbold},
		{int(Emergency), colorred, textblink},
	}

	for _, d := range m {
		p := Priority(d[0])
		n, e := NamePriority(p)
		if e != nil {
			l.Alert("Can not name priority: ", e)
			t.Fail()
		}

		c := d[1]
		f := d[2]

		a, b := getPriorityFormat(p)

		if c != a {
			l.Critical("Wrong color for ", n, ", EXPECTED: ", c, ", GOT: ", a)
			t.Fail()
		}

		if f != b {
			l.Critical("Wrong format for ", n, ", EXPECTED: ", c, ", GOT: ", b)
			t.Fail()
		}
	}
}

func BenchmarkLogRootEmergency(b *testing.B) {
	for i := 0; i < b.N; i++ {
		logMessage(".", Emergency, "Test")
	}
}

func BenchmarkLogRootEmergencyNoColor(b *testing.B) {
	SetNoColor(".", true)

	for i := 0; i < b.N; i++ {
		logMessage(".", Emergency, "Test")
	}
}

func BenchmarkLogRoot(b *testing.B) {
	for i := 0; i < b.N; i++ {
		logMessage(".", Debug, "Test")
	}
}

func BenchmarkLogChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		logMessage("BenchLogChild", Debug, "Test")
	}
}

func BenchmarkLogChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		logMessage("BenchLogChildChild.Test", Debug, "Test")
	}
}

func BenchmarkLogChildChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		logMessage("BenchLogChildChildChild.Test.Test", Debug, "Test")
	}
}

func BenchmarkLogChildAllocated(b *testing.B) {
	SetLevel("BenchLogChildAllocated", Emergency)
	for i := 0; i < b.N; i++ {
		logMessage("BenchLogChildAllocated", Debug, "Test")
	}
}

func BenchmarkLogChildChildAllocated(b *testing.B) {
	SetLevel("BenchLogChildChildAllocated.Test", Emergency)
	for i := 0; i < b.N; i++ {
		logMessage("BenchLogChildChildAllocated.Test", Debug, "Test")
	}
}

func BenchmarkGetParentRoot(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent(".")
	}
}

func BenchmarkGetParentChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent("BenchgetParentChild")
	}
}

func BenchmarkGetParentChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent("BenchgetParentChildChild.Test")
	}
}

func BenchmarkGetParentChildChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent("BenchgetParentChildChild.Test.Test")
	}
}

func BenchmarkGetParentChildChildChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent("BenchgetParentChildChildChild.Test.Test")
	}
}

func BenchmarkGetParentChildChildChildChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent("BenchgetParentChildChildChildChild.Test.Test.Test")
	}
}

func BenchmarkPrintMessage(b *testing.B) {
	var a bytes.Buffer
	l := list.GetLogger("BenchprintMessage")
	l.Output = &a

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		printMessage(l, Debug, "Message")
	}
}

func BenchmarkFormatMessage(b *testing.B) {
	l := list.GetLogger("BenchformatMessage")

	m := new(message)
	m.Time = "Mo 30 Sep 2013 20:29:19 CEST"
	m.Logger = l.Logger
	m.Priority = "Debug"
	m.Message = "Test"

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		formatMessage(m, l.Format)
	}
}
<commit_msg>Added TestGetParentOutputInheritance which checks if the inheritance of the output writer works properly if the child already was defined.<commit_after>package logger

import (
	"bytes"
	"testing"
)

const (
	namet = name + ".Test"
)

func TestGetLevel(t *testing.T) {
	n := New("logger.Test.GetLevel")

	n.Info(n, "Starting")
	m := make(map[Logger]Priority)
	m[""] = DefaultPriority
	m["."] = DefaultPriority
	m["Test"] = DefaultPriority
	m[".Test"] = DefaultPriority

	SetLevel("Test2", Emergency)
	m["Test2"] = Emergency
	m["Test2.Test"] = Emergency
	m["Test2.Test.Test"] = Emergency
	m["Test2.Test.Test.Test"] = Emergency
	m["Test2.Test.Test.Test.Test"] = Emergency
	m["Test2.Test.Test.Test.Test.Test"] = Emergency

	for k, v := range m {
		o := GetLevel(k)
		if o != v {
			n.Error(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
			t.Fail()
		}
		n.Debug(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
	}
	n.Info(n, "Finished")
}

func TestGetParentLevel(t *testing.T) {
	n := New("logger.Test.getParentLevel")

	n.Info(n, "Starting")
	m := make(map[Logger]Priority)
	m["."] = DefaultPriority
	m["Test"] = DefaultPriority
	m["Test.Test"] = DefaultPriority

	SetLevel("Test2", Emergency)
	m["Test2"] = DefaultPriority
	m["Test2.Test"] = Emergency

	for k, v := range m {
		o := getParentLevel(k)
		if o != v {
			n.Error(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
			t.Fail()
		}
		n.Debug(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
	}
	n.Info(n, "Finished")
}

func TestGetParent(t *testing.T) {
	n := New("logger.Test.getParent")

	n.Info(n, "Starting")
	m := [][]Logger{
		{"", "."},
		{".Test", "."},
		{".", "."},
		{"Test", "."},
		{"Test.Test", "Test"},
		{"Test.Test.Test", "Test.Test"},
		{"Test.Test.Test.Test", "Test.Test.Test"},
	}

	for i := range m {
		a := m[i]

		k := a[0]
		v := a[1]

		o := getParent(k)
		if o != v {
			n.Error(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
			t.Fail()
		}
		n.Debug(n, "GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
	}
	n.Info(n, "Finished")
}

func TestGetParentOutputSame(t *testing.T) {
	l := New(namet + ".GetParent.Output.Same")

	p := Logger("Test")
	p.SetFormat("{{.Message}}")

	c := Logger("Test.Test")
	l.Info("Parent: '", getParent(c), "'")

	var b bytes.Buffer
	p.SetOutput(&b)

	p.Notice("Test Parent,")
	c.Notice("Test Child")

	o := b.String()
	v := "Test Parent,Test Child"

	l.Debug("GOT: ", o, ", EXPECTED: ", v)
	if o != v {
		l.Critical("GOT: ", o, ", EXPECTED: ", v)
		t.Fail()
	}
}

func TestGetParentOutputDifferent(t *testing.T) {
	l := New(namet + ".GetParent.Output.Different")

	p := Logger("Test")
	p.SetFormat("{{.Message}}")

	c := Logger("Test.Test")
	l.Info("Parent: '", getParent(c), "'")

	var b bytes.Buffer
	c.SetOutput(&b)

	p.Notice("Test Parent,")
	c.Notice("Test Child")

	o := b.String()
	v := "Test Child"

	l.Debug("GOT: ", o, ", EXPECTED: ", v)
	if o != v {
		l.Critical("GOT: ", o, ", EXPECTED: ", v)
		t.Fail()
	}
}

func TestGetParentOutputInheritance(t *testing.T) {
	l := New(namet + ".GetParent.Output.Inheritance")

	p := Logger("Test")
	p.SetFormat("{{.Message}}")

	c := Logger("Test.Test")
	c.SetLevel(Debug)
	l.Info("Parent: '", getParent(c), "'")

	var b bytes.Buffer
	p.SetOutput(&b)

	p.Notice("Test Parent,")
	c.Notice("Test Child")

	o := b.String()
	v := "TestParent,Test Child"

	l.Debug("GOT: ", o, ", EXPECTED: ", v)
	if o != v {
		l.Critical("GOT: ", o, ", EXPECTED: ", v)
		t.Fail()
	}
}

func TestPrintMessage(t *testing.T) {
	l := New(namet + ".PrintMessage")

	p := "\033[0m"
	b := "Test - " + p + p + "Debug" + p + " - "

	m := [][]string{
		{"", b},
		{"Test", b + "Test"},
		{"Test.Test", b + "Test.Test"},
		{"Test.Test.Test", b + "Test.Test.Test"},
	}

	r := list.GetLogger("Test")
	r.Format = "{{.Logger}} - {{.Priority}} - {{.Message}}"

	for _, d := range m {
		l.Info("Checking: ", d)

		k := d[0]
		v := d[1]

		var b bytes.Buffer
		r.Output = &b

		printMessage(r, Debug, k)
		o := b.String()

		l.Debug("GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
		if o != v {
			l.Critical("GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
			t.Fail()
		}
	}
}

func TestPrintMessageNoColor(t *testing.T) {
	l := New(namet + ".PrintMessage")

	m := [][]string{
		{"", "Test - Debug - "},
		{"Test", "Test - Debug - Test"},
		{"Test.Test", "Test - Debug - Test.Test"},
		{"Test.Test.Test", "Test - Debug - Test.Test.Test"},
	}

	r := list.GetLogger("Test")
	r.Format = "{{.Logger}} - {{.Priority}} - {{.Message}}"
	r.NoColor = true

	for _, d := range m {
		l.Info("Checking: ", d)

		k := d[0]
		v := d[1]

		var b bytes.Buffer
		r.Output = &b

		printMessage(r, Debug, k)
		o := b.String()

		l.Debug("GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
		if o != v {
			l.Critical("GOT: '", o, "', EXPECED: '", v, "'", ", KEY: '", k, "'")
			t.Fail()
		}
	}
}

func TestPrintColors(t *testing.T) {
	l := New("logger.Test.PrintColors")
	SetLevel("logger.Test.PrintColors", Disable)

	//TODO: Compare strings instead of printing.

	l.Debug("Debug")
	l.Info("Info")
	l.Notice("Notice")
	l.Warning("Warning")
	l.Error("Error")
	l.Critical("Critical")
	l.Alert("Alert")
	l.Emergency("Emergency")

	SetNoColor("logger.Test.PrintColors", true)
	l.Debug("NoColorDebug")
	l.Info("NoColorInfo")
	l.Notice("NoColorNotice")
	l.Warning("NoColorWarning")
	l.Error("NoColorError")
	l.Critical("NoColorCritical")
	l.Alert("NoColorAlert")
	l.Emergency("NoColorEmergency")
}

func TestCheckPriorityOK(t *testing.T) {
	l := New(namet + ".CheckPriority.OK")

	for k := range priorities {
		l.Info("Checking: ", k)

		e := checkPriority(k)
		l.Debug("Return of ", k, ": ", e)
		if e != nil {
			l.Critical(e)
			t.Fail()
		}
	}
}

func TestCheckPriorityFail(t *testing.T) {
	l := New(namet + ".CheckPriority.FAIL")

	k := Disable + 1

	l.Info("Checking: ", k)

	e := checkPriority(k)
	l.Debug("Return of ", k, ": ", e)
	if e == nil {
		l.Critical("Should not have succeeded")
		t.Fail()
		return
	}
}

func TestCheckPriorityFailDoesNotExist(t *testing.T) {
	l := New(namet + ".CheckPriority.FAIL.DoesNotExist")

	k := Disable + 1
	x := "priority does not exist"

	l.Info("Checking: ", k)

	e := checkPriority(k)
	l.Debug("Return of ", k, ": ", e)
	if e != nil {

		if e.Error() != x {
			l.Critical("Wrong error, EXPECTED: ", x, ", GOT: ", e.Error())
			t.Fail()
		}
	}
}

func TestGetPriorityFormat(t *testing.T) {
	l := New(namet + ".GetPriorityFormat")

	m := [][]int{
		{int(Debug), colornone, textnormal},
		{int(Notice), colorgreen, textnormal},
		{int(Info), colorblue, textnormal},
		{int(Warning), coloryellow, textnormal},
		{int(Error), coloryellow, textbold},
		{int(Critical), colorred, textnormal},
		{int(Alert), colorred, textbold},
		{int(Emergency), colorred, textblink},
	}

	for _, d := range m {
		p := Priority(d[0])
		n, e := NamePriority(p)
		if e != nil {
			l.Alert("Can not name priority: ", e)
			t.Fail()
		}

		c := d[1]
		f := d[2]

		a, b := getPriorityFormat(p)

		if c != a {
			l.Critical("Wrong color for ", n, ", EXPECTED: ", c, ", GOT: ", a)
			t.Fail()
		}

		if f != b {
			l.Critical("Wrong format for ", n, ", EXPECTED: ", c, ", GOT: ", b)
			t.Fail()
		}
	}
}

func BenchmarkLogRootEmergency(b *testing.B) {
	for i := 0; i < b.N; i++ {
		logMessage(".", Emergency, "Test")
	}
}

func BenchmarkLogRootEmergencyNoColor(b *testing.B) {
	SetNoColor(".", true)

	for i := 0; i < b.N; i++ {
		logMessage(".", Emergency, "Test")
	}
}

func BenchmarkLogRoot(b *testing.B) {
	for i := 0; i < b.N; i++ {
		logMessage(".", Debug, "Test")
	}
}

func BenchmarkLogChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		logMessage("BenchLogChild", Debug, "Test")
	}
}

func BenchmarkLogChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		logMessage("BenchLogChildChild.Test", Debug, "Test")
	}
}

func BenchmarkLogChildChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		logMessage("BenchLogChildChildChild.Test.Test", Debug, "Test")
	}
}

func BenchmarkLogChildAllocated(b *testing.B) {
	SetLevel("BenchLogChildAllocated", Emergency)
	for i := 0; i < b.N; i++ {
		logMessage("BenchLogChildAllocated", Debug, "Test")
	}
}

func BenchmarkLogChildChildAllocated(b *testing.B) {
	SetLevel("BenchLogChildChildAllocated.Test", Emergency)
	for i := 0; i < b.N; i++ {
		logMessage("BenchLogChildChildAllocated.Test", Debug, "Test")
	}
}

func BenchmarkGetParentRoot(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent(".")
	}
}

func BenchmarkGetParentChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent("BenchgetParentChild")
	}
}

func BenchmarkGetParentChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent("BenchgetParentChildChild.Test")
	}
}

func BenchmarkGetParentChildChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent("BenchgetParentChildChild.Test.Test")
	}
}

func BenchmarkGetParentChildChildChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent("BenchgetParentChildChildChild.Test.Test")
	}
}

func BenchmarkGetParentChildChildChildChildChild(b *testing.B) {
	for i := 0; i < b.N; i++ {
		getParent("BenchgetParentChildChildChildChild.Test.Test.Test")
	}
}

func BenchmarkPrintMessage(b *testing.B) {
	var a bytes.Buffer
	l := list.GetLogger("BenchprintMessage")
	l.Output = &a

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		printMessage(l, Debug, "Message")
	}
}

func BenchmarkFormatMessage(b *testing.B) {
	l := list.GetLogger("BenchformatMessage")

	m := new(message)
	m.Time = "Mo 30 Sep 2013 20:29:19 CEST"
	m.Logger = l.Logger
	m.Priority = "Debug"
	m.Message = "Test"

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		formatMessage(m, l.Format)
	}
}
<|endoftext|>


<commit_before>package core

import "github.com/ethereum/go-ethereum/common"

// Set of manually tracked bad hashes (usually hard forks)
var BadHashes = map[common.Hash]bool{
	common.HexToHash("f269c503aed286caaa0d114d6a5320e70abbc2febe37953207e76a2873f2ba79"): true,
	common.HexToHash("38f5bbbffd74804820ffa4bab0cd540e9de229725afb98c1a7e57936f4a714bc"): true,
}
<commit_msg>core: added bad block<commit_after>package core

import "github.com/ethereum/go-ethereum/common"

// Set of manually tracked bad hashes (usually hard forks)
var BadHashes = map[common.Hash]bool{
	common.HexToHash("f269c503aed286caaa0d114d6a5320e70abbc2febe37953207e76a2873f2ba79"): true,
	common.HexToHash("38f5bbbffd74804820ffa4bab0cd540e9de229725afb98c1a7e57936f4a714bc"): true,
	common.HexToHash("7064455b364775a16afbdecd75370e912c6e2879f202eda85b9beae547fff3ac"): true,
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"sort"
	"strings"

	"github.com/pkg/errors"
	"github.com/spf13/cobra"
	yaml "gopkg.in/yaml.v2"

	"github.com/lxc/lxd/shared/api"
	cli "github.com/lxc/lxd/shared/cmd"
	"github.com/lxc/lxd/shared/i18n"
	"github.com/olekukonko/tablewriter"
)

type cmdCluster struct {
	global *cmdGlobal
}

func (c *cmdCluster) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("cluster")
	cmd.Short = i18n.G("Manage cluster members")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Manage cluster members`))

	// List
	clusterListCmd := cmdClusterList{global: c.global, cluster: c}
	cmd.AddCommand(clusterListCmd.Command())

	// Rename
	clusterRenameCmd := cmdClusterRename{global: c.global, cluster: c}
	cmd.AddCommand(clusterRenameCmd.Command())

	// Remove
	clusterRemoveCmd := cmdClusterRemove{global: c.global, cluster: c}
	cmd.AddCommand(clusterRemoveCmd.Command())

	// Show
	clusterShowCmd := cmdClusterShow{global: c.global, cluster: c}
	cmd.AddCommand(clusterShowCmd.Command())

	// Enable
	clusterEnableCmd := cmdClusterEnable{global: c.global, cluster: c}
	cmd.AddCommand(clusterEnableCmd.Command())

	return cmd
}

// List
type cmdClusterList struct {
	global  *cmdGlobal
	cluster *cmdCluster
}

func (c *cmdClusterList) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("list [<remote>:]")
	cmd.Aliases = []string{"ls"}
	cmd.Short = i18n.G("List all the cluster members")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`List all the cluster members`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdClusterList) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 0, 1)
	if exit {
		return err
	}

	// Parse remote
	remote := ""
	if len(args) == 1 {
		remote = args[0]
	}

	resources, err := c.global.ParseServers(remote)
	if err != nil {
		return err
	}

	resource := resources[0]

	// Check if clustered
	cluster, _, err := resource.server.GetCluster()
	if err != nil {
		return err
	}

	if !cluster.Enabled {
		return fmt.Errorf(i18n.G("LXD server isn't part of a cluster"))
	}

	// Get the cluster members
	members, err := resource.server.GetClusterMembers()
	if err != nil {
		return err
	}

	// Render the table
	data := [][]string{}
	for _, member := range members {
		database := "NO"
		if member.Database {
			database = "YES"
		}
		line := []string{member.ServerName, member.URL, database, strings.ToUpper(member.Status), member.Message}
		data = append(data, line)
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoWrapText(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetRowLine(true)
	table.SetHeader([]string{
		i18n.G("NAME"),
		i18n.G("URL"),
		i18n.G("DATABASE"),
		i18n.G("STATE"),
		i18n.G("MESSAGE"),
	})
	sort.Sort(byName(data))
	table.AppendBulk(data)
	table.Render()

	return nil
}

// Show
type cmdClusterShow struct {
	global  *cmdGlobal
	cluster *cmdCluster
}

func (c *cmdClusterShow) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("show [<remote>:]<member>")
	cmd.Short = i18n.G("Show details of a cluster member")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Show details of a cluster member`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdClusterShow) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 1, 1)
	if exit {
		return err
	}

	// Parse remote
	resources, err := c.global.ParseServers(args[0])
	if err != nil {
		return err
	}

	resource := resources[0]

	// Get the member information
	member, _, err := resource.server.GetClusterMember(resource.name)
	if err != nil {
		return err
	}

	// Render as YAML
	data, err := yaml.Marshal(&member)
	if err != nil {
		return err
	}

	fmt.Printf("%s", data)
	return nil
}

// Rename
type cmdClusterRename struct {
	global  *cmdGlobal
	cluster *cmdCluster
}

func (c *cmdClusterRename) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("rename [<remote>:]<member> <new-name>")
	cmd.Aliases = []string{"mv"}
	cmd.Short = i18n.G("Rename a cluster member")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Rename a cluster member`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdClusterRename) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 2, 2)
	if exit {
		return err
	}

	// Parse remote
	resources, err := c.global.ParseServers(args[0])
	if err != nil {
		return err
	}

	resource := resources[0]

	// Perform the rename
	err = resource.server.RenameClusterMember(resource.name, api.ClusterMemberPost{ServerName: args[1]})
	if err != nil {
		return err
	}

	fmt.Printf(i18n.G("Member %s renamed to %s")+"\n", resource.name, args[1])
	return nil
}

// Remove
type cmdClusterRemove struct {
	global  *cmdGlobal
	cluster *cmdCluster

	flagForce bool
}

func (c *cmdClusterRemove) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("remove [<remote>:]<member>")
	cmd.Aliases = []string{"rm"}
	cmd.Short = i18n.G("Remove a member from the cluster")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Remove a member from the cluster`))

	cmd.RunE = c.Run
	cmd.Flags().BoolVarP(&c.flagForce, "force", "f", false, i18n.G("Force removing a member, even if degraded"))

	return cmd
}

func (c *cmdClusterRemove) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 1, 1)
	if exit {
		return err
	}

	// Parse remote
	resources, err := c.global.ParseServers(args[0])
	if err != nil {
		return err
	}

	resource := resources[0]

	// Delete the cluster member
	err = resource.server.DeleteClusterMember(resource.name, c.flagForce)
	if err != nil {
		return err
	}

	fmt.Printf(i18n.G("Member %s removed")+"\n", resource.name)
	return nil
}

// Enable
type cmdClusterEnable struct {
	global  *cmdGlobal
	cluster *cmdCluster

	flagForce bool
}

func (c *cmdClusterEnable) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("enable [<remote>:] <name>")
	cmd.Aliases = []string{"rm"}
	cmd.Short = i18n.G("Enable clustering on a single non-clustered LXD instance")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Enable clustering on a single non-clustered LXD instance

  This command turns a non-clustered LXD instance into the first member of a new
  LXD cluster, which will have the given name.

  It's required that the LXD is already available on the network. You can check
  that by running 'lxc config get core.https_address', and possibly set a value
  for the address if not yet set.`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdClusterEnable) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 1, 2)
	if exit {
		return err
	}

	// Parse remote
	remote := ""
	name := args[0]
	if len(args) == 2 {
		remote = args[0]
		name = args[1]
	}

	resources, err := c.global.ParseServers(remote)
	if err != nil {
		return err
	}

	resource := resources[0]

	// Check if the LXD instance is available on the network.
	server, _, err := resource.server.GetServer()
	if err != nil {
		return errors.Wrap(err, "Failed to retrieve current server config")
	}
	if server.Config["core.https_address"] == "" {
		return fmt.Errorf("This LXD instance is not available on the network")
	}

	// Check if already enabled
	currentCluster, etag, err := resource.server.GetCluster()
	if err != nil {
		return errors.Wrap(err, "Failed to retrieve current cluster config")
	}
	if currentCluster.Enabled {
		return fmt.Errorf("This LXD instance is already clustered")
	}

	// Enable clustering.
	req := api.ClusterPut{}
	req.ServerName = name
	req.Enabled = true
	op, err := resource.server.UpdateCluster(req, etag)
	if err != nil {
		return errors.Wrap(err, "Failed to configure cluster")
	}
	err = op.Wait()
	if err != nil {
		return errors.Wrap(err, "Failed to configure cluster")
	}

	fmt.Printf(i18n.G("Clustering enabled") + "\n")
	return nil
}
<commit_msg>Address style comments<commit_after>package main

import (
	"fmt"
	"os"
	"sort"
	"strings"

	"github.com/pkg/errors"
	"github.com/spf13/cobra"
	yaml "gopkg.in/yaml.v2"

	"github.com/lxc/lxd/shared/api"
	cli "github.com/lxc/lxd/shared/cmd"
	"github.com/lxc/lxd/shared/i18n"
	"github.com/olekukonko/tablewriter"
)

type cmdCluster struct {
	global *cmdGlobal
}

func (c *cmdCluster) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("cluster")
	cmd.Short = i18n.G("Manage cluster members")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Manage cluster members`))

	// List
	clusterListCmd := cmdClusterList{global: c.global, cluster: c}
	cmd.AddCommand(clusterListCmd.Command())

	// Rename
	clusterRenameCmd := cmdClusterRename{global: c.global, cluster: c}
	cmd.AddCommand(clusterRenameCmd.Command())

	// Remove
	clusterRemoveCmd := cmdClusterRemove{global: c.global, cluster: c}
	cmd.AddCommand(clusterRemoveCmd.Command())

	// Show
	clusterShowCmd := cmdClusterShow{global: c.global, cluster: c}
	cmd.AddCommand(clusterShowCmd.Command())

	// Enable
	clusterEnableCmd := cmdClusterEnable{global: c.global, cluster: c}
	cmd.AddCommand(clusterEnableCmd.Command())

	return cmd
}

// List
type cmdClusterList struct {
	global  *cmdGlobal
	cluster *cmdCluster
}

func (c *cmdClusterList) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("list [<remote>:]")
	cmd.Aliases = []string{"ls"}
	cmd.Short = i18n.G("List all the cluster members")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`List all the cluster members`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdClusterList) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 0, 1)
	if exit {
		return err
	}

	// Parse remote
	remote := ""
	if len(args) == 1 {
		remote = args[0]
	}

	resources, err := c.global.ParseServers(remote)
	if err != nil {
		return err
	}

	resource := resources[0]

	// Check if clustered
	cluster, _, err := resource.server.GetCluster()
	if err != nil {
		return err
	}

	if !cluster.Enabled {
		return fmt.Errorf(i18n.G("LXD server isn't part of a cluster"))
	}

	// Get the cluster members
	members, err := resource.server.GetClusterMembers()
	if err != nil {
		return err
	}

	// Render the table
	data := [][]string{}
	for _, member := range members {
		database := "NO"
		if member.Database {
			database = "YES"
		}
		line := []string{member.ServerName, member.URL, database, strings.ToUpper(member.Status), member.Message}
		data = append(data, line)
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoWrapText(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetRowLine(true)
	table.SetHeader([]string{
		i18n.G("NAME"),
		i18n.G("URL"),
		i18n.G("DATABASE"),
		i18n.G("STATE"),
		i18n.G("MESSAGE"),
	})
	sort.Sort(byName(data))
	table.AppendBulk(data)
	table.Render()

	return nil
}

// Show
type cmdClusterShow struct {
	global  *cmdGlobal
	cluster *cmdCluster
}

func (c *cmdClusterShow) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("show [<remote>:]<member>")
	cmd.Short = i18n.G("Show details of a cluster member")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Show details of a cluster member`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdClusterShow) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 1, 1)
	if exit {
		return err
	}

	// Parse remote
	resources, err := c.global.ParseServers(args[0])
	if err != nil {
		return err
	}

	resource := resources[0]

	// Get the member information
	member, _, err := resource.server.GetClusterMember(resource.name)
	if err != nil {
		return err
	}

	// Render as YAML
	data, err := yaml.Marshal(&member)
	if err != nil {
		return err
	}

	fmt.Printf("%s", data)
	return nil
}

// Rename
type cmdClusterRename struct {
	global  *cmdGlobal
	cluster *cmdCluster
}

func (c *cmdClusterRename) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("rename [<remote>:]<member> <new-name>")
	cmd.Aliases = []string{"mv"}
	cmd.Short = i18n.G("Rename a cluster member")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Rename a cluster member`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdClusterRename) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 2, 2)
	if exit {
		return err
	}

	// Parse remote
	resources, err := c.global.ParseServers(args[0])
	if err != nil {
		return err
	}

	resource := resources[0]

	// Perform the rename
	err = resource.server.RenameClusterMember(resource.name, api.ClusterMemberPost{ServerName: args[1]})
	if err != nil {
		return err
	}

	fmt.Printf(i18n.G("Member %s renamed to %s")+"\n", resource.name, args[1])
	return nil
}

// Remove
type cmdClusterRemove struct {
	global  *cmdGlobal
	cluster *cmdCluster

	flagForce bool
}

func (c *cmdClusterRemove) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("remove [<remote>:]<member>")
	cmd.Aliases = []string{"rm"}
	cmd.Short = i18n.G("Remove a member from the cluster")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Remove a member from the cluster`))

	cmd.RunE = c.Run
	cmd.Flags().BoolVarP(&c.flagForce, "force", "f", false, i18n.G("Force removing a member, even if degraded"))

	return cmd
}

func (c *cmdClusterRemove) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 1, 1)
	if exit {
		return err
	}

	// Parse remote
	resources, err := c.global.ParseServers(args[0])
	if err != nil {
		return err
	}

	resource := resources[0]

	// Delete the cluster member
	err = resource.server.DeleteClusterMember(resource.name, c.flagForce)
	if err != nil {
		return err
	}

	fmt.Printf(i18n.G("Member %s removed")+"\n", resource.name)
	return nil
}

// Enable
type cmdClusterEnable struct {
	global  *cmdGlobal
	cluster *cmdCluster

	flagForce bool
}

func (c *cmdClusterEnable) Command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = i18n.G("enable [<remote>:] <name>")
	cmd.Aliases = []string{"rm"}
	cmd.Short = i18n.G("Enable clustering on a single non-clustered LXD instance")
	cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
		`Enable clustering on a single non-clustered LXD instance

  This command turns a non-clustered LXD instance into the first member of a new
  LXD cluster, which will have the given name.

  It's required that the LXD is already available on the network. You can check
  that by running 'lxc config get core.https_address', and possibly set a value
  for the address if not yet set.`))

	cmd.RunE = c.Run

	return cmd
}

func (c *cmdClusterEnable) Run(cmd *cobra.Command, args []string) error {
	// Sanity checks
	exit, err := c.global.CheckArgs(cmd, args, 1, 2)
	if exit {
		return err
	}

	// Parse remote
	remote := ""
	name := args[0]
	if len(args) == 2 {
		remote = args[0]
		name = args[1]
	}

	resources, err := c.global.ParseServers(remote)
	if err != nil {
		return err
	}

	resource := resources[0]

	// Check if the LXD instance is available on the network.
	server, _, err := resource.server.GetServer()
	if err != nil {
		return errors.Wrap(err, "Failed to retrieve current server config")
	}

	if server.Config["core.https_address"] == "" {
		return fmt.Errorf("This LXD instance is not available on the network")
	}

	// Check if already enabled
	currentCluster, etag, err := resource.server.GetCluster()
	if err != nil {
		return errors.Wrap(err, "Failed to retrieve current cluster config")
	}

	if currentCluster.Enabled {
		return fmt.Errorf("This LXD instance is already clustered")
	}

	// Enable clustering.
	req := api.ClusterPut{}
	req.ServerName = name
	req.Enabled = true
	op, err := resource.server.UpdateCluster(req, etag)
	if err != nil {
		return errors.Wrap(err, "Failed to configure cluster")
	}

	err = op.Wait()
	if err != nil {
		return errors.Wrap(err, "Failed to configure cluster")
	}

	fmt.Println(i18n.G("Clustering enabled"))
	return nil
}
<|endoftext|>


<commit_before>package detailed

import (
	"github.com/weaveworks/scope/report"
)

// Parent is the information needed to build a link to the parent of a Node.
type Parent struct {
	ID         string `json:"id"`
	Label      string `json:"label"`
	TopologyID string `json:"topologyId"`
}

// parent topologies, in the order we want to show them
var parentTopologies = []string{
	report.Container,
	report.ContainerImage,
	report.Pod,
	report.Deployment,
	report.DaemonSet,
	report.StatefulSet,
	report.CronJob,
	report.Service,
	report.ECSTask,
	report.ECSService,
	report.SwarmService,
	report.Host,
}

// Parents renders the parents of this report.Node, which have been aggregated
// from the probe reports.
func Parents(r report.Report, n report.Node) []Parent {
	if n.Parents.Size() == 0 {
		return nil
	}
	result := make([]Parent, 0, n.Parents.Size())
	for _, topologyID := range parentTopologies {
		topology, ok := r.Topology(topologyID)
		if !ok {
			continue
		}
		parents, _ := n.Parents.Lookup(topologyID)
		for _, id := range parents {
			if topologyID == n.Topology && id == n.ID {
				continue
			}

			var parentNode report.Node
			// Special case: container image parents should be empty nodes for some reason
			if topologyID == report.ContainerImage {
				parentNode = report.MakeNode(id).WithTopology(topologyID)
			} else {
				if parent, ok := topology.Nodes[id]; ok {
					parentNode = parent
				} else {
					continue
				}
			}

			apiTopologyID, ok := primaryAPITopology[topologyID]
			if !ok {
				continue
			}
			if summary, ok := MakeBasicNodeSummary(r, parentNode); ok {
				result = append(result, Parent{
					ID:         summary.ID,
					Label:      summary.Label,
					TopologyID: apiTopologyID,
				})
			}
		}
	}
	if len(result) == 0 {
		return nil
	}
	return result
}
<commit_msg>render parents which we cannot resolve<commit_after>package detailed

import (
	"github.com/weaveworks/scope/report"
)

// Parent is the information needed to build a link to the parent of a Node.
type Parent struct {
	ID         string `json:"id"`
	Label      string `json:"label"`
	TopologyID string `json:"topologyId"`
}

// parent topologies, in the order we want to show them
var parentTopologies = []string{
	report.Container,
	report.ContainerImage,
	report.Pod,
	report.Deployment,
	report.DaemonSet,
	report.StatefulSet,
	report.CronJob,
	report.Service,
	report.ECSTask,
	report.ECSService,
	report.SwarmService,
	report.Host,
}

// Parents renders the parents of this report.Node, which have been aggregated
// from the probe reports.
func Parents(r report.Report, n report.Node) []Parent {
	if n.Parents.Size() == 0 {
		return nil
	}
	result := make([]Parent, 0, n.Parents.Size())
	for _, topologyID := range parentTopologies {
		topology, ok := r.Topology(topologyID)
		if !ok {
			continue
		}
		parents, _ := n.Parents.Lookup(topologyID)
		for _, id := range parents {
			if topologyID == n.Topology && id == n.ID {
				continue
			}
			parentNode, ok := topology.Nodes[id]
			if !ok {
				parentNode = report.MakeNode(id).WithTopology(topologyID)
			}
			apiTopologyID, ok := primaryAPITopology[topologyID]
			if !ok {
				continue
			}
			if summary, ok := MakeBasicNodeSummary(r, parentNode); ok {
				result = append(result, Parent{
					ID:         summary.ID,
					Label:      summary.Label,
					TopologyID: apiTopologyID,
				})
			}
		}
	}
	if len(result) == 0 {
		return nil
	}
	return result
}
<|endoftext|>


<commit_before>package fsrepo

import (
	"io/ioutil"
	"testing"

	"github.com/jbenet/go-ipfs/repo/config"
)

func testRepoPath(p string, t *testing.T) string {
	name, err := ioutil.TempDir("", p)
	if err != nil {
		t.Fatal(err)
	}
	return name
}

func TestCannotRemoveIfOpen(t *testing.T) {
	path := testRepoPath("TestCannotRemoveIfOpen", t)
	AssertNil(Init(path, &config.Config{}), t, "should initialize successfully")
	r := At(path)
	AssertNil(r.Open(), t)
	AssertErr(Remove(path), t, "should not be able to remove while open")
	AssertNil(r.Close(), t)
	AssertNil(Remove(path), t, "should be able to remove after closed")
}

func TestCanManageReposIndependently(t *testing.T) {
	pathA := testRepoPath("a", t)
	pathB := testRepoPath("b", t)

	t.Log("initialize two repos")
	AssertNil(Init(pathA, &config.Config{}), t, "a", "should initialize successfully")
	AssertNil(Init(pathB, &config.Config{}), t, "b", "should initialize successfully")

	t.Log("ensure repos initialized")
	Assert(IsInitialized(pathA), t, "a should be initialized")
	Assert(IsInitialized(pathB), t, "b should be initialized")

	t.Log("open the two repos")
	repoA := At(pathA)
	repoB := At(pathB)
	AssertNil(repoA.Open(), t, "a")
	AssertNil(repoB.Open(), t, "b")

	t.Log("close and remove b while a is open")
	AssertNil(repoB.Close(), t, "close b")
	AssertNil(Remove(pathB), t, "remove b")

	t.Log("close and remove a")
	AssertNil(repoA.Close(), t)
	AssertNil(Remove(pathA), t)
}

func AssertNil(err error, t *testing.T, msgs ...string) {
	if err != nil {
		t.Fatal(msgs, "error:", err)
	}
}

func Assert(v bool, t *testing.T, msgs ...string) {
	if !v {
		t.Fatal(msgs)
	}
}

func AssertErr(err error, t *testing.T, msgs ...string) {
	if err == nil {
		t.Fatal(msgs, "error:", err)
	}
}
<commit_msg>test(fsrepo): InitIdempotence, NilRemoval, ReopeningDisallowed<commit_after>package fsrepo

import (
	"io/ioutil"
	"testing"

	"github.com/jbenet/go-ipfs/repo/config"
)

func testRepoPath(p string, t *testing.T) string {
	name, err := ioutil.TempDir("", p)
	if err != nil {
		t.Fatal(err)
	}
	return name
}

func TestInitIdempotence(t *testing.T) {
	path := testRepoPath("", t)
	for i := 0; i < 10; i++ {
		AssertNil(Init(path, &config.Config{}), t, "multiple calls to init should succeed")
	}
}

func TestRemove(t *testing.T) {
	path := testRepoPath("foo", t)
	AssertNil(Remove(path), t, "should be able to remove after closed")
}

func TestCannotRemoveIfOpen(t *testing.T) {
	path := testRepoPath("TestCannotRemoveIfOpen", t)
	AssertNil(Init(path, &config.Config{}), t, "should initialize successfully")
	r := At(path)
	AssertNil(r.Open(), t)
	AssertErr(Remove(path), t, "should not be able to remove while open")
	AssertNil(r.Close(), t)
	AssertNil(Remove(path), t, "should be able to remove after closed")
}

func TestCannotBeReopened(t *testing.T) {
	path := testRepoPath("", t)
	AssertNil(Init(path, &config.Config{}), t)
	r := At(path)
	AssertNil(r.Open(), t)
	AssertNil(r.Close(), t)
	AssertErr(r.Open(), t, "shouldn't be possible to re-open the repo")

	// mutable state is the enemy. Take Close() as an opportunity to reduce
	// entropy. Callers ought to start fresh with a new handle by calling `At`.
}

func TestCanManageReposIndependently(t *testing.T) {
	pathA := testRepoPath("a", t)
	pathB := testRepoPath("b", t)

	t.Log("initialize two repos")
	AssertNil(Init(pathA, &config.Config{}), t, "a", "should initialize successfully")
	AssertNil(Init(pathB, &config.Config{}), t, "b", "should initialize successfully")

	t.Log("ensure repos initialized")
	Assert(IsInitialized(pathA), t, "a should be initialized")
	Assert(IsInitialized(pathB), t, "b should be initialized")

	t.Log("open the two repos")
	repoA := At(pathA)
	repoB := At(pathB)
	AssertNil(repoA.Open(), t, "a")
	AssertNil(repoB.Open(), t, "b")

	t.Log("close and remove b while a is open")
	AssertNil(repoB.Close(), t, "close b")
	AssertNil(Remove(pathB), t, "remove b")

	t.Log("close and remove a")
	AssertNil(repoA.Close(), t)
	AssertNil(Remove(pathA), t)
}

func AssertNil(err error, t *testing.T, msgs ...string) {
	if err != nil {
		t.Fatal(msgs, "error:", err)
	}
}

func Assert(v bool, t *testing.T, msgs ...string) {
	if !v {
		t.Fatal(msgs)
	}
}

func AssertErr(err error, t *testing.T, msgs ...string) {
	if err == nil {
		t.Fatal(msgs, "error:", err)
	}
}
<|endoftext|>


<commit_before>package gateway

import (
	"errors"
	"fmt"
	"log"

	"github.com/byuoitav/av-api/base"
	"github.com/byuoitav/av-api/dbo"
	"github.com/byuoitav/av-api/statusevaluators"
	"github.com/byuoitav/configuration-database-microservice/structs"
	"github.com/fatih/color"
)

func SetGateway(action *base.ActionStructure) error {

	if structs.HasRole(action.Device, "GatedDevice") { //we need to add a gateway parameter to the action
		gateway, err := getDeviceGateway(action.Device)
		if err != nil {
			msg := fmt.Sprintf("gateway for %s not found: %s", action.Device.Name, err.Error())
			log.Printf("%s", color.HiRedString("[error] %s", msg))
		}

		action.Parameters["gateway"] = gateway
	}
	return nil

}

func SetStatusGateway(action *statusevaluators.StatusCommand) error {

	if structs.HasRole(action.Device, "GatedDevice") { //we need to add a gateway parameter to the action

		log.Printf("%s", color.HiYellowString("[gateway] identified gated device %s", action.Device.Name))

		gateway, err := getDeviceGateway(action.Device)
		if err != nil {
			return err
		}

		action.Parameters["gateway"] = gateway
	}

	return nil
}

//finds the IP of the device that controls the given device
func getDeviceGateway(d structs.Device) (string, error) {

	for _, port := range d.Ports { //range over all ports

		device, err := dbo.GetDeviceByName(d.Building.Name, d.Room.Name, port.Source)
		if err != nil {
			return "", errors.New(fmt.Sprintf("unable to get source device from port: %s", err.Error()))
		}

		if structs.HasRole(device, "Gateway") {
			return device.Address, nil
		}
	}

	return "", errors.New("gateway not found")
}
<commit_msg>roles are brokengit status<commit_after>package gateway

import (
	"errors"
	"fmt"
	"log"

	"github.com/byuoitav/av-api/base"
	"github.com/byuoitav/av-api/dbo"
	"github.com/byuoitav/av-api/statusevaluators"
	"github.com/byuoitav/configuration-database-microservice/structs"
	"github.com/fatih/color"
)

func SetGateway(action *base.ActionStructure) error {

	if structs.HasRole(action.Device, "GatedDevice") { //we need to add a gateway parameter to the action
		gateway, err := getDeviceGateway(action.Device)
		if err != nil {
			msg := fmt.Sprintf("gateway for %s not found: %s", action.Device.Name, err.Error())
			log.Printf("%s", color.HiRedString("[error] %s", msg))
		}

		action.Parameters["gateway"] = gateway
	}
	return nil

}

func SetStatusGateway(action *statusevaluators.StatusCommand) error {

	if structs.HasRole(action.Device, "GatedDevice") { //we need to add a gateway parameter to the action

		log.Printf("%s", color.HiYellowString("[gateway] identified gated device %s", action.Device.Name))

		gateway, err := getDeviceGateway(action.Device)
		if err != nil {
			return err
		}

		action.Parameters["gateway"] = gateway
	}

	return nil
}

//finds the IP of the device that controls the given device
func getDeviceGateway(d structs.Device) (string, error) {

	for _, port := range d.Ports { //range over all ports

		log.Printf("%s", color.HiYellowString("[gateway] considering device: %s", port.Source))

		device, err := dbo.GetDeviceByName(d.Building.Name, d.Room.Name, port.Source)
		if err != nil {
			return "", errors.New(fmt.Sprintf("unable to get source device from port: %s", err.Error()))
		}

		if len(device.Roles) == 0 {
			log.Printf("%s", color.HiRedString("I HATE YOU!!!"))
		}

		if device.HasRole("Gateway") || structs.HasRole(device, "Gateway") {
			return device.Address, nil
		}
	}

	return "", errors.New("gateway not found")
}
<|endoftext|>


<commit_before>package gatherrun

import (
	"archive/tar"
	"io"
	"os"
	"strings"
)

func untarFile(tarFile string) error {
	var outputFile = strings.TrimSuffix(tarFile, tarSuffix)

	reader, err := os.Open(tarFile)
	if err != nil {
		return err
	}

	tarBallReader := tar.NewReader(reader)

	_, err = tarBallReader.Next()
	if err != nil && err != io.EOF {
		return err
	}

	writer, err := os.Create(outputFile)
	if err != nil {
		return err
	}

	_, err = io.Copy(writer, tarBallReader)
	return err
}
<commit_msg>gather: change file mode after downloading file<commit_after>package gatherrun

import (
	"archive/tar"
	"io"
	"os"
	"strings"
)

func untarFile(tarFile string) error {
	var outputFile = strings.TrimSuffix(tarFile, tarSuffix)

	reader, err := os.Open(tarFile)
	if err != nil {
		return err
	}

	tarBallReader := tar.NewReader(reader)

	_, err = tarBallReader.Next()
	if err != nil && err != io.EOF {
		return err
	}

	writer, err := os.Create(outputFile)
	if err != nil {
		return err
	}

	if err := writer.Chmod(os.ModePerm); err != nil {
		return err
	}

	_, err = io.Copy(writer, tarBallReader)
	return err
}
<|endoftext|>


<commit_before>package api

import (
	"context"
	"net/http"
	"strings"
	"time"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/gorilla/mux"

	"github.com/ovh/cds/engine/api/authentication"
	"github.com/ovh/cds/engine/api/services"
	"github.com/ovh/cds/engine/api/user"
	"github.com/ovh/cds/engine/api/worker"
	"github.com/ovh/cds/engine/service"
	"github.com/ovh/cds/sdk"
	"github.com/ovh/cds/sdk/log"
	"github.com/ovh/cds/sdk/telemetry"
)

const (
	jwtCookieName  = "jwt_token"
	xsrfHeaderName = "X-XSRF-TOKEN"
	xsrfCookieName = "xsrf_token"
)

func (api *API) authMiddleware(ctx context.Context, w http.ResponseWriter, req *http.Request, rc *service.HandlerConfig) (context.Context, error) {
	ctx, end := telemetry.Span(ctx, "router.authMiddleware")
	defer end()

	// Tokens (like izanamy)
	ctx, ok, err := api.authStatusTokenMiddleware(ctx, w, req, rc)
	if err != nil {
		return ctx, sdk.WithStack(err)
	}
	if ok {
		log.Info(ctx, "authMiddleware> authentification granted by token")
		return ctx, nil
	}

	// Check for a JWT in current request and add it to the context
	// If a JWT is given, we also checks that there are a valid session and consumer for it
	ctxWithJWT, err := api.jwtMiddleware(ctx, w, req, rc)
	if err != nil {
		return ctx, err
	}

	var (
		session  *sdk.AuthSession
		consumer *sdk.AuthConsumer
	)

	jwt, ok := ctxWithJWT.Value(contextJWT).(*jwt.Token)
	if ok {
		claims := jwt.Claims.(*sdk.AuthSessionJWTClaims)
		sessionID := claims.StandardClaims.Id
		// Check for session based on jwt from context
		session, err = authentication.CheckSession(ctx, api.mustDB(), sessionID)
		if err != nil {
			log.Warning(ctx, "authMiddleware> cannot find a valid session for given JWT: %v", err)
		}
	}

	if session != nil {
		ctx = context.WithValue(ctxWithJWT, contextSession, session)
		// Load auth consumer for current session in database with authentified user and contacts
		c, err := authentication.LoadConsumerByID(ctx, api.mustDB(), session.ConsumerID,
			authentication.LoadConsumerOptions.WithAuthentifiedUser)
		if err != nil {
			return ctx, sdk.NewErrorWithStack(err, sdk.ErrUnauthorized)
		}
		// If the consumer is disabled, return an error
		if c.Disabled {
			return ctx, sdk.WrapError(sdk.ErrUnauthorized, "consumer (%s) is disabled", c.ID)
		}
		// If the driver was disabled for the consumer that was found, ignore it
		if _, ok := api.AuthenticationDrivers[c.Type]; ok {
			// Add contacts for consumer's user
			if err := user.LoadOptions.WithContacts(ctx, api.mustDB(), c.AuthentifiedUser); err != nil {
				return ctx, err
			}

			// Add service for consumer if exists
			s, err := services.LoadByConsumerID(ctx, api.mustDB(), c.ID)
			if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) {
				return ctx, err
			}
			c.Service = s

			// Add worker for consumer if exists
			w, err := worker.LoadByConsumerID(ctx, api.mustDB(), c.ID)
			if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) {
				return ctx, err
			}
			c.Worker = w

			consumer = c
		}
	}

	if consumer != nil {
		ctx = context.WithValue(ctx, contextAPIConsumer, consumer)

		// Checks scopes, one of expected scopes should be in actual scopes
		// Actual scope empty list means wildcard scope, we don't need to check scopes
		expectedScopes, actualScopes := rc.AllowedScopes, consumer.ScopeDetails
		if len(expectedScopes) > 0 && len(actualScopes) > 0 {
			var found bool
		findScope:
			for i := range expectedScopes {
				for j := range actualScopes {
					if actualScopes[j].Scope == expectedScopes[i] {
						// Check if there are scope details, if yes we should check if current route/method is allowed in restrictions
						if len(actualScopes[j].Endpoints) == 0 {
							found = true
							break findScope
						}

						// if the route is not in current consumer allowed endpoints we should not validate the scope
						if exists, endpoint := actualScopes[j].Endpoints.FindEndpoint(rc.CleanURL); exists &&
							len(endpoint.Methods) == 0 || endpoint.Methods.Contains(rc.Method) {
							found = true
							break findScope
						}
					}
				}
			}
			if !found {
				return ctx, sdk.WrapError(sdk.ErrUnauthorized, "token scopes doesn't match expected: %v", expectedScopes)
			}
		}

		// Check that permission are valid for current route and consumer
		if err := api.checkPermission(ctx, mux.Vars(req), rc.PermissionLevel); err != nil {
			return ctx, err
		}

		jwtFromCookieVal := ctx.Value(contextJWTFromCookie)
		jwtFromCookie, _ := jwtFromCookieVal.(bool)
		if jwtFromCookie {
			ctx, err = api.xsrfMiddleware(ctx, w, req, rc)
			if err != nil {
				return ctx, err
			}
		}
	}

	// If we set Auth(false) on a handler, with should have a consumer in the context if a valid JWT is given
	if rc.NeedAuth && getAPIConsumer(ctx) == nil {
		return ctx, sdk.WithStack(sdk.ErrUnauthorized)
	}

	if rc.NeedAdmin && !isAdmin(ctx) {
		return ctx, sdk.WithStack(sdk.ErrForbidden)
	}

	return ctx, nil
}

// Checks static tokens
func (api *API) authStatusTokenMiddleware(ctx context.Context, w http.ResponseWriter, req *http.Request, rc *service.HandlerConfig) (context.Context, bool, error) {
	if len(rc.AllowedTokens) == 0 {
		return ctx, false, nil
	}
	for _, h := range rc.AllowedTokens {
		log.Debug("authStatusTokenMiddleware> checking allowed token: %v", h)
		headerSplitted := strings.Split(h, ":")
		receivedValue := req.Header.Get(headerSplitted[0])
		if receivedValue != headerSplitted[1] {
			return ctx, false, sdk.WrapError(sdk.ErrUnauthorized, "Router> Authorization denied token on %s %s for %s", req.Method, req.URL, req.RemoteAddr)
		}
	}
	return ctx, true, nil
}

func (api *API) jwtMiddleware(ctx context.Context, w http.ResponseWriter, req *http.Request, rc *service.HandlerConfig) (context.Context, error) {
	ctx, end := telemetry.Span(ctx, "router.jwtMiddleware")
	defer end()

	var jwtRaw string
	var jwtFromCookie bool
	// Try to get the jwt from the cookie firstly then from the authorization bearer header, a XSRF token with cookie
	jwtCookie, _ := req.Cookie(jwtCookieName)
	if jwtCookie != nil {
		jwtRaw = jwtCookie.Value
		jwtFromCookie = true
	} else if strings.HasPrefix(req.Header.Get("Authorization"), "Bearer ") {
		jwtRaw = strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
	}
	// If no jwt is given, simply return empty context without error
	if jwtRaw == "" {
		return ctx, nil
	}

	jwt, err := authentication.CheckSessionJWT(jwtRaw)
	if err != nil {
		if rc.NeedAuth {
			// If the given JWT is not valid log the error and return
			log.Warning(ctx, "jwtMiddleware> invalid given jwt token [%s]: %+v", req.URL.String(), err)
		}
		return ctx, nil
	}

	ctx = context.WithValue(ctx, contextJWTRaw, jwt)
	ctx = context.WithValue(ctx, contextJWT, jwt)
	ctx = context.WithValue(ctx, contextJWTFromCookie, jwtFromCookie)

	return ctx, nil
}

func (api *API) xsrfMiddleware(ctx context.Context, w http.ResponseWriter, req *http.Request, rc *service.HandlerConfig) (context.Context, error) {
	ctx, end := telemetry.Span(ctx, "router.xsrfMiddleware")
	defer end()

	sessionValue := ctx.Value(contextSession)
	if sessionValue == nil {
		return ctx, sdk.WithStack(sdk.ErrUnauthorized)
	}

	session, ok := sessionValue.(*sdk.AuthSession)
	if !ok {
		return ctx, sdk.WithStack(sdk.ErrUnauthorized)
	}

	xsrfToken := req.Header.Get(xsrfHeaderName)
	existingXSRFToken, existXSRFTokenInCache := authentication.GetSessionXSRFToken(api.Cache, session.ID)

	// If it's not a read request we want to check the xsrf token then generate a new one
	// else if its a read request we want to reuse a cached XSRF token or generate one if not in cache or nothing given by the client
	if rc.PermissionLevel > sdk.PermissionRead {
		if !existXSRFTokenInCache || xsrfToken != existingXSRFToken {
			// We want to return a forbidden to allow the user to retry with a new token.
			return ctx, sdk.WithStack(sdk.ErrForbidden)
		}
	} else {
		if !existXSRFTokenInCache || xsrfToken == "" {
			sessionSecondsBeforeExpiration := int(session.ExpireAt.Sub(time.Now()).Seconds())
			var err error
			existingXSRFToken, err = authentication.NewSessionXSRFToken(api.Cache, session.ID, sessionSecondsBeforeExpiration)
			if err != nil {
				return ctx, err
			}
		}

		// Set a cookie with the jwt token
		api.SetCookieSession(w, xsrfCookieName, existingXSRFToken)
	}

	return ctx, nil
}
<commit_msg>fix(api): xsrf renew only if not in cache or not in cookie (#5373)<commit_after>package api

import (
	"context"
	"net/http"
	"strings"
	"time"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/gorilla/mux"

	"github.com/ovh/cds/engine/api/authentication"
	"github.com/ovh/cds/engine/api/services"
	"github.com/ovh/cds/engine/api/user"
	"github.com/ovh/cds/engine/api/worker"
	"github.com/ovh/cds/engine/service"
	"github.com/ovh/cds/sdk"
	"github.com/ovh/cds/sdk/log"
	"github.com/ovh/cds/sdk/telemetry"
)

const (
	jwtCookieName  = "jwt_token"
	xsrfHeaderName = "X-XSRF-TOKEN"
	xsrfCookieName = "xsrf_token"
)

func (api *API) authMiddleware(ctx context.Context, w http.ResponseWriter, req *http.Request, rc *service.HandlerConfig) (context.Context, error) {
	ctx, end := telemetry.Span(ctx, "router.authMiddleware")
	defer end()

	// Tokens (like izanamy)
	ctx, ok, err := api.authStatusTokenMiddleware(ctx, w, req, rc)
	if err != nil {
		return ctx, sdk.WithStack(err)
	}
	if ok {
		log.Info(ctx, "authMiddleware> authentification granted by token")
		return ctx, nil
	}

	// Check for a JWT in current request and add it to the context
	// If a JWT is given, we also checks that there are a valid session and consumer for it
	ctxWithJWT, err := api.jwtMiddleware(ctx, w, req, rc)
	if err != nil {
		return ctx, err
	}

	var (
		session  *sdk.AuthSession
		consumer *sdk.AuthConsumer
	)

	jwt, ok := ctxWithJWT.Value(contextJWT).(*jwt.Token)
	if ok {
		claims := jwt.Claims.(*sdk.AuthSessionJWTClaims)
		sessionID := claims.StandardClaims.Id
		// Check for session based on jwt from context
		session, err = authentication.CheckSession(ctx, api.mustDB(), sessionID)
		if err != nil {
			log.Warning(ctx, "authMiddleware> cannot find a valid session for given JWT: %v", err)
		}
	}

	if session != nil {
		ctx = context.WithValue(ctxWithJWT, contextSession, session)
		// Load auth consumer for current session in database with authentified user and contacts
		c, err := authentication.LoadConsumerByID(ctx, api.mustDB(), session.ConsumerID,
			authentication.LoadConsumerOptions.WithAuthentifiedUser)
		if err != nil {
			return ctx, sdk.NewErrorWithStack(err, sdk.ErrUnauthorized)
		}
		// If the consumer is disabled, return an error
		if c.Disabled {
			return ctx, sdk.WrapError(sdk.ErrUnauthorized, "consumer (%s) is disabled", c.ID)
		}
		// If the driver was disabled for the consumer that was found, ignore it
		if _, ok := api.AuthenticationDrivers[c.Type]; ok {
			// Add contacts for consumer's user
			if err := user.LoadOptions.WithContacts(ctx, api.mustDB(), c.AuthentifiedUser); err != nil {
				return ctx, err
			}

			// Add service for consumer if exists
			s, err := services.LoadByConsumerID(ctx, api.mustDB(), c.ID)
			if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) {
				return ctx, err
			}
			c.Service = s

			// Add worker for consumer if exists
			w, err := worker.LoadByConsumerID(ctx, api.mustDB(), c.ID)
			if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) {
				return ctx, err
			}
			c.Worker = w

			consumer = c
		}
	}

	if consumer != nil {
		ctx = context.WithValue(ctx, contextAPIConsumer, consumer)

		// Checks scopes, one of expected scopes should be in actual scopes
		// Actual scope empty list means wildcard scope, we don't need to check scopes
		expectedScopes, actualScopes := rc.AllowedScopes, consumer.ScopeDetails
		if len(expectedScopes) > 0 && len(actualScopes) > 0 {
			var found bool
		findScope:
			for i := range expectedScopes {
				for j := range actualScopes {
					if actualScopes[j].Scope == expectedScopes[i] {
						// Check if there are scope details, if yes we should check if current route/method is allowed in restrictions
						if len(actualScopes[j].Endpoints) == 0 {
							found = true
							break findScope
						}

						// if the route is not in current consumer allowed endpoints we should not validate the scope
						if exists, endpoint := actualScopes[j].Endpoints.FindEndpoint(rc.CleanURL); exists &&
							len(endpoint.Methods) == 0 || endpoint.Methods.Contains(rc.Method) {
							found = true
							break findScope
						}
					}
				}
			}
			if !found {
				return ctx, sdk.WrapError(sdk.ErrUnauthorized, "token scopes doesn't match expected: %v", expectedScopes)
			}
		}

		// Check that permission are valid for current route and consumer
		if err := api.checkPermission(ctx, mux.Vars(req), rc.PermissionLevel); err != nil {
			return ctx, err
		}

		jwtFromCookieVal := ctx.Value(contextJWTFromCookie)
		jwtFromCookie, _ := jwtFromCookieVal.(bool)
		if jwtFromCookie {
			ctx, err = api.xsrfMiddleware(ctx, w, req, rc)
			if err != nil {
				return ctx, err
			}
		}
	}

	// If we set Auth(false) on a handler, with should have a consumer in the context if a valid JWT is given
	if rc.NeedAuth && getAPIConsumer(ctx) == nil {
		return ctx, sdk.WithStack(sdk.ErrUnauthorized)
	}

	if rc.NeedAdmin && !isAdmin(ctx) {
		return ctx, sdk.WithStack(sdk.ErrForbidden)
	}

	return ctx, nil
}

// Checks static tokens
func (api *API) authStatusTokenMiddleware(ctx context.Context, w http.ResponseWriter, req *http.Request, rc *service.HandlerConfig) (context.Context, bool, error) {
	if len(rc.AllowedTokens) == 0 {
		return ctx, false, nil
	}
	for _, h := range rc.AllowedTokens {
		log.Debug("authStatusTokenMiddleware> checking allowed token: %v", h)
		headerSplitted := strings.Split(h, ":")
		receivedValue := req.Header.Get(headerSplitted[0])
		if receivedValue != headerSplitted[1] {
			return ctx, false, sdk.WrapError(sdk.ErrUnauthorized, "Router> Authorization denied token on %s %s for %s", req.Method, req.URL, req.RemoteAddr)
		}
	}
	return ctx, true, nil
}

func (api *API) jwtMiddleware(ctx context.Context, w http.ResponseWriter, req *http.Request, rc *service.HandlerConfig) (context.Context, error) {
	ctx, end := telemetry.Span(ctx, "router.jwtMiddleware")
	defer end()

	var jwtRaw string
	var jwtFromCookie bool
	// Try to get the jwt from the cookie firstly then from the authorization bearer header, a XSRF token with cookie
	jwtCookie, _ := req.Cookie(jwtCookieName)
	if jwtCookie != nil {
		jwtRaw = jwtCookie.Value
		jwtFromCookie = true
	} else if strings.HasPrefix(req.Header.Get("Authorization"), "Bearer ") {
		jwtRaw = strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
	}
	// If no jwt is given, simply return empty context without error
	if jwtRaw == "" {
		return ctx, nil
	}

	jwt, err := authentication.CheckSessionJWT(jwtRaw)
	if err != nil {
		if rc.NeedAuth {
			// If the given JWT is not valid log the error and return
			log.Warning(ctx, "jwtMiddleware> invalid given jwt token [%s]: %+v", req.URL.String(), err)
		}
		return ctx, nil
	}

	ctx = context.WithValue(ctx, contextJWTRaw, jwt)
	ctx = context.WithValue(ctx, contextJWT, jwt)
	ctx = context.WithValue(ctx, contextJWTFromCookie, jwtFromCookie)

	return ctx, nil
}

func (api *API) xsrfMiddleware(ctx context.Context, w http.ResponseWriter, req *http.Request, rc *service.HandlerConfig) (context.Context, error) {
	ctx, end := telemetry.Span(ctx, "router.xsrfMiddleware")
	defer end()

	sessionValue := ctx.Value(contextSession)
	if sessionValue == nil {
		return ctx, sdk.WithStack(sdk.ErrUnauthorized)
	}

	session, ok := sessionValue.(*sdk.AuthSession)
	if !ok {
		return ctx, sdk.WithStack(sdk.ErrUnauthorized)
	}

	xsrfToken := req.Header.Get(xsrfHeaderName)
	existingXSRFToken, existXSRFTokenInCache := authentication.GetSessionXSRFToken(api.Cache, session.ID)

	xsrfTokenCookie, _ := req.Cookie(xsrfCookieName)
	xsrfTokenCookieExistInCookie := xsrfTokenCookie != nil

	// If it's not a read request we want to check the xsrf token then generate a new one
	// else if its a read request we want to reuse a cached XSRF token or generate one if not in cache or nothing given by the client
	if rc.PermissionLevel > sdk.PermissionRead {
		if !existXSRFTokenInCache || xsrfToken != existingXSRFToken {
			// We want to return a forbidden to allow the user to retry with a new token.
			return ctx, sdk.WithStack(sdk.ErrForbidden)
		}
	} else {
		if !existXSRFTokenInCache || !xsrfTokenCookieExistInCookie {
			sessionSecondsBeforeExpiration := int(session.ExpireAt.Sub(time.Now()).Seconds())
			var err error
			existingXSRFToken, err = authentication.NewSessionXSRFToken(api.Cache, session.ID, sessionSecondsBeforeExpiration)
			if err != nil {
				return ctx, err
			}
		}

		// Set a cookie with the jwt token
		api.SetCookieSession(w, xsrfCookieName, existingXSRFToken)
	}

	return ctx, nil
}
<|endoftext|>