Class: GitlabJanitor::ContainerCleaner

Inherits:
BaseCleaner show all
Defined in:
lib/gitlab_janitor/container_cleaner.rb

Defined Under Namespace

Classes: Model

Instance Attribute Summary collapse

Attributes inherited from BaseCleaner

#deadline, #delay, #logger

Instance Method Summary collapse

Methods inherited from BaseCleaner

#clean, #exiting?, #log_exception

Constructor Details

#initialize(includes: [''], excludes: [''], **kwargs) ⇒ ContainerCleaner

Returns a new instance of ContainerCleaner.



32
33
34
35
36
37
# File 'lib/gitlab_janitor/container_cleaner.rb', line 32

def initialize(includes: [''], excludes: [''], **kwargs)
  super(**kwargs)
  @includes = includes
  @excludes = excludes
  @deadline = deadline
end

Instance Attribute Details

#excludesObject (readonly)

Returns the value of attribute excludes.



30
31
32
# File 'lib/gitlab_janitor/container_cleaner.rb', line 30

def excludes
  @excludes
end

#includesObject (readonly)

Returns the value of attribute includes.



30
31
32
# File 'lib/gitlab_janitor/container_cleaner.rb', line 30

def includes
  @includes
end

Instance Method Details

#do_clean(remove: false) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/gitlab_janitor/container_cleaner.rb', line 39

def do_clean(remove: false)
  to_remove, keep = prepare(Docker::Container.all(all: true).map{|m| Model.new(m) })

  return if to_remove.empty?

  keep.each {|m| logger.debug("  KEEP #{m.name}") }

  if remove
    logger.info 'Removing containers...'
    to_remove.each do |model|
      return false if exiting?

      logger.tagged(model.name) do
        logger.debug '   Removing...'
        log_exception('Stop') { model.stop }
        log_exception('Wait') { model.wait(15) }
        log_exception('Remove') { model.remove }
        logger.debug '   Removing COMPLETED'
      end
    end
  else
    logger.info 'Skip removal due to dry run'
  end
end

#format_item(model) ⇒ Object



92
93
94
# File 'lib/gitlab_janitor/container_cleaner.rb', line 92

def format_item(model)
  "#{Time.at(model.created_at)} Age:#{model.age_text.ljust(10)} #{model.name.first(60).ljust(60)}"
end

#prepare(containers) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/gitlab_janitor/container_cleaner.rb', line 64

def prepare(containers)
  @logger.debug("Selecting containers by includes #{@includes}...")
  to_remove = select_by_name(containers)
  if to_remove.empty?
    @logger.info('Noting to remove.')
    return [], containers
  end
  @logger.info("Selected containers: \n#{to_remove.map{|c| "  + #{format_item(c)}" }.join("\n")}")

  @logger.debug("Filtering containers by excludes #{@excludes}...")
  to_remove = reject_by_name(to_remove)
  if to_remove.empty?
    @logger.info('Noting to remove.')
    return [], containers
  end
  @logger.info("Filtered containers: \n#{to_remove.map{|c| "  + #{format_item(c)}" }.join("\n")}")

  @logger.info("Filtering containers by deadline: older than #{Fugit::Duration.parse(@deadline).deflate.to_plain_s}...")
  to_remove = select_by_deadline(to_remove)
  if to_remove.empty?
    @logger.info('Noting to remove.')
    return [], containers
  end
  @logger.info("Filtered containers: \n#{to_remove.map{|c| "  + #{format_item(c)}" }.join("\n")}")

  [to_remove, containers - to_remove]
end

#reject_by_name(containers) ⇒ Object



104
105
106
107
108
109
110
# File 'lib/gitlab_janitor/container_cleaner.rb', line 104

def reject_by_name(containers)
  containers.reject do |model|
    @excludes.any? do |pattern|
      File.fnmatch(pattern, model.name)
    end
  end
end

#select_by_deadline(containers) ⇒ Object



112
113
114
115
116
# File 'lib/gitlab_janitor/container_cleaner.rb', line 112

def select_by_deadline(containers)
  containers.select do |model|
    model.age > deadline
  end
end

#select_by_name(containers) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/gitlab_janitor/container_cleaner.rb', line 96

def select_by_name(containers)
  containers.select do |model|
    @includes.any? do |pattern|
      File.fnmatch(pattern, model.name)
    end
  end
end