diskid 0.1.3 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/README.md +35 -6
  2. data/Rakefile +1 -0
  3. data/bin/diskid +46 -22
  4. data/bin/diskid-ws +31 -16
  5. data/lib/diskid.rb +68 -1
  6. metadata +29 -18
data/README.md CHANGED
@@ -1,5 +1,16 @@
1
- # Disk Identification Service
1
+ # DiskID
2
2
 
3
+ Get info from a virtual disk file.
4
+
5
+ $ diskid micro-frameos.vmdk
6
+
7
+ diskid.frameos.org
8
+
9
+ file name: micro-frameos.vmdk
10
+ file format: vmdk
11
+ virtual size: 1.2G (1287651328 bytes)
12
+ disk size: 274M (287593984 bytes)
13
+
3
14
  ## Installation
4
15
 
5
16
  gem install diskid
@@ -10,9 +21,9 @@ Internet access is also required, as diskid sends a few bytes to http://diskid.f
10
21
 
11
22
  ## Usage
12
23
 
13
- diskid path-to-disk-file
24
+ diskid --help
14
25
 
15
- i.e.
26
+ ### EXAMPLES
16
27
 
17
28
  $ diskid ubuntu64-1104.vmdk
18
29
 
@@ -20,15 +31,33 @@ i.e.
20
31
 
21
32
  file name: ubuntu64-1104.vmdk
22
33
  file format: vmdk
23
- virtual size: 9.0G (9663676416 bytes)
24
- disk size: 319M (334364672 bytes)
34
+ virtual size: 9.0G
35
+ disk size: 319M
25
36
 
26
37
 
27
38
  PROTIP: You don't need to install diskid to use the service
28
39
 
29
- head -n 20 ubuntu64-1104.vmdk > /tmp/dchunk && curl -X POST -F chunk=@/tmp/dchunk http://diskid.frameos.org
40
+ head -n 20 ubuntu64-1104.vmdk > /tmp/dchunk && curl -X POST -F chunk=@/tmp/dchunk http://diskid.frameos.org/?format=text
30
41
 
42
+ JSON output:
31
43
 
44
+ $ diskid --format json ubuntu64-1104.vmdk
45
+
46
+ diskid.frameos.org
47
+
48
+ {"file_name":"ubuntu64-1104.vmdk","format":"vmdk","virtual_size":"9.0G","disk_size":"319M"}
49
+
50
+ Valid output formats:
51
+
52
+ * json
53
+ * text
54
+ * xml
55
+
56
+ ## NERD STUFF
57
+
58
+ DiskID Webservice is a thin wrapper around the bleeding edge version of qemu-img from the QEMU project: http://qemu.org
59
+
60
+ All the magic happens there!
32
61
 
33
62
  Copyright (c) 2011 Sergio Rubio. See LICENSE.txt for
34
63
  further details.
data/Rakefile CHANGED
@@ -19,6 +19,7 @@ Jeweler::Tasks.new do |gem|
19
19
  gem.add_runtime_dependency 'clamp'
20
20
  gem.add_runtime_dependency 'alchemist'
21
21
  gem.add_runtime_dependency 'rest-client'
22
+ gem.add_runtime_dependency 'json'
22
23
  # dependencies defined in Gemfile
23
24
  end
24
25
  Jeweler::RubygemsDotOrgTasks.new
data/bin/diskid CHANGED
@@ -2,30 +2,54 @@
2
2
  require 'fileutils'
3
3
  require 'clamp'
4
4
  require 'rest-client'
5
+ require 'alchemist'
6
+ require 'diskid'
5
7
 
6
- disk_file = ARGV[0]
7
- if disk_file.nil? or not File.exist?(disk_file)
8
- puts
9
- puts "Usage: diskid path-to-disk-file"
10
- puts
11
- puts "Supported formats: vvfat vpc vmdk vdi sheepdog raw host_cdrom host_floppy host_device file qed qcow2 qcow parallels nbd dmg tftp ftps ftp https http cow cloop bochs blkverify blkdebug"
12
- exit 1
13
- end
14
- host = 'diskid.frameos.org'
8
+ class DiskIDCommand < Clamp::Command
9
+ parameter 'FILE', "Disk file", :attribute_name => 'file'
10
+ option '--server-port', "PORT", "DiskID service port", :default => '80'
11
+ option '--server-host', "HOST", "DiskID service host", :default => 'diskid.frameos.org'
12
+ option '--format', "FORMAT", "Disk info output format (text, json, xml)", :default => 'text'
15
13
 
16
- puts "\n#{host}\n\n"
17
14
 
