Remove multiple interface in an endpoint

Currently the endpoint data model consists of multiple
interfaces per-endpoint. This seems to be an overkill
since there is no real use case for it. Removing it
to remove unnecessary complexity from the code.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
This commit is contained in:
Jana Radhakrishnan
2015-09-11 09:19:01 -07:00
parent 614f396bee
commit a3db98ec00
20 changed files with 229 additions and 340 deletions
+7 -8
View File
@@ -20,7 +20,7 @@ Libnetwork implements Container Network Model (CNM) which formalizes the steps r
**Sandbox**
A Sandbox contains the configuration of a container's network stack.
This includes management of the container's interfaces, routing table and DNS settings.
This includes management of the container's interfaces, routing table and DNS settings.
An implementation of a Sandbox could be a Linux Network Namespace, a FreeBSD Jail or other similar concept.
A Sandbox may contain *many* endpoints from *multiple* networks.
@@ -84,7 +84,7 @@ Consumers of the CNM, like Docker for example, interact through the CNM Objects
7. `endpoint.Delete()` is used to delete an endpoint from a network. This results in deleting an endpoint and cleaning up the cached `sandbox.Info`.
8. `network.Delete()` is used to delete a network. LibNetwork will not allow the delete to proceed if there are any existing endpoints attached to the Network.
8. `network.Delete()` is used to delete a network. LibNetwork will not allow the delete to proceed if there are any existing endpoints attached to the Network.
## Implementation Details
@@ -95,7 +95,7 @@ LibNetwork's Network and Endpoint APIs are primarily for managing the correspond
### Sandbox
Libnetwork provides a framework to implement of a Sandbox in multiple operating systems. Currently we have implemented Sandbox for Linux using `namespace_linux.go` and `configure_linux.go` in `sandbox` package
Libnetwork provides a framework to implement of a Sandbox in multiple operating systems. Currently we have implemented Sandbox for Linux using `namespace_linux.go` and `configure_linux.go` in `sandbox` package
This creates a Network Namespace for each sandbox which is uniquely identified by a path on the host filesystem.
Netlink calls are used to move interfaces from the global namespace to the Sandbox namespace.
Netlink is also used to manage the routing table in the namespace.
@@ -111,7 +111,7 @@ Drivers are essentially an extension of libnetwork and provides the actual imple
* `driver.CreateEndpoint`
* `driver.DeleteEndpoint`
* `driver.Join`
* `driver.Leave`
* `driver.Leave`
These Driver facing APIs makes use of unique identifiers (`networkid`,`endpointid`,...) instead of names (as seen in user-facing APIs).
@@ -121,11 +121,11 @@ The APIs are still work in progress and there can be changes to these based on t
* `Driver.CreateEndpoint`
This method is passed an interface `EndpointInfo`, with methods `Interfaces` and `AddInterface`.
This method is passed an interface `EndpointInfo`, with methods `Interface` and `AddInterface`.
If the slice returned by `Interfaces` is non-empty, the driver is expected to make use of the interface information therein (e.g., treating the address or addresses as statically supplied), and must return an error if it cannot. If the slice is empty, the driver should allocate zero or more _fresh_ interfaces, and use `AddInterface` to record them; or return an error if it cannot.
If the value returned by `Interface` is non-nil, the driver is expected to make use of the interface information therein (e.g., treating the address or addresses as statically supplied), and must return an error if it cannot. If the value is `nil`, the driver should allocate exactly one _fresh_ interface, and use `AddInterface` to record them; or return an error if it cannot.
It is forbidden to use `AddInterface` if `Interfaces` is non-empty.
It is forbidden to use `AddInterface` if `Interface` is non-nil.
## Implementations
@@ -155,4 +155,3 @@ For more details on its design, please see the [Overlay Driver Design](overlay.m
The `remote` package does not provide a driver, but provides a means of supporting drivers over a remote transport.
This allows a driver to be written in a language of your choice.
For further details, please see the [Remote Driver Design](remote.md).
+50 -57
View File
@@ -34,7 +34,7 @@ If the remote process cannot decode, or otherwise detects a syntactic problem wi
If the remote process can decode the request, but cannot complete the operation, it must send a response in the form
{
"Err": string
"Err": string
}
The string value supplied may appear in logs, so should not include confidential information.
@@ -44,7 +44,7 @@ The string value supplied may appear in logs, so should not include confidential
When loaded, a remote driver process receives an HTTP POST on the URL `/Plugin.Activate` with no payload. It must respond with a manifest of the form
{
"Implements": ["NetworkDriver"]
"Implements": ["NetworkDriver"]
}
Other entries in the list value are allowed; `"NetworkDriver"` indicates that the plugin should be registered with LibNetwork as a driver.
@@ -54,10 +54,10 @@ Other entries in the list value are allowed; `"NetworkDriver"` indicates that th
When the proxy is asked to create a network, the remote process shall receive a POST to the URL `/NetworkDriver.CreateNetwork` of the form
{
"NetworkID": string,
"Options": {
...
}
"NetworkID": string,
"Options": {
...
}
}
The `NetworkID` value is generated by LibNetwork. The `Options` value is the arbitrary map given to the proxy by LibNetwork.
@@ -71,7 +71,7 @@ The response indicating success is empty:
When a network owned by the remote driver is deleted, the remote process shall receive a POST to the URL `/NetworkDriver.DeleteNetwork` of the form
{
"NetworkID": string
"NetworkID": string
}
The success response is empty:
@@ -83,53 +83,51 @@ The success response is empty:
When the proxy is asked to create an endpoint, the remote process shall receive a POST to the URL `/NetworkDriver.CreateEndpoint` of the form
{
"NetworkID": string,
"EndpointID": string,
"Options": {
...
},
"Interfaces": [{
"ID": int,
"Address": string,
"AddressIPv6": string,
"MacAddress": string
}, ...]
"NetworkID": string,
"EndpointID": string,
"Options": {
...
},
"Interface": {
"Address": string,
"AddressIPv6": string,
"MacAddress": string
}
}
The `NetworkID` is the generated identifier for the network to which the endpoint belongs; the `EndpointID` is a generated identifier for the endpoint.
`Options` is an arbitrary map as supplied to the proxy.
The `Interfaces` value is a list with values of the form given. The fields in the `Interfaces` entries may be empty; and the `Interfaces` list itself may be empty. If supplied, `Address` is an IPv4 address and subnet in CIDR notation; e.g., `"192.168.34.12/16"`. If supplied, `AddressIPv6` is an IPv6 address and subnet in CIDR notation. `MacAddress` is a MAC address as a string; e.g., `"6e:75:32:60:44:c9"`.
The `Interface` value is of the form given. The fields in the `Interface` may be empty; and the `Interface` itself may be empty. If supplied, `Address` is an IPv4 address and subnet in CIDR notation; e.g., `"192.168.34.12/16"`. If supplied, `AddressIPv6` is an IPv6 address and subnet in CIDR notation. `MacAddress` is a MAC address as a string; e.g., `"6e:75:32:60:44:c9"`.
A success response is of the form
{
"Interfaces": [{
"ID": int,
"Address": string,
"AddressIPv6": string,
"MacAddress": string
}, ...]
"Interface": {
"Address": string,
"AddressIPv6": string,
"MacAddress": string
}
}
with values in the `Interfaces` entries as above. For each entry, an `ID` and `MacAddress` and either or both of `Address` and `AddressIPv6` must be given. The `ID` is arbitrary but must differ among entries. It is used to identify, within the scope of the endpoint, an individual interface during a `Join` call.
with values in the `Interface` as above. As far as the value of `Interface` is concerned, `MacAddress` and either or both of `Address` and `AddressIPv6` must be given.
If the remote process was supplied entries in `Interfaces`, it must respond with an empty `Interfaces` list. LibNetwork will treat it as an error if it supplies a non-empty list and receives a non-empty list back, and roll back the operation.
If the remote process was supplied a non-empty value in `Interface`, it must respond with an empty `Interface` value. LibNetwork will treat it as an error if it supplies a non-empty value and receives a non-empty value back, and roll back the operation.
### Endpoint operational info
The proxy may be asked for "operational info" on an endpoint. When this happens, the remote process shall receive a POST to `/NetworkDriver.EndpointOperInfo` of the form
{
"NetworkID": string,
"EndpointID": string
"NetworkID": string,
"EndpointID": string
}
where `NetworkID` and `EndpointID` have meanings as above. It must send a response of the form
{
"Value": { ... }
"Value": { ... }
}
where the value of the `Value` field is an arbitrary (possibly empty) map.
@@ -139,8 +137,8 @@ where the value of the `Value` field is an arbitrary (possibly empty) map.
When an endpoint is deleted, the remote process shall receive a POST to the URL `/NetworkDriver.DeleteEndpoint` with a body of the form
{
"NetworkID": string,
"EndpointID": string
"NetworkID": string,
"EndpointID": string
}
where `NetworkID` and `EndpointID` have meanings as above. A success response is empty:
@@ -152,10 +150,10 @@ where `NetworkID` and `EndpointID` have meanings as above. A success response is
When a sandbox is given an endpoint, the remote process shall receive a POST to the URL `NetworkDriver.Join` of the form
{
"NetworkID": string,
"EndpointID": string,
"SandboxKey": string,
"Options": { ... }
"NetworkID": string,
"EndpointID": string,
"SandboxKey": string,
"Options": { ... }
}
The `NetworkID` and `EndpointID` have meanings as above. The `SandboxKey` identifies the sandbox. `Options` is an arbitrary map as supplied to the proxy.
@@ -163,29 +161,24 @@ The `NetworkID` and `EndpointID` have meanings as above. The `SandboxKey` identi
The response must have the form
{
"InterfaceNames": [{
SrcName: string,
DstPrefix: string
}, ...],
"Gateway": string,
"GatewayIPv6": string,
"StaticRoutes": [{
"Destination": string,
"RouteType": int,
"NextHop": string,
"InterfaceID": int
}, ...]
"HostsPath": string,
"ResolvConfPath": string
"InterfaceName": {
SrcName: string,
DstPrefix: string
},
"Gateway": string,
"GatewayIPv6": string,
"StaticRoutes": [{
"Destination": string,
"RouteType": int,
"NextHop": string,
}, ...]
}
`Gateway` is optional and if supplied is an IP address as a string; e.g., `"192.168.0.1"`. `GatewayIPv6` is optional and if supplied is an IPv6 address as a string; e.g., `"fe80::7809:baff:fec6:7744"`. `HostsPath` is optional, as is `ResolvConfPath`.
`Gateway` is optional and if supplied is an IP address as a string; e.g., `"192.168.0.1"`. `GatewayIPv6` is optional and if supplied is an IPv6 address as a string; e.g., `"fe80::7809:baff:fec6:7744"`.
The entries in `InterfaceNames` represent veths that should be moved by LibNetwork into the sandbox; the `SrcName` is the name of the veth that the remote process created, and the `DstPrefix` is a prefix for the name the veth should have after it has been moved into the sandbox (LibNetwork will append an index to make sure the actual name does not collide with others).
The entries in `InterfaceName` represent actual OS level interfaces that should be moved by LibNetwork into the sandbox; the `SrcName` is the name of the OS level interface that the remote process created, and the `DstPrefix` is a prefix for the name the OS level interface should have after it has been moved into the sandbox (LibNetwork will append an index to make sure the actual name does not collide with others).
The position of the entries in the list must correspond to the interface IDs given in the response to `/NetworkDriver.CreateEndpoint` as described above. For example, if there were two `Interfaces` in the create endpoint response, with IDs `0` and `1`, then the `InterfaceNames` list would have the interface names respectively in positions `0` and `1`of the list. (For this reason it is recommended that interfaces are given sequential IDs starting with `0`.)
The entries in `"StaticRoutes"` represent routes that should be added to an interface once it has been moved into the sandbox. Since there may be zero or more routes for an interface, unlike the interface names they can be supplied in any order, and are marked with the `InterfaceID` of the corresponding interface.
The entries in `"StaticRoutes"` represent routes that should be added to an interface once it has been moved into the sandbox. Since there may be zero or more routes for an interface, unlike the interface name they can be supplied in any order.
Routes are either given a `RouteType` of `0` and a value for `NextHop`; or, a `RouteType` of `1` and no value for `NextHop`, meaning a connected route.
@@ -194,8 +187,8 @@ Routes are either given a `RouteType` of `0` and a value for `NextHop`; or, a `R
If the proxy is asked to remove an endpoint from a sandbox, the remote process shall receive a POST to the URL `/NetworkDriver.Leave` of the form
{
"NetworkID": string,
"EndpointID": string
"NetworkID": string,
"EndpointID": string
}
where `NetworkID` and `EndpointID` have meanings as above. The success response is empty: