Commit Graph

173 Commits (ogkiosk)

Author SHA1 Message Date
Alejandro Sirgo Rica 3350c30353 cache: add cache.json to track cache metadata
Track partitions and images associated to a restore
operation through a cache.json file located in the
cache partition.

cache.json example contents:
{
    'images': [
        {
            'name': 'xxx.img',
            'disk': 1,
            'partition': 2
        },
        {
            'name': 'xxx.img',
            'disk': 1,
            'partition': 3
        }
    ]
}

Add class CacheDataFile to handle the cache.json
file.

Add an entry to the 'images' array each time a
restore operation is executed successfuly,
replace entries with the same disk/partition.

Remove entry to the 'images' array with image delete
operations.

Add image info to kiosk configuration. This enables
image restore operations. This information is not
retroactive, only newly restored images will enable
the restore button in Kiosk.
2025-02-14 13:57:46 +01:00
Alejandro Sirgo Rica 3ae6298f2c kiosk: add client data to boot view
show IP, MAC, link speed and hostname in the top left of the Kiosk
boot view.

Adjust boot view layout to better fit the new widget.

Add get_mac_from_interface() to net.py
2025-02-14 13:57:46 +01:00
Alejandro Sirgo Rica 7ace7f9403 ogclient: add kiosk
Add Kiosk project as a subtree of ogClient. Kiosk is
an interactive GUI featuring basic functionality to
monitor and operate ogClient withing the client through a
graphical interface written in PyQt6.

Right after ogClient launches in live mode it performs a
fork() call to launch Kiosk as an external process to
prevent Kiosk backtraces to affect ogClient.

A pair of sockets are created through socket.socketpair()
and each process is assigned one of them to leverage the
inter process communication.

API Kiosk -> ogClient:
- Poweroff: request client poweroff
{"command": "poweroff"}
- Reboot: request client reboot
{"command": "reboot"}
- Restore: restore image into a partition
{"command": "restore", "image": "windows.img", "disk": 1, "partition": 2}
- Boot: request an OS boot
{"command": "boot", "disk": 1, "partition": 2}

API ogClient -> Kiosk:
- Busy: inform about ogClient thread status
{"command": "busy", "status": True}
- Refresh: reload the theme.
{"command": "refresh"}
- close: request Kiosk termination.
{"command": "close"}

Add internationalization documentation in README

Add "CACHE" mode in image restore to only restore images
available in the cache partition.

Use set_state() function in OgRest to define the idle or busy
status and notify Kiosk about the status change.
2025-02-14 13:57:44 +01:00
Alejandro Sirgo Rica e0ba9cc98c uefi: log efibootmgr errors as warnings
Log as warning when efibootmgr fails to update the NVRAM.

Raise an exception when the command is not available or when
there are not enough permissions to execute. Provide contextual
information in the error message.
2025-02-13 09:06:38 +01:00
Alejandro Sirgo Rica ccdcb7bfc7 uefi: add missing f-string prefix in _find_bootentry() error
Add missing f-string prefix for proper string interpolation in
the error message of _find_bootentry()
2025-02-13 09:06:25 +01:00
Alejandro Sirgo Rica 0f519ecfeb grub: move disabled boot entries at the end of boot order
The GRUB entry is always set as the second boot option, assuming
PXE is first. This is not always true, as disabled entries before
PXE IPv4 can make it the first valid but not the first defined
entry in the boot order.

Move every disabled boot entry at the end of boot order.
2025-02-05 09:42:38 +01:00
OpenGnSys Support Team 574822907d grub: skip OS guess if partition cannot be mounted
otherwise, _get_os_entries() fails when it finds a swap partition:

  (2025-01-23 17:44:30) ogClient: [ERROR] - Error generating /mnt/nvme0n1p4/EFI/grub/Boot/grub.cfg: Unable to mount /dev/nvme0n1p3 into /mnt/nvme0n1p3
