func TestInspectService(t *testing.T) { testStartService(t, servName, false) defer testKillService(t, servName, true) do := def.NowDo() do.Name = servName do.Operations.Args = []string{"name"} do.Operations.ContainerNumber = 1 log.WithFields(log.Fields{ "=>": fmt.Sprintf("%s:%d", servName, do.Operations.ContainerNumber), "args": do.Operations.Args, }).Debug("Inspect service (from tests)") e := InspectService(do) if e != nil { log.Infof("Error inspecting service: %v", e) tests.IfExit(e) } do = def.NowDo() do.Name = servName do.Operations.Args = []string{"config.user"} do.Operations.ContainerNumber = 1 log.WithFields(log.Fields{ "=>": servName, "args": do.Operations.Args, }).Debug("Inspect service (from tests)") e = InspectService(do) if e != nil { log.Infof("Error inspecting service: %v", e) tests.IfExit(e) } }
func TestStartKillServiceWithDependencies(t *testing.T) { do := def.NowDo() do.Operations.Args = []string{"do_not_use"} log.WithFields(log.Fields{ "service": servName, "dependency": "keys", }).Debug("Starting service with dependency (from tests)") if e := StartService(do); e != nil { log.Infof("Error starting service: %v", e) tests.IfExit(e) } defer func() { testKillService(t, "do_not_use", true) testExistAndRun(t, servName, 1, false, false) testNumbersExistAndRun(t, servName, 0, 0) testKillService(t, "keys", true) }() testExistAndRun(t, servName, 1, true, true) testExistAndRun(t, "keys", 1, true, true) testNumbersExistAndRun(t, "keys", 1, 1) testNumbersExistAndRun(t, servName, 1, 1) }
//from /services/services_test.go func testStartService(t *testing.T, serviceName string, publishAll bool) { do := def.NowDo() do.Operations.Args = []string{serviceName} do.Operations.ContainerNumber = 1 //util.AutoMagic(0, "service", true) do.Operations.PublishAllPorts = publishAll log.WithField("=>", fmt.Sprintf("%s:%d", serviceName, do.Operations.ContainerNumber)).Debug("Starting service (from tests)") e := srv.StartService(do) if e != nil { log.Infof("Error starting service: %v", e) fatal(t, e) } testExistAndRun(t, serviceName, 1, true, true) testNumbersExistAndRun(t, serviceName, 1, 1) }
func testStartKeys(t *testing.T) { serviceName := "keys" do := def.NowDo() do.Operations.Args = []string{serviceName} do.Operations.ContainerNumber = 1 log.WithField("=>", fmt.Sprintf("%s:%d", serviceName, do.Operations.ContainerNumber)).Debug("Starting service (via tests)") e := srv.StartService(do) if e != nil { log.Infof("Error starting service: %v", e) t.Fail() } testExistAndRun(t, serviceName, 1, true, true) testNumbersExistAndRun(t, serviceName, 1, 1) }
// the main function for setting up a chain container // handles both "new" and "fetch" - most of the differentiating logic is in the container func setupChain(do *definitions.Do, cmd string) (err error) { // XXX: if do.Name is unique, we can safely assume (and we probably should) that do.Operations.ContainerNumber = 1 // do.Name is mandatory if do.Name == "" { return fmt.Errorf("setupChain requires a chainame") } containerName := util.ChainContainersName(do.Name, do.Operations.ContainerNumber) if do.ChainID == "" { do.ChainID = do.Name } //if given path does not exist, see if its a reference to something in ~/.eris/chains/chainName if do.Path != "" { src, err := os.Stat(do.Path) if err != nil || !src.IsDir() { log.WithField("path", do.Path).Info("Path does not exist or not a directory") log.WithField("path", "$HOME/.eris/chains/"+do.Path).Info("Trying") do.Path, err = util.ChainsPathChecker(do.Path) if err != nil { return err } } } else if do.GenesisFile == "" && do.CSV == "" && len(do.ConfigOpts) == 0 { // NOTE: this expects you to have ~/.eris/chains/default/ (ie. to have run `eris init`) do.Path, err = util.ChainsPathChecker("default") if err != nil { return err } } // ensure/create data container if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) { log.WithField("=>", do.Name).Debug("Chain data container already exists") } else { ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber) if err := perform.DockerCreateData(ops); err != nil { return fmt.Errorf("Error creating data container =>\t%v", err) } } log.WithField("=>", do.Name).Debug("Chain data container built") // if something goes wrong, cleanup defer func() { if err != nil { log.Infof("Error on setting up chain: %v", err) log.Info("Cleaning up") if err2 := RmChain(do); err2 != nil { // maybe be less dramatic err = fmt.Errorf("Tragic! Our marmots encountered an error during setupChain for %s.\nThey also failed to cleanup after themselves (remove containers) due to another error.\nFirst error =>\t\t\t%v\nCleanup error =>\t\t%v\n", containerName, err, err2) } } }() // copy do.Path, do.GenesisFile, do.ConfigFile, do.Priv, do.CSV into container containerDst := filepath.Join("chains", do.Name) // path in container dst := filepath.Join(DataContainersPath, do.Name, containerDst) // path on host // TODO: deal with do.Operations.ContainerNumbers ....! // we probably need to update Import log.WithFields(log.Fields{ "container path": containerDst, "local path": dst, }).Debug() if err = os.MkdirAll(dst, 0700); err != nil { return fmt.Errorf("Error making data directory: %v", err) } // we accept two csvs: one for validators, one for accounts // if there's only one, its for validators and accounts var csvFiles []string var csvPaths string if do.CSV != "" { csvFiles = strings.Split(do.CSV, ",") if len(csvFiles) > 1 { csvPath1 := fmt.Sprintf("%s/%s/%s/%s", ErisContainerRoot, "chains", do.ChainID, "validators.csv") csvPath2 := fmt.Sprintf("%s/%s/%s/%s", ErisContainerRoot, "chains", do.ChainID, "accounts.csv") csvPaths = fmt.Sprintf("%s,%s", csvPath1, csvPath2) } else { csvPaths = fmt.Sprintf("%s/%s/%s/%s", ErisContainerRoot, "chains", do.ChainID, "genesis.csv") } } filesToCopy := []stringPair{ {do.Path, ""}, {do.GenesisFile, "genesis.json"}, {do.ConfigFile, "config.toml"}, {do.Priv, "priv_validator.json"}, } if len(csvFiles) == 1 { filesToCopy = append(filesToCopy, stringPair{csvFiles[0], "genesis.csv"}) } else if len(csvFiles) > 1 { filesToCopy = append(filesToCopy, stringPair{csvFiles[0], "validators.csv"}) filesToCopy = append(filesToCopy, stringPair{csvFiles[1], "accounts.csv"}) } log.Info("Copying chain files into the correct location") if err := copyFiles(dst, filesToCopy); err != nil { return err } // copy from host to container log.WithFields(log.Fields{ "from": dst, "to": containerDst, }).Debug("Copying files into data container") importDo := definitions.NowDo() importDo.Name = do.Name importDo.Operations = do.Operations importDo.Destination = ErisContainerRoot importDo.Source = filepath.Join(DataContainersPath, do.Name) if err = data.ImportData(importDo); err != nil { return err } chain := loaders.MockChainDefinition(do.Name, do.ChainID, false, do.Operations.ContainerNumber) //set maintainer info chain.Maintainer.Name, chain.Maintainer.Email, err = config.GitConfigUser() if err != nil { log.Debug(err.Error()) } // write the chain definition file ... fileName := filepath.Join(ChainsPath, do.Name) + ".toml" if _, err = os.Stat(fileName); err != nil { if err = WriteChainDefinitionFile(chain, fileName); err != nil { return fmt.Errorf("error writing chain definition to file: %v", err) } } chain, err = loaders.LoadChainDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } log.WithField("image", chain.Service.Image).Debug("Chain loaded") chain.Operations.PublishAllPorts = do.Operations.PublishAllPorts // TODO: remove this and marshall into struct from cli directly // cmd should be "new" or "install" chain.Service.Command = cmd // write the list of <key>:<value> config options as flags buf := new(bytes.Buffer) for _, cv := range do.ConfigOpts { spl := strings.Split(cv, "=") if len(spl) != 2 { return fmt.Errorf("Config options should be <key>=<value> pairs. Got %s", cv) } buf.WriteString(fmt.Sprintf(" --%s=%s", spl[0], spl[1])) } configOpts := buf.String() // set chainid and other vars envVars := []string{ fmt.Sprintf("CHAIN_ID=%s", do.ChainID), fmt.Sprintf("CONTAINER_NAME=%s", containerName), fmt.Sprintf("CSV=%v", csvPaths), // for mintgen fmt.Sprintf("CONFIG_OPTS=%s", configOpts), // for config.toml fmt.Sprintf("NODE_ADDR=%s", do.Gateway), // etcb host fmt.Sprintf("DOCKER_FIX=%s", " "), // https://github.com/docker/docker/issues/14203 } envVars = append(envVars, do.Env...) if do.Run { // run erisdb instead of tendermint envVars = append(envVars, "ERISDB_API=true") } log.WithFields(log.Fields{ "environment": envVars, "links": do.Links, }).Debug() chain.Service.Environment = append(chain.Service.Environment, envVars...) chain.Service.Links = append(chain.Service.Links, do.Links...) // TODO: if do.N > 1 ... chain.Operations.DataContainerName = util.DataContainersName(do.Name, do.Operations.ContainerNumber) if err := bootDependencies(chain, do); err != nil { return err } log.WithFields(log.Fields{ "=>": chain.Service.Name, "image": chain.Service.Image, }).Debug("Performing chain container start") err = perform.DockerRunService(chain.Service, chain.Operations) // this err is caught in the defer above return }