|
2 | 2 | package cleaner |
3 | 3 |
|
4 | 4 | import ( |
5 | | - "io/ioutil" |
6 | 5 | "log" |
7 | 6 | "os" |
8 | | - "path/filepath" |
9 | | - "strings" |
10 | | - "sync" |
11 | | - "time" |
12 | 7 |
|
13 | | - "github.com/deis/builder/pkg/k8s" |
14 | 8 | "k8s.io/kubernetes/pkg/api" |
15 | | - "k8s.io/kubernetes/pkg/fields" |
16 | | - "k8s.io/kubernetes/pkg/labels" |
| 9 | + |
| 10 | + "github.com/deis/builder/pkg/k8s" |
17 | 11 | ) |
18 | 12 |
|
19 | 13 | const ( |
20 | 14 | dotGitSuffix = ".git" |
21 | 15 | ) |
22 | 16 |
|
23 | | -type Ref struct { |
24 | | - mut *sync.Mutex |
25 | | -} |
26 | | - |
27 | | -func NewRef() Ref { |
28 | | - return Ref{mut: new(sync.Mutex)} |
29 | | -} |
30 | | - |
31 | | -func (c Ref) Lock() { |
32 | | - c.mut.Lock() |
33 | | -} |
34 | | - |
35 | | -func (c Ref) Unlock() { |
36 | | - c.mut.Unlock() |
37 | | -} |
| 17 | +// Run starts the deleted app cleaner. Every pollSleepDuration, it compares the result of nsLister.List with the directories in the top level of gitHome on the local file system. On any error, it uses log messages to output a human readable description of what happened. |
| 18 | +func Run(gitHome string, nsLister k8s.NamespaceWatcher) error { |
38 | 19 |
|
39 | | -// localDirs returns all of the local directories immediately under gitHome that filter returns true for. filter will receive only the names of each of the top level directories (not their fully qualified paths), and should return true if it should be included in the output |
40 | | -func localDirs(gitHome string, filter func(string) bool) ([]string, error) { |
41 | | - fileInfos, err := ioutil.ReadDir(gitHome) |
| 20 | + watcher, err := nsLister.Watch(nil, nil, "") |
42 | 21 | if err != nil { |
43 | | - return nil, err |
44 | | - } |
45 | | - var ret []string |
46 | | - for _, fileInfo := range fileInfos { |
47 | | - nm := fileInfo.Name() |
48 | | - if len(nm) <= 0 || nm == "." || !fileInfo.IsDir() { |
49 | | - continue |
50 | | - } |
51 | | - if filter(nm) { |
52 | | - ret = append(ret, filepath.Join(gitHome, nm)) |
53 | | - } |
54 | | - } |
55 | | - return ret, nil |
56 | | -} |
57 | | - |
58 | | -// getDiff gets the directories that are not in namespaceList |
59 | | -func getDiff(namespaceList []api.Namespace, dirs []string) []string { |
60 | | - var ret []string |
61 | | - |
62 | | - // create a set of lowercase namespace names |
63 | | - namespacesSet := make(map[string]struct{}) |
64 | | - for _, ns := range namespaceList { |
65 | | - lowerName := strings.ToLower(ns.Name) |
66 | | - namespacesSet[lowerName] = struct{}{} |
| 22 | + log.Printf("unable to get watch events (%s)", err) |
67 | 23 | } |
68 | | - |
69 | | - // get dirs not in the namespaces set |
70 | | - for _, dir := range dirs { |
71 | | - lowerName := strings.ToLower(dir) |
72 | | - if _, ok := namespacesSet[lowerName]; !ok { |
73 | | - ret = append(ret, lowerName) |
74 | | - } |
75 | | - } |
76 | | - |
77 | | - return ret |
78 | | -} |
79 | | - |
80 | | -func stripSuffixes(strs []string, suffix string) []string { |
81 | | - ret := make([]string, len(strs)) |
82 | | - for i, str := range strs { |
83 | | - idx := strings.LastIndex(str, suffix) |
84 | | - if idx >= 0 { |
85 | | - ret[i] = str[:idx] |
86 | | - } else { |
87 | | - ret[i] = str |
88 | | - } |
89 | | - } |
90 | | - return ret |
91 | | -} |
92 | | - |
93 | | -func dirHasGitSuffix(dir string) bool { |
94 | | - return strings.HasSuffix(dir, dotGitSuffix) |
95 | | -} |
96 | | - |
97 | | -// Run starts the deleted app cleaner. Every pollSleepDuration, it compares the result of nsLister.List with the directories in the top level of gitHome on the local file system. On any error, it uses log messages to output a human readable description of what happened. |
98 | | -func (c Ref) Run(gitHome string, nsLister k8s.NamespaceLister, pollSleepDuration time.Duration) error { |
99 | 24 | for { |
100 | | - nsList, err := nsLister.List(labels.Everything(), fields.Everything()) |
101 | | - if err != nil { |
102 | | - log.Printf("Cleaner error listing namespaces (%s)", err) |
103 | | - continue |
104 | | - } else { |
105 | | - lst := make([]string, len(nsList.Items)) |
106 | | - for i, ns := range nsList.Items { |
107 | | - lst[i] = strings.ToLower(ns.Name) |
| 25 | + event := <-watcher.ResultChan() |
| 26 | + if event.Type == "DELETED" { |
| 27 | + namespace := event.Object.(*api.Namespace) |
| 28 | + appToDelete := gitHome + "/" + namespace.ObjectMeta.Name + dotGitSuffix |
| 29 | + if err := os.RemoveAll(appToDelete); err != nil { |
| 30 | + log.Printf("Cleaner error removing deleted app %s (%s)", appToDelete, err) |
108 | 31 | } |
109 | 32 | } |
110 | 33 |
|
111 | | - gitDirs, err := localDirs(gitHome, dirHasGitSuffix) |
112 | | - if err != nil { |
113 | | - log.Printf("Cleaner error listing local git directories (%s)", err) |
114 | | - continue |
115 | | - } |
116 | | - |
117 | | - gitDirs = stripSuffixes(gitDirs, dotGitSuffix) |
118 | | - |
119 | | - appsToDelete := getDiff(nsList.Items, gitDirs) |
120 | | - |
121 | | - for _, appToDelete := range appsToDelete { |
122 | | - dirToDelete := appToDelete + dotGitSuffix |
123 | | - c.Lock() |
124 | | - if err := os.RemoveAll(dirToDelete); err != nil { |
125 | | - log.Printf("Cleaner error removing deleted app %s (%s)", dirToDelete, err) |
126 | | - } |
127 | | - c.Unlock() |
128 | | - } |
129 | | - |
130 | | - time.Sleep(pollSleepDuration) |
131 | 34 | } |
| 35 | + |
132 | 36 | } |
0 commit comments