From: Jan Provaznik <jprovazn(a)redhat.com>
https://morazi.usersys.redhat.com/redmine/issues/14
usage: rake dc:import[ec2,mifo,ami-316a8358]
Adds attribute imported to template, it's not possible to build imported templates fro
now.
---
src/app/controllers/builds_controller.rb | 4 ++
src/app/models/image.rb | 41 +++++++++++++++++++++
src/app/models/template.rb | 8 ++++
src/db/migrate/20100830150014_create_templates.rb | 1 +
src/lib/tasks/dc_tasks.rake | 16 ++++++++
src/spec/models/image_spec.rb | 18 +++++++++
6 files changed, 88 insertions(+), 0 deletions(-)
diff --git a/src/app/controllers/builds_controller.rb
b/src/app/controllers/builds_controller.rb
index 6ffdd98..292eeaa 100644
--- a/src/app/controllers/builds_controller.rb
+++ b/src/app/controllers/builds_controller.rb
@@ -16,6 +16,10 @@ class BuildsController < ApplicationController
def new
raise "select template to build" unless id = params[:template_id]
@tpl = Template.find(id)
+ if @tpl.imported
+ flash[:warning] = "Build imported template is not supported"
+ redirect_to templates_path
+ end
@all_targets = Image.available_targets
end
diff --git a/src/app/models/image.rb b/src/app/models/image.rb
index 1619289..3263be7 100644
--- a/src/app/models/image.rb
+++ b/src/app/models/image.rb
@@ -84,4 +84,45 @@ class Image < ActiveRecord::Base
end
return img
end
+
+ def self.import(account, image_id)
+ unless imported_image = account.connect.image(image_id)
+ raise "There is no image with '#{image_id}' id"
+ end
+ if ReplicatedImage.find_by_provider_id_and_provider_image_key(account.provider.id,
image_id)
+ raise "Image '#{image_id}' is already imported"
+ end
+
+ ActiveRecord::Base.transaction do
+ template = Template.new(
+ :name => imported_image.name + '_imported_template',
+ :summary => imported_image.description,
+ :platform_hash => {:platform => 'unknown',
+ :version => 'unknown',
+ :architecture => imported_image.architecture},
+ :complete => true,
+ :uploaded => true,
+ :imported => true
+ )
+ template.save!
+
+ image = Image.new(
+ :name => template.name,
+ :status => 'complete',
+ :target => account.provider.cloud_type,
+ :template_id => template.id
+ )
+ image.save!
+
+ rep = ReplicatedImage.new(
+ :image_id => image.id,
+ :provider_id => account.provider.id,
+ :provider_image_key => image_id,
+ :uploaded => true,
+ :registered => true
+ )
+ rep.save!
+ end
+ imported_image
+ end
end
diff --git a/src/app/models/template.rb b/src/app/models/template.rb
index 74bf208..0a83773 100644
--- a/src/app/models/template.rb
+++ b/src/app/models/template.rb
@@ -89,12 +89,20 @@ class Template < ActiveRecord::Base
add_groups(groups)
end
+ # sets platform info from predefined platform list
def platform=(plat)
write_attribute(:platform, plat)
self.platform_version = platforms[plat]['version'].to_s
self.architecture = platforms[plat]['architecture']
end
+ # sets platform info from hash (used when importing images)
+ def platform_hash=(plat)
+ write_attribute(:platform, plat[:platform])
+ self.platform_version = plat[:version]
+ self.architecture = plat[:architecture]
+ end
+
# packages and groups are virtual attributes
def packages
xml.packages
diff --git a/src/db/migrate/20100830150014_create_templates.rb
b/src/db/migrate/20100830150014_create_templates.rb
index 4e6f89d..4bf569d 100644
--- a/src/db/migrate/20100830150014_create_templates.rb
+++ b/src/db/migrate/20100830150014_create_templates.rb
@@ -11,6 +11,7 @@ class CreateTemplates < ActiveRecord::Migration
t.text :summary
t.boolean :complete, :default => false
t.boolean :uploaded, :default => false
+ t.boolean :imported, :default => false
t.integer :images_count
t.timestamps
end
diff --git a/src/lib/tasks/dc_tasks.rake b/src/lib/tasks/dc_tasks.rake
index 3ae6022..4957f57 100644
--- a/src/lib/tasks/dc_tasks.rake
+++ b/src/lib/tasks/dc_tasks.rake
@@ -79,4 +79,20 @@ namespace :dc do
Rake::Task[:'dc:create_admin_user'].invoke
end
+ desc 'Import images'
+ task :import, [:provider, :account, :image] => :environment do |t, args|
+ unless args.provider and args.account and args.image
+ puts "Usage: rake 'dc:import[provider,account,image]'"
+ exit(1)
+ end
+ unless provider = Provider.find_by_name(args.provider)
+ raise "There is no provider with '#{args.provider}' name"
+ end
+ unless account = provider.cloud_accounts.find_by_label(args.account)
+ raise "There is no account with '#{args.account}' label"
+ end
+ img = Image.import(account, args.image)
+ puts "Imported image '#{img.name}'"
+ end
+
end
diff --git a/src/spec/models/image_spec.rb b/src/spec/models/image_spec.rb
index b1b42a8..f473849 100644
--- a/src/spec/models/image_spec.rb
+++ b/src/spec/models/image_spec.rb
@@ -44,6 +44,7 @@ describe Image do
it "should build image if there is provider and cloud account for specified
target" do
acc = Factory.build(:mock_cloud_account)
+ acc.stub!(:valid_credentials?).and_return(true)
acc.save!
tpl = Factory.build(:template)
tpl.save!
@@ -51,4 +52,21 @@ describe Image do
Image.find(img).should == img
ReplicatedImage.find_by_image_id(img.id).should_not be_nil
end
+
+ it "should import image" do
+ image = OpenStruct.new(:id => 'mock', :name => 'mock',
:description => 'imported mock', :architecture => 'i386')
+ client = mock('DeltaCloud', :null_object => true, :image => image)
+ account = Factory.build(:ec2_cloud_account)
+ account.stub!(:connect).and_return(client)
+ account.stub!(:valid_credentials?).and_return(true)
+ account.save!
+
+ lambda do
+ lambda do
+ lambda do
+ Image.import(account, 'mock').should_not be_nil
+ end.should change(Image, :count).by(1)
+ end.should change(Template, :count).by(1)
+ end.should change(ReplicatedImage, :count).by(1)
+ end
end
--
1.7.2.3