Compare commits

..

No commits in common. "master" and "v1.3.2-26" have entirely different histories.

8 changed files with 77 additions and 116 deletions

View File

@ -27,7 +27,7 @@ from src.utils.postinstall import configure_os
from src.utils.net import *
from src.utils.menu import generate_menu
from src.utils.fs import *
from src.utils.probe import *
from src.utils.probe import os_probe, get_cache_dev_path
from src.utils.disk import *
from src.utils.cache import *
from src.utils.tiptorrent import *
@ -82,10 +82,8 @@ class OgLiveOperations:
code = int(pa.parttype, base=16)
if mount_mkdir(pa.padev, target):
part_setup['os'] = ''
if part_setup['disk'] == '1':
probe_result = os_probe(target)
part_setup['os'] = probe_result
probe_result = os_probe(target)
part_setup['os'] = probe_result
total, used, free = shutil.disk_usage(target)
part_setup['used_size'] = used
@ -528,12 +526,7 @@ class OgLiveOperations:
raise OgError(f'Invalid disk number {disk}, {len(get_disks())} disks available.')
diskname = get_disks()[disk-1]
try:
self._partition(diskname, table_type, partlist)
except Exception as e:
ret = subprocess.run(['wipefs', '-af', f'/dev/{diskname}'])
logging.warning(f'wipefs on /dev/{diskname} after failure for consistency, reports {ret.returncode}')
raise
self._partition(diskname, table_type, partlist)
ret = subprocess.run(['partprobe', f'/dev/{diskname}'])
logging.info(f'first partprobe /dev/{diskname} reports {ret.returncode}')
@ -601,14 +594,19 @@ class OgLiveOperations:
extend_filesystem(disk, partition)
if disk == 1:
configure_os(disk, partition)
configure_os(disk, partition)
result = self.refresh(ogRest)
self.refresh(ogRest)
logging.info('Image restore command OK')
return result
json_dict = {
'disk': request.getDisk(),
'partition': request.getPartition(),
'image_id': request.getId(),
'cache': self._get_cache_contents(),
}
return json_dict
def image_create(self, request, ogRest):
disk = int(request.getDisk())
@ -657,7 +655,6 @@ class OgLiveOperations:
raise OgError(f'Cannot mount {ro_mountpoint} as readonly')
try:
is_windows = get_os_family(ro_mountpoint) == OSFamily.WINDOWS
if is_hibernation_enabled(ro_mountpoint):
raise OgError(f'Target system in {padev} has hibernation enabled')
finally:
@ -669,12 +666,10 @@ class OgLiveOperations:
if os.access(f'/opt/opengnsys/images', os.R_OK | os.W_OK) == False:
raise OgError('Cannot access /opt/opengnsys/images in read and write mode, check permissions')
if os.access(image_path, os.R_OK) == True:
if os.access(f'{image_path}', os.R_OK) == True:
logging.info(f'image file {image_path} already exists, updating.')
if is_windows and is_uefi_supported():
copy_windows_efi_bootloader(disk, partition)
copy_windows_efi_bootloader(disk, partition)
if ogReduceFs(disk, partition) == -1:
raise OgError(f'Failed to shrink {fstype} filesystem in {padev}')
@ -746,6 +741,7 @@ class OgLiveOperations:
def cache_delete(self, request, ogRest):
images = request.getImages()
deleted_images = []
logging.info(f'Request to remove files from cache')

View File

@ -52,9 +52,8 @@ class ogClient:
self.ogrest = ogRest(self.CONFIG)
self.seq = None
if self.event_sock:
self.session_check_thread = threading.Thread(target=self._session_check_loop, daemon=True)
self.session_check_thread.start()
self.session_check_thread = threading.Thread(target=self._session_check_loop, daemon=True)
self.session_check_thread.start()
def _session_check_loop(self):
while True:
@ -81,7 +80,7 @@ class ogClient:
def get_state(self):
return self.state
def handle_session_event(self, message):
def send_event_hint(self, message):
try:
event, action, user = message.split(" ")
logging.debug('Sending event: %s, %s, %s', event, action, user)
@ -211,6 +210,6 @@ class ogClient:
self.connect2()
elif state == State.RECEIVING and event_sock in readable:
message = event_sock.recv(4096).decode('utf-8').rstrip()
self.handle_session_event(message)
self.send_event_hint(message)
else:
raise OgError(f'Invalid ogClient run state: {str(state)}.')

View File

@ -343,7 +343,7 @@ class ogRest():
self.process_imagerestore(client, request)
elif ("stop" in URI):
self.process_stop(client)
elif ("image/create" in URI or "image/update" in URI):
elif ("image/create" in URI):
self.process_imagecreate(client, request)
elif ("cache/delete" in URI):
self.process_cache_delete(client, request)

View File

