<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path"
	"strconv"
	"strings"
	"sync"
	"time"

	dockerclient "github.com/fsouza/go-dockerclient"
)

type NFCont struct {
	id       string
	pid      int
	stopchan chan bool
	wg       sync.WaitGroup
	dbclient *DBClient
}

func NewNFCont(id string, pid int, dbclient *DBClient) *NFCont {
	return &NFCont{
		id:       id,
		pid:      pid,
		stopchan: make(chan bool),
		dbclient: dbclient,
	}
}

func (n *NFCont) String() string {
	return fmt.Sprintf("{id:%s, pid:%s}", n.id, n.pid)
}

func (n *NFCont) Tail(docker *dockerclient.Client) {
	n.wg.Add(1)
	go n.tail(docker)
}

func (n *NFCont) StopTail() {
	close(n.stopchan)
	n.wg.Wait()
	log.Println("[INFO] cleaned up for container", n.id)
}

func (n *NFCont) tail(docker *dockerclient.Client) {
	defer n.wg.Done()

	// wait for queue to be created
	netfilter_file := path.Join(HOST_PROC_PATH, strconv.Itoa(n.pid), "/net/netfilter/nfnetlink_queue")
	dev_file := path.Join(HOST_PROC_PATH, strconv.Itoa(n.pid), "/net/dev")
	for {
		timeout := time.After(FILES_CHECK_INTERVAL * time.Millisecond)
		select {
		case <-n.stopchan:
			log.Println("[INFO] no clean up required for containern", n.id)
			return
		case <-timeout:
		}

		if _, err := os.Stat(dev_file); err != nil {
			log.Printf("[WARN] %s file not found!\n", dev_file)
			continue
		}
		if _, err := os.Stat(netfilter_file); err != nil {
			log.Printf("[WARN] %s file not found!\n", netfilter_file)
			continue
		}
		break
	}

	for {
		select {
		case <-n.stopchan:
			log.Println("[INFO] exiting Tail for container", n.id)
			return
		default:
			time.Sleep(time.Duration(READ_PERIOD) * time.Millisecond)
		}

		out, err := ioutil.ReadFile(netfilter_file)
		curtime := time.Now()
		if err != nil {
			log.Println("[WARN] unable to read netfilter file:", err)
			return
		}
		row := strings.Fields(string(out))
		if len(row) < 9 {
			log.Println("[WARN] incorrect parsing of netfilter file, parsed line:", row)
			continue
		}
		if ival, err := strconv.ParseInt(row[2], 10, 64); err != nil {
			log.Println("[WARN] unable to parse", row[2], "err:", err)
		} else {
			n.dbclient.Write("snort_queue_length", n.id, map[string]interface{}{"value": ival}, curtime)
		}
		if ival, err := strconv.ParseInt(row[5], 10, 64); err != nil {
			log.Println("[WARN] unable to parse", row[5], "err:", err)
		} else {
			n.dbclient.Write("snort_queue_drops", n.id, map[string]interface{}{"value": ival}, curtime)
		}
		if ival, err := strconv.ParseInt(row[6], 10, 64); err != nil {
			log.Println("[WARN] unable to parse", row[6], "err:", err)
		} else {
			n.dbclient.Write("snort_user_drops", n.id, map[string]interface{}{"value": ival}, curtime)
		}

		// dev file
		out, err = ioutil.ReadFile(dev_file)
		curtime = time.Now()
		if err != nil {
			log.Println("[WARN] unable to read dev file:", err)
			return
		}
		rows := strings.Split(string(out), "\n")
		if len(rows) < 4 {
			log.Println("[WARN] incorrect number of lines in dev file for container", n.id)
			continue
		}
		index := 3
		if strings.Contains(rows[2], "lo") {
			if strings.Contains(rows[3], "lo") {
				log.Println("[WARN] unable to find correct network interface for container", n.id)
				continue
			}
		} else {
			index = 2
		}
		row = strings.Fields(rows[index])
		if len(row) < 17 {
			log.Println("[WARN] incorrect parsing of dev file, parsed line:", row)
			continue
		}
		if ival, err := strconv.ParseInt(row[2], 10, 64); err != nil {
			log.Println("[WARN] unable to parse", row[2], "err:", err)
		} else {
			n.dbclient.Write("rx_packets", n.id, map[string]interface{}{"value": ival}, curtime)
		}
		if ival, err := strconv.ParseInt(row[10], 10, 64); err != nil {
			log.Println("[WARN] unable to parse", row[10], "err:", err)
		} else {
			n.dbclient.Write("tx_packets", n.id, map[string]interface{}{"value": ival}, curtime)
		}

		// available shares
		cont, err := docker.InspectContainer(n.id)
		if err != nil {
			log.Println("[WARN] unable to inspect container", n.id)
			continue
		}
		n.dbclient.Write("available_shares", n.id, map[string]interface{}{"value": cont.HostConfig.CPUShares}, time.Now())
	}

	log.Println("[INFO] exiting Tail for container", n.id)
}
<commit_msg>monitor : using float for counting packets for uniformity<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path"
	"strconv"
	"strings"
	"sync"
	"time"

	dockerclient "github.com/fsouza/go-dockerclient"
)

type NFCont struct {
	id       string
	pid      int
	stopchan chan bool
	wg       sync.WaitGroup
	dbclient *DBClient
}

func NewNFCont(id string, pid int, dbclient *DBClient) *NFCont {
	return &NFCont{
		id:       id,
		pid:      pid,
		stopchan: make(chan bool),
		dbclient: dbclient,
	}
}

func (n *NFCont) String() string {
	return fmt.Sprintf("{id:%s, pid:%s}", n.id, n.pid)
}

func (n *NFCont) Tail(docker *dockerclient.Client) {
	n.wg.Add(1)
	go n.tail(docker)
}

func (n *NFCont) StopTail() {
	close(n.stopchan)
	n.wg.Wait()
	log.Println("[INFO] cleaned up for container", n.id)
}

func (n *NFCont) tail(docker *dockerclient.Client) {
	defer n.wg.Done()

	// wait for queue to be created
	netfilter_file := path.Join(HOST_PROC_PATH, strconv.Itoa(n.pid), "/net/netfilter/nfnetlink_queue")
	dev_file := path.Join(HOST_PROC_PATH, strconv.Itoa(n.pid), "/net/dev")
	for {
		timeout := time.After(FILES_CHECK_INTERVAL * time.Millisecond)
		select {
		case <-n.stopchan:
			log.Println("[INFO] no clean up required for containern", n.id)
			return
		case <-timeout:
		}

		if _, err := os.Stat(dev_file); err != nil {
			log.Printf("[WARN] %s file not found!\n", dev_file)
			continue
		}
		if _, err := os.Stat(netfilter_file); err != nil {
			log.Printf("[WARN] %s file not found!\n", netfilter_file)
			continue
		}
		break
	}

	for {
		select {
		case <-n.stopchan:
			log.Println("[INFO] exiting Tail for container", n.id)
			return
		default:
			time.Sleep(time.Duration(READ_PERIOD) * time.Millisecond)
		}

		out, err := ioutil.ReadFile(netfilter_file)
		curtime := time.Now()
		if err != nil {
			log.Println("[WARN] unable to read netfilter file:", err)
			return
		}
		row := strings.Fields(string(out))
		if len(row) < 9 {
			log.Println("[WARN] incorrect parsing of netfilter file, parsed line:", row)
			continue
		}
		if ival, err := strconv.ParseInt(row[2], 10, 64); err != nil {
			log.Println("[WARN] unable to parse", row[2], "err:", err)
		} else {
			n.dbclient.Write("snort_queue_length", n.id, map[string]interface{}{"value": ival}, curtime)
		}
		if ival, err := strconv.ParseInt(row[5], 10, 64); err != nil {
			log.Println("[WARN] unable to parse", row[5], "err:", err)
		} else {
			n.dbclient.Write("snort_queue_drops", n.id, map[string]interface{}{"value": ival}, curtime)
		}
		if ival, err := strconv.ParseInt(row[6], 10, 64); err != nil {
			log.Println("[WARN] unable to parse", row[6], "err:", err)
		} else {
			n.dbclient.Write("snort_user_drops", n.id, map[string]interface{}{"value": ival}, curtime)
		}

		// dev file
		out, err = ioutil.ReadFile(dev_file)
		curtime = time.Now()
		if err != nil {
			log.Println("[WARN] unable to read dev file:", err)
			return
		}
		rows := strings.Split(string(out), "\n")
		if len(rows) < 4 {
			log.Println("[WARN] incorrect number of lines in dev file for container", n.id)
			continue
		}
		index := 3
		if strings.Contains(rows[2], "lo") {
			if strings.Contains(rows[3], "lo") {
				log.Println("[WARN] unable to find correct network interface for container", n.id)
				continue
			}
		} else {
			index = 2
		}
		row = strings.Fields(rows[index])
		if len(row) < 17 {
			log.Println("[WARN] incorrect parsing of dev file, parsed line:", row)
			continue
		}
		if fval, err := strconv.ParseFloat(row[2], 64); err != nil {
			log.Println("[WARN] unable to parse", row[2], "err:", err)
		} else {
			n.dbclient.Write("rx_packets", n.id, map[string]interface{}{"value": fval}, curtime)
		}
		if fval, err := strconv.ParseFloat(row[10], 64); err != nil {
			log.Println("[WARN] unable to parse", row[10], "err:", err)
		} else {
			n.dbclient.Write("tx_packets", n.id, map[string]interface{}{"value": fval}, curtime)
		}

		// available shares
		cont, err := docker.InspectContainer(n.id)
		if err != nil {
			log.Println("[WARN] unable to inspect container", n.id)
			continue
		}
		n.dbclient.Write("available_shares", n.id, map[string]interface{}{"value": cont.HostConfig.CPUShares}, time.Now())
	}

	log.Println("[INFO] exiting Tail for container", n.id)
}
<|endoftext|>


<commit_before>//go:build windows
// +build windows

package checks

import (
	"fmt"
	"syscall"

	"golang.org/x/sys/windows"
	"golang.org/x/sys/windows/svc"
	"golang.org/x/sys/windows/svc/mgr"
)

var (
	win windowsSystem = windowsOS{}
)

type OSServiceClient struct {
	scHandle windows.Handle
}

func NewOSServiceClient() (*OSServiceClient, error) {
	scHandle, err := win.OpenSCManager(nil, nil, windows.SC_MANAGER_CONNECT)
	if err != nil {
		return nil, fmt.Errorf("error connecting to service manager: %w", err)
	}
	return &OSServiceClient{scHandle: scHandle}, nil
}

func (client *OSServiceClient) Check(serviceName string) (err error) {
	m := win.getWindowsSvcMgr(client.scHandle)
	defer m.Disconnect()

	svcNamePtr, err := syscall.UTF16PtrFromString(serviceName)
	if err != nil {
		return fmt.Errorf("service name must not contain NUL bytes: %w", err)
	}
	svcHandle, err := win.OpenService(win.getWindowsSvcMgrHandle(m), svcNamePtr, windows.SC_MANAGER_ENUMERATE_SERVICE)
	if err != nil {
		return fmt.Errorf("error accessing service: %w", err)
	}
	service := win.getWindowsSvc(serviceName, svcHandle)
	defer service.Close()

	status, err := service.Query()
	if err != nil {
		return fmt.Errorf("error querying service status: %w", err)
	}

	switch status.State {
	case svc.Running:
		return nil
	case svc.Paused, svc.Stopped:
		err = fmt.Errorf("service status: %v - %w", svcStateString(status.State), ErrOSServiceStatusCritical)
	default:
		err = fmt.Errorf("service status: %v", svcStateString(status.State))
	}

	return err
}

type windowsOS struct{}

func (windowsOS) OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle windows.Handle, err error) {
	return windows.OpenSCManager(machineName, databaseName, access)
}
func (windowsOS) OpenService(mgr windows.Handle, serviceName *uint16, access uint32) (handle windows.Handle, err error) {
	return windows.OpenService(mgr, serviceName, access)
}

func (windowsOS) getWindowsSvcMgr(h windows.Handle) windowsSvcMgr { return &mgr.Mgr{Handle: h} }
func (windowsOS) getWindowsSvcMgrHandle(sm windowsSvcMgr) windows.Handle {
	return sm.(*mgr.Mgr).Handle
}

