<commit_before>// Copyright 2018 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.

// This file implements the knownFormats map which records the valid
// formats for a given type. The valid formats must correspond to
// supported compiler formats implemented in fmt.go, or whatever
// other format verbs are implemented for the given type. The map may
// also be used to change the use of a format verb across all compiler
// sources automatically (for instance, if the implementation of fmt.go
// changes), by using the -r option together with the new formats in the
// map. To generate this file automatically from the existing source,
// run: go test -run Formats -u.
//
// See the package comment in fmt_test.go for additional information.

package main_test

// knownFormats entries are of the form "typename format" -> "newformat".
// An absent entry means that the format is not recognized as valid.
// An empty new format means that the format should remain unchanged.
var knownFormats = map[string]string{
	"*bytes.Buffer %s":                                "",
	"*cmd/compile/internal/gc.Mpflt %v":               "",
	"*cmd/compile/internal/gc.Mpint %v":               "",
	"*cmd/compile/internal/gc.Node %#v":               "",
	"*cmd/compile/internal/gc.Node %+S":               "",
	"*cmd/compile/internal/gc.Node %+v":               "",
	"*cmd/compile/internal/gc.Node %0j":               "",
	"*cmd/compile/internal/gc.Node %L":                "",
	"*cmd/compile/internal/gc.Node %S":                "",
	"*cmd/compile/internal/gc.Node %j":                "",
	"*cmd/compile/internal/gc.Node %p":                "",
	"*cmd/compile/internal/gc.Node %v":                "",
	"*cmd/compile/internal/ssa.Block %s":              "",
	"*cmd/compile/internal/ssa.Block %v":              "",
	"*cmd/compile/internal/ssa.Func %s":               "",
	"*cmd/compile/internal/ssa.Func %v":               "",
	"*cmd/compile/internal/ssa.Register %s":           "",
	"*cmd/compile/internal/ssa.Register %v":           "",
	"*cmd/compile/internal/ssa.SparseTreeNode %v":     "",
	"*cmd/compile/internal/ssa.Value %s":              "",
	"*cmd/compile/internal/ssa.Value %v":              "",
	"*cmd/compile/internal/ssa.sparseTreeMapEntry %v": "",
	"*cmd/compile/internal/types.Field %p":            "",
	"*cmd/compile/internal/types.Field %v":            "",
	"*cmd/compile/internal/types.Sym %0S":             "",
	"*cmd/compile/internal/types.Sym %S":              "",
	"*cmd/compile/internal/types.Sym %p":              "",
	"*cmd/compile/internal/types.Sym %v":              "",
	"*cmd/compile/internal/types.Type %#L":            "",
	"*cmd/compile/internal/types.Type %#v":            "",
	"*cmd/compile/internal/types.Type %+v":            "",
	"*cmd/compile/internal/types.Type %-S":            "",
	"*cmd/compile/internal/types.Type %0S":            "",
	"*cmd/compile/internal/types.Type %L":             "",
	"*cmd/compile/internal/types.Type %S":             "",
	"*cmd/compile/internal/types.Type %p":             "",
	"*cmd/compile/internal/types.Type %s":             "",
	"*cmd/compile/internal/types.Type %v":             "",
	"*cmd/internal/obj.Addr %v":                       "",
	"*cmd/internal/obj.LSym %v":                       "",
	"*math/big.Float %f":                              "",
	"*math/big.Int %#x":                               "",
	"*math/big.Int %s":                                "",
	"*math/big.Int %v":                                "",
	"[16]byte %x":                                     "",
	"[]*cmd/compile/internal/ssa.Block %v":            "",
	"[]*cmd/compile/internal/ssa.Value %v":            "",
	"[][]string %q":                                   "",
	"[]byte %s":                                       "",
	"[]byte %x":                                       "",
	"[]cmd/compile/internal/ssa.Edge %v":              "",
	"[]cmd/compile/internal/ssa.ID %v":                "",
	"[]cmd/compile/internal/ssa.posetNode %v":         "",
	"[]cmd/compile/internal/ssa.posetUndo %v":         "",
	"[]cmd/compile/internal/syntax.token %s":          "",
	"[]string %v":                                     "",
	"[]uint32 %v":                                     "",
	"bool %v":                                         "",
	"byte %08b":                                       "",
	"byte %c":                                         "",
	"byte %q":                                         "",
	"byte %v":                                         "",
	"cmd/compile/internal/arm.shift %d":               "",
	"cmd/compile/internal/gc.Class %d":                "",
	"cmd/compile/internal/gc.Class %s":                "",
	"cmd/compile/internal/gc.Class %v":                "",
	"cmd/compile/internal/gc.Ctype %d":                "",
	"cmd/compile/internal/gc.Ctype %v":                "",
	"cmd/compile/internal/gc.Level %d":                "",
	"cmd/compile/internal/gc.Level %v":                "",
	"cmd/compile/internal/gc.Nodes %#v":               "",
	"cmd/compile/internal/gc.Nodes %+v":               "",
	"cmd/compile/internal/gc.Nodes %.v":               "",
	"cmd/compile/internal/gc.Nodes %v":                "",
	"cmd/compile/internal/gc.Op %#v":                  "",
	"cmd/compile/internal/gc.Op %v":                   "",
	"cmd/compile/internal/gc.Val %#v":                 "",
	"cmd/compile/internal/gc.Val %T":                  "",
	"cmd/compile/internal/gc.Val %v":                  "",
	"cmd/compile/internal/gc.fmtMode %d":              "",
	"cmd/compile/internal/gc.initKind %d":             "",
	"cmd/compile/internal/gc.itag %v":                 "",
	"cmd/compile/internal/ssa.BranchPrediction %d":    "",
	"cmd/compile/internal/ssa.Edge %v":                "",
	"cmd/compile/internal/ssa.GCNode %v":              "",
	"cmd/compile/internal/ssa.ID %d":                  "",
	"cmd/compile/internal/ssa.ID %v":                  "",
	"cmd/compile/internal/ssa.LocPair %s":             "",
	"cmd/compile/internal/ssa.LocalSlot %s":           "",
	"cmd/compile/internal/ssa.LocalSlot %v":           "",
	"cmd/compile/internal/ssa.Location %T":            "",
	"cmd/compile/internal/ssa.Location %s":            "",
	"cmd/compile/internal/ssa.Op %s":                  "",
	"cmd/compile/internal/ssa.Op %v":                  "",
	"cmd/compile/internal/ssa.ValAndOff %s":           "",
	"cmd/compile/internal/ssa.domain %v":              "",
	"cmd/compile/internal/ssa.posetNode %v":           "",
	"cmd/compile/internal/ssa.posetTestOp %v":         "",
	"cmd/compile/internal/ssa.rbrank %d":              "",
	"cmd/compile/internal/ssa.regMask %d":             "",
	"cmd/compile/internal/ssa.register %d":            "",
	"cmd/compile/internal/ssa.relation %s":            "",
	"cmd/compile/internal/syntax.Error %q":            "",
	"cmd/compile/internal/syntax.Expr %#v":            "",
	"cmd/compile/internal/syntax.LitKind %d":          "",
	"cmd/compile/internal/syntax.Node %T":             "",
	"cmd/compile/internal/syntax.Operator %s":         "",
	"cmd/compile/internal/syntax.Pos %s":              "",
	"cmd/compile/internal/syntax.Pos %v":              "",
	"cmd/compile/internal/syntax.position %s":         "",
	"cmd/compile/internal/syntax.token %q":            "",
	"cmd/compile/internal/syntax.token %s":            "",
	"cmd/compile/internal/types.EType %d":             "",
	"cmd/compile/internal/types.EType %s":             "",
	"cmd/compile/internal/types.EType %v":             "",
	"cmd/internal/obj.ABI %v":                         "",
	"error %v":                                        "",
	"float64 %.2f":                                    "",
	"float64 %.3f":                                    "",
	"float64 %.6g":                                    "",
	"float64 %g":                                      "",
	"int %-12d":                                       "",
	"int %-6d":                                        "",
	"int %-8o":                                        "",
	"int %02d":                                        "",
	"int %6d":                                         "",
	"int %c":                                          "",
	"int %d":                                          "",
	"int %v":                                          "",
	"int %x":                                          "",
	"int16 %d":                                        "",
	"int16 %x":                                        "",
	"int32 %d":                                        "",
	"int32 %v":                                        "",
	"int32 %x":                                        "",
	"int64 %+d":                                       "",
	"int64 %-10d":                                     "",
	"int64 %.5d":                                      "",
	"int64 %X":                                        "",
	"int64 %d":                                        "",
	"int64 %v":                                        "",
	"int64 %x":                                        "",
	"int8 %d":                                         "",
	"int8 %x":                                         "",
	"interface{} %#v":                                 "",
	"interface{} %T":                                  "",
	"interface{} %p":                                  "",
	"interface{} %q":                                  "",
	"interface{} %s":                                  "",
	"interface{} %v":                                  "",
	"map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %v": "",
	"map[*cmd/compile/internal/gc.Node][]*cmd/compile/internal/gc.Node %v": "",
	"map[cmd/compile/internal/ssa.ID]uint32 %v":                            "",
	"math/big.Accuracy %s": "",
	"reflect.Type %s":      "",
	"rune %#U":             "",
	"rune %c":              "",
	"rune %q":              "",
	"string %-*s":          "",
	"string %-16s":         "",
	"string %-6s":          "",
	"string %.*s":          "",
	"string %q":            "",
	"string %s":            "",
	"string %v":            "",
	"time.Duration %d":     "",
	"time.Duration %v":     "",
	"uint %04x":            "",
	"uint %5d":             "",
	"uint %d":              "",
	"uint %x":              "",
	"uint16 %d":            "",
	"uint16 %v":            "",
	"uint16 %x":            "",
	"uint32 %#x":           "",
	"uint32 %d":            "",
	"uint32 %v":            "",
	"uint32 %x":            "",
	"uint64 %08x":          "",
	"uint64 %d":            "",
	"uint64 %x":            "",
	"uint8 %d":             "",
	"uint8 %v":             "",
	"uint8 %x":             "",
	"uintptr %d":           "",
}
<commit_msg>cmd/compile: update fmt_test.go for esc.go code cleanup<commit_after>// Copyright 2018 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.

// This file implements the knownFormats map which records the valid
// formats for a given type. The valid formats must correspond to
// supported compiler formats implemented in fmt.go, or whatever
// other format verbs are implemented for the given type. The map may
// also be used to change the use of a format verb across all compiler
// sources automatically (for instance, if the implementation of fmt.go
// changes), by using the -r option together with the new formats in the
// map. To generate this file automatically from the existing source,
// run: go test -run Formats -u.
//
// See the package comment in fmt_test.go for additional information.

