Skip to content

Commit

Permalink
feature: add pouch cp cmd
Browse files Browse the repository at this point in the history
Signed-off-by: zhangyue <zy675793960@yeah.net>
  • Loading branch information
zhangyue authored and allencloud committed Jun 3, 2019
1 parent a8fc483 commit 777292a
Show file tree
Hide file tree
Showing 16 changed files with 1,269 additions and 16 deletions.
91 changes: 91 additions & 0 deletions apis/server/copy_bridge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package server

import (
"context"
"encoding/base64"
"encoding/json"
"errors"
"io"
"net/http"

"github.com/alibaba/pouch/pkg/httputils"

"github.com/gorilla/mux"
)

func (s *Server) putContainersArchive(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
name := mux.Vars(req)["name"]
path := req.FormValue("path")

if name == "" {
return httputils.NewHTTPError(errors.New("name can't be empty"), http.StatusBadRequest)
}
if path == "" {
return httputils.NewHTTPError(errors.New("path can't be empty"), http.StatusBadRequest)
}
noOverwriteDirNonDir := httputils.BoolValue(req, "noOverwriteDirNonDir")
copyUIDGID := httputils.BoolValue(req, "copyUIDGID")

return s.ContainerMgr.ExtractToDir(ctx, name, path, copyUIDGID, noOverwriteDirNonDir, req.Body)
}

func (s *Server) headContainersArchive(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
name := mux.Vars(req)["name"]
path := req.FormValue("path")

if name == "" {
return httputils.NewHTTPError(errors.New("name can't be empty"), http.StatusBadRequest)
}
if path == "" {
return httputils.NewHTTPError(errors.New("path can't be empty"), http.StatusBadRequest)
}

stat, err := s.ContainerMgr.StatPath(ctx, name, path)
if err != nil {
return err
}

statJSON, err := json.Marshal(stat)
if err != nil {
return err
}

rw.Header().Set(
"X-Docker-Container-Path-Stat",
base64.StdEncoding.EncodeToString(statJSON),
)

return nil
}

func (s *Server) getContainersArchive(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
name := mux.Vars(req)["name"]
path := req.FormValue("path")

if name == "" {
return httputils.NewHTTPError(errors.New("name can't be empty"), http.StatusBadRequest)
}
if path == "" {
return httputils.NewHTTPError(errors.New("path can't be empty"), http.StatusBadRequest)
}

tarArchive, stat, err := s.ContainerMgr.ArchivePath(ctx, name, path)
if err != nil {
return err
}
defer tarArchive.Close()

statJSON, err := json.Marshal(stat)
if err != nil {
return err
}
rw.Header().Set(
"X-Docker-Container-Path-Stat",
base64.StdEncoding.EncodeToString(statJSON),
)

rw.Header().Set("Content-Type", "application/x-tar")
_, err = io.Copy(rw, tarArchive)

return err
}
5 changes: 5 additions & 0 deletions apis/server/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ func initRoute(s *Server) *mux.Router {
{Method: http.MethodPost, Path: "/attach/{token}", HandlerFunc: s.criAttach},
{Method: http.MethodGet, Path: "/portforward/{token}", HandlerFunc: s.criPortForward},
{Method: http.MethodPost, Path: "/portforward/{token}", HandlerFunc: s.criPortForward},

// copy
{Method: http.MethodPut, Path: "/containers/{name:.*}/archive", HandlerFunc: s.putContainersArchive},
{Method: http.MethodHead, Path: "/containers/{name:.*}/archive", HandlerFunc: s.headContainersArchive},
{Method: http.MethodGet, Path: "/containers/{name:.*}/archive", HandlerFunc: s.getContainersArchive},
}