18
- begin
19
- RestClient.get "http://#{host}/service-check"
20
- rescue => e
21
- $stderr.puts "Couldn't reach http://#{host}."
22
- exit 1
23
- end
15
+ def execute
16
+
17
+ if file.nil? or not File.exist?(file)
18
+ puts
19
+ puts "Usage: diskid path-to-disk-file"
20
+ puts
21
+ puts "Supported formats: vvfat vpc vmdk vdi sheepdog raw host_cdrom host_floppy host_device file qed qcow2 qcow parallels nbd dmg tftp ftps ftp https http cow cloop bochs blkverify blkdebug"
22
+ exit 1
23
+ end
24
+
25
+ puts "\n#{server_host}\n\n"
26
+
27
+ begin
28
+ RestClient.get "http://#{server_host}:#{server_port}/service-check"
29
+ rescue => e
30
+ $stderr.puts "Couldn't reach http://#{server_host}."
31
+ exit 1
32
+ end
24
33
 
25
- out = `head -n 20 #{disk_file}|curl -s -X POST -F chunk=@- -F file_size=#{File.size(disk_file)} -F file_name=#{File.basename(disk_file)} http://#{host} 2>&1`
26
- if $? != 0
27
- $stderr.puts "Something went wrong :("
28
- $stderr.puts out
29
- else
30
- puts out
34
+ fsize = File.size(file).bytes.to.megabytes.to_f.round
35
+ unit = 'M'
36
+ if fsize > 1024
37
+ fsize = fsize.megabytes.to.gigabytes.to_f.round
38
+ unit = 'G'
39
+ end
40
+
41
+ fsize = "#{fsize}#{unit}"
42
+
43
+ #out = `head -n 20 #{file}|curl -s -X POST -F client_version=#{DiskID::VERSION} -F chunk=@- -F file_size=#{fsize} -F file_name=#{File.basename(file)} http://#{server_host}:#{server_port}/?format=#{format} 2>&1`
44
+ out = RestClient.post "http://#{server_host}:#{server_port}/",
45
+ :chunk => File.read(file, 20000),
46
+ :client_version => DiskID::VERSION,
47
+ :file_size => fsize,
48
+ :file_name => File.basename(file),
49
+ :format => format
50
+ puts out
51
+ end
31
52
  end
53
+
54
+ DiskIDCommand.run
55
+
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'sinatra'
3
3
  require 'alchemist'
4
+ require 'diskid'
4
5
 