package main_test

// knownFormats entries are of the form "typename format" -> "newformat".
// An absent entry means that the format is not recognized as valid.
// An empty new format means that the format should remain unchanged.
var knownFormats = map[string]string{
	"*bytes.Buffer %s":                                "",
	"*cmd/compile/internal/gc.Mpflt %v":               "",
	"*cmd/compile/internal/gc.Mpint %v":               "",
	"*cmd/compile/internal/gc.Node %#v":               "",
	"*cmd/compile/internal/gc.Node %+S":               "",
	"*cmd/compile/internal/gc.Node %+v":               "",
	"*cmd/compile/internal/gc.Node %L":                "",
	"*cmd/compile/internal/gc.Node %S":                "",
	"*cmd/compile/internal/gc.Node %j":                "",
	"*cmd/compile/internal/gc.Node %p":                "",
	"*cmd/compile/internal/gc.Node %v":                "",
	"*cmd/compile/internal/ssa.Block %s":              "",
	"*cmd/compile/internal/ssa.Block %v":              "",
	"*cmd/compile/internal/ssa.Func %s":               "",
	"*cmd/compile/internal/ssa.Func %v":               "",
	"*cmd/compile/internal/ssa.Register %s":           "",
	"*cmd/compile/internal/ssa.Register %v":           "",
	"*cmd/compile/internal/ssa.SparseTreeNode %v":     "",
	"*cmd/compile/internal/ssa.Value %s":              "",
	"*cmd/compile/internal/ssa.Value %v":              "",
	"*cmd/compile/internal/ssa.sparseTreeMapEntry %v": "",
	"*cmd/compile/internal/types.Field %p":            "",
	"*cmd/compile/internal/types.Field %v":            "",
	"*cmd/compile/internal/types.Sym %0S":             "",
	"*cmd/compile/internal/types.Sym %S":              "",
	"*cmd/compile/internal/types.Sym %p":              "",
	"*cmd/compile/internal/types.Sym %v":              "",
	"*cmd/compile/internal/types.Type %#L":            "",
	"*cmd/compile/internal/types.Type %#v":            "",
	"*cmd/compile/internal/types.Type %+v":            "",
	"*cmd/compile/internal/types.Type %-S":            "",
	"*cmd/compile/internal/types.Type %0S":            "",
	"*cmd/compile/internal/types.Type %L":             "",
	"*cmd/compile/internal/types.Type %S":             "",
	"*cmd/compile/internal/types.Type %p":             "",
	"*cmd/compile/internal/types.Type %s":             "",
	"*cmd/compile/internal/types.Type %v":             "",
	"*cmd/internal/obj.Addr %v":                       "",
	"*cmd/internal/obj.LSym %v":                       "",
	"*math/big.Float %f":                              "",
	"*math/big.Int %#x":                               "",
	"*math/big.Int %s":                                "",
	"*math/big.Int %v":                                "",
	"[16]byte %x":                                     "",
	"[]*cmd/compile/internal/ssa.Block %v":            "",
	"[]*cmd/compile/internal/ssa.Value %v":            "",
	"[][]string %q":                                   "",
	"[]byte %s":                                       "",
	"[]byte %x":                                       "",
	"[]cmd/compile/internal/ssa.Edge %v":              "",
	"[]cmd/compile/internal/ssa.ID %v":                "",
	"[]cmd/compile/internal/ssa.posetNode %v":         "",
	"[]cmd/compile/internal/ssa.posetUndo %v":         "",
	"[]cmd/compile/internal/syntax.token %s":          "",
	"[]string %v":                                     "",
	"[]uint32 %v":                                     "",
	"bool %v":                                         "",
	"byte %08b":                                       "",
	"byte %c":                                         "",
	"byte %q":                                         "",
	"byte %v":                                         "",
	"cmd/compile/internal/arm.shift %d":               "",
	"cmd/compile/internal/gc.Class %d":                "",
	"cmd/compile/internal/gc.Class %s":                "",
	"cmd/compile/internal/gc.Class %v":                "",
	"cmd/compile/internal/gc.Ctype %d":                "",
	"cmd/compile/internal/gc.Ctype %v":                "",
	"cmd/compile/internal/gc.Nodes %#v":               "",
	"cmd/compile/internal/gc.Nodes %+v":               "",
	"cmd/compile/internal/gc.Nodes %.v":               "",
	"cmd/compile/internal/gc.Nodes %v":                "",
	"cmd/compile/internal/gc.Op %#v":                  "",
	"cmd/compile/internal/gc.Op %v":                   "",
	"cmd/compile/internal/gc.Val %#v":                 "",
	"cmd/compile/internal/gc.Val %T":                  "",
	"cmd/compile/internal/gc.Val %v":                  "",
	"cmd/compile/internal/gc.fmtMode %d":              "",
	"cmd/compile/internal/gc.initKind %d":             "",
	"cmd/compile/internal/gc.itag %v":                 "",
	"cmd/compile/internal/ssa.BranchPrediction %d":    "",
	"cmd/compile/internal/ssa.Edge %v":                "",
	"cmd/compile/internal/ssa.GCNode %v":              "",
	"cmd/compile/internal/ssa.ID %d":                  "",
	"cmd/compile/internal/ssa.ID %v":                  "",
	"cmd/compile/internal/ssa.LocPair %s":             "",
	"cmd/compile/internal/ssa.LocalSlot %s":           "",
	"cmd/compile/internal/ssa.LocalSlot %v":           "",
	"cmd/compile/internal/ssa.Location %T":            "",
	"cmd/compile/internal/ssa.Location %s":            "",
	"cmd/compile/internal/ssa.Op %s":                  "",
	"cmd/compile/internal/ssa.Op %v":                  "",
	"cmd/compile/internal/ssa.ValAndOff %s":           "",
	"cmd/compile/internal/ssa.domain %v":              "",
	"cmd/compile/internal/ssa.posetNode %v":           "",
	"cmd/compile/internal/ssa.posetTestOp %v":         "",
	"cmd/compile/internal/ssa.rbrank %d":              "",
	"cmd/compile/internal/ssa.regMask %d":             "",
	"cmd/compile/internal/ssa.register %d":            "",
	"cmd/compile/internal/ssa.relation %s":            "",
	"cmd/compile/internal/syntax.Error %q":            "",
	"cmd/compile/internal/syntax.Expr %#v":            "",
	"cmd/compile/internal/syntax.LitKind %d":          "",
	"cmd/compile/internal/syntax.Node %T":             "",
	"cmd/compile/internal/syntax.Operator %s":         "",
	"cmd/compile/internal/syntax.Pos %s":              "",
	"cmd/compile/internal/syntax.Pos %v":              "",
	"cmd/compile/internal/syntax.position %s":         "",
	"cmd/compile/internal/syntax.token %q":            "",
	"cmd/compile/internal/syntax.token %s":            "",
	"cmd/compile/internal/types.EType %d":             "",
	"cmd/compile/internal/types.EType %s":             "",
	"cmd/compile/internal/types.EType %v":             "",
	"cmd/internal/obj.ABI %v":                         "",
	"error %v":                                        "",
	"float64 %.2f":                                    "",
	"float64 %.3f":                                    "",
	"float64 %.6g":                                    "",
	"float64 %g":                                      "",
	"int %-12d":                                       "",
	"int %-6d":                                        "",
	"int %-8o":                                        "",
	"int %02d":                                        "",
	"int %6d":                                         "",
	"int %c":                                          "",
	"int %d":                                          "",
	"int %v":                                          "",
	"int %x":                                          "",
	"int16 %d":                                        "",
	"int16 %x":                                        "",
	"int32 %d":                                        "",
	"int32 %v":                                        "",
	"int32 %x":                                        "",
	"int64 %+d":                                       "",
	"int64 %-10d":                                     "",
	"int64 %.5d":                                      "",
	"int64 %X":                                        "",
	"int64 %d":                                        "",
	"int64 %v":                                        "",
	"int64 %x":                                        "",
	"int8 %d":                                         "",
	"int8 %x":                                         "",
	"interface{} %#v":                                 "",
	"interface{} %T":                                  "",
	"interface{} %p":                                  "",
	"interface{} %q":                                  "",
	"interface{} %s":                                  "",
	"interface{} %v":                                  "",
	"map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %v": "",
	"map[*cmd/compile/internal/gc.Node][]*cmd/compile/internal/gc.Node %v": "",
	"map[cmd/compile/internal/ssa.ID]uint32 %v":                            "",
	"math/big.Accuracy %s": "",
	"reflect.Type %s":      "",
	"rune %#U":             "",
	"rune %c":              "",
	"rune %q":              "",
	"string %-*s":          "",
	"string %-16s":         "",
	"string %-6s":          "",
	"string %q":            "",
	"string %s":            "",
	"string %v":            "",
	"time.Duration %d":     "",
	"time.Duration %v":     "",
	"uint %04x":            "",
	"uint %5d":             "",
	"uint %d":              "",
	"uint %x":              "",
	"uint16 %d":            "",
	"uint16 %x":            "",
	"uint32 %#x":           "",
	"uint32 %d":            "",
	"uint32 %v":            "",
	"uint32 %x":            "",
	"uint64 %08x":          "",
	"uint64 %d":            "",
	"uint64 %x":            "",
	"uint8 %d":             "",
	"uint8 %v":             "",
	"uint8 %x":             "",
	"uintptr %d":           "",
}
<|endoftext|>


<commit_before>package coordinator

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/goraft/raft"
	"github.com/gorilla/mux"
	"io/ioutil"
	"log"
	"math/rand"
	"net"
	"net/http"
	"path/filepath"
	"sync"
	"time"
)

// The raftd server is a combination of the Raft server and an HTTP
// server which acts as the transport.
type RaftServer struct {
	name                        string
	host                        string
	port                        int
	path                        string
	router                      *mux.Router
	raftServer                  *raft.Server
	httpServer                  *http.Server
	clusterConfig               *ClusterConfiguration
	mutex                       sync.RWMutex
	listener                    net.Listener
	nameToConnectionStrings     map[string]string
	nameToConnectionStringsLock sync.RWMutex
}

var registeredCommands bool

