manageiq-smartstate 0.6.0 → 0.8.0
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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +34 -35
- data/.rubocop.yml +3 -3
- data/.rubocop_cc.yml +3 -4
- data/.rubocop_local.yml +1 -1
- data/.travis.yml +2 -3
- data/lib/MiqVm/MiqRhevmVm.rb +1 -1
- data/lib/db/MiqBdb/MiqBdb.rb +0 -2
- data/lib/db/MiqBdb/MiqBdbPage.rb +0 -2
- data/lib/db/MiqSqlite/MiqSqlite3.rb +0 -2
- data/lib/db/MiqSqlite/MiqSqlite3Cell.rb +0 -2
- data/lib/db/MiqSqlite/MiqSqlite3Page.rb +0 -2
- data/lib/db/MiqSqlite/MiqSqlite3Table.rb +0 -2
- data/lib/disk/modules/MSCommon.rb +3 -1
- data/lib/disk/modules/VhdxDisk.rb +3 -1
- data/lib/fs/MiqMountManager.rb +2 -29
- data/lib/fs/VimDatastoreFS/VimDatastoreFS.rb +1 -6
- data/lib/fs/fat32/directory_entry.rb +540 -540
- data/lib/fs/iso9660/boot_sector.rb +3 -2
- data/lib/fs/iso9660/directory_entry.rb +3 -2
- data/lib/fs/iso9660/rock_ridge.rb +3 -1
- data/lib/fs/ntfs/attrib_attribute_list.rb +3 -1
- data/lib/fs/ntfs/attrib_file_name.rb +3 -1
- data/lib/fs/ntfs/attrib_header.rb +3 -1
- data/lib/fs/ntfs/attrib_index_root.rb +3 -1
- data/lib/fs/ntfs/attrib_volume_name.rb +3 -1
- data/lib/manageiq/smartstate/util.rb +18 -0
- data/lib/manageiq/smartstate/version.rb +1 -1
- data/lib/metadata/MIQExtract/MIQExtract.rb +2 -3
- data/lib/metadata/VmConfig/GetNativeCfg.rb +2 -4
- data/lib/metadata/VmConfig/VmConfig.rb +7 -6
- data/lib/metadata/VmConfig/cfgConfig.rb +4 -0
- data/lib/metadata/VmConfig/xmlConfig.rb +3 -3
- data/lib/metadata/linux/MiqRpmPackages.rb +3 -1
- data/lib/metadata/util/win32/Win32Accounts.rb +3 -1
- data/lib/metadata/util/win32/Win32EventLog.rb +3 -1
- data/lib/metadata/util/win32/Win32Software.rb +5 -3
- data/lib/metadata/util/win32/decode.rb +0 -0
- data/lib/metadata/util/win32/fleece_hives.rb +0 -9
- data/lib/metadata/util/win32/ms-registry.rb +3 -2
- data/lib/metadata/util/win32/peheader.rb +3 -2
- data/lib/metadata/util/win32/system_path_win.rb +0 -2
- data/lib/miq_unicode.rb +45 -0
- data/manageiq-smartstate.gemspec +8 -6
- metadata +66 -23
- data/lib/fs/MetakitFS/MetakitFS.rb +0 -530
data/manageiq-smartstate.gemspec
CHANGED
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
+
spec.add_dependency "activesupport"
|
24
|
+
spec.add_dependency "awesome_spawn", "~> 1.5"
|
23
25
|
spec.add_dependency "azure-armrest", "~> 0.9"
|
24
26
|
spec.add_dependency "binary_struct", "~> 2.1"
|
25
27
|
spec.add_dependency "iniparse"
|
@@ -29,16 +31,16 @@ Gem::Specification.new do |spec|
|
|
29
31
|
spec.add_dependency "rufus-lru", "~>1.0.3"
|
30
32
|
spec.add_dependency "sys-uname", "~>1.2.1"
|
31
33
|
spec.add_dependency "uuidtools", "~>2.1"
|
32
|
-
spec.add_dependency "vmware_web_service", "~>
|
34
|
+
spec.add_dependency "vmware_web_service", "~>3.0"
|
33
35
|
|
34
36
|
spec.add_development_dependency "bundler"
|
37
|
+
spec.add_development_dependency "camcorder"
|
38
|
+
spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0.0"
|
39
|
+
spec.add_development_dependency "manageiq-style"
|
35
40
|
spec.add_development_dependency "rake"
|
36
41
|
spec.add_development_dependency "rspec", "~> 3.0"
|
37
|
-
spec.add_development_dependency "
|
42
|
+
spec.add_development_dependency "simplecov"
|
43
|
+
spec.add_development_dependency "sqlite3"
|
38
44
|
spec.add_development_dependency "vcr", "~>3.0.2"
|
39
45
|
spec.add_development_dependency "webmock", "~>2.3.1"
|
40
|
-
spec.add_development_dependency "simplecov"
|
41
|
-
spec.add_development_dependency "rubocop"
|
42
|
-
spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0.0"
|
43
|
-
|
44
46
|
end
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: manageiq-smartstate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ManageIQ Developers
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: awesome_spawn
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.5'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.5'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: azure-armrest
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +170,14 @@ dependencies:
|
|
142
170
|
requirements:
|
143
171
|
- - "~>"
|
144
172
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
173
|
+
version: '3.0'
|
146
174
|
type: :runtime
|
147
175
|
prerelease: false
|
148
176
|
version_requirements: !ruby/object:Gem::Requirement
|
149
177
|
requirements:
|
150
178
|
- - "~>"
|
151
179
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
180
|
+
version: '3.0'
|
153
181
|
- !ruby/object:Gem::Dependency
|
154
182
|
name: bundler
|
155
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -165,7 +193,7 @@ dependencies:
|
|
165
193
|
- !ruby/object:Gem::Version
|
166
194
|
version: '0'
|
167
195
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
196
|
+
name: camcorder
|
169
197
|
requirement: !ruby/object:Gem::Requirement
|
170
198
|
requirements:
|
171
199
|
- - ">="
|
@@ -179,21 +207,21 @@ dependencies:
|
|
179
207
|
- !ruby/object:Gem::Version
|
180
208
|
version: '0'
|
181
209
|
- !ruby/object:Gem::Dependency
|
182
|
-
name:
|
210
|
+
name: codeclimate-test-reporter
|
183
211
|
requirement: !ruby/object:Gem::Requirement
|
184
212
|
requirements:
|
185
213
|
- - "~>"
|
186
214
|
- !ruby/object:Gem::Version
|
187
|
-
version:
|
215
|
+
version: 1.0.0
|
188
216
|
type: :development
|
189
217
|
prerelease: false
|
190
218
|
version_requirements: !ruby/object:Gem::Requirement
|
191
219
|
requirements:
|
192
220
|
- - "~>"
|
193
221
|
- !ruby/object:Gem::Version
|
194
|
-
version:
|
222
|
+
version: 1.0.0
|
195
223
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
224
|
+
name: manageiq-style
|
197
225
|
requirement: !ruby/object:Gem::Requirement
|
198
226
|
requirements:
|
199
227
|
- - ">="
|
@@ -207,33 +235,33 @@ dependencies:
|
|
207
235
|
- !ruby/object:Gem::Version
|
208
236
|
version: '0'
|
209
237
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
238
|
+
name: rake
|
211
239
|
requirement: !ruby/object:Gem::Requirement
|
212
240
|
requirements:
|
213
|
-
- - "
|
241
|
+
- - ">="
|
214
242
|
- !ruby/object:Gem::Version
|
215
|
-
version:
|
243
|
+
version: '0'
|
216
244
|
type: :development
|
217
245
|
prerelease: false
|
218
246
|
version_requirements: !ruby/object:Gem::Requirement
|
219
247
|
requirements:
|
220
|
-
- - "
|
248
|
+
- - ">="
|
221
249
|
- !ruby/object:Gem::Version
|
222
|
-
version:
|
250
|
+
version: '0'
|
223
251
|
- !ruby/object:Gem::Dependency
|
224
|
-
name:
|
252
|
+
name: rspec
|
225
253
|
requirement: !ruby/object:Gem::Requirement
|
226
254
|
requirements:
|
227
255
|
- - "~>"
|
228
256
|
- !ruby/object:Gem::Version
|
229
|
-
version:
|
257
|
+
version: '3.0'
|
230
258
|
type: :development
|
231
259
|
prerelease: false
|
232
260
|
version_requirements: !ruby/object:Gem::Requirement
|
233
261
|
requirements:
|
234
262
|
- - "~>"
|
235
263
|
- !ruby/object:Gem::Version
|
236
|
-
version:
|
264
|
+
version: '3.0'
|
237
265
|
- !ruby/object:Gem::Dependency
|
238
266
|
name: simplecov
|
239
267
|
requirement: !ruby/object:Gem::Requirement
|
@@ -249,7 +277,7 @@ dependencies:
|
|
249
277
|
- !ruby/object:Gem::Version
|
250
278
|
version: '0'
|
251
279
|
- !ruby/object:Gem::Dependency
|
252
|
-
name:
|
280
|
+
name: sqlite3
|
253
281
|
requirement: !ruby/object:Gem::Requirement
|
254
282
|
requirements:
|
255
283
|
- - ">="
|
@@ -263,19 +291,33 @@ dependencies:
|
|
263
291
|
- !ruby/object:Gem::Version
|
264
292
|
version: '0'
|
265
293
|
- !ruby/object:Gem::Dependency
|
266
|
-
name:
|
294
|
+
name: vcr
|
267
295
|
requirement: !ruby/object:Gem::Requirement
|
268
296
|
requirements:
|
269
297
|
- - "~>"
|
270
298
|
- !ruby/object:Gem::Version
|
271
|
-
version:
|
299
|
+
version: 3.0.2
|
272
300
|
type: :development
|
273
301
|
prerelease: false
|
274
302
|
version_requirements: !ruby/object:Gem::Requirement
|
275
303
|
requirements:
|
276
304
|
- - "~>"
|
277
305
|
- !ruby/object:Gem::Version
|
278
|
-
version:
|
306
|
+
version: 3.0.2
|
307
|
+
- !ruby/object:Gem::Dependency
|
308
|
+
name: webmock
|
309
|
+
requirement: !ruby/object:Gem::Requirement
|
310
|
+
requirements:
|
311
|
+
- - "~>"
|
312
|
+
- !ruby/object:Gem::Version
|
313
|
+
version: 2.3.1
|
314
|
+
type: :development
|
315
|
+
prerelease: false
|
316
|
+
version_requirements: !ruby/object:Gem::Requirement
|
317
|
+
requirements:
|
318
|
+
- - "~>"
|
319
|
+
- !ruby/object:Gem::Version
|
320
|
+
version: 2.3.1
|
279
321
|
description: ManageIQ SmartState Analysis
|
280
322
|
email:
|
281
323
|
executables: []
|
@@ -376,7 +418,6 @@ files:
|
|
376
418
|
- lib/disk/modules/miq_dummy_disk.rb
|
377
419
|
- lib/disk/modules/vhdx_bat_entry.rb
|
378
420
|
- lib/disk/test.rb
|
379
|
-
- lib/fs/MetakitFS/MetakitFS.rb
|
380
421
|
- lib/fs/MiqFS/FsProbe.rb
|
381
422
|
- lib/fs/MiqFS/MiqFS.rb
|
382
423
|
- lib/fs/MiqFS/modules/AUFSProbe.rb
|
@@ -546,6 +587,7 @@ files:
|
|
546
587
|
- lib/metadata/util/win32/Win32Software.rb
|
547
588
|
- lib/metadata/util/win32/Win32System.rb
|
548
589
|
- lib/metadata/util/win32/boot_info_win.rb
|
590
|
+
- lib/metadata/util/win32/decode.rb
|
549
591
|
- lib/metadata/util/win32/fleece_hives.rb
|
550
592
|
- lib/metadata/util/win32/ms-registry.rb
|
551
593
|
- lib/metadata/util/win32/peheader.rb
|
@@ -553,6 +595,7 @@ files:
|
|
553
595
|
- lib/metadata/util/win32/system_path_win.rb
|
554
596
|
- lib/metadata/util/win32/versioninfo.rb
|
555
597
|
- lib/miq_tempfile.rb
|
598
|
+
- lib/miq_unicode.rb
|
556
599
|
- lib/tasks/azure.rake
|
557
600
|
- log/.gitkeep
|
558
601
|
- manageiq-smartstate.gemspec
|
@@ -575,7 +618,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
575
618
|
- !ruby/object:Gem::Version
|
576
619
|
version: '0'
|
577
620
|
requirements: []
|
578
|
-
rubygems_version: 3.
|
621
|
+
rubygems_version: 3.2.5
|
579
622
|
signing_key:
|
580
623
|
specification_version: 4
|
581
624
|
summary: ManageIQ SmartState Analysis
|
@@ -1,530 +0,0 @@
|
|
1
|
-
# encoding: US-ASCII
|
2
|
-
|
3
|
-
require 'mk4rb'
|
4
|
-
|
5
|
-
module MetakitFS
|
6
|
-
MK_FENTRY = "fentry[fpath:S,ftype:I,fsize:I,ftags:B,fdata:B]"
|
7
|
-
MK_HASHVW = "sec[_H:I,_R:I]"
|
8
|
-
|
9
|
-
TYPE_FILE = 1
|
10
|
-
TYPE_DIR = 2
|
11
|
-
TYPE_SYMLINK = 3
|
12
|
-
|
13
|
-
def self.supported?(dobj)
|
14
|
-
return(false) unless dobj.mkfile
|
15
|
-
storage = Metakit::Storage.open(dobj.mkfile, 1)
|
16
|
-
return(false) if storage.description != "#{MK_FENTRY},#{MK_HASHVW}"
|
17
|
-
(true)
|
18
|
-
end
|
19
|
-
|
20
|
-
def fs_init
|
21
|
-
raise "No metakit file has been specified" unless @dobj.mkfile
|
22
|
-
@storage = Metakit::Storage.open(@dobj.mkfile, 1)
|
23
|
-
|
24
|
-
newFs = false
|
25
|
-
if @storage.description != "#{MK_FENTRY},#{MK_HASHVW}"
|
26
|
-
raise "#{@dobj.mkfile} is not a MetakitFS" unless @dobj.create
|
27
|
-
newFs = true
|
28
|
-
end
|
29
|
-
|
30
|
-
self.fsType = "MetakitFS"
|
31
|
-
|
32
|
-
vData = @storage.get_as MK_FENTRY
|
33
|
-
vSec = @storage.get_as MK_HASHVW
|
34
|
-
@vFentry = vData.hash(vSec, 1)
|
35
|
-
|
36
|
-
@pPath = Metakit::StringProp.new "fpath"
|
37
|
-
@pType = Metakit::IntProp.new "ftype"
|
38
|
-
@pSize = Metakit::IntProp.new "fsize"
|
39
|
-
@pTags = Metakit::BytesProp.new "ftags"
|
40
|
-
@pData = Metakit::BytesProp.new "fdata"
|
41
|
-
|
42
|
-
@findRow = Metakit::Row.new
|
43
|
-
|
44
|
-
#
|
45
|
-
# If we're creating a new file system, create the root directory.
|
46
|
-
#
|
47
|
-
if newFs
|
48
|
-
create("/", TYPE_DIR) if newFs
|
49
|
-
@storage.commit
|
50
|
-
end
|
51
|
-
|
52
|
-
labels = fs_tagValues("/", "LABEL")
|
53
|
-
@fsId = labels[0] unless labels.empty?
|
54
|
-
end
|
55
|
-
|
56
|
-
def fs_dirEntries(p)
|
57
|
-
raise "Directory: #{p} does not exist" if (i = getFileIndex(p)) < 0
|
58
|
-
raise "#{p} is not a directory" if @pType.get(@vFentry[i]) != TYPE_DIR
|
59
|
-
|
60
|
-
data = @pData.get(@vFentry[i])
|
61
|
-
return [] if data.size == 0
|
62
|
-
data.contents.split("\0")
|
63
|
-
end
|
64
|
-
|
65
|
-
def fs_dirMkdir(p)
|
66
|
-
#
|
67
|
-
# If the target exists, succeed if it is a directory, otherwise fail.
|
68
|
-
#
|
69
|
-
if (i = getFileIndex(p)) >= 0
|
70
|
-
return if @pType.get(@vFentry[i]) == TYPE_DIR
|
71
|
-
raise "Cannot create directory, #{p}: file exists"
|
72
|
-
end
|
73
|
-
|
74
|
-
#
|
75
|
-
# Create the directory.
|
76
|
-
#
|
77
|
-
create(p, TYPE_DIR)
|
78
|
-
|
79
|
-
#
|
80
|
-
# Apply changes to database.
|
81
|
-
#
|
82
|
-
@storage.commit
|
83
|
-
end
|
84
|
-
|
85
|
-
def fs_dirRmdir(p)
|
86
|
-
#
|
87
|
-
# Before we can remove a directory, it must:
|
88
|
-
# exist, be a directory and be empty.
|
89
|
-
#
|
90
|
-
raise "#{p}: no such directory" if (di = getFileIndex(p)) < 0
|
91
|
-
dirRow = @vFentry[di]
|
92
|
-
raise "#{p}: not a directory" if @pType.get(dirRow) != TYPE_DIR
|
93
|
-
raise "#{p}: directory not empty" if @pSize.get(dirRow) != 0
|
94
|
-
|
95
|
-
rmCommon(p, di)
|
96
|
-
end
|
97
|
-
|
98
|
-
def fs_fileExists?(p)
|
99
|
-
return false if getFileIndex(p) < 0
|
100
|
-
true
|
101
|
-
end
|
102
|
-
|
103
|
-
def fs_fileFile?(p)
|
104
|
-
return false if (i = getFileIndex(p)) < 0
|
105
|
-
return true if @pType.get(@vFentry[i]) == TYPE_FILE
|
106
|
-
false
|
107
|
-
end
|
108
|
-
|
109
|
-
def fs_fileDirectory?(p)
|
110
|
-
return false if (i = getFileIndex(p)) < 0
|
111
|
-
return true if @pType.get(@vFentry[i]) == TYPE_DIR
|
112
|
-
false
|
113
|
-
end
|
114
|
-
|
115
|
-
def fs_fileSize(p)
|
116
|
-
raise "File: #{p} does not exist" if (i = getFileIndex(p)) < 0
|
117
|
-
(@pSize.get(@vFentry[i]))
|
118
|
-
end
|
119
|
-
|
120
|
-
def fs_fileSize_obj(fobj)
|
121
|
-
(@pSize.get(fobj.fileRow))
|
122
|
-
end
|
123
|
-
|
124
|
-
def fs_fileAtime(p)
|
125
|
-
File.atime(p)
|
126
|
-
end
|
127
|
-
|
128
|
-
def fs_fileCtime(p)
|
129
|
-
File.ctime(p)
|
130
|
-
end
|
131
|
-
|
132
|
-
def fs_fileMtime(p)
|
133
|
-
File.mtime(p)
|
134
|
-
end
|
135
|
-
|
136
|
-
def fs_fileAtime_obj(fobj)
|
137
|
-
fobj.atime
|
138
|
-
end
|
139
|
-
|
140
|
-
def fs_fileCtime_obj(fobj)
|
141
|
-
fobj.ctime
|
142
|
-
end
|
143
|
-
|
144
|
-
def fs_fileMtime_obj(fobj)
|
145
|
-
fobj.mtime
|
146
|
-
end
|
147
|
-
|
148
|
-
def fs_fileOpen(p, mode = "r")
|
149
|
-
fread = fwrite = fcreate = ftruncate = fappend = false
|
150
|
-
mode.delete!("b")
|
151
|
-
|
152
|
-
case mode[0, 1]
|
153
|
-
when "r"
|
154
|
-
fread = true
|
155
|
-
fwrite = true if mode[-1, 1] == "+"
|
156
|
-
when "w"
|
157
|
-
fwrite = true
|
158
|
-
fcreate = true
|
159
|
-
ftruncate = true
|
160
|
-
fread = true if mode[-1, 1] == "+"
|
161
|
-
when "a"
|
162
|
-
fwrite = true
|
163
|
-
fcreate = true
|
164
|
-
fappend = true
|
165
|
-
fread = true if mode[-1, 1] == "+"
|
166
|
-
else
|
167
|
-
raise "Unrecognized open mode: #{mode}"
|
168
|
-
end
|
169
|
-
|
170
|
-
fileRow = nil
|
171
|
-
fi = getFileIndex(p)
|
172
|
-
|
173
|
-
if fi < 0
|
174
|
-
#
|
175
|
-
# Should we create the file? If not, fail.
|
176
|
-
#
|
177
|
-
raise "#{p}: No such file" unless fcreate
|
178
|
-
|
179
|
-
#
|
180
|
-
# Create the file if it doesn't exist.
|
181
|
-
#
|
182
|
-
fileRow = create(p, TYPE_FILE)
|
183
|
-
fi = getFileIndex(p)
|
184
|
-
else
|
185
|
-
fileRow = @vFentry[fi]
|
186
|
-
end
|
187
|
-
|
188
|
-
fpos = 0
|
189
|
-
fsize = @pSize.get(fileRow)
|
190
|
-
if ftruncate && fsize != 0
|
191
|
-
@pSize.set fileRow, 0
|
192
|
-
@pData.set fileRow, Metakit::Bytes.new("", 0)
|
193
|
-
@storage.commit
|
194
|
-
elsif fappend
|
195
|
-
fpos = fsize
|
196
|
-
end
|
197
|
-
|
198
|
-
(MkFile.new(p, fileRow, fpos, fread, fwrite))
|
199
|
-
end # def fs_fileOpen
|
200
|
-
|
201
|
-
def fs_fileSeek(fobj, _offset, whence)
|
202
|
-
seekPos = 0
|
203
|
-
case whence
|
204
|
-
when IO::SEEK_CUR
|
205
|
-
seekPos = filePos + amt
|
206
|
-
when IO::SEEK_END
|
207
|
-
seekPos = fs_fileSize_obj(fobj) + amt
|
208
|
-
when IO::SEEK_SET
|
209
|
-
seekPos = amt
|
210
|
-
else
|
211
|
-
raise "Invalid whence value: #{whence}"
|
212
|
-
end
|
213
|
-
raise "Invalid seek position: #{seekPos}" if seekPos < 0 || seekPos > fs_fileSize_obj(fobj)
|
214
|
-
|
215
|
-
fobj.filePos = seekPos
|
216
|
-
end
|
217
|
-
|
218
|
-
def fs_fileRead(fobj, len)
|
219
|
-
dataRef = @pData.ref(fobj.fileRow)
|
220
|
-
rb = dataRef.access(fobj.filePos, len)
|
221
|
-
fobj.filePos += rb.size
|
222
|
-
return(rb.contents) if rb.contents.length > 0
|
223
|
-
(nil)
|
224
|
-
end
|
225
|
-
|
226
|
-
def fs_fileWrite(fobj, buf, len)
|
227
|
-
raise "fs_fileWrite: write length is larger than buffer" if len > buf.length
|
228
|
-
size = fs_fileSize_obj(fobj)
|
229
|
-
|
230
|
-
if fobj.filePos == size
|
231
|
-
#
|
232
|
-
# We're appending to the end of the file, so we can just use the
|
233
|
-
# modify operation to add the data to the end of the file.
|
234
|
-
#
|
235
|
-
dataRef = @pData.ref(fobj.fileRow)
|
236
|
-
data = Metakit::Bytes.new(buf, len)
|
237
|
-
dataRef.modify(data, size, len)
|
238
|
-
@pSize.set(fobj.fileRow, size + len)
|
239
|
-
fobj.filePos += len
|
240
|
-
@storage.commit
|
241
|
-
return(len)
|
242
|
-
end
|
243
|
-
#
|
244
|
-
# The Metakit modify operation inserts data. So if we need to overwrite
|
245
|
-
# existing data, we must read the whole file, modify the data, and write
|
246
|
-
# it out again.
|
247
|
-
#
|
248
|
-
dataStr = @pData.get(fobj.fileRow).contents
|
249
|
-
dataStr[fobj.filePos, len] = buf[0, len]
|
250
|
-
data = Metakit::Bytes.new(dataStr, dataStr.length)
|
251
|
-
@pData.set(fobj.fileRow, data)
|
252
|
-
@pSize.set(fobj.fileRow, dataStr.length)
|
253
|
-
@storage.commit
|
254
|
-
(len)
|
255
|
-
end
|
256
|
-
|
257
|
-
def fs_fileClose(_fobj)
|
258
|
-
nil
|
259
|
-
end
|
260
|
-
|
261
|
-
def fs_fileDelete(p)
|
262
|
-
#
|
263
|
-
# Before we can remove a directory, it must:
|
264
|
-
# exist, be a directory and be empty.
|
265
|
-
#
|
266
|
-
raise "#{p}: no such file" if (fi = getFileIndex(p)) < 0
|
267
|
-
dirRow = @vFentry[di]
|
268
|
-
raise "#{p}: is a directory" if @pType.get(dirRow) == TYPE_DIR
|
269
|
-
|
270
|
-
rmCommon(p, fi)
|
271
|
-
end
|
272
|
-
|
273
|
-
def tagAdd(p, tag)
|
274
|
-
fs_tagAdd(normalizePath(p), tag)
|
275
|
-
end
|
276
|
-
|
277
|
-
def fs_tagAdd(p, tag)
|
278
|
-
raise "Path: #{p} does not exist" if (i = getFileIndex(p)) < 0
|
279
|
-
fileRow = @vFentry[i]
|
280
|
-
fs_tagAddCommon(fileRow, tag)
|
281
|
-
end
|
282
|
-
|
283
|
-
def fs_fileTagAdd(fobj, tag)
|
284
|
-
fs_tagAddCommon(fobj.fileRow, tag)
|
285
|
-
end
|
286
|
-
|
287
|
-
def fs_tagAddCommon(fileRow, tag)
|
288
|
-
tagStr = @pTags.get(fileRow).contents
|
289
|
-
tags = tagStr.split("\0")
|
290
|
-
return if tags.include? tag
|
291
|
-
tags << tag
|
292
|
-
tagStr = tags.join("\0")
|
293
|
-
@pTags.set(fileRow, Metakit::Bytes.new(tagStr, tagStr.length))
|
294
|
-
@storage.commit
|
295
|
-
end
|
296
|
-
|
297
|
-
def tagDelete(p, tag)
|
298
|
-
fs_tagDelete(normalizePath(p), tag)
|
299
|
-
end
|
300
|
-
|
301
|
-
def fs_tagDelete(p, tag)
|
302
|
-
raise "Path: #{p} does not exist" if (i = getFileIndex(p)) < 0
|
303
|
-
fileRow = @vFentry[i]
|
304
|
-
fs_tagDeleteCommon(fileRow, tag)
|
305
|
-
end
|
306
|
-
|
307
|
-
def fs_fileTagDelete(fobj, tag)
|
308
|
-
fs_tagDeleteCommon(fobj.fileRow, tag)
|
309
|
-
end
|
310
|
-
|
311
|
-
def fs_tagDeleteCommon(fileRow, tag)
|
312
|
-
tagStr = @pTags.get(fileRow).contents
|
313
|
-
tags = tagStr.split("\0")
|
314
|
-
tags.delete(tag) { raise "Tag #{tag} not found" }
|
315
|
-
tagStr = tags.join("\0")
|
316
|
-
@pTags.set(fileRow, Metakit::Bytes.new(tagStr, tagStr.length))
|
317
|
-
@storage.commit
|
318
|
-
end
|
319
|
-
|
320
|
-
def tags(p)
|
321
|
-
fs_tags(normalizePath(p))
|
322
|
-
end
|
323
|
-
|
324
|
-
def fs_tags(p)
|
325
|
-
raise "Path: #{p} does not exist" if (i = getFileIndex(p)) < 0
|
326
|
-
fileRow = @vFentry[i]
|
327
|
-
fs_tagsCommon(fileRow)
|
328
|
-
end
|
329
|
-
|
330
|
-
def fs_fileTags(fobj)
|
331
|
-
fs_tagsCommon(fobj.fileRow)
|
332
|
-
end
|
333
|
-
|
334
|
-
def fs_tagsCommon(fileRow)
|
335
|
-
tags = @pTags.get(fileRow)
|
336
|
-
return [] if tags.size == 0
|
337
|
-
tags.contents.split("\0")
|
338
|
-
end
|
339
|
-
|
340
|
-
def hasTagName?(p, tag)
|
341
|
-
fs_hasTagName?(normalizePath(p), tag)
|
342
|
-
end
|
343
|
-
|
344
|
-
def fs_hasTagName?(p, tagName)
|
345
|
-
raise "Path: #{p} does not exist" if (i = getFileIndex(p)) < 0
|
346
|
-
fileRow = @vFentry[i]
|
347
|
-
fs_hasTagNameCommon?(fileRow, tagName)
|
348
|
-
end
|
349
|
-
|
350
|
-
def fs_fileHasTagName?(fobj, tagName)
|
351
|
-
fs_hasTagNameCommon?(fobj.fileRow, tagName)
|
352
|
-
end
|
353
|
-
|
354
|
-
def fs_hasTagNameCommon?(fileRow, tagName)
|
355
|
-
fs_tagsCommon(fileRow).each { |t| return true if t =~ /#{tagName}(=.*)*$/ }
|
356
|
-
false
|
357
|
-
end
|
358
|
-
|
359
|
-
def hasTag?(p, tag)
|
360
|
-
fs_hasTag?(normalizePath(p), tag)
|
361
|
-
end
|
362
|
-
|
363
|
-
def fs_hasTag?(p, tag)
|
364
|
-
raise "Path: #{p} does not exist" if (i = getFileIndex(p)) < 0
|
365
|
-
fileRow = @vFentry[i]
|
366
|
-
fs_hasTagCommon?(fileRow, tag)
|
367
|
-
end
|
368
|
-
|
369
|
-
def fs_fileHasTag?(fobj, tag)
|
370
|
-
fs_tagsCommon(fobj.fileRow).include?(tag)
|
371
|
-
end
|
372
|
-
|
373
|
-
def fs_hasTagCommon?(fileRow, tag)
|
374
|
-
fs_tagsCommon(fileRow).include?(tag)
|
375
|
-
end
|
376
|
-
|
377
|
-
def tagValues(p, tag)
|
378
|
-
fs_tagValues(normalizePath(p), tag)
|
379
|
-
end
|
380
|
-
|
381
|
-
def fs_tagValues(p, tag)
|
382
|
-
raise "Path: #{p} does not exist" if (i = getFileIndex(p)) < 0
|
383
|
-
fileRow = @vFentry[i]
|
384
|
-
fs_tagValuesCommon(fileRow, tag)
|
385
|
-
end
|
386
|
-
|
387
|
-
def fs_fileTagValues(fobj, tag)
|
388
|
-
fs_tagValuesCommon(fobj.fileRow, tag)
|
389
|
-
end
|
390
|
-
|
391
|
-
def fs_tagValuesCommon(fileRow, tag)
|
392
|
-
values = []
|
393
|
-
tagFound = false
|
394
|
-
fs_tagsCommon(fileRow).each do |t|
|
395
|
-
if t =~ /#{tag}(=(.*))*$/
|
396
|
-
tagFound = true
|
397
|
-
values << $2 if $2
|
398
|
-
end
|
399
|
-
end
|
400
|
-
|
401
|
-
return [] unless tagFound
|
402
|
-
values
|
403
|
-
end
|
404
|
-
|
405
|
-
def fs_fileObjExtend(fo)
|
406
|
-
fo.extend MkFileMod
|
407
|
-
end
|
408
|
-
|
409
|
-
private
|
410
|
-
|
411
|
-
def getFileIndex(p)
|
412
|
-
@pPath.set @findRow, p
|
413
|
-
(@vFentry.find(@findRow, 0))
|
414
|
-
end
|
415
|
-
|
416
|
-
def rmCommon(p, idx)
|
417
|
-
#
|
418
|
-
# If we get here, the parent hast to exist and it has to be a directory,
|
419
|
-
# so if it isn't, there's a bug somewhere.
|
420
|
-
#
|
421
|
-
parent = File.dirname(p)
|
422
|
-
raise "[BUG] #{parent}: no such directory" if (pi = getFileIndex(parent)) < 0
|
423
|
-
parentRow = @vFentry[pi]
|
424
|
-
raise "[BUG] #{parent}: not a directory" if @pType.get(parentRow) != TYPE_DIR
|
425
|
-
|
426
|
-
#
|
427
|
-
# First, remove the reference in the parent directory.
|
428
|
-
#
|
429
|
-
dirName = File.basename(p)
|
430
|
-
dataStr = @pData.get(parentRow).contents
|
431
|
-
dirEnts = dataStr.split("\0")
|
432
|
-
dirEnts.delete(dirName) { raise "[BUG] Directory #{parent} does not contain entry for #{dirName}" }
|
433
|
-
dataStr = dirEnts.join("\0")
|
434
|
-
@pData.set(parentRow, Metakit::Bytes.new(dataStr, dataStr.length))
|
435
|
-
|
436
|
-
#
|
437
|
-
# Then, remove the directory's row from the database.
|
438
|
-
#
|
439
|
-
@vFentry.remove_at(idx)
|
440
|
-
|
441
|
-
#
|
442
|
-
# Apply changes to database.
|
443
|
-
#
|
444
|
-
@storage.commit
|
445
|
-
end
|
446
|
-
|
447
|
-
def create(p, type)
|
448
|
-
#
|
449
|
-
# Fail if the parent component of the path doesn't exist,
|
450
|
-
# or if it is not a directory.
|
451
|
-
#
|
452
|
-
if p != "/"
|
453
|
-
parent = File.dirname(p)
|
454
|
-
raise "#{parent}: no such directory" if (i = getFileIndex(parent)) < 0
|
455
|
-
parentRow = @vFentry[i]
|
456
|
-
raise "#{parent}: not a directory" if @pType.get(parentRow) != TYPE_DIR
|
457
|
-
end
|
458
|
-
|
459
|
-
#
|
460
|
-
# Create the new empty file or directory.
|
461
|
-
#
|
462
|
-
newRow = Metakit::Row.new
|
463
|
-
@pPath.set newRow, p
|
464
|
-
@pType.set newRow, type
|
465
|
-
@pSize.set newRow, 0
|
466
|
-
@pTags.set newRow, Metakit::Bytes.new("", 0)
|
467
|
-
@pData.set newRow, Metakit::Bytes.new("", 0)
|
468
|
-
@vFentry.add newRow
|
469
|
-
|
470
|
-
if p != "/"
|
471
|
-
#
|
472
|
-
# Then, add an entry for the new file or directory in its parent.
|
473
|
-
#
|
474
|
-
dirName = File.basename(p) + "\0"
|
475
|
-
dataRef = @pData.ref(parentRow)
|
476
|
-
data = Metakit::Bytes.new(dirName, dirName.length)
|
477
|
-
size = @pSize.get(parentRow)
|
478
|
-
dataRef.modify(data, size, data.size)
|
479
|
-
@pSize.set(parentRow, size + data.size)
|
480
|
-
end
|
481
|
-
|
482
|
-
@storage.commit
|
483
|
-
|
484
|
-
fi = getFileIndex(p)
|
485
|
-
raise "[BUG] can't find new file: #{p}" if fi < 0
|
486
|
-
|
487
|
-
#
|
488
|
-
# Must use row obtained through @vFentry.
|
489
|
-
#
|
490
|
-
(@vFentry[fi])
|
491
|
-
end
|
492
|
-
|
493
|
-
class MkFile
|
494
|
-
attr_accessor :filePath, :fileRow, :filePos, :fileRead, :fileWrite
|
495
|
-
|
496
|
-
def initialize(path, fileRow, fpos, fread, fwrite)
|
497
|
-
@filePath = path
|
498
|
-
@fileRow = fileRow
|
499
|
-
@filePos = fpos
|
500
|
-
@fileRead = fread
|
501
|
-
@fileWrite = fwrite
|
502
|
-
end
|
503
|
-
end # class MkFile
|
504
|
-
end # module MetakitFS
|
505
|
-
|
506
|
-
module MkFileMod
|
507
|
-
def addTag(tag)
|
508
|
-
@fs.fs_fileTagAdd(@fobj, tag)
|
509
|
-
end
|
510
|
-
|
511
|
-
def deleteTag(tag)
|
512
|
-
@fs.fs_fileTagDelete(@fobj, tag)
|
513
|
-
end
|
514
|
-
|
515
|
-
def tags
|
516
|
-
@fs.fs_fileTags(@fobj)
|
517
|
-
end
|
518
|
-
|
519
|
-
def hasTagName?(tagName)
|
520
|
-
@fs.fs_fileHasTagName?(@fobj, tagName)
|
521
|
-
end
|
522
|
-
|
523
|
-
def hasTag?(tag)
|
524
|
-
@fs.fs_fileHasTag?(@fobj, tag)
|
525
|
-
end
|
526
|
-
|
527
|
-
def tagValues(tag)
|
528
|
-
@fs.fs_fileTagValues(@fobj, tag)
|
529
|
-
end
|
530
|
-
end
|