gitlab-janitor 0.0.3 → 1.0.2.92939

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20a74b385cc01ef9b3fcaf380a1186f3f8bb24b278aa496d38cfc859889301bc
4
- data.tar.gz: 2488753090d283ed78422395dded9e8935f060285987b032aae9350b3aecb3b4
3
+ metadata.gz: 754be135680d4f02cc976507e6909cad85fa9610ba686be487517a64ac205b85
4
+ data.tar.gz: a849dcf8db984238cd90084df0601ada8c16c8e3d1fc012da434d2a754c6fe4d
5
5
  SHA512:
6
- metadata.gz: 39f830eb28f777462808abea43295d2e7297eed919028661bbfae9d213eb45f2c2e66ed3daea021fb48a790186bb2c678d287b0881c8580f82e5fc203ee650fa
7
- data.tar.gz: cdbbeaa361c77f3aeb5deb707000c2ca93e0c0d26381f5c6b2be63c24917e95586b834fa17bcddfe15a80607c736be1961048c18ce75a7606fe306927877e82f
6
+ metadata.gz: cbf5f383e72d1aeda4fc8426997633035b79db4111d41c5a6afa2743856ad2d0e5d03b14a0d8802a54c42442b740f46facfa641f40bf7129833ae851e6dfd258
7
+ data.tar.gz: 6fe45e92c6488892fa1838c654c535f394775b844bc7e999eee51248379bec91cdf7c4984eaacb636e309c4a9bdcc1c7bbb6b4779a8ad6afa3679d88607d844a
data/Dockerfile CHANGED
@@ -11,23 +11,48 @@ RUN mkdir -p /usr/local/etc \
11
11
  } >> /usr/local/etc/gemrc \
12
12
  && echo 'gem: --no-document' > ~/.gemrc
13
13
 
14
- # RUN set -ex \
15
- # && apk add --no-cache build-base git curl
14
+ RUN set -ex \
15
+ && apk add --no-cache docker-cli
16
+
16
17
 
17
- ADD Gemfile Gemfile.lock /home/app/
18
+ ADD Gemfile Gemfile.lock gitlab-janitor.gemspec /home/app/
19
+ ADD lib/gitlab_janitor/version.rb /home/app/lib/gitlab_janitor/
18
20
 
19
21
  RUN set -ex \
20
22
  && gem install bundler && gem update bundler \
21
23
  && bundle config set --local system 'true' \
24
+ && bundle config set --local without 'development' \
22
25
  && bundle install --jobs=3 \
