dwipe 1.0.3__py3-none-any.whl → 1.0.5__py3-none-any.whl

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.
dwipe/main.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
- """ TBD
3
-
4
-
2
+ """
3
+ dwipe: curse based tool to wipe physical disks or partitions including
4
+ markers to know their state when wiped.
5
5
  """
6
6
  # pylint: disable=too-many-branches,too-many-statements,import-outside-toplevel
7
7
  # pylint: disable=too-many-instance-attributes,invalid-name
@@ -79,6 +79,7 @@ class WipeJob:
79
79
  self.total_written = 0
80
80
  self.wr_hists = [] # list of (mono, written)
81
81
  self.done = False
82
+ self.exception = None # in case of issues
82
83
 
83
84
  @staticmethod
84
85
  def start_job(device_path, total_size, opts):
@@ -185,38 +186,43 @@ class WipeJob:
185
186
  self.total_written = 0 # Track total bytes written
186
187
  is_random = self.opts.random
187
188
 
188
- with open(self.device_path, 'wb') as device:
189
- # for loop in range(10000000000):
190
- offset = 0
191
- chunk = memoryview(WipeJob.zero_buffer)
192
- while True:
193
- if self.do_abort:
194
- break
195
- if is_random:
196
- offset = random.randint(0, WipeJob.BUFFER_SIZE - WipeJob.WRITE_SIZE)
197
- # Use memoryview to avoid copying the data
198
- chunk = memoryview(WipeJob.buffer)[offset:offset + WipeJob.WRITE_SIZE]
199
-
200
- if self.opts.dry_run:
201
- bytes_written = self.total_size // 120
202
- time.sleep(0.25)
203
- else:
204
- try:
205
- bytes_written = device.write(chunk)
206
- except Exception:
207
- bytes_written = 0
208
- self.total_written += bytes_written
209
- # Optional: Check for errors or incomplete writes
210
- if bytes_written < WipeJob.WRITE_SIZE:
211
- break
212
- if self.opts.dry_run and self.total_written >= self.total_size:
213
- break
214
- # clear the beginning of device whether aborted or not
215
- # if we have started writing + status in JSON
216
- if not self.opts.dry_run and self.total_written > 0 and is_random:
217
- device.seek(0)
218
- # chunk = memoryview(WipeJob.zero_buffer)
219
- bytes_written = device.write(self.prep_marker_buffer(is_random))
189
+ try:
190
+ with open(self.device_path, 'wb') as device:
191
+ # for loop in range(10000000000):
192
+ offset = 0
193
+ chunk = memoryview(WipeJob.zero_buffer)
194
+ while True:
195
+ # foo = 1/0 # to force exception only
196
+ if self.do_abort:
197
+ break
198
+ if is_random:
199
+ offset = random.randint(0, WipeJob.BUFFER_SIZE - WipeJob.WRITE_SIZE)
200
+ # Use memoryview to avoid copying the data
201
+ chunk = memoryview(WipeJob.buffer)[offset:offset + WipeJob.WRITE_SIZE]
202
+
203
+ if self.opts.dry_run:
204
+ bytes_written = self.total_size // 120
205
+ time.sleep(0.25)
206
+ else:
207
+ try:
208
+ bytes_written = device.write(chunk)
209
+ except Exception:
210
+ bytes_written = 0
211
+ self.total_written += bytes_written
212
+ # Optional: Check for errors or incomplete writes
213
+ if bytes_written < WipeJob.WRITE_SIZE:
214
+ break
215
+ if self.opts.dry_run and self.total_written >= self.total_size:
216
+ break
217
+ # clear the beginning of device whether aborted or not
218
+ # if we have started writing + status in JSON
219
+ if not self.opts.dry_run and self.total_written > 0:
220
+ device.seek(0)
221
+ # chunk = memoryview(WipeJob.zero_buffer)
222
+ bytes_written = device.write(self.prep_marker_buffer(is_random))
223
+ except Exception:
224
+ self.exception = traceback.format_exc()
225
+
220
226
  self.done = True
221
227
 
222
228
  class DeviceInfo:
@@ -284,6 +290,7 @@ class DeviceInfo:
284
290
  entry.fstype = device.get('fstype', '')
285
291
  if entry.fstype is None:
286
292
  entry.fstype = ''
293
+ entry.type = device.get('type', '')
287
294
  entry.label = device.get('label', '')
288
295
  if not entry.label:
289
296
  entry.label=device.get('partlabel', '')
@@ -313,7 +320,7 @@ class DeviceInfo:
313
320
 
314
321
  # Run the `lsblk` command and get its output in JSON format with additional columns
315
322
  result = subprocess.run(['lsblk', '-J', '--bytes', '-o',
316
- 'NAME,MAJ:MIN,FSTYPE,LABEL,PARTLABEL,FSUSE%,SIZE,MOUNTPOINTS', ],
323
+ 'NAME,MAJ:MIN,FSTYPE,TYPE,LABEL,PARTLABEL,FSUSE%,SIZE,MOUNTPOINTS', ],
317
324
  stdout=subprocess.PIPE, text=True, check=False)
318
325
  parsed_data = json.loads(result.stdout)
319
326
  entries = {}
@@ -407,47 +414,10 @@ class DeviceInfo:
407
414
 
408
415
  def get_disk_partitions(self, nss):
409
416
  """ Determine which partitions we want some are bogus like zram """
410
-
411
- def whitelisted(device_name):
412
- """Check if device_name matches any pattern in whitelist
413
- which are the disk devices."""
414
- WHITELIST = ['nvme*', 'sd*', 'hd*', 'mmcblk*']
415
- for pattern in WHITELIST:
416
- if fnmatch(device_name, pattern):
417
- return True
418
- return False
419
-
420
- def blacklisted(device_name):
421
- """Check if device_name matches any pattern in black list
422
- which are know not to be physical disks."""
423
- BLACKLIST = ['zram*', 'ram*', 'dm-*', 'loop*', 'sr*']
424
- for pattern in BLACKLIST:
425
- if fnmatch(device_name, pattern):
426
- return 'blkLst'
427
- return ''
428
-
429
- def writable(device_name):
430
- """Check if the device is writable."""
431
- device_path = f'/dev/{device_name}'
432
- try: # Check if the device file exists and is writable
433
- return os.access(device_path, os.W_OK)
434
- except FileNotFoundError:
435
- return False
436
-
437
417
  ok_nss = {}
438
418
  for name, ns in nss.items():
439
- if ns.major in self.disk_majors or whitelisted(name):
419
+ if ns.type in ('disk', 'part'):
440
420
  ok_nss[name] = ns
441
- continue
442
- if blacklisted(name):
443
- continue
444
- if writable(name):
445
- if self.DB:
446
- print(r'DB:include {repr(name)} [not white/black but writable]')
447
- ok_nss[name] = ns
448
- continue
449
- if self.DB:
450
- print(r'DB:exclude {repr(name)} [not white/black but unwritable]')
451
421
  return ok_nss
452
422
 
453
423
  def compute_field_widths(self, nss):
@@ -755,6 +725,8 @@ class DiskWipe:
755
725
  line += ' Stop' if self.job_cnt > 0 else ''
756
726
  line += f' quit ?:help /{self.prev_filter} Mode='
757
727
  line += f'{"Random" if self.opts.random else "Zeros"}'
728
+ if self.opts.dry_run:
729
+ line += ' DRY-RUN'
758
730
  # for action in self.actions:
759
731
  # line += f' {action[0]}:{action}'
760
732
  return line[1:]
@@ -834,15 +806,24 @@ class DiskWipe:
834
806
  to='s' if partition.job.do_abort else 'W'
835
807
  self.set_state(partition, to=to)
836
808
  partition.dflt = to
837
- partition.job = None
838
809
  partition.mounts = []
839
810
  self.job_cnt -= 1
811
+ if partition.job.exception:
812
+ self.win.stop_curses()
813
+ print('\n\n\n========== ALERT =========\n')
814
+ print(f' FAILED: wipe {repr(partition.name)}')
815
+ print(partition.job.exception)
816
+ input('\n\n===== Press ENTER to continue ====> ')
817
+ self.win._start_curses()
818
+
819
+ partition.job = None
840
820
  if partition.job:
841
821
  elapsed, pct, rate, until = partition.job.get_status()
842
822
  partition.state = pct
843
823
  partition.mounts = [f'{elapsed} {rate} REM:{until}']
844
824
 
845
- if partition.parent and self.partitions[partition.parent].state == 'Lock':
825
+ if partition.parent and partition.parent in self.partitions and (
826
+ self.partitions[partition.parent].state == 'Lock'):
846
827
  continue
847
828
 
848
829
  if wanted(name) or partition.job:
@@ -1,20 +1,18 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: dwipe
3
- Version: 1.0.3
3
+ Version: 1.0.5
4
4
  Summary: A tool to wipe disks and partitions for Linux
5
- Author-email: Joe Defen <joedef@google.com>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/joedefen/dwipe
8
- Project-URL: Bug Tracker, https://github.com/joedefen/dwipe/issues
9
5
  Keywords: disk,partition,wipe,clean,scrub
6
+ Author-email: Joe Defen <joedef@google.com>
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
10
9
  Classifier: Programming Language :: Python :: 3
11
10
  Classifier: License :: OSI Approved :: MIT License
12
11
  Classifier: Operating System :: POSIX :: Linux
13
- Requires-Python: >=3.8
14
- Description-Content-Type: text/markdown
15
12
  License-File: LICENSE
16
- Requires-Dist: psutil>=5.9
17
- Requires-Dist: importlib-metadata; python_version < "3.8"
13
+ Requires-Dist: importlib-metadata; python_version<"3.8"
14
+ Project-URL: Bug Tracker, https://github.com/joedefen/dwipe/issues
15
+ Project-URL: Homepage, https://github.com/joedefen/dwipe
18
16
 
19
17
  # dwipe
20
18
  `dwipe` is tool to wipe disks and partitions for Linux helps secure you data. `dwipes` aims to reduce mistakes by providing ample information about your devices during selection.
@@ -0,0 +1,8 @@
1
+ dwipe/PowerWindow.py,sha256=pQGXsAMeuiHn-vtEiVG0rgW1eCslh3ukC-VrPhH_j3k,28587
2
+ dwipe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ dwipe/main.py,sha256=MutcKcddLhBJeegULUwjHOzZRV2gR-QluA1UarRHyIU,33909
4
+ dwipe-1.0.5.dist-info/entry_points.txt,sha256=SZHFezmse2c-jxG-BJ0TXy_TZ8vVFf0lPJWs0cdxz6Y,41
5
+ dwipe-1.0.5.dist-info/licenses/LICENSE,sha256=qB9OdnyyF6WYHiEIXVm0rOSdcf8e2ctorrtWs6CC5lU,1062
6
+ dwipe-1.0.5.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
7
+ dwipe-1.0.5.dist-info/METADATA,sha256=hrmh76lFi0rfExxRmCzGSIeEWFTwy1DfLfko7DKofS8,4496
8
+ dwipe-1.0.5.dist-info/RECORD,,
@@ -1,5 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (74.1.2)
2
+ Generator: flit 3.12.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
-
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ dwipe=dwipe.main:main
3
+
@@ -1,9 +0,0 @@
1
- dwipe/PowerWindow.py,sha256=pQGXsAMeuiHn-vtEiVG0rgW1eCslh3ukC-VrPhH_j3k,28587
2
- dwipe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- dwipe/main.py,sha256=6Ooj1i7hCrFxVUkvjRphH_-Dxz3dpm201VrZVybiI8A,34309
4
- dwipe-1.0.3.dist-info/LICENSE,sha256=qB9OdnyyF6WYHiEIXVm0rOSdcf8e2ctorrtWs6CC5lU,1062
5
- dwipe-1.0.3.dist-info/METADATA,sha256=OBoF-WviZm4MNxeIpHWqF9QeeLnfb1BtQItlk93QBdU,4538
6
- dwipe-1.0.3.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
7
- dwipe-1.0.3.dist-info/entry_points.txt,sha256=s-gAs_OhS9lr-oVMKii2ZjsLfCSO4-oHV7Wa9oJe-2g,42
8
- dwipe-1.0.3.dist-info/top_level.txt,sha256=nJT1SUDcOmULgmF9JmYwIIQLmXAIn6qAWW8EdWuxsAg,6
9
- dwipe-1.0.3.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- dwipe = dwipe.main:main
@@ -1 +0,0 @@
1
- dwipe