Example #1
0
func runUploadManifestYaml(c *cli.Context, stackUid string) {
	manifestYamlFile := c.Args().First()
	if manifestYamlFile == "" {
		printFatal("manifest_yaml file path is required")
	} else {
		manifestYamlFile = expandPath(manifestYamlFile)
	}
	manifestYamlBytes, err := ioutil.ReadFile(manifestYamlFile)
	must(err)
	manifestYaml := string(manifestYamlBytes)

	comments := c.String("comments")
	if comments == "" {
		fmt.Println("\nComments can't be blank, Please add one:")
		if term.IsTerminal(os.Stdin) {
			fmt.Printf("> ")
		}

		reader := bufio.NewReader(os.Stdin)
		if comments, err = reader.ReadString('\n'); err != nil {
			printFatal(err.Error())
		}
	}

	_, err = client.CreateManifestYaml(stackUid, manifestYaml, comments)
	must(err)
}
Example #2
0
func runBackups(c *cli.Context) {
	var dbType = c.String("dbtype")

	w := tabwriter.NewWriter(os.Stdout, 1, 2, 2, ' ', 0)
	defer w.Flush()

	stack := mustStack(c)

	backups, err := client.ManagedBackups(stack.Uid)
	must(err)

	var dbTypeGroup = map[string][]cloud66.ManagedBackup{}
	if c.Bool("latest") {
		for _, i := range backups {
			if dbTypeGroup[i.DbType] == nil {
				// it's a new one
				dbTypeGroup[i.DbType] = []cloud66.ManagedBackup{i}
			} else {
				dbTypeGroup[i.DbType] = append(dbTypeGroup[i.DbType], i)
			}
		}

		// now sort each group
		topResults := []cloud66.ManagedBackup{}
		for _, v := range dbTypeGroup {
			sort.Sort(backupsByDate(v))
			topResults = append(topResults, v[0])
		}
		printBackupList(w, topResults, dbType)
	} else {
		printBackupList(w, backups, dbType)
	}
}
Example #3
0
func runContainers(c *cli.Context) {
	stack := mustStack(c)
	w := tabwriter.NewWriter(os.Stdout, 1, 2, 2, ' ', 0)
	defer w.Flush()

	flagServer := c.String("server")
	flagServiceName := c.String("service")
	flagTruncate := c.Bool("trunc")

	var serverUid *string
	if flagServer == "" {
		serverUid = nil
	} else {
		servers, err := client.Servers(stack.Uid)
		if err != nil {
			printFatal(err.Error())
		}
		server, err := findServer(servers, flagServer)
		if err != nil {
			printFatal(err.Error())
		}
		if server == nil {
			printFatal("Server '" + flagServer + "' not found")
		}
		fmt.Printf("Server: %s\n", server.Name)
		serverUid = &server.Uid
	}

	containers, err := client.GetContainers(stack.Uid, serverUid, &flagServiceName)
	must(err)

	printContainerList(w, containers, flagTruncate)
}
Example #4
0
func runContainerExec(c *cli.Context) {
	if len(c.Args()) != 2 {
		cli.ShowSubcommandHelp(c)
		os.Exit(2)
	}

	fmt.Println("Running exec on container...")

	stack := mustStack(c)
	w := tabwriter.NewWriter(os.Stdout, 1, 2, 2, ' ', 0)
	defer w.Flush()

	containerUid := c.Args()[0]
	command := c.Args()[1]
	container, err := client.GetContainer(stack.Uid, containerUid)
	must(err)

	if container == nil {
		printFatal("Container with Id '" + containerUid + "' not found")
	}

	server, err := client.GetServer(stack.Uid, container.ServerUid, 0)
	must(err)

	dockerFlags := c.String("docker-flags")
	userCommand := fmt.Sprintf("sudo docker exec %s %s %s", dockerFlags, container.Uid, command)
	err = SshToServerForCommand(*server, userCommand, true)
	if err != nil {
		printFatal(err.Error())
	}
}
Example #5
0
func runServerSettings(c *cli.Context) {
	stack := mustStack(c)

	// get the server
	serverName := c.String("server")
	if len(serverName) == 0 {
		cli.ShowSubcommandHelp(c)
		os.Exit(2)
	}

	servers, err := client.Servers(stack.Uid)
	if err != nil {
		printFatal(err.Error())
	}

	server, err := findServer(servers, serverName)
	if err != nil {
		printFatal(err.Error())
	}

	if server == nil {
		printFatal("Server '" + serverName + "' not found")
	}

	fmt.Printf("Server: %s\n", server.Name)

	getServerSettings(*stack, *server, c.Args())
}
Example #6
0
func runServerReboot(c *cli.Context) {
	stack := mustStack(c)

	if len(c.Args()) != 0 {
		cli.ShowSubcommandHelp(c)
		os.Exit(2)
	}

	serverName := c.String("server")
	servers, err := client.Servers(stack.Uid)
	if err != nil {
		printFatal(err.Error())
	}

	server, err := findServer(servers, serverName)
	if err != nil {
		printFatal(err.Error())
	}

	if server == nil {
		printFatal("Server '" + serverName + "' not found")
	}

	fmt.Printf("Server: %s\n", server.Name)

	// confirmation is needed if the stack is production
	if !c.Bool("y") {
		mustConfirm("This operation will reboot your server during which time your server will not be available. Proceed with reboot? [yes/N]", "yes")
	}
	executeServerReboot(*stack, *server)
}
Example #7
0
func runRun(c *cli.Context) {
	if runtime.GOOS == "windows" {
		printFatal("Not supported on Windows")
		os.Exit(2)
	}

	stack := mustStack(c)
	if c.String("service") != "" && stack.Framework != "docker" {
		printFatal("The service option only applies to docker stacks")
		os.Exit(2)
	}

	serverName := c.String("server")

	if !c.IsSet("service") {
		if len(c.Args()) != 1 {
			cli.ShowCommandHelp(c, "run")
			os.Exit(2)
		}
	}

	userCommand := ""
	if len(c.Args()) == 1 {
		userCommand = c.Args()[0]
	}

	servers, err := client.Servers(stack.Uid)
	if err != nil {
		printFatal(err.Error())
	}

	server, err := findServer(servers, serverName)
	if err != nil {
		printFatal(err.Error())
	}

	if server == nil {
		printFatal("Server '" + serverName + "' not found")
	}

	if c.String("service") != "" {
		// fetch service information for existing server/command
		service, err := client.GetService(stack.Uid, c.String("service"), &server.Uid, &userCommand)
		must(err)

		userCommand = service.WrapCommand
	}

	includeTty := c.String("service") != ""
	err = SshToServerForCommand(*server, userCommand, includeTty)
	if err != nil {
		printFatal(err.Error())
	}
}
Example #8
0
func runUpload(c *cli.Context) {
	if runtime.GOOS == "windows" {
		printFatal("Not supported on Windows")
		os.Exit(2)
	}

	stack := mustStack(c)

	// args start after stack name
	// and check if user specified target directory
	var targetDirectory string = ""

	if len(c.Args()) < 1 {
		cli.ShowCommandHelp(c, "upload")
		os.Exit(2)
	} else if len(c.Args()) == 2 {
		targetDirectory = c.Args()[1]
	}

	// get the server
	serverName := c.String("server")
	// get the file path
	filePath := c.Args()[0]

	servers, err := client.Servers(stack.Uid)
	if err != nil {
		printFatal(err.Error())
	}

	server, err := findServer(servers, serverName)
	if err != nil {
		printError("server not found, please ensure correct server is specified in command.")
		os.Exit(2)
	}

	if server == nil {
		printFatal("Server '" + serverName + "' not found")
	}

	fmt.Printf("Server: %s\n", server.Name)

	if targetDirectory == "" {
		err = sshToServerToUpload(*server, filePath)
	} else {
		err = sshToServerToUpload(*server, filePath, targetDirectory)
	}

	if err != nil {
		printFatal(err.Error())
	}
}
Example #9
0
func runJobs(c *cli.Context) {
	flagServer := c.String("server")
	flagServiceName := c.String("service")
	stack := mustStack(c)
	w := tabwriter.NewWriter(os.Stdout, 1, 2, 2, ' ', 0)
	defer w.Flush()

	var serverUid *string
	if flagServer == "" {
		serverUid = nil
	} else {
		servers, err := client.Servers(stack.Uid)
		if err != nil {
			printFatal(err.Error())
		}
		server, err := findServer(servers, flagServer)
		if err != nil {
			printFatal(err.Error())
		}
		if server == nil {
			printFatal("Server '" + flagServer + "' not found")
		}
		if !server.HasRole("docker") {
			printFatal("Server '" + flagServer + "' can not host containers")
		}
		fmt.Printf("Server: %s\n", server.Name)
		serverUid = &server.Uid
	}

	var (
		jobs []cloud66.Job
		err  error
	)

	if flagServiceName == "" {
		jobs, err = client.GetJobs(stack.Uid, serverUid)
		must(err)
	}
	// else {
	// 	service, err := client.GetService(stack.Uid, flagServiceName, serverUid, nil)
	// 	must(err)
	// 	if service == nil {
	// 		printFatal("Service '" + flagServiceName + "' not found on specified stack")
	// 	} else {
	// 		services = make([]cloud66.Service, 1)
	// 		services[0] = *service
	// 	}
	// }
	printJobsList(w, jobs, flagServer)
}
Example #10
0
func runLease(c *cli.Context) {
	stack := mustStack(c)

	from := c.String("from")
	tto := c.Int("tto")
	port := c.Int("port")

	fmt.Printf("Attempting to lease from %s to port %d for %d minutes...\n", from, port, tto)
	genericRes, err := client.LeaseSync(stack.Uid, &from, &tto, &port, nil)
	if err != nil {
		printFatal(err.Error())
	}
	printGenericResponse(*genericRes)
}
Example #11
0
func runUpdate(c *cli.Context) {
	debugMode = c.GlobalBool("debug")
	flagForcedVersion = c.String("force")

	if debugMode {
		fmt.Printf("Current version is %s\n", VERSION)
		if flagForcedVersion == "" {
			fmt.Println("No forced version")
		} else {
			fmt.Printf("Forced version is %s\n", flagForcedVersion)
		}
	}
	updateIt, err := needUpdate()
	if err != nil {
		if debugMode {
			fmt.Printf("Cannot verify need for update %v\n", err)
		}
		return
	}
	if !updateIt {
		if debugMode {
			fmt.Println("No need for update")
		}
		return
	}

	// houston we have an update. which one do we need?
	download, err := getVersionManifest(flagForcedVersion)
	if err != nil {
		if debugMode {
			fmt.Printf("Error fetching manifest %v\n", err)
		}
	}
	if download == nil {
		if debugMode {
			fmt.Println("Found no matching download for the current OS and ARCH")
		}
		return
	}

	err = download.update()
	if err != nil {
		if debugMode {
			fmt.Printf("Failed to update: %v\n", err)
		}
		return
	}
}
Example #12
0
func runDownloadManifestYaml(c *cli.Context, stackUid string) {
	version := c.String("version")
	if version == "" {
		version = "latest"
	}

	manifestYaml, err := client.ManifestYamlInfo(stackUid, version)
	must(err)

	output := c.String("output")
	if output != "" {
		err := writeFile(output, manifestYaml.Body)
		must(err)
	} else {
		fmt.Println(manifestYaml.Body)
	}
}
Example #13
0
func runStacks(c *cli.Context) {
	w := tabwriter.NewWriter(os.Stdout, 1, 2, 2, ' ', 0)
	defer w.Flush()
	var stacks []cloud66.Stack
	names := c.Args()
	flagForcedEnvironment := c.String("environment")
	if len(names) == 0 {
		var err error
		stacks, err = client.StackListWithFilter(func(item interface{}) bool {
			if flagForcedEnvironment == "" {
				return true
			}

			return strings.HasPrefix(strings.ToLower(item.(cloud66.Stack).Environment), strings.ToLower(flagForcedEnvironment))
		})
		must(err)
	} else {
		stackch := make(chan *cloud66.Stack, len(names))
		errch := make(chan error, len(names))
		for _, name := range names {
			if name == "" {
				stackch <- nil
			} else {
				go func(stackname string) {
					if stack, err := client.StackInfoWithEnvironment(stackname, flagForcedEnvironment); err != nil {
						errch <- err
					} else {
						stackch <- stack
					}
				}(name)
			}
		}
		for _ = range names {
			select {
			case err := <-errch:
				printFatal(err.Error())
			case stack := <-stackch:
				if stack != nil {
					stacks = append(stacks, *stack)
				}
			}
		}
	}
	printStackList(w, stacks)
}
Example #14
0
func runServiceStop(c *cli.Context) {
	if len(c.Args()) != 1 {
		cli.ShowSubcommandHelp(c)
		os.Exit(2)
	}

	stack := mustStack(c)
	serviceName := c.Args()[0]

	flagServer := c.String("server")

	var serverUid *string
	if flagServer == "" {
		serverUid = nil
	} else {
		servers, err := client.Servers(stack.Uid)
		if err != nil {
			printFatal(err.Error())
		}
		server, err := findServer(servers, flagServer)
		if err != nil {
			printFatal(err.Error())
		}
		if server == nil {
			printFatal("Server '" + flagServer + "' not found")
		}
		if !server.HasRole("docker") {
			printFatal("Server '" + flagServer + "' can not host containers")
		}
		fmt.Printf("Server: %s\n", server.Name)
		serverUid = &server.Uid
	}

	asyncId, err := startServiceStop(stack.Uid, serviceName, serverUid)
	if err != nil {
		printFatal(err.Error())
	}
	genericRes, err := endServiceStop(*asyncId, stack.Uid)
	if err != nil {
		printFatal(err.Error())
	}
	printGenericResponse(*genericRes)
	return
}
Example #15
0
func runServerSet(c *cli.Context) {
	fmt.Println(c.Args())
	stack := mustStack(c)

	if len(c.Args()) != 1 {
		cli.ShowSubcommandHelp(c)
		os.Exit(2)
	}

	// get the server
	args := c.Args()

	serverName := c.String("server")

	// filter out the server name
	kvs := args[0]
	kva := strings.Split(kvs, "=")
	if len(kva) != 2 {
		cli.ShowSubcommandHelp(c)
		os.Exit(2)
	}
	key := kva[0]
	value := kva[1]

	servers, err := client.Servers(stack.Uid)
	if err != nil {
		printFatal(err.Error())
	}

	server, err := findServer(servers, serverName)
	if err != nil {
		printFatal(err.Error())
	}

	if server == nil {
		printFatal("Server '" + serverName + "' not found")
	}

	fmt.Printf("Server: %s\n", server.Name)

	executeServerSet(*stack, *server, c, key, value)
}
Example #16
0
func runServiceInfo(c *cli.Context) {
	if len(c.Args()) != 1 {
		cli.ShowSubcommandHelp(c)
		os.Exit(2)
	}

	w := tabwriter.NewWriter(os.Stdout, 1, 2, 2, ' ', 0)
	defer w.Flush()

	stack := mustStack(c)
	serviceName := c.Args()[0]

	flagServer := c.String("server")

	var serverUid *string
	if flagServer == "" {
		serverUid = nil
	} else {
		servers, err := client.Servers(stack.Uid)
		if err != nil {
			printFatal(err.Error())
		}
		server, err := findServer(servers, flagServer)
		if err != nil {
			printFatal(err.Error())
		}
		if server == nil {
			printFatal("Server '" + flagServer + "' not found")
		}
		if !server.HasRole("docker") {
			printFatal("Server '" + flagServer + "' is not a docker server")
		}
		fmt.Printf("Server: %s\n", server.Name)
		serverUid = &server.Uid
	}

	service, err := client.GetService(stack.Uid, serviceName, serverUid, nil)
	must(err)

	printServiceInfoList(w, service)
	return
}
Example #17
0
func runSlaveResync(c *cli.Context) {
	stack := mustStack(c)

	if len(c.Args()) < 1 {
		cli.ShowSubcommandHelp(c)
		os.Exit(2)
	}

	// get the server
	serverName := c.Args()[0]
	flagDbType := c.String("dbtype")

	servers, err := client.Servers(stack.Uid)
	if err != nil {
		printFatal(err.Error())
	}

	server, err := findServer(servers, serverName)
	if err != nil {
		printFatal(err.Error())
	}

	if server == nil {
		printFatal("Server '" + serverName + "' not found")
	}

	fmt.Printf("Server: %s\n", server.Name)
	currenttime := time.Now().Local()
	fmt.Printf("Started: %s\n", currenttime.Format("2006-01-02 15:04:05"))

	asyncId, err := startSlaveResync(stack.Uid, server.Uid, &flagDbType)
	if err != nil {
		printFatal(err.Error())
	}
	genericRes, err := endSlaveResync(*asyncId, stack.Uid)
	if err != nil {
		printFatal(err.Error())
	}
	printGenericResponse(*genericRes)
}
Example #18
0
func runRedeploy(c *cli.Context) {
	stack := mustStack(c)

	// confirmation is needed if the stack is production
	if stack.Environment == "production" && !c.Bool("y") {
		mustConfirm("This is a production stack. Proceed with deployment? [yes/N]", "yes")
	}

	if len(c.StringSlice("service")) > 0 {
		fmt.Printf("Deploying service(s): ")
		for i, service := range c.StringSlice("service") {
			if i > 0 {
				fmt.Printf(", ")
			}
			fmt.Printf(service)
		}
		fmt.Printf("\n")
	}

	result, err := client.RedeployStack(stack.Uid, c.String("git-ref"), c.StringSlice("service"))
	must(err)

	if !c.Bool("listen") || result.Queued {
		// its queued - just message and exit
		fmt.Println(result.Message)
	} else {
		// tail the logs
		go StartListen(stack)

		stack, err = WaitStackBuild(stack.Uid, false)
		must(err)

		if stack.HealthCode == 2 || stack.HealthCode == 4 || stack.StatusCode == 2 || stack.StatusCode == 7 {
			fmt.Println("Completed with some errors!")
		} else {
			fmt.Println("Completed successfully!")
		}
	}
}
Example #19
0
func runNewBackup(c *cli.Context) {
	stack := mustStack(c)

	var flagDbTypes *string

	if c.IsSet("dbtypes") {
		flagDbTypes = new(string)
		*flagDbTypes = c.String("dbtypes")
	}

	var flagFrequency *string

	if c.IsSet("frequency") {
		flagFrequency = new(string)
		*flagFrequency = c.String("frequency")
	}

	var flagKeep *int

	if c.IsSet("keep") {
		flagKeep = new(int)
		*flagKeep = c.Int("keep")
	}

	var flagGzip *bool

	if c.IsSet("gzip") {
		flagGzip = new(bool)
		*flagGzip = c.Bool("gzip")
	}

	var flagExcludetables *string

	if c.IsSet("exclude-tables") {
		flagExcludetables = new(string)
		*flagExcludetables = c.String("exclude-tables")
	}

	var flagRunonreplica *bool

	if c.IsSet("run-on-replica") {
		flagRunonreplica = new(bool)
		*flagRunonreplica = c.Bool("run-on-replica")
	}

	err := client.NewBackup(stack.Uid, flagDbTypes, flagFrequency, flagKeep, flagGzip, flagExcludetables, flagRunonreplica)

	if err != nil {
		printFatal("Error during backup creation: " + err.Error())
		return
	}

	fmt.Println("queued for creation")
}
Example #20
0
func mustFile(c *cli.Context) ConfigureFile {
	var file ConfigureFile
	switch c.String("file") {
	case "service.yml":
		file = ConfigureFile{
			Name:         c.String("file"),
			ListFunc:     runServiceYamlList,
			DownloadFunc: runDownloadServiceYaml,
			UploadFunc:   runUploadServiceYaml}
	case "manifest.yml":
		file = ConfigureFile{
			Name:         c.String("file"),
			ListFunc:     runManifestYamlList,
			DownloadFunc: runDownloadManifestYaml,
			UploadFunc:   runUploadManifestYaml}
	default:
		printFatal("No file type specified or file type is not supported. Use --file flag to choose file type. supported values are: service.yml , manifest.yml")
	}

	return file
}
Example #21
0
func runServiceScale(c *cli.Context) {
	if len(c.Args()) != 2 {
		cli.ShowSubcommandHelp(c)
		os.Exit(2)
	}

	stack := mustStack(c)
	serviceName := c.Args()[0]
	count := c.Args()[1]

	flagServer := c.String("server")
	flagGroup := c.String("group")

	// fetch servers info
	servers, err := client.Servers(stack.Uid)
	must(err)

	if flagServer != "" {
		server, err := findServer(servers, flagServer)
		must(err)
		if server == nil {
			printFatal("Server '" + flagServer + "' not found")
		}
		if !server.HasRole("docker") {
			printFatal("Server '" + flagServer + "' can not host containers")
		}
		fmt.Printf("Server: %s\n", server.Name)
		// filter servers collection down
		servers = make([]cloud66.Server, 1)
		servers[0] = *server
	}

	if flagGroup != "" {
		if flagGroup != "web" {
			printFatal("Only web group is supported at the moment")
		}
	}

	// param for api call
	serverCountDesired := make(map[string]int)

	var absoluteCount int
	if strings.ContainsAny(count, "+ & -") {

		// fetch service information for existing counts
		service, err := client.GetService(stack.Uid, serviceName, nil, nil)
		must(err)

		serverCountCurrent := service.ServerContainerCountMap()
		relativeCount, _ := strconv.Atoi(count)

		for _, server := range servers {
			if _, present := serverCountCurrent[server.Name]; present {
				serverCountDesired[server.Uid] = relativeCount + serverCountCurrent[server.Name]
			} else {
				serverCountDesired[server.Uid] = relativeCount
			}
		}

	} else {
		absoluteCount, _ = strconv.Atoi(count)
		for _, server := range servers {
			serverCountDesired[server.Uid] = absoluteCount
		}
	}

	// validate non < 0
	for serverUid, count := range serverCountDesired {
		if count < 0 {
			serverCountDesired[serverUid] = 0
		}
	}

	fmt.Println("Scaling your '" + serviceName + "' service")

	var asyncId *int
	if flagGroup != "" {
		var groupMap = make(map[string]int)
		groupMap["web"] = absoluteCount
		asyncId, err = startServiceScaleByGroup(stack.Uid, serviceName, groupMap)
	} else {
		asyncId, err = startServiceScale(stack.Uid, serviceName, serverCountDesired)
	}

	must(err)
	genericRes, err := endServiceScale(*asyncId, stack.Uid)
	must(err)
	printGenericResponse(*genericRes)
	return
}
Example #22
0
func runCreateStack(c *cli.Context) {
	name := c.String("name")
	environment := c.String("environment")
	serviceYamlFile := c.String("service_yaml")
	manifestYamlFile := c.String("manifest_yaml")
	manifestYaml := ""

	if len(name) < 5 {
		printFatal("name is required and must be at least 5 characters long")
	}
	if environment == "" {
		printFatal("environment is required")
	}

	// handle service yaml file
	if serviceYamlFile == "" {
		printFatal("service_yaml file path is required")
	} else {
		serviceYamlFile = expandPath(serviceYamlFile)
	}
	serviceYamlBytes, err := ioutil.ReadFile(serviceYamlFile)
	must(err)
	serviceYaml := string(serviceYamlBytes)

	accountInfo, err := currentAccountInfo()
	must(err)

	fmt.Printf("Using account: %s\n", accountInfo.Owner)

	targetOptions := make(map[string]string)
	if manifestYamlFile != "" {

		fmt.Println("Using supplied manifest file")
		manifestYamlFile = expandPath(manifestYamlFile)
		manifestYamlBytes, err := ioutil.ReadFile(manifestYamlFile)
		must(err)
		manifestYaml = string(manifestYamlBytes)
	} else {

		fmt.Println("Note: No manifest provided; for additional options you can provide your own manifest with this command")
		targetCloud, err := askForCloud(*accountInfo)
		must(err)
		targetOptions["cloud"] = targetCloud.Id
		targetOptions["key_name"] = targetCloud.KeyName

		targetRegion, targetSize, err := askForSizeAndRegion(*targetCloud)
		must(err)
		targetOptions["region"] = targetRegion
		targetOptions["size"] = targetSize

		targetBuildType, err := askForBuildType()
		must(err)
		targetOptions["build_type"] = targetBuildType
	}

	asyncId, err := startCreateStack(name, environment, serviceYaml, manifestYaml, targetOptions)
	must(err)

	// now we fetch the corresponding stack
	stack, err := client.StackInfoWithEnvironment(name, environment)
	must(err)

	// wait for the stack analysis to complete
	_, err = endCreateStack(*asyncId, stack.Uid)
	must(err)
	fmt.Printf("\nStack created; Build starting...\n\n")

	err = initiateStackBuild(stack.Uid)
	must(err)

	// logging output
	go StartListen(stack)

	stack, err = WaitStackBuild(stack.Uid, false)
	must(err)
	fmt.Println("Stack build completed successfully!")
}
Example #23
0
func stack(c *cli.Context) (*cloud66.Stack, error) {
	if flagStack != nil {
		return flagStack, nil
	}

	if c.String("environment") != "" {
		flagEnvironment = c.String("environment")
	}

	var err error
	if c.String("stack") != "" {
		stacks, err := client.StackListWithFilter(filterByEnvironmentExact)
		if err != nil {
			return nil, err
		}
		var stackNames []string
		for _, stack := range stacks {
			stackNames = append(stackNames, stack.Name)
		}
		idx, err := fuzzyFind(stackNames, c.String("stack"), false)
		if err != nil {
			// try fuzzy env match
			stacks, err = client.StackListWithFilter(filterByEnvironmentFuzzy)
			if err != nil {
				return nil, err
			}
			var stackFuzzNames []string
			for _, stack := range stacks {
				stackFuzzNames = append(stackFuzzNames, stack.Name)
			}
			idx, err = fuzzyFind(stackFuzzNames, c.String("stack"), false)
			if err != nil {
				return nil, err
			}
		}

		flagStack = &stacks[idx]

		// toSdout is of type []bool. Take first value
		if c.String("environment") != "" {
			fmt.Printf("(%s)\n", flagStack.Environment)
		}

		return flagStack, err
	}

	if stack := c.String("cxstack"); stack != "" {
		// the environment variable should be exact match
		flagStack, err = client.StackInfo(stack)
		return flagStack, err
	}

	return stackFromGitRemote(remoteGitUrl(), localGitBranch())
}
Example #24
0
func runDownloadBackup(c *cli.Context) {
	if len(c.Args()) == 0 {
		//cmd.printUsage()
		os.Exit(2)
	}

	stack := mustStack(c)
	backupId, err := strconv.Atoi(c.Args()[0])
	if err != nil {
		//cmd.printUsage()
		os.Exit(2)
	}

	segmentIndeces, err := client.GetBackupSegmentIndeces(stack.Uid, backupId)
	must(err)
	if len(segmentIndeces) < 1 {
		printFatal("Cannot find file segments associated with this backup")
	}

	flagDownloadDir := c.String("directory")

	mainDir := filepath.Join(homePath(), "cx_backups")
	if flagDownloadDir != "" {
		mainDir = flagDownloadDir
	}

	// create a download tmp folder
	dir := filepath.Join(mainDir, "tmp", c.Args()[0])
	err = os.MkdirAll(dir, 0777)
	must(err)

	var files = []string{}
	for _, segmentIndex := range segmentIndeces {

		segment, err := client.GetBackupSegment(stack.Uid, backupId, segmentIndex.Extension)
		must(err)

		fmt.Printf("Downloading %s to %s\n", segmentIndex.Filename, dir)
		// this should be moved to go routines
		toFile := filepath.Join(dir, segmentIndex.Filename)
		err = downloadFile(segment.Url, toFile)
		must(err)

		files = append(files, toFile)
	}

	toFile := filepath.Join(mainDir, "backup_"+c.Args()[0]+".tar")
	fmt.Printf("Concatenating files to %s\n", toFile)
	err = appendFiles(files, toFile)
	if err != nil {
		printFatal("Error during concatenation: " + err.Error())
		return
	}

	// remove the temp
	if !debugMode {
		os.RemoveAll(dir)
		fmt.Printf("Deleting %s\n", dir)
	}
	fmt.Println("Done")
}