dwipe 1.0.2__tar.gz → 1.0.4__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dwipe
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: A tool to wipe disks and partitions for Linux
5
5
  Author-email: Joe Defen <joedef@google.com>
6
6
  License: MIT
@@ -47,7 +47,7 @@ build-backend = "setuptools.build_meta"
47
47
 
48
48
  [project]
49
49
  name = "dwipe"
50
- version = "1.0.2"
50
+ version = "1.0.4"
51
51
  description = "A tool to wipe disks and partitions for Linux"
52
52
  authors = [
53
53
  { name = "Joe Defen", email = "joedef@google.com" }
@@ -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:
@@ -307,6 +313,7 @@ class DeviceInfo:
307
313
  state = 'W' if pct >= 100 else 's'
308
314
  dt = datetime.datetime.fromtimestamp(marker.unixtime)
309
315
  entry.marker = f'{state} {pct}% {marker.mode} {dt.strftime('%Y/%m/%d %H:%M')}'
316
+ entry.state = state
310
317
 
311
318
  return entry
312
319
 
@@ -333,8 +340,6 @@ class DeviceInfo:
333
340
  if entry.mounts:
334
341
  entry.state = 'Mnt'
335
342
  parent.state = 'Mnt'
336
- elif entry.marker:
337
- entry.state = entry.marker[0]
338
343
 
339
344
  if self.DB:
340
345
  print('\n\nDB: --->>> after parse_lsblk:')
@@ -532,18 +537,21 @@ class DeviceInfo:
532
537
  if new_ns:
533
538
  if prev_ns.job:
534
539
  new_ns.job = prev_ns.job
535
- new_ns.state = new_ns.dflt = prev_ns.dflt
540
+ new_ns.dflt = prev_ns.dflt
541
+
536
542
  if prev_ns.state == 'Lock':
537
- pass
538
- if prev_ns.state not in ('Busy', 'Unlk'): # re-infer these
539
- new_ns.state = prev_ns.state
543
+ new_ns.state = 'Lock'
544
+ elif new_ns.state not in ('s', 'W'):
545
+ new_ns.state = new_ns.dflt
546
+ if prev_ns.state not in ('s', 'W', 'Busy', 'Unlk'):
547
+ new_ns.state = prev_ns.state # re-infer these
540
548
  elif prev_ns.job:
541
549
  # unplugged device with job..
542
550
  nss[name] = prev_ns # carry forward
543
551
  prev_ns.job.do_abort = True
544
- for name, prev_ns in nss.items():
545
- if name not in prev_nss:
546
- prev_ns.state = '^'
552
+ for name, new_ns in nss.items():
553
+ if name not in prev_nss and new_ns.state not in ('s', 'W'):
554
+ new_ns.state = '^'
547
555
  return nss
548
556
 
549
557
  def assemble_partitions(self, prev_nss=None):
@@ -753,6 +761,8 @@ class DiskWipe:
753
761
  line += ' Stop' if self.job_cnt > 0 else ''
754
762
  line += f' quit ?:help /{self.prev_filter} Mode='
755
763
  line += f'{"Random" if self.opts.random else "Zeros"}'
764
+ if self.opts.dry_run:
765
+ line += ' DRY-RUN'
756
766
  # for action in self.actions:
757
767
  # line += f' {action[0]}:{action}'
758
768
  return line[1:]
@@ -832,9 +842,17 @@ class DiskWipe:
832
842
  to='s' if partition.job.do_abort else 'W'
833
843
  self.set_state(partition, to=to)
834
844
  partition.dflt = to
835
- partition.job = None
836
845
  partition.mounts = []
837
846
  self.job_cnt -= 1
847
+ if partition.job.exception:
848
+ self.win.stop_curses()
849
+ print('\n\n\n========== ALERT =========\n')
850
+ print(f' FAILED: wipe {repr(partition.name)}')
851
+ print(partition.job.exception)
852
+ input('\n\n===== Press ENTER to continue ====> ')
853
+ self.win._start_curses()
854
+
855
+ partition.job = None
838
856
  if partition.job:
839
857
  elapsed, pct, rate, until = partition.job.get_status()
840
858
  partition.state = pct
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dwipe
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: A tool to wipe disks and partitions for Linux
5
5
  Author-email: Joe Defen <joedef@google.com>
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes
File without changes