imagefactory-console 0.4.0

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,77 @@
1
+ #
2
+ # Copyright (C) 2011 Red Hat, Inc.
3
+ # Written by Jason Guiditta <jguiditt@redhat.com>
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; version 2 of the License.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
18
+ # also available at http://www.gnu.org/copyleft/gpl.html.
19
+
20
+
21
+ require 'rubygems'
22
+ require 'rake'
23
+ require 'rake/clean'
24
+ require 'rake/gempackagetask'
25
+ require 'rake/rdoctask'
26
+ require 'rake/testtask'
27
+ require 'spec/rake/spectask'
28
+ require 'rake/rpmtask'
29
+
30
+ RPMBUILD_DIR = "#{File.expand_path('~')}/rpmbuild"
31
+ RPM_SPEC = "rubygem-imagefactory-console.spec"
32
+
33
+ spec = Gem::Specification.new do |s|
34
+ s.name = 'imagefactory-console'
35
+ s.version = '0.4.0'
36
+ s.has_rdoc = true
37
+ #s.extra_rdoc_files = ['README', 'COPYING']
38
+ s.summary = 'QMF Console for Aeolus Image Factory'
39
+ s.description = s.summary
40
+ s.author = 'Jason Guiditta'
41
+ s.email = 'jguiditt@redhat.com'
42
+ # s.executables = ['your_executable_here']
43
+ s.files = %w(Rakefile) + Dir.glob("{bin,lib,spec}/**/*")
44
+ s.require_path = "lib"
45
+ s.bindir = "bin"
46
+ end
47
+
48
+ Rake::GemPackageTask.new(spec) do |p|
49
+ p.gem_spec = spec
50
+ p.need_tar = true
51
+ p.need_zip = true
52
+ end
53
+
54
+ Rake::RDocTask.new do |rdoc|
55
+ files =['lib/**/*.rb'] #'README', 'COPYING',
56
+ rdoc.rdoc_files.add(files)
57
+ #rdoc.main = "README" # page to start on
58
+ rdoc.title = "console Docs"
59
+ rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
60
+ rdoc.options << '--line-numbers'
61
+ end
62
+
63
+ Rake::TestTask.new do |t|
64
+ t.test_files = FileList['test/**/*.rb']
65
+ end
66
+
67
+ Spec::Rake::SpecTask.new do |t|
68
+ t.libs << 'lib'
69
+ t.spec_files = FileList['spec/**/*.rb']
70
+ t.spec_opts = ['--color', '--format nested']
71
+ end
72
+
73
+ Rake::RpmTask.new(RPM_SPEC) do |rpm|
74
+ rpm.need_tar = true
75
+ rpm.package_files.include("lib/*")
76
+ rpm.topdir = "#{RPMBUILD_DIR}"
77
+ end
@@ -0,0 +1,2 @@
1
+ require 'imagefactory/console'
2
+ require 'imagefactory/base_handler'
@@ -0,0 +1,56 @@
1
+ #
2
+ # Copyright (C) 2011 Red Hat, Inc.
3
+ # Written by Jason Guiditta <jguiditt@redhat.com>
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; version 2 of the License.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
18
+ # also available at http://www.gnu.org/copyleft/gpl.html.
19
+
20
+ require 'logger'
21
+
22
+ class BaseHandler
23
+
24
+ def initialize(logger=nil)
25
+ logger(logger)
26
+ end
27
+
28
+ def handle(data)
29
+ logger.debug "====== Type of event: #{data.event}"
30
+ if data.event == 'STATUS'
31
+ logger.debug "calling handle status in base handler"
32
+ handle_status(data)
33
+ elsif data.event == 'FAILURE'
34
+ handle_failed(data)
35
+ end
36
+ end
37
+
38
+ def handle_status(data)
39
+ logger.debug "{data.event}, #{data.new_status}"
40
+ end
41
+
42
+ def handle_failed(data)
43
+ logger.error "#{data.to_s}"
44
+ end
45
+
46
+ protected
47
+ def logger(logger=nil)
48
+ @logger ||= logger
49
+ unless @logger
50
+ @logger = Logger.new(STDOUT)
51
+ @logger.level = Logger::ERROR
52
+ @logger.datetime_format = "%Y-%m-%d %H:%M:%S"
53
+ end
54
+ return @logger
55
+ end
56
+ end
@@ -0,0 +1,251 @@
1
+ #
2
+ # Copyright (C) 2011 Red Hat, Inc.
3
+ # Written by Jason Guiditta <jguiditt@redhat.com>
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; version 2 of the License.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
18
+ # also available at http://www.gnu.org/copyleft/gpl.html.
19
+
20
+ # TODO: figure out what I am doing wrong here that I need this line
21
+ $: << File.expand_path(File.join(File.dirname(__FILE__), "."))
22
+ require 'cqpid'
23
+ require 'qmf2'
24
+ require 'logger'
25
+ require 'base_handler'
26
+
27
+ class ImageFactoryConsole < Qmf2::ConsoleHandler
28
+
29
+ attr_accessor :q, :handler
30
+
31
+ def initialize(args={})
32
+ # @retry_limit = args.include?(:retry_limit) ? args[:retry_limit] : 20
33
+ # @delay = args.include?(:delay) ? args[:delay] : 15
34
+ host = args.include?(:host) ? args[:host] : "localhost"
35
+ port = args.include?(:port) ? args[:port] : 5672
36
+ # url = "amqp://#{host}:#{port}" <- the amqp part here doesnt work yet
37
+ url = "#{host}:#{port}"
38
+ opts = {"reconnect"=>"true"}
39
+ @connection = Cqpid::Connection.new(url, opts)
40
+ @connection.open
41
+ @session = Qmf2::ConsoleSession.new(@connection)
42
+ @session.open
43
+ @session.set_agent_filter("[and, [eq, _vendor, [quote, 'redhat.com']], [eq, _product, [quote, 'imagefactory']]]")
44
+
45
+ if args.include?(:logger)
46
+ @logger = args[:logger]
47
+ else
48
+ @logger = Logger.new(STDOUT)
49
+ @logger.level = Logger::ERROR
50
+ @logger.datetime_format = "%Y-%m-%d %H:%M:%S"
51
+ end
52
+ @handler = args.include?(:handler)? args[:handler]: BaseHandler.new(@logger)
53
+ super(@session)
54
+ end
55
+
56
+ # Call this method to initiate a build, and get back an
57
+ # array of BuildAdaptor objects.
58
+ # * template => String
59
+ # Description of what to build. Can be xml, uuid, or url
60
+ # * targets => Array
61
+ # Represents the names of the clouds to target (ec2, mock, rackspace, etc)
62
+ # * image_id => String
63
+ # The UUID of an image previously built
64
+ # * build_id => String
65
+ # The UUID of a previous build of the image
66
+ # * Returns => an array of BuildAdaptor objects
67
+ #
68
+ def build(template, targets, image='', build='')
69
+ targets = [targets] unless targets.instance_of?(Array)
70
+ # TODO: return error if there is a problem calling this method or getting
71
+ # a factory instance
72
+ begin
73
+ response = factory.build_image(image, build, template, targets)
74
+ build_adaptors(response)
75
+ rescue Exception => e
76
+ @logger.debug "Encountered error in build_image: #{e}"
77
+ return e
78
+ end
79
+ end
80
+
81
+ # Call this method to push an image to a provider, and get back an
82
+ # array of BuildAdaptor objects.
83
+ # * providers => Array
84
+ # Represents the target providers to build for (ec2-us-east, mock1, etc)
85
+ # * credentials => String
86
+ # XML block to be used for registration, upload, etc
87
+ # * image_id => String
88
+ # The UUID of an image previously built
89
+ # * build_id => String
90
+ # The UUID of a previous build of the image
91
+ # * Returns => an array of BuildAdaptor objects
92
+ #
93
+ def push(providers, credentials, image_id, build_id='')
94
+ providers = [providers] unless providers.instance_of?(Array)
95
+ # TODO: return error if there is a problem calling this method or getting
96
+ # a factory instance
97
+ begin
98
+ response = factory.push_image(image_id, build_id, providers, credentials)
99
+ build_adaptors(response)
100
+ rescue Exception => e
101
+ @logger.debug "Encountered error in push_image: #{e}"
102
+ return e
103
+ end
104
+ end
105
+
106
+ # Call this method to import an image
107
+ # array of BuildAdaptor objects.
108
+ # * image => string
109
+ # The uuid of an existing image
110
+ # * build => string
111
+ # the uuid of an existing build, or the empty string
112
+ # * target_identifier => string
113
+ # the target specific image ID
114
+ # * image_desc => string
115
+ # an xml string description of the image
116
+ # * target => string
117
+ # name of the cloud to target
118
+ # * provider => string
119
+ # the name of the cloud provider, often a region
120
+ # Returns => a map including UUIDs as strings for 'target_image', 'build', 'image', 'provider_image'
121
+
122
+ def import_image(image, build, target_identifier, image_description, target, provider)
123
+ # TODO: return error if there is a problem calling this method or getting
124
+ # a factory instance
125
+ begin
126
+ factory.import_image(image, build, target_identifier, image_description, target, provider)
127
+ rescue Exception => e
128
+ @logger.debug "Encountered error in import_image: #{e}"
129
+ return e
130
+ end
131
+ end
132
+
133
+ # <b>DEPRECATED:</b> Please use <tt>build</tt> instead.
134
+ # Call this method to initiate a build, and get back an
135
+ # BuildAdaptor object.
136
+ # * descriptor => String
137
+ # This can be either xml or a url pointing to the xml
138
+ # * target => String
139
+ # Represents the target provider type to build for (ec2, mock, etc)
140
+ # * Returns => a BuildAdaptor object
141
+ #
142
+ def build_image(descriptor, target)
143
+ @logger.warn "[DEPRECATION] 'build_image' is deprecated. Please use 'build' instead."
144
+ # TODO: return error if there is a problem calling this method or getting
145
+ # a factory instance
146
+ begin
147
+ response = factory.image(descriptor, target)
148
+ build_adaptor(response)
149
+ rescue Exception => e
150
+ @logger.debug "Encountered error in build_image: #{e}"
151
+ return e
152
+ end
153
+ end
154
+
155
+ # <b>DEPRECATED:</b> Please use <tt>push</tt> instead.
156
+ # Call this method to push an image to a provider, and get back an
157
+ # BuildAdaptor object.
158
+ # * image_id => String (uuid)
159
+ # * provider => String
160
+ # Represents the target provider to build for (ec2-us-east, mock, etc)
161
+ # * credentials => String
162
+ # XML block to be used for registration, upload, etc
163
+ # * Returns => a BuildAdaptor object
164
+ #
165
+ def push_image(image_id, provider, credentials)
166
+ @logger.warn "[DEPRECATION] 'push_image' is deprecated. Please use 'push' instead."
167
+ # TODO: return error if there is a problem calling this method or getting
168
+ # a factory instance
169
+ begin
170
+ response = factory.provider_image(image_id, provider, credentials)
171
+ build_adaptor(response)
172
+ rescue Exception => e
173
+ @logger.debug "Encountered error in push_image: #{e}"
174
+ return e
175
+ end
176
+ end
177
+
178
+ #TODO: enhance both of these methods to handle multiple agents
179
+ def agent_added(agent)
180
+ @logger.debug "GOT AN AGENT: #{agent} at #{Time.now.utc}"
181
+ @q = agent if agent.product == "imagefactory"
182
+ end
183
+
184
+ def agent_deleted(agent, reason)
185
+ @logger.debug "AGENT GONE: #{agent} at #{Time.now.utc}, because #{reason}"
186
+ unless @q==nil
187
+ @q = nil if (@q.product == agent.product && @q.name.eql?(agent.name))
188
+ end
189
+ end
190
+
191
+ # TODO: handle agent restart events (this will be more useful when
192
+ # restarted agent can recover an in-process build
193
+ def agent_restarted(agent)
194
+ @logger.debug "AGENT RESTARTED: #{agent.product}"
195
+ end
196
+
197
+ # TODO: handle schema updates. This will be more useful when/if
198
+ # we make this a more generic console to talk to different agents.
199
+ def agent_schema_updated(agent)
200
+ @logger.debug "AGENT SCHEMA UPDATED: #{agent.product}"
201
+ end
202
+
203
+ def event_raised(agent, data, timestamp, severity)
204
+ @logger.debug "GOT AN EVENT: #{agent}, #{data} at #{timestamp}"
205
+ @handler.handle(data)
206
+ end
207
+
208
+ def shutdown
209
+ @logger.debug "Closing connections.."
210
+ if @session
211
+ @session.close
212
+ end
213
+ @connection.close
214
+
215
+ #TODO Replace this with some control flow to manage the cancelling of the console handler, atm
216
+ # this code swallows error message generated by closing connection, then cancelling console.
217
+ begin
218
+ self.cancel
219
+ rescue QmfError
220
+ # TODO We should be logging to a file rather than STDOUT, uncomment this code when logging is configured properly
221
+ # Commented out to clean up user output
222
+ #@logger.error "Issue Closing Console Handler"
223
+ end
224
+ end
225
+
226
+ private
227
+
228
+ def factory
229
+ @factory ||= @q.query("{class:ImageFactory, package:'com.redhat.imagefactory'}").first
230
+ end
231
+
232
+ def build_adaptors(response)
233
+ ret = []
234
+ response['build_adaptors'].each do |imgfacaddr|
235
+ query = Qmf2::Query.new(Qmf2::DataAddr.new(imgfacaddr))
236
+ ret << @q.query(query,5).first
237
+ end
238
+ ret
239
+ end
240
+
241
+ def build_adaptor(response)
242
+ @logger.warn "[DEPRECATION] 'build_adaptor' is deprecated. Please use 'build_adaptors' instead."
243
+ imgfacaddr = Qmf2::DataAddr.new(response['build_adaptor'])
244
+ query = Qmf2::Query.new(imgfacaddr)
245
+ @q.query(query,5).first
246
+ end
247
+
248
+ def make_array(a)
249
+ return a ||= [a] unless a.instance_of?(Array)
250
+ end
251
+ end
@@ -0,0 +1,217 @@
1
+ require 'spec_helper'
2
+
3
+ module ImageFactory
4
+ describe ImageFactoryConsole do
5
+ context "needs a real agent running" do
6
+ # for now, these all require an actual agent on the bus
7
+ before(:all) do
8
+ @logger = Logger.new(STDOUT)
9
+ @logger.level = Logger::DEBUG
10
+ @logger.datetime_format = "%Y-%m-%d %H:%M:%S"
11
+ @i = ImageFactoryConsole.new() # Pass this in for more logging: (:logger => @logger)
12
+ @i.start
13
+ # Sadly, this is needed so we wait for an agent to appear.
14
+ # We might be able to extract this somewhere to hold off
15
+ # on tests until we get an agent_added notification
16
+ sleep(5)
17
+ #TODO: take this snippet and make a fixture of some sort to use in tests
18
+ #tmpl = '<template> <name>tmpl1</name> <description>foo</description> <os> <name>Fedora</name>
19
+ # <arch>x86_64</arch> <version>14</version> <install type="url">
20
+ # <url>http://download.fedoraproject.org/pub/fedora/linux/releases/14/Fedora/x86_64/os/</url> </install>
21
+ # </os> <repositories> <repository name="custom"> <url>http://repos.fedorapeople.org/repos/aeolus/demo/webapp/</url>
22
+ # <signed>false</signed> </repository> </repositories> </template>'
23
+ end
24
+
25
+ describe "#q" do
26
+ it "should get an agent set" do
27
+ @i.q.should_not be_nil
28
+ end
29
+ end
30
+
31
+ describe "#build_image" do
32
+ it "should return a build-adaptor with uuid" do
33
+ @i.build_image("<template></template>", "mock").image_id.should_not be_nil
34
+ end
35
+ end
36
+
37
+ describe "#push_image" do
38
+ it "should return a build-adaptor with uuid" do
39
+ @image = @i.build_image("<template></template>", "mock")
40
+ #@i.handler = BaseHandler.new(@logger)
41
+ @i.handler.should_not_receive(:handle_failed)
42
+ @i.push_image(@image.image_id, "mock", "some creds").image_id.should_not be_nil
43
+ end
44
+ end
45
+
46
+ describe "#import_image" do
47
+ it "should return a build-adaptor with uuid" do
48
+ @import = @i.import_image("", "", "ami-test", "<image><name>Test Image</name></image>", "ec2", "ec2-us-east-1")
49
+ is_uuid?(@import['image']).should == true
50
+ is_uuid?(@import['target_image']).should == true
51
+ is_uuid?(@import['build']).should == true
52
+ is_uuid?(@import['provider_image']).should == true
53
+ end
54
+ end
55
+
56
+ describe "#build" do
57
+ it "should return an array of build-adaptors with uuids" do
58
+ @i.build("<template></template>", ["mock"]).each do |adaptor|
59
+ adaptor.image_id.should_not be_nil
60
+ adaptor.image.should_not be_nil
61
+ adaptor.build.should_not be_nil
62
+ end
63
+ end
64
+
65
+ it "should work with single target as string" do
66
+ @i.build("<template></template>", "mock").each do |adaptor|
67
+ adaptor.image_id.should_not be_nil
68
+ adaptor.image.should_not be_nil
69
+ adaptor.build.should_not be_nil
70
+ end
71
+ end
72
+ end
73
+
74
+ describe "#push" do
75
+ it "should return an array of build-adaptors with uuids" do
76
+ @i.build("<template></template>", ["mock"]).each do |adaptor|
77
+ #@i.handler = BaseHandler.new(@logger)
78
+ @i.handler.should_not_receive(:handle_failed)
79
+ @i.push(["mock"], "<provider_credentials/>", adaptor.image).each do |a|
80
+ a.image_id.should_not be_nil
81
+ a.image.should_not be_nil
82
+ a.build.should_not be_nil
83
+ end
84
+ end
85
+ end
86
+
87
+ it "should work with single provider as string" do
88
+ @i.build("<template></template>", "mock").each do |adaptor|
89
+ #@i.handler = BaseHandler.new(@logger)
90
+ @i.handler.should_not_receive(:handle_failed)
91
+ @i.push("mock1", "<provider_credentials/>", adaptor.image).each do |a|
92
+ a.image_id.should_not be_nil
93
+ a.image.should_not be_nil
94
+ a.build.should_not be_nil
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ after(:all) do
101
+ @i.shutdown
102
+ end
103
+ end
104
+
105
+ context "agent is stubbed" do
106
+ before(:each) do
107
+ @agent = mock('agent', :null_object => true)
108
+ @agent.stub(:product).and_return("imagefactory")
109
+ @agent.stub(:name).and_return("redhat.com:imagefactory:b9e131c7-7905-409e-bfb5-dd4848a776a7")
110
+ @output = double('output')
111
+ @i2 = ImageFactoryConsole.new(:logger => @output)
112
+ end
113
+
114
+ describe "#agent_added" do
115
+ it "logs when a new agent appears" do
116
+ @output.should_receive(:debug).with(/GOT AN AGENT/).as_null_object
117
+ @i2.agent_added(@agent)
118
+ end
119
+
120
+ it "stores a reference to that agent if it is a factory" do
121
+ @output.should_receive(:debug).with(/GOT AN AGENT/)
122
+ @i2.agent_added(@agent)
123
+ @i2.q.should respond_to(:product)
124
+ end
125
+ end
126
+
127
+ describe "#agent_deleted" do
128
+ before(:each) do
129
+ @old_agent = mock('agent', :null_object => true)
130
+ @old_agent.stub(:product).and_return("imagefactory")
131
+ @old_agent.stub(:name).and_return("redhat.com:imagefactory:4eb3776e-d91e-4239-9a73-3ab43ecc7e15")
132
+ @output.should_receive(:debug).with(/GOT AN AGENT/)
133
+ @i2.agent_added(@agent)
134
+ end
135
+
136
+ it "logs when an agent is removed" do
137
+ @output.should_receive(:debug).with(/AGENT GONE/).as_null_object
138
+ @i2.agent_deleted(@agent, "aged")
139
+ end
140
+
141
+ it "removes the agent reference if removed agent is the same as console reference" do
142
+ @output.should_receive(:debug).with(/AGENT GONE/).as_null_object
143
+ @i2.agent_deleted(@agent, "aged")
144
+ @i2.q.should be_nil
145
+ end
146
+
147
+ it "does not remove the agent reference if removed agent is the not same as console reference" do
148
+ @output.should_receive(:debug).with(/AGENT GONE/).as_null_object
149
+ @i2.agent_deleted(@old_agent, "aged")
150
+ @i2.q.should_not be_nil
151
+ end
152
+ end
153
+
154
+ describe "#event_raised" do
155
+ before(:each) do
156
+ @data = mock('data', :null_object => true)
157
+ @data.stub(:event).and_return("STATUS")
158
+ end
159
+
160
+ it "should call handle on an event" do
161
+ @output.should_receive(:debug).with(/GOT AN EVENT/)
162
+
163
+ @i2.handler.should_receive(:handle).once
164
+ @i2.event_raised(@agent, @data, Time.now, "horrid")
165
+ end
166
+ end
167
+
168
+ describe "#build_image" do
169
+ it "should gracefully handle errors" do
170
+ @output.should_receive(:debug).with(/Encountered error in build_image/)
171
+ @output.should_receive(:warn).with("[DEPRECATION] 'build_image' is deprecated. Please use 'build' instead.")
172
+ @i2.q=nil
173
+ error = @i2.build_image("<template></template>", "mock")
174
+ error.to_s.should include("undefined method")
175
+ end
176
+ end
177
+
178
+ describe "#push_image" do
179
+ it "should gracefully handle errors" do
180
+ @output.should_receive(:debug).with(/Encountered error in push_image/)
181
+ @output.should_receive(:warn).with("[DEPRECATION] 'push_image' is deprecated. Please use 'push' instead.")
182
+ @i2.q=nil
183
+ error = @i2.push_image(123, "mock", "some creds")
184
+ error.to_s.should include("undefined method")
185
+ end
186
+ end
187
+
188
+ describe "#build" do
189
+ it "should gracefully handle errors" do
190
+ @output.should_receive(:debug).with(/Encountered error in build_image/)
191
+ @i2.q=nil
192
+ error = @i2.build("<template></template>", "mock")
193
+ error.to_s.should include("undefined method")
194
+ end
195
+ end
196
+
197
+ describe "#push" do
198
+ it "should gracefully handle errors" do
199
+ @output.should_receive(:debug).with(/Encountered error in push_image/)
200
+ @i2.q=nil
201
+ error = @i2.push(123, "mock", "some creds")
202
+ error.to_s.should include("undefined method")
203
+ end
204
+ end
205
+
206
+ after(:each) do
207
+ @output.should_receive(:debug).with(/Closing/)
208
+ @i2.shutdown
209
+ end
210
+ end
211
+
212
+ def is_uuid?(test_string)
213
+ regexp = Regexp.new('^[\w]{8}[-][\w]{4}[-][\w]{4}[-][\w]{4}[-][\w]{12}')
214
+ regexp.match(test_string) ? true : false
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,3 @@
1
+ $: << File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
2
+ require 'rubygems'
3
+ require 'imagefactory'
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: imagefactory-console
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
11
+ platform: ruby
12
+ authors:
13
+ - Jason Guiditta
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-07-22 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: QMF Console for Aeolus Image Factory
23
+ email: jguiditt@redhat.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - Rakefile
32
+ - lib/imagefactory.rb
33
+ - lib/imagefactory/base_handler.rb
34
+ - lib/imagefactory/console.rb
35
+ - spec/spec_helper.rb
36
+ - spec/image_factory/console_spec.rb
37
+ has_rdoc: true
38
+ homepage:
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ hash: 3
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.3.7
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: QMF Console for Aeolus Image Factory
71
+ test_files: []
72
+