Skip to content

Commit

Permalink
cleanup (and go fmt) of old debug logging since 17.06-ce and re-label…
Browse files Browse the repository at this point in the history
…ed all changes as follows -

- support sending hostname and domainname in IPAM
- support custom volume naming when using netapp volume driver
- use dashes as seperators for container names
- work in-progress DNS domainname changes
- de-duplicate DNS search domains
- add container "host" /etc/hosts entry equal to value of DOCKER_HOST_EXPORT_IP environment variable if defined
- cleanup duplicate ipvlan and macvlan network IDs during createNetwork (moby/libnetwork#2055)
- support optional skip of IPAM pool conflict checking
- set Swarm tasks to orphaned state if node becomes unavailable
- allow orphaned Swarm tasks assigned to a deleted node to start elseware
- Swarm tasks in an orphaned state should not be allowed to restart
- allow Swarm tasks in a remove state to be transitioned
- prevent oldTaskTimer from allowing the slot to be prematurely updated
- allow Swarm tasks to be cleaned up if they are in a pending state and are marked for removal
- support service level anti-affinity via label h3o-limitActiveServiceSlotsPerNode
  • Loading branch information
eyz committed Feb 9, 2018
1 parent ad7d1ef commit 2f97e75
Show file tree
Hide file tree
Showing 13 changed files with 409 additions and 32 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18.01.0-ce
18.01.0-eyz
4 changes: 4 additions & 0 deletions components/engine/api/types/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ type EndpointIPAMConfig struct {
IPv4Address string `json:",omitempty"`
IPv6Address string `json:",omitempty"`
LinkLocalIPs []string `json:",omitempty"`
// eyz START: support sending hostname and domainname in IPAM
Hostname string `json:",omitempty"`
Domainname string `json:",omitempty"`
// eyz END: support sending hostname and domainname in IPAM
}

// Copy makes a copy of the endpoint ipam config
Expand Down
9 changes: 8 additions & 1 deletion components/engine/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,11 @@ func (container *Container) BuildJoinOptions(n named) ([]libnetwork.EndpointOpti
return nil, err
}
joinOptions = append(joinOptions, libnetwork.CreateOptionAlias(name, alias))
// eyz START: add network alias which includes the container FQDN (Hostname + Domainname)
if container.Config.Domainname != "" {
joinOptions = append(joinOptions, libnetwork.CreateOptionAlias(name, container.Config.Hostname+"."+container.Config.Domainname))
}
// eyz STOP: add network alias which includes the container FQDN (Hostname + Domainname)
}
for k, v := range epConfig.DriverOpts {
joinOptions = append(joinOptions, libnetwork.EndpointOptionGeneric(options.Generic{k: v}))
Expand Down Expand Up @@ -759,8 +764,10 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC
return nil, errors.Errorf("Invalid IPv6 address: %s)", ipam.IPv6Address)
}

// eyz START: support sending hostname and domainname in IPAM
createOptions = append(createOptions,
libnetwork.CreateOptionIpam(ip, ip6, ipList, nil))
libnetwork.CreateOptionIpam(ip, ip6, ipList, ipam.Hostname, ipam.Domainname, nil))
// eyz END: support sending hostname and domainname in IPAM

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,13 @@ func (c *containerAdapter) createVolumes(ctx context.Context) error {
continue
}

// eyz START: support custom volume naming when using netapp volume driver
// Isaac (20171022): do not create netapp volumes here; we currently let them get created by the container.go code instead
if mount.VolumeOptions.DriverConfig.Name == "netapp" {
continue
}
// eyz END: support custom volume naming when using netapp volume driver

req := c.container.volumeCreateRequest(&mount)

// Check if this volume exists on the engine
Expand Down
100 changes: 98 additions & 2 deletions components/engine/daemon/cluster/executor/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
"errors"
"fmt"
"net"
// eyz START: support custom volume naming when using netapp volume driver
"regexp"
// eyz STOP: support custom volume naming when using netapp volume driver
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -131,7 +134,16 @@ func (c *containerConfig) name() string {
}

