itchy 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fdda0b2aa4e9eb5cc2ea91f70fac7563a84549dd
4
- data.tar.gz: a0af4183e2155fc184c60dec6dbbf6bfb845d703
3
+ metadata.gz: 10b5ecfa7e3bc071fecc195d65a0169f0b7545ea
4
+ data.tar.gz: 29c643ccf9dce7e83730e68edefb64ab8e70768d
5
5
  SHA512:
6
- metadata.gz: 7443a124bc70d22664b774c31ebc5e2da9b773b136c0b8a335365478f5813cb27224f152a0272dc1a098a79717cbdb0c99802ec20f4cf370b80176dfc3bd2d07
7
- data.tar.gz: c3c4bc6f42d601077ca9f91390ae9ec77e335fa0819f407bb28e969cb345b021d3318958b1fd02871304ced73a833c7394c429abb51be3d75a8414c4f20fd93a
6
+ metadata.gz: 8359f10ef113911af9947c0eaafc580da3c7040b081d2198eb83783f09a0d129d52e5ed595128c0555bea5a40447b7f7485381edde921d96181a6da4c817e629
7
+ data.tar.gz: ab5fb5cf07d9c7f8e38a0c82300e391eda804bb6e9a948baef2e35376ad37d1c4f11269cc7a6ea4b637837a1d0fe6b4431bfd3b7f7f5396599a243e013aa5119
data/README.md CHANGED
@@ -3,10 +3,127 @@
3
3
  [![Gem Version](https://fury-badge.herokuapp.com/rb/onevmcatcher.png)](https://badge.fury.io/rb/itchy)
4
4
  [![Code Climate](https://codeclimate.com/github/arax/onevmcatcher.png)](https://codeclimate.com/github/kosoburak/itchy)
5
5
 
6
- # Itchy
6
+ # Itchy - vIrTual applianCe Handling utiliTY
7
7
 
8
- Handling images from HEPIX vmcatcher for Nifty.
8
+ ITCHY is tool for handling virtual appliances.
9
9
 
10
+ ## Related tools
11
+ ITCHY is part of tool chain used for automated virtual applience handling.
12
+ Because of character of this tool, separated usage is not really helpfull.
13
+
14
+ Part of ITCHY is designed to be an event handler for [vmcatcher](https://github.com/hepix-virtualisation/vmcatcher).
15
+
16
+ Files created by ITCHY are intended to be uploated and registered in a cloud storage.
17
+ This can be done by our other tool [nifty](https://github.com/CESNET/nifty).
18
+
19
+ ## What and how does ITCHY do?
20
+
21
+ It basically converts heterogeneous output from vmcatcher and prepare all necessary files for upload an registration into a cloud storage.
22
+
23
+ ITCHY consists of two cooperating tasks. One serves for archiving vmcatcher events, second one for further processing. This concept was needed because of two reasons. First reason is that vmcatcher run as a cron job, regularly. There is a possibility, that image processing time would be greater than time period between two vmcatcher runs. In this case, the whole process would fail. The second reason is that we can't interrupt vmcatcher event processing and start over. So, the first part of ITCHY running with vmcatcher as event handler is so simple as it can be. The other acts are separated and they can be restarted or delayed if there is a need to do so, and it won't affect vmcatcher.
24
+
25
+ ## Instalation
26
+
27
+ ###From distribution specific packages
28
+ Distribution specific packages can be created with [omnibus packaging for ITCHY](https://github.com/CESNET/omnibus-itchy). When installing via packages you don't have to install neither ruby nor rubygems. Packages contain embedded ruby and all the necessary gems and libraries witch will not effect your system ruby, gems and libraries.
29
+
30
+ Currently supported distributions:
31
+
32
+ Ubuntu 12.04
33
+ Ubuntu 14.04
34
+ Debian 7.6
35
+ Debian 8.2
36
+ CentOS 6.5
37
+ CentOS 7.1
38
+
39
+ ###From RubyGems.org
40
+ To install the most recent stable version
41
+ ``bash
42
+ gem install nifty
43
+ ``
44
+
45
+ ###From source (dev)
46
+ **Installation from source should never be your first choice! Especially, if you are not
47
+ familiar with RVM, Bundler, Rake and other dev tools for Ruby!**
48
+
49
+ **However, if you wish to contribute to our project, this is the right way to start.**
50
+
51
+ To build and install the bleeding edge version from master
52
+
53
+ ```bash
54
+ git clone git://github.com/CESNET/itchy.git
55
+ cd itchy
56
+ gem install bundler
57
+ bundle install
58
+ bundle exec rake spec
59
+ ```
60
+
61
+ ## Configuration
62
+ ###Create a configuration file for ITCHY
63
+ Configuration file can be read by ITCHY from these
64
+ three locations:
65
+
66
+ * `~/.itchy/itchy.yml`
67
+ * `/etc/itchy/itchy.yml`
68
+ * `PATH_TO_GEM_DIR/config/itchy.yml`
69
+
70
+ The default configuration file can be found at the last location
71
+ `PATH_TO_GEM_DIR/config/itchy.yml`.
72
+
73
+ ## Usage
74
+ ITCHY starts with executable `itchy`. For further assistance run `itchy help`:
75
+ ```bash
76
+ $ itchy help
77
+
78
+ Commands:
79
+ itchy archive # Handle an incoming vmcatcher event and store it for further processing
80
+ itchy help [COMMAND] # Describe available commands or one specific command
81
+ itchy process # Process stored events
82
+
83
+ Options:
84
+ -b, [--log-level=LOG_LEVEL] # Logging level
85
+ # Default: error
86
+ # Possible values: debug, info, warn, error, fatal, unknown
87
+ -d, [--debug], [--no-debug] # Enable debugging
88
+ ```
89
+ ### ARCHIVE
90
+ This command is used as an event handler for `vmcatcher`.
91
+ For proper running it needs to have set required env variables by `vmcatcher`.
92
+ ```bash
93
+ $ itchy help archive
94
+
95
+ ```
96
+ ### PROCESS
97
+
98
+ ```bash
99
+ $itchy help process
100
+
101
+ Usage:
102
+ itchy process
103
+
104
+ Options:
105
+ -m, [--metadata-dir=METADATA_DIR] # Path to a metadata directory for stored events
106
+ # Default: /var/spool/itchy/metadata
107
+ -f, [--required-format=REQUIRED_FORMAT] # Required output format of converted images
108
+ # Default: qcow2
109
+ -o, [--output-dir=OUTPUT_DIR] # Path to a directory where processed events descriptors will be stored
110
+ # Default: /var/spool/itchy/output
111
+ -t, [--temp-image-dir=TEMP_IMAGE_DIR] # Path to a directory where images will be temporary stored while being processed
112
+ # Default: /var/spool/itchy/temp
113
+ -e, [--descriptor-dir=DESCRIPTOR_DIR] # Path to a directory where appliance descriptors will be stored
114
+ # Default: /var/spool/itchy/descriptors
115
+ -p, [--file-permissions=FILE_PERMISSIONS] # Sets permissions for all created files
116
+ # Default: 0664
117
+ -l, [--log-to=LOG_TO] # Logging output, file path or stderr/stdout
118
+ # Default: /var/log/itchy/process.log
119
+ -q, [--qemu-img-binary=QEMU_IMG_BINARY] # Path to qemu-img command binary, if not used, ITCHY will look for it in PATH
120
+ -b, [--log-level=LOG_LEVEL] # Logging level
121
+ # Default: error
122
+ # Possible values: debug, info, warn, error, fatal, unknown
123
+ -d, [--debug], [--no-debug] # Enable debugging
124
+
125
+ Process stored events
126
+ ```
10
127
  ## Contributing
11
128
 
12
129
  1. Fork it ( https://github.com/kosoburak/itchy/fork )
data/bin/itchy CHANGED
@@ -33,12 +33,17 @@ class ItchyRunnable < Thor
33
33
  AVAILABLE_AUTH_METHODS = %w(none basic).freeze
34
34
  ERROR_EXIT_CODE = 1
35
35
 
36
- shared_option_log_level = [:log_level, { enum: AVAILABLE_LOG_LEVELS,
37
- default: Itchy::Settings.log_level,
38
- aliases: '-b', desc: 'Logging level' }]
39
-
40
- shared_option_debug = [:debug, { type: :boolean, default: Itchy::Settings.debug,
41
- aliases: '-d', desc: 'Enable debugging' }]
36
+ class_option :log_level,
37
+ enum: AVAILABLE_LOG_LEVELS,
38
+ default: Itchy::Settings.log_level,
39
+ aliases: '-b',
40
+ desc: 'Logging level'
41
+
42
+ class_option :debug,
43
+ type: :boolean,
44
+ default: Itchy::Settings.debug,
45
+ aliases: '-d',
46
+ desc: 'Enable debugging'
42
47
 
43
48
  # Static method required by Thor to make certain
44
49
  # actions work.
@@ -57,8 +62,8 @@ class ItchyRunnable < Thor
57
62
  method_option :log_to,
58
63
  type: :string,
59
64
  default: Itchy::Settings.log_to.archive_log,
60
- aliasses: '-l',
61
- desc: 'Logging output, file path or stderr/stdout'
65
+ aliases: '-l',
66
+ desc: 'Logging output for archive command, file path or stderr/stdout'
62
67
 
63
68
  method_option :file_permissions,
64
69
  type: :string,
@@ -66,9 +71,6 @@ class ItchyRunnable < Thor
66
71
  aliases: '-p',
67
72
  desc: 'Sets permissions for all created files'
68
73
 
69
- method_option *shared_option_log_level
70
- method_option *shared_option_debug
71
-
72
74
  def archive
73
75
  check_restrictions
74
76
  opts = normalize_options
@@ -125,7 +127,7 @@ class ItchyRunnable < Thor
125
127
  type: :string,
126
128
  default: Itchy::Settings.log_to.process_log,
127
129
  aliases: '-l',
128
- desc: 'Logging output, file path or stderr/stdout'
130
+ desc: 'Logging output for process command, file path or stderr/stdout'
129
131
 
130
132
 
131
133
  method_option :qemu_img_binary,
@@ -134,9 +136,6 @@ class ItchyRunnable < Thor
134
136
  aliases: '-q',
135
137
  desc: 'Path to qemu-img command binary, if not used, ITCHY will look for it in PATH'
136
138
 
137
- method_option *shared_option_log_level
138
- method_option *shared_option_debug
139
-
140
139
  def process
141
140
  check_restrictions
142
141
  opts = normalize_options
@@ -29,6 +29,7 @@ Gem::Specification.new do |gem|
29
29
  gem.add_dependency 'hashie', '~> 3.3', '>= 3.3.1'
30
30
  gem.add_dependency 'thor', '~> 0.19', '>= 0.19.1'
31
31
  gem.add_dependency 'cloud-appliance-descriptor', '~> 0.2'
32
+ gem.add_dependency 'nokogiri', '~>1.6', '>= 1.6.7'
32
33
 
33
34
  gem.add_development_dependency 'bundler', '~> 1.6'
34
35
  gem.add_development_dependency 'rake', '~> 10.0'
@@ -1,4 +1,6 @@
1
1
  require 'active_support/all'
2
+ require 'rubygems'
3
+ require 'nokogiri'
2
4
  require 'settingslogic'
3
5
  require 'multi_json'
4
6
  require 'mixlib/shellout'
@@ -7,12 +9,17 @@ require 'uri'
7
9
  require 'erb'
8
10
  require 'hashie/mash'
9
11
  require 'cloud-appliance-descriptor'
12
+ require 'rubygems/package'
10
13
 
11
14
  # Wraps all internals of the handler.
12
15
  module Itchy
13
16
  BASIC_QEMU_COMMAND = 'qemu-img'
17
+ GEM_DIR = File.realdirpath(File.join(File.dirname(__FILE__), '..'))
18
+ XSD_SCHEMA = File.join(GEM_DIR, 'resources', 'dsp8023_2.0.1.xsd')
19
+ XSD_DIR = File.join(GEM_DIR, 'resources')
14
20
  end
15
21
 
22
+
16
23
  require 'itchy/version'
17
24
  require 'itchy/settings'
18
25
  require 'itchy/log'
@@ -8,6 +8,9 @@ module Itchy
8
8
  # Archive format string msg
9
9
  ARCHIVE_STRING = 'POSIX tar archive'
10
10
 
11
+ # raw boot sector message
12
+ REAL_RAW_STRING = 'boot sector'
13
+
11
14
  # REGEX pattern for getting image format
12
15
  FORMAT_PATTERN = /format:\s(.*?)$/
13
16
 
@@ -34,12 +37,20 @@ module Itchy
34
37
  def transform!(metadata, vmcatcher_configuration)
35
38
  Itchy::Log.info "[#{self.class.name}] Transforming image format " \
36
39
  "for #{metadata.dc_identifier.inspect}"
40
+
41
+ image_file = orig_image_file(metadata, vmcatcher_configuration)
42
+
43
+ unless File.file?(image_file)
44
+ Itchy::Log.error "[#{self.class.name}] Event image file - #{image_file}] - does not exist!"
45
+ fail Itchy::Errors::ImageTransformationError
46
+ end
47
+
37
48
  begin
38
- if archived?(metadata.dc_identifier.inspect)
39
- unpacking_dir = unpack_archived!(metadata, vmcatcher_configuration)
40
- file_format = inspect_unpacked_dir(unpacking_dir, metadata)
49
+ if archived?(image_file)
50
+ unpacking_dir = process_archive(metadata, vmcatcher_configuration)
51
+ file_format = format("#{unpacking_dir}/#{metadata.dc_identifier}")
41
52
  else
42
- file_format = format(orig_image_file(metadata, vmcatcher_configuration))
53
+ file_format = format(image_file)
43
54
  unpacking_dir = copy_unpacked!(metadata, vmcatcher_configuration)
44
55
  end
45
56
  if file_format == @options.required_format
@@ -82,9 +93,85 @@ module Itchy
82
93
  Itchy::Log.error "Image format #{file_format} is unknown and not supported!"
83
94
  fail Itchy::Errors::FileInspectError
84
95
  end
96
+ if file_format.eql? "raw" then
97
+ unless check_real_raw(file)
98
+ Itchy::Log.error "Image format is not a real RAW, it has no boot sector!"
99
+ fail Itchy::Errors::FileInspectError
100
+ end
101
+ end
102
+
85
103
  file_format
86
104
  end
87
105
 
106
+ def check_real_raw(file)
107
+ file_command(file).include? REAL_RAW_STRING
108
+ end
109
+
110
+ def process_archive(metadata, vmcatcher_configuration)
111
+ unpacking_dir = prepare_image_temp_dir(metadata, vmcatcher_configuration)
112
+ File.open(orig_image_file(metadata, vmcatcher_configuration), "rb") do |file|
113
+ Gem::Package::TarReader.new(file) do |archive|
114
+ disk_name = nil
115
+ archive.each do |entry|
116
+ Itchy::Log.debug "EACH NAME: #{entry.full_name}"
117
+ if File.extname(entry.full_name).eql? ".ovf" then
118
+ File.open("#{unpacking_dir}/#{entry.full_name}", "wb") do |f|
119
+ f.write(entry.read)
120
+ end
121
+ disk_name = process_ovf("#{unpacking_dir}/#{entry.full_name}")
122
+ Itchy::Log.debug "FOUND DISK NAME FROM OVF: #{disk_name}"
123
+ break
124
+ end
125
+ end
126
+ begin
127
+ archive.rewind()
128
+ archive.seek(disk_name) do |disk|
129
+ Itchy::Log.debug "Seeked disk - with name: #{disk.full_name}"
130
+ File.open("#{unpacking_dir}/#{metadata.dc_identifier}", "wb") do |f|
131
+ until disk.eof?
132
+ output = disk.read(50000000)
133
+ f.write(output)
134
+ end
135
+ end
136
+ end
137
+ rescue => e
138
+ Ichy::Log.error e.message
139
+ Itchy::Log.error e.backtrace.join("\n")
140
+ fail e
141
+ end
142
+ end
143
+ end
144
+
145
+ unpacking_dir
146
+ end
147
+
148
+ def process_ovf(ovf_file)
149
+ Itchy::Log.debug "PROCESSING OVF FILE: #{ovf_file}"
150
+ doc = Nokogiri::XML(File.open(ovf_file))
151
+ #validate_ovf(doc)
152
+ if doc.css("Envelope DiskSection Disk").count != 1
153
+ Itchy::Log.error "[#{self.class.name}] Unsupported ova, contains 0 or more than one disk!"
154
+ fail Itchy::Errors::FileInspectError
155
+ end
156
+ # return the name of disk
157
+ doc.css("Envelope References File").attr("href").value
158
+ end
159
+
160
+ # Validation is not used for now
161
+ def validate_ovf(doc)
162
+ Itchy::Log.debug "VALIDATING from DIR: #{XSD_DIR} with schema #{XSD_SCHEMA}"
163
+ Dir.chdir(XSD_DIR) do
164
+ xsd = Nokogiri::XML::Schema(File.read(XSD_SCHEMA))
165
+ xsd.validate(doc).each do |error|
166
+ Itchy::Log.error "VALIDATION ERROR: #{error.message}"
167
+ end
168
+ unless xsd.valid?(doc) then
169
+ Itchy::Log.error "[#{self.class.name}] OVF validation failed!"
170
+ fail Itchy::Errors::FileInspectError
171
+ end
172
+ end
173
+ end
174
+
88
175
  #
89
176
  #
90
177
  # @param metadata [Itchy::VmcatcherEvent] event metadata
@@ -215,14 +302,11 @@ module Itchy
215
302
  "#{ex.message}"
216
303
  fail Itchy::Errors::PrepareEnvError, ex
217
304
  end
305
+ temp_dir
218
306
  end
219
307
 
220
- # Checks if file is archived image (format ova or tar)
221
- #
222
- # @param file [String] inspected file name
223
- # @return [Boolean] archived or not
224
- def archived?(file)
225
- image_format_tester = Mixlib::ShellOut.new("file #{file}")
308
+ def file_command(file)
309
+ image_format_tester = Mixlib::ShellOut.new("file --brief #{file}")
226
310
  image_format_tester.run_command
227
311
  begin
228
312
  image_format_tester.error!
@@ -231,9 +315,17 @@ module Itchy
231
315
  Itchy::Log.error "[#{self.class.name}] Checking file format for" \
232
316
  "#{file} failed with #{image_format_tester.stderr}"
233
317
  fail Itchy::Errors::FileInspectError, ex
234
-
235
318
  end
236
- temp = image_format_tester.stdout
319
+ image_format_tester.stdout
320
+ end
321
+
322
+
323
+ # Checks if file is archived image (format ova or tar)
324
+ #
325
+ # @param file [String] inspected file name
326
+ # @return [Boolean] archived or not
327
+ def archived?(file)
328
+ temp = file_command(file)
237
329
  temp.include? ARCHIVE_STRING
238
330
  end
239
331
  end
@@ -1,3 +1,3 @@
1
1
  module Itchy
2
- VERSION = '0.2.7' unless defined?(::Itchy::VERSION)
2
+ VERSION = '0.2.8' unless defined?(::Itchy::VERSION)
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itchy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lubomir Kosaristan
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-03-31 00:00:00.000000000 Z
12
+ date: 2016-05-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: opennebula
@@ -205,6 +205,26 @@ dependencies:
205
205
  - - "~>"
206
206
  - !ruby/object:Gem::Version
207
207
  version: '0.2'
208
+ - !ruby/object:Gem::Dependency
209
+ name: nokogiri
210
+ requirement: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - "~>"
213
+ - !ruby/object:Gem::Version
214
+ version: '1.6'
215
+ - - ">="
216
+ - !ruby/object:Gem::Version
217
+ version: 1.6.7
218
+ type: :runtime
219
+ prerelease: false
220
+ version_requirements: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - "~>"
223
+ - !ruby/object:Gem::Version
224
+ version: '1.6'
225
+ - - ">="
226
+ - !ruby/object:Gem::Version
227
+ version: 1.6.7
208
228
  - !ruby/object:Gem::Dependency
209
229
  name: bundler
210
230
  requirement: !ruby/object:Gem::Requirement