Пример #1
0
func giveMeAllTheNames(name string, srv *def.ServiceDefinition) {
	logger.Debugf("Giving myself all the names =>\t%s\n", name)
	srv.Name = name
	srv.Service.Name = name
	srv.Operations.SrvContainerName = util.DataContainersName(srv.Name, srv.Operations.ContainerNumber)
	srv.Operations.DataContainerName = util.DataContainersName(srv.Name, srv.Operations.ContainerNumber)
	logger.Debugf("My service container name is =>\t%s\n", srv.Operations.SrvContainerName)
	logger.Debugf("My data container name is =>\t%s\n", srv.Operations.DataContainerName)
}
Пример #2
0
func giveMeAllTheNames(name string, srv *def.ServiceDefinition) {
	log.WithField("=>", name).Debug("Giving myself all the names")
	srv.Name = name
	srv.Service.Name = name
	srv.Operations.SrvContainerName = util.DataContainersName(srv.Name, srv.Operations.ContainerNumber)
	srv.Operations.DataContainerName = util.DataContainersName(srv.Name, srv.Operations.ContainerNumber)
	log.WithFields(log.Fields{
		"data container":    srv.Operations.DataContainerName,
		"service container": srv.Operations.SrvContainerName,
	}).Debug("Using names")
}
Пример #3
0
func testExist(t *testing.T, name string, toExist bool) {
	var exist bool
	logger.Infof("\nTesting whether (%s) existing? (%t)\n", name, toExist)
	name = util.DataContainersName(name, 1)

	do := definitions.NowDo()
	do.Quiet = true
	if err := ListKnown(do); err != nil {
		logger.Errorln(err)
		t.FailNow()
	}
	res := strings.Split(do.Result, "\n")
	for _, r := range res {
		logger.Debugf("Existing =>\t\t\t%s\n", r)
		if r == util.ContainersShortName(name) {
			exist = true
		}
	}

	if toExist != exist {
		if toExist {
			logger.Infof("Could not find an existing =>\t%s\n", name)
		} else {
			logger.Infof("Found an existing instance of %s when I shouldn't have\n", name)
		}
		t.Fail()
	}
}
Пример #4
0
// LoadDataDefinition returns an Operation structure for a blank data container
// specified by a name dataName and a cNum number.
func LoadDataDefinition(dataName string, cNum int) *definitions.Operation {
	if cNum == 0 {
		cNum = 1
	}

	log.WithField("=>", fmt.Sprintf("%s:%d", dataName, cNum)).Debug("Loading data definition")

	ops := definitions.BlankOperation()
	ops.ContainerNumber = cNum
	ops.ContainerType = definitions.TypeData
	ops.SrvContainerName = util.DataContainersName(dataName, cNum)
	ops.DataContainerName = util.DataContainersName(dataName, cNum)
	ops.Labels = util.Labels(dataName, ops)

	return ops
}
Пример #5
0
// LoadDataDefinition returns an Operation structure for a blank data container
// specified by a name dataName and a cNum number.
func LoadDataDefinition(dataName string, cNum int) *definitions.Operation {
	if cNum == 0 {
		cNum = 1
	}

	logger.Debugf("Loading Data Definition =>\t%s:%d\n", dataName, cNum)

	ops := definitions.BlankOperation()
	ops.ContainerNumber = cNum
	ops.ContainerType = definitions.TypeData
	ops.SrvContainerName = util.DataContainersName(dataName, cNum)
	ops.DataContainerName = util.DataContainersName(dataName, cNum)
	ops.Labels = util.Labels(dataName, ops)

	return ops
}
Пример #6
0
// ImportData does what it says. It imports from a host's Source to a Dest
// in a data container. It returns an error.
//
//  do.Name                       - name of the data container to use (required)
//  do.Operations.ContainerNumber - container number (optional)
//  do.Source                     - directory which should be imported (required)
//  do.Destination                - directory to _unload_ the payload into (required)
//
func ImportData(do *definitions.Do) error {
	log.WithFields(log.Fields{
		"from": do.Source,
		"to":   do.Destination,
	}).Debug("Importing")
	if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) {

		srv := PretendToBeAService(do.Name, do.Operations.ContainerNumber)
		service, exists := perform.ContainerExists(srv.Operations)

		if !exists {
			return fmt.Errorf("There is no data container for that service.")
		}
		if err := checkErisContainerRoot(do, "import"); err != nil {
			return err
		}

		containerName := util.DataContainersName(do.Name, do.Operations.ContainerNumber)
		os.Chdir(do.Source)

		reader, err := util.Tar(do.Source, 0)
		if err != nil {
			return err
		}
		defer reader.Close()

		opts := docker.UploadToContainerOptions{
			InputStream:          reader,
			Path:                 do.Destination,
			NoOverwriteDirNonDir: true,
		}

		log.WithField("=>", containerName).Info("Copying into container")
		log.WithField("path", do.Source).Debug()
		if err := util.DockerClient.UploadToContainer(service.ID, opts); err != nil {
			return err
		}

		doChown := definitions.NowDo()
		doChown.Operations.DataContainerName = containerName
		doChown.Operations.ContainerType = "data"
		doChown.Operations.ContainerNumber = do.Operations.ContainerNumber
		//required b/c `docker cp` (UploadToContainer) goes in as root
		doChown.Operations.Args = []string{"chown", "--recursive", "eris", do.Destination}
		_, err = perform.DockerRunData(doChown.Operations, nil)
		if err != nil {
			return fmt.Errorf("Error changing owner: %v\n", err)
		}
	} else {
		log.WithField("name", do.Name).Info("Data container does not exist.")
		ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber)
		if err := perform.DockerCreateData(ops); err != nil {
			return fmt.Errorf("Error creating data container %v.", err)
		}
		return ImportData(do)
	}
	do.Result = "success"
	return nil
}
Пример #7
0
func ImportData(do *definitions.Do) error {
	if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) {

		srv := PretendToBeAService(do.Name, do.Operations.ContainerNumber)
		service, exists := perform.ContainerExists(srv.Operations)

		if !exists {
			return fmt.Errorf("There is no data container for that service.")
		}

		containerName := util.DataContainersName(do.Name, do.Operations.ContainerNumber)
		logger.Debugf("Importing FROM =>\t\t%s\n", do.Source)
		os.Chdir(do.Source)

		logger.Debugf("Importing TO =>\t\t\t%s\n", do.Destination)
		reader, err := util.Tar(do.Source, 0)
		if err != nil {
			return err
		}
		defer reader.Close()

		opts := docker.UploadToContainerOptions{
			InputStream:          reader,
			Path:                 do.Destination,
			NoOverwriteDirNonDir: true,
		}

		logger.Infof("Copying into Cont. ID =>\t%s\n", service.ID)
		logger.Debugf("\tPath =>\t\t\t%s\n", do.Source)
		if err := util.DockerClient.UploadToContainer(service.ID, opts); err != nil {
			return err
		}

		doChown := definitions.NowDo()
		doChown.Operations.DataContainerName = containerName
		doChown.Operations.ContainerType = "data"
		doChown.Operations.ContainerNumber = 1
		doChown.Operations.Args = []string{"chown", "--recursive", "eris", do.Destination}
		_, err = perform.DockerRunData(doChown.Operations, nil)
		if err != nil {
			return fmt.Errorf("Error changing owner: %v\n", err)
		}
	} else {
		ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber)
		if err := perform.DockerCreateData(ops); err != nil {
			return fmt.Errorf("Error creating data container %v.", err)
		}
		return ImportData(do)
	}
	do.Result = "success"
	return nil
}
Пример #8
0
func ExecData(do *definitions.Do) error {
	if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) {
		do.Name = util.DataContainersName(do.Name, do.Operations.ContainerNumber)
		logger.Infoln("Running exec on container with volumes from data container " + do.Name)
		if err := perform.DockerRunVolumesFromContainer(do.Name, do.Interactive, do.Args); 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
}
Пример #9
0
func RegisterChain(do *definitions.Do) error {
	// do.Name is mandatory
	if do.Name == "" {
		return fmt.Errorf("RegisterChain requires a chainame")
	}
	etcbChain := do.ChainID
	do.ChainID = do.Name

	// NOTE: registration expects you to have the data container
	if !data.IsKnown(do.Name) {
		return fmt.Errorf("Registration requires you to have a data container for the chain. Could not find data for %s", do.Name)
	}

	chain, err := loaders.LoadChainDefinition(do.Name, false, do.Operations.ContainerNumber)
	if err != nil {
		return err
	}
	logger.Debugf("Chain Loaded. Image =>\t\t%v\n", chain.Service.Image)

	// set chainid and other vars
	envVars := []string{
		fmt.Sprintf("CHAIN_ID=%s", do.ChainID),      // of the etcb chain
		fmt.Sprintf("PUBKEY=%s", do.Pubkey),         // pubkey to register chain with
		fmt.Sprintf("ETCB_CHAIN_ID=%s", etcbChain),  // chain id of the etcb chain
		fmt.Sprintf("NODE_ADDR=%s", do.Gateway),     // etcb node to send the register tx to
		fmt.Sprintf("NEW_P2P_SEEDS=%s", do.Args[0]), // seeds to register for the chain // TODO: deal with multi seed (needs support in tendermint)
	}
	envVars = append(envVars, do.Env...)

	logger.Debugf("Set env vars from RegisterChain =>\t%v\n", envVars)
	chain.Service.Environment = append(chain.Service.Environment, envVars...)
	logger.Debugf("Set links from RegisterChain =>\t%v\n", do.Links)
	chain.Service.Links = append(chain.Service.Links, do.Links...)

	if err := bootDependencies(chain, do); err != nil {
		return err
	}

	logger.Debugf("Starting chain container via Docker =>\t%s\n", chain.Service.Name)
	logger.Debugf("\twith Image =>\t\t%s\n", chain.Service.Image)
	cmd := []string{loaders.ErisChainRegister}
	dataContainerName := util.DataContainersName(chain.Name, chain.Operations.ContainerNumber)
	_, err = perform.DockerRunVolumesFromContainer(dataContainerName, false, cmd, chain.Service)

	return err
}
Пример #10
0
// eris chains new -c _ -csv _
func TestChainsNewConfigAndCSV(t *testing.T) {
	chainID := "testChainsNewConfigAndCSV"
	do := def.NowDo()
	do.Name = chainID
	do.ConfigFile = path.Join(common.BlockchainsPath, "config", "default", "config.toml")
	do.CSV = path.Join(common.BlockchainsPath, "config", "default", "genesis.csv")
	do.Operations.ContainerNumber = 1
	logger.Infof("Creating chain (from tests) =>\t%s\n", do.Name)
	ifExit(NewChain(do))

	b, err := ioutil.ReadFile(do.ConfigFile)
	if err != nil {
		fatal(t, err)
	}

	fmt.Println("CONFIG CONFIG CONFIG:", string(b))

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

	// verify the contents of config.toml
	do.Name = util.DataContainersName(do.Name, do.Operations.ContainerNumber)
	args := []string{"cat", fmt.Sprintf("/home/eris/.eris/blockchains/%s/config.toml", chainID)}
	result := trimResult(string(runContainer(t, do.Name, args)))
	contents := trimResult(ini.DefChainConfig())
	if result != contents {
		fatal(t, 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)
	args = []string{"cat", fmt.Sprintf("/home/eris/.eris/blockchains/%s/genesis.json", chainID)}
	result = string(runContainer(t, do.Name, args))

	var found bool
	for _, s := range strings.Split(result, "\n") {
		if strings.Contains(s, ini.DefaultPubKeys[0]) {
			found = true
			break
		}
	}
	if !found {
		fatal(t, fmt.Errorf("Did not find pubkey %s in genesis.json: %s", ini.DefaultPubKeys[0], result))
	}
}
Пример #11
0
func ImportData(do *definitions.Do) error {
	if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) {

		containerName := util.DataContainersName(do.Name, do.Operations.ContainerNumber)
		importPath := filepath.Join(DataContainersPath, do.Name)

		// temp until docker cp works both ways.
		logger.Debugf("Importing FROM =>\t\t%s\n", importPath)
		os.Chdir(importPath)
		// TODO [eb]: deal with hardcoded user
		// TODO [csk]: drop the whole damn cmd call
		//         use go's tar lib to make a tarball of the directory
		//         read the tar file into an io.Reader
		//         start a container with its Stdin open, connect to an io.Writer
		//         connect them up with io.Pipe
		//         this will free us from any quirks that the cli has
		if do.Path != "" {
			do.Path = do.Path
		} else {
			do.Path = "/home/eris/.eris"
		}

		logger.Debugf("Importing TO =>\t\t\t%s\n", do.Path)
		cmd := "tar chf - . | docker run -i --rm --volumes-from " + containerName + " --user eris eris/data tar xf - -C " + do.Path
		_, err := pipes.RunString(cmd)
		if err != nil {
			cmd := "tar chf - . | docker run -i --volumes-from " + containerName + " --user eris eris/data tar xf - -C " + do.Path
			_, e2 := pipes.RunString(cmd)
			if e2 != nil {
				return fmt.Errorf("Could not import the data container.\nTried with docker --rm =>\t%v\nTried without docker --rm =>\t%v", err, e2)
			}
		}
	} else {
		if err := perform.DockerCreateDataContainer(do.Name, do.Operations.ContainerNumber); err != nil {
			return fmt.Errorf("Error creating data container %v.", err)
		}
		return ImportData(do)
	}
	do.Result = "success"
	return nil
}
Пример #12
0
// Build against Docker cli...
//   Client version: 1.6.2, 1.7
//   Client API version: 1.18, 1.19
// Verified against ...
//   Client version: 1.6.2, 1.7
//   Client API version: 1.18, 1.19
func DockerCreateDataContainer(srvName string, containerNumber int) error {
	logger.Infof("Creating Data Container for =>\t%s\n", srvName)

	srv := def.BlankServiceDefinition()
	srv.Operations.DataContainerName = util.DataContainersName(srvName, containerNumber)
	optsData, err := configureDataContainer(srv.Service, srv.Operations, nil)
	if err != nil {
		return err
	}

	srv.Operations.SrvContainerName = srv.Operations.DataContainerName // mock for the query function
	if _, exists := ContainerExists(srv.Operations); exists {
		logger.Infoln("Data container exists. Not creating.")
		return nil
	}

	cont, err := createContainer(optsData)
	if err != nil {
		return err
	}

	logger.Infof("Data Container ID =>\t\t%s\n", cont.ID)
	return nil
}
Пример #13
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
	logger.Infof("Creating chain (from tests) =>\t%s\n", do.Name)
	ifExit(NewChain(do))

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

	// verify the contents of config.toml
	do.Name = util.DataContainersName(do.Name, do.Operations.ContainerNumber)
	args := []string{"cat", fmt.Sprintf("/home/eris/.eris/blockchains/%s/config.toml", chainID)}
	result := string(runContainer(t, do.Name, args))

	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 {
		fatal(t, fmt.Errorf("failed to find fields: %s", result))
	}
}
Пример #14
0
//----------------------------------------------------------------------
// validation funcs
func checkChainNames(chain *definitions.Chain) {
	chain.Service.Name = chain.Name
	chain.Operations.SrvContainerName = util.ChainContainersName(chain.Name, chain.Operations.ContainerNumber)
	chain.Operations.DataContainerName = util.DataContainersName(chain.Name, chain.Operations.ContainerNumber)
}
Пример #15
0
// MakeChain runs the `eris-cm make` command in a docker container.
// It returns an error. Note that if do.Known, do.AccountTypes
// or do.ChainType are not set the command will run via interactive
// shell.
//
//  do.Name          - name of the chain to be created (required)
//  do.Known         - will use the mintgen tool to parse csv's and create a genesis.json (requires do.ChainMakeVals and do.ChainMakeActs) (optional)
//  do.ChainMakeVals - csv file to use for validators (optional)
//  do.ChainMakeActs - csv file to use for accounts (optional)
//  do.AccountTypes  - use eris-cm make account-types paradigm (example: Root:1,Participants:25,...) (optional)
//  do.ChainType     - use eris-cm make chain-types paradigm (example: simplechain) (optional)
//  do.Tarball       - instead of outputing raw files in directories, output packages of tarbals (optional)
//  do.ZipFile       - similar to do.Tarball except uses zipfiles (optional)
//  do.Verbose       - verbose output (optional)
//  do.Debug         - debug output (optional)
//
func MakeChain(do *definitions.Do) error {
	do.Service.Name = do.Name
	do.Service.Image = path.Join(version.ERIS_REG_DEF, version.ERIS_IMG_CM)
	do.Service.User = "******"
	do.Service.AutoData = true
	do.Service.Links = []string{fmt.Sprintf("%s:%s", util.ServiceContainersName("keys", do.Operations.ContainerNumber), "keys")}
	do.Service.Environment = []string{
		fmt.Sprintf("ERIS_KEYS_PATH=http://keys:%d", 4767), // note, needs to be made aware of keys port...
		fmt.Sprintf("ERIS_CHAINMANAGER_ACCOUNTTYPES=%s", strings.Join(do.AccountTypes, ",")),
		fmt.Sprintf("ERIS_CHAINMANAGER_CHAINTYPE=%s", do.ChainType),
		fmt.Sprintf("ERIS_CHAINMANAGER_TARBALLS=%v", do.Tarball),
		fmt.Sprintf("ERIS_CHAINMANAGER_ZIPFILES=%v", do.ZipFile),
		fmt.Sprintf("ERIS_CHAINMANAGER_OUTPUT=%v", do.Output),
		fmt.Sprintf("ERIS_CHAINMANAGER_VERBOSE=%v", do.Verbose),
		fmt.Sprintf("ERIS_CHAINMANAGER_DEBUG=%v", do.Debug),
	}

	do.Operations.ContainerType = "service"
	do.Operations.SrvContainerName = util.ServiceContainersName(do.Name, do.Operations.ContainerNumber)
	do.Operations.DataContainerName = util.DataContainersName(do.Name, do.Operations.ContainerNumber)
	if do.RmD {
		do.Operations.Remove = true
	}

	if do.Known {
		log.Debug("Using MintGen rather than eris:cm")
		do.Service.EntryPoint = "mintgen"
		do.Service.Command = fmt.Sprintf("known %s --csv=%s,%s > %s", do.Name, do.ChainMakeVals, do.ChainMakeActs, path.Join(ErisContainerRoot, "chains", do.Name, "genesis.json"))
	} else {
		log.Debug("Using eris:cm rather than MintGen")
		do.Service.EntryPoint = fmt.Sprintf("eris-cm make %s", do.Name)
	}

	if !do.Known && len(do.AccountTypes) == 0 && do.ChainType == "" {
		do.Operations.Interactive = true
		do.Operations.Args = strings.Split(do.Service.EntryPoint, " ")
	}

	if do.Known {
		do.Operations.Args = append(do.Operations.Args, strings.Split(do.Service.Command, " ")...)
		do.Service.WorkDir = path.Join(ErisContainerRoot, "chains", do.Name)
	}

	doData := definitions.NowDo()
	doData.Name = do.Name
	doData.Operations.ContainerNumber = do.Operations.ContainerNumber
	doData.Operations.DataContainerName = util.DataContainersName(do.Name, do.Operations.ContainerNumber)
	doData.Operations.ContainerType = "service"
	if !do.RmD {
		defer data.RmData(doData)
	}

	doData.Source = AccountsTypePath
	doData.Destination = path.Join(ErisContainerRoot, "chains", "account-types")
	if err := data.ImportData(doData); err != nil {
		return err
	}
	doData.Source = ChainTypePath
	doData.Destination = path.Join(ErisContainerRoot, "chains", "chain-types")
	if err := data.ImportData(doData); err != nil {
		return err
	}
	chnPath := filepath.Join(ChainsPath, do.Name)
	if _, err := os.Stat(chnPath); !os.IsNotExist(err) {
		doData.Operations.Args = []string{"mkdir", "--parents", path.Join(ErisContainerRoot, "chains", do.Name)}
		if err := data.ExecData(doData); err != nil {
			return err
		}
		doData.Operations.Args = []string{}
		doData.Source = chnPath
		doData.Destination = path.Join(ErisContainerRoot, "chains", do.Name)
		if err := data.ImportData(doData); err != nil {
			return err
		}
	}

	if err := perform.DockerExecService(do.Service, do.Operations); err != nil {
		return err
	}

	doData.Source = path.Join(ErisContainerRoot, "chains")
	doData.Destination = ErisRoot
	return data.ExportData(doData)
}
Пример #16
0
func DefineAppActionService(do *definitions.Do, app *definitions.Contracts) error {
	var cmd string

	switch do.Name {
	case "test":
		cmd = app.AppType.TestCmd
	case "deploy":
		cmd = app.AppType.DeployCmd
	default:
		return fmt.Errorf("I do not know how to perform that task (%s)\nPlease check what you can do with contracts by typing [eris contracts].\n", do.Name)
	}

	// if manual, set task
	if app.AppType.Name == "manual" {
		switch do.Name {
		case "test":
			cmd = app.TestTask
		case "deploy":
			cmd = app.DeployTask
		}
	}

	// task flag override
	if do.Task != "" {
		app.AppType = definitions.GulpApp()
		cmd = do.Task
	}

	if cmd == "nil" {
		return fmt.Errorf("I cannot perform that task against that app type.\n")
	}

	// build service that will run
	do.Service.Name = app.Name + "_tmp_" + do.Name
	do.Service.Image = app.AppType.BaseImage
	do.Service.AutoData = true
	do.Service.EntryPoint = app.AppType.EntryPoint
	do.Service.Command = cmd
	if do.Path != pwd {
		do.Service.WorkDir = do.Path // do.Path is actually where the workdir inside the container goes
	} else {
		do.Service.WorkDir = filepath.Join(common.ErisContainerRoot, "apps", app.Name)
	}
	do.Service.User = "******"

	srv := definitions.BlankServiceDefinition()
	srv.Service = do.Service
	srv.Operations = do.Operations
	loaders.ServiceFinalizeLoad(srv)
	do.Service = srv.Service
	do.Operations = srv.Operations
	do.Operations.Follow = true

	linkAppToChain(do, app)

	if app.AppType.Name == "epm" {
		prepareEpmAction(do, app)
	}

	// make data container and import do.Path to do.Path (if exists)
	doData := definitions.NowDo()
	doData.Name = do.Service.Name
	doData.Operations = do.Operations
	if do.Path != pwd {
		doData.Destination = do.Path
	} else {
		doData.Destination = common.ErisContainerRoot
	}

	doData.Source = filepath.Join(common.DataContainersPath, doData.Name)
	var loca string
	if do.Path != pwd {
		loca = filepath.Join(common.DataContainersPath, doData.Name, do.Path)
	} else {
		loca = filepath.Join(common.DataContainersPath, doData.Name, "apps", app.Name)
	}
	log.WithFields(log.Fields{
		"path":     do.Path,
		"location": loca,
	}).Debug("Creating app data container")
	common.Copy(do.Path, loca)
	if err := data.ImportData(doData); err != nil {
		return err
	}
	do.Operations.DataContainerName = util.DataContainersName(doData.Name, doData.Operations.ContainerNumber)

	log.Debug("App action built")
	return nil
}
Пример #17
0
//export from: do.Source(in container), to: do.Destination(on host)
func ExportData(do *definitions.Do) error {
	if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) {
		log.WithField("=>", do.Name).Info("Exporting data container")

		// we want to export to a temp directory.
		exportPath, err := ioutil.TempDir(os.TempDir(), do.Name) // TODO: do.Operations.ContainerNumber ?
		defer os.Remove(exportPath)
		if err != nil {
			return err
		}

		containerName := util.DataContainersName(do.Name, do.Operations.ContainerNumber)
		srv := PretendToBeAService(do.Name, do.Operations.ContainerNumber)
		service, exists := perform.ContainerExists(srv.Operations)

		if !exists {
			return fmt.Errorf("There is no data container for that service.")
		}

		reader, writer := io.Pipe()
		defer reader.Close()

		if err := checkErisContainerRoot(do, "export"); err != nil {
			return err
		}
		opts := docker.DownloadFromContainerOptions{
			OutputStream: writer,
			Path:         do.Source,
		}

		go func() {
			log.WithField("=>", containerName).Info("Copying out of container")
			log.WithField("path", do.Source).Debug()
			IfExit(util.DockerClient.DownloadFromContainer(service.ID, opts)) // TODO: be smarter about catching this error
			writer.Close()
		}()

		log.WithField("=>", exportPath).Debug("Untarring package from container")
		if err = util.Untar(reader, do.Name, exportPath); err != nil {
			return err
		}

		// now if docker dumps to exportPath/.eris we should remove
		// move everything from .eris to exportPath
		if err := moveOutOfDirAndRmDir(filepath.Join(exportPath, ".eris"), exportPath); err != nil {
			return err
		}

		// finally remove everything in the data directory and move
		// the temp contents there
		if _, err := os.Stat(do.Destination); os.IsNotExist(err) {
			if e2 := os.MkdirAll(do.Destination, 0755); e2 != nil {
				return fmt.Errorf("Error:\tThe marmots could neither find, nor had access to make the directory: (%s)\n", do.Destination)
			}
		}
		if err := moveOutOfDirAndRmDir(exportPath, do.Destination); 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
}
Пример #18
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 := path.Join(common.DataContainersPath, chainID)
	if err := os.MkdirAll(myDir, 0700); err != nil {
		fatal(t, err)
	}
	contents := "this is a file in the directory\n"
	if err := ioutil.WriteFile(path.Join(myDir, "file.file"), []byte(contents), 0600); err != nil {
		fatal(t, err)
	}

	do := def.NowDo()
	do.GenesisFile = path.Join(common.BlockchainsPath, "default", "genesis.json")
	do.Name = chainID
	do.Path = myDir
	do.Operations.ContainerNumber = 1
	logger.Infof("Creating chain (from tests) =>\t%s\n", do.Name)
	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
	do.Name = util.DataContainersName(do.Name, do.Operations.ContainerNumber)
	oldWriter := config.GlobalConfig.Writer
	newWriter := new(bytes.Buffer)
	config.GlobalConfig.Writer = newWriter
	args := []string{"cat", fmt.Sprintf("/home/eris/.eris/blockchains/%s/file.file", chainID)}
	b, err := perform.DockerRunVolumesFromContainer(do.Name, false, args, nil)
	if err != nil {
		fatal(t, err)
	}

	config.GlobalConfig.Writer = oldWriter
	result := trimResult(string(b))
	contents = trimResult(contents)
	if result != contents {
		fatal(t, 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
	args = []string{"cat", fmt.Sprintf("/home/eris/.eris/blockchains/%s/genesis.json", chainID)} //, "|", "jq", ".chain_id"}
	b, err = perform.DockerRunVolumesFromContainer(do.Name, false, args, nil)
	if err != nil {
		fatal(t, err)
	}

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

	s := struct {
		ChainID string `json:"chain_id"`
	}{}
	if err := json.Unmarshal([]byte(result), &s); err != nil {
		fatal(t, err)
	}
	if s.ChainID != chainID {
		fatal(t, fmt.Errorf("ChainID mismatch: got %s, expected %s", s.ChainID, chainID))
	}
}
Пример #19
0
// 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
	}

	// ensure/create data container
	if !data.IsKnown(containerName) {
		if err := perform.DockerCreateDataContainer(do.Name, do.Operations.ContainerNumber); err != nil {
			return fmt.Errorf("Error creating data containr =>\t%v", err)
		}
	} else {
		logger.Debugln("Data container already exists for", do.Name)
	}

	logger.Debugf("Chain's Data Contain Built =>\t%s\n", do.Name)

	// if something goes wrong, cleanup
	defer func() {
		if err != nil {
			logger.Infof("Error on setupChain =>\t\t%v\n", err)
			logger.Infoln("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 := path.Join("blockchains", do.Name)           // path in container
	dst := path.Join(DataContainersPath, do.Name, containerDst) // path on host
	// TODO: deal with do.Operations.ContainerNumbers ....!
	// we probably need to update Import

	logger.Debugln("container destination:", containerDst)
	logger.Debugln("local destination:", dst)

	if err = os.MkdirAll(dst, 0700); err != nil {
		return fmt.Errorf("Error making data directory: %v", err)
	}

	var csvFile, csvPath string
	if do.CSV != "" {
		csvFile = "genesis.csv"
		csvPath = fmt.Sprintf("/home/eris/.eris/blockchains/%s/%s", do.ChainID, csvFile)
	}

	if err := copyFiles(dst, []stringPair{
		{do.Path, ""},
		{do.GenesisFile, "genesis.json"},
		{do.ConfigFile, "config.toml"},
		{do.Priv, "priv_validator.json"},
		{do.CSV, csvFile},
	}); err != nil {
		return err
	}

	// copy from host to container
	logger.Debugf("Copying Files into DataCont =>\t%s:%s\n", dst, containerDst)
	importDo := definitions.NowDo()
	importDo.Name = do.Name
	importDo.Operations = do.Operations
	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 {
		logger.Debugf(err.Error())
	}

	// write the chain definition file ...
	fileName := filepath.Join(BlockchainsPath, 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
	}
	logger.Debugf("Chain Loaded. Image =>\t\t%v\n", chain.Service.Image)
	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

	// do we need to create our own do.GenesisFile?
	var genGen bool
	if do.GenesisFile == "" {
		genGen = true
	}

	// 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("RUN=%v", do.Run),
		fmt.Sprintf("GENERATE_GENESIS=%v", genGen),
		fmt.Sprintf("CSV=%v", csvPath),
		fmt.Sprintf("CONFIG_OPTS=%s", configOpts),
	}

	logger.Debugf("Set env vars from setupChain =>\t%v\n", envVars)
	for _, eV := range envVars {
		chain.Service.Environment = append(chain.Service.Environment, eV)
	}

	// TODO: if do.N > 1 ...

	chain.Operations.DataContainerName = util.DataContainersName(do.Name, do.Operations.ContainerNumber)

	if os.Getenv("TEST_IN_CIRCLE") != "true" {
		chain.Operations.Remove = true
	}

	logger.Debugf("Starting chain via Docker =>\t%s\n", chain.Service.Name)
	logger.Debugf("\twith Image =>\t\t%s\n", chain.Service.Image)
	err = perform.DockerRun(chain.Service, chain.Operations)
	// this err is caught in the defer above

	return
}
Пример #20
0
func DefineDappActionService(do *definitions.Do, dapp *definitions.Contracts) error {
	var cmd string

	switch do.Name {
	case "test":
		cmd = dapp.DappType.TestCmd
	case "deploy":
		cmd = dapp.DappType.DeployCmd
	default:
		return fmt.Errorf("I do not know how to perform that task (%s)\nPlease check what you can do with contracts by typing [eris contracts].\n", do.Name)
	}

	// if manual, set task
	if dapp.DappType.Name == "manual" {
		switch do.Name {
		case "test":
			cmd = dapp.TestTask
		case "deploy":
			cmd = dapp.DeployTask
		}
	}

	// task flag override
	if do.Task != "" {
		dapp.DappType = definitions.GulpDapp()
		cmd = do.Task
	}

	if cmd == "nil" {
		return fmt.Errorf("I cannot perform that task against that dapp type.\n")
	}

	// dapp-specific tests
	if dapp.DappType.Name == "pyepm" {
		if do.ConfigFile == "" {
			return fmt.Errorf("The pyepm dapp type requires a --yaml flag for the package definition you would like to deploy.\n")
		} else {
			cmd = do.ConfigFile
		}
	}

	// build service that will run
	do.Service.Name = dapp.Name + "_tmp_" + do.Name
	do.Service.Image = dapp.DappType.BaseImage
	do.Service.AutoData = true
	do.Service.EntryPoint = dapp.DappType.EntryPoint
	do.Service.Command = cmd
	if do.NewName != "" {
		do.Service.WorkDir = do.NewName // do.NewName is actually where the workdir inside the container goes
	}
	do.Service.User = "******"

	srv := definitions.BlankServiceDefinition()
	srv.Service = do.Service
	srv.Operations = do.Operations
	loaders.ServiceFinalizeLoad(srv)
	do.Service = srv.Service
	do.Operations = srv.Operations
	do.Operations.Remove = true

	linkDappToChain(do, dapp)

	// make data container and import do.Path to do.NewName (if exists)
	doData := definitions.NowDo()
	doData.Name = do.Service.Name
	doData.Operations = do.Operations
	if do.NewName != "" {
		doData.Path = do.NewName
	}

	loca := path.Join(common.DataContainersPath, doData.Name)
	logger.Debugf("Creating Dapp Data Cont =>\t%s:%s\n", do.Path, loca)
	common.Copy(do.Path, loca)
	data.ImportData(doData)
	do.Operations.DataContainerName = util.DataContainersName(doData.Name, doData.Operations.ContainerNumber)

	logger.Debugf("DApp Action Built.\n")

	return nil
}
Пример #21
0
// 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() {
			logger.Infof("Path (%s) does not exist or is not a directory, trying $HOME/.eris/chains/%s\n", do.Path, do.Path)
			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 !data.IsKnown(do.Name) {
		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)
		}
	} else {
		logger.Debugln("Data container already exists for", do.Name)
	}

	logger.Debugf("Chain's Data Contain Built =>\t%s\n", do.Name)

	// if something goes wrong, cleanup
	defer func() {
		if err != nil {
			logger.Infof("Error on setupChain =>\t\t%v\n", err)
			logger.Infoln("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 := path.Join("chains", do.Name)                // path in container
	dst := path.Join(DataContainersPath, do.Name, containerDst) // path on host
	// TODO: deal with do.Operations.ContainerNumbers ....!
	// we probably need to update Import

	logger.Debugf("Container destination =>\t%s\n", containerDst)
	logger.Debugf("Local destination =>\t\t%s\n", dst)

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

	logger.Infof("Copying chain files into the correct location.\n")
	if err := copyFiles(dst, filesToCopy); err != nil {
		return err
	}

	// copy from host to container
	logger.Debugf("Copying Files into DataCont =>\t%s:%s\n", dst, containerDst)
	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 {
		logger.Debugf(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
	}
	logger.Debugf("Chain Loaded. Image =>\t\t%v\n", chain.Service.Image)
	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")
	}

	logger.Debugf("Set env vars from setupChain =>\t%v\n", envVars)
	chain.Service.Environment = append(chain.Service.Environment, envVars...)
	logger.Debugf("Set links from setupChain =>\t%v\n", do.Links)
	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
	}

	logger.Debugf("Starting chain via Docker =>\t%s\n", chain.Service.Name)
	logger.Debugf("\twith Image =>\t\t%s\n", chain.Service.Image)

	err = perform.DockerRunService(chain.Service, chain.Operations)
	// this err is caught in the defer above

	return
}
Пример #22
0
// 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
	}

	// do.Run containers and exit (creates data container)
	if !data.IsKnown(containerName) {
		if err := perform.DockerCreateDataContainer(do.Name, do.Operations.ContainerNumber); err != nil {
			return fmt.Errorf("Error creating data containr =>\t%v", err)
		}
	}

	logger.Debugf("Chain's Data Contain Built =>\t%s\n", do.Name)

	// if something goes wrong, cleanup
	defer func() {
		if err != nil {
			logger.Infof("Error on setupChain =>\t\t%v\n", err)
			logger.Infoln("Cleaning up...")
			if err2 := RmChain(do); err2 != nil {
				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, config into container
	containerDst := path.Join("blockchains", do.Name)           // path in container
	dst := path.Join(DataContainersPath, do.Name, containerDst) // path on host
	// TODO: deal with do.Operations.ContainerNumbers ....!
	// we probably need to update Import

	if err = os.MkdirAll(dst, 0700); err != nil {
		return fmt.Errorf("Error making data directory: %v", err)
	}

	if do.Path != "" {
		if err = Copy(do.Path, dst); err != nil {
			return err
		}
	}
	if do.GenesisFile != "" {
		if err = Copy(do.GenesisFile, path.Join(dst, "genesis.json")); err != nil {
			return err
		}
	} else {
		// TODO: do.Run mintgen and open the do.GenesisFile in editor
	}

	if do.ConfigFile != "" {
		if err = Copy(do.ConfigFile, path.Join(dst, "config."+path.Ext(do.ConfigFile))); err != nil {
			return err
		}
	}

	// copy from host to container
	logger.Debugf("Copying Files into DataCont =>\t%s:%s\n", dst, containerDst)
	importDo := definitions.NowDo()
	importDo.Name = do.Name
	importDo.Operations = do.Operations
	if err = data.ImportData(importDo); err != nil {
		return err
	}

	chain := loaders.MockChainDefinition(do.Name, do.ChainID, false, do.Operations.ContainerNumber)

	//get maintainer info
	uName, err := gitconfig.Username()
	if err != nil {
		logger.Debugf("Could not find git user.name, setting chain.Maintainer.Name = \"\"")
		uName = ""
	}
	email, err := gitconfig.Email()
	if err != nil {
		logger.Debugf("Could not find git user.email, setting chain.Maintainer.Email = \"\"")
		email = ""
	}

	chain.Maintainer.Name = uName
	chain.Maintainer.Email = email

	// write the chain definition file ...
	fileName := filepath.Join(BlockchainsPath, 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
	}
	logger.Debugf("Chain Loaded. Image =>\t\t%v\n", chain.Service.Image)
	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

	// do we need to create our own do.GenesisFile?
	var genGen bool
	if do.GenesisFile == "" {
		genGen = true
	}

	// set chainid and other vars
	envVars := []string{
		"CHAIN_ID=" + do.ChainID,
		"CONTAINER_NAME=" + containerName,
		fmt.Sprintf("RUN=%v", do.Run),
		fmt.Sprintf("GENERATE_GENESIS=%v", genGen),
	}

	logger.Debugf("Set env vars from setupChain =>\t%v\n", envVars)
	for _, eV := range envVars {
		chain.Service.Environment = append(chain.Service.Environment, eV)
	}
	// TODO mint vs. erisdb (in terms of rpc)

	chain.Operations.DataContainerName = util.DataContainersName(do.Name, do.Operations.ContainerNumber)

	if os.Getenv("TEST_IN_CIRCLE") != "true" {
		chain.Operations.Remove = true
	}

	logger.Debugf("Starting chain via Docker =>\t%s\n", chain.Service.Name)
	logger.Debugf("\twith Image =>\t\t%s\n", chain.Service.Image)
	err = perform.DockerRun(chain.Service, chain.Operations)
	// this err is caught in the defer above

	return
}
Пример #23
0
//return to handle failings in each pkg
//typ = type of test for dealing with do.() details
func TestExistAndRun(name, typ string, contNum int, toExist, toRun bool) bool {
	var exist, run bool
	if typ == "actions" {
		name = strings.Replace(name, " ", "_", -1) // dirty
	}

	//logger.Infof("\nTesting whether (%s) existing? (%t)\n", name, toExist)
	logger.Infof("\nTesting whether (%s) is running? (%t) and existing? (%t)\n", name, toRun, toExist)
	if typ == "chains" {
		name = util.ChainContainersName(name, 1) // not worried about containerNumbers, deal with multiple containers in services tests
	} else if typ == "services" {
		name = util.ServiceContainersName(name, contNum)

	} else {
		name = util.DataContainersName(name, 1)
	}
	do := def.NowDo()
	do.Quiet = true
	do.Operations.Args = []string{"testing"}

	if typ == "data" || typ == "chains" || typ == "services" {
		do.Existing = true
	} else if typ == "actions" {
		do.Known = true
	}
	if err := util.ListAll(do, typ); err != nil {
		logger.Errorln(err)
		return true
	}

	res := strings.Split(do.Result, "\n")
	for _, r := range res {
		logger.Debugf("Existing =>\t\t\t%s\n", r)
		if r == util.ContainersShortName(name) {
			exist = true
		}
	}

	if toExist != exist {
		if toExist {
			logger.Infof("Could not find an existing =>\t%s\n", name)
		} else {
			logger.Infof("Found an existing instance of %s when I shouldn't have\n", name)
		}
		return true
	}
	//func should always be testing for toExist, only sometimes tested for runining
	if typ == "chains" || typ == "services" {
		do.Running = true
		do.Existing = false //unset
		if err := util.ListAll(do, typ); err != nil {
			return true
		}
		logger.Debugln("RUNNING RESULT:", do.Result)
		res = strings.Split(do.Result, "\n")
		for _, r := range res {
			logger.Debugf("Running =>\t\t\t%s\n", r)
			if r == util.ContainersShortName(name) {
				run = true
			}
		}

		if toRun != run {
			if toRun {
				logger.Infof("Could not find a running =>\t%s\n", name)
			} else {
				logger.Infof("Found a running instance of %s when I shouldn't have\n", name)
			}
			return true
		}
	}

	return false
}