func (windowsOS) getWindowsSvc(name string, h windows.Handle) windowsSvc {
	return &mgr.Service{Name: name, Handle: h}
}

type windowsSystem interface {
	OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle windows.Handle, err error)
	OpenService(mgr windows.Handle, serviceName *uint16, access uint32) (handle windows.Handle, err error)

	getWindowsSvcMgr(h windows.Handle) windowsSvcMgr
	getWindowsSvcMgrHandle(sm windowsSvcMgr) windows.Handle
	getWindowsSvc(name string, h windows.Handle) windowsSvc
}

type windowsSvcMgr interface {
	Disconnect() error
}

type windowsSvc interface {
	Close() error
	Query() (svc.Status, error)
}

// svcStateString converts svc.State (uint32) to human readable string
//
// source: https://pkg.go.dev/golang.org/x/sys/windows/svc#pkg-constants
func svcStateString(state svc.State) string {
	switch state {
	case svc.State(windows.SERVICE_STOPPED):
		return "Stopped"
	case svc.State(windows.SERVICE_START_PENDING):
		return "StartPending"
	case svc.State(windows.SERVICE_STOP_PENDING):
		return "StopPending"
	case svc.State(windows.SERVICE_RUNNING):
		return "Running"
	case svc.State(windows.SERVICE_CONTINUE_PENDING):
		return "ContinuePending"
	case svc.State(windows.SERVICE_PAUSE_PENDING):
		return "PausePending"
	case svc.State(windows.SERVICE_PAUSED):
		return "Paused"
	default:
		//if not handled we return the underlying uint32
		return fmt.Sprintf("%d", state)
	}
}
<commit_msg>fix(checks): os_service lifecycle bugfix<commit_after>//go:build windows
// +build windows

package checks

import (
	"fmt"
	"syscall"

	"golang.org/x/sys/windows"
	"golang.org/x/sys/windows/svc"
	"golang.org/x/sys/windows/svc/mgr"
)

var (
	win windowsSystem = windowsOS{}
)

type OSServiceClient struct{}

func NewOSServiceClient() (*OSServiceClient, error) {
	return &OSServiceClient{}, nil
}

func (client *OSServiceClient) Check(serviceName string) (err error) {
	h, err := windows.OpenSCManager(nil, nil, windows.SC_MANAGER_CONNECT)
	if err != nil {
		return fmt.Errorf("failed to connect to Windows service manager: %w", err)
	}

	m := win.getWindowsSvcMgr(h)
	defer m.Disconnect()

	svcNamePtr, err := syscall.UTF16PtrFromString(serviceName)
	if err != nil {
		return fmt.Errorf("service name must not contain NUL bytes: %w", err)
	}
	svcHandle, err := win.OpenService(win.getWindowsSvcMgrHandle(m), svcNamePtr, windows.SC_MANAGER_ENUMERATE_SERVICE)
	if err != nil {
		return fmt.Errorf("error accessing service: %w", err)
	}
	service := win.getWindowsSvc(serviceName, svcHandle)
	defer service.Close()

	status, err := service.Query()
	if err != nil {
		return fmt.Errorf("error querying service status: %w", err)
	}

	switch status.State {
	case svc.Running:
		return nil
	case svc.Paused, svc.Stopped:
		err = fmt.Errorf("service status: %v - %w", svcStateString(status.State), ErrOSServiceStatusCritical)
	default:
		err = fmt.Errorf("service status: %v", svcStateString(status.State))
	}

	return err
}

type windowsOS struct{}

func (windowsOS) OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle windows.Handle, err error) {
	return windows.OpenSCManager(machineName, databaseName, access)
}
func (windowsOS) OpenService(mgr windows.Handle, serviceName *uint16, access uint32) (handle windows.Handle, err error) {
	return windows.OpenService(mgr, serviceName, access)
}

func (windowsOS) getWindowsSvcMgr(h windows.Handle) windowsSvcMgr { return &mgr.Mgr{Handle: h} }
func (windowsOS) getWindowsSvcMgrHandle(sm windowsSvcMgr) windows.Handle {
	return sm.(*mgr.Mgr).Handle
}

func (windowsOS) getWindowsSvc(name string, h windows.Handle) windowsSvc {
	return &mgr.Service{Name: name, Handle: h}
}

type windowsSystem interface {
	OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle windows.Handle, err error)
	OpenService(mgr windows.Handle, serviceName *uint16, access uint32) (handle windows.Handle, err error)

	getWindowsSvcMgr(h windows.Handle) windowsSvcMgr
	getWindowsSvcMgrHandle(sm windowsSvcMgr) windows.Handle
	getWindowsSvc(name string, h windows.Handle) windowsSvc
}

type windowsSvcMgr interface {
	Disconnect() error
}

type windowsSvc interface {
	Close() error
	Query() (svc.Status, error)
}

// svcStateString converts svc.State (uint32) to human readable string
//
// source: https://pkg.go.dev/golang.org/x/sys/windows/svc#pkg-constants
func svcStateString(state svc.State) string {
	switch state {
	case svc.State(windows.SERVICE_STOPPED):
		return "Stopped"
	case svc.State(windows.SERVICE_START_PENDING):
		return "StartPending"
	case svc.State(windows.SERVICE_STOP_PENDING):
		return "StopPending"
	case svc.State(windows.SERVICE_RUNNING):
		return "Running"
	case svc.State(windows.SERVICE_CONTINUE_PENDING):
		return "ContinuePending"
	case svc.State(windows.SERVICE_PAUSE_PENDING):
		return "PausePending"
	case svc.State(windows.SERVICE_PAUSED):
		return "Paused"
	default:
		//if not handled we return the underlying uint32
		return fmt.Sprintf("%d", state)
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package outputhost

import (
	"github.com/uber-common/bark"
	"github.com/uber/cherami-server/common"
	"github.com/uber/cherami-server/common/dconfig"
	m "github.com/uber/cherami-thrift/.generated/go/metadata"
)

type (
	// OutputCgConfig is the per cg config used by the
	// cassandra config manager
	OutputCgConfig struct {
		MessageCacheSize []string `name:"messagecachesize" default:"/=10000"`
	}
)

// newConfigManager creates and returns a new instance
// of CassandraConfigManager.
func newConfigManager(mClient m.TChanMetadataService, logger bark.Logger) dconfig.ConfigManager {
	cfgTypes := map[string]interface{}{
		common.OutputServiceName: OutputCgConfig{},
	}
	return dconfig.NewCassandraConfigManager(mClient, cfgTypes, logger)
}
<commit_msg>Update comment about the config item<commit_after>// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package outputhost

import (
	"github.com/uber-common/bark"
	"github.com/uber/cherami-server/common"
	"github.com/uber/cherami-server/common/dconfig"
	m "github.com/uber/cherami-thrift/.generated/go/metadata"
)

type (
	// OutputCgConfig is the per cg config used by the
	// cassandra config manager
	OutputCgConfig struct {
		// MessageCacheSize is used to configure the per CG cache size.
		// This is a string slice, where each entry is a tuple with the
		// destination/CG_name=value.
		// For example, we can ideally have two CGs for the same destination
		// with different size config as follows:
		// "/test/destination//test/cg_1=50,/test/destination//test/cg_2=100"
		MessageCacheSize []string `name:"messagecachesize" default:"/=10000"`
	}
)

// newConfigManager creates and returns a new instance
// of CassandraConfigManager.
func newConfigManager(mClient m.TChanMetadataService, logger bark.Logger) dconfig.ConfigManager {
	cfgTypes := map[string]interface{}{
		common.OutputServiceName: OutputCgConfig{},
	}
	return dconfig.NewCassandraConfigManager(mClient, cfgTypes, logger)
}
<|endoftext|>


<commit_before>package cli

import (
	"fmt"
	"io"
	"os"
	"text/tabwriter"

	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/flynn/go-docopt"
	"github.com/flynn/flynn/host/types"
	"github.com/flynn/flynn/pkg/cluster"
)

func init() {
	Register("inspect", runInspect, `
usage: flynn-host inspect ID

Get low-level information about a job.`)
}

func runInspect(args *docopt.Args, client *cluster.Client) error {
	hostID, jobID, err := cluster.ParseJobID(args.String["ID"])
	if err != nil {
		return err
	}
	hostClient, err := client.DialHost(hostID)
	if err != nil {
		return fmt.Errorf("could not connect to host %s: %s", hostID, err)
	}
	job, err := hostClient.GetJob(jobID)
	if err != nil {
		return fmt.Errorf("no such job")
	}

	printJobDesc(job, os.Stdout)
	return nil
}

func printJobDesc(job *host.ActiveJob, out io.Writer) {
	w := tabwriter.NewWriter(out, 1, 2, 2, ' ', 0)
	defer w.Flush()
	listRec(w, "ID", clusterJobID(*job))
	listRec(w, "Status", job.Status)
	listRec(w, "StartedAt", job.StartedAt)
	listRec(w, "EndedAt", job.EndedAt)
	listRec(w, "ExitStatus", job.ExitStatus)
	listRec(w, "IP Address", job.InternalIP)
	for k, v := range job.Job.Metadata {
		listRec(w, k, v)
	}
}

func listRec(w io.Writer, a ...interface{}) {
	for i, x := range a {
		fmt.Fprint(w, x)
		if i+1 < len(a) {
			w.Write([]byte{'\t'})
		} else {
			w.Write([]byte{'\n'})
		}
	}
}
<commit_msg>host/cli: Update inspect command to print env vars<commit_after>package cli

import (
	"fmt"
	"io"
	"os"
	"text/tabwriter"

	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/flynn/go-docopt"
	"github.com/flynn/flynn/host/types"
	"github.com/flynn/flynn/pkg/cluster"
)

func init() {
	Register("inspect", runInspect, `
usage: flynn-host inspect ID

Get low-level information about a job.`)
}

func runInspect(args *docopt.Args, client *cluster.Client) error {
	hostID, jobID, err := cluster.ParseJobID(args.String["ID"])
	if err != nil {
		return err
	}
	hostClient, err := client.DialHost(hostID)
	if err != nil {
		return fmt.Errorf("could not connect to host %s: %s", hostID, err)
	}
	job, err := hostClient.GetJob(jobID)
	if err != nil {
		return fmt.Errorf("no such job")
	}

	printJobDesc(job, os.Stdout)
	return nil
}

func printJobDesc(job *host.ActiveJob, out io.Writer) {
	w := tabwriter.NewWriter(out, 1, 2, 2, ' ', 0)
	defer w.Flush()
	listRec(w, "ID", clusterJobID(*job))
	listRec(w, "Status", job.Status)
	listRec(w, "StartedAt", job.StartedAt)
	listRec(w, "EndedAt", job.EndedAt)
	listRec(w, "ExitStatus", job.ExitStatus)
	listRec(w, "IP Address", job.InternalIP)
	for k, v := range job.Job.Metadata {
		listRec(w, k, v)
	}
	for k, v := range job.Job.Config.Env {
		listRec(w, fmt.Sprintf("ENV[%s]", k), v)
	}
}

func listRec(w io.Writer, a ...interface{}) {
	for i, x := range a {
		fmt.Fprint(w, x)
		if i+1 < len(a) {
			w.Write([]byte{'\t'})
		} else {
			w.Write([]byte{'\n'})
		}
	}
}
<|endoftext|>


<commit_before>package service

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net"
	"strings"
	"time"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/gen/s3"
)

const (
	minStorageInterval = time.Second * 120
	maxStorageInterval = time.Second * 240

	expireTimeout = time.Minute
)

type bytesReadCloser struct {
	*bytes.Reader
}

func (brc bytesReadCloser) Read(b []byte) (int, error) {
	return brc.Reader.Read(b)
}

func (bytesReadCloser) Close() (err error) {
	return
}

func randomStorageInterval() time.Duration {
	return randomDuration(minStorageInterval, maxStorageInterval)
}

func initStorage(local *localNode, remotes *remoteNodes, notify <-chan struct{}, reply chan<- []*net.UDPAddr, credData []byte, region, bucket, prefix string, dryRun bool, log *Log) (err error) {
	if prefix != "" && !strings.HasSuffix(prefix, "/") {
		prefix += "/"
	}

	localKey := prefix + local.ipAddr

	creds, err := parseCredentials(credData)
	if err != nil {
		return
	}

	var client *s3.S3

	if !dryRun {
		client = s3.New(creds, region, nil)
	}

	if err = updateStorage(local, client, bucket, localKey, log); err != nil {
		return
	}

	if err = scanStorage(local, remotes, reply, client, bucket, prefix, log); err != nil {
		return
	}

	go storageLoop(local, remotes, notify, reply, client, bucket, prefix, localKey, log)

	return
}

func storageLoop(local *localNode, remotes *remoteNodes, notify <-chan struct{}, reply chan<- []*net.UDPAddr, client *s3.S3, bucket, prefix, localKey string, log *Log) {
	timer := time.NewTimer(randomStorageInterval())

	for {
		var scan bool

		select {
		case <-notify:
			scan = false

		case <-timer.C:
			timer.Reset(randomStorageInterval())
			scan = true
		}

		if err := updateStorage(local, client, bucket, localKey, log); err != nil {
			log.Error(err)
		}

		if scan {
			if err := scanStorage(local, remotes, reply, client, bucket, prefix, log); err != nil {
				log.Error(err)
			}
		}
	}
}

func updateStorage(local *localNode, client *s3.S3, bucket, key string, log *Log) (err error) {
	log.Debug("updating S3")

	data, err := local.marshalForStorage()
	if err != nil {
		panic(err)
	}

	err = putObject(client, bucket, key, data, "application/json")
	return
}

func scanStorage(local *localNode, remotes *remoteNodes, reply chan<- []*net.UDPAddr, client *s3.S3, bucket, prefix string, log *Log) (err error) {
	log.Debug("scanning S3")

	objects := listObjects(client, bucket, prefix, log)
	if objects == nil {
		return
	}

	var loadKeys []aws.StringValue
	var deleteKeys []aws.StringValue

	expireThreshold := time.Now().Add(-expireTimeout)

	for object := range objects {
		ipAddr := (*object.Key)[len(prefix):]
		if ipAddr == "" || ipAddr == local.ipAddr {
			continue
		}

		if ip := net.ParseIP(ipAddr); ip == nil {
			log.Errorf("bad S3 key: %s", *object.Key)
			continue
		} else if !ip.IsGlobalUnicast() {
			log.Errorf("bad IP address in S3: %s", *object.Key)
			continue
		}

		if object.LastModified.After(expireThreshold) {
			if remotes.updatable(ipAddr, object.LastModified) {
				loadKeys = append(loadKeys, object.Key)
			}
		} else {
			deleteKeys = append(deleteKeys, object.Key)
		}
	}

	for _, key := range deleteKeys {
		ipAddr := (*key)[len(prefix):]

		log.Infof("deleting %s from S3", ipAddr)

		if err := deleteObject(client, bucket, key); err != nil {
			log.Errorf("S3 DeleteObject: %s", err)
		}
	}

	var newAddrs []*net.UDPAddr

	for _, key := range loadKeys {
		ipAddr := (*key)[len(prefix):]

		log.Debugf("loading %s from S3", ipAddr)

		if output, err := getObject(client, bucket, key); err == nil {
			node := new(Node)
			err := json.NewDecoder(output.Body).Decode(node)
			output.Body.Close()
			if err != nil {
				log.Errorf("S3: %s: %s", ipAddr, err)
				continue
			}

			node.IPAddr = ipAddr
			node.TimeNs = output.LastModified.UnixNano()

			if newAddr := remotes.update(node, local, log); newAddr != nil {
				newAddrs = append(newAddrs, newAddr)
			}
		} else {
			log.Errorf("S3 GetObject: %s", err)
		}
	}

	if len(newAddrs) > 0 {
		reply <- newAddrs
	}

	remotes.expire(expireThreshold, local, log)

	return
}

func parseCredentials(data []byte) (creds aws.CredentialsProvider, err error) {
	var accessKey string
	var secretKey string

	if data != nil {
		fields := strings.Fields(strings.TrimSpace(string(data)))
		if len(fields) != 2 {
			err = errors.New("bad AWS credentials file format")
			return
		}

		accessKey = fields[0]
		secretKey = fields[1]
	}

	creds = aws.DetectCreds(accessKey, secretKey, "")
	return
}

func putObject(client *s3.S3, bucket string, key string, body []byte, contentType string) (err error) {
	contentLength := int64(len(body))

	request := &s3.PutObjectRequest{
		Body:          bytesReadCloser{bytes.NewReader(body)},
		Bucket:        &bucket,
		ContentLength: &contentLength,
		ContentType:   &contentType,
		Key:           &key,
	}

	if client == nil {
		return
	}

	if _, err = client.PutObject(request); err != nil {
		err = fmt.Errorf("S3 PutObject: %s", err)
	}
	return
}

func getObject(client *s3.S3, bucket string, key aws.StringValue) (output *s3.GetObjectOutput, err error) {
	request := &s3.GetObjectRequest{
		Bucket: &bucket,
		Key:    key,
	}

	return client.GetObject(request)
}

func deleteObject(client *s3.S3, bucket string, key aws.StringValue) (err error) {
	request := &s3.DeleteObjectRequest{
		Bucket: &bucket,
		Key:    key,
	}

	_, err = client.DeleteObject(request)
	return
}

func listObjects(client *s3.S3, bucket, prefix string, log *Log) (channel chan *s3.Object) {
	request := &s3.ListObjectsRequest{
		Bucket: &bucket,
		Prefix: &prefix,
	}

	channel = make(chan *s3.Object)

	if client == nil {
		close(channel)
		return
	}

	output, err := client.ListObjects(request)
	if err != nil {
		log.Errorf("S3 ListObjects: %s", err)
		return
	}

	go func() {
		defer close(channel)

		for {
			for i := range output.Contents {
				object := &output.Contents[i]
				channel <- object
				request.Marker = object.Key
			}

			if !*output.IsTruncated {
				break
			}

			if output, err = client.ListObjects(request); err != nil {
				log.Errorf("S3 ListObjects: %s", err)
				break
			}
		}
	}()

	return
}
<commit_msg>sensible S3 key expiration timeout<commit_after>package service

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net"
	"strings"
	"time"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/gen/s3"
)

