Merge pull request #8570 from brahmaroutu/rename_container_3036

Rename a existing container
This commit is contained in:
Jessie Frazelle 2015-01-13 10:37:29 -08:00
commit b9e42d66e7
10 changed files with 275 additions and 2 deletions

View File

@ -818,6 +818,26 @@ func (cli *DockerCli) CmdPause(args ...string) error {
return encounteredError
}
func (cli *DockerCli) CmdRename(args ...string) error {
cmd := cli.Subcmd("rename", "OLD_NAME NEW_NAME", "Rename a container", true)
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() != 2 {
cmd.Usage()
return nil
}
old_name := cmd.Arg(0)
new_name := cmd.Arg(1)
if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/rename?name=%s", old_name, new_name), nil, false)); err != nil {
fmt.Fprintf(cli.err, "%s\n", err)
return fmt.Errorf("Error: failed to rename container named %s", old_name)
}
return nil
}
func (cli *DockerCli) CmdInspect(args ...string) error {
cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container or image", true)
tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template.")

View File

@ -739,6 +739,24 @@ func postContainersRestart(eng *engine.Engine, version version.Version, w http.R
return nil
}
func postContainerRename(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
if vars == nil {
return fmt.Errorf("Missing parameter")
}
newName := r.URL.Query().Get("name")
job := eng.Job("container_rename", vars["name"], newName)
job.Setenv("t", r.Form.Get("t"))
if err := job.Run(); err != nil {
return err
}
w.WriteHeader(http.StatusNoContent)
return nil
}
func deleteContainers(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
@ -1311,6 +1329,7 @@ func createRouter(eng *engine.Engine, logging, enableCors bool, dockerVersion st
"/containers/{name:.*}/exec": postContainerExecCreate,
"/exec/{name:.*}/start": postContainerExecStart,
"/exec/{name:.*}/resize": postContainerExecResize,
"/containers/{name:.*}/rename": postContainerRename,
},
"DELETE": {
"/containers/{name:.*}": deleteContainers,

View File

@ -113,6 +113,7 @@ func (daemon *Daemon) Install(eng *engine.Engine) error {
"commit": daemon.ContainerCommit,
"container_changes": daemon.ContainerChanges,
"container_copy": daemon.ContainerCopy,
"container_rename": daemon.ContainerRename,
"container_inspect": daemon.ContainerInspect,
"containers": daemon.Containers,
"create": daemon.ContainerCreate,

30
daemon/rename.go Normal file
View File

@ -0,0 +1,30 @@
package daemon
import (
"github.com/docker/docker/engine"
)
func (daemon *Daemon) ContainerRename(job *engine.Job) engine.Status {
if len(job.Args) != 2 {
return job.Errorf("usage: %s OLD_NAME NEW_NAME", job.Name)
}
old_name := job.Args[0]
new_name := job.Args[1]
container := daemon.Get(old_name)
if container == nil {
return job.Errorf("No such container: %s", old_name)
}
container.Lock()
defer container.Unlock()
if err := daemon.containerGraph.Delete(container.Name); err != nil {
return job.Errorf("Failed to delete container %q: %v", old_name, err)
}
if _, err := daemon.reserveName(container.ID, new_name); err != nil {
return job.Errorf("Error when allocating new name: %s", err)
}
container.Name = new_name
return engine.StatusOK
}

View File

@ -90,6 +90,7 @@ func init() {
{"ps", "List containers"},
{"pull", "Pull an image or a repository from a Docker registry server"},
{"push", "Push an image or a repository to a Docker registry server"},
{"rename", "Rename an existing container"},
{"restart", "Restart a running container"},
{"rm", "Remove one or more containers"},
{"rmi", "Remove one or more images"},

View File

@ -0,0 +1,13 @@
% DOCKER(1) Docker User Manuals
% Docker Community
% OCTOBER 2014
# NAME
docker-rename - Rename a container
# SYNOPSIS
**docker rename**
OLD_NAME NEW_NAME
# OPTIONS
There are no available options.

View File

@ -647,6 +647,27 @@ Status Codes:
- **404** no such container
- **500** server error
### Rename a container
`POST /containers/(id)/rename/(new_name)`
Rename the container `id` to a `new_name`
**Example request**:
POST /containers/e90e34656806/rename/new_name HTTP/1.1
**Example response**:
HTTP/1.1 204 No Content
Status Codes:
- **204** no error
- **404** no such container
- **409** - conflict name already assigned
- **500** server error
### Pause a container
`POST /containers/(id)/pause`

View File

@ -1366,6 +1366,30 @@ just a specific mapping:
$ sudo docker port test 7890
0.0.0.0:4321
## pause
Usage: docker pause CONTAINER
Pause all processes within a container
The `docker pause` command uses the cgroups freezer to suspend all processes in
a container. Traditionally when suspending a process the `SIGSTOP` signal is
used, which is observable by the process being suspended. With the cgroups freezer
the process is unaware, and unable to capture, that it is being suspended,
and subsequently resumed.
See the
[cgroups freezer documentation](https://www.kernel.org/doc/Documentation/cgroups/freezer-subsystem.txt)
for further details.
## rename
Usage: docker rename OLD_NAME NEW_NAME
rename a existing container to a NEW_NAME
The `docker rename` command allows the container to be renamed to a different name.
## ps
Usage: docker ps [OPTIONS]

View File

@ -1,6 +1,7 @@
package main
import (
"github.com/docker/docker/pkg/iptables"
"io/ioutil"
"os"
"os/exec"
@ -8,8 +9,6 @@ import (
"strings"
"testing"
"time"
"github.com/docker/docker/pkg/iptables"
)
func TestLinksEtcHostsRegularFile(t *testing.T) {
@ -76,6 +75,52 @@ func TestLinksPingLinkedContainers(t *testing.T) {
logDone("links - ping linked container")
}
func TestLinksPingLinkedContainersAfterRename(t *testing.T) {
out, _, _ := dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
idA := stripTrailingCharacters(out)
out, _, _ = dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10")
idB := stripTrailingCharacters(out)
dockerCmd(t, "rename", "container1", "container_new")
dockerCmd(t, "run", "--rm", "--link", "container_new:alias1", "--link", "container2:alias2", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1")
dockerCmd(t, "kill", idA)
dockerCmd(t, "kill", idB)
deleteAllContainers()
logDone("links - ping linked container after rename")
}
func TestLinksPingLinkedContainersOnRename(t *testing.T) {
var out string
out, _, _ = dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
idA := stripTrailingCharacters(out)
if idA == "" {
t.Fatal(out, "id should not be nil")
}
out, _, _ = dockerCmd(t, "run", "-d", "--link", "container1:alias1", "--name", "container2", "busybox", "sleep", "10")
idB := stripTrailingCharacters(out)
if idB == "" {
t.Fatal(out, "id should not be nil")
}
execCmd := exec.Command(dockerBinary, "exec", "container2", "ping", "-c", "1", "alias1", "-W", "1")
out, _, err := runCommandWithOutput(execCmd)
if err != nil {
t.Fatal(out, err)
}
dockerCmd(t, "rename", "container1", "container_new")
execCmd = exec.Command(dockerBinary, "exec", "container2", "ping", "-c", "1", "alias1", "-W", "1")
out, _, err = runCommandWithOutput(execCmd)
if err != nil {
t.Fatal(out, err)
}
deleteAllContainers()
logDone("links - ping linked container upon rename")
}
func TestLinksIpTablesRulesWhenLinkAndUnlink(t *testing.T) {
dockerCmd(t, "run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "sleep", "10")
dockerCmd(t, "run", "-d", "--name", "parent", "--link", "child:http", "busybox", "sleep", "10")

View File

@ -0,0 +1,99 @@
package main
import (
"os/exec"
"strings"
"testing"
)
func TestRenameStoppedContainer(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "--name", "first_name", "-d", "busybox", "sh")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "wait", cleanedContainerID)
out, _, err = runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf(out, err)
}
name, err := inspectField(cleanedContainerID, "Name")
runCmd = exec.Command(dockerBinary, "rename", "first_name", "new_name")
out, _, err = runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf(out, err)
}
name, err = inspectField(cleanedContainerID, "Name")
if err != nil {
t.Fatal(err)
}
if name != "new_name" {
t.Fatal("Failed to rename container ", name)
}
deleteAllContainers()
logDone("rename - stopped container")
}
func TestRenameRunningContainer(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "--name", "first_name", "-d", "busybox", "sh")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf(out, err)
}
cleanedContainerID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "rename", "first_name", "new_name")
out, _, err = runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf(out, err)
}
name, err := inspectField(cleanedContainerID, "Name")
if err != nil {
t.Fatal(err)
}
if name != "new_name" {
t.Fatal("Failed to rename container ")
}
deleteAllContainers()
logDone("rename - running container")
}
func TestRenameCheckNames(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "--name", "first_name", "-d", "busybox", "sh")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf(out, err)
}
runCmd = exec.Command(dockerBinary, "rename", "first_name", "new_name")
out, _, err = runCommandWithOutput(runCmd)
if err != nil {
t.Fatalf(out, err)
}
name, err := inspectField("new_name", "Name")
if err != nil {
t.Fatal(err)
}
if name != "new_name" {
t.Fatal("Failed to rename container ")
}
name, err = inspectField("first_name", "Name")
if err == nil && !strings.Contains(err.Error(), "No such image or container: first_name") {
t.Fatal(err)
}
deleteAllContainers()
logDone("rename - running container")
}