Skip to content

Commit

Permalink
feature:add pouch rename
Browse files Browse the repository at this point in the history
  • Loading branch information
zeppp committed Dec 5, 2017
1 parent 432a53d commit 2677162
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 0 deletions.
12 changes: 12 additions & 0 deletions apis/server/container_bridge.go
Expand Up @@ -20,6 +20,18 @@ func (s *Server) removeContainers(ctx context.Context, resp http.ResponseWriter,
return nil
}

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

if err := s.ContainerMgr.Rename(ctx, id, name); err != nil {
return err
}

resp.WriteHeader(http.StatusNoContent)
return nil
}

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

Expand Down
1 change: 1 addition & 0 deletions apis/server/router.go
Expand Up @@ -33,6 +33,7 @@ func initRoute(s *Server) http.Handler {
r.Path("/containers/{name:.*}").Methods(http.MethodDelete).Handler(s.filter(s.removeContainers))
r.Path("/containers/{name:.*}/exec").Methods(http.MethodPost).Handler(s.filter(s.createContainerExec))
r.Path("/exec/{name:.*}/start").Methods(http.MethodPost).Handler(s.filter(s.startContainerExec))
r.Path("/containers/{name:.*}/rename").Methods(http.MethodPost).Handler(s.filter(s.renameContainer))

// image
r.Path("/images/create").Methods(http.MethodPost).Handler(s.filter(s.pullImage))
Expand Down
31 changes: 31 additions & 0 deletions apis/swagger.yml
Expand Up @@ -267,6 +267,37 @@ paths:
description: "Server error"
schema:
$ref: "#/definitions/Error"
/containers/{id}/rename:
post:
summary: "Rename a container"
operationId: "ContainerRename"
parameters:
- name: "id"
in: "path"
required: true
description: "ID or name of the container"
type: "string"
- name: "name"
in: "query"
required: true
description: "New name for the container"
type: "string"
responses:
204:
description: "no error"
404:
description: "no such container"
schema:
$ref: "#/definitions/Error"
409:
description: "name already in use"
schema:
$ref: "#/definitions/Error"
500:
description: "server error"
schema:
$ref: "#/definitions/Error"
tags: ["Container"]

/volumes:
get:
Expand Down
1 change: 1 addition & 0 deletions cli/main.go
Expand Up @@ -24,6 +24,7 @@ func main() {
cli.AddCommand(base, &ImageCommand{})
cli.AddCommand(base, &VolumeCommand{})
cli.AddCommand(base, &InspectCommand{})
cli.AddCommand(base, &RenameCommand{})

// add generate doc command
cli.AddCommand(base, &GenDocCommand{})
Expand Down
54 changes: 54 additions & 0 deletions cli/rename.go
@@ -0,0 +1,54 @@
package main

import (
"github.com/spf13/cobra"
)

// renameDescription is used to describe rename command in detail and auto generate command doc.
var renameDescription = "Rename a container object in Pouchd. " +
"You can change the name of one container identified by it's name or ID. " +
"The container you renamed is ready to be used by it's new name."

// RenameCommand uses to implement 'rename' command, it renames a container.
type RenameCommand struct {
baseCommand
}

// Init initialize rename command.
func (rc *RenameCommand) Init(c *Cli) {
rc.cli = c

rc.cmd = &cobra.Command{
Use: "rename [container] [newName]",
Short: "Rename a container with newName",
Long: renameDescription,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
return rc.runRename(args)
},
Example: renameExample(),
}
}

// runRename is the entry of rename command.
func (rc *RenameCommand) runRename(args []string) error {
apiClient := rc.cli.Client()
container := args[0]
newName := args[1]

err := apiClient.ContainerRename(container, newName)

return err
}

// renameExample shows examples in rename command, and is used in auto-generated cli docs.
func renameExample() string {
return `$ pouch ps
Name ID Status Image
foo 71b9c1 Running docker.io/library/busybox:latest
$ pouch rename foo newName
$ pouch ps
Name ID Status Image
newName 71b9c1 Running docker.io/library/busybox:latest
`
}
11 changes: 11 additions & 0 deletions client/container.go
Expand Up @@ -120,3 +120,14 @@ func (client *APIClient) ContainerGet(name string) (*types.ContainerJSON, error)

return &container, err
}

// ContainerRename renames a container.
func (client *APIClient) ContainerRename(id string, name string) error {
q := url.Values{}
q.Add("name", name)

resp, err := client.post("/containers/"+id+"/rename", q, nil)
ensureCloseReader(resp)

return err
}
29 changes: 29 additions & 0 deletions daemon/mgr/container.go
Expand Up @@ -49,6 +49,9 @@ type ContainerMgr interface {
// Remove removes a container, it may be running or stopped and so on.
Remove(ctx context.Context, name string, option *ContainerRemoveOption) error

// Rename renames a container
Rename(ctx context.Context, id string, name string) error

// Get the detailed information of container
Get(s string) (*types.ContainerInfo, error)
}
Expand Down Expand Up @@ -376,6 +379,32 @@ func (cm *ContainerManager) Get(s string) (*types.ContainerInfo, error) {
return cm.containerInfo(s)
}

// Rename renames a container
func (cm *ContainerManager) Rename(ctx context.Context, id string, name string) error {
var (
ci *types.ContainerInfo
err error
)

if cm.NameToID.Get(name).Exist() {
return httputils.NewHTTPError(errors.New("The newName already exists"), 409)
}

if ci, err = cm.containerInfo(id); err != nil {
return errors.Wrap(err, "failed to rename container")
}

cm.km.Lock(ci.ID)
defer cm.km.Unlock(ci.ID)

cm.NameToID.Remove(id)
cm.NameToID.Put(name, ci.ID)
ci.Name = name
cm.Store.Put(ci)

return nil
}

// containerInfo returns the 'ContainerInfo' object, the parameter 's' may be container's
// name, id or prefix id.
func (cm *ContainerManager) containerInfo(s string) (*types.ContainerInfo, error) {
Expand Down

0 comments on commit 2677162

Please sign in to comment.