5
6
  DOCS = """
6
7
  <h1>Virtual Disk Identification Service</h1>
@@ -33,31 +34,41 @@ This web service gives you info about a virtual disk file.
33
34
  class DiskIDWS < Sinatra::Base
34
35
 
35
36
  post '/' do
37
+ # post using CURL
36
38
  tmpfile = params[:chunk][:tempfile] rescue nil
39
+ # File was posted using diskid client
40
+ if not tmpfile
41
+ tmpfile = File.open("/tmp/diskid_#{Time.now.to_i}", 'w+')
42
+ tmpfile.write(params[:chunk])
43
+ end
37
44
  file_name = (params[:file_name] || '') rescue ''
38
45
 
39
46
  if tmpfile.nil?
40
47
  halt 400, "Couldn't understand the file you sent me dude."
41
48
  end
42
- file_size = params[:file_size]
43
- out = `qemu-img-bleeding info #{tmpfile.path}`
44
- if $? != 0
45
- halt 400, "Couldn't understand the file you sent me dude."
46
- end
47
-
49
+ file_size = params[:file_size] || ''
48
50
  begin
49
- buf = ''
50
- if file_name.empty?
51
- buf << "\nSome fields are being omitted and 'disk size:' won't be accurate.\n"
52
- buf << "Use diskid command for better results\n\n"
51
+ inspector = DiskID::Inspector.new(tmpfile.path)
52
+ di = inspector.inspect
53
+ di.file_name = file_name
54
+ di.disk_size = file_size
55
+ if params[:format] == 'json'
56
+ buf = di.to_json
57
+ elsif params[:format] == 'xml'
58
+ buf = di.to_xml
53
59
  else
54
- buf << "file name: #{file_name}\n"
55
- end
56
- out.each_line do |l|
57
- buf << l if l !~ /(image:|disk size:)/
60
+ out = di.to_hash
61
+ buf = ''
62
+ if file_name.empty?
63
+ buf << "\nSome fields are being omitted and 'disk size:' won't be accurate.\n"
64
+ buf << "Use diskid command for better results\n\n"
65
+ else
66
+ buf << "file_name: #{file_name}\n"
67
+ end
68
+ out.each do |k,v|
69
+ buf << "#{k}: #{v}\n" if k != 'file_name'
70
+ end
58
71
  end
59
-
60
- buf << "disk size: #{'%.0f' % file_size.to_i.bytes.to.megabytes.to_f}M (#{file_size} bytes)\n"
61
72
  tmpfile.close
62
73
  FileUtils.rm_f tmpfile.path
63
74
  buf
@@ -72,6 +83,10 @@ class DiskIDWS < Sinatra::Base
72
83
  DOCS
73
84
  end
74
85
 
86
+ get '/' do
87
+ DOCS
88
+ end
89
+
75
90
  error do
76
91
  DOCS
77
92
  end
@@ -1,3 +1,70 @@
1
1
  module DiskID
2
- VERSION = "0.1.3"
2
+
3
+ require 'json'
4
+
5
+ VERSION = "0.2"
6
+
7
+ class DiskInfo
8
+
9
+ attr_accessor :file_name, :format, :virtual_size, :disk_size
10
+
11
+ def initialize(params)
12
+ @hash = params
13
+ @file_name = @hash['file_name']
14
+ @format = @hash['format']
15
+ @virtual_size = @hash['virtual_size']
16
+ @disk_size = @hash['disk_size']
17
+ end
18
+
19
+ def to_json
20
+ to_hash.to_json
21
+ end
22
+
23
+ def to_xml
24
+ buf = ""
25
+ buf << "<disk_info>"
26
+ buf << "<file_name>#{@file_name}</file_name>"
27
+ buf << "<format>#{@format}</format>"
28
+ buf << "<virtual_size>#{@virtual_size}</virtual_size>"
29
+ buf << "<disk_size>#{@disk_size}</disk_size>"
30
+ buf << "</disk_info>"
31
+ buf
32
+ end
33
+
34
+ def to_hash
35
+ {
36
+ 'file_name' => @file_name,
37
+ 'format' => @format,
38
+ 'virtual_size' => @virtual_size,
39
+ 'disk_size' => @disk_size
40
+ }
41
+ end
42
+
43
+ end
44
+
45
+ class Inspector
46
+
47
+
48
+ def initialize(file, qemu_img_bin='qemu-img-bleeding')
49
+ @qemu_img_bin = qemu_img_bin
50
+ @file = file
51
+ end
52
+
53
+ def inspect
54
+ out = `#{@qemu_img_bin} info #{@file}`
55
+ raise Exception.new("Error getting info from #{@file}") if $? != 0
56
+
57
+ md = /image:(.*)$\nfile format:(.*)$\nvirtual size:(.*)$\ndisk size:(.*)\n/.match out
58
+ @file_name,@format,@virtual_size,@disk_size = [md[1], md[2], md[3], md[4]].map { |e| e.strip.chomp }
59
+ @virtual_size = @virtual_size.split()[0]
60
+ DiskInfo.new({
61
+ 'file_name' => @file_name,
62
+ 'format' => @format,
63
+ 'virtual_size' => @virtual_size,
64
+ 'disk_size' => @disk_size
65
+ })
66
+ end
67
+
68
+
69
+ end
3
70
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diskid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: '0.2'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-27 00:00:00.000000000 Z
12
+ date: 2011-10-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: shoulda
16
- requirement: &13197200 !ruby/object:Gem::Requirement
16
+ requirement: &14447600 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *13197200
24
+ version_requirements: *14447600
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bundler
27
- requirement: &13196580 !ruby/object:Gem::Requirement
27
+ requirement: &14446900 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.0.0
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *13196580
35
+ version_requirements: *14446900
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: jeweler
38
- requirement: &13194880 !ruby/object:Gem::Requirement
38
+ requirement: &14446160 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.6.4
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *13194880
46
+ version_requirements: *14446160
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rcov
49
- requirement: &13193980 !ruby/object:Gem::Requirement
49
+ requirement: &14445460 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *13193980
57
+ version_requirements: *14445460
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: sinatra
60
- requirement: &13193260 !ruby/object:Gem::Requirement
60
+ requirement: &14444720 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *13193260
68
+ version_requirements: *14444720
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: clamp
71
- requirement: &13192540 !ruby/object:Gem::Requirement
71
+ requirement: &14443980 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *13192540
79
+ version_requirements: *14443980
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: alchemist
82
- requirement: &13191980 !ruby/object:Gem::Requirement
82
+ requirement: &14443500 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *13191980
90
+ version_requirements: *14443500
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rest-client
93
- requirement: &13207720 !ruby/object:Gem::Requirement
93
+ requirement: &14443020 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,18 @@ dependencies:
98
98
  version: '0'
99
99
  type: :runtime
100
100
  prerelease: false
101
- version_requirements: *13207720
101
+ version_requirements: *14443020
102
+ - !ruby/object:Gem::Dependency
103
+ name: json
104
+ requirement: &14442520 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: *14442520
102
113
  description: Virtual Disk Identification Service
103
114
  email: rubiojr@frameos.org
104
115
  executables: