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.
- data/README.md +35 -6
- data/Rakefile +1 -0
- data/bin/diskid +46 -22
- data/bin/diskid-ws +31 -16
- data/lib/diskid.rb +68 -1
- metadata +29 -18
data/README.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
|
-
#
|
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
|
24
|
+
diskid --help
|
14
25
|
|
15
|
-
|
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
|
24
|
-
disk size: 319M
|
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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
+
|
data/bin/diskid-ws
CHANGED
@@ -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
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
data/lib/diskid.rb
CHANGED
@@ -1,3 +1,70 @@
|
|
1
1
|
module DiskID
|
2
|
-
|
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.
|
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-
|
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: &
|
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: *
|
24
|
+
version_requirements: *14447600
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: bundler
|
27
|
-
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: *
|
35
|
+
version_requirements: *14446900
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: jeweler
|
38
|
-
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: *
|
46
|
+
version_requirements: *14446160
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rcov
|
49
|
-
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: *
|
57
|
+
version_requirements: *14445460
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: sinatra
|
60
|
-
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: *
|
68
|
+
version_requirements: *14444720
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: clamp
|
71
|
-
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: *
|
79
|
+
version_requirements: *14443980
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: alchemist
|
82
|
-
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: *
|
90
|
+
version_requirements: *14443500
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: rest-client
|
93
|
-
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: *
|
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:
|