<commit_before>package imapsrv

import "testing"
import "fmt"

func setupTest() (*Server, *session) {
	m := &TestMailstore{}
	s := NewServer(
		Store(m),
	)
	//s.Start()
	sess := createSession(1, s.config, s, nil, nil) // TODO: listener and net.Conn
	return s, sess
}

// A test mailstore used for unit testing
type TestMailstore struct {
}

// Get mailbox information
func (m *TestMailstore) GetMailbox(path []string) (*Mailbox, error) {
	return &Mailbox{
		Name: "inbox",
		Id:   1,
	}, nil
}

// Get a list of mailboxes at the given path
func (m *TestMailstore) GetMailboxes(path []string) ([]*Mailbox, error) {
	if len(path) == 0 {
		// Root
		return []*Mailbox{
			{
				Name: "inbox",
				Path: []string{"inbox"},
				Id:   1,
			},
			{
				Name: "spam",
				Path: []string{"spam"},
				Id:   2,
			},
		}, nil
	} else if len(path) == 1 && path[0] == "inbox" {
		return []*Mailbox{
			{
				Name: "starred",
				Path: []string{"inbox", "stared"},
				Id:   3,
			},
		}, nil
	} else {
		return []*Mailbox{}, nil
	}
}

// Get the sequence number of the first unseen message
func (m *TestMailstore) FirstUnseen(mbox int64) (int64, error) {
	return 4, nil
}

// Get the total number of messages in an IMAP mailbox
func (m *TestMailstore) TotalMessages(mbox int64) (int64, error) {
	return 8, nil
}

// Get the total number of unread messages in an IMAP mailbox
func (m *TestMailstore) RecentMessages(mbox int64) (int64, error) {
	return 4, nil
}

// Get the next available uid in an IMAP mailbox
func (m *TestMailstore) NextUid(mbox int64) (int64, error) {
	return 9, nil
}

func TestCapabilityCommand(t *testing.T) {
	_, session := setupTest()
	cap := &capability{tag: "A00001"}
	resp := cap.execute(session)
	if (resp.tag != "A00001") || (resp.message != "CAPABILITY completed") || (resp.untagged[0] != "CAPABILITY IMAP4rev1") {
		t.Error("Capability Failed - unexpected response.")
		fmt.Println(resp)
	}
}

func TestLogoutCommand(t *testing.T) {
	_, session := setupTest()
	log := &logout{tag: "A00004"}
	resp := log.execute(session)
	if (resp.tag != "A00004") || (resp.message != "LOGOUT completed") || (resp.untagged[0] != "BYE IMAP4rev1 Server logging out") {
		t.Error("Logout Failed - unexpected response.")
		fmt.Println(resp)
	}
}
<commit_msg>Fixed TestCapabilityCommand to indicate STARTTLS availability.<commit_after>package imapsrv

import "testing"
import "fmt"

func setupTest() (*Server, *session) {
	m := &TestMailstore{}
	s := NewServer(
		Store(m),
	)
	//s.Start()
	sess := createSession("1", s.config, s, nil, nil) // TODO: listener and net.Conn
	return s, sess
}

// A test mailstore used for unit testing
type TestMailstore struct {
}

// Get mailbox information
func (m *TestMailstore) GetMailbox(path []string) (*Mailbox, error) {
	return &Mailbox{
		Name: "inbox",
		Id:   1,
	}, nil
}

// Get a list of mailboxes at the given path
func (m *TestMailstore) GetMailboxes(path []string) ([]*Mailbox, error) {
	if len(path) == 0 {
		// Root
		return []*Mailbox{
			{
				Name: "inbox",
				Path: []string{"inbox"},
				Id:   1,
			},
			{
				Name: "spam",
				Path: []string{"spam"},
				Id:   2,
			},
		}, nil
	} else if len(path) == 1 && path[0] == "inbox" {
		return []*Mailbox{
			{
				Name: "starred",
				Path: []string{"inbox", "stared"},
				Id:   3,
			},
		}, nil
	} else {
		return []*Mailbox{}, nil
	}
}

// Get the sequence number of the first unseen message
func (m *TestMailstore) FirstUnseen(mbox int64) (int64, error) {
	return 4, nil
}

// Get the total number of messages in an IMAP mailbox
func (m *TestMailstore) TotalMessages(mbox int64) (int64, error) {
	return 8, nil
}

// Get the total number of unread messages in an IMAP mailbox
func (m *TestMailstore) RecentMessages(mbox int64) (int64, error) {
	return 4, nil
}

// Get the next available uid in an IMAP mailbox
func (m *TestMailstore) NextUid(mbox int64) (int64, error) {
	return 9, nil
}

func TestCapabilityCommand(t *testing.T) {
	_, session := setupTest()
	cap := &capability{tag: "A00001"}
	resp := cap.execute(session)
	// TODO: STARTTLS shouldn't always be available? (i.e. after using STARTTLS)
	if (resp.tag != "A00001") || (resp.message != "CAPABILITY completed") || (resp.untagged[0] != "CAPABILITY IMAP4rev1 STARTTLS") {
		t.Error("Capability Failed - unexpected response.")
		fmt.Println(resp)
	}
}

func TestLogoutCommand(t *testing.T) {
	_, session := setupTest()
	log := &logout{tag: "A00004"}
	resp := log.execute(session)
	if (resp.tag != "A00004") || (resp.message != "LOGOUT completed") || (resp.untagged[0] != "BYE IMAP4rev1 Server logging out") {
		t.Error("Logout Failed - unexpected response.")
		fmt.Println(resp)
	}
}
<|endoftext|>


<commit_before>package clw11

/*
#define CL_USE_DEPRECATED_OPENCL_1_1_APIS
#ifdef __APPLE__
#include "OpenCL/opencl.h"
#else
#include "CL/opencl.h"
#endif
*/
import "C"

type (
	CommandQueue           C.cl_command_queue
	CommandQueueProperties C.cl_command_queue_properties
)

// Bitfield.
const (
	QueueOutOfOrderExecModeEnable CommandQueueProperties = C.CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
	QueueProfilingEnable          CommandQueueProperties = C.CL_QUEUE_PROFILING_ENABLE
)

// Create a command-queue on a specific device.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateCommandQueue.html
func CreateCommandQueue(context Context, device DeviceID, properties CommandQueueProperties) (CommandQueue, error) {
	var err C.cl_int
	result := C.clCreateCommandQueue(context, device, C.cl_command_queue_properties(properties), &err)
	return CommandQueue(result), toError(err)
}

// Increments the command_queue reference count.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clRetainCommandQueue.html
func RetainCommandQueue(command_queue CommandQueue) error {
	return toError(C.clRetainCommandQueue(command_queue))
}

// Decrements the command_queue reference count.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clReleaseCommandQueue.html
func ReleaseCommandQueue(command_queue CommandQueue) error {
	return toError(C.clReleaseCommandQueue(command_queue))
}

// Enqueues a marker command.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueMarker.html
func EnqueueMarker(command_queue CommandQueue, event *Event) error {
	return toError(C.clEnqueueMarker(command_queue, (*C.cl_event)(event)))
}

// Enqueues a wait for a specific event or a list of events to complete before
// any future commands queued in the command-queue are executed.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueWaitForEvents.html
func EnqueueWaitForEvents(command_queue CommandQueue, wait_list []Event) error {
	event_list, num_events := toEventList(wait_list)
	return toError(C.clEnqueueWaitForEvents(command_queue, num_events, event_list))
}

// A synchronization point that enqueues a barrier operation.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueBarrier.html
func EnqueueBarrier(command_queue CommandQueue) error {
	return toError(C.clEnqueueBarrier(command_queue))
}

// Issues all previously queued OpenCL commands in a command-queue to the device
// associated with the command-queue.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clFlush.html
func Flush(cq CommandQueue) error {
	return toError(C.clFlush(cq))
}

// Blocks until all previously queued OpenCL commands in a command-queue are
// issued to the associated device and have completed.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clFinish.html
func Finish(cq CommandQueue) error {
	return toError(C.clFinish(cq))
}
<commit_msg>Added fetching of command queue properties.<commit_after>package clw11

/*
#define CL_USE_DEPRECATED_OPENCL_1_1_APIS
#ifdef __APPLE__
#include "OpenCL/opencl.h"
#else
#include "CL/opencl.h"
#endif
*/
import "C"
import "unsafe"

type (
	CommandQueue           C.cl_command_queue
	CommandQueueProperties C.cl_command_queue_properties
	CommandQueueInfo       C.cl_command_queue_info
)

// Bitfield.
const (
	QueueOutOfOrderExecModeEnable CommandQueueProperties = C.CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
	QueueProfilingEnable          CommandQueueProperties = C.CL_QUEUE_PROFILING_ENABLE
)

const (
	QueueContext        CommandQueueInfo = C.CL_QUEUE_CONTEXT
	QueueDevice         CommandQueueInfo = C.CL_QUEUE_DEVICE
	QueueReferenceCount CommandQueueInfo = C.CL_QUEUE_REFERENCE_COUNT
	QueueProperties     CommandQueueInfo = C.CL_QUEUE_PROPERTIES
)

// Create a command-queue on a specific device.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateCommandQueue.html
func CreateCommandQueue(context Context, device DeviceID, properties CommandQueueProperties) (CommandQueue, error) {
	var err C.cl_int
	result := C.clCreateCommandQueue(context, device, C.cl_command_queue_properties(properties), &err)
	return CommandQueue(result), toError(err)
}

// Increments the command_queue reference count.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clRetainCommandQueue.html
func RetainCommandQueue(command_queue CommandQueue) error {
	return toError(C.clRetainCommandQueue(command_queue))
}

// Decrements the command_queue reference count.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clReleaseCommandQueue.html
func ReleaseCommandQueue(command_queue CommandQueue) error {
	return toError(C.clReleaseCommandQueue(command_queue))
}

// Enqueues a marker command.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueMarker.html
func EnqueueMarker(command_queue CommandQueue, event *Event) error {
	return toError(C.clEnqueueMarker(command_queue, (*C.cl_event)(event)))
}

// Enqueues a wait for a specific event or a list of events to complete before
// any future commands queued in the command-queue are executed.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueWaitForEvents.html
func EnqueueWaitForEvents(command_queue CommandQueue, wait_list []Event) error {
	event_list, num_events := toEventList(wait_list)
	return toError(C.clEnqueueWaitForEvents(command_queue, num_events, event_list))
}

// A synchronization point that enqueues a barrier operation.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueBarrier.html
func EnqueueBarrier(command_queue CommandQueue) error {
	return toError(C.clEnqueueBarrier(command_queue))
}

// Issues all previously queued OpenCL commands in a command-queue to the device
// associated with the command-queue.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clFlush.html
func Flush(cq CommandQueue) error {
	return toError(C.clFlush(cq))
}

// Blocks until all previously queued OpenCL commands in a command-queue are
// issued to the associated device and have completed.
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clFinish.html
func Finish(cq CommandQueue) error {
	return toError(C.clFinish(cq))
}

// Query information about a command-queue.
// https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetCommandQueueInfo.html
func GetCommandQueueInfo(command_queue CommandQueue, param_name CommandQueueInfo, param_value_size Size,
	param_value unsafe.Pointer, param_value_size_ret *Size) error {
	return toError(C.clGetCommandQueueInfo(command_queue, C.cl_command_queue_info(param_name),
		C.size_t(param_value_size), param_value, (*C.size_t)(param_value_size_ret)))
}
<|endoftext|>


<commit_before>package commands

import (
	"fmt"
	"os"
	"os/exec"

	"github.com/leancloud/lean-cli/logo"
	"github.com/leancloud/lean-cli/version"
	"github.com/urfave/cli"
)

// Run the command line
func Run(args []string) {
	// add banner text to help text
	cli.AppHelpTemplate = logo.Logo() + cli.AppHelpTemplate
	cli.SubcommandHelpTemplate = logo.Logo() + cli.SubcommandHelpTemplate

	app := cli.NewApp()
	app.Name = "lean"
	app.Version = version.Version
	app.Usage = "Command line to manage and deploy LeanCloud apps"
	app.EnableBashCompletion = true

	app.CommandNotFound = thirdPartyCommand
	app.Commands = []cli.Command{
		{
			Name: "login",
			Usage: func() string {
				if version.Distribution == "lean" {
					return "Log in to LeanCloud"
				} else {
					return "Log in to TapTap Developer Services"
				}
			}(),
			Action: wrapAction(loginAction),
			ArgsUsage: func() string {
				if version.Distribution == "lean" {
					return "[-u username -p password --use-token -k token (--region <cn-n1> | <cn-e1> | <us-w1>)]"
				} else {
					return "[-k token]"
				}
			}(),
			Flags: func() []cli.Flag {
				if version.Distribution == "lean" {
					return []cli.Flag{
						cli.StringFlag{
							Name:  "username,u",
							Usage: "Username",
						},
						cli.StringFlag{
							Name:  "password,p",
							Usage: "Password",
						},
						cli.StringFlag{
							Name:  "region,r",
							Usage: "The LeanCloud region to log in to (e.g., US, CN)",
						},
						cli.BoolFlag{
							Name:  "use-token",
							Usage: "Use token to log in",
						},
						cli.StringFlag{
							Name:  "token,k",
							Usage: "AccessToken generated from the Console",
						},
					}
				} else {
					return []cli.Flag{
						cli.StringFlag{
							Name:  "token,k",
							Usage: "AccessToken generated from the Console",
						},
					}
				}
			}(),
		},
		{
			Name: "switch",
			Usage: func() string {
				if version.Distribution == "lean" {
					return "Change the associated LeanCloud app"
				} else {
					return "Change the associated CloudEngine app"
				}
			}(),
			Action:    wrapAction(switchAction),
			ArgsUsage: "[appID | appName]",
			Flags: func() []cli.Flag {
				if version.Distribution == "lean" {
					return []cli.Flag{
						cli.StringFlag{
							Name:  "region",
							Usage: "LeanCloud region",
						},
						cli.StringFlag{
							Name:  "group",
							Usage: "LeanEngine group",
						},
					}
				} else {
					return []cli.Flag{
						cli.StringFlag{
							Name:  "group",
							Usage: "CloudEngine group",
						},
					}
				}
			}(),
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "login",
			Usage:     "Log in to LeanCloud",
			Action:    wrapAction(loginAction),
			ArgsUsage: "[-u username -p password (--region <cn-n1> | <us-w1> | <cn-e1>)]",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "username,u",
					Usage: "Username",
				},
				cli.StringFlag{
					Name:  "password,p",
					Usage: "Password",
				},
				cli.StringFlag{
					Name:  "region,r",
					Usage: "The LeanCloud region to log in to (e.g., US, CN)",
				},
			},
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "metric",
			Usage:     "Obtain LeanStorage performance metrics of current project",
			Action:    wrapAction(statusAction),
			ArgsUsage: "[--from fromTime --to toTime --format default|json]",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "from",
					Usage: "Start date, formatted as YYYY-MM-DD，e.g., 1926-08-17",
				},
				cli.StringFlag{
					Name:  "to",
					Usage: "End date formatted as YYYY-MM-DD，e.g., 1926-08-17",
				},
				cli.StringFlag{
					Name:  "format",
					Usage: "Output format，'default' or 'json'",
				},
			},
		},
		{
			Name:   "info",
			Usage:  "Show information about the current user and app",
			Action: wrapAction(infoAction),
		},
		{
			Name:   "up",
			Usage:  "Start a development instance locally",
			Action: wrapAction(upAction),
			Flags: []cli.Flag{
				cli.IntFlag{
					Name:  "port,p",
					Usage: "Local port to listen on",
					Value: 3000,
				},
				cli.IntFlag{
					Name:  "console-port,c",
					Usage: "Port of the debug console",
				},
				cli.StringFlag{
					Name:  "cmd",
					Usage: "Command to start the project, other arguments except --console-port are ignored",
				},
			},
		},
		{
			Name:      "init",
			Usage:     "Initialize a LeanEngine project",
			Action:    wrapAction(initAction),
			ArgsUsage: "[dest]",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "region",
					Usage: "LeanCloud region for the project",
				},
				cli.StringFlag{
					Name:  "group",
					Usage: "LeanEngine group",
				},
			},
		},
		{
			Name:      "switch",
			Usage:     "Change the associated LeanCloud app",
			Action:    wrapAction(switchAction),
			ArgsUsage: "[appID | appName]",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "region",
					Usage: "LeanCloud region",
				},
				cli.StringFlag{
					Name:  "group",
					Usage: "LeanEngine group",
				},
			},
		},
		{
			Name:   "deploy",
			Usage:  "Deploy the project to LeanEngine",
			Action: wrapAction(deployAction),
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "g",
					Usage: "Deploy from git repo",
				},
				cli.BoolFlag{
					Name:  "war",
					Usage: "Deploy .war file for Java project. The first .war file in target/ is used by default",
				},
				cli.BoolFlag{
					Name:  "no-cache",
					Usage: "Force download dependencies",
				},
				cli.BoolFlag{
					Name:  "overwrite-functions",
					Usage: "Overwrite cloud functions with the same name in other groups",
				},
				cli.StringFlag{
					Name:  "leanignore",
					Usage: "Rule file for ignored files in deployment",
					Value: ".leanignore",
				},
				cli.StringFlag{
					Name:  "message,m",
					Usage: "Comment for this deployment, only applicable when deploying from local files",
				},
				cli.BoolFlag{
					Name: "keep-deploy-file",
				},
				cli.StringFlag{
					Name:  "revision,r",
					Usage: "Git revision or branch. Only applicable when deploying from Git",
					Value: "master",
				},
				cli.StringFlag{
					Name:  "options",
					Usage: "Send additional deploy options to server, in urlencode format(like `--options build-root=app&atomic=true`)",
				},
				cli.StringFlag{
					Name:  "prod",
					Usage: "Deploy to production(`--prod 1`) or staging(`--prod 0`) environment, default to staging if it exists",
				},
			},
		},
		{
			Name:   "publish",
			Usage:  "Publish code from staging to production",
			Action: wrapAction(publishAction),
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "overwrite-functions",
					Usage: "Overwrite cloud functions with the same name in other groups",
				},
				cli.StringFlag{
					Name:  "options",
					Usage: "Send additional deploy options to server, in urlencode format(like `--options build-root=app&atomic=true`)",
				},
			},
		},
		{
			Name:      "upload",
			Usage:     "Upload files to the current application (available in the '_File' class)",
			Action:    uploadAction,
			ArgsUsage: "<file-path> <file-path> ...",
		},
		{
			Name:   "logs",
			Usage:  "Show LeanEngine logs",
			Action: wrapAction(logsAction),
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "f",
					Usage: "Wait for and continuously show most recent logs",
				},
				cli.StringFlag{
					Name:  "env,e",
					Usage: "Environment to view (staging / production)",
					Value: "production",
				},
				cli.IntFlag{
					Name:  "limit,l",
					Usage: "Maximum number of lines to show",
					Value: 30,
				},
				cli.StringFlag{
					Name:  "from",
					Usage: "Start date formatted as YYYY-MM-DD (local time) or RFC3339，e.g., 2006-01-02 or 2006-01-02T15:04:05+08:00",
				},
				cli.StringFlag{
					Name:  "to",
					Usage: "End date formated as YYYY-MM-DD (local time) or RFC3339, e.g., 2006-01-02 or 2006-01-02T15:04:05+08:00",
				},
				cli.StringFlag{
					Name:  "format",
					Usage: "Format to use ('default' or 'json')",
					Value: "default",
				},
			},
		},
		{
			Name:   "debug",
			Usage:  "Start the debug console without running the project",
			Action: wrapAction(debugAction),
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "remote,r",
					Usage: "URL of target app",
					Value: "http://localhost:3000",
				},
				cli.StringFlag{
					Name:  "app-id",
					Usage: "Target AppID, use the AppID of the current project by default",
				},
				cli.IntFlag{
					Name:  "port,p",
					Usage: "Port to listen on",
					Value: 3001,
				},
			},
		},
		{
			Name:   "env",
			Usage:  "Output environment variables used by the current project",
			Action: wrapAction(envAction),
			Flags: []cli.Flag{
				cli.IntFlag{
					Name:  "port,p",
					Usage: "Local port for the app (affects value of LC_APP_PORT)",
					Value: 3000,
				},
				cli.StringFlag{
					Name:  "template",
					Usage: "Template for output, 'export {{name}}={{value}}' by default",
				},
			},
			Subcommands: []cli.Command{
				{
					Name:      "set",
					Usage:     "Set the value of an environment variable",
					Action:    wrapAction(envSetAction),
					ArgsUsage: "[env-name] [env-value]",
				},
				{
					Name:      "unset",
					Usage:     "Delete an environment variable",
					Action:    wrapAction(envUnsetAction),
					ArgsUsage: "[env-name]",
				},
			},
		},
		{
			Name:   "cache",
			Usage:  "LeanCache shell",
			Action: wrapAction(cacheAction),
			Flags: []cli.Flag{
				cli.IntFlag{
					Name:  "db",
					Usage: "Number of LeanCache DB",
					Value: 0,
				},
				cli.StringFlag{
					Name:  "name",
					Usage: "Name of LeanCache instance",
				},
				cli.StringFlag{
					Name:  "eval",
					Usage: "LeanCache command to run",
				},
			},
			Subcommands: []cli.Command{
				{
					Name:   "list",
					Usage:  "Show LeanCache instances of the current project",
					Action: wrapAction(cacheListAction),
				},
			},
		},
		{
			Name:   "cql",
			Usage:  "Start CQL interactive mode (warn: CQL is deprecated)",
			Action: wrapAction(cqlAction),
			Flags: []cli.Flag{
				cli.StringFlag{Name: "format,f",
					Usage: "CQL result format",
					Value: "table",
				},
				cli.StringFlag{
					Name:  "eval",
					Usage: "CQL command to run",
				},
			},
		},
		{
			Name:    "help",
			Aliases: []string{"h"},
			Usage:   "Show all commands or help info for one command",
			Action: func(c *cli.Context) error {
				args := c.Args()
				if args.Present() {
					_, err := fmt.Printf("Please use `lean %s -h` for subcommand usage.\n", args.First())
					return err
				}
				return cli.ShowAppHelp(c)
			},
		},
	}

	if version.Distro == "next" {
		app.Commands = append(app.Commands, nextLoginCommand)
	} else {
		app.Commands = append(app.Commands, legacyLoginCommand)
	}

	app.Before = func(c *cli.Context) error {
		disableGA, ok := os.LookupEnv("NO_ANALYTICS")
		if !ok || disableGA == "false" {
			args := []string{"--_collect-stats"}
			args = append(args, c.Args()...)
			_ = exec.Command(os.Args[0], args...).Start()
		}
		return nil
	}

	app.Run(args)
}
<commit_msg>chore: improve text hint in login command help<commit_after>package commands

import (
	"fmt"
	"os"
	"os/exec"

	"github.com/leancloud/lean-cli/logo"
	"github.com/leancloud/lean-cli/version"
	"github.com/urfave/cli"
)

