manageiq-smartstate 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) 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/db/MiqBdb/MiqBdb.rb +0 -2
  9. data/lib/db/MiqBdb/MiqBdbPage.rb +0 -2
  10. data/lib/db/MiqSqlite/MiqSqlite3.rb +0 -2
  11. data/lib/db/MiqSqlite/MiqSqlite3Cell.rb +0 -2
  12. data/lib/db/MiqSqlite/MiqSqlite3Page.rb +0 -2
  13. data/lib/db/MiqSqlite/MiqSqlite3Table.rb +0 -2
  14. data/lib/disk/modules/MSCommon.rb +3 -1
  15. data/lib/disk/modules/VhdxDisk.rb +3 -1
  16. data/lib/fs/MiqMountManager.rb +2 -29
  17. data/lib/fs/VimDatastoreFS/VimDatastoreFS.rb +1 -6
  18. data/lib/fs/fat32/directory_entry.rb +540 -540
  19. data/lib/fs/iso9660/boot_sector.rb +3 -2
  20. data/lib/fs/iso9660/directory_entry.rb +3 -2
  21. data/lib/fs/iso9660/rock_ridge.rb +3 -1
  22. data/lib/fs/ntfs/attrib_attribute_list.rb +3 -1
  23. data/lib/fs/ntfs/attrib_file_name.rb +3 -1
  24. data/lib/fs/ntfs/attrib_header.rb +3 -1
  25. data/lib/fs/ntfs/attrib_index_root.rb +3 -1
  26. data/lib/fs/ntfs/attrib_volume_name.rb +3 -1
  27. data/lib/manageiq/smartstate/util.rb +18 -0
  28. data/lib/manageiq/smartstate/version.rb +1 -1
  29. data/lib/metadata/MIQExtract/MIQExtract.rb +2 -3
  30. data/lib/metadata/VmConfig/GetNativeCfg.rb +2 -4
  31. data/lib/metadata/VmConfig/VmConfig.rb +7 -6
  32. data/lib/metadata/VmConfig/cfgConfig.rb +4 -0
  33. data/lib/metadata/VmConfig/xmlConfig.rb +3 -3
  34. data/lib/metadata/linux/MiqRpmPackages.rb +3 -1
  35. data/lib/metadata/util/win32/Win32Accounts.rb +3 -1
  36. data/lib/metadata/util/win32/Win32EventLog.rb +3 -1
  37. data/lib/metadata/util/win32/Win32Software.rb +5 -3
  38. data/lib/metadata/util/win32/decode.rb +0 -0
  39. data/lib/metadata/util/win32/fleece_hives.rb +0 -9
  40. data/lib/metadata/util/win32/ms-registry.rb +3 -2
  41. data/lib/metadata/util/win32/peheader.rb +3 -2
  42. data/lib/metadata/util/win32/system_path_win.rb +0 -2
  43. data/lib/miq_unicode.rb +45 -0
  44. data/manageiq-smartstate.gemspec +8 -6
  45. metadata +66 -23
  46. data/lib/fs/MetakitFS/MetakitFS.rb +0 -530
@@ -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", "~>2.0"
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 "camcorder"
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.6.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: 2020-08-04 00:00:00.000000000 Z
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: '2.0'
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: '2.0'
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: rake
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: rspec
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: '3.0'
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: '3.0'
222
+ version: 1.0.0
195
223
  - !ruby/object:Gem::Dependency
196
- name: camcorder
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: vcr
238
+ name: rake
211
239
  requirement: !ruby/object:Gem::Requirement
212
240
  requirements:
213
- - - "~>"
241
+ - - ">="
214
242
  - !ruby/object:Gem::Version
215
- version: 3.0.2
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: 3.0.2
250
+ version: '0'
223
251
  - !ruby/object:Gem::Dependency
224
- name: webmock
252
+ name: rspec
225
253
  requirement: !ruby/object:Gem::Requirement
226
254
  requirements:
227
255
  - - "~>"
228
256
  - !ruby/object:Gem::Version
229
- version: 2.3.1
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: 2.3.1
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: rubocop
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: codeclimate-test-reporter
294
+ name: vcr
267
295
  requirement: !ruby/object:Gem::Requirement
268
296
  requirements:
269
297
  - - "~>"
270
298
  - !ruby/object:Gem::Version
271
- version: 1.0.0
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: 1.0.0
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.1.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