`--publish-add 8081:81 --publish-add 8082:82 --publish-rm 80
--publish-rm 81/tcp --publish-rm 82/tcp` would thus result in 81 and
82 to be published.
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
| ... | ... |
@@ -630,15 +630,7 @@ func (r byPortConfig) Less(i, j int) bool {
|
| 630 | 630 |
|
| 631 | 631 |
func portConfigToString(portConfig *swarm.PortConfig) string {
|
| 632 | 632 |
protocol := portConfig.Protocol |
| 633 |
- if protocol == "" {
|
|
| 634 |
- protocol = "tcp" |
|
| 635 |
- } |
|
| 636 |
- |
|
| 637 | 633 |
mode := portConfig.PublishMode |
| 638 |
- if mode == "" {
|
|
| 639 |
- mode = "ingress" |
|
| 640 |
- } |
|
| 641 |
- |
|
| 642 | 634 |
return fmt.Sprintf("%v:%v/%s/%s", portConfig.PublishedPort, portConfig.TargetPort, protocol, mode)
|
| 643 | 635 |
} |
| 644 | 636 |
|
| ... | ... |
@@ -663,28 +655,18 @@ func validatePublishRemove(val string) (string, error) {
|
| 663 | 663 |
func updatePorts(flags *pflag.FlagSet, portConfig *[]swarm.PortConfig) error {
|
| 664 | 664 |
// The key of the map is `port/protocol`, e.g., `80/tcp` |
| 665 | 665 |
portSet := map[string]swarm.PortConfig{}
|
| 666 |
- // Check to see if there are any conflict in flags. |
|
| 667 |
- if flags.Changed(flagPublishAdd) {
|
|
| 668 |
- ports := flags.Lookup(flagPublishAdd).Value.(*opts.PortOpt).Value() |
|
| 669 | 666 |
|
| 670 |
- for _, port := range ports {
|
|
| 671 |
- if v, ok := portSet[portConfigToString(&port)]; ok && v != port {
|
|
| 672 |
- return fmt.Errorf("conflicting port mapping between %v:%v/%s and %v:%v/%s", port.PublishedPort, port.TargetPort, port.Protocol, v.PublishedPort, v.TargetPort, v.Protocol)
|
|
| 673 |
- } |
|
| 674 |
- portSet[portConfigToString(&port)] = port |
|
| 675 |
- } |
|
| 676 |
- } |
|
| 677 |
- |
|
| 678 |
- // Override previous PortConfig in service if there is any duplicate |
|
| 667 |
+ // Build the current list of portConfig |
|
| 679 | 668 |
for _, entry := range *portConfig {
|
| 680 | 669 |
if _, ok := portSet[portConfigToString(&entry)]; !ok {
|
| 681 | 670 |
portSet[portConfigToString(&entry)] = entry |
| 682 | 671 |
} |
| 683 | 672 |
} |
| 684 | 673 |
|
| 685 |
- toRemove := flags.Lookup(flagPublishRemove).Value.(*opts.PortOpt).Value() |
|
| 686 |
- |
|
| 687 | 674 |
newPorts := []swarm.PortConfig{}
|
| 675 |
+ |
|
| 676 |
+ // Clean current ports |
|
| 677 |
+ toRemove := flags.Lookup(flagPublishRemove).Value.(*opts.PortOpt).Value() |
|
| 688 | 678 |
portLoop: |
| 689 | 679 |
for _, port := range portSet {
|
| 690 | 680 |
for _, pConfig := range toRemove {
|
| ... | ... |
@@ -698,6 +680,23 @@ portLoop: |
| 698 | 698 |
newPorts = append(newPorts, port) |
| 699 | 699 |
} |
| 700 | 700 |
|
| 701 |
+ // Check to see if there are any conflict in flags. |
|
| 702 |
+ if flags.Changed(flagPublishAdd) {
|
|
| 703 |
+ ports := flags.Lookup(flagPublishAdd).Value.(*opts.PortOpt).Value() |
|
| 704 |
+ |
|
| 705 |
+ for _, port := range ports {
|
|
| 706 |
+ if v, ok := portSet[portConfigToString(&port)]; ok {
|
|
| 707 |
+ if v != port {
|
|
| 708 |
+ fmt.Println("v", v)
|
|
| 709 |
+ return fmt.Errorf("conflicting port mapping between %v:%v/%s and %v:%v/%s", port.PublishedPort, port.TargetPort, port.Protocol, v.PublishedPort, v.TargetPort, v.Protocol)
|
|
| 710 |
+ } |
|
| 711 |
+ continue |
|
| 712 |
+ } |
|
| 713 |
+ //portSet[portConfigToString(&port)] = port |
|
| 714 |
+ newPorts = append(newPorts, port) |
|
| 715 |
+ } |
|
| 716 |
+ } |
|
| 717 |
+ |
|
| 701 | 718 |
// Sort the PortConfig to avoid unnecessary updates |
| 702 | 719 |
sort.Sort(byPortConfig(newPorts)) |
| 703 | 720 |
*portConfig = newPorts |
| ... | ... |
@@ -220,28 +220,18 @@ func TestUpdatePorts(t *testing.T) {
|
| 220 | 220 |
assert.Equal(t, targetPorts[1], 1000) |
| 221 | 221 |
} |
| 222 | 222 |
|
| 223 |
-func TestUpdatePortsDuplicateEntries(t *testing.T) {
|
|
| 223 |
+func TestUpdatePortsDuplicate(t *testing.T) {
|
|
| 224 | 224 |
// Test case for #25375 |
| 225 | 225 |
flags := newUpdateCommand(nil).Flags() |
| 226 | 226 |
flags.Set("publish-add", "80:80")
|
| 227 | 227 |
|
| 228 | 228 |
portConfigs := []swarm.PortConfig{
|
| 229 |
- {TargetPort: 80, PublishedPort: 80},
|
|
| 230 |
- } |
|
| 231 |
- |
|
| 232 |
- err := updatePorts(flags, &portConfigs) |
|
| 233 |
- assert.Equal(t, err, nil) |
|
| 234 |
- assert.Equal(t, len(portConfigs), 1) |
|
| 235 |
- assert.Equal(t, portConfigs[0].TargetPort, uint32(80)) |
|
| 236 |
-} |
|
| 237 |
- |
|
| 238 |
-func TestUpdatePortsDuplicateKeys(t *testing.T) {
|
|
| 239 |
- // Test case for #25375 |
|
| 240 |
- flags := newUpdateCommand(nil).Flags() |
|
| 241 |
- flags.Set("publish-add", "80:80")
|
|
| 242 |
- |
|
| 243 |
- portConfigs := []swarm.PortConfig{
|
|
| 244 |
- {TargetPort: 80, PublishedPort: 80},
|
|
| 229 |
+ {
|
|
| 230 |
+ TargetPort: 80, |
|
| 231 |
+ PublishedPort: 80, |
|
| 232 |
+ Protocol: swarm.PortConfigProtocolTCP, |
|
| 233 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 234 |
+ }, |
|
| 245 | 235 |
} |
| 246 | 236 |
|
| 247 | 237 |
err := updatePorts(flags, &portConfigs) |
| ... | ... |
@@ -355,13 +345,19 @@ func TestUpdatePortsRmWithProtocol(t *testing.T) {
|
| 355 | 355 |
flags.Set("publish-rm", "82/udp")
|
| 356 | 356 |
|
| 357 | 357 |
portConfigs := []swarm.PortConfig{
|
| 358 |
- {TargetPort: 80, PublishedPort: 8080, Protocol: swarm.PortConfigProtocolTCP},
|
|
| 358 |
+ {
|
|
| 359 |
+ TargetPort: 80, |
|
| 360 |
+ PublishedPort: 8080, |
|
| 361 |
+ Protocol: swarm.PortConfigProtocolTCP, |
|
| 362 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 363 |
+ }, |
|
| 359 | 364 |
} |
| 360 | 365 |
|
| 361 | 366 |
err := updatePorts(flags, &portConfigs) |
| 362 | 367 |
assert.Equal(t, err, nil) |
| 363 |
- assert.Equal(t, len(portConfigs), 1) |
|
| 364 |
- assert.Equal(t, portConfigs[0].TargetPort, uint32(82)) |
|
| 368 |
+ assert.Equal(t, len(portConfigs), 2) |
|
| 369 |
+ assert.Equal(t, portConfigs[0].TargetPort, uint32(81)) |
|
| 370 |
+ assert.Equal(t, portConfigs[1].TargetPort, uint32(82)) |
|
| 365 | 371 |
} |
| 366 | 372 |
|
| 367 | 373 |
// FIXME(vdemeester) port to opts.PortOpt |
| ... | ... |
@@ -264,13 +264,13 @@ func (s *DockerSwarmSuite) TestSwarmPublishAdd(c *check.C) {
|
| 264 | 264 |
c.Assert(err, checker.IsNil, check.Commentf(out)) |
| 265 | 265 |
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") |
| 266 | 266 |
|
| 267 |
- out, err = d.CmdRetryOutOfSequence("service", "update", "--publish-add", tc.publishAdd[0], tc.name)
|
|
| 267 |
+ out, err = d.cmdRetryOutOfSequence("service", "update", "--publish-add", tc.publishAdd[0], tc.name)
|
|
| 268 | 268 |
c.Assert(err, checker.IsNil, check.Commentf(out)) |
| 269 | 269 |
|
| 270 |
- out, err = d.CmdRetryOutOfSequence("service", "update", "--publish-add", tc.publishAdd[1], tc.name)
|
|
| 270 |
+ out, err = d.cmdRetryOutOfSequence("service", "update", "--publish-add", tc.publishAdd[1], tc.name)
|
|
| 271 | 271 |
c.Assert(err, checker.IsNil, check.Commentf(out)) |
| 272 | 272 |
|
| 273 |
- out, err = d.CmdRetryOutOfSequence("service", "update", "--publish-add", tc.publishAdd[2], "--publish-add", tc.publishAdd[3], tc.name)
|
|
| 273 |
+ out, err = d.cmdRetryOutOfSequence("service", "update", "--publish-add", tc.publishAdd[2], "--publish-add", tc.publishAdd[3], tc.name)
|
|
| 274 | 274 |
c.Assert(err, checker.NotNil, check.Commentf(out)) |
| 275 | 275 |
|
| 276 | 276 |
out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.EndpointSpec.Ports }}", tc.name)
|
| ... | ... |
@@ -82,6 +82,14 @@ func (p *PortOpt) Set(value string) error {
|
| 82 | 82 |
return fmt.Errorf("missing mandatory field %q", portOptTargetPort)
|
| 83 | 83 |
} |
| 84 | 84 |
|
| 85 |
+ if pConfig.PublishMode == "" {
|
|
| 86 |
+ pConfig.PublishMode = swarm.PortConfigPublishModeIngress |
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ if pConfig.Protocol == "" {
|
|
| 90 |
+ pConfig.Protocol = swarm.PortConfigProtocolTCP |
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 85 | 93 |
p.ports = append(p.ports, pConfig) |
| 86 | 94 |
} else {
|
| 87 | 95 |
// short syntax |
| ... | ... |
@@ -131,6 +139,7 @@ func ConvertPortToPortConfig( |
| 131 | 131 |
Protocol: swarm.PortConfigProtocol(strings.ToLower(port.Proto())), |
| 132 | 132 |
TargetPort: uint32(port.Int()), |
| 133 | 133 |
PublishedPort: uint32(hostPort), |
| 134 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 134 | 135 |
}) |
| 135 | 136 |
} |
| 136 | 137 |
return ports |
| ... | ... |
@@ -16,8 +16,9 @@ func TestPortOptValidSimpleSyntax(t *testing.T) {
|
| 16 | 16 |
value: "80", |
| 17 | 17 |
expected: []swarm.PortConfig{
|
| 18 | 18 |
{
|
| 19 |
- Protocol: "tcp", |
|
| 20 |
- TargetPort: 80, |
|
| 19 |
+ Protocol: "tcp", |
|
| 20 |
+ TargetPort: 80, |
|
| 21 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 21 | 22 |
}, |
| 22 | 23 |
}, |
| 23 | 24 |
}, |
| ... | ... |
@@ -28,6 +29,7 @@ func TestPortOptValidSimpleSyntax(t *testing.T) {
|
| 28 | 28 |
Protocol: "tcp", |
| 29 | 29 |
TargetPort: 8080, |
| 30 | 30 |
PublishedPort: 80, |
| 31 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 31 | 32 |
}, |
| 32 | 33 |
}, |
| 33 | 34 |
}, |
| ... | ... |
@@ -38,6 +40,7 @@ func TestPortOptValidSimpleSyntax(t *testing.T) {
|
| 38 | 38 |
Protocol: "tcp", |
| 39 | 39 |
TargetPort: 80, |
| 40 | 40 |
PublishedPort: 8080, |
| 41 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 41 | 42 |
}, |
| 42 | 43 |
}, |
| 43 | 44 |
}, |
| ... | ... |
@@ -48,6 +51,7 @@ func TestPortOptValidSimpleSyntax(t *testing.T) {
|
| 48 | 48 |
Protocol: "udp", |
| 49 | 49 |
TargetPort: 8080, |
| 50 | 50 |
PublishedPort: 80, |
| 51 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 51 | 52 |
}, |
| 52 | 53 |
}, |
| 53 | 54 |
}, |
| ... | ... |
@@ -58,11 +62,13 @@ func TestPortOptValidSimpleSyntax(t *testing.T) {
|
| 58 | 58 |
Protocol: "tcp", |
| 59 | 59 |
TargetPort: 8080, |
| 60 | 60 |
PublishedPort: 80, |
| 61 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 61 | 62 |
}, |
| 62 | 63 |
{
|
| 63 | 64 |
Protocol: "tcp", |
| 64 | 65 |
TargetPort: 8081, |
| 65 | 66 |
PublishedPort: 81, |
| 67 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 66 | 68 |
}, |
| 67 | 69 |
}, |
| 68 | 70 |
}, |
| ... | ... |
@@ -73,16 +79,19 @@ func TestPortOptValidSimpleSyntax(t *testing.T) {
|
| 73 | 73 |
Protocol: "udp", |
| 74 | 74 |
TargetPort: 8080, |
| 75 | 75 |
PublishedPort: 80, |
| 76 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 76 | 77 |
}, |
| 77 | 78 |
{
|
| 78 | 79 |
Protocol: "udp", |
| 79 | 80 |
TargetPort: 8081, |
| 80 | 81 |
PublishedPort: 81, |
| 82 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 81 | 83 |
}, |
| 82 | 84 |
{
|
| 83 | 85 |
Protocol: "udp", |
| 84 | 86 |
TargetPort: 8082, |
| 85 | 87 |
PublishedPort: 82, |
| 88 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 86 | 89 |
}, |
| 87 | 90 |
}, |
| 88 | 91 |
}, |
| ... | ... |
@@ -106,7 +115,9 @@ func TestPortOptValidComplexSyntax(t *testing.T) {
|
| 106 | 106 |
value: "target=80", |
| 107 | 107 |
expected: []swarm.PortConfig{
|
| 108 | 108 |
{
|
| 109 |
- TargetPort: 80, |
|
| 109 |
+ TargetPort: 80, |
|
| 110 |
+ Protocol: "tcp", |
|
| 111 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 110 | 112 |
}, |
| 111 | 113 |
}, |
| 112 | 114 |
}, |
| ... | ... |
@@ -114,8 +125,9 @@ func TestPortOptValidComplexSyntax(t *testing.T) {
|
| 114 | 114 |
value: "target=80,protocol=tcp", |
| 115 | 115 |
expected: []swarm.PortConfig{
|
| 116 | 116 |
{
|
| 117 |
- Protocol: "tcp", |
|
| 118 |
- TargetPort: 80, |
|
| 117 |
+ Protocol: "tcp", |
|
| 118 |
+ TargetPort: 80, |
|
| 119 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 119 | 120 |
}, |
| 120 | 121 |
}, |
| 121 | 122 |
}, |
| ... | ... |
@@ -126,6 +138,7 @@ func TestPortOptValidComplexSyntax(t *testing.T) {
|
| 126 | 126 |
Protocol: "tcp", |
| 127 | 127 |
TargetPort: 80, |
| 128 | 128 |
PublishedPort: 8080, |
| 129 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 129 | 130 |
}, |
| 130 | 131 |
}, |
| 131 | 132 |
}, |
| ... | ... |
@@ -136,6 +149,7 @@ func TestPortOptValidComplexSyntax(t *testing.T) {
|
| 136 | 136 |
Protocol: "tcp", |
| 137 | 137 |
TargetPort: 8080, |
| 138 | 138 |
PublishedPort: 80, |
| 139 |
+ PublishMode: swarm.PortConfigPublishModeIngress, |
|
| 139 | 140 |
}, |
| 140 | 141 |
}, |
| 141 | 142 |
}, |
| ... | ... |
@@ -157,6 +171,7 @@ func TestPortOptValidComplexSyntax(t *testing.T) {
|
| 157 | 157 |
TargetPort: 80, |
| 158 | 158 |
PublishedPort: 8080, |
| 159 | 159 |
PublishMode: "host", |
| 160 |
+ Protocol: "tcp", |
|
| 160 | 161 |
}, |
| 161 | 162 |
}, |
| 162 | 163 |
}, |
| ... | ... |
@@ -167,6 +182,7 @@ func TestPortOptValidComplexSyntax(t *testing.T) {
|
| 167 | 167 |
TargetPort: 80, |
| 168 | 168 |
PublishedPort: 8080, |
| 169 | 169 |
PublishMode: "ingress", |
| 170 |
+ Protocol: "tcp", |
|
| 170 | 171 |
}, |
| 171 | 172 |
}, |
| 172 | 173 |
}, |