// 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)) } }
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) }
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) }
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 }
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 }
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 }
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) }
// 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)) } }
// 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 }
//------------------------------------------------------------------------ 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 }
// 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)) } }