From: Jan Provaznik <[email protected]>

import of single image:
  rake dc:import[ec2,uid,password,ami-20b65349]

import of multiple images by passing yaml file:
rake dc:bulk_import[ec2,uid,password,/tmp/list.yml]

yaml file looks like (currently only ID, do we want other attrs?):
-
  id: ari-faf01293
-
  id: ari-fcfd1095
---
 src/app/models/image.rb       |   76 +++++++++++++++++++++++++++++++++++++++++
 src/app/models/template.rb    |    8 ++++
 src/lib/tasks/dc_tasks.rake   |   30 ++++++++++++++++
 src/spec/models/image_spec.rb |   18 ++++++++++
 4 files changed, 132 insertions(+), 0 deletions(-)

diff --git a/src/app/models/image.rb b/src/app/models/image.rb
index 5ca3fd4..f6b10ac 100644
--- a/src/app/models/image.rb
+++ b/src/app/models/image.rb
@@ -85,4 +85,80 @@ class Image < ActiveRecord::Base
     end
     return img
   end
+
+  def self.single_import(providername, username, password, image_id)
+    account = Image.get_account(providername, username, password)
+    Image.import(account, image_id)
+  end
+
+  def self.bulk_import(providername, username, password, images)
+    account = Image.get_account(providername, username, password)
+    images.each do |image|
+      begin
+        Image.import(account, image['id'])
+        $stderr.puts "imported image with id '#{image['id']}'"
+      rescue
+        $stderr.puts "failed to import image with id '#{image['id']}'"
+      end
+    end
+  end
+
+  def self.import(account, image_id)
+    unless raw_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
+
+    image = nil
+    ActiveRecord::Base.transaction do
+      template = Template.new(
+        :name             => raw_image.name + '_template',
+        :summary          => raw_image.description,
+        :platform_hash    => {:platform => 'unknown',
+                              :version => 'unknown',
+                              :architecture => raw_image.architecture},
+        :complete         => true,
+        :uploaded         => true,
+        :imported         => true
+      )
+      template.save!
+
+      image = Image.new(
+        :name         => raw_image.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
+    image
+  end
+
+  private
+
+  def self.get_account(providername, username, password)
+    unless provider = Provider.find_by_name(providername)
+      raise "There is not provider with name '#{providername}'"
+    end
+
+    account = CloudAccount.new(:provider => provider, :username => username, 
:password => password)
+
+    unless account.valid_credentials?
+      raise "Invalid credentials for provider '#{providername}'"
+    end
+
+    return account
+  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/lib/tasks/dc_tasks.rake b/src/lib/tasks/dc_tasks.rake
index 3ae6022..495f3aa 100644
--- a/src/lib/tasks/dc_tasks.rake
+++ b/src/lib/tasks/dc_tasks.rake
@@ -79,4 +79,34 @@ namespace :dc do
     Rake::Task[:'dc:create_admin_user'].invoke
   end
 
+  desc 'Import images'
+  task :import, [:provider, :username, :password, :image] => :environment do 
|t, args|
+    unless args.provider and args.username and args.password and args.image
+      puts "Usage: rake 'dc:import[provider,username,password,imageid]'"
+      exit(1)
+    end
+    #account = get_account(args.provider, args.account)
+    img = Image.single_import(args.provider, args.username, args.password, 
args.image)
+    puts "Imported image with id '#{args.image}'"
+  end
+
+  desc 'Bulk import images'
+  task :bulk_import, [:provider, :username, :password, :yml_file] => 
:environment do |t, args|
+    unless args.provider and args.username and args.password and args.yml_file
+      puts "Usage: rake 'dc:import[provider,username,password,yml_file]'"
+      exit(1)
+    end
+    list = YAML.load_file(args.yml_file)
+    Image.bulk_import(args.provider, args.username, args.password, list)
+  end
+
+  def get_account(provider_name, account_name)
+    unless provider = Provider.find_by_name(provider_name)
+      raise "There is no provider with '#{provider_name}' name"
+    end
+    unless account = provider.cloud_accounts.find_by_label(account_name)
+      raise "There is no account with '#{account_name}' label"
+    end
+    account
+  end
 end
diff --git a/src/spec/models/image_spec.rb b/src/spec/models/image_spec.rb
index 04c8171..58cbc10 100644
--- a/src/spec/models/image_spec.rb
+++ b/src/spec/models/image_spec.rb
@@ -43,6 +43,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!
@@ -50,4 +51,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

_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to