func (c *plugin) Run(context *cmd.Context, client *cmd.Client) error { context.RawOutput() pluginName := context.Args[0] pluginPath := cmd.JoinWithUserDir(".tsuru", "plugins", pluginName) target, err := cmd.GetURL("/") if err != nil { return err } token, err := cmd.ReadToken() if err != nil { return err } envs := os.Environ() tsuruEnvs := []string{ "TSURU_TARGET=" + target, "TSURU_TOKEN=" + token, "TSURU_PLUGIN_NAME=" + pluginName, } envs = append(envs, tsuruEnvs...) opts := exec.ExecuteOptions{ Cmd: pluginPath, Args: context.Args[1:], Stdout: context.Stdout, Stderr: context.Stderr, Stdin: context.Stdin, Envs: envs, } return executor().Execute(opts) }
func (s *S) TestPlugin(c *check.C) { fexec := exectest.FakeExecutor{ Output: map[string][][]byte{ "a b": {[]byte("hello world")}, }, } execut = &fexec defer func() { execut = nil }() var buf bytes.Buffer context := cmd.Context{ Args: []string{"myplugin", "a", "b"}, Stdout: &buf, Stderr: &buf, } client := cmd.NewClient(nil, nil, manager) command := plugin{} err := command.Run(&context, client) c.Assert(err, check.IsNil) pluginPath := cmd.JoinWithUserDir(".tsuru", "plugins", "myplugin") c.Assert(fexec.ExecutedCmd(pluginPath, []string{"a", "b"}), check.Equals, true) c.Assert(buf.String(), check.Equals, "hello world") commands := fexec.GetCommands(pluginPath) c.Assert(commands, check.HasLen, 1) target, err := cmd.ReadTarget() c.Assert(err, check.IsNil) token, err := cmd.ReadToken() c.Assert(err, check.IsNil) envs := os.Environ() tsuruEnvs := []string{ fmt.Sprintf("TSURU_TARGET=%s/", target), fmt.Sprintf("TSURU_TOKEN=%s", token), "TSURU_PLUGIN_NAME=myplugin", } envs = append(envs, tsuruEnvs...) c.Assert(commands[0].GetEnvs(), check.DeepEquals, envs) }
func (sshToContainerCmd) Run(context *cmd.Context, _ *cmd.Client) error { serverURL, err := cmd.GetURL("/docker/ssh/" + context.Args[0]) if err != nil { return err } request, err := http.NewRequest("GET", serverURL, nil) if err != nil { return err } request.Close = true token, err := cmd.ReadToken() if err == nil { request.Header.Set("Authorization", "bearer "+token) } parsedURL, _ := url.Parse(serverURL) conn, err := net.Dial("tcp", parsedURL.Host) if err != nil { return err } defer conn.Close() request.Write(conn) if stdin, ok := context.Stdin.(*os.File); ok { fd := int(stdin.Fd()) if terminal.IsTerminal(fd) { oldState, err := terminal.MakeRaw(fd) if err != nil { return err } defer terminal.Restore(fd, oldState) sigChan := make(chan os.Signal, 2) go func(c <-chan os.Signal) { if _, ok := <-c; ok { terminal.Restore(fd, oldState) os.Exit(1) } }(sigChan) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGQUIT) } } bytesLimit := 50 var readStr string byteBuffer := make([]byte, 1) for i := 0; i < bytesLimit && byteBuffer[0] != '\n'; i++ { _, err := conn.Read(byteBuffer) if err != nil { break } readStr += string(byteBuffer) } matches := httpHeaderRegexp.FindAllStringSubmatch(readStr, -1) if len(matches) > 0 && len(matches[0]) > 1 { code, _ := strconv.Atoi(matches[0][1]) return &errors.HTTP{ Code: code, Message: strings.TrimSpace(readStr), } } else { context.Stdout.Write([]byte(readStr)) } errs := make(chan error, 2) quit := make(chan bool) go io.Copy(conn, context.Stdin) go func() { defer close(quit) _, err := io.Copy(context.Stdout, conn) if err != nil && err != io.EOF { errs <- err } }() <-quit close(errs) return <-errs }