mamiya 0.0.1.alpha21 → 0.0.1.alpha22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/example/.gitignore +5 -0
  3. data/example/Procfile +1 -1
  4. data/example/README.md +83 -0
  5. data/example/config.agent.rb +40 -0
  6. data/example/config.rb +20 -6
  7. data/example/deploy.rb +27 -11
  8. data/example/source/README.md +1 -0
  9. data/lib/mamiya/agent/actions.rb +8 -3
  10. data/lib/mamiya/agent/task_queue.rb +9 -0
  11. data/lib/mamiya/agent/tasks/abstract.rb +13 -0
  12. data/lib/mamiya/agent/tasks/clean.rb +36 -4
  13. data/lib/mamiya/agent/tasks/fetch.rb +1 -0
  14. data/lib/mamiya/agent/tasks/notifyable.rb +0 -1
  15. data/lib/mamiya/agent/tasks/prepare.rb +103 -0
  16. data/lib/mamiya/agent.rb +46 -12
  17. data/lib/mamiya/cli/client.rb +35 -7
  18. data/lib/mamiya/cli.rb +44 -5
  19. data/lib/mamiya/configuration.rb +12 -0
  20. data/lib/mamiya/dsl.rb +6 -2
  21. data/lib/mamiya/helpers/git.rb +24 -0
  22. data/lib/mamiya/master/agent_monitor.rb +22 -2
  23. data/lib/mamiya/master/agent_monitor_handlers.rb +17 -0
  24. data/lib/mamiya/master/web.rb +42 -3
  25. data/lib/mamiya/master.rb +4 -0
  26. data/lib/mamiya/script.rb +28 -8
  27. data/lib/mamiya/steps/abstract.rb +1 -0
  28. data/lib/mamiya/steps/build.rb +107 -19
  29. data/lib/mamiya/steps/extract.rb +1 -0
  30. data/lib/mamiya/steps/prepare.rb +60 -0
  31. data/lib/mamiya/steps/switch.rb +76 -0
  32. data/lib/mamiya/storages/filesystem.rb +92 -0
  33. data/lib/mamiya/storages/mock.rb +1 -0
  34. data/lib/mamiya/util/label_matcher.rb +7 -3
  35. data/lib/mamiya/version.rb +1 -1
  36. data/mamiya.gemspec +1 -1
  37. data/spec/agent/actions_spec.rb +25 -0
  38. data/spec/agent/task_queue_spec.rb +42 -6
  39. data/spec/agent/tasks/abstract_spec.rb +35 -0
  40. data/spec/agent/tasks/clean_spec.rb +94 -45
  41. data/spec/agent/tasks/fetch_spec.rb +1 -0
  42. data/spec/agent/tasks/prepare_spec.rb +127 -0
  43. data/spec/agent_spec.rb +75 -27
  44. data/spec/dsl_spec.rb +6 -8
  45. data/spec/master/agent_monitor_spec.rb +142 -4
  46. data/spec/master/web_spec.rb +43 -1
  47. data/spec/steps/build_spec.rb +101 -0
  48. data/spec/steps/prepare_spec.rb +125 -0
  49. data/spec/steps/switch_spec.rb +146 -0
  50. data/spec/storages/filesystem_spec.rb +305 -0
  51. data/spec/util/label_matcher_spec.rb +32 -0
  52. metadata +20 -6
  53. data/config.example.yml +0 -11
  54. data/example.rb +0 -74
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4a0a40c67ec9701a56d9d5454ed090bca4f8c7c4
4
- data.tar.gz: c6989472920d7302838ca131b425b62715383809
3
+ metadata.gz: 132e823632be17c5738d084b0c0137d92846408f
4
+ data.tar.gz: 19a669e42c52946e603884bf9a27816e7b22bbf7
5
5
  SHA512:
