concourse-technician 0.3.4 → 0.4.2
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 +4 -4
- data/README.org +36 -3
- data/bin/technician +8 -4
- data/concourse-technician.gemspec +2 -0
- data/lib/concourse-technician.rb +1 -0
- data/lib/concourse-technician/volume_reaper.rb +133 -0
- metadata +43 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c97c608157d2c56434e208f79d548d58fd591c7
|
4
|
+
data.tar.gz: 5717fe2194475f37fa01e47ff57d0c9af67eefbb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 194f576c50f1459eb1b1a48b5387f9281256e8efee93877c928e7fd684202a7cdcc325aaed2a16091d298c65440d530f857ebc6fca08df446c5d8cca31a67dce
|
7
|
+
data.tar.gz: 94af80ccab86ad6dc1dd36b941453f086aa86c518f00e9bc75d8c03b7f670e807e94204f54fab295438c564c8a67b293a8cb9ac11f3ae007f494f50e31c8019e
|
data/README.org
CHANGED
@@ -11,23 +11,56 @@
|
|
11
11
|
gem install concourse-technician
|
12
12
|
#+END_SRC
|
13
13
|
|
14
|
+
* Configuration
|
15
|
+
|
16
|
+
~concourse-technician~ needs to be pointed at your Concourse database. It
|
17
|
+
looks for a configuration file at =~/.config/concourse-technician.yaml=. To
|
18
|
+
tell it to look somewhere else, set =CONCOURSE_TECHNICIAN_CONFIG= in the
|
19
|
+
environment.
|
20
|
+
|
21
|
+
** Example
|
22
|
+
|
23
|
+
#+BEGIN_SRC yaml
|
24
|
+
---
|
25
|
+
adapter: postgres
|
26
|
+
database: my-awesome-database
|
27
|
+
host: localhost
|
28
|
+
password: MyVerySecurePasswordStoredUnencryptedOnDisk
|
29
|
+
port: 5432
|
30
|
+
user: me
|
31
|
+
|
32
|
+
volumes_root: /concourse/volumes
|
33
|
+
#+END_SRC
|
34
|
+
|
14
35
|
* Usage
|
15
36
|
|
16
37
|
To get a list of abandoned volumes...
|
17
38
|
|
18
39
|
#+BEGIN_SRC shell
|
19
|
-
technician abandoned_volumes
|
40
|
+
technician database abandoned_volumes
|
20
41
|
#+END_SRC
|
21
42
|
|
22
43
|
To clean up all abandoned volumes...
|
23
44
|
|
24
45
|
#+BEGIN_SRC shell
|
25
|
-
technician delete_abandoned_volumes
|
46
|
+
technician database delete_abandoned_volumes
|
47
|
+
#+END_SRC
|
48
|
+
|
49
|
+
To check if a worker is failing due to issues with volume reaping...
|
50
|
+
|
51
|
+
#+BEGIN_SRC shell
|
52
|
+
technician volume_reaper damaged
|
53
|
+
#+END_SRC
|
54
|
+
|
55
|
+
To resolve issues with volume reaping...
|
56
|
+
|
57
|
+
#+BEGIN_SRC shell
|
58
|
+
technician volume_reaper repair
|
26
59
|
#+END_SRC
|
27
60
|
|
28
61
|
* License
|
29
62
|
|
30
|
-
~
|
63
|
+
~concourse-technician~ is available under the [[https://tldrlegal.com/license/mit-license][MIT License]]. See ~LICENSE.txt~ for the full text.
|
31
64
|
|
32
65
|
* Contributors
|
33
66
|
|
data/bin/technician
CHANGED
@@ -3,9 +3,13 @@
|
|
3
3
|
require 'json'
|
4
4
|
require 'concourse-technician/cli'
|
5
5
|
require 'concourse-technician/database'
|
6
|
+
require 'concourse-technician/volume_reaper'
|
6
7
|
|
7
|
-
|
8
|
-
ConcourseTechnician::
|
9
|
-
|
10
|
-
|
8
|
+
commands = {
|
9
|
+
database: ConcourseTechnician::Database.new,
|
10
|
+
volume_reaper: ConcourseTechnician::VolumeReaper.new
|
11
|
+
}
|
12
|
+
|
13
|
+
ConcourseTechnician::CLI.new(commands).execute(*ARGV).tap do |out|
|
14
|
+
puts JSON.dump(out.respond_to?(:to_i) ? out.to_i : out.to_a) if out
|
11
15
|
end
|
@@ -12,7 +12,9 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
13
13
|
gem.require_paths = ['lib']
|
14
14
|
|
15
|
+
gem.add_runtime_dependency 'btrfs', '~> 0.1', '>= 0.1.5'
|
15
16
|
gem.add_runtime_dependency 'contracts', '~> 0.14', '>= 0.14.0'
|
16
17
|
gem.add_runtime_dependency 'instacli', '~> 1.1', '>= 1.1.2'
|
17
18
|
gem.add_runtime_dependency 'sequel', '~> 4.36', '>= 4.36.0'
|
19
|
+
gem.add_runtime_dependency 'systemized', '~> 0.2', '>= 0.2.4'
|
18
20
|
end
|
data/lib/concourse-technician.rb
CHANGED
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'btrfs'
|
2
|
+
require 'contracts'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'systemized'
|
5
|
+
require 'time'
|
6
|
+
require_relative 'settings'
|
7
|
+
|
8
|
+
module ConcourseTechnician
|
9
|
+
class VolumeReaper
|
10
|
+
include ::Contracts::Core
|
11
|
+
include ::Contracts::Builtin
|
12
|
+
include Settings
|
13
|
+
|
14
|
+
Contract None => ArrayOf[Time]
|
15
|
+
def timestamps
|
16
|
+
@timestamps ||= worker.journal.read(1000).map do |entry|
|
17
|
+
Time.parse entry.split.first
|
18
|
+
end.sort
|
19
|
+
end
|
20
|
+
|
21
|
+
Contract None => ArrayOf[Hash]
|
22
|
+
def recent_events
|
23
|
+
@recent_events ||= logs.read(100).map do |event|
|
24
|
+
begin
|
25
|
+
JSON.load event
|
26
|
+
rescue JSON::ParserError
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end.compact
|
30
|
+
end
|
31
|
+
|
32
|
+
Contract None => Any
|
33
|
+
def damaged
|
34
|
+
detected? ? exit : abort
|
35
|
+
end
|
36
|
+
|
37
|
+
Contract None => Any
|
38
|
+
def repair
|
39
|
+
detected ? repair! : abort
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
Contract RespondTo[:to_s] => Bool
|
45
|
+
def env?(key)
|
46
|
+
if ![nil, 'nil', 'false'].include? ENV[key.to_s.upcase]
|
47
|
+
true
|
48
|
+
else
|
49
|
+
block_given? ? yield : false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
Contract None => Bool
|
54
|
+
def stagnant_logs?
|
55
|
+
env?(:stagnant_logs) do
|
56
|
+
(Time.now - timestamps.last) > (timestamps.last - timestamps.first)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
Contract None => Bool
|
61
|
+
def reaping_failure?
|
62
|
+
env?(:reaping_failure) do
|
63
|
+
recent_events.any? do |event|
|
64
|
+
event['message'] == 'baggageclaim.tick.failed-to-reap'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
Contract RespondTo[:to_s] => nil
|
70
|
+
def report(message)
|
71
|
+
STDERR.puts message.to_s unless env?(:QUIET)
|
72
|
+
end
|
73
|
+
|
74
|
+
Contract None => Bool
|
75
|
+
def detected?
|
76
|
+
stagnant_logs?.tap do |status|
|
77
|
+
report "Most recent log entry @ #{timestamps.last}"
|
78
|
+
report "Logs seem stagnant? #{status}"
|
79
|
+
end && reaping_failure?.tap do |status|
|
80
|
+
report "Recently volume reaping failure? #{status}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
Contract None => ::Systemized::Service
|
85
|
+
def worker
|
86
|
+
@worker = ::Systemized::Service.new('concourse-worker')
|
87
|
+
end
|
88
|
+
|
89
|
+
Contract None => ::Systemized::Journal
|
90
|
+
def logs
|
91
|
+
@logs ||= ::Systemized::Journal.new('concourse-worker', output: 'cat')
|
92
|
+
end
|
93
|
+
|
94
|
+
Contract None => String
|
95
|
+
def volumes_root
|
96
|
+
@volumes_root ||= ENV.fetch('VOLUMES_ROOT') do
|
97
|
+
settings.fetch('volumes_root') { '/concourse/volumes' }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
Contract None => ArrayOf[::Btrfs::Subvolume]
|
102
|
+
def subvolumes
|
103
|
+
@subvolumes ||= ::Btrfs::Volume.new(volumes_root).subvolumes
|
104
|
+
end
|
105
|
+
|
106
|
+
Contract None => Maybe[Bool]
|
107
|
+
def reap_subvolumes
|
108
|
+
report "Reaping #{subvolumes.size} subvolumes..."
|
109
|
+
subvolumes.each(&:delete).all?(&:deleted?) unless env?(:NOOP)
|
110
|
+
end
|
111
|
+
|
112
|
+
Contract None => ArrayOf[String]
|
113
|
+
def dead_volumes
|
114
|
+
Dir.glob("#{volumes_root}/dead/*")
|
115
|
+
end
|
116
|
+
|
117
|
+
Contract None => Any
|
118
|
+
def reap_dead_volumes
|
119
|
+
report "Reaping #{dead_volumes.size} dead volumes..."
|
120
|
+
dead_volumes.each do |volume|
|
121
|
+
FileUtils.rmtree volume, verbose: env?(:QUIET), noop: env?(:NOOP)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
Contract None => Any
|
126
|
+
def repair!
|
127
|
+
worker.stop if worker.active?
|
128
|
+
reap_subvolumes
|
129
|
+
reap_dead_volumes
|
130
|
+
worker.start
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: concourse-technician
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Olstrom
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: btrfs
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.1.5
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.1.5
|
13
33
|
- !ruby/object:Gem::Dependency
|
14
34
|
name: contracts
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,6 +90,26 @@ dependencies:
|
|
70
90
|
- - ">="
|
71
91
|
- !ruby/object:Gem::Version
|
72
92
|
version: 4.36.0
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: systemized
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0.2'
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 0.2.4
|
103
|
+
type: :runtime
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.2'
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 0.2.4
|
73
113
|
description:
|
74
114
|
email: chris@olstrom.com
|
75
115
|
executables:
|
@@ -86,6 +126,7 @@ files:
|
|
86
126
|
- lib/concourse-technician/cli.rb
|
87
127
|
- lib/concourse-technician/database.rb
|
88
128
|
- lib/concourse-technician/settings.rb
|
129
|
+
- lib/concourse-technician/volume_reaper.rb
|
89
130
|
homepage: https://github.com/colstrom/concourse-technician
|
90
131
|
licenses:
|
91
132
|
- MIT
|
@@ -111,4 +152,3 @@ signing_key:
|
|
111
152
|
specification_version: 4
|
112
153
|
summary: Troubleshoot Concourse without fly
|
113
154
|
test_files: []
|
114
|
-
has_rdoc:
|