Class: OsCtld::AutoStop::Plan

Inherits:
Object
  • Object
show all
Includes:
OsCtl::Lib::Utils::Log
Defined in:
lib/osctld/auto_stop/plan.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pool) ⇒ Plan

Returns a new instance of Plan.



10
11
12
13
14
15
# File 'lib/osctld/auto_stop/plan.rb', line 10

def initialize(pool)
  @pool = pool
  @plan = ContinuousExecutor.new(pool.parallel_stop)
  @stop = false
  @nproc = Etc.nprocessors
end

Instance Attribute Details

#planObject (readonly, protected)

Returns the value of attribute plan.



162
163
164
# File 'lib/osctld/auto_stop/plan.rb', line 162

def plan
  @plan
end

#poolObject (readonly)

Returns the value of attribute pool.



8
9
10
# File 'lib/osctld/auto_stop/plan.rb', line 8

def pool
  @pool
end

Instance Method Details

#clearObject



135
136
137
# File 'lib/osctld/auto_stop/plan.rb', line 135

def clear
  plan.clear
end

#do_stop_ct(ct, message: nil) ⇒ Object (protected)



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/osctld/auto_stop/plan.rb', line 164

def do_stop_ct(ct, message: nil)
  if ct.ephemeral?
    Commands::Container::Delete.run(
      pool: pool.name,
      id: ct.id,
      force: true,
      progress: false,
      manipulation_lock: 'ignore',
      message:
    )
  else
    Commands::Container::Stop.run(
      pool: pool.name,
      id: ct.id,
      progress: false,
      manipulation_lock: 'ignore',
      message:
    )

    pool.autostart_plan.clear_ct(ct)
  end
end

#log_typeObject



156
157
158
# File 'lib/osctld/auto_stop/plan.rb', line 156

def log_type
  "#{pool.name}:auto-stop"
end

#queueObject



152
153
154
# File 'lib/osctld/auto_stop/plan.rb', line 152

def queue
  plan.queue
end

#resize(new_size) ⇒ Object



139
140
141
# File 'lib/osctld/auto_stop/plan.rb', line 139

def resize(new_size)
  plan.resize(new_size)
end

#start(message: nil, client_handler: nil, progress_tracker: nil) ⇒ Object

Stop all containers on pool

It is assumed that manipulation lock is held on all containers on the pool.

Parameters:



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/osctld/auto_stop/plan.rb', line 24

def start(message: nil, client_handler: nil, progress_tracker: nil)
  @stop = false
  progress_tracker ||= ProgressTracker.new

  log(
    :info,
    "Auto-stopping containers, #{pool.parallel_stop} containers at a time"
  )

  # Sort containers by reversed autostart priority -- containers with
  # the lowest priority are stopped first
  cts = DB::Containers.get.select { |ct| ct.pool == pool }

  log(:info, "#{cts.size} containers to stop")

  if CpuScheduler.use_sequential_start_stop?
    log(:info, 'Using sequential auto-stop')

    cts.sort! do |a, b|
      a_conf = a.run_conf
      b_conf = b.run_conf

      # rubocop:disable Lint/DuplicateBranch
      #
      # Stop running containers first
      if a_conf && !b_conf
        -1
      elsif !a_conf && b_conf
        1
      elsif !a_conf && !b_conf
        0

      # Stop containers with a CPU package first
      elsif a_conf.cpu_package && !b_conf.cpu_package
        -1
      elsif !a_conf.cpu_package && b_conf.cpu_package
        1
      elsif !a_conf.cpu_package && !b_conf.cpu_package
        0

      # Same CPU package, sort by autostart priority
      elsif a_conf.cpu_package == b_conf.cpu_package
        if a.autostart && b.autostart
          b.autostart <=> a.autostart
        elsif a.autostart
          1
        elsif b.autostart
          -1
        else
          0
        end

      # Sort by CPU package, higher package first
      else
        b_conf.cpu_package <=> a_conf.cpu_package
      end

      # rubocop:enable Lint/DuplicateBranch
    end
  else
    log(:info, 'Using priority auto-stop')

    cts.sort! do |a, b|
      if a.autostart && b.autostart
        b.autostart <=> a.autostart
      elsif a.autostart
        1
      elsif b.autostart
        -1
      else
        0
      end
    end
  end

  # Progress counters
  progress_tracker.add_total(cts.count)
  debug = Daemon.get.config.debug?

  # Stop the containers
  cmds = cts.each_with_index.map do |ct, i|
    if debug
      run_conf = ct.run_conf

      log(
        :debug,
        progress_tracker.progress_line(
          "#{ct.id} priority=#{ct.autostart ? ct.autostart.priority : '-'} cpu-package=#{run_conf ? run_conf.cpu_package : '-'}",
          increment_by: nil
        )
      )
    end

    ContinuousExecutor::Command.new(id: ct.id, priority: i) do |_cmd|
      if client_handler
        progress = progress_tracker.progress_line(
          (ct.ephemeral? ? 'Deleting ephemeral container' : 'Stopping container') +
          " #{ct.ident}"
        )

        client_handler.send_update(progress)
      end

      log(:info, ct, 'Auto-stopping container')
      do_stop_ct(ct, message:)
    end
  end

  plan << cmds
end

#stopObject



147
148
149
150
# File 'lib/osctld/auto_stop/plan.rb', line 147

def stop
  @stop = true
  plan.stop
end

#stop?Boolean (protected)

Returns:

  • (Boolean)


187
188
189
# File 'lib/osctld/auto_stop/plan.rb', line 187

def stop?
  @stop
end

#waitObject



143
144
145
# File 'lib/osctld/auto_stop/plan.rb', line 143

def wait
  plan.wait_until_empty
end