github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/api/handlers/compat/resize.go (about)

     1  package compat
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strings"
     7  
     8  	"github.com/containers/podman/v2/libpod"
     9  	"github.com/containers/podman/v2/libpod/define"
    10  	"github.com/containers/podman/v2/pkg/api/handlers/utils"
    11  	"github.com/gorilla/mux"
    12  	"github.com/gorilla/schema"
    13  	"github.com/pkg/errors"
    14  	"k8s.io/client-go/tools/remotecommand"
    15  )
    16  
    17  func ResizeTTY(w http.ResponseWriter, r *http.Request) {
    18  	runtime := r.Context().Value("runtime").(*libpod.Runtime)
    19  	decoder := r.Context().Value("decoder").(*schema.Decoder)
    20  
    21  	// /containers/{id}/resize
    22  	query := struct {
    23  		height uint16 `schema:"h"`
    24  		width  uint16 `schema:"w"`
    25  	}{
    26  		// override any golang type defaults
    27  	}
    28  
    29  	if err := decoder.Decode(&query, r.URL.Query()); err != nil {
    30  		utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
    31  			errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
    32  		return
    33  	}
    34  
    35  	sz := remotecommand.TerminalSize{
    36  		Width:  query.width,
    37  		Height: query.height,
    38  	}
    39  
    40  	var status int
    41  	switch {
    42  	case strings.Contains(r.URL.Path, "/containers/"):
    43  		name := utils.GetName(r)
    44  		ctnr, err := runtime.LookupContainer(name)
    45  		if err != nil {
    46  			utils.ContainerNotFound(w, name, err)
    47  			return
    48  		}
    49  		if state, err := ctnr.State(); err != nil {
    50  			utils.InternalServerError(w, errors.Wrapf(err, "cannot obtain container state"))
    51  			return
    52  		} else if state != define.ContainerStateRunning {
    53  			utils.Error(w, "Container not running", http.StatusConflict,
    54  				fmt.Errorf("container %q in wrong state %q", name, state.String()))
    55  			return
    56  		}
    57  		if err := ctnr.AttachResize(sz); err != nil {
    58  			utils.InternalServerError(w, errors.Wrapf(err, "cannot resize container"))
    59  			return
    60  		}
    61  		// This is not a 204, even though we write nothing, for compatibility
    62  		// reasons.
    63  		status = http.StatusOK
    64  	case strings.Contains(r.URL.Path, "/exec/"):
    65  		name := mux.Vars(r)["id"]
    66  		ctnr, err := runtime.GetExecSessionContainer(name)
    67  		if err != nil {
    68  			utils.SessionNotFound(w, name, err)
    69  			return
    70  		}
    71  		if state, err := ctnr.State(); err != nil {
    72  			utils.InternalServerError(w, errors.Wrapf(err, "cannot obtain session container state"))
    73  			return
    74  		} else if state != define.ContainerStateRunning {
    75  			utils.Error(w, "Container not running", http.StatusConflict,
    76  				fmt.Errorf("container %q in wrong state %q", name, state.String()))
    77  			return
    78  		}
    79  		if err := ctnr.ExecResize(name, sz); err != nil {
    80  			utils.InternalServerError(w, errors.Wrapf(err, "cannot resize session"))
    81  			return
    82  		}
    83  		// This is not a 204, even though we write nothing, for compatibility
    84  		// reasons.
    85  		status = http.StatusCreated
    86  	}
    87  	utils.WriteResponse(w, status, "")
    88  }