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