diskid 0.1.3 → 0.2

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 (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: