docker-cleaner 0.4.0 → 0.7.0

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: '015757094769f89ae1df19627fe0157b3e874e67a153a5482e9b34399f4a1ddf'
4
- data.tar.gz: c65353e36a434ee17eb8152f1bba8977a25aef48c974ddf5471b7e6244b0d9ed
3
+ metadata.gz: 9245c57a0622e847a3c14b3bbcf81d98db2c0a538729da29cbfef0ca21f6a4c3
4
+ data.tar.gz: cabe356f1d6fe998b4d0000b80d4cbd90f1d0e7d7e8e04ccd17776a4718320d8
5
5
  SHA512:
6
- metadata.gz: a156b7096e1ff001f8f60047794411cfb45bb3647046ae835c8ee0c08bf1fcc7ea8b379731f2fc91f93c8db7a48004d8273d3589a1ce90769fd30b645b4e1ad6
7
- data.tar.gz: a7727a5bd7a06b9b135d7ded6ca3bd40af7d1d35502c9ce0d19c0136169c098476c78975b6b23d36f52280570405b585567b8d7d9cef644af9d0001f8a909c81
6
+ metadata.gz: 64c3d9a8953e7718b4bebd0050aef32510e955494d1945c0bda06c0a4b8a60065f38b14bae8b8eb4b309343815b7ffceaddeba653a34dd9f23592f535830d146
7
+ data.tar.gz: b7050f77ed5bd4880c4ecc83c2eaaaa20b7dcd8f7098927e8c12146adac5c6d75d06f7a125d99712eea8166fb9877ea011981431c2b711f8de1dfdb50e675a3c
@@ -0,0 +1,17 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "bundler"
4
+ directory: "/"
5
+ allow:
6
+ - dependency-type: "all"
7
+ versioning-strategy: lockfile-only
8
+ schedule:
9
+ interval: "monthly"
10
+ reviewers:
11
+ - "leo-scalingo"
12
+ - package-ecosystem: "github-actions"
13
+ directory: "/"
14
+ schedule:
15
+ interval: "monthly"
16
+ reviewers:
17
+ - "leo-scalingo"
@@ -0,0 +1,17 @@
1
+ name: Dependabot auto-approve
2
+ on: pull_request
3
+
4
+ permissions:
5
+ # Mandatory for both the auto-merge enabling and approval steps
6
+ pull-requests: write
7
+ # Mandatory for the auto-merge enabling step
8
+ contents: write
9
+
10
+ jobs:
11
+ dependabot:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - name: Automatically merge Dependabot PRs
15
+ uses: scalingo/ghaction-dependabot-automerge@v1
16
+ env:
17
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
data/.gitignore CHANGED
@@ -1,2 +1,6 @@
1
1
  /.bundle
2
2
  /binstubs
3
+
4
+ # IDE
5
+ .idea/
6
+ .vscode/
@@ -0,0 +1,7 @@
1
+ dependencies = []
2
+ description = "Small ruby script to remove old containers and old images"
3
+ flags = ["deployed-by-chef"]
4
+ languages = ["ruby"]
5
+ owner = "leo@scalingo.com"
6
+ team = "IST"
7
+ version = "1.1.0"
data/Gemfile CHANGED
@@ -1,4 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'docker-api', '~> 1.18'
3
+ gem 'docker-api'
4
+
5
+ # For compat with ruby 2.7
6
+ gem 'multi_json', '1.15'
7
+
4
8
  gem 'docker-cleaner', path: "."
data/Gemfile.lock CHANGED
@@ -1,24 +1,27 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- docker-cleaner (0.3.0)
5
- docker-api (~> 1.0)
4
+ docker-cleaner (0.7.0)
5
+ docker-api (~> 2.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- docker-api (1.34.2)
11
- excon (>= 0.47.0)
10
+ docker-api (2.4.0)
11
+ excon (>= 0.64.0)
12
12
  multi_json
13
- excon (0.72.0)
14
- multi_json (1.14.1)
13
+ excon (1.3.0)
14
+ logger
15
+ logger (1.7.0)
16
+ multi_json (1.15.0)
15
17
 
16
18
  PLATFORMS
17
19
  ruby
18
20
 
19
21
  DEPENDENCIES
20
- docker-api (~> 1.18)
22
+ docker-api
21
23
  docker-cleaner!
24
+ multi_json (= 1.15)
22
25
 
23
26
  BUNDLED WITH
24
- 1.17.2
27
+ 2.2.17
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # Docker Cleaner v0.6.0
2
+
3
+ Small ruby script to remove old containers and old images.
4
+
5
+ For containers, this removes containers that have been stopped for more than 2 hours.
6
+ For images, this removes unused and untagged images.
7
+
8
+ ## Release a New Version
9
+
10
+ Bump new version number in:
11
+ - README.md
12
+ - lib/docker_cleaner/version.rb
13
+ - Gemfile.lock (docker-cleaner specs entry)
14
+
15
+ Commit, tag and create a new release:
16
+ ```shell
17
+ version="0.6.0"
18
+
19
+ git switch --create release/${version}
20
+ git add Gemfile.lock README.md lib/docker_cleaner/version.rb
21
+ git commit -m "release: Bump v${version}"
22
+ git push --set-upstream origin release/${version}
23
+ gh pr create --reviewer=EtienneM --title "$(git log -1 --pretty=%B)"
24
+ ```
25
+
26
+ Once the pull request merged, you can tag the new release.
27
+
28
+ ```shell
29
+ git tag v${version}
30
+ git push origin master v${version}
31
+ gh release create v${version}
32
+ ```
33
+
34
+ The title of the release should be the version number.
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.description = "Small utility to clean old docker data, containers according to some settings"
13
13
  s.license = "MIT"
14
14
 
15
- s.add_dependency "docker-api", "~> 1.0"
15
+ s.add_dependency "docker-api", "~> 2.0"
16
16
 
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
@@ -1,46 +1,46 @@
1
1
  module DockerCleaner
2
- class Containers
3
- def initialize(logger, opts = {})
4
- @logger = logger
5
- @delay = opts.fetch(:delay, 0)
6
- end
7
-
8
- def remove(container)
9
- @logger.info "Remove #{container.id[0...10]} - #{container.info["Image"]} - #{container.info["Names"][0]}"
10
- container.remove v: true
11
- @logger.info "Remove #{container.id[0...10]} - #{container.info["Image"]} - #{container.info["Names"][0]}... OK"
12
- end
2
+ class Containers
3
+ def initialize(logger, opts = {})
4
+ @logger = logger
5
+ @delay = opts.fetch(:delay, 0)
6
+ end
13
7
 
14
- def run
15
- # Remove stopped container which stopped with code '0'
16
- two_hours_ago = Time.now.to_i - 2 * 3600
17
- Docker::Container.all(all: true).select{ |container|
18
- status = container.info["Status"]
19
- (status == "Created" && container.info["Created"].to_i < two_hours_ago) ||
20
- (status.include?("Exited (") && container.info["Created"].to_i < two_hours_ago)
21
- }.each do |container|
22
- remove(container)
23
- sleep(@delay)
8
+ def remove(container)
9
+ @logger.info "Remove #{container.id[0...10]} - #{container.info["Image"]} - #{container.info["Names"][0]}"
10
+ container.remove v: true
11
+ @logger.info "Remove #{container.id[0...10]} - #{container.info["Image"]} - #{container.info["Names"][0]}... OK"
24
12
  end
25
13
 
26
- containers_per_app = {}
27
- Docker::Container.all(all: true).select{ |container|
28
- container.info["Status"].include?("Exited")
29
- }.each{ |container|
30
- app = container.info["Image"].split(":", 2)[0]
31
- if containers_per_app[app].nil?
32
- containers_per_app[app] = [container]
33
- else
34
- containers_per_app[app] << container
35
- end
36
- }
37
- containers_per_app.each do |app, containers|
38
- containers.shift
39
- containers.each do |container|
14
+ def run
15
+ # Remove stopped container which stopped with code '0'
16
+ two_hours_ago = Time.now.to_i - 2 * 3600
17
+ Docker::Container.all(all: true).select{ |container|
18
+ status = container.info["Status"]
19
+ (status == "Created" && container.info["Created"].to_i < two_hours_ago) ||
20
+ (status.include?("Exited (") && container.info["Created"].to_i < two_hours_ago)
21
+ }.each do |container|
40
22
  remove(container)
41
23
  sleep(@delay)
42
24
  end
25
+
26
+ containers_per_app = {}
27
+ Docker::Container.all(all: true).select{ |container|
28
+ container.info["Status"].include?("Exited")
29
+ }.each{ |container|
30
+ app = container.info["Image"].split(":", 2)[0]
31
+ if containers_per_app[app].nil?
32
+ containers_per_app[app] = [container]
33
+ else
34
+ containers_per_app[app] << container
35
+ end
36
+ }
37
+ containers_per_app.each do |app, containers|
38
+ containers.shift
39
+ containers.each do |container|
40
+ remove(container)
41
+ sleep(@delay)
42
+ end
43
+ end
43
44
  end
44
45
  end
45
46
  end
46
- end
@@ -1,117 +1,117 @@
1
1
  module DockerCleaner
2
- class Images
3
- def initialize registries, prefix, logger, opts = {}
4
- @prefix = prefix || ""
5
- @registries = registries
6
- @logger = logger
7
- @delay = opts.fetch(:delay, 0)
8
- @retention = Time.now.to_i - opts.fetch(:retention, 6) * 3600
9
- end
2
+ class Images
3
+ def initialize(registries, prefix, logger, opts = {})
4
+ @prefix = prefix || ""
5
+ @registries = registries
6
+ @logger = logger
7
+ @delay = opts.fetch(:delay, 0)
8
+ @retention = Time.now.to_i - opts.fetch(:retention, 6) * 3600
9
+ end
10
10
 
11
- def run
12
- clean_old_images
13
- clean_unnamed_images
14
- clean_unused_images
15
- end
11
+ def run
12
+ clean_old_images
13
+ clean_unnamed_images
14
+ clean_unused_images
15
+ end
16
16
 
17
- def clean_unnamed_images
18
- Docker::Image.all.select do |image|
19
- image.info["RepoTags"].nil? || image.info["RepoTags"][0] == "<none>:<none>"
20
- end.each do |image|
21
- @logger.info "Remove unnamed image #{image.id[0...10]}"
22
- begin
23
- image.remove
24
- sleep(@delay)
25
- rescue Docker::Error::NotFoundError
26
- rescue Docker::Error::ConflictError => e
27
- @logger.warn "Conflict when removing #{image.id[0...10]}"
28
- @logger.warn " ! #{e.message}"
17
+ def clean_unnamed_images
18
+ Docker::Image.all.select do |image|
19
+ image.info["RepoTags"].nil? || image.info["RepoTags"][0] == "<none>:<none>"
20
+ end.each do |image|
21
+ @logger.info "Remove unnamed image #{image.id[0...10]}"
22
+ begin
23
+ image.remove
24
+ sleep(@delay)
25
+ rescue Docker::Error::NotFoundError
26
+ rescue Docker::Error::ConflictError => e
27
+ @logger.warn "Conflict when removing #{image.id[0...10]}"
28
+ @logger.warn " ! #{e.message}"
29
+ end
29
30
  end
30
31
  end
31
- end
32
32
 
33
- def clean_old_images
34
- apps = images_with_latest
35
- apps.each do |app, images|
36
- if app =~ /.*-tmax$/
37
- next
38
- end
39
- images.each do |i|
40
- unless i.info["Created"] == apps["#{app}-tmax"]
41
- @logger.info "Remove #{i.info['RepoTags'][0]} => #{i.id[0...10]}"
42
- begin
43
- i.remove
44
- sleep(@delay)
45
- rescue Docker::Error::NotFoundError
46
- rescue Docker::Error::ConflictError => e
47
- @logger.warn "Conflict when removing #{i.info['RepoTags'][0]} - ID: #{i.id[0...10]}"
48
- @logger.warn " ! #{e.message}"
33
+ def clean_old_images
34
+ apps = images_with_latest
35
+ apps.each do |app, images|
36
+ if app =~ /.*-tmax$/
37
+ next
38
+ end
39
+ images.each do |i|
40
+ unless i.info["Created"] == apps["#{app}-tmax"]
41
+ @logger.info "Remove #{i.info['RepoTags'][0]} => #{i.id[0...10]}"
42
+ begin
43
+ i.remove
44
+ sleep(@delay)
45
+ rescue Docker::Error::NotFoundError
46
+ rescue Docker::Error::ConflictError => e
47
+ @logger.warn "Conflict when removing #{i.info['RepoTags'][0]} - ID: #{i.id[0...10]}"
48
+ @logger.warn " ! #{e.message}"
49
+ end
49
50
  end
50
51
  end
51
52
  end
52
53
  end
53
- end
54
54
 
55
- def images_with_latest
56
- images ||= Docker::Image.all
57
- apps = {}
55
+ def images_with_latest
56
+ images ||= Docker::Image.all
57
+ apps = {}
58
58
 
59
- images.each do |i|
60
- # RepoTags can be nil sometimes, in this case we ignore the image
61
- next if i.info["RepoTags"].nil?
62
- if registries_include?(i.info["RepoTags"][0])
63
- name = i.info["RepoTags"][0].split(":")[0]
64
- tmax = "#{name}-tmax"
59
+ images.each do |i|
60
+ # RepoTags can be nil sometimes, in this case we ignore the image
61
+ next if i.info["RepoTags"].nil?
62
+ if registries_include?(i.info["RepoTags"][0])
63
+ name = i.info["RepoTags"][0].split(":")[0]
64
+ tmax = "#{name}-tmax"
65
65
 
66
- if apps[name].nil?
67
- apps[name] = [i]
68
- else
69
- apps[name] << i
70
- end
66
+ if apps[name].nil?
67
+ apps[name] = [i]
68
+ else
69
+ apps[name] << i
70
+ end
71
71
 
72
- if apps[tmax].nil?
73
- apps[tmax] = i.info["Created"]
74
- elsif apps[tmax] < i.info["Created"]
75
- apps[tmax] = i.info["Created"]
72
+ if apps[tmax].nil?
73
+ apps[tmax] = i.info["Created"]
74
+ elsif apps[tmax] < i.info["Created"]
75
+ apps[tmax] = i.info["Created"]
76
+ end
76
77
  end
77
78
  end
79
+ apps
78
80
  end
79
- apps
80
- end
81
81
 
82
- def clean_unused_images
83
- used_images = Docker::Container.all.map{|c| c.info["Image"]}.select{|i| registries_include?(i) }.uniq
84
- # Images older than 2 months
85
- images = Docker::Image.all.select{|i| i.info["RepoTags"] && registries_include?(i.info["RepoTags"][0]) && i.info["Created"] < @retention }
86
- image_repos = images.map{|i| i.info["RepoTags"][0]}
87
- unused_images = image_repos - used_images
82
+ def clean_unused_images
83
+ used_images = Docker::Container.all.map{|c| c.info["Image"]}.select{|i| registries_include?(i) }.uniq
84
+ # Images older than 2 months
85
+ images = Docker::Image.all.select{|i| i.info["RepoTags"] && registries_include?(i.info["RepoTags"][0]) && i.info["Created"] < @retention }
86
+ image_repos = images.map{|i| i.info["RepoTags"][0]}
87
+ unused_images = image_repos - used_images
88
88
 
89
- unused_images.each do |i|
90
- image = images.select{|docker_image| docker_image.info["RepoTags"][0] == i}[0]
91
- @logger.info "Remove unused image #{image.info['RepoTags'][0]} => #{image.id[0...10]}"
92
- begin
93
- image.remove
94
- sleep(@delay)
95
- rescue Docker::Error::NotFoundError
96
- rescue Docker::Error::ConflictError => e
97
- @logger.warn "Conflict when removing #{image.info['RepoTags'][0]} - ID: #{image.id[0...10]}"
98
- @logger.warn " ! #{e.message}"
89
+ unused_images.each do |i|
90
+ image = images.select{|docker_image| docker_image.info["RepoTags"][0] == i}[0]
91
+ @logger.info "Remove unused image #{image.info['RepoTags'][0]} => #{image.id[0...10]}"
92
+ begin
93
+ image.remove
94
+ sleep(@delay)
95
+ rescue Docker::Error::NotFoundError
96
+ rescue Docker::Error::ConflictError => e
97
+ @logger.warn "Conflict when removing #{image.info['RepoTags'][0]} - ID: #{image.id[0...10]}"
98
+ @logger.warn " ! #{e.message}"
99
+ end
99
100
  end
100
101
  end
101
- end
102
102
 
103
- protected
103
+ protected
104
104
 
105
- def registries_include?(image)
106
- if image.nil? || image == ''
107
- return false
108
- end
109
- @registries.each do |registry|
110
- if image =~ /^#{registry}\/#{@prefix}/
111
- return true
105
+ def registries_include?(image)
106
+ if image.nil? || image == ''
107
+ return false
108
+ end
109
+ @registries.each do |registry|
110
+ if image =~ /^#{registry}\/#{@prefix}/
111
+ return true
112
+ end
112
113
  end
114
+ return false
113
115
  end
114
- return false
115
116
  end
116
117
  end
117
- end
@@ -1,3 +1,3 @@
1
1
  module DockerCleaner
2
- VERSION = "0.4.0"
2
+ VERSION = "0.7.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker-cleaner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leo Unbekandt
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-15 00:00:00.000000000 Z
11
+ date: 2025-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docker-api
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '2.0'
27
27
  description: Small utility to clean old docker data, containers according to some
28
28
  settings
29
29
  email:
@@ -33,9 +33,13 @@ executables:
33
33
  extensions: []
34
34
  extra_rdoc_files: []
35
35
  files:
36
+ - ".github/dependabot.yml"
37
+ - ".github/workflows/dependabot.yml"
36
38
  - ".gitignore"
39
+ - ".sclng/metadata.toml"
37
40
  - Gemfile
38
41
  - Gemfile.lock
42
+ - README.md
39
43
  - bin/docker-cleaner
40
44
  - docker-cleaner.gemspec
41
45
  - lib/docker_cleaner.rb
@@ -46,7 +50,7 @@ homepage: https://github.com/Scalingo/docker-cleaner
46
50
  licenses:
47
51
  - MIT
48
52
  metadata: {}
49
- post_install_message:
53
+ post_install_message:
50
54
  rdoc_options: []
51
55
  require_paths:
52
56
  - lib
@@ -61,8 +65,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
65
  - !ruby/object:Gem::Version
62
66
  version: '0'
63
67
  requirements: []
64
- rubygems_version: 3.0.3
65
- signing_key:
68
+ rubygems_version: 3.5.11
69
+ signing_key:
66
70
  specification_version: 4
67
71
  summary: Small utility to clean old containers and images
68
72
  test_files: []