6
- metadata.gz: 60cfeb34db85ab130c792c28723e91518f2367a6bf29ff9221b7b969fa956c8fb2dfd12f69e0b44143081619ac346862270ab6c46b6afb4d343cb1fe2c7ac815
7
- data.tar.gz: fc6c115392f4dca0acd05aa5c4708d796a29086b4c8863a65432a82206c397829b065d063bc909a98adb5bf09d70cb6b3bbf08cd5fc9218735d55f50dc0eb62c
6
+ metadata.gz: d1ad837469c4bf7ddbeb9bb2d740070e9705344df425c2047b8f9ccec4e3a0a75626533f19f7b7a189407f147be538d7b628d884633bf68c5f969f2773df20c2
7
+ data.tar.gz: 80e843665be039f845917ce97bc9c47bced11d2f147096868617d6c0d0306e407e600a95516dbab64a4e08ad3cd976358dd11df75939baa4a6297e8aa594113a
@@ -0,0 +1,5 @@
1
+ target/
2
+ packages/*
3
+ source/built_at
4
+ targets/
5
+ builds/
data/example/Procfile CHANGED
@@ -1,2 +1,2 @@
1
1
  master: bundle exec env MAMIYA_SYNC_OUT=1 mamiya master -d --serf bind=0.0.0.0:7760,rpc_addr=127.0.0.1:17760,node=${HOSTNAME}_${PORT}
2
- agent: bundle exec env MAMIYA_SYNC_OUT=1 sh -c 'sleep 2; mamiya agent -d --serf bind=0.0.0.0:$PORT,rpc_addr=127.0.0.1:1$PORT,join=127.0.0.1:7760,node=${HOSTNAME}_${PORT}'
2
+ agent: bundle exec env MAMIYA_SYNC_OUT=1 sh -c 'sleep 2; mamiya agent -C config.agent.rb -d'
data/example/README.md ADDED
@@ -0,0 +1,83 @@
1
+ ## mamiya example configuration
2
+
3
+ You can start both master and agent(s) using foreman, in local.
4
+
5
+ - `deploy.rb`: mamiya script file (for package building, preparing)
6
+ - `config.rb`: master node configuration
7
+ - `config.agent.rb`: agent node configuration
8
+
9
+
10
+ ### Building and pushing packages
11
+
12
+ - specify `$S3_BUCKET`, `$AWS_ACCESS_KEY_ID`, and `$AWS_SECRET_ACCESS_KEY` to use `S3` storage.
13
+ - if not all specified, defaults to `Filesystem` storage uses `./packages` directory.
14
+
15
+ ```
16
+ $ bundle exec mamiya build
17
+ 09/09 09:41:00 INFO | [Build] Initiating package build
18
+ 09/09 09:41:00 INFO | [Build] Running script.before_build
19
+ 09/09 09:41:00 INFO | [Build] Running script.prepare_build
20
+ 09/09 09:41:00 INFO | [Build] Running script.build ...
21
+ 09/09 09:41:00 INFO | [Build] Copying script files...
22
+ 09/09 09:41:00 INFO | [Build] - /.../example/deploy.rb -> /.../example/source/.mamiya.script
23
+ 09/09 09:41:00 INFO | [Build] Package name determined: 2014-09-09_09.41.00-myapp
24
+ 09/09 09:41:00 INFO | [Build] Packaging to: /.../example/builds/2014-09-09_09.41.00-myapp.tar.gz
25
+ 09/09 09:41:00 INFO | [Build] Packed.
26
+ 09/09 09:41:00 INFO | [Build] Running script.after_build
27
+ 09/09 09:41:00 INFO | [Build] DONE!
28
+
29
+ $ tree packages
30
+ builds
31
+ ├── 2014-09-09_09.41.00-myapp.json
32
+ └── 2014-09-09_09.41.00-myapp.tar.gz
33
+
34
+ 0 directories, 2 files
35
+ ```
36
+
37
+ ```
38
+ $ bundle exec mamiya push builds/2014-09-09_09.41.00-myapp.tar.gz
39
+ $ bundle exec mamiya list-packages
40
+ $ bundle exec mamiya fetch 2014-09-09_09.41.00-myapp /tmp/
41
+ ```
42
+
43
+ ### Test steps individually (without agents)
44
+
45
+ ```
46
+ $ bundle exec mamiya extract /tmp/2014-09-09_09.41.00-myapp.tar.gz /tmp/test
47
+ 09/09 09:41:00 INFO | [Extract] Extracting /tmp/2014-09-09_09.41.00-myapp.tar.gz onto /tmp/test/2014-09-09_09.41.00-myapp
48
+ ```
49
+
50
+ ```
51
+ $ bundle exec mamiya prepare /tmp/test/2014-09-09_09.41.00-myapp
52
+ 09/09 09:41:00 INFO | [Prepare] Preparing /private/tmp/test/2014-09-09_09.41.00-myapp...
53
+ ```
54
+
55
+ ### master and agents
56
+
57
+ #### Start cluster in local
58
+
59
+ You have to install [Serf](https://www.serfdom.io/) to run.
60
+
61
+ ```
62
+ $ foreman start
63
+
64
+ (or)
65
+
66
+ $ foreman start -m 'master=1,agent=2'
67
+ ```
68
+
69
+ #### Test `mamiya client`
70
+
71
+ ```
72
+ $ bundle exec mamiya client list-packages -a myapp
73
+ 2014-09-09_09.41.00-myapp
74
+
75
+ $ bundle exec mamiya client show-package -a myapp 2014-09-09_09.41.00-myapp
76
+ {"application"=>"myapp",
77
+ "name"=>"2014-09-09_09.41.00-myapp",
78
+ "meta"=>
79
+ {"application"=>"myapp",
80
+ "script"=>"deploy.rb",
81
+ "name"=>"2014-09-09_09.41.00-myapp",
82
+ "checksum"=>"..."}}
83
+ ```
@@ -0,0 +1,40 @@
1
+ require 'pathname'
2
+
3
+ if ENV['MAMIYA_S3_BUCKET'] || ENV['S3_BUCKET']
4
+ set :storage, {
5
+ type: :s3,
6
+ bucket: ENV["MAMIYA_S3_BUCKET"] || ENV["S3_BUCKET"],
7
+ region: ENV["AWS_REGION"] || 'ap-northeast-1',
8
+ }
9
+ else
10
+ set :storage, {
11
+ type: :filesystem,
12
+ path: File.join(File.dirname(__FILE__), 'packages'),
13
+ }
14
+ end
15
+
16
+ set :serf, {
17
+ agent: {
18
+ bind: "0.0.0.0:#{ENV['PORT']}",
19
+ rpc_addr: "127.0.0.1:#{ENV['PORT']}",
20
+ join: "127.0.0.1:7760",
21
+ node: "#{ENV['HOSTNAME']}_#{ENV['PORT']}",
22
+ }
23
+ }
24
+ p serf
25
+
26
+ agent_name = ENV['PORT'].to_s
27
+
28
+ targets = Pathname.new(File.dirname(__FILE__)).join('targets')
29
+ target = targets.join(agent_name).tap(&:mkpath)
30
+
31
+ set :packages_dir, target.join('packages')
32
+ set :prereleases_dir, target.join('prereleases')
33
+
34
+ # To test
35
+ Dir.mkdir packages_dir unless File.exist?(packages_dir)
36
+ Dir.mkdir prereleases_dir unless File.exist?(prereleases_dir)
37
+
38
+ set :keep_packages, 3
39
+ set :keep_prereleases, 3
40
+ set :fetch_sleep, 2
data/example/config.rb CHANGED
@@ -1,9 +1,23 @@
1
- set :storage, {
2
- type: :s3,
3
- bucket: ENV["MAMIYA_S3_BUCKET"] || ENV["S3_BUCKET"] || raise("specify your S3 bucket via $MAMIYA_S3_BUCKET or $S3_BUCKET"),
4
- region: ENV["AWS_REGION"] || 'ap-northeast-1',
5
- }
1
+ if ENV['MAMIYA_S3_BUCKET'] || ENV['S3_BUCKET']
2
+ set :storage, {
3
+ type: :s3,
4
+ bucket: ENV["MAMIYA_S3_BUCKET"] || ENV["S3_BUCKET"],
5
+ region: ENV["AWS_REGION"] || 'ap-northeast-1',
6
+ }
7
+ else
8
+ set :storage, {
9
+ type: :filesystem,
10
+ path: File.join(File.dirname(__FILE__), 'packages'),
11
+ }
12
+ end
13
+
14
+ set :packages_dir, "#{File.dirname(__FILE__)}/packages"
15
+ set :prereleases_dir, "#{File.dirname(__FILE__)}/target/prereleases"
16
+
17
+ # To test
18
+ Dir.mkdir packages_dir unless File.exist?(packages_dir)
19
+ prereleases_dir.mkpath unless File.exist?(prereleases_dir)
6
20
 
7
- set :packages_dir, "#{File.dirname(__FILE__)}/dst"
8
21
  set :keep_packages, 3
22
+ set :keep_prereleases, 3
9
23
  set :fetch_sleep, 2
data/example/deploy.rb CHANGED
@@ -10,25 +10,41 @@ set :exclude_from_package, ['tmp', 'log', 'spec', '.sass-cache']
10
10
  set :dereference_symlinks, true
11
11
 
12
12
  # http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=45360&view=revision
13
- set :build_to, "#{File.dirname(__FILE__)}/pkg"
14
- set :deploy_to, "..."
13
+ set :build_from, "#{File.dirname(__FILE__)}/source"
14
+ set :build_to, "#{File.dirname(__FILE__)}/builds"
15
+
16
+ dir = File.dirname(__FILE__)
17
+ if File.basename(dir) == 'example'
18
+ set :deploy_to, File.join(dir, 'targets', 'default')
19
+ else
20
+ # target/{releases,prereleases}/<name>/.mamiya.script/../../..
21
+ set :deploy_to, File.expand_path(File.join(dir, '..', '..', '..'))
22
+ end
23
+
24
+ # to test it
25
+ Dir.mkdir build_to unless File.exist?(build_to)
26
+ deploy_to.mkpath unless deploy_to.exist?
15
27
 
16
28
  set :bundle_without, [:development, :test]
17
29
  set :bundle_dir, "#{deploy_to}/shared/bundle"
18
30
 
19
31
  #use :git, exclude_git_clean_targets: true
20
32
 
21
- prepare_build("bundle install") do
22
- run "bundle", "install"
23
- end
33
+ #prepare_build("bundle install") do
34
+ # run "bundle", "install"
35
+ #end
24
36
 
25
- build("include assets and .bundle") do
26
- exclude_from_package.reject! { |_| _ == 'public/assets/' }
27
- exclude_from_package.reject! { |_| _ == '.bundle/' }
37
+ build("test") do
38
+ File.write('built_at', "#{Time.now}\n")
28
39
  end
29
40
 
30
- build("assets compile") do
31
- run "bundle", "exec", "rake", "assets:precompile"
32
- end
41
+ #build("include assets and .bundle") do
42
+ # exclude_from_package.reject! { |_| _ == 'public/assets/' }
43
+ # exclude_from_package.reject! { |_| _ == '.bundle/' }
44
+ #end
45
+ #
46
+ #build("assets compile") do
47
+ # run "bundle", "exec", "rake", "assets:precompile"
48
+ #end
33
49
 
34
50
 
@@ -0,0 +1 @@
1
+ Hello
@@ -1,7 +1,8 @@
1
1
  module Mamiya
2
2
  class Agent
3
3
  module Actions
4
- def order_task(task, coalesce: false, **payload)
4
+ def order_task(task, coalesce: false, labels: nil, **payload)
5
+ payload[:_labels] = labels if labels
5
6
  trigger('task',
6
7
  coalesce: coalesce,
7
8
  task: task,
@@ -9,8 +10,12 @@ module Mamiya
9
10
  )
10
11
  end
11
12
 
12
- def distribute(application, package)
13
- order_task('fetch', app: application, pkg: package)
13
+ def distribute(application, package, labels: nil)
14
+ order_task('fetch', app: application, pkg: package, labels: labels)
15
+ end
16
+
17
+ def prepare(application, package, labels: nil)
18
+ order_task('prepare', app: application, pkg: package, labels: labels)
14
19
  end
15
20
  end
16
21
  end
@@ -84,6 +84,15 @@ module Mamiya
84
84
  def enqueue(task_name, task)
85
85
  raise Stopped, 'this task queue is stopped' unless running?
86
86
 
87
+ if task['_labels'] && !agent.match?(task['_labels'])
88
+ @logger.debug "skipping enqueue #{task_name.inspect}, #{task.inspect}, because agent doesn't match"
89
+ return self
90
+ end
91
+
92
+ task.delete '_labels'
93
+ task.delete 'task'
94
+ task['task'] = task_name
95
+
87
96
  @logger.debug "enqueue #{task_name.inspect}, #{task.inspect}, #{@external_queue.inspect}"
88
97
  @external_queue << [task_name, task]
89
98
  self
@@ -37,6 +37,7 @@ module Mamiya
37
37
  errored
38
38
  @logger.error "Encountered error: #{error.inspect}\n\t#{error.backtrace.join("\n\t")}"
39
39
  ensure
40
+ enqueue_chained unless error
40
41
  after
41
42
  @logger.info "Task finished"
42
43
  end
@@ -55,6 +56,18 @@ module Mamiya
55
56
 
56
57
  private
57
58
 
59
+ def enqueue_chained
60
+ return if !task['_chain'] || task['_chain'].empty?
61
+
62
+ next_task = task.dup
63
+ next_task.delete('task')
64
+
65
+ next_task_name, *next_task['_chain'] = task['_chain']
66
+ next_task.delete('_chain') if next_task['_chain'].empty?
67
+
68
+ task_queue.enqueue(next_task_name.to_sym, next_task)
69
+ end
70
+
58
71
  def config
59
72
  @config ||= agent ? agent.config : nil
60
73
  end
@@ -6,8 +6,14 @@ module Mamiya
6
6
  class Clean < Abstract
7
7
 
8
8
  def run
9
- victims.each do |app, victim|
10
- @logger.info "Cleaning up: remove #{victim}"
9
+ # XXX:
10
+ clean_packages
11
+ clean_prereleases
12
+ end
13
+
14
+ def clean_packages
15
+ package_victims.each do |app, victim|
16
+ @logger.info "Cleaning package: remove #{victim}"
11
17
  File.unlink(victim) if File.exist?(victim)
12
18
 
13
19
  meta_victim = victim.sub(/\.tar\.gz\z/, '.json')
@@ -16,9 +22,10 @@ module Mamiya
16
22
  File.unlink(meta_victim)
17
23
  end
18
24
 
25
+ # XXX: depends on FS structure
19
26
  package_name = File.basename(victim, '.tar.gz')
20
27
 
21
- # XXX: depends on FS structure
28
+ # XXX: TODO: application->app, package->pkg
22
29
  agent.trigger('pkg', action: 'remove',
23
30
  application: app,
24
31
  package: package_name,
@@ -27,7 +34,7 @@ module Mamiya
27
34
  end
28
35
  end
29
36
 
30
- def victims
37
+ def package_victims
31
38
  Dir[File.join(config[:packages_dir], '*')].flat_map do |app|
32
39
  packages = Dir[File.join(app, "*.tar.gz")].
33
40
  sort_by { |_| [File.mtime(_), _] }
@@ -38,6 +45,31 @@ module Mamiya
38
45
  end
39
46
  end
40
47
 
48
+ def clean_prereleases
49
+ prerelease_victims.each do |app, victim|
50
+ @logger.info "Cleaning prerelease: remove #{victim}"
51
+ package_name = File.basename(victim)
52
+ FileUtils.remove_entry_secure victim
53
+
54
+ agent.trigger('prerelease', action: 'remove',
55
+ app: app,
56
+ pkg: package_name,
57
+ coalesce: false,
58
+ )
59
+ end
60
+ end
61
+
62
+ def prerelease_victims
63
+ Dir[File.join(config[:prereleases_dir], '*')].flat_map do |app|
64
+ prereleases = Dir[File.join(app, "*")].
65
+ sort_by { |_| [File.mtime(_), _] }
66
+
67
+ prereleases[0...-(config[:keep_prereleases])].map do |victim|
68
+ [File.basename(app), victim]
69
+ end
70
+ end
71
+ end
72
+
41
73
  end
42
74
  end
43
75
  end
@@ -63,6 +63,7 @@ module Mamiya
63
63
  package: package,
64
64
  destination: destination,
65
65
  config: config,
66
+ logger: logger,
66
67
  )
67
68
  end
68
69
  end
@@ -1,4 +1,3 @@
1
- require 'mamiya/agent'
2
1
  require 'mamiya/agent/tasks/abstract'
3
2
 
4
3
  module Mamiya
@@ -0,0 +1,103 @@
1
+ require 'fileutils'
2
+
3
+ require 'mamiya/agent/tasks/notifyable'
4
+ require 'mamiya/steps/extract'
5
+ require 'mamiya/steps/prepare'
6
+
7
+ module Mamiya
8
+ class Agent
9
+ module Tasks
10
+ class Prepare < Notifyable
11
+ def execute
12
+ return unless check
13
+ super
14
+ end
15
+
16
+ def check
17
+ unless package_path.exist?
18
+ new_chain = ['prepare'] + (task['_chain'] || [])
19
+ logger.info "Package not fetched, enqueueing fetch task with #{new_chain.inspect}"
20
+ task_queue.enqueue(
21
+ :fetch,
22
+ task.merge('_chain' => new_chain)
23
+ )
24
+ return false
25
+ end
26
+
27
+ true
28
+ end
29
+
30
+ def run
31
+ if prerelease_path.exist?
32
+ if prerelease_path.join('.mamiya.prepared').exist?
33
+ return
34
+ else
35
+ FileUtils.remove_entry_secure prerelease_path
36
+ end
37
+ end
38
+
39
+ packages_dir.join(application).mkpath
40
+ prereleases_dir.join(application).mkpath
41
+
42
+ extract_step.run!
43
+ prepare_step.run!
44
+ end
45
+
46
+ private
47
+
48
+ def application
49
+ task['app']
50
+ end
51
+
52
+ def package
53
+ task['pkg']
54
+ end
55
+
56
+ def release_name
57
+ task['release'] || package
58
+ end
59
+
60
+ def packages_dir
61
+ @packages_dir ||= config.packages_dir
62
+ end
63
+
64
+ def prereleases_dir
65
+ @prereleases_dir ||= config.prereleases_dir
66
+ end
67
+
68
+ def package_path
69
+ packages_dir.join(application, "#{package}.tar.gz")
70
+ end
71
+
72
+ def prerelease_path
73
+ prereleases_dir.join(application, release_name)
74
+ end
75
+
76
+
77
+ def labels
78
+ @labels ||= agent.labels
79
+ end
80
+
81
+
82
+ def extract_step
83
+ @extract_step ||= Mamiya::Steps::Extract.new(
84
+ package: package_path,
85
+ destination: prerelease_path,
86
+ config: config,
87
+ logger: logger,
88
+ )
89
+ end
90
+
91
+ def prepare_step
92
+ @prepare_step ||= Mamiya::Steps::Prepare.new(
93
+ script: nil,
94
+ target: prerelease_path,
95
+ config: config,
96
+ labels: labels,
97
+ logger: logger,
98
+ )
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
data/lib/mamiya/agent.rb CHANGED
@@ -2,12 +2,17 @@ require 'thread'
2
2
  require 'villein'
3
3
  require 'mamiya/version'
4
4
 
5
+ require 'mamiya/util/label_matcher'
6
+
5
7
  require 'mamiya/logger'
6
8
 
7
9
  require 'mamiya/steps/fetch'
10
+ require 'mamiya/steps/prepare'
11
+ require 'mamiya/steps/extract'
8
12
  require 'mamiya/agent/task_queue'
9
13
 
10
14
  require 'mamiya/agent/tasks/fetch'
15
+ require 'mamiya/agent/tasks/prepare'
11
16
  require 'mamiya/agent/tasks/clean'
12
17
 
13
18
  require 'mamiya/agent/handlers/task'
@@ -20,6 +25,7 @@ module Mamiya
20
25
  def initialize(config, logger: Mamiya::Logger.new, events_only: nil)
21
26
  @config = config
22
27
  @serf = init_serf
28
+ @trigger_lock = Mutex.new
23
29
  @events_only = events_only
24
30
 
25
31
  @terminate = false
@@ -32,6 +38,7 @@ module Mamiya
32
38
  def task_queue
33
39
  @task_queue ||= Mamiya::Agent::TaskQueue.new(self, logger: logger, task_classes: [
34
40
  Mamiya::Agent::Tasks::Fetch,
41
+ Mamiya::Agent::Tasks::Prepare,
35
42
  Mamiya::Agent::Tasks::Clean,
36
43
  ])
37
44
  end
@@ -66,14 +73,6 @@ module Mamiya
66
73
  @terminate = false
67
74
  end
68
75
 
69
- def update_tags!
70
- serf.tags['mamiya'] = ','.tap do |status|
71
- status.concat('ready,') if status == ','
72
- end
73
-
74
- nil
75
- end
76
-
77
76
  ##
78
77
  # Returns agent status. Used for HTTP API and `serf query` inspection.
79
78
  def status(packages: true)
@@ -81,19 +80,29 @@ module Mamiya
81
80
  {}.tap do |s|
82
81
  s[:name] = serf.name
83
82
  s[:version] = Mamiya::VERSION
83
+ s[:labels] = labels
84
84
 
85
85
  s[:queues] = task_queue.status
86
86
 
87
- s[:packages] = self.existing_packages if packages
87
+ if packages
88
+ s[:packages] = self.existing_packages
89
+ s[:prereleases] = self.existing_prereleases
90
+ end
88
91
  end
89
92
  end
90
93
 
94
+ def labels
95
+ config.labels[[]]
96
+ end
97
+
98
+ include Mamiya::Util::LabelMatcher
99
+
91
100
  ##
92
101
  # Returns hash with existing packages (where valid) by app name.
93
102
  # Packages which has json and tarball is considered as valid.
94
103
  def existing_packages
95
104
  paths_by_app = Dir[File.join(config[:packages_dir], '*', '*.{tar.gz,json}')].group_by { |path|
96
- path.split('/')[-2]
105
+ path.split(File::SEPARATOR)[-2]
97
106
  }
98
107
 
99
108
  Hash[
@@ -117,11 +126,34 @@ module Mamiya
117
126
  ]
118
127
  end
119
128
 
129
+ def existing_prereleases
130
+ paths_by_app = Dir[File.join(config[:prereleases_dir], '*', '*')].group_by { |path|
131
+ path.split(File::SEPARATOR)[-2]
132
+ }
133
+
134
+ Hash[
135
+ paths_by_app.map { |app, paths|
136
+ [
137
+ app,
138
+ paths.select { |path|
139
+ File.exist? File.join(path, '.mamiya.prepared')
140
+ }.map { |path|
141
+ File.basename(path)
142
+ }.sort
143
+ ]
144
+ }
145
+ ]
146
+ end
147
+
120
148
  def trigger(type, action: nil, coalesce: true, **payload)
121
149
  name = "mamiya:#{type}"
122
150
  name << ":#{action}" if action
123
151
 
124
- serf.event(name, payload.merge(name: self.serf.name).to_json, coalesce: coalesce)
152
+ payload_str = payload.merge(name: self.serf.name).to_json
153
+
154
+ @trigger_lock.synchronize do
155
+ serf.event(name, payload_str, coalesce: coalesce)
156
+ end
125
157
  end
126
158
 
127
159
  private
@@ -139,7 +171,9 @@ module Mamiya
139
171
  end
140
172
 
141
173
  serf.respond('mamiya:packages') do |event|
142
- self.existing_packages.to_json
174
+ {'packages' => self.existing_packages,
175
+ 'prereleases' => self.existing_prereleases,
176
+ }.to_json
143
177
  end
144
178
  end
145
179
  end