mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
rename a existing container
Closes #3036 Signed-off-by: Srini Brahmaroutu <srbrahma@us.ibm.com>
This commit is contained in:
parent
9b0072a7e6
commit
21a809d9ae
10 changed files with 275 additions and 2 deletions
|
@ -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.")
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
30
daemon/rename.go
Normal 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
|
||||
}
|
|
@ -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"},
|
||||
|
|
13
docs/man/docker-rename.1.md
Normal file
13
docs/man/docker-rename.1.md
Normal 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.
|
||||
|
|
@ -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`
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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")
|
||||
|
|
99
integration-cli/docker_cli_rename_test.go
Normal file
99
integration-cli/docker_cli_rename_test.go
Normal 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")
|
||||
}
|
Loading…
Reference in a new issue