func (factory *AppRunnerCommandFactory) submitLrp(context *cli.Context) {
	filePath := context.Args().First()
	if filePath == "" {
		factory.UI.SayLine("Path to JSON is required")
		factory.ExitHandler.Exit(exit_codes.InvalidSyntax)
		return
	}

	jsonBytes, err := ioutil.ReadFile(filePath)
	if err != nil {
		factory.UI.SayLine(fmt.Sprintf("Error reading file: %s", err.Error()))
		factory.ExitHandler.Exit(exit_codes.FileSystemError)
		return
	}

	lrpName, err := factory.AppRunner.SubmitLrp(jsonBytes)
	if err != nil {
		factory.UI.SayLine(fmt.Sprintf("Error creating %s: %s", lrpName, err.Error()))
		factory.ExitHandler.Exit(exit_codes.CommandFailed)
		return
	}

	factory.UI.SayLine(colors.Green(fmt.Sprintf("Successfully submitted %s.", lrpName)))
	factory.UI.SayLine(fmt.Sprintf("To view the status of your application: ltc status %s", lrpName))
}
func (factory *AppExaminerCommandFactory) printDistribution() int {
	defer factory.ui.Say(cursor.ClearToEndOfDisplay())

	cells, err := factory.appExaminer.ListCells()
	if err != nil {
		factory.ui.Say("Error visualizing: " + err.Error())
		factory.ui.Say(cursor.ClearToEndOfLine())
		factory.ui.SayNewLine()
		return 1
	}

	for _, cell := range cells {
		factory.ui.Say(cell.CellID)
		if cell.Missing {
			factory.ui.Say(colors.Red("[MISSING]"))
		}
		factory.ui.Say(": ")

		if cell.RunningInstances == 0 && cell.ClaimedInstances == 0 && !cell.Missing {
			factory.ui.Say(colors.Red("empty"))
		} else {
			factory.ui.Say(colors.Green(strings.Repeat("•", cell.RunningInstances)))
			factory.ui.Say(colors.Yellow(strings.Repeat("•", cell.ClaimedInstances)))
		}
		factory.ui.Say(cursor.ClearToEndOfLine())
		factory.ui.SayNewLine()
	}

	return len(cells)
}
func colorInstances(appInfo app_examiner.AppInfo) string {
	instances := fmt.Sprintf("%d/%d", appInfo.ActualRunningInstances, appInfo.DesiredInstances)
	if appInfo.ActualRunningInstances == appInfo.DesiredInstances {
		return colors.Green(instances)
	} else if appInfo.ActualRunningInstances == 0 {
		return colors.Red(instances)
	}

	return colors.Yellow(instances)
}
func (factory *AppRunnerCommandFactory) WaitForAppCreation(appName string, pollTimeout time.Duration, instanceCount int) {
	factory.UI.SayLine("Creating App: " + appName)

	go factory.TailedLogsOutputter.OutputTailedLogs(appName)
	defer factory.TailedLogsOutputter.StopOutputting()

	appStarted := factory.pollUntilAllInstancesRunning(pollTimeout, appName, instanceCount, "start")
	if appStarted {
		factory.UI.SayLine(colors.Green(appName + " is now running."))
	}

	appStatus, err := factory.AppExaminer.AppStatus(appName)
	if err != nil {
		factory.UI.SayLine(fmt.Sprintf("Error querying status of %s: %s", appName, err.Error()))
		factory.ExitHandler.Exit(exit_codes.CommandFailed)
		return
	}

	if len(appStatus.Routes.TcpRoutes) > 0 || len(appStatus.Routes.AppRoutes) > 0 {
		if appStarted {
			factory.UI.SayLine("App is reachable at:")
		} else {
			factory.UI.SayLine("App will be reachable at:")
		}

		if appStatus.Routes.TcpRoutes != nil {
			for _, tcpRoute := range appStatus.Routes.TcpRoutes {
				factory.UI.SayLine(colors.Green(factory.externalPortMappingForApp(tcpRoute.ExternalPort, tcpRoute.Port)))
			}
		}

		if appStatus.Routes.AppRoutes != nil {
			for _, route := range appStatus.Routes.AppRoutes {
				for _, hostname := range route.Hostnames {
					factory.UI.SayLine(colors.Green(fmt.Sprintf("http://%s", hostname)))
				}
			}
		}
	}
}
func (factory *AppRunnerCommandFactory) setAppInstances(pollTimeout time.Duration, appName string, instances int) {
	if err := factory.AppRunner.ScaleApp(appName, instances); err != nil {
		factory.UI.SayLine(fmt.Sprintf("Error Scaling App to %d instances: %s", instances, err))
		factory.ExitHandler.Exit(exit_codes.CommandFailed)
		return
	}

	factory.UI.SayLine(fmt.Sprintf("Scaling %s to %d instances", appName, instances))

	if ok := factory.pollUntilAllInstancesRunning(pollTimeout, appName, instances, "scale"); ok {
		factory.UI.SayLine(colors.Green("App Scaled Successfully"))
	}
}
func (factory *TaskRunnerCommandFactory) deleteTask(context *cli.Context) {
	taskGuid := context.Args().First()
	if taskGuid == "" {
		factory.ui.SayIncorrectUsage("Please input a valid TASK_GUID")
		factory.exitHandler.Exit(exit_codes.InvalidSyntax)
		return
	}

	if err := factory.taskRunner.DeleteTask(taskGuid); err != nil {
		factory.ui.SayLine(fmt.Sprintf(colors.Red("Error deleting %s: %s"), taskGuid, err.Error()))
		factory.exitHandler.Exit(exit_codes.CommandFailed)
		return
	}
	factory.ui.SayLine(colors.Green("OK"))
}
func (factory *TaskRunnerCommandFactory) submitTask(context *cli.Context) {
	filePath := context.Args().First()
	if filePath == "" {
		factory.ui.SayLine("Path to JSON is required")
		factory.exitHandler.Exit(exit_codes.InvalidSyntax)
		return
	}

	jsonBytes, err := ioutil.ReadFile(filePath)
	if err != nil {
		factory.ui.SayLine("Error reading file: " + err.Error())
		factory.exitHandler.Exit(exit_codes.FileSystemError)
		return
	}

	taskName, err := factory.taskRunner.SubmitTask(jsonBytes)
	if err != nil {
		factory.ui.SayLine(fmt.Sprintf("Error submitting %s: %s", taskName, err))
		factory.exitHandler.Exit(exit_codes.CommandFailed)
		return
	}
	factory.ui.SayLine(colors.Green("Successfully submitted " + taskName))
}
func (factory *TaskExaminerCommandFactory) task(context *cli.Context) {
	taskName := context.Args().First()
	if taskName == "" {
		factory.ui.SayIncorrectUsage("Please input a valid TASK_GUID")
		factory.exitHandler.Exit(exit_codes.InvalidSyntax)
		return
	}

	taskInfo, err := factory.taskExaminer.TaskStatus(taskName)
	if err != nil {
		if err.Error() == task_examiner.TaskNotFoundErrorMessage {
			factory.ui.SayLine(colors.Red(fmt.Sprintf("No task '%s' was found", taskName)))
			factory.exitHandler.Exit(exit_codes.CommandFailed)
			return
		}
		factory.ui.SayLine(colors.Red("Error fetching task result: " + err.Error()))
		factory.exitHandler.Exit(exit_codes.CommandFailed)
		return
	}

	w := tabwriter.NewWriter(factory.ui, 9, 8, 1, '\t', 0)

	fmt.Fprintf(w, "%s\t%s\n", "Task GUID", taskInfo.TaskGuid)
	fmt.Fprintf(w, "%s\t%s\n", "Cell ID", taskInfo.CellID)
	if taskInfo.State == "PENDING" || taskInfo.State == "CLAIMED" || taskInfo.State == "RUNNING" {
		fmt.Fprintf(w, "%s\t%s\n", "Status", colors.Yellow(taskInfo.State))
	} else if (taskInfo.State == "COMPLETED" || taskInfo.State == "RESOLVING") && !taskInfo.Failed {
		fmt.Fprintf(w, "%s\t%s\n", "Status", colors.Green(taskInfo.State))
		fmt.Fprintf(w, "%s\t%s\n", "Result", taskInfo.Result)
	} else if taskInfo.Failed {
		fmt.Fprintf(w, "%s\t%s\n", "Status", colors.Red(taskInfo.State))
		fmt.Fprintf(w, "%s\t%s\n", "Failure Reason", taskInfo.FailureReason)
	}

	w.Flush()
}
			BeforeEach(func() {
				var err error
				tmpFile, err = ioutil.TempFile("", "tmp_json")
				Expect(err).ToNot(HaveOccurred())

				jsonContents = []byte(`{"Value":"test value"}`)
				Expect(ioutil.WriteFile(tmpFile.Name(), jsonContents, 0700)).To(Succeed())
			})

			It("submits a task from json", func() {
				fakeTaskRunner.SubmitTaskReturns("some-task", nil)

				args := []string{tmpFile.Name()}
				test_helpers.ExecuteCommandWithArgs(submitTaskCommand, args)

				Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("Successfully submitted some-task")))
				Expect(fakeTaskRunner.SubmitTaskCallCount()).To(Equal(1))
				Expect(fakeTaskRunner.SubmitTaskArgsForCall(0)).To(Equal(jsonContents))
			})

			It("prints an error returned by the task_runner", func() {
				fakeTaskRunner.SubmitTaskReturns("some-task", errors.New("taskypoo"))

				args := []string{tmpFile.Name()}
				test_helpers.ExecuteCommandWithArgs(submitTaskCommand, args)

				Expect(fakeTaskRunner.SubmitTaskCallCount()).To(Equal(1))
				Expect(fakeTaskRunner.SubmitTaskArgsForCall(0)).To(Equal(jsonContents))

				Expect(outputBuffer).To(test_helpers.SayLine("Error submitting some-task: taskypoo"))
				Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.CommandFailed}))
			Expect(createAppParams.User).To(Equal("some-user"))
			Expect(createAppParams.CPUWeight).To(Equal(uint(57)))
			Expect(createAppParams.MemoryMB).To(Equal(12))
			Expect(createAppParams.DiskMB).To(Equal(12))
			Expect(createAppParams.Monitor.Method).To(Equal(app_runner.PortMonitor))
			Expect(createAppParams.Timeout).To(Equal(time.Second * 28))
			Expect(createAppParams.RouteOverrides).To(ContainExactly(app_runner.RouteOverrides{
				{HostnamePrefix: "route-3000-yay", Port: 3000},
				{HostnamePrefix: "route-1111-wahoo", Port: 1111},
				{HostnamePrefix: "route-1111-me-too", Port: 1111},
			}))
			Expect(createAppParams.NoRoutes).To(BeFalse())
			Expect(createAppParams.WorkingDir).To(Equal("/applications"))

			Expect(outputBuffer).To(test_helpers.SayLine("Creating App: cool-web-app"))
			Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("cool-web-app is now running.")))
			Expect(outputBuffer).To(test_helpers.SayLine("App is reachable at:"))
			Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("http://route-3000-yay.192.168.11.11.xip.io")))
			Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("http://route-1111-wahoo.192.168.11.11.xip.io")))
			Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("http://route-1111-me-too.192.168.11.11.xip.io")))
		})

		Context("when the PROCESS_GUID is passed in as --env", func() {
			It("sets the PROCESS_GUID to the value passed in", func() {
				fakeDockerMetadataFetcher.FetchMetadataReturns(&docker_metadata_fetcher.ImageMetadata{StartCommand: []string{""}}, nil)
				fakeAppExaminer.RunningAppInstancesInfoReturns(1, false, nil)

				args := []string{
					"app-to-start",
					"fun-org/app",
					"--env=PROCESS_GUID=MyHappyGuid",
				State:         "COMPLETED",
				CellID:        "cell-01",
				Failed:        false,
				FailureReason: "",
				Result:        "some-result",
			}
			fakeTaskExaminer.TaskStatusReturns(taskInfo, nil)

			test_helpers.ExecuteCommandWithArgs(taskCommand, []string{"boop"})

			Expect(outputBuffer).To(test_helpers.Say("Task GUID"))
			Expect(outputBuffer).To(test_helpers.Say("boop"))
			Expect(outputBuffer).To(test_helpers.Say("Cell ID"))
			Expect(outputBuffer).To(test_helpers.Say("cell-01"))
			Expect(outputBuffer).To(test_helpers.Say("Status"))
			Expect(outputBuffer).To(test_helpers.Say(colors.Green("COMPLETED")))
			Expect(outputBuffer).To(test_helpers.Say("Result"))
			Expect(outputBuffer).To(test_helpers.Say("some-result"))
			Expect(outputBuffer).NotTo(test_helpers.Say("Failure Reason"))

			Expect(fakeTaskExaminer.TaskStatusCallCount()).To(Equal(1))
			Expect(fakeTaskExaminer.TaskStatusArgsForCall(0)).To(Equal("boop"))
		})

		It("displays failure reason for a failed task result", func() {
			taskInfo := task_examiner.TaskInfo{
				TaskGuid:      "boop",
				State:         "COMPLETED",
				CellID:        "cell-01",
				Failed:        true,
				FailureReason: "womp womp",
예제 #12
0
				Expect(colorizer("\t")).To(Equal("\t"))
				Expect(colorizer("\r")).To(Equal("\r"))
			})
		}

		Describe("Red", func() {
			It("adds the red color code", func() {
				Expect(colors.Red("ERROR NOT GOOD")).To(Equal("\x1b[91mERROR NOT GOOD\x1b[0m"))
			})

			itShouldNotColorizeWhitespace(colors.Red)
		})

		Describe("Green", func() {
			It("adds the green color code", func() {
				Expect(colors.Green("TOO GOOD")).To(Equal("\x1b[32mTOO GOOD\x1b[0m"))
			})

			itShouldNotColorizeWhitespace(colors.Green)
		})

		Describe("Cyan", func() {
			It("adds the cyan color code", func() {
				Expect(colors.Cyan("INFO")).To(Equal("\x1b[36mINFO\x1b[0m"))
			})

			itShouldNotColorizeWhitespace(colors.Cyan)
		})

		Describe("Yellow", func() {
			It("adds the yellow color code", func() {
			args := []string{
				"--ports=4444",
				"--http-route=ninetyninety",
				"--http-route=fourtyfourfourtyfour:9090",
				"--tcp-route=50000",
				"--tcp-route=50001:5223",
				"droppy",
				"droplet-name",
				"--",
				"start-em",
			}
			test_helpers.ExecuteCommandWithArgs(launchDropletCommand, args)

			Expect(outputBuffer).To(test_helpers.SayLine("Creating App: droppy"))
			Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("droppy is now running.")))
			Expect(outputBuffer).To(test_helpers.SayLine("App is reachable at:"))
			Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("http://ninetyninety.192.168.11.11.xip.io")))
			Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("http://fourtyfourfourtyfour.192.168.11.11.xip.io")))

			Expect(fakeDropletRunner.LaunchDropletCallCount()).To(Equal(1))
			appName, dropletNameParam, startCommandParam, _, appEnvParam := fakeDropletRunner.LaunchDropletArgsForCall(0)
			Expect(appName).To(Equal("droppy"))
			Expect(dropletNameParam).To(Equal("droplet-name"))
			Expect(startCommandParam).To(Equal("start-em"))
			Expect(appEnvParam.Instances).To(Equal(1))
			Expect(appEnvParam.NoRoutes).To(BeFalse())
			Expect(appEnvParam.RouteOverrides).To(ContainExactly(app_runner.RouteOverrides{
				{HostnamePrefix: "ninetyninety", Port: 4444},
				{HostnamePrefix: "fourtyfourfourtyfour", Port: 9090},
			}))
			BeforeEach(func() {
				tmpDir = os.TempDir()
				var err error
				tmpFile, err = ioutil.TempFile(tmpDir, "tmp_json")
				Expect(err).NotTo(HaveOccurred())

				Expect(ioutil.WriteFile(tmpFile.Name(), []byte(`{"Value":"test value"}`), 0700)).To(Succeed())
			})

			It("creates an app from json", func() {
				fakeAppRunner.SubmitLrpReturns("my-json-app", nil)

				args := []string{tmpFile.Name()}
				test_helpers.ExecuteCommandWithArgs(submitLrpCommand, args)

				Expect(outputBuffer).To(test_helpers.SayLine(colors.Green("Successfully submitted my-json-app.")))
				Expect(outputBuffer).To(test_helpers.SayLine("To view the status of your application: ltc status my-json-app"))
				Expect(fakeAppRunner.SubmitLrpCallCount()).To(Equal(1))
				Expect(fakeAppRunner.SubmitLrpArgsForCall(0)).To(Equal([]byte(`{"Value":"test value"}`)))
			})

			It("prints an error returned by the app_runner", func() {
				fakeAppRunner.SubmitLrpReturns("app-that-broke", errors.New("some error"))
				args := []string{tmpFile.Name()}
				test_helpers.ExecuteCommandWithArgs(submitLrpCommand, args)

				Expect(outputBuffer).To(test_helpers.SayLine("Error creating app-that-broke: some error"))
				Expect(fakeAppRunner.SubmitLrpCallCount()).To(Equal(1))
				Expect(fakeExitHandler.ExitCalledWith).To(Equal([]int{exit_codes.CommandFailed}))
			})
		})
			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("Route")))

			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("process1")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Red("0/21")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("100")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("50")))
			Expect(outputBuffer).To(test_helpers.Say("alldaylong.com => 54321"))

			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("process2")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Yellow("9/8")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("400")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("30")))
			Expect(outputBuffer).To(test_helpers.Say("never.io => 1234"))

			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("process3")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Green("5/5")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("600")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("90")))
			Expect(outputBuffer).To(test_helpers.Say("allthetime.com => 1234, herewego.org => 1234"))

			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("process4")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Green("0/0")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("10")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("10")))

			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("Task Name")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("Cell ID")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("Status")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("Result")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("Failure Reason")))
import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/cloudfoundry-incubator/ltc/app_examiner"
	"github.com/cloudfoundry-incubator/ltc/app_examiner/command_factory/presentation"
	"github.com/cloudfoundry-incubator/ltc/terminal/colors"
	"github.com/cloudfoundry-incubator/receptor"
)

var _ = Describe("Presentation", func() {
	Describe("ColorInstanceState", func() {
		It("colors RUNNING green", func() {
			instanceInfo := app_examiner.InstanceInfo{State: string(receptor.ActualLRPStateRunning)}
			Expect(presentation.ColorInstanceState(instanceInfo)).To(Equal(colors.Green(string(receptor.ActualLRPStateRunning))))
		})

		It("colors CLAIMED yellow", func() {
			instanceInfo := app_examiner.InstanceInfo{State: string(receptor.ActualLRPStateClaimed)}
			Expect(presentation.ColorInstanceState(instanceInfo)).To(Equal(colors.Yellow(string(receptor.ActualLRPStateClaimed))))
		})

		Context("when there is a placement error", func() {
			It("colors UNCLAIMED red", func() {
				instanceInfo := app_examiner.InstanceInfo{
					State:          string(receptor.ActualLRPStateUnclaimed),
					PlacementError: "I misplaced my cells. Uh oh.",
				}

				Expect(presentation.ColorInstanceState(instanceInfo)).To(Equal(colors.Red(string(receptor.ActualLRPStateUnclaimed))))