itchy 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +38 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +16 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +203 -0
  7. data/README.md +16 -0
  8. data/Rakefile +25 -0
  9. data/bin/itchy +142 -0
  10. data/config/itchy.yml +32 -0
  11. data/itchy.gemspec +41 -0
  12. data/lib/itchy/errors/abstract_env_error.rb +4 -0
  13. data/lib/itchy/errors/env_lookup_error.rb +4 -0
  14. data/lib/itchy/errors/event_processing_error.rb +4 -0
  15. data/lib/itchy/errors/file_inspecting_error.rb +4 -0
  16. data/lib/itchy/errors/format_converting_error.rb +4 -0
  17. data/lib/itchy/errors/image_transforming_error.rb +4 -0
  18. data/lib/itchy/errors/not_found_error.rb +4 -0
  19. data/lib/itchy/errors/not_implemented_error.rb +4 -0
  20. data/lib/itchy/errors/unknown_event_error.rb +4 -0
  21. data/lib/itchy/errors/working_with_files_error.rb +4 -0
  22. data/lib/itchy/errors/wrong_state_error.rb +4 -0
  23. data/lib/itchy/errors.rb +5 -0
  24. data/lib/itchy/event_handlers/available_postfix_event_handler.rb +43 -0
  25. data/lib/itchy/event_handlers/available_prefix_event_handler.rb +10 -0
  26. data/lib/itchy/event_handlers/base_event_handler.rb +82 -0
  27. data/lib/itchy/event_handlers/expire_postfix_event_handler.rb +30 -0
  28. data/lib/itchy/event_handlers/expire_prefix_event_handler.rb +9 -0
  29. data/lib/itchy/event_handlers/process_postfix_event_handler.rb +9 -0
  30. data/lib/itchy/event_handlers/process_prefix_event_handler.rb +10 -0
  31. data/lib/itchy/event_handlers/subscription_image_new_event_handler.rb +9 -0
  32. data/lib/itchy/event_handlers.rb +8 -0
  33. data/lib/itchy/event_processer.rb +103 -0
  34. data/lib/itchy/format_converter.rb +43 -0
  35. data/lib/itchy/helpers/vmcatcher_env_helper.rb +44 -0
  36. data/lib/itchy/helpers.rb +5 -0
  37. data/lib/itchy/image_transformer.rb +220 -0
  38. data/lib/itchy/log.rb +78 -0
  39. data/lib/itchy/metadata_archiver.rb +59 -0
  40. data/lib/itchy/settings.rb +35 -0
  41. data/lib/itchy/version.rb +3 -0
  42. data/lib/itchy/vmcatcher_configuration.rb +62 -0
  43. data/lib/itchy/vmcatcher_env.rb +58 -0
  44. data/lib/itchy/vmcatcher_event.rb +71 -0
  45. data/lib/itchy.rb +26 -0
  46. data/spec/itchy/event_handlers/available_postfix_event_handler_spec.rb +0 -0
  47. data/spec/itchy/event_handlers/expire_postfix_event_handler_spec.rb +0 -0
  48. data/spec/itchy/event_processer_spec.rb +0 -0
  49. data/spec/itchy/format_converter_spec.rb +0 -0
  50. data/spec/itchy/image_transformer_spec.rb +0 -0
  51. data/spec/itchy/metadata_archiver_spec.rb +0 -0
  52. data/spec/itchy/vmcatcher_configuration_spec.rb +0 -0
  53. data/spec/itchy/vmcatcher_env_spec.rb +1 -0
  54. data/spec/itchy/vmcatcher_event_spec.rb +0 -0
  55. data/spec/spec_helper.rb +11 -0
  56. metadata +379 -0
@@ -0,0 +1,59 @@
1
+ module Itchy
2
+ # Wraps vmcatcher event handling methods. All events are
3
+ # stored for subsequent processing. There is no actual image
4
+ # handling happening here.
5
+ class MetadataArchiver
6
+ attr_reader :vmc_configuration, :options
7
+
8
+ # Creates an archiver instance for storing vmcatcher
9
+ # events to the file system for delayed processing.
10
+ #
11
+ # @param vmc_configuration [Itchy::VmcatcherConfiguration] vmcatcher configuration
12
+ # @param options [Hashie::Mash] hash-like structure with options
13
+ def initialize(vmc_configuration, options)
14
+ fail ArgumentError, '"vmc_configuration" must be an instance ' \
15
+ 'of Itchy::VmcatcherConfiguration' unless vmc_configuration.is_a? Itchy::VmcatcherConfiguration
16
+
17
+ @vmc_configuration = vmc_configuration
18
+ @options = options || ::Hashie::Mash.new
19
+
20
+ init_metadata_dir!
21
+ end
22
+
23
+ # Triggers archiving of the provided event. Event is written
24
+ # to the file system as a JSON-formatted document for delayed
25
+ # processing.
26
+ #
27
+ # @param vmc_event [Itchy::VmcatcherEvent] event to store
28
+ def archive!(vmc_event)
29
+ fail ArgumentError, '"vmc_event" must be an instance ' \
30
+ 'of Itchy::VmcatcherEvent' unless vmc_event.is_a? Itchy::VmcatcherEvent
31
+
32
+ Itchy::Log.info "[#{self.class.name}] Archiving " \
33
+ "#{vmc_event.type.inspect} " \
34
+ "for #{vmc_event.dc_identifier.inspect}"
35
+
36
+ begin
37
+ event_handler = Itchy::EventHandlers.const_get("#{vmc_event.type}EventHandler")
38
+ rescue NameError => ex
39
+ raise Itchy::Errors::UnknownEventError,
40
+ "Unknown event type #{vmc_event.type.inspect} detected: #{ex.message}"
41
+ end
42
+
43
+ event_handler = event_handler.new(vmc_configuration, options)
44
+ event_handler.archive!(vmc_event)
45
+ end
46
+
47
+ private
48
+
49
+ # Runs a basic check on the metadata directory.
50
+ def init_metadata_dir!
51
+ Itchy::Log.debug "[#{self.class.name}] Checking metadata directory #{options.metadata_dir.inspect}"
52
+
53
+ fail ArgumentError, 'Metadata directory is ' \
54
+ 'not a directory!' unless File.directory? options.metadata_dir
55
+ fail ArgumentError, 'Metadata directory is ' \
56
+ 'not writable!' unless File.writable? options.metadata_dir
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,35 @@
1
+ module Itchy
2
+ # Wraps access to configuration files. Files are loaded
3
+ # in the following order:
4
+ #
5
+ # 1.) ~/.itchy.yml
6
+ # 2.) /etc/itchy/itchy.yml
7
+ # 3.) GEM_INSTALL_DIR/config/itchy.yml
8
+ #
9
+ # The first available file will be used. Settings are never
10
+ # merged from multiple files.
11
+ class Settings < Settingslogic
12
+ HOME_CONF = File.join(
13
+ ENV['HOME'],
14
+ '.itchy.yml'
15
+ )
16
+ GLOBAL_CONF = File.join(
17
+ "#{File::SEPARATOR}etc",
18
+ 'itchy',
19
+ 'itchy.yml'
20
+ )
21
+ GEM_CONF = File.join(
22
+ File.expand_path(File.join('..', '..', '..'), __FILE__),
23
+ 'config',
24
+ 'itchy.yml'
25
+ )
26
+
27
+ source HOME_CONF if File.readable? HOME_CONF
28
+ source GLOBAL_CONF if File.readable? GLOBAL_CONF
29
+ source GEM_CONF
30
+
31
+ namespace ENV['RAILS_ENV'].blank? ? 'production' : ENV['RAILS_ENV']
32
+
33
+ load!
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Itchy
2
+ VERSION = '0.0.1' unless defined?(::Itchy::VERSION)
3
+ end
@@ -0,0 +1,62 @@
1
+ module Itchy
2
+ # Wraps vmcatcher configuration meta data.
3
+ class VmcatcherConfiguration < VmcatcherEnv
4
+ # Known methods names used by this class
5
+ KNOWN_METHOD_NAMES = %w(
6
+ rdbms
7
+ cache_event
8
+ log_conf
9
+ dir_cert
10
+ cache_dir_cache
11
+ cache_dir_download
12
+ cache_dir_expire
13
+ cache_action_download
14
+ cache_action_check
15
+ cache_action_expire).freeze
16
+
17
+ # Prefix for making vmcatcher attributes
18
+ VMCATCHER_ATTR_PREFIX = 'VMCATCHER_'
19
+
20
+ # Known vmcatcher configuration attributes
21
+ REGISTERED_ENV_KEYS = %w(
22
+ VMCATCHER_RDBMS
23
+ VMCATCHER_CACHE_EVENT
24
+ VMCATCHER_LOG_CONF
25
+ VMCATCHER_DIR_CERT
26
+ VMCATCHER_CACHE_DIR_CACHE
27
+ VMCATCHER_CACHE_DIR_DOWNLOAD
28
+ VMCATCHER_CACHE_DIR_EXPIRE
29
+ VMCATCHER_CACHE_ACTION_DOWNLOAD
30
+ VMCATCHER_CACHE_ACTION_CHECK
31
+ VMCATCHER_CACHE_ACTION_EXPIRE).freeze
32
+
33
+ # REGISTERED_ENV_KEYS.each do |registered_env_key|
34
+ # short_env_key = registered_env_key.gsub(/^VMCATCHER_/, '')
35
+
36
+ # class_eval %Q|
37
+ # def #{short_env_key.downcase}
38
+ # attributes["#{registered_env_key}"]
39
+ # end
40
+ # |
41
+ # end
42
+ def method_missing(method_id, *arguments, &block)
43
+ if KNOWN_METHOD_NAMES.include? method_id.to_s
44
+ self.class.send :define_method, method_id do
45
+ temp = VMCATCHER_ATTR_PREFIX + method_id.to_s.upcase
46
+ attributes["#{temp}"]
47
+ end
48
+ send(method_id)
49
+ else
50
+ super
51
+ end
52
+ end
53
+
54
+ def respond_to?(method_id, include_private = false)
55
+ if KNOWN_METHOD_NAMES.include? method_id.to_s
56
+ true
57
+ else
58
+ super
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,58 @@
1
+ module Itchy
2
+ # Wraps vmcatcher metadata taken from the environment.
3
+ class VmcatcherEnv
4
+ # Dummy keys
5
+ REGISTERED_ENV_KEYS = [].freeze
6
+
7
+ attr_reader :attributes
8
+
9
+ # Creates an environment instance with pre-filtered
10
+ # attributes.
11
+ #
12
+ # @param env [Object] hash-like or JSON-like object storing the raw environment
13
+ def initialize(env)
14
+ env = ::JSON.parse(env) if env.is_a?(String)
15
+
16
+ @attributes = Itchy::Helpers::VmcatcherEnvHelper.select_from_env(
17
+ env,
18
+ self.class::REGISTERED_ENV_KEYS
19
+ )
20
+ end
21
+
22
+ # Generates a human-readable JSON document
23
+ # from available ENV attributes.
24
+ #
25
+ # @return [String] pretty JSON document
26
+ def to_pretty_json
27
+ ::JSON.pretty_generate attributes
28
+ end
29
+
30
+ # Generates an ordinary JSON document
31
+ # from available ENV attributes.
32
+ #
33
+ # @return [String] JSON document
34
+ def to_json
35
+ ::JSON.generate attributes
36
+ end
37
+
38
+ # Converts event attributes into a hash-like
39
+ # structure.
40
+ #
41
+ # @return [Hashie::Mash] hash-like structure with metadata
42
+ def to_hash
43
+ attr_converted = ::Hashie::Mash.new
44
+ attributes.each_pair { |name, val| attr_converted[name.downcase] = val }
45
+ attr_converted
46
+ end
47
+
48
+ class << self
49
+ # Creates an instance from a JSON document.
50
+ #
51
+ # @param json [String] JSON to create an instance from
52
+ # @return [Itchy::VmcatcherEnv] instance
53
+ def from_json(json)
54
+ new ::JSON.parse(json)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,71 @@
1
+ module Itchy
2
+ # Wraps vmcatcher event meta data.
3
+ class VmcatcherEvent < VmcatcherEnv
4
+ # Known methods names used by this class
5
+ KNOWN_METHOD_NAMES = %w(
6
+ type
7
+ dc_description
8
+ dc_identifier
9
+ dc_title
10
+ hv_hypervisor
11
+ hv_size
12
+ hv_uri
13
+ hv_format
14
+ hv_version
15
+ sl_arch
16
+ sl_checksum_sha512
17
+ sl_comments
18
+ sl_os
19
+ sl_osversion
20
+ il_dc_identifier
21
+ ad_mpuri
22
+ filename
23
+ vo).freeze
24
+
25
+ # Prefix for making vmcatcher attributes
26
+ VMCATCHER_ATTR_PREFIX = 'VMCATCHER_EVENT_'
27
+
28
+ # Known event attributes used by vmcatcher
29
+ REGISTERED_ENV_KEYS = %w(
30
+ VMCATCHER_EVENT_TYPE
31
+ VMCATCHER_EVENT_DC_DESCRIPTION
32
+ VMCATCHER_EVENT_DC_IDENTIFIER
33
+ VMCATCHER_EVENT_DC_TITLE
34
+ VMCATCHER_EVENT_HV_HYPERVISOR
35
+ VMCATCHER_EVENT_HV_SIZE
36
+ VMCATCHER_EVENT_HV_URI
37
+ VMCATCHER_EVENT_HV_FORMAT
38
+ VMCATCHER_EVENT_HV_VERSION
39
+ VMCATCHER_EVENT_SL_ARCH
40
+ VMCATCHER_EVENT_SL_CHECKSUM_SHA512
41
+ VMCATCHER_EVENT_SL_COMMENTS
42
+ VMCATCHER_EVENT_SL_OS
43
+ VMCATCHER_EVENT_SL_OSVERSION
44
+ VMCATCHER_EVENT_IL_DC_IDENTIFIER
45
+ VMCATCHER_EVENT_AD_MPURI
46
+ VMCATCHER_EVENT_FILENAME
47
+ VMCATCHER_EVENT_VO).freeze
48
+
49
+ def method_missing(method_id, *arguments, &block)
50
+ if KNOWN_METHOD_NAMES.include? method_id.to_s
51
+ self.class.send :define_method, method_id do
52
+ temp = VMCATCHER_ATTR_PREFIX + method_id.to_s.upcase
53
+
54
+ Itchy::Log.debug "[#{method_id}] METHOD MISSING CALL "
55
+ attributes[temp]
56
+ end
57
+ send(method_id)
58
+ else
59
+ super
60
+ end
61
+ end
62
+
63
+ def respond_to?(method_id, include_private = false)
64
+ if KNOWN_METHOD_NAMES.include? method_id.to_s
65
+ true
66
+ else
67
+ super
68
+ end
69
+ end
70
+ end
71
+ end
data/lib/itchy.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'active_support/all'
2
+ require 'settingslogic'
3
+ require 'multi_json'
4
+ require 'mixlib/shellout'
5
+ require 'logger'
6
+ require 'uri'
7
+ require 'erb'
8
+ require 'hashie/mash'
9
+ require 'cloud-appliance-descriptor'
10
+
11
+ # Wraps all internals of the handler.
12
+ module Itchy; end
13
+
14
+ require 'itchy/version'
15
+ require 'itchy/settings'
16
+ require 'itchy/log'
17
+ require 'itchy/errors'
18
+ require 'itchy/helpers'
19
+ require 'itchy/event_handlers'
20
+ require 'itchy/metadata_archiver'
21
+ require 'itchy/image_transformer'
22
+ require 'itchy/vmcatcher_env'
23
+ require 'itchy/vmcatcher_configuration'
24
+ require 'itchy/vmcatcher_event'
25
+ require 'itchy/event_processer'
26
+ require 'itchy/format_converter'
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1 @@
1
+
File without changes
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+
3
+ # enable coverage reports
4
+ if ENV['COVERAGE']
5
+ require 'simplecov'
6
+
7
+ SimpleCov.add_filter '/spec/'
8
+ SimpleCov.start
9
+ end
10
+
11
+ require 'itchy'