2025-01-24 15:15:57 +01:00
Alejandro Sirgo Rica 24568356bc winreg: move disk id functions into disk.py
Move uuid_to_bytes, get_disk_id_bytes and get_part_id_bytes from
winreg.py to the more fitting location disk.py
2025-01-07 15:56:55 +01:00
Alejandro Sirgo Rica d29b601f17 uefi: remove dependency with probe.py
Reduce interdependency between imports by checking the correct OS for
copy_windows_efi_bootloader() from the code invoking the operation.

Break circular dependency where:
probe.py imports from winreg.py
winreg.py imports from uefi.py
uefi.py imports from probe.py
2025-01-07 15:02:04 +01:00
Alejandro Sirgo Rica bf15491435 hw_inventory: fix json parsing
Add support for both lshw -json return formats.
The json structure may follow one of the following.

output:list flag enabled:
[{content}]

output:list flag disabled:
{content}

The output:list flag was defined in the commit 2b1c730 of
https://ezix.org/src/pkg/lshw
2024-12-11 15:17:02 +01:00
Alejandro Sirgo Rica 855768e144 src: refactor windows hive code
Remove usage of hivexget as a subprocess and use Python hivex to
inspect the Windows Registry.

Use registry path constants defined in src.utils.winreg

Remove windows_is64bit() funcion as the code to identify the
architecture relies on a broken Registry query. Fixing the query
proved to be a challenge and the only implication is the removal
of the string "64 bits" at the end of the listed Windows OS
installed in each partition.

Use utility function in src.utils.winreg to make the software
inventory code more compact.

Rewrite onliner in _fill_package_set function and parse the
registry with a for loop.
2024-12-11 15:16:34 +01:00
OpenGnSys Support Team 62b52ff364 src: update license header 2024-11-28 16:45:56 +01:00
Alejandro Sirgo Rica d7658f03ab utils: disable fcntl in ogClient for Windows
Add conditional import for fcntl as it is only supported for
Linux and causes ogClient for Windows fail to start.
2024-11-15 10:47:05 +01:00
Alejandro Sirgo Rica f5f8771b6f grub: fix failed grub configuration when a device is not found
Fix "No medium found" error aborting the grub configuration
process. Just log it and continue.
2024-11-14 18:12:56 +01:00
OpenGnSys Support Team 3b5152cdc1 tiptorrent: use absolute path to tiptorrent-client
instead of using PATH to find it
2024-11-07 19:22:47 +01:00
Alejandro Sirgo Rica 64f1f5403e disk: use different log message in get_disk_data and get_partition_data
Use a more specific message to differentiate the source of the error.

Add the target device to the log message.
2024-10-25 09:47:49 +02:00
Alejandro Sirgo Rica 07b4bc1fcd postinstall: remove call to ogFixBootSector script
Remove call to ogFixBootSector function as it is possibly only
required by Windows XP and FAT filesystem.
2024-10-24 10:52:33 +02:00
Alejandro Sirgo Rica 569caa733f cache: add code to cache the oglive boot files
Add update_live_cache() implementing the legacy script
updateBootCache()

Copy the ogvmlinuz and oginitrd.img files into cache after
a partition and format command with an available cache partition.
2024-10-24 10:52:33 +02:00
Alejandro Sirgo Rica fb707cef0b grub: move get_grub_boot_params() into grub.py
Move get_grub_boot_params() into the file related to all the grub
configuration.
2024-10-22 16:47:44 +02:00
Alejandro Sirgo Rica 373c1b2a72 grub: replace legacy grub install scripts
Translate old legacy grub scripts into grub.py
Implement ogGrubInstallMbr as install_main_grub() and
ogGrubInstallPartition as install_linux_grub().

Add grub configuration file generator through the classes
GrubConfig and MenuEntry.

Ensure EFI tree structure compatibility with legacy code.
The structure of the created folders in the ESP is non-standard,
efi binaries are usually located in the folder below the EFI/
directory.