const (
	minStorageInterval = time.Second * 120
	maxStorageInterval = time.Second * 240

	expireTimeout = time.Minute * 15
)

type bytesReadCloser struct {
	*bytes.Reader
}

func (brc bytesReadCloser) Read(b []byte) (int, error) {
	return brc.Reader.Read(b)
}

func (bytesReadCloser) Close() (err error) {
	return
}

func randomStorageInterval() time.Duration {
	return randomDuration(minStorageInterval, maxStorageInterval)
}

func initStorage(local *localNode, remotes *remoteNodes, notify <-chan struct{}, reply chan<- []*net.UDPAddr, credData []byte, region, bucket, prefix string, dryRun bool, log *Log) (err error) {
	if prefix != "" && !strings.HasSuffix(prefix, "/") {
		prefix += "/"
	}

	localKey := prefix + local.ipAddr

	creds, err := parseCredentials(credData)
	if err != nil {
		return
	}

	var client *s3.S3

	if !dryRun {
		client = s3.New(creds, region, nil)
	}

	if err = updateStorage(local, client, bucket, localKey, log); err != nil {
		return
	}

	if err = scanStorage(local, remotes, reply, client, bucket, prefix, log); err != nil {
		return
	}

	go storageLoop(local, remotes, notify, reply, client, bucket, prefix, localKey, log)

	return
}

func storageLoop(local *localNode, remotes *remoteNodes, notify <-chan struct{}, reply chan<- []*net.UDPAddr, client *s3.S3, bucket, prefix, localKey string, log *Log) {
	timer := time.NewTimer(randomStorageInterval())

	for {
		var scan bool

		select {
		case <-notify:
			scan = false

		case <-timer.C:
			timer.Reset(randomStorageInterval())
			scan = true
		}

		if err := updateStorage(local, client, bucket, localKey, log); err != nil {
			log.Error(err)
		}

		if scan {
			if err := scanStorage(local, remotes, reply, client, bucket, prefix, log); err != nil {
				log.Error(err)
			}
		}
	}
}

func updateStorage(local *localNode, client *s3.S3, bucket, key string, log *Log) (err error) {
	log.Debug("updating S3")

	data, err := local.marshalForStorage()
	if err != nil {
		panic(err)
	}

	err = putObject(client, bucket, key, data, "application/json")
	return
}

func scanStorage(local *localNode, remotes *remoteNodes, reply chan<- []*net.UDPAddr, client *s3.S3, bucket, prefix string, log *Log) (err error) {
	log.Debug("scanning S3")

	objects := listObjects(client, bucket, prefix, log)
	if objects == nil {
		return
	}

	var loadKeys []aws.StringValue
	var deleteKeys []aws.StringValue

	expireThreshold := time.Now().Add(-expireTimeout)

	for object := range objects {
		ipAddr := (*object.Key)[len(prefix):]
		if ipAddr == "" || ipAddr == local.ipAddr {
			continue
		}

		if ip := net.ParseIP(ipAddr); ip == nil {
			log.Errorf("bad S3 key: %s", *object.Key)
			continue
		} else if !ip.IsGlobalUnicast() {
			log.Errorf("bad IP address in S3: %s", *object.Key)
			continue
		}

		if object.LastModified.After(expireThreshold) {
			if remotes.updatable(ipAddr, object.LastModified) {
				loadKeys = append(loadKeys, object.Key)
			}
		} else {
			deleteKeys = append(deleteKeys, object.Key)
		}
	}

	for _, key := range deleteKeys {
		ipAddr := (*key)[len(prefix):]

		log.Infof("deleting %s from S3", ipAddr)

		if err := deleteObject(client, bucket, key); err != nil {
			log.Errorf("S3 DeleteObject: %s", err)
		}
	}

	var newAddrs []*net.UDPAddr

	for _, key := range loadKeys {
		ipAddr := (*key)[len(prefix):]

		log.Debugf("loading %s from S3", ipAddr)

		if output, err := getObject(client, bucket, key); err == nil {
			node := new(Node)
			err := json.NewDecoder(output.Body).Decode(node)
			output.Body.Close()
			if err != nil {
				log.Errorf("S3: %s: %s", ipAddr, err)
				continue
			}

			node.IPAddr = ipAddr
			node.TimeNs = output.LastModified.UnixNano()

			if newAddr := remotes.update(node, local, log); newAddr != nil {
				newAddrs = append(newAddrs, newAddr)
			}
		} else {
			log.Errorf("S3 GetObject: %s", err)
		}
	}

	if len(newAddrs) > 0 {
		reply <- newAddrs
	}

	remotes.expire(expireThreshold, local, log)

	return
}

func parseCredentials(data []byte) (creds aws.CredentialsProvider, err error) {
	var accessKey string
	var secretKey string

	if data != nil {
		fields := strings.Fields(strings.TrimSpace(string(data)))
		if len(fields) != 2 {
			err = errors.New("bad AWS credentials file format")
			return
		}

		accessKey = fields[0]
		secretKey = fields[1]
	}

	creds = aws.DetectCreds(accessKey, secretKey, "")
	return
}

func putObject(client *s3.S3, bucket string, key string, body []byte, contentType string) (err error) {
	contentLength := int64(len(body))

	request := &s3.PutObjectRequest{
		Body:          bytesReadCloser{bytes.NewReader(body)},
		Bucket:        &bucket,
		ContentLength: &contentLength,
		ContentType:   &contentType,
		Key:           &key,
	}

	if client == nil {
		return
	}

	if _, err = client.PutObject(request); err != nil {
		err = fmt.Errorf("S3 PutObject: %s", err)
	}
	return
}

func getObject(client *s3.S3, bucket string, key aws.StringValue) (output *s3.GetObjectOutput, err error) {
	request := &s3.GetObjectRequest{
		Bucket: &bucket,
		Key:    key,
	}

	return client.GetObject(request)
}

func deleteObject(client *s3.S3, bucket string, key aws.StringValue) (err error) {
	request := &s3.DeleteObjectRequest{
		Bucket: &bucket,
		Key:    key,
	}

	_, err = client.DeleteObject(request)
	return
}

