<commit_before>/*
Copyright IBM Corp. 2017 All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"strings"

	"github.com/golang/protobuf/proto"
	"github.com/hyperledger/fabric/bccsp/factory"
	"github.com/hyperledger/fabric/common/channelconfig"
	"github.com/hyperledger/fabric/common/flogging"
	"github.com/hyperledger/fabric/common/tools/protolator"
	"github.com/hyperledger/fabric/internal/configtxgen/encoder"
	genesisconfig "github.com/hyperledger/fabric/internal/configtxgen/localconfig"
	"github.com/hyperledger/fabric/internal/configtxgen/metadata"
	"github.com/hyperledger/fabric/internal/configtxlator/update"
	cb "github.com/hyperledger/fabric/protos/common"
	"github.com/hyperledger/fabric/protoutil"
	"github.com/pkg/errors"
)

var exitCode = 0

var logger = flogging.MustGetLogger("common.tools.configtxgen")

func doOutputBlock(config *genesisconfig.Profile, channelID string, outputBlock string) error {
	pgen, err := encoder.NewBootstrapper(config)
	if err != nil {
		return errors.WithMessage(err, "could not create bootstrapper")
	}
	logger.Info("Generating genesis block")
	if config.Orderer == nil {
		return errors.Errorf("refusing to generate block which is missing orderer section")
	}
	if config.Consortiums == nil {
		logger.Warning("Genesis block does not contain a consortiums group definition.  This block cannot be used for orderer bootstrap.")
	}
	genesisBlock := pgen.GenesisBlockForChannel(channelID)
	logger.Info("Writing genesis block")
	err = ioutil.WriteFile(outputBlock, protoutil.MarshalOrPanic(genesisBlock), 0644)
	if err != nil {
		return fmt.Errorf("Error writing genesis block: %s", err)
	}
	return nil
}

func doOutputChannelCreateTx(conf, baseProfile *genesisconfig.Profile, channelID string, outputChannelCreateTx string) error {
	logger.Info("Generating new channel configtx")

	var configtx *cb.Envelope
	var err error
	if baseProfile == nil {
		configtx, err = encoder.MakeChannelCreationTransaction(channelID, nil, conf)
	} else {
		configtx, err = encoder.MakeChannelCreationTransactionWithSystemChannelContext(channelID, nil, conf, baseProfile)
	}
	if err != nil {
		return err
	}

	logger.Info("Writing new channel tx")
	err = ioutil.WriteFile(outputChannelCreateTx, protoutil.MarshalOrPanic(configtx), 0644)
	if err != nil {
		return fmt.Errorf("Error writing channel create tx: %s", err)
	}
	return nil
}

func doOutputAnchorPeersUpdate(conf *genesisconfig.Profile, channelID string, outputAnchorPeersUpdate string, asOrg string) error {
	logger.Info("Generating anchor peer update")
	if asOrg == "" {
		return fmt.Errorf("Must specify an organization to update the anchor peer for")
	}

	if conf.Application == nil {
		return fmt.Errorf("Cannot update anchor peers without an application section")
	}

	original, err := encoder.NewChannelGroup(conf)
	if err != nil {
		return errors.WithMessage(err, "error parsing profile as channel group")
	}
	original.Groups[channelconfig.ApplicationGroupKey].Version = 1

	updated := proto.Clone(original).(*cb.ConfigGroup)

	originalOrg, ok := original.Groups[channelconfig.ApplicationGroupKey].Groups[asOrg]
	if !ok {
		return errors.Errorf("org with name '%s' does not exist in config", asOrg)
	}

	if _, ok = originalOrg.Values[channelconfig.AnchorPeersKey]; !ok {
		return errors.Errorf("org '%s' does not have any anchor peers defined", asOrg)
	}

	delete(originalOrg.Values, channelconfig.AnchorPeersKey)

	updt, err := update.Compute(&cb.Config{ChannelGroup: original}, &cb.Config{ChannelGroup: updated})
	if err != nil {
		return errors.WithMessage(err, "could not compute update")
	}
	updt.ChannelId = channelID

	newConfigUpdateEnv := &cb.ConfigUpdateEnvelope{
		ConfigUpdate: protoutil.MarshalOrPanic(updt),
	}

	updateTx, err := protoutil.CreateSignedEnvelope(cb.HeaderType_CONFIG_UPDATE, channelID, nil, newConfigUpdateEnv, 0, 0)

	logger.Info("Writing anchor peer update")
	err = ioutil.WriteFile(outputAnchorPeersUpdate, protoutil.MarshalOrPanic(updateTx), 0644)
	if err != nil {
		return fmt.Errorf("Error writing channel anchor peer update: %s", err)
	}
	return nil
}

func doInspectBlock(inspectBlock string) error {
	logger.Info("Inspecting block")
	data, err := ioutil.ReadFile(inspectBlock)
	if err != nil {
		return fmt.Errorf("Could not read block %s", inspectBlock)
	}

	logger.Info("Parsing genesis block")
	block, err := protoutil.UnmarshalBlock(data)
	if err != nil {
		return fmt.Errorf("error unmarshaling to block: %s", err)
	}
	err = protolator.DeepMarshalJSON(os.Stdout, block)
	if err != nil {
		return fmt.Errorf("malformed block contents: %s", err)
	}
	return nil
}

func doInspectChannelCreateTx(inspectChannelCreateTx string) error {
	logger.Info("Inspecting transaction")
	data, err := ioutil.ReadFile(inspectChannelCreateTx)
	if err != nil {
		return fmt.Errorf("could not read channel create tx: %s", err)
	}

	logger.Info("Parsing transaction")
	env, err := protoutil.UnmarshalEnvelope(data)
	if err != nil {
		return fmt.Errorf("Error unmarshaling envelope: %s", err)
	}

	err = protolator.DeepMarshalJSON(os.Stdout, env)
	if err != nil {
		return fmt.Errorf("malformed transaction contents: %s", err)
	}

	return nil
}

func doPrintOrg(t *genesisconfig.TopLevel, printOrg string) error {
	for _, org := range t.Organizations {
		if org.Name == printOrg {
			og, err := encoder.NewOrdererOrgGroup(org)
			if err != nil {
				return errors.Wrapf(err, "bad org definition for org %s", org.Name)
			}

			if err := protolator.DeepMarshalJSON(os.Stdout, og); err != nil {
				return errors.Wrapf(err, "malformed org definition for org: %s", org.Name)
			}
			return nil
		}
	}
	return errors.Errorf("organization %s not found", printOrg)
}

func main() {
	var outputBlock, outputChannelCreateTx, channelCreateTxBaseProfile, profile, configPath, channelID, inspectBlock, inspectChannelCreateTx, outputAnchorPeersUpdate, asOrg, printOrg string

	flag.StringVar(&outputBlock, "outputBlock", "", "The path to write the genesis block to (if set)")
	flag.StringVar(&channelID, "channelID", "", "The channel ID to use in the configtx")
	flag.StringVar(&outputChannelCreateTx, "outputCreateChannelTx", "", "The path to write a channel creation configtx to (if set)")
	flag.StringVar(&channelCreateTxBaseProfile, "channelCreateTxBaseProfile", "", "Specifies a profile to consider as the orderer system channel current state to allow modification of non-application parameters during channel create tx generation. Only valid in conjunction with 'outputCreateChannelTx'.")
	flag.StringVar(&profile, "profile", genesisconfig.SampleInsecureSoloProfile, "The profile from configtx.yaml to use for generation.")
	flag.StringVar(&configPath, "configPath", "", "The path containing the configuration to use (if set)")
	flag.StringVar(&inspectBlock, "inspectBlock", "", "Prints the configuration contained in the block at the specified path")
	flag.StringVar(&inspectChannelCreateTx, "inspectChannelCreateTx", "", "Prints the configuration contained in the transaction at the specified path")
	flag.StringVar(&outputAnchorPeersUpdate, "outputAnchorPeersUpdate", "", "Creates an config update to update an anchor peer (works only with the default channel creation, and only for the first update)")
	flag.StringVar(&asOrg, "asOrg", "", "Performs the config generation as a particular organization (by name), only including values in the write set that org (likely) has privilege to set")
	flag.StringVar(&printOrg, "printOrg", "", "Prints the definition of an organization as JSON. (useful for adding an org to a channel manually)")

	version := flag.Bool("version", false, "Show version information")

	flag.Parse()

	if channelID == "" && (outputBlock != "" || outputChannelCreateTx != "" || outputAnchorPeersUpdate != "") {
		logger.Fatalf("Missing channelID, please specify it with '-channelID'")
	}

	// show version
	if *version {
		printVersion()
		os.Exit(exitCode)
	}

	// don't need to panic when running via command line
	defer func() {
		if err := recover(); err != nil {
			if strings.Contains(fmt.Sprint(err), "Error reading configuration: Unsupported Config Type") {
				logger.Error("Could not find configtx.yaml. " +
					"Please make sure that FABRIC_CFG_PATH or -configPath is set to a path " +
					"which contains configtx.yaml")
				os.Exit(1)
			}
			if strings.Contains(fmt.Sprint(err), "Could not find profile") {
				logger.Error(fmt.Sprint(err) + ". " +
					"Please make sure that FABRIC_CFG_PATH or -configPath is set to a path " +
					"which contains configtx.yaml with the specified profile")
				os.Exit(1)
			}
			logger.Panic(err)
		}
	}()

	logger.Info("Loading configuration")
	factory.InitFactories(nil)
	var profileConfig *genesisconfig.Profile
	if outputBlock != "" || outputChannelCreateTx != "" || outputAnchorPeersUpdate != "" {
		if configPath != "" {
			profileConfig = genesisconfig.Load(profile, configPath)
		} else {
			profileConfig = genesisconfig.Load(profile)
		}
	}
	var topLevelConfig *genesisconfig.TopLevel
	if configPath != "" {
		topLevelConfig = genesisconfig.LoadTopLevel(configPath)
	} else {
		topLevelConfig = genesisconfig.LoadTopLevel()
	}

	var baseProfile *genesisconfig.Profile
	if channelCreateTxBaseProfile != "" {
		if outputChannelCreateTx == "" {
			logger.Warning("Specified 'channelCreateTxBaseProfile', but did not specify 'outputChannelCreateTx', 'channelCreateTxBaseProfile' will not affect output.")
		}
		if configPath != "" {
			baseProfile = genesisconfig.Load(channelCreateTxBaseProfile, configPath)
		} else {
			baseProfile = genesisconfig.Load(channelCreateTxBaseProfile)
		}
	}

	if outputBlock != "" {
		if err := doOutputBlock(profileConfig, channelID, outputBlock); err != nil {
			logger.Fatalf("Error on outputBlock: %s", err)
		}
	}

	if outputChannelCreateTx != "" {
		if err := doOutputChannelCreateTx(profileConfig, baseProfile, channelID, outputChannelCreateTx); err != nil {
			logger.Fatalf("Error on outputChannelCreateTx: %s", err)
		}
	}

	if inspectBlock != "" {
		if err := doInspectBlock(inspectBlock); err != nil {
			logger.Fatalf("Error on inspectBlock: %s", err)
		}
	}

	if inspectChannelCreateTx != "" {
		if err := doInspectChannelCreateTx(inspectChannelCreateTx); err != nil {
			logger.Fatalf("Error on inspectChannelCreateTx: %s", err)
		}
	}

	if outputAnchorPeersUpdate != "" {
		if err := doOutputAnchorPeersUpdate(profileConfig, channelID, outputAnchorPeersUpdate, asOrg); err != nil {
			logger.Fatalf("Error on inspectChannelCreateTx: %s", err)
		}
	}

	if printOrg != "" {
		if err := doPrintOrg(topLevelConfig, printOrg); err != nil {
			logger.Fatalf("Error on printOrg: %s", err)
		}
	}
}

func printVersion() {
	fmt.Println(metadata.GetVersionInfo())
}
<commit_msg>FAB-14551 Properly decorate org proto<commit_after>/*
Copyright IBM Corp. 2017 All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"strings"

	"github.com/golang/protobuf/proto"
	"github.com/hyperledger/fabric/bccsp/factory"
	"github.com/hyperledger/fabric/common/channelconfig"
	"github.com/hyperledger/fabric/common/flogging"
	"github.com/hyperledger/fabric/common/tools/protolator"
	"github.com/hyperledger/fabric/common/tools/protolator/protoext/ordererext"
	"github.com/hyperledger/fabric/internal/configtxgen/encoder"
	genesisconfig "github.com/hyperledger/fabric/internal/configtxgen/localconfig"
	"github.com/hyperledger/fabric/internal/configtxgen/metadata"
	"github.com/hyperledger/fabric/internal/configtxlator/update"
	cb "github.com/hyperledger/fabric/protos/common"
	"github.com/hyperledger/fabric/protoutil"
	"github.com/pkg/errors"
)

var exitCode = 0

var logger = flogging.MustGetLogger("common.tools.configtxgen")

func doOutputBlock(config *genesisconfig.Profile, channelID string, outputBlock string) error {
	pgen, err := encoder.NewBootstrapper(config)
	if err != nil {
		return errors.WithMessage(err, "could not create bootstrapper")
	}
	logger.Info("Generating genesis block")
	if config.Orderer == nil {
		return errors.Errorf("refusing to generate block which is missing orderer section")
	}
	if config.Consortiums == nil {
		logger.Warning("Genesis block does not contain a consortiums group definition.  This block cannot be used for orderer bootstrap.")
	}
	genesisBlock := pgen.GenesisBlockForChannel(channelID)
	logger.Info("Writing genesis block")
	err = ioutil.WriteFile(outputBlock, protoutil.MarshalOrPanic(genesisBlock), 0644)
	if err != nil {
		return fmt.Errorf("Error writing genesis block: %s", err)
	}
	return nil
}

func doOutputChannelCreateTx(conf, baseProfile *genesisconfig.Profile, channelID string, outputChannelCreateTx string) error {
	logger.Info("Generating new channel configtx")

	var configtx *cb.Envelope
	var err error
	if baseProfile == nil {
		configtx, err = encoder.MakeChannelCreationTransaction(channelID, nil, conf)
	} else {
		configtx, err = encoder.MakeChannelCreationTransactionWithSystemChannelContext(channelID, nil, conf, baseProfile)
	}
	if err != nil {
		return err
	}

	logger.Info("Writing new channel tx")
	err = ioutil.WriteFile(outputChannelCreateTx, protoutil.MarshalOrPanic(configtx), 0644)
	if err != nil {
		return fmt.Errorf("Error writing channel create tx: %s", err)
	}
	return nil
}

func doOutputAnchorPeersUpdate(conf *genesisconfig.Profile, channelID string, outputAnchorPeersUpdate string, asOrg string) error {
	logger.Info("Generating anchor peer update")
	if asOrg == "" {
		return fmt.Errorf("Must specify an organization to update the anchor peer for")
	}

	if conf.Application == nil {
		return fmt.Errorf("Cannot update anchor peers without an application section")
	}

	original, err := encoder.NewChannelGroup(conf)
	if err != nil {
		return errors.WithMessage(err, "error parsing profile as channel group")
	}
	original.Groups[channelconfig.ApplicationGroupKey].Version = 1

	updated := proto.Clone(original).(*cb.ConfigGroup)

	originalOrg, ok := original.Groups[channelconfig.ApplicationGroupKey].Groups[asOrg]
	if !ok {
		return errors.Errorf("org with name '%s' does not exist in config", asOrg)
	}

	if _, ok = originalOrg.Values[channelconfig.AnchorPeersKey]; !ok {
		return errors.Errorf("org '%s' does not have any anchor peers defined", asOrg)
	}

	delete(originalOrg.Values, channelconfig.AnchorPeersKey)

	updt, err := update.Compute(&cb.Config{ChannelGroup: original}, &cb.Config{ChannelGroup: updated})
	if err != nil {
		return errors.WithMessage(err, "could not compute update")
	}
	updt.ChannelId = channelID

	newConfigUpdateEnv := &cb.ConfigUpdateEnvelope{
		ConfigUpdate: protoutil.MarshalOrPanic(updt),
	}

	updateTx, err := protoutil.CreateSignedEnvelope(cb.HeaderType_CONFIG_UPDATE, channelID, nil, newConfigUpdateEnv, 0, 0)

	logger.Info("Writing anchor peer update")
	err = ioutil.WriteFile(outputAnchorPeersUpdate, protoutil.MarshalOrPanic(updateTx), 0644)
	if err != nil {
		return fmt.Errorf("Error writing channel anchor peer update: %s", err)
	}
	return nil
}

func doInspectBlock(inspectBlock string) error {
	logger.Info("Inspecting block")
	data, err := ioutil.ReadFile(inspectBlock)
	if err != nil {
		return fmt.Errorf("Could not read block %s", inspectBlock)
	}

	logger.Info("Parsing genesis block")
	block, err := protoutil.UnmarshalBlock(data)
	if err != nil {
		return fmt.Errorf("error unmarshaling to block: %s", err)
	}
	err = protolator.DeepMarshalJSON(os.Stdout, block)
	if err != nil {
		return fmt.Errorf("malformed block contents: %s", err)
	}
	return nil
}

func doInspectChannelCreateTx(inspectChannelCreateTx string) error {
	logger.Info("Inspecting transaction")
	data, err := ioutil.ReadFile(inspectChannelCreateTx)
	if err != nil {
		return fmt.Errorf("could not read channel create tx: %s", err)
	}

	logger.Info("Parsing transaction")
	env, err := protoutil.UnmarshalEnvelope(data)
	if err != nil {
		return fmt.Errorf("Error unmarshaling envelope: %s", err)
	}

	err = protolator.DeepMarshalJSON(os.Stdout, env)
	if err != nil {
		return fmt.Errorf("malformed transaction contents: %s", err)
	}

	return nil
}

func doPrintOrg(t *genesisconfig.TopLevel, printOrg string) error {
	for _, org := range t.Organizations {
		if org.Name == printOrg {
			og, err := encoder.NewOrdererOrgGroup(org)
			if err != nil {
				return errors.Wrapf(err, "bad org definition for org %s", org.Name)
			}

			if err := protolator.DeepMarshalJSON(os.Stdout, &ordererext.DynamicOrdererOrgGroup{ConfigGroup: og}); err != nil {
				return errors.Wrapf(err, "malformed org definition for org: %s", org.Name)
			}
			return nil
		}
	}
	return errors.Errorf("organization %s not found", printOrg)
}

func main() {
	var outputBlock, outputChannelCreateTx, channelCreateTxBaseProfile, profile, configPath, channelID, inspectBlock, inspectChannelCreateTx, outputAnchorPeersUpdate, asOrg, printOrg string

	flag.StringVar(&outputBlock, "outputBlock", "", "The path to write the genesis block to (if set)")
	flag.StringVar(&channelID, "channelID", "", "The channel ID to use in the configtx")
	flag.StringVar(&outputChannelCreateTx, "outputCreateChannelTx", "", "The path to write a channel creation configtx to (if set)")
	flag.StringVar(&channelCreateTxBaseProfile, "channelCreateTxBaseProfile", "", "Specifies a profile to consider as the orderer system channel current state to allow modification of non-application parameters during channel create tx generation. Only valid in conjunction with 'outputCreateChannelTx'.")
	flag.StringVar(&profile, "profile", genesisconfig.SampleInsecureSoloProfile, "The profile from configtx.yaml to use for generation.")
	flag.StringVar(&configPath, "configPath", "", "The path containing the configuration to use (if set)")
	flag.StringVar(&inspectBlock, "inspectBlock", "", "Prints the configuration contained in the block at the specified path")
	flag.StringVar(&inspectChannelCreateTx, "inspectChannelCreateTx", "", "Prints the configuration contained in the transaction at the specified path")
	flag.StringVar(&outputAnchorPeersUpdate, "outputAnchorPeersUpdate", "", "Creates an config update to update an anchor peer (works only with the default channel creation, and only for the first update)")
	flag.StringVar(&asOrg, "asOrg", "", "Performs the config generation as a particular organization (by name), only including values in the write set that org (likely) has privilege to set")
	flag.StringVar(&printOrg, "printOrg", "", "Prints the definition of an organization as JSON. (useful for adding an org to a channel manually)")

	version := flag.Bool("version", false, "Show version information")

	flag.Parse()

	if channelID == "" && (outputBlock != "" || outputChannelCreateTx != "" || outputAnchorPeersUpdate != "") {
		logger.Fatalf("Missing channelID, please specify it with '-channelID'")
	}

	// show version
	if *version {
		printVersion()
		os.Exit(exitCode)
	}

	// don't need to panic when running via command line
	defer func() {
		if err := recover(); err != nil {
			if strings.Contains(fmt.Sprint(err), "Error reading configuration: Unsupported Config Type") {
				logger.Error("Could not find configtx.yaml. " +
					"Please make sure that FABRIC_CFG_PATH or -configPath is set to a path " +
					"which contains configtx.yaml")
				os.Exit(1)
			}
			if strings.Contains(fmt.Sprint(err), "Could not find profile") {
				logger.Error(fmt.Sprint(err) + ". " +
					"Please make sure that FABRIC_CFG_PATH or -configPath is set to a path " +
					"which contains configtx.yaml with the specified profile")
				os.Exit(1)
			}
			logger.Panic(err)
		}
	}()

	logger.Info("Loading configuration")
	factory.InitFactories(nil)
	var profileConfig *genesisconfig.Profile
	if outputBlock != "" || outputChannelCreateTx != "" || outputAnchorPeersUpdate != "" {
		if configPath != "" {
			profileConfig = genesisconfig.Load(profile, configPath)
		} else {
			profileConfig = genesisconfig.Load(profile)
		}
	}
	var topLevelConfig *genesisconfig.TopLevel
	if configPath != "" {
		topLevelConfig = genesisconfig.LoadTopLevel(configPath)
	} else {
		topLevelConfig = genesisconfig.LoadTopLevel()
	}

	var baseProfile *genesisconfig.Profile
	if channelCreateTxBaseProfile != "" {
		if outputChannelCreateTx == "" {
			logger.Warning("Specified 'channelCreateTxBaseProfile', but did not specify 'outputChannelCreateTx', 'channelCreateTxBaseProfile' will not affect output.")
		}
		if configPath != "" {
			baseProfile = genesisconfig.Load(channelCreateTxBaseProfile, configPath)
		} else {
			baseProfile = genesisconfig.Load(channelCreateTxBaseProfile)
		}
	}

	if outputBlock != "" {
		if err := doOutputBlock(profileConfig, channelID, outputBlock); err != nil {
			logger.Fatalf("Error on outputBlock: %s", err)
		}
	}

	if outputChannelCreateTx != "" {
		if err := doOutputChannelCreateTx(profileConfig, baseProfile, channelID, outputChannelCreateTx); err != nil {
			logger.Fatalf("Error on outputChannelCreateTx: %s", err)
		}
	}

	if inspectBlock != "" {
		if err := doInspectBlock(inspectBlock); err != nil {
			logger.Fatalf("Error on inspectBlock: %s", err)
		}
	}

	if inspectChannelCreateTx != "" {
		if err := doInspectChannelCreateTx(inspectChannelCreateTx); err != nil {
			logger.Fatalf("Error on inspectChannelCreateTx: %s", err)
		}
	}

	if outputAnchorPeersUpdate != "" {
		if err := doOutputAnchorPeersUpdate(profileConfig, channelID, outputAnchorPeersUpdate, asOrg); err != nil {
			logger.Fatalf("Error on inspectChannelCreateTx: %s", err)
		}
	}

	if printOrg != "" {
		if err := doPrintOrg(topLevelConfig, printOrg); err != nil {
			logger.Fatalf("Error on printOrg: %s", err)
		}
	}
}

func printVersion() {
	fmt.Println(metadata.GetVersionInfo())
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	logging "github.com/op/go-logging"
)

const (
	LOGSYS   = 1 << 0
	LOGCOLOR = 1 << 1
	LOGTIME  = 1 << 2
)

var (
	logger *logging.Logger
)

func GetLogger(name, level string, flags byte) *logging.Logger {
	log := logging.MustGetLogger(name)
	formatString := `%{level:.4s} ▶ %{shortfunc} %{message}`
	if (flags & LOGTIME) != 0 {
		formatString = `%{time:15:04:05.000} ` + formatString
	}
	if (flags & LOGCOLOR) != 0 {
		formatString = `%{color}` + formatString + `%{color:reset}`
	}
	format := logging.MustStringFormatter(formatString)

	logger := logging.AddModuleLevel(
		logging.NewBackendFormatter(logging.NewLogBackend(os.Stdout, "("+name+")", 0), format),
	)
	switch level {
	case "debug":
		logger.SetLevel(logging.DEBUG, "")
	case "info":
		logger.SetLevel(logging.INFO, "")
	case "notice":
		logger.SetLevel(logging.NOTICE, "")
	case "warning":
		logger.SetLevel(logging.WARNING, "")
	case "error":
		logger.SetLevel(logging.ERROR, "")
	default:
		logger.SetLevel(logging.INFO, "")
	}

	if (flags & LOGSYS) != 0 {
		_sysLogger, _ := logging.NewSyslogBackend(name)
		sysFormat := logging.MustStringFormatter(`%{level:.4s} %{shortfunc} ▶ %{message}`)
		sysLogger := logging.AddModuleLevel(logging.NewBackendFormatter(_sysLogger, sysFormat))
		sysLogger.SetLevel(logging.INFO, "")
		logging.SetBackend(logger, sysLogger)
	} else {
		logging.SetBackend(logger)
	}

	return log
}
<commit_msg>chore: remove shortfunc from log format<commit_after>package main

import (
	"os"

	logging "github.com/op/go-logging"
)

const (
	LOGSYS   = 1 << 0
	LOGCOLOR = 1 << 1
	LOGTIME  = 1 << 2
)

var (
	logger *logging.Logger
)

func GetLogger(name, level string, flags byte) *logging.Logger {
	log := logging.MustGetLogger(name)
	formatString := `%{level:.4s} ▶ %{message}`
	if (flags & LOGTIME) != 0 {
		formatString = `%{time:15:04:05.000} ` + formatString
	}
	if (flags & LOGCOLOR) != 0 {
		formatString = `%{color}` + formatString + `%{color:reset}`
	}
	format := logging.MustStringFormatter(formatString)

	logger := logging.AddModuleLevel(
		logging.NewBackendFormatter(logging.NewLogBackend(os.Stdout, "("+name+")", 0), format),
	)
	switch level {
	case "debug":
		logger.SetLevel(logging.DEBUG, "")
	case "info":
		logger.SetLevel(logging.INFO, "")
	case "notice":
		logger.SetLevel(logging.NOTICE, "")
	case "warning":
		logger.SetLevel(logging.WARNING, "")
	case "error":
		logger.SetLevel(logging.ERROR, "")
	default:
		logger.SetLevel(logging.INFO, "")
	}

	if (flags & LOGSYS) != 0 {
		_sysLogger, _ := logging.NewSyslogBackend(name)
		sysFormat := logging.MustStringFormatter(`%{level:.4s} ▶ %{message}`)
		sysLogger := logging.AddModuleLevel(logging.NewBackendFormatter(_sysLogger, sysFormat))
		sysLogger.SetLevel(logging.INFO, "")
		logging.SetBackend(logger, sysLogger)
	} else {
		logging.SetBackend(logger)
	}

	return log
}
<|endoftext|>


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

package boot

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"

	"github.com/u-root/u-root/pkg/boot/kexec"
	"github.com/u-root/u-root/pkg/boot/util"
	"github.com/u-root/u-root/pkg/uio"
)

// LinuxImage implements OSImage for a Linux kernel + initramfs.
type LinuxImage struct {
	Name string

	Kernel  io.ReaderAt
	Initrd  io.ReaderAt
	Cmdline string
}

var _ OSImage = &LinuxImage{}

// named is satisifed by both *os.File and *vfile.File. Hack hack hack.
type named interface {
	Name() string
}

func stringer(mod io.ReaderAt) string {
	if s, ok := mod.(fmt.Stringer); ok {
		return s.String()
	}
	if f, ok := mod.(named); ok {
		return f.Name()
	}
	return fmt.Sprintf("%T", mod)
}

// Label returns either the Name or a short description.
func (li *LinuxImage) Label() string {
	if len(li.Name) > 0 {
		return li.Name
	}
	return fmt.Sprintf("Linux(kernel=%s initrd=%s)", stringer(li.Kernel), stringer(li.Initrd))
}

// String prints a human-readable version of this linux image.
func (li *LinuxImage) String() string {
	return fmt.Sprintf("LinuxImage(\n  Name: %s\n  Kernel: %s\n  Initrd: %s\n  Cmdline: %s\n)\n", li.Name, stringer(li.Kernel), stringer(li.Initrd), li.Cmdline)
}

func copyToFile(r io.Reader) (*os.File, error) {
	f, err := ioutil.TempFile("", "linux-image")
	if err != nil {
		return nil, err
	}
	defer f.Close()
	if _, err := io.Copy(f, r); err != nil {
		return nil, err
	}
	if err := f.Sync(); err != nil {
		return nil, err
	}

	readOnlyF, err := os.Open(f.Name())
	if err != nil {
		return nil, err
	}
	return readOnlyF, nil
}

// Edit the kernel command line.
func (li *LinuxImage) Edit(f func(cmdline string) string) {
	li.Cmdline = f(li.Cmdline)
}

// Load implements OSImage.Load and kexec_load's the kernel with its initramfs.
func (li *LinuxImage) Load(verbose bool) error {
	if li.Kernel == nil {
		return errors.New("LinuxImage.Kernel must be non-nil")
	}

	kernel, initrd := uio.Reader(util.TryGzipFilter(li.Kernel)), uio.Reader(li.Initrd)
	if verbose {
		// In verbose mode, print a dot every 5MiB. It is not pretty,
		// but it at least proves the files are still downloading.
		progress := func(r io.Reader) io.Reader {
			return &uio.ProgressReader{
				R:        r,
				Symbol:   ".",
				Interval: 5 * 1024 * 1024,
				W:        os.Stdout,
			}
		}
		kernel = progress(kernel)
		initrd = progress(initrd)
	}

	// It seams inefficient to always copy, in particular when the reader
	// is an io.File but that's not sufficient, os.File could be a socket,
	// a pipe or some other strange thing. Also kexec_file_load will fail
	// (similar to execve) if anything as the file opened for writing.
	// That's unfortunately something we can't guarantee here - unless we
	// make a copy of the file and dump it somewhere.
	k, err := copyToFile(kernel)
	if err != nil {
		return err
	}
	defer k.Close()

	var i *os.File
	if li.Initrd != nil {
		i, err = copyToFile(initrd)
		if err != nil {
			return err
		}
		defer i.Close()
	}

	if verbose {
		log.Printf("Kernel: %s", k.Name())
		if i != nil {
			log.Printf("Initrd: %s", i.Name())
		}
		log.Printf("Command line: %s", li.Cmdline)
	}
	return kexec.FileLoad(k, i, li.Cmdline)
}
<commit_msg>boot.LinuxImage: new line after progress bar<commit_after>// Copyright 2018 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package boot

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"

	"github.com/u-root/u-root/pkg/boot/kexec"
	"github.com/u-root/u-root/pkg/boot/util"
	"github.com/u-root/u-root/pkg/uio"
)

// LinuxImage implements OSImage for a Linux kernel + initramfs.
type LinuxImage struct {
	Name string

	Kernel  io.ReaderAt
	Initrd  io.ReaderAt
	Cmdline string
}

var _ OSImage = &LinuxImage{}

// named is satisifed by both *os.File and *vfile.File. Hack hack hack.
type named interface {
	Name() string
}

func stringer(mod io.ReaderAt) string {
	if s, ok := mod.(fmt.Stringer); ok {
		return s.String()
	}
	if f, ok := mod.(named); ok {
		return f.Name()
	}
	return fmt.Sprintf("%T", mod)
}

// Label returns either the Name or a short description.
func (li *LinuxImage) Label() string {
	if len(li.Name) > 0 {
		return li.Name
	}
	return fmt.Sprintf("Linux(kernel=%s initrd=%s)", stringer(li.Kernel), stringer(li.Initrd))
}

// String prints a human-readable version of this linux image.
func (li *LinuxImage) String() string {
	return fmt.Sprintf("LinuxImage(\n  Name: %s\n  Kernel: %s\n  Initrd: %s\n  Cmdline: %s\n)\n", li.Name, stringer(li.Kernel), stringer(li.Initrd), li.Cmdline)
}

func copyToFile(r io.Reader) (*os.File, error) {
	f, err := ioutil.TempFile("", "linux-image")
	if err != nil {
		return nil, err
	}
	defer f.Close()
	if _, err := io.Copy(f, r); err != nil {
		return nil, err
	}
	if err := f.Sync(); err != nil {
		return nil, err
	}

	readOnlyF, err := os.Open(f.Name())
	if err != nil {
		return nil, err
	}
	return readOnlyF, nil
}

// Edit the kernel command line.
func (li *LinuxImage) Edit(f func(cmdline string) string) {
	li.Cmdline = f(li.Cmdline)
}

// Load implements OSImage.Load and kexec_load's the kernel with its initramfs.
func (li *LinuxImage) Load(verbose bool) error {
	if li.Kernel == nil {
		return errors.New("LinuxImage.Kernel must be non-nil")
	}

	kernel, initrd := uio.Reader(util.TryGzipFilter(li.Kernel)), uio.Reader(li.Initrd)
	if verbose {
		// In verbose mode, print a dot every 5MiB. It is not pretty,
		// but it at least proves the files are still loading.
		progress := func(r io.Reader) io.Reader {
			return &uio.ProgressReader{
				R:        r,
				Symbol:   ".",
				Interval: 5 * 1024 * 1024,
				W:        os.Stdout,
			}
		}
		kernel = progress(kernel)
		initrd = progress(initrd)
	}

	// It seams inefficient to always copy, in particular when the reader
	// is an io.File but that's not sufficient, os.File could be a socket,
	// a pipe or some other strange thing. Also kexec_file_load will fail
	// (similar to execve) if anything as the file opened for writing.
	// That's unfortunately something we can't guarantee here - unless we
	// make a copy of the file and dump it somewhere.
	k, err := copyToFile(kernel)
	if err != nil {
		return err
	}
	defer k.Close()
	if verbose {
		os.Stdout.Write([]byte("\n"))
	}

	var i *os.File
	if li.Initrd != nil {
		i, err = copyToFile(initrd)
		if err != nil {
			return err
		}
		defer i.Close()
		if verbose {
			os.Stdout.Write([]byte("\n"))
		}
	}

	if verbose {
		log.Printf("Kernel: %s", k.Name())
		if i != nil {
			log.Printf("Initrd: %s", i.Name())
		}
		log.Printf("Command line: %s", li.Cmdline)
	}
	return kexec.FileLoad(k, i, li.Cmdline)
}
<|endoftext|>


<commit_before>package mdata

import (
	"testing"
	"time"

	"github.com/grafana/metrictank/cluster"
	"github.com/grafana/metrictank/conf"
	"github.com/grafana/metrictank/mdata/cache"
	"github.com/grafana/metrictank/schema"
	"github.com/grafana/metrictank/test"
)

type testcase struct {
	ts       uint32
	span     uint32
	boundary uint32
}

func TestAggBoundary(t *testing.T) {
	cases := []testcase{
		{1, 120, 120},
		{50, 120, 120},
		{118, 120, 120},
		{119, 120, 120},
		{120, 120, 120},
		{121, 120, 240},
		{122, 120, 240},
		{150, 120, 240},
		{237, 120, 240},
		{238, 120, 240},
		{239, 120, 240},
		{240, 120, 240},
		{241, 120, 360},
	}
	for _, c := range cases {
		if ret := AggBoundary(c.ts, c.span); ret != c.boundary {
			t.Fatalf("aggBoundary for ts %d with span %d should be %d, not %d", c.ts, c.span, c.boundary, ret)
		}
	}
}

// note that values don't get "committed" to the metric until the aggregation interval is complete
func TestAggregator(t *testing.T) {
	cluster.Init("default", "test", time.Now(), "http", 6060)
	compare := func(key string, metric Metric, expected []schema.Point) {
		cluster.Manager.SetPrimary(true)
		res, err := metric.Get(0, 1000)

		if err != nil {
			t.Fatalf("expected err nil, got %v", err)
		}

		got := make([]schema.Point, 0, len(expected))
		for _, iter := range res.Iters {
			for iter.Next() {
				ts, val := iter.Values()
				got = append(got, schema.Point{Val: val, Ts: ts})
			}
		}
		if len(got) != len(expected) {
			t.Fatalf("output for testcase %s mismatch: expected: %v points, got: %v", key, len(expected), len(got))

		} else {
			for i, g := range got {
				exp := expected[i]
				if exp.Val != g.Val || exp.Ts != g.Ts {
					t.Fatalf("output for testcase %s mismatch at point %d: expected: %v, got: %v", key, i, exp, g)
				}
			}
		}
		cluster.Manager.SetPrimary(false)
	}
	ret := conf.NewRetentionMT(60, 86400, 120, 10, 0)
	aggs := conf.Aggregation{
		AggregationMethod: []conf.Method{conf.Avg, conf.Min, conf.Max, conf.Sum, conf.Lst},
	}

	agg := NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(0), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	expected := []schema.Point{}
	compare("simple-min-unfinished", agg.minMetric, expected)

	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	agg.Add(130, 130)
	expected = []schema.Point{
		{Val: 5, Ts: 120},
	}
	compare("simple-min-one-block", agg.minMetric, expected)

	// points with a timestamp belonging to the previous aggregation are ignored
	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	agg.Add(130, 130)
	agg.Add(90, 24)
	expected = []schema.Point{
		{Val: 5, Ts: 120},
	}
	compare("simple-min-ignore-back-in-time", agg.minMetric, expected)

	// chunkspan is 120, ingestFrom = 140 means points before chunk starting at 240 are discarded
	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret, aggs, false, 140)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	// this point is not flushed to agg.minMetric because no point after it with a timestamp
	// crossing the aggregation boundary is added (aggregation span here is 60)
	agg.Add(130, 130)
	expected = []schema.Point{}
	compare("simple-min-ingest-from-all-before-next-chunk", agg.minMetric, expected)

	// chunkspan is 120, ingestFrom = 115 means points before chunk starting at 120 are discarded
	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret, aggs, false, 115)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	// this point is not flushed to agg.minMetric for the same reason as in the previous test
	agg.Add(130, 130)
	expected = []schema.Point{
		{Val: 5, Ts: 120},
	}
	compare("simple-min-ingest-from-one-in-next-chunk", agg.minMetric, expected)

	// chunkspan is 120, ingestFrom = 120 means points before chunk starting at 120 are discarded
	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret, aggs, false, 120)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	// this point is not flushed to agg.minMetric for the same reason as in the previous test
	agg.Add(130, 130)
	expected = []schema.Point{
		{Val: 5, Ts: 120},
	}
	compare("simple-min-ingest-from-on-chunk-boundary", agg.minMetric, expected)

	// chunkspan is 120, ingestFrom = 170 means points before chunk starting at 240 are discarded
	// but, each aggregation contains 60s of data, so the point at 240 covers raw data from 181..240

	// raw data         :   1..120 121..180 181..240 241..300 301..360
	// discarded data   :   xxxxxxxxxxxxxxxx
	// aggregated points:      120      180      240      300      360
	// chunks by t0     :      120               240      300      360
	// discarded chunk  :   xxxxxxxxxxxxxxxxxxxxx
	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret, aggs, false, 170)
	agg.Add(1, 1.1)
	agg.Add(119, 119)
	agg.Add(120, 120)
	agg.Add(121, 121)
	agg.Add(179, 179)
	agg.Add(180, 180)
	agg.Add(181, 181)
	agg.Add(220, 220)
	agg.Add(230, 230)
	agg.Add(231, 231)
	agg.Add(233, 233)
	agg.Add(239, 239)
	agg.Add(240, 240)
	agg.Add(245, 245)
	agg.Add(249, 249)
	agg.Add(250, 250)
	agg.Add(299, 299)
	agg.Add(300, 300)
	// these points are not flushed to agg.sumMetric for the same reason as in the previous test
	agg.Add(301, 0)
	agg.Add(320, 0)

	expected = []schema.Point{
		{Val: 181 + 220 + 230 + 231 + 233 + 239 + 240, Ts: 240},
		{Val: 245 + 249 + 250 + 299 + 300, Ts: 300},
	}
	compare("multi-sum-ingest-from-one-in-next-chunk", agg.sumMetric, expected)

	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(2), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	agg.Add(120, 4)
	expected = []schema.Point{
		{Val: 4, Ts: 120},
	}
	compare("simple-min-one-block-done-cause-last-point-just-right", agg.minMetric, expected)

	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(3), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	agg.Add(150, 1.123)
	agg.Add(180, 1)
	expected = []schema.Point{
		{Val: 5, Ts: 120},
		{Val: 1, Ts: 180},
	}
	compare("simple-min-two-blocks-done-cause-last-point-just-right", agg.minMetric, expected)

	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(4), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	agg.Add(190, 2451.123)
	agg.Add(200, 1451.123)
	agg.Add(220, 978894.445)
	agg.Add(250, 1)
	compare("simple-min-skip-a-block", agg.minMetric, []schema.Point{
		{Val: 5, Ts: 120},
		{Val: 1451.123, Ts: 240},
	})
	compare("simple-max-skip-a-block", agg.maxMetric, []schema.Point{
		{Val: 123.4, Ts: 120},
		{Val: 978894.445, Ts: 240},
	})
	compare("simple-cnt-skip-a-block", agg.cntMetric, []schema.Point{
		{Val: 2, Ts: 120},
		{Val: 3, Ts: 240},
	})
	compare("simple-lst-skip-a-block", agg.lstMetric, []schema.Point{
		{Val: 5, Ts: 120},
		{Val: 978894.445, Ts: 240},
	})
	compare("simple-sum-skip-a-block", agg.sumMetric, []schema.Point{
		{Val: 128.4, Ts: 120},
		{Val: 2451.123 + 1451.123 + 978894.445, Ts: 240},
	})

}
<commit_msg>fix build.<commit_after>package mdata

import (
	"testing"
	"time"

	"github.com/grafana/metrictank/cluster"
	"github.com/grafana/metrictank/conf"
	"github.com/grafana/metrictank/mdata/cache"
	"github.com/grafana/metrictank/schema"
	"github.com/grafana/metrictank/test"
)

type testcase struct {
	ts       uint32
	span     uint32
	boundary uint32
}

func TestAggBoundary(t *testing.T) {
	cases := []testcase{
		{1, 120, 120},
		{50, 120, 120},
		{118, 120, 120},
		{119, 120, 120},
		{120, 120, 120},
		{121, 120, 240},
		{122, 120, 240},
		{150, 120, 240},
		{237, 120, 240},
		{238, 120, 240},
		{239, 120, 240},
		{240, 120, 240},
		{241, 120, 360},
	}
	for _, c := range cases {
		if ret := AggBoundary(c.ts, c.span); ret != c.boundary {
			t.Fatalf("aggBoundary for ts %d with span %d should be %d, not %d", c.ts, c.span, c.boundary, ret)
		}
	}
}

// note that values don't get "committed" to the metric until the aggregation interval is complete
func TestAggregator(t *testing.T) {
	cluster.Init("default", "test", time.Now(), "http", 6060)
	compare := func(key string, metric Metric, expected []schema.Point) {
		cluster.Manager.SetPrimary(true)
		res, err := metric.Get(0, 1000)

		if err != nil {
			t.Fatalf("expected err nil, got %v", err)
		}

		got := make([]schema.Point, 0, len(expected))
		for _, iter := range res.Iters {
			for iter.Next() {
				ts, val := iter.Values()
				got = append(got, schema.Point{Val: val, Ts: ts})
			}
		}
		if len(got) != len(expected) {
			t.Fatalf("output for testcase %s mismatch: expected: %v points, got: %v", key, len(expected), len(got))

		} else {
			for i, g := range got {
				exp := expected[i]
				if exp.Val != g.Val || exp.Ts != g.Ts {
					t.Fatalf("output for testcase %s mismatch at point %d: expected: %v, got: %v", key, i, exp, g)
				}
			}
		}
		cluster.Manager.SetPrimary(false)
	}
	ret := conf.NewRetentionMT(60, 86400, 120, 10, 0)
	aggs := conf.Aggregation{
		AggregationMethod: []conf.Method{conf.Avg, conf.Min, conf.Max, conf.Sum, conf.Lst},
	}

	agg := NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(0), ret.String(), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	expected := []schema.Point{}
	compare("simple-min-unfinished", agg.minMetric, expected)

	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret.String(), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	agg.Add(130, 130)
	expected = []schema.Point{
		{Val: 5, Ts: 120},
	}
	compare("simple-min-one-block", agg.minMetric, expected)

	// points with a timestamp belonging to the previous aggregation are ignored
	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret.String(), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	agg.Add(130, 130)
	agg.Add(90, 24)
	expected = []schema.Point{
		{Val: 5, Ts: 120},
	}
	compare("simple-min-ignore-back-in-time", agg.minMetric, expected)

	// chunkspan is 120, ingestFrom = 140 means points before chunk starting at 240 are discarded
	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret.String(), ret, aggs, false, 140)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	// this point is not flushed to agg.minMetric because no point after it with a timestamp
	// crossing the aggregation boundary is added (aggregation span here is 60)
	agg.Add(130, 130)
	expected = []schema.Point{}
	compare("simple-min-ingest-from-all-before-next-chunk", agg.minMetric, expected)

	// chunkspan is 120, ingestFrom = 115 means points before chunk starting at 120 are discarded
	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret.String(), ret, aggs, false, 115)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	// this point is not flushed to agg.minMetric for the same reason as in the previous test
	agg.Add(130, 130)
	expected = []schema.Point{
		{Val: 5, Ts: 120},
	}
	compare("simple-min-ingest-from-one-in-next-chunk", agg.minMetric, expected)

	// chunkspan is 120, ingestFrom = 120 means points before chunk starting at 120 are discarded
	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret.String(), ret, aggs, false, 120)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	// this point is not flushed to agg.minMetric for the same reason as in the previous test
	agg.Add(130, 130)
	expected = []schema.Point{
		{Val: 5, Ts: 120},
	}
	compare("simple-min-ingest-from-on-chunk-boundary", agg.minMetric, expected)

	// chunkspan is 120, ingestFrom = 170 means points before chunk starting at 240 are discarded
	// but, each aggregation contains 60s of data, so the point at 240 covers raw data from 181..240

	// raw data         :   1..120 121..180 181..240 241..300 301..360
	// discarded data   :   xxxxxxxxxxxxxxxx
	// aggregated points:      120      180      240      300      360
	// chunks by t0     :      120               240      300      360
	// discarded chunk  :   xxxxxxxxxxxxxxxxxxxxx
	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(1), ret.String(), ret, aggs, false, 170)
	agg.Add(1, 1.1)
	agg.Add(119, 119)
	agg.Add(120, 120)
	agg.Add(121, 121)
	agg.Add(179, 179)
	agg.Add(180, 180)
	agg.Add(181, 181)
	agg.Add(220, 220)
	agg.Add(230, 230)
	agg.Add(231, 231)
	agg.Add(233, 233)
	agg.Add(239, 239)
	agg.Add(240, 240)
	agg.Add(245, 245)
	agg.Add(249, 249)
	agg.Add(250, 250)
	agg.Add(299, 299)
	agg.Add(300, 300)
	// these points are not flushed to agg.sumMetric for the same reason as in the previous test
	agg.Add(301, 0)
	agg.Add(320, 0)

	expected = []schema.Point{
		{Val: 181 + 220 + 230 + 231 + 233 + 239 + 240, Ts: 240},
		{Val: 245 + 249 + 250 + 299 + 300, Ts: 300},
	}
	compare("multi-sum-ingest-from-one-in-next-chunk", agg.sumMetric, expected)

	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(2), ret.String(), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	agg.Add(120, 4)
	expected = []schema.Point{
		{Val: 4, Ts: 120},
	}
	compare("simple-min-one-block-done-cause-last-point-just-right", agg.minMetric, expected)

	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(3), ret.String(), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	agg.Add(150, 1.123)
	agg.Add(180, 1)
	expected = []schema.Point{
		{Val: 5, Ts: 120},
		{Val: 1, Ts: 180},
	}
	compare("simple-min-two-blocks-done-cause-last-point-just-right", agg.minMetric, expected)

	agg = NewAggregator(mockstore, &cache.MockCache{}, test.GetAMKey(4), ret.String(), ret, aggs, false, 0)
	agg.Add(100, 123.4)
	agg.Add(110, 5)
	agg.Add(190, 2451.123)
	agg.Add(200, 1451.123)
	agg.Add(220, 978894.445)
	agg.Add(250, 1)
	compare("simple-min-skip-a-block", agg.minMetric, []schema.Point{
		{Val: 5, Ts: 120},
		{Val: 1451.123, Ts: 240},
	})
	compare("simple-max-skip-a-block", agg.maxMetric, []schema.Point{
		{Val: 123.4, Ts: 120},
		{Val: 978894.445, Ts: 240},
	})
	compare("simple-cnt-skip-a-block", agg.cntMetric, []schema.Point{
		{Val: 2, Ts: 120},
		{Val: 3, Ts: 240},
	})
	compare("simple-lst-skip-a-block", agg.lstMetric, []schema.Point{
		{Val: 5, Ts: 120},
		{Val: 978894.445, Ts: 240},
	})
	compare("simple-sum-skip-a-block", agg.sumMetric, []schema.Point{
		{Val: 128.4, Ts: 120},
		{Val: 2451.123 + 1451.123 + 978894.445, Ts: 240},
	})

}
<|endoftext|>


<commit_before>package request

import (
	"io/ioutil"
	"net/http"
	"time"
)

type Options struct {
	Url string
}

type Request struct {
	client  *http.Client
	Timeout time.Duration
}

func (r *Request) Get(o *Options) {

}

func Get(o *Options) {

}

func (r *Request) doRequest(m string, o *Options) (*http.Response, []byte, error) {
	req, err := http.NewRequest(m, o.Url, nil)

	if err != nil {
		panic(err)
	}

	resp, err := r.client.Do(req)

	defer resp.Body.Close()

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

	body, err := ioutil.ReadAll(resp.Body)

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

	return resp, body, nil
}
<commit_msg>Added function for getting a single instance.<commit_after>package request

import (
	"io/ioutil"
	"net/http"
	"time"
)

var instance *Request

type Options struct {
	Url string
}

type Request struct {
	client  *http.Client
	Timeout time.Duration
}

func (r *Request) Get(o *Options) {

}

func Get(o *Options) {

}

// ********** Private methods/functions **********
// REMARKS: Used internally by non-instance methods
func getInstance() *Request {
	if instance == nil {
		instance = New()
	}

	return instance
}

func (r *Request) doRequest(m string, o *Options) (*http.Response, []byte, error) {
	req, err := http.NewRequest(m, o.Url, nil)

	if err != nil {
		panic(err)
	}

	resp, err := r.client.Do(req)

	defer resp.Body.Close()

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

	body, err := ioutil.ReadAll(resp.Body)

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

	return resp, body, nil
}
<|endoftext|>


<commit_before>package models

import (
	"time"

	"github.com/dockercn/wharf/utils"
)

const (
	TYPE_WEB = iota
	TYPE_API
)

const (
	LEVELEMERGENCY = iota
	LevelALERT
	LEVELCRITICAL
	LEVELERROR
	LEVELWARNING
	LEVELNOTICE
	LEVELINFORMATIONAL
	LEVELDEBUG
)

const (
	ACTION_SIGNUP = iota
	ACTION_SIGNIN
	ACTION_SINGOUT
	ACTION_UPDATE_PROFILE
	ACTION_UPDATE_PASSWORD
	ACTION_ADD_REPO
	ACTION_GET_REPO
	ACTION_UPDATE_REPO
	ACTION_PUT_REPO_IMAGES
	ACTION_PUT_TAG
	ACTION_PUT_IMAGES_JSON
	ACTION_PUT_IMAGES_LAYER
	ACTION_PUT_IMAGES_CHECKSUM
	ACTION_REMOVE_REPO
	ACTION_ADD_COMMENT
	ACTION_REMOVE_COMMENT
	ACTION_ADD_ORG
	ACTION_UPDATE_ORG
	ACTION_REMOVE_ORG
	ACTION_ADD_TEAM
	ACTION_REMOVE_TEAM
	ACTION_ADD_PRIVILEGE
	ACTION_REMOVE_PRIVILEGE
	ACTION_ADD_STAR
	ACTION_REMOVE_STAR
)

type Log struct {
	UUID       string `json:"UUID"`       //
	Action     int64  `json:"action"`     //
	ActionUUID string `json:"actionuuid"` //
	Level      int64  `json:"level"`      //
	Type       int64  `json:"type"`       //
	Content    string `json:"content"`    //
	Created    int64  `json:"created"`    //
}

type EmailMessage struct {
	UUID     string   `json:"UUID"`     //
	User     string   `json:"user"`     //
	Server   string   `json:"server"`   //
	Template string   `json:"template"` //
	Object   string   `json:"object"`   //
	Message  string   `json:"message"`  //
	Status   string   `json:"status"`   //
	Count    int64    `json:"count"`    //
	Created  int64    `json:"created"`  //
	Updated  int64    `json:"updated"`  //
	Memo     []string `json:"memo"`     //
}

type EmailServer struct {
	UUID     string   `json:"UUID"`    //
	Name     string   `json:"name"`    //
	Host     string   `json:"host"`    //
	Port     int64    `json:"port"`    //
	User     string   `json:"user"`    //
	Password string   `json:"passwd"`  //
	API      string   `json:"api"`     //
	Created  int64    `json:"created"` //
	Updated  int64    `json:"updated"` //
	Memo     []string `json:"memo"`    //
}

type EmailTemplate struct {
	UUID    string   `json:"UUID"`    //
	Server  int64    `json:"server"`  //
	Name    string   `json:"name"`    //
	Content string   `json:"content"` //
	Created int64    `json:"created"` //
	Updated int64    `json:"updated"` //
	Memo    []string `json:"memo"`    //
}

func (l *Log) Has(uuid string) (bool, []byte, error) {
	if len(uuid) <= 0 {
		return false, nil, nil
	}

	err := Get(l, []byte(uuid))

	return true, []byte(uuid), err
}

func (l *Log) Save() error {
	if err := Save(l, []byte(l.UUID)); err != nil {
		return err
	}

	if _, err := LedisDB.HSet([]byte(GLOBAL_LOG_INDEX), []byte(l.UUID), []byte(l.UUID)); err != nil {
		return err
	}

	return nil
}

func (user *User) Log(action, level, t int64, actionUUID string, content []byte) error {
	log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().Unix()}
	log.UUID = string(utils.GeneralKey(actionUUID))

	if err := log.Save(); err != nil {
		return err
	}

	user.Memo = append(user.Memo, log.UUID)

	if err := user.Save(); err != nil {
		return err
	}

	return nil
}

func (admin *Admin) Log(action, level, t int64, actionUUID string, content []byte) error {
	log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().Unix()}
	log.UUID = string(utils.GeneralKey(actionUUID))

	if err := log.Save(); err != nil {
		return err
	}

	admin.Memo = append(admin.Memo, log.UUID)

	if err := admin.Save(); err != nil {
		return err
	}

	return nil
}

func (org *Organization) Log(action, level, t int64, actionUUID string, content []byte) error {
	log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().Unix()}
	log.UUID = string(utils.GeneralKey(actionUUID))

	if err := log.Save(); err != nil {
		return err
	}

	org.Memo = append(org.Memo, log.UUID)

	if err := org.Save(); err != nil {
		return err
	}

	return nil
}

func (team *Team) Log(action, level, t int64, actionUUID string, content []byte) error {
	log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().Unix()}
	log.UUID = string(utils.GeneralKey(actionUUID))

	if err := log.Save(); err != nil {
		return err
	}

	team.Memo = append(team.Memo, log.UUID)

	if err := team.Save(); err != nil {
		return err
	}

	return nil
}

func (repo *Repository) Log(action, level, t int64, actionUUID string, content []byte) error {
	log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().Unix()}
	log.UUID = string(utils.GeneralKey(actionUUID))

	if err := log.Save(); err != nil {
		return err
	}

	repo.Memo = append(repo.Memo, log.UUID)

	if err := repo.Save(); err != nil {
		return err
	}

	return nil
}

func (compose *Compose) Log(action, level, t int64, actionUUID string, content []byte) error {
	log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().Unix()}
	log.UUID = string(utils.GeneralKey(actionUUID))

	if err := log.Save(); err != nil {
		return err
	}

	compose.Memo = append(compose.Memo, log.UUID)

	if err := compose.Save(); err != nil {
		return err
	}

	return nil
}

func (image *Image) Log(action, level, t int64, actionUUID string, content []byte) error {
	log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().Unix()}
	log.UUID = string(utils.GeneralKey(actionUUID))

	if err := log.Save(); err != nil {
		return err
	}

	image.Memo = append(image.Memo, log.UUID)

	if err := image.Save(); err != nil {
		return err
	}

	return nil
}

func (star *Star) Log(action, level, t int64, actionUUID string, content []byte) error {
	log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().Unix()}
	log.UUID = string(utils.GeneralKey(actionUUID))

	if err := log.Save(); err != nil {
		return err
	}

	star.Memo = append(star.Memo, log.UUID)

	if err := star.Save(); err != nil {
		return err
	}

	return nil
}

func (comment *Comment) Log(action, level, t int64, actionUUID string, content []byte) error {
	log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().Unix()}
	log.UUID = string(utils.GeneralKey(actionUUID))

	if err := log.Save(); err != nil {
		return err
	}

	comment.Memo = append(comment.Memo, log.UUID)

	if err := comment.Save(); err != nil {
		return err
	}

	return nil
}

func (p *Privilege) Log(action, level, t int64, actionUUID string, content []byte) error {
	log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().Unix()}
	log.UUID = string(utils.GeneralKey(actionUUID))

	if err := log.Save(); err != nil {
		return err
	}

	p.Memo = append(p.Memo, log.UUID)

	if err := p.Save(); err != nil {
		return err
	}

	return nil
}
<commit_msg>Add Version V1 & V2 const.<commit_after>package models

import (
  "time"

  "github.com/dockercn/wharf/utils"
)

const (
  APIVERSION_V1 = iota
  APIVERSION_V2
)

const (
  TYPE_WEB = iota
  TYPE_API
)

const (
  LEVELEMERGENCY = iota
  LevelALERT
  LEVELCRITICAL
  LEVELERROR
  LEVELWARNING
  LEVELNOTICE
  LEVELINFORMATIONAL
  LEVELDEBUG
)

const (
  ACTION_SIGNUP = iota
  ACTION_SIGNIN
  ACTION_SINGOUT
  ACTION_UPDATE_PROFILE
  ACTION_UPDATE_PASSWORD
  ACTION_ADD_REPO
  ACTION_GET_REPO
  ACTION_UPDATE_REPO
  ACTION_PUT_REPO_IMAGES
  ACTION_PUT_TAG
  ACTION_PUT_IMAGES_JSON
  ACTION_PUT_IMAGES_LAYER
  ACTION_PUT_IMAGES_CHECKSUM
  ACTION_REMOVE_REPO
  ACTION_ADD_COMMENT
  ACTION_REMOVE_COMMENT
  ACTION_ADD_ORG
  ACTION_UPDATE_ORG
  ACTION_REMOVE_ORG
  ACTION_ADD_TEAM
  ACTION_REMOVE_TEAM
  ACTION_ADD_PRIVILEGE
  ACTION_REMOVE_PRIVILEGE
  ACTION_ADD_STAR
  ACTION_REMOVE_STAR
)

type Log struct {
  UUID       string `json:"UUID"`       //
  Action     int64  `json:"action"`     //
  ActionUUID string `json:"actionuuid"` //
  Level      int64  `json:"level"`      //
  Type       int64  `json:"type"`       //
  Content    string `json:"content"`    //
  Created    int64  `json:"created"`    //
}

type EmailMessage struct {
  UUID     string   `json:"UUID"`     //
  User     string   `json:"user"`     //
  Server   string   `json:"server"`   //
  Template string   `json:"template"` //
  Object   string   `json:"object"`   //
  Message  string   `json:"message"`  //
  Status   string   `json:"status"`   //
  Count    int64    `json:"count"`    //
  Created  int64    `json:"created"`  //
  Updated  int64    `json:"updated"`  //
  Memo     []string `json:"memo"`     //
}

type EmailServer struct {
  UUID     string   `json:"UUID"`    //
  Name     string   `json:"name"`    //
  Host     string   `json:"host"`    //
  Port     int64    `json:"port"`    //
  User     string   `json:"user"`    //
  Password string   `json:"passwd"`  //
  API      string   `json:"api"`     //
  Created  int64    `json:"created"` //
  Updated  int64    `json:"updated"` //
  Memo     []string `json:"memo"`    //
}

type EmailTemplate struct {
  UUID    string   `json:"UUID"`    //
  Server  int64    `json:"server"`  //
  Name    string   `json:"name"`    //
  Content string   `json:"content"` //
  Created int64    `json:"created"` //
  Updated int64    `json:"updated"` //
  Memo    []string `json:"memo"`    //
}

func (l *Log) Has(uuid string) (bool, []byte, error) {
  if len(uuid) <= 0 {
    return false, nil, nil
  }

  err := Get(l, []byte(uuid))

  return true, []byte(uuid), err
}

func (l *Log) Save() error {
  if err := Save(l, []byte(l.UUID)); err != nil {
    return err
  }

  if _, err := LedisDB.HSet([]byte(GLOBAL_LOG_INDEX), []byte(l.UUID), []byte(l.UUID)); err != nil {
    return err
  }

  return nil
}

func (user *User) Log(action, level, t int64, actionUUID string, content []byte) error {
  log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().UnixNano() / int64(time.Millisecond)}
  log.UUID = string(utils.GeneralKey(actionUUID))

  if err := log.Save(); err != nil {
    return err
  }

  user.Memo = append(user.Memo, log.UUID)

  if err := user.Save(); err != nil {
    return err
  }

  return nil
}

func (admin *Admin) Log(action, level, t int64, actionUUID string, content []byte) error {
  log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().UnixNano() / int64(time.Millisecond)}
  log.UUID = string(utils.GeneralKey(actionUUID))

  if err := log.Save(); err != nil {
    return err
  }

  admin.Memo = append(admin.Memo, log.UUID)

  if err := admin.Save(); err != nil {
    return err
  }

  return nil
}

func (org *Organization) Log(action, level, t int64, actionUUID string, content []byte) error {
  log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().UnixNano() / int64(time.Millisecond)}
  log.UUID = string(utils.GeneralKey(actionUUID))

  if err := log.Save(); err != nil {
    return err
  }

  org.Memo = append(org.Memo, log.UUID)

  if err := org.Save(); err != nil {
    return err
  }

  return nil
}

func (team *Team) Log(action, level, t int64, actionUUID string, content []byte) error {
  log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().UnixNano() / int64(time.Millisecond)}
  log.UUID = string(utils.GeneralKey(actionUUID))

  if err := log.Save(); err != nil {
    return err
  }

  team.Memo = append(team.Memo, log.UUID)

  if err := team.Save(); err != nil {
    return err
  }

  return nil
}

func (repo *Repository) Log(action, level, t int64, actionUUID string, content []byte) error {
  log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().UnixNano() / int64(time.Millisecond)}
  log.UUID = string(utils.GeneralKey(actionUUID))

  if err := log.Save(); err != nil {
    return err
  }

  repo.Memo = append(repo.Memo, log.UUID)

  if err := repo.Save(); err != nil {
    return err
  }

  return nil
}

func (compose *Compose) Log(action, level, t int64, actionUUID string, content []byte) error {
  log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().UnixNano() / int64(time.Millisecond)}
  log.UUID = string(utils.GeneralKey(actionUUID))

  if err := log.Save(); err != nil {
    return err
  }

  compose.Memo = append(compose.Memo, log.UUID)

  if err := compose.Save(); err != nil {
    return err
  }

  return nil
}

func (image *Image) Log(action, level, t int64, actionUUID string, content []byte) error {
  log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().UnixNano() / int64(time.Millisecond)}
  log.UUID = string(utils.GeneralKey(actionUUID))

  if err := log.Save(); err != nil {
    return err
  }

  image.Memo = append(image.Memo, log.UUID)

  if err := image.Save(); err != nil {
    return err
  }

  return nil
}

func (star *Star) Log(action, level, t int64, actionUUID string, content []byte) error {
  log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().UnixNano() / int64(time.Millisecond)}
  log.UUID = string(utils.GeneralKey(actionUUID))

  if err := log.Save(); err != nil {
    return err
  }

  star.Memo = append(star.Memo, log.UUID)

  if err := star.Save(); err != nil {
    return err
  }

  return nil
}

func (comment *Comment) Log(action, level, t int64, actionUUID string, content []byte) error {
  log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().UnixNano() / int64(time.Millisecond)}
  log.UUID = string(utils.GeneralKey(actionUUID))

  if err := log.Save(); err != nil {
    return err
  }

  comment.Memo = append(comment.Memo, log.UUID)

  if err := comment.Save(); err != nil {
    return err
  }

  return nil
}

func (p *Privilege) Log(action, level, t int64, actionUUID string, content []byte) error {
  log := Log{Action: action, ActionUUID: actionUUID, Level: level, Type: t, Content: string(content), Created: time.Now().UnixNano() / int64(time.Millisecond)}
  log.UUID = string(utils.GeneralKey(actionUUID))

  if err := log.Save(); err != nil {
    return err
  }

  p.Memo = append(p.Memo, log.UUID)

  if err := p.Save(); err != nil {
    return err
  }

  return nil
}
<|endoftext|>


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

package core

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"time"
	"bufio"
	"os"
	"strings"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
	istioNamespace  = "istio-system"
	istioRelease    = "https://storage.googleapis.com/riff-releases/istio/istio-1.0.0-riff.yaml"
	servingRelease  = "https://storage.googleapis.com/knative-releases/serving/previous/v20180809-6b01d8e/release-no-mon.yaml"
	eventingRelease = "https://storage.googleapis.com/knative-releases/eventing/previous/v20180809-34ab480/release.yaml"
	stubBusRelease  = "https://storage.googleapis.com/knative-releases/eventing/previous/v20180809-34ab480/release-clusterbus-stub.yaml"
)

type SystemInstallOptions struct {
	NodePort bool
	Force bool
}

type SystemUninstallOptions struct {
	Istio bool
	Force bool
}

var (
	knativeNamespaces = []string{"knative-eventing", "knative-serving", "knative-build"}
	allNameSpaces     = append(knativeNamespaces, istioNamespace)
)

func (kc *kubectlClient) SystemInstall(options SystemInstallOptions) (bool, error) {

	err := ensureNotTerminating(kc, allNameSpaces, "Please try again later.")
	if err != nil {
		return false, err
	}

	istioStatus, err := getNamespaceStatus(kc,istioNamespace)
	if istioStatus == "'NotFound'" {
		fmt.Print("Installing Istio Components\n")
		istioYaml, err := loadRelease(istioRelease)
		if err != nil {
			return false, err
		}
		if options.NodePort {
			istioYaml = bytes.Replace(istioYaml, []byte("LoadBalancer"), []byte("NodePort"), -1)
		}
		fmt.Printf("Applying resources defined in: %s\n", istioRelease)
		istioLog, err := kc.kubeCtl.ExecStdin([]string{"apply", "-f", "-"}, &istioYaml)
		if err != nil {
			fmt.Printf("%s\n", istioLog)
			return false, err
		}

		fmt.Print("Istio for riff installed\n\n")
	} else {
		if !options.Force {
			answer, err := confirm("Istio is already installed, do you want to install the Knative components for riff?")
			if err != nil {
				return false, err
			}
			if !answer {
				return false, nil
			}
		}
	}

	err = waitForIstioComponents(kc)
	if err != nil {
		return false, err
	}

	fmt.Print("Installing Knative Components\n")

	servingYaml, err := loadRelease(servingRelease)
	if err != nil {
		return false, err
	}
	if options.NodePort {
		servingYaml = bytes.Replace(servingYaml, []byte("LoadBalancer"), []byte("NodePort"), -1)
	}
	fmt.Printf("Applying resources defined in: %s\n", servingRelease)
	servingLog, err := kc.kubeCtl.ExecStdin([]string{"apply", "-f", "-"}, &servingYaml)
	if err != nil {
		fmt.Printf("%s\n", servingLog)
		return false, err
	}

	applyResources(kc, eventingRelease)

	applyResources(kc, stubBusRelease)

	fmt.Print("Knative for riff installed\n\n")
	return true, nil
}

func (kc *kubectlClient) SystemUninstall(options SystemUninstallOptions) (bool, error) {

	err := ensureNotTerminating(kc, allNameSpaces, "This would indicate that the system was already uninstalled.")
	if err != nil {
		return false, err
	}
	knativeNsCount, err := checkNamespacesExists(kc, knativeNamespaces)
	istioNsCount, err := checkNamespacesExists(kc, []string{istioNamespace})
	if err != nil {
		return false, err
	}
	if knativeNsCount == 0 {
		fmt.Print("No Knative components for riff found\n")
	} else {
		if !options.Force {
			answer, err := confirm("Are you sure you want to uninstall the riff system?")
			if err != nil {
				return false, err
			}
			if !answer {
				return false, nil
			}
		}
		fmt.Print("Removing Knative for riff components\n")
		err = deleteCrds(kc, "knative.dev")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrolebinding", "knative-")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrolebinding", "build-controller-")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrolebinding", "eventing-controller-")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrolebinding", "clusterbus-controller-")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrole", "knative-")
		if err != nil {
			return false, err
		}
		err = deleteNamespaces(kc, knativeNamespaces)
		if err != nil {
			return false, err
		}
	}
	if istioNsCount == 0 {
		fmt.Print("No Istio components found\n")
	} else {
		if !options.Istio {
			if options.Force {
				return true, nil
			}
			answer, err := confirm("Do you also want to uninstall Istio components?")
			if err != nil {
				return false, err
			}
			if !answer {
				return false, nil
			}
		}
		fmt.Print("Removing Istio components\n")
		err = deleteCrds(kc, "istio.io")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrolebinding", "istio-")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrole", "istio-")
		if err != nil {
			return false, err
		}
		err = deleteNamespaces(kc, []string{istioNamespace})
		if err != nil {
			return false, err
		}
	}
	return true, nil
}

func resolveReleaseURLs(filename string) (url.URL, error) {
	u, err := url.Parse(filename)
	if err != nil {
		return url.URL{}, err
	}
	if u.Scheme == "http" || u.Scheme == "https" {
		return *u, nil
	}
	return *u, fmt.Errorf("filename must be file, http or https, got %s", u.Scheme)
}

func loadRelease(release string) ([]byte, error) {
	releaseUrl, err := resolveReleaseURLs(release)
	if err != nil {
		return nil, err
	}
	resp, err := http.Get(releaseUrl.String())
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return body, nil
}

func waitForIstioComponents(kc *kubectlClient) error {
	fmt.Print("Waiting for the Istio components to start ")
	for i := 0; i < 36; i++ {
		fmt.Print(".")
		pods := kc.kubeClient.CoreV1().Pods(istioNamespace)
		podList, err := pods.List(metav1.ListOptions{})
		if err != nil {
			return err
		}
		waitLonger := false
		for _, pod := range podList.Items {
			if !strings.HasPrefix(pod.Name, "istio-") {
				continue
			}
			if pod.Status.Phase != "Running" && pod.Status.Phase != "Succeeded" {
				waitLonger = true
				break
			} else {
				if pod.Status.Phase == "Running" {
					containers := pod.Status.ContainerStatuses
					for _, cont := range containers {
						if !cont.Ready {
							waitLonger = true
							break
						}
					}
				}
			}
		}
		if !waitLonger {
			fmt.Print(" all components are 'Running'\n\n")
			return nil
		}
		time.Sleep(10 * time.Second) // wait for them to start
	}
	return errors.New("the Istio components did not start in time")
}

func applyResources(kc *kubectlClient, release string) error {
	releaseUrl, err := resolveReleaseURLs(release)
	if err != nil {
		return err
	}
	fmt.Printf("Applying resources defined in: %s\n", releaseUrl.String())
	releaseLog, err := kc.kubeCtl.Exec([]string{"apply", "-f", releaseUrl.String()})
	if err != nil {
		fmt.Printf("%s", releaseLog)
	}
	return nil
}

func deleteNamespaces(kc *kubectlClient, namespaces []string) error {
	for _, namespace := range namespaces {
		fmt.Printf("Deleting resources defined in: %s\n", namespace)
		deleteLog, err := kc.kubeCtl.Exec([]string{"delete", "namespace", namespace})
		if err != nil {
			fmt.Printf("%s", deleteLog)
		}
	}
	return nil
}

func deleteClusterResources(kc *kubectlClient, resourceType string, prefix string) error {
	fmt.Printf("Deleting %ss prefixed with %s\n", resourceType, prefix)
	resourceList, err := kc.kubeCtl.Exec([]string{"get", resourceType, "-ocustom-columns=name:metadata.name"})
	if err != nil {
		return err
	}
	resource := strings.Split(string(resourceList), "\n")
	var resourcesToDelete []string
	for _, resource := range resource {
		if strings.HasPrefix(resource, prefix) {
			resourcesToDelete = append(resourcesToDelete, resource)
		}
	}
	if len(resourcesToDelete) > 0 {
		resourceLog, err := kc.kubeCtl.Exec(append([]string{"delete", resourceType}, resourcesToDelete...))
		if err != nil {
			fmt.Printf("%s", resourceLog)
			return err
		}
	}
	return nil
}

func deleteCrds(kc *kubectlClient, suffix string) error {
	fmt.Printf("Deleting CRDs for %s\n", suffix)
	crdList, err := kc.kubeCtl.Exec([]string{"get", "customresourcedefinitions", "-ocustom-columns=name:metadata.name"})
	if err != nil {
		return err
	}
	crds := strings.Split(string(crdList), "\n")
	var crdsToDelete []string
	for _, crd := range crds {
		if strings.HasSuffix(crd, suffix) {
			crdsToDelete = append(crdsToDelete, crd)
		}
	}
	if len(crdsToDelete) > 0 {
		crdLog, err := kc.kubeCtl.Exec(append([]string{"delete", "customresourcedefinition"}, crdsToDelete...))
		if err != nil {
			fmt.Printf("%s", crdLog)
			return err
		}
	}
	return nil
}

func checkNamespacesExists (kc *kubectlClient, names []string) (int, error) {
	count := 0
	for _, name := range names {
		status, err := getNamespaceStatus(kc, name)
		if err != nil {
			return count, err
		}
		if status != "'NotFound'" {
			count =+ 1
		}
	}
	return count, nil
}

func ensureNotTerminating (kc *kubectlClient, names []string, message string) error {
	for _, name := range names {
		status, err := getNamespaceStatus(kc, name)
		if err != nil {
			return err
		}
		if status == "'Terminating'" {
			return errors.New(fmt.Sprintf("The %s namespace is currently 'Terminating'. %s", name, message))
		}
	}
	return nil
}

func getNamespaceStatus(kc *kubectlClient, name string) (string, error) {
	nsLog, err := kc.kubeCtl.Exec([]string{"get", "namespace", name, "-o", "jsonpath='{.status.phase}'"})
	if err != nil {
		if strings.Contains(nsLog, "NotFound") {
			return "'NotFound'", nil
		}
		return "", err
	}
	return nsLog, nil
}

func confirm(s string) (bool, error) {
	reader := bufio.NewReader(os.Stdin)
	fmt.Printf("%s [y/N]: ", s)
	res, err := reader.ReadString('\n')
	if err != nil {
		return false, err
	}
	if len(res) < 2 {
		return false, nil
	}
	answer := strings.ToLower(strings.TrimSpace(res))[0] == 'y'
	return answer, nil
}
<commit_msg>Split Istio install into crds and main file and wait 5s between (#663)<commit_after>/*
 * Copyright 2018 The original author or authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package core

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"time"
	"bufio"
	"os"
	"strings"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
	istioNamespace  = "istio-system"
	istioCrds       = "https://storage.googleapis.com/riff-releases/istio/istio-1.0.0-riff-crds.yaml"
	istioRelease    = "https://storage.googleapis.com/riff-releases/istio/istio-1.0.0-riff-main.yaml"
	servingRelease  = "https://storage.googleapis.com/knative-releases/serving/previous/v20180809-6b01d8e/release-no-mon.yaml"
	eventingRelease = "https://storage.googleapis.com/knative-releases/eventing/previous/v20180809-34ab480/release.yaml"
	stubBusRelease  = "https://storage.googleapis.com/knative-releases/eventing/previous/v20180809-34ab480/release-clusterbus-stub.yaml"
)

type SystemInstallOptions struct {
	NodePort bool
	Force bool
}

type SystemUninstallOptions struct {
	Istio bool
	Force bool
}

var (
	knativeNamespaces = []string{"knative-eventing", "knative-serving", "knative-build"}
	allNameSpaces     = append(knativeNamespaces, istioNamespace)
)

func (kc *kubectlClient) SystemInstall(options SystemInstallOptions) (bool, error) {

	err := ensureNotTerminating(kc, allNameSpaces, "Please try again later.")
	if err != nil {
		return false, err
	}

	istioStatus, err := getNamespaceStatus(kc,istioNamespace)
	if istioStatus == "'NotFound'" {
		fmt.Print("Installing Istio components\n")
		applyResources(kc, istioCrds)
		time.Sleep(5 * time.Second) // wait for them to get created
		istioYaml, err := loadRelease(istioRelease)
		if err != nil {
			return false, err
		}
		if options.NodePort {
			istioYaml = bytes.Replace(istioYaml, []byte("LoadBalancer"), []byte("NodePort"), -1)
		}
		fmt.Printf("Applying resources defined in: %s\n", istioRelease)
		istioLog, err := kc.kubeCtl.ExecStdin([]string{"apply", "-f", "-"}, &istioYaml)
		if err != nil {
			fmt.Printf("%s\n", istioLog)
			return false, err
		}

		fmt.Print("Istio for riff installed\n\n")
	} else {
		if !options.Force {
			answer, err := confirm("Istio is already installed, do you want to install the Knative components for riff?")
			if err != nil {
				return false, err
			}
			if !answer {
				return false, nil
			}
		}
	}

	err = waitForIstioComponents(kc)
	if err != nil {
		return false, err
	}

	fmt.Print("Installing Knative components\n")

	servingYaml, err := loadRelease(servingRelease)
	if err != nil {
		return false, err
	}
	if options.NodePort {
		servingYaml = bytes.Replace(servingYaml, []byte("LoadBalancer"), []byte("NodePort"), -1)
	}
	fmt.Printf("Applying resources defined in: %s\n", servingRelease)
	servingLog, err := kc.kubeCtl.ExecStdin([]string{"apply", "-f", "-"}, &servingYaml)
	if err != nil {
		fmt.Printf("%s\n", servingLog)
		return false, err
	}

	applyResources(kc, eventingRelease)

	applyResources(kc, stubBusRelease)

	fmt.Print("Knative for riff installed\n\n")
	return true, nil
}

func (kc *kubectlClient) SystemUninstall(options SystemUninstallOptions) (bool, error) {

	err := ensureNotTerminating(kc, allNameSpaces, "This would indicate that the system was already uninstalled.")
	if err != nil {
		return false, err
	}
	knativeNsCount, err := checkNamespacesExists(kc, knativeNamespaces)
	istioNsCount, err := checkNamespacesExists(kc, []string{istioNamespace})
	if err != nil {
		return false, err
	}
	if knativeNsCount == 0 {
		fmt.Print("No Knative components for riff found\n")
	} else {
		if !options.Force {
			answer, err := confirm("Are you sure you want to uninstall the riff system?")
			if err != nil {
				return false, err
			}
			if !answer {
				return false, nil
			}
		}
		fmt.Print("Removing Knative for riff components\n")
		err = deleteCrds(kc, "knative.dev")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrolebinding", "knative-")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrolebinding", "build-controller-")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrolebinding", "eventing-controller-")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrolebinding", "clusterbus-controller-")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrole", "knative-")
		if err != nil {
			return false, err
		}
		err = deleteNamespaces(kc, knativeNamespaces)
		if err != nil {
			return false, err
		}
	}
	if istioNsCount == 0 {
		fmt.Print("No Istio components found\n")
	} else {
		if !options.Istio {
			if options.Force {
				return true, nil
			}
			answer, err := confirm("Do you also want to uninstall Istio components?")
			if err != nil {
				return false, err
			}
			if !answer {
				return false, nil
			}
		}
		fmt.Print("Removing Istio components\n")
		err = deleteCrds(kc, "istio.io")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrolebinding", "istio-")
		if err != nil {
			return false, err
		}
		err = deleteClusterResources(kc, "clusterrole", "istio-")
		if err != nil {
			return false, err
		}
		err = deleteNamespaces(kc, []string{istioNamespace})
		if err != nil {
			return false, err
		}
	}
	return true, nil
}

func resolveReleaseURLs(filename string) (url.URL, error) {
	u, err := url.Parse(filename)
	if err != nil {
		return url.URL{}, err
	}
	if u.Scheme == "http" || u.Scheme == "https" {
		return *u, nil
	}
	return *u, fmt.Errorf("filename must be file, http or https, got %s", u.Scheme)
}

func loadRelease(release string) ([]byte, error) {
	releaseUrl, err := resolveReleaseURLs(release)
	if err != nil {
		return nil, err
	}
	resp, err := http.Get(releaseUrl.String())
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return body, nil
}

func waitForIstioComponents(kc *kubectlClient) error {
	fmt.Print("Waiting for the Istio components to start ")
	for i := 0; i < 36; i++ {
		fmt.Print(".")
		pods := kc.kubeClient.CoreV1().Pods(istioNamespace)
		podList, err := pods.List(metav1.ListOptions{})
		if err != nil {
			return err
		}
		waitLonger := false
		for _, pod := range podList.Items {
			if !strings.HasPrefix(pod.Name, "istio-") {
				continue
			}
			if pod.Status.Phase != "Running" && pod.Status.Phase != "Succeeded" {
				waitLonger = true
				break
			} else {
				if pod.Status.Phase == "Running" {
					containers := pod.Status.ContainerStatuses
					for _, cont := range containers {
						if !cont.Ready {
							waitLonger = true
							break
						}
					}
				}
			}
		}
		if !waitLonger {
			fmt.Print(" all components are 'Running'\n\n")
			return nil
		}
		time.Sleep(10 * time.Second) // wait for them to start
	}
	return errors.New("the Istio components did not start in time")
}

func applyResources(kc *kubectlClient, release string) error {
	releaseUrl, err := resolveReleaseURLs(release)
	if err != nil {
		return err
	}
	fmt.Printf("Applying resources defined in: %s\n", releaseUrl.String())
	releaseLog, err := kc.kubeCtl.Exec([]string{"apply", "-f", releaseUrl.String()})
	if err != nil {
		fmt.Printf("%s", releaseLog)
	}
	return nil
}

func deleteNamespaces(kc *kubectlClient, namespaces []string) error {
	for _, namespace := range namespaces {
		fmt.Printf("Deleting resources defined in: %s\n", namespace)
		deleteLog, err := kc.kubeCtl.Exec([]string{"delete", "namespace", namespace})
		if err != nil {
			fmt.Printf("%s", deleteLog)
		}
	}
	return nil
}

func deleteClusterResources(kc *kubectlClient, resourceType string, prefix string) error {
	fmt.Printf("Deleting %ss prefixed with %s\n", resourceType, prefix)
	resourceList, err := kc.kubeCtl.Exec([]string{"get", resourceType, "-ocustom-columns=name:metadata.name"})
	if err != nil {
		return err
	}
	resource := strings.Split(string(resourceList), "\n")
	var resourcesToDelete []string
	for _, resource := range resource {
		if strings.HasPrefix(resource, prefix) {
			resourcesToDelete = append(resourcesToDelete, resource)
		}
	}
	if len(resourcesToDelete) > 0 {
		resourceLog, err := kc.kubeCtl.Exec(append([]string{"delete", resourceType}, resourcesToDelete...))
		if err != nil {
			fmt.Printf("%s", resourceLog)
			return err
		}
	}
	return nil
}

func deleteCrds(kc *kubectlClient, suffix string) error {
	fmt.Printf("Deleting CRDs for %s\n", suffix)
	crdList, err := kc.kubeCtl.Exec([]string{"get", "customresourcedefinitions", "-ocustom-columns=name:metadata.name"})
	if err != nil {
		return err
	}
	crds := strings.Split(string(crdList), "\n")
	var crdsToDelete []string
	for _, crd := range crds {
		if strings.HasSuffix(crd, suffix) {
			crdsToDelete = append(crdsToDelete, crd)
		}
	}
	if len(crdsToDelete) > 0 {
		crdLog, err := kc.kubeCtl.Exec(append([]string{"delete", "customresourcedefinition"}, crdsToDelete...))
		if err != nil {
			fmt.Printf("%s", crdLog)
			return err
		}
	}
	return nil
}

func checkNamespacesExists (kc *kubectlClient, names []string) (int, error) {
	count := 0
	for _, name := range names {
		status, err := getNamespaceStatus(kc, name)
		if err != nil {
			return count, err
		}
		if status != "'NotFound'" {
			count =+ 1
		}
	}
	return count, nil
}

func ensureNotTerminating (kc *kubectlClient, names []string, message string) error {
	for _, name := range names {
		status, err := getNamespaceStatus(kc, name)
		if err != nil {
			return err
		}
		if status == "'Terminating'" {
			return errors.New(fmt.Sprintf("The %s namespace is currently 'Terminating'. %s", name, message))
		}
	}
	return nil
}

func getNamespaceStatus(kc *kubectlClient, name string) (string, error) {
	nsLog, err := kc.kubeCtl.Exec([]string{"get", "namespace", name, "-o", "jsonpath='{.status.phase}'"})
	if err != nil {
		if strings.Contains(nsLog, "NotFound") {
			return "'NotFound'", nil
		}
		return "", err
	}
	return nsLog, nil
}

func confirm(s string) (bool, error) {
	reader := bufio.NewReader(os.Stdin)
	fmt.Printf("%s [y/N]: ", s)
	res, err := reader.ReadString('\n')
	if err != nil {
		return false, err
	}
	if len(res) < 2 {
		return false, nil
	}
	answer := strings.ToLower(strings.TrimSpace(res))[0] == 'y'
	return answer, nil
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Xuyuan Pang <xuyuanp@gmail.com>
 *
 * 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 glogger

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"time"
)

// gLogger is the default Logger
type gLogger struct {
	GroupFilter
	handlerGroup
	name  string
	level LogLevel
}

// New return a new Logger.
// level is the logger's level, all the logs with level lower than this will be ignore
// New will panic if this name has been registered.
func NewLogger() Logger {
	l := &gLogger{
		level: DebugLevel,
	}
	return l
}

// Debug see details in Logger interface
func (l *gLogger) Debug(f string, v ...interface{}) {
	l.log(DebugLevel, fmt.Sprintf(f, v...))
}

// Info see details in Logger interface
func (l *gLogger) Info(f string, v ...interface{}) {
	l.log(InfoLevel, fmt.Sprintf(f, v...))
}

// Warning see details in Logger interface
func (l *gLogger) Warning(f string, v ...interface{}) {
	l.log(WarnLevel, fmt.Sprintf(f, v...))
}

// Error see details in Logger interface
func (l *gLogger) Error(f string, v ...interface{}) {
	l.log(ErrorLevel, fmt.Sprintf(f, v...))
}

// Critical see details in Logger interface
func (l *gLogger) Critical(f string, v ...interface{}) {
	l.log(CriticalLevel, fmt.Sprintf(f, v...))
}

func (l *gLogger) log(level LogLevel, msg string) {
	if level < l.level {
		return
	}
	now := time.Now()
	pc, file, line, ok := runtime.Caller(2)
	var funcname string
	if !ok {
		file = "???"
		line = 0
		funcname = "???"
	} else {
		funcname = runtime.FuncForPC(pc).Name()
	}
	rec := NewRecord(l.name, now, level, file, funcname, line, msg)
	if !l.Filter(rec) {
		return
	}
	l.Handle(rec)
}

func (l *gLogger) Level() LogLevel {
	return l.level
}

func (l *gLogger) SetLevel(level LogLevel) {
	l.level = level
}

func (l *gLogger) LoadConfig(config []byte) {
	var m map[string]interface{}
	if err := json.Unmarshal(config, &m); err == nil {
		l.LoadConfigFromMap(m)
	} else {
		panic(err)
	}
}

func (l *gLogger) LoadConfigFromMap(config map[string]interface{}) {
	if level, ok := config["level"]; ok {
		l.level = StringToLevel[level.(string)]
	} else {
		panic("'level' field is required")
	}
	if handlers, ok := config["handlers"]; ok {
		if len(handlers.([]interface{})) == 0 {
			panic("handler name is required")
		}
		for _, hname := range handlers.([]interface{}) {
			if handler := GetHandler(hname.(string)); handler != nil {
				l.AddHandler(handler)
			} else {
				panic("unknown handler name: " + hname.(string))
			}
		}
	} else {
		panic("'handlers' field is required")
	}
}

func (l *gLogger) LoadConfigFromFile(fileName string) {
	if file, err := os.Open(fileName); err == nil {
		defer file.Close()
		if code, err := ioutil.ReadAll(file); err == nil {
			l.LoadConfig(code)
		} else {
			panic(err)
		}
	} else {
		panic(err)
	}
}
<commit_msg>change comment<commit_after>/*
 * Copyright 2014 Xuyuan Pang <xuyuanp@gmail.com>
 *
 * 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 glogger

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"time"
)

// gLogger is the default Logger
type gLogger struct {
	GroupFilter
	handlerGroup
	name  string
	level LogLevel
}

// NewLogger return a new Logger with debug level as default.
func NewLogger() Logger {
	l := &gLogger{
		level: DebugLevel,
	}
	return l
}

// Debug see details in Logger interface
func (l *gLogger) Debug(f string, v ...interface{}) {
	l.log(DebugLevel, fmt.Sprintf(f, v...))
}

// Info see details in Logger interface
func (l *gLogger) Info(f string, v ...interface{}) {
	l.log(InfoLevel, fmt.Sprintf(f, v...))
}

// Warning see details in Logger interface
func (l *gLogger) Warning(f string, v ...interface{}) {
	l.log(WarnLevel, fmt.Sprintf(f, v...))
}

// Error see details in Logger interface
func (l *gLogger) Error(f string, v ...interface{}) {
	l.log(ErrorLevel, fmt.Sprintf(f, v...))
}

// Critical see details in Logger interface
func (l *gLogger) Critical(f string, v ...interface{}) {
	l.log(CriticalLevel, fmt.Sprintf(f, v...))
}

func (l *gLogger) log(level LogLevel, msg string) {
	if level < l.level {
		return
	}
	now := time.Now()
	pc, file, line, ok := runtime.Caller(2)
	var funcname string
	if !ok {
		file = "???"
		line = 0
		funcname = "???"
	} else {
		funcname = runtime.FuncForPC(pc).Name()
	}
	rec := NewRecord(l.name, now, level, file, funcname, line, msg)
	if !l.Filter(rec) {
		return
	}
	l.Handle(rec)
}

func (l *gLogger) Level() LogLevel {
	return l.level
}

func (l *gLogger) SetLevel(level LogLevel) {
	l.level = level
}

func (l *gLogger) LoadConfig(config []byte) {
	var m map[string]interface{}
	if err := json.Unmarshal(config, &m); err == nil {
		l.LoadConfigFromMap(m)
	} else {
		panic(err)
	}
}

func (l *gLogger) LoadConfigFromMap(config map[string]interface{}) {
	if level, ok := config["level"]; ok {
		l.level = StringToLevel[level.(string)]
	} else {
		panic("'level' field is required")
	}
	if handlers, ok := config["handlers"]; ok {
		if len(handlers.([]interface{})) == 0 {
			panic("handler name is required")
		}
		for _, hname := range handlers.([]interface{}) {
			if handler := GetHandler(hname.(string)); handler != nil {
				l.AddHandler(handler)
			} else {
				panic("unknown handler name: " + hname.(string))
			}
		}
	} else {
		panic("'handlers' field is required")
	}
}

func (l *gLogger) LoadConfigFromFile(fileName string) {
	if file, err := os.Open(fileName); err == nil {
		defer file.Close()
		if code, err := ioutil.ReadAll(file); err == nil {
			l.LoadConfig(code)
		} else {
			panic(err)
		}
	} else {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package spec

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
	VaultResourceKind   = "Vault"
	VaultResourcePlural = "Vaults"
)

type VaultList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata"`
	Items           []Vault `json:"items"`
}

type Vault struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata"`
	Spec              VaultSpec    `json:"spec"`
	Status            *VaultStatus `json:"status,omitempty"`
}

type VaultSpec struct {
	// Number of instances to deploy for a Vault deployment.
	// Default: 1.
	Replicas int32 `json:"replicas,omitempty"`

	// Base image to use for a Vault deployment.
	BaseImage string `json:"baseImage"`

	// Version of Vault to be deployed.
	Version string `json:"version"`
}

type VaultStatus struct {
	// Initialized indicates if the Vault service is initialized.
	Initialized bool `json:"initialized"`

	// Endpoints of available replicas.
	// Avaliable replica is a running Vault pod, but not necessarily unsealed and ready
	// to serve requests).
	AvailableReplicas []string `json:"availableReplicas"`

	// Endpoints of ready Vault replicas.
	ReadyReplicas []string `json:"sealedReplicas"`

	// Endpoints of Sealed Vault replicas. Sealed replicas MUST be manually unsealed to
	// be ready to serve requests.
	SealedReplicas []string `json:"unsealedReplicas"`
}
<commit_msg>Update types.go<commit_after>package spec

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
	VaultResourceKind   = "Vault"
	VaultResourcePlural = "Vaults"
)

type VaultList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata"`
	Items           []Vault `json:"items"`
}

type Vault struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata"`
	Spec              VaultSpec    `json:"spec"`
	Status            *VaultStatus `json:"status,omitempty"`
}

type VaultSpec struct {
	// Number of instances to deploy for a Vault deployment.
	// Default: 1.
	Replicas int32 `json:"replicas,omitempty"`

	// Base image to use for a Vault deployment.
	BaseImage string `json:"baseImage"`

	// Version of Vault to be deployed.
	Version string `json:"version"`
}

type VaultStatus struct {
	// Initialized indicates if the Vault service is initialized.
	Initialized bool `json:"initialized"`

	// Endpoints of available replicas.
	// Avaliable replica is a running Vault pod, but not necessarily unsealed and ready
	// to serve requests.
	AvailableReplicas []string `json:"availableReplicas"`

	// Endpoints of ready Vault replicas. Ready replicas are unsealed and ready to serve
	// requests.
	ReadyReplicas []string `json:"sealedReplicas"`

	// Endpoints of Sealed Vault replicas. Sealed replicas MUST be manually unsealed to
	// be ready to serve requests.
	SealedReplicas []string `json:"unsealedReplicas"`
}
<|endoftext|>


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

package request

import (
	"github.com/realglobe-Inc/go-lib/erro"
	"net/http"
	"strings"
)

// リクエストの基本情報。
type Request struct {
	sess string
	src  string
}

const (
	tagX_forwarded_for = "X-Forwarded-For"
)

func Parse(r *http.Request, sessLabel string) *Request {
	var sess string
	if cook, err := r.Cookie(sessLabel); err != nil {
		if err != http.ErrNoCookie {
			log.Warn(erro.Wrap(err))
		}
	} else {
		sess = cook.Value
	}

	var src string
	if forwarded := r.Header.Get(tagX_forwarded_for); forwarded == "" {
		src = r.RemoteAddr
	} else {
		parts := strings.SplitN(forwarded, ",", 2)
		src = parts[0]
	}

	return &Request{
		sess: sess,
		src:  src,
	}
}

// Cookie で宣言されているセッション ID を返す。
func (this *Request) Session() string {
	return this.sess
}

// 送信元の IP アドレスを返す。
func (this *Request) Source() string {
	return this.src
}

var SessionDisplayLength = 8

// <セッション ID の最初の数文字>@<IP アドレス>
func (this *Request) String() string {
	str := ""
	if this.sess != "" {
		str += cutoff(this.sess, SessionDisplayLength) + "@"
	}
	return str + this.src
}

func cutoff(str string, max int) string {
	if len(str) <= max {
		return str
	} else {
		return str[:max]
	}
}
<commit_msg>ラベルが未指定ならセッションを取得しないようにした<commit_after>// Copyright 2015 realglobe, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package request

import (
	"github.com/realglobe-Inc/go-lib/erro"
	"net/http"
	"strings"
)

// リクエストの基本情報。
type Request struct {
	sess string
	src  string
}

const (
	tagX_forwarded_for = "X-Forwarded-For"
)

func Parse(r *http.Request, sessLabel string) *Request {
	var sess string
	if sessLabel != "" {
		if cook, err := r.Cookie(sessLabel); err != nil {
			if err != http.ErrNoCookie {
				log.Warn(erro.Wrap(err))
			}
		} else {
			sess = cook.Value
		}
	}

	var src string
	if forwarded := r.Header.Get(tagX_forwarded_for); forwarded == "" {
		src = r.RemoteAddr
	} else {
		parts := strings.SplitN(forwarded, ",", 2)
		src = parts[0]
	}

	return &Request{
		sess: sess,
		src:  src,
	}
}

// Cookie で宣言されているセッション ID を返す。
func (this *Request) Session() string {
	return this.sess
}

// 送信元の IP アドレスを返す。
func (this *Request) Source() string {
	return this.src
}

var SessionDisplayLength = 8

// <セッション ID の最初の数文字>@<IP アドレス>
func (this *Request) String() string {
	str := ""
	if this.sess != "" {
		str += cutoff(this.sess, SessionDisplayLength) + "@"
	}
	return str + this.src
}

func cutoff(str string, max int) string {
	if len(str) <= max {
		return str
	} else {
		return str[:max]
	}
}
<|endoftext|>