Structure used by ogClient:

EFI/
├── grub/
│   └── Boot/
│       ├── BOOTX64.CSV
│       ├── grub.cfg
│       ├── mmx64.efi
│       ├── shimx64.efi
│       ├── BOOTX64.EFI
│       ├── grubx64.efi
│       └── ogloader.efi
...

The function _mangle_efi_folder handles the folder structure after
grub-install to comply with the location expected by ogLive.

install_linux_grub() installs a grub local to each Linux install
to enable chainloading, each grub is located in EFI/Part-xx-yy/ in
UEFI. The local linux BIOS grub in legacy scripts is unreliable,
grub-install reports a failure during the install process.

install_main_grub() installs a global grub in EFI/grub/ to show a
grub menu when the pxe boot fails. The global grub contains entries
to every installed os. No global grub is installed for BIOS
systems, a Boot partition would be required to store the grub
configuration.
2024-10-22 16:47:38 +02:00
Alejandro Sirgo Rica 2fcdf89606 disk: use cxt.label.name to dtect disk type in get_efi_partition
Use cxt.label.name instead of cxt.label to identify if the disk is
GPT or MBR. This way is more used in other parts of the codebase.
2024-10-21 16:56:05 +02:00
Alejandro Sirgo Rica b3659a30fc bios: fix use of undefined initrd_dir variable in get_vmlinuz_path
Use the intended linuz_dir instead of initrd_dir in the function
get_vmlinuz_path.
2024-10-21 12:04:23 +02:00
Alejandro Sirgo Rica 7be953dbe7 uefi: fix error message when no EFI loader
Fix log error message when _find_efi_loader does not find any
EFI loader in the ESP.
2024-10-11 12:06:37 +02:00
Alejandro Sirgo Rica 039bee2a05 bios.py: fix typo in GRUB_CMDLINE_LINUX_DEFAULT string
Check against GRUB_CMDLINE_LINUX_DEFAULT instead of
GRUB_CMDLINE_LINUE_DEFAULT.
2024-10-09 16:25:14 +02:00
Alejandro Sirgo Rica e8ddbbd075 src: isolate libfdisk operations to enable mount operations
python-libfdisk does not close file descriptor until the cxt
object goes out of scope.

Define get_partition_data and get_disk_data functions to isolate
the python-libfdisk logic and return the data as an object.

Improve error handling of libfdisk operaions in refresh.
2024-10-08 10:07:45 +02:00
Alejandro Sirgo Rica f942b19eae src: fix cache mount in new ogLive
Mount cache in image_create() image_restore() and cache_fetch().

Remove init_cache() and ensure /opt/opengnsys/images/ exists
within the cache mountpoint if it does not exists in cache_mount().
2024-10-08 10:07:45 +02:00
Alejandro Sirgo Rica 0f167cf29f src: consolidate compute_md5 functions
Add compute_md5 function in src/utils/fs.py

Remove identical md5 functions from src/live/ogOperations.py and
src/utils/tiptorrent.py

Move error checks from ogOperations.py into compute_md5 function in
src/utils/fs.py
2024-10-02 14:50:14 +02:00
Alejandro Sirgo Rica cc70274079 src: check if the system is hibernated before /image/create
Mount the system partition in readonly mode and check for the
hiberfil.sys file if the target system is a Windows.

Fail the image creation process if the target system is hibernated.
2024-10-02 14:25:04 +02:00
OpenGnSys Support Team e003ff6d8c tiptorrent: missing f-string in error
tip_client_get() needs f-string to display error
2024-10-01 17:48:07 +02:00
Alejandro Sirgo Rica e30e934272 src: replace DEVICE env variable with get_ethernet_interface()
Use a python function to obtain the main net interface. Detect
the first ethernet inferface in use.
Stop using the DEVICE environment variable.
2024-10-01 15:32:54 +02:00
Alejandro Sirgo Rica 8754c21694 src: report used and free partition data in bytes
Add "used_size" and "free_size" to the partition data and the
cache data.

Old response from ogClient for /cache/delete, /cache/fetch
and /image/restore:
{
  'cache': [
    {'name': 'windows.img', 'size': 2432370213, checksum: '5d4dcc677bc19f40a647d0002f4ade90'},
    {'name': 'linux.img', 'size': 243234534213, checksum: '3eb22f888f88a55ad954f55644e1192e'}
  ]
}

New response:
{
  'cache': {
    'used_size': 4520232322423,
    'free_size': 48273465287452945,
    'images': [
      {'name': 'windows.img', 'size': 2432370213, checksum: '5d4dcc677bc19f40a647d0002f4ade90'},
      {'name': 'linux.img', 'size': 243234534213, checksum: '3eb22f888f88a55ad954f55644e1192e'}
    ]
  }
}
2024-09-25 14:35:41 +02:00
Alejandro Sirgo Rica 3b40ec7918 sw_inventory: consolidate os_probe logic
Reuse os_probe() function from probe.py and change the fallback
case to "unknown" to prevent OS id mismatch in ogserver.

The OS id mismatch causes the images to stop being associated with
partitions after the /refresh command.
2024-09-25 14:35:41 +02:00
Alejandro Sirgo Rica 51258613cc src: verify the fields of the efibootmgr json in /refresh
Don't send the efi data in the /refresh payload if efibootmgr
is missing any of the json keys.

Log the missing keys in case of missing some.
2024-09-25 14:35:41 +02:00
Alejandro Sirgo Rica 11a963c709 utils: Add windows_register_c_drive implementation
Add python implementation of the legacy ogWindowsRegisterPartition
function.

This function configures the system partition to be considered the
new C drive after a Windows image restore.

The drive letter configuration is stored in the SYSTEM hive of
the windows registry. The node MountedDevices contains all the
configuration as key-value pairs.
The C drive key \DosDevices\C: contains a different value based on
the partitioning type.

GPT
the value is DMIO:ID: followed by the 16 byte GUID of the
partition.
Example: DMIO:ID:\xc9\xfc\x1c\x86\x13\x11O\t\xa2\x9c{/\xf1\xdf\xe4)

MBR
The value is a little endian byte sequence with 2 parts.
The first 4 bytes correspond to the disk id. The second part is
the byte offset start of the partition in that disk.
Example: \xe1\\\x9cP\x00\x00\x10j\x18\x00\x00\x00

If we format the MBR value in a more readable way we get
e1 5c 9c 50 00 00 10 6a 18 00 00 00
In this case the disk ID is 509c5ce1.
The partition offset is 186a100000.

This patch adds the following helper functions to:

- get_disk_id_bytes(): to obtain the disk identifier.

- get_part_id_bytes(): to obtain a partition identifier as UUID
  for MBR or DMIO:ID format for GPT.

- get_sector_size(): to query the sector size of a specific disk.
  Read /sys/class/block/{device_name}/queue/hw_sector_size to obtain the value.
  This is MBR specific.

- get_partition_start_offset(): to query the start sector of a specific
  partition and disk. Use sfdisk with the -J argument to get fdisk data in
  json format. This is MBR specific.
2024-09-12 10:43:09 +02:00
Alejandro Sirgo Rica f31e55fea4 bcd: make recovery modifications optional
Ignore recovery disable if no Recovery node is found in the BCD.
2024-09-10 15:37:08 +02:00
Alejandro Sirgo Rica f7b37ba010 utils: replace the legacy function ogConfigureFstab
Implement configure_fstab() as a replacement of ogConfigureFstab.

Create src/utils/fstab.py to implement the main fstab
configuration functions. Define two fstab helper classes,
FstabBuilder and FstabEntry.