func listObjects(client *s3.S3, bucket, prefix string, log *Log) (channel chan *s3.Object) {
	request := &s3.ListObjectsRequest{
		Bucket: &bucket,
		Prefix: &prefix,
	}

	channel = make(chan *s3.Object)

	if client == nil {
		close(channel)
		return
	}

	output, err := client.ListObjects(request)
	if err != nil {
		log.Errorf("S3 ListObjects: %s", err)
		return
	}

	go func() {
		defer close(channel)

		for {
			for i := range output.Contents {
				object := &output.Contents[i]
				channel <- object
				request.Marker = object.Key
			}

			if !*output.IsTruncated {
				break
			}

			if output, err = client.ListObjects(request); err != nil {
				log.Errorf("S3 ListObjects: %s", err)
				break
			}
		}
	}()

	return
}
<|endoftext|>


<commit_before>/**
 * Provides a redis storage adapter for storing and retrieving actions.
 */

package msActionStorage

import (
	// Utilities
	"encoding/json"
	"errors"
	"fmt"
	"strconv"

	// Redis.
  "github.com/mediocregopher/radix.v2/redis"

	// Internal dependencies.
	common "github.com/krystalcode/go-mantis-shrimp/actions/common"
	chat   "github.com/krystalcode/go-mantis-shrimp/actions/chat"
)

/**
 * Redis storage provider.
 */

// Implements the Storage interface.
type Redis struct {
	dsn     string
	client *redis.Client
}

// Get an Action by its ID.
func (storage Redis) Get(_id int) common.Action {
	if storage.client == nil {
		panic("The Redis client has not been initialized yet.")
	}

	key := redisKey(_id)

	r := storage.client.Cmd("GET", key)
	if r.Err != nil {
		panic(r.Err)
	}

	jsonAction, err := r.Bytes()
	// If an error happens here, it should be because there is no value for this
	// key. It could be the case that the data is corrupted or the wrong data is
	// stored, we should see how to handle this later.
	// @I Handle edge cases when deserializing json in Redis
	if err != nil {
		return nil
	}

	// @I Dynamically detect the Action type and convert json to struct
	//    accordingly
	action := chat.Action{}
	json.Unmarshal(jsonAction, &action)

	return action
}

// Set an Action.
// @I Consider using hashmaps instead of json values
func (storage Redis) Set(action common.Action) int {
	if storage.client == nil {
		panic("The Redis client has not been initialized yet.")
	}

	jsonAction, err := json.Marshal(action)
	if err != nil {
		panic(err)
	}

	// Generate an ID, store the Action, and update the Actions index set.
	_id := storage.generateID()
	key := redisKey(_id)
	err = storage.client.Cmd("SET", key, jsonAction).Err
	if err != nil {
		panic(err)
	}
	err = storage.client.Cmd("ZADD", "actions", _id, key).Err
	if err != nil {
		panic(err)
	}

	return _id
}

func (storage Redis) generateID() int {
	// Get the last ID that exists on the Actions index set, so that we can generate
	// the next one.
	r, err := storage.client.Cmd("ZREVRANGE", "actions", 0, 0, "WITHSCORES").List()
	if err != nil {
		panic(err)
	}

	// If there are no actions yet, start with ID 1.
	if len(r) == 0 {
		return 1
	}

	_id, err := strconv.Atoi(r[1])
	if err != nil {
		panic(err)
	}

	return _id + 1
}

// Implements the StorageFactory interface.
// Connects to the Redis database defined in the given configuration and returns
// the storage.
func NewRedisStorage(config map[string]string) (Storage, error) {
	dsn, ok := config["STORAGE_REDIS_DSN"]
	if !ok {
		err := errors.New(
			fmt.Sprintf(
				"The \"%s\" configuration option is required for the Redis storage",
				"STORAGE_REDIS_DSN",
			),
		)
		return nil, err
	}

	client, err := redis.Dial("tcp", dsn)
	if err != nil {
		err := errors.New(fmt.Sprintf("Failed to connect to Redis: %s", err.Error()))
		return nil, err
	}

	storage := Redis {
		dsn    : dsn,
		client : client,
	}

	return storage, nil
}

/**
 * For internal use.
 */

// Generate a Redis key for the given Action ID.
func redisKey(_id int) string {
	return "action:" + string(_id)
}
<commit_msg>ms_action_storage Fixed redis key not being properly constructed<commit_after>/**
 * Provides a redis storage adapter for storing and retrieving actions.
 */

package msActionStorage

import (
	// Utilities
	"encoding/json"
	"errors"
	"fmt"
	"strconv"

	// Redis.
  "github.com/mediocregopher/radix.v2/redis"

	// Internal dependencies.
	common "github.com/krystalcode/go-mantis-shrimp/actions/common"
	chat   "github.com/krystalcode/go-mantis-shrimp/actions/chat"
)

/**
 * Redis storage provider.
 */

// Implements the Storage interface.
type Redis struct {
	dsn     string
	client *redis.Client
}

// Get an Action by its ID.
func (storage Redis) Get(_id int) common.Action {
	if storage.client == nil {
		panic("The Redis client has not been initialized yet.")
	}

	key := redisKey(_id)

	r := storage.client.Cmd("GET", key)
	if r.Err != nil {
		panic(r.Err)
	}

	jsonAction, err := r.Bytes()
	// If an error happens here, it should be because there is no value for this
	// key. It could be the case that the data is corrupted or the wrong data is
	// stored, we should see how to handle this later.
	// @I Handle edge cases when deserializing json in Redis
	if err != nil {
		return nil
	}

	// @I Dynamically detect the Action type and convert json to struct
	//    accordingly
	action := chat.Action{}
	json.Unmarshal(jsonAction, &action)

	return action
}

// Set an Action.
// @I Consider using hashmaps instead of json values
func (storage Redis) Set(action common.Action) int {
	if storage.client == nil {
		panic("The Redis client has not been initialized yet.")
	}

	jsonAction, err := json.Marshal(action)
	if err != nil {
		panic(err)
	}

	// Generate an ID, store the Action, and update the Actions index set.
	_id := storage.generateID()
	key := redisKey(_id)
	err = storage.client.Cmd("SET", key, jsonAction).Err
	if err != nil {
		panic(err)
	}
	err = storage.client.Cmd("ZADD", "actions", _id, key).Err
	if err != nil {
		panic(err)
	}

	return _id
}

func (storage Redis) generateID() int {
	// Get the last ID that exists on the Actions index set, so that we can generate
	// the next one.
	r, err := storage.client.Cmd("ZREVRANGE", "actions", 0, 0, "WITHSCORES").List()
	if err != nil {
		panic(err)
	}

	// If there are no actions yet, start with ID 1.
	if len(r) == 0 {
		return 1
	}

	_id, err := strconv.Atoi(r[1])
	if err != nil {
		panic(err)
	}

	return _id + 1
}

// Implements the StorageFactory interface.
// Connects to the Redis database defined in the given configuration and returns
// the storage.
func NewRedisStorage(config map[string]string) (Storage, error) {
	dsn, ok := config["STORAGE_REDIS_DSN"]
	if !ok {
		err := errors.New(
			fmt.Sprintf(
				"The \"%s\" configuration option is required for the Redis storage",
				"STORAGE_REDIS_DSN",
			),
		)
		return nil, err
	}

	client, err := redis.Dial("tcp", dsn)
	if err != nil {
		err := errors.New(fmt.Sprintf("Failed to connect to Redis: %s", err.Error()))
		return nil, err
	}

	storage := Redis {
		dsn    : dsn,
		client : client,
	}

	return storage, nil
}

/**
 * For internal use.
 */

// Generate a Redis key for the given Action ID.
func redisKey(_id int) string {
	return "action:" + strconv.Itoa(_id)
}
<|endoftext|>


<commit_before>// Copyright 2015 Square Inc.
//
// 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 standard

import (
	standard_logger "log"

	"github.com/square/metrics/log"
)

type Logger struct {
	Logger *standard_logger.Logger
}

func (sl *Logger) logf(level string, format string, args ...interface{}) {
	sl.Logger.Printf(level+" "+format, args)
}

func (sl *Logger) Debugf(format string, args ...interface{}) {
	sl.logf("DEBUG", format, args)
}

func (sl *Logger) Infof(format string, args ...interface{}) {
	sl.logf("INFO", format, args)
}

func (sl *Logger) Warningf(format string, args ...interface{}) {
	sl.logf("WARNING", format, args)
}

func (sl *Logger) Errorf(format string, args ...interface{}) {
	sl.logf("ERROR", format, args)
}

func (sl *Logger) Fatalf(format string, args ...interface{}) {
	sl.Logger.Fatalf(format, args)
}

var _ log.Logger = (*Logger)(nil)
<commit_msg>Properly format log messages for the standard logger<commit_after>// Copyright 2015 Square Inc.
//
// 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 standard

import (
	standard_logger "log"

	"github.com/square/metrics/log"
)

type Logger struct {
	Logger *standard_logger.Logger
}

func (sl *Logger) logf(format string, level string, args ...interface{}) {
	sl.Logger.Printf(level+" "+format, args...)
}

func (sl *Logger) Debugf(format string, args ...interface{}) {
	sl.logf(format, "DEBUG", args...)
}

func (sl *Logger) Infof(format string, args ...interface{}) {
	sl.logf(format, "INFO", args...)
}

func (sl *Logger) Warningf(format string, args ...interface{}) {
	sl.logf(format, "WARNING", args...)
}

func (sl *Logger) Errorf(format string, args ...interface{}) {
	sl.logf(format, "ERROR", args...)
}

func (sl *Logger) Fatalf(format string, args ...interface{}) {
	sl.Logger.Fatalf(format, args...)
}

var _ log.Logger = (*Logger)(nil)
<|endoftext|>


<commit_before>package types

import "github.com/graph-gophers/graphql-go/errors"

// FieldDefinition is a representation of a GraphQL FieldDefinition.
//
// http://spec.graphql.org/draft/#FieldDefinition
type FieldDefinition struct {
	Alias           Ident
	Name            Ident
	Arguments       ArgumentsDefinition
	Type            Type
	Directives      DirectiveList
	Desc            string
	Selections      SelectionSet
	SelectionSetLoc errors.Location
}

// FieldsDefinition is a list of an ObjectTypeDefinition's Fields.
//
// https://spec.graphql.org/draft/#FieldsDefinition
type FieldsDefinition []*FieldDefinition

// Get returns a FieldDefinition in a FieldsDefinition by name or nil if not found.
func (l FieldsDefinition) Get(name string) *FieldDefinition {
	for _, f := range l {
		if f.Name.Name == name {
			return f
		}
	}
	return nil
}

// Names returns a slice of FieldDefinition names.
func (l FieldsDefinition) Names() []string {
	names := make([]string, len(l))
	for i, f := range l {
		names[i] = f.Name.Name
	}
	return names
}
<commit_msg>unused fields<commit_after>package types

// FieldDefinition is a representation of a GraphQL FieldDefinition.
//
// http://spec.graphql.org/draft/#FieldDefinition
type FieldDefinition struct {
	Alias      Ident
	Name       Ident
	Arguments  ArgumentsDefinition
	Type       Type
	Directives DirectiveList
	Desc       string
}

// FieldsDefinition is a list of an ObjectTypeDefinition's Fields.
//
// https://spec.graphql.org/draft/#FieldsDefinition
type FieldsDefinition []*FieldDefinition

// Get returns a FieldDefinition in a FieldsDefinition by name or nil if not found.
func (l FieldsDefinition) Get(name string) *FieldDefinition {
	for _, f := range l {
		if f.Name.Name == name {
			return f
		}
	}
	return nil
}

// Names returns a slice of FieldDefinition names.
func (l FieldsDefinition) Names() []string {
	names := make([]string, len(l))
	for i, f := range l {
		names[i] = f.Name.Name
	}
	return names
}
<|endoftext|>


<commit_before>// Package types is used for API stability in the types and response to the
// consumers of the API stats endpoint.
package types

import "time"