// Run the command line
func Run(args []string) {
	// add banner text to help text
	cli.AppHelpTemplate = logo.Logo() + cli.AppHelpTemplate
	cli.SubcommandHelpTemplate = logo.Logo() + cli.SubcommandHelpTemplate

	app := cli.NewApp()
	app.Name = "lean"
	app.Version = version.Version
	app.Usage = "Command line to manage and deploy LeanCloud apps"
	app.EnableBashCompletion = true

	app.CommandNotFound = thirdPartyCommand
	app.Commands = []cli.Command{
		{
			Name: "login",
			Usage: func() string {
				if version.Distribution == "lean" {
					return "Log in to LeanCloud"
				} else {
					return "Log in to TapTap Developer Services"
				}
			}(),
			Action: wrapAction(loginAction),
			ArgsUsage: func() string {
				if version.Distribution == "lean" {
					return "[-u username -p password --use-token -k token (--region <cn-n1> | <cn-e1> | <us-w1>)]"
				} else {
					return "[-k token]"
				}
			}(),
			Flags: func() []cli.Flag {
				if version.Distribution == "lean" {
					return []cli.Flag{
						cli.StringFlag{
							Name:  "username,u",
							Usage: "Username",
						},
						cli.StringFlag{
							Name:  "password,p",
							Usage: "Password",
						},
						cli.StringFlag{
							Name:  "region,r",
							Usage: "The LeanCloud region to log in to (e.g., US, CN)",
						},
						cli.BoolFlag{
							Name:  "use-token",
							Usage: "Use AccessToken to log in",
						},
						cli.StringFlag{
							Name:  "token,k",
							Usage: "AccessToken generated from the Dashboard",
						},
					}
				} else {
					return []cli.Flag{
						cli.StringFlag{
							Name:  "token,k",
							Usage: "AccessToken generated from the Dashboard",
						},
					}
				}
			}(),
		},
		{
			Name: "switch",
			Usage: func() string {
				if version.Distribution == "lean" {
					return "Change the associated LeanCloud app"
				} else {
					return "Change the associated CloudEngine app"
				}
			}(),
			Action:    wrapAction(switchAction),
			ArgsUsage: "[appID | appName]",
			Flags: func() []cli.Flag {
				if version.Distribution == "lean" {
					return []cli.Flag{
						cli.StringFlag{
							Name:  "region",
							Usage: "LeanCloud region",
						},
						cli.StringFlag{
							Name:  "group",
							Usage: "LeanEngine group",
						},
					}
				} else {
					return []cli.Flag{
						cli.StringFlag{
							Name:  "group",
							Usage: "CloudEngine group",
						},
					}
				}
			}(),
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "login",
			Usage:     "Log in to LeanCloud",
			Action:    wrapAction(loginAction),
			ArgsUsage: "[-u username -p password (--region <cn-n1> | <us-w1> | <cn-e1>)]",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "username,u",
					Usage: "Username",
				},
				cli.StringFlag{
					Name:  "password,p",
					Usage: "Password",
				},
				cli.StringFlag{
					Name:  "region,r",
					Usage: "The LeanCloud region to log in to (e.g., US, CN)",
				},
			},
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "metric",
			Usage:     "Obtain LeanStorage performance metrics of current project",
			Action:    wrapAction(statusAction),
			ArgsUsage: "[--from fromTime --to toTime --format default|json]",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "from",
					Usage: "Start date, formatted as YYYY-MM-DD，e.g., 1926-08-17",
				},
				cli.StringFlag{
					Name:  "to",
					Usage: "End date formatted as YYYY-MM-DD，e.g., 1926-08-17",
				},
				cli.StringFlag{
					Name:  "format",
					Usage: "Output format，'default' or 'json'",
				},
			},
		},
		{
			Name:   "info",
			Usage:  "Show information about the current user and app",
			Action: wrapAction(infoAction),
		},
		{
			Name:   "up",
			Usage:  "Start a development instance locally",
			Action: wrapAction(upAction),
			Flags: []cli.Flag{
				cli.IntFlag{
					Name:  "port,p",
					Usage: "Local port to listen on",
					Value: 3000,
				},
				cli.IntFlag{
					Name:  "console-port,c",
					Usage: "Port of the debug console",
				},
				cli.StringFlag{
					Name:  "cmd",
					Usage: "Command to start the project, other arguments except --console-port are ignored",
				},
			},
		},
		{
			Name:      "init",
			Usage:     "Initialize a LeanEngine project",
			Action:    wrapAction(initAction),
			ArgsUsage: "[dest]",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "region",
					Usage: "LeanCloud region for the project",
				},
				cli.StringFlag{
					Name:  "group",
					Usage: "LeanEngine group",
				},
			},
		},
		{
			Name:      "switch",
			Usage:     "Change the associated LeanCloud app",
			Action:    wrapAction(switchAction),
			ArgsUsage: "[appID | appName]",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "region",
					Usage: "LeanCloud region",
				},
				cli.StringFlag{
					Name:  "group",
					Usage: "LeanEngine group",
				},
			},
		},
		{
			Name:   "deploy",
			Usage:  "Deploy the project to LeanEngine",
			Action: wrapAction(deployAction),
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "g",
					Usage: "Deploy from git repo",
				},
				cli.BoolFlag{
					Name:  "war",
					Usage: "Deploy .war file for Java project. The first .war file in target/ is used by default",
				},
				cli.BoolFlag{
					Name:  "no-cache",
					Usage: "Force download dependencies",
				},
				cli.BoolFlag{
					Name:  "overwrite-functions",
					Usage: "Overwrite cloud functions with the same name in other groups",
				},
				cli.StringFlag{
					Name:  "leanignore",
					Usage: "Rule file for ignored files in deployment",
					Value: ".leanignore",
				},
				cli.StringFlag{
					Name:  "message,m",
					Usage: "Comment for this deployment, only applicable when deploying from local files",
				},
				cli.BoolFlag{
					Name: "keep-deploy-file",
				},
				cli.StringFlag{
					Name:  "revision,r",
					Usage: "Git revision or branch. Only applicable when deploying from Git",
					Value: "master",
				},
				cli.StringFlag{
					Name:  "options",
					Usage: "Send additional deploy options to server, in urlencode format(like `--options build-root=app&atomic=true`)",
				},
				cli.StringFlag{
					Name:  "prod",
					Usage: "Deploy to production(`--prod 1`) or staging(`--prod 0`) environment, default to staging if it exists",
				},
			},
		},
		{
			Name:   "publish",
			Usage:  "Publish code from staging to production",
			Action: wrapAction(publishAction),
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "overwrite-functions",
					Usage: "Overwrite cloud functions with the same name in other groups",
				},
				cli.StringFlag{
					Name:  "options",
					Usage: "Send additional deploy options to server, in urlencode format(like `--options build-root=app&atomic=true`)",
				},
			},
		},
		{
			Name:      "upload",
			Usage:     "Upload files to the current application (available in the '_File' class)",
			Action:    uploadAction,
			ArgsUsage: "<file-path> <file-path> ...",
		},
		{
			Name:   "logs",
			Usage:  "Show LeanEngine logs",
			Action: wrapAction(logsAction),
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "f",
					Usage: "Wait for and continuously show most recent logs",
				},
				cli.StringFlag{
					Name:  "env,e",
					Usage: "Environment to view (staging / production)",
					Value: "production",
				},
				cli.IntFlag{
					Name:  "limit,l",
					Usage: "Maximum number of lines to show",
					Value: 30,
				},
				cli.StringFlag{
					Name:  "from",
					Usage: "Start date formatted as YYYY-MM-DD (local time) or RFC3339，e.g., 2006-01-02 or 2006-01-02T15:04:05+08:00",
				},
				cli.StringFlag{
					Name:  "to",
					Usage: "End date formated as YYYY-MM-DD (local time) or RFC3339, e.g., 2006-01-02 or 2006-01-02T15:04:05+08:00",
				},
				cli.StringFlag{
					Name:  "format",
					Usage: "Format to use ('default' or 'json')",
					Value: "default",
				},
			},
		},
		{
			Name:   "debug",
			Usage:  "Start the debug console without running the project",
			Action: wrapAction(debugAction),
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "remote,r",
					Usage: "URL of target app",
					Value: "http://localhost:3000",
				},
				cli.StringFlag{
					Name:  "app-id",
					Usage: "Target AppID, use the AppID of the current project by default",
				},
				cli.IntFlag{
					Name:  "port,p",
					Usage: "Port to listen on",
					Value: 3001,
				},
			},
		},
		{
			Name:   "env",
			Usage:  "Output environment variables used by the current project",
			Action: wrapAction(envAction),
			Flags: []cli.Flag{
				cli.IntFlag{
					Name:  "port,p",
					Usage: "Local port for the app (affects value of LC_APP_PORT)",
					Value: 3000,
				},
				cli.StringFlag{
					Name:  "template",
					Usage: "Template for output, 'export {{name}}={{value}}' by default",
				},
			},
			Subcommands: []cli.Command{
				{
					Name:      "set",
					Usage:     "Set the value of an environment variable",
					Action:    wrapAction(envSetAction),
					ArgsUsage: "[env-name] [env-value]",
				},
				{
					Name:      "unset",
					Usage:     "Delete an environment variable",
					Action:    wrapAction(envUnsetAction),
					ArgsUsage: "[env-name]",
				},
			},
		},
		{
			Name:   "cache",
			Usage:  "LeanCache shell",
			Action: wrapAction(cacheAction),
			Flags: []cli.Flag{
				cli.IntFlag{
					Name:  "db",
					Usage: "Number of LeanCache DB",
					Value: 0,
				},
				cli.StringFlag{
					Name:  "name",
					Usage: "Name of LeanCache instance",
				},
				cli.StringFlag{
					Name:  "eval",
					Usage: "LeanCache command to run",
				},
			},
			Subcommands: []cli.Command{
				{
					Name:   "list",
					Usage:  "Show LeanCache instances of the current project",
					Action: wrapAction(cacheListAction),
				},
			},
		},
		{
			Name:   "cql",
			Usage:  "Start CQL interactive mode (warn: CQL is deprecated)",
			Action: wrapAction(cqlAction),
			Flags: []cli.Flag{
				cli.StringFlag{Name: "format,f",
					Usage: "CQL result format",
					Value: "table",
				},
				cli.StringFlag{
					Name:  "eval",
					Usage: "CQL command to run",
				},
			},
		},
		{
			Name:    "help",
			Aliases: []string{"h"},
			Usage:   "Show all commands or help info for one command",
			Action: func(c *cli.Context) error {
				args := c.Args()
				if args.Present() {
					_, err := fmt.Printf("Please use `lean %s -h` for subcommand usage.\n", args.First())
					return err
				}
				return cli.ShowAppHelp(c)
			},
		},
	}

	if version.Distro == "next" {
		app.Commands = append(app.Commands, nextLoginCommand)
	} else {
		app.Commands = append(app.Commands, legacyLoginCommand)
	}

	app.Before = func(c *cli.Context) error {
		disableGA, ok := os.LookupEnv("NO_ANALYTICS")
		if !ok || disableGA == "false" {
			args := []string{"--_collect-stats"}
			args = append(args, c.Args()...)
			_ = exec.Command(os.Args[0], args...).Start()
		}
		return nil
	}

	app.Run(args)
}
<|endoftext|>


<commit_before>package packet

import (
	"fmt"
)

// Decode performs 6b/4b decoding and CRC verification.
// It returns the decoded data, excluding the CRC byte.
func Decode(p []byte) ([]byte, error) {
	data, err := Decode6b4b(p)
	if len(data) == 0 {
		err = fmt.Errorf("empty packet")
	}
	if err != nil {
		return data, err
	}
	last := len(data) - 1
	pktCRC := data[last]
	data = data[:last] // without CRC
	calcCRC := CRC8(data)
	if calcCRC != pktCRC {
		err = fmt.Errorf("computed CRC %02X but received %02X", calcCRC, pktCRC)

	}
	return data, err
}

// Encode appends the CRC to the data and returns the 4b/6b-encoded result.
// This may modify data's underlying array.
func Encode(data []byte) []byte {
	return Encode4b6b(append(data, CRC8(data)))
}
<commit_msg>Detect packet decoding error<commit_after>package packet

import (
	"fmt"
)

// Decode performs 6b/4b decoding and CRC verification.
// It returns the decoded data, excluding the CRC byte.
func Decode(p []byte) ([]byte, error) {
	data, err := Decode6b4b(p)
	if err != nil {
		return data, err
	}
	if len(data) == 0 {
		return nil, fmt.Errorf("empty packet")
	}
	last := len(data) - 1
	pktCRC := data[last]
	data = data[:last] // without CRC
	calcCRC := CRC8(data)
	if calcCRC != pktCRC {
		err = fmt.Errorf("computed CRC %02X but received %02X", calcCRC, pktCRC)

	}
	return data, err
}

// Encode appends the CRC to the data and returns the 4b/6b-encoded result.
// This may modify data's underlying array.
func Encode(data []byte) []byte {
	return Encode4b6b(append(data, CRC8(data)))
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/gob"
	"flag"
	"fmt"
	"github.com/4180122/distbayes/distmlMatlab"
	"github.com/arcaneiceman/GoVector/govec"
	"net"
	"os"
)

const BUFFSIZE = 400000

//10485760

var (
	cnum      int = 0
	maxnode   int = 0
	myaddr    *net.TCPAddr
	cnumhist  map[int]int
	client    map[string]int
	claddr    map[int]*net.TCPAddr
	tempmodel map[int]aggregate
	testqueue map[int]map[int]bool
	models    map[int]distmlMatlab.MatModel
	modelR    map[int]map[int]float64
	modelC    map[int]float64
	modelD    float64
	channel   chan message
	logger    *govec.GoLog
	l         *net.TCPListener
	gmodel    distmlMatlab.MatGlobalModel
	gempty    distmlMatlab.MatGlobalModel
)

type aggregate struct {
	cnum  int
	model distmlMatlab.MatModel
	r     map[int]float64
	c     float64
	d     float64
}

type message struct {
	Id       int
	NodeIp   string
	NodeName string
	Type     string
	Model    distmlMatlab.MatModel
	GModel   distmlMatlab.MatGlobalModel
}

type response struct {
	Resp  string
	Error string
}

func main() {
	//Initialize stuff
	client = make(map[string]int)
	claddr = make(map[int]*net.TCPAddr)
	models = make(map[int]distmlMatlab.MatModel)
	modelR = make(map[int]map[int]float64)
	modelC = make(map[int]float64)
	modelD = 0.0
	gmodel = distmlMatlab.MatGlobalModel{nil}
	tempmodel = make(map[int]aggregate)
	testqueue = make(map[int]map[int]bool)
	cnumhist = make(map[int]int)
	channel = make(chan message)

	go updateGlobal(channel)

	//Parsing inputargs
	parseArgs()

	//Hacky solution to the Matlab problem (Mathworks, please fix this!)
	// see: https://www.mathworks.com/matlabcentral/answers/305877-what-is-the-primary-message-table-for-module-77
	// and  https://github.com/JuliaInterop/MATLAB.jl/issues/47
	distmlMatlab.Hack()

	//Initialize TCP Connection and listener
	l, _ = net.ListenTCP("tcp", myaddr)
	fmt.Printf("Server initialized.\n")

	for {
		conn, err := l.AcceptTCP()
		checkError(err)
		go connHandler(conn)
	}

}

func connHandler(conn *net.TCPConn) {
	var msg message
	dec := gob.NewDecoder(conn)
	enc := gob.NewEncoder(conn)
	err := dec.Decode(&msg)
	checkError(err)
	fmt.Println(msg.NodeIp, msg.NodeName, msg.Type)
	switch msg.Type {
	case "commit_request":
		//node is sending a model, must forward to others for testing
		flag := checkQueue(client[msg.NodeName])
		fmt.Printf("<-- Received commit request from %v.\n", msg.NodeName)
		if flag {
			enc.Encode(response{"OK", ""})
			conn.Close()
			processTestRequest(msg)
		} else {
			//denied
			enc.Encode(response{"NO", "Pending tests are not complete."})
			fmt.Printf("--> Denied commit request from %v.\n", msg.NodeName)
			conn.Close()
		}
	case "global_request":
		//node is requesting the global model, will forward
		enc.Encode(response{"OK", ""})
		fmt.Printf("<-- Received global model request from %v.\n", msg.NodeName)
		genGlobalModel() //TODO maybe move this elsewhere
		sendGlobal(msg)
		conn.Close()
	case "test_complete":
		//node is submitting test results, will update its queue
		enc.Encode(response{"OK", ""})
		fmt.Printf("<-- Received completed test results from %v.\n", msg.NodeName)
		testqueue[client[msg.NodeName]][cnumhist[msg.Id]] = false
		conn.Close()
		//update the pending commit and merge if complete
		channel <- msg
	case "join_request":
		enc.Encode(response{"OK", ""})
		processJoin(msg)
		conn.Close()
	default:
		fmt.Println("something weird happened!")
		fmt.Println(msg.NodeIp, msg.NodeName, msg.Type)
		enc.Encode(response{"OK", ""})
		conn.Close()
	}

}

func updateGlobal(ch chan message) {
	// Function that aggregates the global model and commits when ready
	for {
		m := <-ch
		id := cnumhist[m.Id]
		tempAggregate := tempmodel[id]
		tempAggregate.d += m.Model.Size
		tempAggregate.r[client[m.NodeName]] = m.Model.Weight
		tempmodel[id] = tempAggregate
		if modelD < tempAggregate.d {
			modelD = tempAggregate.d
		}
		if float64(tempAggregate.d) > float64(modelD)*0.6 {
			models[id] = tempAggregate.model
			modelR[id] = tempAggregate.r
			modelC[id] = tempAggregate.c
			logger.LogLocalEvent("commit_complete")
			fmt.Printf("--- Committed model%v for commit number: %v.\n", id, tempAggregate.cnum)
		}
	}
}

func genGlobalModel() {
	modelstemp := models
	modelRtemp := modelR
	modelCtemp := modelC
	modelDtemp := modelD
	gmodel = distmlMatlab.CompactGlobal(modelstemp, modelRtemp, modelCtemp, modelDtemp)
}

func processTestRequest(m message) {
	cnum++
	//initialize new aggregate
	tempweight := make(map[int]float64)
	r := m.Model.Weight
	d := m.Model.Size
	m.Model.Weight = 0.0
	m.Model.Size = 0.0
	tempweight[client[m.NodeName]] = r
	tempmodel[client[m.NodeName]] = aggregate{cnum, m.Model, tempweight, d, d}
	cnumhist[cnum] = client[m.NodeName]
	for name, id := range client {
		if id != client[m.NodeName] {
			sendTestRequest(name, id, cnum, m.Model)
		}
	}
}

func sendTestRequest(name string, id, tcnum int, tmodel distmlMatlab.MatModel) {
	//func sendTestRequest(name string, id, tcnum int, tmodel bclass.Model) {
	//create test request
	msg := message{tcnum, myaddr.String(), "server", "test_request", tmodel, gempty}
	//increment tests in queue for that node
	if queue, ok := testqueue[id]; !ok {
		queue := make(map[int]bool)
		queue[cnumhist[tcnum]] = true
		testqueue[id] = queue
	} else {
		queue[cnumhist[tcnum]] = true
	}
	//send the request
	fmt.Printf("--> Sending test request from %v to %v.", cnumhist[tcnum], name)
	err := tcpSend(claddr[id], msg)
	if err != nil {
		fmt.Printf(" [NO!]\n*** Could not send test request to %v.\n", name)
	}
}

func sendGlobal(m message) {
	fmt.Printf("--> Sending global model to %v.", m.NodeName)
	msg := message{m.Id, myaddr.String(), "server", "global_grant", m.Model, gmodel}
	tcpSend(claddr[client[m.NodeName]], msg)
}

func tcpSend(addr *net.TCPAddr, msg message) error {
	conn, err := net.DialTCP("tcp", nil, addr)
	if err == nil {
		enc := gob.NewEncoder(conn)
		dec := gob.NewDecoder(conn)
		err := enc.Encode(msg)
		checkError(err)
		var r response
		err = dec.Decode(&r)
		checkError(err)
		if r.Resp == "OK" {
			fmt.Printf(" [OK]\n")
		} else {
			fmt.Printf(" [%s]\n<-- Request was denied by node: %v.\nEnter command: ", r.Resp, r.Error)
		}
	}
	return err
}

func checkQueue(id int) bool {
	flag := true
	for _, v := range testqueue[id] {
		if flag && v {
			flag = false
		}
	}
	return flag
}

func processJoin(m message) {
	//process depending on if it is a new node or a returning one
	if _, ok := client[m.NodeName]; !ok {
		//adding a node that has never been added before
		id := maxnode
		maxnode++
		client[m.NodeName] = id
		claddr[id], _ = net.ResolveTCPAddr("tcp", m.NodeIp)
		fmt.Printf("--- Added %v as node%v.\n", m.NodeName, id)
		for _, v := range tempmodel {
			sendTestRequest(m.NodeName, id, v.cnum, v.model)
		}
	} else {
		//node is rejoining, update address and resend the unfinished test requests
		id := client[m.NodeName]
		claddr[id], _ = net.ResolveTCPAddr("tcp", m.NodeIp)
		fmt.Printf("--- %v at node%v is back online.\n", m.NodeName, id)
		for k, v := range testqueue[id] {
			if v {
				aggregate := tempmodel[k]
				sendTestRequest(m.NodeName, id, aggregate.cnum, aggregate.model)
			}
		}
	}
}

func parseArgs() {
	flag.Parse()
	inputargs := flag.Args()
	var err error
	if len(inputargs) < 1 {
		fmt.Printf("Not enough inputs.\n")
		return
	}
	myaddr, err = net.ResolveTCPAddr("tcp", inputargs[0])
	checkError(err)
	logger = govec.Initialize(inputargs[1], inputargs[1])
}

func checkError(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
		os.Exit(1)
	}
}
<commit_msg>One last debugging line removed.<commit_after>package main

import (
	"encoding/gob"
	"flag"
	"fmt"
	"github.com/4180122/distbayes/distmlMatlab"
	"github.com/arcaneiceman/GoVector/govec"
	"net"
	"os"
)

const BUFFSIZE = 400000

//10485760

var (
	cnum      int = 0
	maxnode   int = 0
	myaddr    *net.TCPAddr
	cnumhist  map[int]int
	client    map[string]int
	claddr    map[int]*net.TCPAddr
	tempmodel map[int]aggregate
	testqueue map[int]map[int]bool
	models    map[int]distmlMatlab.MatModel
	modelR    map[int]map[int]float64
	modelC    map[int]float64
	modelD    float64
	channel   chan message
	logger    *govec.GoLog
	l         *net.TCPListener
	gmodel    distmlMatlab.MatGlobalModel
	gempty    distmlMatlab.MatGlobalModel
)

type aggregate struct {
	cnum  int
	model distmlMatlab.MatModel
	r     map[int]float64
	c     float64
	d     float64
}

type message struct {
	Id       int
	NodeIp   string
	NodeName string
	Type     string
	Model    distmlMatlab.MatModel
	GModel   distmlMatlab.MatGlobalModel
}

type response struct {
	Resp  string
	Error string
}

func main() {
	//Initialize stuff
	client = make(map[string]int)
	claddr = make(map[int]*net.TCPAddr)
	models = make(map[int]distmlMatlab.MatModel)
	modelR = make(map[int]map[int]float64)
	modelC = make(map[int]float64)
	modelD = 0.0
	gmodel = distmlMatlab.MatGlobalModel{nil}
	tempmodel = make(map[int]aggregate)
	testqueue = make(map[int]map[int]bool)
	cnumhist = make(map[int]int)
	channel = make(chan message)

	go updateGlobal(channel)

	//Parsing inputargs
	parseArgs()

	//Hacky solution to the Matlab problem (Mathworks, please fix this!)
	// see: https://www.mathworks.com/matlabcentral/answers/305877-what-is-the-primary-message-table-for-module-77
	// and  https://github.com/JuliaInterop/MATLAB.jl/issues/47
	distmlMatlab.Hack()

	//Initialize TCP Connection and listener
	l, _ = net.ListenTCP("tcp", myaddr)
	fmt.Printf("Server initialized.\n")

	for {
		conn, err := l.AcceptTCP()
		checkError(err)
		go connHandler(conn)
	}

}

func connHandler(conn *net.TCPConn) {
	var msg message
	dec := gob.NewDecoder(conn)
	enc := gob.NewEncoder(conn)
	err := dec.Decode(&msg)
	checkError(err)
	switch msg.Type {
	case "commit_request":
		//node is sending a model, must forward to others for testing
		flag := checkQueue(client[msg.NodeName])
		fmt.Printf("<-- Received commit request from %v.\n", msg.NodeName)
		if flag {
			enc.Encode(response{"OK", ""})
			conn.Close()
			processTestRequest(msg)
		} else {
			//denied
			enc.Encode(response{"NO", "Pending tests are not complete."})
			fmt.Printf("--> Denied commit request from %v.\n", msg.NodeName)
			conn.Close()
		}
	case "global_request":
		//node is requesting the global model, will forward
		enc.Encode(response{"OK", ""})
		fmt.Printf("<-- Received global model request from %v.\n", msg.NodeName)
		genGlobalModel() //TODO maybe move this elsewhere
		sendGlobal(msg)
		conn.Close()
	case "test_complete":
		//node is submitting test results, will update its queue
		enc.Encode(response{"OK", ""})
		fmt.Printf("<-- Received completed test results from %v.\n", msg.NodeName)
		testqueue[client[msg.NodeName]][cnumhist[msg.Id]] = false
		conn.Close()
		//update the pending commit and merge if complete
		channel <- msg
	case "join_request":
		enc.Encode(response{"OK", ""})
		processJoin(msg)
		conn.Close()
	default:
		fmt.Println("something weird happened!")
		//fmt.Println(msg.NodeIp, msg.NodeName, msg.Type)
		enc.Encode(response{"NO", "Unknown Request"})
		conn.Close()
	}

}

func updateGlobal(ch chan message) {
	// Function that aggregates the global model and commits when ready
	for {
		m := <-ch
		id := cnumhist[m.Id]
		tempAggregate := tempmodel[id]
		tempAggregate.d += m.Model.Size
		tempAggregate.r[client[m.NodeName]] = m.Model.Weight
		tempmodel[id] = tempAggregate
		if modelD < tempAggregate.d {
			modelD = tempAggregate.d
		}
		if float64(tempAggregate.d) > float64(modelD)*0.6 {
			models[id] = tempAggregate.model
			modelR[id] = tempAggregate.r
			modelC[id] = tempAggregate.c
			logger.LogLocalEvent("commit_complete")
			fmt.Printf("--- Committed model%v for commit number: %v.\n", id, tempAggregate.cnum)
		}
	}
}

func genGlobalModel() {
	modelstemp := models
	modelRtemp := modelR
	modelCtemp := modelC
	modelDtemp := modelD
	gmodel = distmlMatlab.CompactGlobal(modelstemp, modelRtemp, modelCtemp, modelDtemp)
}

func processTestRequest(m message) {
	cnum++
	//initialize new aggregate
	tempweight := make(map[int]float64)
	r := m.Model.Weight
	d := m.Model.Size
	m.Model.Weight = 0.0
	m.Model.Size = 0.0
	tempweight[client[m.NodeName]] = r
	tempmodel[client[m.NodeName]] = aggregate{cnum, m.Model, tempweight, d, d}
	cnumhist[cnum] = client[m.NodeName]
	for name, id := range client {
		if id != client[m.NodeName] {
			sendTestRequest(name, id, cnum, m.Model)
		}
	}
}

func sendTestRequest(name string, id, tcnum int, tmodel distmlMatlab.MatModel) {
	//func sendTestRequest(name string, id, tcnum int, tmodel bclass.Model) {
	//create test request
	msg := message{tcnum, myaddr.String(), "server", "test_request", tmodel, gempty}
	//increment tests in queue for that node
	if queue, ok := testqueue[id]; !ok {
		queue := make(map[int]bool)
		queue[cnumhist[tcnum]] = true
		testqueue[id] = queue
	} else {
		queue[cnumhist[tcnum]] = true
	}
	//send the request
	fmt.Printf("--> Sending test request from %v to %v.", cnumhist[tcnum], name)
	err := tcpSend(claddr[id], msg)
	if err != nil {
		fmt.Printf(" [NO!]\n*** Could not send test request to %v.\n", name)
	}
}

