7
7
package main
8
8
9
9
import (
10
+ "bytes"
10
11
"context"
12
+ "encoding/json"
11
13
"fmt"
12
14
"io"
13
15
"log/syslog"
16
+ "net/http"
14
17
"os"
15
18
"path/filepath"
16
19
"strings"
@@ -43,6 +46,8 @@ type PluginConfig struct {
43
46
Readable bool `toml:"readable"`
44
47
Timeout int `toml:"timeout"`
45
48
Overwrite bool `toml:"overwrite"`
49
+ Domain string `toml:"domain"`
50
+ Port string `toml:"port"`
46
51
}
47
52
48
53
type PluginArgs struct {
@@ -104,6 +109,16 @@ func buildFlags(args *PluginArgs) []cli.Flag {
104
109
Usage : "whether to overwrite the existed persistent files" ,
105
110
Destination : & args .Config .Overwrite ,
106
111
},
112
+ & cli.StringFlag {
113
+ Name : "domain" ,
114
+ Usage : "domain of prefetchlist store service" ,
115
+ Destination : & args .Config .Domain ,
116
+ },
117
+ & cli.StringFlag {
118
+ Name : "port" ,
119
+ Usage : "port of prefetchlist store service" ,
120
+ Destination : & args .Config .Port ,
121
+ },
107
122
}
108
123
}
109
124
@@ -129,9 +144,12 @@ var (
129
144
)
130
145
131
146
const (
132
- imageNameLabel = "io.kubernetes.cri.image-name"
147
+ imageNameLabel = "io.kubernetes.cri.image-name"
148
+ containerNameLabel = "io.kubernetes.cri.container-name"
133
149
)
134
150
151
+ const defaultEndpoint = "/api/v1/prefetch/upload"
152
+
135
153
func (p * plugin ) Configure (config , runtime , version string ) (stub.EventMask , error ) {
136
154
log .Infof ("got configuration data: %q from runtime %s %s" , config , runtime , version )
137
155
if config == "" {
@@ -156,11 +174,26 @@ func (p *plugin) Configure(config, runtime, version string) (stub.EventMask, err
156
174
return p .mask , nil
157
175
}
158
176
177
+ type PrefetchFile struct {
178
+ Path string
179
+ }
180
+
181
+ type CacheItem struct {
182
+ ImageName string
183
+ ContainerName string
184
+ PrefetchFiles []PrefetchFile
185
+ }
186
+
187
+ type Cache struct {
188
+ Items map [string ]* CacheItem
189
+ }
190
+
159
191
func (p * plugin ) StartContainer (_ * api.PodSandbox , container * api.Container ) error {
160
192
dir , imageName , err := GetImageName (container .Annotations )
161
193
if err != nil {
162
194
return err
163
195
}
196
+ containerName := container .Annotations [containerNameLabel ]
164
197
165
198
persistDir := filepath .Join (cfg .PersistDir , dir )
166
199
if err := os .MkdirAll (persistDir , os .ModePerm ); err != nil {
@@ -178,11 +211,74 @@ func (p *plugin) StartContainer(_ *api.PodSandbox, container *api.Container) err
178
211
return err
179
212
}
180
213
214
+ imageRepo := container .Annotations [imageNameLabel ]
215
+ serverURL := fmt .Sprintf ("%s:%s" , cfg .Domain , cfg .Port )
216
+
217
+ go func () {
218
+ time .Sleep (1 * time .Minute )
219
+ if err := sendToServer (imageRepo , persistFile , containerName , serverURL ); err != nil {
220
+ log .WithError (err ).Error ("failed to send prefetch to http server" )
221
+ }
222
+ }()
223
+
181
224
globalFanotifyServer [imageName ] = fanotifyServer
182
225
183
226
return nil
184
227
}
185
228
229
+ func sendToServer (imageName , prefetchlistPath , containerName , serverURL string ) error {
230
+ data , err := os .ReadFile (prefetchlistPath )
231
+ if err != nil {
232
+ return fmt .Errorf ("error reading file: %w" , err )
233
+ }
234
+
235
+ filePaths := strings .Split (string (data ), "\n " )
236
+
237
+ var prefetchFiles []PrefetchFile
238
+ for _ , path := range filePaths {
239
+ if path != "" {
240
+ prefetchFiles = append (prefetchFiles , PrefetchFile {Path : path })
241
+ }
242
+ }
243
+
244
+ item := CacheItem {
245
+ ImageName : imageName ,
246
+ ContainerName : containerName ,
247
+ PrefetchFiles : prefetchFiles ,
248
+ }
249
+
250
+ url := fmt .Sprintf ("http://%s%s" , serverURL , defaultEndpoint )
251
+
252
+ err = postRequest (item , url )
253
+ if err != nil {
254
+ return fmt .Errorf ("error uploading to server: %w" , err )
255
+ }
256
+
257
+ return nil
258
+ }
259
+
260
+ func postRequest (item CacheItem , endpoint string ) error {
261
+ data , err := json .Marshal (item )
262
+ if err != nil {
263
+ return err
264
+ }
265
+
266
+ resp , err := http .Post (endpoint , "application/json" , bytes .NewBuffer (data ))
267
+ if err != nil {
268
+ return err
269
+ }
270
+ defer resp .Body .Close ()
271
+
272
+ body , err := io .ReadAll (resp .Body )
273
+ if err != nil {
274
+ return fmt .Errorf ("failed to read response body: %w" , err )
275
+ }
276
+
277
+ fmt .Println ("Server Response:" , string (body ))
278
+
279
+ return nil
280
+ }
281
+
186
282
func (p * plugin ) StopContainer (_ * api.PodSandbox , container * api.Container ) ([]* api.ContainerUpdate , error ) {
187
283
var update = []* api.ContainerUpdate {}
188
284
_ , imageName , err := GetImageName (container .Annotations )
0 commit comments