// ThrottlingData stores CPU throttling stats of one running container
type ThrottlingData struct {
	// Number of periods with throttling active
	Periods uint64 `json:"periods"`
	// Number of periods when the container hit its throttling limit.
	ThrottledPeriods uint64 `json:"throttled_periods"`
	// Aggregate time the container was throttled for in nanoseconds.
	ThrottledTime uint64 `json:"throttled_time"`
}

// CPUUsage stores All CPU stats aggregated since container inception.
type CPUUsage struct {
	// Total CPU time consumed.
	// Units: nanoseconds.
	TotalUsage uint64 `json:"total_usage"`
	// Total CPU time consumed per core.
	// Units: nanoseconds.
	PercpuUsage []uint64 `json:"percpu_usage"`
	// Time spent by tasks of the cgroup in kernel mode.
	// Units: nanoseconds.
	UsageInKernelmode uint64 `json:"usage_in_kernelmode"`
	// Time spent by tasks of the cgroup in user mode.
	// Units: nanoseconds.
	UsageInUsermode uint64 `json:"usage_in_usermode"`
}

// CPUStats aggregates and wraps all CPU related info of container
type CPUStats struct {
	CPUUsage       CPUUsage       `json:"cpu_usage"`
	SystemUsage    uint64         `json:"system_cpu_usage"`
	ThrottlingData ThrottlingData `json:"throttling_data,omitempty"`
}

// MemoryStats aggregates All memory stats since container inception
type MemoryStats struct {
	// current res_counter usage for memory
	Usage uint64 `json:"usage"`
	// maximum usage ever recorded.
	MaxUsage uint64 `json:"max_usage"`
	// TODO(vishh): Export these as stronger types.
	// all the stats exported via memory.stat.
	Stats map[string]uint64 `json:"stats"`
	// number of times memory usage hits limits.
	Failcnt uint64 `json:"failcnt"`
	Limit   uint64 `json:"limit"`
}

// BlkioStatEntry is one small entity to store a piece of Blkio stats
// TODO Windows: This can be factored out
type BlkioStatEntry struct {
	Major uint64 `json:"major"`
	Minor uint64 `json:"minor"`
	Op    string `json:"op"`
	Value uint64 `json:"value"`
}

// BlkioStats stores All IO service stats for data read and write
// TODO Windows: This can be factored out
type BlkioStats struct {
	// number of bytes transferred to and from the block device
	IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive"`
	IoServicedRecursive     []BlkioStatEntry `json:"io_serviced_recursive"`
	IoQueuedRecursive       []BlkioStatEntry `json:"io_queue_recursive"`
	IoServiceTimeRecursive  []BlkioStatEntry `json:"io_service_time_recursive"`
	IoWaitTimeRecursive     []BlkioStatEntry `json:"io_wait_time_recursive"`
	IoMergedRecursive       []BlkioStatEntry `json:"io_merged_recursive"`
	IoTimeRecursive         []BlkioStatEntry `json:"io_time_recursive"`
	SectorsRecursive        []BlkioStatEntry `json:"sectors_recursive"`
}

// NetworkStats aggregates All network stats of one container
// TODO Windows: This will require refactoring
type NetworkStats struct {
	RxBytes   uint64 `json:"rx_bytes"`
	RxPackets uint64 `json:"rx_packets"`
	RxErrors  uint64 `json:"rx_errors"`
	RxDropped uint64 `json:"rx_dropped"`
	TxBytes   uint64 `json:"tx_bytes"`
	TxPackets uint64 `json:"tx_packets"`
	TxErrors  uint64 `json:"tx_errors"`
	TxDropped uint64 `json:"tx_dropped"`
}

// PidsStats contains the stats of a container's pids
type PidsStats struct {
	// Current is the number of pids in the cgroup
	Current uint64 `json:"current,omitempty"`
}

// Stats is Ultimate struct aggregating all types of stats of one container
type Stats struct {
	Read        time.Time   `json:"read"`
	PreCPUStats CPUStats    `json:"precpu_stats,omitempty"`
	CPUStats    CPUStats    `json:"cpu_stats,omitempty"`
	MemoryStats MemoryStats `json:"memory_stats,omitempty"`
	BlkioStats  BlkioStats  `json:"blkio_stats,omitempty"`
	PidsStats   PidsStats   `json:"pids_stats,omitempty"`
}

// StatsJSON is newly used Networks
type StatsJSON struct {
	Stats

	// Networks request version >=1.21
	Networks map[string]NetworkStats `json:"networks,omitempty"`
}
<commit_msg>types: stats: add pids.max to PidsStats<commit_after>// Package types is used for API stability in the types and response to the
// consumers of the API stats endpoint.
package types

import "time"

// ThrottlingData stores CPU throttling stats of one running container
type ThrottlingData struct {
	// Number of periods with throttling active
	Periods uint64 `json:"periods"`
	// Number of periods when the container hit its throttling limit.
	ThrottledPeriods uint64 `json:"throttled_periods"`
	// Aggregate time the container was throttled for in nanoseconds.
	ThrottledTime uint64 `json:"throttled_time"`
}

// CPUUsage stores All CPU stats aggregated since container inception.
type CPUUsage struct {
	// Total CPU time consumed.
	// Units: nanoseconds.
	TotalUsage uint64 `json:"total_usage"`
	// Total CPU time consumed per core.
	// Units: nanoseconds.
	PercpuUsage []uint64 `json:"percpu_usage"`
	// Time spent by tasks of the cgroup in kernel mode.
	// Units: nanoseconds.
	UsageInKernelmode uint64 `json:"usage_in_kernelmode"`
	// Time spent by tasks of the cgroup in user mode.
	// Units: nanoseconds.
	UsageInUsermode uint64 `json:"usage_in_usermode"`
}

// CPUStats aggregates and wraps all CPU related info of container
type CPUStats struct {
	CPUUsage       CPUUsage       `json:"cpu_usage"`
	SystemUsage    uint64         `json:"system_cpu_usage"`
	ThrottlingData ThrottlingData `json:"throttling_data,omitempty"`
}

// MemoryStats aggregates All memory stats since container inception
type MemoryStats struct {
	// current res_counter usage for memory
	Usage uint64 `json:"usage"`
	// maximum usage ever recorded.
	MaxUsage uint64 `json:"max_usage"`
	// TODO(vishh): Export these as stronger types.
	// all the stats exported via memory.stat.
	Stats map[string]uint64 `json:"stats"`
	// number of times memory usage hits limits.
	Failcnt uint64 `json:"failcnt"`
	Limit   uint64 `json:"limit"`
}

// BlkioStatEntry is one small entity to store a piece of Blkio stats
// TODO Windows: This can be factored out
type BlkioStatEntry struct {
	Major uint64 `json:"major"`
	Minor uint64 `json:"minor"`
	Op    string `json:"op"`
	Value uint64 `json:"value"`
}

// BlkioStats stores All IO service stats for data read and write
// TODO Windows: This can be factored out
type BlkioStats struct {
	// number of bytes transferred to and from the block device
	IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive"`
	IoServicedRecursive     []BlkioStatEntry `json:"io_serviced_recursive"`
	IoQueuedRecursive       []BlkioStatEntry `json:"io_queue_recursive"`
	IoServiceTimeRecursive  []BlkioStatEntry `json:"io_service_time_recursive"`
	IoWaitTimeRecursive     []BlkioStatEntry `json:"io_wait_time_recursive"`
	IoMergedRecursive       []BlkioStatEntry `json:"io_merged_recursive"`
	IoTimeRecursive         []BlkioStatEntry `json:"io_time_recursive"`
	SectorsRecursive        []BlkioStatEntry `json:"sectors_recursive"`
}

// NetworkStats aggregates All network stats of one container
// TODO Windows: This will require refactoring
type NetworkStats struct {
	RxBytes   uint64 `json:"rx_bytes"`
	RxPackets uint64 `json:"rx_packets"`
	RxErrors  uint64 `json:"rx_errors"`
	RxDropped uint64 `json:"rx_dropped"`
	TxBytes   uint64 `json:"tx_bytes"`
	TxPackets uint64 `json:"tx_packets"`
	TxErrors  uint64 `json:"tx_errors"`
	TxDropped uint64 `json:"tx_dropped"`
}

// PidsStats contains the stats of a container's pids
type PidsStats struct {
	// Current is the number of pids in the cgroup
	Current uint64 `json:"current,omitempty"`
	// Limit is the hard limit on the number of pids in the cgroup.
	// A "Limit" of 0 means that there is no limit.
	Limit uint64 `json:"limit,omitempty"`
}

// Stats is Ultimate struct aggregating all types of stats of one container
type Stats struct {
	Read        time.Time   `json:"read"`
	PreCPUStats CPUStats    `json:"precpu_stats,omitempty"`
	CPUStats    CPUStats    `json:"cpu_stats,omitempty"`
	MemoryStats MemoryStats `json:"memory_stats,omitempty"`
	BlkioStats  BlkioStats  `json:"blkio_stats,omitempty"`
	PidsStats   PidsStats   `json:"pids_stats,omitempty"`
}

// StatsJSON is newly used Networks
type StatsJSON struct {
	Stats

	// Networks request version >=1.21
	Networks map[string]NetworkStats `json:"networks,omitempty"`
}
<|endoftext|>


<commit_before>package types

import (
	"os"
	"time"

	"github.com/docker/docker/daemon/network"
	"github.com/docker/docker/pkg/version"
	"github.com/docker/docker/runconfig"
)

// ContainerCreateResponse contains the information returned to a client on the
// creation of a new container.
type ContainerCreateResponse struct {
	// ID is the ID of the created container.
	ID string `json:"Id"`

	// Warnings are any warnings encountered during the creation of the container.
	Warnings []string `json:"Warnings"`
}

// POST /containers/{name:.*}/exec
type ContainerExecCreateResponse struct {
	// ID is the exec ID.
	ID string `json:"Id"`
}

// POST /auth
type AuthResponse struct {
	// Status is the authentication status
	Status string `json:"Status"`
}

// POST "/containers/"+containerID+"/wait"
type ContainerWaitResponse struct {
	// StatusCode is the status code of the wait job
	StatusCode int `json:"StatusCode"`
}

// POST "/commit?container="+containerID
type ContainerCommitResponse struct {
	ID string `json:"Id"`
}

// GET "/containers/{name:.*}/changes"
type ContainerChange struct {
	Kind int
	Path string
}

// GET "/images/{name:.*}/history"
type ImageHistory struct {
	ID        string `json:"Id"`
	Created   int64
	CreatedBy string
	Tags      []string
	Size      int64
	Comment   string
}

// DELETE "/images/{name:.*}"
type ImageDelete struct {
	Untagged string `json:",omitempty"`
	Deleted  string `json:",omitempty"`
}

// GET "/images/json"
type Image struct {
	ID          string `json:"Id"`
	ParentId    string
	RepoTags    []string
	RepoDigests []string
	Created     int
	Size        int
	VirtualSize int
	Labels      map[string]string
}

type GraphDriverData struct {
	Name string
	Data map[string]string
}

// GET "/images/{name:.*}/json"
type ImageInspect struct {
	Id              string
	Parent          string
	Comment         string
	Created         string
	Container       string
	ContainerConfig *runconfig.Config
	DockerVersion   string
	Author          string
	Config          *runconfig.Config
	Architecture    string
	Os              string
	Size            int64
	VirtualSize     int64
	GraphDriver     GraphDriverData
}

// GET  "/containers/json"
type Port struct {
	IP          string `json:",omitempty"`
	PrivatePort int
	PublicPort  int `json:",omitempty"`
	Type        string
}

type Container struct {
	ID         string `json:"Id"`
	Names      []string
	Image      string
	Command    string
	Created    int
	Ports      []Port
	SizeRw     int `json:",omitempty"`
	SizeRootFs int `json:",omitempty"`
	Labels     map[string]string
	Status     string
	HostConfig struct {
		NetworkMode string `json:",omitempty"`
	}
}

// POST "/containers/"+containerID+"/copy"
type CopyConfig struct {
	Resource string
}

// ContainerPathStat is used to encode the header from
// 	GET /containers/{name:.*}/archive
// "name" is the file or directory name.
// "path" is the absolute path to the resource in the container.
type ContainerPathStat struct {
	Name  string      `json:"name"`
	Path  string      `json:"path"`
	Size  int64       `json:"size"`
	Mode  os.FileMode `json:"mode"`
	Mtime time.Time   `json:"mtime"`
}