26
+ && bundle clean --force \
23
27
  && rm -rf /tmp/* /var/tmp/* /usr/src/ruby /root/.gem /usr/local/bundle/cache
24
28
 
25
29
  ADD . /home/app/
26
30
 
27
31
  RUN set -ex \
28
32
  && bundle install --jobs=3 \
33
+ && bundle clean --force \
29
34
  && rm -rf /tmp/* /var/tmp/* /usr/src/ruby /root/.gem /usr/local/bundle/cache
30
35
 
31
- CMD ["bundle", "exec", "giltab-janitor"]
36
+ ARG \
37
+ CREATED="2022-08-05 15:22:36+03:00" \
38
+ VERSION="unknown" \
39
+ REVISION="unknown" \
40
+ REFNAME="unknown"
41
+
42
+ LABEL \
43
+ org.opencontainers.image.created="${CREATED}" \
44
+ org.opencontainers.image.authors="Samoylenko Yuri <kinnalru@yandex.ru>" \
45
+ org.opencontainers.image.url="https://github.com/RND-SOFT/gitlab-janitor" \
46
+ org.opencontainers.image.documentation="https://github.com/RND-SOFT/gitlab-janitor" \
47
+ org.opencontainers.image.source="https://github.com/RND-SOFT/gitlab-janitor" \
48
+ org.opencontainers.image.version="${VERSION}" \
49
+ org.opencontainers.image.revision="${REVISION}" \
50
+ org.opencontainers.image.vendor="RNDSOFT" \
51
+ org.opencontainers.image.licenses="MIT" \
52
+ org.opencontainers.image.ref.name="${REFNAME}" \
53
+ org.opencontainers.image.title="GitLab Janitor is a tool to automatically manage stalled and dangling resources when using Docker in Gitlab CI/CD" \
54
+ org.opencontainers.image.description="GitLab Janitor is a tool to automatically manage stalled and dangling resources when using Docker in Gitlab CI/CD"
55
+
56
+ CMD ["bundle", "exec", "bin/gitlab-janitor"]
32
57
 
33
58
 
data/Gemfile CHANGED
@@ -2,6 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
-
6
-
7
-
data/Gemfile.lock CHANGED
@@ -1,11 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-janitor (0.0.3)
4
+ gitlab-janitor (1.0.2.92939)
5
5
  activesupport (~> 6.0)
6
6
  docker-api
7
7
  fugit
8
8
  optparse
9
+ redis
10
+ tzinfo-data
9
11
 
10
12
  GEM
11
13
  remote: https://rubygems.org/
@@ -37,6 +39,7 @@ GEM
37
39
  optparse (0.2.0)
38
40
  raabro (1.4.0)
39
41
  rake (13.0.6)
42
+ redis (4.7.1)
40
43
  rspec (3.11.0)
41
44
  rspec-core (~> 3.11.0)
42
45
  rspec-expectations (~> 3.11.0)
@@ -66,6 +69,8 @@ GEM
66
69
  unicode-display_width (>= 1.1.1, < 3)
67
70
  tzinfo (2.0.5)
68
71
  concurrent-ruby (~> 1.0)
72
+ tzinfo-data (1.2022.1)
73
+ tzinfo (>= 1.0.0)
69
74
  unicode-display_width (2.2.0)
70
75
  zeitwerk (2.6.0)
71
76
 
@@ -83,4 +88,4 @@ DEPENDENCIES
83
88
  simplecov-console
84
89
 
85
90
  BUNDLED WITH
86
- 2.3.15
91
+ 2.3.11
data/README.md CHANGED
@@ -1,52 +1,171 @@
1
1
  # gitlab-janitor
2
2
 
3
- GitLab Janitor is a tool to automatically manage stalled containers when using Docker.
4
-
5
- Commain line options and default valuee:
6
-
7
- ```bash
8
- $ ./gitlab-janitor.rb --help
9
-
10
- Usage: gitlab-janitor.rb [options]
11
- --clean-delay=30m Delay between clean operation ENV[CLEAN_DELAY]
12
- --include=*units* <List> Include container for removal. ENV[INCLUDE]
13
- --exclude=*gitlab* <List> Exclude container from removal by name. ENV[EXCLUDE]
14
- --container-deadline=1s Maximum container run duration. ENV[CONTAINER_DEADLINE]
15
- --volume-deadline=2d6h Maximum volume life dudation. ENV[VOLUME_DEADLINE]
16
- --image-deadline=20d Maximum image life duration. ENV[IMAGE_DEADLINE]
17
- --remove Real remove instead of dry run. ENV[REMOVE]
18
- --docker=unix:///var/run/docker.sock
19
- Docker api endpoint. ENV[DOCKER_HOST]
3
+ <div align="center">
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/gitlab-janitor.svg)](https://rubygems.org/gems/gitlab-janitor)
6
+ [![Gem](https://img.shields.io/gem/dt/gitlab-janitor.svg)](https://rubygems.org/gems/gitlab-janitor/versions)
7
+ [![YARD](https://badgen.net/badge/YARD/doc/blue)](http://www.rubydoc.info/gems/gitlab-janitor)
8
+
9
+ [![Docker Pulls](https://badgen.net/docker/pulls/rnds/gitlab-janitor?icon=docker&label=pulls)](https://hub.docker.com/r/rnds/gitlab-janitor/)
10
+ [![Docker Stars](https://badgen.net/docker/stars/rnds/gitlab-janitor?icon=docker&label=stars)](https://hub.docker.com/r/rnds/gitlab-janitor/)
11
+
12
+ </div>
13
+
14
+ Gitlab Janitor это утилита для автоматической очистки зависших и брошенных ресурсов при использовании Docker в `Gitlab` CI/CD. Проект вдохновлён утилитой [GitLab Runner Docker Cleanup](https://gitlab.com/gitlab-org/gitlab-runner-docker-cleanup).
15
+
16
+ ---
17
+
18
+ GitLab Janitor is a tool to automatically manage stalled and dangling resources when using Docker in `Gitlab` CI/CD. Project inpired by [GitLab Runner Docker Cleanup](https://gitlab.com/gitlab-org/gitlab-runner-docker-cleanup).
19
+
20
+ Возможности / Features
21
+
22
+ - Удаление повисших контейнеров / Remove dangling containers
23
+ - Удаление неиспользуемых хранилищ / Remove unused anonymous volumes
24
+ - Удаление неиспользуемых образов / Remove unused images
25
+ - Отслеживание вререни использвоания образов / Track image usage timestamp
26
+ - Очистка кешей Docker (build cache) / Cleanup docker build cache
27
+ - Готовый [docker-образ](https://hub.docker.com/r/rnds/gitlab-janitor) / Production ready [docker image](https://hub.docker.com/r/rnds/gitlab-janitor)
28
+
29
+ ## Установка / Installation
30
+
31
+ ```sh
32
+ $ gem install gitlab-janitor
33
+ ```
34
+
35
+ При установке `Gitlab Janitor` через bundler добавте следующую строку в `Gemfile`, установив `require` параметр в `false`:
36
+
37
+ ---
38
+
39
+ If you'd rather install `Gitlab Janitor` using bundler, add a line for it in your `Gemfile` (but set the `require` option to `false`, as it is a standalone tool):
40
+
41
+ ```sh
42
+ gem 'rubocop', require: false
43
+ ```
44
+
45
+ Для установки с помощью docker контейнера [скачайте образ](https://hub.docker.com/r/rnds/gitlab-janitor):
46
+
47
+ ---
48
+
49
+ To install as docker container just [pull the image](https://hub.docker.com/r/rnds/gitlab-janitor):
50
+
51
+
52
+ ```sh
53
+ docker pull rnds/gitlab-janitor:latest
54
+ ```
55
+
56
+ ## Быстрый запуск / Quickstart
57
+
58
+ Запустите `gitlab-janitor` и смотрите за процессом или запустите docker:
59
+
60
+ ---
61
+
62
+ Just type `gitlab-janitor` and watch the magic happen or run in docker:
63
+
64
+ ```sh
65
+ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock rnds/gitlab-janitor:latest
20
66
  ```
21
67
 
68
+ ## Документация / Documentation
69
+
70
+ Параметры командной строки, переменные окружения и занчения по-умолчанию:
71
+
72
+ Commain line options, environment variables and default values:
73
+
74
+ ```sh
75
+ $ gitlab-janitor --help
76
+
77
+ Usage: gitlab-janitor [options]
78
+ --clean-delay=30m ENV[CLEAN_DELAY] Delay between clean operation.
79
+ --include=*units* ENV[INCLUDE] <List> Include container for removal.
80
+ --exclude=*gitlab* ENV[EXCLUDE] <List> Exclude container from removal by name.
81
+ --container-deadline=1h10m ENV[CONTAINER_DEADLINE] Maximum container run duration.
82
+ --volume-include=runner*cache*
83
+ ENV[VOLUME_INCLUDE] <List> Include volumes for removal.
84
+ --volume-deadline=2d6h ENV[VOLUME_DEADLINE] Maximum volume life duration.
85
+ --image-deadline=20d ENV[IMAGE_DEADLINE] Maximum image life duration.
86
+ --image-store=./images.txt ENV[IMAGE_STORE] File to store images timestamps.
87
+ --cache-size=10G ENV[CACHE_SIZE] Size of docker cache to keep.
88
+ --remove ENV[REMOVE] Real remove instead of dry run.
89
+ --docker=unix:///tmp/mysock ENV[DOCKER_HOST] Docker api endpoint.
90
+ --debug ENV[LOG_LEVEL] Verbose logs. ENV values: debug, info, warn, error
91
+ ```
22
92
 
23
- ## Удаление зависших контейнеров
93
+ ### Удаление зависших контейнеров / Removing stalled containers
24
94
 
25
95
  Порядок определения контейнреов для удаления:
26
96
 
27
- - `include=*units*` - в список на удаление включаются контейнеры удовлетворябющие шаблону;
28
- - `exclude=*gitlab*` - из спсика исключаются контейнеры по шаблону;
97
+ - `include=[*units*]` - в список на удаление включаются контейнеры удовлетворябющие шаблону;
98
+ - `exclude=[*gitlab*]` - из спсика исключаются контейнеры по шаблону;
29
99
  - `container-deadline=[1h10m]` - результирующий список проверяется на длительность запуска контенйра;
30
100
 
31
- ## Удаление ненужных volumes
101
+ ---
32
102
 
33
- Порядок определения вольюмов для удалени:
103
+ Containers deleted when:
34
104
 
35
- - на удаление попадают только вольюмы, не являющиеся именованными;
105
+ - `include=[*units*]` - select containers by matching name by pattern;
106
+ - `exclude=[*gitlab*]` - **reject** containers by matching name by pattern;
107
+ - `container-deadline=[1h10m]` - when container lifetime exceeding the deadline it is removed;
108
+
109
+ ### Удаление ненужных volumes / Removing unused volumes
110
+
111
+ Порядок определения вольюмов для удаления:
112
+
113
+ - на удаление попадают вольюмы, не являющиеся именованными;
114
+ - `volume-include=[runner*cache*]`- дополнительные волюмы для удаления;
36
115
  - `volume-deadline=[2d6h]` - результирующий список проверяется на длительность существования вольюма;
37
116
 
38
- ## Удаление образов
117
+ ---
118
+
119
+ Volumes deleted when:
120
+
121
+ - select all anonymous volumes;
122
+ - `volume-include=[runner*cache*]`- add volumes by matching name by pattern;
123
+ - `volume-deadline=[2d6h]` - when volume lifetime exceeding the deadline it is removed;
39
124
 
40
- Docker не сохраняет временную метку образа при скачивании (pull), там образом используя средства Docker API невозможно понять как давно образ был скачан и когда его поря удалять. Для решения этой задачи сервис сохраняет информацию о скачанных образах, отслеживая там образом интервалы устаревания.
125
+ ### Removing images / Удаление образов
41
126
 
42
- Порядок определения образов для удалени:
127
+ Docker не сохраняет временную метку образа при скачивании (pull), таким образом используя средства `Docker API` невозможно понять как давно образ был скачан и когда его пора удалять. Для решения этой задачи сервис сохраняет информацию о скачанных образах, отслеживая таким образом интервалы устаревания.
43
128
 
44
- - на удаление попадают только образы, не имеющие тэг `latest`;
129
+ Порядок определения образов для удаления:
130
+
131
+ - При первой встрече нового образа врменная метка сохраняется в локальное хранилище (файл);
132
+ - При достижении лимита хранения образ удаляется;
133
+ - При обнаружении запущенного контейнера временная метка для соответствующего образа обнуляется;
45
134
  - `image-deadline=[20d]` - результирующий список проверяется на длительность существования образа;
46
135
 
47
136
 
48
- ## Пример запуска
137
+ ---
138
+
139
+ Docker don't track timestamp when puling image, so there is impossible track lifetime through `Docker API`. To solve this problem, the service saves information about downloaded images, thus keeping track of lifetime deadline.
140
+
141
+ Images deleted when:
142
+
143
+ - When a new image is first encountered, the timestamp is stored in local storage (file);
144
+ - When a running container is found, the timestamp for the corresponding image is reset to zero;
145
+ - `image-deadline=[20d]` - when lifetime exceeding the deadline image it is removed (`docker rmi <image>`);
146
+
147
+ ## Приеры / Examples
148
+
149
+ Конфиг для продуктового режима / Production ready config:
150
+
151
+ ```sh
152
+ REMOVE=true INCLUDE="*integr*, *units*" EXCLUDE="*gitlab*" CONTAINER_DEADLINE="1h10m" VOLUME_DEADLINE="3d" IMAGE_DEADLINE="20d" gitlab-janitor
153
+ ```
154
+
155
+ ## Запуск в докере / Running in docker
156
+
157
+ ```sh
158
+ docker run --rm \
159
+ -v /var/run/docker.sock:/var/run/docker.sock \
160
+ -e REMOVE=true \
161
+ -e INCLUDE="*integr*, *units*" \
162
+ -e EXCLUDE="*gitlab*" \
163
+ -e CONTAINER_DEADLINE="1h10m" \
164
+ -e VOLUME_DEADLINE="3d" \
165
+ -e IMAGE_DEADLINE="20d" \
166
+ rnds/gitlab-janitor:latest
167
+ ```
168
+
169
+ ## Лицензия / License
49
170
 
50
- ```bash
51
- REMOVE=true INCLUDE="*integr*, *units*" EXCLUDE="*gitlab*" CONTAINER_DEADLINE="1h10m" VOLUME_DEADLINE="3d" IMAGE_DEADLINE="20d" ./main.rb
52
- ```
171
+ [MIT](./LICENSE)
data/bin/gitlab-janitor CHANGED
@@ -1,19 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- #cwd = __dir__
4
- #$root = "#{cwd}/"
5
- #$: << $root
3
+ # cwd = __dir__
4
+ # $root = "#{cwd}/"
5
+ # $: << $root
6
6
 
7
- #lib = File.expand_path('lib', __dir__)
8
- #$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
+ # lib = File.expand_path('lib', __dir__)
8
+ # $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
9
9
 
10
10
 
11
- #require 'rubygems'
12
- #require 'bundler'
13
- #require 'bundler/setup'
14
- #Bundler.require(:default)
11
+ # require 'rubygems'
12
+ # require 'bundler'
13
+ # require 'bundler/setup'
14
+ # Bundler.require(:default)
15
15
 
16
- require 'active_support/all'
17
16
  require 'docker-api'
18
17
  require 'fugit'
19
18
  require 'optparse'
@@ -25,80 +24,129 @@ UTIL = File.basename(__FILE__)
25
24
  GitlabJanitor::Util.setup
26
25
 
27
26
  @opts = {
28
- includes: [ENV.fetch('INCLUDE', '*units*')],
29
- excludes: [ENV.fetch('EXCLUDE', '*gitlab*')],
30
- clean_delay: ENV.fetch('CLEAN_DELAY', '30m'),
27
+ includes: [ENV.fetch('INCLUDE', '*units*').split(/[,;]/)].flatten.compact,
28
+ excludes: [ENV.fetch('EXCLUDE', '*gitlab*').split(/[,;]/)].flatten.compact,
29
+ clean_delay: ENV.fetch('CLEAN_DELAY', '10m'),
31
30
  container_deadline: ENV.fetch('CONTAINER_DEADLINE', '1h10m'),
32
- volume_deadline: ENV.fetch('VOLUME_DEADLINE', '2d6h'),
33
- image_deadline: ENV.fetch('IMAGE_DEADLINE', '20d'),
31
+ volume_includes: [ENV.fetch('IMAGE_INCLUDE', 'runner*cache*').split(/[,;]/)].flatten.compact,
32
+ volume_deadline: ENV.fetch('VOLUME_DEADLINE', '3d'),
33
+ image_deadline: ENV.fetch('IMAGE_DEADLINE', '14d'),
34
+ image_store: ENV.fetch('IMAGE_STORE', './images.txt'),
35
+ cache_size: ENV.fetch('CACHE_SIZE', '10G'),
34
36
  remove: ENV.fetch('REMOVE', 'false').to_bool,
35
- docker_host: ENV.fetch('DOCKER_HOST', 'unix:///var/run/docker.sock')
37
+ log_level: ENV.fetch('LOG_LEVEL', ::Logger::INFO),
38
+ docker_host: ENV.fetch('DOCKER_HOST', 'unix:///var/run/docker.sock'),
39
+ redis_url: ENV.fetch('REDIS_URL', 'redis://127.0.0.1:6379/0')
36
40
  }
37
41
 
38
42
  parser = OptionParser.new do |o|
39
43
  o.banner = "Usage: #{UTIL} [options] "
40
44
 
41
- o.on("--clean-delay=#{@opts[:clean_delay]}", 'Delay between clean operation ENV[CLEAN_DELAY]') do |pattern|
45
+ o.on("--clean-delay=#{@opts[:clean_delay]}",
46
+ 'ENV[CLEAN_DELAY]'.ljust(25) + 'Delay between clean operation.') do |pattern|
42
47
  @opts[:clean_delay] = pattern.strip
43
48
  end
44
49
 
45
- o.on("--include=#{@opts[:includes].join(',')}", '<List> Include container for removal. ENV[INCLUDE]') do |pattern|
50
+ o.on("--include=#{@opts[:includes].join(',')}",
51
+ 'ENV[INCLUDE]'.ljust(25) + '<List> Include container for removal.') do |pattern|
46
52
  @opts[:includes] += pattern.split(/[,;]/)
47
53
  end
48
54
 
49
- o.on("--exclude=#{@opts[:excludes].join(',')}", '<List> Exclude container from removal by name. ENV[EXCLUDE]') do |pattern|
55
+ o.on("--exclude=#{@opts[:excludes].join(',')}",
56
+ 'ENV[EXCLUDE]'.ljust(25) + '<List> Exclude container from removal by name.') do |pattern|
50
57
  @opts[:excludes] += pattern.split(/[,;]/)
51
58
  end
52
59
 
53
- o.on("--container-deadline=#{@opts[:container_deadline]}", 'Maximum container run duration. ENV[CONTAINER_DEADLINE]') do |pattern|
60
+ o.on("--container-deadline=#{@opts[:container_deadline]}",
61
+ 'ENV[CONTAINER_DEADLINE]'.ljust(25) + 'Maximum container run duration.') do |pattern|
54
62
  @opts[:container_deadline] = pattern.strip
55
63
  end
56
64
 
57
- o.on("--volume-deadline=#{@opts[:volume_deadline]}", 'Maximum volume life dudation. ENV[VOLUME_DEADLINE]') do |pattern|
65
+ o.on("--volume-include=#{@opts[:volume_includes].join(',')}",
66
+ 'ENV[VOLUME_INCLUDE]'.ljust(25) + '<List> Include volumes for removal.') do |pattern|
67
+ @opts[:volume_includes] += pattern.split(/[,;]/)
68
+ end
69
+
70
+ o.on("--volume-deadline=#{@opts[:volume_deadline]}",
71
+ 'ENV[VOLUME_DEADLINE]'.ljust(25) + 'Maximum volume life duration.') do |pattern|
58
72
  @opts[:volume_deadline] = pattern.strip
59
73
  end
60
74
 
61
- o.on("--image-deadline=#{@opts[:image_deadline]}", 'Maximum image life duration. ENV[IMAGE_DEADLINE]') do |pattern|
75
+ o.on("--image-deadline=#{@opts[:image_deadline]}",
76
+ 'ENV[IMAGE_DEADLINE]'.ljust(25) + 'Maximum image life duration.') do |pattern|
62
77
  @opts[:image_deadline] = pattern.strip
63
78
  end
64
79
 
65
- o.on("--remove", 'Real remove instead of dry run. ENV[REMOVE]') do |value|
80
+ o.on("--image-store=#{@opts[:image_store]}",
81
+ 'ENV[IMAGE_STORE]'.ljust(25) + 'File to store images timestamps.') do |value|
82
+ @opts[:image_store] = value.strip
83
+ end
84
+
85
+ o.on("--cache-size=#{@opts[:cache_size]}",
86
+ 'ENV[CACHE_SIZE]'.ljust(25) + 'Size of docker cache to keep.') do |value|
87
+ @opts[:cache_size] = value.strip
88
+ end
89
+
90
+ o.on('--remove', 'ENV[REMOVE]'.ljust(25) + 'Real remove instead of dry run.') do |value|
66
91
  @opts[:remove] = value.strip.to_bool
67
92
  end
68
93
 
69
- o.on("--docker=#{@opts[:docker_host]}", 'Docker api endpoint. ENV[DOCKER_HOST]') do |url|
70
- @opts[:docker_host] = value.strip
94
+ o.on("--docker=#{@opts[:docker_host]}", 'ENV[DOCKER_HOST]'.ljust(25) + 'Docker api endpoint.') do |url|
95
+ @opts[:docker_host] = url.strip
96
+ end
97
+
98
+ o.on("--redis=#{@opts[:redis_url]}", 'ENV[REDIS_URL]'.ljust(25) + 'Redis endpoint.') do |url|
99
+ @opts[:redis_url] = url.strip
71
100
  end
72
101
 
102
+ o.on('--debug', 'ENV[LOG_LEVEL]'.ljust(25) + 'Verbose logs. ENV values: debug, info, warn, error') do
103
+ @opts[:log_level] = ::Logger::DEBUG
104
+ end
73
105
  end
74
106
  parser.parse!
75
107
 
76
108
  Docker.url = @opts[:docker_host]
77
109
 
78
- GitlabJanitor::Util::logger.debug do
110
+ GitlabJanitor::Util.logger.level = @opts[:log_level]
111
+
112
+ GitlabJanitor::Util.logger.debug do
79
113
  "Config: #{JSON.pretty_generate(@opts)}"
80
114
  end
81
115
 
82
116
  containers = GitlabJanitor::ContainerCleaner.new(
83
- delay: Fugit::Duration.parse(@opts[:clean_delay]).to_sec,
84
117
  includes: @opts[:includes],
85
118
  excludes: @opts[:excludes],
119
+ delay: Fugit::Duration.parse(@opts[:clean_delay]).to_sec,
86
120
  deadline: Fugit::Duration.parse(@opts[:container_deadline]).to_sec
87
121
  )
88
122
 
89
123
  volumes = GitlabJanitor::VolumeCleaner.new(
90
- delay: Fugit::Duration.parse(@opts[:clean_delay]).to_sec,
124
+ includes: @opts[:volume_includes],
125
+ delay: Fugit::Duration.parse(@opts[:clean_delay]).to_sec,
91
126
  deadline: Fugit::Duration.parse(@opts[:volume_deadline]).to_sec
92
127
  )
93
128
 
129
+ images = GitlabJanitor::ImageCleaner.new(
130
+ image_store: File.expand_path(@opts[:image_store]),
131
+ redis: @opts[:redis_url],
132
+ delay: Fugit::Duration.parse(@opts[:clean_delay]).to_sec,
133
+ deadline: Fugit::Duration.parse(@opts[:image_deadline]).to_sec
134
+ )
135
+
136
+ cache = GitlabJanitor::CacheCleaner.new(
137
+ keep_size: @opts[:cache_size],
138
+ delay: Fugit::Duration.parse(@opts[:clean_delay]).to_sec,
139
+ deadline: Fugit::Duration.parse(@opts[:image_deadline]).to_sec
140
+ )
141
+
142
+ until GitlabJanitor::Util.exiting?
143
+ File.write('/tmp/service.pid', Process.pid)
94
144
 
95
- while !$exiting do
96
145
  containers.clean(remove: @opts[:remove])
97
146
  volumes.clean(remove: @opts[:remove])
147
+ images.clean(remove: @opts[:remove])
148
+ cache.clean(remove: @opts[:remove])
98
149
 
99
150
  sleep 3
100
151
  end
101
152
 
102
-
103
-
104
-
data/docker-compose.yml CHANGED
@@ -9,6 +9,10 @@ services:
9
9
  context: .
10
10
  args:
11
11
  RUBY_VERSION: 3.1
12
+ CREATED: ${OC_IMAGE_CREATED-2022-08-05 15:22:36+03:00}
13
+ VERSION: ${OC_IMAGE_VERSION-unknown}
14
+ REVISION: ${OC_IMAGE_REVISION-unknown}
15
+ REFNAME: ${OC_IMAGE_REFNAME-unknown}
12
16
  image: ${SERVICE_IMAGE-rnds/gitlab-janitor}:${SERVICE_TAG-latest}
13
17
  working_dir: /home/app
14
18
  tmpfs: /tmp
@@ -2,32 +2,35 @@ lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  # Maintain your gem's version:
5
- require 'gitlab-janitor/version'
5
+ require 'gitlab_janitor/version'
6
6
 
7
7
  Gem::Specification.new 'gitlab-janitor' do |spec|
8
- spec.version = ENV['BUILDVERSION'].to_i > 0 ? "#{Lusnoc::VERSION}.#{ENV['BUILDVERSION'].to_i}" : GitlabJanitor::VERSION
8
+ spec.version = ENV['BUILDVERSION'].to_i > 0 ? "#{GitlabJanitor::VERSION}.#{ENV['BUILDVERSION'].to_i}" : GitlabJanitor::VERSION
9
9
  spec.authors = ['Samoilenko Yuri']
10
10
  spec.email = ['kinnalru@gmail.com']
11
11
  spec.description = spec.summary = 'GitLab Janitor is a tool to automatically manage stalled containers when using Docker.'
12
12
  spec.homepage = 'https://github.com/RnD-Soft/gitlab-janitor'
13
13
  spec.license = 'MIT'
14
14
 
15
- spec.files = Dir['bin/**/*', 'lib/**/*', 'Gemfile*', 'LICENSE', 'README.md', 'Dockerfile*', 'docker-compose.yml', '*.gemspec']
15
+ spec.files = Dir['bin/**/*', 'lib/**/*', 'Gemfile*', 'LICENSE', 'README.md',
16
+ 'Dockerfile*', 'docker-compose.yml', '*.gemspec']
16
17
  spec.bindir = 'bin'
