Пример #1
0
func (cmd *Push) processDomainsAndBindRoutes(
	appParams models.AppParams,
	routeActor actors.RouteActor,
	app models.Application,
	domain models.DomainFields,
) {
	if appParams.IsHostEmpty() {
		cmd.createAndBindRoute(
			nil,
			appParams.UseRandomRoute,
			appParams.UseRandomPort,
			routeActor,
			app,
			appParams.NoHostname,
			domain,
			appParams.RoutePath,
		)
	} else {
		for _, host := range *(appParams.Hosts) {
			cmd.createAndBindRoute(
				&host,
				appParams.UseRandomRoute,
				appParams.UseRandomPort,
				routeActor,
				app,
				appParams.NoHostname,
				domain,
				appParams.RoutePath,
			)
		}
	}
}
Пример #2
0
func (cmd *Push) updateRoutes(routeActor actors.RouteActor, app models.Application, appParams models.AppParams) {
	defaultRouteAcceptable := len(app.Routes) == 0
	routeDefined := appParams.Domains != nil || !appParams.IsHostEmpty() || appParams.NoHostname

	if appParams.NoRoute {
		if len(app.Routes) == 0 {
			cmd.ui.Say(T("App {{.AppName}} is a worker, skipping route creation",
				map[string]interface{}{"AppName": terminal.EntityNameColor(app.Name)}))
		} else {
			routeActor.UnbindAll(app)
		}
		return
	}

	if routeDefined || defaultRouteAcceptable {
		if appParams.Domains == nil {
			domain := cmd.findDomain(nil)
			appParams.UseRandomPort = isTcp(domain)
			cmd.processDomainsAndBindRoutes(appParams, routeActor, app, domain)
		} else {
			for _, d := range *(appParams.Domains) {
				domain := cmd.findDomain(&d)
				appParams.UseRandomPort = isTcp(domain)
				cmd.processDomainsAndBindRoutes(appParams, routeActor, app, domain)
			}
		}
	}
}
Пример #3
0
func (cmd *Push) createAppSetFromContextAndManifest(contextApp models.AppParams, manifestApps []models.AppParams) []models.AppParams {
	var err error
	var apps []models.AppParams

	switch len(manifestApps) {
	case 0:
		if contextApp.Name == nil {
			cmd.ui.Failed(
				T("Manifest file is not found in the current directory, please provide either an app name or manifest") +
					"\n\n" +
					command_registry.Commands.CommandUsage("push"),
			)
		} else {
			err = addApp(&apps, contextApp)
		}
	case 1:
		manifestApps[0].Merge(&contextApp)
		err = addApp(&apps, manifestApps[0])
	default:
		selectedAppName := contextApp.Name
		contextApp.Name = nil

		if !contextApp.IsEmpty() {
			cmd.ui.Failed("%s", T("Incorrect Usage. Command line flags (except -f) cannot be applied when pushing multiple apps from a manifest file."))
		}

		if selectedAppName != nil {
			var foundApp bool
			for _, appParams := range manifestApps {
				if appParams.Name != nil && *appParams.Name == *selectedAppName {
					foundApp = true
					addApp(&apps, appParams)
				}
			}

			if !foundApp {
				err = errors.New(T("Could not find app named '{{.AppName}}' in manifest", map[string]interface{}{"AppName": *selectedAppName}))
			}
		} else {
			for _, manifestApp := range manifestApps {
				addApp(&apps, manifestApp)
			}
		}
	}

	if err != nil {
		cmd.ui.Failed(T("Error: {{.Err}}", map[string]interface{}{"Err": err.Error()}))
	}

	return apps
}
Пример #4
0
func (cmd *Push) updateRoutes(routeActor actors.RouteActor, app models.Application, appParams models.AppParams) {
	defaultRouteAcceptable := len(app.Routes) == 0
	routeDefined := appParams.Domains != nil || !appParams.IsHostEmpty() || appParams.NoHostname

	if appParams.NoRoute {
		cmd.removeRoutes(app, routeActor)
		return
	}

	if routeDefined || defaultRouteAcceptable {
		if appParams.Domains == nil {
			cmd.processDomainsAndBindRoutes(appParams, routeActor, app, cmd.findDomain(nil))
		} else {
			for _, d := range *(appParams.Domains) {
				cmd.processDomainsAndBindRoutes(appParams, routeActor, app, cmd.findDomain(&d))
			}
		}
	}
}
Пример #5
0
func addApp(apps *[]models.AppParams, app models.AppParams) (err error) {
	if app.Name == nil {
		err = errors.New(T("App name is a required field"))
	}
	if app.Path == nil {
		cwd, _ := os.Getwd()
		app.Path = &cwd
	}
	*apps = append(*apps, app)
	return
}
Пример #6
0
func (cmd *Push) createAppSetFromContextAndManifest(contextApp models.AppParams, manifestApps []models.AppParams) (apps []models.AppParams) {
	var err error

	switch len(manifestApps) {
	case 0:
		if contextApp.Name == nil {
			err = errors.New(T("Manifest file is not found in the current directory, please provide either an app name or manifest"))
		} else {
			err = addApp(&apps, contextApp)
		}
	case 1:
		manifestApps[0].Merge(&contextApp)
		err = addApp(&apps, manifestApps[0])
	default:
		selectedAppName := contextApp.Name
		contextApp.Name = nil

		if !contextApp.IsEmpty() {
			cmd.ui.Failed("%s", T("Incorrect Usage. Command line flags (except -f) cannot be applied when pushing multiple apps from a manifest file."))
		}

		if selectedAppName != nil {
			var manifestApp models.AppParams
			manifestApp, err = findAppWithNameInManifest(*selectedAppName, manifestApps)
			if err == nil {
				addApp(&apps, manifestApp)
			}
		} else {
			for _, manifestApp := range manifestApps {
				addApp(&apps, manifestApp)
			}
		}
	}

	if err != nil {
		cmd.ui.Failed(T("Error: {{.Err}}", map[string]interface{}{"Err": err.Error()}))
	}

	return
}
Пример #7
0
func (cmd *Push) createAppSetFromContextAndManifest(contextApp models.AppParams, manifestApps []models.AppParams) (apps []models.AppParams) {
	var err error

	switch len(manifestApps) {
	case 0:
		err = addApp(&apps, contextApp)
	case 1:
		manifestApps[0].Merge(&contextApp)
		err = addApp(&apps, manifestApps[0])
	default:
		selectedAppName := contextApp.Name
		contextApp.Name = nil

		if !contextApp.IsEmpty() {
			cmd.ui.Failed("%s", "Incorrect Usage. Command line flags (except -f) cannot be applied when pushing multiple apps from a manifest file.")
		}

		if selectedAppName != nil {
			var manifestApp models.AppParams
			manifestApp, err = findAppWithNameInManifest(*selectedAppName, manifestApps)
			if err == nil {
				addApp(&apps, manifestApp)
			}
		} else {
			for _, manifestApp := range manifestApps {
				addApp(&apps, manifestApp)
			}
		}
	}

	if err != nil {
		cmd.ui.Failed("Error: %s", err)
	}

	return
}
Пример #8
0
func (cmd *Push) processDomainsAndBindRoutes(
	appParams models.AppParams,
	app models.Application,
	domain models.DomainFields,
) error {
	if appParams.IsHostEmpty() {
		err := cmd.createAndBindRoute(
			nil,
			appParams.UseRandomRoute,
			appParams.UseRandomPort,
			app,
			appParams.NoHostname,
			domain,
			appParams.RoutePath,
		)
		if err != nil {
			return err
		}
	} else {
		for _, host := range *(appParams.Hosts) {
			err := cmd.createAndBindRoute(
				&host,
				appParams.UseRandomRoute,
				appParams.UseRandomPort,
				app,
				appParams.NoHostname,
				domain,
				appParams.RoutePath,
			)
			if err != nil {
				return err
			}
		}
	}
	return nil
}
Пример #9
0
func (cmd *Push) fetchStackGuid(appParams *models.AppParams) {
	if appParams.StackName == nil {
		return
	}

	stackName := *appParams.StackName
	cmd.ui.Say("Using stack %s...", terminal.EntityNameColor(stackName))

	stack, apiErr := cmd.stackRepo.FindByName(stackName)
	if apiErr != nil {
		cmd.ui.Failed(apiErr.Error())
		return
	}

	cmd.ui.Ok()
	appParams.StackGuid = &stack.Guid
}
Пример #10
0
func addApp(apps *[]models.AppParams, app models.AppParams) error {
	if app.Name == nil {
		return errors.New(T("App name is a required field"))
	}

	if app.Path == nil {
		cwd, err := os.Getwd()
		if err != nil {
			return err
		}
		app.Path = &cwd
	}

	*apps = append(*apps, app)

	return nil
}
Пример #11
0
func (cmd *Push) fetchStackGuid(appParams *models.AppParams) {
	if appParams.StackName == nil {
		return
	}

	stackName := *appParams.StackName
	cmd.ui.Say(T("Using stack {{.StackName}}...",
		map[string]interface{}{"StackName": terminal.EntityNameColor(stackName)}))

	stack, apiErr := cmd.stackRepo.FindByName(stackName)
	if apiErr != nil {
		cmd.ui.Failed(apiErr.Error())
		return
	}

	cmd.ui.Ok()
	appParams.StackGuid = &stack.Guid
}
Пример #12
0
func (cmd *Push) fetchStackGUID(appParams *models.AppParams) error {
	if appParams.StackName == nil {
		return nil
	}

	stackName := *appParams.StackName
	cmd.ui.Say(T("Using stack {{.StackName}}...",
		map[string]interface{}{"StackName": terminal.EntityNameColor(stackName)}))

	stack, err := cmd.stackRepo.FindByName(stackName)
	if err != nil {
		return err
	}

	cmd.ui.Ok()
	appParams.StackGUID = &stack.GUID
	return nil
}
Пример #13
0
func (cmd *Push) createApp(appParams models.AppParams) (app models.Application) {
	spaceGuid := cmd.config.SpaceFields().Guid
	appParams.SpaceGuid = &spaceGuid

	cmd.ui.Say(T("Creating app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...",
		map[string]interface{}{
			"AppName":   terminal.EntityNameColor(*appParams.Name),
			"OrgName":   terminal.EntityNameColor(cmd.config.OrganizationFields().Name),
			"SpaceName": terminal.EntityNameColor(cmd.config.SpaceFields().Name),
			"Username":  terminal.EntityNameColor(cmd.config.Username())}))

	app, apiErr := cmd.appRepo.Create(appParams)
	if apiErr != nil {
		cmd.ui.Failed(apiErr.Error())
	}

	cmd.ui.Ok()
	cmd.ui.Say("")

	return
}
Пример #14
0
func (cmd *Push) createApp(appParams models.AppParams) (app models.Application) {
	spaceGuid := cmd.config.SpaceFields().Guid
	appParams.SpaceGuid = &spaceGuid

	cmd.ui.Say("Creating app %s in org %s / space %s as %s...",
		terminal.EntityNameColor(*appParams.Name),
		terminal.EntityNameColor(cmd.config.OrganizationFields().Name),
		terminal.EntityNameColor(cmd.config.SpaceFields().Name),
		terminal.EntityNameColor(cmd.config.Username()),
	)

	app, apiErr := cmd.appRepo.Create(appParams)
	if apiErr != nil {
		cmd.ui.Failed(apiErr.Error())
	}

	cmd.ui.Ok()
	cmd.ui.Say("")

	return
}
Пример #15
0
func (cmd *Push) updateRoutes(app models.Application, appParams models.AppParams, appParamsFromContext models.AppParams) error {
	defaultRouteAcceptable := len(app.Routes) == 0
	routeDefined := appParams.Domains != nil || !appParams.IsHostEmpty() || appParams.IsNoHostnameTrue()

	switch {
	case appParams.NoRoute:
		if len(app.Routes) == 0 {
			cmd.ui.Say(T("App {{.AppName}} is a worker, skipping route creation",
				map[string]interface{}{"AppName": terminal.EntityNameColor(app.Name)}))
		} else {
			err := cmd.routeActor.UnbindAll(app)
			if err != nil {
				return err
			}
		}
	case len(appParams.Routes) > 0:
		for _, manifestRoute := range appParams.Routes {
			err := cmd.actor.MapManifestRoute(manifestRoute.Route, app, appParamsFromContext)
			if err != nil {
				return err
			}
		}
	case (routeDefined || defaultRouteAcceptable) && appParams.Domains == nil:
		domain, err := cmd.findDomain(nil)
		if err != nil {
			return err
		}
		appParams.UseRandomPort = isTCP(domain)
		err = cmd.processDomainsAndBindRoutes(appParams, app, domain)
		if err != nil {
			return err
		}
	case routeDefined || defaultRouteAcceptable:
		for _, d := range appParams.Domains {
			domain, err := cmd.findDomain(&d)
			if err != nil {
				return err
			}
			appParams.UseRandomPort = isTCP(domain)
			err = cmd.processDomainsAndBindRoutes(appParams, app, domain)
			if err != nil {
				return err
			}
		}
	}
	return nil
}
Пример #16
0
func mapToAppParams(basePath string, yamlMap generic.Map) (models.AppParams, error) {
	err := checkForNulls(yamlMap)
	if err != nil {
		return models.AppParams{}, err
	}

	var appParams models.AppParams
	var errs []error
	appParams.BuildpackUrl = stringValOrDefault(yamlMap, "buildpack", &errs)
	appParams.DiskQuota = bytesVal(yamlMap, "disk_quota", &errs)

	domainAry := *sliceOrEmptyVal(yamlMap, "domains", &errs)
	if domain := stringVal(yamlMap, "domain", &errs); domain != nil {
		domainAry = append(domainAry, *domain)
	}
	appParams.Domains = removeDuplicatedValue(domainAry)

	hostsArr := *sliceOrEmptyVal(yamlMap, "hosts", &errs)
	if host := stringVal(yamlMap, "host", &errs); host != nil {
		hostsArr = append(hostsArr, *host)
	}
	appParams.Hosts = removeDuplicatedValue(hostsArr)

	appParams.Name = stringVal(yamlMap, "name", &errs)
	appParams.Path = stringVal(yamlMap, "path", &errs)
	appParams.StackName = stringVal(yamlMap, "stack", &errs)
	appParams.Command = stringValOrDefault(yamlMap, "command", &errs)
	appParams.Memory = bytesVal(yamlMap, "memory", &errs)
	appParams.InstanceCount = intVal(yamlMap, "instances", &errs)
	appParams.HealthCheckTimeout = intVal(yamlMap, "timeout", &errs)
	appParams.NoRoute = boolVal(yamlMap, "no-route", &errs)
	appParams.NoHostname = boolVal(yamlMap, "no-hostname", &errs)
	appParams.UseRandomHostname = boolVal(yamlMap, "random-route", &errs)
	appParams.ServicesToBind = sliceOrEmptyVal(yamlMap, "services", &errs)
	appParams.EnvironmentVars = envVarOrEmptyMap(yamlMap, &errs)
	appParams.HealthCheckType = stringVal(yamlMap, "health-check-type", &errs)

	if appParams.Path != nil {
		path := *appParams.Path
		if filepath.IsAbs(path) {
			path = filepath.Clean(path)
		} else {
			path = filepath.Join(basePath, path)
		}
		appParams.Path = &path
	}

	if len(errs) > 0 {
		message := ""
		for _, err := range errs {
			message = message + fmt.Sprintf("%s\n", err.Error())
		}
		return models.AppParams{}, errors.New(message)
	}

	return appParams, nil
}
Пример #17
0
			applicationModel := resource.ToModel()
			Expect(*applicationModel.PackageUpdatedAt).To(Equal(testtime.MustParse(eventTimestampFormat, "2013-10-07T16:51:07+00:00")))
		})
	})

	Describe("NewApplicationEntityFromAppParams", func() {
		var (
			appParams models.AppParams

			diskQuota, memory                 int64
			healthCheckTimeout, instanceCount int
			diego, enableSSH                  bool
			packageUpdatedAt                  time.Time
			appPorts                          []int
			environmentVars                   map[string]interface{}

			buildpackURL,
			command,
			healthCheckType,
			dockerImage,
			name,
			spaceGUID,
			stackGUID,
			state string
		)

		BeforeEach(func() {
			buildpackURL = "buildpack-url"
			command = "command"
			diskQuota = int64(1024)
			environmentVars = map[string]interface{}{
Пример #18
0
func (cmd *Scale) Run(c *cli.Context) {
	currentApp := cmd.appReq.GetApplication()
	if !anyFlagsSet(c) {
		cmd.ui.Say("Showing current scale of app %s in org %s / space %s as %s...",
			terminal.EntityNameColor(currentApp.Name),
			terminal.EntityNameColor(cmd.config.OrganizationFields().Name),
			terminal.EntityNameColor(cmd.config.SpaceFields().Name),
			terminal.EntityNameColor(cmd.config.Username()),
		)
		cmd.ui.Ok()
		cmd.ui.Say("")

		cmd.ui.Say("%s %s", terminal.HeaderColor("memory:"), formatters.ByteSize(currentApp.Memory*bytesInAMegabyte))
		cmd.ui.Say("%s %s", terminal.HeaderColor("disk:"), formatters.ByteSize(currentApp.DiskQuota*bytesInAMegabyte))
		cmd.ui.Say("%s %d", terminal.HeaderColor("instances:"), currentApp.InstanceCount)

		return
	}

	params := models.AppParams{}
	shouldRestart := false

	if c.String("m") != "" {
		memory, err := formatters.ToMegabytes(c.String("m"))
		if err != nil {
			cmd.ui.Failed("Invalid memory limit: %s\n%s", c.String("m"), err)
		}
		params.Memory = &memory
		shouldRestart = true
	}

	if c.String("k") != "" {
		diskQuota, err := formatters.ToMegabytes(c.String("k"))
		if err != nil {
			cmd.ui.Failed("Invalid disk quota: %s\n%s", c.String("k"), err)
		}
		params.DiskQuota = &diskQuota
		shouldRestart = true
	}

	if c.IsSet("i") {
		instances := c.Int("i")
		if instances > 0 {
			params.InstanceCount = &instances
		} else {
			cmd.ui.Failed("Invalid instance count: %d\nInstance count must be a positive integer", instances)
		}
	}

	if shouldRestart && !cmd.confirmRestart(c, currentApp.Name) {
		return
	}

	cmd.ui.Say("Scaling app %s in org %s / space %s as %s...",
		terminal.EntityNameColor(currentApp.Name),
		terminal.EntityNameColor(cmd.config.OrganizationFields().Name),
		terminal.EntityNameColor(cmd.config.SpaceFields().Name),
		terminal.EntityNameColor(cmd.config.Username()),
	)

	updatedApp, apiErr := cmd.appRepo.Update(currentApp.Guid, params)
	if apiErr != nil {
		cmd.ui.Failed(apiErr.Error())
		return
	}

	cmd.ui.Ok()

	if shouldRestart {
		cmd.restarter.ApplicationRestart(updatedApp)
	}
}
Пример #19
0
func (cmd *Scale) Execute(c flags.FlagContext) {
	currentApp := cmd.appReq.GetApplication()
	if !anyFlagsSet(c) {
		cmd.ui.Say(T("Showing current scale of app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...",
			map[string]interface{}{
				"AppName":     terminal.EntityNameColor(currentApp.Name),
				"OrgName":     terminal.EntityNameColor(cmd.config.OrganizationFields().Name),
				"SpaceName":   terminal.EntityNameColor(cmd.config.SpaceFields().Name),
				"CurrentUser": terminal.EntityNameColor(cmd.config.Username()),
			}))
		cmd.ui.Ok()
		cmd.ui.Say("")

		cmd.ui.Say("%s %s", terminal.HeaderColor(T("memory:")), formatters.ByteSize(currentApp.Memory*bytesInAMegabyte))
		cmd.ui.Say("%s %s", terminal.HeaderColor(T("disk:")), formatters.ByteSize(currentApp.DiskQuota*bytesInAMegabyte))
		cmd.ui.Say("%s %d", terminal.HeaderColor(T("instances:")), currentApp.InstanceCount)

		return
	}

	params := models.AppParams{}
	shouldRestart := false

	if c.String("m") != "" {
		memory, err := formatters.ToMegabytes(c.String("m"))
		if err != nil {
			cmd.ui.Failed(T("Invalid memory limit: {{.Memory}}\n{{.ErrorDescription}}",
				map[string]interface{}{
					"Memory":           c.String("m"),
					"ErrorDescription": err,
				}))
		}
		params.Memory = &memory
		shouldRestart = true
	}

	if c.String("k") != "" {
		diskQuota, err := formatters.ToMegabytes(c.String("k"))
		if err != nil {
			cmd.ui.Failed(T("Invalid disk quota: {{.DiskQuota}}\n{{.ErrorDescription}}",
				map[string]interface{}{
					"DiskQuota":        c.String("k"),
					"ErrorDescription": err,
				}))
		}
		params.DiskQuota = &diskQuota
		shouldRestart = true
	}

	if c.IsSet("i") {
		instances := c.Int("i")
		if instances > 0 {
			params.InstanceCount = &instances
		} else {
			cmd.ui.Failed(T("Invalid instance count: {{.InstanceCount}}\nInstance count must be a positive integer",
				map[string]interface{}{
					"InstanceCount": instances,
				}))
		}
	}

	if shouldRestart && !cmd.confirmRestart(c, currentApp.Name) {
		return
	}

	cmd.ui.Say(T("Scaling app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...",
		map[string]interface{}{
			"AppName":     terminal.EntityNameColor(currentApp.Name),
			"OrgName":     terminal.EntityNameColor(cmd.config.OrganizationFields().Name),
			"SpaceName":   terminal.EntityNameColor(cmd.config.SpaceFields().Name),
			"CurrentUser": terminal.EntityNameColor(cmd.config.Username()),
		}))

	updatedApp, apiErr := cmd.appRepo.Update(currentApp.Guid, params)
	if apiErr != nil {
		cmd.ui.Failed(apiErr.Error())
		return
	}

	cmd.ui.Ok()

	if shouldRestart {
		cmd.restarter.ApplicationRestart(updatedApp, cmd.config.OrganizationFields().Name, cmd.config.SpaceFields().Name)
	}
}
Пример #20
0
func (cmd *Push) getAppParamsFromContext(c flags.FlagContext) (models.AppParams, error) {
	noHostBool := c.Bool("no-hostname")
	appParams := models.AppParams{
		NoRoute:        c.Bool("no-route"),
		UseRandomRoute: c.Bool("random-route"),
		NoHostname:     &noHostBool,
	}

	if len(c.Args()) > 0 {
		appParams.Name = &c.Args()[0]
	}

	if c.String("n") != "" {
		appParams.Hosts = []string{c.String("n")}
	}

	if c.String("route-path") != "" {
		routePath := c.String("route-path")
		appParams.RoutePath = &routePath
	}

	if c.String("app-ports") != "" {
		appPortStrings := strings.Split(c.String("app-ports"), ",")
		appPorts := make([]int, len(appPortStrings))

		for i, s := range appPortStrings {
			p, err := strconv.Atoi(s)
			if err != nil {
				return models.AppParams{}, errors.New(T("Invalid app port: {{.AppPort}}\nApp port must be a number", map[string]interface{}{
					"AppPort": s,
				}))
			}
			appPorts[i] = p
		}

		appParams.AppPorts = &appPorts
	}

	if c.String("b") != "" {
		buildpack := c.String("b")
		if buildpack == "null" || buildpack == "default" {
			buildpack = ""
		}
		appParams.BuildpackURL = &buildpack
	}

	if c.String("c") != "" {
		command := c.String("c")
		if command == "null" || command == "default" {
			command = ""
		}
		appParams.Command = &command
	}

	if c.String("d") != "" {
		appParams.Domains = []string{c.String("d")}
	}

	if c.IsSet("i") {
		instances := c.Int("i")
		if instances < 1 {
			return models.AppParams{}, errors.New(T("Invalid instance count: {{.InstancesCount}}\nInstance count must be a positive integer",
				map[string]interface{}{"InstancesCount": instances}))
		}
		appParams.InstanceCount = &instances
	}

	if c.String("k") != "" {
		diskQuota, err := formatters.ToMegabytes(c.String("k"))
		if err != nil {
			return models.AppParams{}, errors.New(T("Invalid disk quota: {{.DiskQuota}}\n{{.Err}}",
				map[string]interface{}{"DiskQuota": c.String("k"), "Err": err.Error()}))
		}
		appParams.DiskQuota = &diskQuota
	}

	if c.String("m") != "" {
		memory, err := formatters.ToMegabytes(c.String("m"))
		if err != nil {
			return models.AppParams{}, errors.New(T("Invalid memory limit: {{.MemLimit}}\n{{.Err}}",
				map[string]interface{}{"MemLimit": c.String("m"), "Err": err.Error()}))
		}
		appParams.Memory = &memory
	}

	if c.String("docker-image") != "" {
		dockerImage := c.String("docker-image")
		appParams.DockerImage = &dockerImage
	}

	if c.String("p") != "" {
		path := c.String("p")
		appParams.Path = &path
	}

	if c.String("s") != "" {
		stackName := c.String("s")
		appParams.StackName = &stackName
	}

	if c.String("t") != "" {
		timeout, err := strconv.Atoi(c.String("t"))
		if err != nil {
			return models.AppParams{}, fmt.Errorf("Error: %s", fmt.Errorf(T("Invalid timeout param: {{.Timeout}}\n{{.Err}}",
				map[string]interface{}{"Timeout": c.String("t"), "Err": err.Error()})))
		}

		appParams.HealthCheckTimeout = &timeout
	}

	if healthCheckType := c.String("u"); healthCheckType != "" {
		if healthCheckType != "port" && healthCheckType != "none" {
			return models.AppParams{}, fmt.Errorf("Error: %s", fmt.Errorf(T("Invalid health-check-type param: {{.healthCheckType}}",
				map[string]interface{}{"healthCheckType": healthCheckType})))
		}

		appParams.HealthCheckType = &healthCheckType
	}

	return appParams, nil
}