esteem 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 340aa00a323b11ea872b48a404e951df6eabb2eb
4
+ data.tar.gz: e9b5ee78c4c9f76e0b041617f7984f88f884526b
5
+ SHA512:
6
+ metadata.gz: 8ff6c19a502f907dd2a30d0391042e13f8bd1b646ed19d8a634a54044e2d3db6c22bb89cb820cdbf57fe1f7b233bd8b83b3b52b91cf4537475d46fcec7daf832
7
+ data.tar.gz: 3cc3b6cf92f7c058a9724b8b23c61f772c087bd38dceb330e9545e82732a02ced2b13ce46d8030c3a4a2e73b79346e80700859fbc54b56be7d2e4f982923f71e
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ *~
2
+ *.gem
3
+ *.log
4
+ *.out
5
+ *.pid
6
+ *.swp
7
+ .DS_Store
8
+ .yardoc
9
+ doc
10
+ pkg
11
+ tmp
12
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'pry'
7
+ gem 'rake'
8
+ gem 'yard'
9
+ gem 'version'
10
+ gem 'rubygems-tasks'
11
+ end
12
+
13
+ group :test do
14
+ gem 'minitest'
15
+ end
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2015 Sean Clemmer
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any
4
+ purpose with or without fee is hereby granted, provided that the above
5
+ copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13
+ PERFORMANCE OF THIS SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'rake'
4
+
5
+ require 'rake/testtask'
6
+ Rake::TestTask.new(:test) do |test|
7
+ test.libs << 'lib' << 'test'
8
+ test.test_files = FileList['test/test*.rb']
9
+ test.verbose = true
10
+ end
11
+
12
+ task default: :test
13
+
14
+
15
+ require 'yard'
16
+ YARD::Rake::YardocTask.new do |t|
17
+ t.files = %w[ --readme Readme.md lib/**/*.rb - VERSION ]
18
+ end
19
+
20
+
21
+ require 'rubygems/tasks'
22
+ Gem::Tasks.new push: true, sign: {} do |tasks|
23
+ tasks.console.command = 'pry'
24
+ end
25
+ Gem::Tasks::Sign::Checksum.new sha2: true
26
+
27
+
28
+ require 'rake/version_task'
29
+ Rake::VersionTask.new
data/Readme.md ADDED
@@ -0,0 +1,3 @@
1
+ # Esteem
2
+
3
+ Tips, tricks and scripts for managing time-based Elasticsearch indexes.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/bin/esteem ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'esteem'
3
+ rc = Esteem::Main.start ARGV
4
+ exit rc unless rc.nil?
data/esteem.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path(File.join('..', 'lib'), __FILE__)
3
+ require 'esteem/metadata'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'esteem'
7
+ s.version = Esteem::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.author = Esteem::AUTHOR
10
+ s.license = Esteem::LICENSE
11
+ s.homepage = Esteem::HOMEPAGE
12
+ s.email = Esteem::EMAIL
13
+ s.summary = Esteem::SUMMARY
14
+ s.description = Esteem::SUMMARY + '.'
15
+
16
+ s.add_runtime_dependency 'thor', '~> 0'
17
+ s.add_runtime_dependency 'slog', '~> 1.1'
18
+ s.add_runtime_dependency 'oj', '~> 2.11'
19
+ s.add_runtime_dependency 'rest-client', '~> 1.7'
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- test/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File::basename(f) }
24
+ s.require_paths = %w[ lib ]
25
+ end
@@ -0,0 +1,28 @@
1
+ require 'thor/util'
2
+ require 'thor/actions'
3
+
4
+
5
+ module Esteem
6
+
7
+ # Mixins for Esteem's Thor subclasses.
8
+ module Helpers
9
+
10
+ # Save the canonical implementation of "puts"
11
+ alias_method :old_puts, :puts
12
+
13
+ # Monkeypatch puts to support Thor::Shell::Color.
14
+ def puts *args
15
+ return old_puts if args.empty?
16
+ old_puts shell.set_color(*args)
17
+ end
18
+
19
+
20
+ # Shortcut for Thor::Util.
21
+ def util ; Thor::Util end
22
+
23
+
24
+ # Shortcut for Thor::Actions.
25
+ def actions ; Thor::Actions end
26
+
27
+ end
28
+ end
@@ -0,0 +1,47 @@
1
+ require 'thor'
2
+ require 'slog'
3
+
4
+ require_relative 'reindex'
5
+ require_relative 'helpers'
6
+ require_relative 'metadata'
7
+
8
+
9
+ module Esteem
10
+
11
+ # Esteem's entrypoint.
12
+ class Main < Thor
13
+ include Esteem::Helpers
14
+
15
+
16
+ desc 'version', 'Echo the application version'
17
+ def version
18
+ puts VERSION
19
+ return nil
20
+ end
21
+
22
+
23
+ desc 'art', 'View the application art'
24
+ def art
25
+ puts
26
+ puts ART
27
+ puts
28
+ return nil
29
+ end
30
+
31
+
32
+ desc 'reindex', 'Move data to a new index gracefully'
33
+ option :update, type: :boolean, aliases: %w[ -u ]
34
+ option :frame, type: :numeric, aliases: %w[ -f ], default: 1000
35
+ option :source, type: :string, aliases: %w[ -s ], required: true
36
+ option :destination, type: :string, aliases: %w[ -d ], required: true
37
+ def reindex
38
+ reindex = Reindex.new \
39
+ update: options.update?,
40
+ frame: options.frame,
41
+ src: options.source,
42
+ dst: options.destination
43
+ return reindex.success
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,30 @@
1
+ # Esteem gives you confidence!
2
+ module Esteem
3
+
4
+ # Pull the project version out of the VERSION file
5
+ VERSION = File.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION')).strip
6
+
7
+ # A quick summary for use in the command-line interface
8
+ SUMMARY = 'Tips, tricks and scripts for managing time-based Elasticsearch indexes'
9
+
10
+ # Take credit for your work
11
+ AUTHOR = 'Sean Clemmer'
12
+
13
+ # Like the MIT license, but even simpler
14
+ LICENSE = 'ISC'
15
+
16
+ # Where you should look first
17
+ HOMEPAGE = 'https://github.com/sczizzo/esteem'
18
+
19
+ # Take responsibility for your work
20
+ EMAIL = 'EMAIL'
21
+
22
+ # Every project deserves its own ASCII art
23
+ ART = <<-'EOART'
24
+ ____ ____ ____
25
+ | ..'''' `````|````` | | .'. .`.
26
+ |______ .'' | |______ |______ .' ` `.
27
+ | ..' | | | .' `.
28
+ |___________ ....'' | |___________ |___________ .' `.
29
+ EOART
30
+ end
@@ -0,0 +1,151 @@
1
+ require 'oj'
2
+ require 'rest-client'
3
+
4
+
5
+ Oj.default_options = { mode: :compat }
6
+
7
+ module Esteem
8
+
9
+ # Cribbed from geronime's "es-reindex" script: https://github.com/geronime/es-reindex
10
+ class Reindex
11
+ attr_reader :success
12
+
13
+
14
+ # Perform a new reindex job. Success or failure will be reported by the
15
+ # read-only "success" attribute.
16
+ #
17
+ # @option [String] :source URL for source index and type
18
+ # @option [String] :destination URL for destination index
19
+ # @option [Integer] :frame Scroll window size
20
+ # @option [Boolean] :update Set to update existing documents
21
+ def initialize source:, destination:, frame:, update:
22
+ src, dst = source, destination
23
+ @success = false
24
+
25
+ type, src = src.reverse.split('/', 2).map(&:reverse)
26
+
27
+ surl, durl, sidx, didx = '', '', '', ''
28
+ [[src, surl, sidx], [dst, durl, didx]].each{|param, url, idx|
29
+ if param =~ %r{^(.*)/(.*?)$}
30
+ url.replace $1
31
+ idx.replace $2
32
+ else
33
+ url.replace 'http://127.0.0.1:9200'
34
+ idx.replace param
35
+ end
36
+ }
37
+
38
+ puts "Copying '%s/%s/%s' to '%s/%s'" % [ surl, sidx, type, durl, didx ]
39
+
40
+ scount = retried_request :get, "#{surl}/#{sidx}/#{type}/_count?q=*"
41
+ scount = Oj.load(scount)['count'].to_i
42
+
43
+ puts "%d documents" % scount
44
+
45
+ if scount == 0
46
+ puts "Hey, this index is empty! Skipping..."
47
+ @success = true
48
+ return
49
+ end
50
+
51
+ t, done = Time.now, 0
52
+ shards = retried_request :get, "#{surl}/#{sidx}/_count?q=*"
53
+ shards = Oj.load(shards)['_shards']['total'].to_i
54
+ scan = retried_request(:get, "#{surl}/#{sidx}/#{type}/_search?search_type=scan&scroll=10m&size=#{frame / shards}")
55
+ scan = Oj.load scan
56
+ scroll_id = scan['_scroll_id']
57
+ total = scan['hits']['total']
58
+ printf " %u/%u (%.1f%%) done.\r", done, total, 0
59
+
60
+ bulk_op = update ? "index" : "create"
61
+
62
+ loop do
63
+ data = retried_request(:get, "#{surl}/_search/scroll?scroll=10m&scroll_id=#{scroll_id}")
64
+ data = Oj.load data
65
+ break if data['hits']['hits'].empty?
66
+
67
+ scroll_id = data['_scroll_id']
68
+ bulk = ''
69
+
70
+ data['hits']['hits'].each do |doc|
71
+ bulk << %Q({"#{bulk_op}": {"_index" : "#{didx}", "_id" : "#{
72
+ doc['_id']}", "_type" : "#{doc['_type']}"}}\n)
73
+ bulk << Oj.dump(doc['_source']) + "\n"
74
+ done += 1
75
+ end
76
+
77
+ unless bulk.empty?
78
+ bulk << "\n" # empty line in the end required
79
+ retried_request :post, "#{durl}/_bulk", bulk
80
+ end
81
+
82
+ eta = total * (Time.now - t) / done
83
+ printf " %u/%u (%.1f%%) done in %s, E.T.A.: %s.\r",
84
+ done, total, 100.0 * done / total, tm_len(Time.now - t), t + eta
85
+ end
86
+
87
+ printf "#{' ' * 80}\r %u/%u done in %s.\n",
88
+ done, total, tm_len(Time.now - t)
89
+
90
+
91
+
92
+ tries = 0
93
+ dcount = -1
94
+
95
+ puts "Waiting for documents to appear in index..."
96
+ until total <= dcount
97
+ dcount = retried_request :get, "#{durl}/#{didx}/#{type}/_count"
98
+ dcount = Oj.load(dcount)['count'].to_i
99
+ tries += 1
100
+
101
+ if tries > 30
102
+ puts "Too many tries!"
103
+ @success = false
104
+ return
105
+ end
106
+
107
+ sleep 15
108
+ end
109
+
110
+ if done != dcount
111
+ puts "Incomplete done! %d != %d" % [ done, dcount ]
112
+ @success = false
113
+ return
114
+ end
115
+
116
+ @success = true
117
+ end
118
+
119
+
120
+
121
+ private
122
+
123
+ def tm_len l
124
+ t = []
125
+ t.push l/86400; l %= 86400
126
+ t.push l/3600; l %= 3600
127
+ t.push l/60; l %= 60
128
+ t.push l
129
+ out = sprintf '%u', t.shift
130
+ out = out == '0' ? '' : out + ' days, '
131
+ out += sprintf('%u:%02u:%02u', *t)
132
+ out
133
+ end
134
+
135
+
136
+ def retried_request method, url, data=nil
137
+ while true
138
+ begin
139
+ return data ?
140
+ RestClient.send(method, url, data) :
141
+ RestClient.send(method, url)
142
+ rescue RestClient::ResourceNotFound # no point to retry
143
+ return nil
144
+ rescue => e
145
+ warn "\nRetrying #{method.to_s.upcase} ERROR: #{e.class} - #{e.message}"
146
+ end
147
+ end
148
+ end
149
+
150
+ end
151
+ end
data/lib/esteem.rb ADDED
@@ -0,0 +1 @@
1
+ require_relative 'esteem/main'
@@ -0,0 +1,27 @@
1
+ require 'tmpdir'
2
+ require 'logger'
3
+ require 'tempfile'
4
+ require 'fileutils'
5
+ require 'pathname'
6
+
7
+ require 'minitest/autorun'
8
+
9
+ require_relative '../lib/esteem'
10
+
11
+
12
+
13
+ class TestEsteem < MiniTest::Test
14
+ def setup
15
+ @tmpdir = Dir.mktmpdir
16
+ @logger = Logger.new STDERR
17
+ @logger.level = Logger::WARN
18
+ end
19
+
20
+ def teardown
21
+ FileUtils.rm_rf @tmpdir
22
+ end
23
+
24
+ def test_something
25
+ assert true
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: esteem
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sean Clemmer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: slog
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: oj
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.11'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.11'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rest-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.7'
69
+ description: Tips, tricks and scripts for managing time-based Elasticsearch indexes.
70
+ email: EMAIL
71
+ executables:
72
+ - esteem
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE
79
+ - Rakefile
80
+ - Readme.md
81
+ - VERSION
82
+ - bin/esteem
83
+ - esteem.gemspec
84
+ - lib/esteem.rb
85
+ - lib/esteem/helpers.rb
86
+ - lib/esteem/main.rb
87
+ - lib/esteem/metadata.rb
88
+ - lib/esteem/reindex.rb
89
+ - test/test_esteem.rb
90
+ homepage: https://github.com/sczizzo/esteem
91
+ licenses:
92
+ - ISC
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.2.2
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: Tips, tricks and scripts for managing time-based Elasticsearch indexes
114
+ test_files:
115
+ - test/test_esteem.rb