From f219e0b270c366aeb249677201dc67ffc37aef8e Mon Sep 17 00:00:00 2001 From: javivf Date: Fri, 29 Nov 2024 23:42:05 +0100 Subject: [PATCH 1/2] using worker pool to boost deletion process --- README.md | 5 +++-- main.go | 60 +++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 11571a5..3ac8255 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Golang CLI to delete GitLab stored artifacts When you need to wipe out a Gitlab project's artifacts, this is the tool for you. It will delete all the artifacts in a project. It will not delete the project itself. It will not delete the project's repository. Because of GitLab API limitations, you need to know how many job pages you need to iterate through to delete all the artifacts. This is how GitLab API works. If you don't know it, just use the standard values: - + ```yaml per_page: 100 page: 20 @@ -22,9 +22,10 @@ Parameters: - `--project_id`: Project ID or path. - `--per-page`: Number of jobs to fetch per page. Default: `100` - `--page`: Page number. Default: `1` +- `--concurrent_requests`: Number of concurrent requests ```bash -gitlab-artifacts-cleaner --server https://gitlab.com --token --project_id --pages 10 --per_page 100 +gitlab-artifacts-cleaner --server https://gitlab.com --token --project_id --pages 10 --per_page 100 --concurrent_requests 5 ``` This is a work in progress. If you have any suggestions, please open an issue. diff --git a/main.go b/main.go index e0c42ad..9559e7e 100644 --- a/main.go +++ b/main.go @@ -5,22 +5,48 @@ import ( "flag" "fmt" "net/http" + "sync" ) type Job struct { - ID int `json:"id"` + ID int `json:"id"` } -func main () { +func worker(server string, project_id int, token string, jobs <-chan Job, results chan<- *http.Response, wg *sync.WaitGroup) { + for job := range jobs { + fmt.Println("job to process:", job.ID) + url := fmt.Sprintf("%v/api/v4/projects/%v/jobs/%d/artifacts", server, project_id, job.ID) + req, err := http.NewRequest("DELETE", url, nil) + if err != nil { + fmt.Println(err) + return + } + req.Header.Set("PRIVATE-TOKEN", token) + resp, err := http.DefaultClient.Do(req) + if err != nil { + fmt.Println(err) + return + } + defer resp.Body.Close() + fmt.Println("job artifacts deleted:", job.ID, resp.StatusCode) + + results <- resp + wg.Done() + } +} + +func main() { var project_id int var per_page int var pages int + var concurrent_requests int var token string var server string flag.IntVar(&project_id, "project_id", 0, "Project ID") flag.IntVar(&per_page, "per_page", 100, "Number of jobs per page") flag.IntVar(&pages, "pages", 1, "Number of pages") + flag.IntVar(&concurrent_requests, "concurrent_requests", 5, "Number of concurrent requests") flag.StringVar(&token, "token", "", "Private token") flag.StringVar(&server, "server", "", "Gitlab server") flag.Parse() @@ -50,22 +76,22 @@ func main () { return } + pool_jobs := make(chan Job, len(jobs)) + results := make(chan *http.Response, len(jobs)) + var wg sync.WaitGroup + + // Start workers + for w := 0; w < concurrent_requests; w++ { + go worker(server, project_id, token, pool_jobs, results, &wg) + } + + // Sending jobs to the worker pool + wg.Add(len(jobs)) for _, job := range jobs { - fmt.Println("job to process:", job.ID) - url := fmt.Sprintf("%v/api/v4/projects/%v/jobs/%d/artifacts", server, project_id, job.ID) - req, err := http.NewRequest("DELETE", url, nil) - if err != nil { - fmt.Println(err) - return - } - req.Header.Set("PRIVATE-TOKEN", token) - resp, err := http.DefaultClient.Do(req) - if err != nil { - fmt.Println(err) - return - } - defer resp.Body.Close() - fmt.Println("job artifacts deleted:", job.ID) + pool_jobs <- job } + close(pool_jobs) + wg.Wait() + } } From 8dfd706adeff9be0a225907e2006ca94c5f86c33 Mon Sep 17 00:00:00 2001 From: javivf Date: Fri, 29 Nov 2024 23:48:23 +0100 Subject: [PATCH 2/2] removed debug data --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 9559e7e..4ccc20f 100644 --- a/main.go +++ b/main.go @@ -28,7 +28,7 @@ func worker(server string, project_id int, token string, jobs <-chan Job, result return } defer resp.Body.Close() - fmt.Println("job artifacts deleted:", job.ID, resp.StatusCode) + fmt.Println("job artifacts deleted:", job.ID) results <- resp wg.Done()