// Creates a new server.
func NewRaftServer(path string, host string, port int, clusterConfig *ClusterConfiguration) *RaftServer {
	if !registeredCommands {
		//		raft.SetLogLevel(raft.Trace)
		registeredCommands = true
		raft.RegisterCommand(&AddApiKeyCommand{})
		raft.RegisterCommand(&RemoveApiKeyCommand{})
		raft.RegisterCommand(&AddServerToLocationCommand{})
		raft.RegisterCommand(&RemoveServerFromLocationCommand{})
	}
	s := &RaftServer{
		host:                    host,
		port:                    port,
		path:                    path,
		clusterConfig:           clusterConfig,
		router:                  mux.NewRouter(),
		nameToConnectionStrings: make(map[string]string),
	}

	// Read existing name or generate a new one.
	if b, err := ioutil.ReadFile(filepath.Join(path, "name")); err == nil {
		s.name = string(b)
	} else {
		s.name = fmt.Sprintf("%07x", rand.Int())[0:7]
		if err = ioutil.WriteFile(filepath.Join(path, "name"), []byte(s.name), 0644); err != nil {
			panic(err)
		}
	}

	return s
}

func (s *RaftServer) leaderConnectString() (string, bool) {
	leader := s.raftServer.Leader()
	peers := s.raftServer.Peers()
	if peer, ok := peers[leader]; !ok {
		return "", false
	} else {
		return peer.ConnectionString, true
	}
	// s.nameToConnectionStringsLock.RLock()
	// defer s.nameToConnectionStringsLock.RUnlock()
	// l, ok := s.nameToConnectionStrings[leader]
	// return l, ok
}

func (s *RaftServer) doOrProxyCommand(command raft.Command, commandType string) error {
	if s.raftServer.State() == raft.Leader {
		_, err := s.raftServer.Do(command)
		return err
	} else {
		if leader, ok := s.leaderConnectString(); !ok {
			return errors.New("Couldn't connect to the cluster leader...")
		} else {
			var b bytes.Buffer
			json.NewEncoder(&b).Encode(command)
			resp, err := http.Post(leader+"/process_command/"+commandType, "application/json", &b)
			if err != nil {
				return err
			}
			resp.Body.Close()
		}
	}
	return nil
}

func (s *RaftServer) AddReadApiKey(db, key string) error {
	command := NewAddApikeyCommand(db, key, ReadKey)
	return s.doOrProxyCommand(command, "add_api_key")
}

func (s *RaftServer) AddWriteApiKey(db, key string) error {
	command := NewAddApikeyCommand(db, key, WriteKey)
	return s.doOrProxyCommand(command, "add_api_key")
}

func (s *RaftServer) RemoveApiKey(db, key string) error {
	command := NewRemoveApiKeyCommand(db, key)
	return s.doOrProxyCommand(command, "remove_api_key")
}

func (s *RaftServer) AddServerToLocation(host string, location int64) error {
	command := NewAddServerToLocationCommand(host, location)
	return s.doOrProxyCommand(command, "add_server")
}

func (s *RaftServer) RemoveServerFromLocation(host string, location int64) error {
	command := NewRemoveServerFromLocationCommand(host, location)
	return s.doOrProxyCommand(command, "remove_server")
}

func (s *RaftServer) connectionString() string {
	return fmt.Sprintf("http://%s:%d", s.host, s.port)
}

func (s *RaftServer) ListenAndServe(potentialLeaders []string, retryUntilJoin bool) error {
	var err error

	log.Printf("Initializing Raft Server: %s %d", s.path, s.port)

	// Initialize and start Raft server.
	transporter := raft.NewHTTPTransporter("/raft")
	s.raftServer, err = raft.NewServer(s.name, s.path, transporter, nil, s.clusterConfig, "")
	if err != nil {
		log.Fatal(err)
	}
	transporter.Install(s.raftServer, s)
	s.raftServer.Start()

	if s.raftServer.IsLogEmpty() {
		for {
			joined := false
			for _, leader := range potentialLeaders {
				log.Println("Attempting to join leader: ", leader, s.port)

				if err := s.Join(leader); err == nil {
					joined = true
					log.Println("Joined: ", leader)
					break
				}
			}
			// couldn't join a leader so we must be the first one up
			if joined {
				break
			} else if !joined && !retryUntilJoin {
				log.Println("Couldn't contact a leader so initializing new cluster for server on port: ", s.port)

				_, err := s.raftServer.Do(&raft.DefaultJoinCommand{
					Name:             s.raftServer.Name(),
					ConnectionString: s.connectionString(),
				})
				if err != nil {
					log.Fatal(err)
				}
				break
			} else {
				// sleep for a little bit and retry it
				log.Println("Couldn't join any of the seeds, sleeping and retrying...")
				time.Sleep(100 * time.Millisecond)
			}
		}
	} else {
		log.Println("Recovered from log")
	}

	log.Println("Initializing Raft HTTP server")

	l, err := net.Listen("tcp", fmt.Sprintf(":%d", s.port))
	if err != nil {
		return err
	}
	// Initialize and start HTTP server.
	s.httpServer = &http.Server{
		Handler: s.router,
	}

	s.router.HandleFunc("/cluster_config", s.configHandler).Methods("GET")
	s.router.HandleFunc("/join", s.joinHandler).Methods("POST")
	s.router.HandleFunc("/process_command/{command_type}", s.processCommandHandler).Methods("POST")

	log.Println("Listening at:", s.connectionString())

	s.listener = l
	return s.httpServer.Serve(l)
}

func (self *RaftServer) Close() {
	self.raftServer.Stop()
	self.listener.Close()
}

// This is a hack around Gorilla mux not providing the correct net/http
// HandleFunc() interface.
func (s *RaftServer) HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) {
	s.router.HandleFunc(pattern, handler)
}

// Joins to the leader of an existing cluster.
func (s *RaftServer) Join(leader string) error {
	command := &raft.DefaultJoinCommand{
		Name:             s.raftServer.Name(),
		ConnectionString: s.connectionString(),
	}

	var b bytes.Buffer
	json.NewEncoder(&b).Encode(command)
	resp, err := http.Post(fmt.Sprintf("http://%s/join", leader), "application/json", &b)
	if err != nil {
		return err
	}
	resp.Body.Close()

	return nil
}

func (s *RaftServer) joinHandler(w http.ResponseWriter, req *http.Request) {
	command := &raft.DefaultJoinCommand{}

	if err := json.NewDecoder(req.Body).Decode(&command); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	if _, err := s.raftServer.Do(command); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	} else {
		s.nameToConnectionStringsLock.Lock()
		defer s.nameToConnectionStringsLock.Unlock()
		log.Println("Adding: ", command.Name, command.ConnectionString)
		s.nameToConnectionStrings[command.Name] = command.ConnectionString
	}
}

func (s *RaftServer) configHandler(w http.ResponseWriter, req *http.Request) {
	jsonObject := make(map[string]interface{})
	readKeys := make([]string, 0)
	for k, _ := range s.clusterConfig.ReadApiKeys {
		readKeys = append(readKeys, k)
	}
	jsonObject["read_keys"] = readKeys
	writeKeys := make([]string, 0)
	for k, _ := range s.clusterConfig.WriteApiKeys {
		writeKeys = append(writeKeys, k)
	}
	jsonObject["write_keys"] = writeKeys
	locations := make([]map[string]interface{}, 0)
	for location, servers := range s.clusterConfig.RingLocationToServers {
		s := servers
		locations = append(locations, map[string]interface{}{"location": location, "servers": s})
	}
	jsonObject["locations"] = locations

	js, err := json.Marshal(jsonObject)
	if err != nil {
		log.Println("ERROR marshalling config: ", err)
	}
	w.Write(js)
}

func (s *RaftServer) marshalAndDoCommandFromBody(command raft.Command, req *http.Request) error {
	log.Println("marshalAndDoCommand")
	if err := json.NewDecoder(req.Body).Decode(&command); err != nil {
		return err
	}
	if _, err := s.raftServer.Do(command); err != nil {
		return err
	}
	return nil
}

func (s *RaftServer) processCommandHandler(w http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	value := vars["command_type"]
	var command raft.Command
	if value == "add_api_key" {
		command = &AddApiKeyCommand{}
	} else if value == "remove_api_key" {
		command = &RemoveApiKeyCommand{}
	} else if value == "add_server" {
		command = &AddServerToLocationCommand{}
	} else if value == "remove_server" {
		command = &RemoveServerFromLocationCommand{}
	}
	if err := s.marshalAndDoCommandFromBody(command, req); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}
<commit_msg>Remove some cruft around storing the connect string of the leader<commit_after>package coordinator

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/goraft/raft"
	"github.com/gorilla/mux"
	"io/ioutil"
	"log"
	"math/rand"
	"net"
	"net/http"
	"path/filepath"
	"sync"
	"time"
)

// The raftd server is a combination of the Raft server and an HTTP
// server which acts as the transport.
type RaftServer struct {
	name          string
	host          string
	port          int
	path          string
	router        *mux.Router
	raftServer    *raft.Server
	httpServer    *http.Server
	clusterConfig *ClusterConfiguration
	mutex         sync.RWMutex
	listener      net.Listener
}

var registeredCommands bool

// Creates a new server.
func NewRaftServer(path string, host string, port int, clusterConfig *ClusterConfiguration) *RaftServer {
	if !registeredCommands {
		//		raft.SetLogLevel(raft.Trace)
		registeredCommands = true
		raft.RegisterCommand(&AddApiKeyCommand{})
		raft.RegisterCommand(&RemoveApiKeyCommand{})
		raft.RegisterCommand(&AddServerToLocationCommand{})
		raft.RegisterCommand(&RemoveServerFromLocationCommand{})
	}
	s := &RaftServer{
		host:          host,
		port:          port,
		path:          path,
		clusterConfig: clusterConfig,
		router:        mux.NewRouter(),
	}

	// Read existing name or generate a new one.
	if b, err := ioutil.ReadFile(filepath.Join(path, "name")); err == nil {
		s.name = string(b)
	} else {
		s.name = fmt.Sprintf("%07x", rand.Int())[0:7]
		if err = ioutil.WriteFile(filepath.Join(path, "name"), []byte(s.name), 0644); err != nil {
			panic(err)
		}
	}

	return s
}

func (s *RaftServer) leaderConnectString() (string, bool) {
	leader := s.raftServer.Leader()
	peers := s.raftServer.Peers()
	if peer, ok := peers[leader]; !ok {
		return "", false
	} else {
		return peer.ConnectionString, true
	}
}