17
18
  spec.executables = spec.files.grep(%r{^bin/gitlab-janitor}) {|f| File.basename(f) }
18
19
  spec.require_paths = ['lib']
19
20
 
21
+ spec.add_development_dependency 'awesome_print'
20
22
  spec.add_development_dependency 'bundler', '~> 2.0', '>= 2.0.1'
21
23
  spec.add_development_dependency 'rake'
22
24
  spec.add_development_dependency 'rspec'
23
25
  spec.add_development_dependency 'rspec_junit_formatter'
24
26
  spec.add_development_dependency 'simplecov'
25
27
  spec.add_development_dependency 'simplecov-console'
26
- spec.add_development_dependency 'awesome_print'
27
28
 
28
29
  spec.add_runtime_dependency 'activesupport', '~> 6.0'
29
30
  spec.add_runtime_dependency 'docker-api'
30
31
  spec.add_runtime_dependency 'fugit'
32
+ spec.add_runtime_dependency 'redis'
31
33
  spec.add_runtime_dependency 'optparse'
34
+ spec.add_runtime_dependency 'tzinfo-data'
32
35
  end
33
36
 
@@ -1,5 +1,2 @@
1
- require_relative 'gitlab-janitor/version'
2
- require_relative 'gitlab-janitor/utils'
3
- require_relative 'gitlab-janitor/base-cleaner'
4
- require_relative 'gitlab-janitor/container-cleaner'
5
- require_relative 'gitlab-janitor/volume-cleaner'
1
+ require_relative './gitlab_janitor'
2
+
@@ -2,9 +2,11 @@ module GitlabJanitor
2
2
  class BaseCleaner
