manageiq-smartstate 0.5.9 → 0.7.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +34 -35
  3. data/.rubocop.yml +3 -3
  4. data/.rubocop_cc.yml +3 -4
  5. data/.rubocop_local.yml +1 -1
  6. data/.travis.yml +2 -3
  7. data/lib/MiqVm/MiqRhevmVm.rb +1 -1
  8. data/lib/MiqVm/MiqVm.rb +0 -140
  9. data/lib/OpenStackExtract/MiqOpenStackVm/MiqOpenStackImage.rb +0 -1
  10. data/lib/OpenStackExtract/MiqOpenStackVm/MiqOpenStackInstance.rb +0 -1
  11. data/lib/VolumeManager/MiqLdm.rb +1 -1
  12. data/lib/db/MiqSqlite/MiqSqlite3Cell.rb +2 -3
  13. data/lib/disk/modules/MSCommon.rb +3 -1
  14. data/lib/disk/modules/VhdxDisk.rb +3 -1
  15. data/lib/fs/MiqMountManager.rb +2 -29
  16. data/lib/fs/VimDatastoreFS/VimDatastoreFS.rb +1 -6
  17. data/lib/fs/ext3/superblock.rb +1 -1
  18. data/lib/fs/ext4/superblock.rb +2 -2
  19. data/lib/fs/fat32/directory_entry.rb +60 -60
  20. data/lib/fs/iso9660/boot_sector.rb +3 -2
  21. data/lib/fs/iso9660/directory_entry.rb +3 -2
  22. data/lib/fs/iso9660/rock_ridge.rb +3 -1
  23. data/lib/fs/modules/LinuxMount.rb +3 -3
  24. data/lib/fs/ntfs/attrib_attribute_list.rb +3 -1
  25. data/lib/fs/ntfs/attrib_file_name.rb +3 -1
  26. data/lib/fs/ntfs/attrib_header.rb +3 -1
  27. data/lib/fs/ntfs/attrib_index_root.rb +3 -1
  28. data/lib/fs/ntfs/attrib_object_id.rb +1 -1
  29. data/lib/fs/ntfs/attrib_volume_name.rb +3 -1
  30. data/lib/fs/xfs/allocation_group.rb +1 -1
  31. data/lib/fs/xfs/bmap_btree_block.rb +1 -1
  32. data/lib/fs/xfs/superblock.rb +1 -1
  33. data/lib/manageiq/smartstate/util.rb +18 -0
  34. data/lib/manageiq/smartstate/version.rb +1 -1
  35. data/lib/metadata/MIQExtract/MIQExtract.rb +2 -3
  36. data/lib/metadata/VmConfig/GetNativeCfg.rb +2 -4
  37. data/lib/metadata/VmConfig/VmConfig.rb +7 -5
  38. data/lib/metadata/VmConfig/cfgConfig.rb +4 -0
  39. data/lib/metadata/VmConfig/xmlConfig.rb +3 -3
  40. data/lib/metadata/linux/MiqRpmPackages.rb +3 -1
  41. data/lib/metadata/util/md5deep.rb +4 -2
  42. data/lib/metadata/util/win32/Win32Accounts.rb +3 -0
  43. data/lib/metadata/util/win32/Win32EventLog.rb +5 -3
  44. data/lib/metadata/util/win32/Win32Software.rb +5 -3
  45. data/lib/metadata/util/win32/decode.rb +0 -0
  46. data/lib/metadata/util/win32/fleece_hives.rb +0 -8
  47. data/lib/metadata/util/win32/ms-registry.rb +3 -1
  48. data/lib/metadata/util/win32/peheader.rb +7 -8
  49. data/lib/miq_unicode.rb +45 -0
  50. data/manageiq-smartstate.gemspec +9 -7
  51. metadata +76 -33
  52. data/lib/fs/MetakitFS/MetakitFS.rb +0 -530
@@ -0,0 +1,45 @@
1
+ module ManageIQ
2
+ module UnicodeString
3
+ refine String do
4
+ def UnicodeToUtf8
5
+ dup.UnicodeToUtf8!
6
+ end
7
+
8
+ def UnicodeToUtf8!
9
+ force_encoding("UTF-16LE").encode!("UTF-8")
10
+ end
11
+
12
+ def Utf8ToUnicode
13
+ dup.Utf8ToUnicode!
14
+ end
15
+
16
+ def Utf8ToUnicode!
17
+ force_encoding("UTF-8").encode!("UTF-16LE")
18
+ end
19
+
20
+ def AsciiToUtf8
21
+ dup.AsciiToUtf8!
22
+ end
23
+
24
+ def AsciiToUtf8!
25
+ force_encoding("ISO-8859-1").encode!("UTF-8")
26
+ end
27
+
28
+ def Utf8ToAscii
29
+ dup.Utf8ToAscii!
30
+ end
31
+
32
+ def Utf8ToAscii!
33
+ force_encoding("UTF-8").encode!("ISO-8859-1")
34
+ end
35
+
36
+ def Ucs2ToAscii
37
+ dup.Ucs2ToAscii!
38
+ end
39
+
40
+ def Ucs2ToAscii!
41
+ force_encoding("UTF-16LE").encode!("ISO-8859-1")
42
+ end
43
+ end
44
+ end
45
+ end
@@ -20,7 +20,9 @@ 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 "azure-armrest", "~> 0.9.6"
23
+ spec.add_dependency "activesupport"
24
+ spec.add_dependency "awesome_spawn", "~> 1.5"
25
+ spec.add_dependency "azure-armrest", "~> 0.9"
24
26
  spec.add_dependency "binary_struct", "~> 2.1"
