chef-solr 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,133 @@
1
+ #
2
+ # Author:: AJ Christensen (<aj@opscode.com)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ require 'chef'
19
+ require 'chef/log'
20
+ require 'chef/config'
21
+ require 'chef/application'
22
+ require 'chef/solr'
23
+ require 'chef/solr/index'
24
+ require 'chef/solr/index_queue_consumer'
25
+ require 'chef/daemon'
26
+ require 'chef/webui_user'
27
+
28
+ class Chef
29
+ class Solr
30
+ class Application
31
+ class Indexer < Chef::Application
32
+
33
+ option :config_file,
34
+ :short => "-c CONFIG",
35
+ :long => "--config CONFIG",
36
+ :default => "/etc/chef/solr.rb",
37
+ :description => "The configuration file to use"
38
+
39
+ option :log_level,
40
+ :short => "-l LEVEL",
41
+ :long => "--log_level LEVEL",
42
+ :description => "Set the log level (debug, info, warn, error, fatal)",
43
+ :proc => lambda { |l| l.to_sym }
44
+
45
+ option :log_location,
46
+ :short => "-L LOGLOCATION",
47
+ :long => "--logfile LOGLOCATION",
48
+ :description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
49
+ :proc => nil
50
+
51
+ option :help,
52
+ :short => "-h",
53
+ :long => "--help",
54
+ :description => "Show this message",
55
+ :on => :tail,
56
+ :boolean => true,
57
+ :show_options => true,
58
+ :exit => 0
59
+
60
+ option :user,
61
+ :short => "-u USER",
62
+ :long => "--user USER",
63
+ :description => "User to set privilege to",
64
+ :proc => nil
65
+
66
+ option :group,
67
+ :short => "-g GROUP",
68
+ :long => "--group GROUP",
69
+ :description => "Group to set privilege to",
70
+ :proc => nil
71
+
72
+ option :daemonize,
73
+ :short => "-d",
74
+ :long => "--daemonize",
75
+ :description => "Daemonize the process",
76
+ :proc => lambda { |p| true }
77
+
78
+ option :amqp_host,
79
+ :long => "--amqp-host HOST",
80
+ :description => "The amqp host"
81
+
82
+ option :amqp_port,
83
+ :long => "--amqp-port PORT",
84
+ :description => "The amqp port"
85
+
86
+ option :amqp_user,
87
+ :long => "--amqp-user USER",
88
+ :description => "The amqp user"
89
+
90
+ option :amqp_pass,
91
+ :long => "--amqp-pass PASS",
92
+ :description => "The amqp password"
93
+
94
+ option :amqp_vhost,
95
+ :long => "--amqp-vhost VHOST",
96
+ :description => "The amqp vhost"
97
+
98
+ Signal.trap("INT") do
99
+ begin
100
+ AmqpClient.instance.stop
101
+ rescue Bunny::ProtocolError, Bunny::ConnectionError, Bunny::UnsubscribeError
102
+ end
103
+ fatal!("SIGINT received, stopping", 2)
104
+ end
105
+
106
+ Kernel.trap("TERM") do
107
+ begin
108
+ AmqpClient.instance.stop
109
+ rescue Bunny::ProtocolError, Bunny::ConnectionError, Bunny::UnsubscribeError
110
+ end
111
+ fatal!("SIGTERM received, stopping", 1)
112
+ end
113
+
114
+ def initialize
115
+ super
116
+
117
+ @index = Chef::Solr::Index.new
118
+ @consumer = Chef::Solr::IndexQueueConsumer.new
119
+ end
120
+
121
+ def setup_application
122
+ Chef::Daemon.change_privilege
123
+ Chef::Log.level = Chef::Config[:log_level]
124
+ end
125
+
126
+ def run_application
127
+ Chef::Daemon.daemonize("chef-solr-indexer") if Chef::Config[:daemonize]
128
+ @consumer.start
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,93 @@
1
+ #
2
+ # Author:: AJ Christensen (<aj@opscode.com)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ require 'chef'
19
+ require 'chef/log'
20
+ require 'chef/config'
21
+ require 'chef/application'
22
+ require 'chef/solr'
23
+ require 'chef/solr/index'
24
+
25
+ class Chef
26
+ class Solr
27
+ class Application
28
+ class Rebuild < Chef::Application
29
+
30
+ option :config_file,
31
+ :short => "-c CONFIG",
32
+ :long => "--config CONFIG",
33
+ :default => "/etc/chef/solr.rb",
34
+ :description => "The configuration file to use"
35
+
36
+ option :log_level,
37
+ :short => "-l LEVEL",
38
+ :long => "--log_level LEVEL",
39
+ :description => "Set the log level (debug, info, warn, error, fatal)",
40
+ :proc => lambda { |l| l.to_sym }
41
+
42
+ option :log_location,
43
+ :short => "-L LOGLOCATION",
44
+ :long => "--logfile LOGLOCATION",
45
+ :description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
46
+ :proc => nil
47
+
48
+ option :help,
49
+ :short => "-h",
50
+ :long => "--help",
51
+ :description => "Show this message",
52
+ :on => :tail,
53
+ :boolean => true,
54
+ :show_options => true,
55
+ :exit => 0
56
+
57
+ option :couchdb_database,
58
+ :short => "-d DB",
59
+ :long => "--couchdb-database DB",
60
+ :description => "The CouchDB Database to re-index"
61
+
62
+ option :couchdb_url,
63
+ :short => "-u URL",
64
+ :long => "--couchdb-url URL",
65
+ :description => "The CouchDB URL"
66
+
67
+ def initialize
68
+ super
69
+
70
+ @index = Chef::Solr::Index.new
71
+ end
72
+
73
+ def setup_application
74
+ Chef::Log.level = Chef::Config[:log_level]
75
+ Chef::Log.warn("This operation is destructive!")
76
+ Chef::Log.warn("I'm going to count to 10, and then delete your Solr index and rebuild it.")
77
+ Chef::Log.warn("CTRL-C will, of course, stop this disaster.")
78
+ 0.upto(10) do |num|
79
+ Chef::Log.warn("... #{num}")
80
+ sleep 1
81
+ end
82
+ Chef::Log.warn("... Bombs away!")
83
+ end
84
+
85
+ def run_application
86
+ s = Chef::Solr.new(Chef::Config[:solr_url])
87
+ Chef::Log.info("Destroying the index")
88
+ s.rebuild_index
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,165 @@
1
+ #
2
+ # Author:: AJ Christensen (<aj@opscode.com)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ require 'chef'
19
+ require 'chef/log'
20
+ require 'chef/config'
21
+ require 'chef/application'
22
+ require 'chef/daemon'
23
+ require 'chef/client'
24
+
25
+ class Chef
26
+ class Solr
27
+ class Application
28
+ class Solr < Chef::Application
29
+
30
+ option :config_file,
31
+ :short => "-c CONFIG",
32
+ :long => "--config CONFIG",
33
+ :default => "/etc/chef/solr.rb",
34
+ :description => "The configuration file to use"
35
+
36
+ option :log_level,
37
+ :short => "-l LEVEL",
38
+ :long => "--log_level LEVEL",
39
+ :description => "Set the log level (debug, info, warn, error, fatal)",
40
+ :proc => lambda { |l| l.to_sym }
41
+
42
+ option :log_location,
43
+ :short => "-L LOGLOCATION",
44
+ :long => "--logfile LOGLOCATION",
45
+ :description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
46
+ :proc => nil
47
+
48
+ option :help,
49
+ :short => "-h",
50
+ :long => "--help",
51
+ :description => "Show this message",
52
+ :on => :tail,
53
+ :boolean => true,
54
+ :show_options => true,
55
+ :exit => 0
56
+
57
+ option :user,
58
+ :short => "-u USER",
59
+ :long => "--user USER",
60
+ :description => "User to set privilege to",
61
+ :proc => nil
62
+
63
+ option :group,
64
+ :short => "-g GROUP",
65
+ :long => "--group GROUP",
66
+ :description => "Group to set privilege to",
67
+ :proc => nil
68
+
69
+ option :daemonize,
70
+ :short => "-d",
71
+ :long => "--daemonize",
72
+ :description => "Daemonize the process",
73
+ :proc => lambda { |p| true }
74
+
75
+ option :solr_jetty_path,
76
+ :short => "-W PATH",
77
+ :long => "--solr-jetty-dir PATH",
78
+ :description => "Where to place the Solr Jetty instance"
79
+
80
+ option :solr_data_path,
81
+ :short => "-D PATH",
82
+ :long => "--solr-data-dir PATH",
83
+ :description => "Where the Solr data lives"
84
+
85
+ option :solr_home_path,
86
+ :short => "-H PATH",
87
+ :long => "--solr-home-dir PATH",
88
+ :description => "Solr home directory"
89
+
90
+ option :solr_heap_size,
91
+ :short => "-x SIZE",
92
+ :long => "--solor-heap-size SIZE",
93
+ :description => "Set the size of the Java Heap"
94
+
95
+ option :solr_java_opts,
96
+ :short => "-j OPTS",
97
+ :long => "--java-opts OPTS",
98
+ :description => "Raw options passed to Java"
99
+
100
+ def initialize
101
+ super
102
+ Chef::Log.level = Chef::Config[:log_level]
103
+ end
104
+
105
+ def setup_application
106
+ Chef::Daemon.change_privilege
107
+
108
+ # Build up a client
109
+ c = Chef::Client.new
110
+ c.build_node(nil, true)
111
+
112
+ solr_base = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "solr"))
113
+
114
+ # Create the Jetty container
115
+ unless File.directory?(Chef::Config[:solr_jetty_path])
116
+ Chef::Log.warn("Initializing the Jetty container")
117
+ solr_jetty_dir = Chef::Resource::Directory.new(Chef::Config[:solr_jetty_path], nil, c.node)
118
+ solr_jetty_dir.recursive(true)
119
+ solr_jetty_dir.run_action(:create)
120
+ solr_jetty_untar = Chef::Resource::Execute.new("untar_jetty", nil, c.node)
121
+ solr_jetty_untar.command("tar zxvf #{File.join(solr_base, 'solr-jetty.tar.gz')}")
122
+ solr_jetty_untar.cwd(Chef::Config[:solr_jetty_path])
123
+ solr_jetty_untar.run_action(:run)
124
+ end
125
+
126
+ # Create the solr home
127
+ unless File.directory?(Chef::Config[:solr_home_path])
128
+ Chef::Log.warn("Initializing Solr home directory")
129
+ solr_home_dir = Chef::Resource::Directory.new(Chef::Config[:solr_home_path], nil, c.node)
130
+ solr_home_dir.recursive(true)
131
+ solr_home_dir.run_action(:create)
132
+ solr_jetty_untar = Chef::Resource::Execute.new("untar_solr_home", nil, c.node)
133
+ solr_jetty_untar.command("tar zxvf #{File.join(solr_base, 'solr-home.tar.gz')}")
134
+ solr_jetty_untar.cwd(Chef::Config[:solr_home_path])
135
+ solr_jetty_untar.run_action(:run)
136
+ end
137
+
138
+ # Create the solr data path
139
+ unless File.directory?(Chef::Config[:solr_data_path])
140
+ Chef::Log.warn("Initializing Solr data directory")
141
+ solr_data_dir = Chef::Resource::Directory.new(Chef::Config[:solr_data_path], nil, c.node)
142
+ solr_data_dir.recursive(true)
143
+ solr_data_dir.run_action(:create)
144
+ end
145
+ end
146
+
147
+ def run_application
148
+ if Chef::Config[:daemonize]
149
+ Chef::Daemon.daemonize("chef-solr")
150
+ end
151
+ Dir.chdir(Chef::Config[:solr_jetty_path]) do
152
+ command = "java -Xmx#{Chef::Config[:solr_heap_size]} -Xms#{Chef::Config[:solr_heap_size]}"
153
+ command << " -Dsolr.data.dir=#{Chef::Config[:solr_data_path]}"
154
+ command << " -Dsolr.solr.home=#{Chef::Config[:solr_home_path]}"
155
+ command << " #{Chef::Config[:solr_java_opts]}" if Chef::Config[:solr_java_opts]
156
+ command << " -jar #{File.join(Chef::Config[:solr_jetty_path], 'start.jar')}"
157
+ Chef::Log.info("Starting Solr with #{command}")
158
+ Kernel.exec(command)
159
+
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,153 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2009 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/log'
20
+ require 'chef/config'
21
+ require 'chef/solr'
22
+ require 'libxml'
23
+ require 'net/http'
24
+
25
+ class Chef
26
+ class Solr
27
+ class Index < Solr
28
+
29
+ def add(id, database, type, item)
30
+ raise ArgumentError, "Object must respond to keys!" unless item.respond_to?(:keys)
31
+ to_index = flatten_and_expand(item)
32
+ to_index["X_CHEF_id_CHEF_X"] = id
33
+ to_index["X_CHEF_database_CHEF_X"] = database
34
+ to_index["X_CHEF_type_CHEF_X"] = type
35
+ solr_add(to_index)
36
+ to_index
37
+ end
38
+
39
+ def delete(id)
40
+ solr_delete_by_id(id)
41
+ end
42
+
43
+ def delete_by_query(query)
44
+ solr_delete_by_query(query)
45
+ end
46
+
47
+ def flatten_and_expand(item, fields=Hash.new, parent=nil)
48
+ item.keys.each do |key|
49
+ # If we have a parent, we want to add the current key as a value
50
+ if parent
51
+ # foo_bar = bar
52
+ set_field_value(fields, parent, key)
53
+ # foo_X = bar, etc.
54
+ make_expando_fields(parent).each do |ex_key|
55
+ set_field_value(fields, ex_key, key)
56
+ end
57
+ end
58
+ case item[key]
59
+ when Hash
60
+ parent_key = parent ? "#{parent}_#{key}" : key
61
+ flatten_and_expand(item[key], fields, parent_key)
62
+ else
63
+ parent_key = parent ? "#{parent}_#{key}" : key
64
+ set_field_value(fields, key, item[key])
65
+ set_field_value(fields, parent_key, item[key]) if parent
66
+ make_expando_fields(parent_key).each do |ex_key|
67
+ set_field_value(fields, ex_key, item[key])
68
+ end
69
+ end
70
+ end
71
+ fields
72
+ end
73
+
74
+ def make_expando_fields(key)
75
+ key = key.to_s
76
+ fields = Array.new
77
+ parts = key.split("_")
78
+ length = parts.length
79
+ parts.each_index do |i|
80
+ beginning = nil
81
+ remainder = nil
82
+ if i == 0
83
+ beginning = "X"
84
+ else
85
+ beginning = parts[0..i-1].join("_")
86
+ end
87
+
88
+ if i == length-1
89
+ remainder = "X"
90
+ else
91
+ remainder = parts[i+1..-1].join("_")
92
+ end
93
+
94
+ if beginning == "X" || remainder == "X"
95
+ unless beginning == "X" && remainder == "X"
96
+ fields << "#{beginning}_#{remainder}"
97
+ end
98
+ else
99
+ fields << "#{beginning}_X_#{remainder}"
100
+ end
101
+ end
102
+ fields
103
+ end
104
+
105
+ def set_field_value(fields, key, value)
106
+ key = key.to_s
107
+ if fields.has_key?(key)
108
+ convert_field_to_array(fields, key, value) unless fields[key].kind_of?(Array)
109
+ add_value_to_field_array(fields, key, value)
110
+ else
111
+ check_value(value)
112
+ if value.kind_of?(Array)
113
+ fields[key] = Array.new
114
+ value.each do |v|
115
+ fields[key] << v.to_s
116
+ end
117
+ else
118
+ fields[key] = value.to_s
119
+ end
120
+ end
121
+ fields
122
+ end
123
+
124
+ def add_value_to_field_array(fields, key, value)
125
+ check_value(value)
126
+ if value.kind_of?(Array)
127
+ value.each do |v|
128
+ check_value(v)
129
+ fields[key] << v.to_s unless fields[key].include?(v.to_s)
130
+ end
131
+ else
132
+ fields[key] << value.to_s unless fields[key].include?(value.to_s)
133
+ end
134
+ fields
135
+ end
136
+
137
+ def convert_field_to_array(fields, key, value)
138
+ if fields[key] != value
139
+ safe = fields[key]
140
+ fields[key] = [ safe ]
141
+ end
142
+ fields
143
+ end
144
+
145
+ def check_value(value)
146
+ raise ArgumentError, "Value must not be a type of hash!" if value.kind_of?(Hash)
147
+ value
148
+ end
149
+
150
+ end
151
+ end
152
+ end
153
+