예제 #1
0
// eris chains new -c _ -csv _
func TestChainsNewConfigAndCSV(t *testing.T) {
	chainID := "testChainsNewConfigAndCSV"
	do := def.NowDo()
	do.Name = chainID
	do.ConfigFile = filepath.Join(common.ChainsPath, "default", "config.toml")
	do.CSV = filepath.Join(common.ChainsPath, "default", "genesis.csv")
	do.Operations.ContainerNumber = 1
	do.Operations.PublishAllPorts = true
	log.WithField("=>", do.Name).Info("Creating chain (from tests)")
	tests.IfExit(NewChain(do))
	_, err := ioutil.ReadFile(do.ConfigFile)
	if err != nil {
		tests.IfExit(err)
	}

	// remove the data container
	defer removeChainContainer(t, chainID, do.Operations.ContainerNumber)

	// verify the contents of config.toml
	ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber)
	util.Merge(ops, do.Operations)
	ops.Args = []string{"cat", fmt.Sprintf("/home/eris/.eris/chains/%s/config.toml", chainID)}
	result := trimResult(string(runContainer(t, ops)))

	configDefault := filepath.Join(erisDir, "chains", "default", "config.toml")
	read, err := ioutil.ReadFile(configDefault)
	if err != nil {
		tests.IfExit(err)
	}
	contents := trimResult(string(read))

	if result != contents {
		tests.IfExit(fmt.Errorf("config not properly copied. Got: %s \n Expected: %s", result, contents))
	}

	// verify the contents of genesis.json (should have the validator from the csv)
	ops = loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber)
	util.Merge(ops, do.Operations)
	ops.Args = []string{"cat", fmt.Sprintf("/home/eris/.eris/chains/%s/genesis.json", chainID)}
	result = string(runContainer(t, ops))
	var found bool
	for _, s := range strings.Split(result, "\n") {
		if strings.Contains(s, ini.DefaultPubKeys[0]) {
			found = true
			break
		}
	}
	if !found {
		tests.IfExit(fmt.Errorf("Did not find pubkey %s in genesis.json: %s", ini.DefaultPubKeys[0], result))
	}
}
예제 #2
0
func ExecService(do *definitions.Do) error {
	service, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber)
	if err != nil {
		return err
	}

	util.Merge(service.Operations, do.Operations)

	// Get the main service container name, check if it's running.
	main := util.FindServiceContainer(do.Name, do.Operations.ContainerNumber, false)
	if main != nil {
		if service.Service.ExecHost == "" {
			log.Info("exec_host not found in service definition file")
			log.WithField("service", do.Name).Info("May not be able to communicate with the service")
		} else {
			service.Service.Environment = append(service.Service.Environment,
				fmt.Sprintf("%s=%s", service.Service.ExecHost, do.Name))
		}

		// Use service's short name as a link alias.
		service.Service.Links = append(service.Service.Links, fmt.Sprintf("%s:%s", main.FullName, do.Name))
	}

	// Override links on the command line.
	if len(do.Links) > 0 {
		service.Service.Links = do.Links
	}

	return perform.DockerExecService(service.Service, service.Operations)
}
예제 #3
0
func StartService(do *definitions.Do) (err error) {
	var services []*definitions.ServiceDefinition

	do.Operations.Args = append(do.Operations.Args, do.ServicesSlice...)
	log.WithField("args", do.Operations.Args).Info("Building services group")
	for _, srv := range do.Operations.Args {
		s, e := BuildServicesGroup(srv, do.Operations.ContainerNumber)
		if e != nil {
			return e
		}
		services = append(services, s...)
	}

	// [csk]: controls for ops reconciliation, overwrite will, e.g., merge the maps and stuff
	for _, s := range services {
		util.Merge(s.Operations, do.Operations)
	}

	log.Debug("Preparing to build chain")
	for _, s := range services {
		log.WithFields(log.Fields{
			"name":         s.Name,
			"dependencies": s.Dependencies,
			"links":        s.Service.Links,
			"volumes from": s.Service.VolumesFrom,
		}).Debug()

		// Spacer.
		log.Debug()
	}
	services, err = BuildChainGroup(do.ChainName, services)
	if err != nil {
		return err
	}
	log.Debug("Checking services after build chain")
	for _, s := range services {
		log.WithFields(log.Fields{
			"name":         s.Name,
			"dependencies": s.Dependencies,
			"links":        s.Service.Links,
			"volumes from": s.Service.VolumesFrom,
		}).Debug()

		// Spacer.
		log.Debug()
	}

	// NOTE: the top level service should be at the end of the list
	topService := services[len(services)-1]
	topService.Service.Environment = append(topService.Service.Environment, do.Env...)
	topService.Service.Links = append(topService.Service.Links, do.Links...)
	services[len(services)-1] = topService

	return StartGroup(services)
}
예제 #4
0
파일: operate.go 프로젝트: mxjxn/eris-cli
func ExecData(do *definitions.Do) error {
	if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) {
		log.WithField("=>", do.Operations.DataContainerName).Info("Executing data container")

		ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber)
		util.Merge(ops, do.Operations)
		if err := perform.DockerExecData(ops, nil); err != nil {
			return err
		}
	} else {
		return fmt.Errorf("The marmots cannot find that data container.\nPlease check the name of the data container with [eris data ls].")
	}
	do.Result = "success"
	return nil
}
예제 #5
0
func RenameData(do *definitions.Do) error {
	logger.Infof("Renaming Data =>\t\t%s:%s\n", do.Name, do.NewName)
	logger.Debugf("\twith ContainerNumber =>\t%d\n", do.Operations.ContainerNumber)

	if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) {
		ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber)
		util.Merge(ops, do.Operations)

		err := perform.DockerRename(ops, do.NewName)
		if err != nil {
			return err
		}
	} else {
		return fmt.Errorf("I cannot find that data container. Please check the data container name you sent me.")
	}
	do.Result = "success"
	return nil
}
예제 #6
0
파일: manage.go 프로젝트: mxjxn/eris-cli
func RenameData(do *definitions.Do) error {
	log.WithFields(log.Fields{
		"from": fmt.Sprintf("%s:%d", do.Name, do.Operations.ContainerNumber),
		"to":   fmt.Sprintf("%s:%d", do.NewName, do.Operations.ContainerNumber),
	}).Info("Renaming data container")

	if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) {
		ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber)
		util.Merge(ops, do.Operations)

		err := perform.DockerRename(ops, do.NewName)
		if err != nil {
			return err
		}
	} else {
		return fmt.Errorf("I cannot find that data container. Please check the data container name you sent me.")
	}
	do.Result = "success"
	return nil
}
예제 #7
0
func StartService(do *definitions.Do) (err error) {
	var services []*definitions.ServiceDefinition

	do.Operations.Args = append(do.Operations.Args, do.ServicesSlice...)
	logger.Infof("Building the Services Group =>\t%v\n", do.Operations.Args)
	for _, srv := range do.Operations.Args {
		s, e := BuildServicesGroup(srv, do.Operations.ContainerNumber)
		if e != nil {
			return e
		}
		services = append(services, s...)
	}

	// [csk]: controls for ops reconciliation, overwrite will, e.g., merge the maps and stuff
	for _, s := range services {
		util.Merge(s.Operations, do.Operations)
	}

	logger.Debugln("Services before build chain =>")
	for _, s := range services {
		logger.Debugln("\t", s.Name, s.Dependencies, s.Service.Links, s.Service.VolumesFrom)
	}
	services, err = BuildChainGroup(do.ChainName, services)
	if err != nil {
		return err
	}
	logger.Debugln("Services after build chain =>")
	for _, s := range services {
		logger.Debugln("\t", s.Name, s.Dependencies, s.Service.Links, s.Service.VolumesFrom)
	}

	// NOTE: the top level service should be at the end of the list
	topService := services[len(services)-1]
	topService.Service.Environment = append(topService.Service.Environment, do.Env...)
	topService.Service.Links = append(topService.Service.Links, do.Links...)
	services[len(services)-1] = topService

	logger.Infof("Starting Services Group.\n")
	return StartGroup(services)
}
예제 #8
0
// eris chains new --options
func TestChainsNewConfigOpts(t *testing.T) {
	// XXX: need to use a different chainID or remove the local tmp/eris/data/chainID dir with each test!
	chainID := "testChainsNewConfigOpts"
	do := def.NowDo()

	do.Name = chainID
	do.ConfigOpts = []string{"moniker=satoshi", "p2p=1.1.1.1:42", "fast-sync=true"}
	do.Operations.ContainerNumber = 1
	do.Operations.PublishAllPorts = true
	log.WithField("=>", do.Name).Info("Creating chain (from tests)")
	tests.IfExit(NewChain(do))

	// remove the data container
	defer removeChainContainer(t, chainID, do.Operations.ContainerNumber)

	// verify the contents of config.toml
	ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber)
	util.Merge(ops, do.Operations)
	ops.Args = []string{"cat", fmt.Sprintf("/home/eris/.eris/chains/%s/config.toml", chainID)}
	result := string(runContainer(t, ops))

	spl := strings.Split(result, "\n")
	var found bool
	for _, s := range spl {
		if ensureTomlValue(t, s, "moniker", "satoshi") {
			found = true
		}
		if ensureTomlValue(t, s, "node_laddr", "1.1.1.1:42") {
			found = true
		}
		if ensureTomlValue(t, s, "fast_sync", "true") {
			found = true
		}
	}
	if !found {
		tests.IfExit(fmt.Errorf("failed to find fields: %s", result))
	}
}
예제 #9
0
// marshal from viper to definitions struct
func MarshalChainDefinition(chainConf *viper.Viper, chain *definitions.Chain) error {
	chnTemp := definitions.BlankChain()
	err := chainConf.Marshal(chnTemp)
	if err != nil {
		return fmt.Errorf("The marmots coult not marshal from viper to chain def: %v", err)
	}

	util.Merge(chain.Service, chnTemp.Service)
	chain.ChainID = chnTemp.ChainID

	// toml bools don't really marshal well
	// data_container can be in the chain or
	// in the service layer. this is very
	// opinionated. we know.
	for _, s := range []string{"", "service."} {
		if chainConf.GetBool(s + "data_container") {
			logger.Debugln("Loader.Chain.Marshal. Data Containers Turned On.")
			chain.Service.AutoData = true
		}
	}

	return nil
}
예제 #10
0
//------------------------------------------------------------------------
func startChain(do *definitions.Do, exec bool) error {
	chain, err := loaders.LoadChainDefinition(do.Name, false, do.Operations.ContainerNumber)
	if err != nil {
		logger.Errorln("Cannot start a chain I cannot find.")
		do.Result = "no file"
		return nil
	}

	if chain.Name == "" {
		logger.Errorln("Cannot start a chain without a name.")
		do.Result = "no name"
		return nil
	}

	// boot the dependencies (eg. keys)
	if err := bootDependencies(chain, do); err != nil {
		return err
	}

	chain.Service.Command = loaders.ErisChainStart
	util.Merge(chain.Operations, do.Operations)
	chain.Service.Environment = append(chain.Service.Environment, "CHAIN_ID="+chain.ChainID)
	chain.Service.Environment = append(chain.Service.Environment, do.Env...)
	if do.Run {
		chain.Service.Environment = append(chain.Service.Environment, "ERISDB_API=true")
	}
	chain.Service.Links = append(chain.Service.Links, do.Links...)

	logger.Infof("StartChainRaw to DockerRunService =>\t%s\n", chain.Service.Name)
	logger.Debugf("\twith ChainID =>\t\t%v\n", chain.ChainID)
	logger.Debugf("\twith Environment =>\t%v\n", chain.Service.Environment)
	logger.Debugf("\twith AllPortsPublshd =>\t%v\n", chain.Operations.PublishAllPorts)

	if exec {

		if do.Image != "" {
			chain.Service.Image = do.Image
		}

		chain.Operations.Args = do.Operations.Args
		logger.Debugf("\twith Args =>\t\t%v:%v\n", chain.Operations.Args, chain.Operations.Interactive)

		// This override is necessary because erisdb uses an entryPoint and
		// the perform package will respect the images entryPoint if it
		// exists.
		chain.Service.EntryPoint = ""
		chain.Service.Command = ""

		// there is literally never a reason not to randomize the ports.
		chain.Operations.PublishAllPorts = true

		// always link the chain to the exec container when doing chains exec
		// so that there is never any problems with sending info to the service (chain) container
		chain.Service.Links = append(chain.Service.Links, fmt.Sprintf("%s:%s", util.ContainersName("chain", chain.Name, 1), "chain"))

		err = perform.DockerExecService(chain.Service, chain.Operations)
	} else {
		err = perform.DockerRunService(chain.Service, chain.Operations)
	}
	if err != nil {
		do.Result = "error"
		return err
	}

	return nil
}
예제 #11
0
// eris chains new --dir _ -g _
// the default chain_id is my_tests, so should be overwritten
func TestChainsNewDirGen(t *testing.T) {
	chainID := "testChainsNewDirGen"
	myDir := filepath.Join(common.DataContainersPath, chainID)
	if err := os.MkdirAll(myDir, 0700); err != nil {
		tests.IfExit(err)
	}
	contents := "this is a file in the directory\n"
	if err := ioutil.WriteFile(filepath.Join(myDir, "file.file"), []byte(contents), 0664); err != nil {
		tests.IfExit(err)
	}

	do := def.NowDo()
	do.GenesisFile = filepath.Join(common.ChainsPath, "default", "genesis.json")
	do.Name = chainID
	do.Path = myDir
	do.Operations.ContainerNumber = 1
	do.Operations.PublishAllPorts = true
	log.WithField("=>", do.Name).Info("Creating chain (from tests)")
	tests.IfExit(NewChain(do))

	// remove the data container
	defer removeChainContainer(t, chainID, do.Operations.ContainerNumber)

	// verify the contents of file.file - swap config writer with bytes.Buffer
	// TODO: functions for facilitating this
	oldWriter := config.GlobalConfig.Writer
	newWriter := new(bytes.Buffer)
	config.GlobalConfig.Writer = newWriter
	ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber)
	util.Merge(ops, do.Operations)
	ops.Args = []string{"cat", fmt.Sprintf("/home/eris/.eris/file.file")}
	b, err := perform.DockerRunData(ops, nil)
	if err != nil {
		tests.IfExit(err)
	}

	config.GlobalConfig.Writer = oldWriter
	result := trimResult(string(b))
	contents = trimResult(contents)
	if result != contents {
		tests.IfExit(fmt.Errorf("file not faithfully copied. Got: %s \n Expected: %s", result, contents))
	}

	// verify the chain_id got swapped in the genesis.json
	// TODO: functions for facilitating this
	oldWriter = config.GlobalConfig.Writer
	newWriter = new(bytes.Buffer)
	config.GlobalConfig.Writer = newWriter
	ops = loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber)
	util.Merge(ops, do.Operations)
	ops.Args = []string{"cat", fmt.Sprintf("/home/eris/.eris/chains/%s/genesis.json", chainID)} //, "|", "jq", ".chain_id"}
	b, err = perform.DockerRunData(ops, nil)
	if err != nil {
		tests.IfExit(err)
	}

	config.GlobalConfig.Writer = oldWriter
	result = string(b)

	s := struct {
		ChainID string `json:"chain_id"`
	}{}
	if err := json.Unmarshal([]byte(result), &s); err != nil {
		tests.IfExit(err)
	}

	if s.ChainID != chainID {
		tests.IfExit(fmt.Errorf("ChainID mismatch: got %s, expected %s", s.ChainID, chainID))
	}
}