diff --git a/apis/server/container_bridge.go b/apis/server/container_bridge.go index c70f3b7d4..3fc9d6413 100644 --- a/apis/server/container_bridge.go +++ b/apis/server/container_bridge.go @@ -354,5 +354,25 @@ func (s *Server) logsContainer(ctx context.Context, rw http.ResponseWriter, req // TODO return nil +} + +func (s *Server) resizeContainer(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { + opts := types.ResizeOptions{} + // decode request body + if err := json.NewDecoder(req.Body).Decode(opts); err != nil { + return httputils.NewHTTPError(err, http.StatusBadRequest) + } + // validate request body + if err := opts.Validate(strfmt.NewFormats()); err != nil { + return httputils.NewHTTPError(err, http.StatusBadRequest) + } + name := mux.Vars(req)["name"] + + if err := s.ContainerMgr.Resize(ctx, name, opts); err != nil { + return err + } + + rw.WriteHeader(http.StatusOK) + return nil } diff --git a/apis/server/router.go b/apis/server/router.go index b02db091a..d8c4baeb3 100644 --- a/apis/server/router.go +++ b/apis/server/router.go @@ -46,6 +46,7 @@ func initRoute(s *Server) http.Handler { r.Path(versionMatcher + "/containers/{name:.*}/upgrade").Methods(http.MethodPost).Handler(s.filter(s.upgradeContainer)) r.Path(versionMatcher + "/containers/{name:.*}/top").Methods(http.MethodGet).Handler(s.filter(s.topContainer)) r.Path(versionMatcher + "/containers/{name:.*}/logs").Methods(http.MethodGet).Handler(s.filter(s.logsContainer)) + r.Path(versionMatcher + "/containers/{name:.*}/resize").Methods(http.MethodPost).Handler(s.filter(s.resizeContainer)) // image r.Path(versionMatcher + "/images/create").Methods(http.MethodPost).Handler(s.filter(s.pullImage)) diff --git a/apis/swagger.yml b/apis/swagger.yml index 064530ed1..c4db36579 100644 --- a/apis/swagger.yml +++ b/apis/swagger.yml @@ -611,6 +611,29 @@ paths: default: "all" tags: ["Container"] + /containers/{id}/resize: + post: + summary: "changes the size of the tty for a container" + operationId: "ContainerResize" + parameters: + - $ref: "#/parameters/id" + - name: "height" + in: "query" + description: "height of the tty" + type: "string" + - name: "width" + in: "query" + description: "width of the tty" + type: "string" + responses: + 200: + description: "no error" + 400: + description: "bad parameter" + schema: + $ref: "#/definitions/Error" + tags: ["Container"] + /exec/{id}/start: post: summary: "Start an exec instance" @@ -3034,6 +3057,15 @@ definitions: additionalProperties: type: "string" + ResizeOptions: + description: "options of resizing container tty size" + type: "object" + properties: + Height: + type: "integer" + Width: + type: "integer" + parameters: id: name: id diff --git a/apis/types/resize_options.go b/apis/types/resize_options.go new file mode 100644 index 000000000..369e3bb27 --- /dev/null +++ b/apis/types/resize_options.go @@ -0,0 +1,57 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package types + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" +) + +// ResizeOptions options of resizing container tty size +// swagger:model ResizeOptions + +type ResizeOptions struct { + + // height + Height int64 `json:"Height,omitempty"` + + // width + Width int64 `json:"Width,omitempty"` +} + +/* polymorph ResizeOptions Height false */ + +/* polymorph ResizeOptions Width false */ + +// Validate validates this resize options +func (m *ResizeOptions) Validate(formats strfmt.Registry) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// MarshalBinary interface implementation +func (m *ResizeOptions) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *ResizeOptions) UnmarshalBinary(b []byte) error { + var res ResizeOptions + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/client/container.go b/client/container.go index 850b2af64..fe33047c2 100644 --- a/client/container.go +++ b/client/container.go @@ -6,6 +6,7 @@ import ( "io" "net" "net/url" + "strconv" "strings" "github.com/alibaba/pouch/apis/types" @@ -192,6 +193,7 @@ func (client *APIClient) ContainerUpdate(ctx context.Context, name string, confi // ContainerUpgrade upgrade a container with new image and args. func (client *APIClient) ContainerUpgrade(ctx context.Context, name string, config types.ContainerConfig, hostConfig *types.HostConfig) error { + // TODO return nil } @@ -252,3 +254,15 @@ func (client *APIClient) ContainerLogs(ctx context.Context, name string, options ensureCloseReader(resp) return resp.Body, nil } + +// ContainerResize resizes the size of container tty. +func (client *APIClient) ContainerResize(ctx context.Context, name string, opts types.ResizeOptions) error { + query := url.Values{} + query.Set("h", strconv.Itoa(int(opts.Height))) + query.Set("w", strconv.Itoa(int(opts.Width))) + + resp, err := client.post(ctx, "/containers/"+name+"/resize", query, nil, nil) + ensureCloseReader(resp) + + return err +} diff --git a/client/interface.go b/client/interface.go index 6f6f976ba..9fa8c07e1 100644 --- a/client/interface.go +++ b/client/interface.go @@ -37,6 +37,7 @@ type ContainerAPIClient interface { ContainerUpgrade(ctx context.Context, name string, config types.ContainerConfig, hostConfig *types.HostConfig) error ContainerTop(ctx context.Context, name string, arguments []string) (types.ContainerProcessList, error) ContainerLogs(ctx context.Context, name string, options types.ContainerLogsOptions) (io.ReadCloser, error) + ContainerResize(ctx context.Context, name string, options types.ResizeOptions) error } // ImageAPIClient defines methods of Image client. diff --git a/daemon/mgr/container.go b/daemon/mgr/container.go index 1dfadbf7e..b98b8291b 100644 --- a/daemon/mgr/container.go +++ b/daemon/mgr/container.go @@ -79,6 +79,9 @@ type ContainerMgr interface { // Top lists the processes running inside of the given container Top(ctx context.Context, name string, psArgs string) (*types.ContainerProcessList, error) + + // Resize resizes the size of container tty. + Resize(ctx context.Context, name string, opts types.ResizeOptions) error } // ContainerManager is the default implement of interface ContainerMgr. @@ -842,6 +845,12 @@ func (mgr *ContainerManager) Top(ctx context.Context, name string, psArgs string return procList, nil } +// Resize resizes the size of a container tty. +func (mgr *ContainerManager) Resize(ctx context.Context, name string, opts types.ResizeOptions) error { + // TODO + return nil +} + func (mgr *ContainerManager) openContainerIO(id string, attach *AttachConfig) (*containerio.IO, error) { return mgr.openIO(id, attach, false) } diff --git a/test/api_container_resize.go b/test/api_container_resize.go new file mode 100644 index 000000000..2699f0593 --- /dev/null +++ b/test/api_container_resize.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/alibaba/pouch/test/environment" + + "github.com/go-check/check" +) + +// APIContainerResizeSuite is the test suite for container upgrade API. +type APIContainerResizeSuite struct{} + +func init() { + check.Suite(&APIContainerResizeSuite{}) +} + +// SetUpTest does common setup in the beginning of each test. +func (suite *APIContainerResizeSuite) SetUpTest(c *check.C) { + SkipIfFalse(c, environment.IsLinux) + +} + +// TODO add test case.