// GET "/containers/{name:.*}/top"
type ContainerProcessList struct {
	Processes [][]string
	Titles    []string
}

type Version struct {
	Version       string
	ApiVersion    version.Version
	GitCommit     string
	GoVersion     string
	Os            string
	Arch          string
	KernelVersion string `json:",omitempty"`
	Experimental  bool   `json:",omitempty"`
	BuildTime     string `json:",omitempty"`
}

// GET "/info"
type Info struct {
	ID                 string
	Containers         int
	Images             int
	Driver             string
	DriverStatus       [][2]string
	MemoryLimit        bool
	SwapLimit          bool
	CpuCfsPeriod       bool
	CpuCfsQuota        bool
	IPv4Forwarding     bool
	BridgeNfIptables   bool
	BridgeNfIp6tables  bool
	Debug              bool
	NFd                int
	OomKillDisable     bool
	NGoroutines        int
	SystemTime         string
	ExecutionDriver    string
	LoggingDriver      string
	NEventsListener    int
	KernelVersion      string
	OperatingSystem    string
	IndexServerAddress string
	RegistryConfig     interface{}
	InitSha1           string
	InitPath           string
	NCPU               int
	MemTotal           int64
	DockerRootDir      string
	HttpProxy          string
	HttpsProxy         string
	NoProxy            string
	Name               string
	Labels             []string
	ExperimentalBuild  bool
}

// This struct is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
type ExecStartCheck struct {
	// ExecStart will first check if it's detached
	Detach bool
	// Check if there's a tty
	Tty bool
}

type ContainerState struct {
	Running    bool
	Paused     bool
	Restarting bool
	OOMKilled  bool
	Dead       bool
	Pid        int
	ExitCode   int
	Error      string
	StartedAt  string
	FinishedAt string
}

// GET "/containers/{name:.*}/json"
type ContainerJSONBase struct {
	Id              string
	Created         string
	Path            string
	Args            []string
	State           *ContainerState
	Image           string
	NetworkSettings *network.Settings
	ResolvConfPath  string
	HostnamePath    string
	HostsPath       string
	LogPath         string
	Name            string
	RestartCount    int
	Driver          string
	ExecDriver      string
	MountLabel      string
	ProcessLabel    string
	AppArmorProfile string
	ExecIDs         []string
	HostConfig      *runconfig.HostConfig
	GraphDriver     GraphDriverData
}

type ContainerJSON struct {
	*ContainerJSONBase
	Mounts []MountPoint
	Config *runconfig.Config
}

// backcompatibility struct along with ContainerConfig. Note this is not
// used by the Windows daemon.
type ContainerJSONPre120 struct {
	*ContainerJSONBase
	Volumes   map[string]string
	VolumesRW map[string]bool
	Config    *ContainerConfig
}

type ContainerConfig struct {
	*runconfig.Config

	// backward compatibility, they now live in HostConfig
	Memory     int64
	MemorySwap int64
	CpuShares  int64
	Cpuset     string
}

// MountPoint represents a mount point configuration inside the container.
type MountPoint struct {
	Name        string `json:",omitempty"`
	Source      string
	Destination string
	Driver      string `json:",omitempty"`
	Mode        string
	RW          bool
}
<commit_msg>Fix `docker cp` Behavior With Symlinks<commit_after>package types

import (
	"os"
	"time"

	"github.com/docker/docker/daemon/network"
	"github.com/docker/docker/pkg/version"
	"github.com/docker/docker/runconfig"
)

// ContainerCreateResponse contains the information returned to a client on the
// creation of a new container.
type ContainerCreateResponse struct {
	// ID is the ID of the created container.
	ID string `json:"Id"`

	// Warnings are any warnings encountered during the creation of the container.
	Warnings []string `json:"Warnings"`
}

// POST /containers/{name:.*}/exec
type ContainerExecCreateResponse struct {
	// ID is the exec ID.
	ID string `json:"Id"`
}

// POST /auth
type AuthResponse struct {
	// Status is the authentication status
	Status string `json:"Status"`
}

// POST "/containers/"+containerID+"/wait"
type ContainerWaitResponse struct {
	// StatusCode is the status code of the wait job
	StatusCode int `json:"StatusCode"`
}

// POST "/commit?container="+containerID
type ContainerCommitResponse struct {
	ID string `json:"Id"`
}

// GET "/containers/{name:.*}/changes"
type ContainerChange struct {
	Kind int
	Path string
}

// GET "/images/{name:.*}/history"
type ImageHistory struct {
	ID        string `json:"Id"`
	Created   int64
	CreatedBy string
	Tags      []string
	Size      int64
	Comment   string
}

// DELETE "/images/{name:.*}"
type ImageDelete struct {
	Untagged string `json:",omitempty"`
	Deleted  string `json:",omitempty"`
}

// GET "/images/json"
type Image struct {
	ID          string `json:"Id"`
	ParentId    string
	RepoTags    []string
	RepoDigests []string
	Created     int
	Size        int
	VirtualSize int
	Labels      map[string]string
}

type GraphDriverData struct {
	Name string
	Data map[string]string
}

// GET "/images/{name:.*}/json"
type ImageInspect struct {
	Id              string
	Parent          string
	Comment         string
	Created         string
	Container       string
	ContainerConfig *runconfig.Config
	DockerVersion   string
	Author          string
	Config          *runconfig.Config
	Architecture    string
	Os              string
	Size            int64
	VirtualSize     int64
	GraphDriver     GraphDriverData
}

// GET  "/containers/json"
type Port struct {
	IP          string `json:",omitempty"`
	PrivatePort int
	PublicPort  int `json:",omitempty"`
	Type        string
}

type Container struct {
	ID         string `json:"Id"`
	Names      []string
	Image      string
	Command    string
	Created    int
	Ports      []Port
	SizeRw     int `json:",omitempty"`
	SizeRootFs int `json:",omitempty"`
	Labels     map[string]string
	Status     string
	HostConfig struct {
		NetworkMode string `json:",omitempty"`
	}
}

// POST "/containers/"+containerID+"/copy"
type CopyConfig struct {
	Resource string
}

// ContainerPathStat is used to encode the header from
// 	GET /containers/{name:.*}/archive
// "name" is basename of the resource.
type ContainerPathStat struct {
	Name       string      `json:"name"`
	Size       int64       `json:"size"`
	Mode       os.FileMode `json:"mode"`
	Mtime      time.Time   `json:"mtime"`
	LinkTarget string      `json:"linkTarget"`
}

// GET "/containers/{name:.*}/top"
type ContainerProcessList struct {
	Processes [][]string
	Titles    []string
}

type Version struct {
	Version       string
	ApiVersion    version.Version
	GitCommit     string
	GoVersion     string
	Os            string
	Arch          string
	KernelVersion string `json:",omitempty"`
	Experimental  bool   `json:",omitempty"`
	BuildTime     string `json:",omitempty"`
}

// GET "/info"
type Info struct {
	ID                 string
	Containers         int
	Images             int
	Driver             string
	DriverStatus       [][2]string
	MemoryLimit        bool
	SwapLimit          bool
	CpuCfsPeriod       bool
	CpuCfsQuota        bool
	IPv4Forwarding     bool
	BridgeNfIptables   bool
	BridgeNfIp6tables  bool
	Debug              bool
	NFd                int
	OomKillDisable     bool
	NGoroutines        int
	SystemTime         string
	ExecutionDriver    string
	LoggingDriver      string
	NEventsListener    int
	KernelVersion      string
	OperatingSystem    string
	IndexServerAddress string
	RegistryConfig     interface{}
	InitSha1           string
	InitPath           string
	NCPU               int
	MemTotal           int64
	DockerRootDir      string
	HttpProxy          string
	HttpsProxy         string
	NoProxy            string
	Name               string
	Labels             []string
	ExperimentalBuild  bool
}

// This struct is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
type ExecStartCheck struct {
	// ExecStart will first check if it's detached
	Detach bool
	// Check if there's a tty
	Tty bool
}

type ContainerState struct {
	Running    bool
	Paused     bool
	Restarting bool
	OOMKilled  bool
	Dead       bool
	Pid        int
	ExitCode   int
	Error      string
	StartedAt  string
	FinishedAt string
}

// GET "/containers/{name:.*}/json"
type ContainerJSONBase struct {
	Id              string
	Created         string
	Path            string
	Args            []string
	State           *ContainerState
	Image           string
	NetworkSettings *network.Settings
	ResolvConfPath  string
	HostnamePath    string
	HostsPath       string
	LogPath         string
	Name            string
	RestartCount    int
	Driver          string
	ExecDriver      string
	MountLabel      string
	ProcessLabel    string
	AppArmorProfile string
	ExecIDs         []string
	HostConfig      *runconfig.HostConfig
	GraphDriver     GraphDriverData
}

type ContainerJSON struct {
	*ContainerJSONBase
	Mounts []MountPoint
	Config *runconfig.Config
}

// backcompatibility struct along with ContainerConfig. Note this is not
// used by the Windows daemon.
type ContainerJSONPre120 struct {
	*ContainerJSONBase
	Volumes   map[string]string
	VolumesRW map[string]bool
	Config    *ContainerConfig
}

type ContainerConfig struct {
	*runconfig.Config

	// backward compatibility, they now live in HostConfig
	Memory     int64
	MemorySwap int64
	CpuShares  int64
	Cpuset     string
}

// MountPoint represents a mount point configuration inside the container.
type MountPoint struct {
	Name        string `json:",omitempty"`
	Source      string
	Destination string
	Driver      string `json:",omitempty"`
	Mode        string
	RW          bool
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"
)

type UDP_manager struct {
	ipAddress string
	pl        net.PacketConn
	open      bool
	conn      *IP_Conn
	buff      map[uint16](chan byte)
}

type UDP struct {
	manager   *UDP_manager
	conn      *IP_Conn
	bytes     chan byte
	src, dest uint16
}

func NewUDP_Manager(ip string) (*UDP_manager, error) {
	p, err := net.ListenPacket("ip4:17", ip)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	r, err := NewIP_Conn(ip)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	x := &UDP_manager{open: true, conn: r, pl: p, buff: make(map[uint16](chan byte)), ipAddress: ip}

	//go x.readAll()

	return x, nil
}

func (x *UDP_manager) readAll() {
	b := make([]byte, 1024)

	for {
		payload, err := x.conn.ReadFrom(b)
		if err != nil {
			continue
		}

		dest := (((uint16)(payload[2])) << 8) + ((uint16)(payload[3]))
		//		fmt.Println(dest)
		//		fmt.Println(payload)
		//
		//		fmt.Println(x.buff)
		c, ok := x.buff[dest]
		//fmt.Println(ok)
		payload = payload[8:]
		if ok {
			go func() {
				for _, elem := range payload {
					//fmt.Println("Writing")
					c <- elem
				}
			}()
		}
	}
}

func (x *UDP_manager) NewUDP(src, dest uint16) (*UDP, error) {
	x.buff[src] = make(chan byte, 1024)
	return &UDP{src: src, dest: dest, conn: x.conn, bytes: x.buff[src], manager: x}, nil
}

func (c *UDP) read(size int) ([]byte, error) {
	data := make([]byte, size)
	for i := 0; i < size; i++ {
		//fmt.Println("test")
		data[i] = <-c.bytes
		//fmt.Println(data[i])
	}
	return data, nil
}
func (c *UDP) write(x []byte) error {
	UDPHeader := []byte{
		(byte)(c.src >> 8), (byte)(c.src), // Source port in byte slice
		(byte)(c.dest >> 8), (byte)(c.dest), // Dest port in byte slice
		(byte)((8 + len(x)) >> 8), (byte)(8 + len(x)), // Length in bytes of UDP header + data
		0, 0, // Checksum
	}

	x = append(UDPHeader, x...)

	err := c.conn.WriteTo(x)
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}
func (c *UDP) close() error {
	return c.conn.Close()
}
<commit_msg>Enables reading<commit_after>package main

import (
	"fmt"
	"net"
)

