desi 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -0
- data/Guardfile +5 -0
- data/README.md +50 -13
- data/Rakefile +2 -0
- data/desi.gemspec +5 -0
- data/lib/desi.rb +7 -6
- data/lib/desi/http_client.rb +28 -3
- data/lib/desi/index_manager.rb +114 -0
- data/lib/desi/local_install.rb +49 -2
- data/lib/desi/process_manager.rb +4 -1
- data/lib/desi/runner.rb +23 -5
- data/lib/desi/version.rb +1 -1
- data/tasks/yard.rake +9 -0
- metadata +70 -2
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--no-private --protected lib/**/*.rb - README.md LICENSE
|
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -2,8 +2,56 @@
|
|
2
2
|
|
3
3
|
Desi (Developper ElasticSearch Installer) is very simple tool to quickly set up
|
4
4
|
an [Elastic Search](http://www.elasticsearch.org/) local install for
|
5
|
-
development purposes.
|
6
|
-
|
5
|
+
development purposes.
|
6
|
+
|
7
|
+
It can:
|
8
|
+
|
9
|
+
* download and install ElasticSearch (the latest release by default)
|
10
|
+
* start/stop/restart it.
|
11
|
+
* do basic indices management (list, delete, empty a given set of indices)
|
12
|
+
|
13
|
+
It can be used both as a command-line tool and as a library.
|
14
|
+
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
$ desi list # List locally installed ElasticSearch releases
|
19
|
+
$ desi releases # List all upstream Elastic Search releases (latest 5 by default)
|
20
|
+
$ desi install [VERSION] # Install a specific version (latest by default)
|
21
|
+
$ desi start # Start a local 1-node cluster (noop if active)
|
22
|
+
$ desi restart # (Re)start cluster (even if active)
|
23
|
+
$ desi stop # Stop cluster
|
24
|
+
$ desi status [--host HOST] # Show running cluster info
|
25
|
+
|
26
|
+
$ desi indices "^foo" # List all indices whose name match /^foo/
|
27
|
+
$ desi indices "^foo" --delete # Delete all matching indices
|
28
|
+
$ desi indices "bar$" --empty # Remove all records from the matching
|
29
|
+
# indices
|
30
|
+
|
31
|
+
## Examples
|
32
|
+
|
33
|
+
### Currently installed releases
|
34
|
+
|
35
|
+
The current version is the one symlinked to `$HOME/elasticsearch/current`
|
36
|
+
|
37
|
+
* command-line
|
38
|
+
|
39
|
+
```shell
|
40
|
+
$ desi list
|
41
|
+
Local ES installs (current one is tagged with '*'):
|
42
|
+
* elasticsearch-0.19.9 (/home/me/elasticsearch/elasticsearch-0.19.9)
|
43
|
+
- elasticsearch-0.19.8 (/home/me/elasticsearch/elasticsearch-0.19.8)
|
44
|
+
```
|
45
|
+
|
46
|
+
|
47
|
+
* library
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
Desi::LocalInstall.new.releases.map(&:name) #=> ["elasticsearch-0.19.8", "elasticsearch-0.19.9"]
|
51
|
+
Desi::LocalInstall.new.releases.detect(&:current?).version #=> "0.19.9"
|
52
|
+
```
|
53
|
+
|
54
|
+
|
7
55
|
|
8
56
|
## Installation
|
9
57
|
|
@@ -19,21 +67,10 @@ Or install it yourself as:
|
|
19
67
|
|
20
68
|
$ gem install desi
|
21
69
|
|
22
|
-
## Usage
|
23
|
-
|
24
|
-
$ desi list # List locally installed ElasticSearch versions
|
25
|
-
$ desi releases # List all upstream Elastic Search releases (latest 5 by default)
|
26
|
-
$ desi install [VERSION] # Install a specific version (latest by default)
|
27
|
-
$ desi start # Start a local 1-node cluster (noop if active)
|
28
|
-
$ desi restart # (Re)start cluster (even if active)
|
29
|
-
$ desi stop # Stop cluster
|
30
|
-
$ desi status # Show running cluster info
|
31
|
-
|
32
70
|
## TODO
|
33
71
|
|
34
72
|
* add tests, dammit!
|
35
73
|
|
36
|
-
* index management (list, create, delete ES indices)
|
37
74
|
* `desi upgrade` (Upgrade to latest version and migrate data)
|
38
75
|
* `desi switch VERSION` (Switch currently active ES version to VERSION)
|
39
76
|
* plugin management ? (list, install, remove ES plugins)
|
data/Rakefile
CHANGED
data/desi.gemspec
CHANGED
@@ -13,6 +13,11 @@ an Elastic Search local install for development purposes.}
|
|
13
13
|
|
14
14
|
gem.add_dependency "boson"
|
15
15
|
gem.add_dependency "cocaine"
|
16
|
+
gem.add_dependency "addressable"
|
17
|
+
|
18
|
+
gem.add_development_dependency "guard-yard"
|
19
|
+
gem.add_development_dependency "redcarpet"
|
20
|
+
gem.add_development_dependency "rb-inotify"
|
16
21
|
|
17
22
|
gem.files = `git ls-files`.split($\)
|
18
23
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
data/lib/desi.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require "desi/version"
|
2
2
|
|
3
3
|
module Desi
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
require 'desi/downloader'
|
5
|
+
require 'desi/http_client'
|
6
|
+
require 'desi/local_install'
|
7
|
+
require 'desi/upstream'
|
8
|
+
require 'desi/installer'
|
9
|
+
require 'desi/process_manager'
|
10
|
+
require 'desi/index_manager'
|
10
11
|
end
|
11
12
|
|
data/lib/desi/http_client.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require "net/https"
|
4
|
-
require "uri"
|
4
|
+
require "addressable/uri"
|
5
5
|
require "json"
|
6
6
|
|
7
7
|
module Desi
|
@@ -10,8 +10,8 @@ module Desi
|
|
10
10
|
|
11
11
|
attr_reader :uri
|
12
12
|
|
13
|
-
def initialize(
|
14
|
-
@uri =
|
13
|
+
def initialize(host_string)
|
14
|
+
@uri = to_uri(host_string)
|
15
15
|
|
16
16
|
case @uri.scheme
|
17
17
|
when 'https'
|
@@ -39,6 +39,31 @@ module Desi
|
|
39
39
|
raise response.error!
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
def delete(uri)
|
44
|
+
response = @http.request(Net::HTTP::Delete.new(uri))
|
45
|
+
|
46
|
+
case response
|
47
|
+
when Net::HTTPSuccess
|
48
|
+
response
|
49
|
+
else
|
50
|
+
raise response.error!
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def to_uri(host_string)
|
57
|
+
scheme, host, port = ['http', '127.0.0.1', 9200]
|
58
|
+
|
59
|
+
%r{(?<scheme>(https?|))(?:\:\/\/|)(?<host>[^:]*?):?(?<port>\d*)/?$}.match(host_string) do |m|
|
60
|
+
scheme = m[:scheme] unless m[:scheme].empty?
|
61
|
+
host = m[:host] unless m[:host].empty?
|
62
|
+
port = m[:port] unless m[:port].empty?
|
63
|
+
end
|
64
|
+
|
65
|
+
Addressable::URI.new(scheme: scheme, host: host, port: port)
|
66
|
+
end
|
42
67
|
end
|
43
68
|
|
44
69
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "desi/http_client"
|
4
|
+
|
5
|
+
module Desi
|
6
|
+
|
7
|
+
# Performs some simple index-related operations on a local or distance
|
8
|
+
# Elastic Search cluster
|
9
|
+
class IndexManager
|
10
|
+
|
11
|
+
# Initializes a Desi::IndexManager instance
|
12
|
+
#
|
13
|
+
# @param [#to_hash] opts Hash of extra 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
|
18
|
+
#
|
19
|
+
# @return [undefined]
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
def initialize(opts = {})
|
23
|
+
@host = opts.fetch(:host, 'http://127.0.0.1:9200')
|
24
|
+
@verbose = opts[:verbose]
|
25
|
+
@client = Desi::HttpClient.new(@host)
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# List index names for the specified cluster
|
30
|
+
#
|
31
|
+
# You can restrict the list using a regular expression pattern. (The default
|
32
|
+
# pattern being +/.*/+, all releases will be returned if you do not
|
33
|
+
# specify anything.)
|
34
|
+
#
|
35
|
+
# @param [#to_s] pattern Regexp pattern used to restrict the selection
|
36
|
+
# @return [Array<String>] List of index names of the ES cluster
|
37
|
+
#
|
38
|
+
# @note This method will also output its result on STDOUT if +@verbose+ is
|
39
|
+
# true
|
40
|
+
#
|
41
|
+
# @example List all indices whose name begins with "foo"
|
42
|
+
# Desi::IndexManager.new.list('^foo') #=> ["foo1", "foo2", "foo3"]
|
43
|
+
#
|
44
|
+
# @api public
|
45
|
+
def list(pattern = '.*')
|
46
|
+
pattern = Regexp.new(pattern || '.*')
|
47
|
+
|
48
|
+
puts "Indices from host #{@client.uri} matching the pattern #{pattern.inspect}\n\n" if @verbose
|
49
|
+
|
50
|
+
list = indices(pattern).sort
|
51
|
+
list.each {|i| puts i } if @verbose
|
52
|
+
list
|
53
|
+
end
|
54
|
+
|
55
|
+
# Delete all indices matching the specified pattern
|
56
|
+
#
|
57
|
+
# @param [#to_s] pattern Regexp pattern used to restrict the selection
|
58
|
+
# @return [undefined]
|
59
|
+
#
|
60
|
+
# @note No confirmation is needed, so beware!
|
61
|
+
#
|
62
|
+
# @note This method will also output its result on STDOUT if +@verbose+ is
|
63
|
+
# true
|
64
|
+
#
|
65
|
+
# @example Delete all indices whose name begins with "test"
|
66
|
+
# Desi::IndexManager.new.delete!('^test') #=> nil
|
67
|
+
#
|
68
|
+
# @api public
|
69
|
+
def delete!(pattern)
|
70
|
+
warn "You must provide a pattern" and exit if pattern.nil?
|
71
|
+
|
72
|
+
puts "The following indices from host #{@client.uri} are now deleted" if @verbose
|
73
|
+
|
74
|
+
indices(Regexp.new(pattern)).each do |index|
|
75
|
+
@client.delete(index)
|
76
|
+
puts " * #{index}" if @verbose
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Empty (remove all records) from indices matching the specified pattern
|
81
|
+
#
|
82
|
+
# @param [#to_s] pattern Regexp pattern used to restrict the selection
|
83
|
+
# @return [undefined]
|
84
|
+
#
|
85
|
+
# @note No confirmation is needed, so beware!
|
86
|
+
#
|
87
|
+
# @note This method will also output its result on STDOUT if +@verbose+ is
|
88
|
+
# true
|
89
|
+
#
|
90
|
+
# @example Empty all indices whose name begins with "log"
|
91
|
+
# Desi::IndexManager.new.empty!('^log') #=> nil
|
92
|
+
#
|
93
|
+
# @api public
|
94
|
+
def empty!(pattern)
|
95
|
+
warn "You must provide a pattern" and exit if pattern.nil?
|
96
|
+
|
97
|
+
puts "The following indices from host #{@client.uri} are now emptied" if @verbose
|
98
|
+
|
99
|
+
indices(Regexp.new(pattern)).each do |index|
|
100
|
+
@client.delete("#{index}/_query?q=*")
|
101
|
+
puts " * #{index}" if @verbose
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def indices(pattern)
|
108
|
+
JSON.parse(@client.get('_status').body)["indices"].keys.select {|i|
|
109
|
+
i =~ pattern
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
data/lib/desi/local_install.rb
CHANGED
@@ -1,9 +1,56 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require "pathname"
|
4
|
+
|
3
5
|
module Desi
|
4
6
|
class LocalInstall
|
5
7
|
DEFAULT_DIR = '~/elasticsearch'
|
6
8
|
|
9
|
+
class Release
|
10
|
+
def self.all_in(workdir)
|
11
|
+
Dir[workdir.join('*')].
|
12
|
+
select {|subdir| File.directory?(subdir) && File.basename(subdir) =~ /^elasticsearch\-\d+\.\d+\.\d+/ }.
|
13
|
+
map {|dirname| new(dirname, workdir) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(dirname, workdir)
|
17
|
+
@dirname = Pathname.new(dirname)
|
18
|
+
@workdir = workdir
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
@name ||= File.basename(@dirname)
|
23
|
+
end
|
24
|
+
|
25
|
+
def current?
|
26
|
+
current_symlink? && current_symlink.realpath == @dirname
|
27
|
+
end
|
28
|
+
|
29
|
+
def version
|
30
|
+
@version ||= /^elasticsearch\-(?<version>.*)$/.match(name.to_s)[:version]
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
current_mark = current? ? '*' : '-'
|
35
|
+
|
36
|
+
" #{current_mark} #{name} (#{@dirname})"
|
37
|
+
end
|
38
|
+
|
39
|
+
def <=>(other)
|
40
|
+
name <=> other.name
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def current_symlink
|
46
|
+
@current_symlink ||= Pathname(@workdir).join('current')
|
47
|
+
end
|
48
|
+
|
49
|
+
def current_symlink?
|
50
|
+
current_symlink.exist?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
7
54
|
def initialize(workdir = nil)
|
8
55
|
@workdir = Pathname(File.expand_path(workdir || DEFAULT_DIR))
|
9
56
|
end
|
@@ -20,8 +67,8 @@ module Desi
|
|
20
67
|
FileUtils.mkdir_p @workdir
|
21
68
|
end
|
22
69
|
|
23
|
-
def
|
24
|
-
|
70
|
+
def releases
|
71
|
+
Release.all_in(@workdir)
|
25
72
|
end
|
26
73
|
|
27
74
|
def to_path
|
data/lib/desi/process_manager.rb
CHANGED
@@ -3,14 +3,17 @@
|
|
3
3
|
require "json"
|
4
4
|
require "cocaine"
|
5
5
|
require "ostruct"
|
6
|
+
require "desi/http_client"
|
7
|
+
require "desi/local_install"
|
6
8
|
|
7
9
|
module Desi
|
8
10
|
class ProcessManager
|
9
11
|
|
10
12
|
def initialize(opts = {})
|
13
|
+
@host = opts.fetch(:host, 'http://127.0.0.1:9200')
|
11
14
|
@verbose = opts[:verbose]
|
12
15
|
@local_install = LocalInstall.new
|
13
|
-
@client = Desi::HttpClient.new(
|
16
|
+
@client = Desi::HttpClient.new(@host)
|
14
17
|
end
|
15
18
|
|
16
19
|
def start
|
data/lib/desi/runner.rb
CHANGED
@@ -13,9 +13,9 @@ module Desi
|
|
13
13
|
desc "List locally installed Elastic Search releases"
|
14
14
|
verbosity_option
|
15
15
|
def list(options = {})
|
16
|
-
puts "Local ES installs:" unless quiet?(options)
|
17
|
-
Desi::LocalInstall.new.
|
18
|
-
puts
|
16
|
+
puts "Local ES installs (current one is tagged with '*'):" unless quiet?(options)
|
17
|
+
Desi::LocalInstall.new.releases.sort.reverse.each do |v|
|
18
|
+
puts v
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -31,7 +31,7 @@ module Desi
|
|
31
31
|
releases
|
32
32
|
else
|
33
33
|
puts "Here are #{limit == 0 ? 'all the' : "the #{limit} latest"} releases"
|
34
|
-
releases.each {|rel| puts "
|
34
|
+
releases.each {|rel| puts " - #{rel.name} (#{rel.release_date})" }
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -71,8 +71,26 @@ module Desi
|
|
71
71
|
|
72
72
|
desc "Show current status"
|
73
73
|
verbosity_option
|
74
|
+
option "--host", type: :string, desc: "Elastic Search cluster URL", default: '127.0.0.1:9200'
|
74
75
|
def status(options = {})
|
75
|
-
Desi::ProcessManager.new(verbose: !quiet?(options)).status
|
76
|
+
Desi::ProcessManager.new(verbose: !quiet?(options), host: options[:host]).status
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "List indices"
|
80
|
+
verbosity_option
|
81
|
+
option "--host", type: :string, desc: "Elastic Search cluster URL", default: '127.0.0.1:9200'
|
82
|
+
option "--delete", type: :boolean, desc: "Delete the specified indices (You've been warned!)", default: false
|
83
|
+
option "--empty", type: :boolean, desc: "Delete all documents from the specified indices", default: false
|
84
|
+
def indices(pattern = nil, options = {})
|
85
|
+
index_manager = Desi::IndexManager.new(verbose: !quiet?(options), host: options[:host])
|
86
|
+
|
87
|
+
if options[:delete]
|
88
|
+
index_manager.delete!(pattern)
|
89
|
+
elsif options[:empty]
|
90
|
+
index_manager.empty!(pattern)
|
91
|
+
else
|
92
|
+
index_manager.list(pattern)
|
93
|
+
end
|
76
94
|
end
|
77
95
|
|
78
96
|
# desc "Upgrade to latest ElasticSearch version"
|
data/lib/desi/version.rb
CHANGED
data/tasks/yard.rake
ADDED
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.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: boson
|
@@ -43,6 +43,70 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: addressable
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: guard-yard
|
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: redcarpet
|
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: rb-inotify
|
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'
|
46
110
|
description: ! 'Desi (Developper ElasticSearch Installer) is very simple tool to quickly
|
47
111
|
set up
|
48
112
|
|
@@ -55,7 +119,9 @@ extensions: []
|
|
55
119
|
extra_rdoc_files: []
|
56
120
|
files:
|
57
121
|
- .gitignore
|
122
|
+
- .yardopts
|
58
123
|
- Gemfile
|
124
|
+
- Guardfile
|
59
125
|
- LICENSE
|
60
126
|
- README.md
|
61
127
|
- Rakefile
|
@@ -65,12 +131,14 @@ files:
|
|
65
131
|
- lib/desi.rb
|
66
132
|
- lib/desi/downloader.rb
|
67
133
|
- lib/desi/http_client.rb
|
134
|
+
- lib/desi/index_manager.rb
|
68
135
|
- lib/desi/installer.rb
|
69
136
|
- lib/desi/local_install.rb
|
70
137
|
- lib/desi/process_manager.rb
|
71
138
|
- lib/desi/runner.rb
|
72
139
|
- lib/desi/upstream.rb
|
73
140
|
- lib/desi/version.rb
|
141
|
+
- tasks/yard.rake
|
74
142
|
homepage: https://github.com/AF83/desi/
|
75
143
|
licenses: []
|
76
144
|
post_install_message:
|