// fallback to service.slot.id.
return fmt.Sprintf("%s.%s.%s", c.task.ServiceAnnotations.Name, slot, c.task.ID)
// eyz START: support custom volume naming when using netapp volume driver, use dashes as seperators for container names
//return fmt.Sprintf("%s.%s.%s", c.task.ServiceAnnotations.Name, slot, c.task.ID)
// only override container name if we are using a netapp mount volume driver
if c.hasMountDriverName("netapp") {
return fmt.Sprintf("%s-%s", c.task.ServiceAnnotations.Name, slot)
} else {
return fmt.Sprintf("%s-%s-%s", c.task.ServiceAnnotations.Name, slot, c.task.ID)
}
// eyz END: support custom volume naming when using netapp volume driver, use dashes as seperators for container names

}

func (c *containerConfig) image() string {
Expand Down Expand Up @@ -208,6 +220,40 @@ func (c *containerConfig) config() *enginecontainer.Config {
Healthcheck: c.healthcheck(),
}

// eyz START: support custom volume naming when using netapp volume driver, use dashes as seperators for container names, work in-progress DNS domainname changes
// If we have a defined service name and slot ...
if c.task != nil && c.task.ServiceAnnotations.Name != "" && c.task.Slot > 0 {

slot := fmt.Sprint(c.task.Slot)
if slot == "" || c.task.Slot == 0 {
slot = c.task.NodeID
}

if c.hasMountDriverName("netapp") {
// ... and we're using a netapp mount volume driver, then set the Hostname to "SERVICENAME-SLOT"
config.Hostname = fmt.Sprintf("%s-%s", c.task.ServiceAnnotations.Name, slot)
} else {
// ... otherwise, set the Hostname "SERVICENAME-SLOT-TASKID"
config.Hostname = fmt.Sprintf("%s-%s-%s", c.task.ServiceAnnotations.Name, slot, c.task.ID)
}

///// testing START
stackNamespace, stackNamespaceExists := c.task.ServiceAnnotations.Labels["com.docker.stack.namespace"]
if stackNamespaceExists {
//config.Domainname = fmt.Sprintf("%s.swarm.DOMAIN.COM", stackNamespace)
// doesn't work
// config.Domainname = stackNamespace + "-test"
// config.Domainname = stackNamespace + ".swarm"
// works -
config.Domainname = stackNamespace
} else {
config.Domainname = "nostack"
}
logrus.Debugf("* engine/daemon/cluster/executor/container config() set config.Domainname to: %s", config.Domainname)
///// testing STOP
}
// eyz STOP: support custom volume naming when using netapp volume driver, use dashes as seperators for container names, work in-progress DNS domainname changes

if len(c.spec().Command) > 0 {
// If Command is provided, we replace the whole invocation with Command
// by replacing Entrypoint and specifying Cmd. Args is ignored in this
Expand Down Expand Up @@ -255,14 +301,51 @@ func (c *containerConfig) labels() map[string]string {
return labels
}

// eyz START: support custom volume naming when using netapp volume driver
// helper function to find if a mount volume driver name was found
func (c *containerConfig) hasMountDriverName(mountDriverName string) bool {
for _, mount := range c.spec().Mounts {
m := convertMount(mount)
if m.VolumeOptions != nil && m.VolumeOptions.DriverConfig != nil && m.VolumeOptions.DriverConfig.Name == mountDriverName {
return true
}
}
return false
}

// eyz END: support custom volume naming when using netapp volume driver

// eyz START: support custom volume naming when using netapp volume driver
func (c *containerConfig) mounts() []enginemount.Mount {
var r []enginemount.Mount
nonWordRegex, _ := regexp.Compile("[^a-zA-Z0-9]+")
for _, mount := range c.spec().Mounts {
r = append(r, convertMount(mount))
m := convertMount(mount)
if m.VolumeOptions != nil && m.VolumeOptions.DriverConfig != nil && m.VolumeOptions.DriverConfig.Name == "netapp" && c.task != nil && c.task.ServiceAnnotations.Name != "" && c.task.Slot > 0 {
slot := fmt.Sprint(c.task.Slot)
if slot == "" || c.task.Slot == 0 {
slot = c.task.NodeID
}

var newSourceRaw string
// if m.Source starts with c.task.ServiceAnnotations.Name, then don't include the c.task.ServiceAnnotations.Name prepend in the new volume Source; only the m.Source and slot, as c.task.ServiceAnnotations.Name would be redundant in this case
if strings.HasPrefix(m.Source, c.task.ServiceAnnotations.Name) {
newSourceRaw = fmt.Sprintf("%s_%s", m.Source, slot)
} else {
newSourceRaw = fmt.Sprintf("%s_%s_%s", c.task.ServiceAnnotations.Name, m.Source, slot)
}
// for compatibility with the NetApp Docker Volume Plugin, ensure all contiguous non-word characters are replaced with underscores
m.Source = nonWordRegex.ReplaceAllString(newSourceRaw, "_")
}
r = append(r, m)
//r = append(r, convertMount(mount))

}
return r
}

// eyz END: support custom volume naming when using netapp volume driver

func convertMount(m api.Mount) enginemount.Mount {
mount := enginemount.Mount{
Source: m.Source,
Expand Down Expand Up @@ -363,6 +446,19 @@ func (c *containerConfig) hostConfig() *enginecontainer.HostConfig {
hc.DNSOptions = c.spec().DNSConfig.Options
}

// eyz START: work in-progress DNS domainname changes
stackNamespace, stackNamespaceExists := c.task.ServiceAnnotations.Labels["com.docker.stack.namespace"]
if stackNamespaceExists {
//stackNamespaceSearchDomainPrepend := []string{fmt.Sprintf("%s.swarm.DOMAIN.COM", stackNamespace)}
stackNamespaceSearchDomainPrepend := []string{stackNamespace}
if len(hc.DNSSearch) > 0 {
hc.DNSSearch = append(stackNamespaceSearchDomainPrepend, hc.DNSSearch...)
} else {
hc.DNSSearch = stackNamespaceSearchDomainPrepend
}
}
// eyz STOP: work in-progress DNS domainname changes

c.applyPrivileges(hc)

// The format of extra hosts on swarmkit is specified in:
Expand Down
82 changes: 77 additions & 5 deletions components/engine/daemon/container_operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,43 @@ var (
getPortMapInfo = container.GetSandboxPortMapInfo
)

func (daemon *Daemon) getDNSSearchSettings(container *container.Container) []string {
if len(container.HostConfig.DNSSearch) > 0 {
return container.HostConfig.DNSSearch
// eyz START: de-duplicate DNS search domains
func removeDuplicates(elements []string) []string {
seen := map[string]bool{}
result := []string{}

for _, element := range elements {
if !seen[element] {
seen[element] = true
result = append(result, element)
}
}
return result
}

// eyz STOP: de-duplicate DNS search domains

// eyz START: de-duplicate DNS search domains
func (daemon *Daemon) getDNSSearchSettings(container *container.Container) []string {
/*
if len(container.HostConfig.DNSSearch) > 0 {
return container.HostConfig.DNSSearch
}
if len(daemon.configStore.DNSSearch) > 0 {
return daemon.configStore.DNSSearch
}
*/

if len(daemon.configStore.DNSSearch) > 0 {
return daemon.configStore.DNSSearch
if len(container.HostConfig.DNSSearch) > 0 || len(daemon.configStore.DNSSearch) > 0 {
return removeDuplicates(append(container.HostConfig.DNSSearch, daemon.configStore.DNSSearch...))
}

return nil
}

// eyz STOP: de-duplicate DNS search domains

func (daemon *Daemon) buildSandboxOptions(container *container.Container) ([]libnetwork.SandboxOption, error) {
var (
sboxOptions []libnetwork.SandboxOption
Expand Down Expand Up @@ -116,15 +141,51 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container) ([]lib
}
}

// eyz START: add container "host" /etc/hosts entry equal to value of DOCKER_HOST_EXPORT_IP environment variable if defined
// NOTE: if env var DOCKER_HOST_EXPORT_IP is set on the host, then
// 1) we intend to create a hosts entry of "host" with the value of DOCKER_HOST_EXPORT_IP -- dockerHostExportIpAppendHost will be set: true
// 2) we intend to persist this environment variable into each launched container
dockerHostExportIpVal, dockerHostExportIpEnvExported := os.LookupEnv("DOCKER_HOST_EXPORT_IP")
// dockerHostExportIpAppendHost defaults to true if dockerHostExportIpEnvExported
dockerHostExportIpAppendHost := dockerHostExportIpEnvExported
// eyz STOP: add container "host" /etc/hosts entry equal to value of DOCKER_HOST_EXPORT_IP environment variable if defined

for _, extraHost := range container.HostConfig.ExtraHosts {
// allow IPv6 addresses in extra hosts; only split on first ":"
if _, err := opts.ValidateExtraHost(extraHost); err != nil {
return nil, err
}
parts := strings.SplitN(extraHost, ":", 2)

// eyz START: add container "host" /etc/hosts entry equal to value of DOCKER_HOST_EXPORT_IP environment variable if defined
// NOTE: if an extraHost entry for "host" (case-insensitive) has been specified, then we will not append the DOCKER_HOST_EXPORT_IP -- letting this extraHost of "host" override DOCKER_HOST_EXPORT_IP even if it is set
if strings.ToLower(parts[0]) == "host" {
dockerHostExportIpAppendHost = false
}
// eyz STOP: add container "host" /etc/hosts entry equal to value of DOCKER_HOST_EXPORT_IP environment variable if defined

sboxOptions = append(sboxOptions, libnetwork.OptionExtraHost(parts[0], parts[1]))
}

// eyz START: add container "host" /etc/hosts entry equal to value of DOCKER_HOST_EXPORT_IP environment variable if defined
// NOTE: if env var DOCKER_HOST_EXPORT_IP is set on the host, then create a hosts entry of "host" with the value of DOCKER_HOST_EXPORT_IP
if dockerHostExportIpAppendHost {
sboxOptions = append(sboxOptions, libnetwork.OptionExtraHost("host", dockerHostExportIpVal))
}

if dockerHostExportIpEnvExported {
dockerHostExportIpEnvInConfig := false
for _, envValue := range container.Config.Env {
if strings.HasPrefix(strings.ToUpper(envValue), "DOCKER_HOST_EXPORT_IP=") {
dockerHostExportIpEnvInConfig = true
}
}
if !dockerHostExportIpEnvInConfig {
container.Config.Env = append(container.Config.Env, fmt.Sprintf("DOCKER_HOST_EXPORT_IP=%s", dockerHostExportIpVal))
}
}
// eyz STOP: add container "host" /etc/hosts entry equal to value of DOCKER_HOST_EXPORT_IP environment variable if defined

if container.HostConfig.PortBindings != nil {
for p, b := range container.HostConfig.PortBindings {
bindings[p] = []nat.PortBinding{}
Expand Down Expand Up @@ -719,6 +780,17 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName
}
}

// eyz START: support sending hostname and domainname in IPAM
if endpointConfig.IPAMConfig != nil {
if container.Config.Hostname != "" {
endpointConfig.IPAMConfig.Hostname = container.Config.Hostname
}
if container.Config.Domainname != "" {
endpointConfig.IPAMConfig.Domainname = container.Config.Domainname
}
}
// eyz END: support sending hostname and domainname in IPAM

err = daemon.updateNetworkConfig(container, n, endpointConfig, updateSettings)
if err != nil {
return err
Expand Down

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

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

Loading

0 comments on commit 2f97e75

Please sign in to comment.