func sendGlobal(m message) {
	fmt.Printf("--> Sending global model to %v.", m.NodeName)
	msg := message{m.Id, myaddr.String(), "server", "global_grant", m.Model, gmodel}
	tcpSend(claddr[client[m.NodeName]], msg)
}

func tcpSend(addr *net.TCPAddr, msg message) error {
	conn, err := net.DialTCP("tcp", nil, addr)
	if err == nil {
		enc := gob.NewEncoder(conn)
		dec := gob.NewDecoder(conn)
		err := enc.Encode(msg)
		checkError(err)
		var r response
		err = dec.Decode(&r)
		checkError(err)
		if r.Resp == "OK" {
			fmt.Printf(" [OK]\n")
		} else {
			fmt.Printf(" [%s]\n<-- Request was denied by node: %v.\nEnter command: ", r.Resp, r.Error)
		}
	}
	return err
}

func checkQueue(id int) bool {
	flag := true
	for _, v := range testqueue[id] {
		if flag && v {
			flag = false
		}
	}
	return flag
}

func processJoin(m message) {
	//process depending on if it is a new node or a returning one
	if _, ok := client[m.NodeName]; !ok {
		//adding a node that has never been added before
		id := maxnode
		maxnode++
		client[m.NodeName] = id
		claddr[id], _ = net.ResolveTCPAddr("tcp", m.NodeIp)
		fmt.Printf("--- Added %v as node%v.\n", m.NodeName, id)
		for _, v := range tempmodel {
			sendTestRequest(m.NodeName, id, v.cnum, v.model)
		}
	} else {
		//node is rejoining, update address and resend the unfinished test requests
		id := client[m.NodeName]
		claddr[id], _ = net.ResolveTCPAddr("tcp", m.NodeIp)
		fmt.Printf("--- %v at node%v is back online.\n", m.NodeName, id)
		for k, v := range testqueue[id] {
			if v {
				aggregate := tempmodel[k]
				sendTestRequest(m.NodeName, id, aggregate.cnum, aggregate.model)
			}
		}
	}
}

func parseArgs() {
	flag.Parse()
	inputargs := flag.Args()
	var err error
	if len(inputargs) < 1 {
		fmt.Printf("Not enough inputs.\n")
		return
	}
	myaddr, err = net.ResolveTCPAddr("tcp", inputargs[0])
	checkError(err)
	logger = govec.Initialize(inputargs[1], inputargs[1])
}

