garcun 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +17 -0
  3. data/.gitignore +197 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +22 -0
  6. data/LICENSE +201 -0
  7. data/README.md +521 -0
  8. data/Rakefile +47 -0
  9. data/garcun.gemspec +83 -0
  10. data/lib/garcon.rb +290 -0
  11. data/lib/garcon/chef/chef_helpers.rb +343 -0
  12. data/lib/garcon/chef/coerce/coercer.rb +134 -0
  13. data/lib/garcon/chef/coerce/coercions/boolean_definitions.rb +34 -0
  14. data/lib/garcon/chef/coerce/coercions/date_definitions.rb +32 -0
  15. data/lib/garcon/chef/coerce/coercions/date_time_definitions.rb +32 -0
  16. data/lib/garcon/chef/coerce/coercions/fixnum_definitions.rb +34 -0
  17. data/lib/garcon/chef/coerce/coercions/float_definitions.rb +32 -0
  18. data/lib/garcon/chef/coerce/coercions/hash_definitions.rb +29 -0
  19. data/lib/garcon/chef/coerce/coercions/integer_definitions.rb +31 -0
  20. data/lib/garcon/chef/coerce/coercions/string_definitions.rb +45 -0
  21. data/lib/garcon/chef/coerce/coercions/time_definitions.rb +32 -0
  22. data/lib/garcon/chef/handler/devreporter.rb +127 -0
  23. data/lib/garcon/chef/log.rb +64 -0
  24. data/lib/garcon/chef/node.rb +100 -0
  25. data/lib/garcon/chef/provider/civilize.rb +209 -0
  26. data/lib/garcon/chef/provider/development.rb +159 -0
  27. data/lib/garcon/chef/provider/download.rb +420 -0
  28. data/lib/garcon/chef/provider/house_keeping.rb +265 -0
  29. data/lib/garcon/chef/provider/node_cache.rb +31 -0
  30. data/lib/garcon/chef/provider/partial.rb +183 -0
  31. data/lib/garcon/chef/provider/recovery.rb +80 -0
  32. data/lib/garcon/chef/provider/zip_file.rb +271 -0
  33. data/lib/garcon/chef/resource/attribute.rb +52 -0
  34. data/lib/garcon/chef/resource/base_dsl.rb +174 -0
  35. data/lib/garcon/chef/resource/blender.rb +140 -0
  36. data/lib/garcon/chef/resource/lazy_eval.rb +66 -0
  37. data/lib/garcon/chef/resource/resource_name.rb +109 -0
  38. data/lib/garcon/chef/secret_bag.rb +204 -0
  39. data/lib/garcon/chef/validations.rb +76 -0
  40. data/lib/garcon/chef_inclusions.rb +151 -0
  41. data/lib/garcon/configuration.rb +138 -0
  42. data/lib/garcon/core_ext.rb +39 -0
  43. data/lib/garcon/core_ext/array.rb +27 -0
  44. data/lib/garcon/core_ext/binding.rb +64 -0
  45. data/lib/garcon/core_ext/boolean.rb +66 -0
  46. data/lib/garcon/core_ext/duration.rb +271 -0
  47. data/lib/garcon/core_ext/enumerable.rb +34 -0
  48. data/lib/garcon/core_ext/file.rb +127 -0
  49. data/lib/garcon/core_ext/filetest.rb +62 -0
  50. data/lib/garcon/core_ext/hash.rb +279 -0
  51. data/lib/garcon/core_ext/kernel.rb +159 -0
  52. data/lib/garcon/core_ext/lazy.rb +222 -0
  53. data/lib/garcon/core_ext/method_access.rb +243 -0
  54. data/lib/garcon/core_ext/module.rb +92 -0
  55. data/lib/garcon/core_ext/nil.rb +53 -0
  56. data/lib/garcon/core_ext/numeric.rb +44 -0
  57. data/lib/garcon/core_ext/object.rb +342 -0
  58. data/lib/garcon/core_ext/pathname.rb +152 -0
  59. data/lib/garcon/core_ext/process.rb +41 -0
  60. data/lib/garcon/core_ext/random.rb +497 -0
  61. data/lib/garcon/core_ext/string.rb +312 -0
  62. data/lib/garcon/core_ext/struct.rb +49 -0
  63. data/lib/garcon/core_ext/symbol.rb +170 -0
  64. data/lib/garcon/core_ext/time.rb +234 -0
  65. data/lib/garcon/exceptions.rb +101 -0
  66. data/lib/garcon/inflections.rb +237 -0
  67. data/lib/garcon/inflections/defaults.rb +79 -0
  68. data/lib/garcon/inflections/inflections.rb +182 -0
  69. data/lib/garcon/inflections/rules_collection.rb +37 -0
  70. data/lib/garcon/secret.rb +271 -0
  71. data/lib/garcon/stash/format.rb +114 -0
  72. data/lib/garcon/stash/journal.rb +226 -0
  73. data/lib/garcon/stash/queue.rb +83 -0
  74. data/lib/garcon/stash/serializer.rb +86 -0
  75. data/lib/garcon/stash/store.rb +435 -0
  76. data/lib/garcon/task.rb +31 -0
  77. data/lib/garcon/task/atomic.rb +151 -0
  78. data/lib/garcon/task/atomic_boolean.rb +127 -0
  79. data/lib/garcon/task/condition.rb +99 -0
  80. data/lib/garcon/task/copy_on_notify_observer_set.rb +154 -0
  81. data/lib/garcon/task/copy_on_write_observer_set.rb +153 -0
  82. data/lib/garcon/task/count_down_latch.rb +92 -0
  83. data/lib/garcon/task/delay.rb +196 -0
  84. data/lib/garcon/task/dereferenceable.rb +144 -0
  85. data/lib/garcon/task/event.rb +119 -0
  86. data/lib/garcon/task/executor.rb +275 -0
  87. data/lib/garcon/task/executor_options.rb +59 -0
  88. data/lib/garcon/task/future.rb +107 -0
  89. data/lib/garcon/task/immediate_executor.rb +84 -0
  90. data/lib/garcon/task/ivar.rb +171 -0
  91. data/lib/garcon/task/lazy_reference.rb +74 -0
  92. data/lib/garcon/task/monotonic_time.rb +69 -0
  93. data/lib/garcon/task/obligation.rb +256 -0
  94. data/lib/garcon/task/observable.rb +101 -0
  95. data/lib/garcon/task/priority_queue.rb +234 -0
  96. data/lib/garcon/task/processor_count.rb +128 -0
  97. data/lib/garcon/task/read_write_lock.rb +304 -0
  98. data/lib/garcon/task/safe_task_executor.rb +58 -0
  99. data/lib/garcon/task/single_thread_executor.rb +97 -0
  100. data/lib/garcon/task/thread_pool/cached.rb +71 -0
  101. data/lib/garcon/task/thread_pool/executor.rb +294 -0
  102. data/lib/garcon/task/thread_pool/fixed.rb +61 -0
  103. data/lib/garcon/task/thread_pool/worker.rb +90 -0
  104. data/lib/garcon/task/timer.rb +44 -0
  105. data/lib/garcon/task/timer_set.rb +194 -0
  106. data/lib/garcon/task/timer_task.rb +377 -0
  107. data/lib/garcon/task/waitable_list.rb +58 -0
  108. data/lib/garcon/utility/ansi.rb +199 -0
  109. data/lib/garcon/utility/at_random.rb +77 -0
  110. data/lib/garcon/utility/crypto.rb +292 -0
  111. data/lib/garcon/utility/equalizer.rb +146 -0
  112. data/lib/garcon/utility/faker/extensions/array.rb +22 -0
  113. data/lib/garcon/utility/faker/extensions/symbol.rb +9 -0
  114. data/lib/garcon/utility/faker/faker.rb +164 -0
  115. data/lib/garcon/utility/faker/faker/company.rb +17 -0
  116. data/lib/garcon/utility/faker/faker/hacker.rb +30 -0
  117. data/lib/garcon/utility/faker/faker/version.rb +3 -0
  118. data/lib/garcon/utility/faker/locales/en-US.yml +83 -0
  119. data/lib/garcon/utility/faker/locales/en.yml +21 -0
  120. data/lib/garcon/utility/file_helper.rb +170 -0
  121. data/lib/garcon/utility/hookers.rb +178 -0
  122. data/lib/garcon/utility/interpolation.rb +90 -0
  123. data/lib/garcon/utility/memstash.rb +364 -0
  124. data/lib/garcon/utility/misc.rb +54 -0
  125. data/lib/garcon/utility/msg_from_god.rb +62 -0
  126. data/lib/garcon/utility/retry.rb +238 -0
  127. data/lib/garcon/utility/timeout.rb +58 -0
  128. data/lib/garcon/utility/uber/builder.rb +91 -0
  129. data/lib/garcon/utility/uber/callable.rb +7 -0
  130. data/lib/garcon/utility/uber/delegates.rb +13 -0
  131. data/lib/garcon/utility/uber/inheritable_attr.rb +37 -0
  132. data/lib/garcon/utility/uber/options.rb +101 -0
  133. data/lib/garcon/utility/uber/uber_version.rb +3 -0
  134. data/lib/garcon/utility/uber/version.rb +33 -0
  135. data/lib/garcon/utility/url_helper.rb +100 -0
  136. data/lib/garcon/utils.rb +29 -0
  137. data/lib/garcon/version.rb +62 -0
  138. data/lib/garcun.rb +24 -0
  139. metadata +680 -0
