Remove runconfig package dependency from the API.
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,16 @@ |
| 0 |
+package httputils |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "io" |
|
| 4 |
+ |
|
| 5 |
+ "github.com/docker/engine-api/types/container" |
|
| 6 |
+ "github.com/docker/engine-api/types/network" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// ContainerDecoder specifies how |
|
| 10 |
+// to translate an io.Reader into |
|
| 11 |
+// container configuration. |
|
| 12 |
+type ContainerDecoder interface {
|
|
| 13 |
+ DecodeConfig(src io.Reader) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) |
|
| 14 |
+ DecodeHostConfig(src io.Reader) (*container.HostConfig, error) |
|
| 15 |
+} |
| ... | ... |
@@ -1,17 +1,22 @@ |
| 1 | 1 |
package container |
| 2 | 2 |
|
| 3 |
-import "github.com/docker/docker/api/server/router" |
|
| 3 |
+import ( |
|
| 4 |
+ "github.com/docker/docker/api/server/httputils" |
|
| 5 |
+ "github.com/docker/docker/api/server/router" |
|
| 6 |
+) |
|
| 4 | 7 |
|
| 5 | 8 |
// containerRouter is a router to talk with the container controller |
| 6 | 9 |
type containerRouter struct {
|
| 7 | 10 |
backend Backend |
| 11 |
+ decoder httputils.ContainerDecoder |
|
| 8 | 12 |
routes []router.Route |
| 9 | 13 |
} |
| 10 | 14 |
|
| 11 | 15 |
// NewRouter initializes a new container router |
| 12 |
-func NewRouter(b Backend) router.Router {
|
|
| 16 |
+func NewRouter(b Backend, decoder httputils.ContainerDecoder) router.Router {
|
|
| 13 | 17 |
r := &containerRouter{
|
| 14 | 18 |
backend: b, |
| 19 |
+ decoder: decoder, |
|
| 15 | 20 |
} |
| 16 | 21 |
r.initRoutes() |
| 17 | 22 |
return r |
| ... | ... |
@@ -16,7 +16,6 @@ import ( |
| 16 | 16 |
"github.com/docker/docker/pkg/ioutils" |
| 17 | 17 |
"github.com/docker/docker/pkg/signal" |
| 18 | 18 |
"github.com/docker/docker/pkg/term" |
| 19 |
- "github.com/docker/docker/runconfig" |
|
| 20 | 19 |
"github.com/docker/engine-api/types" |
| 21 | 20 |
"github.com/docker/engine-api/types/container" |
| 22 | 21 |
"github.com/docker/engine-api/types/filters" |
| ... | ... |
@@ -137,7 +136,7 @@ func (s *containerRouter) postContainersStart(ctx context.Context, w http.Respon |
| 137 | 137 |
return err |
| 138 | 138 |
} |
| 139 | 139 |
|
| 140 |
- c, err := runconfig.DecodeHostConfig(r.Body) |
|
| 140 |
+ c, err := s.decoder.DecodeHostConfig(r.Body) |
|
| 141 | 141 |
if err != nil {
|
| 142 | 142 |
return err |
| 143 | 143 |
} |
| ... | ... |
@@ -338,7 +337,7 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo |
| 338 | 338 |
|
| 339 | 339 |
name := r.Form.Get("name")
|
| 340 | 340 |
|
| 341 |
- config, hostConfig, networkingConfig, err := runconfig.DecodeContainerConfig(r.Body) |
|
| 341 |
+ config, hostConfig, networkingConfig, err := s.decoder.DecodeConfig(r.Body) |
|
| 342 | 342 |
if err != nil {
|
| 343 | 343 |
return err |
| 344 | 344 |
} |
| ... | ... |
@@ -1,17 +1,22 @@ |
| 1 | 1 |
package image |
| 2 | 2 |
|
| 3 |
-import "github.com/docker/docker/api/server/router" |
|
| 3 |
+import ( |
|
| 4 |
+ "github.com/docker/docker/api/server/httputils" |
|
| 5 |
+ "github.com/docker/docker/api/server/router" |
|
| 6 |
+) |
|
| 4 | 7 |
|
| 5 | 8 |
// imageRouter is a router to talk with the image controller |
| 6 | 9 |
type imageRouter struct {
|
| 7 | 10 |
backend Backend |
| 11 |
+ decoder httputils.ContainerDecoder |
|
| 8 | 12 |
routes []router.Route |
| 9 | 13 |
} |
| 10 | 14 |
|
| 11 | 15 |
// NewRouter initializes a new image router |
| 12 |
-func NewRouter(backend Backend) router.Router {
|
|
| 16 |
+func NewRouter(backend Backend, decoder httputils.ContainerDecoder) router.Router {
|
|
| 13 | 17 |
r := &imageRouter{
|
| 14 | 18 |
backend: backend, |
| 19 |
+ decoder: decoder, |
|
| 15 | 20 |
} |
| 16 | 21 |
r.initRoutes() |
| 17 | 22 |
return r |
| ... | ... |
@@ -17,7 +17,6 @@ import ( |
| 17 | 17 |
"github.com/docker/docker/pkg/ioutils" |
| 18 | 18 |
"github.com/docker/docker/pkg/streamformatter" |
| 19 | 19 |
"github.com/docker/docker/reference" |
| 20 |
- "github.com/docker/docker/runconfig" |
|
| 21 | 20 |
"github.com/docker/engine-api/types" |
| 22 | 21 |
"github.com/docker/engine-api/types/container" |
| 23 | 22 |
"golang.org/x/net/context" |
| ... | ... |
@@ -40,7 +39,7 @@ func (s *imageRouter) postCommit(ctx context.Context, w http.ResponseWriter, r * |
| 40 | 40 |
pause = true |
| 41 | 41 |
} |
| 42 | 42 |
|
| 43 |
- c, _, _, err := runconfig.DecodeContainerConfig(r.Body) |
|
| 43 |
+ c, _, _, err := s.decoder.DecodeConfig(r.Body) |
|
| 44 | 44 |
if err != nil && err != io.EOF { //Do not fail if body is empty.
|
| 45 | 45 |
return err |
| 46 | 46 |
} |
| ... | ... |
@@ -1,6 +1,8 @@ |
| 1 | 1 |
package network |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "github.com/docker/engine-api/types" |
|
| 5 |
+ "github.com/docker/engine-api/types/filters" |
|
| 4 | 6 |
"github.com/docker/engine-api/types/network" |
| 5 | 7 |
"github.com/docker/libnetwork" |
| 6 | 8 |
) |
| ... | ... |
@@ -11,8 +13,8 @@ type Backend interface {
|
| 11 | 11 |
FindNetwork(idName string) (libnetwork.Network, error) |
| 12 | 12 |
GetNetworkByName(idName string) (libnetwork.Network, error) |
| 13 | 13 |
GetNetworksByID(partialID string) []libnetwork.Network |
| 14 |
- GetAllNetworks() []libnetwork.Network |
|
| 15 |
- CreateNetwork(name, driver string, ipam network.IPAM, options map[string]string, labels map[string]string, internal bool, enableIPv6 bool) (libnetwork.Network, error) |
|
| 14 |
+ FilterNetworks(netFilters filters.Args) ([]libnetwork.Network, error) |
|
| 15 |
+ CreateNetwork(types.NetworkCreate) (*types.NetworkCreateResponse, error) |
|
| 16 | 16 |
ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error |
| 17 | 17 |
DisconnectContainerFromNetwork(containerName string, network libnetwork.Network, force bool) error |
| 18 | 18 |
DeleteNetwork(name string) error |
| 19 | 19 |
deleted file mode 100644 |
| ... | ... |
@@ -1,110 +0,0 @@ |
| 1 |
-package network |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "fmt" |
|
| 5 |
- "regexp" |
|
| 6 |
- "strings" |
|
| 7 |
- |
|
| 8 |
- "github.com/docker/docker/runconfig" |
|
| 9 |
- "github.com/docker/engine-api/types/filters" |
|
| 10 |
- "github.com/docker/libnetwork" |
|
| 11 |
-) |
|
| 12 |
- |
|
| 13 |
-type filterHandler func([]libnetwork.Network, string) ([]libnetwork.Network, error) |
|
| 14 |
- |
|
| 15 |
-var ( |
|
| 16 |
- // supportedFilters predefined some supported filter handler function |
|
| 17 |
- supportedFilters = map[string]filterHandler{
|
|
| 18 |
- "type": filterNetworkByType, |
|
| 19 |
- "name": filterNetworkByName, |
|
| 20 |
- "id": filterNetworkByID, |
|
| 21 |
- } |
|
| 22 |
- |
|
| 23 |
- // acceptFilters is an acceptable filter flag list |
|
| 24 |
- // generated for validation. e.g. |
|
| 25 |
- // acceptedFilters = map[string]bool{
|
|
| 26 |
- // "type": true, |
|
| 27 |
- // "name": true, |
|
| 28 |
- // "id": true, |
|
| 29 |
- // } |
|
| 30 |
- acceptedFilters = func() map[string]bool {
|
|
| 31 |
- ret := make(map[string]bool) |
|
| 32 |
- for k := range supportedFilters {
|
|
| 33 |
- ret[k] = true |
|
| 34 |
- } |
|
| 35 |
- return ret |
|
| 36 |
- }() |
|
| 37 |
-) |
|
| 38 |
- |
|
| 39 |
-func filterNetworkByType(nws []libnetwork.Network, netType string) (retNws []libnetwork.Network, err error) {
|
|
| 40 |
- switch netType {
|
|
| 41 |
- case "builtin": |
|
| 42 |
- for _, nw := range nws {
|
|
| 43 |
- if runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 44 |
- retNws = append(retNws, nw) |
|
| 45 |
- } |
|
| 46 |
- } |
|
| 47 |
- case "custom": |
|
| 48 |
- for _, nw := range nws {
|
|
| 49 |
- if !runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 50 |
- retNws = append(retNws, nw) |
|
| 51 |
- } |
|
| 52 |
- } |
|
| 53 |
- default: |
|
| 54 |
- return nil, fmt.Errorf("Invalid filter: 'type'='%s'", netType)
|
|
| 55 |
- } |
|
| 56 |
- return retNws, nil |
|
| 57 |
-} |
|
| 58 |
- |
|
| 59 |
-func filterNetworkByName(nws []libnetwork.Network, name string) (retNws []libnetwork.Network, err error) {
|
|
| 60 |
- for _, nw := range nws {
|
|
| 61 |
- // exact match (fast path) |
|
| 62 |
- if nw.Name() == name {
|
|
| 63 |
- retNws = append(retNws, nw) |
|
| 64 |
- continue |
|
| 65 |
- } |
|
| 66 |
- |
|
| 67 |
- // regexp match (slow path) |
|
| 68 |
- match, err := regexp.MatchString(name, nw.Name()) |
|
| 69 |
- if err != nil || !match {
|
|
| 70 |
- continue |
|
| 71 |
- } else {
|
|
| 72 |
- retNws = append(retNws, nw) |
|
| 73 |
- } |
|
| 74 |
- } |
|
| 75 |
- return retNws, nil |
|
| 76 |
-} |
|
| 77 |
- |
|
| 78 |
-func filterNetworkByID(nws []libnetwork.Network, id string) (retNws []libnetwork.Network, err error) {
|
|
| 79 |
- for _, nw := range nws {
|
|
| 80 |
- if strings.HasPrefix(nw.ID(), id) {
|
|
| 81 |
- retNws = append(retNws, nw) |
|
| 82 |
- } |
|
| 83 |
- } |
|
| 84 |
- return retNws, nil |
|
| 85 |
-} |
|
| 86 |
- |
|
| 87 |
-// filterAllNetworks filters network list according to user specified filter |
|
| 88 |
-// and returns user chosen networks |
|
| 89 |
-func filterNetworks(nws []libnetwork.Network, filter filters.Args) ([]libnetwork.Network, error) {
|
|
| 90 |
- // if filter is empty, return original network list |
|
| 91 |
- if filter.Len() == 0 {
|
|
| 92 |
- return nws, nil |
|
| 93 |
- } |
|
| 94 |
- |
|
| 95 |
- var displayNet []libnetwork.Network |
|
| 96 |
- for fkey, fhandler := range supportedFilters {
|
|
| 97 |
- errFilter := filter.WalkValues(fkey, func(fval string) error {
|
|
| 98 |
- passList, err := fhandler(nws, fval) |
|
| 99 |
- if err != nil {
|
|
| 100 |
- return err |
|
| 101 |
- } |
|
| 102 |
- displayNet = append(displayNet, passList...) |
|
| 103 |
- return nil |
|
| 104 |
- }) |
|
| 105 |
- if errFilter != nil {
|
|
| 106 |
- return nil, errFilter |
|
| 107 |
- } |
|
| 108 |
- } |
|
| 109 |
- return displayNet, nil |
|
| 110 |
-} |
| ... | ... |
@@ -2,13 +2,11 @@ package network |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"encoding/json" |
| 5 |
- "fmt" |
|
| 6 | 5 |
"net/http" |
| 7 | 6 |
|
| 8 | 7 |
"golang.org/x/net/context" |
| 9 | 8 |
|
| 10 | 9 |
"github.com/docker/docker/api/server/httputils" |
| 11 |
- "github.com/docker/docker/runconfig" |
|
| 12 | 10 |
"github.com/docker/engine-api/types" |
| 13 | 11 |
"github.com/docker/engine-api/types/filters" |
| 14 | 12 |
"github.com/docker/engine-api/types/network" |
| ... | ... |
@@ -26,21 +24,14 @@ func (n *networkRouter) getNetworksList(ctx context.Context, w http.ResponseWrit |
| 26 | 26 |
return err |
| 27 | 27 |
} |
| 28 | 28 |
|
| 29 |
- if netFilters.Len() != 0 {
|
|
| 30 |
- if err := netFilters.Validate(acceptedFilters); err != nil {
|
|
| 31 |
- return err |
|
| 32 |
- } |
|
| 33 |
- } |
|
| 34 |
- |
|
| 35 | 29 |
list := []*types.NetworkResource{}
|
| 36 | 30 |
|
| 37 |
- nwList := n.backend.GetAllNetworks() |
|
| 38 |
- displayable, err := filterNetworks(nwList, netFilters) |
|
| 31 |
+ nwList, err := n.backend.FilterNetworks(netFilters) |
|
| 39 | 32 |
if err != nil {
|
| 40 | 33 |
return err |
| 41 | 34 |
} |
| 42 | 35 |
|
| 43 |
- for _, nw := range displayable {
|
|
| 36 |
+ for _, nw := range nwList {
|
|
| 44 | 37 |
list = append(list, buildNetworkResource(nw)) |
| 45 | 38 |
} |
| 46 | 39 |
|
| ... | ... |
@@ -61,7 +52,6 @@ func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r |
| 61 | 61 |
|
| 62 | 62 |
func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| 63 | 63 |
var create types.NetworkCreate |
| 64 |
- var warning string |
|
| 65 | 64 |
|
| 66 | 65 |
if err := httputils.ParseForm(r); err != nil {
|
| 67 | 66 |
return err |
| ... | ... |
@@ -75,31 +65,12 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr |
| 75 | 75 |
return err |
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 |
- if runconfig.IsPreDefinedNetwork(create.Name) {
|
|
| 79 |
- return httputils.WriteJSON(w, http.StatusForbidden, |
|
| 80 |
- fmt.Sprintf("%s is a pre-defined network and cannot be created", create.Name))
|
|
| 81 |
- } |
|
| 82 |
- |
|
| 83 |
- nw, err := n.backend.GetNetworkByName(create.Name) |
|
| 84 |
- if _, ok := err.(libnetwork.ErrNoSuchNetwork); err != nil && !ok {
|
|
| 85 |
- return err |
|
| 86 |
- } |
|
| 87 |
- if nw != nil {
|
|
| 88 |
- if create.CheckDuplicate {
|
|
| 89 |
- return libnetwork.NetworkNameError(create.Name) |
|
| 90 |
- } |
|
| 91 |
- warning = fmt.Sprintf("Network with name %s (id : %s) already exists", nw.Name(), nw.ID())
|
|
| 92 |
- } |
|
| 93 |
- |
|
| 94 |
- nw, err = n.backend.CreateNetwork(create.Name, create.Driver, create.IPAM, create.Options, create.Labels, create.Internal, create.EnableIPv6) |
|
| 78 |
+ nw, err := n.backend.CreateNetwork(create) |
|
| 95 | 79 |
if err != nil {
|
| 96 | 80 |
return err |
| 97 | 81 |
} |
| 98 | 82 |
|
| 99 |
- return httputils.WriteJSON(w, http.StatusCreated, &types.NetworkCreateResponse{
|
|
| 100 |
- ID: nw.ID(), |
|
| 101 |
- Warning: warning, |
|
| 102 |
- }) |
|
| 83 |
+ return httputils.WriteJSON(w, http.StatusCreated, nw) |
|
| 103 | 84 |
} |
| 104 | 85 |
|
| 105 | 86 |
func (n *networkRouter) postNetworkConnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| ... | ... |
@@ -6,8 +6,11 @@ import ( |
| 6 | 6 |
"net/http" |
| 7 | 7 |
"strings" |
| 8 | 8 |
|
| 9 |
+ netsettings "github.com/docker/docker/daemon/network" |
|
| 9 | 10 |
"github.com/docker/docker/errors" |
| 10 | 11 |
"github.com/docker/docker/runconfig" |
| 12 |
+ "github.com/docker/engine-api/types" |
|
| 13 |
+ "github.com/docker/engine-api/types/filters" |
|
| 11 | 14 |
"github.com/docker/engine-api/types/network" |
| 12 | 15 |
"github.com/docker/libnetwork" |
| 13 | 16 |
) |
| ... | ... |
@@ -77,8 +80,8 @@ func (daemon *Daemon) GetNetworksByID(partialID string) []libnetwork.Network {
|
| 77 | 77 |
return list |
| 78 | 78 |
} |
| 79 | 79 |
|
| 80 |
-// GetAllNetworks returns a list containing all networks |
|
| 81 |
-func (daemon *Daemon) GetAllNetworks() []libnetwork.Network {
|
|
| 80 |
+// getAllNetworks returns a list containing all networks |
|
| 81 |
+func (daemon *Daemon) getAllNetworks() []libnetwork.Network {
|
|
| 82 | 82 |
c := daemon.netController |
| 83 | 83 |
list := []libnetwork.Network{}
|
| 84 | 84 |
l := func(nw libnetwork.Network) bool {
|
| ... | ... |
@@ -91,12 +94,33 @@ func (daemon *Daemon) GetAllNetworks() []libnetwork.Network {
|
| 91 | 91 |
} |
| 92 | 92 |
|
| 93 | 93 |
// CreateNetwork creates a network with the given name, driver and other optional parameters |
| 94 |
-func (daemon *Daemon) CreateNetwork(name, driver string, ipam network.IPAM, netOption map[string]string, labels map[string]string, internal bool, enableIPv6 bool) (libnetwork.Network, error) {
|
|
| 94 |
+func (daemon *Daemon) CreateNetwork(create types.NetworkCreate) (*types.NetworkCreateResponse, error) {
|
|
| 95 |
+ if runconfig.IsPreDefinedNetwork(create.Name) {
|
|
| 96 |
+ err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name)
|
|
| 97 |
+ return nil, errors.NewErrorWithStatusCode(err, http.StatusForbidden) |
|
| 98 |
+ } |
|
| 99 |
+ |
|
| 100 |
+ var warning string |
|
| 101 |
+ nw, err := daemon.GetNetworkByName(create.Name) |
|
| 102 |
+ if err != nil {
|
|
| 103 |
+ if _, ok := err.(libnetwork.ErrNoSuchNetwork); !ok {
|
|
| 104 |
+ return nil, err |
|
| 105 |
+ } |
|
| 106 |
+ } |
|
| 107 |
+ if nw != nil {
|
|
| 108 |
+ if create.CheckDuplicate {
|
|
| 109 |
+ return nil, libnetwork.NetworkNameError(create.Name) |
|
| 110 |
+ } |
|
| 111 |
+ warning = fmt.Sprintf("Network with name %s (id : %s) already exists", nw.Name(), nw.ID())
|
|
| 112 |
+ } |
|
| 113 |
+ |
|
| 95 | 114 |
c := daemon.netController |
| 115 |
+ driver := create.Driver |
|
| 96 | 116 |
if driver == "" {
|
| 97 | 117 |
driver = c.Config().Daemon.DefaultDriver |
| 98 | 118 |
} |
| 99 | 119 |
|
| 120 |
+ ipam := create.IPAM |
|
| 100 | 121 |
v4Conf, v6Conf, err := getIpamConfig(ipam.Config) |
| 101 | 122 |
if err != nil {
|
| 102 | 123 |
return nil, err |
| ... | ... |
@@ -104,20 +128,23 @@ func (daemon *Daemon) CreateNetwork(name, driver string, ipam network.IPAM, netO |
| 104 | 104 |
|
| 105 | 105 |
nwOptions := []libnetwork.NetworkOption{
|
| 106 | 106 |
libnetwork.NetworkOptionIpam(ipam.Driver, "", v4Conf, v6Conf, ipam.Options), |
| 107 |
- libnetwork.NetworkOptionEnableIPv6(enableIPv6), |
|
| 108 |
- libnetwork.NetworkOptionDriverOpts(netOption), |
|
| 109 |
- libnetwork.NetworkOptionLabels(labels), |
|
| 107 |
+ libnetwork.NetworkOptionEnableIPv6(create.EnableIPv6), |
|
| 108 |
+ libnetwork.NetworkOptionDriverOpts(create.Options), |
|
| 109 |
+ libnetwork.NetworkOptionLabels(create.Labels), |
|
| 110 | 110 |
} |
| 111 |
- if internal {
|
|
| 111 |
+ if create.Internal {
|
|
| 112 | 112 |
nwOptions = append(nwOptions, libnetwork.NetworkOptionInternalNetwork()) |
| 113 | 113 |
} |
| 114 |
- n, err := c.NewNetwork(driver, name, nwOptions...) |
|
| 114 |
+ n, err := c.NewNetwork(driver, create.Name, nwOptions...) |
|
| 115 | 115 |
if err != nil {
|
| 116 | 116 |
return nil, err |
| 117 | 117 |
} |
| 118 | 118 |
|
| 119 | 119 |
daemon.LogNetworkEvent(n, "create") |
| 120 |
- return n, nil |
|
| 120 |
+ return &types.NetworkCreateResponse{
|
|
| 121 |
+ ID: n.ID(), |
|
| 122 |
+ Warning: warning, |
|
| 123 |
+ }, nil |
|
| 121 | 124 |
} |
| 122 | 125 |
|
| 123 | 126 |
func getIpamConfig(data []network.IPAMConfig) ([]*libnetwork.IpamConf, []*libnetwork.IpamConf, error) {
|
| ... | ... |
@@ -203,3 +230,15 @@ func (daemon *Daemon) DeleteNetwork(networkID string) error {
|
| 203 | 203 |
daemon.LogNetworkEvent(nw, "destroy") |
| 204 | 204 |
return nil |
| 205 | 205 |
} |
| 206 |
+ |
|
| 207 |
+// FilterNetworks returns a list of networks filtered by the given arguments. |
|
| 208 |
+// It returns an error if the filters are not included in the list of accepted filters. |
|
| 209 |
+func (daemon *Daemon) FilterNetworks(netFilters filters.Args) ([]libnetwork.Network, error) {
|
|
| 210 |
+ if netFilters.Len() != 0 {
|
|
| 211 |
+ if err := netFilters.Validate(netsettings.AcceptedFilters); err != nil {
|
|
| 212 |
+ return nil, err |
|
| 213 |
+ } |
|
| 214 |
+ } |
|
| 215 |
+ nwList := daemon.getAllNetworks() |
|
| 216 |
+ return netsettings.FilterNetworks(nwList, netFilters) |
|
| 217 |
+} |
| 206 | 218 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,110 @@ |
| 0 |
+package network |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "regexp" |
|
| 5 |
+ "strings" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/docker/docker/runconfig" |
|
| 8 |
+ "github.com/docker/engine-api/types/filters" |
|
| 9 |
+ "github.com/docker/libnetwork" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+type filterHandler func([]libnetwork.Network, string) ([]libnetwork.Network, error) |
|
| 13 |
+ |
|
| 14 |
+var ( |
|
| 15 |
+ // supportedFilters predefined some supported filter handler function |
|
| 16 |
+ supportedFilters = map[string]filterHandler{
|
|
| 17 |
+ "type": filterNetworkByType, |
|
| 18 |
+ "name": filterNetworkByName, |
|
| 19 |
+ "id": filterNetworkByID, |
|
| 20 |
+ } |
|
| 21 |
+ |
|
| 22 |
+ // AcceptedFilters is an acceptable filter flag list |
|
| 23 |
+ // generated for validation. e.g. |
|
| 24 |
+ // acceptedFilters = map[string]bool{
|
|
| 25 |
+ // "type": true, |
|
| 26 |
+ // "name": true, |
|
| 27 |
+ // "id": true, |
|
| 28 |
+ // } |
|
| 29 |
+ AcceptedFilters = func() map[string]bool {
|
|
| 30 |
+ ret := make(map[string]bool) |
|
| 31 |
+ for k := range supportedFilters {
|
|
| 32 |
+ ret[k] = true |
|
| 33 |
+ } |
|
| 34 |
+ return ret |
|
| 35 |
+ }() |
|
| 36 |
+) |
|
| 37 |
+ |
|
| 38 |
+func filterNetworkByType(nws []libnetwork.Network, netType string) (retNws []libnetwork.Network, err error) {
|
|
| 39 |
+ switch netType {
|
|
| 40 |
+ case "builtin": |
|
| 41 |
+ for _, nw := range nws {
|
|
| 42 |
+ if runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 43 |
+ retNws = append(retNws, nw) |
|
| 44 |
+ } |
|
| 45 |
+ } |
|
| 46 |
+ case "custom": |
|
| 47 |
+ for _, nw := range nws {
|
|
| 48 |
+ if !runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 49 |
+ retNws = append(retNws, nw) |
|
| 50 |
+ } |
|
| 51 |
+ } |
|
| 52 |
+ default: |
|
| 53 |
+ return nil, fmt.Errorf("Invalid filter: 'type'='%s'", netType)
|
|
| 54 |
+ } |
|
| 55 |
+ return retNws, nil |
|
| 56 |
+} |
|
| 57 |
+ |
|
| 58 |
+func filterNetworkByName(nws []libnetwork.Network, name string) (retNws []libnetwork.Network, err error) {
|
|
| 59 |
+ for _, nw := range nws {
|
|
| 60 |
+ // exact match (fast path) |
|
| 61 |
+ if nw.Name() == name {
|
|
| 62 |
+ retNws = append(retNws, nw) |
|
| 63 |
+ continue |
|
| 64 |
+ } |
|
| 65 |
+ |
|
| 66 |
+ // regexp match (slow path) |
|
| 67 |
+ match, err := regexp.MatchString(name, nw.Name()) |
|
| 68 |
+ if err != nil || !match {
|
|
| 69 |
+ continue |
|
| 70 |
+ } else {
|
|
| 71 |
+ retNws = append(retNws, nw) |
|
| 72 |
+ } |
|
| 73 |
+ } |
|
| 74 |
+ return retNws, nil |
|
| 75 |
+} |
|
| 76 |
+ |
|
| 77 |
+func filterNetworkByID(nws []libnetwork.Network, id string) (retNws []libnetwork.Network, err error) {
|
|
| 78 |
+ for _, nw := range nws {
|
|
| 79 |
+ if strings.HasPrefix(nw.ID(), id) {
|
|
| 80 |
+ retNws = append(retNws, nw) |
|
| 81 |
+ } |
|
| 82 |
+ } |
|
| 83 |
+ return retNws, nil |
|
| 84 |
+} |
|
| 85 |
+ |
|
| 86 |
+// FilterNetworks filters network list according to user specified filter |
|
| 87 |
+// and returns user chosen networks |
|
| 88 |
+func FilterNetworks(nws []libnetwork.Network, filter filters.Args) ([]libnetwork.Network, error) {
|
|
| 89 |
+ // if filter is empty, return original network list |
|
| 90 |
+ if filter.Len() == 0 {
|
|
| 91 |
+ return nws, nil |
|
| 92 |
+ } |
|
| 93 |
+ |
|
| 94 |
+ var displayNet []libnetwork.Network |
|
| 95 |
+ for fkey, fhandler := range supportedFilters {
|
|
| 96 |
+ errFilter := filter.WalkValues(fkey, func(fval string) error {
|
|
| 97 |
+ passList, err := fhandler(nws, fval) |
|
| 98 |
+ if err != nil {
|
|
| 99 |
+ return err |
|
| 100 |
+ } |
|
| 101 |
+ displayNet = append(displayNet, passList...) |
|
| 102 |
+ return nil |
|
| 103 |
+ }) |
|
| 104 |
+ if errFilter != nil {
|
|
| 105 |
+ return nil, errFilter |
|
| 106 |
+ } |
|
| 107 |
+ } |
|
| 108 |
+ return displayNet, nil |
|
| 109 |
+} |
| ... | ... |
@@ -37,6 +37,7 @@ import ( |
| 37 | 37 |
"github.com/docker/docker/pkg/signal" |
| 38 | 38 |
"github.com/docker/docker/pkg/system" |
| 39 | 39 |
"github.com/docker/docker/registry" |
| 40 |
+ "github.com/docker/docker/runconfig" |
|
| 40 | 41 |
"github.com/docker/docker/utils" |
| 41 | 42 |
"github.com/docker/go-connections/tlsconfig" |
| 42 | 43 |
) |
| ... | ... |
@@ -405,9 +406,11 @@ func loadDaemonCliConfig(config *daemon.Config, daemonFlags *flag.FlagSet, commo |
| 405 | 405 |
} |
| 406 | 406 |
|
| 407 | 407 |
func initRouter(s *apiserver.Server, d *daemon.Daemon) {
|
| 408 |
+ decoder := runconfig.ContainerDecoder{}
|
|
| 409 |
+ |
|
| 408 | 410 |
routers := []router.Router{
|
| 409 |
- container.NewRouter(d), |
|
| 410 |
- image.NewRouter(d), |
|
| 411 |
+ container.NewRouter(d, decoder), |
|
| 412 |
+ image.NewRouter(d, decoder), |
|
| 411 | 413 |
systemrouter.NewRouter(d), |
| 412 | 414 |
volume.NewRouter(d), |
| 413 | 415 |
build.NewRouter(dockerfile.NewBuildManager(d)), |
| ... | ... |
@@ -296,8 +296,8 @@ func createNetwork(c *check.C, config types.NetworkCreate, shouldSucceed bool) s |
| 296 | 296 |
return "" |
| 297 | 297 |
} |
| 298 | 298 |
|
| 299 |
- c.Assert(status, checker.Equals, http.StatusCreated) |
|
| 300 | 299 |
c.Assert(err, checker.IsNil) |
| 300 |
+ c.Assert(status, checker.Equals, http.StatusCreated) |
|
| 301 | 301 |
|
| 302 | 302 |
var nr types.NetworkCreateResponse |
| 303 | 303 |
err = json.Unmarshal(resp, &nr) |
| ... | ... |
@@ -10,6 +10,20 @@ import ( |
| 10 | 10 |
networktypes "github.com/docker/engine-api/types/network" |
| 11 | 11 |
) |
| 12 | 12 |
|
| 13 |
+// ContainerDecoder implements httputils.ContainerDecoder |
|
| 14 |
+// calling DecodeContainerConfig. |
|
| 15 |
+type ContainerDecoder struct{}
|
|
| 16 |
+ |
|
| 17 |
+// DecodeConfig makes ContainerDecoder to implement httputils.ContainerDecoder |
|
| 18 |
+func (r ContainerDecoder) DecodeConfig(src io.Reader) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
|
|
| 19 |
+ return DecodeContainerConfig(src) |
|
| 20 |
+} |
|
| 21 |
+ |
|
| 22 |
+// DecodeHostConfig makes ContainerDecoder to implement httputils.ContainerDecoder |
|
| 23 |
+func (r ContainerDecoder) DecodeHostConfig(src io.Reader) (*container.HostConfig, error) {
|
|
| 24 |
+ return DecodeHostConfig(src) |
|
| 25 |
+} |
|
| 26 |
+ |
|
| 13 | 27 |
// DecodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper |
| 14 | 28 |
// struct and returns both a Config and an HostConfig struct |
| 15 | 29 |
// Be aware this function is not checking whether the resulted structs are nil, |