From: Jan Provaznik <[email protected]>

---
 src/app/models/image_descriptor.rb                 |   31 +++++
 src/app/models/image_descriptor_target.rb          |    7 +
 src/app/util/image_descriptor_xml.rb               |  136 ++++++++++++++++++++
 src/app/util/repository_manager.rb                 |   98 ++++++++++++++
 .../20100527095400_create_image_descriptors.rb     |   14 ++
 ...100527095428_create_image_descriptor_targets.rb |   14 ++
 src/test/fixtures/image_descriptor_targets.yml     |    7 +
 src/test/fixtures/image_descriptors.yml            |    7 +
 .../unit/helpers/image_descriptor_helper_test.rb   |    4 +
 src/test/unit/image_descriptor_target_test.rb      |    8 +
 src/test/unit/image_descriptor_test.rb             |    8 +
 11 files changed, 334 insertions(+), 0 deletions(-)
 create mode 100644 src/app/models/image_descriptor.rb
 create mode 100644 src/app/models/image_descriptor_target.rb
 create mode 100644 src/app/util/image_descriptor_xml.rb
 create mode 100644 src/app/util/repository_manager.rb
 create mode 100644 src/db/migrate/20100527095400_create_image_descriptors.rb
 create mode 100644 
src/db/migrate/20100527095428_create_image_descriptor_targets.rb
 create mode 100644 src/test/fixtures/image_descriptor_targets.yml
 create mode 100644 src/test/fixtures/image_descriptors.yml
 create mode 100644 src/test/unit/helpers/image_descriptor_helper_test.rb
 create mode 100644 src/test/unit/image_descriptor_target_test.rb
 create mode 100644 src/test/unit/image_descriptor_test.rb