@@ -0,0 +1,114 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ #
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ module Garcon
21
+ module Stash
22
+ # Database format serializer and deserializer. You can create your own
23
+ # implementation of this class and define your own database format!
24
+ #
25
+ # @api public
26
+ class Format
27
+ # Read database header from input stream
28
+ #
29
+ # @param [#read] input
30
+ # the input stream
31
+ #
32
+ # @return void
33
+ #
34
+ def read_header(input)
35
+ raise 'Not a stash' if input.read(MAGIC.bytesize) != MAGIC
36
+ ver = input.read(2).unpack('n').first
37
+ raise "Expected stash version #{VERSION}, got #{ver}" if ver != VERSION
38
+ end
39
+
40
+ # Return database header as string
41
+ #
42
+ # @return [String] database file header
43
+ #
44
+ def header
45
+ MAGIC + [VERSION].pack('n')
46
+ end
47
+
48
+ # Serialize record and return string.
49
+ #
50
+ # @param [Array] rec
51
+ # an array with [key, value] or [key] if the record is deleted
52
+ #
53
+ # @return [String] serialized record
54
+ #
55
+ def dump(rec)
56
+ data = if rec.size == 1
57
+ [rec[0].bytesize, DELETE].pack('NN') << rec[0]
58
+ else
59
+ [rec[0].bytesize, rec[1].bytesize].pack('NN') << rec[0] << rec[1]
60
+ end
61
+ data << crc32(data)
62
+ end
63
+
64
+ # Deserialize records from buffer, and yield them.
65
+ #
66
+ # @param [String] buf
67
+ # the buffer to read from
68
+ #
69
+ # @yield [Array] block
70
+ # deserialized record [key, value] or [key] if the record is deleted
71
+ #
72
+ # @return [Fixnum] number of records
73
+ #
74
+ def parse(buf)
75
+ n, count = 0, 0
76
+ while n < buf.size
77
+ key_size, value_size = buf[n, 8].unpack('NN')
78
+ data_size = key_size + 8
79
+ data_size += value_size if value_size != DELETE
80
+ data = buf[n, data_size]
81
+ n += data_size
82
+ unless buf[n, 4] == crc32(data)
83
+ raise 'CRC mismatch: your stash might be corrupted!'
84
+ end
85
+ n += 4
86
+ yield(value_size == DELETE ? [data[8, key_size]] : [data[8, key_size], data[8 + key_size, value_size]])
87
+ count += 1
88
+ end
89
+ count
90
+ end
91
+
92
+ protected # A T T E N Z I O N E A R E A P R O T E T T A
93
+
94
+ # Magic string of the file header.
95
+ MAGIC = 'ABRACADABRA'
96
+
97
+ # Database file format version (it is a hash after all).
98
+ VERSION = 420
99
+
100
+ # Special value size used for deleted records
101
+ DELETE = (1 << 32) - 1
102
+
103
+ # Compute crc32 of string
104
+ #
105
+ # @param [String] s a string
106
+ #
107
+ # @return [Fixnum]
108
+ #
109
+ def crc32(s)
110
+ [Zlib.crc32(s, 0)].pack('N')
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,226 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ #
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ module Garcon
21
+ module Stash
22
+ # Stash::Io handles background io, compaction and is the arbiter
23
+ # of multiprocess safety.
24
+ #
25
+ # @api private
26
+ class Journal < Queue
27
+ attr_reader :size, :file
28
+
29
+ def initialize(file, format, serializer, &block)
30
+ super()
31
+ @file, @format, @serializer, @emit = file, format, serializer, block
32
+ open
33
+ @worker = Thread.new(&method(:worker))
34
+ @worker.priority = -1
35
+ load
36
+ end
37
+
38
+ # Is the journal closed?
39
+ #
40
+ def closed?
41
+ @fd.closed?
42
+ end
43
+
44
+ # Clear the queue and close the file handler
45
+ #
46
+ def close
47
+ self << nil
48
+ @worker.join
49
+ @fd.close
50
+ super
51
+ end
52
+
53
+ # Load new journal entries
54
+ #
55
+ def load
56
+ flush
57
+ replay
58
+ end
59
+
60
+ # Lock the logfile across thread and process boundaries
61
+ #
62
+ def lock
63
+ flush
64
+ with_flock(File::LOCK_EX) do
65
+ replay
66
+ result = yield
67
+ flush
68
+ result
69
+ end
70
+ end
71
+
72
+ # Clear the database log and yield
73
+ #
74
+ def clear
75
+ flush
76
+ with_tmpfile do |path, file|
77
+ file.write(@format.header)
78
+ file.close
79
+ with_flock(File::LOCK_EX) do
80
+ File.rename(path, @file)
81
+ end
82
+ end
83
+ open
84
+ end
85
+
86
+ # Compact the logfile to represent the in-memory state
87
+ #
88
+ def compact
89
+ load
90
+ with_tmpfile do |path, file|
91
+ # Compactified database has the same size -> return
92
+ return self if @pos == file.write(dump(yield, @format.header))
93
+ with_flock(File::LOCK_EX) do
94
+ if @pos != nil
95
+ file.write(read)
96
+ file.close
97
+ File.rename(path, @file)
98
+ end
99
+ end
100
+ end
101
+ open
102
+ replay
103
+ end
104
+
105
+ # Return byte size of journal
106
+ #
107
+ def bytesize
108
+ @fd.stat.size
109
+ end
110
+
111
+ private # P R O P R I E T À P R I V A T A Vietato L'accesso
112
+
113
+ # Emit records as we parse them
114
+ def replay
115
+ buf = read
116
+ @size += @format.parse(buf, &@emit)
117
+ end
118
+
119
+ # Open or reopen file
120
+ #
121
+ def open
122
+ @fd.close if @fd
123
+ @fd = File.open(@file, 'ab+')
124
+ @fd.advise(:sequential) if @fd.respond_to? :advise
125
+ stat = @fd.stat
126
+ @inode = stat.ino
127
+ write(@format.header) if stat.size == 0
128
+ @pos = nil
129
+ end
130
+
131
+ # Read new file content
132
+ #
133
+ def read
134
+ with_flock(File::LOCK_SH) do
135
+ unless @pos
136
+ @fd.pos = 0
137
+ @format.read_header(@fd)
138
+ @size = 0
139
+ @emit.call(nil)
140
+ else
141
+ @fd.pos = @pos
142
+ end
143
+ buf = @fd.read
144
+ @pos = @fd.pos
145
+ buf
146
+ end
147
+ end
148
+
149
+ # Return database dump as string
150
+ #
151
+ def dump(records, dump = '')
152
+ records.each do |record|
153
+ record[1] = @serializer.dump(record.last)
154
+ dump << @format.dump(record)
155
+ end
156
+ dump
157
+ end
158
+
159
+ # Worker thread
160
+ #
161
+ def worker
162
+ while (record = first)
163
+ tries = 0
164
+ begin
165
+ if Hash === record
166
+ write(dump(record))
167
+ @size += record.size
168
+ else
169
+ record[1] = @serializer.dump(record.last) if record.size > 1
170
+ write(@format.dump(record))
171
+ @size += 1
172
+ end
173
+ rescue Exception => e
174
+ tries += 1
175
+ warn "Stash worker, try #{tries}: #{e.message}"
176
+ tries <= 3 ? retry : raise
177
+ ensure
178
+ pop
179
+ end
180
+ end
181
+ rescue Exception => e
182
+ warn "Stash worker terminated: #{e.message}"
183
+ end
184
+
185
+ # Write data to output stream and advance @pos
186
+ #
187
+ def write(dump)
188
+ with_flock(File::LOCK_EX) do
189
+ @fd.write(dump)
190
+ @fd.flush
191
+ end
192
+ @pos = @fd.pos if @pos && @fd.pos == @pos + dump.bytesize
193
+ end
194
+
195
+ # Block with file lock
196
+ #
197
+ def with_flock(mode)
198
+ return yield if @locked
199
+ begin
200
+ loop do
201
+ Thread.pass until @fd.flock(mode)
202
+ stat = @fd.stat
203
+ break if stat.nlink > 0 && stat.ino == @inode
204
+ open
205
+ end
206
+ @locked = true
207
+ yield
208
+ ensure
209
+ @fd.flock(File::LOCK_UN)
210
+ @locked = false
211
+ end
212
+ end
213
+
214
+ # Open temporary file and pass it to the block
215
+ #
216
+ def with_tmpfile
217
+ path = [@file, $$.to_s(36), Thread.current.object_id.to_s(36)].join
218
+ file = File.open(path, 'wb')
219
+ yield(path, file)
220
+ ensure
221
+ file.close unless file.closed?
222
+ File.unlink(path) if File.exists?(path)
223
+ end
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,83 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ #
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ module Garcon
21
+ module Stash
22
+ class Queue
23
+ def initialize
24
+ @queue, @full, @empty = [], [], []
25
+ @stop = false
26
+ @heartbeat = Thread.new(&method(:heartbeat))
27
+ @heartbeat.priority = -9
28
+ end
29
+
30
+ def <<(x)
31
+ @queue << x
32
+ thread = @full.first
33
+ thread.wakeup if thread
34
+ end
35
+
36
+ def pop
37
+ @queue.shift
38
+ if @queue.empty?
39
+ thread = @empty.first
40
+ thread.wakeup if thread
41
+ end
42
+ end
43
+
44
+ def first
45
+ while @queue.empty?
46
+ begin
47
+ @full << Thread.current
48
+ Thread.stop while @queue.empty?
49
+ ensure
50
+ @full.delete(Thread.current)
51
+ end
52
+ end
53
+ @queue.first
54
+ end
55
+
56
+ def flush
57
+ until @queue.empty?
58
+ begin
59
+ @empty << Thread.current
60
+ Thread.stop until @queue.empty?
61
+ ensure
62
+ @empty.delete(Thread.current)
63
+ end
64
+ end
65
+ end
66
+
67
+ def close
68
+ @stop = true
69
+ @heartbeat.join
70
+ end
71
+
72
+ private # P R O P R I E T À P R I V A T A Vietato L'accesso
73
+
74
+ def heartbeat
75
+ until @stop
76
+ @empty.each(&:wakeup)
77
+ @full.each(&:wakeup)
78
+ sleep 0.1
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ #
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ module Garcon
21
+ module Stash
22
+ module Serializer
23
+ # Serializer which only encodes key in binary
24
+ #
25
+ # @api public
26
+ class None
27
+ # (see Stash::Serializer::Default#key_for)
28
+ if ''.respond_to? :force_encoding
29
+ def key_for(key)
30
+ if key.encoding != Encoding::BINARY
31
+ key = key.dup if key.frozen?
32
+ key.force_encoding(Encoding::BINARY)
33
+ end
34
+ key
35
+ end
36
+ else
37
+ def key_for(key)
38
+ key
39
+ end
40
+ end
41
+
42
+ # (see Stash::Serializer::Default#dump)
43
+ def dump(value)
44
+ value
45
+ end
46
+
47
+ # (see Stash::Serializer::Default#load)
48
+ def load(value)
49
+ value
50
+ end
51
+ end
52
+
53
+ # Default serializer which converts keys to strings and marshalls values.
54
+ #
55
+ # @api public
56
+ class Default < None
57
+ # Transform the key to a string.
58
+ #
59
+ # @param [Object] key
60
+ # @return [String]
61
+ # The key transformed to string.
62
+ def key_for(key)
63
+ super(key.to_s)
64
+ end
65
+
66
+ # Serialize a value.
67
+ #
68
+ # @param [Object] value
69
+ # @return [String]
70
+ # The value transformed to string.
71
+ def dump(value)
72
+ Marshal.dump(value)
73
+ end
74
+
75
+ # Parse a value.
76
+ #
77
+ # @param [String] value
78
+ # @return [Object]
79
+ # The deserialized value.
80
+ def load(value)
81
+ Marshal.load(value)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end