Skip to content

Commit f8506da

Browse files
committed
Merge pull request #3204 from aledbf/remove_stoped_container
feat(publisher): remove application when is stopped
2 parents 0767383 + be660e0 commit f8506da

1 file changed

Lines changed: 35 additions & 3 deletions

File tree

publisher/server/publisher.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package server
22

33
import (
4-
"errors"
54
"fmt"
65
"log"
76
"net"
87
"os"
98
"regexp"
109
"strconv"
10+
"sync"
1111
"time"
1212

1313
"github.com/coreos/go-etcd/etcd"
@@ -25,6 +25,11 @@ type Server struct {
2525
EtcdClient *etcd.Client
2626
}
2727

28+
var safeMap = struct {
29+
sync.RWMutex
30+
data map[string]string
31+
}{data: make(map[string]string)}
32+
2833
// Listen adds an event listener to the docker client and publishes containers that were started.
2934
func (s *Server) Listen(ttl time.Duration) {
3035
listener := make(chan *docker.APIEvents)
@@ -44,6 +49,8 @@ func (s *Server) Listen(ttl time.Duration) {
4449
continue
4550
}
4651
s.publishContainer(container, ttl)
52+
} else if event.Status == "stop" {
53+
s.removeContainer(event.ID)
4754
}
4855
}
4956
}
@@ -73,7 +80,7 @@ func (s *Server) getContainer(id string) (*docker.APIContainers, error) {
7380
return &container, nil
7481
}
7582
}
76-
return nil, errors.New("could not find container")
83+
return nil, fmt.Errorf("could not find container with id %v", id)
7784
}
7885

7986
// publishContainer publishes the docker container to etcd.
@@ -89,19 +96,36 @@ func (s *Server) publishContainer(container *docker.APIContainers, ttl time.Dura
8996
continue
9097
}
9198
appName := match[1]
92-
keyPath := fmt.Sprintf("/deis/services/%s/%s", appName, containerName)
99+
appPath := fmt.Sprintf("%s/%s", appName, containerName)
100+
keyPath := fmt.Sprintf("/deis/services/%s", appPath)
93101
for _, p := range container.Ports {
94102
port := strconv.Itoa(int(p.PublicPort))
95103
hostAndPort := host + ":" + port
96104
if s.IsPublishableApp(containerName) && s.IsPortOpen(hostAndPort) {
97105
s.setEtcd(keyPath, hostAndPort, uint64(ttl.Seconds()))
106+
safeMap.Lock()
107+
safeMap.data[container.ID] = appPath
108+
safeMap.Unlock()
98109
}
99110
// TODO: support multiple exposed ports
100111
break
101112
}
102113
}
103114
}
104115

116+
// removeContainer remove a container published by this component
117+
func (s *Server) removeContainer(event string) {
118+
safeMap.RLock()
119+
appPath := safeMap.data[event]
120+
safeMap.RUnlock()
121+
122+
if appPath != "" {
123+
keyPath := fmt.Sprintf("/deis/services/%s", appPath)
124+
log.Printf("stopped %s\n", keyPath)
125+
s.removeEtcd(keyPath, false)
126+
}
127+
}
128+
105129
// IsPublishableApp determines if the application should be published to etcd.
106130
func (s *Server) IsPublishableApp(name string) bool {
107131
r := regexp.MustCompile(appNameRegex)
@@ -183,3 +207,11 @@ func (s *Server) setEtcd(key, value string, ttl uint64) {
183207
}
184208
log.Println("set", key, "->", value)
185209
}
210+
211+
// removeEtcd removes the corresponding etcd key
212+
func (s *Server) removeEtcd(key string, recursive bool) {
213+
if _, err := s.EtcdClient.Delete(key, recursive); err != nil {
214+
log.Println(err)
215+
}
216+
log.Println("del", key)
217+
}

0 commit comments

Comments
 (0)