func (s *RaftServer) doOrProxyCommand(command raft.Command, commandType string) error {
	if s.raftServer.State() == raft.Leader {
		_, err := s.raftServer.Do(command)
		return err
	} else {
		if leader, ok := s.leaderConnectString(); !ok {
			return errors.New("Couldn't connect to the cluster leader...")
		} else {
			var b bytes.Buffer
			json.NewEncoder(&b).Encode(command)
			resp, err := http.Post(leader+"/process_command/"+commandType, "application/json", &b)
			if err != nil {
				return err
			}
			resp.Body.Close()
		}
	}
	return nil
}

func (s *RaftServer) AddReadApiKey(db, key string) error {
	command := NewAddApikeyCommand(db, key, ReadKey)
	return s.doOrProxyCommand(command, "add_api_key")
}

func (s *RaftServer) AddWriteApiKey(db, key string) error {
	command := NewAddApikeyCommand(db, key, WriteKey)
	return s.doOrProxyCommand(command, "add_api_key")
}

func (s *RaftServer) RemoveApiKey(db, key string) error {
	command := NewRemoveApiKeyCommand(db, key)
	return s.doOrProxyCommand(command, "remove_api_key")
}

func (s *RaftServer) AddServerToLocation(host string, location int64) error {
	command := NewAddServerToLocationCommand(host, location)
	return s.doOrProxyCommand(command, "add_server")
}

func (s *RaftServer) RemoveServerFromLocation(host string, location int64) error {
	command := NewRemoveServerFromLocationCommand(host, location)
	return s.doOrProxyCommand(command, "remove_server")
}

func (s *RaftServer) connectionString() string {
	return fmt.Sprintf("http://%s:%d", s.host, s.port)
}

func (s *RaftServer) ListenAndServe(potentialLeaders []string, retryUntilJoin bool) error {
	var err error

	log.Printf("Initializing Raft Server: %s %d", s.path, s.port)

	// Initialize and start Raft server.
	transporter := raft.NewHTTPTransporter("/raft")
	s.raftServer, err = raft.NewServer(s.name, s.path, transporter, nil, s.clusterConfig, "")
	if err != nil {
		log.Fatal(err)
	}
	transporter.Install(s.raftServer, s)
	s.raftServer.Start()

	if s.raftServer.IsLogEmpty() {
		for {
			joined := false
			for _, leader := range potentialLeaders {
				log.Println("Attempting to join leader: ", leader, s.port)

				if err := s.Join(leader); err == nil {
					joined = true
					log.Println("Joined: ", leader)
					break
				}
			}
			// couldn't join a leader so we must be the first one up
			if joined {
				break
			} else if !joined && !retryUntilJoin {
				log.Println("Couldn't contact a leader so initializing new cluster for server on port: ", s.port)

				_, err := s.raftServer.Do(&raft.DefaultJoinCommand{
					Name:             s.raftServer.Name(),
					ConnectionString: s.connectionString(),
				})
				if err != nil {
					log.Fatal(err)
				}
				break
			} else {
				// sleep for a little bit and retry it
				log.Println("Couldn't join any of the seeds, sleeping and retrying...")
				time.Sleep(100 * time.Millisecond)
			}
		}
	} else {
		log.Println("Recovered from log")
	}

	log.Println("Initializing Raft HTTP server")

	l, err := net.Listen("tcp", fmt.Sprintf(":%d", s.port))
	if err != nil {
		return err
	}
	// Initialize and start HTTP server.
	s.httpServer = &http.Server{
		Handler: s.router,
	}

	s.router.HandleFunc("/cluster_config", s.configHandler).Methods("GET")
	s.router.HandleFunc("/join", s.joinHandler).Methods("POST")
	s.router.HandleFunc("/process_command/{command_type}", s.processCommandHandler).Methods("POST")

	log.Println("Listening at:", s.connectionString())

	s.listener = l
	return s.httpServer.Serve(l)
}

func (self *RaftServer) Close() {
	self.raftServer.Stop()
	self.listener.Close()
}

// This is a hack around Gorilla mux not providing the correct net/http
// HandleFunc() interface.
func (s *RaftServer) HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) {
	s.router.HandleFunc(pattern, handler)
}

// Joins to the leader of an existing cluster.
func (s *RaftServer) Join(leader string) error {
	command := &raft.DefaultJoinCommand{
		Name:             s.raftServer.Name(),
		ConnectionString: s.connectionString(),
	}

	var b bytes.Buffer
	json.NewEncoder(&b).Encode(command)
	resp, err := http.Post(fmt.Sprintf("http://%s/join", leader), "application/json", &b)
	if err != nil {
		return err
	}
	resp.Body.Close()

	return nil
}

