@@ -5,18 +5,18 @@ import (
5
5
"context"
6
6
"fmt"
7
7
"os/exec"
8
+ "sort"
9
+ "strconv"
10
+ "strings"
8
11
"text/template"
12
+ "time"
9
13
10
14
"github.com/golang/glog"
11
15
varnishclient "github.com/martin-helmich/go-varnish-client"
12
16
)
13
17
14
18
func (v * VarnishController ) watchConfigUpdates (ctx context.Context , c * exec.Cmd , errors chan <- error ) {
15
- i := 0
16
-
17
19
for {
18
- i ++
19
-
20
20
select {
21
21
case tmplContents := <- v .vclTemplateUpdates :
22
22
glog .Infof ("VCL template has been updated" )
@@ -29,7 +29,7 @@ func (v *VarnishController) watchConfigUpdates(ctx context.Context, c *exec.Cmd,
29
29
30
30
v .vclTemplate = tmpl
31
31
32
- errors <- v .rebuildConfig (ctx , i )
32
+ errors <- v .rebuildConfig (ctx )
33
33
34
34
case newConfig := <- v .frontendUpdates :
35
35
glog .Infof ("received new frontend configuration: %+v" , newConfig )
@@ -40,14 +40,14 @@ func (v *VarnishController) watchConfigUpdates(ctx context.Context, c *exec.Cmd,
40
40
v .varnishSignaller .SetEndpoints (v .frontend )
41
41
}
42
42
43
- errors <- v .rebuildConfig (ctx , i )
43
+ errors <- v .rebuildConfig (ctx )
44
44
45
45
case newConfig := <- v .backendUpdates :
46
46
glog .Infof ("received new backend configuration: %+v" , newConfig )
47
47
48
48
v .backend = newConfig
49
49
50
- errors <- v .rebuildConfig (ctx , i )
50
+ errors <- v .rebuildConfig (ctx )
51
51
52
52
case <- ctx .Done ():
53
53
errors <- ctx .Err ()
@@ -56,7 +56,7 @@ func (v *VarnishController) watchConfigUpdates(ctx context.Context, c *exec.Cmd,
56
56
}
57
57
}
58
58
59
- func (v * VarnishController ) rebuildConfig (ctx context.Context , i int ) error {
59
+ func (v * VarnishController ) rebuildConfig (ctx context.Context ) error {
60
60
buf := new (bytes.Buffer )
61
61
62
62
err := v .renderVCL (buf , v .frontend .Endpoints , v .frontend .Primary , v .backend .Endpoints , v .backend .Primary )
@@ -77,7 +77,46 @@ func (v *VarnishController) rebuildConfig(ctx context.Context, i int) error {
77
77
return err
78
78
}
79
79
80
- configname := fmt .Sprintf ("k8s-upstreamcfg-%d" , i )
80
+ maxVclParam , err := client .GetParameter (ctx , "max_vcl" )
81
+ if err != nil {
82
+ return err
83
+ }
84
+
85
+ maxVcl , err := strconv .Atoi (maxVclParam .Value )
86
+ if err != nil {
87
+ return err
88
+ }
89
+
90
+ loadedVcl , err := client .ListVCL (ctx )
91
+ if err != nil {
92
+ return err
93
+ }
94
+
95
+ availableVcl := make ([]varnishclient.VCLConfig , 0 )
96
+
97
+ for i := range loadedVcl {
98
+ if loadedVcl [i ].Status == varnishclient .VCLAvailable {
99
+ availableVcl = append (availableVcl , loadedVcl [i ])
100
+ }
101
+ }
102
+
103
+ if len (loadedVcl ) >= maxVcl {
104
+ // we're abusing the fact that "boot" < "reload"
105
+ sort .Slice (availableVcl , func (i , j int ) bool {
106
+ return availableVcl [i ].Name < availableVcl [j ].Name
107
+ })
108
+
109
+ for i := 0 ; i < len (loadedVcl )- maxVcl + 1 ; i ++ {
110
+ glog .V (8 ).Infof ("discarding VCL: %s" , availableVcl [i ].Name )
111
+
112
+ err = client .DiscardVCL (ctx , availableVcl [i ].Name )
113
+ if err != nil {
114
+ return err
115
+ }
116
+ }
117
+ }
118
+
119
+ configname := strings .ReplaceAll (time .Now ().Format ("reload_20060102_150405.00000" ), "." , "_" )
81
120
82
121
err = client .DefineInlineVCL (ctx , configname , vcl , varnishclient .VCLStateAuto )
83
122
if err != nil {
0 commit comments