gitlab-janitor 0.0.3 → 1.0.2.92939

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+