desi 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/Guardfile +6 -0
- data/README.md +55 -7
- data/desi.gemspec +3 -0
- data/lib/desi/downloader.rb +1 -1
- data/lib/desi/http_client.rb +0 -2
- data/lib/desi/index_manager.rb +19 -14
- data/lib/desi/process_manager.rb +2 -2
- data/lib/desi/upstream.rb +3 -2
- data/lib/desi/version.rb +1 -1
- data/spec/desi/index_manager_spec.rb +134 -0
- data/spec/spec_helper.rb +11 -0
- metadata +61 -2
data/.rspec
ADDED
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -13,7 +13,7 @@ It can:
|
|
13
13
|
It can be used both as a command-line tool and as a library.
|
14
14
|
|
15
15
|
|
16
|
-
## Usage
|
16
|
+
## Usage (command-line)
|
17
17
|
|
18
18
|
$ desi list # List locally installed ElasticSearch releases
|
19
19
|
$ desi releases # List all upstream Elastic Search releases (latest 5 by default)
|
@@ -25,14 +25,14 @@ It can be used both as a command-line tool and as a library.
|
|
25
25
|
|
26
26
|
$ desi indices "^foo" # List all indices whose name match /^foo/
|
27
27
|
$ desi indices "^foo" --delete # Delete all matching indices
|
28
|
-
$ desi indices "bar$" --empty # Remove all records from the matching
|
29
|
-
# indices
|
28
|
+
$ desi indices "bar$" --empty # Remove all records from the matching indices
|
30
29
|
|
31
|
-
## Examples
|
30
|
+
## Examples (command-line and Ruby)
|
32
31
|
|
33
|
-
###
|
32
|
+
### Get the list of locally installed releases
|
34
33
|
|
35
|
-
The current version is the one symlinked to `$HOME/elasticsearch/current
|
34
|
+
The current version is the one symlinked to `$HOME/elasticsearch/current`, that
|
35
|
+
will be spun up by (`desi start`)
|
36
36
|
|
37
37
|
* command-line
|
38
38
|
|
@@ -52,6 +52,54 @@ The current version is the one symlinked to `$HOME/elasticsearch/current`
|
|
52
52
|
```
|
53
53
|
|
54
54
|
|
55
|
+
### List and delete some indices
|
56
|
+
|
57
|
+
* command-line
|
58
|
+
|
59
|
+
```shell
|
60
|
+
$ # List all local indices
|
61
|
+
$ desi indices
|
62
|
+
Indices from host http://127.0.0.1:9200 matching the pattern /.*/
|
63
|
+
|
64
|
+
foo
|
65
|
+
bar
|
66
|
+
baz
|
67
|
+
|
68
|
+
$ # List all indices on remote cluster 129.168.1.42, reachable on port 9800
|
69
|
+
$ desi indices --host 129.168.1.42:9800 foo
|
70
|
+
Indices from host http://192.168.1.42:9800 matching the pattern /foo/
|
71
|
+
|
72
|
+
remotefoo1
|
73
|
+
remotefoo2
|
74
|
+
|
75
|
+
$ # Remove all indices whose name starts with "ba"
|
76
|
+
$ desi indices --delete "^ba"
|
77
|
+
The following indices from host http://127.0.0.1:9200 are now deleted
|
78
|
+
* bar
|
79
|
+
* baz
|
80
|
+
```
|
81
|
+
|
82
|
+
|
83
|
+
* library
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
# All local indices
|
87
|
+
Desi::IndexManager.new.list #=> ["foo", "bar", "baz"]
|
88
|
+
|
89
|
+
# All local indices whose name starts with `b`
|
90
|
+
Desi::IndexManager.new.list("^b") #=> ["bar", "baz"]
|
91
|
+
|
92
|
+
# All indices from distant cluster
|
93
|
+
Desi::IndexManager.new(host: "192.168.1.42:9800").list #=> ["remotefoo1", "remotefoo2"]
|
94
|
+
|
95
|
+
# Delete all local indices whose name starts with `ba`
|
96
|
+
Desi::IndexManager.new.delete!("^ba") #=> nil
|
97
|
+
|
98
|
+
# The indices actually disappeared
|
99
|
+
Desi::IndexManager.new.list #=> ["foo"]
|
100
|
+
```
|
101
|
+
|
102
|
+
|
55
103
|
|
56
104
|
## Installation
|
57
105
|
|
@@ -69,7 +117,7 @@ Or install it yourself as:
|
|
69
117
|
|
70
118
|
## TODO
|
71
119
|
|
72
|
-
* add tests
|
120
|
+
* add more tests
|
73
121
|
|
74
122
|
* `desi upgrade` (Upgrade to latest version and migrate data)
|
75
123
|
* `desi switch VERSION` (Switch currently active ES version to VERSION)
|
data/desi.gemspec
CHANGED
@@ -15,6 +15,9 @@ an Elastic Search local install for development purposes.}
|
|
15
15
|
gem.add_dependency "cocaine"
|
16
16
|
gem.add_dependency "addressable"
|
17
17
|
|
18
|
+
gem.add_development_dependency "rake"
|
19
|
+
gem.add_development_dependency "rspec"
|
20
|
+
gem.add_development_dependency "guard-rspec"
|
18
21
|
gem.add_development_dependency "guard-yard"
|
19
22
|
gem.add_development_dependency "redcarpet"
|
20
23
|
gem.add_development_dependency "rb-inotify"
|
data/lib/desi/downloader.rb
CHANGED
@@ -11,7 +11,7 @@ module Desi
|
|
11
11
|
def initialize(opts = {})
|
12
12
|
@destination_dir = Pathname(opts.fetch(:destination_dir, Desi::LocalInstall.new))
|
13
13
|
@host = URI(opts.fetch(:host, 'http://cloud.github.com/'))
|
14
|
-
@client = Desi::HttpClient.new(@host)
|
14
|
+
@client = opts.fetch(:http_client_factory, Desi::HttpClient).new(@host)
|
15
15
|
@verbose = opts[:verbose]
|
16
16
|
end
|
17
17
|
|
data/lib/desi/http_client.rb
CHANGED
data/lib/desi/index_manager.rb
CHANGED
@@ -10,19 +10,24 @@ module Desi
|
|
10
10
|
|
11
11
|
# Initializes a Desi::IndexManager instance
|
12
12
|
#
|
13
|
-
# @param [#to_hash] opts
|
14
|
-
# @option opts [#to_s] :host Host to manage indices for
|
15
|
-
# (default: 'http://127.0.0.1:9200')
|
16
|
-
# @option opts [Boolean] :verbose Whether to output the actions' result
|
17
|
-
# on STDOUT
|
13
|
+
# @param [#to_hash] opts Hash of extra opts
|
18
14
|
#
|
15
|
+
# @option opts [#to_s] :host ('http://127.0.0.1:9200') Host to manage indices for
|
16
|
+
# @option opts [Boolean] :verbose (nil) Whether to output the actions' result
|
17
|
+
# on STDOUT
|
18
|
+
# @option opts [#new] :http_client_factory (Desi::HttpClient) HTTP transport class
|
19
|
+
# to use
|
20
|
+
#
|
21
|
+
# @note The +:http_client_factory+ should return an instance that responds
|
22
|
+
# to #get and #delete
|
19
23
|
# @return [undefined]
|
20
24
|
#
|
21
25
|
# @api public
|
22
26
|
def initialize(opts = {})
|
23
27
|
@host = opts.fetch(:host, 'http://127.0.0.1:9200')
|
24
28
|
@verbose = opts[:verbose]
|
25
|
-
@
|
29
|
+
@outputter = opts.fetch(:outputter, Kernel)
|
30
|
+
@client = opts.fetch(:http_client_factory, Desi::HttpClient).new(@host)
|
26
31
|
end
|
27
32
|
|
28
33
|
|
@@ -32,8 +37,8 @@ module Desi
|
|
32
37
|
# pattern being +/.*/+, all releases will be returned if you do not
|
33
38
|
# specify anything.)
|
34
39
|
#
|
35
|
-
# @param [#to_s] pattern
|
36
|
-
# @return [Array<String>]
|
40
|
+
# @param [#to_s] pattern ('.*') Regexp pattern used to restrict the selection
|
41
|
+
# @return [Array<String>] List of index names of the ES cluster
|
37
42
|
#
|
38
43
|
# @note This method will also output its result on STDOUT if +@verbose+ is
|
39
44
|
# true
|
@@ -45,10 +50,10 @@ module Desi
|
|
45
50
|
def list(pattern = '.*')
|
46
51
|
pattern = Regexp.new(pattern || '.*')
|
47
52
|
|
48
|
-
puts "Indices from host #{@
|
53
|
+
@outputter.puts "Indices from host #{@host} matching the pattern #{pattern.inspect}\n\n" if @verbose
|
49
54
|
|
50
55
|
list = indices(pattern).sort
|
51
|
-
list.each {|i| puts i } if @verbose
|
56
|
+
list.each {|i| @outputter.puts i } if @verbose
|
52
57
|
list
|
53
58
|
end
|
54
59
|
|
@@ -69,11 +74,11 @@ module Desi
|
|
69
74
|
def delete!(pattern)
|
70
75
|
warn "You must provide a pattern" and exit if pattern.nil?
|
71
76
|
|
72
|
-
puts "The following indices from host #{@
|
77
|
+
@outputter.puts "The following indices from host #{@host} are now deleted" if @verbose
|
73
78
|
|
74
79
|
indices(Regexp.new(pattern)).each do |index|
|
75
80
|
@client.delete(index)
|
76
|
-
puts " * #{index}" if @verbose
|
81
|
+
@outputter.puts " * #{index}" if @verbose
|
77
82
|
end
|
78
83
|
end
|
79
84
|
|
@@ -94,11 +99,11 @@ module Desi
|
|
94
99
|
def empty!(pattern)
|
95
100
|
warn "You must provide a pattern" and exit if pattern.nil?
|
96
101
|
|
97
|
-
puts "The following indices from host #{@
|
102
|
+
@outputter.puts "The following indices from host #{@host} are now emptied" if @verbose
|
98
103
|
|
99
104
|
indices(Regexp.new(pattern)).each do |index|
|
100
105
|
@client.delete("#{index}/_query?q=*")
|
101
|
-
puts " * #{index}" if @verbose
|
106
|
+
@outputter.puts " * #{index}" if @verbose
|
102
107
|
end
|
103
108
|
end
|
104
109
|
|
data/lib/desi/process_manager.rb
CHANGED
@@ -13,7 +13,7 @@ module Desi
|
|
13
13
|
@host = opts.fetch(:host, 'http://127.0.0.1:9200')
|
14
14
|
@verbose = opts[:verbose]
|
15
15
|
@local_install = LocalInstall.new
|
16
|
-
@client = Desi::HttpClient.new(@host)
|
16
|
+
@client = opts.fetch(:http_client_factory, Desi::HttpClient).new(@host)
|
17
17
|
end
|
18
18
|
|
19
19
|
def start
|
@@ -50,7 +50,7 @@ module Desi
|
|
50
50
|
if version = running_version
|
51
51
|
msg = "OK. Elastic Search cluster '#{cluster_health.cluster_name}' (v#{version}) is running on #{cluster_health.number_of_nodes} node(s) with status #{cluster_health.status}"
|
52
52
|
else
|
53
|
-
msg = "KO. No Elastic Search instance was found running on #{@
|
53
|
+
msg = "KO. No Elastic Search instance was found running on #{@host}"
|
54
54
|
end
|
55
55
|
puts msg if @verbose
|
56
56
|
msg
|
data/lib/desi/upstream.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require "desi/http_client"
|
4
|
+
require "json"
|
4
5
|
|
5
6
|
module Desi
|
6
7
|
class Upstream
|
@@ -11,8 +12,8 @@ module Desi
|
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
|
-
def initialize
|
15
|
-
@client = Desi::HttpClient.new('https://api.github.com/')
|
15
|
+
def initialize(opts = {})
|
16
|
+
@client = opts.fetch(:http_client_factory, Desi::HttpClient).new('https://api.github.com/')
|
16
17
|
end
|
17
18
|
|
18
19
|
def releases
|
data/lib/desi/version.rb
CHANGED
@@ -0,0 +1,134 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "desi/index_manager"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
describe Desi::IndexManager do
|
8
|
+
|
9
|
+
subject { described_class.new(http_client_factory: http_client_factory) }
|
10
|
+
|
11
|
+
let(:http_client_factory) { double(new: http_client) }
|
12
|
+
let(:http_client) { double('http_client') }
|
13
|
+
|
14
|
+
def stub_request(method, path, payload)
|
15
|
+
http_client.stub(method).with(path).and_return(
|
16
|
+
mock("response", body: JSON.unparse(payload))
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def stub_indices(*names)
|
21
|
+
stub_request(:get, '_status', {"indices" => Hash[Array(names).zip]})
|
22
|
+
end
|
23
|
+
|
24
|
+
before do
|
25
|
+
stub_indices('foo', 'bar')
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#list" do
|
29
|
+
context "with no specified pattern" do
|
30
|
+
it "returns the names of all indices" do
|
31
|
+
subject.list.should == %w[bar foo]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with a pattern" do
|
36
|
+
it "returns the matching indices" do
|
37
|
+
subject.list('oo').should == %w[foo]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when verbose is on" do
|
42
|
+
let(:outputter) { double("outputter") }
|
43
|
+
|
44
|
+
subject do
|
45
|
+
described_class.new(
|
46
|
+
http_client_factory: http_client_factory,
|
47
|
+
outputter: outputter,
|
48
|
+
verbose: true)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "also outputs on STDOUT" do
|
52
|
+
outputter.should_receive(:puts).at_least(:once)
|
53
|
+
subject.list('oo')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#delete!" do
|
59
|
+
context "when the mandatory pattern is not specified" do
|
60
|
+
it "raises an ArgumentError" do
|
61
|
+
expect { subject.delete! }.to raise_error(ArgumentError)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "deletes all matching indices" do
|
66
|
+
http_client.should_receive(:delete).with("foo")
|
67
|
+
http_client.should_not_receive(:delete).with("bar")
|
68
|
+
|
69
|
+
subject.delete!('f.*')
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when verbose is on" do
|
73
|
+
let(:outputter) { double("outputter") }
|
74
|
+
|
75
|
+
subject do
|
76
|
+
described_class.new(
|
77
|
+
http_client_factory: http_client_factory,
|
78
|
+
outputter: outputter,
|
79
|
+
verbose: true)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "also outputs on STDOUT" do
|
83
|
+
http_client.stub(:delete)
|
84
|
+
|
85
|
+
outputter.should_receive(:puts).at_least(:once)
|
86
|
+
subject.delete!('f.*')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#empty!" do
|
92
|
+
context "when the mandatory pattern is not specified" do
|
93
|
+
it "raises an ArgumentError" do
|
94
|
+
expect { subject.empty! }.to raise_error(ArgumentError)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "deletes all matching indices" do
|
99
|
+
http_client.should_receive(:delete).with("foo/_query?q=*")
|
100
|
+
http_client.should_not_receive(:delete).with("bar")
|
101
|
+
|
102
|
+
subject.empty!('f.*')
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when verbose is on" do
|
106
|
+
let(:outputter) { double("outputter") }
|
107
|
+
|
108
|
+
subject do
|
109
|
+
described_class.new(
|
110
|
+
http_client_factory: http_client_factory,
|
111
|
+
outputter: outputter,
|
112
|
+
verbose: true)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "also outputs on STDOUT" do
|
116
|
+
http_client.stub(:delete)
|
117
|
+
|
118
|
+
outputter.should_receive(:puts).at_least(:once)
|
119
|
+
subject.empty!('f.*')
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "when given another host" do
|
125
|
+
let(:factory_for_remote_host) { double("http_client_factory") }
|
126
|
+
|
127
|
+
it "sends the other host's url to initialize the client" do
|
128
|
+
factory_for_remote_host.should_receive(:new).with("http://foobar.com")
|
129
|
+
|
130
|
+
described_class.new(host: "http://foobar.com", http_client_factory: factory_for_remote_host)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
3
|
+
config.run_all_when_everything_filtered = true
|
4
|
+
config.filter_run :focus
|
5
|
+
|
6
|
+
# Run specs in random order to surface order dependencies. If you find an
|
7
|
+
# order dependency and want to debug it, you can fix the order by providing
|
8
|
+
# the seed, which is printed after each run.
|
9
|
+
# --seed 1234
|
10
|
+
config.order = 'random'
|
11
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: desi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -59,6 +59,54 @@ dependencies:
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: guard-rspec
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
62
110
|
- !ruby/object:Gem::Dependency
|
63
111
|
name: guard-yard
|
64
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,6 +167,7 @@ extensions: []
|
|
119
167
|
extra_rdoc_files: []
|
120
168
|
files:
|
121
169
|
- .gitignore
|
170
|
+
- .rspec
|
122
171
|
- .yardopts
|
123
172
|
- Gemfile
|
124
173
|
- Guardfile
|
@@ -138,6 +187,8 @@ files:
|
|
138
187
|
- lib/desi/runner.rb
|
139
188
|
- lib/desi/upstream.rb
|
140
189
|
- lib/desi/version.rb
|
190
|
+
- spec/desi/index_manager_spec.rb
|
191
|
+
- spec/spec_helper.rb
|
141
192
|
- tasks/yard.rake
|
142
193
|
homepage: https://github.com/AF83/desi/
|
143
194
|
licenses: []
|
@@ -151,17 +202,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
151
202
|
- - ! '>='
|
152
203
|
- !ruby/object:Gem::Version
|
153
204
|
version: '0'
|
205
|
+
segments:
|
206
|
+
- 0
|
207
|
+
hash: 1725098947325688636
|
154
208
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
209
|
none: false
|
156
210
|
requirements:
|
157
211
|
- - ! '>='
|
158
212
|
- !ruby/object:Gem::Version
|
159
213
|
version: '0'
|
214
|
+
segments:
|
215
|
+
- 0
|
216
|
+
hash: 1725098947325688636
|
160
217
|
requirements: []
|
161
218
|
rubyforge_project:
|
162
219
|
rubygems_version: 1.8.24
|
163
220
|
signing_key:
|
164
221
|
specification_version: 3
|
165
222
|
summary: A developer tool to quickly set up an Elastic Search local install.
|
166
|
-
test_files:
|
223
|
+
test_files:
|
224
|
+
- spec/desi/index_manager_spec.rb
|
225
|
+
- spec/spec_helper.rb
|
167
226
|
has_rdoc:
|