3
3
 
4
4
  class Model
5
+
5
6
  attr_reader :model
6
- def initialize(m)
7
- @model = m
7
+
8
+ def initialize(model)
9
+ @model = model
8
10
  end
9
11
 
10
12
  def method_missing(method, *args, &block)
@@ -20,11 +22,12 @@ module GitlabJanitor
20
22
  def respond_to_missing?(method_name, include_private = false)
21
23
  model.send(:respond_to_missing?, method_name, include_private) || super
22
24
  end
25
+
23
26
  end
24
27
 
25
28
  attr_reader :delay, :deadline, :logger
26
29
 
27
- def initialize delay: 10, deadline: 1.second, logger: GitlabJanitor::Util::logger, **args
30
+ def initialize(delay: 10, deadline: 1.second, logger: GitlabJanitor::Util.logger, **_args)
28
31
  @delay = delay
29
32
  @deadline = deadline
30
33
  @logger = logger.tagged(self.class.to_s)
@@ -36,7 +39,11 @@ module GitlabJanitor
36
39
  do_clean(remove: remove)
37
40
 
38
41
  @cleaned_at = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
39
- return true
42
+ true
43
+ end
44
+
45
+ def exiting?
46
+ GitlabJanitor::Util.exiting?
40
47
  end
41
48
 
42
49
  def log_exception(text)
@@ -47,4 +54,5 @@ module GitlabJanitor
47
54
  end
48
55
 
49
56
  end
50
- end
57
+ end
58
+
@@ -0,0 +1,24 @@
1
+ require 'open3'
2
+
3
+ module GitlabJanitor
4
+ class CacheCleaner < BaseCleaner
5
+
6
+ def initialize(**kwargs)
7
+ super(**kwargs)
8
+ end
9
+
10
+ def do_clean(keep_size: '10G', remove: false)
11
+ logger.info 'Removing cache...'
12
+ if remove
13
+ out, _status = Open3.capture2e("docker builder prune --keep-storage #{keep_size} -f")
14
+ logger.info(out)
15
+ else
16
+ logger.info 'Skip removal due to dry run'
17
+ end
18
+ out, _status = Open3.capture2e('docker system df')
19
+ logger.info(out)
20
+ end
21
+
22
+ end
23
+ end
24
+