25
27
  spec.add_dependency "iniparse"
26
28
  spec.add_dependency "linux_block_device", "~>0.2.1"
@@ -28,16 +30,16 @@ Gem::Specification.new do |spec|
28
30
  spec.add_dependency "memory_buffer", ">=0.1.0"
29
31
  spec.add_dependency "rufus-lru", "~>1.0.3"
30
32
  spec.add_dependency "sys-uname", "~>1.2.1"
31
- spec.add_dependency "vmware_web_service", "~>1.0"
33
+ spec.add_dependency "uuidtools", "~>2.1"
34
+ spec.add_dependency "vmware_web_service", "~>2.0"
32
35
 
33
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"
34
40
  spec.add_development_dependency "rake"
35
41
  spec.add_development_dependency "rspec", "~> 3.0"
36
- spec.add_development_dependency "camcorder"
42
+ spec.add_development_dependency "simplecov"
37
43
  spec.add_development_dependency "vcr", "~>3.0.2"
38
44
  spec.add_development_dependency "webmock", "~>2.3.1"
39
- spec.add_development_dependency "simplecov"
40
- spec.add_development_dependency "rubocop"
41
- spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0.0"
42
-
43
45
  end
metadata CHANGED
@@ -1,29 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manageiq-smartstate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.9
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ManageIQ Developers
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-15 00:00:00.000000000 Z
11
+ date: 2021-01-28 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
16
44
  requirements:
17
45
  - - "~>"
18
46
  - !ruby/object:Gem::Version
19
- version: 0.9.6
47
+ version: '0.9'
20
48
  type: :runtime
21
49
  prerelease: false
22
50
  version_requirements: !ruby/object:Gem::Requirement
23
51
  requirements:
24
52
  - - "~>"
25
53
  - !ruby/object:Gem::Version
26
- version: 0.9.6
54
+ version: '0.9'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: binary_struct
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -122,20 +150,34 @@ dependencies:
122
150
  - - "~>"
123
151
  - !ruby/object:Gem::Version
124
152
  version: 1.2.1
153
+ - !ruby/object:Gem::Dependency
154
+ name: uuidtools
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '2.1'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '2.1'
125
167
  - !ruby/object:Gem::Dependency
126
168
  name: vmware_web_service
127
169
  requirement: !ruby/object:Gem::Requirement
128
170
  requirements:
129
171
  - - "~>"
130
172
  - !ruby/object:Gem::Version
131
- version: '1.0'
173
+ version: '2.0'
132
174
  type: :runtime
133
175
  prerelease: false
134
176
  version_requirements: !ruby/object:Gem::Requirement
135
177
  requirements:
136
178
  - - "~>"
137
179
  - !ruby/object:Gem::Version
138
- version: '1.0'
180
+ version: '2.0'
139
181
  - !ruby/object:Gem::Dependency
140
182
  name: bundler
141
183
  requirement: !ruby/object:Gem::Requirement
@@ -151,7 +193,7 @@ dependencies:
151
193
  - !ruby/object:Gem::Version
152
194
  version: '0'
153
195
  - !ruby/object:Gem::Dependency
154
- name: rake
196
+ name: camcorder
155
197
  requirement: !ruby/object:Gem::Requirement
156
198
  requirements:
157
199
  - - ">="
@@ -165,21 +207,21 @@ dependencies:
165
207
  - !ruby/object:Gem::Version
166
208
  version: '0'
167
209
  - !ruby/object:Gem::Dependency
168
- name: rspec
210
+ name: codeclimate-test-reporter
169
211
  requirement: !ruby/object:Gem::Requirement
170
212
  requirements:
171
213
  - - "~>"
172
214
  - !ruby/object:Gem::Version
173
- version: '3.0'
215
+ version: 1.0.0
174
216
  type: :development
175
217
  prerelease: false
176
218
  version_requirements: !ruby/object:Gem::Requirement
177
219
  requirements:
178
220
  - - "~>"
179
221
  - !ruby/object:Gem::Version
180
- version: '3.0'
222
+ version: 1.0.0
181
223
  - !ruby/object:Gem::Dependency
182
- name: camcorder
224
+ name: manageiq-style
183
225
  requirement: !ruby/object:Gem::Requirement
184
226
  requirements:
185
227
  - - ">="
@@ -193,33 +235,33 @@ dependencies:
193
235
  - !ruby/object:Gem::Version
194
236
  version: '0'
195
237
  - !ruby/object:Gem::Dependency
196
- name: vcr
238
+ name: rake
197
239
  requirement: !ruby/object:Gem::Requirement
