nifty 0.0.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +79 -12
  3. data/bin/nifty +2 -0
  4. data/config/nifty.yml +18 -0
  5. data/config/templates/image.erb +38 -0
  6. data/config/templates/template.erb +26 -0
  7. data/lib/nifty/backend.rb +55 -0
  8. data/lib/nifty/backends/opennebula.rb +109 -0
  9. data/lib/nifty/backends/utils/opennebula/datastore_handler.rb +36 -0
  10. data/lib/nifty/backends/utils/opennebula/group_handler.rb +23 -0
  11. data/lib/nifty/backends/utils/opennebula/handler.rb +60 -0
  12. data/lib/nifty/backends/utils/opennebula/helper.rb +44 -0
  13. data/lib/nifty/backends/utils/opennebula/image_handler.rb +209 -0
  14. data/lib/nifty/backends/utils/opennebula/template_handler.rb +91 -0
  15. data/lib/nifty/backends/utils/opennebula.rb +9 -0
  16. data/lib/nifty/backends/utils.rb +2 -0
  17. data/lib/nifty/backends.rb +5 -0
  18. data/lib/nifty/command_executioner.rb +202 -0
  19. data/lib/nifty/errors/api_call_timeout_error.rb +1 -0
  20. data/lib/nifty/errors/argument_error.rb +1 -0
  21. data/lib/nifty/errors/backend_error.rb +1 -0
  22. data/lib/nifty/errors/backends/opennebula/authentication_error.rb +1 -0
  23. data/lib/nifty/errors/backends/opennebula/resource_not_found_error.rb +1 -0
  24. data/lib/nifty/errors/backends/opennebula/resource_retrieval_error.rb +1 -0
  25. data/lib/nifty/errors/backends/opennebula/resource_state_error.rb +1 -0
  26. data/lib/nifty/errors/backends/opennebula/stub_error.rb +1 -0
  27. data/lib/nifty/errors/backends/opennebula/user_not_authorized_error.rb +1 -0
  28. data/lib/nifty/errors/backends/opennebula.rb +5 -0
  29. data/lib/nifty/errors/backends/opennebula_error.rb +1 -0
  30. data/lib/nifty/errors/backends.rb +4 -0
  31. data/lib/nifty/errors/command_execution_error.rb +1 -0
  32. data/lib/nifty/errors/event/converter_error.rb +1 -0
  33. data/lib/nifty/errors/event/loader_error.rb +1 -0
  34. data/lib/nifty/errors/event.rb +5 -0
  35. data/lib/nifty/errors/events/event_error.rb +1 -0
  36. data/lib/nifty/errors/events/expiration_event_error.rb +1 -0
  37. data/lib/nifty/errors/events/registration_event_error.rb +1 -0
  38. data/lib/nifty/errors/events.rb +4 -0
  39. data/lib/nifty/errors/standard_error.rb +1 -0
  40. data/lib/nifty/errors/transfer_method_error.rb +1 -0
  41. data/lib/nifty/errors/transfer_methods/destination_not_directory_error.rb +1 -0
  42. data/lib/nifty/errors/transfer_methods/destination_not_writable_error.rb +1 -0
  43. data/lib/nifty/errors/transfer_methods/image_file_not_readable_error.rb +1 -0
  44. data/lib/nifty/errors/transfer_methods.rb +4 -0
  45. data/lib/nifty/errors.rb +10 -0
  46. data/lib/nifty/event/converter.rb +29 -0
  47. data/lib/nifty/event/loader.rb +27 -0
  48. data/lib/nifty/event/processor.rb +96 -0
  49. data/lib/nifty/event.rb +6 -0
  50. data/lib/nifty/events/event.rb +32 -0
  51. data/lib/nifty/events/opennebula/event.rb +23 -0
  52. data/lib/nifty/events/opennebula/expiration_event.rb +32 -0
  53. data/lib/nifty/events/opennebula/metadata_update_event.rb +12 -0
  54. data/lib/nifty/events/opennebula/registration_event.rb +113 -0
  55. data/lib/nifty/events/opennebula/utils/events_common.rb +69 -0
  56. data/lib/nifty/events/opennebula/utils.rb +4 -0
  57. data/lib/nifty/events/opennebula.rb +6 -0
  58. data/lib/nifty/events.rb +5 -0
  59. data/lib/nifty/exit_codes.rb +8 -0
  60. data/lib/nifty/settings.rb +18 -0
  61. data/lib/nifty/transfer_method.rb +69 -0
  62. data/lib/nifty/transfer_methods/opennebula/cp.rb +52 -0
  63. data/lib/nifty/transfer_methods/opennebula/noop.rb +27 -0
  64. data/lib/nifty/transfer_methods/opennebula.rb +4 -0
  65. data/lib/nifty/transfer_methods.rb +4 -0
  66. data/lib/nifty/version.rb +1 -1
  67. data/lib/nifty.rb +20 -2
  68. data/nifty.gemspec +7 -0
  69. data/schema/appliance.json +295 -0
  70. data/templates/image.erb +8 -0
  71. data/templates/template.erb +13 -0
  72. metadata +166 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 144a359133c932d83555b37798b63e89b809efa0