@ -11,7 +11,6 @@ import logging
import shlex
import subprocess
import json
from uuid import UUID
from src.log import OgError
import fdisk
@ -191,38 +190,3 @@ def get_partition_start_offset(disk, partition):
raise OgError(f'Error while trying to parse sfdisk: {e}') from e
return start_offset
def uuid_to_bytes(uuid):
uuid = uuid.replace('-', '')
group0 = f'{uuid[6:8]}{uuid[4:6]}{uuid[2:4]}{uuid[0:2]}'
group1 = f'{uuid[10:12]}{uuid[8:10]}'
group2 = f'{uuid[14:16]}{uuid[12:14]}'
group3 = uuid[16:20]
group4 = uuid[20:32]
res = f'{group0}-{group1}-{group2}-{group3}-{group4}'
return UUID(res).bytes
def get_disk_id_bytes(disk):
from src.utils.uefi import is_uefi_supported
disk_id = get_disk_id(disk)
if is_uefi_supported():
return uuid_to_bytes(disk_id)
return bytes.fromhex(disk_id)[::-1]
def get_part_id_bytes(disk, partition):
from src.utils.uefi import is_uefi_supported
if is_uefi_supported():
part_id = get_partition_id(disk, partition)
return uuid_to_bytes(part_id)
partition_start_offset = get_partition_start_offset(disk, partition)
sector_size = get_sector_size(disk)
byte_offset = partition_start_offset * sector_size
byte_offset = "{0:016x}".format(byte_offset)
return bytes.fromhex(byte_offset)[::-1]

View File

@ -153,19 +153,13 @@ def mkfs(fs, disk, partition, label=None):
if fs not in fsdict:
raise OgError(f'mkfs failed, unsupported target filesystem {fs}')
partdev = get_partition_device(disk, partition)
try:
partdev = get_partition_device(disk, partition)
except ValueError as e:
raise OgError(f'mkfs aborted: {e}') from e
ret = subprocess.run(['wipefs', '-af', f'{partdev}'])
if ret.returncode != 0:
logging.warning(f'wipefs on {partdev}, fails with {ret.returncode}')
return fsdict[fs](partdev, label)
err = fsdict[fs](partdev, label)
if err != 0:
ret = subprocess.run(['wipefs', '-af', f'{partdev}'])
if ret.returncode != 0:
logging.warning(f'wipefs on {partdev} for consistency, fails with {ret.returncode}')
return err
def mkfs_ext4(partdev, label=None):
err = -1

View File

@ -279,7 +279,7 @@ def _get_os_entries(esp_mountpoint):
continue
if not mount_mkdir(p.padev, mountpoint):
continue
raise OgError(f'Unable to mount {p.padev} into {mountpoint}')
try:
os_family = get_os_family(mountpoint)
@ -334,7 +334,6 @@ def get_disk_part_type(disk_num):
def _update_nvram(esp_disk, esp_part_number):
loader_path = '/EFI/grub/Boot/shimx64.efi'
bootlabel = 'grub'
egibootmgr_reorder_disabled_entries()
efibootmgr_delete_bootentry(bootlabel)
efibootmgr_create_bootentry(esp_disk, esp_part_number, loader_path, bootlabel, add_to_bootorder=False)
efibootmgr_set_entry_order(bootlabel, 1)

View File

@ -14,6 +14,7 @@ import subprocess
import shutil
from src.utils.disk import *
from src.utils.fs import *
from src.utils.probe import *
from src.log import OgError
import fdisk
@ -25,7 +26,7 @@ def _find_bootentry(entries, label):
if entry['description'] == label:
return entry
else:
raise OgError(f'Boot entry {label} not found')
raise OgError('Boot entry {label} not found')
def _strip_boot_prefix(entry):
@ -95,13 +96,8 @@ def efibootmgr_bootnext(description):
entry = _find_bootentry(boot_entries, description)
num = _strip_boot_prefix(entry) # efibootmgr output uses BootXXXX for each entry, remove the "Boot" prefix.
bootnext_cmd = bootnext_cmd.format(bootnum=num, efibootmgr=EFIBOOTMGR_BIN)
try:
subprocess.run(shlex.split(bootnext_cmd), check=True,
stdout=subprocess.DEVNULL)
except subprocess.CalledProcessError:
logging.warning("Failed to update BootNext. UEFI firmware might be buggy")
except OSError as e:
raise OgError(f"Unexpected error updating BootNext: {e}") from e
subprocess.run(shlex.split(bootnext_cmd), check=True,
stdout=subprocess.DEVNULL)
def efibootmgr_delete_bootentry(label):
@ -112,12 +108,7 @@ def efibootmgr_delete_bootentry(label):
if entry['description'] == label:
num = entry['name'][4:] # Remove "Boot" prefix to extract num
efibootmgr_cmd = efibootmgr_cmd.format(bootnum=num, efibootmgr=EFIBOOTMGR_BIN)
try:
subprocess.run(shlex.split(efibootmgr_cmd), check=True)
except subprocess.CalledProcessError:
logging.warning(f"Failed to delete boot entry {label}. UEFI firmware might be buggy")
except OSError as e:
raise OgError(f"Unexpected error deleting boot entry {label}: {e}") from e
subprocess.run(shlex.split(efibootmgr_cmd), check=True)
break
else:
logging.info(f'Cannot delete boot entry {label} because it was not found.')
@ -131,10 +122,8 @@ def efibootmgr_create_bootentry(disk, part, loader, label, add_to_bootorder=True
logging.info(f'{EFIBOOTMGR_BIN} command creating boot entry: {efibootmgr_cmd}')
try:
proc = subprocess.run(shlex.split(efibootmgr_cmd), check=True, text=True)
except subprocess.CalledProcessError:
logging.warning(f"Failed to add boot entry {label} to NVRAM. UEFI firmware might be buggy")
except OSError as e:
raise OgError(f"Unexpected error adding boot entry {label}: {e}") from e
raise OgError(f'Unexpected error adding boot entry to nvram. UEFI firmware might be buggy') from e
def efibootmgr_set_entry_order(label, position):
logging.info(f'Setting {label} entry to position {position} of boot order')
@ -152,29 +141,8 @@ def efibootmgr_set_entry_order(label, position):
try:
proc = subprocess.run([EFIBOOTMGR_BIN, "-o", ",".join(boot_order)], check=True, text=True)
except subprocess.CalledProcessError:
logging.warning("Failed to set boot order to NVRAM. UEFI firmware might be buggy")
except OSError as e:
raise OgError(f"Unexpected error updating boot order: {e}") from e
def egibootmgr_reorder_disabled_entries():
logging.info(f'Setting disabled entries at the end of boot order')
boot_info = run_efibootmgr_json(validate=False)
boot_entries = boot_info.get('vars', [])
boot_order = boot_info.get('BootOrder', [])
for entry in boot_entries:
entry_number = _strip_boot_prefix(entry)
if not entry['active'] and entry_number in boot_order:
boot_order.remove(entry_number)
boot_order.append(entry_number)
try:
proc = subprocess.run([EFIBOOTMGR_BIN, "-o", ",".join(boot_order)], check=True, text=True)
except subprocess.CalledProcessError:
logging.warning("Failed to update boot order. UEFI firmware might be buggy")
except OSError as e:
raise OgError(f"Unexpected error updating boot order: {e}") from e
raise OgError(f'Unexpected error setting boot order to NVRAM. UEFI firmware might be buggy') from e
def _find_efi_loader(loader_paths):
for efi_app in loader_paths:
@ -202,7 +170,13 @@ def copy_windows_efi_bootloader(disk, partition):
device = get_partition_device(disk, partition)
mountpoint = device.replace('dev', 'mnt')
if not mount_mkdir(device, mountpoint):
raise OgError(f'Unable to mount {device} into {mountpoint}')
raise OgError(f'Cannot probe OS family. Unable to mount {device} into {mountpoint}')
os_family = get_os_family(mountpoint)
is_uefi = is_uefi_supported()
if not is_uefi or os_family != OSFamily.WINDOWS:
return
bootlabel = f'Part-{disk:02d}-{partition:02d}'
esp, esp_disk, esp_part_number = get_efi_partition(disk, enforce_gpt=True)
@ -235,7 +209,7 @@ def restore_windows_efi_bootloader(disk, partition):
device = get_partition_device(disk, partition)
mountpoint = device.replace('dev', 'mnt')
if not mount_mkdir(device, mountpoint):
raise OgError(f'Unable to mount {device} into {mountpoint}')
raise OgError(f'Cannot probe OS family. Unable to mount {device} into {mountpoint}')
bootlabel = f'Part-{disk:02d}-{partition:02d}'
esp, esp_disk, esp_part_number = get_efi_partition(disk, enforce_gpt=True)

View File

@ -10,7 +10,9 @@ import libhivexmod
import hivex
from enum import Enum
from src.log import OgError
from uuid import UUID
from src.utils.disk import *
from src.utils.uefi import is_uefi_supported
WINDOWS_HIVES_PATH = '/Windows/System32/config'
@ -100,3 +102,36 @@ def get_node_child_from_path(hive, node, path):
child_node = get_node_child(hive, child_node, node_name)
return child_node
def uuid_to_bytes(uuid):
uuid = uuid.replace('-', '')
group0 = f'{uuid[6:8]}{uuid[4:6]}{uuid[2:4]}{uuid[0:2]}'
group1 = f'{uuid[10:12]}{uuid[8:10]}'
group2 = f'{uuid[14:16]}{uuid[12:14]}'
group3 = uuid[16:20]
group4 = uuid[20:32]
res = f'{group0}-{group1}-{group2}-{group3}-{group4}'
return UUID(res).bytes
def get_disk_id_bytes(disk):
disk_id = get_disk_id(disk)
if is_uefi_supported():
return uuid_to_bytes(disk_id)
return bytes.fromhex(disk_id)[::-1]
def get_part_id_bytes(disk, partition):
if is_uefi_supported():
part_id = get_partition_id(disk, partition)
return uuid_to_bytes(part_id)
partition_start_offset = get_partition_start_offset(disk, partition)
sector_size = get_sector_size(disk)
byte_offset = partition_start_offset * sector_size
byte_offset = "{0:016x}".format(byte_offset)
return bytes.fromhex(byte_offset)[::-1]