Support for --publish-service flag in docker run
This commit makes use of the CNM model supported by LibNetwork and provides an ability to let a container to publish a specified service. Behind the scenes, if a service with the given name doesnt exist, it is automatically created on appropriate network and attach the container. Signed-off-by: Alessandro Boch <aboch@docker.com> Signed-off-by: Madhu Venugopal <madhu@docker.com> Upstream-commit: 1ac350a0ecfe9d28c82d6dff6a763a378ff9c472 Component: engine
This commit is contained in:
@@ -737,11 +737,23 @@ func (container *Container) buildCreateEndpointOptions() ([]libnetwork.EndpointO
|
||||
return createOptions, nil
|
||||
}
|
||||
|
||||
func createDefaultNetwork(controller libnetwork.NetworkController) (libnetwork.Network, error) {
|
||||
func parseService(controller libnetwork.NetworkController, service string) (string, string, string) {
|
||||
dn := controller.Config().Daemon.DefaultNetwork
|
||||
dd := controller.Config().Daemon.DefaultDriver
|
||||
|
||||
snd := strings.Split(service, ".")
|
||||
if len(snd) > 2 {
|
||||
return strings.Join(snd[:len(snd)-2], "."), snd[len(snd)-2], snd[len(snd)-1]
|
||||
}
|
||||
if len(snd) > 1 {
|
||||
return snd[0], snd[1], dd
|
||||
}
|
||||
return snd[0], dn, dd
|
||||
}
|
||||
|
||||
func createNetwork(controller libnetwork.NetworkController, dnet string, driver string) (libnetwork.Network, error) {
|
||||
createOptions := []libnetwork.NetworkOption{}
|
||||
genericOption := options.Generic{}
|
||||
dnet := controller.Config().Daemon.DefaultNetwork
|
||||
driver := controller.Config().Daemon.DefaultDriver
|
||||
|
||||
// Bridge driver is special due to legacy reasons
|
||||
if runconfig.NetworkMode(driver).IsBridge() {
|
||||
@@ -763,31 +775,53 @@ func (container *Container) AllocateNetwork() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var networkDriver string
|
||||
service := container.Config.PublishService
|
||||
networkName := mode.NetworkName()
|
||||
if mode.IsDefault() {
|
||||
networkName = controller.Config().Daemon.DefaultNetwork
|
||||
if service != "" {
|
||||
service, networkName, networkDriver = parseService(controller, service)
|
||||
} else {
|
||||
networkName = controller.Config().Daemon.DefaultNetwork
|
||||
networkDriver = controller.Config().Daemon.DefaultDriver
|
||||
}
|
||||
} else if service != "" {
|
||||
return fmt.Errorf("conflicting options: publishing a service and network mode")
|
||||
}
|
||||
|
||||
if service == "" {
|
||||
service = strings.Replace(container.Name, ".", "-", -1)
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
n, err := controller.NetworkByName(networkName)
|
||||
if err != nil {
|
||||
if !mode.IsDefault() {
|
||||
return fmt.Errorf("error locating network with name %s: %v", networkName, err)
|
||||
// Create Network automatically only in default mode
|
||||
if _, ok := err.(libnetwork.ErrNoSuchNetwork); !ok || !mode.IsDefault() {
|
||||
return err
|
||||
}
|
||||
if n, err = createDefaultNetwork(controller); err != nil {
|
||||
|
||||
if n, err = createNetwork(controller, networkName, networkDriver); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
createOptions, err := container.buildCreateEndpointOptions()
|
||||
ep, err := n.EndpointByName(service)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := err.(libnetwork.ErrNoSuchEndpoint); !ok {
|
||||
return err
|
||||
}
|
||||
|
||||
ep, err := n.CreateEndpoint(container.Name, createOptions...)
|
||||
if err != nil {
|
||||
return err
|
||||
createOptions, err := container.buildCreateEndpointOptions()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ep, err = n.CreateEndpoint(service, createOptions...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := container.updateNetworkSettings(n, ep); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user