pulp 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +19 -0
  4. data/Gemfile.lock +42 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +147 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/examples/repositories.rb +205 -0
  10. data/examples/test_pulp.yml +4 -0
  11. data/lib/pulp.rb +26 -0
  12. data/lib/pulp/cds.rb +25 -0
  13. data/lib/pulp/common/debug.rb +37 -0
  14. data/lib/pulp/common/lifecycle.rb +166 -0
  15. data/lib/pulp/common/lifecycle/create.rb +16 -0
  16. data/lib/pulp/common/lifecycle/delete.rb +23 -0
  17. data/lib/pulp/common/lifecycle/get.rb +22 -0
  18. data/lib/pulp/common/lifecycle/update.rb +23 -0
  19. data/lib/pulp/connection/base.rb +84 -0
  20. data/lib/pulp/connection/handler.rb +59 -0
  21. data/lib/pulp/consumer.rb +23 -0
  22. data/lib/pulp/consumergroup.rb +22 -0
  23. data/lib/pulp/content.rb +14 -0
  24. data/lib/pulp/distribution.rb +11 -0
  25. data/lib/pulp/errata.rb +17 -0
  26. data/lib/pulp/event.rb +8 -0
  27. data/lib/pulp/filter.rb +19 -0
  28. data/lib/pulp/package.rb +20 -0
  29. data/lib/pulp/package_group.rb +8 -0
  30. data/lib/pulp/package_group_category.rb +7 -0
  31. data/lib/pulp/repository.rb +114 -0
  32. data/lib/pulp/service.rb +51 -0
  33. data/lib/pulp/task.rb +37 -0
  34. data/lib/pulp/task_history.rb +10 -0
  35. data/lib/pulp/task_snapshot.rb +9 -0
  36. data/lib/pulp/user.rb +12 -0
  37. data/spec/pulp/common/debug_spec.rb +42 -0
  38. data/spec/pulp/common/lifecycle/create_spec.rb +21 -0
  39. data/spec/pulp/common/lifecycle/delete_spec.rb +40 -0
  40. data/spec/pulp/common/lifecycle/get_spec.rb +42 -0
  41. data/spec/pulp/common/lifecycle/update_spec.rb +48 -0
  42. data/spec/pulp/common/lifecycle_spec.rb +393 -0
  43. data/spec/pulp/connection/base_spec.rb +312 -0
  44. data/spec/pulp/connection/handler_spec.rb +123 -0
  45. data/spec/pulp/content_spec.rb +21 -0
  46. data/spec/pulp/package_spec.rb +14 -0
  47. data/spec/pulp/repository_spec.rb +14 -0
  48. data/spec/pulp/service_spec.rb +85 -0
  49. data/spec/pulp/task_spec.rb +48 -0
  50. data/spec/pulp_spec.rb +4 -0
  51. data/spec/spec.opts +6 -0
  52. data/spec/spec_helper.rb +32 -0
  53. metadata +252 -0
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem "rest-client", "~> 1.6.7"
7
+ gem "activesupport"
8
+ gem "json"
9
+ gem "i18n"
10
+
11
+ # Add dependencies to develop your gem here.
12
+ # Include everything needed to run rake, tests, features, etc.
13
+ group :development do
14
+ gem "rspec", "~> 2.3.0"
15
+ gem "bundler", "~> 1.0.0"
16
+ gem "jeweler", "~> 1.6.4"
17
+ gem "rcov", ">= 0"
18
+ gem "mocha"
19
+ end
@@ -0,0 +1,42 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.1.0)
5
+ diff-lcs (1.1.3)
6
+ git (1.2.5)
7
+ i18n (0.6.0)
8
+ jeweler (1.6.4)
9
+ bundler (~> 1.0)
10
+ git (>= 1.2.5)
11
+ rake
12
+ json (1.6.4)
13
+ metaclass (0.0.1)
14
+ mime-types (1.16)
15
+ mocha (0.10.0)
16
+ metaclass (~> 0.0.1)
17
+ rake (0.9.2)
18
+ rcov (0.9.11)
19
+ rest-client (1.6.7)
20
+ mime-types (>= 1.16)
21
+ rspec (2.3.0)
22
+ rspec-core (~> 2.3.0)
23
+ rspec-expectations (~> 2.3.0)
24
+ rspec-mocks (~> 2.3.0)
25
+ rspec-core (2.3.1)
26
+ rspec-expectations (2.3.0)
27
+ diff-lcs (~> 1.1.2)
28
+ rspec-mocks (2.3.0)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ activesupport
35
+ bundler (~> 1.0.0)
36
+ i18n
37
+ jeweler (~> 1.6.4)
38
+ json
39
+ mocha
40
+ rcov
41
+ rest-client (~> 1.6.7)
42
+ rspec (~> 2.3.0)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 mh
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,147 @@
1
+ = ruby-pulp
2
+
3
+ A ruby gem to talk to a pulp server using its REST-api.
4
+
5
+ Pulp is juicy software repository managment and so we want to talk to it in a juicy language.
6
+
7
+ The library provides easy to use, `activerecord`-like objects for the different resources you can manage
8
+ via Pulp's REST-Api. So that if you for example like to create a new repository you need to do only the
9
+ following:
10
+
11
+ repo = Pulp::Repository.create(
12
+ :id => 'pulp-rhel6-x86_64',
13
+ :name => 'Example Repository for pulp on RHEL 6 x86_64',
14
+ :arch => 'x86_64',
15
+ :feed => "http://repos.fedorapeople.org/repos/pulp/pulp/6Server/x86_64/",
16
+ :relative_path => "pulp_test/#{random_id}",
17
+ :sync_schedule => ''
18
+ )
19
+
20
+ You can then search by any field that is allowed as search field for that repository:
21
+
22
+ Pulp::Repository.find_by_arch('x86_64').find{{|r| r.name == 'pulp-rhel6-x86_64' }
23
+ puts repo.name
24
+
25
+ Or simply get it by its id:
26
+
27
+ repo = Pulp::Repository.get('pulp-rhel6-x86_64')
28
+ puts repo.name
29
+
30
+ If you don't like it anymore, you can simply delete it:
31
+
32
+ repo.delete
33
+
34
+ As you would know things from working with activerecord.
35
+
36
+ == Disclaimer
37
+
38
+ Not all parts have already been used and tested against a real pulp server. Pulp is still a piece of software
39
+ that is moving very quickly forward. So use it only with the latest pulp version, and it might be that things
40
+ are broken.
41
+
42
+ Bug reports / Pull requests (including tests) are welcome! See below.
43
+
44
+ == Configuration
45
+
46
+ When requiring the gem, it is looking for the environment variable PULP_YML, if it points to an existing yaml file,
47
+ or whether a yaml file exist at `~/.pulp.yaml` or `/etc/pulp/pulp.yaml`. It then tries to configure itself with
48
+ the options from that file.
49
+
50
+ However, you can also later configure the access credentils with:
51
+
52
+ Pulp::Connection::Handler.hostname = 'localhost'
53
+ Pulp::Connection::Handler.username = 'admin'
54
+ Pulp::Connection::Handler.password = 'admin'
55
+
56
+ == Examples
57
+
58
+ A few examples can be found in `examples/`. The main one `repositories.rb` can easily be run agains a local
59
+ pulp server, that does have internet connection.
60
+ It will generate a new repository, clone from it, and will cleanup at the end. Give it a shot, otherwise even
61
+ reading the code, might give you already an idea of how to use this gem.
62
+
63
+ == Defining resources
64
+
65
+ This gem comes with a little framework behind that provides various methods to create the classes for the
66
+ resources in a very declarative manner. The main idea is that a Pulp resource inherits from `Pulp::Connection::Base`
67
+ and then declares its field and their behavior with the various class methods. These fields and actions are mainly
68
+ take from the existing PULP-Api documentation: https://fedorahosted.org/pulp/wiki/UGRESTAPI
69
+
70
+ The idea is to make it very easy to declare the fields and actions of resources and to not let you rewrite a lot
71
+ of common code to just interact with the REST-API. What follows is a short description of the most important fields.
72
+
73
+ By default we assume that the objects have an `id` field that is their unique identifier.
74
+
75
+ We can then define further fields of the resource, with the `pulp_field(s)` method. For example for a
76
+ `Pulp::Repository` we can define the fields `arch`, `name`, `release`.
77
+
78
+ module Pulp
79
+ class Repository
80
+ ...
81
+ pulp_fields :arch, :name, :release
82
+ ...
83
+ end
84
+ end
85
+
86
+ puts repo.name
87
+ repo.name = 'some other name'
88
+ repo.save # will to an UPDATE including the new name
89
+
90
+ You can also execute various actions on the different pulp resources. These actions can be declared using `pulp_action`:
91
+
92
+ module Pulp
93
+ class Repository
94
+ ...
95
+ pulp_action :create_packagegroupcategory, :returns => Pulp::PackageGroupCategory
96
+ pulp_action :delete_errata, :parse => false
97
+ ...
98
+ end
99
+ end
100
+
101
+ This means that you can use `repo.create_packagegroupcategory({...})` and pass it a hash of options as described in the API
102
+ documentation and it will return the newly created `Pulp::PackageGroupCategory`. `repo.delete_errata({...})` will delete an
103
+ errata, but won't parse the actual result, as it might simply return 'true' or 'false'. Attention: the last part might change
104
+ within the near future of pulp.
105
+
106
+ A `pulp_update_action` can be used to describe update methods for various special (usually locked fields).
107
+
108
+ Any other methods can simple be added added using short methods, for example like, getting all the schedules or deleting a
109
+ node of a repository:
110
+
111
+ module Pulp
112
+ class Repository
113
+ ...
114
+ def self.schedules
115
+ self.base_get('schedules/')
116
+ end
117
+ def delete_note(key)
118
+ self.class.base_unparsed_delete("notes/#{key}/",self.id)
119
+ refresh
120
+ self
121
+ end
122
+ ...
123
+ end
124
+ end
125
+ Pulp::Repository.schedules
126
+ repo.delete_note('some_key')
127
+
128
+ If you are unsure how certain things are used or can be added, I recommend you to A) read the pulp API docuemntation, B) read
129
+ the code of this gem and C) read the pulp python code, as some things might not work as documented or are not documented at
130
+ all. But the pulp maintainers are doing a really great job to get this last point fixe. Kudos to them! And they are also very
131
+ happy if you point things out in the api, that does currently not work very correctly, does not follow the REST-"Standard",
132
+ is undocumented or is somehow else weird.
133
+
134
+ == Contributing to ruby-pulp
135
+
136
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
137
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
138
+ * Fork the project
139
+ * Start a feature/bugfix branch
140
+ * Commit and push until you are happy with your contribution
141
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
142
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
143
+
144
+ == Copyright
145
+
146
+ Copyright (c) 2011 mh. See LICENSE.txt for further details.
147
+
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "pulp"
18
+ gem.homepage = "https://github.com/duritong"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{A little ruby wrapper around th pulp API}
21
+ gem.description = %Q{A little ruby wrapper around th pulp (http://pulpproject.org) API}
22
+ gem.email = "mh@immerda.ch"
23
+ gem.authors = ["mh"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rake/rdoctask'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "ruby-pulp #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.8
@@ -0,0 +1,205 @@
1
+ base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
2
+ $LOAD_PATH << File.join(base, "lib")
3
+ $LOAD_PATH << File.join(base, "examples")
4
+
5
+ puts <<EOS
6
+ Pulp examples: Repositories
7
+ ---------------------------
8
+
9
+ This will do a simple workflow through the management of repositories via the PULP Api using our ruby wrapper.
10
+
11
+ It will either use the test_pulp.yml file in this directory or use the PULP_YML environment variable, so you can set it to your own.
12
+
13
+ The test_pulp.yml file assumes that you have a pulp server running on localhost with username and password set to admin.
14
+
15
+ It will:
16
+ * Basic operations:
17
+ * list all existing repositories
18
+ * create a repository from the offical pulp repository for RHEL 6 - with a random prefix
19
+ * list all x86_64 repositories via a search filter
20
+ * relist all repositories
21
+ * run a sync on the created repository and wait till the sync finished
22
+ * make a clone of said repository
23
+ * list all repositories
24
+ * Additional Operations:
25
+ * unpublish the cloned repository
26
+ * Adjust the name of the created repository
27
+ * Add a note to the created repository
28
+ * Update this note
29
+ * Delete the note
30
+ * Add a group to the cloned repository
31
+ * Remove that group
32
+ * Add a filter to the cloned repository
33
+ * Remove that filter
34
+ * Republish the cloned repository
35
+ * Cleanup operations
36
+ * Delete the cloned repository
37
+ * Delete the created repository
38
+ * Print all repositories
39
+
40
+ Do you like to start? (y/n)
41
+ EOS
42
+
43
+ exit 1 unless STDIN.gets.chomp == 'y'
44
+
45
+ ENV['PULP_YML'] ||= File.expand_path(File.join(File.dirname(__FILE__), 'test_pulp.yml'))
46
+ require 'pulp'
47
+
48
+ def field_sizes
49
+ @field_sizes ||= Hash.new(12).merge('id' => 27)
50
+ end
51
+ def fields
52
+ @fields ||= ['id', 'name', 'arch', 'source', 'release', 'last_sync', 'publish']
53
+ end
54
+ def pretty_table_row(obj = nil)
55
+ '| ' + fields.collect{|field| sprintf("%0-#{field_sizes[field]}s", (obj ? obj.send(field).inspect : field).to_s[0..field_sizes[field]-1]) }.join(' | ') + ' |'
56
+ end
57
+
58
+ def print_repos(repos=Pulp::Repository.all)
59
+ header = pretty_table_row
60
+ [header,header.gsub(/./, '-'), repos.collect{|r| pretty_table_row(r) },header.gsub(/./, '-')].flatten.join("\n")
61
+ end
62
+
63
+ puts print_repos
64
+ random_id = "pulp-rhel6-x86_64-#{8.times.collect{|a| (65 + rand(25)).chr}.join('')}"
65
+
66
+ puts "Creating repository"
67
+ repo = Pulp::Repository.create(
68
+ :id => random_id,
69
+ :name => 'Example Repository for pulp on RHEL 6 x86_64',
70
+ :arch => 'x86_64',
71
+ :feed => "http://repos.fedorapeople.org/repos/pulp/pulp/6Server/x86_64/",
72
+ :relative_path => "pulp_test/#{random_id}",
73
+ :sync_schedule => ''
74
+ )
75
+ puts print_repos
76
+
77
+ puts "All x86_64 repos:"
78
+ puts print_repos(Pulp::Repository.find_by_arch('x86_64'))
79
+
80
+ puts "Starting repo sync"
81
+
82
+ task = repo.sync
83
+
84
+ puts "Syncing enqueued with task id: #{task.id} and arguments: #{task.args.inspect}"
85
+
86
+ while ['waiting','running'].include?(task.refresh.state) do
87
+ puts "Task is in state #{task.state} - Will wait for 30s and recheck"
88
+ sleep 30
89
+ end
90
+
91
+ puts "Task finished with state: #{task.state}"
92
+ if task.exception
93
+ puts "The following exception occured: #{task.exception}"
94
+ end
95
+
96
+ puts "Cloning repository"
97
+
98
+ task = repo.clone(
99
+ :clone_id => "clone-#{random_id}",
100
+ :clone_name => "Clone of #{random_id}",
101
+ :feed => 'parent'
102
+ )
103
+
104
+ puts "Cloning with task id: #{task.id} and arguments: #{task.args.inspect}"
105
+
106
+ while ['waiting','running'].include?(task.refresh.state) do
107
+ puts "Task is in state #{task.state} - Will wait for 30s and recheck"
108
+ sleep 30
109
+ end
110
+
111
+ puts "Task finished with state: #{task.state}"
112
+ if task.exception
113
+ puts "The following exception occurred: #{task.exception}"
114
+ end
115
+
116
+ clone_repo = Pulp::Repository.get("clone-#{random_id}")
117
+
118
+ puts print_repos
119
+
120
+ puts "Unpublish the cloned repository"
121
+ clone_repo.update_publish(:state => false)
122
+ clone_repo.refresh
123
+
124
+ puts print_repos
125
+
126
+
127
+ puts "Adjust name: #{repo.name}"
128
+ repo.name = 'Some other name'
129
+ repo.save
130
+ puts "New name: #{repo.name}"
131
+
132
+ puts
133
+
134
+ puts "Managing notes"
135
+ puts "---------------"
136
+ puts "Current notes: #{repo.notes.inspect}"
137
+ repo.add_note('test_note','foo')
138
+ repo.refresh
139
+ puts "Current notes: #{repo.notes.inspect}"
140
+ repo.update_note('test_note','foo 2')
141
+ repo.refresh
142
+ puts "Updated notes: #{repo.notes.inspect}"
143
+ puts "Delete note"
144
+ repo.delete_note('test_note')
145
+ repo.refresh
146
+ puts "Current notes: #{repo.notes.inspect}"
147
+
148
+ puts
149
+
150
+ puts "Managing groups"
151
+ puts "---------------"
152
+ puts "Current groups: #{repo.groupid.inspect}"
153
+ repo.add_group(:addgrp => 'test_group')
154
+ repo.refresh
155
+ puts "Current groups: #{repo.groupid.inspect}"
156
+ puts "Delete groups"
157
+ repo.remove_group(:rmgrp => 'test_group')
158
+ repo.refresh
159
+ puts "Current groups: #{repo.groupid.inspect}"
160
+
161
+ puts
162
+
163
+ puts "Managing filters"
164
+ puts "----------------"
165
+ puts "Init filter"
166
+ begin
167
+ filter = nil
168
+ Pulp::Filter.get('wildcard')
169
+ rescue RestClient::ResourceNotFound => e
170
+ filter = Pulp::Filter.create(:id => 'wildcard', :description => 'discard everything', :type => 'blacklist', :package_list => '*')
171
+ end
172
+
173
+ puts "Current filters: #{clone_repo.filters.inspect}"
174
+ puts "Adding filter 'wildcard'"
175
+ clone_repo.add_filters(:filters => ['wildcard'])
176
+ clone_repo.refresh
177
+ puts "Current filters: #{clone_repo.filters.inspect}"
178
+ puts "Delete filter"
179
+ clone_repo.remove_filters(:filters => ['wildcard'])
180
+ clone_repo.refresh
181
+ puts "Current filters: #{clone_repo.filters.inspect}"
182
+
183
+ if filter
184
+ puts "Removing filter as it have been created by us"
185
+ filter.delete
186
+ end
187
+
188
+ puts
189
+
190
+ puts "Republish the cloned repository"
191
+ clone_repo.update_publish(:state => true)
192
+ clone_repo.refresh
193
+
194
+ puts print_repos
195
+
196
+ puts
197
+
198
+ puts "Deleting repository"
199
+
200
+ repo.delete
201
+ clone_repo.delete
202
+
203
+ puts print_repos
204
+
205
+ puts "Finished..."