type UDP_manager struct {
	ipAddress string
	pl        net.PacketConn
	open      bool
	conn      *IP_Conn
	buff      map[uint16](chan byte)
}

type UDP struct {
	manager   *UDP_manager
	conn      *IP_Conn
	bytes     chan byte
	src, dest uint16
}

func NewUDP_Manager(ip string) (*UDP_manager, error) {
	p, err := net.ListenPacket("ip4:17", ip)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	r, err := NewIP_Conn(ip)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	x := &UDP_manager{open: true, conn: r, pl: p, buff: make(map[uint16](chan byte)), ipAddress: ip}

	go x.readAll()

	return x, nil
}

func (x *UDP_manager) readAll() {
	b := make([]byte, 1024)

	for {
		payload, err := x.conn.ReadFrom(b)
		if err != nil {
			continue
		}

		dest := (((uint16)(payload[2])) << 8) + ((uint16)(payload[3]))
		//		fmt.Println(dest)
		//		fmt.Println(payload)
		//
		//		fmt.Println(x.buff)
		c, ok := x.buff[dest]
		//fmt.Println(ok)
		payload = payload[8:]
		if ok {
			go func() {
				for _, elem := range payload {
					//fmt.Println("Writing")
					c <- elem
				}
			}()
		}
	}
}

func (x *UDP_manager) NewUDP(src, dest uint16) (*UDP, error) {
	x.buff[src] = make(chan byte, 1024)
	return &UDP{src: src, dest: dest, conn: x.conn, bytes: x.buff[src], manager: x}, nil
}

func (c *UDP) read(size int) ([]byte, error) {
	data := make([]byte, size)
	for i := 0; i < size; i++ {
		//fmt.Println("test")
		data[i] = <-c.bytes
		//fmt.Println(data[i])
	}
	return data, nil
}
func (c *UDP) write(x []byte) error {
	UDPHeader := []byte{
		(byte)(c.src >> 8), (byte)(c.src), // Source port in byte slice
		(byte)(c.dest >> 8), (byte)(c.dest), // Dest port in byte slice
		(byte)((8 + len(x)) >> 8), (byte)(8 + len(x)), // Length in bytes of UDP header + data
		0, 0, // Checksum
	}

	x = append(UDPHeader, x...)

	err := c.conn.WriteTo(x)
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}
func (c *UDP) close() error {
	return c.conn.Close()
}
<|endoftext|>


<commit_before>package hector

import(
    "strconv"
    "math/rand"
    "math"
    "fmt"
)

type NeuralNetworkParams struct {
    LearningRate float64
    Regularization float64
    Hidden int64
    Steps int
}

type TwoLayerWeights struct {
    L1 *Matrix
    L2 *Matrix
}

/*
Please refer to this chapter to know algorithm details :
http://www4.rgu.ac.uk/files/chapter3%20-%20bp.pdf
*/
type NeuralNetwork struct {
    Model TwoLayerWeights
    MaxLabel int
    Params NeuralNetworkParams
}

func RandomInitVector(dim int64) *Vector{
    v := NewVector()
    var i int64
    for i = 0; i < dim; i++ {
        v.data[i] = (rand.Float64() - 0.5) / math.Sqrt(float64(dim))
    }
    return v
}

func (self *NeuralNetwork) SaveModel(path string){

}

func (self *NeuralNetwork) LoadModel(path string){

}

func (algo *NeuralNetwork) Init(params map[string]string) {
    algo.Params.LearningRate, _ = strconv.ParseFloat(params["learning-rate"], 64)
    algo.Params.Regularization, _ = strconv.ParseFloat(params["regularization"], 64)
    steps, _ := strconv.ParseInt(params["steps"], 10, 32)
    hidden, _ := strconv.ParseInt(params["hidden"], 10, 64)

    algo.Params.Steps = int(steps)
    algo.Params.Hidden = int64(hidden)
}

func (algo *NeuralNetwork) Train(dataset * DataSet) {
    algo.Model = TwoLayerWeights{}

    algo.Model.L1 = NewMatrix()
    for i := int64(0); i < algo.Params.Hidden; i++ {
        algo.Model.L1.data[i] = NewVector()
    }

    initalized := make(map[int64]int)
    max_label := 0
    for _, sample := range dataset.Samples {
        if max_label < sample.Label{
            max_label = sample.Label
        }
        for _, f := range sample.Features{
            _, ok := initalized[f.Id]
            if !ok{
                for i := int64(0); i < algo.Params.Hidden; i++ {
                    algo.Model.L1.SetValue(i, f.Id, (rand.Float64() - 0.5) / math.Sqrt(float64(algo.Params.Hidden)))
                }
                initalized[f.Id] = 1
            }
        }
    }
    algo.MaxLabel = max_label

    algo.Model.L2 = NewMatrix()
    for i := int64(0); i < algo.Params.Hidden; i++ {
        for j := int64(0); j <= int64(max_label); j++ {
            algo.Model.L2.SetValue(i, j, (rand.NormFloat64() / math.Sqrt(float64(max_label) + 1.0)))
        }
    }

    for step := 0; step < algo.Params.Steps; step++{
        fmt.Printf(".")
        for _, sample := range dataset.Samples {
            y := NewVector()
            z := NewVector()
            for i := int64(0); i < algo.Params.Hidden; i++ {
                sum := float64(0)
                for _, f := range sample.Features {
                    sum += f.Value * algo.Model.L1.data[i].GetValue(f.Id)
                }
                y.data[i] = Sigmoid(sum)
                for j := int64(0); j <= int64(max_label); j++ {
                    z.AddValue(j, y.GetValue(i) * algo.Model.L2.GetValue(i, j))
                }
            }
            z = z.SoftMaxNorm()

            err := NewVector()
            err.AddValue(int64(sample.Label), 1.0)
            err.AddVector(z, -1.0)

            delta_hidden := NewVector()
            for i := int64(0); i < algo.Params.Hidden; i++ {
                out_i := y.GetValue(i)
                for j := int64(0); j <= int64(max_label); j++ {
                    wij := algo.Model.L2.GetValue(i, j)
                    delta_j := err.GetValue(j)

                    wij += algo.Params.LearningRate * (out_i * delta_j - algo.Params.Regularization * wij)
                    algo.Model.L2.SetValue(i, j, wij)
                    delta_hidden.AddValue(i, out_i * (1.0 - out_i) * delta_j * wij)
                }
            }

            for _, f := range sample.Features {
                for j := int64(0); j < algo.Params.Hidden; j++ {
                    wij := algo.Model.L1.GetValue(j, f.Id)
                    wij += algo.Params.LearningRate * (delta_hidden.GetValue(j) * f.Value - algo.Params.Regularization * wij)
                    algo.Model.L1.SetValue(j, f.Id, wij)
                }
            }
        }
    }
    fmt.Println()
}

func (algo *NeuralNetwork) PredictMultiClass(sample * Sample) * ArrayVector {
    y := NewVector()
    z := NewArrayVector()
    for i := int64(0); i < algo.Params.Hidden; i++ {
        sum := float64(0)
        for _, f := range sample.Features {
            sum += f.Value * algo.Model.L1.data[i].GetValue(f.Id)
        }
        y.data[i] = Sigmoid(sum)
        for j := 0; j <= algo.MaxLabel; j++ {
            z.AddValue(j, y.GetValue(i) * algo.Model.L2.GetValue(i, int64(j)))
        }
    }
    z = z.SoftMaxNorm()
    return z
}

func (algo *NeuralNetwork) Predict(sample *Sample) float64 {
    z := algo.PredictMultiClass(sample)
    return z.GetValue(1)
}

<commit_msg>BP algorithm tuning<commit_after>package hector

import(
    "strconv"
    "math/rand"
    "math"
    "fmt"
)

type NeuralNetworkParams struct {
    LearningRate float64
    Regularization float64
    Hidden int64
    Steps int
}

type TwoLayerWeights struct {
    L1 *Matrix
    L2 *Matrix
}

/*
Please refer to this chapter to know algorithm details :
http://www4.rgu.ac.uk/files/chapter3%20-%20bp.pdf
*/
type NeuralNetwork struct {
    Model TwoLayerWeights
    MaxLabel int
    Params NeuralNetworkParams
}

func RandomInitVector(dim int64) *Vector{
    v := NewVector()
    var i int64
    for i = 0; i < dim; i++ {
        v.data[i] = (rand.Float64() - 0.5) / math.Sqrt(float64(dim))
    }
    return v
}

func (self *NeuralNetwork) SaveModel(path string){

}

func (self *NeuralNetwork) LoadModel(path string){

}

func (algo *NeuralNetwork) Init(params map[string]string) {
    algo.Params.LearningRate, _ = strconv.ParseFloat(params["learning-rate"], 64)
    algo.Params.Regularization, _ = strconv.ParseFloat(params["regularization"], 64)
    steps, _ := strconv.ParseInt(params["steps"], 10, 32)
    hidden, _ := strconv.ParseInt(params["hidden"], 10, 64)

    algo.Params.Steps = int(steps)
    algo.Params.Hidden = int64(hidden)
}

func (algo *NeuralNetwork) Train(dataset * DataSet) {
    algo.Model = TwoLayerWeights{}

    algo.Model.L1 = NewMatrix()
    for i := int64(0); i < algo.Params.Hidden; i++ {
        algo.Model.L1.data[i] = NewVector()
    }

    initalized := make(map[int64]int)
    max_label := 0
    for _, sample := range dataset.Samples {
        if max_label < sample.Label{
            max_label = sample.Label
        }
        for _, f := range sample.Features{
            _, ok := initalized[f.Id]
            if !ok{
                for i := int64(0); i < algo.Params.Hidden; i++ {
                    algo.Model.L1.SetValue(i, f.Id, (rand.Float64() - 0.5) / math.Sqrt(float64(algo.Params.Hidden)))
                }
                initalized[f.Id] = 1
            }
        }
    }
    algo.MaxLabel = max_label

    algo.Model.L2 = NewMatrix()
    for i := int64(0); i < algo.Params.Hidden; i++ {
        for j := int64(0); j <= int64(max_label); j++ {
            algo.Model.L2.SetValue(i, j, (rand.NormFloat64() / math.Sqrt(float64(max_label) + 1.0)))
        }
    }

    for step := 0; step < algo.Params.Steps; step++{
        fmt.Printf(".")
        for _, sample := range dataset.Samples {
            y := NewVector()
            z := NewVector()
            for i := int64(0); i < algo.Params.Hidden; i++ {
                sum := float64(0)
                for _, f := range sample.Features {
                    sum += f.Value * algo.Model.L1.data[i].GetValue(f.Id)
                }
                y.data[i] = Sigmoid(sum)
                for j := int64(0); j <= int64(max_label); j++ {
                    z.AddValue(j, y.GetValue(i) * algo.Model.L2.GetValue(i, j))
                }
            }
            z = z.SoftMaxNorm()

            err := NewVector()
            err.AddValue(int64(sample.Label), 1.0)
            err.AddVector(z, -1.0)

            delta_hidden := NewVector()
            for i := int64(0); i < algo.Params.Hidden; i++ {
                for j := int64(0); j <= int64(max_label); j++ {
                    wij := algo.Model.L2.GetValue(i, j)
                    delta_j := err.GetValue(j)

                    sig_ij := delta_j * (1-z.GetValue(j)) * z.GetValue(j)
                    delta_hidden.AddValue(i, sig_ij * wij)
                    wij += algo.Params.LearningRate * (y.GetValue(i) * sig_ij - algo.Params.Regularization * wij)
                    algo.Model.L2.SetValue(i, j, wij)
                }
            }

            for _, f := range sample.Features {
                for j := int64(0); j < algo.Params.Hidden; j++ {
                    wij := algo.Model.L1.GetValue(j, f.Id)
                    wij += algo.Params.LearningRate * (delta_hidden.GetValue(j) * f.Value * y.GetValue(j) * (1-y.GetValue(j)) - algo.Params.Regularization * wij)
                    algo.Model.L1.SetValue(j, f.Id, wij)
                }
            }
        }
    }
    fmt.Println()
}