FstabEntry
Represents each line in the fstab file.
Has the values: device, mountpoint, fstype, options, dump_code
and pass_code.

FstabBuilder
Contains a list of FstabEntry. Handles loading of a
preexisting fstab file and the serialization of multiple
FstabEntry into a file.

The fstab configuration has 3 main steps:

Root partition:
- Update the device field with the device where
the new system is installed.

Swap partition:
- Preserve all the swapfile entries in every case.
- If the filesystem has a swap partition: update the device field
  in the first fstab swap entry and remove the rest swap entries
  pointing to a swap partition. Only one swap partition is supported.
  Create a new fstab entry if no preexisting swap entry exists.
- If the system has no swap partition remove every swap partition
  entry.

EFI partition:
- Update the device field of the EFI fstab entry if it exists.
  Create a new fstab entry if no preexisting EFI entry exists.

Add get_filesystem_id to disk.py to obtain the UUID.
Define every device field as a UUID. That method is more robust
than a plain device path as it works after disks being added or
removed.
2024-08-30 12:19:48 +02:00
OpenGnSys Support Team c09c064f28 postinstall: ignore legacy scripts non-zero return code
legacy scripts are not reliable, legacy scripts continue processing on errors,
warn on errors until they are converted to native code instead.
2024-08-30 11:56:41 +02:00
OpenGnSys Support Team 9270a6c58f src: append .img to log that report image fetching 2024-08-29 13:10:50 +02:00
OpenGnSys Support Team 3d47b5069a src: use logging.warning()
logging.warn() is deprecated since 3.3.

And use .error() instead when command is unsupported or client is busy, that
should not ever happen.
2024-08-27 12:44:13 +02:00
OpenGnSys Support Team 4b62b80be7 utils: bcd: update logging related to BCD updates with MBR partition
MBR requires manual bcdedit invocation to generalize image before creation.
Report via logging that no BCD update occurs.
2024-08-27 12:34:58 +02:00
OpenGnSys Support Team 19e8825805 utils: return False instead of rising exception
if image file and checksum are not found in the cache, then report checksum
validation has failed so it can proceed to fetch new files from server.
2024-08-21 09:21:53 +02:00
OpenGnSys Support Team 1ca3992f71 src: remove call to restoreImageCustom script
remove call to custom version of legacy script, display warning.
2024-08-21 09:21:53 +02:00
Alejandro Sirgo Rica 71b3211d3d postinstall: remove shell=True
Remove the use of shell=True.
2024-08-09 11:05:02 +02:00
OpenGnSys Support Team 89d711be2a postinstall: ignore output when invoking legacy scripts
output is never consumed.
2024-08-08 13:36:32 +02:00
OpenGnSys Support Team 9be639ae78 postinstall: add logging to report this stage
log that image restoration has entered OS configuration stage.
2024-08-08 12:21:05 +02:00
OpenGnSys Support Team 9ee5f4adaa live: move filesystem expansion out of OS configuration
just a clean up.
2024-08-06 18:39:37 +02:00
OpenGnSys Support Team 9a52df7711 postinstall: add logging to report postconfiguration script invocation 2024-08-06 18:16:23 +02:00
OpenGnSys Support Team 16251d42d3 postinstall: typo in maximum win hostname error
s/nor/not
2024-08-06 17:30:19 +02:00
OpenGnSys Support Team fd64b84bcc postinstall: linux does not allow more than 64 bytes long hostnames
As per:

  $ getconf HOST_NAME_MAX
  64

truncate it to the maximum.
2024-08-06 17:29:57 +02:00
OpenGnSys Support Team 9b317cf3e0 utils: disk: revisit logging to find EFI partition
instead of

	Checking partition "Microsoft Basic Data"...
	Checking partition "EFI System"...

show

	Searching EFI partition...
	EFI partition found at /dev/sda1

and refer to EFI partition consistently in logs.
2024-07-30 16:50:17 +02:00