chef-solr 0.8.2

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.
@@ -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
+