Exemple #1
0
func Scale(app string, sync bool, types []string) error {
	var size string
	scaleParams := &api.AppsScaleParams{}

	for _, t := range types {
		splitT := strings.Split(t, ":")
		if len(splitT) != 2 && len(splitT) != 3 {
			return errgo.Newf("%s is invalid, format is <type>:<amount>[:<size>]", t)
		}
		typeName, typeAmount := splitT[0], splitT[1]
		if len(splitT) == 3 {
			size = splitT[2]
		}

		amount, err := strconv.ParseInt(typeAmount, 10, 32)
		if err != nil {
			return errgo.Newf("%s in %s should be an integer", typeAmount, t)
		}
		scaleParams.Containers = append(scaleParams.Containers, api.Container{Name: typeName, Amount: int(amount), Size: size})
	}

	res, err := api.AppsScale(app, scaleParams)
	if err != nil {
		return errgo.Mask(err)
	}
	defer res.Body.Close()

	if res.StatusCode == 422 {
		var scaleUnprocessableEntity ScaleUnprocessableEntity
		err = api.ParseJSON(res, &scaleUnprocessableEntity)
		if err != nil {
			return errgo.Mask(err)
		}
		return scaleUnprocessableEntity
	}

	var scaleRes ScaleRes
	err = api.ParseJSON(res, &scaleRes)
	if err != nil {
		return errgo.Mask(err)
	}

	fmt.Printf("Your application is being scaled to:\n")
	for _, ct := range scaleRes.Containers {
		fmt.Println(io.Indent(fmt.Sprintf("%s: %d - %s", ct.Name, ct.Amount, ct.Size), 2))
	}

	if !sync {
		return nil
	}

	err = handleOperation(app, res)
	if err != nil {
		return errgo.Mask(err)
	}

	fmt.Println("Your application has been scaled.")
	return nil
}
Exemple #2
0
func Run(opts RunOpts) error {
	if opts.CmdEnv == nil {
		opts.CmdEnv = []string{}
	}
	if opts.Files == nil {
		opts.Files = []string{}
	}
	if opts.StdinCopyFunc == nil {
		opts.StdinCopyFunc = io.Copy
	}
	if opts.StdoutCopyFunc == nil {
		opts.StdoutCopyFunc = io.Copy
	}

	env, err := buildEnv(opts.CmdEnv)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	err = validateFiles(opts.Files)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	res, err := api.Run(opts.App, opts.Cmd, env)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}
	runStruct := make(map[string]interface{})
	api.ParseJSON(res, &runStruct)
	debug.Printf("%+v\n", runStruct)

	if res.StatusCode == http.StatusNotFound {
		return errgo.Newf("application %s not found", opts.App)
	}

	attachURL, ok := runStruct["attach_url"].(string)
	if !ok {
		return errgo.New("unexpected answer from server")
	}

	debug.Println("Run Service URL is", attachURL)

	if len(opts.Files) > 0 {
		err := uploadFiles(attachURL+"/files", opts.Files)
		if err != nil {
			return err
		}
	}

	res, socket, err := connectToRunServer(attachURL)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}
	if res.StatusCode != http.StatusOK {
		return errgo.Newf("Fail to attach: %s", res.Status)
	}

	if err := term.MakeRaw(os.Stdin); err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	stopSignalsMonitoring := make(chan bool)
	defer close(stopSignalsMonitoring)

	go func() {
		signals.CatchQuitSignals = false
		signals := run.NotifiedSignals()
		defer close(signals)

		go run.NofityTermSizeUpdate(signals)
		for {
			select {
			case s := <-signals:
				run.HandleSignal(s, socket, attachURL)
			case <-stopSignalsMonitoring:
				signal.Stop(signals)
				return
			}
		}
	}()

	go opts.StdinCopyFunc(socket, os.Stdin)
	_, err = opts.StdinCopyFunc(os.Stdout, socket)

	stopSignalsMonitoring <- true

	if err := term.Restore(os.Stdin); err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	return nil
}