diff --git a/src/app/models/image_descriptor.rb 
b/src/app/models/image_descriptor.rb
new file mode 100644
index 0000000..5567e67
--- /dev/null
+++ b/src/app/models/image_descriptor.rb
@@ -0,0 +1,31 @@
+require 'util/repository_manager'
+require 'util/image_descriptor_xml'
+
+class ImageDescriptor < ActiveRecord::Base
+  has_many :image_descriptor_targets,  :dependent => :destroy
+
+  #TODO: validations
+
+  def update_xml_attributes!(opts = {})
+    doc = ImageDescriptorXML.new(self[:xml])
+    doc.name = opts[:name] if opts[:name]
+    doc.platform = opts[:platform] if opts[:platform]
+    doc.description = opts[:description] if opts[:description]
+    doc.services = opts[:services] if opts[:services]
+    self[:xml] = doc.to_xml
+    @xml = doc
+    save!
+  end
+
+  #def xml=(data)
+  #  self[:xml] = data.to_xml(:skip_types => true, :root => 'image')
+  #  @xml = nil
+  #end
+
+  def xml
+    unless @xml
+      @xml = ImageDescriptorXML.new(self[:xml].to_s)
+    end
+    return @xml
+  end
+end
diff --git a/src/app/models/image_descriptor_target.rb 
b/src/app/models/image_descriptor_target.rb
new file mode 100644
index 0000000..b585a39
--- /dev/null
+++ b/src/app/models/image_descriptor_target.rb
@@ -0,0 +1,7 @@
+class ImageDescriptorTarget < ActiveRecord::Base
+  belongs_to :image_descriptor
+
+  #TODO: validations
+  validates_presence_of :name
+  validates_uniqueness_of :name
+end
diff --git a/src/app/util/image_descriptor_xml.rb 
b/src/app/util/image_descriptor_xml.rb
new file mode 100644
index 0000000..79c835b
--- /dev/null
+++ b/src/app/util/image_descriptor_xml.rb
@@ -0,0 +1,136 @@
+#
+# Copyright (C) 2009 Red Hat, Inc.
+# Written by Jan Provaznik <[email protected]>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.  A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+require 'yaml'
+
+class ImageDescriptorXML
+  def initialize(xmlstr = "")
+    @doc = Nokogiri::XML(xmlstr)
+    # create at least root node if it doesn't exist
+    unless @doc.root
+      @doc.root = Nokogiri::XML::Node.new('image', @doc)
+    end
+    @root = @doc.root.at_xpath('/image')
+  end
+
+  def name=(str)
+    node = get_or_create_node('name')
+    node.content = str
+  end
+
+  def name
+    return get_node_text('name')
+  end
+
+  def platform=(str)
+    unless repconf = platforms[str]
+      raise "unknown platform #{str}"
+    end
+
+    repo_node = get_or_create_node('repos')
+    repo_node.xpath('//repo').remove
+    rnode = get_or_create_node('repo', repo_node)
+    rnode.content = repconf['baseurl']
+
+    node = get_or_create_node('os')
+    node.content = str
+  end
+
+  def platform
+    return get_node_text('os')
+  end
+
+  def platforms
+    unless @platforms
+      @platforms = 
YAML.load_file("#{RAILS_ROOT}/config/image_descriptor_platform_repositories.yml")
+    end
+    return @platforms
+  end
+
+  def description=(str)
+    node = get_or_create_node('description')
+    node.content = str
+  end
+
+  def description
+    return get_node_text('description')
+  end
+
+  def services=(services)
+    service_node = get_or_create_node('services')
+    service_node.xpath('//service').remove
+    repositories = repository_manager.repositories
+    services.each do |s|
+      snode = Nokogiri::XML::Node.new('service', @doc)
+      service_node << snode
+      snode.content = s[0]
+      if repo = repositories[s[0]]
+        add_service_packages(s[0], repo)
+      end
+    end
+    @services = nil
+  end
+
+  def services
+    unless @services
+      @services = []
+      @root.xpath('/image/services/service').each do |s|
+        services << s.text
+      end
+    end
+    return @services
+  end
+
+  def to_xml
+    return @doc.to_xml
+  end
+
+  private
+
+  def get_or_create_node(name, parent = @root)
+    unless node = @root.at_xpath(name)
+      node = Nokogiri::XML::Node.new(name, @doc)
+      parent << node
+    end
+    return node
+  end
+
+  def get_node_text(path)
+    node = @root.at_xpath('/image/' + path)
+    return node ? node.text : nil
+  end
+
+  def add_service_packages(repid, repconf)
+    repo = repository_manager.get_repository(repid)
+    packages = repo.get_packages
+    pkgs_node = get_or_create_node('packages')
+    pkgs_node.xpath('//package').remove
+    packages.each do |package|
+      pnode = get_or_create_node('package', pkgs_node)
+      pnode.content = package[:name]
+    end
+  end
+
+  def repository_manager
+    unless @repository_manager
+      @repository_manager = RepositoryManager.new
+    end
+    return @repository_manager
+  end
+end
diff --git a/src/app/util/repository_manager.rb 
b/src/app/util/repository_manager.rb
new file mode 100644
index 0000000..0041557
--- /dev/null
+++ b/src/app/util/repository_manager.rb
@@ -0,0 +1,98 @@
+#
+# Copyright (C) 2009 Red Hat, Inc.
+# Written by Jan Provaznik <[email protected]>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.  A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+require 'open-uri'
+require 'yaml'
+
+class RepositoryManager
+  class CompsRepository
+    def initialize(baseurl)
+      @baseurl = baseurl
+      @repomd = Nokogiri::XML(open(File.join(@baseurl, 'repodata', 
'repomd.xml')))
+    end
+
+    def get_packages
+      packages = []
+      # FIXME: currently are selected only mandatory and default packages,
+      # optional packages are ingored
+      get_packages_nodes.each do |node|
+        name = node.at_xpath('//xmlns:name/child::text()')
+        group = node.at_xpath('//xmlns:format/rpm:group/child::text()')
+        description = node.at_xpath('//xmlns:description/child::text()')
+        next unless name and group
+        $stderr.puts name.text
+        packages << {
+          :name => name.text,
+          :group => group.text,
+          :description => description ? description.text : nil,
+        }
+      end
+      return packages
+    end
+
+    def get_packages_by_groups
+      groups = {}
+      get_packages.each do |p|
+        group = (groups[p[:group]] ||= [])
+        group << p
+      end
+      return groups
+    end
+
+    private
+
+    def get_packages_nodes
+      unless @packages_nodes
+        data = get_xml(get_primary_url)
+        xml = Nokogiri::XML(data)
+        @packages_nodes = xml.xpath('/xmlns:metadata/xmlns:package')
+      end
+      return @packages_nodes
+    end
+
+    def get_xml(url)
+      xml_data = open(url)
+      if url =~ /\.gz$/
+        return Zlib::GzipReader.new(xml_data).read
+      else
+        return xml_data
+      end
+    end
+
+    def get_primary_url
+      location = 
@repomd.xpath('/xmlns:repomd/xmlns:da...@type="primary"]/xmlns:location').first
+      raise "location for primary data not found" unless location
+      return File.join(@baseurl, location['href'])
+    end
+  end
+
+  def initialize
+    @config = 
YAML.load_file("#{RAILS_ROOT}/config/image_descriptor_package_repositories.yml")
+  end
+
+  def get_repository(repository_id)
+    repo = @config[repository_id]
+    raise "Repository '#{repository_id}' doesn't exist" unless repo
+    return CompsRepository.new(repo['baseurl'])
+  end
+
+  def repositories
+    return @config
+  end
+end
diff --git a/src/db/migrate/20100527095400_create_image_descriptors.rb 
b/src/db/migrate/20100527095400_create_image_descriptors.rb
new file mode 100644
index 0000000..9f91629
--- /dev/null
+++ b/src/db/migrate/20100527095400_create_image_descriptors.rb
@@ -0,0 +1,14 @@
+class CreateImageDescriptors < ActiveRecord::Migration
+  def self.up
+    create_table :image_descriptors do |t|
+      t.binary :xml, :null => false
+      t.string :uri
+      t.boolean :complete
+      t.timestamps
+    end
+  end
+
+  def self.down
+    drop_table :image_descriptors
+  end
+end
diff --git a/src/db/migrate/20100527095428_create_image_descriptor_targets.rb 
b/src/db/migrate/20100527095428_create_image_descriptor_targets.rb
new file mode 100644
index 0000000..3cbe78f
--- /dev/null
+++ b/src/db/migrate/20100527095428_create_image_descriptor_targets.rb
@@ -0,0 +1,14 @@
+class CreateImageDescriptorTargets < ActiveRecord::Migration
+  def self.up
+    create_table :image_descriptor_targets do |t|
+      t.string :name, :null => false
+      t.integer :build_id
+      t.integer :image_descriptor_id
+      t.timestamps
+    end
+  end
+
+  def self.down
+    drop_table :image_descriptor_targets
+  end
+end
diff --git a/src/test/fixtures/image_descriptor_targets.yml 
b/src/test/fixtures/image_descriptor_targets.yml
new file mode 100644
index 0000000..5bf0293
--- /dev/null
+++ b/src/test/fixtures/image_descriptor_targets.yml
@@ -0,0 +1,7 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+
+# one:
+#   column: value
+#
+# two:
+#   column: value
diff --git a/src/test/fixtures/image_descriptors.yml 
b/src/test/fixtures/image_descriptors.yml
new file mode 100644
index 0000000..5bf0293
--- /dev/null
+++ b/src/test/fixtures/image_descriptors.yml
@@ -0,0 +1,7 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+
+# one:
+#   column: value
+#
+# two:
+#   column: value
diff --git a/src/test/unit/helpers/image_descriptor_helper_test.rb 
b/src/test/unit/helpers/image_descriptor_helper_test.rb
new file mode 100644
index 0000000..0c9addf
--- /dev/null
+++ b/src/test/unit/helpers/image_descriptor_helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class ImageDescriptorHelperTest < ActionView::TestCase
+end
diff --git a/src/test/unit/image_descriptor_target_test.rb 
b/src/test/unit/image_descriptor_target_test.rb
new file mode 100644
index 0000000..826391b
--- /dev/null
+++ b/src/test/unit/image_descriptor_target_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class ImageDescriptorTargetTest < ActiveSupport::TestCase
+  # Replace this with your real tests.
+  test "the truth" do
+    assert true
+  end
+end
diff --git a/src/test/unit/image_descriptor_test.rb 
b/src/test/unit/image_descriptor_test.rb
new file mode 100644
index 0000000..1b8e292
--- /dev/null
+++ b/src/test/unit/image_descriptor_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class ImageDescriptorTest < ActiveSupport::TestCase
+  # Replace this with your real tests.
+  test "the truth" do
+    assert true
+  end
+end
-- 
1.7.0.1

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

Reply via email to