@@ -89,6 +89,15 @@ func scrapeMetricsForServer(t TestingT, srv RunningServer) {
8989 if err := ScrapeMetrics (ctx , srv .RootShardSystemMasterBaseConfig (t ), promUrl , repoDir , jobName , caFile , labels ); err != nil {
9090 t .Logf ("error configuring Prometheus scraping for server %s: %v" , srv .Name (), err )
9191 }
92+
93+ // Clean up Prometheus configuration when test finishes
94+ t .Cleanup (func () {
95+ cleanupCtx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
96+ defer cancel ()
97+ if err := CleanupScrapeMetrics (cleanupCtx , promUrl , repoDir , jobName ); err != nil {
98+ t .Logf ("error cleaning up Prometheus scrape config for server %s: %v" , srv .Name (), err )
99+ }
100+ })
92101}
93102
94103func ScrapeMetrics (ctx context.Context , cfg * rest.Config , promUrl , promCfgDir , jobName , caFile string , labels map [string ]string ) error {
@@ -174,3 +183,90 @@ func ScrapeMetrics(ctx context.Context, cfg *rest.Config, promUrl, promCfgDir, j
174183 resp .Body .Close ()
175184 return nil
176185}
186+
187+ func CleanupScrapeMetrics (ctx context.Context , promUrl , promCfgDir , jobNamePrefix string ) error {
188+ type staticConfigs struct {
189+ Targets []string `yaml:"targets,omitempty"`
190+ Labels map [string ]string `yaml:"labels,omitempty"`
191+ }
192+ type tlsConfig struct {
193+ InsecureSkipVerify bool `yaml:"insecure_skip_verify,omitempty"`
194+ CaFile string `yaml:"ca_file,omitempty"`
195+ }
196+ type scrapeConfig struct {
197+ JobName string `yaml:"job_name,omitempty"`
198+ ScrapeInterval string `yaml:"scrape_interval,omitempty"`
199+ BearerToken string `yaml:"bearer_token,omitempty"`
200+ TlsConfig tlsConfig `yaml:"tls_config,omitempty"`
201+ Scheme string `yaml:"scheme,omitempty"`
202+ StaticConfigs []staticConfigs `yaml:"static_configs,omitempty"`
203+ }
204+ type config struct {
205+ ScrapeConfigs []scrapeConfig `yaml:"scrape_configs,omitempty"`
206+ }
207+
208+ err := func () error {
209+ scrapeConfigFile := filepath .Join (promCfgDir , ".prometheus-config.yaml" )
210+ f , err := os .OpenFile (scrapeConfigFile , os .O_RDWR , 0o644 )
211+ if os .IsNotExist (err ) {
212+ return nil // Nothing to clean up
213+ }
214+ if err != nil {
215+ return err
216+ }
217+ defer f .Close ()
218+
219+ // lock config file exclusively
220+ err = syscall .Flock (int (f .Fd ()), syscall .LOCK_EX )
221+ if err != nil {
222+ return err
223+ }
224+ defer syscall .Flock (int (f .Fd ()), syscall .LOCK_UN )
225+
226+ promCfg := config {}
227+ err = gopkgyaml .NewDecoder (f ).Decode (& promCfg )
228+ if err != nil && ! errors .Is (err , io .EOF ) {
229+ return err
230+ }
231+
232+ // Remove scrape configs that match the job name prefix
233+ var filteredConfigs []scrapeConfig
234+ for _ , cfg := range promCfg .ScrapeConfigs {
235+ // Check if CA file still exists - if not, remove the config
236+ if cfg .TlsConfig .CaFile != "" {
237+ if _ , err := os .Stat (cfg .TlsConfig .CaFile ); os .IsNotExist (err ) {
238+ continue // Skip this config - CA file is gone
239+ }
240+ }
241+ filteredConfigs = append (filteredConfigs , cfg )
242+ }
243+
244+ promCfg .ScrapeConfigs = filteredConfigs
245+
246+ err = f .Truncate (0 )
247+ if err != nil {
248+ return err
249+ }
250+ _ , err = f .Seek (0 , 0 )
251+ if err != nil {
252+ return err
253+ }
254+ return gopkgyaml .NewEncoder (f ).Encode (& promCfg )
255+ }()
256+ if err != nil {
257+ return err
258+ }
259+
260+ // Reload Prometheus configuration
261+ req , err := http .NewRequestWithContext (ctx , http .MethodPost , promUrl + "/-/reload" , http .NoBody )
262+ if err != nil {
263+ return err
264+ }
265+ c := & http.Client {}
266+ resp , err := c .Do (req )
267+ if err != nil {
268+ return err
269+ }
270+ resp .Body .Close ()
271+ return nil
272+ }
0 commit comments