func (s *RaftServer) joinHandler(w http.ResponseWriter, req *http.Request) {
	command := &raft.DefaultJoinCommand{}

	if err := json.NewDecoder(req.Body).Decode(&command); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	if _, err := s.raftServer.Do(command); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func (s *RaftServer) configHandler(w http.ResponseWriter, req *http.Request) {
	jsonObject := make(map[string]interface{})
	readKeys := make([]string, 0)
	for k, _ := range s.clusterConfig.ReadApiKeys {
		readKeys = append(readKeys, k)
	}
	jsonObject["read_keys"] = readKeys
	writeKeys := make([]string, 0)
	for k, _ := range s.clusterConfig.WriteApiKeys {
		writeKeys = append(writeKeys, k)
	}
	jsonObject["write_keys"] = writeKeys
	locations := make([]map[string]interface{}, 0)
	for location, servers := range s.clusterConfig.RingLocationToServers {
		s := servers
		locations = append(locations, map[string]interface{}{"location": location, "servers": s})
	}
	jsonObject["locations"] = locations

	js, err := json.Marshal(jsonObject)
	if err != nil {
		log.Println("ERROR marshalling config: ", err)
	}
	w.Write(js)
}

func (s *RaftServer) marshalAndDoCommandFromBody(command raft.Command, req *http.Request) error {
	log.Println("marshalAndDoCommand")
	if err := json.NewDecoder(req.Body).Decode(&command); err != nil {
		return err
	}
	if _, err := s.raftServer.Do(command); err != nil {
		return err
	}
	return nil
}

func (s *RaftServer) processCommandHandler(w http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	value := vars["command_type"]
	var command raft.Command
	if value == "add_api_key" {
		command = &AddApiKeyCommand{}
	} else if value == "remove_api_key" {
		command = &RemoveApiKeyCommand{}
	} else if value == "add_server" {
		command = &AddServerToLocationCommand{}
	} else if value == "remove_server" {
		command = &RemoveServerFromLocationCommand{}
	}
	if err := s.marshalAndDoCommandFromBody(command, req); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}
<|endoftext|>


<commit_before>package backend

import (
	"fmt"
	"io"
	"runtime"
	"sync"

	"github.com/fsouza/go-dockerclient"
	"golang.org/x/net/context"
)

type DockerProvider struct {
	client *docker.Client

	cpuSetsMutex sync.Mutex
	cpuSets      []bool
}

type DockerInstance struct {
	client    *docker.Client
	container *docker.Container
}

func NewDockerProvider(endpoint string) (*DockerProvider, error) {
	client, err := docker.NewClient(endpoint)
	if err != nil {
		return nil, err
	}

	return &DockerProvider{
		client:  client,
		cpuSets: make([]bool, runtime.NumCPU()),
	}, nil
}

func (p *DockerProvider) Start(ctx context.Context) (Instance, error) {
	cpuSets, err := p.checkoutCPUSets()
	if err != nil {
		return nil, err
	}

	createOptions := docker.CreateContainerOptions{
		Config: &docker.Config{
			Cmd:      []string{"/sbin/init"},
			Image:    "travis:ruby",
			Memory:   1024 * 1024 * 1024 * 4,
			CPUSet:   cpuSets,
			Hostname: "",
		},
	}

	container, err := p.client.CreateContainer(createOptions)
	if err != nil {
		if container != nil {
			err := p.client.RemoveContainer(docker.RemoveContainerOptions{
				ID:            container.ID,
				RemoveVolumes: true,
				Force:         true,
			})
			if err != nil {
				// TODO: logrusify
				fmt.Printf("error: couldn't remove container after create failure: %v\n", err)
			}
		}

		return nil, err
	}

	err = p.client.StartContainer(container.ID, &docker.HostConfig{})
	if err != nil {
		return nil, err
	}

	return &DockerInstance{
		client:    p.client,
		container: container,
	}, nil
}

func (p *DockerProvider) checkoutCPUSets() (string, error) {
	p.cpuSetsMutex.Lock()
	defer p.cpuSetsMutex.Unlock()

	cpuSets := []int{}

	for i, checkedOut := range p.cpuSets {
		if len(cpuSets) > 2 {
			break
		}
		if !checkedOut {
			cpuSets = append(cpuSets, i)
		}
	}

	if len(cpuSets) != 2 {
		return "", fmt.Errorf("not enough free CPUsets")
	}

	return fmt.Sprintf("%d,%d", cpuSets[0], cpuSets[1]), nil
}

func (p *DockerProvider) checkinCPUSets(sets string) {
	p.cpuSetsMutex.Lock()
	defer p.cpuSetsMutex.Unlock()

	var cpu1, cpu2 int
	fmt.Sscanf(sets, "%d,%d", &cpu1, &cpu2)

	p.cpuSets[cpu1] = false
	p.cpuSets[cpu2] = false
}

func (i *DockerInstance) UploadScript(ctx context.Context, script []byte) error {
	return nil
}

func (i *DockerInstance) RunScript(ctx context.Context, output io.WriteCloser) (RunResult, error) {
	return RunResult{}, nil
}

func (i *DockerInstance) Stop(ctx context.Context) error {
	err := i.client.StopContainer(i.container.ID, 30)
	if err != nil {
		err2 := i.client.RemoveContainer(docker.RemoveContainerOptions{
			ID:            i.container.ID,
			RemoveVolumes: true,
			Force:         true,
		})

		if err2 != nil {
			// TODO: logrusify
			fmt.Printf("error: couldn't remove container after stop failure: %v\n", err2)
		}

		return err
	}

	return nil
}
<commit_msg>docker: fetch image ID instead of using the tag<commit_after>package backend

import (
	"fmt"
	"io"
	"runtime"
	"sync"

	"github.com/fsouza/go-dockerclient"
	"golang.org/x/net/context"
)

type DockerProvider struct {
	client *docker.Client

	cpuSetsMutex sync.Mutex
	cpuSets      []bool
}

type DockerInstance struct {
	client    *docker.Client
	container *docker.Container
}

func NewDockerProvider(endpoint string) (*DockerProvider, error) {
	client, err := docker.NewClient(endpoint)
	if err != nil {
		return nil, err
	}

	return &DockerProvider{
		client:  client,
		cpuSets: make([]bool, runtime.NumCPU()),
	}, nil
}

func (p *DockerProvider) Start(ctx context.Context) (Instance, error) {
	cpuSets, err := p.checkoutCPUSets()
	if err != nil {
		return nil, err
	}

	imageID, err := p.imageForLanguage("ruby")
	if err != nil {
		return nil, err
	}

	createOptions := docker.CreateContainerOptions{
		Config: &docker.Config{
			Cmd:      []string{"/sbin/init"},
			Image:    imageID,
			Memory:   1024 * 1024 * 1024 * 4,
			CPUSet:   cpuSets,
			Hostname: "",
		},
	}

	container, err := p.client.CreateContainer(createOptions)
	if err != nil {
		if container != nil {
			err := p.client.RemoveContainer(docker.RemoveContainerOptions{
				ID:            container.ID,
				RemoveVolumes: true,
				Force:         true,
			})
			if err != nil {
				// TODO: logrusify
				fmt.Printf("error: couldn't remove container after create failure: %v\n", err)
			}
		}

		return nil, err
	}

	err = p.client.StartContainer(container.ID, &docker.HostConfig{})
	if err != nil {
		return nil, err
	}

	return &DockerInstance{
		client:    p.client,
		container: container,
	}, nil
}

func (p *DockerProvider) imageForLanguage(language string) (string, error) {
	searchTag := "travis:" + language

	images, err := p.client.ListImages(docker.ListImagesOptions{All: true})
	if err != nil {
		return "", err
	}

	for _, image := range images {
		for _, tag := range image.RepoTags {
			if tag == searchTag {
				return image.ID, nil
			}
		}
	}

	return "", fmt.Errorf("no image found with language %s", language)
}

func (p *DockerProvider) checkoutCPUSets() (string, error) {
	p.cpuSetsMutex.Lock()
	defer p.cpuSetsMutex.Unlock()

	cpuSets := []int{}

	for i, checkedOut := range p.cpuSets {
		if len(cpuSets) > 2 {
			break
		}
		if !checkedOut {
			cpuSets = append(cpuSets, i)
		}
	}

	if len(cpuSets) != 2 {
		return "", fmt.Errorf("not enough free CPUsets")
	}

	return fmt.Sprintf("%d,%d", cpuSets[0], cpuSets[1]), nil
}

func (p *DockerProvider) checkinCPUSets(sets string) {
	p.cpuSetsMutex.Lock()
	defer p.cpuSetsMutex.Unlock()

	var cpu1, cpu2 int
	fmt.Sscanf(sets, "%d,%d", &cpu1, &cpu2)

	p.cpuSets[cpu1] = false
	p.cpuSets[cpu2] = false
}

func (i *DockerInstance) UploadScript(ctx context.Context, script []byte) error {
	return nil
}

func (i *DockerInstance) RunScript(ctx context.Context, output io.WriteCloser) (RunResult, error) {
	return RunResult{}, nil
}

func (i *DockerInstance) Stop(ctx context.Context) error {
	err := i.client.StopContainer(i.container.ID, 30)
	if err != nil {
		err2 := i.client.RemoveContainer(docker.RemoveContainerOptions{
			ID:            i.container.ID,
			RemoveVolumes: true,
			Force:         true,
		})

		if err2 != nil {
			// TODO: logrusify
			fmt.Printf("error: couldn't remove container after stop failure: %v\n", err2)
		}

		return err
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2015 CloudAwan LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package appservice

import (
	"github.com/astaxie/beego"
	"github.com/cloudawan/cloudone_gui/controllers/identity"
	"github.com/cloudawan/cloudone_gui/controllers/utility/configuration"
	"github.com/cloudawan/cloudone_gui/controllers/utility/dashboard"
	"github.com/cloudawan/cloudone_gui/controllers/utility/guimessagedisplay"
	"github.com/cloudawan/cloudone_utility/rbac"
	"github.com/cloudawan/cloudone_utility/restclient"
	"strconv"
)

type DeployInformation struct {
	Namespace                 string
	ImageInformationName      string
	CurrentVersion            string
	CurrentVersionDescription string
	Description               string
}

type Service struct {
	Name            string
	Namespace       string
	PortSlice       []ServicePort
	Selector        map[string]interface{}
	ClusterIP       string
	LabelMap        map[string]interface{}
	SessionAffinity string
	Display         string
}

type ServicePort struct {
	Name       string
	Protocol   string
	Port       int
	TargetPort string
	NodePort   int
}

type ReplicationControllerAndRelatedPod struct {
	Name               string
	Namespace          string
	ReplicaAmount      int
	AliveReplicaAmount int
	Selector           map[string]string
	Label              map[string]string
	PodSlice           []Pod
}

type Pod struct {
	Name           string
	Namespace      string
	HostIP         string
	PodIP          string
	ContainerSlice []PodContainer
}

type PodContainer struct {
	Name      string
	Image     string
	PortSlice []PodContainerPort
}

type PodContainerPort struct {
	Name          string
	ContainerPort int
	Protocol      string
}

type DeployClusterApplication struct {
	Name                           string
	Size                           int
	ServiceName                    string
	ReplicationControllerNameSlice []string
}

type IndexController struct {
	beego.Controller
}

func (c *IndexController) Get() {
	guimessage := guimessagedisplay.GetGUIMessage(c)
	c.TplName = "dashboard/appservice/index.html"

	// Authorization for web page display
	c.Data["layoutMenu"] = c.GetSession("layoutMenu")
	// Dashboard tab menu
	user, _ := c.GetSession("user").(*rbac.User)
	c.Data["dashboardTabMenu"] = identity.GetDashboardTabMenu(user, "appservice")

	cloudoneGUIProtocol := beego.AppConfig.String("cloudoneGUIProtocol")
	cloudoneGUIHost := c.Ctx.Input.Host()
	cloudoneGUIPort := c.Ctx.Input.Port()

	c.Data["cloudoneGUIProtocol"] = cloudoneGUIProtocol
	c.Data["cloudoneGUIHost"] = cloudoneGUIHost
	c.Data["cloudoneGUIPort"] = cloudoneGUIPort

	guimessage.OutputMessage(c.Data)
}

const (
	allKeyword = "All"
)

type DataController struct {
	beego.Controller
}

func (c *DataController) Get() {
	cloudoneProtocol := beego.AppConfig.String("cloudoneProtocol")
	cloudoneHost := beego.AppConfig.String("cloudoneHost")
	cloudonePort := beego.AppConfig.String("cloudonePort")
	kubeapiHost, kubeapiPort, err := configuration.GetAvailableKubeapiHostAndPort()
	if err != nil {
		c.Data["json"].(map[string]interface{})["error"] = err.Error()
		c.ServeJSON()
		return
	}

	scope := c.GetString("scope")
	tokenHeaderMap, _ := c.GetSession("tokenHeaderMap").(map[string]string)

	namespaceSlice := make([]string, 0)
	if scope == allKeyword {
		url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort +
			"/api/v1/namespaces/" + "?kubeapihost=" + kubeapiHost + "&kubeapiport=" + strconv.Itoa(kubeapiPort)

		_, err := restclient.RequestGetWithStructure(url, &namespaceSlice, tokenHeaderMap)

		if identity.IsTokenInvalidAndRedirect(c, c.Ctx, err) {
			return
		}

		if err != nil {
			c.Data["json"].(map[string]interface{})["error"] = err.Error()
			c.ServeJSON()
			return
		}
	} else {
		namespace, _ := c.GetSession("namespace").(string)
		namespaceSlice = append(namespaceSlice, namespace)
	}

	url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort +
		"/api/v1/deploys/"

	deployInformationSlice := make([]DeployInformation, 0)

	_, err = restclient.RequestGetWithStructure(url, &deployInformationSlice, tokenHeaderMap)

	if identity.IsTokenInvalidAndRedirect(c, c.Ctx, err) {
		return
	}

	if err != nil {
		c.Data["json"].(map[string]interface{})["error"] = err.Error()
		c.ServeJSON()
		return
	}

	// Json
	c.Data["json"] = make(map[string]interface{})
	c.Data["json"].(map[string]interface{})["applicationlView"] = make([]interface{}, 0)
	c.Data["json"].(map[string]interface{})["thirdpartyView"] = make([]interface{}, 0)
	c.Data["json"].(map[string]interface{})["errorMap"] = make(map[string]interface{})

	// Application view
	applicationJsonMap := make(map[string]interface{})
	applicationJsonMap["name"] = "App View"
	applicationJsonMap["children"] = make([]interface{}, 0)
	c.Data["json"].(map[string]interface{})["applicationlView"] = append(c.Data["json"].(map[string]interface{})["applicationlView"].([]interface{}), applicationJsonMap)

	// Third-party view
	thirdpartyJsonMap := make(map[string]interface{})
	thirdpartyJsonMap["name"] = "3rd Party View"
	thirdpartyJsonMap["children"] = make([]interface{}, 0)
	c.Data["json"].(map[string]interface{})["thirdpartyView"] = append(c.Data["json"].(map[string]interface{})["thirdpartyView"].([]interface{}), thirdpartyJsonMap)

	applicationViewLeafAmount := 0
	thirdpartyViewLeafAmount := 0
	for _, namespace := range namespaceSlice {
		// Application view
		applicationNamespaceJsonMap := make(map[string]interface{})
		applicationNamespaceJsonMap["name"] = namespace
		applicationNamespaceJsonMap["color"] = dashboard.TextColorNamespace
		applicationNamespaceJsonMap["children"] = make([]interface{}, 0)

		url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort +
			"/api/v1/services/" + namespace + "?kubeapihost=" + kubeapiHost + "&kubeapiport=" + strconv.Itoa(kubeapiPort)

		serviceSlice := make([]Service, 0)

		_, err := restclient.RequestGetWithStructure(url, &serviceSlice, tokenHeaderMap)

		if identity.IsTokenInvalidAndRedirect(c, c.Ctx, err) {
			return
		}

		if err != nil {
			// Error
			c.Data["json"].(map[string]interface{})["error"] = "Get service data error"
			c.Data["json"].(map[string]interface{})["errorMap"].(map[string]interface{})[namespace] = err.Error()
		} else {
			url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort +
				"/api/v1/replicationcontrollers/" + namespace + "?kubeapihost=" + kubeapiHost + "&kubeapiport=" + strconv.Itoa(kubeapiPort)

			replicationControllerAndRelatedPodSlice := make([]ReplicationControllerAndRelatedPod, 0)

			_, err := restclient.RequestGetWithStructure(url, &replicationControllerAndRelatedPodSlice, tokenHeaderMap)

			if identity.IsTokenInvalidAndRedirect(c, c.Ctx, err) {
				return
			}

			if err != nil {
				// Error
				c.Data["json"].(map[string]interface{})["error"] = "Get replication controller data error"
				c.Data["json"].(map[string]interface{})["errorMap"].(map[string]interface{})[namespace] = err.Error()
			} else {
				namespaceOwnAmount := 0
				for _, deployInformation := range deployInformationSlice {
					if namespace == deployInformation.Namespace {
						namespaceOwnAmount++

						serviceName := "NO SERVICE"
						for _, service := range serviceSlice {
							if deployInformation.ImageInformationName == service.Name {
								serviceName = service.Name
								for _, port := range service.PortSlice {
									nodePortText := ""
									if port.NodePort >= 0 {
										nodePortText = strconv.Itoa(port.NodePort)
									}
									serviceName += " " + strconv.Itoa(port.Port) + "/" + nodePortText
								}
							}
						}

						serviceJsonMap := make(map[string]interface{})
						serviceJsonMap["name"] = serviceName
						serviceJsonMap["color"] = dashboard.TextColorService
						serviceJsonMap["children"] = make([]interface{}, 0)

						applicationNameJsonMap := make(map[string]interface{})
						applicationNameJsonMap["children"] = make([]interface{}, 0)

						instanceAmount := 0
						for _, replicationControllerAndRelatedPod := range replicationControllerAndRelatedPodSlice {
							if deployInformation.ImageInformationName+deployInformation.CurrentVersion == replicationControllerAndRelatedPod.Name {
								instanceAmount = replicationControllerAndRelatedPod.ReplicaAmount
								replicationControllerJsonMap := make(map[string]interface{})
								replicationControllerJsonMap["name"] = replicationControllerAndRelatedPod.Name + " (" + strconv.Itoa(instanceAmount) + ")"
								replicationControllerJsonMap["color"] = dashboard.TextColorReplicationController
								replicationControllerJsonMap["children"] = make([]interface{}, 0)
								applicationNameJsonMap["children"] = append(applicationNameJsonMap["children"].([]interface{}), replicationControllerJsonMap)
								applicationViewLeafAmount++
							}
						}

						applicationNameJsonMap["name"] = deployInformation.ImageInformationName + " (" + strconv.Itoa(instanceAmount) + ")"
						applicationNameJsonMap["color"] = dashboard.TextColorDeployInformation
						serviceJsonMap["children"] = append(serviceJsonMap["children"].([]interface{}), applicationNameJsonMap)
						applicationNamespaceJsonMap["children"] = append(applicationNamespaceJsonMap["children"].([]interface{}), serviceJsonMap)
					}
				}

				if namespaceOwnAmount == 0 {
					applicationViewLeafAmount++
				}

				applicationJsonMap["children"] = append(applicationJsonMap["children"].([]interface{}), applicationNamespaceJsonMap)
			}
		}

		// Third-party view
		thirdpartyNamespaceJsonMap := make(map[string]interface{})
		thirdpartyNamespaceJsonMap["name"] = namespace
		thirdpartyNamespaceJsonMap["children"] = make([]interface{}, 0)

		url = cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort +
			"/api/v1/deployclusterapplications/" + namespace

		deployClusterApplicationSlice := make([]DeployClusterApplication, 0)

		_, err = restclient.RequestGetWithStructure(url, &deployClusterApplicationSlice, tokenHeaderMap)

		if identity.IsTokenInvalidAndRedirect(c, c.Ctx, err) {
			return
		}

		if err != nil {
			// Error
			c.Data["json"].(map[string]interface{})["error"] = "Get third party application data error"
			c.Data["json"].(map[string]interface{})["errorMap"].(map[string]interface{})[namespace] = err.Error()
		} else {
			for _, deployClusterApplication := range deployClusterApplicationSlice {

				serviceName := deployClusterApplication.ServiceName
				for _, service := range serviceSlice {
					if service.Name == deployClusterApplication.ServiceName {
						for _, port := range service.PortSlice {
							nodePortText := ""
							if port.NodePort >= 0 {
								nodePortText = strconv.Itoa(port.NodePort)
							}
							serviceName += " " + strconv.Itoa(port.Port) + "/" + nodePortText
						}
					}
				}

				serviceJsonMap := make(map[string]interface{})
				serviceJsonMap["name"] = serviceName
				serviceJsonMap["color"] = dashboard.TextColorService
				serviceJsonMap["children"] = make([]interface{}, 0)

				thirdpartyNameJsonMap := make(map[string]interface{})
				thirdpartyNameJsonMap["name"] = deployClusterApplication.Name + " (" + strconv.Itoa(deployClusterApplication.Size) + ")"
				thirdpartyNameJsonMap["color"] = dashboard.TextColorDeployClusterApplication
				thirdpartyNameJsonMap["children"] = make([]interface{}, 0)

				replicationControllerNameAmount := len(deployClusterApplication.ReplicationControllerNameSlice)
				for _, replicationControllerName := range deployClusterApplication.ReplicationControllerNameSlice {
					replicationControllerJsonMap := make(map[string]interface{})
					replicationControllerJsonMap["name"] = replicationControllerName + " (" + strconv.Itoa(deployClusterApplication.Size/replicationControllerNameAmount) + ")"
					replicationControllerJsonMap["color"] = dashboard.TextColorReplicationController
					replicationControllerJsonMap["children"] = make([]interface{}, 0)
					thirdpartyNameJsonMap["children"] = append(thirdpartyNameJsonMap["children"].([]interface{}), replicationControllerJsonMap)
					thirdpartyViewLeafAmount++
				}

				serviceJsonMap["children"] = append(serviceJsonMap["children"].([]interface{}), thirdpartyNameJsonMap)
				thirdpartyNamespaceJsonMap["children"] = append(thirdpartyNamespaceJsonMap["children"].([]interface{}), serviceJsonMap)
			}
			if len(deployClusterApplicationSlice) == 0 {
				thirdpartyViewLeafAmount++
			}
			thirdpartyJsonMap["children"] = append(thirdpartyJsonMap["children"].([]interface{}), thirdpartyNamespaceJsonMap)
		}
	}
	c.Data["json"].(map[string]interface{})["applicationViewLeafAmount"] = applicationViewLeafAmount
	c.Data["json"].(map[string]interface{})["thirdpartyViewLeafAmount"] = thirdpartyViewLeafAmount

	dashboard.RecursiveSortTheDataInGraphJsonMap(c.Data["json"].(map[string]interface{}))

	c.ServeJSON()
}
<commit_msg>Add color<commit_after>// Copyright 2015 CloudAwan LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package appservice

import (
	"github.com/astaxie/beego"
	"github.com/cloudawan/cloudone_gui/controllers/identity"
	"github.com/cloudawan/cloudone_gui/controllers/utility/configuration"
	"github.com/cloudawan/cloudone_gui/controllers/utility/dashboard"
	"github.com/cloudawan/cloudone_gui/controllers/utility/guimessagedisplay"
	"github.com/cloudawan/cloudone_utility/rbac"
	"github.com/cloudawan/cloudone_utility/restclient"
	"strconv"
)

type DeployInformation struct {
	Namespace                 string
	ImageInformationName      string
	CurrentVersion            string
	CurrentVersionDescription string
	Description               string
}

type Service struct {
	Name            string
	Namespace       string
	PortSlice       []ServicePort
	Selector        map[string]interface{}
	ClusterIP       string
	LabelMap        map[string]interface{}
	SessionAffinity string
	Display         string
}

type ServicePort struct {
	Name       string
	Protocol   string
	Port       int
	TargetPort string
	NodePort   int
}

type ReplicationControllerAndRelatedPod struct {
	Name               string
	Namespace          string
	ReplicaAmount      int
	AliveReplicaAmount int
	Selector           map[string]string
	Label              map[string]string
	PodSlice           []Pod
}

type Pod struct {
	Name           string
	Namespace      string
	HostIP         string
	PodIP          string
	ContainerSlice []PodContainer
}

type PodContainer struct {
	Name      string
	Image     string
	PortSlice []PodContainerPort
}

type PodContainerPort struct {
	Name          string
	ContainerPort int
	Protocol      string
}

type DeployClusterApplication struct {
	Name                           string
	Size                           int
	ServiceName                    string
	ReplicationControllerNameSlice []string
}

type IndexController struct {
	beego.Controller
}

func (c *IndexController) Get() {
	guimessage := guimessagedisplay.GetGUIMessage(c)
	c.TplName = "dashboard/appservice/index.html"

	// Authorization for web page display
	c.Data["layoutMenu"] = c.GetSession("layoutMenu")
	// Dashboard tab menu
	user, _ := c.GetSession("user").(*rbac.User)
	c.Data["dashboardTabMenu"] = identity.GetDashboardTabMenu(user, "appservice")

	cloudoneGUIProtocol := beego.AppConfig.String("cloudoneGUIProtocol")
	cloudoneGUIHost := c.Ctx.Input.Host()
	cloudoneGUIPort := c.Ctx.Input.Port()

	c.Data["cloudoneGUIProtocol"] = cloudoneGUIProtocol
	c.Data["cloudoneGUIHost"] = cloudoneGUIHost
	c.Data["cloudoneGUIPort"] = cloudoneGUIPort

	guimessage.OutputMessage(c.Data)
}

const (
	allKeyword = "All"
)

type DataController struct {
	beego.Controller
}

func (c *DataController) Get() {
	cloudoneProtocol := beego.AppConfig.String("cloudoneProtocol")
	cloudoneHost := beego.AppConfig.String("cloudoneHost")
	cloudonePort := beego.AppConfig.String("cloudonePort")
	kubeapiHost, kubeapiPort, err := configuration.GetAvailableKubeapiHostAndPort()
	if err != nil {
		c.Data["json"].(map[string]interface{})["error"] = err.Error()
		c.ServeJSON()
		return
	}

	scope := c.GetString("scope")
	tokenHeaderMap, _ := c.GetSession("tokenHeaderMap").(map[string]string)

	namespaceSlice := make([]string, 0)
	if scope == allKeyword {
		url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort +
			"/api/v1/namespaces/" + "?kubeapihost=" + kubeapiHost + "&kubeapiport=" + strconv.Itoa(kubeapiPort)

		_, err := restclient.RequestGetWithStructure(url, &namespaceSlice, tokenHeaderMap)

		if identity.IsTokenInvalidAndRedirect(c, c.Ctx, err) {
			return
		}

		if err != nil {
			c.Data["json"].(map[string]interface{})["error"] = err.Error()
			c.ServeJSON()
			return
		}
	} else {
		namespace, _ := c.GetSession("namespace").(string)
		namespaceSlice = append(namespaceSlice, namespace)
	}

	url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort +
		"/api/v1/deploys/"

	deployInformationSlice := make([]DeployInformation, 0)

	_, err = restclient.RequestGetWithStructure(url, &deployInformationSlice, tokenHeaderMap)

	if identity.IsTokenInvalidAndRedirect(c, c.Ctx, err) {
		return
	}

	if err != nil {
		c.Data["json"].(map[string]interface{})["error"] = err.Error()
		c.ServeJSON()
		return
	}

	// Json
	c.Data["json"] = make(map[string]interface{})
	c.Data["json"].(map[string]interface{})["applicationlView"] = make([]interface{}, 0)
	c.Data["json"].(map[string]interface{})["thirdpartyView"] = make([]interface{}, 0)
	c.Data["json"].(map[string]interface{})["errorMap"] = make(map[string]interface{})

	// Application view
	applicationJsonMap := make(map[string]interface{})
	applicationJsonMap["name"] = "App View"
	applicationJsonMap["children"] = make([]interface{}, 0)
	c.Data["json"].(map[string]interface{})["applicationlView"] = append(c.Data["json"].(map[string]interface{})["applicationlView"].([]interface{}), applicationJsonMap)

	// Third-party view
	thirdpartyJsonMap := make(map[string]interface{})
	thirdpartyJsonMap["name"] = "3rd Party View"
	thirdpartyJsonMap["children"] = make([]interface{}, 0)
	c.Data["json"].(map[string]interface{})["thirdpartyView"] = append(c.Data["json"].(map[string]interface{})["thirdpartyView"].([]interface{}), thirdpartyJsonMap)

	applicationViewLeafAmount := 0
	thirdpartyViewLeafAmount := 0
	for _, namespace := range namespaceSlice {
		// Application view
		applicationNamespaceJsonMap := make(map[string]interface{})
		applicationNamespaceJsonMap["name"] = namespace
		applicationNamespaceJsonMap["color"] = dashboard.TextColorNamespace
		applicationNamespaceJsonMap["children"] = make([]interface{}, 0)

		url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort +
			"/api/v1/services/" + namespace + "?kubeapihost=" + kubeapiHost + "&kubeapiport=" + strconv.Itoa(kubeapiPort)

		serviceSlice := make([]Service, 0)

		_, err := restclient.RequestGetWithStructure(url, &serviceSlice, tokenHeaderMap)

		if identity.IsTokenInvalidAndRedirect(c, c.Ctx, err) {
			return
		}

		if err != nil {
			// Error
			c.Data["json"].(map[string]interface{})["error"] = "Get service data error"
			c.Data["json"].(map[string]interface{})["errorMap"].(map[string]interface{})[namespace] = err.Error()
		} else {
			url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort +
				"/api/v1/replicationcontrollers/" + namespace + "?kubeapihost=" + kubeapiHost + "&kubeapiport=" + strconv.Itoa(kubeapiPort)

			replicationControllerAndRelatedPodSlice := make([]ReplicationControllerAndRelatedPod, 0)

			_, err := restclient.RequestGetWithStructure(url, &replicationControllerAndRelatedPodSlice, tokenHeaderMap)

			if identity.IsTokenInvalidAndRedirect(c, c.Ctx, err) {
				return
			}

			if err != nil {
				// Error
				c.Data["json"].(map[string]interface{})["error"] = "Get replication controller data error"
				c.Data["json"].(map[string]interface{})["errorMap"].(map[string]interface{})[namespace] = err.Error()
			} else {
				namespaceOwnAmount := 0
				for _, deployInformation := range deployInformationSlice {
					if namespace == deployInformation.Namespace {
						namespaceOwnAmount++

						serviceName := "NO SERVICE"
						for _, service := range serviceSlice {
							if deployInformation.ImageInformationName == service.Name {
								serviceName = service.Name
								for _, port := range service.PortSlice {
									nodePortText := ""
									if port.NodePort >= 0 {
										nodePortText = strconv.Itoa(port.NodePort)
									}
									serviceName += " " + strconv.Itoa(port.Port) + "/" + nodePortText
								}
							}
						}

						serviceJsonMap := make(map[string]interface{})
						serviceJsonMap["name"] = serviceName
						serviceJsonMap["color"] = dashboard.TextColorService
						serviceJsonMap["children"] = make([]interface{}, 0)

						applicationNameJsonMap := make(map[string]interface{})
						applicationNameJsonMap["children"] = make([]interface{}, 0)

						instanceAmount := 0
						for _, replicationControllerAndRelatedPod := range replicationControllerAndRelatedPodSlice {
							if deployInformation.ImageInformationName+deployInformation.CurrentVersion == replicationControllerAndRelatedPod.Name {
								instanceAmount = replicationControllerAndRelatedPod.ReplicaAmount
								replicationControllerJsonMap := make(map[string]interface{})
								replicationControllerJsonMap["name"] = replicationControllerAndRelatedPod.Name + " (" + strconv.Itoa(instanceAmount) + ")"
								replicationControllerJsonMap["color"] = dashboard.TextColorReplicationController
								replicationControllerJsonMap["children"] = make([]interface{}, 0)
								applicationNameJsonMap["children"] = append(applicationNameJsonMap["children"].([]interface{}), replicationControllerJsonMap)
								applicationViewLeafAmount++
							}
						}

						applicationNameJsonMap["name"] = deployInformation.ImageInformationName + " (" + strconv.Itoa(instanceAmount) + ")"
						applicationNameJsonMap["color"] = dashboard.TextColorDeployInformation
						serviceJsonMap["children"] = append(serviceJsonMap["children"].([]interface{}), applicationNameJsonMap)
						applicationNamespaceJsonMap["children"] = append(applicationNamespaceJsonMap["children"].([]interface{}), serviceJsonMap)
					}
				}

				if namespaceOwnAmount == 0 {
					applicationViewLeafAmount++
				}

				applicationJsonMap["children"] = append(applicationJsonMap["children"].([]interface{}), applicationNamespaceJsonMap)
			}
		}

		// Third-party view
		thirdpartyNamespaceJsonMap := make(map[string]interface{})
		thirdpartyNamespaceJsonMap["name"] = namespace
		thirdpartyNamespaceJsonMap["color"] = dashboard.TextColorNamespace
		thirdpartyNamespaceJsonMap["children"] = make([]interface{}, 0)

		url = cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort +
			"/api/v1/deployclusterapplications/" + namespace

		deployClusterApplicationSlice := make([]DeployClusterApplication, 0)

		_, err = restclient.RequestGetWithStructure(url, &deployClusterApplicationSlice, tokenHeaderMap)

		if identity.IsTokenInvalidAndRedirect(c, c.Ctx, err) {
			return
		}

		if err != nil {
			// Error
			c.Data["json"].(map[string]interface{})["error"] = "Get third party application data error"
			c.Data["json"].(map[string]interface{})["errorMap"].(map[string]interface{})[namespace] = err.Error()
		} else {
			for _, deployClusterApplication := range deployClusterApplicationSlice {

				serviceName := deployClusterApplication.ServiceName
				for _, service := range serviceSlice {
					if service.Name == deployClusterApplication.ServiceName {
						for _, port := range service.PortSlice {
							nodePortText := ""
							if port.NodePort >= 0 {
								nodePortText = strconv.Itoa(port.NodePort)
							}
							serviceName += " " + strconv.Itoa(port.Port) + "/" + nodePortText
						}
					}
				}

				serviceJsonMap := make(map[string]interface{})
				serviceJsonMap["name"] = serviceName
				serviceJsonMap["color"] = dashboard.TextColorService
				serviceJsonMap["children"] = make([]interface{}, 0)

				thirdpartyNameJsonMap := make(map[string]interface{})
				thirdpartyNameJsonMap["name"] = deployClusterApplication.Name + " (" + strconv.Itoa(deployClusterApplication.Size) + ")"
				thirdpartyNameJsonMap["color"] = dashboard.TextColorDeployClusterApplication
				thirdpartyNameJsonMap["children"] = make([]interface{}, 0)

				replicationControllerNameAmount := len(deployClusterApplication.ReplicationControllerNameSlice)
				for _, replicationControllerName := range deployClusterApplication.ReplicationControllerNameSlice {
					replicationControllerJsonMap := make(map[string]interface{})
					replicationControllerJsonMap["name"] = replicationControllerName + " (" + strconv.Itoa(deployClusterApplication.Size/replicationControllerNameAmount) + ")"
					replicationControllerJsonMap["color"] = dashboard.TextColorReplicationController
					replicationControllerJsonMap["children"] = make([]interface{}, 0)
					thirdpartyNameJsonMap["children"] = append(thirdpartyNameJsonMap["children"].([]interface{}), replicationControllerJsonMap)
					thirdpartyViewLeafAmount++
				}

				serviceJsonMap["children"] = append(serviceJsonMap["children"].([]interface{}), thirdpartyNameJsonMap)
				thirdpartyNamespaceJsonMap["children"] = append(thirdpartyNamespaceJsonMap["children"].([]interface{}), serviceJsonMap)
			}
			if len(deployClusterApplicationSlice) == 0 {
				thirdpartyViewLeafAmount++
			}
			thirdpartyJsonMap["children"] = append(thirdpartyJsonMap["children"].([]interface{}), thirdpartyNamespaceJsonMap)
		}
	}
	c.Data["json"].(map[string]interface{})["applicationViewLeafAmount"] = applicationViewLeafAmount
	c.Data["json"].(map[string]interface{})["thirdpartyViewLeafAmount"] = thirdpartyViewLeafAmount

	dashboard.RecursiveSortTheDataInGraphJsonMap(c.Data["json"].(map[string]interface{}))

	c.ServeJSON()
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/urfave/cli"
)

type kernelModule struct {
	// description
	desc string

	// maps parameter names to values
	parameters map[string]string
}

const (
	moduleParamDir = "parameters"
	cpuFlagsTag    = "flags"
)

// variables rather than consts to allow tests to modify them
var (
	procCPUInfo  = "/proc/cpuinfo"
	sysModuleDir = "/sys/module"
	modInfoCmd   = "modinfo"
)

// requiredCPUFlags maps a CPU flag value to search for and a
// human-readable description of that value.
var requiredCPUFlags = map[string]string{
	"vmx":    "Virtualization support",
	"lm":     "64Bit CPU",
	"sse4_1": "SSE4.1",
}

// requiredCPUAttribs maps a CPU (non-CPU flag) attribute value to search for
// and a human-readable description of that value.
var requiredCPUAttribs = map[string]string{
	"GenuineIntel": "Intel Architecture CPU",
}

// requiredKernelModules maps a required module name to a human-readable
// description of the modules functionality and an optional list of
// required module parameters.
var requiredKernelModules = map[string]kernelModule{
	"kvm": {
		desc: "Kernel-based Virtual Machine",
	},
	"kvm_intel": {
		desc: "Intel KVM",
		parameters: map[string]string{
			"nested":             "Y",
			"unrestricted_guest": "Y",
		},
	},
	"vhost": {
		desc: "Host kernel accelerator for virtio",
	},
	"vhost_net": {
		desc: "Host kernel accelerator for virtio network",
	},
}

// return details of the first CPU
func getCPUInfo(cpuInfoFile string) (string, error) {
	text, err := getFileContents(cpuInfoFile)
	if err != nil {
		return "", err
	}

	cpus := strings.SplitAfter(text, "\n\n")

	trimmed := strings.TrimSpace(cpus[0])
	if trimmed == "" {
		return "", fmt.Errorf("Cannot determine CPU details")
	}

	return trimmed, nil
}

func findAnchoredString(haystack, needle string) bool {
	if haystack == "" || needle == "" {
		return false
	}

	// Ensure the search string is anchored
	pattern := regexp.MustCompile(`\b` + needle + `\b`)

	matched := pattern.MatchString(haystack)

	if matched {
		return true
	}

	return false
}

func getCPUFlags(cpuinfo string) string {
	for _, line := range strings.Split(cpuinfo, "\n") {
		if strings.HasPrefix(line, cpuFlagsTag) {
			fields := strings.Split(line, ":")
			if len(fields) == 2 {
				return strings.TrimSpace(fields[1])
			}
		}
	}

	return ""
}

func haveKernelModule(module string) bool {
	// First, check to see if the module is already loaded
	path := filepath.Join(sysModuleDir, module)
	if fileExists(path) {
		return true
	}

	// Now, check if the module is unloaded, but available
	cmd := exec.Command(modInfoCmd, module)
	err := cmd.Run()
	if err == nil {
		return true
	}

	return false
}

func checkCPU(tag, cpuinfo string, attribs map[string]string) error {
	if cpuinfo == "" {
		return fmt.Errorf("Need cpuinfo")
	}

	for attrib, desc := range attribs {
		found := findAnchoredString(cpuinfo, attrib)
		if found {
			ccLog.Infof("Found CPU %v %q (%s)", tag, desc, attrib)
		} else {
			return fmt.Errorf("CPU does not have required %v: %q (%s)", tag, desc, attrib)
		}
	}

	return nil
}
func checkCPUFlags(cpuflags string, required map[string]string) error {
	return checkCPU("flag", cpuflags, required)
}

func checkCPUAttribs(cpuinfo string, attribs map[string]string) error {
	return checkCPU("attribute", cpuinfo, attribs)
}

func checkKernelModules(modules map[string]kernelModule) error {
	for module, details := range modules {
		if !haveKernelModule(module) {
			return fmt.Errorf("kernel module %q (%s) not found", module, details.desc)
		}

		ccLog.Infof("Found kernel module %q (%s)", details.desc, module)

		for param, expected := range details.parameters {
			path := filepath.Join(sysModuleDir, module, moduleParamDir, param)
			value, err := getFileContents(path)
			if err != nil {
				return err
			}

			value = strings.TrimRight(value, "\n\r")

			if value == expected {
				ccLog.Infof("Kernel module %q parameter %q has correct value", details.desc, param)
			} else {
				return fmt.Errorf("kernel module %q parameter %q has value %q (expected %q)", details.desc, param, value, expected)
			}
		}
	}

	return nil
}

// hostIsClearContainersCapable determines if the system is capable of
// running Clear Containers.
func hostIsClearContainersCapable(cpuinfoFile string) error {
	cpuinfo, err := getCPUInfo(cpuinfoFile)
	if err != nil {
		return err
	}

	if err = checkCPUAttribs(cpuinfo, requiredCPUAttribs); err != nil {
		return err
	}

	cpuFlags := getCPUFlags(cpuinfo)
	if cpuFlags == "" {
		return fmt.Errorf("Cannot find CPU flags")
	}

	if err = checkCPUFlags(cpuFlags, requiredCPUFlags); err != nil {
		return err
	}

	if err = checkKernelModules(requiredKernelModules); err != nil {
		return err
	}

	return nil
}

var ccCheckCommand = cli.Command{
	Name:  "cc-check",
	Usage: "tests if system can run " + project,
	Action: func(context *cli.Context) error {
		err := hostIsClearContainersCapable(procCPUInfo)
		if err != nil {
			return fmt.Errorf("ERROR: %v", err)
		}

		ccLog.Info("")
		ccLog.Info("System is capable of running " + project)

		return nil
	},
}
<commit_msg>cc-check: Add const for success message.<commit_after>// Copyright (c) 2017 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/urfave/cli"
)

type kernelModule struct {
	// description
	desc string

	// maps parameter names to values
	parameters map[string]string
}

const (
	moduleParamDir = "parameters"
	cpuFlagsTag    = "flags"
	successMessage = "System is capable of running " + project
)

// variables rather than consts to allow tests to modify them
var (
	procCPUInfo  = "/proc/cpuinfo"
	sysModuleDir = "/sys/module"
	modInfoCmd   = "modinfo"
)

// requiredCPUFlags maps a CPU flag value to search for and a
// human-readable description of that value.
var requiredCPUFlags = map[string]string{
	"vmx":    "Virtualization support",
	"lm":     "64Bit CPU",
	"sse4_1": "SSE4.1",
}

// requiredCPUAttribs maps a CPU (non-CPU flag) attribute value to search for
// and a human-readable description of that value.
var requiredCPUAttribs = map[string]string{
	"GenuineIntel": "Intel Architecture CPU",
}

// requiredKernelModules maps a required module name to a human-readable
// description of the modules functionality and an optional list of
// required module parameters.
var requiredKernelModules = map[string]kernelModule{
	"kvm": {
		desc: "Kernel-based Virtual Machine",
	},
	"kvm_intel": {
		desc: "Intel KVM",
		parameters: map[string]string{
			"nested":             "Y",
			"unrestricted_guest": "Y",
		},
	},
	"vhost": {
		desc: "Host kernel accelerator for virtio",
	},
	"vhost_net": {
		desc: "Host kernel accelerator for virtio network",
	},
}

// return details of the first CPU
func getCPUInfo(cpuInfoFile string) (string, error) {
	text, err := getFileContents(cpuInfoFile)
	if err != nil {
		return "", err
	}

	cpus := strings.SplitAfter(text, "\n\n")

	trimmed := strings.TrimSpace(cpus[0])
	if trimmed == "" {
		return "", fmt.Errorf("Cannot determine CPU details")
	}

	return trimmed, nil
}

func findAnchoredString(haystack, needle string) bool {
	if haystack == "" || needle == "" {
		return false
	}

	// Ensure the search string is anchored
	pattern := regexp.MustCompile(`\b` + needle + `\b`)

	matched := pattern.MatchString(haystack)

	if matched {
		return true
	}

	return false
}

func getCPUFlags(cpuinfo string) string {
	for _, line := range strings.Split(cpuinfo, "\n") {
		if strings.HasPrefix(line, cpuFlagsTag) {
			fields := strings.Split(line, ":")
			if len(fields) == 2 {
				return strings.TrimSpace(fields[1])
			}
		}
	}

	return ""
}

func haveKernelModule(module string) bool {
	// First, check to see if the module is already loaded
	path := filepath.Join(sysModuleDir, module)
	if fileExists(path) {
		return true
	}

	// Now, check if the module is unloaded, but available
	cmd := exec.Command(modInfoCmd, module)
	err := cmd.Run()
	if err == nil {
		return true
	}

	return false
}

func checkCPU(tag, cpuinfo string, attribs map[string]string) error {
	if cpuinfo == "" {
		return fmt.Errorf("Need cpuinfo")
	}

	for attrib, desc := range attribs {
		found := findAnchoredString(cpuinfo, attrib)
		if found {
			ccLog.Infof("Found CPU %v %q (%s)", tag, desc, attrib)
		} else {
			return fmt.Errorf("CPU does not have required %v: %q (%s)", tag, desc, attrib)
		}
	}

	return nil
}
func checkCPUFlags(cpuflags string, required map[string]string) error {
	return checkCPU("flag", cpuflags, required)
}

func checkCPUAttribs(cpuinfo string, attribs map[string]string) error {
	return checkCPU("attribute", cpuinfo, attribs)
}

func checkKernelModules(modules map[string]kernelModule) error {
	for module, details := range modules {
		if !haveKernelModule(module) {
			return fmt.Errorf("kernel module %q (%s) not found", module, details.desc)
		}

		ccLog.Infof("Found kernel module %q (%s)", details.desc, module)

		for param, expected := range details.parameters {
			path := filepath.Join(sysModuleDir, module, moduleParamDir, param)
			value, err := getFileContents(path)
			if err != nil {
				return err
			}

			value = strings.TrimRight(value, "\n\r")

			if value == expected {
				ccLog.Infof("Kernel module %q parameter %q has correct value", details.desc, param)
			} else {
				return fmt.Errorf("kernel module %q parameter %q has value %q (expected %q)", details.desc, param, value, expected)
			}
		}
	}

	return nil
}

// hostIsClearContainersCapable determines if the system is capable of
// running Clear Containers.
func hostIsClearContainersCapable(cpuinfoFile string) error {
	cpuinfo, err := getCPUInfo(cpuinfoFile)
	if err != nil {
		return err
	}

	if err = checkCPUAttribs(cpuinfo, requiredCPUAttribs); err != nil {
		return err
	}

	cpuFlags := getCPUFlags(cpuinfo)
	if cpuFlags == "" {
		return fmt.Errorf("Cannot find CPU flags")
	}

	if err = checkCPUFlags(cpuFlags, requiredCPUFlags); err != nil {
		return err
	}

	if err = checkKernelModules(requiredKernelModules); err != nil {
		return err
	}

	return nil
}

var ccCheckCommand = cli.Command{
	Name:  "cc-check",
	Usage: "tests if system can run " + project,
	Action: func(context *cli.Context) error {
		err := hostIsClearContainersCapable(procCPUInfo)
		if err != nil {
			return fmt.Errorf("ERROR: %v", err)
		}

		ccLog.Info("")
		ccLog.Info(successMessage)

		return nil
	},
}
<|endoftext|>