mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
commit
23b3747945
7 changed files with 103 additions and 146 deletions
|
@ -187,9 +187,6 @@ func (b *buildFile) CmdCmd(args string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *buildFile) CmdExpose(args string) error {
|
func (b *buildFile) CmdExpose(args string) error {
|
||||||
if strings.Contains(args, ":") {
|
|
||||||
return fmt.Errorf("EXPOSE cannot be used to bind to a host ip or port")
|
|
||||||
}
|
|
||||||
ports := strings.Split(args, " ")
|
ports := strings.Split(args, " ")
|
||||||
b.config.PortSpecs = append(ports, b.config.PortSpecs...)
|
b.config.PortSpecs = append(ports, b.config.PortSpecs...)
|
||||||
return b.commit("", b.config.Cmd, fmt.Sprintf("EXPOSE %v", ports))
|
return b.commit("", b.config.Cmd, fmt.Sprintf("EXPOSE %v", ports))
|
||||||
|
@ -433,10 +430,13 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
container, _, err := b.runtime.Create(b.config, "")
|
container, warnings, err := b.runtime.Create(b.config, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for _, warning := range warnings {
|
||||||
|
fmt.Fprintf(b.out, " ---> [Warning] %s\n", warning)
|
||||||
|
}
|
||||||
b.tmpContainers[container.ID] = struct{}{}
|
b.tmpContainers[container.ID] = struct{}{}
|
||||||
fmt.Fprintf(b.out, " ---> Running in %s\n", utils.TruncateID(container.ID))
|
fmt.Fprintf(b.out, " ---> Running in %s\n", utils.TruncateID(container.ID))
|
||||||
id = container.ID
|
id = container.ID
|
||||||
|
|
|
@ -14,12 +14,16 @@ Building a redis container to link as a child of our web application.
|
||||||
Building the redis container
|
Building the redis container
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
We will use a pre-build version of redis from the index under
|
Lets build a redis image with the following Dockerfile.
|
||||||
the name ``crosbymichael/redis``. If you are interested in the
|
|
||||||
Dockerfile that was used to build this container here it is.
|
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
git clone https://github.com/antirez/redis.git
|
||||||
|
cd redis
|
||||||
|
git checkout 2.6
|
||||||
|
|
||||||
|
# Save this Dockerfile to the root of the redis repository.
|
||||||
|
|
||||||
# Build redis from source
|
# Build redis from source
|
||||||
# Make sure you have the redis source code checked out in
|
# Make sure you have the redis source code checked out in
|
||||||
# the same directory as this Dockerfile
|
# the same directory as this Dockerfile
|
||||||
|
@ -34,7 +38,6 @@ Dockerfile that was used to build this container here it is.
|
||||||
ADD . /redis
|
ADD . /redis
|
||||||
|
|
||||||
RUN (cd /redis && make)
|
RUN (cd /redis && make)
|
||||||
RUN (cd /redis && make test)
|
|
||||||
|
|
||||||
RUN mkdir -p /redis-data
|
RUN mkdir -p /redis-data
|
||||||
VOLUME ["/redis-data"]
|
VOLUME ["/redis-data"]
|
||||||
|
@ -43,6 +46,9 @@ Dockerfile that was used to build this container here it is.
|
||||||
ENTRYPOINT ["/redis/src/redis-server"]
|
ENTRYPOINT ["/redis/src/redis-server"]
|
||||||
CMD ["--dir", "/redis-data"]
|
CMD ["--dir", "/redis-data"]
|
||||||
|
|
||||||
|
# docker build our new redis image from source
|
||||||
|
docker build -t redis-2.6 .
|
||||||
|
|
||||||
|
|
||||||
We need to ``EXPOSE`` the default port of 6379 so that our link knows what ports
|
We need to ``EXPOSE`` the default port of 6379 so that our link knows what ports
|
||||||
to connect to our redis container on. If you do not expose any ports for the
|
to connect to our redis container on. If you do not expose any ports for the
|
||||||
|
@ -54,31 +60,28 @@ Run the redis container
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
docker run -d -e PASSWORD=docker -name redis crosbymichael/redis --requirepass=docker
|
docker run -d -e PASSWORD=docker -name redis redis-2.6 --requirepass docker
|
||||||
|
|
||||||
This will run our redis container using the default port of 6379 and using docker
|
This will run our redis container wit the password docker
|
||||||
as password to secure our service. By specifying the ``-name`` flag on run
|
to secure our service. By specifying the ``-name`` flag on run
|
||||||
we will assign the name ``redis`` to this container.
|
we will assign the name ``redis`` to this container. If we do not specify a name for
|
||||||
We can issue all the commands that you would expect; start, stop, attach, using the name.
|
our container via the ``-name`` flag docker will automatically generate a name for us.
|
||||||
The name also allows us to link other containers into this one. If you do not specify a
|
We can issue all the commands that you would expect; start, stop, attach, using the name for our container.
|
||||||
name on docker run, docker will automatically generate a name for your container.
|
The name also allows us to link other containers into this one.
|
||||||
|
|
||||||
Linking redis as a child
|
Linking redis as a child
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
Next we can start a new web application that has a dependency on redis and apply a link
|
Next we can start a new web application that has a dependency on redis and apply a link
|
||||||
to connect both containers. If you noticed when running our redis service we did not use
|
to connect both containers. If you noticed when running our redis server we did not use
|
||||||
the ``-p`` option to publish the redis port to the host system. Redis exposed port 6379
|
the ``-p`` flag to publish the redis port to the host system. Redis exposed port 6379 via the Dockerfile
|
||||||
but we did not publish the port. This allows docker to prevent all network traffic to
|
and this is all we need to establish a link.
|
||||||
the redis container except when explicitly specified within a link. This is a big win
|
|
||||||
for security.
|
|
||||||
|
|
||||||
|
|
||||||
Now lets start our web application with a link into redis.
|
Now lets start our web application with a link into redis.
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
docker run -t -i -link /redis:db -name webapp ubuntu bash
|
docker run -t -i -link redis:db -name webapp ubuntu bash
|
||||||
|
|
||||||
root@4c01db0b339c:/# env
|
root@4c01db0b339c:/# env
|
||||||
|
|
||||||
|
@ -101,22 +104,25 @@ Now lets start our web application with a link into redis.
|
||||||
|
|
||||||
|
|
||||||
When we inspect the environment of the linked container we can see a few extra environment
|
When we inspect the environment of the linked container we can see a few extra environment
|
||||||
variables have been added. When you specified ``-link /redis:db`` you are telling docker
|
variables have been added. When you specified ``-link redis:db`` you are telling docker
|
||||||
to link the container named ``/redis`` into this new container with the alias ``db``.
|
to link the container named ``redis`` into this new container with the alias ``db``.
|
||||||
Environment variables are prefixed with the alias so that the parent container can access
|
Environment variables are prefixed with the alias so that the parent container can access
|
||||||
network and environment information from the child.
|
network and environment information from the containers that are linked into it.
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
# The name of the child container
|
# The name of the child container
|
||||||
DB_NAME=/webapp/db
|
DB_NAME=/webapp/db
|
||||||
|
|
||||||
# The default protocol, ip, and port of the service running in the container
|
# The default protocol, ip, and port of the service running in the container
|
||||||
DB_PORT=tcp://172.17.0.8:6379
|
DB_PORT=tcp://172.17.0.8:6379
|
||||||
|
|
||||||
# A specific protocol, ip, and port of various services
|
# A specific protocol, ip, and port of various services
|
||||||
DB_PORT_6379_TCP=tcp://172.17.0.8:6379
|
DB_PORT_6379_TCP=tcp://172.17.0.8:6379
|
||||||
DB_PORT_6379_TCP_PROTO=tcp
|
DB_PORT_6379_TCP_PROTO=tcp
|
||||||
DB_PORT_6379_TCP_ADDR=172.17.0.8
|
DB_PORT_6379_TCP_ADDR=172.17.0.8
|
||||||
DB_PORT_6379_TCP_PORT=6379
|
DB_PORT_6379_TCP_PORT=6379
|
||||||
|
|
||||||
# Get environment variables of the container
|
# Get environment variables of the container
|
||||||
DB_ENV_PASSWORD=dockerpass
|
DB_ENV_PASSWORD=dockerpass
|
||||||
|
|
||||||
|
|
|
@ -13,113 +13,47 @@ You can use your Docker containers with process managers like ``upstart``,
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
If you want a process manager to manage your containers you will need to run
|
||||||
|
the docker daemon with the ``-r=false`` so that docker will not automatically
|
||||||
|
restart your containers when the host is restarted.
|
||||||
|
|
||||||
When you have finished setting up your image and are happy with your
|
When you have finished setting up your image and are happy with your
|
||||||
running container, you may want to use a process manager to manage
|
running container, you may want to use a process manager to manage
|
||||||
it. To help with this, we provide a simple image: ``creack/manager:min``
|
it. When your run ``docker start -a`` docker will automatically attach
|
||||||
|
to the process and forward all signals so that the process manager can
|
||||||
|
detect when a container stops and correctly restart it.
|
||||||
|
|
||||||
This image takes the container ID as parameter. We also can specify
|
Here are a few sample scripts for systemd and upstart to integrate with docker.
|
||||||
the kind of process manager and metadata like *Author* and
|
|
||||||
*Description*. The output will will be text suitable for a
|
|
||||||
configuration file, echoed to stdout. It is up to you to create the
|
|
||||||
.conf file (for `upstart
|
|
||||||
<http://upstart.ubuntu.com/cookbook/#job-configuration-file>`_) or
|
|
||||||
.service file (for `systemd
|
|
||||||
<http://0pointer.de/public/systemd-man/systemd.service.html>`_) and
|
|
||||||
put it in the right place for your system.
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
Sample Upstart Script
|
||||||
|
---------------------
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
docker run creack/manager:min [OPTIONS] <container id>
|
description "Redis container"
|
||||||
|
author "Me"
|
||||||
|
start on filesystem and started lxc-net and started docker
|
||||||
|
stop on runlevel [!2345]
|
||||||
|
respawn
|
||||||
|
exec docker start -a 0a7e070b698b
|
||||||
|
|
||||||
.. program:: docker run creack/manager:min
|
|
||||||
|
|
||||||
.. cmdoption:: -a="<none>"
|
Sample systemd Script
|
||||||
|
---------------------
|
||||||
Author of the image
|
|
||||||
|
|
||||||
.. cmdoption:: -d="<none>"
|
|
||||||
|
|
||||||
Description of the image
|
|
||||||
|
|
||||||
.. cmdoption:: -t="upstart"
|
|
||||||
|
|
||||||
Type of manager requested: ``upstart`` or ``systemd``
|
|
||||||
|
|
||||||
Example Output
|
|
||||||
..............
|
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
docker run creack/manager:min -t="systemd" b28605f2f9a4
|
[Unit]
|
||||||
[Unit]
|
Description=Redis container
|
||||||
Description=<none>
|
Author=Me
|
||||||
Author=<none>
|
After=docker.service
|
||||||
After=docker.service
|
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Restart=always
|
Restart=always
|
||||||
ExecStart=/usr/bin/docker start -a b28605f2f9a4
|
ExecStart=/usr/bin/docker start -a 0a7e070b698b
|
||||||
ExecStop=/usr/bin/docker stop -t 2 b28605f2f9a4
|
ExecStop=/usr/bin/docker stop -t 2 0a7e070b698b
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=local.target
|
WantedBy=local.target
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Development
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The image ``creack/manager:min`` is a ``busybox`` base with the
|
|
||||||
compiled binary of ``manager.go`` as the :ref:`Entrypoint
|
|
||||||
<entrypoint_def>`. It is meant to be light and fast to download.
|
|
||||||
|
|
||||||
If you would like to change or add things, you can download the full
|
|
||||||
``creack/manager`` repository that contains ``creack/manager:min`` and
|
|
||||||
``creack/manager:dev``.
|
|
||||||
|
|
||||||
The Dockerfiles and the sources are available in
|
|
||||||
`/contrib/host_integration
|
|
||||||
<https://github.com/dotcloud/docker/tree/master/contrib/host_integration>`_.
|
|
||||||
|
|
||||||
|
|
||||||
Upstart
|
|
||||||
-------
|
|
||||||
|
|
||||||
Upstart is the default process manager. The generated script will
|
|
||||||
start the container after the ``docker`` daemon. If the container
|
|
||||||
dies, it will respawn. Start/Restart/Stop/Reload are
|
|
||||||
supported. Reload will send a SIGHUP to the container.
|
|
||||||
|
|
||||||
Example (``upstart`` on Debian)
|
|
||||||
...............................
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
CID=$(docker run -d creack/firefo-vnc)
|
|
||||||
docker run creack/manager:min -a 'Guillaume J. Charmes <guillaume@dotcloud.com>' -d 'Awesome Firefox in VLC' $CID > /etc/init/firefoxvnc.conf
|
|
||||||
|
|
||||||
You can now ``start firefoxvnc`` or ``stop firefoxvnc`` and if the container
|
|
||||||
dies for some reason, upstart will restart it.
|
|
||||||
|
|
||||||
Systemd
|
|
||||||
-------
|
|
||||||
|
|
||||||
In order to generate a systemd script, we need to use the ``-t``
|
|
||||||
option. The generated script will start the container after docker
|
|
||||||
daemon. If the container dies, it will respawn.
|
|
||||||
``Start/Restart/Reload/Stop`` are supported.
|
|
||||||
|
|
||||||
Example (``systemd`` on Fedora)
|
|
||||||
...............................
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
CID=$(docker run -d creack/firefo-vnc)
|
|
||||||
docker run creack/manager:min -t systemd -a 'Guillaume J. Charmes <guillaume@dotcloud.com>' -d 'Awesome Firefox in VLC' $CID > /usr/lib/systemd/system/firefoxvnc.service
|
|
||||||
|
|
||||||
You can now run ``systemctl start firefoxvnc`` or ``systemctl stop
|
|
||||||
firefoxvnc`` and if the container dies for some reason, ``systemd``
|
|
||||||
will restart it.
|
|
||||||
|
|
2
links.go
2
links.go
|
@ -22,7 +22,7 @@ func NewLink(parent, child *Container, name, bridgeInterface string) (*Link, err
|
||||||
return nil, fmt.Errorf("Cannot link to self: %s == %s", parent.ID, child.ID)
|
return nil, fmt.Errorf("Cannot link to self: %s == %s", parent.ID, child.ID)
|
||||||
}
|
}
|
||||||
if !child.State.Running {
|
if !child.State.Running {
|
||||||
return nil, fmt.Errorf("Cannot link to a non running container: %s AS %s", child.ID, name)
|
return nil, fmt.Errorf("Cannot link to a non running container: %s AS %s", child.Name, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
ports := make([]Port, len(child.Config.ExposedPorts))
|
ports := make([]Port, len(child.Config.ExposedPorts))
|
||||||
|
|
23
runtime.go
23
runtime.go
|
@ -317,22 +317,20 @@ func (runtime *Runtime) Create(config *Config, name string) (*Container, []strin
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
warnings := []string{}
|
|
||||||
if img.Config != nil {
|
if img.Config != nil {
|
||||||
if img.Config.PortSpecs != nil && warnings != nil {
|
|
||||||
for _, p := range img.Config.PortSpecs {
|
|
||||||
if strings.Contains(p, ":") {
|
|
||||||
warnings = append(warnings, "This image expects private ports to be mapped to public ports on your host. "+
|
|
||||||
"This has been deprecated and the public mappings will not be honored."+
|
|
||||||
"Use -p to publish the ports.")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := MergeConfig(config, img.Config); err != nil {
|
if err := MergeConfig(config, img.Config); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
warnings := []string{}
|
||||||
|
if config.PortSpecs != nil {
|
||||||
|
for _, p := range config.PortSpecs {
|
||||||
|
if strings.Contains(p, ":") {
|
||||||
|
warnings = append(warnings, "The mapping to public ports on your host has been deprecated. Use -p to publish the ports.")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(config.Entrypoint) != 0 && config.Cmd == nil {
|
if len(config.Entrypoint) != 0 && config.Cmd == nil {
|
||||||
config.Cmd = []string{}
|
config.Cmd = []string{}
|
||||||
|
@ -357,6 +355,9 @@ func (runtime *Runtime) Create(config *Config, name string) (*Container, []strin
|
||||||
|
|
||||||
// Set the enitity in the graph using the default name specified
|
// Set the enitity in the graph using the default name specified
|
||||||
if _, err := runtime.containerGraph.Set(name, id); err != nil {
|
if _, err := runtime.containerGraph.Set(name, id); err != nil {
|
||||||
|
if strings.HasSuffix(err.Error(), "name are not unique") {
|
||||||
|
return nil, nil, fmt.Errorf("Conflict, %s already exists.", name)
|
||||||
|
}
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,6 +260,21 @@ func TestRuntimeCreate(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test expose 80:8000
|
||||||
|
container, warnings, err := runtime.Create(&Config{
|
||||||
|
Image: GetTestImage(runtime).ID,
|
||||||
|
Cmd: []string{"ls", "-al"},
|
||||||
|
PortSpecs: []string{"80:8000"},
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if warnings == nil || len(warnings) != 1 {
|
||||||
|
t.Error("Expected a warning, got none")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDestroy(t *testing.T) {
|
func TestDestroy(t *testing.T) {
|
||||||
|
|
27
server.go
27
server.go
|
@ -84,13 +84,13 @@ func (srv *Server) ContainerKill(name string, sig int) error {
|
||||||
// If no signal is passed, perform regular Kill (SIGKILL + wait())
|
// If no signal is passed, perform regular Kill (SIGKILL + wait())
|
||||||
if sig == 0 {
|
if sig == 0 {
|
||||||
if err := container.Kill(); err != nil {
|
if err := container.Kill(); err != nil {
|
||||||
return fmt.Errorf("Error killing container %s: %s", name, err)
|
return fmt.Errorf("Cannot kill container %s: %s", name, err)
|
||||||
}
|
}
|
||||||
srv.LogEvent("kill", container.ShortID(), srv.runtime.repositories.ImageName(container.Image))
|
srv.LogEvent("kill", container.ShortID(), srv.runtime.repositories.ImageName(container.Image))
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, just send the requested signal
|
// Otherwise, just send the requested signal
|
||||||
if err := container.kill(sig); err != nil {
|
if err := container.kill(sig); err != nil {
|
||||||
return fmt.Errorf("Error killing container %s: %s", name, err)
|
return fmt.Errorf("Cannot kill container %s: %s", name, err)
|
||||||
}
|
}
|
||||||
// FIXME: Add event for signals
|
// FIXME: Add event for signals
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ func (srv *Server) ImagesViz(out io.Writer) error {
|
||||||
for _, image := range images {
|
for _, image := range images {
|
||||||
parentImage, err = image.GetParent()
|
parentImage, err = image.GetParent()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error while getting parent image: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
if parentImage != nil {
|
if parentImage != nil {
|
||||||
out.Write([]byte(" \"" + parentImage.ShortID() + "\" -> \"" + image.ShortID() + "\"\n"))
|
out.Write([]byte(" \"" + parentImage.ShortID() + "\" -> \"" + image.ShortID() + "\"\n"))
|
||||||
|
@ -335,7 +335,7 @@ func (srv *Server) ContainerTop(name, ps_args string) (*APITop, error) {
|
||||||
if container := srv.runtime.Get(name); container != nil {
|
if container := srv.runtime.Get(name); container != nil {
|
||||||
output, err := exec.Command("lxc-ps", "--name", container.ID, "--", ps_args).CombinedOutput()
|
output, err := exec.Command("lxc-ps", "--name", container.ID, "--", ps_args).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error trying to use lxc-ps: %s (%s)", err, output)
|
return nil, fmt.Errorf("lxc-ps: %s (%s)", err, output)
|
||||||
}
|
}
|
||||||
procs := APITop{}
|
procs := APITop{}
|
||||||
for i, line := range strings.Split(string(output), "\n") {
|
for i, line := range strings.Split(string(output), "\n") {
|
||||||
|
@ -346,7 +346,7 @@ func (srv *Server) ContainerTop(name, ps_args string) (*APITop, error) {
|
||||||
scanner := bufio.NewScanner(strings.NewReader(line))
|
scanner := bufio.NewScanner(strings.NewReader(line))
|
||||||
scanner.Split(bufio.ScanWords)
|
scanner.Split(bufio.ScanWords)
|
||||||
if !scanner.Scan() {
|
if !scanner.Scan() {
|
||||||
return nil, fmt.Errorf("Error trying to use lxc-ps")
|
return nil, fmt.Errorf("Wrong output using lxc-ps")
|
||||||
}
|
}
|
||||||
// no scanner.Text because we skip container id
|
// no scanner.Text because we skip container id
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
|
@ -819,7 +819,7 @@ func (srv *Server) pushImage(r *registry.Registry, out io.Writer, remote, imgID,
|
||||||
out = utils.NewWriteFlusher(out)
|
out = utils.NewWriteFlusher(out)
|
||||||
jsonRaw, err := ioutil.ReadFile(path.Join(srv.runtime.graph.Root, imgID, "json"))
|
jsonRaw, err := ioutil.ReadFile(path.Join(srv.runtime.graph.Root, imgID, "json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Error while retrieving the path for {%s}: %s", imgID, err)
|
return "", fmt.Errorf("Cannot retrieve the path for {%s}: %s", imgID, err)
|
||||||
}
|
}
|
||||||
out.Write(sf.FormatStatus("", "Pushing %s", imgID))
|
out.Write(sf.FormatStatus("", "Pushing %s", imgID))
|
||||||
|
|
||||||
|
@ -969,7 +969,7 @@ func (srv *Server) ContainerCreate(config *Config, name string) (string, []strin
|
||||||
func (srv *Server) ContainerRestart(name string, t int) error {
|
func (srv *Server) ContainerRestart(name string, t int) error {
|
||||||
if container := srv.runtime.Get(name); container != nil {
|
if container := srv.runtime.Get(name); container != nil {
|
||||||
if err := container.Restart(t); err != nil {
|
if err := container.Restart(t); err != nil {
|
||||||
return fmt.Errorf("Error restarting container %s: %s", name, err)
|
return fmt.Errorf("Cannot restart container %s: %s", name, err)
|
||||||
}
|
}
|
||||||
srv.LogEvent("restart", container.ShortID(), srv.runtime.repositories.ImageName(container.Image))
|
srv.LogEvent("restart", container.ShortID(), srv.runtime.repositories.ImageName(container.Image))
|
||||||
} else {
|
} else {
|
||||||
|
@ -986,9 +986,10 @@ func (srv *Server) ContainerDestroy(name string, removeVolume, removeLink bool)
|
||||||
return fmt.Errorf("No such link: %s", name)
|
return fmt.Errorf("No such link: %s", name)
|
||||||
}
|
}
|
||||||
name = srv.runtime.getFullName(name)
|
name = srv.runtime.getFullName(name)
|
||||||
|
|
||||||
parent, n := path.Split(name)
|
parent, n := path.Split(name)
|
||||||
|
if parent == "/" {
|
||||||
|
return fmt.Errorf("Conflict, cannot remove the default name of the container")
|
||||||
|
}
|
||||||
pe := srv.runtime.containerGraph.Get(parent)
|
pe := srv.runtime.containerGraph.Get(parent)
|
||||||
if pe == nil {
|
if pe == nil {
|
||||||
return fmt.Errorf("Cannot get parent %s for name %s", parent, name)
|
return fmt.Errorf("Cannot get parent %s for name %s", parent, name)
|
||||||
|
@ -1021,7 +1022,7 @@ func (srv *Server) ContainerDestroy(name string, removeVolume, removeLink bool)
|
||||||
volumes[volumeId] = struct{}{}
|
volumes[volumeId] = struct{}{}
|
||||||
}
|
}
|
||||||
if err := srv.runtime.Destroy(container); err != nil {
|
if err := srv.runtime.Destroy(container); err != nil {
|
||||||
return fmt.Errorf("Error destroying container %s: %s", name, err)
|
return fmt.Errorf("Cannot destroy container %s: %s", name, err)
|
||||||
}
|
}
|
||||||
srv.LogEvent("destroy", container.ShortID(), srv.runtime.repositories.ImageName(container.Image))
|
srv.LogEvent("destroy", container.ShortID(), srv.runtime.repositories.ImageName(container.Image))
|
||||||
|
|
||||||
|
@ -1165,7 +1166,7 @@ func (srv *Server) ImageDelete(name string, autoPrune bool) ([]APIRmi, error) {
|
||||||
}
|
}
|
||||||
if !autoPrune {
|
if !autoPrune {
|
||||||
if err := srv.runtime.graph.Delete(img.ID); err != nil {
|
if err := srv.runtime.graph.Delete(img.ID); err != nil {
|
||||||
return nil, fmt.Errorf("Error deleting image %s: %s", name, err)
|
return nil, fmt.Errorf("Cannot delete image %s: %s", name, err)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -1252,7 +1253,7 @@ func (srv *Server) ContainerStart(name string, hostConfig *HostConfig) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := container.Start(hostConfig); err != nil {
|
if err := container.Start(hostConfig); err != nil {
|
||||||
return fmt.Errorf("Error starting container %s: %s", name, err)
|
return fmt.Errorf("Cannot start container %s: %s", name, err)
|
||||||
}
|
}
|
||||||
srv.LogEvent("start", container.ShortID(), runtime.repositories.ImageName(container.Image))
|
srv.LogEvent("start", container.ShortID(), runtime.repositories.ImageName(container.Image))
|
||||||
|
|
||||||
|
@ -1262,7 +1263,7 @@ func (srv *Server) ContainerStart(name string, hostConfig *HostConfig) error {
|
||||||
func (srv *Server) ContainerStop(name string, t int) error {
|
func (srv *Server) ContainerStop(name string, t int) error {
|
||||||
if container := srv.runtime.Get(name); container != nil {
|
if container := srv.runtime.Get(name); container != nil {
|
||||||
if err := container.Stop(t); err != nil {
|
if err := container.Stop(t); err != nil {
|
||||||
return fmt.Errorf("Error stopping container %s: %s", name, err)
|
return fmt.Errorf("Cannot stop container %s: %s", name, err)
|
||||||
}
|
}
|
||||||
srv.LogEvent("stop", container.ShortID(), srv.runtime.repositories.ImageName(container.Image))
|
srv.LogEvent("stop", container.ShortID(), srv.runtime.repositories.ImageName(container.Image))
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Reference in a new issue