Пример #1
0
func StartServicesAndChains(do *definitions.Do) error {
	// start the services and chains
	doSrvs := definitions.NowDo()
	if do.Action.Dependencies == nil || len(do.Action.Dependencies.Services) == 0 {
		log.Debug("No services to start")
	} else {
		doSrvs.Operations.Args = do.Action.Dependencies.Services
		log.WithField("args", doSrvs.Operations.Args).Debug("Starting services")
		if err := services.StartService(doSrvs); err != nil {
			return err
		}
	}

	doChns := definitions.NowDo()
	doChns.Name = do.Action.Chain
	if doChns.Name == "" {
		log.Debug("No chain to start")
	} else {
		log.WithField("=>", doChns.Name).Debug("Starting chain")
		if err := chains.StartChain(do); err != nil {
			return err
		}
	}

	return nil
}
Пример #2
0
// Add a new entry (name) to the top of the HEAD file
// Expects the chain type and head (id) to be full (already resolved)
func ChangeHead(name string) error {
	if !IsKnownChain(name) && name != "" {
		log.Debug("Chain name not known. Not saving")
		return nil
	}

	log.Debug("Chain name known (or blank). Saving to head file")
	// read in the entire head file and clip
	// if we have reached the max length
	b, err := ioutil.ReadFile(common.HEAD)
	if err != nil {
		return err
	}
	bspl := strings.Split(string(b), "\n")
	var bsp string
	if len(bspl) >= MaxHead {
		bsp = strings.Join(bspl[:MaxHead-1], "\n")
	} else {
		bsp = string(b)
	}

	// add the new head
	var s string
	// handle empty head
	s = name + "\n" + bsp
	err = ioutil.WriteFile(common.HEAD, []byte(s), 0666)
	if err != nil {
		return err
	}

	log.Debug("Head file saved")
	return nil
}
Пример #3
0
//------- helpers --------
func checkIPFSnotRunning() {
	//os.Setenv("ERIS_IPFS_HOST", "http://0.0.0.0") //conflicts with docker-machine
	do := def.NowDo()
	do.Known = false
	do.Existing = false
	do.Running = true
	do.Quiet = true
	log.Debug("Finding the running services")
	if err := list.ListAll(do, "services"); err != nil {
		IfExit(err)
	}
	res := strings.Split(do.Result, "\n")
	for _, r := range res {
		if r == "ipfs" {
			IfExit(fmt.Errorf("IPFS service is running.\nPlease stop it with.\neris services stop -rx ipfs\n"))
		}
	}
	// make sure ipfs container does not exist
	do = def.NowDo()
	do.Known = false
	do.Existing = true
	do.Running = false
	do.Quiet = true
	log.Debug("Finding the existing services")
	if err := list.ListAll(do, "services"); err != nil {
		IfExit(err)
	}
	res = strings.Split(do.Result, "\n")
	for _, r := range res {
		if r == "ipfs" {
			IfExit(fmt.Errorf("IPFS service exists.\nPlease remove it with\neris services rm ipfs\n"))
		}
	}
}
Пример #4
0
// ----------------------------------------------------------------------------
// ---------------------    Container Core ------------------------------------
// ----------------------------------------------------------------------------
func createContainer(opts docker.CreateContainerOptions) (*docker.Container, error) {
	dockerContainer, err := util.DockerClient.CreateContainer(opts)
	if err != nil {
		if err == docker.ErrNoSuchImage {
			if os.Getenv("ERIS_PULL_APPROVE") != "true" {
				var input string
				log.WithField("image", opts.Config.Image).Warn("The docker image not found locally")
				fmt.Print("Would you like the marmots to pull it from the repository? (y/n): ")
				fmt.Scanln(&input)

				if input == "Y" || input == "y" || input == "YES" || input == "Yes" || input == "yes" {
					log.Debug("User assented to pull")
				} else {
					log.Debug("User refused to pull")
					return nil, fmt.Errorf("Cannot start a container based on an image you will not let me pull.\n")
				}
			} else {
				log.WithField("image", opts.Config.Image).Warn("The Docker image is not found locally")
				log.Warn("The marmots are approved to pull it from the repository on your behalf")
				log.Warn("This could take a few minutes")
			}
			if err := pullImage(opts.Config.Image, nil); err != nil {
				return nil, err
			}
			dockerContainer, err = util.DockerClient.CreateContainer(opts)
			if err != nil {
				return nil, err
			}
		} else {
			return nil, err
		}
	}
	return dockerContainer, nil
}
Пример #5
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)
}
Пример #6
0
func getMachineDeets(machName string) (string, string, error) {
	var out = new(bytes.Buffer)
	var out2 = new(bytes.Buffer)

	noConnectError := fmt.Errorf("Could not evaluate the env vars for the %s docker-machine.\n", machName)
	dHost, dPath := popHostAndPath()

	if (dHost != "" && dPath != "") && (machName == "eris" || machName == "default") {
		return dHost, dPath, nil
	}

	// TODO: when go-dockerclient adds machine API endpoints use those instead.
	log.WithField("machine", machName).Debug("Querying Docker Machine URL")
	cmd := exec.Command("docker-machine", "url", machName)
	cmd.Stdout = out
	if err := cmd.Run(); err != nil {
		return "", "", fmt.Errorf("%vError:\t%v\n", noConnectError, err)
	}
	dHost = strings.TrimSpace(out.String())
	log.WithField("host", dHost).Debug()

	// TODO: when go-dockerclient adds machine API endpoints use those instead.
	log.WithField("machine", machName).Debug("Querying Docker Machine cert path")
	cmd2 := exec.Command("docker-machine", "inspect", machName, "--format", "{{.HostOptions.AuthOptions.ServerCertPath}}")
	cmd2.Stdout = out2
	//cmd2.Stderr = os.Stderr
	if err := cmd2.Run(); err != nil {
		return "", "", fmt.Errorf("%vError:\t%v\n", noConnectError, err)
	}
	dPath = out2.String()
	dPath = strings.Replace(dPath, "'", "", -1)
	dPath = filepath.Dir(dPath)
	log.WithField("cert path", dPath).Debug()

	if dPath == "" || dHost == "" {
		return "", "", noConnectError
	}

	log.Info("Querying host and user have access to the right files for TLS connection to Docker")
	if err := checkKeysAndCerts(dPath); err != nil {
		return "", "", err
	}
	log.Debug("Certificate files look good")

	// technically, do not *have* to do this, but it will make repetitive tasks faster
	log.Debug("Setting environment variables for quick future development")
	os.Setenv("DOCKER_HOST", dHost)
	os.Setenv("DOCKER_CERT_PATH", dPath)
	os.Setenv("DOCKER_TLS_VERIFY", "1")
	os.Setenv("DOCKER_MACHINE_NAME", machName)

	log.WithField("machine", machName).Debug("Finished getting machine details")
	return dHost, dPath, nil
}
Пример #7
0
func setupErisMachine(driver string) error {
	cmd := "docker-machine"
	args := []string{"status", "eris"}
	if err := exec.Command(cmd, args...).Run(); err == nil {
		// if err == nil this means the machine is created. if err != nil that means machine doesn't exist.
		log.Debug("Eris Docker Machine exists. Starting")
		return startErisMachine()
	}
	log.Debug("Eris Docker Machine doesn't exist")

	return createErisMachine(driver)
}
Пример #8
0
func readActionDefinition(actionName []string, dropped map[string]string, varNum int) (*viper.Viper, map[string]string, error) {
	if len(actionName) == 0 {
		log.WithFields(log.Fields{
			"action": actionName,
			"drop":   dropped,
			"var#":   varNum,
		}).Debug("Failed to load action definition file")
		return nil, dropped, fmt.Errorf("The marmots could not find the action definition file.\nPlease check your actions with [eris actions ls]")
	}

	log.WithField("file", strings.Join(actionName, "_")).Debug("Preparing to read action definition file")
	log.WithField("drop", dropped).Debug()

	var actionConf = viper.New()

	actionConf.AddConfigPath(dir.ActionsPath)
	actionConf.SetConfigName(strings.Join(actionName, "_"))
	err := actionConf.ReadInConfig()

	if err != nil {
		log.WithField("action", actionName[len(actionName)-1]).Debug("Dropping and retrying")
		dropped[fmt.Sprintf("$%d", varNum)] = actionName[len(actionName)-1]
		actionName = actionName[:len(actionName)-1]
		varNum++
		return readActionDefinition(actionName, dropped, varNum)
	} else {
		log.Debug("Successfully read action definition file")
	}

	return actionConf, dropped, nil
}
Пример #9
0
func NewService(do *definitions.Do) error {
	srv := definitions.BlankServiceDefinition()
	srv.Name = do.Name
	srv.Service.Name = do.Name
	srv.Service.Image = do.Operations.Args[0]
	srv.Service.AutoData = true

	var err error
	//get maintainer info
	srv.Maintainer.Name, srv.Maintainer.Email, err = config.GitConfigUser()
	if err != nil {
		log.Debug(err.Error())
	}

	log.WithFields(log.Fields{
		"service": srv.Service.Name,
		"image":   srv.Service.Image,
	}).Debug("Creating a new service definition file")
	err = WriteServiceDefinitionFile(srv, filepath.Join(ServicesPath, do.Name+".toml"))
	if err != nil {
		return err
	}
	do.Result = "success"
	return nil
}
Пример #10
0
// this function is for parsing single variables
func printField(container interface{}, field string) error {
	log.WithField("=>", field).Debug("Inspecting field")
	var line string

	// We allow fields to be passed using dot syntax, but
	// we have to make sure all fields are Camelized
	lineSplit := strings.Split(field, ".")
	for n, f := range lineSplit {
		lineSplit[n] = camelize(f)
	}
	FieldCamel := strings.Join(lineSplit, ".")

	f, _ := reflections.GetFieldKind(container, FieldCamel)
	log.Debug("Field type", f)
	switch f.String() {
	case "ptr":
		//we don't recurse into to gain a bit more control... this function will be rarely used and doesn't have to be perfectly parseable.
	case "map":
		line = fmt.Sprintf("{{ range $key, $val := .%v }}{{ $key }}->{{ $val }}\n{{ end }}\n", FieldCamel)
	case "slice":
		line = fmt.Sprintf("{{ range .%v }}{{ . }}\n{{ end }}\n", FieldCamel)
	default:
		line = fmt.Sprintf("{{.%v}}\n", FieldCamel)
	}
	return writeTemplate(container, line)
}
Пример #11
0
//TODO test that this doesn't fmt things up, see note in #400
func moveOutOfDirAndRmDir(src, dest string) error {
	log.WithFields(log.Fields{
		"from": src,
		"to":   dest,
	}).Info("Move all files/dirs out of a dir and `rm -rf` that dir")
	toMove, err := filepath.Glob(filepath.Join(src, "*"))
	if err != nil {
		return err
	}

	if len(toMove) == 0 {
		log.Debug("No files to move")
	}

	for _, f := range toMove {
		// using a copy (read+write) strategy to get around swap partitions and other
		//   problems that cause a simple rename strategy to fail. it is more io overhead
		//   to do this, but for now that is preferable to alternative solutions.
		Copy(f, filepath.Join(dest, filepath.Base(f)))
	}

	log.WithField("=>", src).Info("Removing directory")
	err = os.RemoveAll(src)
	if err != nil {
		return err
	}

	return nil
}
Пример #12
0
func ManagePinned(do *definitions.Do) error {
	ensureRunning()
	if do.Rm && do.Hash != "" {
		return fmt.Errorf("Either remove a file by hash or all of them\n")
	}

	if do.Rm {
		log.Info("Removing all cached files")
		hashes, err := rmAllPinned()
		if err != nil {
			return err
		}
		do.Result = hashes
	} else if do.Hash != "" {
		log.WithField("hash", do.Hash).Info("Removing from cache")
		hashes, err := rmPinnedByHash(do.Hash)
		if err != nil {
			return err
		}
		do.Result = hashes
	} else {
		log.Debug("Listing files pinned locally")
		hash, err := listPinned()
		if err != nil {
			return err
		}
		do.Result = hash
	}
	return nil
}
Пример #13
0
func InstallEris() {
	goArgs := []string{"install", "./cmd/eris"}

	stdOut, err := exec.Command("go", goArgs...).CombinedOutput()
	if err != nil {
		log.Fatalf("Error with go install ./cmd/eris: %v", string(stdOut))
	}

	log.Debug("Go install worked correctly")
}
Пример #14
0
func startErisMachine() error {
	log.Info("Starting Eris Docker Machine")
	cmd := "docker-machine"
	args := []string{"start", "eris"}
	if err := exec.Command(cmd, args...).Run(); err != nil {
		return fmt.Errorf("There was an error starting the newly created docker-machine.\nError:\t%v\n", err)
	}
	log.Debug("Eris Docker Machine started")

	return nil
}
Пример #15
0
func canWeMigrate() bool {
	fmt.Print("Permission to migrate deprecated directories required: would you like to continue? (Y/y): ")
	var input string
	fmt.Scanln(&input)
	if input == "Y" || input == "y" || input == "YES" || input == "Yes" || input == "yes" {
		log.Debug("Confirmation verified. Proceeding")
		return true
	} else {
		return false
	}
}
Пример #16
0
func NewChain(do *definitions.Do) error {
	//overwrites directory if --force
	dir := filepath.Join(DataContainersPath, do.Name)
	if _, err := os.Stat(dir); err == nil {
		log.WithField("dir", dir).Debug("Chain data already exists in")
		if do.Force {
			log.Debug("Overwriting with new data")
			if os.RemoveAll(dir); err != nil {
				return err
			}
		} else {
			log.Debug("Using existing data; `--force` flag not given")
		}
	}

	// for now we just let setupChain force do.ChainID = do.Name
	// and we overwrite using jq in the container
	log.WithField("=>", do.Name).Debug("Setting up chain")
	return setupChain(do, loaders.ErisChainNew)
}
Пример #17
0
func PortsService(do *definitions.Do) error {
	service, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber)
	if err != nil {
		return err
	}

	if IsServiceExisting(service.Service, service.Operations) {
		log.Debug("Service exists, getting port mapping")
		return util.PrintPortMappings(service.Operations.SrvContainerID, do.Operations.Args)
	}

	return nil
}
Пример #18
0
func createErisMachine(driver string) error {
	log.Warn("Creating the Eris Docker Machine")
	log.Warn("This will take some time, please feel free to go feed your marmot")
	log.WithField("driver", driver).Debug()
	cmd := "docker-machine"
	args := []string{"create", "--driver", driver, "eris"}
	if err := exec.Command(cmd, args...).Run(); err != nil {
		log.Debugf("There was an error creating the Eris Docker Machine: %v", err)
		return mustInstallError()
	}
	log.Debug("Eris Docker Machine created")

	return startErisMachine()
}
Пример #19
0
func connectDockerTLS(dockerHost, dockerCertPath string) error {
	var err error

	log.WithFields(log.Fields{
		"host":      dockerHost,
		"cert path": dockerCertPath,
	}).Debug("Connecting to Docker via TLS")
	DockerClient, err = docker.NewTLSClient(dockerHost, filepath.Join(dockerCertPath, "cert.pem"), filepath.Join(dockerCertPath, "key.pem"), filepath.Join(dockerCertPath, "ca.pem"))
	if err != nil {
		return err
	}

	log.Debug("Connected via TLS")
	return nil
}
Пример #20
0
func fixSteps(action *def.Action, dropReversed map[string]string) {
	log.Debug("Replacing $1, $2, $3 in steps with args from command line")

	if len(dropReversed) == 0 {
		return
	} else {
		log.WithField("replace", dropReversed).Debug()
	}

	// Because we pop from the end of the args list, the variables
	// in the map $1, $2, etc. are actually the exact opposite of
	// what they should be.
	dropped := make(map[string]string)
	j := 1
	for i := len(dropReversed); i > 0; i-- {
		log.WithField("=>", fmt.Sprintf("$%d:$%d", i, j)).Debug("Reversing")
		dropped[fmt.Sprintf("$%d", j)] = dropReversed[fmt.Sprintf("$%d", i)]
		j++
	}

	reg := regexp.MustCompile(`\$\d`)
	for n, step := range action.Steps {
		if reg.MatchString(step) {
			log.WithField("matched", step).Debug()
			for _, m := range reg.FindAllString(step, -1) {
				action.Steps[n] = strings.Replace(step, m, dropped[m], -1)
			}
			log.WithField("replaced", step).Debug()
		}
	}

	log.Debug("Checking fixed steps")
	for _, step := range action.Steps {
		log.WithField("step", step).Debug()
	}
}
Пример #21
0
func CleanUp(do *definitions.Do) error {
	log.Info("Cleaning up")
	do.Force = true

	if do.Chain.ChainType == "throwaway" {
		log.WithField("=>", do.Chain.Name).Debug("Destroying throwaway chain")
		doRm := definitions.NowDo()
		doRm.Operations = do.Operations
		doRm.Name = do.Chain.Name
		doRm.Rm = true
		doRm.RmD = true
		doRm.Volumes = true
		KillChain(doRm)

		latentDir := filepath.Join(DataContainersPath, do.Chain.Name)
		latentFile := filepath.Join(ChainsPath, do.Chain.Name+".toml")

		if doRm.Name == "default" {
			log.WithField("dir", latentDir).Debug("Removing latent dir")
			os.RemoveAll(latentDir)
		} else {
			log.WithFields(log.Fields{
				"dir":  latentDir,
				"file": latentFile,
			}).Debug("Removing latent dir and file")
			os.RemoveAll(latentDir)
			os.Remove(latentFile)
		}

	} else {
		log.Debug("No throwaway chain to destroy")
	}

	if do.RmD {
		log.WithField("dir", filepath.Join(DataContainersPath, do.Service.Name)).Debug("Removing data dir on host")
		os.RemoveAll(filepath.Join(DataContainersPath, do.Service.Name))
	}

	if do.Rm {
		log.WithField("=>", do.Operations.SrvContainerName).Debug("Removing tmp service container")
		perform.DockerRemove(do.Service, do.Operations, true, true, false)
	}

	return nil
}
Пример #22
0
func RunPackage(do *definitions.Do) error {
	log.Debug("Welcome! Say the marmots. Running app package")
	var err error
	pwd, err = os.Getwd()
	if err != nil {
		return fmt.Errorf("Could not get the present working directory. Are you on Mars?\nError: %v\n", err)
	}

	log.WithFields(log.Fields{
		"host path": do.Path,
		"pwd":       pwd,
	}).Debug()
	app, err := loaders.LoadContractPackage(do.Path, do.ChainName, do.Name, do.Type)
	if err != nil {
		do.Result = "could not load package"
		return err
	}

	if err := BootServicesAndChain(do, app); err != nil {
		do.Result = "could not boot chain or services"
		CleanUp(do, app)
		return err
	}

	do.Path = pwd
	if err := DefineAppActionService(do, app); err != nil {
		do.Result = "could not define app action service"
		CleanUp(do, app)
		return err
	}

	if err := PerformAppActionService(do, app); err != nil {
		do.Result = "could not perform app action service"
		CleanUp(do, app)
		return err
	}

	do.Result = "success"
	return CleanUp(do, app)
}
Пример #23
0
func cullCLIVariables(act []string) ([]string, []string) {
	var actionVars []string
	var action []string

	log.Debug("Pulling out named variables")
	for _, a := range act {
		if strings.Contains(a, ":") {
			r := strings.Replace(a, ":", "=", 1)
			actionVars = append(actionVars, r)
			log.WithField("=>", r).Debug("Culling from variable list")
		} else {
			action = append(action, a)
		}
	}

	log.Info("Successfully parsed named variables")
	log.WithFields(log.Fields{
		"culled":     actionVars,
		"not culled": action,
	}).Debug()
	return action, actionVars
}
Пример #24
0
func fixChain(action *def.Action, chainName string) {
	// Steps can include a $chain variable which will be populated *solely*
	// the --chain flag which has been passed via the command line
	if chainName == "" {
		return
	}

	reg := regexp.MustCompile(`\$chain`)
	for n, step := range action.Steps {
		if reg.MatchString(step) {
			log.WithField("matched", step).Debug()
			for _, m := range reg.FindAllString(step, -1) {
				action.Steps[n] = strings.Replace(step, m, chainName, -1)
			}
			log.WithField("replaced", step).Debug()
		}
	}

	log.Debug("Checking fixed chain")
	for _, step := range action.Steps {
		log.WithField("step", step).Debug()
	}
}
Пример #25
0
// marshal from viper to definitions struct
func MarshalChainDefinition(chainConf *viper.Viper, chain *definitions.Chain) error {
	log.Debug("Marshalling chain")
	chnTemp := definitions.BlankChain()
	err := chainConf.Unmarshal(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") {
			chain.Service.AutoData = true
			log.WithField("autodata", chain.Service.AutoData).Debug()
		}
	}

	return nil
}
Пример #26
0
func PutFiles(do *definitions.Do) error {
	ensureRunning()

	if do.Gateway != "" {
		_, err := url.Parse(do.Gateway)
		if err != nil {
			return fmt.Errorf("Invalid gateway URL provided %v\n", err)
		}
		log.WithField("gateway", do.Gateway).Debug("Posting to")
	} else {
		log.Debug("Posting to gateway.ipfs.io")
	}

	if do.AddDir {
		log.WithFields(log.Fields{
			"dir":     do.Name,
			"gateway": do.Gateway,
		}).Debug("Adding contents of a directory")
		hashes, err := exportDir(do.Name, do.Gateway)
		if err != nil {
			return err
		}
		do.Result = hashes
	} else {
		log.WithFields(log.Fields{
			"file":    do.Name,
			"gateway": do.Gateway,
		}).Debug("Adding a file")
		hash, err := exportFile(do.Name, do.Gateway)
		if err != nil {
			return err
		}
		do.Result = hash
	}
	return nil
}
Пример #27
0
//func askToPull removed since it's basically a duplicate of this
func checkIfCanOverwrite(doYes bool) error {
	if doYes {
		return nil
	}
	var input string
	log.WithField("path", common.ErisRoot).Warn("Eris root directory already exists")
	log.WithFields(log.Fields{
		"services path": common.ServicesPath,
		"actions path":  common.ActionsPath,
		"chains path":   common.ChainsPath,
	}).Warn("Continuing may overwrite files in:")
	fmt.Print("Do you wish to continue? (y/n): ")
	if _, err := fmt.Scanln(&input); err != nil {
		return fmt.Errorf("Error reading from stdin: %v\n", err)
	}
	if input == "Y" || input == "y" || input == "YES" || input == "Yes" || input == "yes" {
		log.Debug("Confirmation verified. Proceeding")
	} else {
		log.Warn("The marmots will not proceed without your permission to overwrite")
		log.Warn("Please backup your files and try again")
		return fmt.Errorf("Error:\tno permission given to overwrite services and actions\n")
	}
	return nil
}
Пример #28
0
func CleanUp(do *definitions.Do, app *definitions.Contracts) error {
	log.Info("Cleaning up")

	if do.Chain.ChainType == "throwaway" {
		log.WithField("=>", do.Chain.Name).Debug("Destroying throwaway chain")
		doRm := definitions.NowDo()
		doRm.Operations = do.Operations
		doRm.Name = do.Chain.Name
		doRm.Rm = true
		doRm.RmD = true
		chains.KillChain(doRm)

		latentDir := filepath.Join(common.DataContainersPath, do.Chain.Name)
		latentFile := filepath.Join(common.ChainsPath, do.Chain.Name+".toml")
		log.WithFields(log.Fields{
			"dir":  latentDir,
			"file": latentFile,
		}).Debug("Removing latent dir and file")

		os.RemoveAll(latentDir)
		os.Remove(latentFile)
	} else {
		log.Debug("No throwaway chain to destroy")
	}

	doData := definitions.NowDo()
	doData.Name = do.Service.Name
	doData.Operations = do.Operations

	doData.Source = common.ErisContainerRoot
	if do.Path != pwd {
		doData.Destination = do.Path
	} else {
		doData.Destination = 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":     doData.Source,
		"location": loca,
	}).Debug("Exporting results")
	data.ExportData(doData)

	if app.AppType.Name == "epm" {
		files, _ := filepath.Glob(filepath.Join(loca, "*"))
		for _, f := range files {
			dest := filepath.Join(do.Path, filepath.Base(f))
			log.WithFields(log.Fields{
				"from": f,
				"to":   dest,
			}).Debug("Moving file")
			common.Copy(f, dest)
		}
	}

	if !do.RmD {
		log.WithField("dir", filepath.Join(common.DataContainersPath, do.Service.Name)).Debug("Removing data dir on host")
		os.RemoveAll(filepath.Join(common.DataContainersPath, do.Service.Name))
	}

	if !do.Rm {
		doRemove := definitions.NowDo()
		doRemove.Operations.SrvContainerName = do.Operations.DataContainerName
		log.WithField("=>", doRemove.Operations.SrvContainerName).Debug("Removing data container")
		if err := perform.DockerRemove(nil, doRemove.Operations, false, true); err != nil {
			return err
		}
	}

	return nil
}
Пример #29
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
}
Пример #30
0
// XXX: What's going on here? => [csk]: magic
func RenameChain(do *definitions.Do) error {
	if do.Name == do.NewName {
		return fmt.Errorf("Cannot rename to same name")
	}

	newNameBase := strings.Replace(do.NewName, filepath.Ext(do.NewName), "", 1)
	transformOnly := newNameBase == do.Name

	if util.IsKnownChain(do.Name) {
		log.WithFields(log.Fields{
			"from": do.Name,
			"to":   do.NewName,
		}).Info("Renaming chain")

		log.WithField("=>", do.Name).Debug("Loading chain definition file")
		chainDef, err := loaders.LoadChainDefinition(do.Name, false, 1) // TODO:CNUM
		if err != nil {
			return err
		}

		if !transformOnly {
			log.Debug("Renaming chain container")
			err = perform.DockerRename(chainDef.Operations, do.NewName)
			if err != nil {
				return err
			}
		}

		oldFile := util.GetFileByNameAndType("chains", do.Name)
		if err != nil {
			return err
		}

		if filepath.Base(oldFile) == do.NewName {
			log.Info("Those are the same file. Not renaming")
			return nil
		}

		log.Debug("Renaming chain definition file")
		var newFile string
		if filepath.Ext(do.NewName) == "" {
			newFile = strings.Replace(oldFile, do.Name, do.NewName, 1)
		} else {
			newFile = filepath.Join(ChainsPath, do.NewName)
		}

		chainDef.Name = newNameBase
		// Generally we won't want to use Service.Name
		// as it will be confused with the Name.
		chainDef.Service.Name = ""
		// Service.Image should be taken from the default.toml.
		chainDef.Service.Image = ""
		err = WriteChainDefinitionFile(chainDef, newFile)
		if err != nil {
			return err
		}

		if !transformOnly {
			log.WithFields(log.Fields{
				"from": fmt.Sprintf("%s:%d", do.Name, chainDef.Operations.ContainerNumber),
				"to":   fmt.Sprintf("%s:%d", do.NewName, chainDef.Operations.ContainerNumber),
			}).Info("Renaming chain data container")
			do.Operations.ContainerNumber = chainDef.Operations.ContainerNumber
			err = data.RenameData(do)
			if err != nil {
				return err
			}
		}

		os.Remove(oldFile)
	} else {
		return fmt.Errorf("I cannot find that chain. Please check the chain name you sent me.")
	}
	return nil
}