if s.APIPlugin != nil {
Expand Down
153 changes: 153 additions & 0 deletions apis/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,134 @@ paths:
schema:
$ref: "#/definitions/ContainerCommitOptions"

/containers/{id}/archive:
head:
summary: "Get information about files in a container"
description: "A response header `X-Docker-Container-Path-Stat` is return containing a base64 - encoded JSON object with some filesystem header information about the path."
operationId: "ContainerArchiveInfo"
responses:
200:
description: "no error"
headers:
X-Docker-Container-Path-Stat:
type: "string"
description: "A base64 - encoded JSON object with some filesystem header information about the path"
400:
description: "Bad parameter"
schema:
$ref: "#/responses/400ErrorResponse"
404:
description: "Container or path does not exist"
schema:
$ref: "#/responses/404ErrorResponse"
examples:
application/json:
message: "No such container: c2ada9df5af8"
500:
description: "Server error"
schema:
$ref: "#/responses/500ErrorResponse"
parameters:
- name: "id"
in: "path"
required: true
description: "ID or name of the container"
type: "string"
- name: "path"
in: "query"
required: true
description: "Resource in the container’s filesystem to archive."
type: "string"
tags: ["Copy"]
get:
summary: "Get an archive of a filesystem resource in a container"
description: "Get a tar archive of a resource in the filesystem of container id."
operationId: "ContainerArchive"
produces: ["application/x-tar"]
responses:
200:
description: "no error"
400:
description: "Bad parameter"
schema:
$ref: "#/responses/400ErrorResponse"
404:
description: "Container or path does not exist"
schema:
$ref: "#/responses/404ErrorResponse"
examples:
application/json:
message: "No such container: c2ada9df5af8"
500:
description: "server error"
schema:
$ref: "#/responses/500ErrorResponse"
parameters:
- name: "id"
in: "path"
required: true
description: "ID or name of the container"
type: "string"
- name: "path"
in: "query"
required: true
description: "Resource in the container’s filesystem to archive."
type: "string"
tags: ["Copy"]
put:
summary: "Extract an archive of files or folders to a directory in a container"
description: "Upload a tar archive to be extracted to a path in the filesystem of container id."
operationId: "PutContainerArchive"
consumes: ["application/x-tar", "application/octet-stream"]
responses:
200:
description: "The content was extracted successfully"
400:
description: "Bad parameter"
schema:
$ref: "#/responses/400ErrorResponse"
403:
description: "Permission denied, the volume or container rootfs is marked as read-only."
schema:
$ref: "#/responses/403ErrorResponse"
404:
description: "No such container or path does not exist inside the container"
schema:
$ref: "#/responses/404ErrorResponse"
examples:
application/json:
message: "No such container: c2ada9df5af8"
500:
description: "Server error"
schema:
$ref: "#/responses/500ErrorResponse"
parameters:
- name: "id"
in: "path"
required: true
description: "ID or name of the container"
type: "string"
- name: "path"
in: "query"
required: true
description: "Path to a directory in the container to extract the archive’s contents into. "
type: "string"
- name: "noOverwriteDirNonDir"
in: "query"
description: "If “1”, “true”, or “True” then it will be an error if unpacking the given content would cause an existing directory to be replaced with a non-directory and vice versa."
type: "string"
- name: "copyUIDGID"
in: "query"
description: "If “1”, “true”, or “True” then it will copy UID/GID maps to dest file."
type: "string"
- name: "inputStream"
in: "body"
required: true
description: "The input stream must be a tar archive compressed with one of the following algorithms: identity (no compression), gzip, bzip2, xz."
schema:
type: "string"
tags: ["Copy"]

definitions:
Error:
type: "object"
Expand Down Expand Up @@ -4389,6 +4517,23 @@ definitions:
type: "string"
description: "ID uniquely identifies an image committed by a container"

ContainerPathStat:
description: "ContainerPathStat is used to describe the stat of file"
type: "object"
properties:
name:
type: "string"
size:
type: "string"
mode:
type: "integer"
format: "uint32"
mtime:
description: "modification time."
type: "string"
format: date-time
path:
type: "string"

parameters:
id:
Expand All @@ -4405,10 +4550,18 @@ parameters:
type: string

responses:
400ErrorResponse:
description: An unexpected 400 error occurred.
schema:
$ref: "#/definitions/Error"
401ErrorResponse:
description: An unexpected 401 error occurred.
schema:
$ref: "#/definitions/Error"
403ErrorResponse:
description: An unexpected 403 error occurred.
schema:
$ref: "#/definitions/Error"
404ErrorResponse:
description: An unexpected 404 error occurred.
schema:
Expand Down
79 changes: 79 additions & 0 deletions apis/types/container_path_stat.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 777292a

Please sign in to comment.