func (h *containerSession) ServeTCP(ctx context.Context, conn net.Conn) { defer conn.Close() logger.Log(ctx, "at", "HandleConn", "received new tcp connection.") buf := bufio.NewReader(conn) str, err := buf.ReadString('\n') if err != nil { logger.Log(ctx, "at", "ServeTCP", "err", err) return } name := strings.TrimRight(str, "\r\n") if c, ok := h.relay.sessions[name]; ok { logger.Log(ctx, "at", "HandleConn", "name", name, "container exists, attaching.") fmt.Fprintln(conn, "Creating container...") if err := h.relay.CreateContainer(ctx, c); err != nil { fmt.Fprintln(conn, err.Error()) logger.Log(ctx, "at", "CreateContainer", "err", err) return } fmt.Fprintln(conn, "Attaching to container...") errCh := make(chan error, 2) go func() { err := h.relay.AttachToContainer(ctx, name, conn, conn) if err != nil { logger.Log(ctx, "at", "AttachToContainer", "err", err) } errCh <- err }() fmt.Fprintln(conn, "Starting container...") if err := h.relay.StartContainer(ctx, name); err != nil { fmt.Fprintln(conn, err.Error()) logger.Log(ctx, "at", "StartContainer", "err", err) return } logger.Log(ctx, "at", "WaitContainer", "name", name) go func() { _, err := h.relay.WaitContainer(ctx, name) errCh <- err }() // Wait for Attach or Wait to finish. err := <-errCh logger.Log(ctx, "at", "finished-attach-or-wait", "err", err) if err := h.relay.PurgeContainer(ctx, name); err != nil { logger.Log(ctx, "at", "PurgeContainer", "err", err) } } else { logger.Log(ctx, "at", "HandleConn", "container", name, "container does not exist.") } }
// PurgeContainer stops, deletes and unregisters a container. func (r *Relay) PurgeContainer(ctx context.Context, name string) (err error) { if err = r.manager.Stop(name); err != nil { logger.Log(ctx, "at", "PurgeContainer", "err", err, "error stopping container") } if err = r.manager.Remove(name); err != nil { logger.Log(ctx, "at", "PurgeContainer", "err", err, "error removing container") } r.UnregisterContainer(name) return err }
func (h *PostContainers) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, r *http.Request) error { var form PostContainersForm if err := Decode(r, &form); err != nil { return err } if form.User == "" { form.User = "******" } name := h.GenContainerName(fmt.Sprintf("run.%s", form.User)) logger.Log(ctx, "at", "PostContainers", "container-name", name, "starting new container session") c := &Container{ Image: form.Image, Name: name, Command: form.Command, State: "starting", Env: form.Env, Attach: form.Attach, AttachURL: fmt.Sprintf("%s/%s", h.Host, name), } h.RegisterContainer(name, c) w.WriteHeader(201) return Encode(w, c) }
// Report logs the error to the Logger. func (h *LogReporter) Report(ctx context.Context, err error) error { switch err := err.(type) { case *Error: var line *BacktraceLine if len(err.Backtrace) > 0 { line = err.Backtrace[0] } else { line = &BacktraceLine{ File: "unknown", Line: 0, } } logger.Log(ctx, "error", fmt.Sprintf(`"%v"`, err), "line", line.Line, "file", line.File) default: logger.Log(ctx, "error", fmt.Sprintf(`"%v"`, err)) } return nil }