Skip to content

Commit

Permalink
support create a container with a given id
Browse files Browse the repository at this point in the history
Signed-off-by: allen.wang <[email protected]>
  • Loading branch information
wangforthinker committed Sep 12, 2018
1 parent a0171dc commit 1244439
Show file tree
Hide file tree
Showing 13 changed files with 421 additions and 71 deletions.
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright The PouchContainer Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# TEST_FLAGS used as flags of go test.
TEST_FLAGS ?= -v --race

Expand All @@ -16,6 +30,13 @@ INTEGRATION_TESTCASE_BINARY_NAME=pouchd-integration-test
# DEST_DIR is base path used to install pouch & pouchd
DEST_DIR=/usr/local

# PREFIX is base path to install pouch & pouchd
# PREFIX will override the value of DEST_DIR when specified
# example: make install PREFIX=/usr
ifdef PREFIX
DEST_DIR := $(PREFIX)
endif

# the following variables used for the daemon build

# API_VERSION is used for daemon API Version in go build.
Expand Down
52 changes: 43 additions & 9 deletions VAGRANT.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Vagrant support for pouch
# Vagrant support for PouchContainer

You can using Vagrant to quickly experience pouch or cross compile on non-linux.
You can using [Vagrant](https://www.vagrantup.com) to quickly experience PouchContainer or cross compile on non-linux.

## Requirements

* Vagrant 1.9.x or newer
* VirtuaBox

## Get started
## Getting Started

```bash
vagrant up
Expand All @@ -18,22 +18,56 @@ pouch run -d --name nginx -p 80:80 nginx
curl http://localhost
```

## Build pouch with vagrant
## Getting Started with Kubernetes

```bash
# On macOS or Linux
POUCH_KUBE=true vagrant up

# On MacOS or Linux
export POUCH_BUILD=true
# On Windows
set POUCH_KUBE=true
vagrant up

vagrant ssh -c "sudo -i"

$ kubectl cluster-info
Kubernetes master is running at https://10.0.2.15:6443
KubeDNS is running at https://10.0.2.15:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy


$ kubectl get cs
NAME STATUS MESSAGE
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health": "true"}

$ kubectl get po -o wide --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE
default nginx-6dc97b4cbd-cq4pb 1/1 Running 0 2m 10.244.0.2 pouch
default nginx-6dc97b4cbd-ktlwc 1/1 Running 0 2m 10.244.0.3 pouch
kube-system etcd-pouch 1/1 Running 0 3m 10.0.2.15 pouch
kube-system kube-apiserver-pouch 1/1 Running 0 2m 10.0.2.15 pouch
kube-system kube-controller-manager-pouch 1/1 Running 0 2m 10.0.2.15 pouch
kube-system kube-dns-b4bd9576-gwqzv 3/3 Running 0 2m 10.244.0.4 pouch
kube-system kube-flannel-ds-amd64-vd466 1/1 Running 1 2m 10.0.2.15 pouch
kube-system kube-proxy-c8l8j 1/1 Running 0 2m 10.0.2.15 pouch
kube-system kube-scheduler-pouch 1/1 Running 0 2m 10.0.2.15 pouch
```

## Build pouch with vagrant

```bash
# On macOS or Linux
POUCH_BUILD=true vagrant up

# On Windows
set POUCH_BUILD=true
vagrant up

# Install compiled pouch binarys for pouch service.
# Install compiled pouch binaries for pouch service.
vagrant ssh -c "sudo -i"
cd ~/go/src/github.com/alibaba/pouch
make DEST_DIR=/usr install
make PREFIX=/usr install
systemctl restart pouch
pouch version
```
```
29 changes: 28 additions & 1 deletion Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ Vagrant.configure("2") do |config|
config.vm.define :pouch do |pouch|
pouch.vm.hostname = "pouch"
pouch.vm.box = "ubuntu/xenial64"
pouch.vm.provider 'virtualbox' do |v, override|
v.memory = 2048
end

pouch.vm.provision "shell", inline: <<-SHELL
until apt-get update &> /dev/null; do echo "Waiting apt-get for 3 seconds..."; sleep 3; done
apt-get --no-install-recommends install lxcfs
Expand Down Expand Up @@ -40,8 +44,31 @@ Vagrant.configure("2") do |config|
mkdir -p $GOPATH/src/github.com/alibaba
ln -s /vagrant $GOPATH/src/github.com/alibaba/pouch
cd $GOPATH/src/github.com/alibaba/pouch && make install
cd $GOPATH/src/github.com/alibaba/pouch
make PREFIX=/usr install
systemctl restart pouch
SHELL
end

if ENV["POUCH_KUBE"] == "true"
env = {
"KUBERNETES_VERSION" => "1.10",
"CRI_VERSION" => "v1alpha2",
"RELEASE_UBUNTU" => "v1.10.2",
"MASTER_NODE" => "true",
"INSTALL_FLANNEL" => "true",
"INSTALL_SAMPLE" => "true"
}

if ENV["http_proxy"] != ""
proxy = ENV["http_proxy"]

env["http_proxy"] = proxy
env["https_proxy"] = proxy
env["no_proxy"] = "localhost,127.0.0.1,10.96.0.0/16,10.0.0.0/16,10.244.0.0/16"
end

pouch.vm.provision "install_kubernetes", type: "shell", path: "hack/kubernetes/allinone_aliyun.sh", env: env
end
end
end
5 changes: 5 additions & 0 deletions apis/server/container_bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ func (s *Server) createContainer(ctx context.Context, rw http.ResponseWriter, re
logCreateOptions("container", config)

name := req.FormValue("name")
//consider set specific id by url params
specificID := req.FormValue("recover-id")
if specificID != "" {
config.SpecificID = specificID
}

// to do compensation to potential nil pointer after validation
if config.HostConfig == nil {
Expand Down
7 changes: 7 additions & 0 deletions apis/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2211,6 +2211,13 @@ definitions:
description: "net priority."
type: "integer"
default: 0
SpecificID:
type: "string"
description: |
Create container with given id.
The length of given id should be in [12,64].
The characters of given id should be in 0123456789abcdef.
By default, given id is unnecessary.
ContainerCreateResp:
description: "response returned by daemon when container create successfully"
Expand Down
9 changes: 9 additions & 0 deletions apis/types/container_config.go

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

1 change: 1 addition & 0 deletions cli/common_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container {
flagSet.Int64Var(&c.oomScoreAdj, "oom-score-adj", -500, "Tune host's OOM preferences (-1000 to 1000)")

flagSet.StringVar(&c.name, "name", "", "Specify name of container")
flagSet.StringVar(&c.specificID, "specific-id", "", "Specify id of container, length of id should be in [12,64], characters of id should be in '0123456789abcdef'")

flagSet.StringSliceVar(&c.networks, "net", nil, "Set networks to container")
flagSet.StringSliceVarP(&c.ports, "port", "p", nil, "Set container ports mapping")
Expand Down
2 changes: 2 additions & 0 deletions cli/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type container struct {
hostname string
rm bool
disableNetworkFiles bool
specificID string

blkioWeight uint16
blkioWeightDevice config.WeightDevice
Expand Down Expand Up @@ -194,6 +195,7 @@ func (c *container) config() (*types.ContainerCreateConfig, error) {
QuotaID: c.quotaID,
SpecAnnotation: specAnnotation,
NetPriority: c.netPriority,
SpecificID: c.specificID,
},

HostConfig: &types.HostConfig{
Expand Down
20 changes: 12 additions & 8 deletions ctrd/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,18 @@ func (c *Client) execContainer(ctx context.Context, process *Process) error {
exitTime: status.ExitTime(),
}

// run hook if not got fail here
if err := <-fail; err == nil {
for _, hook := range c.hooks {
if err := hook(process.ExecID, msg); err != nil {
logrus.Errorf("failed to execute the exec exit hooks: %v", err)
break
}
if err := <-fail; err != nil {
msg.err = err
// exit code should not be zero when exec get failed.
if msg.exitCode == 0 {
msg.exitCode = 126
}
}
// XXX: if exec process get run, io should be closed in this function,
for _, hook := range c.hooks {
if err := hook(process.ExecID, msg); err != nil {
logrus.Errorf("failed to execute the exec exit hooks: %v", err)
break
}
}

Expand All @@ -141,7 +146,6 @@ func (c *Client) execContainer(ctx context.Context, process *Process) error {
// start the exec process
if err := execProcess.Start(ctx); err != nil {
fail <- err
return errors.Wrap(err, "failed to exec process")
}

return nil
Expand Down
50 changes: 43 additions & 7 deletions daemon/mgr/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package mgr
import (
"context"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
Expand Down Expand Up @@ -34,6 +35,7 @@ import (
containerdtypes "github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/mount"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/libnetwork"
"github.com/go-openapi/strfmt"
"github.com/imdario/mergo"
Expand Down Expand Up @@ -263,6 +265,9 @@ func (mgr *ContainerManager) Restore(ctx context.Context) error {

// Create checks passed in parameters and create a Container object whose status is set at Created.
func (mgr *ContainerManager) Create(ctx context.Context, name string, config *types.ContainerCreateConfig) (resp *types.ContainerCreateResp, err error) {
var (
id = ""
)
// cleanup allocated resources when failed
cleanups := []func() error{}
defer func() {
Expand Down Expand Up @@ -291,16 +296,43 @@ func (mgr *ContainerManager) Create(ctx context.Context, name string, config *ty
return nil, errors.Wrapf(errtypes.ErrInvalidParam, "NetworkingConfig cannot be empty")
}

id, err := mgr.generateID()
if err != nil {
return nil, err
if config.SpecificID != "" {
if len(config.SpecificID) < 12 || len(config.SpecificID) > 64 {
return nil, errors.Wrap(errtypes.ErrInvalidParam, "Container id length should be in [12,64]")
}
//characters of containerID should be in "0123456789abcdef"
for _, c := range []byte(config.SpecificID) {
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) {
return nil, errors.Wrap(errtypes.ErrInvalidParam, "The characters of container id should be in '0123456789abcdef'")
}
}

if mgr.cache.Get(config.SpecificID).Exist() {
return nil, errors.Wrap(errtypes.ErrAlreadyExisted, "container id: "+config.SpecificID)
}
id = config.SpecificID
} else {
tmpID, err := mgr.generateID()
if err != nil {
return nil, err
}
id = tmpID
}
//put container id to cache to prevent concurrent containerCreateReq with same specific id
mgr.cache.Put(id, nil)
defer func() {
//clear cache
if err != nil {
mgr.cache.Remove(id)
}
}()

if name == "" {
name = mgr.generateName(id)
} else if mgr.NameToID.Get(name).Exist() {
return nil, errors.Wrapf(errtypes.ErrAlreadyExisted, "container name %s", name)
}
//todo: consider to do as the former ?

// set hostname.
if config.Hostname.String() == "" {
Expand Down Expand Up @@ -1860,17 +1892,21 @@ func (mgr *ContainerManager) execExitedAndRelease(id string, m *ctrd.Message) er
execConfig.Running = false
execConfig.Error = m.RawError()

io := mgr.IOs.Get(id)
if io == nil {
eio := mgr.IOs.Get(id)
if eio == nil {
return nil
}

if err := m.RawError(); err != nil {
fmt.Fprintf(io.Stdout, "%v\n", err)
var stdout io.Writer = eio.Stdout
if !execConfig.Tty && !eio.MuxDisabled {
stdout = stdcopy.NewStdWriter(stdout, stdcopy.Stdout)
}
stdout.Write([]byte(err.Error() + "\r\n"))
}

// close io
io.Close()
eio.Close()
mgr.IOs.Remove(id)

return nil
Expand Down
1 change: 1 addition & 0 deletions docs/api/HTTP_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ POST /containers/{id}/start
|HTTP Code|Description|Schema|
|---|---|---|
|**204**|no error|No Content|
|**304**|container already started|No Content|
|**404**|An unexpected 404 error occurred.|[Error](#error)|
|**409**|container is paused|[Error](#error)|
|**500**|An unexpected server error occurred.|[Error](#error)|
Expand Down
Loading

0 comments on commit 1244439

Please sign in to comment.