Class: Mamiya::Agent

Inherits:
Object
  • Object
show all
Includes:
Actions, Util::LabelMatcher
Defined in:
lib/mamiya/agent.rb,
lib/mamiya/agent/actions.rb,
lib/mamiya/agent/task_queue.rb,
lib/mamiya/agent/tasks/ping.rb,
lib/mamiya/agent/tasks/clean.rb,
lib/mamiya/agent/tasks/fetch.rb,
lib/mamiya/agent/tasks/switch.rb,
lib/mamiya/agent/handlers/task.rb,
lib/mamiya/agent/tasks/prepare.rb,
lib/mamiya/agent/tasks/abstract.rb,
lib/mamiya/agent/tasks/notifyable.rb,
lib/mamiya/agent/handlers/abstract.rb

Direct Known Subclasses

Master

Defined Under Namespace

Modules: Actions, Handlers, Tasks Classes: TaskQueue

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util::LabelMatcher

#match?, parse_string_expr

Methods included from Actions

#distribute, #order_task, #ping, #prepare, #switch

Constructor Details

#initialize(config, logger: Mamiya::Logger.new, events_only: nil) ⇒ Agent

Returns a new instance of Agent.



29
30
31
32
33
34
35
36
37
38
# File 'lib/mamiya/agent.rb', line 29

def initialize(config, logger: Mamiya::Logger.new, events_only: nil)
  @config = config
  @serf = init_serf
  @trigger_lock = Mutex.new
  @events_only = events_only

  @terminate = false

  @logger = logger['agent']
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



40
41
42
# File 'lib/mamiya/agent.rb', line 40

def config
  @config
end

#loggerObject (readonly)

Returns the value of attribute logger.



40
41
42
# File 'lib/mamiya/agent.rb', line 40

def logger
  @logger
end

#serfObject (readonly)

Returns the value of attribute serf.



40
41
42
# File 'lib/mamiya/agent.rb', line 40

def serf
  @serf
end

Instance Method Details

#currentsObject



171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/mamiya/agent.rb', line 171

def currents
  # TODO: when the target is in outside?
  Hash[config.applications.map do |name, app|
    deploy_to = Pathname.new(app[:deploy_to])
    current = deploy_to.join('current')
    next unless current.exist?

    [
      name,
      current.realpath.basename.to_s
    ]
  end.compact]
end

#existing_packagesObject

Returns hash with existing packages (where valid) by app name. Packages which has json and tarball is considered as valid.



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/mamiya/agent.rb', line 111

def existing_packages
  paths_by_app = Dir[File.join(config[:packages_dir], '*', '*.{tar.gz,json}')].group_by { |path|
    path.split(File::SEPARATOR)[-2]
  }

  Hash[
    paths_by_app.map { |app, paths|
      names_by_base = paths.group_by do |path|
        File.basename(path).sub(/\.(?:tar\.gz|json)\z/, '')
      end

      packages = names_by_base.flat_map { |base, names|
        names.map do |name|
          (
            name.end_with?(".tar.gz") &&
            names.find { |_| _.end_with?(".json") } &&
            base
          ) || nil
        end
      }.compact

      [app, packages.sort]
    }
  ]
end

#existing_prereleasesObject



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/mamiya/agent.rb', line 137

def existing_prereleases
  paths_by_app = Dir[File.join(config[:prereleases_dir], '*', '*')].group_by { |path|
    path.split(File::SEPARATOR)[-2]
  }

  Hash[
    paths_by_app.map { |app, paths|
      [
        app,
        paths.select { |path|
          File.exist? File.join(path, '.mamiya.prepared')
        }.map { |path|
          File.basename(path)
        }.sort
      ]
    }
  ]
end

#labelsObject



102
103
104
# File 'lib/mamiya/agent.rb', line 102

def labels
  config.labels[[]]
end

#releasesObject



156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/mamiya/agent.rb', line 156

def releases
  Hash[config.applications.map do |name, app|
    deploy_to = Pathname.new(app[:deploy_to])
    releases = deploy_to.join('releases')
    next [name, []] unless releases.exist?

    [
      name,
      releases.children.map do |release|
        release.basename.to_s
      end.sort
    ]
  end.compact]
end

#run!Object



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/mamiya/agent.rb', line 52

def run!
  logger.info "Starting..."
  start()
  logger.info "Started."

  loop do
    if @terminate
      terminate
      return
    end
    sleep 1
  end
end

#startObject



70
71
72
73
# File 'lib/mamiya/agent.rb', line 70

def start
  serf_start
  task_queue_start
end

#status(packages: true) ⇒ Object

Returns agent status. Used for HTTP API and ‘serf query` inspection.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/mamiya/agent.rb', line 84

def status(packages: true)
  # When changing signature, don't forget to change samely of Master#status too
  {}.tap do |s|
    s[:name] = serf.name
    s[:version] = Mamiya::VERSION
    s[:labels] = labels

    s[:queues] = task_queue.status

    if packages
      s[:packages] = self.existing_packages
      s[:prereleases] = self.existing_prereleases
      s[:releases] = self.releases
      s[:currents] = self.currents
    end
  end
end

#stop!Object



66
67
68
# File 'lib/mamiya/agent.rb', line 66

def stop!
  @terminate = true
end

#task_queueObject



42
43
44
45
46
47
48
49
50
# File 'lib/mamiya/agent.rb', line 42

def task_queue
  @task_queue ||= Mamiya::Agent::TaskQueue.new(self, logger: logger, task_classes: [
    Mamiya::Agent::Tasks::Fetch,
    Mamiya::Agent::Tasks::Prepare,
    Mamiya::Agent::Tasks::Clean,
    Mamiya::Agent::Tasks::Switch,
    Mamiya::Agent::Tasks::Ping,
  ])
end

#terminateObject



75
76
77
78
79
80
# File 'lib/mamiya/agent.rb', line 75

def terminate
  serf.stop!
  task_queue.stop!
ensure
  @terminate = false
end

#trigger(type, action: nil, coalesce: true, **payload) ⇒ Object



185
186
187
188
189
190
191
192
193
194
# File 'lib/mamiya/agent.rb', line 185

def trigger(type, action: nil, coalesce: true, **payload)
  name = "mamiya:#{type}"
  name << ":#{action}" if action

  payload_str = payload.merge(name: self.serf.name).to_json

  @trigger_lock.synchronize do
    serf.event(name, payload_str, coalesce: coalesce)
  end
end