orphan disk search update
This commit is contained in:
+25
-5
@@ -2,6 +2,7 @@
|
||||
"""Read-only Proxmox storage/reference inventory; no third-party dependencies."""
|
||||
import argparse
|
||||
import csv
|
||||
from datetime import datetime
|
||||
import json
|
||||
import math
|
||||
from pathlib import Path
|
||||
@@ -198,17 +199,36 @@ def render(rows, warnings, coverage):
|
||||
|
||||
|
||||
def export_csv(path, rows):
|
||||
destination = Path(path).expanduser()
|
||||
folder = destination.is_dir() or str(path).endswith('/')
|
||||
if folder:
|
||||
destination.mkdir(parents=True, exist_ok=True)
|
||||
destination /= datetime.now().strftime('tapm-orphan-disks-%Y-%m-%d-%H%M%S.csv')
|
||||
elif destination.suffix.lower() != '.csv':
|
||||
destination = Path(str(destination) + '.csv')
|
||||
# Exclusive creation avoids overwriting existing files, including symlink targets.
|
||||
with open(path, 'x', newline='') as handle:
|
||||
base = destination
|
||||
suffix = 0
|
||||
while True:
|
||||
try:
|
||||
handle = destination.open('x', newline='')
|
||||
break
|
||||
except FileExistsError:
|
||||
if not folder:
|
||||
raise
|
||||
suffix += 1
|
||||
destination = base.with_name(f'{base.stem}-{suffix}.csv')
|
||||
with handle:
|
||||
writer = csv.DictWriter(handle, fieldnames=FIELDS + ['disk_size'])
|
||||
writer.writeheader()
|
||||
for row in rows:
|
||||
writer.writerow(dict(row, disk_size=format_size(row['size_bytes'], row.get('size_is_approximate', False))))
|
||||
return destination
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--csv', metavar='PATH', help='export to a new CSV file')
|
||||
parser.add_argument('--csv', metavar='PATH', help='export to a CSV file or folder (.csv is added if missing)')
|
||||
parser.add_argument('--interactive', action='store_true', help='offer CSV export after the report')
|
||||
# The TAPM preloader pads its forwarded arguments with empty strings.
|
||||
args = parser.parse_args([arg for arg in sys.argv[1:] if arg])
|
||||
@@ -217,10 +237,10 @@ def main():
|
||||
render(rows, warnings, coverage)
|
||||
destination = args.csv
|
||||
if args.interactive and sys.stdin.isatty() and not destination:
|
||||
destination = input('\nCSV export path (Enter to skip): ').strip()
|
||||
destination = input('\nCSV export file or folder (Enter to skip): ').strip()
|
||||
if destination:
|
||||
export_csv(destination, rows)
|
||||
print('CSV saved: ' + destination)
|
||||
destination = export_csv(destination, rows)
|
||||
print(f'CSV saved: {destination}')
|
||||
return 2 if warnings else 0
|
||||
except (OSError, RuntimeError, ValueError, subprocess.TimeoutExpired) as exc:
|
||||
print(f'Disk report failed: {exc}', file=sys.stderr)
|
||||
|
||||
Reference in New Issue
Block a user