示例#1
0
文件: cli.go 项目: ChaosCloud/docker
func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string, tlsConfig *tls.Config) *DockerCli {
	var (
		isTerminal = false
		terminalFd uintptr
	)

	if in != nil {
		if file, ok := in.(*os.File); ok {
			terminalFd = file.Fd()
			isTerminal = term.IsTerminal(terminalFd)
		}
	}

	if err == nil {
		err = out
	}
	return &DockerCli{
		proto:      proto,
		addr:       addr,
		in:         in,
		out:        out,
		err:        err,
		isTerminal: isTerminal,
		terminalFd: terminalFd,
		tlsConfig:  tlsConfig,
	}
}
示例#2
0
func (c *DockerClient) hijack(method, path string, setRawTerminal bool, in io.Reader, errStream io.Writer, out io.Writer) error {
	req, err := http.NewRequest(method, c.getURL(path), nil)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "plain/text")
	protocol := c.endpointURL.Scheme
	address := c.endpointURL.Path
	if protocol != "unix" {
		protocol = "tcp"
		address = c.endpointURL.Host
	}
	dial, err := net.Dial(protocol, address)
	if err != nil {
		return err
	}
	clientconn := httputil.NewClientConn(dial, nil)
	clientconn.Do(req)
	defer clientconn.Close()
	rwc, br := clientconn.Hijack()
	defer rwc.Close()
	errStdout := make(chan error, 1)
	go func() {
		var err error
		if setRawTerminal {
			_, err = io.Copy(out, br)
		} else {
			_, err = utils.StdCopy(out, errStream, br)
		}
		errStdout <- err
	}()
	if inFile, ok := in.(*os.File); ok && setRawTerminal && term.IsTerminal(inFile.Fd()) && os.Getenv("NORAW") == "" {
		oldState, err := term.SetRawTerminal(inFile.Fd())
		if err != nil {
			return err
		}
		defer term.RestoreTerminal(inFile.Fd(), oldState)
	}
	go func() {
		if in != nil {
			io.Copy(rwc, in)
		}
		if err := rwc.(interface {
			CloseWrite() error
		}).CloseWrite(); err != nil && errStream != nil {
			fmt.Fprintf(errStream, "Couldn't send EOF: %s\n", err)
		}
	}()
	if err := <-errStdout; err != nil {
		return err
	}
	return nil
}
示例#3
0
func CmdPrompt(args []string, stdout, stderr io.Writer, in beam.Receiver, out beam.Sender) {
	if len(args) < 2 {
		fmt.Fprintf(stderr, "usage: %s PROMPT...\n", args[0])
		return
	}
	if !term.IsTerminal(0) {
		fmt.Fprintf(stderr, "can't prompt: no tty available...\n")
		return
	}
	fmt.Printf("%s: ", strings.Join(args[1:], " "))
	oldState, _ := term.SaveState(0)
	term.DisableEcho(0, oldState)
	line, _, err := bufio.NewReader(os.Stdin).ReadLine()
	if err != nil {
		fmt.Fprintln(stderr, err.Error())
		return
	}
	val := string(line)
	fmt.Printf("\n")
	term.RestoreTerminal(0, oldState)
	out.Send(data.Empty().Set("fromcmd", args...).Set("value", val).Bytes(), nil)
}
示例#4
0
文件: client.go 项目: johnzan/drone
func (c *Client) stream(method, path string, in io.Reader, out io.Writer, headers http.Header) error {
	if (method == "POST" || method == "PUT") && in == nil {
		in = bytes.NewReader(nil)
	}

	// setup the request
	req, err := http.NewRequest(method, fmt.Sprintf("/v%g%s", APIVERSION, path), in)
	if err != nil {
		return err
	}

	// set default headers
	req.Header = headers
	req.Header.Set("User-Agent", "Docker-Client/0.6.4")
	req.Header.Set("Content-Type", "plain/text")

	// dial the host server
	req.Host = c.addr
	dial, err := net.Dial(c.proto, c.addr)
	if err != nil {
		return err
	}

	// make the request
	conn := httputil.NewClientConn(dial, nil)
	resp, err := conn.Do(req)
	defer conn.Close()
	if err != nil {
		return err
	}

	// make sure we defer close the body
	defer resp.Body.Close()

	// Check for an http error status (ie not 200 StatusOK)
	switch resp.StatusCode {
	case 404:
		return ErrNotFound
	case 403:
		return ErrForbidden
	case 401:
		return ErrNotAuthorized
	case 400:
		return ErrBadRequest
	}

	// If no output we exit now with no errors
	if out == nil {
		return nil
	}

	// copy the output stream to the writer
	if resp.Header.Get("Content-Type") == "application/json" {
		var terminalFd = os.Stdin.Fd()
		var isTerminal = term.IsTerminal(terminalFd)

		// it may not make sense to put this code here, but it works for
		// us at the moment, and I don't feel like refactoring
		return utils.DisplayJSONMessagesStream(resp.Body, out, terminalFd, isTerminal)
	}
	// otherwise plain text
	if _, err := io.Copy(out, resp.Body); err != nil {
		return err
	}

	return nil
}
示例#5
0
func main() {
	fd3 := os.NewFile(3, "beam-introspect")
	if introsp, err := beam.FileConn(fd3); err == nil {
		introspect = introsp
		Logf("introspection enabled\n")
	} else {
		Logf("introspection disabled\n")
	}
	fd3.Close()
	flag.BoolVar(&flX, "x", false, "print commands as they are being executed")
	flag.Parse()
	if flag.NArg() == 0 {
		if term.IsTerminal(0) {
			// No arguments, stdin is terminal --> interactive mode
			input := bufio.NewScanner(os.Stdin)
			for {
				fmt.Printf("[%d] beamsh> ", os.Getpid())
				if !input.Scan() {
					break
				}
				line := input.Text()
				if len(line) != 0 {
					cmd, err := dockerscript.Parse(strings.NewReader(line))
					if err != nil {
						fmt.Fprintf(os.Stderr, "error: %v\n", err)
						continue
					}
					if err := executeRootScript(cmd); err != nil {
						Fatal(err)
					}
				}
				if err := input.Err(); err == io.EOF {
					break
				} else if err != nil {
					Fatal(err)
				}
			}
		} else {
			// No arguments, stdin not terminal --> batch mode
			script, err := dockerscript.Parse(os.Stdin)
			if err != nil {
				Fatal("parse error: %v\n", err)
			}
			if err := executeRootScript(script); err != nil {
				Fatal(err)
			}
		}
	} else {
		// 1+ arguments: parse them as script files
		for _, scriptpath := range flag.Args() {
			f, err := os.Open(scriptpath)
			if err != nil {
				Fatal(err)
			}
			script, err := dockerscript.Parse(f)
			if err != nil {
				Fatal("parse error: %v\n", err)
			}
			if err := executeRootScript(script); err != nil {
				Fatal(err)
			}
		}
	}
}
示例#6
0
func init() {
	if term.IsTerminal(1) {
		Colorize = true
	}
}