mirror of
https://github.com/docker/cli.git
synced 2026-08-24 10:05:37 -05:00
Compare commits
33
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7e417335c | ||
|
|
bb8c1249be | ||
|
|
19db96873d | ||
|
|
5303070e05 | ||
|
|
672ea2ab2a | ||
|
|
eb990142ac | ||
|
|
55d38f9cd6 | ||
|
|
29e8b830bb | ||
|
|
2df40e7778 | ||
|
|
ef8fe31895 | ||
|
|
77c3cf33ae | ||
|
|
35e513d55c | ||
|
|
cb764708de | ||
|
|
5578ebd2a2 | ||
|
|
bb23c93d28 | ||
|
|
073d80bc46 | ||
|
|
91fd299b2c | ||
|
|
a0040598f2 | ||
|
|
7219fddea4 | ||
|
|
29fcd5dfae | ||
|
|
9600fb4e78 | ||
|
|
0f80f28c1a | ||
|
|
29e7f7b8c9 | ||
|
|
4c2cf22362 | ||
|
|
afcb08cfb0 | ||
|
|
46a9d6b041 | ||
|
|
b8c7116a23 | ||
|
|
b089783b38 | ||
|
|
605ffe91cf | ||
|
|
eb837fd7bc | ||
|
|
475c218fd7 | ||
|
|
f2eb8b825b | ||
|
|
1891675559 |
@@ -7,6 +7,11 @@ be found.
|
||||
|
||||
## 17.06.0-ce (2017-06-19)
|
||||
|
||||
**NOTE**: Docker 17.06 by default disables communication with legacy (v1) registries. If you
|
||||
require interaction with registries that have not yet migrated to the v2 protocol, set the
|
||||
`--disable-legacy-registry=false` daemon option. Interaction with v1 registries will be removed
|
||||
in Docker 17.12.
|
||||
|
||||
### Builder
|
||||
|
||||
+ Add `--iidfile` option to docker build. It allows specifying a location where to save the resulting image ID
|
||||
@@ -29,6 +34,7 @@ be found.
|
||||
- Correctly handle a Docker daemon without registry info [#docker/cli/126](https://github.com/docker/cli/pull/126)
|
||||
+ Allow --detach and --quiet flags when using --rollback [#docker/cli/144](https://github.com/docker/cli/pull/144)
|
||||
+ Remove deprecated `--email` flag from `docker login` [#docker/cli/143](https://github.com/docker/cli/pull/143)
|
||||
* Adjusted `docker stats` memory output [#docker/cli/80](https://github.com/docker/cli/pull/80)
|
||||
|
||||
### Distribution
|
||||
|
||||
@@ -44,6 +50,7 @@ be found.
|
||||
+ Add Support swarm-mode services with node-local networks such as macvlan, ipvlan, bridge, host [#32981](https://github.com/moby/moby/pull/32981)
|
||||
+ Pass driver-options to network drivers on service creation [#32981] (https://github.com/moby/moby/pull/33130)
|
||||
+ Isolate Swarm Control-plane traffic from Application data traffic using --data-path-addr [#32717] (https://github.com/moby/moby/pull/32717)
|
||||
* Several improvments to Service Discovery [#docker/libnetwork/1796](https://github.com/docker/libnetwork/pull/1796)
|
||||
|
||||
### Packaging
|
||||
|
||||
@@ -89,6 +96,11 @@ be found.
|
||||
- Fix possible hang when joining fails [#docker-ce/19](https://github.com/docker/docker-ce/pull/19)
|
||||
- Fix an issue preventing external CA to be accepted [#33341](https://github.com/moby/moby/pull/33341)
|
||||
- Fix possible orchestration panic in mixed version clusters [#swarmkit/2233](https://github.com/docker/swarmkit/pull/2233)
|
||||
- Avoid assigning duplicate IPs during initialization [#swarmkit/2237](https://github.com/docker/swarmkit/pull/2237)
|
||||
|
||||
### Deprecation
|
||||
|
||||
* Disable legacy registry (v1) by default [#33629](https://github.com/moby/moby/pull/33629)
|
||||
|
||||
## 17.05.0-ce (2017-05-04)
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
17.06.0-ce-rc3
|
||||
17.06.0-ce-rc5
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/compose/convert"
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
@@ -34,6 +35,13 @@ type fakeClient struct {
|
||||
configRemoveFunc func(configID string) error
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ServerVersion(ctx context.Context) (types.Version, error) {
|
||||
return types.Version{
|
||||
Version: "docker-dev",
|
||||
APIVersion: api.DefaultVersion,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||
if cli.serviceListFunc != nil {
|
||||
return cli.serviceListFunc(options)
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/net/context"
|
||||
@@ -55,10 +56,20 @@ func runRemove(dockerCli command.Cli, opts removeOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
configs, err := getStackConfigs(ctx, client, namespace)
|
||||
var configs []swarm.Config
|
||||
|
||||
version, err := client.ServerVersion(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if versions.LessThan(version.APIVersion, "1.30") {
|
||||
fmt.Fprintf(dockerCli.Err(), `WARNING: ignoring "configs" (requires API version 1.30, but the Docker daemon API version is %s)`, version.APIVersion)
|
||||
} else {
|
||||
configs, err = getStackConfigs(ctx, client, namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(services)+len(networks)+len(secrets)+len(configs) == 0 {
|
||||
fmt.Fprintf(dockerCli.Out(), "Nothing found in stack: %s\n", namespace)
|
||||
|
||||
@@ -1 +1 @@
|
||||
17.06.0-ce-rc3
|
||||
17.06.0-ce-rc5
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/pkg/pools"
|
||||
"github.com/docker/docker/pkg/promise"
|
||||
"github.com/docker/docker/pkg/term"
|
||||
)
|
||||
@@ -86,7 +87,7 @@ func (c *Config) CopyStreams(ctx context.Context, cfg *AttachConfig) chan error
|
||||
if cfg.TTY {
|
||||
_, err = copyEscapable(cfg.CStdin, cfg.Stdin, cfg.DetachKeys)
|
||||
} else {
|
||||
_, err = io.Copy(cfg.CStdin, cfg.Stdin)
|
||||
_, err = pools.Copy(cfg.CStdin, cfg.Stdin)
|
||||
}
|
||||
if err == io.ErrClosedPipe {
|
||||
err = nil
|
||||
@@ -116,7 +117,7 @@ func (c *Config) CopyStreams(ctx context.Context, cfg *AttachConfig) chan error
|
||||
}
|
||||
|
||||
logrus.Debugf("attach: %s: begin", name)
|
||||
_, err := io.Copy(stream, streamPipe)
|
||||
_, err := pools.Copy(stream, streamPipe)
|
||||
if err == io.ErrClosedPipe {
|
||||
err = nil
|
||||
}
|
||||
@@ -174,5 +175,5 @@ func copyEscapable(dst io.Writer, src io.ReadCloser, keys []byte) (written int64
|
||||
pr := term.NewEscapeProxy(src, keys)
|
||||
defer src.Close()
|
||||
|
||||
return io.Copy(dst, pr)
|
||||
return pools.Copy(dst, pr)
|
||||
}
|
||||
|
||||
@@ -31,9 +31,10 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm {
|
||||
AutoLockManagers: c.Spec.EncryptionConfig.AutoLockManagers,
|
||||
},
|
||||
CAConfig: types.CAConfig{
|
||||
// do not include the signing CA key (it should already be redacted via the swarm APIs)
|
||||
SigningCACert: string(c.Spec.CAConfig.SigningCACert),
|
||||
ForceRotate: c.Spec.CAConfig.ForceRotate,
|
||||
// do not include the signing CA cert or key (it should already be redacted via the swarm APIs) -
|
||||
// the key because it's secret, and the cert because otherwise doing a get + update on the spec
|
||||
// can cause issues because the key would be missing and the cert wouldn't
|
||||
ForceRotate: c.Spec.CAConfig.ForceRotate,
|
||||
},
|
||||
},
|
||||
TLSInfo: types.TLSInfo{
|
||||
|
||||
@@ -966,20 +966,21 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) {
|
||||
for j := 0; j < 18; j++ {
|
||||
info, err := m.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(info.Cluster.Spec.CAConfig.SigningCACert, checker.Equals, expectedCert)
|
||||
// the desired CA key is always redacted
|
||||
|
||||
// the desired CA cert and key is always redacted
|
||||
c.Assert(info.Cluster.Spec.CAConfig.SigningCAKey, checker.Equals, "")
|
||||
c.Assert(info.Cluster.Spec.CAConfig.SigningCACert, checker.Equals, "")
|
||||
|
||||
clusterTLSInfo = info.Cluster.TLSInfo
|
||||
|
||||
if !info.Cluster.RootRotationInProgress {
|
||||
// if root rotation is done and the trust root has changed, we don't have to poll anymore
|
||||
if !info.Cluster.RootRotationInProgress && clusterTLSInfo.TrustRoot != currentTrustRoot {
|
||||
break
|
||||
}
|
||||
|
||||
// root rotation not done
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
}
|
||||
c.Assert(clusterTLSInfo.TrustRoot, checker.Not(checker.Equals), currentTrustRoot)
|
||||
if cert != nil {
|
||||
c.Assert(clusterTLSInfo.TrustRoot, checker.Equals, expectedCert)
|
||||
}
|
||||
|
||||
@@ -17,15 +17,16 @@ import (
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
)
|
||||
|
||||
const buffer32K = 32 * 1024
|
||||
|
||||
var (
|
||||
// BufioReader32KPool is a pool which returns bufio.Reader with a 32K buffer.
|
||||
BufioReader32KPool = newBufioReaderPoolWithSize(buffer32K)
|
||||
// BufioWriter32KPool is a pool which returns bufio.Writer with a 32K buffer.
|
||||
BufioWriter32KPool = newBufioWriterPoolWithSize(buffer32K)
|
||||
buffer32KPool = newBufferPoolWithSize(buffer32K)
|
||||
)
|
||||
|
||||
const buffer32K = 32 * 1024
|
||||
|
||||
// BufioReaderPool is a bufio reader that uses sync.Pool.
|
||||
type BufioReaderPool struct {
|
||||
pool sync.Pool
|
||||
@@ -54,11 +55,31 @@ func (bufPool *BufioReaderPool) Put(b *bufio.Reader) {
|
||||
bufPool.pool.Put(b)
|
||||
}
|
||||
|
||||
type bufferPool struct {
|
||||
pool sync.Pool
|
||||
}
|
||||
|
||||
func newBufferPoolWithSize(size int) *bufferPool {
|
||||
return &bufferPool{
|
||||
pool: sync.Pool{
|
||||
New: func() interface{} { return make([]byte, size) },
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (bp *bufferPool) Get() []byte {
|
||||
return bp.pool.Get().([]byte)
|
||||
}
|
||||
|
||||
func (bp *bufferPool) Put(b []byte) {
|
||||
bp.pool.Put(b)
|
||||
}
|
||||
|
||||
// Copy is a convenience wrapper which uses a buffer to avoid allocation in io.Copy.
|
||||
func Copy(dst io.Writer, src io.Reader) (written int64, err error) {
|
||||
buf := BufioReader32KPool.Get(src)
|
||||
written, err = io.Copy(dst, buf)
|
||||
BufioReader32KPool.Put(buf)
|
||||
buf := buffer32KPool.Get()
|
||||
written, err = io.CopyBuffer(dst, src, buf)
|
||||
buffer32KPool.Put(buf)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -159,3 +159,8 @@ func TestNewWriteCloserWrapperWithAWriteCloser(t *testing.T) {
|
||||
t.Fatalf("The ReaderCloser should have been closed, it is not.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBufferPoolPutAndGet(t *testing.T) {
|
||||
buf := buffer32KPool.Get()
|
||||
buffer32KPool.Put(buf)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ github.com/imdario/mergo 0.2.1
|
||||
golang.org/x/sync de49d9dcd27d4f764488181bea099dfe6179bcf0
|
||||
|
||||
#get libnetwork packages
|
||||
github.com/docker/libnetwork 4f5310be349d9299f6cab6d5822312f00cfa965c
|
||||
github.com/docker/libnetwork 20bf4e23da1bb3f9d3dc70e4cf531b84c45947bd
|
||||
github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894
|
||||
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
|
||||
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
||||
@@ -107,7 +107,7 @@ github.com/containerd/containerd cfb82a876ecc11b5ca0977d1733adbe58599088a
|
||||
github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
|
||||
|
||||
# cluster
|
||||
github.com/docker/swarmkit 6083c7689ed00a6f2d67941443603df69c2ff6ba
|
||||
github.com/docker/swarmkit 9edb625cfb4407da456cc7fc479db6d824fe81f3
|
||||
github.com/gogo/protobuf v0.4
|
||||
github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
|
||||
github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e
|
||||
|
||||
+10
-9
@@ -648,13 +648,13 @@ func (ep *endpoint) addServiceInfoToCluster(sb *sandbox) error {
|
||||
TaskAliases: ep.myAliases,
|
||||
EndpointIP: ep.Iface().Address().IP.String(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if agent != nil {
|
||||
if err := agent.networkDB.CreateEntry(libnetworkEPTable, n.ID(), ep.ID(), buf); err != nil {
|
||||
logrus.Warnf("addServiceInfoToCluster NetworkDB CreateEntry failed for %s %s err:%s", ep.id, n.id, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -686,6 +686,13 @@ func (ep *endpoint) deleteServiceInfoFromCluster(sb *sandbox, method string) err
|
||||
name = ep.MyAliases()[0]
|
||||
}
|
||||
|
||||
if agent != nil {
|
||||
// First delete from networkDB then locally
|
||||
if err := agent.networkDB.DeleteEntry(libnetworkEPTable, n.ID(), ep.ID()); err != nil {
|
||||
logrus.Warnf("deleteServiceInfoFromCluster NetworkDB DeleteEntry failed for %s %s err:%s", ep.id, n.id, err)
|
||||
}
|
||||
}
|
||||
|
||||
if ep.Iface().Address() != nil {
|
||||
if ep.svcID != "" {
|
||||
// This is a task part of a service
|
||||
@@ -693,7 +700,7 @@ func (ep *endpoint) deleteServiceInfoFromCluster(sb *sandbox, method string) err
|
||||
if n.ingress {
|
||||
ingressPorts = ep.ingressPorts
|
||||
}
|
||||
if err := c.rmServiceBinding(ep.svcName, ep.svcID, n.ID(), ep.ID(), name, ep.virtualIP, ingressPorts, ep.svcAliases, ep.myAliases, ep.Iface().Address().IP, "deleteServiceInfoFromCluster"); err != nil {
|
||||
if err := c.rmServiceBinding(ep.svcName, ep.svcID, n.ID(), ep.ID(), name, ep.virtualIP, ingressPorts, ep.svcAliases, ep.myAliases, ep.Iface().Address().IP, "deleteServiceInfoFromCluster", true); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
@@ -704,12 +711,6 @@ func (ep *endpoint) deleteServiceInfoFromCluster(sb *sandbox, method string) err
|
||||
}
|
||||
}
|
||||
|
||||
if agent != nil {
|
||||
if err := agent.networkDB.DeleteEntry(libnetworkEPTable, n.ID(), ep.ID()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Debugf("deleteServiceInfoFromCluster from %s END for %s %s", method, ep.svcName, ep.ID())
|
||||
|
||||
return nil
|
||||
@@ -900,7 +901,7 @@ func (c *controller) handleEpTableEvent(ev events.Event) {
|
||||
logrus.Debugf("handleEpTableEvent DEL %s R:%v", isAdd, eid, epRec)
|
||||
if svcID != "" {
|
||||
// This is a remote task part of a service
|
||||
if err := c.rmServiceBinding(svcName, svcID, nid, eid, containerName, vip, ingressPorts, serviceAliases, taskAliases, ip, "handleEpTableEvent"); err != nil {
|
||||
if err := c.rmServiceBinding(svcName, svcID, nid, eid, containerName, vip, ingressPorts, serviceAliases, taskAliases, ip, "handleEpTableEvent", true); err != nil {
|
||||
logrus.Errorf("failed removing service binding for %s epRec:%v err:%s", eid, epRec, err)
|
||||
return
|
||||
}
|
||||
|
||||
+22
-10
@@ -10,24 +10,26 @@ import (
|
||||
type SetMatrix interface {
|
||||
// Get returns the members of the set for a specific key as a slice.
|
||||
Get(key string) ([]interface{}, bool)
|
||||
// Contains is used to verify is an element is in a set for a specific key
|
||||
// Contains is used to verify if an element is in a set for a specific key
|
||||
// returns true if the element is in the set
|
||||
// returns true if there is a set for the key
|
||||
Contains(key string, value interface{}) (bool, bool)
|
||||
// Insert inserts the mapping between the IP and the endpoint identifier
|
||||
// returns true if the mapping was not present, false otherwise
|
||||
// returns also the number of endpoints associated to the IP
|
||||
// Insert inserts the value in the set of a key
|
||||
// returns true if the value is inserted (was not already in the set), false otherwise
|
||||
// returns also the length of the set for the key
|
||||
Insert(key string, value interface{}) (bool, int)
|
||||
// Remove removes the mapping between the IP and the endpoint identifier
|
||||
// returns true if the mapping was deleted, false otherwise
|
||||
// returns also the number of endpoints associated to the IP
|
||||
// Remove removes the value in the set for a specific key
|
||||
// returns true if the value is deleted, false otherwise
|
||||
// returns also the length of the set for the key
|
||||
Remove(key string, value interface{}) (bool, int)
|
||||
// Cardinality returns the number of elements in the set of a specfic key
|
||||
// returns false if the key is not in the map
|
||||
// Cardinality returns the number of elements in the set for a key
|
||||
// returns false if the set is not present
|
||||
Cardinality(key string) (int, bool)
|
||||
// String returns the string version of the set, empty otherwise
|
||||
// returns false if the key is not in the map
|
||||
// returns false if the set is not present
|
||||
String(key string) (string, bool)
|
||||
// Returns all the keys in the map
|
||||
Keys() []string
|
||||
}
|
||||
|
||||
type setMatrix struct {
|
||||
@@ -121,3 +123,13 @@ func (s *setMatrix) String(key string) (string, bool) {
|
||||
}
|
||||
return set.String(), ok
|
||||
}
|
||||
|
||||
func (s *setMatrix) Keys() []string {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
keys := make([]string, 0, len(s.matrix))
|
||||
for k := range s.matrix {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
+93
-69
@@ -92,12 +92,20 @@ type EndpointWalker func(ep Endpoint) bool
|
||||
// Its an indication to defer PTR queries also to that external server.
|
||||
type ipInfo struct {
|
||||
name string
|
||||
serviceID string
|
||||
extResolver bool
|
||||
}
|
||||
|
||||
// svcMapEntry is the body of the element into the svcMap
|
||||
// The ip is a string because the SetMatrix does not accept non hashable values
|
||||
type svcMapEntry struct {
|
||||
ip string
|
||||
serviceID string
|
||||
}
|
||||
|
||||
type svcInfo struct {
|
||||
svcMap map[string][]net.IP
|
||||
svcIPv6Map map[string][]net.IP
|
||||
svcMap common.SetMatrix
|
||||
svcIPv6Map common.SetMatrix
|
||||
ipMap common.SetMatrix
|
||||
service map[string][]servicePorts
|
||||
}
|
||||
@@ -933,6 +941,9 @@ func (n *network) delete(force bool) error {
|
||||
id := n.id
|
||||
n.Unlock()
|
||||
|
||||
c.networkLocker.Lock(id)
|
||||
defer c.networkLocker.Unlock(id)
|
||||
|
||||
n, err := c.getNetworkFromStore(id)
|
||||
if err != nil {
|
||||
return &UnknownNetworkError{name: name, id: id}
|
||||
@@ -991,12 +1002,6 @@ func (n *network) delete(force bool) error {
|
||||
|
||||
c.cleanupServiceBindings(n.ID())
|
||||
|
||||
// The network had been left, the service discovery can be cleaned up
|
||||
c.Lock()
|
||||
logrus.Debugf("network %s delete, clean svcRecords", n.id)
|
||||
delete(c.svcRecords, n.id)
|
||||
c.Unlock()
|
||||
|
||||
removeFromStore:
|
||||
// deleteFromStore performs an atomic delete operation and the
|
||||
// network.epCnt will help prevent any possible
|
||||
@@ -1070,6 +1075,9 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi
|
||||
ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}}
|
||||
ep.id = stringid.GenerateRandomID()
|
||||
|
||||
n.ctrlr.networkLocker.Lock(n.id)
|
||||
defer n.ctrlr.networkLocker.Unlock(n.id)
|
||||
|
||||
// Initialize ep.network with a possibly stale copy of n. We need this to get network from
|
||||
// store. But once we get it from store we will have the most uptodate copy possibly.
|
||||
ep.network = n
|
||||
@@ -1228,75 +1236,77 @@ func (n *network) updateSvcRecord(ep *endpoint, localEps []*endpoint, isAdd bool
|
||||
ipv6 = iface.AddressIPv6().IP
|
||||
}
|
||||
|
||||
serviceID := ep.svcID
|
||||
if serviceID == "" {
|
||||
serviceID = ep.ID()
|
||||
}
|
||||
if isAdd {
|
||||
// If anonymous endpoint has an alias use the first alias
|
||||
// for ip->name mapping. Not having the reverse mapping
|
||||
// breaks some apps
|
||||
if ep.isAnonymous() {
|
||||
if len(myAliases) > 0 {
|
||||
n.addSvcRecords(ep.ID(), myAliases[0], iface.Address().IP, ipv6, true, "updateSvcRecord")
|
||||
n.addSvcRecords(ep.ID(), myAliases[0], serviceID, iface.Address().IP, ipv6, true, "updateSvcRecord")
|
||||
}
|
||||
} else {
|
||||
n.addSvcRecords(ep.ID(), epName, iface.Address().IP, ipv6, true, "updateSvcRecord")
|
||||
n.addSvcRecords(ep.ID(), epName, serviceID, iface.Address().IP, ipv6, true, "updateSvcRecord")
|
||||
}
|
||||
for _, alias := range myAliases {
|
||||
n.addSvcRecords(ep.ID(), alias, iface.Address().IP, ipv6, false, "updateSvcRecord")
|
||||
n.addSvcRecords(ep.ID(), alias, serviceID, iface.Address().IP, ipv6, false, "updateSvcRecord")
|
||||
}
|
||||
} else {
|
||||
if ep.isAnonymous() {
|
||||
if len(myAliases) > 0 {
|
||||
n.deleteSvcRecords(ep.ID(), myAliases[0], iface.Address().IP, ipv6, true, "updateSvcRecord")
|
||||
n.deleteSvcRecords(ep.ID(), myAliases[0], serviceID, iface.Address().IP, ipv6, true, "updateSvcRecord")
|
||||
}
|
||||
} else {
|
||||
n.deleteSvcRecords(ep.ID(), epName, iface.Address().IP, ipv6, true, "updateSvcRecord")
|
||||
n.deleteSvcRecords(ep.ID(), epName, serviceID, iface.Address().IP, ipv6, true, "updateSvcRecord")
|
||||
}
|
||||
for _, alias := range myAliases {
|
||||
n.deleteSvcRecords(ep.ID(), alias, iface.Address().IP, ipv6, false, "updateSvcRecord")
|
||||
n.deleteSvcRecords(ep.ID(), alias, serviceID, iface.Address().IP, ipv6, false, "updateSvcRecord")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addIPToName(ipMap common.SetMatrix, name string, ip net.IP) {
|
||||
func addIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) {
|
||||
reverseIP := netutils.ReverseIP(ip.String())
|
||||
ipMap.Insert(reverseIP, ipInfo{
|
||||
name: name,
|
||||
name: name,
|
||||
serviceID: serviceID,
|
||||
})
|
||||
}
|
||||
|
||||
func addNameToIP(svcMap map[string][]net.IP, name string, epIP net.IP) {
|
||||
ipList := svcMap[name]
|
||||
for _, ip := range ipList {
|
||||
if ip.Equal(epIP) {
|
||||
return
|
||||
}
|
||||
}
|
||||
svcMap[name] = append(svcMap[name], epIP)
|
||||
func delIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) {
|
||||
reverseIP := netutils.ReverseIP(ip.String())
|
||||
ipMap.Remove(reverseIP, ipInfo{
|
||||
name: name,
|
||||
serviceID: serviceID,
|
||||
})
|
||||
}
|
||||
|
||||
func delNameToIP(svcMap map[string][]net.IP, name string, epIP net.IP) {
|
||||
ipList := svcMap[name]
|
||||
for i, ip := range ipList {
|
||||
if ip.Equal(epIP) {
|
||||
ipList = append(ipList[:i], ipList[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
svcMap[name] = ipList
|
||||
|
||||
if len(ipList) == 0 {
|
||||
delete(svcMap, name)
|
||||
}
|
||||
func addNameToIP(svcMap common.SetMatrix, name, serviceID string, epIP net.IP) {
|
||||
svcMap.Insert(name, svcMapEntry{
|
||||
ip: epIP.String(),
|
||||
serviceID: serviceID,
|
||||
})
|
||||
}
|
||||
|
||||
func (n *network) addSvcRecords(eID, name string, epIP net.IP, epIPv6 net.IP, ipMapUpdate bool, method string) {
|
||||
func delNameToIP(svcMap common.SetMatrix, name, serviceID string, epIP net.IP) {
|
||||
svcMap.Remove(name, svcMapEntry{
|
||||
ip: epIP.String(),
|
||||
serviceID: serviceID,
|
||||
})
|
||||
}
|
||||
|
||||
func (n *network) addSvcRecords(eID, name, serviceID string, epIP, epIPv6 net.IP, ipMapUpdate bool, method string) {
|
||||
// Do not add service names for ingress network as this is a
|
||||
// routing only network
|
||||
if n.ingress {
|
||||
return
|
||||
}
|
||||
|
||||
logrus.Debugf("%s (%s).addSvcRecords(%s, %s, %s, %t) %s", eID, n.ID()[0:7], name, epIP, epIPv6, ipMapUpdate, method)
|
||||
logrus.Debugf("%s (%s).addSvcRecords(%s, %s, %s, %t) %s sid:%s", eID, n.ID()[0:7], name, epIP, epIPv6, ipMapUpdate, method, serviceID)
|
||||
|
||||
c := n.getController()
|
||||
c.Lock()
|
||||
@@ -1305,34 +1315,34 @@ func (n *network) addSvcRecords(eID, name string, epIP net.IP, epIPv6 net.IP, ip
|
||||
sr, ok := c.svcRecords[n.ID()]
|
||||
if !ok {
|
||||
sr = svcInfo{
|
||||
svcMap: make(map[string][]net.IP),
|
||||
svcIPv6Map: make(map[string][]net.IP),
|
||||
svcMap: common.NewSetMatrix(),
|
||||
svcIPv6Map: common.NewSetMatrix(),
|
||||
ipMap: common.NewSetMatrix(),
|
||||
}
|
||||
c.svcRecords[n.ID()] = sr
|
||||
}
|
||||
|
||||
if ipMapUpdate {
|
||||
addIPToName(sr.ipMap, name, epIP)
|
||||
addIPToName(sr.ipMap, name, serviceID, epIP)
|
||||
if epIPv6 != nil {
|
||||
addIPToName(sr.ipMap, name, epIPv6)
|
||||
addIPToName(sr.ipMap, name, serviceID, epIPv6)
|
||||
}
|
||||
}
|
||||
|
||||
addNameToIP(sr.svcMap, name, epIP)
|
||||
addNameToIP(sr.svcMap, name, serviceID, epIP)
|
||||
if epIPv6 != nil {
|
||||
addNameToIP(sr.svcIPv6Map, name, epIPv6)
|
||||
addNameToIP(sr.svcIPv6Map, name, serviceID, epIPv6)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *network) deleteSvcRecords(eID, name string, epIP net.IP, epIPv6 net.IP, ipMapUpdate bool, method string) {
|
||||
func (n *network) deleteSvcRecords(eID, name, serviceID string, epIP net.IP, epIPv6 net.IP, ipMapUpdate bool, method string) {
|
||||
// Do not delete service names from ingress network as this is a
|
||||
// routing only network
|
||||
if n.ingress {
|
||||
return
|
||||
}
|
||||
|
||||
logrus.Debugf("%s (%s).deleteSvcRecords(%s, %s, %s, %t) %s", eID, n.ID()[0:7], name, epIP, epIPv6, ipMapUpdate, method)
|
||||
logrus.Debugf("%s (%s).deleteSvcRecords(%s, %s, %s, %t) %s sid:%s ", eID, n.ID()[0:7], name, epIP, epIPv6, ipMapUpdate, method, serviceID)
|
||||
|
||||
c := n.getController()
|
||||
c.Lock()
|
||||
@@ -1344,21 +1354,17 @@ func (n *network) deleteSvcRecords(eID, name string, epIP net.IP, epIPv6 net.IP,
|
||||
}
|
||||
|
||||
if ipMapUpdate {
|
||||
sr.ipMap.Remove(netutils.ReverseIP(epIP.String()), ipInfo{
|
||||
name: name,
|
||||
})
|
||||
delIPToName(sr.ipMap, name, serviceID, epIP)
|
||||
|
||||
if epIPv6 != nil {
|
||||
sr.ipMap.Remove(netutils.ReverseIP(epIPv6.String()), ipInfo{
|
||||
name: name,
|
||||
})
|
||||
delIPToName(sr.ipMap, name, serviceID, epIPv6)
|
||||
}
|
||||
}
|
||||
|
||||
delNameToIP(sr.svcMap, name, epIP)
|
||||
delNameToIP(sr.svcMap, name, serviceID, epIP)
|
||||
|
||||
if epIPv6 != nil {
|
||||
delNameToIP(sr.svcIPv6Map, name, epIPv6)
|
||||
delNameToIP(sr.svcIPv6Map, name, serviceID, epIPv6)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1376,19 +1382,31 @@ func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record {
|
||||
|
||||
n.ctrlr.Lock()
|
||||
defer n.ctrlr.Unlock()
|
||||
sr, _ := n.ctrlr.svcRecords[n.id]
|
||||
sr, ok := n.ctrlr.svcRecords[n.id]
|
||||
if !ok || sr.svcMap == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for h, ip := range sr.svcMap {
|
||||
if strings.Split(h, ".")[0] == epName {
|
||||
svcMapKeys := sr.svcMap.Keys()
|
||||
// Loop on service names on this network
|
||||
for _, k := range svcMapKeys {
|
||||
if strings.Split(k, ".")[0] == epName {
|
||||
continue
|
||||
}
|
||||
if len(ip) == 0 {
|
||||
logrus.Warnf("Found empty list of IP addresses for service %s on network %s (%s)", h, n.name, n.id)
|
||||
// Get all the IPs associated to this service
|
||||
mapEntryList, ok := sr.svcMap.Get(k)
|
||||
if !ok {
|
||||
// The key got deleted
|
||||
continue
|
||||
}
|
||||
if len(mapEntryList) == 0 {
|
||||
logrus.Warnf("Found empty list of IP addresses for service %s on network %s (%s)", k, n.name, n.id)
|
||||
continue
|
||||
}
|
||||
|
||||
recs = append(recs, etchosts.Record{
|
||||
Hosts: h,
|
||||
IP: ip[0].String(),
|
||||
Hosts: k,
|
||||
IP: mapEntryList[0].(svcMapEntry).ip,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1845,8 +1863,7 @@ func (n *network) ResolveName(req string, ipType int) ([]net.IP, bool) {
|
||||
}
|
||||
|
||||
req = strings.TrimSuffix(req, ".")
|
||||
var ip []net.IP
|
||||
ip, ok = sr.svcMap[req]
|
||||
ipSet, ok := sr.svcMap.Get(req)
|
||||
|
||||
if ipType == types.IPv6 {
|
||||
// If the name resolved to v4 address then its a valid name in
|
||||
@@ -1856,13 +1873,20 @@ func (n *network) ResolveName(req string, ipType int) ([]net.IP, bool) {
|
||||
if ok && n.enableIPv6 == false {
|
||||
ipv6Miss = true
|
||||
}
|
||||
ip = sr.svcIPv6Map[req]
|
||||
ipSet, ok = sr.svcIPv6Map.Get(req)
|
||||
}
|
||||
|
||||
if ip != nil {
|
||||
ipLocal := make([]net.IP, len(ip))
|
||||
copy(ipLocal, ip)
|
||||
return ipLocal, false
|
||||
if ok && len(ipSet) > 0 {
|
||||
// this map is to avoid IP duplicates, this can happen during a transition period where 2 services are using the same IP
|
||||
noDup := make(map[string]bool)
|
||||
var ipLocal []net.IP
|
||||
for _, ip := range ipSet {
|
||||
if _, dup := noDup[ip.(svcMapEntry).ip]; !dup {
|
||||
noDup[ip.(svcMapEntry).ip] = true
|
||||
ipLocal = append(ipLocal, net.ParseIP(ip.(svcMapEntry).ip))
|
||||
}
|
||||
}
|
||||
return ipLocal, ok
|
||||
}
|
||||
|
||||
return nil, ipv6Miss
|
||||
|
||||
+1
-7
@@ -85,14 +85,8 @@ type loadBalancer struct {
|
||||
|
||||
// Map of backend IPs backing this loadbalancer on this
|
||||
// network. It is keyed with endpoint ID.
|
||||
backEnds map[string]loadBalancerBackend
|
||||
backEnds map[string]net.IP
|
||||
|
||||
// Back pointer to service to which the loadbalancer belongs.
|
||||
service *service
|
||||
}
|
||||
|
||||
type loadBalancerBackend struct {
|
||||
ip net.IP
|
||||
containerName string
|
||||
taskAliases []string
|
||||
}
|
||||
|
||||
+70
-44
@@ -15,29 +15,35 @@ func (c *controller) addEndpointNameResolution(svcName, svcID, nID, eID, contain
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Debugf("addEndpointNameResolution %s %s add_service:%t", eID, svcName, addService)
|
||||
logrus.Debugf("addEndpointNameResolution %s %s add_service:%t sAliases:%v tAliases:%v", eID, svcName, addService, serviceAliases, taskAliases)
|
||||
|
||||
// Add container resolution mappings
|
||||
c.addContainerNameResolution(nID, eID, containerName, taskAliases, ip, method)
|
||||
|
||||
serviceID := svcID
|
||||
if serviceID == "" {
|
||||
// This is the case of a normal container not part of a service
|
||||
serviceID = eID
|
||||
}
|
||||
|
||||
// Add endpoint IP to special "tasks.svc_name" so that the applications have access to DNS RR.
|
||||
n.(*network).addSvcRecords(eID, "tasks."+svcName, ip, nil, false, method)
|
||||
n.(*network).addSvcRecords(eID, "tasks."+svcName, serviceID, ip, nil, false, method)
|
||||
for _, alias := range serviceAliases {
|
||||
n.(*network).addSvcRecords(eID, "tasks."+alias, ip, nil, false, method)
|
||||
n.(*network).addSvcRecords(eID, "tasks."+alias, serviceID, ip, nil, false, method)
|
||||
}
|
||||
|
||||
// Add service name to vip in DNS, if vip is valid. Otherwise resort to DNS RR
|
||||
if len(vip) == 0 {
|
||||
n.(*network).addSvcRecords(eID, svcName, ip, nil, false, method)
|
||||
n.(*network).addSvcRecords(eID, svcName, serviceID, ip, nil, false, method)
|
||||
for _, alias := range serviceAliases {
|
||||
n.(*network).addSvcRecords(eID, alias, ip, nil, false, method)
|
||||
n.(*network).addSvcRecords(eID, alias, serviceID, ip, nil, false, method)
|
||||
}
|
||||
}
|
||||
|
||||
if addService && len(vip) != 0 {
|
||||
n.(*network).addSvcRecords(eID, svcName, vip, nil, false, method)
|
||||
n.(*network).addSvcRecords(eID, svcName, serviceID, vip, nil, false, method)
|
||||
for _, alias := range serviceAliases {
|
||||
n.(*network).addSvcRecords(eID, alias, vip, nil, false, method)
|
||||
n.(*network).addSvcRecords(eID, alias, serviceID, vip, nil, false, method)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,11 +58,11 @@ func (c *controller) addContainerNameResolution(nID, eID, containerName string,
|
||||
logrus.Debugf("addContainerNameResolution %s %s", eID, containerName)
|
||||
|
||||
// Add resolution for container name
|
||||
n.(*network).addSvcRecords(eID, containerName, ip, nil, true, method)
|
||||
n.(*network).addSvcRecords(eID, containerName, eID, ip, nil, true, method)
|
||||
|
||||
// Add resolution for taskaliases
|
||||
for _, alias := range taskAliases {
|
||||
n.(*network).addSvcRecords(eID, alias, ip, nil, true, method)
|
||||
n.(*network).addSvcRecords(eID, alias, eID, ip, nil, true, method)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -68,32 +74,38 @@ func (c *controller) deleteEndpointNameResolution(svcName, svcID, nID, eID, cont
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Debugf("deleteEndpointNameResolution %s %s rm_service:%t suppress:%t", eID, svcName, rmService, multipleEntries)
|
||||
logrus.Debugf("deleteEndpointNameResolution %s %s rm_service:%t suppress:%t sAliases:%v tAliases:%v", eID, svcName, rmService, multipleEntries, serviceAliases, taskAliases)
|
||||
|
||||
// Delete container resolution mappings
|
||||
c.delContainerNameResolution(nID, eID, containerName, taskAliases, ip, method)
|
||||
|
||||
serviceID := svcID
|
||||
if serviceID == "" {
|
||||
// This is the case of a normal container not part of a service
|
||||
serviceID = eID
|
||||
}
|
||||
|
||||
// Delete the special "tasks.svc_name" backend record.
|
||||
if !multipleEntries {
|
||||
n.(*network).deleteSvcRecords(eID, "tasks."+svcName, ip, nil, false, method)
|
||||
n.(*network).deleteSvcRecords(eID, "tasks."+svcName, serviceID, ip, nil, false, method)
|
||||
for _, alias := range serviceAliases {
|
||||
n.(*network).deleteSvcRecords(eID, "tasks."+alias, ip, nil, false, method)
|
||||
n.(*network).deleteSvcRecords(eID, "tasks."+alias, serviceID, ip, nil, false, method)
|
||||
}
|
||||
}
|
||||
|
||||
// If we are doing DNS RR delete the endpoint IP from DNS record right away.
|
||||
if !multipleEntries && len(vip) == 0 {
|
||||
n.(*network).deleteSvcRecords(eID, svcName, ip, nil, false, method)
|
||||
n.(*network).deleteSvcRecords(eID, svcName, serviceID, ip, nil, false, method)
|
||||
for _, alias := range serviceAliases {
|
||||
n.(*network).deleteSvcRecords(eID, alias, ip, nil, false, method)
|
||||
n.(*network).deleteSvcRecords(eID, alias, serviceID, ip, nil, false, method)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the DNS record for VIP only if we are removing the service
|
||||
if rmService && len(vip) != 0 && !multipleEntries {
|
||||
n.(*network).deleteSvcRecords(eID, svcName, vip, nil, false, method)
|
||||
n.(*network).deleteSvcRecords(eID, svcName, serviceID, vip, nil, false, method)
|
||||
for _, alias := range serviceAliases {
|
||||
n.(*network).deleteSvcRecords(eID, alias, vip, nil, false, method)
|
||||
n.(*network).deleteSvcRecords(eID, alias, serviceID, vip, nil, false, method)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,11 +120,11 @@ func (c *controller) delContainerNameResolution(nID, eID, containerName string,
|
||||
logrus.Debugf("delContainerNameResolution %s %s", eID, containerName)
|
||||
|
||||
// Delete resolution for container name
|
||||
n.(*network).deleteSvcRecords(eID, containerName, ip, nil, true, method)
|
||||
n.(*network).deleteSvcRecords(eID, containerName, eID, ip, nil, true, method)
|
||||
|
||||
// Delete resolution for taskaliases
|
||||
for _, alias := range taskAliases {
|
||||
n.(*network).deleteSvcRecords(eID, alias, ip, nil, true, method)
|
||||
n.(*network).deleteSvcRecords(eID, alias, eID, ip, nil, true, method)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -152,6 +164,7 @@ func (c *controller) getLBIndex(sid, nid string, ingressPorts []*PortConfig) int
|
||||
func (c *controller) cleanupServiceBindings(cleanupNID string) {
|
||||
var cleanupFuncs []func()
|
||||
|
||||
logrus.Debugf("cleanupServiceBindings for %s", cleanupNID)
|
||||
c.Lock()
|
||||
services := make([]*service, 0, len(c.serviceBindings))
|
||||
for _, s := range c.serviceBindings {
|
||||
@@ -171,16 +184,27 @@ func (c *controller) cleanupServiceBindings(cleanupNID string) {
|
||||
continue
|
||||
}
|
||||
|
||||
for eid, be := range lb.backEnds {
|
||||
// The network is being deleted, erase all the associated service discovery records
|
||||
// TODO(fcrisciani) separate the Load Balancer from the Service discovery, this operation
|
||||
// can be done safely here, but the rmServiceBinding is still keeping consistency in the
|
||||
// data structures that are tracking the endpoint to IP mapping.
|
||||
c.Lock()
|
||||
logrus.Debugf("cleanupServiceBindings erasing the svcRecords for %s", nid)
|
||||
delete(c.svcRecords, nid)
|
||||
c.Unlock()
|
||||
|
||||
for eid, ip := range lb.backEnds {
|
||||
epID := eid
|
||||
epIP := ip
|
||||
service := s
|
||||
loadBalancer := lb
|
||||
networkID := nid
|
||||
epID := eid
|
||||
epIP := be.ip
|
||||
|
||||
cleanupFuncs = append(cleanupFuncs, func() {
|
||||
if err := c.rmServiceBinding(service.name, service.id, networkID, epID, be.containerName, loadBalancer.vip,
|
||||
service.ingressPorts, service.aliases, be.taskAliases, epIP, "cleanupServiceBindings"); err != nil {
|
||||
// ContainerName and taskAliases are not available here, this is still fine because the Service discovery
|
||||
// cleanup already happened before. The only thing that rmServiceBinding is still doing here a part from the Load
|
||||
// Balancer bookeeping, is to keep consistent the mapping of endpoint to IP.
|
||||
if err := c.rmServiceBinding(service.name, service.id, networkID, epID, "", loadBalancer.vip,
|
||||
service.ingressPorts, service.aliases, []string{}, epIP, "cleanupServiceBindings", false); err != nil {
|
||||
logrus.Errorf("Failed to remove service bindings for service %s network %s endpoint %s while cleanup: %v",
|
||||
service.id, networkID, epID, err)
|
||||
}
|
||||
@@ -228,8 +252,7 @@ func (c *controller) addServiceBinding(svcName, svcID, nID, eID, containerName s
|
||||
}
|
||||
s.Unlock()
|
||||
}
|
||||
logrus.Debugf("addServiceBinding from %s START for %s %s", method, svcName, eID)
|
||||
|
||||
logrus.Debugf("addServiceBinding from %s START for %s %s p:%p nid:%s skey:%v", method, svcName, eID, s, nID, skey)
|
||||
defer s.Unlock()
|
||||
|
||||
lb, ok := s.loadBalancers[nID]
|
||||
@@ -242,7 +265,7 @@ func (c *controller) addServiceBinding(svcName, svcID, nID, eID, containerName s
|
||||
lb = &loadBalancer{
|
||||
vip: vip,
|
||||
fwMark: fwMarkCtr,
|
||||
backEnds: make(map[string]loadBalancerBackend),
|
||||
backEnds: make(map[string]net.IP),
|
||||
service: s,
|
||||
}
|
||||
|
||||
@@ -253,9 +276,7 @@ func (c *controller) addServiceBinding(svcName, svcID, nID, eID, containerName s
|
||||
addService = true
|
||||
}
|
||||
|
||||
lb.backEnds[eID] = loadBalancerBackend{ip: ip,
|
||||
containerName: containerName,
|
||||
taskAliases: taskAliases}
|
||||
lb.backEnds[eID] = ip
|
||||
|
||||
ok, entries := s.assignIPToEndpoint(ip.String(), eID)
|
||||
if !ok || entries > 1 {
|
||||
@@ -277,7 +298,7 @@ func (c *controller) addServiceBinding(svcName, svcID, nID, eID, containerName s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *controller) rmServiceBinding(svcName, svcID, nID, eID, containerName string, vip net.IP, ingressPorts []*PortConfig, serviceAliases []string, taskAliases []string, ip net.IP, method string) error {
|
||||
func (c *controller) rmServiceBinding(svcName, svcID, nID, eID, containerName string, vip net.IP, ingressPorts []*PortConfig, serviceAliases []string, taskAliases []string, ip net.IP, method string, deleteSvcRecords bool) error {
|
||||
|
||||
var rmService bool
|
||||
|
||||
@@ -294,7 +315,6 @@ func (c *controller) rmServiceBinding(svcName, svcID, nID, eID, containerName st
|
||||
c.Lock()
|
||||
s, ok := c.serviceBindings[skey]
|
||||
c.Unlock()
|
||||
logrus.Debugf("rmServiceBinding from %s START for %s %s", method, svcName, eID)
|
||||
if !ok {
|
||||
logrus.Warnf("rmServiceBinding %s %s %s aborted c.serviceBindings[skey] !ok", method, svcName, eID)
|
||||
return nil
|
||||
@@ -302,6 +322,7 @@ func (c *controller) rmServiceBinding(svcName, svcID, nID, eID, containerName st
|
||||
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
logrus.Debugf("rmServiceBinding from %s START for %s %s p:%p nid:%s sKey:%v deleteSvc:%t", method, svcName, eID, s, nID, skey, deleteSvcRecords)
|
||||
lb, ok := s.loadBalancers[nID]
|
||||
if !ok {
|
||||
logrus.Warnf("rmServiceBinding %s %s %s aborted s.loadBalancers[nid] !ok", method, svcName, eID)
|
||||
@@ -322,17 +343,7 @@ func (c *controller) rmServiceBinding(svcName, svcID, nID, eID, containerName st
|
||||
rmService = true
|
||||
|
||||
delete(s.loadBalancers, nID)
|
||||
}
|
||||
|
||||
if len(s.loadBalancers) == 0 {
|
||||
// All loadbalancers for the service removed. Time to
|
||||
// remove the service itself.
|
||||
c.Lock()
|
||||
|
||||
// Mark the object as deleted so that the add won't use it wrongly
|
||||
s.deleted = true
|
||||
delete(c.serviceBindings, skey)
|
||||
c.Unlock()
|
||||
logrus.Debugf("rmServiceBinding %s delete %s, p:%p in loadbalancers len:%d", eID, nID, lb, len(s.loadBalancers))
|
||||
}
|
||||
|
||||
ok, entries := s.removeIPToEndpoint(ip.String(), eID)
|
||||
@@ -348,7 +359,22 @@ func (c *controller) rmServiceBinding(svcName, svcID, nID, eID, containerName st
|
||||
}
|
||||
|
||||
// Delete the name resolutions
|
||||
c.deleteEndpointNameResolution(svcName, svcID, nID, eID, containerName, vip, serviceAliases, taskAliases, ip, rmService, entries > 0, "rmServiceBinding")
|
||||
if deleteSvcRecords {
|
||||
c.deleteEndpointNameResolution(svcName, svcID, nID, eID, containerName, vip, serviceAliases, taskAliases, ip, rmService, entries > 0, "rmServiceBinding")
|
||||
}
|
||||
|
||||
if len(s.loadBalancers) == 0 {
|
||||
// All loadbalancers for the service removed. Time to
|
||||
// remove the service itself.
|
||||
c.Lock()
|
||||
|
||||
// Mark the object as deleted so that the add won't use it wrongly
|
||||
s.deleted = true
|
||||
// NOTE The delete from the serviceBindings map has to be the last operation else we are allowing a race between this service
|
||||
// that is getting deleted and a new service that will be created if the entry is not anymore there
|
||||
delete(c.serviceBindings, skey)
|
||||
c.Unlock()
|
||||
}
|
||||
|
||||
logrus.Debugf("rmServiceBinding from %s END for %s %s", method, svcName, eID)
|
||||
return nil
|
||||
|
||||
+2
-2
@@ -102,8 +102,8 @@ func (sb *sandbox) populateLoadbalancers(ep *endpoint) {
|
||||
}
|
||||
|
||||
lb.service.Lock()
|
||||
for _, l := range lb.backEnds {
|
||||
sb.addLBBackend(l.ip, lb.vip, lb.fwMark, lb.service.ingressPorts, eIP, gwIP, n.ingress)
|
||||
for _, ip := range lb.backEnds {
|
||||
sb.addLBBackend(ip, lb.vip, lb.fwMark, lb.service.ingressPorts, eIP, gwIP, n.ingress)
|
||||
}
|
||||
lb.service.Unlock()
|
||||
}
|
||||
|
||||
+1
-1
@@ -887,7 +887,7 @@ func GetRemoteSignedCertificate(ctx context.Context, csr []byte, rootCAPool *x50
|
||||
caClient = api.NewNodeCAClient(conn.ClientConn)
|
||||
|
||||
// If there was no deadline exceeded error, and the certificate was issued, return
|
||||
case err == nil && statusResponse.Status.State == api.IssuanceStateIssued:
|
||||
case err == nil && (statusResponse.Status.State == api.IssuanceStateIssued || statusResponse.Status.State == api.IssuanceStateRotate):
|
||||
if statusResponse.Certificate == nil {
|
||||
conn.Close(false)
|
||||
return nil, errors.New("no certificate in CertificateStatus response")
|
||||
|
||||
Generated
Vendored
+4
@@ -152,6 +152,10 @@ func (na *NetworkAllocator) Allocate(n *api.Network) error {
|
||||
n.DriverState = &api.Driver{
|
||||
Name: d.name,
|
||||
}
|
||||
// In order to support backward compatibility with older daemon
|
||||
// versions which assumes the network attachment to contains
|
||||
// non nil IPAM attribute, passing an empty object
|
||||
n.IPAM = &api.IPAMOptions{Driver: &api.Driver{}}
|
||||
} else {
|
||||
nw.pools, err = na.allocatePools(n)
|
||||
if err != nil {
|
||||
|
||||
Generated
Vendored
+5
@@ -247,6 +247,11 @@ func redactClusters(clusters []*api.Cluster) []*api.Cluster {
|
||||
// Do not copy secret keys
|
||||
redactedSpec := cluster.Spec.Copy()
|
||||
redactedSpec.CAConfig.SigningCAKey = nil
|
||||
// the cert is not a secret, but if API users get the cluster spec and then update,
|
||||
// then because the cert is included but not the key, the user can get update errors
|
||||
// or unintended consequences (such as telling swarm to forget about the key so long
|
||||
// as there is a corresponding external CA)
|
||||
redactedSpec.CAConfig.SigningCACert = nil
|
||||
|
||||
redactedRootCA := cluster.RootCA.Copy()
|
||||
redactedRootCA.CAKey = nil
|
||||
|
||||
+8
-7
@@ -945,18 +945,19 @@ func (m *Manager) becomeLeader(ctx context.Context) {
|
||||
if err := store.CreateNetwork(tx, newIngressNetwork()); err != nil {
|
||||
log.G(ctx).WithError(err).Error("failed to create default ingress network")
|
||||
}
|
||||
// Create now the static predefined node-local networks which
|
||||
// are known to be present in each cluster node. This is needed
|
||||
// in order to allow running services on the predefined docker
|
||||
// networks like `bridge` and `host`.
|
||||
log.G(ctx).Info("Creating node-local predefined networks")
|
||||
for _, p := range networkallocator.PredefinedNetworks() {
|
||||
}
|
||||
// Create now the static predefined if the store does not contain predefined
|
||||
//networks like bridge/host node-local networks which
|
||||
// are known to be present in each cluster node. This is needed
|
||||
// in order to allow running services on the predefined docker
|
||||
// networks like `bridge` and `host`.
|
||||
for _, p := range networkallocator.PredefinedNetworks() {
|
||||
if store.GetNetwork(tx, p.Name) == nil {
|
||||
if err := store.CreateNetwork(tx, newPredefinedNetwork(p.Name, p.Driver)); err != nil {
|
||||
log.G(ctx).WithError(err).Error("failed to create predefined network " + p.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
-11
@@ -4,7 +4,6 @@ import (
|
||||
"container/heap"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/swarmkit/api"
|
||||
"github.com/docker/swarmkit/manager/constraint"
|
||||
@@ -32,16 +31,6 @@ func (ns *nodeSet) nodeInfo(nodeID string) (NodeInfo, error) {
|
||||
// addOrUpdateNode sets the number of tasks for a given node. It adds the node
|
||||
// to the set if it wasn't already tracked.
|
||||
func (ns *nodeSet) addOrUpdateNode(n NodeInfo) {
|
||||
if n.Tasks == nil {
|
||||
n.Tasks = make(map[string]*api.Task)
|
||||
}
|
||||
if n.ActiveTasksCountByService == nil {
|
||||
n.ActiveTasksCountByService = make(map[string]int)
|
||||
}
|
||||
if n.recentFailures == nil {
|
||||
n.recentFailures = make(map[string][]time.Time)
|
||||
}
|
||||
|
||||
ns.nodes[n.ID] = n
|
||||
}
|
||||
|
||||
|
||||
Generated
Vendored
+14
-7
@@ -296,19 +296,26 @@ func (s *Scheduler) deleteTask(ctx context.Context, t *api.Task) bool {
|
||||
}
|
||||
|
||||
func (s *Scheduler) createOrUpdateNode(n *api.Node) {
|
||||
nodeInfo, _ := s.nodeSet.nodeInfo(n.ID)
|
||||
nodeInfo, nodeInfoErr := s.nodeSet.nodeInfo(n.ID)
|
||||
var resources api.Resources
|
||||
if n.Description != nil && n.Description.Resources != nil {
|
||||
resources = *n.Description.Resources
|
||||
// reconcile resources by looping over all tasks in this node
|
||||
for _, task := range nodeInfo.Tasks {
|
||||
reservations := taskReservations(task.Spec)
|
||||
resources.MemoryBytes -= reservations.MemoryBytes
|
||||
resources.NanoCPUs -= reservations.NanoCPUs
|
||||
if nodeInfoErr == nil {
|
||||
for _, task := range nodeInfo.Tasks {
|
||||
reservations := taskReservations(task.Spec)
|
||||
resources.MemoryBytes -= reservations.MemoryBytes
|
||||
resources.NanoCPUs -= reservations.NanoCPUs
|
||||
}
|
||||
}
|
||||
}
|
||||
nodeInfo.Node = n
|
||||
nodeInfo.AvailableResources = resources
|
||||
|
||||
if nodeInfoErr != nil {
|
||||
nodeInfo = newNodeInfo(n, nil, resources)
|
||||
} else {
|
||||
nodeInfo.Node = n
|
||||
nodeInfo.AvailableResources = resources
|
||||
}
|
||||
s.nodeSet.addOrUpdateNode(nodeInfo)
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ ubuntu-xenial: ## build ubuntu xenial deb packages
|
||||
-v $(CURDIR)/debbuild/$@:/build \
|
||||
-v $(ENGINE_DIR):/engine \
|
||||
-v $(CLI_DIR):/cli \
|
||||
-v $(CURDIR)/systemd:/root/build-deb/systemd \
|
||||
debbuild-$@/$(ARCH)
|
||||
$(CHOWN) -R $(shell id -u):$(shell id -g) debbuild/$@
|
||||
|
||||
@@ -42,6 +43,7 @@ ubuntu-trusty: ## build ubuntu trusty deb packages
|
||||
-v $(CURDIR)/debbuild/$@:/build \
|
||||
-v $(ENGINE_DIR):/engine \
|
||||
-v $(CLI_DIR):/cli \
|
||||
-v $(CURDIR)/systemd:/root/build-deb/systemd \
|
||||
debbuild-$@/$(ARCH)
|
||||
$(CHOWN) -R $(shell id -u):$(shell id -g) debbuild/$@
|
||||
|
||||
@@ -53,6 +55,7 @@ ubuntu-yakkety: ## build ubuntu yakkety deb packages
|
||||
-v $(CURDIR)/debbuild/$@:/build \
|
||||
-v $(ENGINE_DIR):/engine \
|
||||
-v $(CLI_DIR):/cli \
|
||||
-v $(CURDIR)/systemd:/root/build-deb/systemd \
|
||||
debbuild-$@/$(ARCH)
|
||||
$(CHOWN) -R $(shell id -u):$(shell id -g) debbuild/$@
|
||||
|
||||
@@ -64,6 +67,7 @@ ubuntu-zesty: ## build ubuntu zesty deb packages
|
||||
-v $(CURDIR)/debbuild/$@:/build \
|
||||
-v $(ENGINE_DIR):/engine \
|
||||
-v $(CLI_DIR):/cli \
|
||||
-v $(CURDIR)/systemd:/root/build-deb/systemd \
|
||||
debbuild-$@/$(ARCH)
|
||||
$(CHOWN) -R $(shell id -u):$(shell id -g) debbuild/$@
|
||||
|
||||
@@ -75,6 +79,7 @@ debian-jessie: ## build debian jessie deb packages
|
||||
-v $(CURDIR)/debbuild/$@:/build \
|
||||
-v $(ENGINE_DIR):/engine \
|
||||
-v $(CLI_DIR):/cli \
|
||||
-v $(CURDIR)/systemd:/root/build-deb/systemd \
|
||||
debbuild-$@/$(ARCH)
|
||||
$(CHOWN) -R $(shell id -u):$(shell id -g) debbuild/$@
|
||||
|
||||
@@ -86,6 +91,7 @@ debian-stretch: ## build debian stretch deb packages
|
||||
-v $(CURDIR)/debbuild/$@:/build \
|
||||
-v $(ENGINE_DIR):/engine \
|
||||
-v $(CLI_DIR):/cli \
|
||||
-v $(CURDIR)/systemd:/root/build-deb/systemd \
|
||||
debbuild-$@/$(ARCH)
|
||||
$(CHOWN) -R $(shell id -u):$(shell id -g) debbuild/$@
|
||||
|
||||
@@ -97,5 +103,6 @@ debian-wheezy: ## build debian wheezy deb packages
|
||||
-v $(CURDIR)/debbuild/$@:/build \
|
||||
-v $(ENGINE_DIR):/engine \
|
||||
-v $(CLI_DIR):/cli \
|
||||
-v $(CURDIR)/systemd:/root/build-deb/systemd \
|
||||
debbuild-$@/$(ARCH)
|
||||
$(CHOWN) -R $(shell id -u):$(shell id -g) debbuild/$@
|
||||
|
||||
@@ -16,7 +16,7 @@ Recommends: aufs-tools,
|
||||
git,
|
||||
xz-utils,
|
||||
${apparmor:Recommends}
|
||||
Conflicts: docker (<< 1.5~), docker.io, lxc-docker, lxc-docker-virtual-package, docker-engine-cs
|
||||
Conflicts: docker (<< 1.5~), docker.io, lxc-docker, lxc-docker-virtual-package, docker-engine, docker-engine-cs, docker-ee
|
||||
Replaces: docker-engine
|
||||
Description: Docker: the open-source application container engine
|
||||
Docker is an open source project to build, ship and run any application as a
|
||||
|
||||
@@ -5,8 +5,8 @@ engine/contrib/*-integration usr/share/docker-ce/contrib/
|
||||
engine/contrib/check-config.sh usr/share/docker-ce/contrib/
|
||||
engine/contrib/completion/fish/docker.fish usr/share/fish/vendor_completions.d/
|
||||
engine/contrib/completion/zsh/_docker usr/share/zsh/vendor-completions/
|
||||
engine/contrib/init/systemd/docker.service lib/systemd/system/
|
||||
engine/contrib/init/systemd/docker.socket lib/systemd/system/
|
||||
systemd/docker.service lib/systemd/system/
|
||||
systemd/docker.socket lib/systemd/system/
|
||||
engine/contrib/mk* usr/share/docker-ce/contrib/
|
||||
engine/contrib/nuke-graph-directory.sh usr/share/docker-ce/contrib/
|
||||
engine/contrib/syntax/nano/Dockerfile.nanorc usr/share/nano/
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
[Unit]
|
||||
Description=Docker Application Container Engine
|
||||
Documentation=https://docs.docker.com
|
||||
After=network-online.target docker.socket firewalld.service
|
||||
Wants=network-online.target
|
||||
Requires=docker.socket
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
# the default is not to use systemd for cgroups because the delegate issues still
|
||||
# exists and systemd currently does not support the cgroup feature set required
|
||||
# for containers run by docker
|
||||
ExecStart=/usr/bin/dockerd -H fd://
|
||||
ExecReload=/bin/kill -s HUP $MAINPID
|
||||
LimitNOFILE=1048576
|
||||
# Having non-zero Limit*s causes performance problems due to accounting overhead
|
||||
# in the kernel. We recommend using cgroups to do container-local accounting.
|
||||
LimitNPROC=infinity
|
||||
LimitCORE=infinity
|
||||
# Uncomment TasksMax if your systemd version supports it.
|
||||
# Only systemd 226 and above support this version.
|
||||
#TasksMax=infinity
|
||||
TimeoutStartSec=0
|
||||
# set delegate yes so that systemd does not reset the cgroups of docker containers
|
||||
Delegate=yes
|
||||
# kill only the docker process, not all processes in the cgroup
|
||||
KillMode=process
|
||||
# restart the docker process if it exits prematurely
|
||||
Restart=on-failure
|
||||
StartLimitBurst=3
|
||||
StartLimitInterval=60s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Docker Socket for the API
|
||||
PartOf=docker.service
|
||||
|
||||
[Socket]
|
||||
ListenStream=/var/run/docker.sock
|
||||
SocketMode=0660
|
||||
SocketUser=root
|
||||
SocketGroup=docker
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
@@ -11,7 +11,8 @@ RPMBUILD=docker run --privileged --rm -i \
|
||||
-v $(CURDIR)/rpmbuild/BUILD:/root/rpmbuild/BUILD \
|
||||
-v $(CURDIR)/rpmbuild/BUILDROOT:/root/rpmbuild/BUILDROOT \
|
||||
-v $(CURDIR)/rpmbuild/RPMS:/root/rpmbuild/RPMS \
|
||||
-v $(CURDIR)/rpmbuild/SRPMS:/root/rpmbuild/SRPMS
|
||||
-v $(CURDIR)/rpmbuild/SRPMS:/root/rpmbuild/SRPMS \
|
||||
-v $(CURDIR)/systemd:/systemd
|
||||
RPMBUILD_FLAGS=-ba\
|
||||
--define '_gitcommit $(word 3,$(GEN_RPM_VER))' \
|
||||
--define '_release $(word 2,$(GEN_RPM_VER))' \
|
||||
|
||||
@@ -35,6 +35,12 @@ Requires: device-mapper-libs >= 1.02.90-1
|
||||
Conflicts: docker
|
||||
Conflicts: docker-io
|
||||
Conflicts: docker-engine-cs
|
||||
Conflicts: docker-ee
|
||||
|
||||
# Obsolete packages
|
||||
Obsoletes: docker-ce-selinux
|
||||
Obsoletes: docker-engine-selinux
|
||||
Obsoletes: docker-engine
|
||||
|
||||
%description
|
||||
Docker is an open source project to build, ship and run any application as a
|
||||
@@ -95,7 +101,7 @@ install -p -m 644 engine/contrib/udev/80-docker.rules $RPM_BUILD_ROOT/%{_sysconf
|
||||
install -d $RPM_BUILD_ROOT/etc/sysconfig
|
||||
install -d $RPM_BUILD_ROOT/%{_initddir}
|
||||
install -d $RPM_BUILD_ROOT/%{_unitdir}
|
||||
install -p -m 644 engine/contrib/init/systemd/docker.service.rpm $RPM_BUILD_ROOT/%{_unitdir}/docker.service
|
||||
install -p -m 644 /systemd/docker.service $RPM_BUILD_ROOT/%{_unitdir}/docker.service
|
||||
# add bash, zsh, and fish completions
|
||||
install -d $RPM_BUILD_ROOT/usr/share/bash-completion/completions
|
||||
install -d $RPM_BUILD_ROOT/usr/share/zsh/vendor-completions
|
||||
@@ -124,9 +130,18 @@ install -p -m 644 engine/contrib/syntax/vim/syntax/dockerfile.vim $RPM_BUILD_ROO
|
||||
install -d $RPM_BUILD_ROOT/usr/share/nano
|
||||
install -p -m 644 engine/contrib/syntax/nano/Dockerfile.nanorc $RPM_BUILD_ROOT/usr/share/nano/Dockerfile.nanorc
|
||||
|
||||
mkdir -p build-docs
|
||||
for engine_file in AUTHORS CHANGELOG.md CONTRIBUTING.md LICENSE MAINTAINERS NOTICE README.md; do
|
||||
cp "engine/$engine_file" "build-docs/engine-$engine_file"
|
||||
done
|
||||
for cli_file in LICENSE MAINTAINERS NOTICE README.md; do
|
||||
cp "cli/$cli_file" "build-docs/cli-$cli_file"
|
||||
done
|
||||
|
||||
# list files owned by the package here
|
||||
%files
|
||||
%doc engine/AUTHORS engine/CHANGELOG.md engine/CONTRIBUTING.md engine/LICENSE engine/MAINTAINERS engine/NOTICE engine/README.md
|
||||
%doc build-docs/engine-AUTHORS build-docs/engine-CHANGELOG.md build-docs/engine-CONTRIBUTING.md build-docs/engine-LICENSE build-docs/engine-MAINTAINERS build-docs/engine-NOTICE build-docs/engine-README.md
|
||||
%doc build-docs/cli-LICENSE build-docs/cli-MAINTAINERS build-docs/cli-NOTICE build-docs/cli-README.md
|
||||
/%{_bindir}/docker
|
||||
/%{_bindir}/dockerd
|
||||
/%{_bindir}/docker-containerd
|
||||
@@ -149,6 +164,20 @@ install -p -m 644 engine/contrib/syntax/nano/Dockerfile.nanorc $RPM_BUILD_ROOT/u
|
||||
/usr/share/vim/vimfiles/syntax/dockerfile.vim
|
||||
/usr/share/nano/Dockerfile.nanorc
|
||||
|
||||
%pre
|
||||
if [ $1 -gt 0 ] ; then
|
||||
# package upgrade scenario, before new files are installed
|
||||
|
||||
# clear any old state
|
||||
rm -f %{_localstatedir}/lib/rpm-state/docker-is-active > /dev/null 2>&1 || :
|
||||
|
||||
# check if docker service is running
|
||||
if systemctl is-active docker > /dev/null 2>&1; then
|
||||
systemctl stop docker > /dev/null 2>&1 || :
|
||||
touch %{_localstatedir}/lib/rpm-state/docker-is-active > /dev/null 2>&1 || :
|
||||
fi
|
||||
fi
|
||||
|
||||
%post
|
||||
%systemd_post docker
|
||||
if ! getent group docker > /dev/null; then
|
||||
@@ -161,7 +190,30 @@ fi
|
||||
%postun
|
||||
%systemd_postun_with_restart docker
|
||||
|
||||
%posttrans
|
||||
if [ $1 -ge 0 ] ; then
|
||||
# package upgrade scenario, after new files are installed
|
||||
|
||||
# check if docker was running before upgrade
|
||||
if [ -f %{_localstatedir}/lib/rpm-state/docker-is-active ]; then
|
||||
systemctl start docker > /dev/null 2>&1 || :
|
||||
rm -f %{_localstatedir}/lib/rpm-state/docker-is-active > /dev/null 2>&1 || :
|
||||
fi
|
||||
fi
|
||||
|
||||
%changelog
|
||||
|
||||
* Wed May 10 2017 <andrewhsu@docker.com> 17.06.0-dev
|
||||
- Initial RPM release
|
||||
* Mon Jun 19 2017 <eli.uriegas@docker.com> 17.06.0-ce-rc5
|
||||
- release docker-ce 17.06.0-ce-rc5
|
||||
|
||||
* Thu Jun 15 2017 <andrewhsu@docker.com> 17.06.0-ce-rc4
|
||||
- release docker-ce 17.06.0-ce-rc4
|
||||
|
||||
* Tue Jun 13 2017 <andrewhsu@docker.com> 17.06.0-ce-rc3
|
||||
- release docker-ce 17.06.0-ce-rc3
|
||||
|
||||
* Wed Jun 07 2017 <andrewhsu@docker.com> 17.06.0-ce-rc2
|
||||
- release docker-ce 17.06.0-ce-rc2
|
||||
|
||||
* Mon May 29 2017 <andrewhsu@docker.com> 17.06.0-ce-rc1
|
||||
- release docker-ce 17.06.0-ce-rc1
|
||||
|
||||
@@ -27,6 +27,7 @@ Requires: libcgroup
|
||||
Requires: systemd-units
|
||||
Requires: tar
|
||||
Requires: xz
|
||||
Requires: container-selinux >= 1.10.3-55
|
||||
|
||||
# Resolves: rhbz#1165615
|
||||
Requires: device-mapper-libs >= 1.02.90-1
|
||||
@@ -35,6 +36,12 @@ Requires: device-mapper-libs >= 1.02.90-1
|
||||
Conflicts: docker
|
||||
Conflicts: docker-io
|
||||
Conflicts: docker-engine-cs
|
||||
Conflicts: docker-ee
|
||||
|
||||
# Obsolete packages
|
||||
Obsoletes: docker-ce-selinux
|
||||
Obsoletes: docker-engine-selinux
|
||||
Obsoletes: docker-engine
|
||||
|
||||
%description
|
||||
Docker is an open source project to build, ship and run any application as a
|
||||
@@ -95,7 +102,7 @@ install -p -m 644 engine/contrib/udev/80-docker.rules $RPM_BUILD_ROOT/%{_sysconf
|
||||
install -d $RPM_BUILD_ROOT/etc/sysconfig
|
||||
install -d $RPM_BUILD_ROOT/%{_initddir}
|
||||
install -d $RPM_BUILD_ROOT/%{_unitdir}
|
||||
install -p -m 644 engine/contrib/init/systemd/docker.service.rpm $RPM_BUILD_ROOT/%{_unitdir}/docker.service
|
||||
install -p -m 644 /systemd/docker.service $RPM_BUILD_ROOT/%{_unitdir}/docker.service
|
||||
# add bash, zsh, and fish completions
|
||||
install -d $RPM_BUILD_ROOT/usr/share/bash-completion/completions
|
||||
install -d $RPM_BUILD_ROOT/usr/share/zsh/vendor-completions
|
||||
@@ -124,9 +131,18 @@ install -p -m 644 engine/contrib/syntax/vim/syntax/dockerfile.vim $RPM_BUILD_ROO
|
||||
install -d $RPM_BUILD_ROOT/usr/share/nano
|
||||
install -p -m 644 engine/contrib/syntax/nano/Dockerfile.nanorc $RPM_BUILD_ROOT/usr/share/nano/Dockerfile.nanorc
|
||||
|
||||
mkdir -p build-docs
|
||||
for engine_file in AUTHORS CHANGELOG.md CONTRIBUTING.md LICENSE MAINTAINERS NOTICE README.md; do
|
||||
cp "engine/$engine_file" "build-docs/engine-$engine_file"
|
||||
done
|
||||
for cli_file in LICENSE MAINTAINERS NOTICE README.md; do
|
||||
cp "cli/$cli_file" "build-docs/cli-$cli_file"
|
||||
done
|
||||
|
||||
# list files owned by the package here
|
||||
%files
|
||||
%doc engine/AUTHORS engine/CHANGELOG.md engine/CONTRIBUTING.md engine/LICENSE engine/MAINTAINERS engine/NOTICE engine/README.md
|
||||
%doc build-docs/engine-AUTHORS build-docs/engine-CHANGELOG.md build-docs/engine-CONTRIBUTING.md build-docs/engine-LICENSE build-docs/engine-MAINTAINERS build-docs/engine-NOTICE build-docs/engine-README.md
|
||||
%doc build-docs/cli-LICENSE build-docs/cli-MAINTAINERS build-docs/cli-NOTICE build-docs/cli-README.md
|
||||
/%{_bindir}/docker
|
||||
/%{_bindir}/dockerd
|
||||
/%{_bindir}/docker-containerd
|
||||
@@ -149,6 +165,20 @@ install -p -m 644 engine/contrib/syntax/nano/Dockerfile.nanorc $RPM_BUILD_ROOT/u
|
||||
/usr/share/vim/vimfiles/syntax/dockerfile.vim
|
||||
/usr/share/nano/Dockerfile.nanorc
|
||||
|
||||
%pre
|
||||
if [ $1 -gt 0 ] ; then
|
||||
# package upgrade scenario, before new files are installed
|
||||
|
||||
# clear any old state
|
||||
rm -f %{_localstatedir}/lib/rpm-state/docker-is-active > /dev/null 2>&1 || :
|
||||
|
||||
# check if docker service is running
|
||||
if systemctl is-active docker > /dev/null 2>&1; then
|
||||
systemctl stop docker > /dev/null 2>&1 || :
|
||||
touch %{_localstatedir}/lib/rpm-state/docker-is-active > /dev/null 2>&1 || :
|
||||
fi
|
||||
fi
|
||||
|
||||
%post
|
||||
%systemd_post docker
|
||||
if ! getent group docker > /dev/null; then
|
||||
@@ -161,7 +191,30 @@ fi
|
||||
%postun
|
||||
%systemd_postun_with_restart docker
|
||||
|
||||
%posttrans
|
||||
if [ $1 -ge 0 ] ; then
|
||||
# package upgrade scenario, after new files are installed
|
||||
|
||||
# check if docker was running before upgrade
|
||||
if [ -f %{_localstatedir}/lib/rpm-state/docker-is-active ]; then
|
||||
systemctl start docker > /dev/null 2>&1 || :
|
||||
rm -f %{_localstatedir}/lib/rpm-state/docker-is-active > /dev/null 2>&1 || :
|
||||
fi
|
||||
fi
|
||||
|
||||
%changelog
|
||||
|
||||
* Wed May 10 2017 <andrewhsu@docker.com> 17.06.0-dev
|
||||
- Initial RPM release
|
||||
* Mon Jun 19 2017 <eli.uriegas@docker.com> 17.06.0-ce-rc5
|
||||
- release docker-ce 17.06.0-ce-rc5
|
||||
|
||||
* Thu Jun 15 2017 <andrewhsu@docker.com> 17.06.0-ce-rc4
|
||||
- release docker-ce 17.06.0-ce-rc4
|
||||
|
||||
* Tue Jun 13 2017 <andrewhsu@docker.com> 17.06.0-ce-rc3
|
||||
- release docker-ce 17.06.0-ce-rc3
|
||||
|
||||
* Wed Jun 07 2017 <andrewhsu@docker.com> 17.06.0-ce-rc2
|
||||
- release docker-ce 17.06.0-ce-rc2
|
||||
|
||||
* Mon May 29 2017 <andrewhsu@docker.com> 17.06.0-ce-rc1
|
||||
- release docker-ce 17.06.0-ce-rc1
|
||||
|
||||
@@ -34,6 +34,12 @@ Requires: device-mapper-libs >= 1.02.90-1
|
||||
Conflicts: docker
|
||||
Conflicts: docker-io
|
||||
Conflicts: docker-engine-cs
|
||||
Conflicts: docker-ee
|
||||
|
||||
# Obsolete packages
|
||||
Obsoletes: docker-ce-selinux
|
||||
Obsoletes: docker-engine-selinux
|
||||
Obsoletes: docker-engine
|
||||
|
||||
%description
|
||||
Docker is an open source project to build, ship and run any application as a
|
||||
@@ -94,7 +100,7 @@ install -p -m 644 engine/contrib/udev/80-docker.rules $RPM_BUILD_ROOT/%{_sysconf
|
||||
install -d $RPM_BUILD_ROOT/etc/sysconfig
|
||||
install -d $RPM_BUILD_ROOT/%{_initddir}
|
||||
install -d $RPM_BUILD_ROOT/%{_unitdir}
|
||||
install -p -m 644 engine/contrib/init/systemd/docker.service.rpm $RPM_BUILD_ROOT/%{_unitdir}/docker.service
|
||||
install -p -m 644 /systemd/docker.service $RPM_BUILD_ROOT/%{_unitdir}/docker.service
|
||||
# add bash, zsh, and fish completions
|
||||
install -d $RPM_BUILD_ROOT/usr/share/bash-completion/completions
|
||||
install -d $RPM_BUILD_ROOT/usr/share/zsh/vendor-completions
|
||||
@@ -123,9 +129,18 @@ install -p -m 644 engine/contrib/syntax/vim/syntax/dockerfile.vim $RPM_BUILD_ROO
|
||||
install -d $RPM_BUILD_ROOT/usr/share/nano
|
||||
install -p -m 644 engine/contrib/syntax/nano/Dockerfile.nanorc $RPM_BUILD_ROOT/usr/share/nano/Dockerfile.nanorc
|
||||
|
||||
mkdir -p build-docs
|
||||
for engine_file in AUTHORS CHANGELOG.md CONTRIBUTING.md LICENSE MAINTAINERS NOTICE README.md; do
|
||||
cp "engine/$engine_file" "build-docs/engine-$engine_file"
|
||||
done
|
||||
for cli_file in LICENSE MAINTAINERS NOTICE README.md; do
|
||||
cp "cli/$cli_file" "build-docs/cli-$cli_file"
|
||||
done
|
||||
|
||||
# list files owned by the package here
|
||||
%files
|
||||
%doc engine/AUTHORS engine/CHANGELOG.md engine/CONTRIBUTING.md engine/LICENSE engine/MAINTAINERS engine/NOTICE engine/README.md
|
||||
%doc build-docs/engine-AUTHORS build-docs/engine-CHANGELOG.md build-docs/engine-CONTRIBUTING.md build-docs/engine-LICENSE build-docs/engine-MAINTAINERS build-docs/engine-NOTICE build-docs/engine-README.md
|
||||
%doc build-docs/cli-LICENSE build-docs/cli-MAINTAINERS build-docs/cli-NOTICE build-docs/cli-README.md
|
||||
/%{_bindir}/docker
|
||||
/%{_bindir}/dockerd
|
||||
/%{_bindir}/docker-containerd
|
||||
@@ -148,6 +163,20 @@ install -p -m 644 engine/contrib/syntax/nano/Dockerfile.nanorc $RPM_BUILD_ROOT/u
|
||||
/usr/share/vim/vimfiles/syntax/dockerfile.vim
|
||||
/usr/share/nano/Dockerfile.nanorc
|
||||
|
||||
%pre
|
||||
if [ $1 -gt 0 ] ; then
|
||||
# package upgrade scenario, before new files are installed
|
||||
|
||||
# clear any old state
|
||||
rm -f %{_localstatedir}/lib/rpm-state/docker-is-active > /dev/null 2>&1 || :
|
||||
|
||||
# check if docker service is running
|
||||
if systemctl is-active docker > /dev/null 2>&1; then
|
||||
systemctl stop docker > /dev/null 2>&1 || :
|
||||
touch %{_localstatedir}/lib/rpm-state/docker-is-active > /dev/null 2>&1 || :
|
||||
fi
|
||||
fi
|
||||
|
||||
%post
|
||||
%systemd_post docker
|
||||
if ! getent group docker > /dev/null; then
|
||||
@@ -160,7 +189,30 @@ fi
|
||||
%postun
|
||||
%systemd_postun_with_restart docker
|
||||
|
||||
%posttrans
|
||||
if [ $1 -ge 0 ] ; then
|
||||
# package upgrade scenario, after new files are installed
|
||||
|
||||
# check if docker was running before upgrade
|
||||
if [ -f %{_localstatedir}/lib/rpm-state/docker-is-active ]; then
|
||||
systemctl start docker > /dev/null 2>&1 || :
|
||||
rm -f %{_localstatedir}/lib/rpm-state/docker-is-active > /dev/null 2>&1 || :
|
||||
fi
|
||||
fi
|
||||
|
||||
%changelog
|
||||
|
||||
* Wed May 10 2017 <andrewhsu@docker.com> 17.06.0-dev
|
||||
- Initial RPM release
|
||||
* Mon Jun 19 2017 <eli.uriegas@docker.com> 17.06.0-ce-rc5
|
||||
- release docker-ce 17.06.0-ce-rc5
|
||||
|
||||
* Thu Jun 15 2017 <andrewhsu@docker.com> 17.06.0-ce-rc4
|
||||
- release docker-ce 17.06.0-ce-rc4
|
||||
|
||||
* Tue Jun 13 2017 <andrewhsu@docker.com> 17.06.0-ce-rc3
|
||||
- release docker-ce 17.06.0-ce-rc3
|
||||
|
||||
* Wed Jun 07 2017 <andrewhsu@docker.com> 17.06.0-ce-rc2
|
||||
- release docker-ce 17.06.0-ce-rc2
|
||||
|
||||
* Mon May 29 2017 <andrewhsu@docker.com> 17.06.0-ce-rc1
|
||||
- release docker-ce 17.06.0-ce-rc1
|
||||
|
||||
@@ -5,6 +5,11 @@ VERSION=$2
|
||||
|
||||
[[ $# < 2 ]] && echo 'not enough args' && exit 1
|
||||
|
||||
DATE_COMMAND="date"
|
||||
if [[ $(uname) -eq "Darwin" ]]; then
|
||||
DATE_COMMAND="docker run --rm alpine date"
|
||||
fi
|
||||
|
||||
GIT_COMMAND="git -C $ENGINE_DIR"
|
||||
rpmName=docker-ce
|
||||
rpmVersion="$VERSION"
|
||||
@@ -32,7 +37,7 @@ fi
|
||||
# if we have a "-dev" suffix or have change in Git, let's make this package version more complex so it works better
|
||||
if [[ "$rpmVersion" == *-dev ]] || [ -n "$($GIT_COMMAND status --porcelain)" ]; then
|
||||
gitUnix="$($GIT_COMMAND log -1 --pretty='%at')"
|
||||
gitDate="$(date --date "@$gitUnix" +'%Y%m%d.%H%M%S')"
|
||||
gitDate="$($DATE_COMMAND --date "@$gitUnix" +'%Y%m%d.%H%M%S')"
|
||||
gitCommit="$($GIT_COMMAND log -1 --pretty='%h')"
|
||||
gitVersion="${gitDate}.git${gitCommit}"
|
||||
# gitVersion is now something like '20150128.112847.17e840a'
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
[Unit]
|
||||
Description=Docker Application Container Engine
|
||||
Documentation=https://docs.docker.com
|
||||
After=network-online.target firewalld.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
# the default is not to use systemd for cgroups because the delegate issues still
|
||||
# exists and systemd currently does not support the cgroup feature set required
|
||||
# for containers run by docker
|
||||
ExecStart=/usr/bin/dockerd
|
||||
ExecReload=/bin/kill -s HUP $MAINPID
|
||||
# Having non-zero Limit*s causes performance problems due to accounting overhead
|
||||
# in the kernel. We recommend using cgroups to do container-local accounting.
|
||||
LimitNOFILE=infinity
|
||||
LimitNPROC=infinity
|
||||
LimitCORE=infinity
|
||||
# Uncomment TasksMax if your systemd version supports it.
|
||||
# Only systemd 226 and above support this version.
|
||||
#TasksMax=infinity
|
||||
TimeoutStartSec=0
|
||||
# set delegate yes so that systemd does not reset the cgroups of docker containers
|
||||
Delegate=yes
|
||||
# kill only the docker process, not all processes in the cgroup
|
||||
KillMode=process
|
||||
# restart the docker process if it exits prematurely
|
||||
Restart=on-failure
|
||||
StartLimitBurst=3
|
||||
StartLimitInterval=60s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user