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