From: Jan Provaznik <jprov...@redhat.com>

(see https://fedorahosted.org/pulp/wiki/Install for pulp setup)
---
 src/app/util/image_descriptor_xml.rb               |    9 +-
 src/app/util/repository_manager.rb                 |  165 ++++----------------
 .../util/repository_manager/abstract_repository.rb |    9 +
 .../util/repository_manager/comps_repository.rb    |  116 ++++++++++++++
 src/app/util/repository_manager/pulp_repository.rb |   71 +++++++++
 .../image_descriptor_package_repositories.yml      |   21 ++-
 6 files changed, 246 insertions(+), 145 deletions(-)
 create mode 100644 src/app/util/repository_manager/abstract_repository.rb
 create mode 100644 src/app/util/repository_manager/comps_repository.rb
 create mode 100644 src/app/util/repository_manager/pulp_repository.rb

diff --git a/src/app/util/image_descriptor_xml.rb 
b/src/app/util/image_descriptor_xml.rb
index d9b8348..2100109 100644
--- a/src/app/util/image_descriptor_xml.rb
+++ b/src/app/util/image_descriptor_xml.rb
@@ -216,9 +216,9 @@ class ImageDescriptorXML
     rnode = get_or_create_node('repo', repo_node)
     rnode.content = repconf['baseurl']
 
-    repository_manager.repositories.each do |rname, repo|
+    repository_manager.repositories.each do |repo|
       rnode = get_or_create_node('repo', repo_node)
-      rnode.content = repo['baseurl']
+      rnode.content = repo.baseurl
     end
   end
 
@@ -246,9 +246,6 @@ class ImageDescriptorXML
   end
 
   def repository_manager
-    unless @repository_manager
-      @repository_manager = RepositoryManager.new
-    end
-    return @repository_manager
+    @repository_manager ||= RepositoryManager.new
   end
 end
diff --git a/src/app/util/repository_manager.rb 
b/src/app/util/repository_manager.rb
index 05cc5da..1075bf4 100644
--- a/src/app/util/repository_manager.rb
+++ b/src/app/util/repository_manager.rb
@@ -17,145 +17,24 @@
 # 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'
+require 'util/repository_manager/comps_repository'
+require 'util/repository_manager/pulp_repository'
 
 class RepositoryManager
-  class CompsRepository
-    def initialize(baseurl, id)
-      @id = id
-      @baseurl = baseurl
-    end
-
-    def get_packages
-      packages = []
-      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
-        packages << {
-          :repository_id => @id,
-          :name => name.text,
-          :group => group.text,
-          :description => description ? description.text : '',
-        }
-      end
-      return packages
-    end
-
-    def get_groups
-      groups = {}
-      get_groups_nodes.each do |g|
-        pkgs = get_group_packages(g)
-        next if pkgs.empty?
-        name = g.at_xpath('name').text
-        groups[name] = {
-          :name => name,
-          :description => (t = g.at_xpath('description')) ? t.text : '',
-          :packages => pkgs,
-        }
-      end
-      return groups
-    end
-
-    def download_xml(type)
-      begin
-        url = get_url(type)
-      rescue
-        return ''
-      end
-
-      xml_data = open(url)
-      if url =~ /\.gz$/
-        return Zlib::GzipReader.new(xml_data).read
-      else
-        return xml_data.read
-      end
-    end
-
-    private
-
-    def get_xml(type)
-      # FIXME: I'm not sure config is right dir for automatic storing of
-      # xml files, but this should be temporary solution until Image Repo is
-      # done
-      xml_dir = "#{RAILS_ROOT}/config/image_descriptor_xmls"
-      xml_file = "#{xml_dir}/#...@id}.#{type}.xml"
-      begin
-        return File.open(xml_file) { |f| f.read }
-      rescue
-        xml = download_xml(type)
-        Dir.mkdir(xml_dir) unless File.directory?(xml_dir)
-        File.open(xml_file, 'w') { |f| f.write xml }
-        return xml
-      end
-    end
-
-    def get_group_packages(group_node)
-      pkgs = {}
-      group_node.xpath('packagelist/packagereq').each do |p|
-        pkgs[p.text] = p.attr('type')
-      end
-      return pkgs
-    end
-
-    def get_packages_nodes
-      unless @packages_nodes
-        data = get_xml('primary')
-        xml = Nokogiri::XML(data)
-        @packages_nodes = xml.xpath('/xmlns:metadata/xmlns:package')
-      end
-      return @packages_nodes
-    end
+  attr_reader :repositories
 
-    def get_groups_nodes
-      unless @groups_nodes
-        data = get_xml('group')
-        xml = Nokogiri::XML(data)
-        @groups_nodes = xml.xpath('/comps/group')
-      end
-      return @groups_nodes
-    end
-
-    def get_url(type)
-      if type == 'repomd'
-        return File.join(@baseurl, 'repodata', 'repomd.xml')
-      else
-        location = 
repomd.xpath("/xmlns:repomd/xmlns:da...@type=\"#{type}\"]/xmlns:location").first
-        raise "location for #{type} data not found" unless location
-        return File.join(@baseurl, location['href'])
-      end
-    end
-
-    def repomd
-      unless @repomd
-        @repomd = Nokogiri::XML(get_xml('repomd'))
-      end
-      return @repomd
-    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'], repository_id)
-  end
-
-  def repositories
-    return @config
+  def initialize(opts = {})
+    @config = opts[:config]
+    @repositories = get_repositories
   end
 
   def all_groups(repository = nil)
     unless @all_groups
       @all_groups = {}
-      repositories.keys.each do |r|
-        next if repository and repository != 'all' and repository != r
-        get_repository(r).get_groups.each do |group, data|
+      repositories.each do |r|
+        next if repository and repository != 'all' and repository != r.id
+        r.groups.each do |group, data|
           if @all_groups[group]
             @all_groups[group][:packages].merge!(data[:packages])
           else
@@ -170,11 +49,31 @@ class RepositoryManager
   def all_packages(repository = nil)
     unless @all_packages
       @all_packages = []
-      repositories.keys.each do |r|
-        next if repository and repository != 'all' and repository != r
-        @all_packages += get_repository(r).get_packages
+      repositories.each do |r|
+        next if repository and repository != 'all' and repository != r.id
+        @all_packages += r.packages
       end
     end
     return @all_packages
   end
+
+  private
+
+  def get_repositories
+    repositories = []
+    if config
+      config.each do |rep|
+        if rep['type'] == 'xml'
+          repositories << CompsRepository.new(rep)
+        elsif rep['type'] == 'pulp'
+          repositories += PulpRepository.repositories(rep)
+        end
+      end
+    end
+    return repositories
+  end
+
+  def config
+    @config ||= 
YAML.load_file("#{RAILS_ROOT}/config/image_descriptor_package_repositories.yml")
+  end
 end
diff --git a/src/app/util/repository_manager/abstract_repository.rb 
b/src/app/util/repository_manager/abstract_repository.rb
new file mode 100644
index 0000000..ab35d04
--- /dev/null
+++ b/src/app/util/repository_manager/abstract_repository.rb
@@ -0,0 +1,9 @@
+class AbstractRepository
+  attr_reader :id, :name, :baseurl
+
+  def initialize(conf)
+    @id = conf['id']
+    @name = conf['name']
+    @baseurl = conf['baseurl']
+  end
+end
diff --git a/src/app/util/repository_manager/comps_repository.rb 
b/src/app/util/repository_manager/comps_repository.rb
new file mode 100644
index 0000000..d7e192a
--- /dev/null
+++ b/src/app/util/repository_manager/comps_repository.rb
@@ -0,0 +1,116 @@
+require 'util/repository_manager/abstract_repository'
+require 'open-uri'
+
+class CompsRepository < AbstractRepository
+  def initialize(conf)
+    super
+    @baseurl = conf['baseurl']
+  end
+
+  def packages
+    packages = []
+    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
+      packages << {
+        :repository_id => @id,
+        :name => name.text,
+        :description => description ? description.text : '',
+      }
+    end
+    return packages
+  end
+
+  def groups
+    groups = {}
+    get_groups_nodes.each do |g|
+      pkgs = get_group_packages(g)
+      next if pkgs.empty?
+      name = g.at_xpath('name').text
+      groups[name] = {
+        :name => name,
+        :description => (t = g.at_xpath('description')) ? t.text : '',
+        :packages => pkgs,
+      }
+    end
+    return groups
+  end
+
+  def download_xml(type)
+    begin
+      url = get_url(type)
+    rescue
+      return ''
+    end
+
+    xml_data = open(url)
+    if url =~ /\.gz$/
+      return Zlib::GzipReader.new(xml_data).read
+    else
+      return xml_data.read
+    end
+  end
+
+  private
+
+  def get_xml(type)
+    # FIXME: I'm not sure config is right dir for automatic storing of
+    # xml files, but this should be temporary solution until Image Repo is
+    # done
+    xml_dir = "#{RAILS_ROOT}/config/image_descriptor_xmls"
+    xml_file = "#{xml_dir}/#...@id}.#{type}.xml"
+    begin
+      return File.open(xml_file) { |f| f.read }
+    rescue
+      xml = download_xml(type)
+      Dir.mkdir(xml_dir) unless File.directory?(xml_dir)
+      File.open(xml_file, 'w') { |f| f.write xml }
+      return xml
+    end
+  end
+
+  def get_group_packages(group_node)
+    pkgs = {}
+    group_node.xpath('packagelist/packagereq').each do |p|
+      pkgs[p.text] = p.attr('type')
+    end
+    return pkgs
+  end
+
+  def get_packages_nodes
+    unless @packages_nodes
+      data = get_xml('primary')
+      xml = Nokogiri::XML(data)
+      @packages_nodes = xml.xpath('/xmlns:metadata/xmlns:package')
+    end
+    return @packages_nodes
+  end
+
+  def get_groups_nodes
+    unless @groups_nodes
+      data = get_xml('group')
+      xml = Nokogiri::XML(data)
+      @groups_nodes = xml.xpath('/comps/group')
+    end
+    return @groups_nodes
+  end
+
+  def get_url(type)
+    if type == 'repomd'
+      return File.join(@baseurl, 'repodata', 'repomd.xml')
+    else
+      location = 
repomd.xpath("/xmlns:repomd/xmlns:da...@type=\"#{type}\"]/xmlns:location").first
+      raise "location for #{type} data not found" unless location
+      return File.join(@baseurl, location['href'])
+    end
+  end
+
+  def repomd
+    unless @repomd
+      @repomd = Nokogiri::XML(get_xml('repomd'))
+    end
+    return @repomd
+  end
+end
diff --git a/src/app/util/repository_manager/pulp_repository.rb 
b/src/app/util/repository_manager/pulp_repository.rb
new file mode 100644
index 0000000..4edb1ff
--- /dev/null
+++ b/src/app/util/repository_manager/pulp_repository.rb
@@ -0,0 +1,71 @@
+require 'restclient'
+require 'json'
+require 'util/repository_manager/abstract_repository'
+
+class PulpRepository < AbstractRepository
+  class WrappedRestClient
+    def self.method_missing(method, *args)
+      begin
+        JSON.parse(RestClient.send(method, *args))
+      rescue Errno::ECONNREFUSED
+        raise "pulp repository: connection failed (#{args.first})"
+      rescue RestClient::ResourceNotFound
+        raise "pulp repository: resource not found (#{args.first})"
+      rescue JSON::ParserError
+        raise "pulp repository: failed to parse response (#{args.first})"
+      end
+    end
+  end
+
+  def self.repositories(conf)
+    WrappedRestClient.get(File.join(conf['baseurl'], "/repositories/")).map do 
|r|
+      next if conf['except'] and conf['except'].include?(r['id'])
+      PulpRepository.new(r.merge('baseurl' => conf['baseurl']))
+    end.compact
+  end
+
+  def initialize(conf)
+    super
+    @packages_url = File.join(strip_path(@baseurl), conf['packages'])
+    @groups_url = File.join(strip_path(@baseurl), conf['packagegroups'])
+  end
+
+  def packages
+    packages = []
+    WrappedRestClient.get(@packages_url).each_value do |info|
+      packages << {
+        :repository_id => @id,
+        :name => info['name'],
+        :description => info['description'],
+      }
+    end
+    return packages
+  end
+
+  def groups
+    groups = {}
+    #JSON.parse(`GET "#...@groups_url}"`).each do |id, info|
+    WrappedRestClient.get(@groups_url, {}).each do |id, info|
+      pkgs = {}
+      info['default_package_names'].each {|p| pkgs[p] = 'default'}
+      info['optional_package_names'].each {|p| pkgs[p] = 'optional'}
+      info['mandatory_package_names'].each {|p| pkgs[p] = 'mandatory'}
+      next if pkgs.empty?
+      name = info['name']
+      groups[name] = {
+        :name => name,
+        :description => info['description'].to_s,
+        :packages => pkgs,
+      }
+    end
+    return groups
+  end
+
+  private
+
+  def strip_path(url)
+    uri = URI.parse(url)
+    uri.path = ''
+    uri.to_s
+  end
+end
diff --git a/src/config/image_descriptor_package_repositories.yml 
b/src/config/image_descriptor_package_repositories.yml
index 40335ea..60dcec4 100644
--- a/src/config/image_descriptor_package_repositories.yml
+++ b/src/config/image_descriptor_package_repositories.yml
@@ -1,6 +1,15 @@
-fedora:
-  name: Fedora
-  baseurl: 
http://download.fedoraproject.org/pub/fedora/linux/releases/11/Everything/x86_64/os/
-jboss:
-  name: JBoss
-  baseurl: http://repo.oddthesis.org/cirras/packages/fedora/11/RPMS/noarch/
+#-
+#  id: fedora
+#  name: Fedora
+#  baseurl: 
http://download.fedoraproject.org/pub/fedora/linux/releases/11/Everything/x86_64/os/
+#  type: xml
+#
+#-
+#  id: jboss
+#  name: JBoss
+#  baseurl: http://repo.oddthesis.org/cirras/packages/fedora/11/RPMS/noarch/
+#  type: xml
+#
+-
+  baseurl: https://admin:ad...@localhost/pulp/api/
+  type: pulp
-- 
1.7.2.2

_______________________________________________
deltacloud-devel mailing list
deltacloud-devel@lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to