コード例 #1
0
ファイル: load.go プロジェクト: antonylewis/eris-cli
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
}
コード例 #2
0
ファイル: chains_test.go プロジェクト: mxjxn/eris-cli
func TestRmChain(t *testing.T) {
	testStartChain(t, chainName)

	do := def.NowDo()
	do.Operations.Args, do.Rm, do.RmD = []string{"keys"}, true, true
	log.WithField("=>", do.Name).Info("Removing keys (from tests)")
	if e := services.KillService(do); e != nil {
		tests.IfExit(e)
	}

	do = def.NowDo()
	do.Name, do.Rm, do.RmD = chainName, false, false
	log.WithField("=>", do.Name).Info("Stopping chain (from tests)")
	if e := KillChain(do); e != nil {
		tests.IfExit(e)
	}
	testExistAndRun(t, chainName, true, false)

	do = def.NowDo()
	do.Name = chainName
	do.RmD = true
	log.WithField("=>", do.Name).Info("Removing chain (from tests)")
	if e := RmChain(do); e != nil {
		tests.IfExit(e)
	}

	testExistAndRun(t, chainName, false, false)
}
コード例 #3
0
ファイル: perform.go プロジェクト: mxjxn/eris-cli
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
}
コード例 #4
0
ファイル: manage.go プロジェクト: mxjxn/eris-cli
// TODO: skip errors flag
func RmData(do *definitions.Do) (err error) {
	if len(do.Operations.Args) == 0 {
		do.Operations.Args = []string{do.Name}
	}
	for _, name := range do.Operations.Args {
		do.Name = name
		if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) {
			log.WithField("=>", do.Name).Info("Removing data container")

			srv := definitions.BlankServiceDefinition()
			srv.Operations.SrvContainerName = util.ContainersName("data", do.Name, do.Operations.ContainerNumber)

			if err = perform.DockerRemove(srv.Service, srv.Operations, false, do.Volumes); err != nil {
				log.Errorf("Error removing %s: %v", do.Name, err)
				return err
			}

		} else {
			err = fmt.Errorf("I cannot find that data container for %s. Please check the data container name you sent me.", do.Name)
			log.Error(err)
			return err
		}

		if do.RmHF {
			log.WithField("=>", do.Name).Warn("Removing host directory")
			if err = os.RemoveAll(filepath.Join(DataContainersPath, do.Name)); err != nil {
				return err
			}
		}
	}

	do.Result = "success"
	return err
}
コード例 #5
0
// lists the containers running for a chain/service
// eventually remotes/actions
// existing -> true to ls existing; false to ls running
func ListRunningOrExisting(quiet, existing bool, typ string) (result string, err error) {
	re := "Running"
	if existing {
		re = "Existing"
	}
	log.WithField("status", strings.ToLower(re)).Debug("Asking Docker to list containers")
	//gotta go
	if quiet {
		if typ == "services" {
			result = strings.Join(util.ServiceContainerNames(existing), "\n")
		}
		if typ == "chains" {
			result = strings.Join(util.ChainContainerNames(existing), "\n")
		}
	} else {
		if typ == "services" {
			log.WithField("=>", fmt.Sprintf("service:%v", strings.ToLower(re))).Debug("Printing table")
			result, _ = PrintTableReport("service", existing, false) //false is for All, dealt with somewhere else
		}
		if typ == "chains" {
			log.WithField("=>", fmt.Sprintf("chain:%v", strings.ToLower(re))).Debugf("Printing table")
			result, _ = PrintTableReport("chain", existing, false)
		}
	}
	return result, nil
}
コード例 #6
0
ファイル: docker_run.go プロジェクト: antonylewis/eris-cli
// DockerStop stops a running ops.SrvContainerName container unforcedly.
// timeout is a number of seconds to wait before killing the container process
// ungracefully.
// It returns Docker errors on exit if not successful. DockerStop doesn't return
// an error if the container isn't running.
func DockerStop(srv *def.Service, ops *def.Operation, timeout uint) error {
	// don't limit this to verbose because it takes a few seconds
	// [zr] unless force sets timeout to 0 (for, eg. stdout)
	if timeout != 0 {
		log.WithField("=>", srv.Name).Warn("Stopping (may take a few seconds)")
	}

	log.WithFields(log.Fields{
		"=>":      ops.SrvContainerName,
		"timeout": timeout,
	}).Info("Stopping container")

	_, running := ContainerExists(ops)
	if running {
		log.WithField("=>", ops.SrvContainerName).Debug("Container found running")

		err := stopContainer(ops.SrvContainerName, timeout)
		if err != nil {
			return err
		}
	} else {
		log.WithField("=>", ops.SrvContainerName).Debug("Container found not running")
	}

	log.WithField("=>", ops.SrvContainerName).Info("Container stopped")

	return nil
}
コード例 #7
0
ファイル: docker_run.go プロジェクト: antonylewis/eris-cli
// ----------------------------------------------------------------------------
// ---------------------    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
}
コード例 #8
0
ファイル: clean_test.go プロジェクト: antonylewis/eris-cli
//[zr] TODO move to testings package
func testNumbersExistAndRun(t *testing.T, servName string, containerExist, containerRun int) {
	log.WithFields(log.Fields{
		"=>":        servName,
		"existing#": containerExist,
		"running#":  containerRun,
	}).Info("Checking number of containers for")

	log.WithField("=>", servName).Debug("Checking existing containers for")
	exist := util.HowManyContainersExisting(servName, "service")

	log.WithField("=>", servName).Debug("Checking running containers for")
	run := util.HowManyContainersRunning(servName, "service")

	if exist != containerExist {
		log.WithFields(log.Fields{
			"name":     servName,
			"expected": containerExist,
			"got":      exist,
		}).Error("Wrong number of existing containers")
		fatal(t, nil)
	}

	if run != containerRun {
		log.WithFields(log.Fields{
			"name":     servName,
			"expected": containerExist,
			"got":      run,
		}).Error("Wrong number of running containers")
		fatal(t, nil)
	}

	log.Info("All good")
}
コード例 #9
0
ファイル: docker_run.go プロジェクト: antonylewis/eris-cli
// DockerExecData runs a data container with volumes-from field set interactively.
//
//  ops.Args         - command line parameters
//  ops.Interactive  - if true, set Entrypoint to ops.Args,
//                     if false, set Cmd to ops.Args
//
// See parameter description for DockerRunData.
func DockerExecData(ops *def.Operation, service *def.Service) (err error) {
	log.WithFields(log.Fields{
		"=>":   ops.DataContainerName,
		"args": ops.Args,
	}).Info("Executing data container")

	opts := configureVolumesFromContainer(ops, service)
	log.WithField("image", opts.Config.Image).Info("Data container configured")

	_, err = createContainer(opts)
	if err != nil {
		return err
	}

	// Clean up the container.
	defer func() {
		log.WithField("=>", opts.Name).Info("Removing data container")
		if err2 := removeContainer(opts.Name, true, false); err2 != nil {
			if os.Getenv("CIRCLE_BRANCH") == "" {
				err = fmt.Errorf("Tragic! Error removing data container after executing (%v): %v", err, err2)
			}
		}
		log.WithField("=>", opts.Name).Info("Data container removed")
	}()

	// Start the container.
	log.WithField("=>", opts.Name).Info("Executing interactive data container")
	if err = startInteractiveContainer(opts); err != nil {
		return err
	}

	return nil
}
コード例 #10
0
ファイル: container_info.go プロジェクト: mxjxn/eris-cli
func ContainerDisassemble(containerName string) *ContainerName {
	pop := strings.Split(containerName, "_")

	if len(pop) < 4 {
		log.WithField("=>", containerName).Debug("The marmots cannot disassemble container name")
		return &ContainerName{}
	}

	if !(pop[0] == "eris" || pop[0] == "/eris") {
		log.WithField("=>", containerName).Debug("The marmots cannot disassemble container name")
		return &ContainerName{}
	}

	typ := pop[1]
	srt := strings.Join(pop[2:len(pop)-1], "_")
	num, err := strconv.Atoi(pop[len(pop)-1])
	if err != nil {
		log.WithField("=>", containerName).Debug("The marmots cannot disassemble container name")

		return &ContainerName{}
	}

	// remove the leading slash docker adds
	containerName = strings.Replace(containerName, "/", "", 1)

	return &ContainerName{
		FullName:    containerName,
		DockersName: "/" + containerName,
		Type:        typ,
		Number:      num,
		ShortName:   srt,
	}
}
コード例 #11
0
ファイル: services_test.go プロジェクト: mxjxn/eris-cli
func TestKillRmService(t *testing.T) {
	testStartService(t, servName, false)
	do := def.NowDo()
	do.Name = servName
	do.Rm = false
	do.RmD = false
	do.Operations.Args = []string{servName}
	log.WithField("=>", servName).Debug("Stopping service (from tests)")
	if e := KillService(do); e != nil {
		log.Error(e)
		tests.IfExit(e)
	}

	testExistAndRun(t, servName, 1, true, false)
	testNumbersExistAndRun(t, servName, 1, 0)

	if os.Getenv("TEST_IN_CIRCLE") == "true" {
		log.Warn("Testing in Circle where we don't have rm privileges. Skipping test")
		return
	}

	do = def.NowDo()
	do.Name = servName
	do.Operations.Args = []string{servName}
	do.File = false
	do.RmD = true
	log.WithField("=>", servName).Debug("Removing service (from tests)")
	if e := RmService(do); e != nil {
		log.Error(e)
		tests.IfExit(e)
	}

	testExistAndRun(t, servName, 1, false, false)
	testNumbersExistAndRun(t, servName, 0, 0)
}
コード例 #12
0
ファイル: update_tool.go プロジェクト: antonylewis/eris-cli
func ChangeDirectory(to string) {
	if to == "bin" {
		erisLoc, err := exec.LookPath("eris")
		if err != nil {
			log.Fatalf("Error finding eris binary: %v", err)
		}
		err = os.Chdir(filepath.Dir(erisLoc))
		if err != nil {
			log.Fatalf("Error changing directory: %v", err)
		}
		log.WithField("dir", erisLoc).Debug("Directory changed to")
	} else if to == "src" {
		goPath := os.Getenv("GOPATH")
		if goPath == "" {
			log.Fatal("You do not have $GOPATH set. Please make sure this is set and rerun the command.")
		}

		dir := filepath.Join(goPath, "src", "github.com", "eris-ltd", "eris-cli")
		err := os.Chdir(dir)

		if err != nil {
			log.Fatalf("Error changing directory: %v")
		}
		log.WithField("dir", dir).Debug("Directory changed to")
	}
}
コード例 #13
0
// AutoMagic will return the highest container number which would represent the most recent
// container to work on unless newCont == true in which case it would return the highest
// container number plus one.
func AutoMagic(cNum int, typ string, newCont bool) int {
	log.WithField("automagic", cNum).Debug()
	contns := ErisContainersByType(typ, true)

	contnums := make([]int, len(contns))
	for i, c := range contns {
		contnums[i] = c.Number
	}

	// get highest container number
	g := 0
	for _, n := range contnums {
		if n >= g {
			g = n
		}
	}

	// ensure outcomes appropriate
	result := g
	if newCont {
		result = g + 1
	}
	if result == 0 {
		result = 1
	}

	log.WithField("automagic", result).Debug()

	return result
}
コード例 #14
0
ファイル: chains_test.go プロジェクト: antonylewis/eris-cli
func TestRmChain(t *testing.T) {
	start(t, chainName)

	do := def.NowDo()
	do.Operations.Args, do.Rm, do.RmD = []string{"keys"}, true, true
	if err := services.KillService(do); err != nil {
		t.Fatalf("expected service to be stopped, got %v", err)
	}

	do = def.NowDo()
	do.Name, do.Rm, do.RmD = chainName, false, false
	log.WithField("=>", do.Name).Info("Stopping chain (from tests)")
	if err := KillChain(do); err != nil {
		t.Fatalf("expected chain to be stopped, got %v", err)
	}
	if n := util.HowManyContainersExisting(chainName, def.TypeChain); n != 1 {
		t.Fatalf("expecting 1 chain containers, got %v", n)
	}

	do = def.NowDo()
	do.Name = chainName
	do.RmD = true
	log.WithField("=>", do.Name).Info("Removing chain (from tests)")
	if err := RmChain(do); err != nil {
		t.Fatalf("expected chain to be removed, got %v", err)
	}
	if n := util.HowManyContainersExisting(chainName, def.TypeChain); n != 0 {
		t.Fatalf("expecting 0 chain containers, got %v", n)
	}
}
コード例 #15
0
ファイル: manage.go プロジェクト: mxjxn/eris-cli
func RenameAction(do *definitions.Do) error {
	if do.Name == do.NewName {
		return fmt.Errorf("Cannot rename to same name")
	}

	do.Name = strings.Replace(do.Name, " ", "_", -1)
	do.NewName = strings.Replace(do.NewName, " ", "_", -1)
	act, _, err := LoadActionDefinition(do.Name)
	if err != nil {
		log.WithFields(log.Fields{
			"from": do.Name,
			"to":   do.NewName,
		}).Debug("Failed renaming action")
		return err
	}

	do.Name = strings.Replace(do.Name, " ", "_", -1)
	log.WithField("file", do.Name).Debug("Finding action definition file")
	oldFile := util.GetFileByNameAndType("actions", do.Name)
	if oldFile == "" {
		return fmt.Errorf("Could not find that action definition file.")
	}
	log.WithField("file", oldFile).Debug("Found action definition file")

	// if !strings.Contains(oldFile, ActionsPath) {
	// 	oldFile = filepath.Join(ActionsPath, oldFile) + ".toml"
	// }

	var newFile string
	newNameBase := strings.Replace(strings.Replace(do.NewName, " ", "_", -1), filepath.Ext(do.NewName), "", 1)

	if newNameBase == do.Name {
		newFile = strings.Replace(oldFile, filepath.Ext(oldFile), filepath.Ext(do.NewName), 1)
	} else {
		newFile = strings.Replace(oldFile, do.Name, do.NewName, 1)
		newFile = strings.Replace(newFile, " ", "_", -1)
	}

	if newFile == oldFile {
		log.Info("Not renaming the same file")
		return nil
	}

	act.Name = strings.Replace(newNameBase, "_", " ", -1)

	log.WithFields(log.Fields{
		"old": act.Name,
		"new": newFile,
	}).Debug("Writing new action definition file")
	err = WriteActionDefinitionFile(act, newFile)
	if err != nil {
		return err
	}

	log.WithField("file", oldFile).Debug("Removing old file")
	os.Remove(oldFile)

	return nil
}
コード例 #16
0
ファイル: operate.go プロジェクト: antonylewis/eris-cli
// 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
}
コード例 #17
0
ファイル: update_tool.go プロジェクト: antonylewis/eris-cli
func CheckoutBranch(branch string) {
	checkoutArgs := []string{"checkout", branch}

	stdOut, err := exec.Command("git", checkoutArgs...).CombinedOutput()
	if err != nil {
		log.WithField("branch", branch).Fatalf("Error checking out branch: %v", string(stdOut))
	}

	log.WithField("branch", branch).Debug("Branch checked-out")
}
コード例 #18
0
ファイル: operate.go プロジェクト: antonylewis/eris-cli
// start a group of chains or services. catch errors on a channel so we can stop as soon as something goes wrong
func StartGroup(group []*definitions.ServiceDefinition) error {
	log.WithField("services#", len(group)).Debug("Starting services group")
	for _, srv := range group {
		log.WithField("=>", srv.Name).Debug("Performing container start")
		if err := perform.DockerRunService(srv.Service, srv.Operations); err != nil {
			return fmt.Errorf("StartGroup. Err starting srv =>\t%s:%v\n", srv.Name, err)
		}
	}
	return nil
}
コード例 #19
0
ファイル: docker_client.go プロジェクト: mxjxn/eris-cli
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
}
コード例 #20
0
ファイル: container_info.go プロジェクト: mxjxn/eris-cli
func FindChainContainer(name string, number int, running bool) *ContainerName {
	for _, srv := range ChainContainers(running) {
		if srv.ShortName == name {
			if srv.Number == number {
				log.WithField("match", fmt.Sprintf("%s:%d", srv.ShortName, srv.Number)).Debug("Found chain container")
				return srv
			}
		}
	}
	log.WithField("=>", fmt.Sprintf("%s:%d", name, number)).Info("Could not find chain container")
	return nil
}
コード例 #21
0
ファイル: container_info.go プロジェクト: mxjxn/eris-cli
func FindDataContainer(name string, number int) *ContainerName {
	for _, srv := range DataContainers() {
		if srv.ShortName == name {
			if srv.Number == number {
				log.WithField("match", fmt.Sprintf("%s:%d", srv.ShortName, srv.Number)).Debug("Found data container")
				return srv
			}
		}
	}
	log.WithField("=>", fmt.Sprintf("%s:%d", name, number)).Info("Could not find data container")
	return nil
}
コード例 #22
0
ファイル: perform.go プロジェクト: mxjxn/eris-cli
func PerformCommand(action *definitions.Action, actionVars []string, quiet bool) error {
	log.WithField("action", action.Name).Info("Performing action")

	dir, err := os.Getwd()
	if err != nil {
		return err
	}
	log.WithField("directory", dir).Debug()

	// pull actionVars (first given from command line) and
	// combine with the environment variables (given in the
	// action definition files) and finally combine with
	// the hosts os.Environ() to provide the full set of
	// variables to be consumed during the steps phase.
	for k, v := range action.Environment {
		actionVars = append(actionVars, fmt.Sprintf("%s=%s", k, v))
	}

	for _, v := range actionVars {
		log.WithField("variable", v).Debug()
	}

	actionVars = append(os.Environ(), actionVars...)

	for n, step := range action.Steps {
		cmd := exec.Command("sh", "-c", step)
		if runtime.GOOS == "windows" {
			cmd = exec.Command("cmd", "/c", step)
		}
		cmd.Env = actionVars
		cmd.Dir = dir

		log.WithField("=>", strings.Join(cmd.Args, " ")).Debugf("Performing step %d", n+1)

		prev, err := cmd.Output()
		if err != nil {
			return fmt.Errorf("error running command (%v): %s", err, prev)
		}

		if !quiet {
			log.Warn(strings.TrimSpace(string(prev)))
		}

		if n != 0 {
			actionVars = actionVars[:len(actionVars)-1]
		}
		actionVars = append(actionVars, ("prev=" + strings.TrimSpace(string(prev))))
	}

	log.Info("Action performed")
	return nil
}
コード例 #23
0
//XXX chains and services only
func ListAll(do *definitions.Do, typ string) (err error) {
	quiet := do.Quiet
	var result string
	if do.All == true { //overrides all the functionality used for flags/tests to stdout a nice table
		resK, err := ListKnown(typ)
		if err != nil {
			return err
		}
		do.Result = resK //for testing but not rly needed
		knowns := strings.Split(resK, "\n")
		typs := fmt.Sprintf("The known %s on your host kind marmot:", typ)
		log.WithField("=>", knowns[0]).Warn(typs)
		knowns = append(knowns[:0], knowns[1:]...)
		for _, known := range knowns {
			log.WithField("=>", known).Warn()
		}

		result, err = PrintTableReport(typ, true, true) //when latter bool is true, former one will be ignored...
		if err != nil {
			return err
		}
		contType := fmt.Sprintf("Active %s containers:", typ)
		log.Warn(contType)
		log.Warn(result)
	} else {

		var resK, resR, resE string

		if do.Known {
			if resK, err = ListKnown(typ); err != nil {
				return err
			}
			do.Result = resK
		}
		if do.Running {
			if resR, err = ListRunningOrExisting(quiet, false, typ); err != nil {
				return err
			}
			do.Result = resR
		}
		if do.Existing {
			if resE, err = ListRunningOrExisting(quiet, true, typ); err != nil {
				return err
			}
			do.Result = resE
		}
	}
	return nil
}
コード例 #24
0
ファイル: chains.go プロジェクト: antonylewis/eris-cli
// viper read config file, marshal to definition struct,
// load service, validate name and data container
func LoadChainDefinition(chainName string, newCont bool, cNum ...int) (*definitions.Chain, error) {
	if len(cNum) == 0 {
		cNum = append(cNum, 0)
	}

	if cNum[0] == 0 {
		cNum[0] = util.AutoMagic(0, definitions.TypeChain, newCont)
		log.WithField("=>", fmt.Sprintf("%s:%d", chainName, cNum[0])).Debug("Loading chain definition (autoassigned)")
	} else {
		log.WithField("=>", fmt.Sprintf("%s:%d", chainName, cNum[0])).Debug("Loading chain definition")
	}

	chain := definitions.BlankChain()
	chain.Name = chainName
	chain.Operations.ContainerNumber = cNum[0]
	chain.Operations.ContainerType = definitions.TypeChain
	chain.Operations.Labels = util.Labels(chain.Name, chain.Operations)
	if err := setChainDefaults(chain); err != nil {
		return nil, err
	}

	chainConf, err := config.LoadViperConfig(filepath.Join(ChainsPath), chainName, "chain")
	if err != nil {
		return nil, err
	}

	// marshal chain and always reset the operational requirements
	// this will make sure to sync with docker so that if changes
	// have occured in the interim they are caught.
	if err = MarshalChainDefinition(chainConf, chain); err != nil {
		return nil, err
	}

	// Docker 1.6 (which eris doesn't support) had different linking mechanism.
	if ver, _ := util.DockerClientVersion(); ver >= version.DVER_MIN {
		if chain.Dependencies != nil {
			addDependencyVolumesAndLinks(chain.Dependencies, chain.Service, chain.Operations)
		}
	}

	checkChainNames(chain)
	log.WithFields(log.Fields{
		"container number": chain.Operations.ContainerNumber,
		"environment":      chain.Service.Environment,
		"entrypoint":       chain.Service.EntryPoint,
		"cmd":              chain.Service.Command,
	}).Debug("Chain definition loaded")
	return chain, nil
}
コード例 #25
0
ファイル: chains_test.go プロジェクト: mxjxn/eris-cli
func TestChainGraduate(t *testing.T) {
	do := def.NowDo()
	do.Name = chainName
	log.WithField("=>", do.Name).Info("Graduate chain (from tests)")
	if err := GraduateChain(do); err != nil {
		tests.IfExit(err)
	}

	srvDef, err := loaders.LoadServiceDefinition(chainName, false, 1)
	if err != nil {
		tests.IfExit(err)
	}

	image := "quay.io/eris/erisdb:" + version.VERSION
	if srvDef.Service.Image != image {
		tests.IfExit(fmt.Errorf("FAILURE: improper service image on GRADUATE. expected: %s\tgot: %s\n", image, srvDef.Service.Image))
	}

	if srvDef.Service.Command != loaders.ErisChainStart {
		tests.IfExit(fmt.Errorf("FAILURE: improper service command on GRADUATE. expected: %s\tgot: %s\n", loaders.ErisChainStart, srvDef.Service.Command))
	}

	if !srvDef.Service.AutoData {
		tests.IfExit(fmt.Errorf("FAILURE: improper service autodata on GRADUATE. expected: %t\tgot: %t\n", true, srvDef.Service.AutoData))
	}

	if len(srvDef.Dependencies.Services) != 1 {
		tests.IfExit(fmt.Errorf("FAILURE: improper service deps on GRADUATE. expected: [\"keys\"]\tgot: %s\n", srvDef.Dependencies.Services))
	}
}
コード例 #26
0
ファイル: init.go プロジェクト: mxjxn/eris-cli
func GetTheImages() error {
	if os.Getenv("ERIS_PULL_APPROVE") == "true" {
		if err := pullDefaultImages(); err != nil {
			return err
		}
		log.Warn("Pulling of default images successful")
	} else {
		var input string
		log.Warn(`WARNING: Approximately 1 gigabyte of docker images are about to be pulled onto your host machine
Please ensure that you have sufficient bandwidth to handle the download
On a remote host in the cloud, this should only take a few minutes but can sometimes take 10 or more.
These times can double or triple on local host machines
If you already have these images, they will be updated`)

		log.WithField("ERIS_PULL_APPROVE", "true").Warn("To avoid this warning on all future pulls, set as an environment variable")

		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" {
			if err := pullDefaultImages(); err != nil {
				return err
			}
			log.Warn("Pulling of default images successful")
		}
	}
	return nil
}
コード例 #27
0
ファイル: handle.go プロジェクト: mxjxn/eris-cli
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
}
コード例 #28
0
ファイル: operate.go プロジェクト: mxjxn/eris-cli
//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
}
コード例 #29
0
ファイル: manage.go プロジェクト: antonylewis/eris-cli
func RmService(do *definitions.Do) error {
	for _, servName := range do.Operations.Args {
		service, err := loaders.LoadServiceDefinition(servName, false, do.Operations.ContainerNumber)
		if err != nil {
			return err
		}
		if IsServiceExisting(service.Service, service.Operations) {
			err = perform.DockerRemove(service.Service, service.Operations, do.RmD, do.Volumes, do.Force)
			if err != nil {
				return err
			}
		}

		if do.File {
			oldFile := util.GetFileByNameAndType("services", servName)
			if err != nil {
				return err
			}
			oldFile = filepath.Join(ServicesPath, oldFile) + ".toml"
			log.WithField("file", oldFile).Warn("Removing file")
			if err := os.Remove(oldFile); err != nil {
				return err
			}
		}
	}
	do.Result = "success"
	return nil
}
コード例 #30
0
ファイル: init.go プロジェクト: mxjxn/eris-cli
func InitDefaults(do *definitions.Do, newDir bool) error {
	var srvPath string
	var actPath string
	var chnPath string

	srvPath = common.ServicesPath
	actPath = common.ActionsPath
	chnPath = common.ChainsPath

	tsErrorFix := "toadserver may be down: re-run with `--source=rawgit`"

	if err := dropServiceDefaults(srvPath, do.Source); err != nil {
		return fmt.Errorf("%v\n%s\n", err, tsErrorFix)
	}

	if err := dropActionDefaults(actPath, do.Source); err != nil {
		return fmt.Errorf("%v\n%s\n", err, tsErrorFix)
	}

	if err := dropChainDefaults(chnPath, do.Source); err != nil {
		return fmt.Errorf("%v\n%s\n", err, tsErrorFix)
	}

	log.WithField("root", common.ErisRoot).Warn("Initialized eris root directory with default service, action, and chain files")

	return nil
}