tikh-klarlack 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Max Schöfmann
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,43 @@
1
+ = klarlack
2
+
3
+ Klarlack is a ruby client library for the varnish administration interface.
4
+
5
+ See also: http://www.varnish-cache.org
6
+
7
+ Please note: You need at least version 2.0.3 of varnish for purging to work.
8
+
9
+ === Installation (from gemcutter.org)
10
+
11
+ sudo gem install klarlack
12
+
13
+ === Example
14
+
15
+ Lets purge all blog posts from the cache...
16
+
17
+ require 'rubygems'
18
+ require 'klarlack'
19
+
20
+ varnish = Varnish::Client.new '127.0.0.1:6082'
21
+ # the regexp is not a ruby regexp, just a plain string varnishd understands
22
+ varnish.purge :url, "^/posts/.*"
23
+
24
+ In a Rails app, you might want to use use this in a cache sweeper.
25
+
26
+ === Specs
27
+
28
+ Start up a local varnishd with <tt>-T 127.0.0.1:6082</tt>. Then run
29
+
30
+ spec spec
31
+
32
+ === TODO
33
+
34
+ * Support authentication when varnishd is started with <tt>-S</tt>
35
+ * Make parameter manipulation/display more friendly
36
+
37
+ === WTF?
38
+
39
+ http://dict.leo.org/?search=klarlack
40
+
41
+ === Copyright
42
+
43
+ Copyright (c) 2009-2010 Max Schöfmann. Distributed under the MIT-License
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "klarlack"
8
+ gem.summary = %Q{ruby client for varnishd's admin interface}
9
+ gem.email = "max@pragmatic-it.de"
10
+ gem.homepage = "http://github.com/schoefmax/klarlack"
11
+ gem.authors = ["Max Schöfmann"]
12
+
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+ rescue LoadError
16
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
17
+ end
18
+
19
+ require 'spec/rake/spectask'
20
+ Spec::Rake::SpecTask.new(:spec) do |spec|
21
+ spec.libs << 'lib' << 'spec'
22
+ spec.spec_files = FileList['spec/**/*_spec.rb']
23
+ end
24
+
25
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.pattern = 'spec/**/*_spec.rb'
28
+ spec.rcov = true
29
+ end
30
+
31
+
32
+ task :default => :spec
33
+
34
+ require 'rake/rdoctask'
35
+ Rake::RDocTask.new do |rdoc|
36
+ if File.exist?('VERSION.yml')
37
+ config = YAML.load(File.read('VERSION.yml'))
38
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
39
+ else
40
+ version = ""
41
+ end
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "klarlack #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
48
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 0
3
+ :patch: 6
4
+ :major: 0
data/lib/klarlack.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'socket'
2
+ require 'varnish/socket_factory'
3
+ require 'varnish/client'
4
+
5
+ module Varnish
6
+ VERSION = '0.0.6'
7
+ end
@@ -0,0 +1,302 @@
1
+ module Varnish
2
+ class Error < StandardError; end
3
+ class BrokenConnection < Error; end
4
+ class CommandFailed < Error; end
5
+ class Client
6
+ # Default management port of varnishd
7
+ DEFAULT_PORT = 6082
8
+
9
+ # We assume varnishd on localhost
10
+ DEFAULT_HOST = 'localhost'
11
+
12
+ DEFAULT_OPTS = {
13
+ :keep_alive => false,
14
+ :timeout => 1,
15
+ :secret_file => nil
16
+ }
17
+
18
+ # timeout in seconds when connecting to varnishd. Default is 1
19
+ attr_accessor :timeout
20
+
21
+ # set to true, to keep the connection alive. Default is false
22
+ attr_accessor :keep_alive
23
+
24
+ # the authentication secret file if needed. Default is nil
25
+ attr_accessor :secret_file
26
+
27
+ # hostname or IP-address of varnishd. Default is "localhost"
28
+ attr_accessor :host
29
+
30
+ # port number of varnishd. Default is 6082
31
+ attr_accessor :port
32
+
33
+ # Examples:
34
+ #
35
+ # Varnish::Client.new "127.0.0.1"
36
+ # Varnish::Client.new "mydomain.com:6082"
37
+ # Varnish::Client.new :timeout => 5
38
+ # Varnish::Client.new "10.0.0.3:6060", :timeout => nil, :keep_alive => true
39
+ #
40
+ # === Configuration options
41
+ #
42
+ # +timeout+:: if specified (seconds), calls to varnish
43
+ # will be wrapped in a timeout, default is 1 second.
44
+ # Disable with <tt>:timeout => nil</tt>
45
+ # +keep_alive+:: if true, the connection is kept alive by sending
46
+ # ping commands to varnishd every few seconds
47
+ # +secret_file+:: specifies the authentication secret file
48
+ def initialize(*args)
49
+ opts = {}
50
+
51
+ case args.length
52
+ when 0
53
+ self.server = DEFAULT_HOST
54
+ when 1
55
+ arg = args[0]
56
+ case arg
57
+ when String
58
+ self.server = arg
59
+ when Hash
60
+ self.server = DEFAULT_HOST
61
+ opts = arg
62
+ end
63
+ when 2
64
+ self.server = args[0]
65
+ opts = args[1]
66
+ else
67
+ raise ArgumentError, "wrong number of arguments (#{args.length} for 2)"
68
+ end
69
+
70
+ opts = DEFAULT_OPTS.merge(opts)
71
+ @timeout = opts[:timeout]
72
+ @keep_alive = opts[:keep_alive]
73
+ @secret_file = opts[:secret_file]
74
+
75
+ @mutex = Mutex.new
76
+ end
77
+
78
+ # Set the varnishd management host and port.
79
+ # Expects a string as "hostname" or "hostname:port"
80
+ def server=(server)
81
+ @host, @port = server.split(':')
82
+ @port = (@port || DEFAULT_PORT).to_i
83
+ server
84
+ end
85
+
86
+ # Returns the varnishd management host and port as "hostname:port"
87
+ def server
88
+ "#{@host}:#{@port}"
89
+ end
90
+
91
+ # Manipulate the VCL configuration
92
+ #
93
+ # .vcl :load, <configname>, <filename>
94
+ # .vcl :inline, <configname>, <quoted_VCLstring>
95
+ # .vcl :use, <configname>
96
+ # .vcl :discard, <configname>
97
+ # .vcl :list
98
+ # .vcl :show, <configname>
99
+ #
100
+ # Returns an array of VCL configurations for :list, and the servers
101
+ # response as string otherwise
102
+ #
103
+ # Ex.:
104
+ # v = Varnish::Client.new
105
+ # v.vcl :list
106
+ # #=> [["active", 0, "boot"]]
107
+ #
108
+ # v.vcl :load, "newconf", "/etc/varnish/myconf.vcl"
109
+ #
110
+ #
111
+ def vcl(op, *params)
112
+ response = cmd("vcl.#{op}", *params)
113
+ case op
114
+ when :list
115
+ response.split("\n").map do |line|
116
+ a = line.split(/\s+/, 3)
117
+ [a[0], a[1].to_i, a[2]]
118
+ end
119
+ else
120
+ response
121
+ end
122
+ end
123
+
124
+ # Purge objects from the cache or show the purge queue.
125
+ #
126
+ # Takes one or two arguments:
127
+ #
128
+ # 1.
129
+ # .purge :url, <regexp>
130
+ # .purge :hash, <regexp>
131
+ #
132
+ # <regexp> is a string containing a varnish compatible regexp
133
+ #
134
+ # 2.
135
+ # .purge <costum-purge-conditions>
136
+ # .purge :list
137
+ #
138
+ # Returns true for purging, returns an array containing the purge queue
139
+ # for :list
140
+ #
141
+ # Ex.:
142
+ # v = Varnish::Client.new
143
+ # v.purge :url, '.*'
144
+ #
145
+ # v.purge "req.http.host ~ www.foo.com && req.http.url ~ images"
146
+ #
147
+ # v.purge :list
148
+ # #=> [[1, "req.url ~ .*"]]
149
+ #
150
+ def purge(*args)
151
+ c = 'purge'
152
+ c << ".#{args.shift}" if [:url, :hash, :list].include?(args.first)
153
+ response = cmd(c, *args)
154
+ case c
155
+ when 'purge.list'
156
+ response.split("\n").map do |line|
157
+ a = line.split("\t")
158
+ [a[0].to_i, a[1]]
159
+ end
160
+ else
161
+ bool response
162
+ end
163
+ end
164
+
165
+ # Ping the server to keep the connection alive
166
+ def ping(timestamp = nil)
167
+ cmd("ping", timestamp)
168
+ end
169
+
170
+ # Returns a hash of status information
171
+ #
172
+ # Ex.:
173
+ # v = Varnish::Client.new
174
+ # v.stats
175
+ # => {"Total header bytes"=>0, "Cache misses"=>0 ...}
176
+ def stats
177
+ result = cmd("stats")
178
+ Hash[*result.split("\n").map { |line|
179
+ stat = line.strip!.split(/\s+/, 2)
180
+ [stat[1], stat[0].to_i]
181
+ }.flatten
182
+ ]
183
+ end
184
+
185
+ # Set and show parameters
186
+ #
187
+ # .param :show, [-l], [<param>]
188
+ # .param :set, <param>, <value>
189
+ def param(op, *args)
190
+ cmd("param.#{op}", *args)
191
+ end
192
+
193
+ # Returns the status string from varnish.
194
+ # See also #running? and #stopped?
195
+ def status
196
+ cmd("status")
197
+ end
198
+
199
+ def start
200
+ bool cmd("start")
201
+ end
202
+
203
+ def stop
204
+ bool cmd("stop")
205
+ end
206
+
207
+ def running?
208
+ bool status =~ /running/
209
+ end
210
+
211
+ def stopped?
212
+ bool status =~ /stopped/
213
+ end
214
+
215
+ # close the connection to varnishd.
216
+ # Note that the connection will automatically be re-established
217
+ # when another command is issued.
218
+ def disconnect
219
+ if connected?
220
+ @conn.write "quit\n"
221
+ @conn.gets
222
+ @conn.close unless @conn.closed?
223
+ end
224
+ end
225
+
226
+ def connected?
227
+ bool @conn && !@conn.closed?
228
+ end
229
+
230
+ private
231
+
232
+ # Sends a command to varnishd.
233
+ # Raises a Varnish::CommandFailed error when a non-200 status is returned
234
+ # Returns the response text
235
+ def cmd(name, *params)
236
+ @mutex.synchronize do
237
+ connect unless connected?
238
+ @conn.write "#{name} #{params.join(' ').gsub('\\', '\\\\\\')}\n"
239
+ status, length = conn_gets.split # <status> <content_length>\n
240
+ content = conn_read(length.to_i + 1) # +1 = \n
241
+ content.chomp!
242
+ raise CommandFailed, "Command #{name} returned with status #{status}: #{content}" if status.to_i != 200
243
+ content
244
+ end
245
+ end
246
+
247
+ def get_challenge_or_banner
248
+ status, length = conn_gets.split # <status> <content_length>\n
249
+ content = conn_read(length.to_i + 1) # +1 = \n
250
+ if status.to_i == 107
251
+ @conn.write "auth #{auth_response(content[0,32])}\n"
252
+ end
253
+ end
254
+
255
+ def connect
256
+ @conn = SocketFactory.tcp_socket(@host, @port, @timeout)
257
+ get_challenge_or_banner
258
+
259
+ # If keep alive, we ping the server every few seconds.
260
+ if @keep_alive
261
+ varnish = self
262
+ Thread.new do
263
+ while(true) do
264
+ if varnish.connected?
265
+ varnish.ping
266
+ sleep 5
267
+ else
268
+ break
269
+ end
270
+ end
271
+ end
272
+ end
273
+
274
+ @conn
275
+ end
276
+
277
+ def conn_gets
278
+ @conn.gets || raise(BrokenConnection, "Expected to read one line from Varnish, got nil")
279
+ end
280
+
281
+ def conn_read(bytes)
282
+ @conn.read(bytes) || raise(BrokenConnection, "Expected to read #{bytes} bytes from Varnish, got nil")
283
+ end
284
+
285
+ def auth_response(challenge)
286
+ ctx = Digest::SHA2.new
287
+ ctx << challenge
288
+ ctx << "\n"
289
+ ctx << File.read(secret_file)
290
+ ctx << challenge
291
+ ctx << "\n"
292
+ puts "#{ctx.to_s}"
293
+ ctx.to_s
294
+ end
295
+
296
+ # converts +value+ into a boolean
297
+ def bool(value)
298
+ !!value
299
+ end
300
+
301
+ end
302
+ end
@@ -0,0 +1,57 @@
1
+ module Varnish
2
+ # Wrapper around Ruby's Socket.
3
+ #
4
+ # Uses Mike Perhams superior (in both reliability and
5
+ # performance) connection technique with proper timeouts:
6
+ # See: http://github.com/mperham/memcache-client
7
+ class SocketFactory
8
+
9
+ begin
10
+ # Try to use the SystemTimer gem instead of Ruby's timeout library
11
+ # when running on something that looks like Ruby 1.8.x. See:
12
+ # http://ph7spot.com/articles/system_timer
13
+ # We don't want to bother trying to load SystemTimer on jruby and
14
+ # ruby 1.9+.
15
+ if RUBY_VERSION =~ /^1\.8\./ and RUBY_PLATFORM !~ /java/
16
+ require 'system_timer'
17
+ Timer = SystemTimer
18
+ else
19
+ require 'timeout'
20
+ Timer = Timeout
21
+ end
22
+ rescue LoadError => e
23
+ $stderr.puts "[klarlack] Could not load SystemTimer gem, falling back to Ruby's slower/unsafe timeout library: #{e.message}"
24
+ require 'timeout'
25
+ Timer = Timeout
26
+ end
27
+
28
+ def self.tcp_socket(host, port, timeout = nil)
29
+ addr = Socket.getaddrinfo(host, nil)
30
+ sock = Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0)
31
+
32
+ if timeout
33
+ secs = Integer(timeout)
34
+ usecs = Integer((timeout - secs) * 1_000_000)
35
+ optval = [secs, usecs].pack("l_2")
36
+ sock.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
37
+ sock.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
38
+
39
+ # Socket timeouts don't work for more complex IO operations
40
+ # like gets which lay on top of read. We need to fall back to
41
+ # the standard Timeout mechanism.
42
+ sock.instance_eval <<-EOR
43
+ alias :blocking_gets :gets
44
+ def gets
45
+ Timer.timeout(#{timeout}) do
46
+ self.blocking_gets
47
+ end
48
+ end
49
+ EOR
50
+ end
51
+ sock.connect(Socket.pack_sockaddr_in(port, addr[0][3]))
52
+ sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
53
+ sock
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,198 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Varnish::Client do
4
+
5
+ before(:each) do
6
+ @varnish = Varnish::Client.new "127.0.0.1:6082"
7
+ end
8
+
9
+ describe '(connection handling)' do
10
+
11
+ it 'should not be connected on object instantiation' do
12
+ @varnish.connected?.should be_false
13
+ end
14
+
15
+ it 'should not raise an error when trying to disconnect a non-connected client' do
16
+ lambda { @varnish.disconnect }.should_not raise_error
17
+ end
18
+
19
+ it 'should automatically connect when a command is issued' do
20
+ @varnish.ping
21
+ @varnish.connected?.should be_true
22
+ end
23
+
24
+ it 'should use timeouts when sending commands' do
25
+ Varnish::SocketFactory::Timer.should_receive(:timeout).and_return("200 0")
26
+ @varnish.timeout = 10
27
+ @varnish.ping
28
+ end
29
+
30
+ it 'should be possible to disable timeouts' do
31
+ Varnish::SocketFactory::Timer.should_not_receive(:timeout)
32
+ @varnish.timeout = nil
33
+ @varnish.ping
34
+ end
35
+
36
+ it '#disconnect should close the connection' do
37
+ @varnish.ping
38
+ @varnish.connected?.should be_true
39
+ @varnish.disconnect
40
+ @varnish.connected?.should be_false
41
+ end
42
+
43
+ it 'given keep_alive is set, the connection should be kept alive with pings' do
44
+ @varnish.keep_alive = true
45
+ @varnish.should_receive :ping
46
+ @varnish.send :connect
47
+ end
48
+
49
+ it 'given keep_alive is not set, no pings should be sent to varnishd' do
50
+ @varnish.keep_alive = false
51
+ @varnish.should_not_receive :ping
52
+ @varnish.send :connect
53
+ end
54
+
55
+ it '#server should return the host and port for the connection' do
56
+ @varnish.host = "foohost"
57
+ @varnish.port = 1234
58
+ @varnish.server.should == "foohost:1234"
59
+ end
60
+
61
+ it '#server= should set the host and port for the connection' do
62
+ @varnish.server = "blahost:9876"
63
+ @varnish.host.should == "blahost"
64
+ @varnish.port.should == 9876
65
+ end
66
+
67
+ end
68
+
69
+ describe '(commands)' do
70
+
71
+ before(:each) do
72
+ ensure_started
73
+ end
74
+
75
+ # ... the specs for #param, #purge and #vcl could be better ...
76
+
77
+ it '#param should send the param command to varnishd' do
78
+ @varnish.param(:show).should_not be_empty
79
+ end
80
+
81
+ it '#purge should allow purging by url, hash and custom fields' do
82
+ @varnish.purge(:url, '^/articles/.*').should be_true
83
+ @varnish.purge(:hash, 12345).should be_true
84
+ @varnish.purge("req.http.host", "~", "www.example.com").should be_true
85
+ @varnish.purge("req.http.host ~ www.example.com").should be_true
86
+ end
87
+
88
+ it '#purge with :list should return an array with queued purges' do
89
+ @varnish.purge(:url, '^/posts/.*')
90
+ list = @varnish.purge(:list)
91
+ list.last[0].should be_kind_of(Integer)
92
+ list.last[1].should == "req.url ~ ^/posts/.*"
93
+ end
94
+
95
+ it '#vcl with :list should return an array of VCL configurations' do
96
+ list = @varnish.vcl(:list)
97
+ list.should_not be_empty
98
+ list.should be_kind_of(Array)
99
+ list.first[0].should be_kind_of(String)
100
+ list.first[1].should be_kind_of(Integer)
101
+ list.first[2].should be_kind_of(String)
102
+ end
103
+
104
+ it '#ping should send a ping to the server and return a string containing the response' do
105
+ @varnish.ping.should =~ /^PONG \d+/
106
+ end
107
+
108
+
109
+ it '#status should return a string explaining the daemons status' do
110
+ @varnish.status.should =~ /running|stopped|stopping|starting/
111
+ end
112
+
113
+ it "#stats should return a hash containing status information" do
114
+ stats = @varnish.stats
115
+ stats.should_not be_empty
116
+ stats.values.each {|v| v.should be_kind_of(Integer) }
117
+ stats.keys.each {|k| k.should_not be_empty }
118
+ end
119
+
120
+ end
121
+
122
+ describe '(regression)' do
123
+
124
+ it '#purge.hash with regex containing backslashes should be escaped properly' do
125
+ test_regex = '/home\?x=1'
126
+ @varnish.purge :hash, test_regex
127
+ list = @varnish.purge :list
128
+ list.flatten.join.should include(test_regex)
129
+ end
130
+
131
+ end
132
+
133
+ describe '(broken connection)' do
134
+
135
+ before(:each) do
136
+ fake_connection!(:connected => true, :return => "200 1\n")
137
+ end
138
+
139
+ it 'should fail with a Varnish::Error when the connection does return nil for gets' do
140
+ @conn.stub!(:gets).and_return(nil)
141
+ lambda { @varnish.ping }.should raise_error(Varnish::BrokenConnection)
142
+ end
143
+
144
+ it 'should fail with a Varnish::Error when the connection does return nil for read' do
145
+ @conn.stub!(:read).and_return(nil)
146
+ lambda { @varnish.ping }.should raise_error(Varnish::BrokenConnection)
147
+ end
148
+
149
+ end
150
+
151
+ describe '(daemon lifecycle)' do
152
+
153
+ it '#start, #stop, #running?, #stopped? should bahave as advertised' do
154
+ ensure_stopped # issues #stop
155
+ @varnish.stopped?.should be_true
156
+ @varnish.running?.should be_false
157
+ ensure_started # issues #start
158
+ @varnish.stopped?.should be_false
159
+ @varnish.running?.should be_true
160
+ end
161
+
162
+ it 'starting an already started daemon should raise an error' do
163
+ ensure_started
164
+ lambda { @varnish.start }.should raise_error(Varnish::CommandFailed)
165
+ end
166
+
167
+ it 'stopping an already stopped daemon should raise an error' do
168
+ ensure_stopped
169
+ lambda { @varnish.stop }.should raise_error(Varnish::CommandFailed)
170
+ end
171
+
172
+ end
173
+
174
+ def ensure_started
175
+ @varnish.start if @varnish.stopped?
176
+ while(!@varnish.running?) do sleep 0.1 end
177
+ end
178
+
179
+ def ensure_stopped
180
+ @varnish.stop if @varnish.running?
181
+ while(!@varnish.stopped?) do sleep 0.1 end
182
+ end
183
+
184
+ class FakeConn
185
+ attr_accessor :retval
186
+ def read(*args) @retval end
187
+ def gets(*args) @retval end
188
+ def write(str) str.to_s.size end
189
+ end
190
+
191
+ def fake_connection!(opts = {})
192
+ @conn = FakeConn.new
193
+ @conn.retval = opts[:return] || ''
194
+ @varnish.stub!(:connected?).and_return(opts[:connected] || false)
195
+ @varnish.instance_variable_set('@conn', @conn)
196
+ end
197
+
198
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec'
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require 'klarlack'
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tikh-klarlack
3
+ version: !ruby/object:Gem::Version
4
+ hash: 17
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 7
10
+ version: 0.0.7
11
+ platform: ruby
12
+ authors:
13
+ - "Max Sch\xC3\xB6fmann"
14
+ - Konstantin Tikhonov
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-04-07 00:00:00 +04:00
20
+ default_executable:
21
+ dependencies: []
22
+
23
+ description:
24
+ email: max@pragmatic-it.de
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files:
30
+ - LICENSE
31
+ - README.rdoc
32
+ files:
33
+ - LICENSE
34
+ - README.rdoc
35
+ - Rakefile
36
+ - VERSION.yml
37
+ - lib/klarlack.rb
38
+ - lib/varnish/client.rb
39
+ - lib/varnish/socket_factory.rb
40
+ - spec/klarlack_spec.rb
41
+ - spec/spec_helper.rb
42
+ has_rdoc: true
43
+ homepage: http://github.com/schoefmax/klarlack
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --charset=UTF-8
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.7
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: ruby client for varnishd's admin interface
76
+ test_files:
77
+ - spec/klarlack_spec.rb
78
+ - spec/spec_helper.rb