198
240
  requirements:
199
- - - "~>"
241
+ - - ">="
200
242
  - !ruby/object:Gem::Version
201
- version: 3.0.2
243
+ version: '0'
202
244
  type: :development
203
245
  prerelease: false
204
246
  version_requirements: !ruby/object:Gem::Requirement
205
247
  requirements:
206
- - - "~>"
248
+ - - ">="
207
249
  - !ruby/object:Gem::Version
208
- version: 3.0.2
250
+ version: '0'
209
251
  - !ruby/object:Gem::Dependency
210
- name: webmock
252
+ name: rspec
211
253
  requirement: !ruby/object:Gem::Requirement
212
254
  requirements:
213
255
  - - "~>"
214
256
  - !ruby/object:Gem::Version
215
- version: 2.3.1
257
+ version: '3.0'
216
258
  type: :development
217
259
  prerelease: false
218
260
  version_requirements: !ruby/object:Gem::Requirement
219
261
  requirements:
220
262
  - - "~>"
221
263
  - !ruby/object:Gem::Version
222
- version: 2.3.1
264
+ version: '3.0'
223
265
  - !ruby/object:Gem::Dependency
224
266
  name: simplecov
225
267
  requirement: !ruby/object:Gem::Requirement
@@ -235,35 +277,35 @@ dependencies:
235
277
  - !ruby/object:Gem::Version
236
278
  version: '0'
237
279
  - !ruby/object:Gem::Dependency
238
- name: rubocop
280
+ name: vcr
239
281
  requirement: !ruby/object:Gem::Requirement
240
282
  requirements:
241
- - - ">="
283
+ - - "~>"
242
284
  - !ruby/object:Gem::Version
243
- version: '0'
285
+ version: 3.0.2
244
286
  type: :development
245
287
  prerelease: false
246
288
  version_requirements: !ruby/object:Gem::Requirement
247
289
  requirements:
248
- - - ">="
290
+ - - "~>"
249
291
  - !ruby/object:Gem::Version
250
- version: '0'
292
+ version: 3.0.2
251
293
  - !ruby/object:Gem::Dependency
252
- name: codeclimate-test-reporter
294
+ name: webmock
253
295
  requirement: !ruby/object:Gem::Requirement
254
296
  requirements:
255
297
  - - "~>"
256
298
  - !ruby/object:Gem::Version
257
- version: 1.0.0
299
+ version: 2.3.1
258
300
  type: :development
259
301
  prerelease: false
260
302
  version_requirements: !ruby/object:Gem::Requirement
261
303
  requirements:
262
304
  - - "~>"
263
305
  - !ruby/object:Gem::Version
264
- version: 1.0.0
306
+ version: 2.3.1
265
307
  description: ManageIQ SmartState Analysis
266
- email:
308
+ email:
267
309
  executables: []
268
310
  extensions: []
269
311
  extra_rdoc_files: []
@@ -362,7 +404,6 @@ files:
362
404
  - lib/disk/modules/miq_dummy_disk.rb
363
405
  - lib/disk/modules/vhdx_bat_entry.rb
364
406
  - lib/disk/test.rb
365
- - lib/fs/MetakitFS/MetakitFS.rb
366
407
  - lib/fs/MiqFS/FsProbe.rb
367
408
  - lib/fs/MiqFS/MiqFS.rb
368
409
  - lib/fs/MiqFS/modules/AUFSProbe.rb
@@ -532,6 +573,7 @@ files:
532
573
  - lib/metadata/util/win32/Win32Software.rb
533
574
  - lib/metadata/util/win32/Win32System.rb
534
575
  - lib/metadata/util/win32/boot_info_win.rb
576
+ - lib/metadata/util/win32/decode.rb
535
577
  - lib/metadata/util/win32/fleece_hives.rb
536
578
  - lib/metadata/util/win32/ms-registry.rb
537
579
  - lib/metadata/util/win32/peheader.rb
@@ -539,6 +581,7 @@ files:
539
581
  - lib/metadata/util/win32/system_path_win.rb
540
582
  - lib/metadata/util/win32/versioninfo.rb
541
583
  - lib/miq_tempfile.rb
584
+ - lib/miq_unicode.rb
542
585
  - lib/tasks/azure.rake
543
586
  - log/.gitkeep
544
587
  - manageiq-smartstate.gemspec
@@ -546,7 +589,7 @@ homepage: https://github.com/ManageIQ/manageiq-smartstate
546
589
  licenses:
547
590
  - Apache-2.0
548
591
  metadata: {}
549
- post_install_message:
592
+ post_install_message:
550
593
  rdoc_options: []
551
594
  require_paths:
552
595
  - lib
@@ -561,8 +604,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
561
604
  - !ruby/object:Gem::Version
562
605
  version: '0'
563
606
  requirements: []
564
- rubygems_version: 3.1.2
565
- signing_key:
607
+ rubygems_version: 3.0.3
608
+ signing_key:
566
609
  specification_version: 4
567
610
  summary: ManageIQ SmartState Analysis
568
611
  test_files: []
@@ -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