4
- data.tar.gz: 25c2ca02a30599c5551dd3f732421144e20ddc05
3
+ metadata.gz: 34535f6d35b3c8a655fd2e09ba345bed53776e33
4
+ data.tar.gz: 3da0882d184d3100c510ad0586c0b38c8adb9b7d
5
5
  SHA512:
6
- metadata.gz: 1438877502e061b80cf124843c1807818d47b6bb3a7967004841221487eb98a14e069bb76b6c177279fc1a0c6c0f89ebc784128aa117001e9f16eca118de09f0
7
- data.tar.gz: e579c6241833505e0e3802cde2e21beb0bf7e0a3ba714600c849ed5bcd60434453727c8cec7187b6df5960bb92bfa42196d58d26a89e297a665c40392626dc8e
6
+ metadata.gz: fdaeac11c89d829767d745b7e33f5290cf02bd9a243fd24a637303d8c8bf79270d94a8a8b5f64236bfa444ca0463c6396eca4ca6c6356bcbc54afc890578c532
7
+ data.tar.gz: a6d550cf0e9c89b9bfebe07c971892bdee2af05c3479485c33fa0d4597df41839ebdb84d01c10bb9f0ea0b31e8af6eba4f4583d798f1e9be222f964536b065f7
data/README.md CHANGED
@@ -2,17 +2,33 @@
2
2
 
3
3
  NIFTY is a tool for uploading and registering cloud appliances in OpenNebula.
4
4
 
5
- [![Build Status](https://secure.travis-ci.org/Misenko/nifty.png)](http://travis-ci.org/Misenko/nifty)
6
- [![Dependency Status](https://gemnasium.com/Misenko/nifty.png)](https://gemnasium.com/Misenko/nifty)
5
+ [![Build Status](https://secure.travis-ci.org/CESNET/nifty.png)](http://travis-ci.org/CESNET/nifty)
6
+ [![Dependency Status](https://gemnasium.com/CESNET/nifty.png)](https://gemnasium.com/CESNET/nifty)
7
7
  [![Gem Version](https://fury-badge.herokuapp.com/rb/nifty.png)](https://badge.fury.io/rb/nifty)
8
- [![Code Climate](https://codeclimate.com/github/Misenko/nifty.png)](https://codeclimate.com/github/Misenko/nifty)
8
+ [![Code Climate](https://codeclimate.com/github/CESNET/nifty.png)](https://codeclimate.com/github/CESNET/nifty)
9
+
10
+ ##What does NIFY do?
11
+ Basically NIFTY takes a prepared appliance (virtual machine) and its descriptor and automatically uploads, register and prepares template in OpenNebula. Virtual machine can be than easily instantiated. Furthermore, NIFTY can expire an appliance so users will no longer be able to use it (for example due to security reasons). Expired appliances are automatically cleaned after configured time period.
12
+
13
+ ##How does NIFTY work?
14
+ NIFTY cooperates with two other tools [COMFY](https://github.com/CESNET/comfy) and [ITCHY](https://github.com/CESNET/itchy) which can prepare an appliance with a correct descriptor. NIFTY then reads a descriptor and either registers or expires the appliance.
9
15
 
10
16
  ##Requirements
11
17
  * Ruby >= 1.9.3
12
18
  * Rubygems
13
19
 
20
+ ###OpenNebula backend
21
+ * [OpenNebula](http://opennebula.org/) >= 4.6 (doesn't have to be present on the same machine)
22
+
14
23
  ## Installation
15
- **Unfortunately, neither gem nor packages are available for NIFTY right now. To try NIFTY, please use the [From source](#from-source-dev) guide below.**
24
+ ###From distribution specific packages
25
+ Omnibus packaging for NIFTY will be available soon. Meanwhile, use one of other installation methods.
26
+
27
+ ###From RubyGems.org
28
+ To install the most recent stable version
29
+ ```bash
30
+ gem install nifty
31
+ ```
16
32
 
17
33
  ###From source (dev)
18
34
  **Installation from source should never be your first choice! Especially, if you are not
@@ -23,7 +39,7 @@ familiar with RVM, Bundler, Rake and other dev tools for Ruby!**
23
39
  To build and install the bleeding edge version from master
24
40
 
25
41
  ```bash
26
- git clone git://github.com/Misenko/nifty.git
42
+ git clone git://github.com/CESNET/nifty.git
27
43
  cd nifty
28
44
  gem install bundler
29
45
  bundle install
@@ -35,18 +51,69 @@ bundle exec rake spec
35
51
  Configuration file can be read by NIFTY from these
36
52
  three locations:
37
53
 
38
- * `~/.nifty/conf.yml`
39
- * `/etc/nifty/conf.yml`
40
- * `PATH_TO_GEM_DIR/config/conf.yml`
54
+ * `~/.nifty/nifty.yml`
55
+ * `/etc/nifty/nifty.yml`
56
+ * `PATH_TO_GEM_DIR/config/nifty.yml`
41
57
 
42
58
  The example configuration file can be found at the last location
43
- `PATH_TO_GEM_DIR/config/conf.yml`.
59
+ `PATH_TO_GEM_DIR/config/nifty.yml`.
60
+
61
+ ##Usage
62
+ NIFTY is run with executable `nifty`. For further assistance run `nifty help`:
63
+ ```bash
64
+ $ nifty help
65
+
66
+ Commands:
67
+ nifty backends # Lists all available backends with their description
68
+ nifty help [COMMAND] # Describe available commands or one specific command
69
+ nifty opennebula --expiration-interval=EXPIRATION-INTERVAL -d, --datastores=one two three # Runs NIFTY with backend opennebula
70
+ nifty opennebula-transfer-methods # Lists all available transfer methods with their description for opennebula backend
71
+ nifty version # Prints NIFTY's version
72
+
73
+ Options:
74
+ -a, --appliance-dir=APPLIANCE-DIR # Directory from where appliance descriptors will be loaded
75
+ -m, --transfer-method=TRANSFER-METHOD # Transfer method for image upload
76
+ -t, [--transfer-destination=TRANSFER-DESTINATION] # Image upload destination
77
+ --logging-level=LOGGING-LEVEL
78
+ [--logging-file=LOGGING-FILE] # File to write log to
79
+ [--debug], [--no-debug] # Runs nifty in debug mode
80
+ ```
81
+
82
+ ###Backends
83
+ OpenNebula is currently the only supported backend for NIFTY. NIFTY can upload and register images and create VM templates in OpenNebula. Image and template generating mechanism can be customized by providing custom templates via `--template-dir` option. Default templates are situated in `PATH_TO_GEM_DIR/config/templates` directory. To list all options for Opennebula backend run `nifty help opennebula`:
84
+ ```bash
85
+ $ nifty help opennebula
86
+
87
+ Usage:
88
+ nifty opennebula --expiration-interval=EXPIRATION-INTERVAL -d, --datastores=one two three
89
+
90
+ Options:
91
+ [--secret=SECRET] # Pair of username and password in form of 'username:password' for accessing OpenNebula
92
+ [--endpoint=ENDPOINT] # OpenNebula's XML RPC endpoint
93
+ --expiration-interval=EXPIRATION-INTERVAL # How long should expired images be kept in OpenNebula befor removal, 0 means don't remove
94
+ -d, --datastores=one two three # Names of OpenNebula datastores images will be uploaded to
95
+ [--template-dir=TEMPLATE-DIR] # If set, templates within this directory are used to construct images and templates in OpenNebula
96
+ [--description-naming], [--no-description-naming] # If true, uses identifier and version from appliance description as template/image name instead of generated uuids
97
+ [--disk-expiration], [--no-disk-expiration] # Will expire old disks before the new one is registered
98
+ --permissions=PERMISSIONS # UNIX-like image and template permissions in OpenNebula
99
+ -a, --appliance-dir=APPLIANCE-DIR # Directory from where appliance descriptors will be loaded
100
+ -m, --transfer-method=TRANSFER-METHOD # Transfer method for image upload
101
+ -t, [--transfer-destination=TRANSFER-DESTINATION] # Image upload destination
102
+ -b, --backend=BACKEND # Backend for registering images
103
+ --logging-level=LOGGING-LEVEL
104
+ [--logging-file=LOGGING-FILE] # File to write log to
105
+ [--debug], [--no-debug] # Runs nifty in debug mode
106
+ ```
107
+
108
+ ###Transfer methods
109
+ NIFTY currently supports two transfer methods:
110
+ * `noop` (no operation) - dummy transfer method, doesn't change image location
111
+ * `cp` (copy) - creates an image copy in `--transfer-destination` directory
44
112
 
45
- ## Usage
46
- NIFTY is run with executable `nifty`.
113
+ To list all available transfer methods for selected backend run `nifty <BACKEND>-transfer-methods`, for example `nifty opennebula-transfer-methods`.
47
114
 
48
115
  ## Contributing
49
- 1. Fork it ( https://github.com/[my-github-username]/nifty/fork )
116
+ 1. Fork it ( https://github.com/CESNET/nifty/fork )
50
117
  2. Create your feature branch (`git checkout -b my-new-feature`)
51
118
  3. Commit your changes (`git commit -am 'Add some feature'`)
52
119
  4. Push to the branch (`git push origin my-new-feature`)
data/bin/nifty CHANGED
@@ -1,2 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'nifty'
3
+
4
+ Nifty::CommandExecutioner.start(ARGV)
data/config/nifty.yml ADDED
@@ -0,0 +1,18 @@
1
+ production:
2
+ appliance-dir: /var/run/nifty/appliances # Directory from where appliance descriptors will be loaded.
3
+ transfer:
4
+ method: noop # Transfer method for image upload. Available methods can be listed in help.
5
+ destination: # Image upload destination. Format depends on transfer method.
6
+ opennebula:
7
+ secret: oneadmin:opennebula # If not specified, looking for secret in environment variable ONE_AUTH and file ~/.one/one_auth
8
+ endpoint: http://localhost:2633/RPC2 # If not specified, looking for endpoint in environment variable ONE_XMLRPC and file ~/.one/one_endpoint
9
+ datastores: # Array of names of OpenNebula datastores images will be uploaded to. Has to contain at least one datastore if opennebula backend is selected
10
+ expiration-interval: 2w # How long should expired images be kept in OpenNebula before removal, 0 means don't remove
11
+ template-dir: # If set, templates within this directory are used to construct images and templates in OpenNebula
12
+ description-naming: false # If true, uses identifier and version from appliance description as template/image name instead of generated uuids
13
+ disk-expiration: true # Will expire old disks before the new one is registered
14
+ permissions: "640" # UNIX-like image and template permissions in OpenNebula, MUST be a string
15
+ logging:
16
+ level: ERROR # Logging level
17
+ file: /var/log/nifty/nifty.log # File to write log to. To turn off file logging leave this field empty.
18
+ debug: false # Debug mode
@@ -0,0 +1,38 @@
1
+ NAME = "<%= name %>"
2
+
3
+ <% if appliance.title && appliance.description %>
4
+ DESCRIPTION = "<%= "#{appliance.title} - #{appliance.description} created using NIFTY on #{::DateTime.now.readable_inspect}." %>"
5
+ <% else %>
6
+ DESCRIPTION = "<%= "Image created using NIFTY on #{::DateTime.now.readable_inspect}." %>"
7
+ <% end %>
8
+
9
+ <% case disk.type.upcase %>
10
+ <% when "CDROM" %>
11
+ TYPE = "CDROM"
12
+ DISK_TYPE = "CDROM"
13
+ PATH = "<%= disk.path %>"
14
+ <% when "FILE" %>
15
+ TYPE = "FILE"
16
+ DISK_TYPE = "FILE"
17
+ PATH = "<%= disk.path %>"
18
+ <% else %>
19
+ TYPE = "OS"
20
+ DISK_TYPE = "BLOCK"
21
+ PATH = "<%= disk.path %>"
22
+ <% end %>
23
+
24
+ <% if disk.device_prefix %>
25
+ DEV_PREFIX = "<%= disk.device_prefix %>"
26
+ <% end %>
27
+
28
+ <% if disk.target %>
29
+ BUS = "<%= disk.target %>"
30
+ <% end %>
31
+
32
+ <% if disk.format %>
33
+ DRIVER = "<%= disk.format %>"
34
+ <% end %>
35
+
36
+ <% appliance.attributes.each do |key, value| %>
37
+ <%= key %> = "<%= value %>"
38
+ <% end %>
@@ -0,0 +1,26 @@
1
+ NAME = "<%= name %>"
2
+
3
+ <% if appliance.title && appliance.description %>
4
+ DESCRIPTION = "<%= "#{appliance.title} - #{appliance.description} created using NIFTY on #{::DateTime.now.readable_inspect}." %>"
5
+ <% else %>
6
+ DESCRIPTION = "<%= "Template created using NIFTY on #{::DateTime.now.readable_inspect}." %>"
7
+ <% end %>
8
+
9
+ MEMORY = "<%= appliance.memory || 1024 %>"
10
+ CPU = "<%= appliance.cpu || 0.25 %>"
11
+ VCPU = "<%= appliance.cpu || 1 %>"
12
+
13
+ OS = [
14
+ ARCH = "<%= appliance.os.arch || "x86_64" %>"
15
+ ]
16
+
17
+ <% disk_names.each do |name| %>
18
+ DISK = [
19
+ IMAGE = "<%= name %>",
20
+ IMAGE_UNAME = "<%= username %>"
21
+ ]
22
+ <% end %>
23
+
24
+ <% appliance.attributes.each do |key, value| %>
25
+ <%= key %> = "<%= value %>"
26
+ <% end %>
@@ -0,0 +1,55 @@
1
+ # Abstract class for all NIFTY backends
2
+ #
3
+ # @author Michal Kimle
4
+ class Nifty::Backend
5
+ class << self
6
+ # Helper method to recognize NIFTY backend
7
+ #
8
+ # @return [TrueClass, FalseClass] whether or not class is a NIFTY backend
9
+ def backend?
10
+ false
11
+ end
12
+
13
+ # Returns textual description of the backend
14
+ # Used in help messages.
15
+ #
16
+ # @abstract
17
+ # @return [String, nil] textual description of the backend
18
+ def description
19
+ nil
20
+ end
21
+
22
+ # Returns hash from which new CLI command for backend is constructed
23
+ #
24
+ # @abstract
25
+ # @return [Hash, nil] hash from which new CLI command for backend is constructed
26
+ def options
27
+ nil
28
+ end
29
+
30
+ # Routine run before any events are processed
31
+ #
32
+ # @abstract
33
+ # @param [Hash] parameters to run pre method with
34
+ def pre(parameters)
35
+ end
36
+
37
+ # Routine run after all the events are processed
38
+ #
39
+ # @abstract
40
+ # @param [Hash] parameters to run post method with
41
+ def post(parameters)
42
+ end
43
+
44
+ # Creates specific event for the backend
45
+ #
46
+ # @abstract
47
+ # @param [Nifty::Events::Event] event_class class object representing event
48
+ # @param [Cloud::Appliance::Descriptor::Appliance] appliance description
49
+ # @param [Nifty::TransferMethod] transfer_method instance of transfer method used in the event
50
+ # @param [Hash] parameters any additional parameters
51
+ # @return [Nifty::Events::Event] instance of event
52
+ def create_event(event_class, appliance, transfer_method, parameters)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,109 @@
1
+ require 'time'
2
+ require 'nifty/backends/utils/opennebula'
3
+ require 'chronic_duration'
4
+
5
+ # OpenNebula backend
6
+ class Nifty::Backends::Opennebula < Nifty::Backend
7
+ class << self
8
+ # @see Nifty::Backend#backend?
9
+ def backend?
10
+ true
11
+ end
12
+
13
+ # @see Nifty::Backend#description
14
+ def description
15
+ "OpenNebula backend"
16
+ end
17
+
18
+ # @see Nifty::Backend#options
19
+ def options
20
+ { :secret => {
21
+ :type => :string,
22
+ :desc => 'Pair of username and password in form of \'username:password\' for accessing OpenNebula'
23
+ },
24
+ :endpoint => {
25
+ :type => :string,
26
+ :desc => 'OpenNebula\'s XML RPC endpoint'
27
+ },
28
+ :"expiration-interval" => {
29
+ :required => true,
30
+ :type => :string,
31
+ :desc => 'How long should expired images be kept in OpenNebula befor removal, 0 means don\'t remove'
32
+ },
33
+ :datastores => {
34
+ :required => true,
35
+ :type => :array,
36
+ :aliases => '-d',
37
+ :desc => 'Names of OpenNebula datastores images will be uploaded to'
38
+ },
39
+ :"template-dir" => {
40
+ :default => File.join(Nifty::GEM_DIR, 'config', 'templates'),
41
+ :type => :string,
42
+ :desc => 'If set, templates within this directory are used to construct images and templates in OpenNebula'
43
+ },
44
+ :"description-naming" => {
45
+ :type => :boolean,
46
+ :desc => 'If true, uses identifier and version from appliance description as template/image name instead of generated uuids'
47
+ },
48
+ :"disk-expiration" => {
49
+ :type => :boolean,
50
+ :desc => 'Will expire old disks before the new one is registered'
51
+ },
52
+ :permissions => {
53
+ :required => true,
54
+ :type => :string,
55
+ :desc => 'UNIX-like image and template permissions in OpenNebula'
56
+ }
57
+ }
58
+ end
59
+
60
+ # @see Nifty::Backend#pre
61
+ def pre(parameters)
62
+ expiration_check(parameters)
63
+ end
64
+
65
+ # @see Nifty::Backend#create_event
66
+ # @param [Hash] parameters
67
+ # @option parameters [String] secret OpenNebula's secret
68
+ # @option parameters [String] endpoint OpenNebula's endpoint
69
+ # @option parameters [Array] datastores array of datastore names
70
+ # @option parameters [String] template-dir path to dir with image and template templates
71
+ def create_event(event_class, appliance, transfer_method, parameters)
72
+ client = Nifty::Backends::Utils::Opennebula::Helper.client(parameters[:secret], parameters[:endpoint])
73
+ datastores = Nifty::Backends::Utils::Opennebula::DatastoreHandler.new(client).datastores(parameters[:datastores])
74
+ event_class.new(appliance, transfer_method, client, datastores, parameters)
75
+ rescue Nifty::Errors::Backends::OpennebulaError => ex
76
+ fail Nifty::Errors::BackendError, ex
77
+ end
78
+
79
+ private
80
+
81
+ # Checks whether there are expired images that should be removed
82
+ #
83
+ # @param [Hash] parameters
84
+ # @option parameters [String] expiration-interval expiration interval in human readable form
85
+ # @option parameters [String] secret OpenNebula's secret
86
+ # @option parameters [String] endpoint OpenNebula's endpoint
87
+ def expiration_check(parameters)
88
+ interval = ChronicDuration.parse(parameters[:"expiration-interval"])
89
+ return unless interval
90
+
91
+ client = Nifty::Backends::Utils::Opennebula::Helper.client(parameters[:secret], parameters[:endpoint])
92
+ image_handler = Nifty::Backends::Utils::Opennebula::ImageHandler.new(client)
93
+ now = Time.now
94
+
95
+ logger.debug('Looking for expired images...')
96
+ image_handler.expired_images.each do |image|
97
+ image_handler.disable_image image
98
+
99
+ image_expiration_date = Time.parse(image['TEMPLATE/NIFTY_EXPIRATION'])
100
+ # checks whether image is already expired for specified time
101
+ next if (now - image_expiration_date) < interval
102
+
103
+ image_handler.delete_image image
104
+ end
105
+ rescue Nifty::Errors::Backends::OpennebulaError => ex
106
+ logger.error("Cannot check and remove expired images: #{ex.message}")
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,36 @@
1
+ # Handler for OpenNebula DatastorePool
2
+ #
3
+ # @author Michal Kimle
4
+ class Nifty::Backends::Utils::Opennebula::DatastoreHandler < Nifty::Backends::Utils::Opennebula::Handler
5
+
6
+ # Constructor
7
+ #
8
+ # @see Nifty::Backends::Utils::Opennebula::Handler#initialize
9
+ def initialize(client)
10
+ super(client)
11
+ @pool = OpenNebula::DatastorePool.new(client)
12
+ end
13
+
14
+ # Returns list of datastores matching the names
15
+ # If there is no datastore with given name, it's skipped.
16
+ #
17
+ # @param [Array] names array of the names
18
+ # @return [Array] array of found datastores
19
+ def datastores(names)
20
+ reload!
21
+
22
+ datastores = []
23
+ names.each do |name|
24
+ datastore = pool.find { |ds| ds.name == name }
25
+
26
+ unless datastore
27
+ logger.warn("Datastore #{name.inspect} was not found, skipping.")
28
+ next
29
+ end
30
+
31
+ datastores << datastore
32
+ end
33
+
34
+ datastores
35
+ end
36
+ end
@@ -0,0 +1,23 @@
1
+ # Handler for OpenNebula GroupPool
2
+ #
3
+ # @author Michal Kimle
4
+ class Nifty::Backends::Utils::Opennebula::GroupHandler < Nifty::Backends::Utils::Opennebula::Handler
5
+
6
+ # Constructor
7
+ #
8
+ # @see Nifty::Backends::Utils::Opennebula::Handler#initialize
9
+ def initialize(client)
10
+ super(client)
11
+ @pool = OpenNebula::GroupPool.new(client)
12
+ end
13
+
14
+ # Returns groupt with specified name
15
+ #
16
+ # @param [String] name
17
+ # @return [OpenNebula::Group] group with specified name
18
+ def group(name)
19
+ reload!
20
+
21
+ pool.find { |group| group.name == name }
22
+ end
23
+ end
@@ -0,0 +1,60 @@
1
+ # Handler for OpenNebula pools
2
+ #
3
+ # @author Michal Kimle
4
+ # @abstract
5
+ # @attr_reader [OpenNebula::Client] client
6
+ # @attr [OpenNebula::Pool] pool
7
+ class Nifty::Backends::Utils::Opennebula::Handler
8
+ attr_reader :client
9
+ attr_accessor :pool
10
+
11
+ ONEADMIN_ID = 0
12
+ LEAVE_AS_IS = -1
13
+ ATTRIBUTE_APPLIANCE_ID = 'NIFTY_APPLIANCE_ID'
14
+ OWNER_OCTET = '600'
15
+
16
+ # Constructor
17
+ #
18
+ # @param [OpenNebula::Client] client
19
+ def initialize(client)
20
+ @client = client
21
+ end
22
+
23
+ # Reloads the pool
24
+ #
25
+ def reload!
26
+ return unless pool
27
+
28
+ if pool.respond_to?('info_all!')
29
+ Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { pool.info_all! }
30
+ return
31
+ end
32
+
33
+ Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { pool.info! }
34
+ end
35
+
36
+ # Change owner of the element
37
+ #
38
+ # @param [OpenNebula::PoolElement] element
39
+ # @param [Fixnum] owner_id
40
+ # @param [Fixnum] group_id
41
+ def self.chown(element, owner_id, group_id)
42
+ Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { element.info! }
43
+
44
+ old_owner_id = element['UID'].to_i
45
+ old_group_id = element.gid
46
+ owner_id = LEAVE_AS_IS if owner_id == old_owner_id
47
+ group_id = LEAVE_AS_IS if group_id == old_group_id
48
+
49
+ Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { element.chown(owner_id, group_id) }
50
+ end
51
+
52
+ # Change permissions on the element
53
+ #
54
+ # @param [OpenNebula::PoolElement] element
55
+ # @param [String] octet UNIX-like permission octet
56
+ def self.chmod(element, octet)
57
+ Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { element.info! }
58
+ Nifty::Backends::Utils::Opennebula::Helper.handle_opennebula_error { element.chmod_octet(octet) }
59
+ end
60
+ end
@@ -0,0 +1,44 @@
1
+ require 'opennebula'
2
+
3
+ # Helper class for OpenNebula backend
4
+ #
5
+ # @author Michal Kimle
6
+ class Nifty::Backends::Utils::Opennebula::Helper
7
+ class << self
8
+ # Creates client for communication with OpenNebula
9
+ #
10
+ # @param [String] secret OpenNebula's authentication secret
11
+ # @param [String] endpoint OpenNebula's endpoint
12
+ # @return [OpenNebula::Client] OpenNebula client instance
13
+ def client(secret, endpoint)
14
+ OpenNebula::Client.new(secret, endpoint)
15
+ end
16
+
17
+ # Handles OpenNebula error codes and turn them into exceptions
18
+ #
19
+ # @raise [Nifty::Errors::Backends::Opennebula::AuthenticationError]
20
+ # @raise [Nifty::Errors::Backends::Opennebula::UserNotAuthorizedError]
21
+ # @raise [Nifty::Errors::Backends::Opennebula::ResourceNotFoundError]
22
+ # @raise [Nifty::Errors::Backends::Opennebula::ResourceStateError]
23
+ # @raise [Nifty::Errors::Backends::Opennebula::ResourceRetrievalError]
24
+ def handle_opennebula_error
25
+ fail Nifty::Errors::Backends::Opennebula::StubError, 'OpenNebula service-wrapper was called without a block!' unless block_given?
26
+
27
+ return_value = yield
28
+ return return_value unless OpenNebula.is_error?(return_value)
29
+
30
+ case return_value.errno
31
+ when OpenNebula::Error::EAUTHENTICATION
32
+ fail Nifty::Errors::Backends::Opennebula::AuthenticationError, return_value.message
33
+ when OpenNebula::Error::EAUTHORIZATION
34
+ fail Nifty::Errors::Backends::Opennebula::UserNotAuthorizedError, return_value.message
35
+ when OpenNebula::Error::ENO_EXISTS
36
+ fail Nifty::Errors::Backends::Opennebula::ResourceNotFoundError, return_value.message
37
+ when OpenNebula::Error::EACTION
38
+ fail Nifty::Errors::Backends::Opennebula::ResourceStateError, return_value.message
39
+ else
40
+ fail Nifty::Errors::Backends::Opennebula::ResourceRetrievalError, return_value.message
41
+ end
42
+ end
43
+ end
44
+ end