func checkError(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// CMAC message authentication code, defined in
// NIST Special Publication SP 800-38B.

package cmac

import (
	"crypto/cipher"
	"crypto/subtle"
	"errors"
	"hash"
)

const (
	// minimal irreducible polynomial of degree b
	r64  = 0x1b
	r128 = 0x87
)

type cmac struct {
	k1, k2, ci, digest []byte
	p                  int // position in ci
	c                  cipher.Block
}

// New returns a new instance of a CMAC message authentication code
// digest using the given cipher.Block.
func New(c cipher.Block) (hash.Hash, error) {
	var r int
	n := c.BlockSize()
	switch n {
	case 64 / 8:
		r = r64
	case 128 / 8:
		r = r128
	default:
		return nil, errors.New("cmac: invalid cipher block size")
	}

	d := new(cmac)
	d.c = c
	d.k1 = make([]byte, n)
	d.k2 = make([]byte, n)
	d.ci = make([]byte, n)
	d.digest = make([]byte, n)

	// Subkey generation, p. 7
	c.Encrypt(d.k1, d.k1)

	v1 := shift1(d.k1, d.k1)
	d.k1[n-1] ^= byte(subtle.ConstantTimeSelect(v1, r, 0))

	v2 := shift1(d.k1, d.k2)
	d.k2[n-1] ^= byte(subtle.ConstantTimeSelect(v2, r, 0))

	return d, nil
}

// Reset clears the digest state, starting a new digest.
func (d *cmac) Reset() {
	for i := range d.ci {
		d.ci[i] = 0
	}
	d.p = 0
}

// Write adds the given data to the digest state.
func (d *cmac) Write(p []byte) (nn int, err error) {
	nn = len(p)
	bs := len(d.ci)
	left := bs - d.p

	if len(p) > left {
		xor(d.ci[d.p:], p[:left])
		p = p[left:]
		d.c.Encrypt(d.ci, d.ci)
		d.p = 0
	}

	for len(p) > bs {
		xor(d.ci, p[:bs])
		p = p[bs:]
		d.c.Encrypt(d.ci, d.ci)
	}

	if len(p) > 0 {
		xor(d.ci[d.p:], p)
		d.p += len(p)
	}
	return
}

// Sum returns the CMAC digest, one cipher block in length,
// of the data written with Write.
func (d *cmac) Sum(in []byte) []byte {
	// Finish last block, mix in key, encrypt.
	// Don't edit ci, in case caller wants
	// to keep digesting after call to Sum.
	k := d.k1
	if d.p < len(d.digest) {
		k = d.k2
	}
	for i := 0; i < len(d.ci); i++ {
		d.digest[i] = d.ci[i] ^ k[i]
	}
	if d.p < len(d.digest) {
		d.digest[d.p] ^= 0x80
	}
	d.c.Encrypt(d.digest, d.digest)
	return append(in, d.digest...)
}

func (d *cmac) Size() int { return len(d.digest) }

func (d *cmac) BlockSize() int { return d.c.BlockSize() }

func shift1(src, dst []byte) int {
	var b byte
	for i := len(src) - 1; i >= 0; i-- {
		bb := src[i] >> 7
		dst[i] = src[i]<<1 | b
		b = bb
	}
	return int(b)
}

func xor(a, b []byte) {
	for i, v := range b {
		a[i] ^= v
	}
}
<commit_msg>Clean digest in Reset<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// CMAC message authentication code, defined in
// NIST Special Publication SP 800-38B.

package cmac

import (
	"crypto/cipher"
	"crypto/subtle"
	"errors"
	"hash"
)

const (
	// minimal irreducible polynomial of degree b
	r64  = 0x1b
	r128 = 0x87
)

type cmac struct {
	k1, k2, ci, digest []byte
	p                  int // position in ci
	c                  cipher.Block
}

// New returns a new instance of a CMAC message authentication code
// digest using the given cipher.Block.
func New(c cipher.Block) (hash.Hash, error) {
	var r int
	n := c.BlockSize()
	switch n {
	case 64 / 8:
		r = r64
	case 128 / 8:
		r = r128
	default:
		return nil, errors.New("cmac: invalid cipher block size")
	}

	d := new(cmac)
	d.c = c
	d.k1 = make([]byte, n)
	d.k2 = make([]byte, n)
	d.ci = make([]byte, n)
	d.digest = make([]byte, n)

	// Subkey generation, p. 7
	c.Encrypt(d.k1, d.k1)

	v1 := shift1(d.k1, d.k1)
	d.k1[n-1] ^= byte(subtle.ConstantTimeSelect(v1, r, 0))

	v2 := shift1(d.k1, d.k2)
	d.k2[n-1] ^= byte(subtle.ConstantTimeSelect(v2, r, 0))

	return d, nil
}

// Reset clears the digest state, starting a new digest.
func (d *cmac) Reset() {
	for i := range d.ci {
		d.ci[i] = 0
	}
	for i := range d.digest {
		d.digest[i] = 0
	}
	d.p = 0
}

// Write adds the given data to the digest state.
func (d *cmac) Write(p []byte) (nn int, err error) {
	nn = len(p)
	bs := len(d.ci)
	left := bs - d.p

	if len(p) > left {
		xor(d.ci[d.p:], p[:left])
		p = p[left:]
		d.c.Encrypt(d.ci, d.ci)
		d.p = 0
	}

	for len(p) > bs {
		xor(d.ci, p[:bs])
		p = p[bs:]
		d.c.Encrypt(d.ci, d.ci)
	}

	if len(p) > 0 {
		xor(d.ci[d.p:], p)
		d.p += len(p)
	}
	return
}

// Sum returns the CMAC digest, one cipher block in length,
// of the data written with Write.
func (d *cmac) Sum(in []byte) []byte {
	// Finish last block, mix in key, encrypt.
	// Don't edit ci, in case caller wants
	// to keep digesting after call to Sum.
	k := d.k1
	if d.p < len(d.digest) {
		k = d.k2
	}
	for i := 0; i < len(d.ci); i++ {
		d.digest[i] = d.ci[i] ^ k[i]
	}
	if d.p < len(d.digest) {
		d.digest[d.p] ^= 0x80
	}
	d.c.Encrypt(d.digest, d.digest)
	return append(in, d.digest...)
}

func (d *cmac) Size() int { return len(d.digest) }

func (d *cmac) BlockSize() int { return d.c.BlockSize() }

func shift1(src, dst []byte) int {
	var b byte
	for i := len(src) - 1; i >= 0; i-- {
		bb := src[i] >> 7
		dst[i] = src[i]<<1 | b
		b = bb
	}
	return int(b)
}

func xor(a, b []byte) {
	for i, v := range b {
		a[i] ^= v
	}
}
<|endoftext|>


<commit_before>package image

import (
	"fmt"
	"octlink/rstore/modules/blobsmanifest"
	"octlink/rstore/modules/config"
	"octlink/rstore/modules/manifest"
	"octlink/rstore/modules/task"
	"octlink/rstore/utils"
	"octlink/rstore/utils/configuration"
	"octlink/rstore/utils/merrors"
	"octlink/rstore/utils/octlog"
	"octlink/rstore/utils/uuid"
	"strings"
)

var logger *octlog.LogConfig

// InitLog to init log config
func InitLog(level int) {
	logger = octlog.InitLogConfig("image.log", level)
}

const (
	// ImageStoreFile for image basic info store file
	ImageStoreFile = "imagestore_info.json"
)

const (
	// ImageStateEnabled for image state of Enabled
	ImageStateEnabled = "Enabled"

	// ImageStateDisabled for image state disabled
	ImageStateDisabled = "Disabled"
)

// Image for Image sturcture
type Image struct {
	ID          string `json:"uuid"`
	Name        string `json:"name"`
	State       string `json:"state"`
	Status      string `json:"status"`
	MediaType   string `json:"mediaType"`
	CreateTime  string `json:"createTime"`
	LastSync    string `json:"lastSync"`
	Desc        string `json:"description"`
	DiskSize    int64  `json:"diskSize"`
	VirtualSize int64  `json:"virtualSize"`
	Md5Sum      string `json:"md5sum"`
	URL         string `json:"url"`
	GuestOsType string `json:"guestOsType"` // Guest OS Type
	Arch        string `json:"arch"`
	Platform    string `json:"platform"`
	Format      string `json:"format"`
	System      bool   `json:"isSystem"`
	Account     string `json:"account"`
	InstallPath string `json:"installPath"` // rstore://iamgeid/blobsum
	Username    string `json:"username"`
	Password    string `json:"password"`
}

// GetImageCount to return image count by condition
func GetImageCount(account string, mediaType string, keyword string) int {
	all := GetAllImages(account, mediaType, keyword)
	return len(all)
}

// Brief to return brief info for image
func (image *Image) Brief() map[string]string {
	return map[string]string{
		"id":   image.ID,
		"name": image.Name,
	}
}

// Update to update image
func (image *Image) Update() int {
	WriteImages()
	return 0
}

// UpdateImageCallback when image download OK, update its info
func UpdateImageCallback(imageID string, diskSize int64, virtualSize int64,
	blobsum string, status string) error {

	im := GetImage(imageID)
	if im != nil {
		octlog.Warn("Got image of %s\n", imageID)
		im.Status = config.ImageStatusReady
		im.DiskSize = diskSize
		im.VirtualSize = virtualSize
		im.Md5Sum = blobsum
		im.InstallPath = fmt.Sprintf("rstore://%s/%s", im.ID, im.Md5Sum)
		im.Status = status

		WriteImages()

		return nil
	}

	return fmt.Errorf("Image of %s not exist", imageID)
}

// Add for image, after image added,
// installpath, diskSize, virtualSize, Status, md5sum need update after manifest installed
func (image *Image) Add() (string, int) {

	GImages = append(GImages, image)
	GImagesMap[image.ID] = image

	WriteImages()

	if image.URL != "" {
		t := new(task.Task)
		t.ID = uuid.Generate().Simple()
		t.URL = image.URL
		t.CreateTime = utils.CurrentTimeStr()
		t.ImageName = image.ID
		t.Status = task.TaskStatusNew
		t.AddAndRun(UpdateImageCallback)
		return t.ID, merrors.ErrSuccess
	}

	return "", merrors.ErrSuccess
}

func (image *Image) removeManifest() {
	m := manifest.GetManifest(image.ID, utils.GetDigestStr(image.ID))
	if m != nil {
		m.Delete()
		octlog.Warn("deleted manifest (%s:%s)\n", image.Name, m.BlobSum)
	}
}

func isBlobsManifestUsed(imageID string, blobsum string) bool {

	for _, im := range GImages {
		if im.Md5Sum == blobsum && im.ID != imageID {
			return true
		}
	}

	return false
}

func (image *Image) removeBlobsManifest() {

	bm := blobsmanifest.GetBlobsManifest(image.Md5Sum)
	if bm == nil {
		octlog.Error("blobs-manifest of %s not exist\n", image.Md5Sum)
		return
	}

	if !isBlobsManifestUsed(image.ID, image.Md5Sum) {
		bm.Delete()
		octlog.Warn("deleted blobs-manifest (%s:%s)\n", image.ID, image.Md5Sum)
	}
}

func (image *Image) removeManifestDir() {
	baseDir := configuration.GetConfig().RootDirectory + fmt.Sprintf(manifest.ImageManifestDirProto, image.ID)
	utils.RemoveDir(baseDir)
}

// Delete for image
func (image *Image) Delete() int {

	octlog.Warn("now to delete image (%s:%s)\n", image.Name, image.ID)

	len := len(GImages)

	for i, im := range GImages {
		if im.ID == image.ID {
			if i == 0 {
				GImages = GImages[1:len]
			} else {
				GImages = append(GImages[0:i], GImages[i+1:len]...)
			}
			delete(GImagesMap, im.ID)

			// To remove manifest firstly
			im.removeManifest()

			// To remove base manifest directory
			im.removeManifestDir()

			// then remove all blobs
			im.removeBlobsManifest()

			octlog.Warn("deleted image (%s:%s)\n", image.Name, image.ID)
		}
	}

	WriteImages()

	return 0
}

// GetImage by ID
func GetImage(id string) *Image {
	return GImagesMap[id]
}

// GetAllImages by condition
func GetAllImages(account string, mediaType string, keyword string) []*Image {

	images := make([]*Image, 0)

	for _, image := range GImages {

		// filter account
		if account != "" && image.Account != account {
			continue
		}

		// filter mediaType
		if mediaType != "" && image.MediaType != mediaType {
			continue
		}

		// filter keyword
		if keyword != "" && !strings.Contains(image.Name, keyword) {
			continue
		}

		images = append(images, image)
	}

	return images
}

// ContainAccount check account cantaination
func ContainAccount(accounts []string, id string) bool {
	for _, account := range accounts {
		if account == id {
			return true
		}
	}
	return false
}

// GetAccountList return account list for image
func GetAccountList() []string {

	images := GetAllImages("", "", "")
	accounts := make([]string, 0)
	for _, image := range images {
		if image.Account != "" && !ContainAccount(accounts, image.Account) {
			accounts = append(accounts, image.Account)
		}
	}

	return accounts
}
<commit_msg>create image info if it not exist<commit_after>package image

import (
	"fmt"
	"octlink/rstore/modules/blobsmanifest"
	"octlink/rstore/modules/config"
	"octlink/rstore/modules/manifest"
	"octlink/rstore/modules/task"
	"octlink/rstore/utils"
	"octlink/rstore/utils/configuration"
	"octlink/rstore/utils/merrors"
	"octlink/rstore/utils/octlog"
	"octlink/rstore/utils/uuid"
	"strings"
)

var logger *octlog.LogConfig

// InitLog to init log config
func InitLog(level int) {
	logger = octlog.InitLogConfig("image.log", level)
}

const (
	// ImageStoreFile for image basic info store file
	ImageStoreFile = "imagestore_info.json"
)

const (
	// ImageStateEnabled for image state of Enabled
	ImageStateEnabled = "Enabled"

	// ImageStateDisabled for image state disabled
	ImageStateDisabled = "Disabled"
)

// Image for Image sturcture
type Image struct {
	ID          string `json:"uuid"`
	Name        string `json:"name"`
	State       string `json:"state"`
	Status      string `json:"status"`
	MediaType   string `json:"mediaType"`
	CreateTime  string `json:"createTime"`
	LastSync    string `json:"lastSync"`
	Desc        string `json:"description"`
	DiskSize    int64  `json:"diskSize"`
	VirtualSize int64  `json:"virtualSize"`
	Md5Sum      string `json:"md5sum"`
	URL         string `json:"url"`
	GuestOsType string `json:"guestOsType"` // Guest OS Type
	Arch        string `json:"arch"`
	Platform    string `json:"platform"`
	Format      string `json:"format"`
	System      bool   `json:"isSystem"`
	Account     string `json:"account"`
	InstallPath string `json:"installPath"` // rstore://iamgeid/blobsum
	Username    string `json:"username"`
	Password    string `json:"password"`
}

// GetImageCount to return image count by condition
func GetImageCount(account string, mediaType string, keyword string) int {
	all := GetAllImages(account, mediaType, keyword)
	return len(all)
}

// Brief to return brief info for image
func (image *Image) Brief() map[string]string {
	return map[string]string{
		"id":   image.ID,
		"name": image.Name,
	}
}

// Update to update image
func (image *Image) Update() int {
	WriteImages()
	return 0
}

// UpdateImageCallback when image download OK, update its info,
// if Image not exist, just create a new one and update it.
func UpdateImageCallback(imageID string, diskSize int64, virtualSize int64,
	blobsum string, status string) error {

	im := GetImage(imageID)
	if im == nil {
		im = new(Image)
	}
	im.Status = config.ImageStatusReady
	im.DiskSize = diskSize
	im.VirtualSize = virtualSize
	im.Md5Sum = blobsum
	im.InstallPath = fmt.Sprintf("rstore://%s/%s", im.ID, im.Md5Sum)
	im.Status = status

	WriteImages()

	return nil
}

// Add for image, after image added,
// installpath, diskSize, virtualSize, Status, md5sum need update after manifest installed
func (image *Image) Add() (string, int) {

	GImages = append(GImages, image)
	GImagesMap[image.ID] = image

	WriteImages()

	if image.URL != "" {
		t := new(task.Task)
		t.ID = uuid.Generate().Simple()
		t.URL = image.URL
		t.CreateTime = utils.CurrentTimeStr()
		t.ImageName = image.ID
		t.Status = task.TaskStatusNew
		t.AddAndRun(UpdateImageCallback)
		return t.ID, merrors.ErrSuccess
	}

	return "", merrors.ErrSuccess
}

func (image *Image) removeManifest() {
	m := manifest.GetManifest(image.ID, utils.GetDigestStr(image.ID))
	if m != nil {
		m.Delete()
		octlog.Warn("deleted manifest (%s:%s)\n", image.Name, m.BlobSum)
	}
}

func isBlobsManifestUsed(imageID string, blobsum string) bool {

	for _, im := range GImages {
		if im.Md5Sum == blobsum && im.ID != imageID {
			return true
		}
	}

	return false
}

func (image *Image) removeBlobsManifest() {

	bm := blobsmanifest.GetBlobsManifest(image.Md5Sum)
	if bm == nil {
		octlog.Error("blobs-manifest of %s not exist\n", image.Md5Sum)
		return
	}

	if !isBlobsManifestUsed(image.ID, image.Md5Sum) {
		bm.Delete()
		octlog.Warn("deleted blobs-manifest (%s:%s)\n", image.ID, image.Md5Sum)
	}
}

func (image *Image) removeManifestDir() {
	baseDir := configuration.GetConfig().RootDirectory + fmt.Sprintf(manifest.ImageManifestDirProto, image.ID)
	utils.RemoveDir(baseDir)
}

// Delete for image
func (image *Image) Delete() int {

	octlog.Warn("now to delete image (%s:%s)\n", image.Name, image.ID)

	len := len(GImages)

	for i, im := range GImages {
		if im.ID == image.ID {
			if i == 0 {
				GImages = GImages[1:len]
			} else {
				GImages = append(GImages[0:i], GImages[i+1:len]...)
			}
			delete(GImagesMap, im.ID)

			// To remove manifest firstly
			im.removeManifest()

			// To remove base manifest directory
			im.removeManifestDir()

			// then remove all blobs
			im.removeBlobsManifest()

			octlog.Warn("deleted image (%s:%s)\n", image.Name, image.ID)
		}
	}

	WriteImages()

	return 0
}

// GetImage by ID
func GetImage(id string) *Image {
	return GImagesMap[id]
}

// GetAllImages by condition
func GetAllImages(account string, mediaType string, keyword string) []*Image {

	images := make([]*Image, 0)

	for _, image := range GImages {

		// filter account
		if account != "" && image.Account != account {
			continue
		}

		// filter mediaType
		if mediaType != "" && image.MediaType != mediaType {
			continue
		}

		// filter keyword
		if keyword != "" && !strings.Contains(image.Name, keyword) {
			continue
		}

		images = append(images, image)
	}

	return images
}

// ContainAccount check account cantaination
func ContainAccount(accounts []string, id string) bool {
	for _, account := range accounts {
		if account == id {
			return true
		}
	}
	return false
}

// GetAccountList return account list for image
func GetAccountList() []string {

	images := GetAllImages("", "", "")
	accounts := make([]string, 0)
	for _, image := range images {
		if image.Account != "" && !ContainAccount(accounts, image.Account) {
			accounts = append(accounts, image.Account)
		}
	}

	return accounts
}
<|endoftext|>


<commit_before>package miner

import (
	"errors"
	"log"
	"sync"
	"time"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/types"
)

const (
	// HeaderMemory is the number of previous calls to 'header'
	// that are remembered. Additionally, 'header' will only poll for a
	// new block every 'headerMemory / blockMemory' times it is
	// called. This reduces the amount of memory used, but comes at the cost of
	// not always having the most recent transactions.
	HeaderMemory = 10000

	// BlockMemory is the maximum number of blocks the miner will store
	// Blocks take up to 2 megabytes of memory, which is why this number is
	// limited.
	BlockMemory = 50

	// MaxSourceBlockAge is the maximum amount of time that is allowed to
	// elapse between generating source blocks.
	MaxSourceBlockAge = 60 * time.Second
)

var (
	errNilCS     = errors.New("miner cannot use a nil consensus set")
	errNilTpool  = errors.New("miner cannot use a nil transaction pool")
	errNilWallet = errors.New("miner cannot use a nil wallet")
)

// Miner struct contains all variables the miner needs
// in order to create and submit blocks.
type Miner struct {
	// Module dependencies.
	cs     modules.ConsensusSet
	tpool  modules.TransactionPool
	wallet modules.Wallet

	// BlockManager variables. Becaues blocks are large, one block is used to
	// make many headers which can be used by miners. Headers include an
	// arbitrary data transaction (appended to the block) to make the merkle
	// roots unique (preventing miners from doing redundant work). Every N
	// requests or M seconds, a new block is used to create headers.
	//
	// Only 'blocksMemory' blocks are kept in memory at a time, which
	// keeps ram usage reasonable. Miners may request many headers in parallel,
	// and thus may be working on different blocks. When they submit the solved
	// header to the block manager, the rest of the block needs to be found in
	// a lookup.
	blockMem        map[types.BlockHeader]*types.Block             // Mappings from headers to the blocks they are derived from.
	arbDataMem      map[types.BlockHeader][crypto.EntropySize]byte // Mappings from the headers to their unique arb data.
	headerMem       []types.BlockHeader                            // A circular list of headers that have been given out from the api recently.
	sourceBlock     *types.Block                                   // The block from which new headers for mining are created.
	sourceBlockTime time.Time                                      // How long headers have been using the same block (different from 'recent block').
	memProgress     int                                            // The index of the most recent header used in headerMem.

	// CPUMiner variables.
	miningOn bool  // indicates if the miner is supposed to be running
	mining   bool  // indicates if the miner is actually running
	hashRate int64 // indicates hashes per second

	// Utils
	persistDir string
	persist    persistence
	log        *log.Logger
	mu         sync.RWMutex
}

// New returns a ready-to-go miner that is not mining.
func New(cs modules.ConsensusSet, tpool modules.TransactionPool, w modules.Wallet, persistDir string) (*Miner, error) {
	// Create the miner and its dependencies.
	if cs == nil {
		return nil, errNilCS
	}
	if tpool == nil {
		return nil, errNilTpool
	}
	if w == nil {
		return nil, errNilWallet
	}

	// Assemble the miner. The miner is assembled without an address because
	// the wallet is likely not unlocked yet. The miner will grab an address
	// after the miner is unlocked (this must be coded manually for each
	// function that potentially requires the miner to have an address.
	m := &Miner{
		cs:     cs,
		tpool:  tpool,
		wallet: w,

		blockMem:   make(map[types.BlockHeader]*types.Block),
		arbDataMem: make(map[types.BlockHeader][crypto.EntropySize]byte),
		headerMem:  make([]types.BlockHeader, HeaderMemory),

		persistDir: persistDir,
	}

	err := m.initPersist()
	if err != nil {
		return nil, errors.New("miner persistence startup failed: " + err.Error())
	}

	err = m.cs.ConsensusSetPersistentSubscribe(m, m.persist.RecentChange)
	if err == modules.ErrInvalidConsensusChangeID {
		// If the change id is not recognized, it means that the consensus set
		// has somehow reset or otherwise changed, and a rescan must be
		// performed.
		m.log.Println("Inconsistency found between the miner and the consensus set, fixing...")

		// Perform the rescan and block until rescanning is complete. Rescan
		// does need access to a lock, but no lock is held during startup
		// anyway, so blocking until the channel returns an error is safe.
		c := make(chan error)
		m.threadedConsensusRescan(c)
		err = <-c
		if err != nil {
			return nil, errors.New("miner startup failed - rescanning failed: " + err.Error())
		}
	} else if err != nil {
		return nil, errors.New("miner subscription failed: " + err.Error())
	}

	m.tpool.TransactionPoolSubscribe(m)
	return m, nil
}

// checkAddress checks that the miner has an address, fetching an address from
// the wallet if not.
func (m *Miner) checkAddress() error {
	if m.persist.Address != (types.UnlockHash{}) {
		return nil
	}
	uc, err := m.wallet.NextAddress()
	if err != nil {
		return err
	}
	m.persist.Address = uc.UnlockHash()
	return nil
}

// BlocksMined returns the number of good blocks and stale blocks that have
// been mined by the miner.
func (m *Miner) BlocksMined() (goodBlocks, staleBlocks int) {
	m.mu.Lock()
	defer m.mu.Unlock()

	for _, blockID := range m.persist.BlocksFound {
		if m.cs.InCurrentPath(blockID) {
			goodBlocks++
		} else {
			staleBlocks++
		}
	}
	return
}
<commit_msg>break error handling into separate function<commit_after>package miner

import (
	"errors"
	"log"
	"sync"
	"time"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/types"
)

const (
	// HeaderMemory is the number of previous calls to 'header'
	// that are remembered. Additionally, 'header' will only poll for a
	// new block every 'headerMemory / blockMemory' times it is
	// called. This reduces the amount of memory used, but comes at the cost of
	// not always having the most recent transactions.
	HeaderMemory = 10000

	// BlockMemory is the maximum number of blocks the miner will store
	// Blocks take up to 2 megabytes of memory, which is why this number is
	// limited.
	BlockMemory = 50

	// MaxSourceBlockAge is the maximum amount of time that is allowed to
	// elapse between generating source blocks.
	MaxSourceBlockAge = 60 * time.Second
)

var (
	errNilCS     = errors.New("miner cannot use a nil consensus set")
	errNilTpool  = errors.New("miner cannot use a nil transaction pool")
	errNilWallet = errors.New("miner cannot use a nil wallet")
)

// Miner struct contains all variables the miner needs
// in order to create and submit blocks.
type Miner struct {
	// Module dependencies.
	cs     modules.ConsensusSet
	tpool  modules.TransactionPool
	wallet modules.Wallet

	// BlockManager variables. Becaues blocks are large, one block is used to
	// make many headers which can be used by miners. Headers include an
	// arbitrary data transaction (appended to the block) to make the merkle
	// roots unique (preventing miners from doing redundant work). Every N
	// requests or M seconds, a new block is used to create headers.
	//
	// Only 'blocksMemory' blocks are kept in memory at a time, which
	// keeps ram usage reasonable. Miners may request many headers in parallel,
	// and thus may be working on different blocks. When they submit the solved
	// header to the block manager, the rest of the block needs to be found in
	// a lookup.
	blockMem        map[types.BlockHeader]*types.Block             // Mappings from headers to the blocks they are derived from.
	arbDataMem      map[types.BlockHeader][crypto.EntropySize]byte // Mappings from the headers to their unique arb data.
	headerMem       []types.BlockHeader                            // A circular list of headers that have been given out from the api recently.
	sourceBlock     *types.Block                                   // The block from which new headers for mining are created.
	sourceBlockTime time.Time                                      // How long headers have been using the same block (different from 'recent block').
	memProgress     int                                            // The index of the most recent header used in headerMem.

	// CPUMiner variables.
	miningOn bool  // indicates if the miner is supposed to be running
	mining   bool  // indicates if the miner is actually running
	hashRate int64 // indicates hashes per second

	// Utils
	persistDir string
	persist    persistence
	log        *log.Logger
	mu         sync.RWMutex
}

// handleErrInvalidConsensusChangeID manages the rescanning in the event that a
// subscription during startup fails.
func (m *Miner) handleErrInvalidConsensusChangeID() error {
	// If the change id is not recognized, it means that the consensus set
	// has somehow reset or otherwise changed, and a rescan must be
	// performed.
	m.log.Println("Inconsistency found between the miner and the consensus set, fixing...")

	// Perform the rescan and block until rescanning is complete. Rescan
	// does need access to a lock, but no lock is held during startup
	// anyway, so blocking until the channel returns an error is safe.
	c := make(chan error)
	m.threadedConsensusRescan(c)
	return <-c
}

// New returns a ready-to-go miner that is not mining.
func New(cs modules.ConsensusSet, tpool modules.TransactionPool, w modules.Wallet, persistDir string) (*Miner, error) {
	// Create the miner and its dependencies.
	if cs == nil {
		return nil, errNilCS
	}
	if tpool == nil {
		return nil, errNilTpool
	}
	if w == nil {
		return nil, errNilWallet
	}

	// Assemble the miner. The miner is assembled without an address because
	// the wallet is likely not unlocked yet. The miner will grab an address
	// after the miner is unlocked (this must be coded manually for each
	// function that potentially requires the miner to have an address.
	m := &Miner{
		cs:     cs,
		tpool:  tpool,
		wallet: w,

		blockMem:   make(map[types.BlockHeader]*types.Block),
		arbDataMem: make(map[types.BlockHeader][crypto.EntropySize]byte),
		headerMem:  make([]types.BlockHeader, HeaderMemory),

		persistDir: persistDir,
	}

	err := m.initPersist()
	if err != nil {
		return nil, errors.New("miner persistence startup failed: " + err.Error())
	}

	err = m.cs.ConsensusSetPersistentSubscribe(m, m.persist.RecentChange)
	if err == modules.ErrInvalidConsensusChangeID {
		err = m.handleErrInvalidConsensusChangeID()
		if err != nil {
			return nil, errors.New("miner startup failed - rescanning failed: " + err.Error())
		}
	} else if err != nil {
		return nil, errors.New("miner subscription failed: " + err.Error())
	}

	m.tpool.TransactionPoolSubscribe(m)
	return m, nil
}

// checkAddress checks that the miner has an address, fetching an address from
// the wallet if not.
func (m *Miner) checkAddress() error {
	if m.persist.Address != (types.UnlockHash{}) {
		return nil
	}
	uc, err := m.wallet.NextAddress()
	if err != nil {
		return err
	}
	m.persist.Address = uc.UnlockHash()
	return nil
}

// BlocksMined returns the number of good blocks and stale blocks that have
// been mined by the miner.
func (m *Miner) BlocksMined() (goodBlocks, staleBlocks int) {
	m.mu.Lock()
	defer m.mu.Unlock()

	for _, blockID := range m.persist.BlocksFound {
		if m.cs.InCurrentPath(blockID) {
			goodBlocks++
		} else {
			staleBlocks++
		}
	}
	return
}
<|endoftext|>


<commit_before>package grifts

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"

	. "github.com/markbates/grift/grift"
)