func (algo *NeuralNetwork) PredictMultiClass(sample * Sample) * ArrayVector {
    y := NewVector()
    z := NewArrayVector()
    for i := int64(0); i < algo.Params.Hidden; i++ {
        sum := float64(0)
        for _, f := range sample.Features {
            sum += f.Value * algo.Model.L1.data[i].GetValue(f.Id)
        }
        y.data[i] = Sigmoid(sum)
        for j := 0; j <= algo.MaxLabel; j++ {
            z.AddValue(j, y.GetValue(i) * algo.Model.L2.GetValue(i, int64(j)))
        }
    }
    z = z.SoftMaxNorm()
    return z
}

func (algo *NeuralNetwork) Predict(sample *Sample) float64 {
    z := algo.PredictMultiClass(sample)
    return z.GetValue(1)
}

<|endoftext|>


<commit_before>package neutron

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

const X_AUTH_TOKEN_HEADER = "X-Auth-Token"

type Client struct {
	URL   string
	token string
}

func NewClient(url, token string) (*Client, error) {
	if url == "" {
		return nil, fmt.Errorf("missing URL")
	}
	if token == "" {
		return nil, fmt.Errorf("missing token")
	}
	return &Client{URL: url, token: token}, nil
}

type request struct {
	URL          string
	Method       string
	Body         []byte
	OkStatusCode int
}

type response struct {
	Body       []byte
	StatusCode int
}

func (c *Client) doRequest(r request) (response, error) {
	client := &http.Client{}

	req, err := http.NewRequest(r.Method, r.URL, bytes.NewBuffer(r.Body))
	if err != nil {
		return response{}, err
	}

	req.Header.Add(X_AUTH_TOKEN_HEADER, c.token)
	req.Header.Set("Content-Type", "application/json")

	resp, err := client.Do(req)
	if err != nil {
		return response{}, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return response{}, err
	}

	details := fmt.Sprintf("resp: %s", body)

	if resp.StatusCode != r.OkStatusCode {
		return response{}, fmt.Errorf("Error: %s details: %s\n", resp.Status, details)
	}
	return response{Body: body, StatusCode: resp.StatusCode}, nil
}

func (c *Client) CreateNetwork(net Network) (Network, error) {
	jsonStr, err := json.Marshal(SingleNetwork{Network: net})
	if err != nil {
		return Network{}, fmt.Errorf("invalid network: ", err)
	}

	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/networks", c.URL),
		Method:       "POST",
		Body:         jsonStr,
		OkStatusCode: http.StatusCreated,
	})
	if err != nil {
		return Network{}, err
	}

	var r SingleNetwork
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return Network{}, err
	}

	return r.Network, nil
}

func (c *Client) DeleteNetwork(id string) error {
	if id == "" {
		return fmt.Errorf("empty 'id' parameter")
	}
	_, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/networks/%s", c.URL, id),
		Method:       "DELETE",
		OkStatusCode: http.StatusNoContent,
	})
	if err != nil {
		return err
	}
	return nil
}

func (c *Client) Networks() ([]Network, error) {
	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/networks", c.URL),
		Method:       "GET",
		OkStatusCode: http.StatusOK,
	})
	if err != nil {
		return nil, err
	}

	var r GetNetworks
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return nil, err
	}
	return r.Networks, nil
}

func (c *Client) NetworksByName(name string) ([]Network, error) {
	if name == "" {
		return nil, fmt.Errorf("empty 'name' parameter")
	}

	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/networks?name=%s", c.URL, name),
		Method:       "GET",
		OkStatusCode: http.StatusOK,
	})
	if err != nil {
		return nil, err
	}

	var r GetNetworks
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return nil, err
	}
	return r.Networks, nil
}

func (c *Client) Subnets() ([]Subnet, error) {
	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/subnets", c.URL),
		Method:       "GET",
		OkStatusCode: http.StatusOK,
	})
	if err != nil {
		return nil, err
	}

	var r GetSubnets
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return nil, err
	}
	return r.Subnets, nil
}

func (c *Client) SubnetsByName(name string) ([]Subnet, error) {
	if name == "" {
		return nil, fmt.Errorf("empty 'name' parameter")
	}

	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/subnets?name=%s", c.URL, name),
		Method:       "GET",
		OkStatusCode: http.StatusOK,
	})
	if err != nil {
		return nil, err
	}

	var r GetSubnets
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return nil, err
	}
	return r.Subnets, nil
}

func (c *Client) CreateSubnet(s Subnet) (Subnet, error) {
	jsonStr, err := json.Marshal(SingleSubnet{Subnet: s})
	if err != nil {
		return Subnet{}, fmt.Errorf("invalid subnet: ", err)
	}

	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/subnets", c.URL),
		Method:       "POST",
		Body:         jsonStr,
		OkStatusCode: http.StatusCreated,
	})

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

	var r SingleSubnet
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return Subnet{}, err
	}

	return r.Subnet, nil
}

func (c *Client) CreatePort(p Port) (Port, error) {
	jsonStr, err := json.Marshal(SinglePort{Port: p})
	if err != nil {
		return Port{}, fmt.Errorf("invalid port: ", err)
	}

	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/ports", c.URL),
		Method:       "POST",
		Body:         jsonStr,
		OkStatusCode: http.StatusCreated,
	})

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

	var r SinglePort
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return Port{}, err
	}

	return r.Port, nil
}

func (c *Client) DeletePort(id string) error {
	if id == "" {
		return fmt.Errorf("empty 'id' parameter")
	}
	_, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/ports/%s", c.URL, id),
		Method:       "DELETE",
		OkStatusCode: http.StatusNoContent,
	})
	if err != nil {
		return err
	}
	return nil
}
<commit_msg>add details to err resp<commit_after>package neutron

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

const X_AUTH_TOKEN_HEADER = "X-Auth-Token"

type request struct {
	URL          string
	Method       string
	Body         []byte
	OkStatusCode int
}

type response struct {
	Body       []byte
	StatusCode int
}

type Client struct {
	URL   string
	token string
}

func NewClient(url, token string) (*Client, error) {
	if url == "" {
		return nil, fmt.Errorf("missing URL")
	}
	if token == "" {
		return nil, fmt.Errorf("missing token")
	}
	return &Client{URL: url, token: token}, nil
}

func (c *Client) doRequest(r request) (response, error) {
	client := &http.Client{}

	req, err := http.NewRequest(r.Method, r.URL, bytes.NewBuffer(r.Body))
	if err != nil {
		return response{}, err
	}

	req.Header.Add(X_AUTH_TOKEN_HEADER, c.token)
	req.Header.Set("Content-Type", "application/json")

	resp, err := client.Do(req)
	if err != nil {
		return response{}, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return response{}, err
	}

	if resp.StatusCode != r.OkStatusCode {
		return response{}, fmt.Errorf("Error: %s details: %s\n", resp.Status, body)
	}
	return response{Body: body, StatusCode: resp.StatusCode}, nil
}

func (c *Client) CreateNetwork(net Network) (Network, error) {
	jsonStr, err := json.Marshal(SingleNetwork{Network: net})
	if err != nil {
		return Network{}, fmt.Errorf("invalid network: ", err)
	}

	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/networks", c.URL),
		Method:       "POST",
		Body:         jsonStr,
		OkStatusCode: http.StatusCreated,
	})
	if err != nil {
		return Network{}, err
	}

	var r SingleNetwork
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return Network{}, err
	}

	return r.Network, nil
}

func (c *Client) DeleteNetwork(id string) error {
	if id == "" {
		return fmt.Errorf("empty 'id' parameter")
	}
	_, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/networks/%s", c.URL, id),
		Method:       "DELETE",
		OkStatusCode: http.StatusNoContent,
	})
	if err != nil {
		return err
	}
	return nil
}

func (c *Client) Networks() ([]Network, error) {
	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/networks", c.URL),
		Method:       "GET",
		OkStatusCode: http.StatusOK,
	})
	if err != nil {
		return nil, err
	}

	var r GetNetworks
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return nil, err
	}
	return r.Networks, nil
}

func (c *Client) NetworksByName(name string) ([]Network, error) {
	if name == "" {
		return nil, fmt.Errorf("empty 'name' parameter")
	}

	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/networks?name=%s", c.URL, name),
		Method:       "GET",
		OkStatusCode: http.StatusOK,
	})
	if err != nil {
		return nil, err
	}

	var r GetNetworks
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return nil, err
	}
	return r.Networks, nil
}

func (c *Client) Subnets() ([]Subnet, error) {
	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/subnets", c.URL),
		Method:       "GET",
		OkStatusCode: http.StatusOK,
	})
	if err != nil {
		return nil, err
	}

	var r GetSubnets
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return nil, err
	}
	return r.Subnets, nil
}

func (c *Client) SubnetsByName(name string) ([]Subnet, error) {
	if name == "" {
		return nil, fmt.Errorf("empty 'name' parameter")
	}

	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/subnets?name=%s", c.URL, name),
		Method:       "GET",
		OkStatusCode: http.StatusOK,
	})
	if err != nil {
		return nil, err
	}

	var r GetSubnets
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return nil, err
	}
	return r.Subnets, nil
}

func (c *Client) CreateSubnet(s Subnet) (Subnet, error) {
	jsonStr, err := json.Marshal(SingleSubnet{Subnet: s})
	if err != nil {
		return Subnet{}, fmt.Errorf("invalid subnet: ", err)
	}

	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/subnets", c.URL),
		Method:       "POST",
		Body:         jsonStr,
		OkStatusCode: http.StatusCreated,
	})

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

	var r SingleSubnet
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return Subnet{}, err
	}

	return r.Subnet, nil
}

func (c *Client) CreatePort(p Port) (Port, error) {
	jsonStr, err := json.Marshal(SinglePort{Port: p})
	if err != nil {
		return Port{}, fmt.Errorf("invalid port: ", err)
	}

	resp, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/ports", c.URL),
		Method:       "POST",
		Body:         jsonStr,
		OkStatusCode: http.StatusCreated,
	})

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

	var r SinglePort
	err = json.Unmarshal(resp.Body, &r)
	if err != nil {
		return Port{}, err
	}

	return r.Port, nil
}

func (c *Client) DeletePort(id string) error {
	if id == "" {
		return fmt.Errorf("empty 'id' parameter")
	}
	_, err := c.doRequest(request{
		URL:          fmt.Sprintf("%s/v2.0/ports/%s", c.URL, id),
		Method:       "DELETE",
		OkStatusCode: http.StatusNoContent,
	})
	if err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>package util

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"math/big"
	"strconv"

	"golang.org/x/crypto/scrypt"
)

// GetRandomString 16桁のランダムな文字列を返す
func GetRandomString() string {
	const base = 36
	size := big.NewInt(base)
	n := make([]byte, 16)
	for i, _ := range n {
		c, _ := rand.Int(rand.Reader, size)
		n[i] = strconv.FormatInt(c.Int64(), base)[0]
	}
	return string(n)
}

// CreateTokenHash 渡された文字列とsaltからTokenハッシュを生成する
func CreateTokenHash(str string, salt string) string {
	converted, _ := scrypt.Key([]byte(str), []byte(salt), 16384, 8, 1, 32)
	return hex.EncodeToString(converted[:])
}

// GenHashFromString 文字列からハッシュを生成する
func GenHashFromString(str string) string {
	converted := sha256.Sum256([]byte(str))
	return hex.EncodeToString(converted[:])
}
<commit_msg>fix: lint対応<commit_after>package util

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"math/big"
	"strconv"

	"golang.org/x/crypto/scrypt"
)

// GetRandomString 16桁のランダムな文字列を返す
func GetRandomString() string {
	const base = 36
	size := big.NewInt(base)
	n := make([]byte, 16)
	for i := range n {
		c, _ := rand.Int(rand.Reader, size)
		n[i] = strconv.FormatInt(c.Int64(), base)[0]
	}
	return string(n)
}

// CreateTokenHash 渡された文字列とsaltからTokenハッシュを生成する
func CreateTokenHash(str string, salt string) string {
	converted, _ := scrypt.Key([]byte(str), []byte(salt), 16384, 8, 1, 32)
	return hex.EncodeToString(converted[:])
}

// GenHashFromString 文字列からハッシュを生成する
func GenHashFromString(str string) string {
	converted := sha256.Sum256([]byte(str))
	return hex.EncodeToString(converted[:])
}
<|endoftext|>