var _ = Desc("release", "Generates a CHANGELOG and creates a new GitHub release based on what is in the version.go file.")
var _ = Add("release", func(c *Context) error {
	v, err := findVersion()
	if err != nil {
		return err
	}

	err = installBin()
	if err != nil {
		return err
	}

	err = dockerTest()
	if err != nil {
		return err
	}

	err = tagRelease(v)
	if err != nil {
		return err
	}

	err = runChangelogGenerator(v)
	if err != nil {
		return err
	}

	return commitAndPush(v)
})

func installBin() error {
	cmd := exec.Command("go", "install", "-v", "./buffalo")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func dockerTest() error {
	cmd := exec.Command("docker", "build", ".")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func tagRelease(v string) error {
	token := os.Getenv("GITHUB_TOKEN")
	if token == "" {
		return errors.New("GITHUB_TOKEN is not set!!")
	}

	body := map[string]interface{}{
		"tag_name":   fmt.Sprintf("v%s", v),
		"prerelease": false,
	}

	b, err := json.Marshal(&body)
	if err != nil {
		return err
	}

	res, err := http.Post(fmt.Sprintf("https://api.github.com/repos/markbates/buffalo/releases?access_token=%s", token), "application/json", bytes.NewReader(b))
	if err != nil {
		return err
	}

	code := res.StatusCode
	if code < 200 || code >= 300 {
		return fmt.Errorf("got a not successful status code from github! %d", code)
	}

	return nil
}

func runChangelogGenerator(v string) error {
	cmd := exec.Command("github_changelog_generator")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func commitAndPush(v string) error {
	cmd := exec.Command("git", "commit", "CHANGELOG.md", "-m", fmt.Sprintf("Updated changelog for release v%s", v))
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	err := cmd.Run()
	if err != nil {
		return err
	}

	cmd = exec.Command("git", "push", "origin")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func findVersion() (string, error) {
	pwd, err := os.Getwd()
	if err != nil {
		return "", err
	}
	vfile, err := ioutil.ReadFile(filepath.Join(pwd, "buffalo/cmd/version.go"))
	if err != nil {
		return "", err
	}

	//var Version = "0.4.0"
	re := regexp.MustCompile(`var Version = "(.+)"`)
	matches := re.FindStringSubmatch(string(vfile))
	if len(matches) < 2 {
		return "", errors.New("failed to find the version!")
	}
	v := matches[1]
	return v, nil
}
<commit_msg>run the tests locally first, before docker<commit_after>package grifts

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"

	. "github.com/markbates/grift/grift"
)

var _ = Desc("release", "Generates a CHANGELOG and creates a new GitHub release based on what is in the version.go file.")
var _ = Add("release", func(c *Context) error {
	v, err := findVersion()
	if err != nil {
		return err
	}

	err = installBin()
	if err != nil {
		return err
	}

	err = localTest()
	if err != nil {
		return err
	}

	err = dockerTest()
	if err != nil {
		return err
	}

	err = tagRelease(v)
	if err != nil {
		return err
	}

	err = runChangelogGenerator(v)
	if err != nil {
		return err
	}

	return commitAndPush(v)
})

func installBin() error {
	cmd := exec.Command("go", "install", "-v", "./buffalo")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func localTest() error {
	cmd := exec.Command("go", "test", "-v", "-race", "./...")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func dockerTest() error {
	cmd := exec.Command("docker", "build", ".")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func tagRelease(v string) error {
	token := os.Getenv("GITHUB_TOKEN")
	if token == "" {
		return errors.New("GITHUB_TOKEN is not set!!")
	}

	body := map[string]interface{}{
		"tag_name":   fmt.Sprintf("v%s", v),
		"prerelease": false,
	}

	b, err := json.Marshal(&body)
	if err != nil {
		return err
	}

	res, err := http.Post(fmt.Sprintf("https://api.github.com/repos/markbates/buffalo/releases?access_token=%s", token), "application/json", bytes.NewReader(b))
	if err != nil {
		return err
	}

	code := res.StatusCode
	if code < 200 || code >= 300 {
		return fmt.Errorf("got a not successful status code from github! %d", code)
	}

	return nil
}

func runChangelogGenerator(v string) error {
	cmd := exec.Command("github_changelog_generator")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func commitAndPush(v string) error {
	cmd := exec.Command("git", "commit", "CHANGELOG.md", "-m", fmt.Sprintf("Updated changelog for release v%s", v))
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	err := cmd.Run()
	if err != nil {
		return err
	}

	cmd = exec.Command("git", "push", "origin")
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func findVersion() (string, error) {
	pwd, err := os.Getwd()
	if err != nil {
		return "", err
	}
	vfile, err := ioutil.ReadFile(filepath.Join(pwd, "buffalo/cmd/version.go"))
	if err != nil {
		return "", err
	}

	//var Version = "0.4.0"
	re := regexp.MustCompile(`var Version = "(.+)"`)
	matches := re.FindStringSubmatch(string(vfile))
	if len(matches) < 2 {
		return "", errors.New("failed to find the version!")
	}
	v := matches[1]
	return v, nil
}
<|endoftext|>


<commit_before>package commands

import (
	"github.com/ghodss/yaml"
	"github.com/jawher/mow.cli"
	"github.com/mesos/mesos-go"
	"github.com/vektorlab/mesos-cli/config"
	"github.com/vektorlab/mesos-cli/runner"
	"io/ioutil"
	"os"
)

type Run struct{}

func (_ Run) Name() string { return "run" }
func (_ Run) Desc() string { return "Run tasks on Mesos" }

func (_ Run) Init(profile config.ProfileFn) func(*cli.Cmd) {
	return func(cmd *cli.Cmd) {
		cmd.Spec = "[OPTIONS] [FILE]"

		var (
			file     = cmd.StringArg("FILE", "Mesosfile", "File containing Mesos TaskInfos, - for stdin")
			hostname = cmd.StringOpt("m master", "", "Mesos Master")
			restart  = cmd.BoolOpt("restart", false, "Restart containers on failure")
			sync     = cmd.BoolOpt("s sync", false, "Run containers synchronously")
		)

		cmd.Action = func() {
			profile().With(
				config.Master(*hostname),
				config.Restart(*restart),
				config.Sync(*sync),
			)

			tasks := []*mesos.TaskInfo{}

			if *file == "-" {
				raw, err := ioutil.ReadAll(os.Stdin)
				failOnErr(err)
				failOnErr(yaml.Unmarshal(raw, &tasks))
			} else {
				raw, err := ioutil.ReadFile(*file)
				failOnErr(err)
				failOnErr(yaml.Unmarshal(raw, &tasks))
			}
			failOnErr(runner.Run(profile(), tasks))
		}
	}
}
<commit_msg>add default resources and port mappings to run input<commit_after>package commands

import (
	"github.com/ghodss/yaml"
	"github.com/jawher/mow.cli"
	"github.com/mesos/mesos-go"
	"github.com/vektorlab/mesos-cli/commands/options"
	"github.com/vektorlab/mesos-cli/config"
	"github.com/vektorlab/mesos-cli/runner"
	"io/ioutil"
	"os"
)

type Run struct{}

func (_ Run) Name() string { return "run" }
func (_ Run) Desc() string { return "Run tasks on Mesos" }

func (_ Run) Init(profile config.ProfileFn) func(*cli.Cmd) {
	return func(cmd *cli.Cmd) {
		cmd.Spec = "[OPTIONS] [FILE]"

		var (
			file     = cmd.StringArg("FILE", "Mesosfile", "File containing Mesos TaskInfos, - for stdin")
			hostname = cmd.StringOpt("m master", "", "Mesos Master")
			restart  = cmd.BoolOpt("restart", false, "Restart containers on failure")
			sync     = cmd.BoolOpt("s sync", false, "Run containers synchronously")
		)

		cmd.Action = func() {
			profile().With(
				config.Master(*hostname),
				config.Restart(*restart),
				config.Sync(*sync),
			)

			tasks := []*mesos.TaskInfo{}

			if *file == "-" {
				raw, err := ioutil.ReadAll(os.Stdin)
				failOnErr(err)
				failOnErr(yaml.Unmarshal(raw, &tasks))
			} else {
				raw, err := ioutil.ReadFile(*file)
				failOnErr(err)
				failOnErr(yaml.Unmarshal(raw, &tasks))
			}

			for _, task := range tasks {
				options.Apply(
					task,
					options.WithDefaultResources(),
					options.WithPorts(),
				)
			}

			failOnErr(runner.Run(profile(), tasks))
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 Stratumn SAS. All rights reserved.
// Use of this source code is governed by an Apache License 2.0
// LICENSE file.

// Package bcbatchfossilizer implements a fossilizer that fossilize batches of
// hashes on a blockchain.
package bcbatchfossilizer

import (
	"fmt"

	log "github.com/Sirupsen/logrus"

	"github.com/stratumn/sdk/cs"
	"github.com/stratumn/sdk/cs/evidences"
	"github.com/stratumn/sdk/fossilizer"
	"github.com/stratumn/sdk/types"

	"github.com/stratumn/goprivate/batchfossilizer"
	"github.com/stratumn/goprivate/blockchain"
)

const (
	// Name is the name set in the fossilizer's information.
	Name = "bcbatch"

	// Description is the description set in the fossilizer's information.
	Description = "Stratumn Blockchain Batch Fossilizer"
)

// Config contains configuration options for the fossilizer.
type Config struct {
	HashTimestamper blockchain.HashTimestamper
}

// Info is the info returned by GetInfo.
type Info struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Version     string `json:"version"`
	Commit      string `json:"commit"`
	Blockchain  string `json:"blockchain"`
}

// Fossilizer is the type that
// implements github.com/stratumn/sdk/fossilizer.Adapter.
type Fossilizer struct {
	*batchfossilizer.Fossilizer
	config            *Config
	lastRoot          *types.Bytes32
	lastTransactionID types.TransactionID
}

// New creates an instance of a Fossilizer.
func New(config *Config, batchConfig *batchfossilizer.Config) (*Fossilizer, error) {
	if batchConfig.MaxSimBatches > 1 {
		return nil, fmt.Errorf("MaxSimBatches is %d want less than 2", batchConfig.MaxSimBatches)
	}

	b, err := batchfossilizer.New(batchConfig)
	if err != nil {
		return nil, err
	}

	f := Fossilizer{
		Fossilizer: b,
		config:     config,
	}

	f.SetTransformer(f.transform)

	return &f, err
}

// GetInfo implements github.com/stratumn/sdk/fossilizer.Adapter.GetInfo.
func (a *Fossilizer) GetInfo() (interface{}, error) {
	batchInfo, err := a.Fossilizer.GetInfo()
	if err != nil {
		return nil, err
	}

	info, ok := batchInfo.(*batchfossilizer.Info)
	if !ok {
		return nil, fmt.Errorf("unexpected batchfossilizer info %#v", batchInfo)
	}

	return &Info{
		Name:        Name,
		Description: Description,
		Version:     info.Version,
		Commit:      info.Commit,
		Blockchain:  a.config.HashTimestamper.Network().String(),
	}, nil
}

func (a *Fossilizer) transform(evidence *cs.Evidence, data, meta []byte) (*fossilizer.Result, error) {
	var (
		root = evidence.Proof.(*evidences.BatchProof).Root
		txid types.TransactionID
		err  error
	)

	if a.lastRoot == nil || *root != *a.lastRoot {
		txid, err = a.config.HashTimestamper.TimestampHash(root)
		if err != nil {
			return nil, err
		}
		log.WithFields(log.Fields{
			"txid": txid,
			"root": root,
		}).Info("Broadcasted transaction")

		a.lastRoot = root
		a.lastTransactionID = txid
	}

	evidence.Provider = a.config.HashTimestamper.Network().String()
	evidence.Backend = Name
	evidence.Proof = &evidences.BcBatchProof{
		Batch:         *evidence.Proof.(*evidences.BatchProof),
		TransactionID: a.lastTransactionID,
	}

	r := fossilizer.Result{
		Evidence: *evidence,
		Data:     data,
		Meta:     meta,
	}

	return &r, nil
}
<commit_msg>bcbatchfossilizer: update dependencies<commit_after>// Copyright 2016 Stratumn SAS. All rights reserved.
// Use of this source code is governed by an Apache License 2.0
// LICENSE file.

// Package bcbatchfossilizer implements a fossilizer that fossilize batches of
// hashes on a blockchain.
package bcbatchfossilizer

import (
	"fmt"

	log "github.com/sirupsen/logrus"

	"github.com/stratumn/sdk/cs"
	"github.com/stratumn/sdk/cs/evidences"
	"github.com/stratumn/sdk/fossilizer"
	"github.com/stratumn/sdk/types"

	"github.com/stratumn/goprivate/batchfossilizer"
	"github.com/stratumn/goprivate/blockchain"
)

const (
	// Name is the name set in the fossilizer's information.
	Name = "bcbatch"

	// Description is the description set in the fossilizer's information.
	Description = "Stratumn Blockchain Batch Fossilizer"
)

// Config contains configuration options for the fossilizer.
type Config struct {
	HashTimestamper blockchain.HashTimestamper
}

// Info is the info returned by GetInfo.
type Info struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Version     string `json:"version"`
	Commit      string `json:"commit"`
	Blockchain  string `json:"blockchain"`
}

// Fossilizer is the type that
// implements github.com/stratumn/sdk/fossilizer.Adapter.
type Fossilizer struct {
	*batchfossilizer.Fossilizer
	config            *Config
	lastRoot          *types.Bytes32
	lastTransactionID types.TransactionID
}

// New creates an instance of a Fossilizer.
func New(config *Config, batchConfig *batchfossilizer.Config) (*Fossilizer, error) {
	if batchConfig.MaxSimBatches > 1 {
		return nil, fmt.Errorf("MaxSimBatches is %d want less than 2", batchConfig.MaxSimBatches)
	}

	b, err := batchfossilizer.New(batchConfig)
	if err != nil {
		return nil, err
	}

	f := Fossilizer{
		Fossilizer: b,
		config:     config,
	}

	f.SetTransformer(f.transform)

	return &f, err
}

// GetInfo implements github.com/stratumn/sdk/fossilizer.Adapter.GetInfo.
func (a *Fossilizer) GetInfo() (interface{}, error) {
	batchInfo, err := a.Fossilizer.GetInfo()
	if err != nil {
		return nil, err
	}

	info, ok := batchInfo.(*batchfossilizer.Info)
	if !ok {
		return nil, fmt.Errorf("unexpected batchfossilizer info %#v", batchInfo)
	}

	return &Info{
		Name:        Name,
		Description: Description,
		Version:     info.Version,
		Commit:      info.Commit,
		Blockchain:  a.config.HashTimestamper.Network().String(),
	}, nil
}

func (a *Fossilizer) transform(evidence *cs.Evidence, data, meta []byte) (*fossilizer.Result, error) {
	var (
		root = evidence.Proof.(*evidences.BatchProof).Root
		txid types.TransactionID
		err  error
	)

	if a.lastRoot == nil || *root != *a.lastRoot {
		txid, err = a.config.HashTimestamper.TimestampHash(root)
		if err != nil {
			return nil, err
		}
		log.WithFields(log.Fields{
			"txid": txid,
			"root": root,
		}).Info("Broadcasted transaction")

		a.lastRoot = root
		a.lastTransactionID = txid
	}

	evidence.Provider = a.config.HashTimestamper.Network().String()
	evidence.Backend = Name
	evidence.Proof = &evidences.BcBatchProof{
		Batch:         *evidence.Proof.(*evidences.BatchProof),
		TransactionID: a.lastTransactionID,
	}

	r := fossilizer.Result{
		Evidence: *evidence,
		Data:     data,
		Meta:     meta,
	}

	return &r, nil
}
<|endoftext|>


<commit_before>// Package genetics holds data holders and helper utilities used to implement genetic evolution algorithm
package genetics

// The innovation method type to be applied
type innovationType byte
// Available innovation types
const (
	// The novelty will be introduced by new NN node
	newNodeInnType innovationType = iota + 1
	// The novelty will be introduced by new NN link
	newLinkInnType
)

// The mutator type that specifies a kind of mutation of connection weights between NN nodes
type mutatorType byte
// Available mutator types
const (
	//This adds Gaussian noise to the weights
	gaussianMutator mutatorType = iota + 1
	//This sets weights to numbers chosen from a Gaussian distribution
	goldGaussianMutator
)

<commit_msg>Added genome encoding types definitions and common errors during to raise during genome reading<commit_after>// Package genetics holds data holders and helper utilities used to implement genetic evolution algorithm
package genetics

import "errors"

// The innovation method type to be applied
type innovationType byte
// Available innovation types
const (
	// The novelty will be introduced by new NN node
	newNodeInnType innovationType = iota + 1
	// The novelty will be introduced by new NN link
	newLinkInnType
)

// The mutator type that specifies a kind of mutation of connection weights between NN nodes
type mutatorType byte
// Available mutator types
const (
	//This adds Gaussian noise to the weights
	gaussianMutator mutatorType = iota + 1
	//This sets weights to numbers chosen from a Gaussian distribution
	goldGaussianMutator
)

// Defines format of Genome data encoding
type GenomeEncoding byte

const (
	// The plain text
	PlainGenomeEncoding GenomeEncoding = iota + 1
	// The rich text in YAML
	YAMLGenomeEncoding
)

var (
	ErrUnsupportedGenomeEncoding = errors.New("unsupported genome encoding")
)

<|endoftext|>


<commit_before>package daemon

import (
	"sort"
)

// History is a convenience type for storing a list of containers,
// ordered by creation date.
type History []*Container

func (history *History) Len() int {
	return len(*history)
}

func (history *History) Less(i, j int) bool {
	containers := *history
	return containers[j].Created.Before(containers[i].Created)
}

func (history *History) Swap(i, j int) {
	containers := *history
	tmp := containers[i]
	containers[i] = containers[j]
	containers[j] = tmp
}

func (history *History) Add(container *Container) {
	*history = append(*history, container)
}

func (history *History) Sort() {
	sort.Sort(history)
}
<commit_msg>History.Swap Use parallel assignment to swap elements, as it's<commit_after>package daemon

import (
	"sort"
)

// History is a convenience type for storing a list of containers,
// ordered by creation date.
type History []*Container

func (history *History) Len() int {
	return len(*history)
}

func (history *History) Less(i, j int) bool {
	containers := *history
	return containers[j].Created.Before(containers[i].Created)
}

func (history *History) Swap(i, j int) {
	containers := *history
	containers[i], containers[j] = containers[j], containers[i]
}

func (history *History) Add(container *Container) {
	*history = append(*history, container)
}

func (history *History) Sort() {
	sort.Sort(history)
}
<|endoftext|>


<commit_before><commit_msg>Fix mispelled words - thanks to ubogdan (https://github.com/ubogdan).<commit_after><|endoftext|>